commit 5edbb7a80a158583a81de286b7fcc5392916ba38 Author: mnerv Date: Sun Aug 27 18:03:45 2023 +0200 FreeType 1.31.1 diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 0000000..acd3f61 --- /dev/null +++ b/.cvsignore @@ -0,0 +1,7 @@ +config.cache +MakeSub +Makefile +config.status +libtool +ft_conf.h +config.log diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..d461635 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.10) +project(freetype VERSION 1.3.1) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Generate compile_commands.json for ccls +set_property(GLOBAL PROPERTY USE_FOLDERS ON) # Group CMake targets inside a folder + + diff --git a/FILES b/FILES new file mode 100644 index 0000000..b02bce9 --- /dev/null +++ b/FILES @@ -0,0 +1,76 @@ +This text file contains an overview of this package's directory and +file hierarchy. + + + docs/ Documentation. + docs/image GIF images for documentation. + + lib/ The C engine source directory. + lib/extend Some standard engine extensions. + lib/arch/ System-specific configuration header files. + + howto/ Various system-specific HOWTOs, explaining how + to compile the library on different platforms. + + test/ The C test programs. + test/arch/ System-specific graphics drivers for test + programs. + + contrib/ Contributions directory. + contrib/mac An HQX archive containing a port to the Mac. + contrib/ttf2pk The ttf2pk TrueType to PK converter source + code. + contrib/ttf2pfb The ttf2pfb TrueType to PS font converter + source code. + contrib/ttf2bdf The ttf2bdf TrueType to BDF converter source + code. + contrib/ftos2 The FreeType/2 font server source code for + OS/2. + contrib/ttfbanner An ASCII poster program source code. + + po/ Contributions to the internationalized error + message strings extension. + + pascal/lib Pascal engine source directory. + pascal/test Pascal test programs. + + +The following files might be helpful: + +FILES This file. + +README A short and general introduction to FreeType. + +INSTALL The FreeType installation How-To. Everything you need + to know to build the library and the test programs. + This file contains only generic explanations. See the + `freetype/howto' directory for system-specific hints. + +license.txt The FreeType license. + +announce The FreeType UseNet announce post. This file is sent + to some newsgroups when a new release is made. + + +The following files are Unix-specific and can be ignored on other +platforms: + +ft_conf.h.in Generic library configuration header file for + autoconf. +configure.in Generic configure script for autoconf. +configure Configure script generated from `configure.in' by + autoconf. +config.sub Script needed by configure. +config.guess Script needed by configure. +Makefile.in Generic makefile for configure. +MakeSub.in Generic makefile for libtool. +ltconfig Libtool configuration script. +ltmain.sh Libtool script. +mkinstalldirs Tool for generating subdirectories. +a4local.m4, +net.m4 Auxiliary data files for autoconf. +install-sh Script used to install the library in a portable way +freetype.spec This file can be used as a specification to build RPMs + from the FreeType package. + +--- end of FILES --- diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..09fff40 --- /dev/null +++ b/INSTALL @@ -0,0 +1,879 @@ + + The FreeType compilation guide + + +Table of contents +----------------- + + I. Introduction + + II. Compiling and installing the C library + + 1. Choosing a configuration file + 2. Compiling the library + 3. System-specific builds + 4. Compiling the extensions + 5. Using a Makefile + 6. Building a dynamic library (`DLL' or `so') + 7. Internationalization and the `ftxerr18' extension + 8. TrueType patents + + +III. Compiling the test programs + + 1. Compiling the graphics sub-system + 2. Internationalization on Unix + 3. Compiling the test programs + 4. The `fdebug' program + + + IV. Compiling the Pascal source + + 1. Compiling the library + 2. Compiling the test programs + 3. Porting the library to a different Pascal compiler + +-------------------------------------------------------------------- + + + +I. Introduction +=============== + + This file gives detailed information on how to compile and install + this release of FreeType on your system. + + +******************************************************************** +* * +* FOR A QUICK INSTALLATION GUIDE, WE STRONGLY RECOMMEND TO READ * +* THE SYSTEM-SPECIFIC DOCUMENTS LOCATED IN THE `howto' DIRECTORY * +* INSTEAD OF THIS GENERIC DOCUMENTATION. * +* * +******************************************************************** + + + This package, known as the FreeType 1.3.1 Public Release, contains + several things which are best described by the directories + containing them: + + - `lib' + + Contains the 1.3.1 release of the FreeType library. It is written + in portable ANSI C and should compile fine with any type of + ANSI C compiler. + + Note however that some system-specific files are provided in the + `lib/arch' directory, in order to provide enhanced performance. + + If you need to include FreeType in a graphics library or an + embedded system, you will most probably only need to use its + contents and discard the rest. + + - `test' + + Contains test and demo programs used during development. Note + that some of these programs might not compile on all platforms, + as they need to display graphics. + + - `pascal' + + Contains the Pascal version of FreeType's source code. Note + that the library has been successfully compiled with Turbo + Pascal 6, Borland Pascal 7, Virtual Pascal, Free Pascal, + Delphi 1, 2 and 3. + + The pascal source tree contains its own test programs which + should *only* run with either Borland or Virtual Pascal + compilers. + + - `po' + + On Unix, all of FreeType test programs support + internationalization through the use of the `gettext' library. + This directory contains `po' files, which are used to translate + the original english text into language-specific one. + + Note also that this release contains an extension, called + `ftxerr18' used to return internationalized strings from the + usual FreeType error codes. The `po' files also contain + translations for this extension. + + If you don't plan to use `ftxerr18' or internationalization, + simply ignore it. Note also that even if `gettext' isn't + available on your system, the test programs will be compiled + correctly (using the `--disable-nls' configure switch). + + - `contrib' + + Contains a set of contributed tools and utilities related to + TrueType or FreeType. Here you can find real situations how to + use the library. + + + This file explains how to compile the library, and the test + programs on various platforms. + + + +II. Compiling the C library +=========================== + + +******************************************************************** +* * +* NOTE THAT WE STRONGLY RECOMMEND TO READ THE SYSTEM-SPECIFIC * +* DOCUMENTS LOCATED IN THE `howto' DIRECTORY FOR A * +* `QUICK'N'EASY' COMPILATION & INSTALLATION GUIDE ON YOUR * +* PLATFORM. THE FOLLOWING IS A VERY DETAILED EXPLANATION ON HOW * +* TO COMPILE THE LIBRARY. * +* * +******************************************************************** + + + The following concepts are important to build the library. + + + 1. Choosing a configuration file + -------------------------------- + + The source code for the C library is located in the `lib' + directory. + + It uses a file named `ft_conf.h', which contains the definitions + of many configuration macros to toggle various engine features, + as well as tell system-specific information (e.g., the size of + the `int' type in bytes, etc). + + There are several configuration files provided with this + release. They are located in the `lib/arch/' directory, + where stands for a given architecture or environment. + + For example, the file `lib/arch/ansi/ft_conf.h' can be used to + build the library with any ANSI-compliant compiler and runtime + library. + + This release also provides configuration files for the following + systems: MS-DOS, OS/2, Unix, VMS, Win 16, Amiga OS, and Win 32. + + Make sure, when compiling each source file of the FreeType + library, to include the path to your configuration file in your + include directories. + + + 2. Compiling the library + ------------------------ + + The library can be quickly compiled by invoking a Makefile, as + described in the system-specific documents in the `howto' + directory. + + We will now describe how to compile the library by hand. + + Traditionally, building a library like FreeType needs the + following steps: + + - Compile each individual `.c' file into the corresponding + object file, whose extension might be `.o' or `.obj', + depending on the platform. + + - Group all object files into a library (e.g. `libfreetype.a' or + `freetype.lib'), which is later used at link time to build the + executables using it. + + For example, to build a static FreeType library on an ANSI + system, with gcc, one should type + + cd lib # go to `lib' directory + gcc -c -Iarch/ansi tt*.c # compile base engine sources + ar -r libfreetype.a tt*.o # create library from objects + + Note that we included the path to the configuration file in the + include list during compilation, by using the `-I' switch on the + `arch/ansi' directory. This is required to use the + configuration file named `lib/arch/ansi/ft_conf.h'. + + However, we recommend you to build the base FreeType engine as a + SINGLE OBJECT FILE, i.e., a single `freetype.o' or + `freetype.obj' file containing all the code for the base engine. + It works by including all the `.c' files in a single one, and + has a few advantages over a `traditional build': + + - Because all the code is `part' of a single source file, many + internal functions need not be declared as `extern' anymore. + + This means that when compiling the engine as a dynamic + library, only FreeType external functions will (correctly) be + exported as entry points. + + This also typically allows the compiler to perform more + aggressive optimizations on the source code, and results in + somewhat faster and/or smaller overall code size depending on + your compiler and environment. + + - Compilation speed is greatly improved, as the pre-processor + and compiler need to be called only once, instead of a dozen + times. + + - During development, this allows to detect very easily + unresolved dependencies regarding the base engine's internal + symbols. + + To compile the engine as a single object file, simply go to the + `lib' directory and compile the file + `lib/arch//freetype.c'. + + For example, to compile the ANSI build with gcc in SINGLE OBJECT + MODE, use + + cd lib + gcc -c -Iarch/ansi -I. arch/ansi/freetype.c + + This will create a single file called `freetype.o' containing + the object code for the base TrueType engine. + + Note that we did include the paths to the configuration file + (i.e. `arch/ansi') AND to the current directory (i.e. `.', + where the included source files are located). + + `freetype.o' only contains the base engine. Extensions to the + engine are located in the `lib/extend' directory and must be + compiled separately as described later. + + + 3. System-specific builds + ------------------------- + + The files `ttfile.c', `ttmemory.c', and `ttmutex.c' are used to + provide an implementation of i/o access, memory management, and + thread synchronization for the rest of the library. + + These source files, located in the `lib' directory, use the ANSI + C library for i/o and memory, and simply ignore threads (as the + standard doesn't know threads at all). + + However, this release provides, for each supported platform, + system-specific versions of these files, located in the + `lib/arch/' hierarchy. Here are a few examples: + + lib/arch/os2/os2file.c: + + A replacement for `ttfile' which directly uses OS/2 system + calls for i/o access. This results in slightly better + performance, but much reduced resource requirements. + + lib/arch/unix/ttmmap.c: + + A replacement for `ttfile' which uses memory-mapped files + instead of buffered-based reads on Unix. This increases + *dramatically* the engine's performance when reading font + files and loading glyphs. + + These files are directly included by the platform specific + versions of `freetype.c' which are located in + `lib/arch/'. This means that, by default, the + single-object build of FreeType always chooses the best + implementation available for a supported system. + + Note that it is also possible to redefine `ttmemory' or + `ttmutex' with a similar scheme. This is used, for example, by + the OS/2 font driver based on FreeType (called FreeType/2), + which uses some special system calls to allocate memory + shareable among distinct processes. + + By providing your own version of `ttfile', `ttmemory', and + `ttmutex', you are able to tailor the FreeType engine for + optimal performance and resource usage on your system. + + + 4. Compiling the extensions + --------------------------- + + The base TrueType engine is located in the `lib' directory. + This release also provides many specific extensions in + `lib/extend'. + + An extension is a simple way to extend FreeType's capabilities. + It is used to perform any of the following: + + - Access some TrueType tables that are not loaded and returned + by the base engine, like + + * the kerning table(s) + * the `gasp' table + * the glyph Postscript names + * some OpenType layout tables (GDEF, GSUB; GPOS is not + finished yet) + + - Perform some advanced operations on the TrueType data for very + specific uses, like + + * enumerate the contents of a given charmap + * access a font file's embedded bitmaps (called sbits) + * return an array containing the dimensions of each glyph in + the font + + The idea is to keep the base engine small (under 50kByte), while + providing optional enhancements for specific uses. + + Writing an extension is rather easy. And adding a new extension + to the engine doesn't need any modifications to the base + engine's source code. + + To compile the extensions, simply go to the `lib' directory, + then compile each file in `lib/extend'. Here is an example with + gcc: + + cd lib ; go to `lib' + gcc -c -Iarch/ansi -I. extend/ftx*.c ; compile all extensions + + + You can later add each extension object file to the FreeType + library file. For example, here is how to create the static + library on Unix: + + cd lib + -- compile the engine, then the extensions + ar libfreetype.a *.o ; create static library + + + 5. Using a Makefile + ------------------- + + This release also provides Makefiles for many systems and + compilers in the `lib/arch/' hierarchy. For more + information, please read the documentation in the `howto' + directory, which contains system-specific instructions on how to + use them. + + Generally, you should go the `lib' directory, then invoke your + system-specific Makefile from there. Here is an example: + + cd lib + make -farch\msdos\Makefile.TC + + to compile the library under DOS with the Turbo C compiler and + make tool. Or: + + cd lib + wmake -f arch\msdos\Makefile.wat + + to compile it under DOS with the Watcom compiler and wmake tool. + + The ANSI target does not come with a Makefile, as there is no + standard make tool available on all platforms. You will have to + compile the library by hand as described in section I.3. + + We welcome new Makefile submissions for platforms not currently + listed in the `lib/arch' hierarchy. + + Finally, note that most of the makefiles will build the library + in single object mode; for a `traditional compile', try the + `debug' target (i.e., say `make debug'). + + + 6. Building a dynamic library (`DLL' or `so') + --------------------------------------------- + + It is possible to build the engine as a dynamic library. The + method to do so can vary greatly depending on the platform. + + a. Building a shared object on Unix + + NOTE THAT THIS RELEASE USES `libtool' TO AUTOMATICALLY CREATE + A SHARED OBJECT FOR FREETYPE ON UNIX SYSTEMS THAT SUPPORT + DYNAMIC LIBRARIES. WE STRONGLY RECOMMEND YOU TO READ THE + `howto/unix.txt' FILE TO KNOW HOW TO USE THE `configure' + SCRIPT. THIS SUB-SECTION DESCRIBES HOW TO COMPILE THE SHARED + OBJECT BY HAND. + + In order to build a shared object like `libfreetype.so' on + Unix, one has to compile each object file as + position-independent code (a.k.a. PIC). + + We also strongly recommend to build the base engine as a + single object, as this prevents internal `extern' functions to + be exported as entry points (and creating a smaller overall + .so file). + + For example, this with gcc, one can use the `-fPIC' flag when + compiling the object files. Here is an example: + + cd lib ; go to `lib' + gcc -c -fPIC -Iarch/ansi -I. \ + arch/ansi/freetype.c ; compile engine + gcc -c -fPIC -Iarch/ansi -I. extend/ftx*.c ; & extensions + + You can now invoke your linker to create the shared object + from the various object files. See your system's + documentation for details, or read the Unix-specific howto to + know how to do it `easily' through the use of `libtool'. + + b. Building a DLL on Windows or OS/2 + + The dynamic linkers of Windows and OS/2 differ greatly from + Unix ones. + + - The first difference is that the object files that make up + the DLL do not need to be compiled as position-independent + code. + + - The second difference is that the DLL's entry points must + generally be declared as so in the source file, and/or maybe + listed in a `definition' file used at link time when + creating the DLL. + + Each FreeType API function is declared with the help of a + special macro named EXPORT_DEF. For example, here is the + declaration of the function `FT_Init_FreeType', as written in + `freetype.h': + + EXPORT_DEF + TT_Error TT_Init_FreeType( TT_Engine* engine ); + + If the configuration file `ft_conf.h' doesn't define + EXPORT_DEF, it is automatically set to `extern' by default. + + In order to build FreeType as a DLL, one might need to define + EXPORT_DEF in its `ft_conf.h' to a keyword tagging the + function as a DLL entry point. This keyword varies with + compilers and platforms; examples are `__system', + `__dllentry', etc. + + Please refer to your compiler's user guide for instructions. + + You can also `grep' for EXPORT_DEF in the `freetype.h' source + file to obtain the list of exported functions of the FreeType + API, which could then be used to write a `def' file for the + DLL. We provide a sample .def file (built with an Unix script) + for Windows. + + Note also that the definition (i.e. its implementation) of + each exported function is preceded with the EXPORT_FUNC macro, + as in + + EXPORT_FUNC + TT_Error TT_Init_FreeType( TT_Engine* engine ) + { + TT_Error error; + ... + } + + (to be found in `ttapi.c'). + + By default, EXPORT_FUNC converts to an empty string, but it + can also be redefined if you need to. + + Note that the EXPORT_DEF/EXPORT_FUNC mechanism does not work + for 16-bit Windows (in this environment, the special keyword + for declaring entry points, (the `__export' keyword), must be + after the type name). We suggest you to use the makefiles we + provide for both Microsoft and Borland compilers. + + + 7. Internationalization and the `ftxerr18' extension + ---------------------------------------------------- + + The engine extension named `ftxerr18' is used to convert a + FreeType error code into a human-readable string of text. + + However, it is able to support internationalization on Unix + systems through the use of the `gettext' library. This means + that the error messages will be localized to your system's + language, provided it is available in this release. The + currently available languages are + + - English (by default) + - Czech + - German + - Spanish + - French + - Dutch + + One can add a new language by adding a `.po' file in the `po' + directory. Please read the file `docs/i18n.txt' for more + details on how to use `gettext'. + + In order to enable localization of the `ftxerr18' extension, one + has to set the macro HAVE_LIBINTL_H at compile time. By + default, the extension will build with support for the English + language. + + Unix-specific: ------------------------------------------------- + + Note that the Unix `configure' script that comes with this + release is able to automatically detect whether your system + has `gettext' installed and set HAVE_LIBINTL_H in the + `ft_conf_h' file accordingly. + + To disable internationalization, run `configure' with the + option `--disable-nls' (NLS stands for `National Language + Support'). Then rebuild the library. + + ---------------------------------------------------------------- + + Note that we do not support internationalization on non-Unix + platforms, as the `gettext' library isn't available everywhere, + or does not work in a consistent way in different environments. + + + 8. TrueType patents + ------------------- + + We have recently discovered that Apple owns several patents that + relate to the rendering of TrueType fonts. This could mean that + the free use and distribution of the FreeType library could be + illegal in the US, Japan, and possibly other countries. + + For more information, please see the FreeType Patents page at: + + http://www.freetype.org/patents.htm + + This section will now explain how to build a `patent-free' + engine, at the cost of rendering quality. This is done simply + by de-activating the compilation of the TrueType bytecode + interpreter (which is the only part of FreeType that might + violate an Apple patent). This has two effects: + + - saving about 18kByte of code in the engine + - ignoring completely the grid-fitting of vector outlines, which + results in extremely low quality at small pixel sizes. + + Such an engine can be used by font converters and/or graphics + libraries to display glyphs at high pixel sizes. + + In order to do so, simply look for the following line in your + configuration file `ft_conf.h': + + #undef FT_CONFIG_OPTION_NO_INTERPRETER + + Then change the `#undef' into a `#define': + + #define FT_CONFIG_OPTION_NO_INTERPRETER + + Now rebuild the engine with this new configuration file. + + + +III. Compiling the test programs +================================ + + This section explains how to compile the FreeType test programs + located in the `test' directory. Note that you should have + successfully compiled the library, as described in section I + before proceeding. + + WE STRONGLY RECOMMEND TO READ THE SYSTEM-SPECIFIC DOCUMENTS IN THE + `howto' DIRECTORY FOR A `QUICK'N'EASY' GUIDE ON HOW TO COMPILE AND + RUN THE TEST PROGRAMS. + + + 1. Compile the graphics sub-system and utility sources + ------------------------------------------------------ + + Some of the test programs need to display a graphics window to + show their results. In order to do so, they use a tiny graphics + system which was specifically written for FreeType (Note: The + code isn't really clean there -- you have been warned). + + Also, some simple C sources in the `test' directory are utility + functions used by nearly all test programs, and they should also + be compiled before them. These are the following files: + + gmain.h: the sub-system interface + gmain.c: the sub-system device-independent implementation + gevents.h: the definition of the events used by the test + program + gdriver.h: the system-specific device interface + blitter.c: a set of simple bitmap blitting functions + common.c: common routines used by all test programs + display.c: some routines dealing with text display + + as well as a system-specific `graphics driver' located in the + `test/arch/' hierarchy. For example: + + test/arch/msdos/gfs_dos.c: used to display graphics in a + full-screen Dos session + test/arch/os2/gpm_os2.c: used to display graphics in an OS/2 + Presentation Manager window + test/arch/unix/gwin_x11.c: used to display graphics in an X11 + window. + + You must compile the graphics sub-system and utilities before + compiling the test programs. This can be done simply with gcc + as: + + cd test + gcc -c -I../lib gmain.c blitter.c common.c display.c + gcc -c -I../lib -I. arch//yourdriver.c -o ./gdriver.o + + Note that a given test program may require some specific include + paths (like `/usr/X11/include' with X11 for example). + + The resulting object files can be grouped in a library if you + want to. + + + 2. Internationalization on Unix + ------------------------------- + + On Unix and Unix-like systems, the test programs are able to + support internationalization through the use of the `gettext' + library and the `ftxerr18' engine extension (see section I.7). + + To enable it, one has to compile each test program with the + macro HAVE_LIBINTL_H set. This is the same macro used to enable + it in `ftxerr18'. + + Note that the Unix `configure' script that comes with this + release is able to automatically detect whether `gettext' is + available on your system and set the macro accordingly when + compiling the test programs. + + You can disable internationalisation with the `--disable-nls' + option when invoking the `configure' script. + + + 3. Compile the test programs + ---------------------------- + + All test programs begin with the `ft' prefix in the `test' + directory, as in `ftzoom', `ftdump', `ftmetric'", etc. are test + programs. + + The easiest way to compile the test programs is compiling each + source file to an object file, including the path to the + FreeType engine source and its extensions. You need to use the + following include paths: + + - the path to the engine's public header file, i.e. `freetype.h' + which normally is `lib' + + - the path to the engine's extensions header files, located + normally in `lib/extend' + + - the path to the configuration file `ft_conf.h'. This is only + required to support internationalisation, as the test programs + read `ft_conf.h' only to see whether HAVE_LIBINTL_H is + defined. + + When compiling your own programs to FreeType, you shouldn't + normally need this file and path. + + Here is an example, compiling a test program with the ANSI + build: + + cd test + gcc -c -I../lib -I../lib/extend -I../lib/arch/ansi \ + .c + + Then, link this object file to the FreeType library, utilities + and graphics sub-system to build an executable. + + You can then invoke each program directly. + + + 4. The `fdebug' test program + ---------------------------- + + All test programs begin with the `ft' prefix (in the `test' + directory) as in `ftzoom', `ftdump', `ftmetric', etc. + + However, one test program named `fdebug' is used exclusively by + FreeType developers. It is a very simple TrueType bytecode + debugger, and was written to inspect the execution of the + TrueType interpreter. + + Note that we rather use the Pascal debugger for real work on the + interpreter, as it provides a much easier windowed interface + through the use of the Turbo Vision library. The C debugger is + mainly used to check that both Pascal and C sources produce the + same output. + + You will need gcc to compile the debugger. It uses a special + build of the FreeType engine to work. Follow these steps to + compile it: + + 1. Compile the library for the `debugger' system, i.e. + + cd freetype/lib + make -f arch/debugger/Makefile + + this will create a file named `libttf.a' in the directory + `freetype/lib/arch/debugger' which will NOT interfere with + your normal build (which is located in `freetype/lib'). + + 2. Compile the debugger: + + cd freetype/test + make -f arch/debugger/Makefile + + This will create an executable called `fdebug.exe' or + `fdebug', which is linked with the version of the library + found in `freetype/lib/arch/debugger' as described above. + + [For old Unix variants like 4.2BSD please uncomment the flag + HAVE_POSIX_TERMIOS in the makefile.] + + You can invoke the debugger in two ways: + + a. To debug a given glyph program in a given font, type + + fdebug glyph_number pointsize fontfile[.ttf] + + b. To debug a given font's CVT program, type + + fdebug --cvt pointsize fontfile[.ttf] + + Type `?' while running fdebug for a list of key bindings. + + +IV. Compiling the Pascal source +=============================== + + This section deals with the compilation of the Pascal version of + the FreeType engine, whose source code is located in the `pascal' + directory. + + Note that the Pascal version is more limited than the C one, as it + lacks the following `features': + + - Extensions are neither supported nor provided in Pascal. + + - The interpreter is more pedantic than the C one and will + probably not work with many broken glyphs. + + - It doesn't compile on old Turbo Pascal (TP 6.0 is a minimum), as + it uses inline assembly code. + + Other than that, the Pascal version supports charmaps and the name + table correctly since the 1.3 release. + +******************************************************************** +* * +* AN IMPORTANT NOTE REGARDING TURBO AND BORLAND PASCAL USERS * +* ========================================================== * +* * +* Programs compiled with TP6 and BP7 might not be able to run on * +* fast machines! * +* * +* Usually, the program aborts immediately with a message like * +* * +* Runtime error 200: Divide by zero at xxxx:xxxx * +* * +* The bug is located in the runtime's initialization routine * +* used to compute the machine's speed. It does so by dividing a * +* value taken through the BIOS timer by a small constant. * +* * +* On fast machines, the result exceeds 16 bits, which causes a * +* CPU exception/interrupt. The latter is caught by the * +* runtime's exception handlers which aborts the execution and * +* prints the above message. * +* * +* We don't know anything that can be done to fix this bug, as it * +* would need a recompilation of a version of the Borland runtime * +* initialization code. * +* * +******************************************************************** + + Due to lack of time, the library could not be fully tested under + TP6 or BP7. + + + 1. Compiling the library + ------------------------ + + The library itself is located in `pascal/lib'. You can compile + it very simply by invoking your Pascal compiler on the file + `freetype.pas'. + + As always with Pascal, dependencies are resolved automatically. + + + 2. Compiling the test programs + ------------------------------ + + The test programs are located in `pascal/test'. You will mainly + find there the following: + + lint - A TrueType glyph loading checker. This test program + will simply load each glyph in a font file and check + for errors in its hinting programs. It is useful to + find broken glyphs in fonts. + + view - A simple TrueType glyph viewer. Shows all the glyphs + within a given font file on a graphics screen. Only + works under DOS (with Borland Pascal) and OS/2 (with + Virtual Pascal). + + timer - A simple benchmark program for the scan-line + converter. Similar to the C `fttimer' test program. + + debugger - A TrueType bytecode debugger. This one must be + compiled with the Turbo Vision library. It uses a + rather advanced windowed interface to display the + glyph program and their execution. It can also + display the current glyph in a graphics window. A + bit rough but extremely useful to the development + of FreeType. + + dump - A TrueType metrics checker. This test program simply + checks that the hinted width of each glyph corresponds + to the one found in the TrueType `hdmx' table when + present. This program is now obsolete and should be + ignored. + + As always, simply invoke the root source file to make an + executable automatically -- don't forget to include the path to + the FreeType unit as described in section III.1. + + + 3. Porting the library to a different Pascal compiler + ----------------------------------------------------- + + The Pascal sources use inline assembly to implement the 64-bit + computation routines needed by the TrueType engine. This + release comes with various versions of the `ttcalc' inline + assembly. + + These files are (within `pascal/lib'): + + ttcalc1.inc: for Turbo and Borland Pascal & Delphi 1 (16-bit) + ttcalc2.inc: for Virtual Pascal (32-bit) + ttcalc3.inc: for Delphi 2 & 3 (untested on Delphi 4 & 5) + ttcalc4.inc: for Free Pascal on a i386 (32-bit) + + Note that in order to port the Pascal source to a new compiler, + one has to: + + a. Write a specific version of `ttcalc?.inc' for the compiler's + inline assembly. + + Be sure to respect the compiler's assembler syntax, as well + as its parameter-passing function interface, i.e., which + registers and/or stack slots are used to pass arguments at + function call. + + b. Add some lines to detect your compiler in `ttconfig.inc'. + + This file contains some tests to define macros used to + determine which compiler is used. These macros are used + later in `ttcalc.pas' in order to select the correct inline + assembly file to use. + + See the source files for more details. + + c. Add an include to the new `ttcalc?.inc' in `ttcalc.pas'. + + Make this according to the compiler detected in + `ttconfig.inc'. + + See the source files for more details. + + d. Submit your changes to the FreeType Developers list. + + In order to see them added to the next release of the Pascal + engine. + + +--- end of INSTALL --- diff --git a/MakeSub.in b/MakeSub.in new file mode 100644 index 0000000..90d10b9 --- /dev/null +++ b/MakeSub.in @@ -0,0 +1,7 @@ +# this file is part of the FreeType project + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +libdir = @libdir@ +bindir = @bindir@ +includedir = @includedir@ diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..f4e1c94 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,60 @@ +# This file is part of the FreeType project. + +RMF = @RM@ -f + +MAKEFILE = arch/unix/Makefile + +FTLIBDIR = lib +FTTESTDIR = test +FTPODIR = po + +all: ttlib tttest ttpo + +debug: ttlibdebug tttest ttpo + +# we can't use the target names 'lib', 'test', etc. +# because make will believe that the directories are +# the targets and are up-to-date! Grrr... >:-( + +ttlib: + cd $(FTLIBDIR); $(MAKE) -f $(MAKEFILE) all + +ttlibdebug: + cd $(FTLIBDIR); $(MAKE) -f $(MAKEFILE) debug + +tttest: + cd $(FTTESTDIR); $(MAKE) -f $(MAKEFILE) all + +ttpo: + cd $(FTPODIR); $(MAKE) all + +install: + cd $(FTLIBDIR); $(MAKE) -f $(MAKEFILE) install + cd $(FTTESTDIR); $(MAKE) -f $(MAKEFILE) install + cd $(FTPODIR); $(MAKE) install + +uninstall: + cd $(FTLIBDIR); $(MAKE) -f $(MAKEFILE) uninstall + cd $(FTTESTDIR); $(MAKE) -f $(MAKEFILE) uninstall + cd $(FTPODIR); $(MAKE) uninstall + +clean: + cd $(FTLIBDIR); $(MAKE) -f $(MAKEFILE) clean + cd $(FTTESTDIR); $(MAKE) -f $(MAKEFILE) clean + cd $(FTPODIR); $(MAKE) clean + +distclean: + cd $(FTLIBDIR); $(MAKE) -f $(MAKEFILE) distclean + cd $(FTTESTDIR); $(MAKE) -f $(MAKEFILE) distclean + cd $(FTPODIR); $(MAKE) distclean + $(RMF) config.cache config.log config.status Makefile \ + MakeSub ft_conf.h libtool + +check: + @echo This package does not yet have a validation suite + +depend: + cd $(FTLIBDIR); $(MAKE) -f $(MAKEFILE) depend + cd $(FTTESTDIR); $(MAKE) -f $(MAKEFILE) depend + +# end of Makefile.in diff --git a/PATENTS b/PATENTS new file mode 100644 index 0000000..8c02625 --- /dev/null +++ b/PATENTS @@ -0,0 +1,27 @@ + + FreeType Patents Disclaimer + August 1999 + + + +WE HAVE DISCOVERED THAT APPLE OWNS SEVERAL PATENTS RELATED TO THE +RENDERING OF TRUETYPE FONTS. THIS COULD MEAN THAT THE FREE USE OF +FREETYPE MIGHT BE ILLEGAL IN THE USA, JAPAN, AND POSSIBLY OTHER +COUNTRIES, BE IT IN COMMERCIAL OR OPEN SOURCE PRODUCTS. + +FOR MORE DETAILS, WE STRONGLY ADVISE YOU TO GO TO THE FREETYPE +PATENTS PAGE AT THE FOLLOWING WEB ADDRESS: + + http://www.freetype.org/patents.htm + +WE WILL NOT PLACE INFORMATION IN THIS FILE AS THE SITUATION IS STILL +UNDETERMINED FOR NOW. AT THE TIME THESE LINES ARE WRITTEN, WE HAVE +CONTACTED APPLE'S LEGAL DEPARTMENT AND ARE STILL WAITING FOR THEIR +ANSWER ON THE SUBJECT. + +PLEASE READ THE `INSTALL' FILE TO SEE HOW TO DISABLE THE ENGINE'S +BYTECODE INTERPRETER IN ORDER TO BUILD A PATENT-FREE ENGINE, AT THE +COST OF RENDERING QUALITY. + + +--- end of PATENTS --- diff --git a/README b/README new file mode 100644 index 0000000..28950be --- /dev/null +++ b/README @@ -0,0 +1,695 @@ + + + Welcome to the + + F R E E T Y P E P R O J E C T + + http://www.freetype.org + + Release 1.3.1 + + The FREE TrueType Font Engine + + Copyright 1996 David Turner + - 1999 Robert Wilhelm + Werner Lemberg + + + Table of Contents + ----------------- + + I. Introduction + + II. The FreeType mini-FAQ + + III. How to use the test programs + + 1. ftzoom + 2. ftlint + 3. ftview + 4. fttimer + 5. ftdump + 6. ftstring + 7. ftstrpnm + 8. fterror + 9. ftsbit + 10. ftmetric + 11. ftstrtto + + IV. How to use the programs in the `contrib' directory + + V. Final remarks + + +I. Introduction +=============== + + Please read the file `INSTALL' for installation instructions! + + The FreeType engine is a free and portable TrueType font rendering + engine. It has been developed to provide TrueType support to a + great variety of platforms and environments. + + Notice that FreeType is a *library*. It is *not* a font server + for your preferred environment, even though it has been written to + allow the design of many font servers. + + To our knowledge, this is the only royalty-free complete TrueType + engine available. Moreover, its quality fully matches these of + Windows or the Macintosh, a thing that cannot be said for most + other commercial engines available. + + FreeType is a clean-room implementation that is not derived from + the original TrueType engine developed by Apple and Microsoft. It + has been created with the sole help of the published TrueType + specifications, which, to our great surprise and pain, turned out + to be extremely poor or misleading in critical areas. Much hard + work has been undertaken to solve numerous ambiguities; + nevertheless, its end result is a portable, fast quality renderer! + + The library itself takes about 55kByte of Intel code, complete + with a TrueType byte-code interpreter and a high-performance + scan-line converter. + + You will find in this release: + + - A TrueType engine, with source code in ANSI C and Pascal. + + The C source code has been successfully compiled and run on + various platforms, including MS-DOS, OS/2, Amiga, Linux, and + several other variants of Unix. It should be portable to many + other platforms too. + + The Pascal code has been successfully compiled and run on DOS + (Borland's BP7) and OS/2 (fPrint's Virtual Pascal). A Delphi + port is in beta (the code in freetype/pascal compiles). + Unfortunately, it is not up to date compared to the C version. + + - An API to be used by client applications and font servers, + providing several low level abstractions that can be used to + open font files and collections, create point sizes and load, + process and render glyph outlines and bitmaps. + + - Support for the following features: + + o Font smoothing, a.k.a. gray-level rendering. + + Just like Windows 95, the renderer uses a `fine' algorithm + that only smoothes diagonals and curves, while keeping the + horizontal and vertical stems intact. + + This results in glyphs that are much more legible than the + `fuzzy' ones generated by programs like Acrobat. + + o Support for all character mapping formats. + + o A full-featured TrueType byte-code interpreter. + + The engine is able to hint the glyphs to produce excellent + output at small sizes. It was extremely difficult to get this + component right, due to the ambiguous and misleading TrueType + specifications. However, we now *match* Windows and Macintosh + qualities. + + o TrueType collection support, when several fonts are embedded + in the same file. + + o Support for extensions. + + It is now possible to extend the library in parts to support + additional features, like optional tables that are not + considered by the current core engine. + + o Kerning support. + + Provided as a sample extension with this release, kerning + tables can be accessed from a TrueType font for applications + that need it. + + o Support for vertical metrics. + + It is possible to load vertical metrics when they are present + in a font file. Metrics can be retrieved glyph by glyph, + using the loader, or in arrays with a new API. + + o Support for thread-safety and re-entrancy. + + You will only need to specialize the file `ttmutex.c' for your + platform to include system-specific synchronization calls. + + o New in 1.3: Support for embedded bitmaps. + + This feature is already used in xtt, a TrueType font server + for X Window System. + + Note also that: + + - Though development of the library is mainly performed on OS/2 + and Linux, the library does not contain system-specific code. + + - The package contains some graphics drivers used by the test + programs for display purposes on MS-DOS, OS/2, Amiga, and X11. + These drivers are absolutely not mandatory for running the + FreeType engine. Some console-mode test programs like `ftlint' + or `ftdump' don't use graphics at all. + + - FreeType 1.3 is binary compatible with 1.2, which means that you + won't need to recompile your programs if they used the engine as + a shared library (libttf.so on Linux, or FreeType.dll on + Windows). See the file `freetype/docs/changes.txt' for more + information about (minimal) API changes. + + +II. The FreeType mini-FAQ +========================= + + Summary + + 0. Where to find the latest FreeType release? + + 1. Did the API change? + + 2. What does the `Free' in FreeType means? Can you use it in a + commercial product? (YES!) + + 3. I have made a small program based on the test programs but I + would like to know how to do xxx? + + 4. When will I be able to use FreeType to display TrueType fonts + under X11, OS/2 or Wine? (NOW!) + + 5. Trying to compile the FreeType sources gives me lots of + warnings with my ANSI C compliant compiler! + + ------------------------------------------------------------------ + + 0. Where to find the latest FreeType release? + + The latest package is usually uploaded to various source + repositories, like SunSite, SimTel, or Hobbes. There are two + archive formats (zip and tar.gz), which also differ by their + CR/LF conventions. + + * for DOS and OS/2: `ft-13.zip' + + which should be available at: + + Hobbes: ftp://ftp.cdrom.com/pub/os2/fonts + SimTel: ftp://oak.oakland.edu/pub/simtel.net/msdos/graphics + + * for UNIX and Amiga: `freetype-1.3.tar.gz' + + look at: + + SunSite: ftp://sunsite.unc.edu/pub/Linux/X11/fonts + + * As uploading can take several days before the package becomes + available to the public, we advise you to download it from + our own ftp site if you read this message few days after the + announcement at: + + ftp://ftp.freetype.org/pub/freetype + + Our home page is at: + + http://www.freetype.org + + Screen shots are available! + + There are also three mailing lists: + + o freetype-announce@freetype.org + + Announcements only about new versions of FreeType and + related packages. This list is moderated and expected to + have very low traffic. + + o freetype@freetype.org + + Discusses general use of FreeType, future, and needed + additions, as well as many other font-related discussions + which do not always relate directly to the FreeType code + itself... + + o devel@freetype.org + + Discusses development, design choices, portability issues, + internals, specific licenses, etc. + + To subscribe, send the usual subscription commands to: + + majordomo@freetype.org + + To report bugs please use send an email to the address + bugs@freetype.org -- if you want help fixing bugs, contact + robert.wilhelm@freetype.org to be manually subscribed to this + closed list. + + ------------------------------------------------------------------ + + 1. Did the API change since the version 1.2? + + Only very marginally. Please refer to `changes.txt'. + + ------------------------------------------------------------------ + + 2. What does the `Free' in FreeType means? Can you use it in a + commercial product? (YES!) + + We have placed this release under our special FreeType license. + + It was inspired by the BSD, Artistic, and IJG (Independent JPEG + group) licences, which specifically encourage the use of this + software in commercial products! + + The reason we did this is that we believe that TrueType is a + very useful technology, and want to make it available on all + machines and platforms. The license is there to ensure that + the engine can be spread as widely as possible. + + However, free does not mean public domain. This engine is + copyrighted by its authors, and they will fiercely defend their + rights. + + ------------------------------------------------------------------ + + 3. I have made a small program based on the test programs but I + would like to know how to do xxx? + + (Where xxx is a feature lacking from the current + implementation). + + First of all, read the documentation. The user guide gives + some basic hints and concepts. You can also read the source + code of the test programs that you didn't consider yet. If + you're really stuck, mail your question to: + + freetype@freetype.org + + We'll try to help you. + + ------------------------------------------------------------------ + + 4. When will I be able to use FreeType to display TrueType fonts + under X11, OS/2, or Wine? + + You can already do that under X11 and OS/2 :-) Go to the + FreeType web page (http://www.freetype.org) for up-to-date + information. + + And yes, it looks terrific! + + For X11, you could also take a look at `xfstt', an independent + TrueType font server for Unix which doesn't rely on the + FreeType code. + + You're welcome to volunteer for other platforms, like: + + Amiga, RISC OS, BeOS, and others + + Please contact devel@freetype.org for more information. + + ------------------------------------------------------------------ + + 5. Trying to compile the FreeType sources gives me lots of + warnings with my ANSI C compliant compiler! + + We use gcc as our reference compiler for warnings. This means + that we use the `-ansi -pedantic -Wall' flags and try to get + rid of warnings in this situation. + + If you're compiling with another compiler, you may encounter + warnings, not errors. + + We have spent much efforts to reduce seriously the number of + warnings produced by major compilers, including Visual Age, + Visual C++ and Borland C++. + + Note that the Borland compilers seem to produce lots of + irrelevant warnings (like `potential loss of precision'). + + +III. How to use the test programs +================================= + + All test programs having a graphic interface use the same key + convention: + + x : fine counter_clockwise rotation + c : fine clockwise rotation + + v : fast counter_clockwise rotation + b : fast clockwise rotation + + h : toggle hinting on/off + K : toggle kerning on/off + B : toggle display of embedded bitmaps on/off + G : toggle GSUB on/off + + + : fast scale up + - : fast scale down + u : fine scale up + j : fine scale down + + l : go to next glyph + k : go to previous glyph + + o : go to tenth next glyph + i : go to tenth previous glyph + + 0 : go to hundredth next glyph (useful for CJK fonts) + 9 : go to hundredth previous glyph + + ) : go to thousandth next glyph + ( : go to thousandth previous glyph + + } : go to tenthousandth next glyph + { : go to tenthousandth previous glyph + + q : + ESC : exit + + These keys were chosen because they are available on all + platforms. Note also that each program uses only a subset of this + key map. + + 1. FTZOOM + --------- + + `ftzoom' is a very simple glyph viewer that supports font + smoothing. Its usage is: + + ftzoom [-g] [-p platformID -e encodingID] + [-r resolution] [-z magnification] [-n] fontfilename + + With -g you can select gray-scaling; with -n you can suppress + usage of the `post' table in the TrueType font. + + For example: + + ftzoom arial.ttf to show the glyphs found + in the Arial font + ftzoom -g times.ttf to show smoothed version of + Times's glyphs. + ftzoom -p 3 -e 1 uwjmg3.ttf use cmap for platform ID 3, + encoding ID 1 for this Japanese + font. + + 2. FTLINT + --------- + + `ftlint' is used to execute all glyphs instructions found in a + font file at a given char size size. Its usage is: + + ftlint pointsize fontfilename [fontfilename] ... + + For example: + + ftlint 12 arial.ttf + ftlint 15 times.ttf + + It reports error codes and faulty glyph numbers. This is a + console tool that doesn't need the graphics subsystem. + + NOTE: Trying to hint at sizes smaller than 7 is irrelevant. + + 3. FTVIEW + --------- + + A font viewer that supports hinting and font smoothing. Its + usage: + + ftview [-g] -[r resolution] [-B] pointsize fontfilename + + like in: + + ftview 12 arial.ttf show the hinted Arial at size 12pt. + + ftview -g 15 timesi.ttf show the hinted and font-smoothed + Times at size 15pt. + + `-r' selects the resolution; `-B' forces the use of embedded + bitmaps. + + Note that it is possible to change the point size during display + with the keys `u', `j', `+', and `-'. It is also possible to + browse the whole glyph set with the `k', `l', `i', `o', `0', + `9', `(', `)', `{', and `}' keys (see key map above). + + The OS/2 PM driver comes with an additional magnifying window. + The magnified zone is set with the mouse, while the scale is + changed with the help of `PageUp' and `PageDown'. + + Note 1: The engine uses the font's CVT program to determine at + which size to enable or disable glyph hinting. Don't be + surprised to see unhinted glyphs at sizes < 7pt. + + Note 2: Vertical drop-out control has been added to the gray + scaling renderer. As a consequence, the library doesn't + produce unpleasant results at small ppems with badly + hinted glyphs. + + 4. FTTIMER + ---------- + + This program is used to benchmark FreeType's scan-converter (the + component in charge of translating a vectorial shape description + into a bitmap). It does so in preloading all glyphs from a font + file, then rendering them as fast as possible in a 640x450 + buffer. The glyphs are rendered at size 400pt / 96dpi, which is + _quite_ big. + + Its usage is: + + fttimer [-g] [-v] fontfilename + + where + + -g : Asks for gray-level rendering at size 200pt instead + (a.k.a. font-smoothing). + + -v : Asks for the display of the produced bitmap. Beware + that display slows things down (display on X11 is + _terrible_, especially with gray-levels, but this is + not a problem for us :-). + + Note that the returned numbers are not a benchmark of FreeType's + overall performance! Only of the scan-line renderer (which + seems quite fast, apparently :-). + + When comparing measured performances across machines, please + only consider the undisplayed ones. We're interested in all + kinds of results (please provide the following information: + + font file + number of rendered glyphs + render time + total time + glyphs / s + processor type + CPU clock + + and which compiler used (with optimization involved)! This + can make a great difference! + + etc.) + + 5. FTDUMP + --------- + + This program is a very simple font dumper. In its current + incarnation, it will only output a font's name table, character + encoding maps IDs and total memory consumption. For TrueType + Open files, the available GSUB tables are also shown. + + The `total memory used' reported is the amount that is used by + the engine to load one face, with one instance (a point size). + + Each additional instance takes only a fraction of that amount, + and is labeled by `instance object'. As you can see, FreeType + isn't really greedy. + + Usage: ftdump fontpathname[.ttf|.ttc] + + 6. FTSTRING + ----------- + + This program demonstrates string text generation. It only + displays a given message on the screen, and lets you resize it + with the classic key bindings `u', `j', `+', and `-'. + + Usage: + + ftstring ptsize fontname[.ttf|.ttc] [message_string] + + If the message is omitted, it will revert to the classic + typographic test sentence: + + The quick brown fox jumps over the lazy dog + + which is made of all letters of the English alphabet. + + `ftstring' only works with font files that contain a Unicode + character mapping table (either Windows Unicode or Apple + Unicode). For the moment, the message can however only be + written in ASCII, as accents aren't supported yet. + + 7. FTSTRPNM + ----------- + + Usage: + + ftstrpnm [options] filename [string] + + Options: + + -g gray-level rendering (default: off) + -h hinting off (default: on) + -r X resolution X dpi (default: 96) + -p X pointsize X pt (default: 12) + -b X border X pixels wide (default: 0) + + This program is quite similar to ftstring but converts the + rendered image of the specified string into a bitmap in PBM or + PGM format written to stdout; PBM (Portable BitMap) and PGM + (Portable GrayMap) formats can be further converted to popular + graphics formats like GIF or PNG with the netpbm tool suite + available via Internet. + + 8. FTERROR + ---------- + + This program tests the gettext() functionality on UNIX platforms + (usually provided in the GNU gettext package). It will return + language specific error and warning messages depending on your + locale. Currently French, Dutch, Spanish, German, and Czech + translations of the FreeType messages are included -- we invite + you to contribute more translations. + + Typically, you have to set the LANG environment variable to your + locale to get localized messages. Example: + + LANG=de fterror + + Note that providing message strings for FreeType's error and + warning messages is an extension and not part of the FreeType + library itself. Please refer to `docs/i18n.txt' for further + details. + + 9. FTSBIT + --------- + + Usage: + + ftsbit ppem fontname[.ttf|.ttc] glyph_index [glyph_index2..] + + This tool dumps the information in the tables for embedded + bitmaps. Additionally, it prints (to the console) a selected + glyph bitmap. + + 10. FTMETRIC + ------------ + + Usage: + + ftmetric [options below] point fontname[.ttf|.ttc] ... + + -B show sbit's metrics (default: none) + -c C use C'th font index of TrueType collection + (default: 0) + -i index glyph index (default: 0) + -r R use resolution R dpi (default: 72dpi) + + With this small program you can inspect the metric data of a + given glyph; additionally, it dumps the particular glyph to the + console. + + 11. FTSTRTTO + ------------ + + Usage: + + ftstrtto [options below] ppem fontname[.ttf|.ttc] [string|-] + + -c C use font with index C in TrueType collection + (default: 0) + -f F use feature F (can be specified more than once) + -g gray-level rendering + -l L use language L + -r R use resolution R dpi (default: 96dpi) + -s S use script S + -u interpret input data as UTF8-encoded + -v display string vertically + -x display string from right to left + + F, L, and S must be specified as 4-character tags. + Specifying only F and S selects default language system of S. + Specifying only L and S selects the req. feature of L only + (if any). + + If `-' is specified as input string, stdin is read instead. + + This program uses almost all features of FreeType to display a + string on screen. Its usage is similar to `ftstring', but you + can additionally select GSUB features, the collection in a font, + toggle kerning and embedded bitmaps interactively, and input the + optional string in UTF8 encoding. + + For a list of available script, language, and feature tags + please refer to the TrueType Open (resp. OpenType) + specification. + + Example: + + ftstrtto -s "latn" -l "DEU " -f "liga" -f "frac" \ + 40 pala.ttf "fi ff ffi ffl 1/2" + + Note that you can inspect the available tags in a font with + `ftdump'. + + The features `init', `medi', and `fina', and `isol' are treated + specially. Internally, ftstrtto assigns initial, medial, + isolated, and final properties to Arabic characters in the input + string. If one of the features is switched on, all glyphs with + the corresponding property are modified (if covered). + + Example: + + ftstrtto -s arab -f init -f medi -f fina -f isol \ + -f liga -f mset -x -u 20 trado.ttf - < arab.utf8 + + `mset' is another, Arabic specific feature to position combining + marks. + + If you select the swash feature `swsh', the displayed + alternative in the string is always the first available one. + + + +IV. HOW TO USE THE PROGRAMS IN THE `CONTRIB' DIRECTORY +====================================================== + + These programs are contributions to FreeType and not really part + of it. Please read the documentation files in the respective + subdirectories how to compile and install them. + + +V. FINAL REMARKS +================ + +Of course, all source code is provided `as is'. Please read the +file `license.txt' for more information. + +We hope you will find this engine useful, and look forward to file. +your feed-back. We're of course very interested in bug reports, as +well as FreeType success stories :-) + + +Thanks for your time and consideration, + + + David Turner, Robert Wilhelm, Werner Lemberg, + and all the FreeType enthusiasts... + + +--- end of README --- diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..2ad3206 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,427 @@ +## libtool.m4 - Configure libtool for the target system. -*-Shell-script-*- +## Copyright (C) 1996-1999 Free Software Foundation, Inc. +## Originally by Gordon Matzigkeit , 1996 +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## As a special exception to the GNU General Public License, if you +## distribute this file as part of a program that contains a +## configuration script generated by Autoconf, you may include it under +## the same distribution terms that you use for the rest of that program. + +# serial 40 AC_PROG_LIBTOOL +AC_DEFUN(AC_PROG_LIBTOOL, +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl + +# Save cache, so that ltconfig can load it +AC_CACHE_SAVE + +# Actually configure libtool. ac_aux_dir is where install-sh is found. +CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \ +LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \ +DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \ +$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \ +|| AC_MSG_ERROR([libtool configure failed]) + +# Reload cache, that may have been modified by ltconfig +AC_CACHE_LOAD + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log +]) + +AC_DEFUN(AC_LIBTOOL_SETUP, +[AC_PREREQ(2.13)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_RANLIB])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_NM])dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +dnl + +# Check for any special flags to pass to ltconfig. +libtool_flags="--cache-file=$cache_file" +test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared" +test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static" +test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install" +test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc" +test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld" +ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN], +[libtool_flags="$libtool_flags --enable-dlopen"]) +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +[libtool_flags="$libtool_flags --enable-win32-dll"]) +AC_ARG_ENABLE(libtool-lock, + [ --disable-libtool-lock avoid locking (might break parallel builds)]) +test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock" +test x"$silent" = xyes && libtool_flags="$libtool_flags --silent" + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case "$host" in +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case "`/usr/bin/file conftest.o`" in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +[*-*-cygwin* | *-*-mingw*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +]) +esac +]) + +# AC_LIBTOOL_DLOPEN - enable checks for dlopen support +AC_DEFUN(AC_LIBTOOL_DLOPEN, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])]) + +# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's +AC_DEFUN(AC_LIBTOOL_WIN32_DLL, [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])]) + +# AC_ENABLE_SHARED - implement the --enable-shared flag +# Usage: AC_ENABLE_SHARED[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN(AC_ENABLE_SHARED, [dnl +define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(shared, +changequote(<<, >>)dnl +<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case "$enableval" in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl +]) + +# AC_DISABLE_SHARED - set the default shared flag to --disable-shared +AC_DEFUN(AC_DISABLE_SHARED, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_SHARED(no)]) + +# AC_ENABLE_STATIC - implement the --enable-static flag +# Usage: AC_ENABLE_STATIC[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN(AC_ENABLE_STATIC, [dnl +define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(static, +changequote(<<, >>)dnl +<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case "$enableval" in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_static=AC_ENABLE_STATIC_DEFAULT)dnl +]) + +# AC_DISABLE_STATIC - set the default static flag to --disable-static +AC_DEFUN(AC_DISABLE_STATIC, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_STATIC(no)]) + + +# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag +# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN(AC_ENABLE_FAST_INSTALL, [dnl +define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(fast-install, +changequote(<<, >>)dnl +<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case "$enableval" in +yes) enable_fast_install=yes ;; +no) enable_fast_install=no ;; +*) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl +]) + +# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install +AC_DEFUN(AC_DISABLE_FAST_INSTALL, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_FAST_INSTALL(no)]) + +# AC_PROG_LD - find the path to the GNU or non-GNU linker +AC_DEFUN(AC_PROG_LD, +[AC_ARG_WITH(gnu-ld, +[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], +test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +ac_prog=ld +if test "$ac_cv_prog_gcc" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + ac_prog=`($CC -print-prog-name=ld) 2>&5` + case "$ac_prog" in + # Accept absolute paths. +changequote(,)dnl + [\\/]* | [A-Za-z]:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' +changequote([,])dnl + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(ac_cv_path_LD, +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + ac_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + ac_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$ac_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_SUBST(LD) +AC_PROG_LD_GNU +]) + +AC_DEFUN(AC_PROG_LD_GNU, +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + ac_cv_prog_gnu_ld=yes +else + ac_cv_prog_gnu_ld=no +fi]) +]) + +# AC_PROG_NM - find the path to a BSD-compatible name lister +AC_DEFUN(AC_PROG_NM, +[AC_MSG_CHECKING([for BSD-compatible nm]) +AC_CACHE_VAL(ac_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + ac_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -B" + break + elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -p" + break + else + ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm +fi]) +NM="$ac_cv_path_NM" +AC_MSG_RESULT([$NM]) +AC_SUBST(NM) +]) + +# AC_CHECK_LIBM - check for math library +AC_DEFUN(AC_CHECK_LIBM, +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case "$host" in +*-*-beos* | *-*-cygwin*) + # These system don't have libm + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, main, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, main, LIBM="-lm") + ;; +esac +]) + +# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl convenience library, adds --enable-ltdl-convenience to +# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor +# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed +# to be `${top_builddir}/libltdl'. Make sure you start DIR with +# '${top_builddir}/' (note the single quotes!) if your package is not +# flat, and, if you're not using automake, define top_builddir as +# appropriate in the Makefiles. +AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + case "$enable_ltdl_convenience" in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la + INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl']) +]) + +# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl installable library, and adds --enable-ltdl-install to +# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor +# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed +# to be `${top_builddir}/libltdl'. Make sure you start DIR with +# '${top_builddir}/' (note the single quotes!) if your package is not +# flat, and, if you're not using automake, define top_builddir as +# appropriate in the Makefiles. +# In the future, this macro may have to be called after AC_PROG_LIBTOOL. +AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + AC_CHECK_LIB(ltdl, main, + [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], + [if test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + else + enable_ltdl_install=yes + fi + ]) + if test x"$enable_ltdl_install" = x"yes"; then + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la + INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + INCLTDL= + fi +]) + +dnl old names +AC_DEFUN(AM_PROG_LIBTOOL, [indir([AC_PROG_LIBTOOL])])dnl +AC_DEFUN(AM_ENABLE_SHARED, [indir([AC_ENABLE_SHARED], $@)])dnl +AC_DEFUN(AM_ENABLE_STATIC, [indir([AC_ENABLE_STATIC], $@)])dnl +AC_DEFUN(AM_DISABLE_SHARED, [indir([AC_DISABLE_SHARED], $@)])dnl +AC_DEFUN(AM_DISABLE_STATIC, [indir([AC_DISABLE_STATIC], $@)])dnl +AC_DEFUN(AM_PROG_LD, [indir([AC_PROG_LD])])dnl +AC_DEFUN(AM_PROG_NM, [indir([AC_PROG_NM])])dnl + +dnl This is just to silence aclocal about the macro not being used +ifelse([AC_DISABLE_FAST_INSTALL])dnl diff --git a/announce b/announce new file mode 100644 index 0000000..1412202 --- /dev/null +++ b/announce @@ -0,0 +1,60 @@ + + + Announcing + + + F R E E T Y P E 1 . 3 . 1 + + + The FREE TrueType Font Engine + + + Copyright (C) 1996-1999 The FreeType Development Team + + + + The FreeType engine is a free and portable TrueType font rendering + engine, available in ANSI C and Pascal source code. It has been + developed to provide TrueType support to a great variety of + platforms and environments. + + Notice that FreeType is a *library*. It is *not* a font server + for your preferred environment, even though it has been designed + to be the basis of many high-level libraries, tools and font + servers. + + + DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER + DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER + DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER + DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER + + WE HAVE RECENTLY DISCOVERED THAT APPLE OWNS SEVERAL PATENTS + RELATED TO THE RENDERING OF TRUETYPE FONTS. THIS COULD MEAN THAT + THE FREE USE OF THE FREETYPE LIBRARY MIGHT BE ILLEGAL IN THE USA, + JAPAN, AND POSSIBLY OTHER COUNTRIES. FOR MORE INFORMATION, WE + STRONGLY ADVISE YOU TO GO TO THE FREETYPE WEB SITE AT: + + http://www.freetype.org/patents.htm + + DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER + DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER + DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER + DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER + + + It's a clean-room implementation that is not derived from the + original TrueType engine developed by Apple and Microsoft, though + it matches it regarding rendering quality. To our knowledge, it's + the only royalty-free complete TrueType engine available. + + Version 1.3.1 fixes several bugs found in 1.3. + + Version 1.3 fixes several bugs found in 1.2, as well as provide + the engine with enhanced capabilities, like support for embedded + bitmaps and rudimentary TrueType Open support. + + For more information, please visit the freetype web site at: + + http://www.freetype.org + diff --git a/config.guess b/config.guess new file mode 100644 index 0000000..6cb567b --- /dev/null +++ b/config.guess @@ -0,0 +1,1087 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999 +# Free Software Foundation, Inc. +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Written by Per Bothner . +# The master version of this file is at the FSF in /home/gd/gnu/lib. +# Please send patches to the Autoconf mailing list . +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit system type (host/target name). +# +# Only a few systems have been added to this list; please add others +# (but try to keep the structure clean). +# + +# Use $HOST_CC if defined. $CC may point to a cross-compiler +if test x"$CC_FOR_BUILD" = x; then + if test x"$HOST_CC" != x; then + CC_FOR_BUILD="$HOST_CC" + else + if test x"$CC" != x; then + CC_FOR_BUILD="$CC" + else + CC_FOR_BUILD=cc + fi + fi +fi + + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 8/24/94.) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +dummy=dummy-$$ +trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15 + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + cat <$dummy.s + .globl main + .ent main +main: + .frame \$30,0,\$26,0 + .prologue 0 + .long 0x47e03d80 # implver $0 + lda \$2,259 + .long 0x47e20c21 # amask $2,$1 + srl \$1,8,\$2 + sll \$2,2,\$2 + sll \$0,3,\$0 + addl \$1,\$0,\$0 + addl \$2,\$0,\$0 + ret \$31,(\$26),1 + .end main +EOF + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + ./$dummy + case "$?" in + 7) + UNAME_MACHINE="alpha" + ;; + 15) + UNAME_MACHINE="alphaev5" + ;; + 14) + UNAME_MACHINE="alphaev56" + ;; + 10) + UNAME_MACHINE="alphapca56" + ;; + 16) + UNAME_MACHINE="alphaev6" + ;; + esac + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-cbm-sysv4 + exit 0;; + amiga:NetBSD:*:*) + echo m68k-cbm-netbsd${UNAME_RELEASE} + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + arc64:OpenBSD:*:*) + echo mips64el-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hkmips:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + arm32:NetBSD:*:*) + echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + SR2?01:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + atari*:NetBSD:*:*) + echo m68k-atari-netbsd${UNAME_RELEASE} + exit 0 ;; + atari*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + sun3*:NetBSD:*:*) + echo m68k-sun-netbsd${UNAME_RELEASE} + exit 0 ;; + sun3*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:NetBSD:*:*) + echo m68k-apple-netbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + macppc:NetBSD:*:*) + echo powerpc-apple-netbsd${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy \ + && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \ + -o ${TARGET_BINARY_INTERFACE}x = x ] ; then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i?86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:4) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` + if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=4.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + sed 's/^ //' << EOF >$dummy.c + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + ($CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` + rm -f $dummy.c $dummy + esac + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i?86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + hppa*:OpenBSD:*:*) + echo hppa-unknown-openbsd + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*X-MP:*:*:*) + echo xmp-cray-unicos + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY*T3E:*:*:*) + echo t3e-cray-unicosmk${UNAME_RELEASE} + exit 0 ;; + CRAY-2:*:*:*) + echo cray2-cray-unicos + exit 0 ;; + F300:UNIX_System_V:*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + F301:UNIX_System_V:*:*) + echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` + exit 0 ;; + hp3[0-9][05]:NetBSD:*:*) + echo m68k-hp-netbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + i?86:BSD/386:*:* | i?86:BSD/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + if test -x /usr/bin/objformat; then + if test "elf" = "`/usr/bin/objformat`"; then + echo ${UNAME_MACHINE}-unknown-freebsdelf`echo ${UNAME_RELEASE}|sed -e 's/[-_].*//'` + exit 0 + fi + fi + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:NetBSD:*:*) + echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + *:Linux:*:*) + # uname on the ARM produces all sorts of strangeness, and we need to + # filter it out. + case "$UNAME_MACHINE" in + armv*) UNAME_MACHINE=$UNAME_MACHINE ;; + arm* | sa110*) UNAME_MACHINE="arm" ;; + esac + + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + ld_help_string=`cd /; ld --help 2>&1` + ld_supported_emulations=`echo $ld_help_string \ + | sed -ne '/supported emulations:/!d + s/[ ][ ]*/ /g + s/.*supported emulations: *// + s/ .*// + p'` + case "$ld_supported_emulations" in + i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;; + i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;; + sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; + armlinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; + m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; + elf32ppc) + # Determine Lib Version + cat >$dummy.c < +#if defined(__GLIBC__) +extern char __libc_version[]; +extern char __libc_release[]; +#endif +main(argc, argv) + int argc; + char *argv[]; +{ +#if defined(__GLIBC__) + printf("%s %s\n", __libc_version, __libc_release); +#else + printf("unkown\n"); +#endif + return 0; +} +EOF + LIBC="" + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null + if test "$?" = 0 ; then + ./$dummy | grep 1\.99 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.c $dummy + echo powerpc-unknown-linux-gnu${LIBC} ; exit 0 ;; + esac + + if test "${UNAME_MACHINE}" = "alpha" ; then + sed 's/^ //' <$dummy.s + .globl main + .ent main + main: + .frame \$30,0,\$26,0 + .prologue 0 + .long 0x47e03d80 # implver $0 + lda \$2,259 + .long 0x47e20c21 # amask $2,$1 + srl \$1,8,\$2 + sll \$2,2,\$2 + sll \$0,3,\$0 + addl \$1,\$0,\$0 + addl \$2,\$0,\$0 + ret \$31,(\$26),1 + .end main +EOF + LIBC="" + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + ./$dummy + case "$?" in + 7) + UNAME_MACHINE="alpha" + ;; + 15) + UNAME_MACHINE="alphaev5" + ;; + 14) + UNAME_MACHINE="alphaev56" + ;; + 10) + UNAME_MACHINE="alphapca56" + ;; + 16) + UNAME_MACHINE="alphaev6" + ;; + esac + + objdump --private-headers $dummy | \ + grep ld.so.1 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0 + elif test "${UNAME_MACHINE}" = "mips" ; then + cat >$dummy.c </dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + else + # Either a pre-BFD a.out linker (linux-gnuoldld) + # or one that does not give us useful --help. + # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. + # If ld does not provide *any* "supported emulations:" + # that means it is gnuoldld. + echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:" + test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 + + case "${UNAME_MACHINE}" in + i?86) + VENDOR=pc; + ;; + *) + VENDOR=unknown; + ;; + esac + # Determine whether the default compiler is a.out or elf + cat >$dummy.c < +#ifdef __cplusplus + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif +#ifdef __ELF__ +# ifdef __GLIBC__ +# if __GLIBC__ >= 2 + printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +#else + printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); +#endif + return 0; +} +EOF + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + fi ;; +# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions +# are messed up and put the nodename in both sysname and nodename. + i?86:DYNIX/ptx:4*:*) + echo i386-sequent-sysv4 + exit 0 ;; + i?86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} + fi + exit 0 ;; + i?86:*:5:7*) + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent.*II' >/dev/null) && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) && UNAME_MACHINE=i585 + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}${UNAME_VERSION}-sysv${UNAME_RELEASE} + exit 0 ;; + i?86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + pc:*:*:*) + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:*:6*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +#if !defined (ultrix) + printf ("vax-dec-bsd\n"); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0 +rm -f $dummy.c $dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +#echo '(Unable to guess system type)' 1>&2 + +exit 1 diff --git a/config.sub b/config.sub new file mode 100644 index 0000000..2436b45 --- /dev/null +++ b/config.sub @@ -0,0 +1,1215 @@ +#! /bin/sh +# Configuration validation subroutine script, version 1.1. +# Copyright (C) 1991, 92-97, 1998, 1999 Free Software Foundation, Inc. +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +if [ x$1 = x ] +then + echo Configuration name missing. 1>&2 + echo "Usage: $0 CPU-MFR-OPSYS" 1>&2 + echo "or $0 ALIAS" 1>&2 + echo where ALIAS is a recognized configuration type. 1>&2 + exit 1 +fi + +# First pass through any local machine types. +case $1 in + *local*) + echo $1 + exit 0 + ;; + *) + ;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + linux-gnu*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=vxworks + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \ + | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \ + | 580 | i960 | h8300 \ + | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \ + | alpha | alphaev[4-7] | alphaev56 | alphapca5[67] \ + | we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \ + | 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \ + | mips64orion | mips64orionel | mipstx39 | mipstx39el \ + | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \ + | mips64vr5000 | miprs64vr5000el \ + | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \ + | thumb | d10v) + basic_machine=$basic_machine-unknown + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i[34567]86) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \ + | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \ + | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ + | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \ + | xmp-* | ymp-* \ + | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* | hppa2.0n-* \ + | alpha-* | alphaev[4-7]-* | alphaev56-* | alphapca5[67]-* \ + | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \ + | clipper-* | orion-* \ + | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ + | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \ + | mips64el-* | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \ + | mipstx39-* | mipstx39el-* \ + | f301-* | armv*-* | t3e-* \ + | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \ + | thumb-* | v850-* | d30v-* | tic30-* | c30-* ) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-cbm + ;; + amigaos | amigados) + basic_machine=m68k-cbm + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-cbm + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | ymp) + basic_machine=ymp-cray + os=-unicos + ;; + cray2) + basic_machine=cray2-cray + os=-unicos + ;; + [ctj]90-cray) + basic_machine=c90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + os=-mvs + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i[34567]86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i[34567]86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i[34567]86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i[34567]86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + i386-go32 | go32) + basic_machine=i386-unknown + os=-go32 + ;; + i386-mingw32 | mingw32) + basic_machine=i386-unknown + os=-mingw32 + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | *MiNT) + basic_machine=m68k-atari + os=-mint + ;; + mipsel*-linux*) + basic_machine=mipsel-unknown + os=-linux-gnu + ;; + mips*-linux*) + basic_machine=mips-unknown + os=-linux-gnu + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + msdos) + basic_machine=i386-unknown + os=-msdos + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-corel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + np1) + basic_machine=np1-gould + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexen) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexen-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=rs6000-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sparclite-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=t3e-cray + os=-unicos + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xmp) + basic_machine=xmp-cray + os=-unicos + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + mips) + if [ x$os = x-linux-gnu ]; then + basic_machine=mips-unknown + else + basic_machine=mips-mips + fi + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sparc | sparcv9) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + c4x*) + basic_machine=c4x-none + os=-coff + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -openstep* | -oskit*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -ns2 ) + os=-nextstep2 + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -*MiNT) + os=-mint + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-corel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f301-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -*MiNT) + vendor=atari + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os diff --git a/configure b/configure new file mode 100644 index 0000000..3907281 --- /dev/null +++ b/configure @@ -0,0 +1,4515 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --enable-static[=PKGS] build static libraries [default=no]" +ac_help="$ac_help + --enable-shared[=PKGS] build shared libraries [default=yes]" +ac_help="$ac_help + --enable-fast-install[=PKGS] optimize for fast installation [default=yes]" +ac_help="$ac_help + --with-gnu-ld assume the C compiler uses GNU ld [default=no]" +ac_help="$ac_help + --disable-libtool-lock avoid locking (might break parallel builds)" +ac_help="$ac_help + --disable-nls don't use NLS" +ac_help="$ac_help + --with-locale-dir=DIR Location of the locale file(s) + [PREFIX/share/locale]" +ac_help="$ac_help + --with-x use the X Window System" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=lib/freetype.h + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +srcdir=`cd $srcdir; pwd` + +# Check whether --enable-static or --disable-static was given. +if test "${enable_static+set}" = set; then + enableval="$enable_static" + p=${PACKAGE-default} +case "$enableval" in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_static=no +fi + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + +# Check whether --enable-shared or --disable-shared was given. +if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + p=${PACKAGE-default} +case "$enableval" in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_shared=yes +fi + +# Check whether --enable-fast-install or --disable-fast-install was given. +if test "${enable_fast_install+set}" = set; then + enableval="$enable_fast_install" + p=${PACKAGE-default} +case "$enableval" in +yes) enable_fast_install=yes ;; +no) enable_fast_install=no ;; +*) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_fast_install=yes +fi + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:640: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking build system type""... $ac_c" 1>&6 +echo "configure:661: checking build system type" >&5 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&6 + +# Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:681: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:711: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:741: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:792: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:824: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 835 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:840: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:866: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:871: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:899: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +# Check whether --with-gnu-ld or --without-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval="$with_gnu_ld" + test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$ac_cv_prog_gcc" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6 +echo "configure:942: checking for ld used by GCC" >&5 + ac_prog=`($CC -print-prog-name=ld) 2>&5` + case "$ac_prog" in + # Accept absolute paths. + [\\/]* | [A-Za-z]:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + echo $ac_n "checking for GNU ld""... $ac_c" 1>&6 +echo "configure:966: checking for GNU ld" >&5 +else + echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 +echo "configure:969: checking for non-GNU ld" >&5 +fi +if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + ac_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + ac_cv_path_LD="$LD" # Let the user override the test with a path. +fi +fi + +LD="$ac_cv_path_LD" +if test -n "$LD"; then + echo "$ac_t""$LD" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi +test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; } + +echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6 +echo "configure:1005: checking if the linker ($LD) is GNU ld" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + ac_cv_prog_gnu_ld=yes +else + ac_cv_prog_gnu_ld=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6 + + +echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6 +echo "configure:1021: checking for BSD-compatible nm" >&5 +if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$NM"; then + # Let the user override the test. + ac_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -B" + break + elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -p" + break + else + ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm +fi +fi + +NM="$ac_cv_path_NM" +echo "$ac_t""$NM" 1>&6 + + +echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 +echo "configure:1058: checking whether ln -s works" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftestdata +if ln -s X conftestdata 2>/dev/null +then + rm -f conftestdata + ac_cv_prog_LN_S="ln -s" +else + ac_cv_prog_LN_S=ln +fi +fi +LN_S="$ac_cv_prog_LN_S" +if test "$ac_cv_prog_LN_S" = "ln -s"; then + echo "$ac_t""yes" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +# Check for any special flags to pass to ltconfig. +libtool_flags="--cache-file=$cache_file" +test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared" +test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static" +test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install" +test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc" +test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld" + + +# Check whether --enable-libtool-lock or --disable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then + enableval="$enable_libtool_lock" + : +fi + +test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock" +test x"$silent" = xyes && libtool_flags="$libtool_flags --silent" + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case "$host" in +*-*-irix6*) + # Find out which ABI we are using. + echo '#line 1102 "configure"' > conftest.$ac_ext + if { (eval echo configure:1103: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + case "`/usr/bin/file conftest.o`" in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6 +echo "configure:1124: checking whether the C compiler needs -belf" >&5 +if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + lt_cv_cc_needs_belf=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + lt_cv_cc_needs_belf=no +fi +rm -f conftest* +fi + +echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6 + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + + +esac + + +# Save cache, so that ltconfig can load it +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + + +# Actually configure libtool. ac_aux_dir is where install-sh is found. +CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \ +LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \ +DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \ +$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \ +|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; } + +# Reload cache, that may have been modified by ltconfig +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log + + +freetype_version='1.2.0' + +version_info='4:0:2' + +# Check whether --enable-nls or --disable-nls was given. +if test "${enable_nls+set}" = set; then + enableval="$enable_nls" + USE_NLS=no +else + USE_NLS=yes +fi + + + + +# Do some error checking and defaulting for the host and target type. +# The inputs are: +# configure --host=HOST --target=TARGET --build=BUILD NONOPT +# +# The rules are: +# 1. You are not allowed to specify --host, --target, and nonopt at the +# same time. +# 2. Host defaults to nonopt. +# 3. If nonopt is not specified, then host defaults to the current host, +# as determined by config.guess. +# 4. Target and build default to nonopt. +# 5. If nonopt is not specified, then target and build default to host. + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +case $host---$target---$nonopt in +NONE---*---* | *---NONE---* | *---*---NONE) ;; +*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; +esac + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:1280: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking target system type""... $ac_c" 1>&6 +echo "configure:1301: checking target system type" >&5 + +target_alias=$target +case "$target_alias" in +NONE) + case $nonopt in + NONE) target_alias=$host_alias ;; + *) target_alias=$nonopt ;; + esac ;; +esac + +target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` +target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$target" 1>&6 + +echo $ac_n "checking build system type""... $ac_c" 1>&6 +echo "configure:1319: checking build system type" >&5 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&6 + +test "$host_alias" != "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1345: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1375: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1426: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:1458: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 1469 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:1474: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:1500: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:1505: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:1533: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:1565: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1586: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1603: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1620: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + + + +if test "x$CC" = xgcc; then + XX_CFLAGS="-Wall -pedantic -ansi" +else + case "$host" in + *-dec-osf*) + XX_CFLAGS="-std1 -O2 -g3" + ;; + *) + XX_CFLAGS= + ;; + esac +fi + + + +case "$host" in + *-dec-osf*) + ln -s ../../MakeSub lib/arch + ln -s ../../MakeSub test/arch + ;; +esac + + + + +if test "$USE_NLS" = "yes"; then + + echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:1674: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +for ac_hdr in locale.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1704: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1714: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + for ac_func in setlocale +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1743: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1771: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + + + + ALL_LINGUAS="de fr cs nl es" + for ac_hdr in libintl.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1802: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1812: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + echo $ac_n "checking for gettext in -lintl""... $ac_c" 1>&6 +echo "configure:1839: checking for gettext in -lintl" >&5 +ac_lib_var=`echo intl'_'gettext | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lintl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo intl | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + + + + + LOCALEDIR='${prefix}/share/locale' + # Check whether --with-locale-dir or --without-locale-dir was given. +if test "${with_locale_dir+set}" = set; then + withval="$with_locale_dir" + + if test x$withval = xyes; then + echo "configure: warning: Usage is: --with-locale-dir=basedir" 1>&2 + else + if test x$withval = xno; then + echo "configure: warning: Usage is: --with-locale-dir=basedir" 1>&2 + else + LOCALEDIR=$withval + fi + fi + +fi + + + + # Extract the first word of "msgfmt", so it can be a program name with args. +set dummy msgfmt; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1910: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$MSGFMT" in + /*) + ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_MSGFMT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="$MSGFMT" + ;; +esac +fi +MSGFMT="$ac_cv_path_MSGFMT" +if test -n "$MSGFMT"; then + echo "$ac_t""$MSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -n "$MSGFMT"; then + for ac_func in dcgettext +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1947: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1975: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + + # Extract the first word of "gmsgfmt", so it can be a program name with args. +set dummy gmsgfmt; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2002: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$GMSGFMT" in + /*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_GMSGFMT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" + ;; +esac +fi +GMSGFMT="$ac_cv_path_GMSGFMT" +if test -n "$GMSGFMT"; then + echo "$ac_t""$GMSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + # Extract the first word of "xgettext", so it can be a program name with args. +set dummy xgettext; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2038: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$XGETTEXT" in + /*) + ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_XGETTEXT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT="$XGETTEXT" + ;; +esac +fi +XGETTEXT="$ac_cv_path_XGETTEXT" +if test -n "$XGETTEXT"; then + echo "$ac_t""$XGETTEXT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + # Extract the first word of "msgmerge", so it can be a program name with args. +set dummy msgmerge; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2074: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_MSGMERGE'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$MSGMERGE" in + /*) + ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_MSGMERGE="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_MSGMERGE" && ac_cv_path_MSGMERGE="$MSGMERGE" + ;; +esac +fi +MSGMERGE="$ac_cv_path_MSGMERGE" +if test -n "$MSGMERGE"; then + echo "$ac_t""$MSGMERGE" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + if test -n "$XGETTEXT"; then + if $XGETTEXT --omit-header /dev/null 2> /dev/null; then + : ; + else + echo "$ac_t""found xgettext program is not GNU xgettext; ignore it" 1>&6 + XGETTEXT="" + fi + fi + + if test -n "$XGETTEXT"; then + if $XGETTEXT --help > /dev/null 2> /dev/null; then + : ; + else + echo "$ac_t""found xgettext program is not GNU xgettext; ignore it" 1>&6 + XGETTEXT="" + fi + fi + + if test -n "$MSGFMT"; then + if $MSGFMT < /dev/null 2> /dev/null; then + echo "$ac_t""found msgfmt program is not GNU msgfmt; NLS won't be installed" 1>&6 + MSGFMT="" + fi + fi + + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + CATOBJEXT=.gmo + DATADIRNAME=share +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CATOBJEXT=.mo + DATADIRNAME=lib +fi +rm -f conftest* + INSTOBJEXT=.mo + fi + + if test -n "$ALL_LINGUAS"; then + for lang in $ALL_LINGUAS; do + CATALOGS="$CATALOGS $lang$CATOBJEXT" + done + fi + + + + +fi + +if test x"$MSGFMT" = x; then + USE_NLS=no +fi + + +# Extract the first word of "rm", so it can be a program name with args. +set dummy rm; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2176: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RM'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RM"; then + ac_cv_prog_RM="$RM" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RM="rm" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +RM="$ac_cv_prog_RM" +if test -n "$RM"; then + echo "$ac_t""$RM" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Extract the first word of "rmdir", so it can be a program name with args. +set dummy rmdir; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2205: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RMDIR'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RMDIR"; then + ac_cv_prog_RMDIR="$RMDIR" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RMDIR="rmdir" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +RMDIR="$ac_cv_prog_RMDIR" +if test -n "$RMDIR"; then + echo "$ac_t""$RMDIR" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:2243: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 +echo "configure:2296: checking whether ln -s works" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftestdata +if ln -s X conftestdata 2>/dev/null +then + rm -f conftestdata + ac_cv_prog_LN_S="ln -s" +else + ac_cv_prog_LN_S=ln +fi +fi +LN_S="$ac_cv_prog_LN_S" +if test "$ac_cv_prog_LN_S" = "ln -s"; then + echo "$ac_t""yes" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + + + + # Most operating systems have gethostbyname() in the default searched + # libraries (i.e. libc): + echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6 +echo "configure:2323: checking for gethostbyname" >&5 +if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) +choke me +#else +gethostbyname(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2351: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_gethostbyname=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_gethostbyname=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +# Some OSes (eg. Solaris) place it in libnsl: + echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6 +echo "configure:2370: checking for gethostbyname in -lnsl" >&5 +ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lnsl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo nsl | sed -e 's/^a-zA-Z0-9_/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +# Some strange OSes (SINIX) have it in libsocket: + echo $ac_n "checking for gethostbyname in -lsocket""... $ac_c" 1>&6 +echo "configure:2416: checking for gethostbyname in -lsocket" >&5 +ac_lib_var=`echo socket'_'gethostbyname | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsocket $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo socket | sed -e 's/^a-zA-Z0-9_/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +# Unfortunately libsocket sometimes depends on libnsl. + # AC_CHECK_LIB's API is essentially broken so the following + # ugliness is necessary: + echo $ac_n "checking for gethostbyname in -lsocket""... $ac_c" 1>&6 +echo "configure:2464: checking for gethostbyname in -lsocket" >&5 +ac_lib_var=`echo socket'_'gethostbyname | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsocket -lnsl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="-lsocket -lnsl $LIBS" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for gethostbyname in -lresolv""... $ac_c" 1>&6 +echo "configure:2502: checking for gethostbyname in -lresolv" >&5 +ac_lib_var=`echo resolv'_'gethostbyname | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lresolv $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo resolv | sed -e 's/^a-zA-Z0-9_/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + +fi + + +fi + + +fi + + +fi + + echo $ac_n "checking for socket""... $ac_c" 1>&6 +echo "configure:2560: checking for socket" >&5 +if eval "test \"`echo '$''{'ac_cv_func_socket'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char socket(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_socket) || defined (__stub___socket) +choke me +#else +socket(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2588: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_socket=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_socket=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'socket`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6 +echo "configure:2606: checking for socket in -lsocket" >&5 +ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsocket $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo socket | sed -e 's/^a-zA-Z0-9_/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6 +echo "configure:2651: checking for socket in -lsocket" >&5 +ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsocket -lnsl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="-lsocket -lnsl $LIBS" +else + echo "$ac_t""no" 1>&6 +fi + +fi + +fi + + +echo $ac_n "checking for cos in -lm""... $ac_c" 1>&6 +echo "configure:2696: checking for cos in -lm" >&5 +ac_lib_var=`echo m'_'cos | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lm $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo m | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + + +# If we find X, set shell vars x_includes and x_libraries to the +# paths, otherwise set no_x=yes. +# Uses ac_ vars as temps to allow command line to override cache and checks. +# --without-x overrides everything else, but does not touch the cache. +echo $ac_n "checking for X""... $ac_c" 1>&6 +echo "configure:2748: checking for X" >&5 + +# Check whether --with-x or --without-x was given. +if test "${with_x+set}" = set; then + withval="$with_x" + : +fi + +# $have_x is `yes', `no', `disabled', or empty when we do not yet know. +if test "x$with_x" = xno; then + # The user explicitly disabled X. + have_x=disabled +else + if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then + # Both variables are already set. + have_x=yes + else +if eval "test \"`echo '$''{'ac_cv_have_x'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # One or both of the vars are not set, and there is no cached value. +ac_x_includes=NO ac_x_libraries=NO +rm -fr conftestdir +if mkdir conftestdir; then + cd conftestdir + # Make sure to not put "make" in the Imakefile rules, since we grep it out. + cat > Imakefile <<'EOF' +acfindx: + @echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"' +EOF + if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then + # GNU make sometimes prints "make[1]: Entering...", which would confuse us. + eval `${MAKE-make} acfindx 2>/dev/null | grep -v make` + # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. + for ac_extension in a so sl; do + if test ! -f $ac_im_usrlibdir/libX11.$ac_extension && + test -f $ac_im_libdir/libX11.$ac_extension; then + ac_im_usrlibdir=$ac_im_libdir; break + fi + done + # Screen out bogus values from the imake configuration. They are + # bogus both because they are the default anyway, and because + # using them would break gcc on systems where it needs fixed includes. + case "$ac_im_incroot" in + /usr/include) ;; + *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes="$ac_im_incroot" ;; + esac + case "$ac_im_usrlibdir" in + /usr/lib | /lib) ;; + *) test -d "$ac_im_usrlibdir" && ac_x_libraries="$ac_im_usrlibdir" ;; + esac + fi + cd .. + rm -fr conftestdir +fi + +if test "$ac_x_includes" = NO; then + # Guess where to find include files, by looking for this one X11 .h file. + test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h + + # First, try using that file with no special directory specified. +cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2815: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + # We can compile using X headers with no special include directory. +ac_x_includes= +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + # Look for the header file in a standard set of common directories. +# Check X11 before X11Rn because it is often a symlink to the current release. + for ac_dir in \ + /usr/X11/include \ + /usr/X11R6/include \ + /usr/X11R5/include \ + /usr/X11R4/include \ + \ + /usr/include/X11 \ + /usr/include/X11R6 \ + /usr/include/X11R5 \ + /usr/include/X11R4 \ + \ + /usr/local/X11/include \ + /usr/local/X11R6/include \ + /usr/local/X11R5/include \ + /usr/local/X11R4/include \ + \ + /usr/local/include/X11 \ + /usr/local/include/X11R6 \ + /usr/local/include/X11R5 \ + /usr/local/include/X11R4 \ + \ + /usr/X386/include \ + /usr/x386/include \ + /usr/XFree86/include/X11 \ + \ + /usr/include \ + /usr/local/include \ + /usr/unsupported/include \ + /usr/athena/include \ + /usr/local/x11r5/include \ + /usr/lpp/Xamples/include \ + \ + /usr/openwin/include \ + /usr/openwin/share/include \ + ; \ + do + if test -r "$ac_dir/$x_direct_test_include"; then + ac_x_includes=$ac_dir + break + fi + done +fi +rm -f conftest* +fi # $ac_x_includes = NO + +if test "$ac_x_libraries" = NO; then + # Check for the libraries. + + test -z "$x_direct_test_library" && x_direct_test_library=Xt + test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc + + # See if we find them without any special options. + # Don't add to $LIBS permanently. + ac_save_LIBS="$LIBS" + LIBS="-l$x_direct_test_library $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + LIBS="$ac_save_LIBS" +# We can link X programs with no special library path. +ac_x_libraries= +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + LIBS="$ac_save_LIBS" +# First see if replacing the include by lib works. +# Check X11 before X11Rn because it is often a symlink to the current release. +for ac_dir in `echo "$ac_x_includes" | sed s/include/lib/` \ + /usr/X11/lib \ + /usr/X11R6/lib \ + /usr/X11R5/lib \ + /usr/X11R4/lib \ + \ + /usr/lib/X11 \ + /usr/lib/X11R6 \ + /usr/lib/X11R5 \ + /usr/lib/X11R4 \ + \ + /usr/local/X11/lib \ + /usr/local/X11R6/lib \ + /usr/local/X11R5/lib \ + /usr/local/X11R4/lib \ + \ + /usr/local/lib/X11 \ + /usr/local/lib/X11R6 \ + /usr/local/lib/X11R5 \ + /usr/local/lib/X11R4 \ + \ + /usr/X386/lib \ + /usr/x386/lib \ + /usr/XFree86/lib/X11 \ + \ + /usr/lib \ + /usr/local/lib \ + /usr/unsupported/lib \ + /usr/athena/lib \ + /usr/local/x11r5/lib \ + /usr/lpp/Xamples/lib \ + /lib/usr/lib/X11 \ + \ + /usr/openwin/lib \ + /usr/openwin/share/lib \ + ; \ +do + for ac_extension in a so sl; do + if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then + ac_x_libraries=$ac_dir + break 2 + fi + done +done +fi +rm -f conftest* +fi # $ac_x_libraries = NO + +if test "$ac_x_includes" = NO || test "$ac_x_libraries" = NO; then + # Didn't find X anywhere. Cache the known absence of X. + ac_cv_have_x="have_x=no" +else + # Record where we found X for the cache. + ac_cv_have_x="have_x=yes \ + ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries" +fi +fi + fi + eval "$ac_cv_have_x" +fi # $with_x != no + +if test "$have_x" != yes; then + echo "$ac_t""$have_x" 1>&6 + no_x=yes +else + # If each of the values was on the command line, it overrides each guess. + test "x$x_includes" = xNONE && x_includes=$ac_x_includes + test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries + # Update the cache value to reflect the command line values. + ac_cv_have_x="have_x=yes \ + ac_x_includes=$x_includes ac_x_libraries=$x_libraries" + echo "$ac_t""libraries $x_libraries, headers $x_includes" 1>&6 +fi + +if test "$no_x" = yes; then + # Not all programs may use this symbol, but it does not hurt to define it. + cat >> confdefs.h <<\EOF +#define X_DISPLAY_MISSING 1 +EOF + + X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS= +else + if test -n "$x_includes"; then + X_CFLAGS="$X_CFLAGS -I$x_includes" + fi + + # It would also be nice to do this for all -L options, not just this one. + if test -n "$x_libraries"; then + X_LIBS="$X_LIBS -L$x_libraries" + # For Solaris; some versions of Sun CC require a space after -R and + # others require no space. Words are not sufficient . . . . + case "`(uname -sr) 2>/dev/null`" in + "SunOS 5"*) + echo $ac_n "checking whether -R must be followed by a space""... $ac_c" 1>&6 +echo "configure:2997: checking whether -R must be followed by a space" >&5 + ac_xsave_LIBS="$LIBS"; LIBS="$LIBS -R$x_libraries" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_R_nospace=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_R_nospace=no +fi +rm -f conftest* + if test $ac_R_nospace = yes; then + echo "$ac_t""no" 1>&6 + X_LIBS="$X_LIBS -R$x_libraries" + else + LIBS="$ac_xsave_LIBS -R $x_libraries" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_R_space=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_R_space=no +fi +rm -f conftest* + if test $ac_R_space = yes; then + echo "$ac_t""yes" 1>&6 + X_LIBS="$X_LIBS -R $x_libraries" + else + echo "$ac_t""neither works" 1>&6 + fi + fi + LIBS="$ac_xsave_LIBS" + esac + fi + + # Check for system-dependent libraries X programs must link with. + # Do this before checking for the system-independent R6 libraries + # (-lICE), since we may need -lsocket or whatever for X linking. + + if test "$ISC" = yes; then + X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet" + else + # Martyn.Johnson@cl.cam.ac.uk says this is needed for Ultrix, if the X + # libraries were built with DECnet support. And karl@cs.umb.edu says + # the Alpha needs dnet_stub (dnet does not exist). + echo $ac_n "checking for dnet_ntoa in -ldnet""... $ac_c" 1>&6 +echo "configure:3062: checking for dnet_ntoa in -ldnet" >&5 +ac_lib_var=`echo dnet'_'dnet_ntoa | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldnet $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" +else + echo "$ac_t""no" 1>&6 +fi + + if test $ac_cv_lib_dnet_dnet_ntoa = no; then + echo $ac_n "checking for dnet_ntoa in -ldnet_stub""... $ac_c" 1>&6 +echo "configure:3103: checking for dnet_ntoa in -ldnet_stub" >&5 +ac_lib_var=`echo dnet_stub'_'dnet_ntoa | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldnet_stub $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" +else + echo "$ac_t""no" 1>&6 +fi + + fi + + # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT, + # to get the SysV transport functions. + # chad@anasazi.com says the Pyramis MIS-ES running DC/OSx (SVR4) + # needs -lnsl. + # The nsl library prevents programs from opening the X display + # on Irix 5.2, according to dickey@clark.net. + echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6 +echo "configure:3151: checking for gethostbyname" >&5 +if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) +choke me +#else +gethostbyname(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3179: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_gethostbyname=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_gethostbyname=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +fi + + if test $ac_cv_func_gethostbyname = no; then + echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6 +echo "configure:3200: checking for gethostbyname in -lnsl" >&5 +ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lnsl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" +else + echo "$ac_t""no" 1>&6 +fi + + fi + + # lieder@skyler.mavd.honeywell.com says without -lsocket, + # socket/setsockopt and other routines are undefined under SCO ODT + # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary + # on later versions), says simon@lia.di.epfl.ch: it contains + # gethostby* variants that don't use the nameserver (or something). + # -lsocket must be given before -lnsl if both are needed. + # We assume that if connect needs -lnsl, so does gethostbyname. + echo $ac_n "checking for connect""... $ac_c" 1>&6 +echo "configure:3249: checking for connect" >&5 +if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char connect(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_connect) || defined (__stub___connect) +choke me +#else +connect(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3277: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_connect=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_connect=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'connect`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +fi + + if test $ac_cv_func_connect = no; then + echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6 +echo "configure:3298: checking for connect in -lsocket" >&5 +ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsocket $X_EXTRA_LIBS $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" +else + echo "$ac_t""no" 1>&6 +fi + + fi + + # gomez@mi.uni-erlangen.de says -lposix is necessary on A/UX. + echo $ac_n "checking for remove""... $ac_c" 1>&6 +echo "configure:3341: checking for remove" >&5 +if eval "test \"`echo '$''{'ac_cv_func_remove'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char remove(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_remove) || defined (__stub___remove) +choke me +#else +remove(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3369: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_remove=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_remove=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'remove`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +fi + + if test $ac_cv_func_remove = no; then + echo $ac_n "checking for remove in -lposix""... $ac_c" 1>&6 +echo "configure:3390: checking for remove in -lposix" >&5 +ac_lib_var=`echo posix'_'remove | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lposix $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" +else + echo "$ac_t""no" 1>&6 +fi + + fi + + # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. + echo $ac_n "checking for shmat""... $ac_c" 1>&6 +echo "configure:3433: checking for shmat" >&5 +if eval "test \"`echo '$''{'ac_cv_func_shmat'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shmat(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_shmat) || defined (__stub___shmat) +choke me +#else +shmat(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3461: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_shmat=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_shmat=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'shmat`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +fi + + if test $ac_cv_func_shmat = no; then + echo $ac_n "checking for shmat in -lipc""... $ac_c" 1>&6 +echo "configure:3482: checking for shmat in -lipc" >&5 +ac_lib_var=`echo ipc'_'shmat | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lipc $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" +else + echo "$ac_t""no" 1>&6 +fi + + fi + fi + + # Check for libraries that X11R6 Xt/Xaw programs need. + ac_save_LDFLAGS="$LDFLAGS" + test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries" + # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to + # check for ICE first), but we must link in the order -lSM -lICE or + # we get undefined symbols. So assume we have SM if we have ICE. + # These have to be linked with before -lX11, unlike the other + # libraries we check for below, so use a different variable. + # --interran@uluru.Stanford.EDU, kb@cs.umb.edu. + echo $ac_n "checking for IceConnectionNumber in -lICE""... $ac_c" 1>&6 +echo "configure:3534: checking for IceConnectionNumber in -lICE" >&5 +ac_lib_var=`echo ICE'_'IceConnectionNumber | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lICE $X_EXTRA_LIBS $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" +else + echo "$ac_t""no" 1>&6 +fi + + LDFLAGS="$ac_save_LDFLAGS" + +fi + +for ac_hdr in stdlib.h fcntl.h unistd.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:3581: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:3591: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + +echo $ac_n "checking for working const""... $ac_c" 1>&6 +echo "configure:3619: checking for working const" >&5 +if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <j = 5; +} +{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; +} + +; return 0; } +EOF +if { (eval echo configure:3673: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_const=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_c_const=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_c_const" 1>&6 +if test $ac_cv_c_const = no; then + cat >> confdefs.h <<\EOF +#define const +EOF + +fi + +echo $ac_n "checking size of int""... $ac_c" 1>&6 +echo "configure:3694: checking size of int" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(int)); + exit(0); +} +EOF +if { (eval echo configure:3713: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_int=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_int=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_int" 1>&6 +cat >> confdefs.h <&6 +echo "configure:3733: checking size of long" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(long)); + exit(0); +} +EOF +if { (eval echo configure:3752: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_long=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_long=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_long" 1>&6 +cat >> confdefs.h <&6 +echo "configure:3777: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:3787: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + +for ac_func in getpagesize +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3816: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3844: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +echo $ac_n "checking for working mmap""... $ac_c" 1>&6 +echo "configure:3869: checking for working mmap" >&5 +if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_mmap_fixed_mapped=no +else + cat > conftest.$ac_ext < +#include +#include + +/* This mess was copied from the GNU getpagesize.h. */ +#ifndef HAVE_GETPAGESIZE +# ifdef HAVE_UNISTD_H +# include +# endif + +/* Assume that all systems that can run configure have sys/param.h. */ +# ifndef HAVE_SYS_PARAM_H +# define HAVE_SYS_PARAM_H 1 +# endif + +# ifdef _SC_PAGESIZE +# define getpagesize() sysconf(_SC_PAGESIZE) +# else /* no _SC_PAGESIZE */ +# ifdef HAVE_SYS_PARAM_H +# include +# ifdef EXEC_PAGESIZE +# define getpagesize() EXEC_PAGESIZE +# else /* no EXEC_PAGESIZE */ +# ifdef NBPG +# define getpagesize() NBPG * CLSIZE +# ifndef CLSIZE +# define CLSIZE 1 +# endif /* no CLSIZE */ +# else /* no NBPG */ +# ifdef NBPC +# define getpagesize() NBPC +# else /* no NBPC */ +# ifdef PAGESIZE +# define getpagesize() PAGESIZE +# endif /* PAGESIZE */ +# endif /* no NBPC */ +# endif /* no NBPG */ +# endif /* no EXEC_PAGESIZE */ +# else /* no HAVE_SYS_PARAM_H */ +# define getpagesize() 8192 /* punt totally */ +# endif /* no HAVE_SYS_PARAM_H */ +# endif /* no _SC_PAGESIZE */ + +#endif /* no HAVE_GETPAGESIZE */ + +#ifdef __cplusplus +extern "C" { void *malloc(unsigned); } +#else +char *malloc(); +#endif + +int +main() +{ + char *data, *data2, *data3; + int i, pagesize; + int fd; + + pagesize = getpagesize(); + + /* + * First, make a file with some known garbage in it. + */ + data = malloc(pagesize); + if (!data) + exit(1); + for (i = 0; i < pagesize; ++i) + *(data + i) = rand(); + umask(0); + fd = creat("conftestmmap", 0600); + if (fd < 0) + exit(1); + if (write(fd, data, pagesize) != pagesize) + exit(1); + close(fd); + + /* + * Next, try to mmap the file at a fixed address which + * already has something else allocated at it. If we can, + * also make sure that we see the same garbage. + */ + fd = open("conftestmmap", O_RDWR); + if (fd < 0) + exit(1); + data2 = malloc(2 * pagesize); + if (!data2) + exit(1); + data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1); + if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_FIXED, fd, 0L)) + exit(1); + for (i = 0; i < pagesize; ++i) + if (*(data + i) != *(data2 + i)) + exit(1); + + /* + * Finally, make sure that changes to the mapped area + * do not percolate back to the file as seen by read(). + * (This is a bug on some variants of i386 svr4.0.) + */ + for (i = 0; i < pagesize; ++i) + *(data2 + i) = *(data2 + i) + 1; + data3 = malloc(pagesize); + if (!data3) + exit(1); + if (read(fd, data3, pagesize) != pagesize) + exit(1); + for (i = 0; i < pagesize; ++i) + if (*(data + i) != *(data3 + i)) + exit(1); + close(fd); + unlink("conftestmmap"); + exit(0); +} + +EOF +if { (eval echo configure:4017: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_func_mmap_fixed_mapped=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_func_mmap_fixed_mapped=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6 +if test $ac_cv_func_mmap_fixed_mapped = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_MMAP 1 +EOF + +fi + +if test "$ac_cv_func_mmap_fixed_mapped" != yes; then + TT_FILE_COMPONENT=ttfile.c +else + TT_FILE_COMPONENT=arch/unix/ttmmap.c +fi + + +for ac_func in memcpy memmove +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:4049: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:4077: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + + + + +$srcdir/mkinstalldirs lib/arch/unix test/arch/unix + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +DEFS=-DHAVE_CONFIG_H + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile + MakeSub + lib/arch/unix/Makefile + test/arch/unix/Makefile + po/Makefile.in ft_conf.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@build@%$build%g +s%@build_alias@%$build_alias%g +s%@build_cpu@%$build_cpu%g +s%@build_vendor@%$build_vendor%g +s%@build_os@%$build_os%g +s%@RANLIB@%$RANLIB%g +s%@CC@%$CC%g +s%@LD@%$LD%g +s%@NM@%$NM%g +s%@LN_S@%$LN_S%g +s%@LIBTOOL@%$LIBTOOL%g +s%@USE_NLS@%$USE_NLS%g +s%@target@%$target%g +s%@target_alias@%$target_alias%g +s%@target_cpu@%$target_cpu%g +s%@target_vendor@%$target_vendor%g +s%@target_os@%$target_os%g +s%@CPP@%$CPP%g +s%@XX_CFLAGS@%$XX_CFLAGS%g +s%@freetype_version@%$freetype_version%g +s%@version_info@%$version_info%g +s%@SET_MAKE@%$SET_MAKE%g +s%@HAVE_LOCALE_H@%$HAVE_LOCALE_H%g +s%@HAVE_LIBINTL_H@%$HAVE_LIBINTL_H%g +s%@HAVE_LIBINTL@%$HAVE_LIBINTL%g +s%@LOCALEDIR@%$LOCALEDIR%g +s%@MSGFMT@%$MSGFMT%g +s%@GMSGFMT@%$GMSGFMT%g +s%@XGETTEXT@%$XGETTEXT%g +s%@MSGMERGE@%$MSGMERGE%g +s%@CATALOGS@%$CATALOGS%g +s%@CATOBJEXT@%$CATOBJEXT%g +s%@INSTOBJEXT@%$INSTOBJEXT%g +s%@DATADIRNAME@%$DATADIRNAME%g +s%@RM@%$RM%g +s%@RMDIR@%$RMDIR%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@X_CFLAGS@%$X_CFLAGS%g +s%@X_PRE_LIBS@%$X_PRE_LIBS%g +s%@X_LIBS@%$X_LIBS%g +s%@X_EXTRA_LIBS@%$X_EXTRA_LIBS%g +s%@TT_FILE_COMPONENT@%$TT_FILE_COMPONENT%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +if test "${CONFIG_HEADERS+set}" != set; then +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +fi +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + cat $ac_file_inputs > conftest.in + +EOF + +# Transform confdefs.h into a sed script conftest.vals that substitutes +# the proper values into config.h.in to produce config.h. And first: +# Protect against being on the right side of a sed subst in config.status. +# Protect against being in an unquoted here document in config.status. +rm -f conftest.vals +cat > conftest.hdr <<\EOF +s/[\\&%]/\\&/g +s%[\\$`]%\\&%g +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%ac_d%ac_u%gp +s%ac_u%ac_e%gp +EOF +sed -n -f conftest.hdr confdefs.h > conftest.vals +rm -f conftest.hdr + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >> conftest.vals <<\EOF +s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% +EOF + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. + +rm -f conftest.tail +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write a limited-size here document to conftest.frag. + echo ' cat > conftest.frag <> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in +' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + fi + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + + + diff --git a/configure.in b/configure.in new file mode 100644 index 0000000..100c847 --- /dev/null +++ b/configure.in @@ -0,0 +1,201 @@ +dnl This file is part of the FreeType project. +dnl +dnl Process this file with autoconf to produce a configure script. + +AC_INIT(lib/freetype.h) + +dnl Due to a bug in autoconf we must set $srcdir explicitly to an absolute +dnl path. +srcdir=`cd $srcdir; pwd` + +AM_DISABLE_STATIC +AM_PROG_LIBTOOL + +dnl FreeType version +freetype_version='1.2.0' + +dnl libttf.so version +version_info='4:0:2' + +AC_ARG_ENABLE(nls, + [ --disable-nls don't use NLS], + USE_NLS=no, USE_NLS=yes) +AC_SUBST(USE_NLS) + +dnl Checks for system type. +AC_CANONICAL_SYSTEM + +dnl Checks for programs. +AC_PROG_CC +AC_PROG_CPP + +dnl get Compiler flags right. + +if test "x$CC" = xgcc; then + XX_CFLAGS="-Wall -pedantic -ansi" +else + case "$host" in + *-dec-osf*) + XX_CFLAGS="-std1 -O2 -g3" + ;; + *) + XX_CFLAGS= + ;; + esac +fi +AC_SUBST(XX_CFLAGS) + +dnl at least Digital UNIX 4.0d needs this due to a strange make program + +case "$host" in + *-dec-osf*) + ln -s ../../MakeSub lib/arch + ln -s ../../MakeSub test/arch + ;; +esac + +AC_SUBST(freetype_version) +AC_SUBST(version_info) + +dnl gettext support +if test "$USE_NLS" = "yes"; then + AC_REQUIRE([AC_PROG_MAKE_SET]) + AC_CHECK_HEADERS(locale.h) + AC_CHECK_FUNCS(setlocale) + AC_SUBST(HAVE_LOCALE_H) + + ALL_LINGUAS="de fr cs nl es" + AC_CHECK_HEADERS(libintl.h) + AC_CHECK_LIB(intl,gettext) + AC_SUBST(HAVE_LIBINTL_H) + AC_SUBST(HAVE_LIBINTL) + + dnl Handle localedir + LOCALEDIR='${prefix}/share/locale' + AC_ARG_WITH(locale-dir, + [ --with-locale-dir=DIR Location of the locale file(s) + [PREFIX/share/locale]],[ + if test x$withval = xyes; then + AC_MSG_WARN(Usage is: --with-locale-dir=basedir) + else + if test x$withval = xno; then + AC_MSG_WARN(Usage is: --with-locale-dir=basedir) + else + LOCALEDIR=$withval + fi + fi + ]) + AC_SUBST(LOCALEDIR) + + AC_PATH_PROG(MSGFMT, msgfmt, $MSGFMT) + if test -n "$MSGFMT"; then + AC_CHECK_FUNCS(dcgettext) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + AC_PATH_PROG(XGETTEXT, xgettext, $XGETTEXT) + AC_PATH_PROG(MSGMERGE, msgmerge, $MSGMERGE) + + dnl Test whether we really found GNU xgettext. + if test -n "$XGETTEXT"; then + if $XGETTEXT --omit-header /dev/null 2> /dev/null; then + : ; + else + AC_MSG_RESULT( + [found xgettext program is not GNU xgettext; ignore it]) + XGETTEXT="" + fi + fi + + dnl We add another test for comparing GNU xgettext with openwin xgettext + if test -n "$XGETTEXT"; then + if $XGETTEXT --help > /dev/null 2> /dev/null; then + : ; + else + AC_MSG_RESULT( + [found xgettext program is not GNU xgettext; ignore it]) + XGETTEXT="" + fi + fi + + dnl Test whether we really found GNU msgfmt. + if test -n "$MSGFMT"; then + if $MSGFMT < /dev/null 2> /dev/null; then + AC_MSG_RESULT( + [found msgfmt program is not GNU msgfmt; NLS won't be installed]) + MSGFMT="" + fi + fi + + AC_TRY_LINK(, + [extern int _nl_msg_cat_cntr; + return _nl_msg_cat_cntr], + [CATOBJEXT=.gmo + DATADIRNAME=share], + [CATOBJEXT=.mo + DATADIRNAME=lib]) + INSTOBJEXT=.mo + fi + + if test -n "$ALL_LINGUAS"; then + for lang in $ALL_LINGUAS; do + CATALOGS="$CATALOGS $lang$CATOBJEXT" + done + fi + AC_SUBST(CATALOGS) + AC_SUBST(CATOBJEXT) + AC_SUBST(INSTOBJEXT) + AC_SUBST(DATADIRNAME) +fi + +dnl don't use NLS, when there is no gettext installed +if test x"$MSGFMT" = x; then + USE_NLS=no +fi + + +AC_CHECK_PROG(RM, rm, rm) +AC_CHECK_PROG(RMDIR, rmdir, rmdir) +AC_PROG_INSTALL +AC_PROG_LN_S + +dnl Checks for libraries. +sinclude(net.m4) +AC_LIBRARY_NET +AC_CHECK_LIB(m, cos) + +dnl Checks for header files. +AC_PATH_XTRA +AC_CHECK_HEADERS(stdlib.h fcntl.h unistd.h) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_CHECK_SIZEOF(int) +AC_CHECK_SIZEOF(long) + +dnl Checks for library functions. + +dnl Here we check whether we can use our mmap file component. +AC_FUNC_MMAP +if test "$ac_cv_func_mmap_fixed_mapped" != yes; then + TT_FILE_COMPONENT=ttfile.c +else + TT_FILE_COMPONENT=arch/unix/ttmmap.c +fi +AC_SUBST(TT_FILE_COMPONENT) + +AC_CHECK_FUNCS(memcpy memmove) + +AC_CONFIG_HEADER(ft_conf.h) + +dnl Another bug: to make --srcdir work correctly we have to create the +dnl directory hierarchy first since autoconf only uses mkdir. +$srcdir/mkinstalldirs lib/arch/unix test/arch/unix + +AC_OUTPUT(Makefile + MakeSub + lib/arch/unix/Makefile + test/arch/unix/Makefile + po/Makefile.in, + [sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile]) + + +dnl end of configure.in diff --git a/contrib/ftos2/DEVELFAQ b/contrib/ftos2/DEVELFAQ new file mode 100644 index 0000000..f8aafbc --- /dev/null +++ b/contrib/ftos2/DEVELFAQ @@ -0,0 +1,38 @@ + + This is a FreeType/2 programmers' mini-FAQ + +Q1: Is the source code available? + +A1: Yes! But if you think you have all you need, you're probably wrong :-) + The source is now actually part of FreeType project, located at + ftp://ftp.physiol.med.tu-muenchen.de/pub/freetype + + We have now the permission to distribute the OS/2 IFI headers with + the FreeType/2 source code. They're all the files beginning with a + "32" in the "ifi" directory. It seems that some people had problems + with the download indicated in the last beta. + + +Q2: What compilers are supported? + +A2: The development of FreeType/2 was done primarily in IBM's VisualAge C++ + version 3.0. It should be possible to build the DLL with Watcom C/C++ but + it's not quite working yet. + It is perhaps possible to build the Font Driver with another compiler, + but you'll have to know the compiler (and OS/2 of course) _quite_ well. + + Note that the FreeType library itself supports also EMX/GCC (and I + believe it was mainly developed in it). + + +Q3: What other tools do I need? + +A3: You'll need a kernel debugger. Check out IBM's ICAT, it's great and + it's free! Actually without ICAT this code would probably never happen. + If you've lived under a rock and don't know what ICAT is, it's actually + an interface to ol' good KDB. It is a source-level debugger and it looks + and feels very much like the VisualAge debugger, IPMD. + + And if you haven't got it yet, you'll need _two_ computers to use ICAT. + But believe me, it's worth it! + diff --git a/contrib/ftos2/FAQ b/contrib/ftos2/FAQ new file mode 100644 index 0000000..d4a7922 --- /dev/null +++ b/contrib/ftos2/FAQ @@ -0,0 +1,260 @@ +This is a FreeType/2 users' mini-FAQ + +Table of Contents: + +Q1: Where can I find the latest FreeType/2 release? +Q2: Now that I have FreeType/2 installed, how do I actually add TrueType +fonts to OS/2? +Q3: When will you add font-smoothing to the DLL? I really want that! +Q4: Why does IBM's TrueType engine do such a poor job? +Q5: But there are still differences with the glyphs produced by Windows or +the Mac, right? +Q6: I've got TrueType Times New Roman installed but the system still seems +to be using the original ATM (Type 1) font. Why this odd behaviour? +Q7: I noticed it takes a second or two before the Font Palette object opens +for the first time. Why? +Q8: I noticed the characters sometimes have odd spacing. When will you fix +it? +Q9: Could you explain the open fonts limit? +Q10: Can you recommend some fonts to use? +Q11: What's a 'broken glyph'? +Q12: Why do some fonts appear twice, once starting with an '@'? +Q13: I've got a Chinese (Japanese, Korean) font but the characters aren't +there! Why? +Q14: I tried to use a DBCS font but I got an exception un UCONV.DLL. What's +wrong? +Q15: My system won't boot after I installed FreeType/2 and the uninstall +script won't work when I boot to command line. What now? +Q16: I'm upgrading from previous version and I don't want to uninstall and +reinstall. Is there any other way? +Q17: What's this stuff about Times New Roman being aliased to Tms Rmn? +Please explain this. + +Questions & Answers: + +Q1: Where can I find the latest FreeType/2 release? + +A1: Links to the latest release can be found at the FreeType/2 homepage at +http://www.freetype.org/ft_os2/index.html. + +Q2: Now that I have FreeType/2 installed, how do I actually add TrueType +fonts to OS/2? + +A2: I thought everyone knew that... It's simple, really. Open the Font +Palette object (in System Setup folder) then click 'Edit font' and 'Add'. +Now type the directory path where your TrueType fonts reside, such as +'C:\WINDOWS\FONTS' if you have Win95 and click 'Add'. You'll be presented a +list of all fonts that OS/2 found in specified directory. Simply select all +fonts you wish to install click 'Add' for the last time. If you wish to +remove fonts, just use the 'Delete' button in the 'Edit Font' dialog. +TIP: If you wish to add font to OS/2 but don't want to actually copy the +file, just type the directory name where the font files already are instead +of 'X:\PSFONTS' in the 'Add New Fonts' dialog. + +Q3: When will you add font-smoothing to the DLL? I really want that! + +A3: Short answer: We can't. +Long answer: The FreeType library already supports font-smoothing (or +antialiasing or grayscaling). The problem is that OS/2's font engine, in +its current incarnation, doesn't know anything about anti-aliased text and +is only able to manage monochrome bitmaps. Font smoothing support would +require some changes of PM/GPI/GRE components, which certainly is out of +our scope, and isn't planned by IBM (to our knowledge) in foreseeable +future, if ever. + +If you really need font smoothing in your application, you can still use +the FreeType library itself. Be warned that it is a rather low-level engine +and that you'll need to add a various number of text features on top of +this code to get the equivalent of PM's font API. + +There is a good chance that FreeType 2.0 will ease the pain for developers +when it's available. + +And if you really want font smoothing in OS/2, ask IBM! + +Q4: Why does IBM's TrueType engine do such a poor job? + +A4: It'd be easy to throw one or two stones at IBM's engineers if this was +the result of lazy coding or bad software engineering. However, the problem +is more complex, and PSP programmers deserve little, if any, blame. + +Trouble is that the TrueType specification, which can be found both on +Microsoft and Apple sites, has severe lacks, as well as particularly fuzzy +definitions. Part of the TT spec is the TrueType bytecode specification. +This bytecode is used to write glyph programs that are used to explicitely +hint each glyph to have it rendered perfectly on the screen (and on +printers). It is made of approximately 200 opcodes, which relate to moving +points on a pixel grid, measuring distances in any kind of direction, +keeping widths and heights consistent across a single font, etc.. + +Some of these opcodes are simply un-documented, or lack precise and +important details related to their exact implementation. As a consequence, +when FreeType started, it's first bytecode interpreter exhibited results +which were very similar to OS/2's one (i.e. bad baseline, incoherent +widths, "swashs" and bad serifs, etc..). There are several commercial +engines which provide the same kind of "erroneous" output, like the one in +the BeOS for instance. + +It took FreeType developers _many_ months and experimentation to discover +the real meaning of some opcodes, and incorporate it into the library. This +"spelunker" work has been painful and slow, which is why few commercial +companies, if any, dared to do it, but it finally pays off ! Moreover, the +FreeType library is released under a BSD-like free license. This means that +_anyone_ is now able to take the work that has been done to rewrite or fix +his own TrueType interpreter. (Of course, another good idea is to use +FreeType as your core TrueType engine, to be able to benefit to ongoing +fixes and "undocumented features" discoveries, etc...) + +Q5: But there are still differences with the glyphs produced by Windows or +the Mac, right? + +A5: Right. Another feature of the TrueType specification is to use fixed +float pixel coordinates. When measuring distances along diagonals, some +rouding error usually occur. Also, some TrueType opcodes have a more or +less "chaotic" behaviour, where a ridiculous difference in inputs can +produce vastly different results. These factors mean that the only way to +match bit-to-bit the glyphs produced by Windows or the Macintosh is to +implement the _exact_ same computation routines, and reproduce all their +rounding errors ! As FreeType is a clean-room implementation, this will +never be possible. Note that the bitmaps match in 95% cases, at least, and +that there are already differences between the Win 3.1 and Win95 TrueType +renderers (i.e. look at the "m" of Arial at size 8 for example). + +The FreeType team tries very hard to "catch" differences, but there is a +point where this just isn't possible... However, we're very satisfied with +its current quality, and we hope you'll be too :-) + +Q6: I've got TrueType Times New Roman installed but the system still seems +to be using the original ATM (Type 1) font. Why this odd behaviour? + +A6: It seems in case of a name clash OS/2 is using the font that was +installed later. Try removing and reinstalling the TrueType font. +Alternately remove the ATM (Type 1) font (not recommended). +Experiments also suggest that different apps behave differently. Some apps +will for example show both fonts but will use only one of them anyway. It +really depends. + +Q7: I noticed it takes a second or two before the Font Palette object opens +for the first time. Why? + +A7: Because FreeType/2 postpones as much work on the fonts as possible +until it's really needed. This means the first opening of a font is a bit +slower. But it also means no resources are unnecessarily wasted. And it's +not really that bad :-) This behaviour is also noticeable when e.g. opening +a document for the first time. Note that subsequent openings are OK because +OS/2 caches as much information as possible. + +Q8: I noticed the characters sometimes have odd spacing. When will you fix +it? + +A8: I won't. It's not really a bug, it's a feature. If they weren't spaced +'oddly', the result might look better, but only at the cost of +Windows-style 'WYSIWYG', i.e. what you see on screen will almost certainly +look totally different on any other device. Anyway, the spacing is +controlled by OS/2 and not by the Font Driver itself, so if you still don't +like it, IBM is the right one to ask :-) + +This problem is particularly visible in Netscape. Most probably this +happens because Netscape tries to use fractional pointsizes, but most +TrueType fonts don't allow that. This means that Netscape sometimes +positions characters as if they were e.g. 8.6 points while their actual +size is only 8 points. + +Q9: Could you explain the open fonts limit? + +A9: Sure. If you install 50 fonts in OS/2, the system opens them all at +startup and keeps them open until shutdown. While many users may want to +have large number of fonts installed (like me), very few of them probably +use all the fonts all the time. This of course wastes lots of memory and +swap space. Just for your information, normal fonts take up 30-50 K of +memory with FreeType/2, but for example Times New Roman MT 30 takes over +500K! + +FreeType/2 overcomes this problem by only actually keeping in memory the +last n most recently used fonts. The actual number is settable via entry in +OS2.INI and there's an simple REXX script to do that. Good default might be +10-15 fonts, depending what you want to do with them. + +Note that this process is totally transparent to the system. You won't have +to do anything, FreeType/2 will take care of everything. The only things +you will notice is dramatically reduced memory consumption and when working +with large numbers of fonts there may be slight delay when reopening a +font. + +Q10: Can you recommend some fonts to use? + +A10: Yes! I recommend to use Micro$oft's (oh no!) Core Fonts - Times New +Roman, Arial and Courier New, plus other MS fonts. There are several +reasons: the fonts have very good quality, stick to the TrueType spec prety +well, support many countries and are widely available. Moreover they're +free. You can certainly find some Win95 or NT machine in your neighbourhood +(all too easily I'm afraid). They should also be available from MS's Web +site. +Note: If you want to copy the fonts from a Win95 machine, they're in +\WINDOWS\FONTS. Watch out, the directory is hidden! + +Q11: What's a 'broken glyph'? + +A11: Some fonts contain buggy or 'broken' glyphs that cannot be reliably +loaded and rendered. Those glyphs are usually very rarely used so you might +never notice. There was a problem with the first Beta of FreeType/2 that if +there was a single broken glyph in a font, the +whole font didn't work. + +Q12: Why do some fonts appear twice, once starting with an '@'? + +A12: It's because of DBCS systems. If you don't have one, you can safely +ignore these fonts. The DBCS characters in them are rotated 90 degrees +counterclockwise. It allows you to write vertical text (e.g. Chinese) with +a normal word processor. You write the text horizontally but if you turn +the resulting page 90 degrees clockwise, you've got vertical text. +It's not working perfectly yet. + +Q13: I've got a Chinese (Japanese, Korean) font but the characters aren't +there! Why? + +A13: Most probably the font and your system settings don't mix. One +possible cause is that your country setting is different than that of the +font and the font contains no information about what language it's meant +for. In that case, FreeType/2 has to guess from your country setting. This +means it might try to treat e.g. Japanese font as a Korean one which means +you won't be able to access the Japanese characters in it. It's all a bit +more complicated but it's a result of how national language support is done +in OS/2. + +Q14: I tried to use a DBCS font but I got an exception un UCONV.DLL. What's +wrong? + +A14: UCONV.DLL it used for character code translation. A likely cause is +that you are missing the required translation table in \LANGUAGE\CODEPAGE +directory on your boot drive. Look for file named 'IBM', where is +the codepage you use, e.g. IBM950 for Taiwan or IBM949 for Korea. + +Q15: My system won't boot after I installed FreeType/2 and the uninstall +script won't work when I boot to command line. What now? + +A15: But you've archived the key files, haven't you? If not, one way out of +this mess is booting to command line and renaming or deleting FREETYPE.DLL +from \OS2\DLL. Your system should boot then. + +Q16: I'm upgrading from previous version and I don't want to uninstall and +reinstall. Is there any other way? + +A16: Yes! There's a little utility called REPMOD.EXE which allows you to +replace files that are in use. In case you don't already have it, it's +included in the FreeType/2 package. You should simply run UPDATE.CMD. The +new version will be used on next reboot. + +Q17: What's this stuff about Times New Roman being aliased to Tms Rmn? +Please explain this. + +A17: OS/2 contains bitmap font called Tms Rmn which is often used in dialog +windows and elsewhere. The bitmap font contains only several pointsizes (8, +10, 12, 14, 18, 24). If you request a missing pointsize, OS/2's graphics +engine (GRE) substitutes it from the (outline) ATM font Times New Roman +which can also be referred to as Roman/Tms Rmn. Now FreeType/2 mimics this +functionality and can fully replace the ATM version. I recommend to +uninstall the ATM font since if both fonts are installed, some apps use the +ATM one, others TrueType one, without any apparent logic. If you uninstall +(via Font Palette) the ATM version, you will always get high-quality +TrueType Times New Roman. diff --git a/contrib/ftos2/ft2.gif b/contrib/ftos2/ft2.gif new file mode 100644 index 0000000..b3e9632 Binary files /dev/null and b/contrib/ftos2/ft2.gif differ diff --git a/contrib/ftos2/ifi/32fddef.h b/contrib/ftos2/ifi/32fddef.h new file mode 100644 index 0000000..73ae565 --- /dev/null +++ b/contrib/ftos2/ifi/32fddef.h @@ -0,0 +1,53 @@ +/*********************************************************************\ +* Module Name: 32FDDEF.H +* +* OS/2 Intelligent Font Interface +* +* Copyright (c) 1989,1994 IBM Corporation +* Copyright (c) 1989 Microsoft Corporation +* +\*********************************************************************/ +#ifndef __32FDDEF_H__ +#define __32FDDEF_H__ + +/* Typedef the Font Driver 32 Bit entry points */ + +/* FdLoadFontFile */ +typedef HFF (* _syscall PFDLFF)(PSZ pszFileName); + +/* FdQueryFaces */ +typedef LONG (* _syscall PFDQF)(HFF hff, PIFIMETRICS pifim, + ULONG cMetricLen, ULONG cFontCount, + ULONG cStart); +/* FdConvertFontFile */ +typedef LONG (* _syscall PFDCFF)(PSZ pszSrc, PSZ pszDestDir, + PSZ pszName); + +/* FdClaimFontFile */ +typedef LONG (* _syscall PFDCLF)(PSZ pszFileName); + +/* FdUnloadFontFile */ +typedef LONG (* _syscall PFDUFF)(HFF hff); + +/* FdOpenFontContext */ +typedef HFC (* _syscall PFDOFC)(HFF hff, ULONG ulFont); + +/* FdSetFontContext */ +typedef LONG (* _syscall PFDSFC)(HFC hfc, PCONTEXTINFO pci); + +/* FdCloseFontContext */ +typedef LONG (* _syscall PFDCFC)(HFC hfc); + +/* FdQueryFaceAttr */ +typedef LONG (* _syscall PFDQFA)(HFC hfc, ULONG iQuery, PBYTE pBuffer, + ULONG cb, PGLYPH pagi, GLYPH gistart); + +/* FdQueryCharAttr */ +typedef LONG (* _syscall PFDQCA)(HFC hfc, PCHARATTR pCharAttr, + PBITMAPMETRICS pbmm); + +/* FdQueryFullFaces */ +typedef LONG (* _syscall PFDQFF)(HFF hff, PVOID pBuf, PULONG cBufLen, + PULONG cFontCount, ULONG cStart); +#endif + diff --git a/contrib/ftos2/ifi/32fdstrc.h b/contrib/ftos2/ifi/32fdstrc.h new file mode 100644 index 0000000..0db1d72 --- /dev/null +++ b/contrib/ftos2/ifi/32fdstrc.h @@ -0,0 +1,161 @@ +/*********************************************************************\ +* Module Name: 32FDSTRC.H +* +* OS/2 Intelligent Font Interface +* +* Copyright (c) 1989,1994 IBM Corporation +* Copyright (c) 1989 Microsoft Corporation +* +\*********************************************************************/ +#ifndef __32FDSTRC_H__ +#define __32FDSTRC_H__ + +#define FACESIZE 32 +#define GLYPHNAMESIZE 16 + +/* Error codes defined to be returned by IFI */ +/* NOTE: The actual values are subject to change */ + +/*#define PMERR_BUFFER_TOO_SMALL 23003L*/ +#define PMERR_FACENAME_NOT_FOUND 23004L +#define PMERR_FD_ALREADY_INSTALLED 23005L +#define PMERR_INVALID_CONTEXTINFO 23006L +#define PMERR_NOT_A_FONT_FILE 23007L +#define PMERR_INVALID_FONT_SELECTION 23008L +#define PMERR_INVALID_FORMAT 23009L +#define PMERR_BUSY_HFC 230010L +#define PMERR_INVALID_HFC 230011L +#define PMERR_INVALID_INDEX 230012L +#define PMERR_INVALID_QUERY_TYPE 230013L +#define PMERR_CONTEXT_NOT_SET 230014L + +/* Query faces subfunction */ +#define FD_QUERY_CONTEXTMETRICS 1L +#define FD_QUERY_ABC_WIDTHS 2L +#define FD_QUERY_KERNINGPAIRS 3L + +/* Query char subfunction */ +#define FD_QUERY_CHARIMAGE 1L +#define FD_QUERY_OUTLINE 2L +#define FD_QUERY_BITMAPMETRICS 4L + +#define FD_CHARATTR_ALIGNED_8 0x00000001 +#define FD_CHARATTR_ALIGNED_16 0x00000002 +#define FD_CHARATTR_ALIGNED_32 0x00000004 +#define FD_CHARATTR_NO_CACHE 0x00000010 + +typedef struct _ABC_TRIPLETS /*abc*/ +{ + LONG lA; + ULONG ulB; + LONG lC; +} ABC_TRIPLETS; +typedef ABC_TRIPLETS *PABC_TRIPLETS; + +// THIS STRUCTURE NOW RESIDES IN PMDDI.H FOR CRUISER WORLD +// BUT IFI FONT DRIVER DOES NOT INCLUDE PMDDI.H + +#ifndef INCL_IFI +typedef struct _POINTFX { /* ptfx */ + FIXED x; + FIXED y; +} POINTFX; +typedef POINTFX *PPOINTFX; +#endif + +typedef struct _BITMAPMETRICS /* bmm */ +{ + SIZEL sizlExtent; + ULONG cyAscent; +#ifdef OLD_DRIVER + POINTFX *ppfxOrigin; /* Return character origin. */ +#else + POINTFX pfxOrigin; /* Return character origin. */ +#endif +} BITMAPMETRICS; +typedef BITMAPMETRICS *PBITMAPMETRICS; + +typedef struct _MAT2 /* mat */ +{ + FIXED eM11; + FIXED eM12; + FIXED eM21; + FIXED eM22; +} MAT2; + +typedef struct _FD_KERNINGPAIRS /* krnpr */ +{ + GLYPH giFirst; + GLYPH giSecond; + LONG eKerningAmount; +} FD_KERNINGPAIRS; + +typedef struct _CONTEXTINFO /* ci */ +{ + ULONG cb; /* Length in bytes of this structure. */ + ULONG fl; /* Flags. */ + SIZEL sizlPPM; /* Device resolution in pels/meter. */ + POINTFX pfxSpot; /* Spot size in pels. */ + MAT2 matXform; /* Notional to Device transform. */ +} CONTEXTINFO; +typedef CONTEXTINFO *PCONTEXTINFO; + +typedef struct _CHARATTR /* ca */ +{ + ULONG cb; + ULONG iQuery; /* Query type. */ + GLYPH gi; /* Glyph index in font. */ + PBYTE pBuffer; /* Bitmap buffer. */ + ULONG cbLen; /* Size of buffer in bytes. */ +} CHARATTR; +typedef CHARATTR *PCHARATTR; + +typedef struct _CHARATTR2 /* ca2 */ +{ + ULONG cb; + ULONG iQuery; /* Query type. */ + GLYPH gi; /* Glyph index in font. */ + PBYTE pBuffer; /* Bitmap buffer. */ + ULONG cbLen; /* Size of buffer in bytes. */ + ULONG fl; /* Flags */ +} CHARATTR2; +typedef CHARATTR2 *PCHARATTR2; + +typedef struct _CONTEXTMETRICS +{ + SIZEL sizlMax; + ULONG cyMaxAscent; + ULONG cyMaxDescent; + ULONG cxTotal; + ULONG cGlyphs; +} CONTEXTMETRICS; +typedef CONTEXTMETRICS * PCONTEXTMETRICS; + +typedef struct _POLYGONHEADER { + ULONG cb; + ULONG iType; /* Must be FD_POLYGON_TYPE */ +} POLYGONHEADER; +typedef POLYGONHEADER *PPOLYGONHEADER; + +typedef struct _PRIMLINE { + ULONG iType; /* Must be FD_PRIM_LINE */ + POINTFX pte; +} PRIMLINE; +typedef PRIMLINE *PPRIMLINE; + +typedef struct _PRIMSPLINE { + ULONG iType; /* Must be FD_PRIM_SPLINE */ + POINTFX pte[3]; +} PRIMSPLINE; +typedef PRIMSPLINE *PPRIMSPLINE; + +/* + * The names of these were changed to avoid conflict with PRIM_LINE + * which is defined ion some other header file. + */ +#define FD_POLYGON_TYPE 24 +#define FD_PRIM_LINE 1 +#define FD_PRIM_SPLINE 3 + +#endif + diff --git a/contrib/ftos2/ifi/32ifimet.h b/contrib/ftos2/ifi/32ifimet.h new file mode 100644 index 0000000..d965ce0 --- /dev/null +++ b/contrib/ftos2/ifi/32ifimet.h @@ -0,0 +1,118 @@ +/*********************************************************************\ +* Module Name: 32IFIMET.H +* +* OS/2 Intelligent Font Interface +* +* Copyright (c) 1989,1994 IBM Corporation +* Copyright (c) 1989 Microsoft Corporation +* +* Definition and description of IFIMETRICS structure +* This file is included by FDSTRUCS.H +* +\*********************************************************************/ +#ifndef __32IFIMET_H__ +#define __32IFIMET_H__ + +#define FACESIZE 32 +#define GLYPHNAMESIZE 16 + +/* #defines for fsType in IFIMETRICS */ + +#define IFIMETRICS_FIXED 0x0001 /*Fixed pitch */ +#define IFIMETRICS_LICENSED 0x0002 /*Font subject of licensing agreement */ +#define IFIMETRICS_KERNING 0x0004 /*Font has kerning data */ +#define IFIMETRICS_DBCS 0x0010 /*DBCS font */ +#define IFIMETRICS_MBCS 0x0018 /*MBCS (DBCS + SBCS) font */ +/* Reserved 0x8000 */ +#define IFIMETRICS_ATOMS 0x4000 /*The atom name fields are valid */ +#define IFIMETRICS_FAMTRUNC 0x2000 /*Familyname field is truncated */ +#define IFIMETRICS_FACETRUNC 0x1000 /*Facename field is truncated */ +#define IFIMETRICS_ANTIALIASED 0x0020 +#define IFIMETRICS_UNICODE 0x0040 +#define IFIMETRICS_NO_CACHE 0x0080 + +/* #defines for fsDefn in IFIMETRICS */ + +#define IFIMETRICS_OUTLINE 0x0001 /*1 - Outline. 0 - Raster */ +/* Reserved 0x0002 */ +/* Reserved 0x0004 */ +/* Reserved 0x8000 */ +#define IFIMETRICS_UDC_FONT 0x0010 /*User defined font */ +/* Reserved */ + +/* #defines for fsSelection in IFIMETRICS valid for bitmap or outline fonts */ + +#define IFIMETRICS_ITALIC 0x8000 /*Italic */ +#define IFIMETRICS_UNDERSCORE 0x4000 /*Underscored */ +#define IFIMETRICS_OVERSTRUCK 0x2000 /*Overstruck */ + +/* #defines for fsSelection in IFIMETRICS valid for bitmap fonts */ + +#define IFIMETRICS_NEGATIVE 0x1000 /*Negative image */ +#define IFIMETRICS_HOLLOW 0x0800 /*Outline (hollow) */ + +#if defined(__IBMCPP__) || defined(__IBMC__) + #pragma pack(1) +#else + #pragma Align_members(1) +#endif + +typedef struct _IFIMETRICS /* ifim */ +{ /* UNITS */ + UCHAR szFamilyname[FACESIZE]; /*Font Family Name, e.g. Roman */ + UCHAR szFacename[FACESIZE]; /*Face name, e.g. Tms Rmn Bold Italic */ + UCHAR szGlyphlistName[GLYPHNAMESIZE]; /*e.g. PM316, Latin-2, Greek */ + USHORT idRegistry; /*IBM registration number (or zero). I */ + LONG lCapEmHeight; /*Height of uppercase M N */ + LONG lXHeight; /*Nominal height of lowercase N */ + LONG lMaxAscender; /*Maximum height above baseline of any char N */ + LONG lMaxDescender; /*Maximum depth below baseline of any char N */ + LONG lLowerCaseAscent; /*Maximum height above baseline of any a-z N */ + LONG lLowerCaseDescent; /*Maximum depth below basiline of any a-z N */ + LONG lInternalLeading; /*White space within character N */ + LONG lExternalLeading; /*White space between lines N */ + LONG lAveCharWidth; /*Weighted average character width N */ + LONG lMaxCharInc; /*Maximum character increment N */ + LONG lEmInc; /*Increment for Capitals (typically 'M') N */ + LONG lMaxBaselineExt; /*Height of character cell N */ + FIXED fxCharSlope; /*Slope angle, degrees, clockwise D */ + FIXED fxInlineDir; /*Drawing direction, degrees clockwise D */ + FIXED fxCharRot; /*Glyph rotation in cell, degrees clockwise D */ + USHORT usWeightClass; /*Character weight, 1-9 (1=ultra-light) I */ + USHORT usWidthClass; /*Character width, 1-9 (1=ultra condensed) I */ + LONG lEmSquareSizeX; /*Em Square size, x-direction N */ + LONG lEmSquareSizeY; /*Em Square size, y-direction N */ + GLYPH giFirstChar; /*Number of first glyph in font I */ + GLYPH giLastChar; /*Number of last glyph in font I */ + GLYPH giDefaultChar; /*Glyph used if requested glyph invalid I */ + GLYPH giBreakChar; /*Space glyph I */ + USHORT usNominalPointSize; /*Point size for which font was designed N */ + USHORT usMinimumPointSize; /*Minimum point size scaling for font N */ + USHORT usMaximumPointSize; /*Maximum point size scaling for font N */ + USHORT fsType; /*Type indicators (see #defines) B */ + USHORT fsDefn; /*Font definition data (see #defines) B */ + USHORT fsSelection; /*Font selection flags (see #defines) B */ + USHORT fsCapabilities; /*Font capabilities must be 0 B */ + LONG lSubscriptXSize; /*Size in x-direction of subscript N */ + LONG lSubscriptYSize; /*Size in y-direction of subscript N */ + LONG lSubscriptXOffset; /*Offset in x-direction of subscript N */ + LONG lSubscriptYOffset; /*Offset in y-direction of subscript N */ + LONG lSuperscriptXSize; /*Size in x-direction of superscript N */ + LONG lSuperscriptYSize; /*Size in y-direction of superscript N */ + LONG lSuperscriptXOffset; /*Offset in x-direction of superscript N */ + LONG lSuperscriptYOffset; /*Offset in y-direction of superscript N */ + LONG lUnderscoreSize; /*Underscore size N */ + LONG lUnderscorePosition; /*Underscore position N */ + LONG lStrikeoutSize; /*Strikeout size N */ + LONG lStrikeoutPosition; /*Strikeout position N */ + SHORT cKerningPairs; /*Number of kerning pairs in pair table I */ + ULONG ulFontClass; /*IBM font classification B */ +} IFIMETRICS; +typedef IFIMETRICS FAR *PIFIMETRICS; +#if defined(__IBMCPP__) || defined(__IBMC__) + #pragma pack() +#else + #pragma Align_members() +#endif + +#endif diff --git a/contrib/ftos2/ifi/32pmifi.h b/contrib/ftos2/ifi/32pmifi.h new file mode 100644 index 0000000..e0bdb89 --- /dev/null +++ b/contrib/ftos2/ifi/32pmifi.h @@ -0,0 +1,79 @@ +/*********************************************************************\ +* Module Name: 32PMIFI.H +* +* OS/2 Intelligent Font Interface +* +* Copyright (c) 1989,1994 IBM Corporation +* Copyright (c) 1989 Microsoft Corporation +* +\*********************************************************************/ +#ifndef __32PMIFI_H__ +#define __32PMIFI_H__ + +#define INCL_IFD + +typedef PVOID HFF; /* Font file handle */ +typedef PVOID HFC; /* Font context handle */ + +#ifndef INCL_GRE_FONTS +typedef ULONG GLYPH; /* gi */ +typedef ULONG *PGLYPH; /* pgi */ +#endif + +#include "32fdstrc.h" /* Font Driver structures */ +#include "32ifimet.h" /* Pifi Metrics */ +#include "32fddef.h" /* Font Driver entry definitions */ + + +typedef struct _FDDISPATCH16 { /* fdisp */ + PVOID FdLoadFontFile; + PVOID FdQueryFaces; + PVOID FdUnloadFontFile; + PVOID FdOpenFontContext; + PVOID FdSetFontContext; + PVOID FdCloseFontContext; + PVOID FdQueryFaceAttr; + PVOID FdQueryCharAttr; + PVOID FdClaimFontFile; + PVOID FdConvertFontFile; +} FDDISPATCH16; +typedef FDDISPATCH16 FAR *PFDDISPATCH16; + + +typedef struct _FDDISPATCH { /* fdisp */ + PFDLFF FdLoadFontFile; + PFDQF FdQueryFaces; + PFDUFF FdUnloadFontFile; + PFDOFC FdOpenFontContext; + PFDSFC FdSetFontContext; + PFDCFC FdCloseFontContext; + PFDQFA FdQueryFaceAttr; + PFDQCA FdQueryCharAttr; + PFDCLF FdClaimFontFile; + PFDCFF FdConvertFontFile; + PFDQFF FdQueryFullFaces; +} FDDISPATCH; +typedef FDDISPATCH *PFDDISPATCH; + +typedef struct _FDHEADER { /* fdhdr */ + ULONG cbLength; /* Length of FDHEADER */ + UCHAR strId[16]; /* String 'OS/2 FONT DRIVER' */ + UCHAR szTechnology[40]; /* Identifier of Font Driver technology */ + ULONG ulVersion; /* IFI version number (0x0100) */ + ULONG ufDeviceCaps; /* Capabilities of device */ + PFDDISPATCH pfddisp; +} FDHEADER; + +typedef FDHEADER FAR *PFDHEADER; + +#define OK 0 +#define ERROR -1 + +#define IFI_VERSION 10 +#define IFI_VERSION20 20 +#define IFI_VERSION21 21 + +#define FD_DISPATCH_COUNT 11 +#define DISPATCHTABLE "FONT_DRIVER_DISPATCH_TABLE" + +#endif diff --git a/contrib/ftos2/ifi/FreeType.def b/contrib/ftos2/ifi/FreeType.def new file mode 100644 index 0000000..a9e06b2 --- /dev/null +++ b/contrib/ftos2/ifi/FreeType.def @@ -0,0 +1,10 @@ +;LIBRARY FreeType INITGLOBAL TERMGLOBAL +LIBRARY FreeType INITINSTANCE TERMINSTANCE + +PROTMODE + +DATA SINGLE SHARED READWRITE LOADONCALL +;DATA MULTIPLE NONSHARED READWRITE LOADONCALL +CODE LOADONCALL + +DESCRIPTION "FreeType/2, Copyright (C) 1998 Michal Necasek" diff --git a/contrib/ftos2/ifi/FreeType.icc b/contrib/ftos2/ifi/FreeType.icc new file mode 100644 index 0000000..1c9d230 --- /dev/null +++ b/contrib/ftos2/ifi/FreeType.icc @@ -0,0 +1,35 @@ +# Makefile for FTIFI using IBM VisualAge C++ +# +# Explanation of compiler switches used: +# -C compile only, do not link +# -Sp1 pack structures on byte boundaries (quite important) +# -Ss accept double slash (//) comments +# -Ge- build a DLL +# -Rn build a subsystem DLL; means that a special C library is +# linked and some calls cannot be used +# -Fo create object file +# -O+ optimizations on +# -G4 optimize for 486 (should be better for my 6x86MX, produces smaller +# code than Pentium optimization) +# Linker switches used: +# /DE include debug info in executable +# /NOE no extended dictionary search +# /E:2 exepack (for Warp 3 and higher) +# /A:32 align pages of code on 32-byte boundaries (makes smaller file) +# /DBGPACK pack debug info + +# uncomment ICCR and LNKR to build a release version +ICCR=-O+ -G4 +LNKR=/PACKC /PACKD /M /A:32 /E:2 +# uncomment ICCD and LNKD to build a debug version. Note that debug and +# release version is not mutually exclusive in this case. +#ICCD=-Ti+ -DDEBUG +#ICCD=-Ti+ +#LNKD=/DE /DBGPACK /M + + +FreeType.dll: $*.obj $*.def ..\lib\libttf.lib + ilink /NOE $(LNKD) $(LNKR) $*.obj ..\lib\libttf.lib libconv.lib $*.def + +FreeType.obj: ftifi.c ftifi.h FreeType.icc + icc $(ICCD) $(ICCR) -C -Sp1 -Ss -Ge- -Rn -FoFreeType -I..\lib -I..\lib\extend -I..\lib\arch\os2 ftifi.c diff --git a/contrib/ftos2/ifi/FreeType.wat b/contrib/ftos2/ifi/FreeType.wat new file mode 100644 index 0000000..ecb1a6c --- /dev/null +++ b/contrib/ftos2/ifi/FreeType.wat @@ -0,0 +1,29 @@ +# WARNING!! this doesn't quite work yet!!!! +# +# Makefile for FTIFI using Watcom C/C++ +# +# Explanation of compiler switches used: +# -4r register calling convention, generate 486 code. Better than +# Pentium opt. for Cyrix/IBM and AMD +# -otexan maximum optimization for speed +# -zp1 pack structures on byte boundaries (quite important!) +# -bd build a DLL +# -zc +# -d2 include debug info +# +# Important linker options used: +# initglobal call DLL initialization function only once (not for each +# process) +# termglobal call DLL termination function only once +# oneautodata use only one shared data segment + +WCCR=-4r -otexan +#WCCD=-d2 -DDEBUG +#LNKD=debug all + + +FreeType.dll: $*.obj $*.def + wlink system os2v2 dll initglobal termglobal op oneautodata export GetOutline_ export FONT_DRIVER_DISPATCH_TABLE=_fdhdr file $* lib ..\lib\libttf.lib $(LNKD) + +FreeType.obj: ftifi.c ftifi.h + wcc386 $(WCCD) $(WCCR) -zp1 -bd -zc -I..\lib -I..\lib\extend ftifi.c /Fo=freetype.obj diff --git a/contrib/ftos2/ifi/ftifi.c b/contrib/ftos2/ifi/ftifi.c new file mode 100644 index 0000000..9cb6721 --- /dev/null +++ b/contrib/ftos2/ifi/ftifi.c @@ -0,0 +1,3209 @@ +/* */ +/* OS/2 Font Driver using the FreeType library */ +/* */ +/* Copyright (C) 1997, 1998 Michal Necasek */ +/* Copyright (C) 1997, 1998 David Turner */ +/* Copyright (C) 1997, 1998 International Business Machines */ +/* */ +/* Version: 0.9.90 (Beta) */ +/* */ +/* This source is to be compiled with IBM VisualAge C++ 3.0 or possibly */ +/* Watcom C/C++ 10.0 or higher (Wactom doesn't quite work yet). */ +/* Other compilers may actually work too but don't forget this is NOT a */ +/* normal DLL but rather a subsystem DLL. That means it shouldn't use */ +/* the usual C library as it has to run without runtime environment. */ +/* VisualAge provides a special subsystem version of the run-time library. */ +/* All this is of course very compiler-dependent. See makefiles for */ +/* discussion of switches used. */ +/* */ +/* Implemantation Notes: */ +/* */ +/* Note #1: As a consequence of this being a subsystem librarary, I had to */ +/* slightly modify the FreeType source, namely ttmemory.c and ttfile.c. */ +/* FreeType/2 now allocates several chunks of memory and uses them as a */ +/* heap. Note that memory allocation should use TTAlloc(), possibly */ +/* directly SSAllocMem(). malloc() is unusable here and it doesn't work */ +/* at all (runtime library isn't even initialized). See ttmemory.c for */ +/* more info. */ +/* In ttfile.c I had to change all fopen(), fseek()... calls */ +/* to OS/2 API calls (DosOpen, DosSetFilePtr...) because without proper */ +/* runtime environment a subsystem DLL cannot use std C library calls. */ +/* */ +/* Note #2: On exit of each function reading from font file the API */ +/* TT_Flush_Stream() must be called. This is because file handles opened */ +/* by this DLL actually belong to the calling process. As a consequence */ +/* a) it's easy to run out of file handles, which results in really */ +/* very nasty behavior and/or crashes. This could be solved by */ +/* increased file handles limit, but cannot because */ +/* b) it is impossible to close files open by another process and */ +/* therefore the fonts cannot be properly uninstalled (you can't */ +/* delete them while the're open by other process) */ +/* The only solution I found is very simple - just close the file before */ +/* exiting a DLL function. This ensures files are not left open across */ +/* processes and other problems. */ +/* */ +/* Note #3: The whole business with linked lists is aimed at lowering */ +/* memory consumption drastically. If you install 50 TT fonts, OS/2 */ +/* opens all of them at startup. Even if you never use them, they take */ +/* up at least over 1 Meg memory. With certain fonts the consumption can */ +/* easily go over several MB. We limit such waste of memory by only */ +/* actually keeping open several typefaces most recently used. Their */ +/* number can be set via entry in OS2.INI. */ +/* */ +/* For Intelligent Font Interface (IFI) specification please see IFI32.TXT */ + +#ifndef __IBMC__ + #ifndef __WATCOMC__ + #error "This source requires IBM VisualAge C++ or Watcom C/C++" + #endif +#endif + +/* Defining the following uses UCONV.DLL instead of the built-in */ +/* translation tables. This code should work on any Warp 4 and */ +/* Warp 3 w/ FixPak 35(?) and above */ +/* Note: this should be defined before FTIFI.H is #included */ +#undef USE_UCONV + +#define INCL_WINSHELLDATA /* for accessing OS2.INI */ +#define INCL_DOSMISC +#define INCL_DOSNLS +#define INCL_DOSPROCESS +#define INCL_GRE_DCS +#define INCL_GRE_DEVSUPPORT +#define INCL_DDIMISC +#define INCL_IFI +#include +#include /* SSAllocmem(), SSFreemem() and more */ + +#ifdef USE_UCONV /* uconv.h isn't always available */ +#include +#endif /* USE_UCONV */ + +#include +#include /* min and max macros */ + +#define _syscall _System /* the IFI headers don't compile without it */ + +#include "32pmifi.h" /* IFI header */ +#include "freetype.h" /* FreeType header */ +#include "ftxkern.h" /* kerning extension */ +#include "ftxwidth.h" /* glyph width extension */ +#include "ftifi.h" /* xlate table */ + + +/* For the sake of Netscape's text rendering bugs ! */ +#define NETSCAPE_FIX + +/* Create 'fake' Roman face for Times New Roman (to mimic PMATM's */ +/* behaviour */ +#define FAKE_TNR + +/* (indirectly) exported functions */ +LONG _System ConvertFontFile(PSZ pszSrc, PSZ pszDestDir, PSZ pszNewName); +HFF _System LoadFontFile(PSZ pszFileName); +LONG _System UnloadFontFile(HFF hff); +LONG _System QueryFaces(HFF hff, PIFIMETRICS pifiMetrics, ULONG cMetricLen, + ULONG cFountCount, ULONG cStart); +HFC _System OpenFontContext(HFF hff, ULONG ulFont); +LONG _System SetFontContext(HFC hfc, PCONTEXTINFO pci); +LONG _System CloseFontContext(HFC hfc); +LONG _System QueryFaceAttr(HFC hfc, ULONG iQuery, PBYTE pBuffer, + ULONG cb, PGLYPH pagi, GLYPH giStart); +LONG _System QueryCharAttr(HFC hfc, PCHARATTR pCharAttr, + PBITMAPMETRICS pbmm); +LONG _System QueryFullFaces(HFF hff, PVOID pBuff, PULONG buflen, + PULONG cFontCount, ULONG cStart); + +FDDISPATCH fdisp = { /* Font driver dispatch table */ + LoadFontFile, + QueryFaces, + UnloadFontFile, + OpenFontContext, + SetFontContext, + CloseFontContext, + QueryFaceAttr, + QueryCharAttr, + NULL, /* this one is no more used, only the spec fails to mention it */ + ConvertFontFile, + QueryFullFaces +}; + + + +/****************************************************************************/ +/* the single exported entry point; this way is faster than exporting every */ +/* single function and a bit more flexible */ +/* */ +#pragma export (fdhdr, "FONT_DRIVER_DISPATCH_TABLE", 1) +FDHEADER fdhdr = +{ /* Font driver Header */ + sizeof(FDHEADER), + "OS/2 FONT DRIVER", /* do not change */ + "TrueType (Using FreeType Engine)", /* description up to 40 chars */ + IFI_VERSION20, /* version */ + 0, /* reserved */ + &fdisp +}; + + +/****************************************************************************/ +/* some debug macros and functions. the debug version logs system requests */ +/* to the file C:\FTIFI.LOG */ +/* */ +#ifdef DEBUG + HFILE LogHandle = NULLHANDLE; + ULONG Written = 0; + char log[2048] = ""; + char buf[2048] = ""; + + +char* itoa10( int i, char* buffer ) { + char* ptr = buffer; + char* rptr = buffer; + char digit; + + if (i == 0) { + buffer[0] = '0'; + buffer[1] = 0; + return buffer; + } + + if (i < 0) { + *ptr = '-'; + ptr++; rptr++; + i = -i; + } + + while (i != 0) { + *ptr = (char) (i % 10 + '0'); + ptr++; + i /= 10; + } + + *ptr = 0; ptr--; + + while (ptr > rptr) { + digit = *ptr; + *ptr = *rptr; + *rptr = digit; + ptr--; + rptr++; + } + + return buffer; +} + + #define COPY(s) strcpy(log, s) + #define CAT(s) strcat(log, s) + #define CATI(v) strcat(log, itoa10( (int)v, buf )) + #define WRITE DosWrite(LogHandle, log, strlen(log), &Written) + + #define ERET1(label) { COPY("Error at "); \ + CATI(__LINE__); \ + CAT("\r\n"); \ + WRITE; \ + goto label; \ + } + + #define ERRRET(e) { COPY("Error at "); \ + CATI(__LINE__); \ + CAT("\r\n"); \ + WRITE; \ + return(e); \ + } + + +#else + + #define COPY(s) + #define CAT(s) + #define CATI(v) + #define WRITE + + #define ERET1(label) goto label; + + #define ERRRET(e) return(e); + +#endif /* DEBUG */ + + +/****************************************************************************/ +/* */ +/* 'engine' : */ +/* */ +/* The FreeType engine instance. Although this is a DLL, it isn't */ +/* supposed to be shared by apps, as it is only called by the OS/2 GRE. */ +/* This means that there is no need to bother with reentrancy/thread */ +/* safety, which aren't supported by FreeType 1.0 anyway. */ +/* */ +TT_Engine engine; + +/****************************************************************************/ +/* */ +/* TList and TListElement : */ +/* */ +/* simple structures used to implement a doubly linked list. Lists are */ +/* used to implement the HFF object lists, as well as the font size and */ +/* outline caches. */ +/* */ + +typedef struct _TListElement TListElement, *PListElement; + +struct _TListElement +{ + PListElement next; /* next element in list - NULL if tail */ + PListElement prev; /* previous element in list - NULL if head */ + long key; /* value used for searches */ + void* data; /* pointer to the listed/cached object */ +}; + +typedef struct _TList TList, *PList; +struct _TList +{ + PListElement head; /* first element in list - NULL if empty */ + PListElement tail; /* last element in list - NULL if empty */ + int count; /* number of elements in list */ +}; + +static PListElement free_elements = 0; + +#if 0 +/****************************************************************************/ +/* */ +/* TGlyph_Image : */ +/* */ +/* structure used to store a glyph's attributes, i.e. outlines and metrics */ +/* Note that we do not cache bitmaps ourselves for the moment. */ +/* */ +typedef struct _TGlyph_Image TGlyph_Image, *PGlyph_Image; + +struct _TGlyph_Image +{ + PListElement element; /* list element for this glyph image */ + TT_Glyph_Metrics metrics; + TT_Outline outline; +}; +#endif + + +/****************************************************************************/ +/* */ +/* TFontFace : */ +/* */ +/* a structure related to an open font face. It contains data for each of */ +/* possibly several faces in a .TTC file. */ + +typedef struct _TFontFace TFontFace, *PFontFace; + +struct _TFontFace +{ + TT_Face face; /* handle to actual FreeType face object */ + TT_Glyph glyph; /* handle to FreeType glyph container */ + TT_CharMap charMap; /* handle to FreeType character map */ + TT_Kerning directory; /* kerning directory */ + USHORT *widths; /* glyph width cache for large fonts */ + USHORT *kernIndices; /* reverse translation cache for kerning */ + LONG em_size; /* points per em square */ + ULONG flags; /* various FC_* flags (like FC_FLAG_FIXED)*/ +#if 0 /* not now */ + TList sizes; /* list of live child font sizes */ +#endif + LONG charMode; /* character translation mode : */ + /* 0 = Unicode to UGL */ + /* 1 = Symbol (no translation) */ + /* 2 = Unicode w/o translation */ +}; + + +/****************************************************************************/ +/* */ +/* TFontFile : */ +/* */ +/* a structure related to an open font file handle. All TFontFiles are */ +/* kept in a simple linked list. There can be several faces in one font. */ +/* Face(s) information is stored in a variable-length array of TFontFaces. */ +/* A single TFontFile structure exactly corresponds to one HFF. */ + +typedef struct _TFontFile TFontFile, *PFontFile; + +struct _TFontFile +{ + PListElement element; /* list element for this font face */ + HFF hff; /* HFF handle used from outside */ + CHAR filename[260]; /* font file name */ + LONG ref_count; /* number of times this font file is open */ + ULONG flags; /* various FL_* flags */ + ULONG numFaces; /* number of faces in a file (normally 1) */ + TFontFace *faces; /* array of FontFace structures */ +}; + + +/* Flag : The font face has a fixed pitch width */ +#define FC_FLAG_FIXED_WIDTH 1 + +/* Flag : Effectively duplicated FL_FLAG_DBCS_FILE. This info is */ +/* kept twice for simplified access */ +#define FC_FLAG_DBCS_FACE 2 + +/* Flag : This face is an alias */ +#define FL_FLAG_FAKE_ROMAN 8 + +/* Flag : The font file has a live FreeType face object */ +#define FL_FLAG_LIVE_FACE 16 + +/* Flag : A font file's face has a context open - DON'T CLOSE IT! */ +#define FL_FLAG_CONTEXT_OPEN 32 + +/* Flag : This file has been already opened previously*/ +#define FL_FLAG_ALREADY_USED 64 + +/* Flag : This is a font including DBCS characters; this also means */ +/* the font driver presents to the system a second, vertically */ +/* rendered, version of this typeface with name prepended by */ +/* an '@' (used in horizontal-only word processors) */ +/* Note : For TTCs, the whole collection is either DBCS or not. I've */ +/* no idea if there are any TTCs with both DBCS and non-DBCS */ +/* faces. It's possible, but sounds unlikely. */ +#define FL_FLAG_DBCS_FILE 128 + +/* Note, we'll only keep the first max_open_files files with opened */ +/* FreeType objects/instances.. */ +int max_open_files = 10; + +/* number of processes using the font driver; used by the init/term */ +/* routine */ +ULONG ulProcessCount = 0; + +/* the list of live faces */ +static TList liveFiles = { NULL, NULL, 0 }; + +/* the list of sleeping faces */ +static TList idleFiles = { NULL, NULL, 0 }; + +/****************************************************************************/ +/* */ +/* TFontSize : */ +/* */ +/* a structure related to a opened font context (a.k.a. instance or */ +/* transform/pointsize). It exactly corresponds to a HFC. */ +/* */ + +typedef struct _TFontSize TFontSize, *PFontSize; + +struct _TFontSize +{ + PListElement element; /* List element for this font size */ + HFC hfc; /* HFC handle used from outside */ + TT_Instance instance; /* handle to FreeType instance */ + BOOL transformed; /* TRUE = rotation/shearing used (rare) */ + BOOL vertical; /* TRUE = vertically rendered DBCS face */ + TT_Matrix matrix; /* transformation matrix */ + PFontFile file; /* HFF this context belongs to */ + ULONG faceIndex; /* index of face in a font (for TTCs) */ +/* TList outlines;*/ /* outlines cache list */ +}; + +/****************************************************************************/ +/* array of font context handles. Note that there isn't more than one font */ +/* context open at any time anyway, but we want to be safe.. */ +/* */ +#define MAX_CONTEXTS 5 + +static TFontSize contexts[MAX_CONTEXTS]; /* this is rather too much */ + + +/****************************************************************************/ +/* few globals used for NLS */ +/* */ +/* Note: most of the internationalization (I18N) code was kindly provided */ +/* by Ken Borgendale and Marc L Cohen from IBM (big thanks!). I also */ +/* received help from Tetsuro Nishimura from IBM Japan. */ +/* I was also unable to test the I18N code on actual Japanese, Chinese... */ +/* etc. systems. But it might work. */ +/* */ + +static ULONG ScriptTag = -1; +static ULONG LangSysTag = -1; +static ULONG iLangId = TT_MS_LANGID_ENGLISH_UNITED_STATES; /* language ID */ +static ULONG uLastGlyph = 255; /* last glyph for language */ +static PSZ pGlyphlistName = "SYMBOL"; /* PM383, PMJPN, PMKOR.... */ +static BOOL isGBK = TRUE; /* only used for Chinese */ +static ULONG ulCp[2] = {1}; /* codepages used */ +static UCHAR DBCSLead[12]; /* DBCS lead byte table */ + +/* rather simple-minded test to decide if given glyph index is a 'halfchar',*/ +/* i.e. Latin character in a DBCS font which is _not_ to be rotated */ +#define is_HALFCHAR(_x) ((_x) < 0x0400) + + +/****************************************************************************/ +/* */ +/* interfaceSEId: */ +/* */ +/* interfaceSEId (Interface-specific Encoding Id) determines what encoding */ +/* the font driver should use if a font includes a Unicode encoding. */ +/* */ +LONG interfaceSEId(TT_Face face, BOOL UDCflag, LONG encoding); + +/****************************************************************************/ +/* */ +/* LookUpName : */ +/* */ +/* this function tries to find M$ English name for a face */ +/* length is limited to FACESIZE (defined by OS/2); returns NULL if */ +/* unsuccessful. warning: the string gets overwritten on the next */ +/* invocation */ +/* */ +/* TODO: needs enhancing for I18N */ +static char* LookupName(TT_Face face, int index ); + + +/****************************************************************************/ +/* */ +/* GetCharMap : */ +/* */ +/* get suitable charmap from font */ +/* */ +static ULONG GetCharmap(TT_Face face); + + +/****************************************************************************/ +/* */ +/* GetOutlineLen : */ +/* */ +/* get # of bytes needed for glyph outline */ +/* */ +static int GetOutlineLen(TT_Outline *ol); + + +/****************************************************************************/ +/* */ +/* GetOutline : */ +/* */ +/* get glyph outline in PM format */ +/* */ +static int GetOutline(TT_Outline *ol, PBYTE pb); + + + +/****************************************************************************/ +/* */ +/* IsDBCSChar : */ +/* */ +/* Returns TRUE if character is first byte of a DBCS char, FALSE otherwise */ +/* */ +BOOL IsDBCSChar(UCHAR c) +{ + ULONG i; + + for (i = 0; DBCSLead[i] && DBCSLead[i+1]; i += 2) + if ((c >= DBCSLead[i]) && (c <= DBCSLead[i+1])) + return TRUE; + return FALSE; +} + + +/****************************************************************************/ +/* */ +/* TT_Alloc & TT_Free : */ +/* */ +/* The following two functions are declared here because including */ +/* the entire ttmemory.h creates more problems than it solves */ +/* */ +TT_Error TT_Alloc( long Size, void** P ); +TT_Error TT_Free( void** P ); +TT_Error TTMemory_Init(void); + +static TT_Error error; + +#define ALLOC( p, size ) TT_Alloc( (size), (void**)&(p) ) +#define FREE( p ) TT_Free( (void**)&(p) ) + +/****************************************************************************/ +/* */ +/* New_Element : */ +/* */ +/* return a fresh list element. Either new or recycled. */ +/* returns NULL if out of memory. */ +/* */ +static PListElement New_Element( void ) +{ + PListElement e = free_elements; + + if (e) + free_elements = e->next; + else + { + if ( ALLOC( e, sizeof(TListElement) ) ) + return NULL; + } + e->next = e->prev = e->data = NULL; + e->key = 0; + + return e; +} + +/****************************************************************************/ +/* */ +/* Done_Element : */ +/* */ +/* recycles an old list element */ +/* */ +static void Done_Element( PListElement element ) +{ + element->next = free_elements; + free_elements = element; +} + +/****************************************************************************/ +/* */ +/* List_Insert : */ +/* */ +/* inserts a new object at the head of a given list */ +/* returns 0 in case of success, -1 otherwise. */ +/* */ +static int List_Insert( PList list, PListElement element ) +{ + if (!list || !element) + return -1; + + element->next = list->head; + + if (list->head) + list->head->prev = element; + + element->prev = NULL; + list->head = element; + + if (!list->tail) + list->tail = element; + + list->count++; + return 0; +} + +/****************************************************************************/ +/* */ +/* List_Remove : */ +/* */ +/* removes an element from its list. Returns 0 in case of success, */ +/* -1 otherwise. WARNING : this function doesn't check that the */ +/* element is part of the list. */ +/* */ +static int List_Remove( PList list, PListElement element ) +{ + if (!element) + return -1; + + if (element->prev) + element->prev->next = element->next; + else + list->head = element->next; + + if (element->next) + element->next->prev = element->prev; + else + list->tail = element->prev; + + element->next = element->prev = NULL; + list->count --; + return 0; +} + +/****************************************************************************/ +/* */ +/* List_Find : */ +/* */ +/* Look for a given object with a specified key. Returns NULL if the */ +/* list is empty, or the object wasn't found. */ +/* */ +static PListElement List_Find( PList list, long key ) +{ + static PListElement cur; + + for ( cur=list->head; cur; cur = cur->next ) + if ( cur->key == key ) + return cur; + + /* not found */ + return NULL; +} + +/****************************************************************************/ +/* */ +/* Sleep_FontFile : */ +/* */ +/* closes a font file's FreeType objects to leave room in memory. */ +/* */ +static int Sleep_FontFile( PFontFile cur_file ) +{ + int i; + + if (!(cur_file->flags & FL_FLAG_LIVE_FACE)) + ERRRET(-1); /* already asleep */ + + /* is this face in use? */ + if (cur_file->flags & FL_FLAG_CONTEXT_OPEN) { + /* move face to top of the list */ + if (List_Remove( &liveFiles, cur_file->element )) + ERRRET(-1); + if (List_Insert( &liveFiles, cur_file->element )) + ERRRET(-1); + + cur_file = (PFontFile)(liveFiles.tail->data); + } + + /* remove the face from the live list */ + if (List_Remove( &liveFiles, cur_file->element )) + ERRRET(-1); + + /* add it to the sleep list */ + if (List_Insert( &idleFiles, cur_file->element )) + ERRRET(-1); + + /* deactivate its objects - we ignore errors there */ + for (i = 0; i < cur_file->numFaces; i++) { + TT_Done_Glyph( cur_file->faces[i].glyph ); + TT_Close_Face( cur_file->faces[i].face ); + } + cur_file->flags &= ~FL_FLAG_LIVE_FACE; + + return 0; +} + +/****************************************************************************/ +/* */ +/* Wake_FontFile : */ +/* */ +/* awakes a font file, and reloads important data from disk. */ +/* */ +static int Wake_FontFile( PFontFile cur_file ) +{ + static TT_Face face; + static TT_Glyph glyph; + static TT_CharMap cmap; + static TT_Face_Properties props; + static PFontFace cur_face; + ULONG encoding, i; + + if (cur_file->flags & FL_FLAG_LIVE_FACE) + ERRRET(-1); /* already awoken !! */ + + /* OK, try to activate the FreeType objects */ + error = TT_Open_Face(engine, cur_file->filename, &face); + if (error) + { + COPY( "Error while opening " ); CAT( cur_file->filename ); + CAT( ", error code = " ); CATI( error ); CAT( "\r\n" ); WRITE; + return -1; /* error, can't open file */ + /* XXX : should set error condition here! */ + } + + /* Create a glyph container for it */ + error = TT_New_Glyph( face, &glyph ); + if (error) + { + COPY( "Error while creating container for " ); CAT( cur_file->filename ); + CAT( ", error code = " ); CATI( error ); CAT( "\r\n" ); WRITE; + goto Fail_Face; + } + + /* now get suitable charmap for this font */ + encoding = GetCharmap(face); + error = TT_Get_CharMap(face, encoding & 0xFFFF, &cmap); + if (error) + { + COPY( "Error: No char map in " ); CAT( cur_file->filename ); + CAT( "\r\n" ); WRITE; + goto Fail_Glyph; + } + + /* Get face properties. Necessary to find out number of fonts for TTCs */ + TT_Get_Face_Properties(face, &props); + + /* all right, now remove the face from the sleep list */ + if (List_Remove( &idleFiles, cur_file->element )) + ERET1( Fail_Glyph ); + + /* add it to the live list */ + if (List_Insert( &liveFiles, cur_file->element )) + ERET1( Fail_Glyph ); + + /* If the file is a TTC, the first face is now opened successfully. */ + + cur_file->numFaces = props.num_Faces; + + /* Now allocate memory for face data (one struct for each face in TTC). */ + if (cur_file->faces == NULL) { + if (ALLOC(cur_face, sizeof(TFontFace) * cur_file->numFaces)) + ERET1( Fail_Glyph ); + + cur_file->faces = cur_face; + } + else + cur_face = cur_file->faces; + + cur_face->face = face; /* possibly first face in a TTC */ + cur_face->glyph = glyph; + cur_face->charMap = cmap; + cur_file->flags |= FL_FLAG_LIVE_FACE; + + + if (!(cur_file->flags & FL_FLAG_ALREADY_USED)) { + cur_face->charMode = encoding >> 16; /* Unicode, Symbol, ... */ + cur_face->em_size = props.header->Units_Per_EM; + + /* if a face contains over 1024 glyphs, assume it's a DBCS font - */ + /* VERY probable */ + TT_Get_Face_Properties(cur_face->face, &props); + + if (props.num_Glyphs > 1024) { + cur_file->flags |= FL_FLAG_DBCS_FILE; + cur_face->flags |= FC_FLAG_DBCS_FACE; + } + + cur_face->widths = NULL; + cur_face->kernIndices = NULL; + } + /* load kerning directory, if any */ + error = TT_Get_Kerning_Directory(face, &(cur_face->directory)); + if (error) + cur_face->directory.nTables = 0; /* indicates no kerning in font */ + + TT_Flush_Face(face); /* this is important ! */ + + /* open remaining faces if this font is a TTC */ + for (i = 1; i < cur_file->numFaces; i++) { + error = TT_Open_Collection(engine, cur_file->filename, + i, &face); + if (error) + return -1; /* TODO: handle bad TTCs more tolerantly */ + + error = TT_New_Glyph( face, &glyph ); + if (error) + ERET1(Fail_Face); + + encoding = GetCharmap(face); + error = TT_Get_CharMap(face, encoding & 0xFFFF, &cmap); + if (error) + ERET1(Fail_Glyph); + + cur_face = &(cur_file->faces[i]); + + cur_face->face = face; + cur_face->glyph = glyph; + cur_face->charMap = cmap; + + if (!(cur_file->flags & FL_FLAG_ALREADY_USED)) { + cur_face->em_size = props.header->Units_Per_EM; + cur_face->charMode = encoding >> 16; /* 0 - Unicode; 1 - Symbol */ + + if (cur_file->flags & FL_FLAG_DBCS_FILE) + cur_face->flags |= FC_FLAG_DBCS_FACE; + + cur_face->widths = NULL; + cur_face->kernIndices = NULL; + } + + /* load kerning directory, if any */ + error = TT_Get_Kerning_Directory(face, &(cur_face->directory)); + if (error) + cur_face->directory.nTables = 0; /* indicates no kerning in font */ + } + + cur_file->flags |= FL_FLAG_ALREADY_USED; /* indicates some fields need no re-init */ + + error = TT_Flush_Face(face); /* this is important ! */ + if (error) { + COPY("Error flushing face\r\n"); WRITE; + } + + return 0; /* everything is in order, return 0 == success */ + +Fail_Glyph: + /* This line isn't really necessary, because the glyph container */ + /* would be destroyed by the following TT_Close_Face anyway. We */ + /* however use it for the sake of orthodoxy */ + TT_Done_Glyph( glyph ); + +Fail_Face: + TT_Close_Face(face); + + /* note that in case of error (e.g. out of memory), the face stays */ + /* on the sleeping list */ + return -1; +} + +/****************************************************************************/ +/* */ +/* Done_FontFile : */ +/* */ +/* destroys a given font file object. This will also destroy all of its */ +/* live child font sizes (which in turn will destroy the glyph caches). */ +/* This is done for all faces if the file is a collection. */ +/* */ +/* WARNING : The font face must be removed from its list by the caller */ +/* before this function is called. */ +/* */ +static void Done_FontFile( PFontFile *file ) +{ + static PListElement element; + static PListElement next; + ULONG i; + +#if 0 /* this part isn't really used and maybe it never will */ + /* destroy its font sizes */ + element = (*face)->sizes.head; + while (element) + { + next = element->next; + /* XXX : right now, we simply free the font size object, */ + /* because the instance is destroyed automatically */ + /* by FreeType. */ + + FREE( element->data ); + /* Done_FontSize( (PFontSize)element->data ); - later */ + + Done_Element( element ); + element = next; + } +#endif + + /* now discard the font face itself */ + if ((*file)->flags & FL_FLAG_LIVE_FACE) + { + for (i = 0; i < (*file)->numFaces; i++) { + TT_Done_Glyph( (*file)->faces[i].glyph ); + TT_Close_Face( (*file)->faces[i].face ); + + if ((*file)->faces[i].widths) + FREE((*file)->faces[i].widths); + if ((*file)->faces[i].kernIndices) + FREE((*file)->faces[i].kernIndices); + } + } + + FREE( (*file)->faces ); + FREE( *file ); +} + + +/****************************************************************************/ +/* */ +/* New_FontFile : */ +/* */ +/* return the address of the TFontFile corresponding to a given */ +/* HFF. Note that in our implementation, we could simply to a */ +/* typecast like '(PFontFile)hff'. However, for safety reasons, we */ +/* look up the handle in the list. */ +/* */ +static PFontFile New_FontFile( char* file_name ) +{ + static PListElement element; + static PFontFile cur_file; + static TT_CharMap cmap; + + /* first, check if it's already open - in the live list */ + for ( element = liveFiles.head; element; element = element->next ) + { + cur_file = (PFontFile)element->data; + if (strcmp( cur_file->filename, file_name ) == 0) + goto Exit_Same; + } + + /* check in the idle list */ + for ( element = idleFiles.head; element; element = element->next ) + { + cur_file = (PFontFile)element->data; + if (strcmp( cur_file->filename, file_name ) == 0) + goto Exit_Same; + } + + /* OK, this file isn't opened yet. Create a new font face object */ + /* then try to wake it up. This will fail if the file can't be found */ + /* or if we lack memory.. */ + + element = New_Element(); + if (!element) + ERRRET(NULL); + + if ( ALLOC( cur_file, sizeof(TFontFile) ) ) + ERET1( Fail_Element ); + + element->data = cur_file; + element->key = (long)cur_file; /* use the HFF as cur key */ + + cur_file->element = element; + cur_file->ref_count = 1; + cur_file->hff = (HFF)cur_file; + strcpy( cur_file->filename, file_name); + cur_file->flags = 0; + cur_file->faces = NULL; +#if 0 /* not used */ + cur_face->sizes.head = NULL; + cur_face->sizes.tail = NULL; + cur_face->sizes.count= 0; +#endif + + /* add new font face to sleep list */ + if (List_Insert( &idleFiles, element )) + ERET1( Fail_File ); + + /* Make enough room in the live list */ + if ( liveFiles.count >= max_open_files) + { + COPY( "rolling...\n" ); WRITE; + if (Sleep_FontFile( (PFontFile)(liveFiles.tail->data) )) + ERET1( Fail_File ); + } + + /* wake new font file */ + if ( Wake_FontFile( cur_file ) ) + { + COPY( "could not open/wake " ); CAT( file_name ); CAT( "\r\n" ); WRITE; + if (List_Remove( &idleFiles, element )) + ERET1( Fail_File ); + + ERET1( Fail_File ); + } + + return cur_file; /* everything is in order */ + +Fail_File: + FREE( cur_file ); + +Fail_Element: + Done_Element( element ); + return NULL; + +Exit_Same: + cur_file->ref_count++; /* increment reference count */ + + COPY( " -> (duplicate) hff = " ); CATI( cur_file->hff ); + CAT( "\r\n" ); WRITE; + + return cur_file; /* no sense going on */ +} + +/****************************************************************************/ +/* */ +/* getFontFile : */ +/* */ +/* return the address of the TFontFile corresponding to a given */ +/* HFF. If asleep, the file and its face object(s) is awoken. */ +/* */ +PFontFile getFontFile( HFF hff ) +{ + static PListElement element; + + /* look in the live list first */ + element = List_Find( &liveFiles, (long)hff ); + if (element) + { + /* move it to the front of the live list - if it isn't already */ + if ( liveFiles.head != element ) + { + if ( List_Remove( &liveFiles, element ) ) + ERRRET( NULL ); + + if ( List_Insert( &liveFiles, element ) ) + ERRRET( NULL ); + } + return (PFontFile)(element->data); + } + + /* the file may be asleep, look in the second list */ + element = List_Find( &idleFiles, (long)hff ); + if (element) + { + /* we need to awake the font, but before that, we must be sure */ + /* that there is enough room in the live list */ + if ( liveFiles.count >= max_open_files ) + if (Sleep_FontFile( (PFontFile)(liveFiles.tail->data) )) + ERRRET( NULL ); + + if ( Wake_FontFile( (PFontFile)(element->data) ) ) + ERRRET( NULL ); + + COPY ( "hff " ); CATI( hff ); CAT( " awoken\n" ); WRITE; + return (PFontFile)(element->data); + } + + COPY( "Could not find hff " ); CATI( hff ); CAT( " in lists\n" ); WRITE; + +#ifdef DEBUG + + /* dump files lists */ + COPY( "Live files : " ); CATI( liveFiles.count ); CAT( "\r\n" ); WRITE; + + for (element = liveFiles.head; element; element = element->next) + { + COPY( ((PFontFile)(element->data))->filename ); CAT("\r\n");WRITE; + } + + COPY( "Idle files : " ); CATI( idleFiles.count ); CAT( "\r\n" ); WRITE; + for (element = idleFiles.head; element; element = element->next) + { + COPY( ((PFontFile)(element->data))->filename ); CAT("\r\n");WRITE; + } +#endif + + /* could not find the HFF in the list */ + return NULL; +} + + +/****************************************************************************/ +/* */ +/* getFontSize : */ +/* */ +/* return pointer to a TFontSize given a HFC handle, NULL if error */ +/* */ +static PFontSize getFontSize( HFC hfc ) +{ + int i; + for ( i = 0; i < MAX_CONTEXTS; i++ ) + if ( contexts[i].hfc == hfc ) { + return &contexts[i]; + } + + return NULL; +} + +#ifdef USE_UCONV + +/* maximum number of cached UCONV objects */ +#define MAX_UCONV_CACHE 10 + +/* UCONV object used for conversion from UGL to Unicode */ +#define UCONV_TYPE_UGL 1 + +/* UCONV objects used for conversion from local DBCS codepage to Unicode */ +#define UCONV_TYPE_BIG5 2 +#define UCONV_TYPE_SJIS 4 + +/* UCONV objects cache entry */ +typedef struct _UCACHEENTRY { + UconvObject object; /* actual UCONV object */ + PID pid; /* process ID the object is valid for */ + ULONG type; /* type of UCONV object (UGL or DBCS) */ +} UCACHEENTRY, *PUCACHEENTRY; + +/* UCONV globals */ +static UCACHEENTRY UconvCache[MAX_UCONV_CACHE]; /* 10 should do it */ +static int slotsUsed = 0; /* number of cache slots used */ + +/****************************************************************************/ +/* */ +/* getUconvObject : */ +/* */ +/* a function to cache UCONV objects based on current process. The only */ +/* problem is that FT/2 currently doesn't keep track of processes and */ +/* consequently the objects aren't freed when a process ends. But UCONV */ +/* frees the objects itself anyway. */ +int getUconvObject(UniChar *name, UconvObject *ConvObj, ULONG UconvType) { + PPIB ppib; /* process/thread info blocks */ + PTIB ptib; + PID curPid; /* current process ID */ + int i; + + /* query current process ID */ + if (DosGetInfoBlocks(&ptib, &ppib)) + return -1; + + curPid = ppib->pib_ulpid; + + if (slotsUsed == 0) { /* initialize cache */ + if (UniCreateUconvObject(name, ConvObj) != ULS_SUCCESS) + return -1; + UconvCache[0].object = *ConvObj; + UconvCache[0].pid = curPid; + UconvCache[0].type = UconvType; + + for (i = 1; i < MAX_UCONV_CACHE; i++) { + UconvCache[i].object = NULL; + UconvCache[i].pid = 0; + } + slotsUsed = 1; + return 0; + } + + /* search cache for available conversion object */ + i = 0; + while ((UconvCache[i].pid != curPid || UconvCache[i].type != UconvType) + && i < slotsUsed) + i++; + + if (i < slotsUsed) { /* entry found in cache */ + *ConvObj = UconvCache[i].object; + return 0; + } + + /* if cache is full, remove first entry and shift the others 'down' */ + if (slotsUsed == MAX_UCONV_CACHE) { + UniFreeUconvObject(UconvCache[0].object); + for (i = 1; i < MAX_UCONV_CACHE; i++) { + UconvCache[i - 1].object = UconvCache[i].object; + UconvCache[i - 1].pid = UconvCache[i].pid; + UconvCache[i - 1].type = UconvCache[i].type; + } + } + + if (UniCreateUconvObject(name, ConvObj) != ULS_SUCCESS) + return -1; + + if (slotsUsed < MAX_UCONV_CACHE) + slotsUsed++; + + UconvCache[slotsUsed - 1].object = *ConvObj; + UconvCache[slotsUsed - 1].pid = curPid; + UconvCache[slotsUsed - 1].type = UconvType; + + return 0; +} + +/****************************************************************************/ +/* */ +/* CleanUCONVCache : */ +/* */ +/* When process is terminated, removes this process' entries in the UCONV */ +/* object cache. Errors are disregarded at this point. */ +void CleanUCONVCache(void) { + PPIB ppib; /* process/thread info blocks */ + PTIB ptib; + PID curPid; /* current process ID */ + int i = 0, j; + + /* query current process ID */ + if (DosGetInfoBlocks(&ptib, &ppib)) + return; + + curPid = ppib->pib_ulpid; + + while (i < slotsUsed) { + /* if PID matches, remove the entry and shift the others 'down' (or up?) */ + if (UconvCache[i].pid == curPid) { + UniFreeUconvObject(UconvCache[i].object); + for (j = i + 1; j < slotsUsed; j++) { + UconvCache[j - 1].object = UconvCache[j].object; + UconvCache[j - 1].pid = UconvCache[j].pid; + UconvCache[j - 1].type = UconvCache[j].type; + } + slotsUsed--; + } + i++; + } +} +#endif /* USE_UCONV */ + +/****************************************************************************/ +/* */ +/* PM2TT : */ +/* */ +/* a function to convert PM codepoint to TT glyph index. This is the real */ +/* tricky part. */ +/* mode = TRANSLATE_UGL - translate UGL to Unicode */ +/* mode = TRANSLATE_SYMBOL - no translation - symbol font */ +/* mode = TRANSLATE_UNICODE- no translation - Unicode */ +static int PM2TT( TT_CharMap charMap, + ULONG mode, + int index) +{ +#ifdef USE_UCONV + /* Brand new version that uses UCONV.DLL. This should make FreeType/2 */ + /* smaller and at the same time more flexible as it now should use */ + /* the Unicode translation tables supplied with base OS/2 Warp 4. */ + /* Unfortunately there's a complication (again) since UCONV objects */ + /* created in one process can't be used in another. Therefore we */ + /* keep a small cache of recently used UCONV objects. */ + static UconvObject UGLObj = NULL; /* UGL->Unicode conversion object */ + static BOOL UconvSet = FALSE; + char char_data[2], *pin_char_str; + size_t in_bytes_left, uni_chars_left, num_subs; + UniChar *pout_uni_str, uni_buffer[4]; + int rc; + static UniChar uglName[10] = L"OS2UGL"; + static UniChar uglNameBig5[10] = L"IBM-950"; + static UniChar uglNameSJIS[10] = L"IBM-943"; + + switch (mode) { + case TRANSLATE_UGL: + if (UconvSet == FALSE) { + switch (iLangId) { /* select proper conversion table */ + case TT_MS_LANGID_GREEK_GREECE: + strncpy((char*)uglName, (char*)L"OS2UGLG", 16); + break; + case TT_MS_LANGID_HEBREW_ISRAEL: + strncpy((char*)uglName, (char*)L"OS2UGLH", 16); + break; + case TT_MS_LANGID_ARABIC_SAUDI_ARABIA: + strncpy((char*)uglName, (char*)L"OS2UGLA", 16); + break; + } + UconvSet = TRUE; + } + + /* get Uconv object - either new or cached */ + if (getUconvObject(uglName, &UGLObj, UCONV_TYPE_UGL) != 0) + return 0; + + if (index > MAX_GLYPH) + return 0; + + char_data[0] = index; + char_data[1] = index >> 8; + + pout_uni_str = uni_buffer; + pin_char_str = char_data; + in_bytes_left = 2; + uni_chars_left = 1; + + rc = UniUconvToUcs(UGLObj, (void**)&pin_char_str, &in_bytes_left, + &pout_uni_str, &uni_chars_left, + &num_subs); + if (rc != ULS_SUCCESS) + return 0; + else + return TT_Char_Index(charMap, ((unsigned short*)uni_buffer)[0]); + + case TRANSLATE_SYMBOL: + case TRANSLATE_UNICODE: + case TRANSLATE_BIG5: + case TRANSLATE_SJIS: + return TT_Char_Index(charMap, index); + + case TRANSLATE_UNI_BIG5: + case TRANSLATE_UNI_SJIS: + + /* get Uconv object - either new or cached */ + switch (mode) { + /* get proper conversion object */ + case TRANSLATE_UNI_BIG5: + if (getUconvObject(uglNameBig5, &UGLObj, UCONV_TYPE_BIG5) != 0) + return 0; + break; + + case TRANSLATE_UNI_SJIS: + if (getUconvObject(uglNameSJIS, &UGLObj, UCONV_TYPE_SJIS) != 0) + return 0; + break; + } + + /* Note the bytes are swapped here for double byte chars! */ + if (index & 0xFF00) { + char_data[0] = (index & 0xFF00) >> 8; + char_data[1] = index & 0x00FF; + } + else { + char_data[0] = index; + char_data[1] = 0; + } + + pout_uni_str = uni_buffer; + pin_char_str = char_data; + in_bytes_left = 2; + uni_chars_left = 2; + + rc = UniUconvToUcs(UGLObj, (void**)&pin_char_str, &in_bytes_left, + &pout_uni_str, &uni_chars_left, + &num_subs); + if (rc != ULS_SUCCESS) + return 0; + else + return TT_Char_Index(charMap, ((unsigned short*)uni_buffer)[0]); + + default: + return 0; + } +#else + switch (mode) + { + /* convert from PM383 to Unicode */ + case TRANSLATE_UGL: + /* TODO: Hebrew and Arabic UGL */ + if (iLangId == TT_MS_LANGID_GREEK_GREECE) /* use Greek UGL */ + if ((index >= GREEK_START) && (index < GREEK_START + GREEK_GLYPHS)) + return TT_Char_Index(charMap, SubUGLGreek[index - GREEK_START]); + + if (index <= MAX_GLYPH) + return TT_Char_Index(charMap, UGL2Uni[index]); + else + ERRRET(0); + + case TRANSLATE_SYMBOL : + case TRANSLATE_UNICODE: + case TRANSLATE_BIG5: + case TRANSLATE_SJIS: + return TT_Char_Index(charMap, index); + + default: + return 0; + } +#endif +} + +/****************************************************************************/ +/* */ +/* mystricmp : */ +/* */ +/* A simple function for comparing strings without case sensitivity. Just */ +/* returns zero if strings match, one otherwise. I wrote this because */ +/* stricmp is not available in the subsystem run-time library (probably */ +/* because it uses locales). toupper() is unfortunately unavailable too. */ +/* */ + +#define toupper( c ) ( ((c) >= 'a') && ((c) <= 'z') ? (c) - 'a' + 'A' : (c) ) + +static +int mystricmp(const char *s1, const char *s2) { + int i = 0; + int match = 0; + int len = strlen(s1); + + if (len != strlen(s2)) + return 1; /* no match */ + + while (i < len) { + if (toupper(s1[i]) != toupper(s2[i])) { + match = 1; + break; + } + i++; + } + return match; +} + +/* DBCS enabled strrchr (only looks for SBCS chars though) */ +static +char *mystrrchr(char *s, char c) { + int i = 0; + int lastfound = -1; + int len = strlen(s); + + while (i <= len) { + if (IsDBCSChar(s[i])) { + i += 2; + continue; + } + if (s[i] == c) + lastfound = i; + i++; + } + if (lastfound == -1) + return NULL; + else + return s + lastfound; +} + +/* -------------------------------------------------------------------------*/ +/* here begin the exported functions */ +/* -------------------------------------------------------------------------*/ + +/****************************************************************************/ +/* */ +/* ConvertFontFile : */ +/* */ +/* Install/delete font file */ +/* */ +LONG _System ConvertFontFile( PSZ source, + PSZ dest_dir, + PSZ new_name ) +{ + PSZ source_name; + + COPY("ConvertFontFile: Src = "); CAT(source); + if (dest_dir) { + CAT(", DestDir = "); CAT(dest_dir); + } + CAT("\r\n"); WRITE; + + if (dest_dir && new_name) + { + /* install the font file */ + source_name = mystrrchr( source, '\\' ); /* find the last backslash */ + if (!source_name) + ERRRET(-1); + + source_name++; + strcpy( new_name, source_name ); + + /* check if file is to be copied onto itself */ + if (strncmp(source, dest_dir, strlen(dest_dir)) == 0) + return OK; /* do nothing */ + + if ( DosCopy( source, dest_dir, DCPY_EXISTING) ) /* overwrite file */ + ERRRET(-1); /* XXX : we should probably set the error condition */ + + COPY(" -> Name: "); CAT(new_name); CAT("\r\n"); WRITE; + } + else + { + COPY("Delete file "); CAT(source); CAT("\r\n"); WRITE; + DosDelete(source); /* fail quietly */ + } + + return OK; +} + +/****************************************************************************/ +/* */ +/* LoadFontFile : */ +/* */ +/* open a font file and return a handle for it */ +/* */ +HFF _System LoadFontFile( PSZ file_name ) +{ + PSZ extension; + PFontFile cur_file; + PListElement element; + + COPY( "LoadFontFile " ); CAT( file_name ); CAT( "\r\n" ); WRITE; + + /* first check if the file extension is supported */ + extension = mystrrchr( file_name, '.' ); /* find the last dot */ + if ( extension == NULL || + (mystricmp(extension, ".TTF") && + mystricmp(extension, ".TTC")) ) + return ((HFF)-1); + + /* now actually open the file */ + cur_file = New_FontFile( file_name ); + if (cur_file) + return cur_file->hff; + else + return (HFF)-1; +} + +/****************************************************************************/ +/* */ +/* UnloadFontFile : */ +/* */ +/* destroy resources associated with a given HFF */ +/* */ +LONG _System UnloadFontFile( HFF hff ) +{ + PListElement element; + + COPY("UnloadFontFile: hff = "); CATI((int) hff); CAT("\r\n"); WRITE; + + /* look in the live list first */ + for (element = liveFiles.head; element; element = element->next) + { + if (element->key == (long)hff) + { + PFontFile file = (PFontFile)element->data; + + if (--file->ref_count > 0) /* don't really close, return OK */ + return 0; + + List_Remove( &liveFiles, element ); + Done_Element( element ); + Done_FontFile( &file ); + return 0; + } + } + + /* now look in sleep list */ + for (element = idleFiles.head; element; element = element->next) + { + if (element->key == (long)hff) + { + PFontFile file = (PFontFile)element->data; + + if (--file->ref_count > 0) /* don't really close, return OK */ + return 0; + + List_Remove( &idleFiles, element ); + Done_Element( element ); + Done_FontFile( &file ); + return 0; + } + } + + /* didn't find the file */ + return -1; +} + +/****************************************************************************/ +/* */ +/* QueryFaces : */ +/* */ +/* Return font metrics. This routine has to do a lot of not very */ +/* hard work. */ +/* */ +LONG _System QueryFaces( HFF hff, + PIFIMETRICS pifiMetrics, + ULONG cMetricLen, + ULONG cFontCount, + ULONG cStart) +{ + static TT_Face_Properties properties; + static IFIMETRICS ifi; /* temporary structure */ + PFontFace pface; + TT_Header *phead; + TT_Horizontal_Header *phhea; + TT_OS2 *pOS2; + TT_Postscript *ppost; + PIFIMETRICS pifi2; + PFontFile file; + LONG index, faceIndex, ifiCount = 0; + char *name; + + COPY( "QueryFaces: hff = " ); CATI( hff ); + CAT( ", cFontCount = " ); CATI( cFontCount ); + CAT( ", cStart = " ); CATI( cStart ); + CAT( ", cMetricLen = " ); CATI( cMetricLen ); + CAT( "\r\n"); + WRITE; + + file = getFontFile(hff); + if (!file) + ERRRET(-1) /* error, invalid handle */ + + if (cMetricLen == 0) { /* only number of faces is requested */ + #ifdef FAKE_TNR + /* create an alias for Times New Roman */ + pface = &(file->faces[0]); + name = LookupName(pface->face, TT_NAME_ID_FONT_FAMILY); + if (!strcmp(name, "Times New Roman")) { + file->flags |= FL_FLAG_FAKE_ROMAN; + return 2; + } + #endif + if (file->flags & FL_FLAG_DBCS_FILE) + return file->numFaces * 2; + else + return file->numFaces; + } + + for (faceIndex = 0; faceIndex < file->numFaces; faceIndex++) { + /* get pointer to this face's data */ + pface = &(file->faces[faceIndex]); + + TT_Get_Face_Properties( pface->face, &properties ); + + pOS2 = properties.os2; + phead = properties.header; + phhea = properties.horizontal; + ppost = properties.postscript; + + /* get font name and check it's really found */ + name = LookupName(pface->face, TT_NAME_ID_FONT_FAMILY); + if (name == NULL) + ERET1(Fail); + + strncpy(ifi.szFamilyname, name, FACESIZE); + ifi.szFamilyname[FACESIZE - 1] = '\0'; + + name = LookupName(pface->face, TT_NAME_ID_FULL_NAME); + if (name == NULL) { + ERET1(Fail); + } + strncpy(ifi.szFacename, name, FACESIZE); + ifi.szFacename[FACESIZE - 1] = '\0'; + + /* If Unicode cmap exists in font and it contains more than 1024 glyphs, */ + /* then do not translate from UGL to Unicode and use straight Unicode. */ + /* But first check if it's a DBCS font and handle it properly */ + if ((pface->charMode == TRANSLATE_UGL) && (properties.num_Glyphs > 1024)) + { + LONG specEnc; + BOOL UDCflag = FALSE; /* !!!!TODO: UDC support */ + + specEnc = interfaceSEId(pface->face, UDCflag, PSEID_UNICODE); + switch (specEnc) { + case PSEID_SHIFTJIS: + strcpy( ifi.szGlyphlistName, "PMJPN" ); + pface->charMode = TRANSLATE_UNI_SJIS; + break; + + case PSEID_BIG5: + strcpy( ifi.szGlyphlistName, "PMCHT" ); + pface->charMode = TRANSLATE_UNI_BIG5; + break; + + default: /* do use straight Unicode */ + strcpy( ifi.szGlyphlistName, "UNICODE" ); + pface->charMode = TRANSLATE_UNICODE; /* straight Unicode */ + } +#if 0 + strcpy( ifi.szGlyphlistName, "PMJPN" ); + pface->charMode = TRANSLATE_UNI_SJIS; +#endif + } + else + if (pface->charMode == TRANSLATE_SYMBOL) /* symbol encoding */ + strcpy(ifi.szGlyphlistName, "SYMBOL"); + else + if (pface->charMode == TRANSLATE_BIG5) /* Big5 encoding */ + strcpy(ifi.szGlyphlistName, "PMCHT"); + else + if (pface->charMode == TRANSLATE_SJIS) + strcpy(ifi.szGlyphlistName, "PMJPN"); /* ShiftJIS encoding */ + else + strcpy(ifi.szGlyphlistName, "PM383"); + + ifi.idRegistry = 0; + ifi.lCapEmHeight = phead->Units_Per_EM; /* ??? probably correct */ + ifi.lXHeight = phead->yMax /2; /* IBM TRUETYPE.DLL does */ + ifi.lMaxAscender = pOS2->usWinAscent; + + if ((LONG)pOS2->usWinDescent >= 0) + ifi.lMaxDescender = pOS2->usWinDescent; + else + ifi.lMaxDescender = -pOS2->usWinDescent; + + ifi.lLowerCaseAscent = phhea->Ascender; + ifi.lLowerCaseDescent = -phhea->Descender; + + ifi.lInternalLeading = ifi.lMaxAscender + ifi.lMaxDescender + - ifi.lCapEmHeight; + + ifi.lExternalLeading = 0; + ifi.lAveCharWidth = pOS2->xAvgCharWidth; + ifi.lMaxCharInc = phhea->advance_Width_Max; + ifi.lEmInc = phead->Units_Per_EM; + ifi.lMaxBaselineExt = ifi.lMaxAscender + ifi.lMaxDescender; + ifi.fxCharSlope = -ppost->italicAngle; /* is this correct ? */ + ifi.fxInlineDir = 0; + ifi.fxCharRot = 0; + ifi.usWeightClass = pOS2->usWeightClass; /* hopefully OK */ + ifi.usWidthClass = pOS2->usWidthClass; + ifi.lEmSquareSizeX = phead->Units_Per_EM; + ifi.lEmSquareSizeY = phead->Units_Per_EM; /* probably correct */ + ifi.giFirstChar = 0; /* following values should work */ + ifi.giLastChar = 503; /* either 383 or 503 */ + ifi.giDefaultChar = 0; + ifi.giBreakChar = 32; + ifi.usNominalPointSize = 120; /* these are simply constants */ + ifi.usMinimumPointSize = 10; + ifi.usMaximumPointSize = 10000; /* limit to 1000 pt (like the ATM fonts) */ + ifi.fsType = pOS2->fsType & IFIMETRICS_LICENSED; /* ??? */ + ifi.fsDefn = IFIMETRICS_OUTLINE; /* always with TrueType */ + ifi.fsSelection = 0; + ifi.fsCapabilities = 0; /* must be zero according to the IFI spec */ + ifi.lSubscriptXSize = pOS2->ySubscriptXSize; + ifi.lSubscriptYSize = pOS2->ySubscriptYSize; + ifi.lSubscriptXOffset = pOS2->ySubscriptXOffset; + ifi.lSubscriptYOffset = pOS2->ySubscriptYOffset; + ifi.lSuperscriptXSize = pOS2->ySuperscriptXSize; + ifi.lSuperscriptYSize = pOS2->ySuperscriptYSize; + ifi.lSuperscriptXOffset = pOS2->ySuperscriptXOffset; + ifi.lSuperscriptYOffset = pOS2->ySuperscriptYOffset; + ifi.lUnderscoreSize = ppost->underlineThickness; + if (ifi.lUnderscoreSize == 150) + ifi.lUnderscoreSize = 100; /* little fix for Arial */ + ifi.lUnderscorePosition = -ppost->underlinePosition; + ifi.lStrikeoutSize = pOS2->yStrikeoutSize; + ifi.lStrikeoutPosition = pOS2->yStrikeoutPosition; + +#if 1 + if (pface->directory.nTables != 0 && + pface->directory.tables[0].format == 0) { /* we support only format */ + ifi.cKerningPairs = (pface->directory.tables[0].length - 8) / 6; + ifi.fsType |= IFIMETRICS_KERNING; /* !!! for testing only! */ + } + else +#endif + ifi.cKerningPairs = 0; + + /* Note that the following field seems to be the only reliable method of */ + /* recognizing a TT font from an app! Not that it should be done. */ + ifi.ulFontClass = 0x10D; /* just like TRUETYPE.DLL */ + + /* the following adjustment are needed because the TT spec defines */ + /* usWeightClass and fsType differently */ + if (ifi.usWeightClass >= 100) + ifi.usWeightClass /= 100; + if (ifi.usWeightClass == 4) + ifi.usWeightClass = 5; /* does this help? */ + if (pOS2->panose[3] == 9) { + ifi.fsType |= IFIMETRICS_FIXED; + pface->flags |= FC_FLAG_FIXED_WIDTH; /* we'll need this later */ + } + + switch (pface->charMode) { /* adjustments for var. encodings */ + case TRANSLATE_UNICODE: + ifi.giLastChar = pOS2->usLastCharIndex; + ifi.fsType |= IFIMETRICS_MBCS | IFIMETRICS_DBCS; + break; + + case TRANSLATE_SYMBOL: + ifi.giLastChar = 255; + break; + + case TRANSLATE_BIG5: + case TRANSLATE_UNI_BIG5: + ifi.giLastChar = 383; + ifi.fsType |= IFIMETRICS_MBCS | IFIMETRICS_DBCS; + break; + + case TRANSLATE_SJIS: + case TRANSLATE_UNI_SJIS: + ifi.giLastChar = 890; + ifi.fsType |= IFIMETRICS_MBCS | IFIMETRICS_DBCS; + break; + + } + + /* adjust fsSelection (TT defines this differently) */ + /* Note: Interestingly, the PMATM font driver seems to use the values + defined in TT spec, at least for italic. Strange. Better leave it. */ + if (pOS2->fsSelection & 0x01) { + ifi.fsSelection |= 0x01; + } + if (pOS2->fsSelection & 0x02) { + ifi.fsSelection |= IFIMETRICS_UNDERSCORE; + } + if (pOS2->fsSelection & 0x04) { + ifi.fsSelection |= IFIMETRICS_OVERSTRUCK; + } + + /* copy the right amount of data to output buffer, */ + /* also handle the 'fake' vertically rendered DBCS fonts */ + index = faceIndex * ((file->flags & FL_FLAG_DBCS_FILE) ? 2 : 1); + if ((index >= cStart) && (index < (cStart + cFontCount))) { + memcpy((((PBYTE) pifiMetrics) + ifiCount), &ifi, + sizeof(IFIMETRICS) > cMetricLen ? cMetricLen : sizeof(IFIMETRICS)); + ifiCount += cMetricLen; + } + if ((file->flags & FL_FLAG_DBCS_FILE) && (index + 1 >= cStart) && + (index + 1 < (cStart + cFontCount))) { + + pifi2 = (PIFIMETRICS) (((PBYTE) pifiMetrics) + ifiCount); + memcpy(pifi2, &ifi, + sizeof(IFIMETRICS) > cMetricLen ? cMetricLen : sizeof(IFIMETRICS)); + strcpy(pifi2->szFamilyname + 1, ifi.szFamilyname); + pifi2->szFamilyname[0] = '@'; + strcpy(pifi2->szFacename + 1, ifi.szFacename); + pifi2->szFacename[0] = '@'; + ifiCount += cMetricLen; + } + #ifdef FAKE_TNR + if ((file->flags & FL_FLAG_FAKE_ROMAN) && (index + 1 >= cStart) && + (index + 1 < (cStart + cFontCount))) { + pifi2 = (PIFIMETRICS) (((PBYTE) pifiMetrics) + ifiCount); + memcpy(pifi2, &ifi, + sizeof(IFIMETRICS) > cMetricLen ? cMetricLen : sizeof(IFIMETRICS)); + strcpy(pifi2->szFamilyname, "Roman"); + switch (strlen(ifi.szFacename)) { /* This looks weird but... works */ + case 15: /* Times New Roman */ + strcpy(pifi2->szFacename, "Tms Rmn"); + break; + case 20: /* Times New Roman Bold*/ + strcpy(pifi2->szFacename, "Tms Rmn Bold"); + break; + case 22: /* Times New Roman Italic*/ + strcpy(pifi2->szFacename, "Tms Rmn Italic"); + break; + case 27: /* Times New Roman Bold Italic*/ + strcpy(pifi2->szFacename, "Tms Rmn Bold Italic"); + break; + } + ifiCount += cMetricLen; + } + #endif + } + +Exit: + TT_Flush_Face(pface->face); + return cFontCount; + +Fail: + TT_Flush_Face(pface->face); + return -1; +} + +/****************************************************************************/ +/* */ +/* OpenFontContext : */ +/* */ +/* open new font context */ +/* */ +HFC _System OpenFontContext( HFF hff, + ULONG ulFont) +{ + int i = 0; + static TT_Instance instance; + static PFontFile file; + ULONG faceIndex; + + COPY("OpenFontContext: hff = "); CATI((int) hff); CAT("\r\n"); + COPY(" ulFont = "); CATI((int) ulFont); CAT("\r\n"); + WRITE; + + file = getFontFile(hff); + if (!file) + ERRRET((HFC)-1) /* error, invalid font handle */ + + /* calculate real face index in font file */ + faceIndex = file->flags & FL_FLAG_DBCS_FILE ? ulFont / 2 : ulFont; + + #ifdef FAKE_TNR + if (file->flags & FL_FLAG_FAKE_ROMAN) + /* This font isn't real! */ + faceIndex = 0; + #endif + + if (faceIndex > file->numFaces) + ERRRET((HFC)-1) + + /* OK, create new instance with defaults */ + error = TT_New_Instance( file->faces[faceIndex].face, &instance); + if (error) + ERET1( Fail ); + + /* Instance resolution is set to 72 dpi and is never changed */ + error = TT_Set_Instance_Resolutions(instance, 72, 72); + if (error) + ERRRET((HFC)-1) + + /* find first unused index */ + i = 0; + while ((contexts[i].hfc != 0) && (i < MAX_CONTEXTS)) + i++; + + if (i == MAX_CONTEXTS) + ERET1( Fail ); /* no free slot in table */ + + contexts[i].hfc = (HFC)(i + 0x100); /* initialize table entries */ + contexts[i].instance = instance; + contexts[i].transformed = FALSE; /* no scaling/rotation assumed */ + contexts[i].file = file; + contexts[i].faceIndex = faceIndex; + + /* for DBCS fonts/collections, odd indices are vertical versions*/ + if ((file->flags & FL_FLAG_DBCS_FILE) && (ulFont & 1)) + contexts[i].vertical = TRUE; + else + contexts[i].vertical = FALSE; + + file->flags |= FL_FLAG_CONTEXT_OPEN; /* flag as in-use */ + + COPY("-> hfc "); CATI((int) contexts[i].hfc); CAT("\r\n"); WRITE; + + TT_Flush_Face(file->faces[faceIndex].face); + return contexts[i].hfc; /* everything OK */ + +Fail: + TT_Flush_Face(file->faces[faceIndex].face); + return (HFC)-1; +} + +/****************************************************************************/ +/* */ +/* SetFontContext : */ +/* */ +/* set font context parameters */ +/* */ +LONG _System SetFontContext( HFC hfc, + PCONTEXTINFO pci ) +{ + LONG ptsize, temp, emsize; + PFontSize size; + + COPY("SetFontContext: hfc = "); CATI((int) hfc); + CAT(", sizlPPM.cx = "); CATI((int) pci->sizlPPM.cx); + CAT(", sizlPPM.cy = "); CATI((int) pci->sizlPPM.cy); + CAT("\r\n pfxSpot.x = "); CATI((int) pci->pfxSpot.x); + CAT(", pfxSpot.y = "); CATI((int) pci->pfxSpot.y); + CAT("\r\n eM11 = "); CATI((int) pci->matXform.eM11); + CAT(", eM12 = "); CATI((int) pci->matXform.eM12); + CAT(", eM21 = "); CATI((int) pci->matXform.eM21); + CAT(", eM22 = "); CATI((int) pci->matXform.eM22); + CAT("\r\n"); + WRITE; + + size = getFontSize(hfc); + if (!size) + ERRRET(-1) /* error, invalid context handle */ + + emsize = size->file->faces[size->faceIndex].em_size; + + /* Look at matrix and see if a transform is asked for */ + /* Actually when rotating by 90 degrees hinting could be used */ + + size->transformed = + ( pci->matXform.eM11 != pci->matXform.eM22 || + (pci->matXform.eM12 | pci->matXform.eM21) != 0 || + pci->matXform.eM11 <= 0 ); + + if ( size->transformed ) + { + /* check for simple stretch in one direction */ + if ((pci->matXform.eM11 > 0 && pci->matXform.eM22 > 0) && + (pci->matXform.eM12 | pci->matXform.eM21) == 0) { + + LONG ptsizex, ptsizey; + + size->transformed = FALSE; /* will be handled like nontransformed font */ + + ptsizex = (emsize * pci->matXform.eM11) >> 10; + ptsizey = (emsize * pci->matXform.eM22) >> 10; + + error = TT_Set_Instance_CharSizes(size->instance, ptsizex, ptsizey); + if (error) + ERRRET(-1) /* engine problem */ + + return 0; + } + /* note that eM21 and eM12 are swapped; I have no idea why, but */ + /* it seems to be correct */ + size->matrix.xx = pci->matXform.eM11 * 64; + size->matrix.xy = pci->matXform.eM21 * 64; + size->matrix.yx = pci->matXform.eM12 * 64; + size->matrix.yy = pci->matXform.eM22 * 64; + + /* set pointsize to Em size; this effectively disables scaling */ + /* but enables use of hinting */ + error = TT_Set_Instance_CharSize(size->instance, emsize); + if (error) + ERRRET(-1) /* engine problem */ + + return 0; + } + + /* calculate & set point size */ + ptsize = (emsize * (pci->matXform.eM11 + pci->matXform.eM21)) >> 10; + + if (ptsize <= 0) /* must not allow zero point size ! */ + ptsize = 1; /* !!! should be handled better */ + + error = TT_Set_Instance_CharSize(size->instance, ptsize); + if (error) + ERRRET(-1) /* engine problem */ + + return 0; /* pretend everything is OK */ +} + +/****************************************************************************/ +/* */ +/* CloseFontContext : */ +/* */ +/* destroy a font context */ +/* */ +LONG _System CloseFontContext( HFC hfc) +{ + PFontSize size; + + COPY("CloseFontContext: hfc = "); CATI((int)hfc); CAT("\r\n"); WRITE; + + size = getFontSize(hfc); + if (!size) + ERRRET(-1) /* error, invalid context handle */ + + /* mark table entry as free */ + size->hfc = 0; + + /* !!!!! set flag in TFontFile structure */ + size->file->flags &= ~FL_FLAG_CONTEXT_OPEN; /* reset the in-use flag */ + + if (size->file->flags & FL_FLAG_LIVE_FACE) { + COPY("Closing instance: "); CATI((int)(size->instance.z)); CAT("\r\n"); WRITE; + error = TT_Done_Instance(size->instance); + if (error) + ERRRET(-1) /* engine error */ + } + + COPY("CloseFontContext successful\r\n"); WRITE; + + return 0; /* success */ +} + +#define MAX_KERN_INDEX 504 + +GLYPH ReverseTranslate(PFontFace face, USHORT index) { + ULONG i; + GLYPH newidx = 0; + + /* TODO: enable larger fonts */ + for (i = 0; i < MAX_KERN_INDEX; i++) { + newidx = PM2TT(face->charMap, + face->charMode, + i); + if (newidx == index) + break; + } + if (i < MAX_KERN_INDEX) + return i; + else + return 0; +} + +/****************************************************************************/ +/* */ +/* QueryFaceAttr */ +/* */ +/* Return various info about font face */ +/* */ +LONG _System QueryFaceAttr( HFC hfc, + ULONG iQuery, + PBYTE pBuffer, + ULONG cb, + PGLYPH pagi, + GLYPH giStart ) +{ + int count, i = 0; + PFontSize size; + PFontFace face; + static TT_Face_Properties properties; + TT_OS2 *pOS2; + ABC_TRIPLETS* pt; + + COPY("QueryFaceAttr: hfc = "); CATI((int) hfc); CAT("\r\n"); WRITE; + + size = getFontSize(hfc); + if (!size) + ERRRET(-1) /* error, invalid context handle */ + + face = &(size->file->faces[size->faceIndex]); + + if (iQuery == FD_QUERY_KERNINGPAIRS) + { + TT_Kern_0 kerntab; /* actual kerning table */ + ULONG used = 0; /* # bytes used in output buffer */ + FD_KERNINGPAIRS *kpair; + USHORT *kernIndices, idx; + + count = cb / sizeof(FD_KERNINGPAIRS); + + COPY("QUERY_KERNINGPAIRS, "); CATI((int) count); + CAT("\r\n"); WRITE; +#if 1 + + if (face->directory.tables == NULL) + return 0; /* no kerning info provided */ + /* !!!! could use better error checking */ + /* Only format 0 is supported (which is what M$ recommends) */ + if (face->directory.tables[0].format != 0) /* need only format 0 */ + ERRRET(-1); + + error = TT_Load_Kerning_Table(face->face, 0); + if (error) + ERET1( Fail ); + + kerntab = face->directory.tables[0].t.kern0; + kpair = (PVOID)pBuffer; + + if (face->kernIndices == NULL) { + TT_Get_Face_Properties( face->face, &properties ); + error = ALLOC(face->kernIndices, + properties.num_Glyphs * sizeof (USHORT)); + if (error) + ERET1( Fail ); + + /* fill all entries with -1s */ + memset(face->kernIndices, 0xFF, + properties.num_Glyphs * sizeof (USHORT)); + } + + kernIndices = face->kernIndices; + + while ((i < kerntab.nPairs) && (i < count)) + { + idx = kerntab.pairs[i].left; + if (kernIndices[idx] == (USHORT)-1) + kernIndices[idx] = ReverseTranslate(face, idx); + kpair->giFirst = kernIndices[idx]; + idx = kerntab.pairs[i].right; + if (kernIndices[idx] == (USHORT)-1) + kernIndices[idx] = ReverseTranslate(face, idx); + kpair->giSecond = kernIndices[idx]; + kpair->eKerningAmount = kerntab.pairs[i].value; + kpair++; + i++; + } + + COPY("Returned kerning pairs: "); CATI(i); CAT("\r\n"); WRITE; + return i; /* # items filled */ +#else + return 0; /* no kerning support */ + +#endif + } + + if (iQuery == FD_QUERY_ABC_WIDTHS) + { + count = cb / sizeof(ABC_TRIPLETS); + + COPY("QUERY_ABC_WIDTHS, "); CATI((int) count); + CAT(" items, giStart = "); CATI((int) giStart); + if (pBuffer == NULL) + CAT(" NULL buffer"); + CAT("\r\n"); WRITE; + + /* This call never fails - no error check needed */ + TT_Get_Face_Properties( face->face, &properties ); + + pt = (ABC_TRIPLETS*)pBuffer; + for (i = giStart; i < giStart + count; i++, pt++) + { + int index; + unsigned short wid; + static unsigned short adv_widths [2]; + static unsigned short adv_heights[2]; + + static unsigned short widths[2], heights[2]; + static short lefts [2], tops [2]; + + index = PM2TT( face->charMap, + face->charMode, + i ); + + /* get advances and bearings */ + if (size->vertical && properties.vertical && 0) /* TODO: enable */ + error = TT_Get_Face_Metrics( face->face, index, index, + lefts, adv_widths, tops, adv_heights ); + else + error = TT_Get_Face_Metrics( face->face, index, index, + lefts, adv_widths, NULL, NULL ); + + if (error) + goto Broken_Glyph; + + /* skip complicated calculations for fixed fonts */ + if (face->flags & FC_FLAG_FIXED_WIDTH) { + wid = adv_widths[0] - lefts[0]; + } + else { /* proportianal font, it gets trickier */ + /* store glyph widths for DBCS fonts + - needed for reasonable performance */ + if (face->flags & FC_FLAG_DBCS_FACE) { + if (face->widths == NULL) { + error = ALLOC(face->widths, + properties.num_Glyphs * sizeof (USHORT)); + if (error) + goto Broken_Glyph; /* this error really shouldn't happen */ + + /* tag all entries as unused */ + memset(face->widths, 0xFF, + properties.num_Glyphs * sizeof (USHORT)); + } + if (face->widths[index] == 0xFFFF) { /* get from file if needed */ + error = TT_Get_Face_Widths( face->face, index, index, + widths, heights ); + if (error) + goto Broken_Glyph; + + /* save for later */ + wid = face->widths[index] = widths[0]; + } + else + wid = face->widths[index]; + } + /* 'small' font, no need to remember widths, OS/2 takes care of it */ + else { + /* get width or height - use ftxwidth.c */ + error = TT_Get_Face_Widths( face->face, index, index, + widths, heights ); + if (error) + goto Broken_Glyph; + + wid = widths[0]; + } + } + + if (size->vertical && !is_HALFCHAR(i)) + { + if (properties.vertical && 0) /* TODO: enable */ + { + pt->lA = tops[0]; + pt->ulB = heights[0]; + pt->lC = adv_heights[0] - pt->lA - pt->ulB; + } + else + { + pt->lA = pt->lC = 0; + pt->ulB = properties.os2->usWinAscent + + properties.os2->usWinDescent; + } + + } + else + { + pt->lA = lefts[0]; + pt->ulB = wid; + pt->lC = adv_widths[0] - pt->lA - pt->ulB; + } + +#ifdef NETSCAPE_FIX + if (face->charMode != TRANSLATE_SYMBOL && + !size->vertical) { + if (face->flags & FC_FLAG_FIXED_WIDTH) { + pt->ulB = pt->ulB + pt->lA + pt->lC; + pt->lA = 0; + pt->lC = 0; + } else if (i == 32) { + /* return nonzero B width for 'space' */ + pt->ulB = adv_widths[0] - 2 * lefts[0]; + pt->lC = lefts[0]; + } + } +#endif + continue; + + Broken_Glyph: /* handle broken glyphs gracefully */ + pt->lA = pt->lC = 0; + + if (size->vertical && !is_HALFCHAR(i)) + pt->ulB = properties.os2->usWinAscent + + properties.os2->usWinDescent; + else + pt->ulB = properties.horizontal->xMax_Extent; + + } + } + + TT_Flush_Face(face->face); + return count; /* number of entries filled in */ + +Fail: + TT_Flush_Face(face->face); + return -1; +} + +/****************************************************************************/ +/* */ +/* QueryCharAttr : */ +/* */ +/* Return glyph attributes, basically glyph's bit-map or outline */ +/* some variables are declared static to conserve stack space. */ +/* */ +LONG _System QueryCharAttr( HFC hfc, + PCHARATTR pCharAttr, + PBITMAPMETRICS pbmm ) +{ + static TT_Raster_Map bitmap; + static TT_Outline outline; + static TT_BBox bbox; + + PFontSize size; + PFontFace face; + LONG temp; + PBYTE pb; + int i, j; + ULONG cb; + + size = getFontSize(hfc); + if (!size) + ERRRET(-1) /* error, invalid context handle */ + + face = &(size->file->faces[size->faceIndex]); + + error = TT_Load_Glyph( size->instance, + face->glyph, + PM2TT( face->charMap, + face->charMode, + pCharAttr->gi), + TTLOAD_DEFAULT); + + if (error) + { + if (i == 0) + ERET1( Fail ) /* this font's no good, return error */ + else + { /* try to recover quietly */ + error = TT_Load_Glyph( size->instance, + face->glyph, + 0, + TTLOAD_DEFAULT); + if (error) { + COPY("Error code is "); CATI(error); CAT("\r\n"); WRITE; + ERET1( Fail ); + } + } + } + + TT_Flush_Face( face->face ); + + error = TT_Get_Glyph_Outline( face->glyph, &outline ); + if (error) + ERRRET(-1); + + /* --- Vertical fonts handling----------------------------------- */ + + if (size->vertical && !is_HALFCHAR(pCharAttr->gi)) { + TT_Matrix vertMatrix; + + vertMatrix.xx = 0x00000; + vertMatrix.xy = -0x10000; + vertMatrix.yx = 0x10000; + vertMatrix.yy = 0x00000; + TT_Get_Outline_BBox( &outline, &bbox ); + + /* rotate outline 90 degrees counterclockwise */ + TT_Transform_Outline(&outline, &vertMatrix); + + /* move outline to the right to adjust for rotation */ + TT_Translate_Outline(&outline, bbox.yMax, 0); + /* move outline down a bit */ + TT_Translate_Outline(&outline, 0, bbox.yMin); + } + + if (size->transformed) + TT_Transform_Outline( &outline, &size->matrix ); + + /* --- Outline processing --------------------------------------- */ + + if ( pCharAttr->iQuery & FD_QUERY_OUTLINE ) + { + if (pCharAttr->cbLen == 0) /* send required outline size in bytes */ + return GetOutlineLen( &outline ); + + return GetOutline( &outline, pCharAttr->pBuffer ); + } + + /* --- Bitmap processing ---------------------------------------- */ + + TT_Get_Outline_BBox( &outline, &bbox ); + + /* the following seems to be necessary for rotated glyphs */ + if (size->transformed) { + bbox.xMax = bbox.xMin = 0; + for (i = 0; i < outline.n_points; i++) { + if (bbox.xMin > outline.points[i].x) + bbox.xMin = outline.points[i].x; + if (bbox.xMax < outline.points[i].x) + bbox.xMax = outline.points[i].x; + } + } + /* grid-fit the bbox */ + bbox.xMin &= -64; + bbox.yMin &= -64; + + bbox.xMax = (bbox.xMax+63) & -64; + bbox.yMax = (bbox.yMax+63) & -64; + + if (pCharAttr->iQuery & FD_QUERY_BITMAPMETRICS) + { + /* fill in bitmap metrics */ + /* metrics values are in 26.6 format ! */ + pbmm->sizlExtent.cx = (bbox.xMax - bbox.xMin) >> 6; + pbmm->sizlExtent.cy = (bbox.yMax - bbox.yMin) >> 6; + pbmm->cyAscent = 0; + pbmm->pfxOrigin.x = bbox.xMin << 10; + pbmm->pfxOrigin.y = bbox.yMax << 10; + + if (!(pCharAttr->iQuery & FD_QUERY_CHARIMAGE)) + return sizeof(*pbmm); + } + + /* --- actual bitmap processing here --- */ + if (pCharAttr->iQuery & FD_QUERY_CHARIMAGE) + { + /* values in 26.6 format ?!? */ + bitmap.width = (bbox.xMax - bbox.xMin) >> 6; + bitmap.rows = (bbox.yMax - bbox.yMin) >> 6; + /* width rounded up to nearest multiple of 4 */ + bitmap.cols = ((bitmap.width + 31) / 8) & -4; + bitmap.flow = TT_Flow_Down; + bitmap.bitmap = pCharAttr->pBuffer; + bitmap.size = bitmap.rows * bitmap.cols; + + if (pCharAttr->cbLen == 0) + return bitmap.size; + + if (bitmap.size > pCharAttr->cbLen) + ERRRET(-1) /* otherwise we might overwrite something */ + + /* clean provided buffer (unfortunately necessary) */ + memset(bitmap.bitmap, 0, pCharAttr->cbLen); + + error = TT_Get_Glyph_Bitmap( face->glyph, + &bitmap, + -bbox.xMin, + -bbox.yMin ); + if (error) + ERRRET(-1); /* engine error */ + + return bitmap.size; /* return # of bytes */ + } + ERRRET(-1) /* error */ + +Fail: + TT_Flush_Face(face->face); + return -1; +} + +/****************************************************************************/ +/* */ +/* QueryFullFaces : */ +/* */ +/* Query names of all faces in this file */ +/* */ +LONG _System QueryFullFaces( HFF hff, + PVOID pBuff, + PULONG buflen, + PULONG cFontCount, + ULONG cStart ) +{ + COPY("!QueryFullFaces: hff = "); CATI((int) hff); CAT("\r\n"); WRITE; + ERRRET(-1) /* error ? */ +} + +/*---------------------------------------------------------------------------*/ +/* end of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/****************************************************************************/ +/* LimitsInit reads OS2.INI and sets up max_open_files limit, possibly */ +/* other variables as well. */ +/* */ +static void LimitsInit(void) { + char cBuffer[25]; /* ought to be enough */ + + if (PrfQueryProfileString(HINI_USERPROFILE, "FreeType/2", "OPENFACES", + NULL, cBuffer, sizeof(cBuffer)) > 0) { + max_open_files = atoi(cBuffer); + + if (max_open_files < 8) /* ensure limit isn't too low */ + max_open_files = 8; + } + else + max_open_files = 12; /* reasonable default */ +} + + +/****************************************************************************/ +/* my_itoa is used only in the following function GetUdcInfo. */ +/* Works pretty much like expected. */ +/* */ +void my_itoa(int num, char *cp) { + char temp[10]; + int i = 0; + + do { + temp[i++] = (num % 10) + '0'; + num /= 10; + } while (num); /* enddo */ + + while (i--) { + *cp++ = temp[i]; + } /* endwhile */ + *cp = '\0'; +} + +/****************************************************************************/ +/* GetUdcInfo determines the UDC ranges used */ +/* */ +VOID GetUdcInfo(VOID) { + ULONG ulUdc, ulUdcInfo, i; + PVOID gPtr; + HINI hini; + CHAR szCpStr[10] = "CP"; + + DosQueryCp(sizeof(ulCp), (ULONG*)&ulCp, &i); /* find out default codepage */ + my_itoa((INT) ulCp, szCpStr + 2); /* convert to ASCII */ + +} + +/****************************************************************************/ +/* LangInit determines language used at DLL startup, non-zero return value */ +/* means error. */ +/* This code is crucial, because it determines behaviour of the font driver */ +/* with regard to language encodings it will use. */ +static ULONG LangInit(void) { + COUNTRYCODE cc = {0, 0}; + COUNTRYINFO ci; + ULONG cilen; + + isGBK = FALSE; + + GetUdcInfo(); /* get User Defined Character info */ + + /* get country info; ci.country then contains country code */ + if (DosQueryCtryInfo(sizeof(ci), &cc, &ci, &cilen)) + return -1; + /* get DBCS lead byte values for later use */ + DosQueryDBCSEnv(sizeof(DBCSLead), &cc, DBCSLead); + + uLastGlyph = 383; + switch (ci.country) { + case 81: /* Japan */ + iLangId = TT_MS_LANGID_JAPANESE_JAPAN; + ScriptTag = *(ULONG *) "kana"; + LangSysTag = *(ULONG *) "JAN "; + pGlyphlistName = "PMJPN"; + uLastGlyph = 890; + break; + + case 88: /* Taiwan */ + iLangId = TT_MS_LANGID_CHINESE_TAIWAN; + ScriptTag = *(ULONG *) "kana"; + LangSysTag = *(ULONG *) "CHT "; + pGlyphlistName = "PMCHT"; + break; + + case 86: /* People's Republic of China */ + if (ci.codepage == 1386 || ulCp[0] == 1386 || ulCp[1] == 1386) { + isGBK = TRUE; + } /* endif */ + iLangId = TT_MS_LANGID_CHINESE_PRC; + ScriptTag = *(ULONG *) "kana"; + LangSysTag = *(ULONG *) "CHS "; + pGlyphlistName = "PMPRC"; + break; + + case 82: /* Korea */ + iLangId = TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA; + ScriptTag = *(ULONG *) "hang"; + LangSysTag = *(ULONG *) "KOR "; + pGlyphlistName = "PMKOR"; + uLastGlyph = 949; + break; + + case 30: /* Greece - for Alex! */ + iLangId = TT_MS_LANGID_GREEK_GREECE; + + default: /* none of the above countries */ + ScriptTag = *(ULONG *) ""; + LangSysTag = *(ULONG *) ""; + break; + } /* endswitch */ + + return 0; +} + +/****************************************************************************/ +/* */ +/* FirstInit : */ +/* */ +/* Called when font driver is loaded for the first time. Performs the */ +/* necessary one-time initialization. */ +ULONG FirstInit(void) { + LONG lReqCount; + ULONG ulCurMaxFH; + + #ifdef DEBUG + ULONG Action; + #endif /* DEBUG */ + #ifdef DEBUG + DosOpen("C:\\FTIFI.LOG", &LogHandle, &Action, 0, FILE_NORMAL, + OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS, + OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_WRITE_THROUGH | + OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYWRITE | OPEN_ACCESS_WRITEONLY, + NULL); + COPY("FreeType/2 loaded.\r\n"); + WRITE; + #endif /* DEBUG */ + + /* increase # of file handles by five to be on the safe side */ + lReqCount = 5; + DosSetRelMaxFH(&lReqCount, &ulCurMaxFH); + error = TT_Init_FreeType(&engine); /* turn on the FT engine */ + if (error) + return 0; /* exit immediately */ + error = TT_Init_Kerning_Extension(engine); /* load kerning support */ + COPY("FreeType Init called\r\n"); + WRITE; + + if (LangInit()) /* initialize NLS */ + return 0; /* exit on error */ + COPY("NLS initialized.\r\n"); + WRITE; + + LimitsInit(); /* initialize max_open_files */ + COPY("Open faces limit set to "); CATI(max_open_files); CAT("\r\n"); + WRITE; + + if (error) + return 0; /* exit immediately */ + COPY("Initialization successful.\r\n"); + WRITE; + return 1; +} + + +/****************************************************************************/ +/* */ +/* FinalTerm : */ +/* */ +/* Called when font driver is unloaded for the last time time. Performs */ +/* final clean-up, shuts down engine etc. */ +ULONG FinalTerm(void) { + PListElement cur; + PListElement tmp; + + /* throw away elements from 'free elements' list */ + cur = free_elements; + while (cur != NULL) { + tmp = cur; + cur = cur->next; + FREE(tmp); + } + + /* turn off engine */ + TT_Done_FreeType(engine); + + #ifdef DEBUG + COPY("FreeType/2 terminated.\r\n"); + WRITE; + DosClose(LogHandle); + #endif + return 1; +} +/****************************************************************************/ +/* */ +/* _DLL_InitTerm : */ +/* */ +/* This is the DLL Initialization/termination function. It initializes */ +/* the FreeType engine and some internal structures at startup. It cleans */ +/* up the UCONV cache at process termination. */ +ULONG _System _DLL_InitTerm(ULONG hModule, ULONG ulFlag) { + switch (ulFlag) { + case 0: /* initializing */ + if (++ulProcessCount == 1) + return FirstInit(); /* loaded for the first time */ + else + return 1; + + case 1: { /* terminating */ + int i; + /* clean UCONV cache */ + #ifdef USE_UCONV + CleanUCONVCache(); + #endif + if(--ulProcessCount == 0) + return FinalTerm(); + else + return 1; + } + } + return 0; +} + +/****************************************************************************/ +/* */ +/* interfaceSEId (Interface-specific Encoding Id) determines what encoding */ +/* the font driver should use if a font includes a Unicode encoding. */ +/* */ +LONG interfaceSEId(TT_Face face, BOOL UDCflag, LONG encoding) { + ULONG range1 = 0; + ULONG bits, mask; + TT_OS2 *pOS2; + static TT_Face_Properties props; + + TT_Get_Face_Properties(face, &props); + pOS2 = props.os2; + + if (encoding == PSEID_UNICODE) { + + /* if font is 'small', use PM383; this is done because of DBCS + systems */ + if (!UDCflag && props.num_Glyphs < 1024) { + encoding = PSEID_PM383; + } else if (pOS2->version >= 1) { + /* + * * OS/2 table version 1 and later contains codepage * + * bitfield to support multiple codepages. + */ + range1 = pOS2->ulCodePageRange1; + bits = 0; + + if (range1 & OS2_CP1_ANSI_OEM_JAPANESE_JIS) + bits++; + if (range1 & OS2_CP1_ANSI_OEM_CHINESE_SIMPLIFIED) + bits++; + if (range1 & OS2_CP1_ANSI_OEM_CHINESE_TRADITIONAL) + bits++; + if (range1 & OS2_CP1_ANSI_OEM_KOREAN_WANSUNG) + bits++; + if (range1 & OS2_CP1_ANSI_OEM_KOREAN_JOHAB) + bits++; + + /* Note: if font supports more than one of the following codepages, + * encoding is left at PSEID_UNICODE! + */ + if (bits == 1) { + switch (range1) { + case OS2_CP1_ANSI_OEM_JAPANESE_JIS: + encoding = PSEID_SHIFTJIS; + break; + case OS2_CP1_ANSI_OEM_CHINESE_SIMPLIFIED: + encoding = PSEID_PRC; + break; + case OS2_CP1_ANSI_OEM_CHINESE_TRADITIONAL: + encoding = PSEID_BIG5; + break; + case OS2_CP1_ANSI_OEM_KOREAN_WANSUNG: + encoding = PSEID_WANSUNG; + break; + case OS2_CP1_ANSI_OEM_KOREAN_JOHAB: + encoding = PSEID_JOHAB; + break; + default: + break; + } /* endswitch */ + } /* endif */ + } else { + /* + * The codepage range bitfield is not available. + * Codepage must be assumed from the COUNTRY setting. + * This means the user is on his own. + */ + + switch (iLangId) { + case TT_MS_LANGID_JAPANESE_JAPAN: + encoding = PSEID_SHIFTJIS; + break; + case TT_MS_LANGID_CHINESE_PRC: + case TT_MS_LANGID_CHINESE_SINGAPORE: + encoding = PSEID_PRC; + break; + case TT_MS_LANGID_CHINESE_TAIWAN: + case TT_MS_LANGID_CHINESE_HONG_KONG: + encoding = PSEID_BIG5; + break; + case TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA: + encoding = PSEID_WANSUNG; + break; + case TT_MS_LANGID_KOREAN_JOHAB_KOREA: + encoding = PSEID_JOHAB; + break; + } + + } + } + return encoding; +} + +/****************************************************************************/ +/* */ +/* LookupName : */ +/* */ +/* Look for a TrueType name by index, prefer current language */ +/* */ +static char* LookupName(TT_Face face, int index ) +{ + static char name_buffer[FACESIZE + 2]; + int name_len = 0; + int i, j, n; + + USHORT platform, encoding, language, id; + char* string; + USHORT string_len; + + int found; + + n = TT_Get_Name_Count( face ); + if ( n < 0 ) + return NULL; + + for ( i = 0; i < n; i++ ) + { + TT_Get_Name_ID( face, i, &platform, &encoding, &language, &id ); + TT_Get_Name_String( face, i, &string, &string_len ); + + if ( id == index ) + { + found = 0; + + /* Try to find an appropriate name */ + if ( platform == TT_PLATFORM_MICROSOFT ) + for ( j = 5; j >= 0; j-- ) + if ( encoding == j ) /* Microsoft ? */ + switch (language) + { + case TT_MS_LANGID_CHINESE_TAIWAN: + if (encoding == PSEID_PRC) + found = 1; + break; + + case TT_MS_LANGID_JAPANESE_JAPAN: + if (encoding == PSEID_SHIFTJIS) + found = 1; + break; + + /* these aren't all possibilities; just the most likely ones */ + case TT_MS_LANGID_ENGLISH_UNITED_STATES : + case TT_MS_LANGID_ENGLISH_UNITED_KINGDOM : + case TT_MS_LANGID_ENGLISH_AUSTRALIA : + case TT_MS_LANGID_ENGLISH_CANADA : + case TT_MS_LANGID_ENGLISH_NEW_ZEALAND : + case TT_MS_LANGID_ENGLISH_IRELAND : + case TT_MS_LANGID_ENGLISH_SOUTH_AFRICA : + found = 1; + break; + } + + if ( !found && platform == 0 && language == 0 ) + found = 1; + + if (found) + { + if (language == TT_MS_LANGID_CHINESE_TAIWAN || + language == TT_MS_LANGID_JAPANESE_JAPAN) { + /* it's a DBCS string, copy everything except NULLs */ + int i,j; + if (string_len > FACESIZE - 1) + string_len = FACESIZE - 1; + + for (i=0, j=0; i FACESIZE * 2) + string_len = FACESIZE * 2; + + name_len = 0; + + for ( i = 1; i < string_len; i += 2 ) + name_buffer[name_len++] = string[i]; + + name_buffer[name_len] = '\0'; + + return name_buffer; + } + } + } + } + + /* Not found */ + return NULL; +} + +/****************************************************************************/ +/* */ +/* GetCharMap : */ +/* */ +/* A function to find a suitable charmap, searching in the following */ +/* order of importance : */ +/* */ +/* 1) Windows Unicode */ +/* 2) Apple Unicode */ +/* 3) ROC (Taiwan) */ +/* 4) ShiftJIS (Japan) */ +/* 5) Apple Roman */ +/* 6) Windows Symbol - not really supported */ +/* */ +/* High word of returned ULONG contains type of encoding */ +/* */ +static ULONG GetCharmap(TT_Face face) +{ + int n; /* # of encodings (charmaps) available */ + USHORT platform, encoding; + int i, best, bestVal, val; + + n = TT_Get_CharMap_Count(face); + + if (n < 0) /* no encodings at all; don't yet know what the best course of action would be */ + ERRRET(-1) /* such font should probably be rejected */ + + bestVal = 16; + best = -1; + + for (i = 0; i < n; i++) + { + TT_Get_CharMap_ID( face, i, &platform, &encoding ); + + /* Windows Unicode is the highest encoding, return immediately */ + /* if we find it.. */ + if ( platform == TT_PLATFORM_MICROSOFT && encoding == TT_MS_ID_UNICODE_CS) + return i; + + /* otherwise, compare it to the best encoding found */ + val = -1; + if (platform == TT_PLATFORM_APPLE_UNICODE) + val = 2; + else if (platform == TT_PLATFORM_MICROSOFT + && encoding == TT_MS_ID_BIG_5) + val = 3; + else if (platform == TT_PLATFORM_MICROSOFT + && encoding == TT_MS_ID_SJIS) + val = 4; + else if (platform == TT_PLATFORM_MACINTOSH + && encoding == TT_MAC_ID_ROMAN) + val = 5; + else if (platform == TT_PLATFORM_MICROSOFT + && encoding == TT_MS_ID_SYMBOL_CS) + val = 6; + + if (val > 0 && val <= bestVal) + { + bestVal = val; + best = i; + } + } + + if (i < 0) + return 0; /* we didn't find any suitable encoding !! */ + + if (bestVal == 3) /* Taiwanese font */ + best |= ( TRANSLATE_BIG5 << 16 ); + + if (bestVal == 4) /* Japanese font */ + best |= ( TRANSLATE_SJIS << 16 ); + + if (bestVal == 5) /* for Apple Roman encoding only, this */ + best |= ( TRANSLATE_SYMBOL << 16 ); /* means no translation should be performed */ + + return best; +} + +/****************************************************************************/ +/* */ +/* GetOutlineLen : */ +/* */ +/* Used to compute the size of an outline once it is converted to */ +/* OS/2's specific format. The translation is performed by the later */ +/* function called simply "GetOultine". */ +/* */ +static int GetOutlineLen(TT_Outline *ol) +{ + int index; /* current point's index */ + BOOL on_curve; /* current point's state */ + int i, start = 0; + int first, last; + ULONG cb = 0; + + /* loop thru all contours in a glyph */ + for ( i = 0; i < ol->n_contours; i++ ) { + + cb += sizeof(POLYGONHEADER); + + first = start; + last = ol->contours[i]; + + on_curve = (ol->flags[first] & 1); + index = first; + + /* process each contour point individually */ + while ( index < last ) { + index++; + + if ( on_curve ) { + /* the previous point was on the curve */ + on_curve = ( ol->flags[index] & 1 ); + if ( on_curve ) { + /* two successive on points => emit segment */ + cb += sizeof(PRIMLINE); + } + } + else { + /* the previous point was off the curve */ + on_curve = ( ol->flags[index] & 1 ); + if ( on_curve ) { + /* reaching an `on' point */ + cb += sizeof(PRIMSPLINE); + } + else { + /* two successive `off' points => create middle point */ + cb += sizeof(PRIMSPLINE); + } + } + } + + /* end of contour, close curve cleanly */ + if ( ol->flags[first] & 1 ) + { + if ( on_curve ) + cb += sizeof(PRIMLINE); + else + cb += sizeof(PRIMSPLINE); + } + else + if (!on_curve) + cb += sizeof(PRIMSPLINE); + + start = ol->contours[i] + 1; + + } + return cb; /* return # bytes used */ +} + +/****************************************************************************/ +/* */ +/* a few global variables used in the following functions */ +/* */ +static ULONG cb = 0, polycb; +static LONG lastX, lastY; +static PBYTE pb; +static POINTFX Q, R; +static POLYGONHEADER hdr = {0, FD_POLYGON_TYPE}; +static PRIMLINE line = {FD_PRIM_LINE}; +static PRIMSPLINE spline = {FD_PRIM_SPLINE}; + +/****************************************************************************/ +/* */ +/* LineFrom : */ +/* */ +/* add a line segment to the PM outline that GetOultine is currently */ +/* building. */ +/* */ +static void Line_From(LONG x, LONG y) { + line.pte.x = x << 10; + line.pte.y = y << 10; + /* store to output buffer */ + memcpy(&(pb[cb]), &line, sizeof(line)); + cb += sizeof(PRIMLINE); + polycb += sizeof(PRIMLINE); +} + + +/****************************************************************************/ +/* */ +/* BezierFrom : */ +/* */ +/* add a bezier arc to the PM outline that GetOutline is currently */ +/* buidling. The second-order Bezier is trivially converted to its */ +/* equivalent third-order form. */ +/* */ +static void Bezier_From( LONG x0, LONG y0, LONG x2, LONG y2, LONG x1, LONG y1 ) { + spline.pte[0].x = x0 << 10; + spline.pte[0].y = y0 << 10; + /* convert from second-order to cubic Bezier spline */ + Q.x = (x0 + 2 * x1) / 3; + Q.y = (y0 + 2 * y1) / 3; + R.x = (x2 + 2 * x1) / 3; + R.y = (y2 + 2 * y1) / 3; + spline.pte[1].x = Q.x << 10; + spline.pte[1].y = Q.y << 10; + spline.pte[2].x = R.x << 10; + spline.pte[2].y = R.y << 10; + /* store to output buffer */ + memcpy(&(pb[cb]), &spline, sizeof(spline)); + cb += sizeof(PRIMSPLINE); + polycb += sizeof(PRIMSPLINE); +} + + +/****************************************************************************/ +/* */ +/* GetOutline : */ +/* */ +/* Translate a FreeType glyph outline into PM format. The buffer is */ +/* expected to be of the size returned by a previous call to the */ +/* function GetOutlineLen(). */ +/* */ +/* This code is taken right from the FreeType ttraster.c source, and */ +/* subsequently modified to emit PM segments and arcs. */ +/* */ +static int GetOutline(TT_Outline *ol, PBYTE pbuf) { + LONG x, y; /* current point */ + LONG cx, cy; /* current Bezier control point */ + LONG mx, my; /* current middle point */ + LONG x_first, y_first; /* first point's coordinates */ + LONG x_last, y_last; /* last point's coordinates */ + + int index; /* current point's index */ + BOOL on_curve; /* current point's state */ + int i, start = 0; + int first, last; + ULONG polystart; + + pb = pbuf; + cb = 0; + + /* loop thru all contours in a glyph */ + for ( i = 0; i < ol->n_contours; i++ ) { + + polystart = cb; /* save this polygon's start offset */ + polycb = sizeof(POLYGONHEADER); /* size of this polygon */ + cb += sizeof(POLYGONHEADER); + + first = start; + last = ol->contours[i]; + + x_first = ol->points[first].x; + y_first = ol->points[first].y; + + x_last = ol->points[last].x; + y_last = ol->points[last].y; + + lastX = cx = x_first; + lastY = cy = y_first; + + on_curve = (ol->flags[first] & 1); + index = first; + + /* check first point to determine origin */ + if ( !on_curve ) { + /* first point is off the curve. Yes, this happens... */ + if ( ol->flags[last] & 1 ) { + lastX = x_last; /* start at last point if it */ + lastY = y_last; /* is on the curve */ + } + else { + /* if both first and last points are off the curve, */ + /* start at their middle and record its position */ + /* for closure */ + lastX = (lastX + x_last)/2; + lastY = (lastY + y_last)/2; + + x_last = lastX; + y_last = lastY; + } + } + + /* now process each contour point individually */ + while ( index < last ) { + index++; + x = ( ol->points[index].x ); + y = ( ol->points[index].y ); + + if ( on_curve ) { + /* the previous point was on the curve */ + on_curve = ( ol->flags[index] & 1 ); + if ( on_curve ) { + /* two successive on points => emit segment */ + Line_From( lastX, lastY ); /*x, y*/ + lastX = x; + lastY = y; + } + else { + /* else, keep current control point for next bezier */ + cx = x; + cy = y; + } + } + else { + /* the previous point was off the curve */ + on_curve = ( ol->flags[index] & 1 ); + if ( on_curve ) { + /* reaching an `on' point */ + Bezier_From(lastX, lastY, x, y, cx, cy ); + lastX = x; + lastY = y; + } + else { + /* two successive `off' points => create middle point */ + mx = (cx + x) / 2; + my = (cy + y)/2; + + Bezier_From( lastX, lastY, mx, my, cx, cy ); + lastX = mx; + lastY = my; + + cx = x; + cy = y; + } + } + } + + /* end of contour, close curve cleanly */ + if ( ol->flags[first] & 1 ) { + if ( on_curve ) + Line_From( lastX, lastY); /* x_first, y_first );*/ + else + Bezier_From( lastX, lastY, x_first, y_first, cx, cy ); + } + else + if (!on_curve) + Bezier_From( lastX, lastY, x_last, y_last, cx, cy ); + + start = ol->contours[i] + 1; + + hdr.cb = polycb; + memcpy(&(pb[polystart]), &hdr, sizeof(hdr)); + + } + return cb; /* return # bytes used */ +} + diff --git a/contrib/ftos2/ifi/ftifi.h b/contrib/ftos2/ifi/ftifi.h new file mode 100644 index 0000000..e8be787 --- /dev/null +++ b/contrib/ftos2/ifi/ftifi.h @@ -0,0 +1,305 @@ +/* + Conversion from OS/2 UGL to Unicode + + Copyright (C) 1997 Robert Muchsel + Copyright (C) 1997,1998 Michal Necasek + + All entries that were previously 0xFFFF were changed to 0x0000 because + TrueType 'missing glyph' has index 0 +*/ + +#ifndef _FTIFI_H_INCLUDED_ +#define _FTIFI_H_INCLUDED_ + +/* Platform-specific Encoding IDs for MS platform */ +#define PSEID_SYMBOL 0 +#define PSEID_UNICODE 1 +#define PSEID_SHIFTJIS 2 +#define PSEID_BIG5 3 +#define PSEID_PRC 4 +#define PSEID_WANSUNG 5 +#define PSEID_JOHAB 6 +/* defined by me! */ +#define PSEID_PM383 100 + +/* bit masks for determining supported codepages */ +#define OS2_CP1_ANSI_OEM_JAPANESE_JIS (1 << 17) +#define OS2_CP1_ANSI_OEM_CHINESE_SIMPLIFIED (1 << 18) +#define OS2_CP1_ANSI_OEM_CHINESE_TRADITIONAL (1 << 19) +#define OS2_CP1_ANSI_OEM_KOREAN_WANSUNG (1 << 20) +#define OS2_CP1_ANSI_OEM_KOREAN_JOHAB (1 << 21) + +/* defines for character translation */ +/* from Unicode to UGL */ +#define TRANSLATE_UGL 0 +/* Symbol - no translation */ +#define TRANSLATE_SYMBOL 1 +/* Unicode - no translation */ +#define TRANSLATE_UNICODE 2 +/* Big5 - no translation */ +#define TRANSLATE_BIG5 4 +/* ShiftJIS - no translation */ +#define TRANSLATE_SJIS 5 +/* from Unicode to Big5 */ +#define TRANSLATE_UNI_BIG5 16 +/* from Unicode to ShiftJIS */ +#define TRANSLATE_UNI_SJIS 17 + + +#define MAX_GLYPH 504 +/* I suppose more than 949 is never used */ +/* 504 should be OK for (most) European and American countries */ + +#ifndef USE_UCONV +static const int UGL2Uni[MAX_GLYPH + 1] = { + + /* PM383 UGL mapping */ + + /* 0..9 */ + 0x0000, 0x263a, 0x263b, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, 0x25d8, 0x25cb, + /* 10..19 */ + 0x25d9, 0x2642, 0x2640, 0x266a, 0x266b, 0x263c, 0x25ba, 0x25c4, 0x2195, 0x203c, + /* 20..29 */ + 0xb6, 0xa7, 0x25ac, 0x21a8, 0x2191, 0x2193, 0x2192, 0x2190, 0x221f, 0x2194, + /* 30..39 */ + 0x25b2, 0x25bc, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + /* 40..49 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, + /* 50..59 */ + 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + /* 60..69 */ + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + /* 70..79 */ + 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + /* 80..89 */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + /* 90..99 */ + 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, + /* 100..109 */ + 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, + /* 110..119 */ + 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + /* 120..129 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x2302, 0xc7, 0xfc, + /* 130..139 */ + 0xe9, 0xe2, 0xe4, 0xe0, 0xe5, 0xe7, 0xea, 0xeb, 0xe8, 0xef, + /* 140..149 */ + 0xee, 0xec, 0xc4, 0xc5, 0xc9, 0xe6, 0xc6, 0xf4, 0xf6, 0xf2, + /* 150..159 */ + 0xfb, 0xf9, 0xff, 0xd6, 0xdc, 0xf8, 0xa3, 0xd8, 0xd7, 0x192, + /* 160..169 */ + 0xe1, 0xed, 0xf3, 0xfa, 0xf1, 0xd1, 0xaa, 0xba, 0xbf, 0xae, + /* 170..179 */ + 0xac, 0xbd, 0xbc, 0xa1, 0xab, 0xbb, 0x2591, 0x2592, 0x2593, 0x2502, + /* 180..189 */ + 0x2524, 0xc1, 0xc2, 0xc0, 0xa9, 0x2563, 0x2551, 0x2557, 0x255d, 0xa2, + /* 190..199 */ + 0xa5, 0x2510, 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0xe3, 0xc3, + /* 200..209 */ + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0xa4, 0xf0, 0xd0, + /* 210..219 */ + 0xca, 0xcb, 0xc8, 0x131, 0xcd, 0xce, 0xcf, 0x2518, 0x250c, 0x2588, + /* 220..229 */ + 0x2584, 0xa6, 0xcc, 0x2580, 0xd3, 0xdf, 0xd4, 0xd2, 0xf5, 0xd5, + /* 230..239 */ + 0xb5, 0xfe, 0xde, 0xda, 0xdb, 0xd9, 0xfd, 0xdd, 0xaf, 0xb4, + /* 240..249 */ + 0xad, 0xb1, 0x2017, 0xbe, 0xb6, 0xa7, 0xf7, 0xb8, 0xb0, 0xa8, + /* 250..259 */ + 0xb7, 0xb9, 0xb3, 0xb2, 0x25a0, 0xa0, 0x20a7, 0x2310, 0x2561, 0x2562, + /* 260..269 */ + 0x2556, 0x2555, 0x255c, 0x255b, 0x255e, 0x255f, 0x2567, 0x2568, 0x2564, 0x2565, + /* 270..279 */ + 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, 0x256a, 0x258c, 0x2590, 0x3b1, 0x393, + /* 280..289 */ + 0x3c0, 0x3a3, 0x3c3, 0x3c4, 0x3a6, 0x398, 0x3a9, 0x3b4, 0x221e, 0x3c6, + /* 290..299 */ + 0x3b5, 0x2229, 0x2261, 0x2265, 0x2264, 0x2320, 0x2321, 0x2248, 0x2219, 0x221a, + /* 300..309 */ + 0x207f, 0x2c9, 0x2d8, 0x2d9, 0x2da, 0x2dd, 0x2db, 0x2c7, 0x2018, 0x2019, + /* 310..318*/ + 0x201c, 0x201d, 0x2013, 0x2014, 0x2c6, 0x2dc, 0x201a, 0x201e, 0x2026, + + /* 319..329 */ + 0x2020, 0x2021, 0x2c6, 0x2030, 0x160, 0x2039, 0x152, 0x303, 0x2122, 0x161, 0x203a, + /* 330..339 */ + 0x153, 0x178, 0x11f, 0x11e, 0x130, 0x15f, 0x15e, 0x103, 0x102, 0x105, + /* 340..349 */ + 0x104, 0x107, 0x106, 0x10d, 0x10c, 0x10f, 0x10e, 0x111, 0x11b, 0x11a, + /* 350..359 */ + 0x119, 0x118, 0x13a, 0x139, 0x13e, 0x13d, 0x142, 0x141, 0x144, 0x143, + /* 360..369 */ + 0x148, 0x147, 0x151, 0x150, 0x155, 0x154, 0x159, 0x158, 0x15b, 0x15a, + /* 370..379 */ + 0x165, 0x164, 0x163, 0x162, 0x171, 0x170, 0x16f, 0x16e, 0x17a, 0x179, + /* 380..383 */ + 0x17e, 0x17d, 0x17c, 0x17b, + + /* I don't know whether the following are used by PM, but they are in + the I18N unicode library */ + /* yes they ARE used (for Cyrillic systems) */ + + /* 384..389 */ + 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, + /* 390..399 */ + 0x407, 0x408, 0x409, 0x40a, 0x40b, 0x40c, 0x40e, 0x40f, 0x410, 0x411, + /* 400..409 */ + 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41a, 0x41b, + /* 410..419 */ + 0x41c, 0x41d, 0x41e, 0x41f, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, + /* 420..429 */ + 0x426, 0x427, 0x428, 0x429, 0x42a, 0x42b, 0x42c, 0x42d, 0x42e, 0x42f, + /* 430..439 */ + 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, + /* 440..449 */ + 0x43a, 0x43b, 0x43c, 0x43d, 0x43e, 0x43f, 0x440, 0x441, 0x442, 0x443, + /* 450..459 */ + 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44a, 0x44b, 0x44c, 0x44d, + /* 460..469 */ + 0x44e, 0x44f, 0x2116, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, + /* 470..479 */ + 0x458, 0x459, 0x45a, 0x45b, 0x45c, 0x45e, 0x45f, 0x490, 0x491, 0x156, + /* 480..489 */ + 0x12e, 0x100, 0x112, 0x116, 0x122, 0x136, 0x12a, 0x1eb, 0x145, 0x14c, + /* 490..499 */ + 0x172, 0x16a, 0x157, 0x12f, 0x101, 0x113, 0x117, 0x123, 0x137, 0x12b, + /* 500..504 */ + 0x13c, 0x146, 0x14d, 0x173, 0x16b + +#if MAX_GLYPH > 504 + , 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 510..519 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 520..529 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 530..539 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 540..549 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 550..559 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 560..569 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 570..579 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 580..589 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 590..599 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 600..609 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 610..619 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 620..629 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 630..639 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 640..649 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 650..659 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 660..669 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 670..679 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 680..689 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 690..699 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 700..709 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 710..719 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 720..729 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 730..739 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 740..749 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 750..759 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 760..769 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x303f, 0x21b5, + /* 770..779 */ + 0x3002, 0x300c, 0x300d, 0x3001, 0x0000, 0x30f2, 0x30a1, 0x30a3, 0x30a5, 0x30a7, + /* 780..789 */ + 0x30a9, 0x30e3, 0x30e5, 0x30e7, 0x30c3, 0x30fc, 0x30a2, 0x30a4, 0x30a6, 0x30a8, + /* 790..799 */ + 0x30aa, 0x30ab, 0x30ad, 0x30af, 0x30b1, 0x30b3, 0x30b5, 0x30b7, 0x30b9, 0x30bb, + /* 800..809 */ + 0x30bd, 0x30bf, 0x30c1, 0x30c4, 0x30c6, 0x30c8, 0x30ca, 0x30cb, 0x30cc, 0x30cd, + /* 810..819 */ + 0x30ce, 0x30cf, 0x30d2, 0x30d5, 0x30d8, 0x30db, 0x30de, 0x30df, 0x30e0, 0x30e1, + /* 820..829 */ + 0x30e2, 0x30e4, 0x30e6, 0x30e8, 0x30e9, 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ef, + /* 830..839 */ + 0x30f3, 0x309b, 0x309c, 0x3041, 0x3043, 0x3045, 0x3047, 0x3049, 0x3083, 0x3085, + /* 840..849 */ + 0x3049, 0x3063, 0x3042, 0x3044, 0x3046, 0x3048, 0x304a, 0x304b, 0x304d, 0x304f, + /* 850..859 */ + 0x3051, 0x3053, 0x3055, 0x3057, 0x3059, 0x305b, 0x305d, 0x305f, 0x3061, 0x3064, + /* 860..869 */ + 0x3066, 0x3068, 0x306a, 0x306b, 0x306c, 0x306d, 0x306e, 0x306f, 0x3072, 0x3075, + /* 870..879 */ + 0x3078, 0x307b, 0x307e, 0x307f, 0x3080, 0x3081, 0x3082, 0x3084, 0x3086, 0x3088, + /* 880..889 */ + 0x3089, 0x308a, 0x308b, 0x308c, 0x308d, 0x308f, 0x3092, 0x3093, 0x300e, 0x300f, + /* 890..899 */ + 0x30f6, 0x3005, 0x0000, 0x0000, 0x0000, 0x0000, 0x3131, 0x3132, 0x3133, 0x3134, + /* 900..909 */ + 0x3135, 0x3136, 0x3137, 0x3138, 0x3139, 0x313a, 0x313b, 0x313c, 0x313d, 0x313e, + /* 910..919 */ + 0x313f, 0x3140, 0x3141, 0x3142, 0x3143, 0x3144, 0x3145, 0x3146, 0x3147, 0x3148, + /* 920..929 */ + 0x3149, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e, 0x314f, 0x3150, 0x3151, 0x3152, + /* 930..939 */ + 0x3153, 0x3154, 0x3155, 0x3156, 0x3157, 0x3158, 0x3159, 0x315a, 0x315b, 0x315c, + /* 940..949 */ + 0x315d, 0x315e, 0x315f, 0x3160, 0x3161, 0x3162, 0x3163, 0x20a9, 0x0000, 0x3164, + /* 950..959 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 960..969 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 970..979 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 980..989 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 990..999 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 1000..1009 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 1010..1019 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 1020..1023 */ + 0x0000, 0x0000, 0x0000, 0x0000 +#endif /* MAX_GLYHP > 504 */ +}; + + +/* on Greek systems, the UGL is a bit different */ +/* and changes the entries 319-383 inclusive */ + +/* # of Greek glyphs in UGL */ +#define GREEK_GLYPHS 65 +/* start of Greek glyphs in UGL */ +#define GREEK_START 319 + +static const int SubUGLGreek[GREEK_GLYPHS] = { + /* 319..328 */ + 0x0391, 0x0392, 0x0395, 0x0396, 0x0397, 0x0399, 0x039a, 0x039c, 0x039d, 0x039f, + /* 329..338 */ + 0x03a1, 0x03a4, 0x03a5, 0x03a7, 0x03b7, 0x03bd, 0x03c7, 0x03bf, 0x0384, 0x0308, + /* 339..348 */ + 0x0385, 0x0390, 0x0020, 0x00A6, 0x0386, 0x0388, 0x0389, 0x038a, 0x038c, 0x038e, + /* 349..358 */ + 0x038f, 0x0394, 0x0398, 0x039b, 0x039e, 0x03a0, 0x03a8, 0x03aa, 0x03ab, 0x03ac, + /* 359..368 */ + 0x03ad, 0x03ae, 0x03af, 0x03b0, 0x03b2, 0x03b3, 0x03b6, 0x03b8, 0x03b9, 0x03ba, + /* 369..378 */ + 0x03bb, 0x03bc, 0x03be, 0x03c1, 0x03c2, 0x03c5, 0x03c6, 0x03c8, 0x03c9, 0x03ca, + /* 379..383 */ + 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0x0000 +}; +#endif /* USE_UCONV */ + +#endif /* _FTIFI_H_INCLUDED_ */ diff --git a/contrib/ftos2/ifi/ftmem.c b/contrib/ftos2/ifi/ftmem.c new file mode 100644 index 0000000..f0f15f3 --- /dev/null +++ b/contrib/ftos2/ifi/ftmem.c @@ -0,0 +1,184 @@ +/* */ +/* ** This is part of the FreeType/2 project! ** */ +/* A small utility to display online memory usage stats for FreeType/2 */ +/* */ +/* The method used to keep the window float on top may be completely */ +/* stupid but I found no other way (except putting WinSetWindowPos() */ +/* in the timer code which looks odd). */ +/* */ +/* Copyright (C) 1998 by M. Necasek */ + +#define INCL_DOSMISC +#define INCL_WINTIMER +#define INCL_PM +#include +#include + +#define ID_TIMER 42 +#define IDM_FLOAT 155 + + +/* name of shared memory used for memory usage reporting */ +#define MEM_NAME "\\sharemem\\freetype" + +typedef struct _INFOSTRUCT { + ULONG signature; /* signature (0x46524545, 'FREE') */ + ULONG used; /* bytes actually used */ + ULONG maxused; /* maximum amount ever used */ + ULONG num_err; /* number of (de)allocation errors */ +} INFOSTRUCT, *PINFOSTRUCT; + +/* structure (in named shared memory) pointing to the above struct */ +typedef struct _INFOPTR { + PINFOSTRUCT address; /* pointer to actual memory info */ +} INFOPTR, *PINFOPTR; + +HAB hab; +HWND hwndFrame; +PINFOSTRUCT meminfo; +PINFOPTR memptr; +ULONG bFloat = TRUE; +HWND hwndSysSubmenu; + +VOID AddFloat(HWND hwndFrame) { + MENUITEM mi; + HWND hwndSysMenu; + SHORT sMenuID; + + /* add Float option to system menu */ + hwndSysMenu = WinWindowFromID(hwndFrame, FID_SYSMENU); + sMenuID = (SHORT)WinSendMsg(hwndSysMenu, MM_ITEMIDFROMPOSITION, + MPFROMSHORT(0), MPVOID); + WinSendMsg(hwndSysMenu, MM_QUERYITEM, MPFROMSHORT(sMenuID), + MPFROMP(&mi)); + hwndSysSubmenu = mi.hwndSubMenu; + mi.iPosition = MIT_END; + mi.afStyle = MIS_SEPARATOR; + mi.afAttribute = 0; + mi.id = -1; + mi.hwndSubMenu = 0; + mi.hItem = 0; + WinSendMsg(hwndSysSubmenu, MM_INSERTITEM, MPFROMP (&mi), NULL); + mi.afStyle = MIS_TEXT; + mi.afAttribute = MIA_CHECKED; + mi.id = IDM_FLOAT; + WinSendMsg(hwndSysSubmenu, MM_INSERTITEM, MPFROMP (&mi), "~Float on top"); +} + +MRESULT EXPENTRY ClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) +{ + HPS hps; + RECTL rcl; + static ULONG i = 1; + ULONG ulMem; + char szBuf[200]; + + switch (msg) { + case WM_CREATE: + /* use smaller text */ + WinSetPresParam(hwnd, PP_FONTNAMESIZE, 7, (PVOID)"8.Helv"); + /* start the timer (ticks each 0.5 sec.) */ + AddFloat(WinQueryWindow(hwnd, QW_PARENT)); + WinStartTimer(hab, hwnd, ID_TIMER, 500); + break; + + /* make window always stay on top (if desired) */ + case WM_VRNENABLED: + if (bFloat) + WinSetWindowPos(hwndFrame, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER); + break; + + case WM_COMMAND: /* why doesn't WM_SYSCOMMAND work? */ + if (LOUSHORT(mp1) == IDM_FLOAT) { + bFloat = !bFloat; + WinCheckMenuItem(hwndSysSubmenu, IDM_FLOAT, bFloat); + } + break; + + case WM_TIMER: + if (++i > 13) + i = 1; + WinInvalidateRect(hwnd, NULL, FALSE); + return FALSE; + + case WM_PAINT: + hps = WinBeginPaint(hwnd, NULLHANDLE, &rcl); + /* necessary to avoid incorrectly repainting window */ + WinQueryWindowRect(hwnd, &rcl); + +/* sprintf(szBuf, " Current use %dK Maximum ever used %dK Errors %d", + meminfo->used / 1024, + meminfo->maxused / 1024, meminfo->num_err);*/ + sprintf(szBuf, " Current use %dB Maximum ever used %dK Errors %d", + meminfo->used, + meminfo->maxused / 1024, meminfo->num_err); + WinDrawText(hps, -1, szBuf, &rcl, CLR_BLACK, CLR_WHITE, + DT_CENTER | DT_VCENTER | DT_ERASERECT); + + WinEndPaint(hps); + break; + } + + return WinDefWindowProc(hwnd, msg, mp1, mp2); +} + +void main (void) +{ + QMSG qmsg; + HMQ hmq; + HWND hwndClient; + ULONG flFrameFlags; + + WinInitialize(0); + hmq = WinCreateMsgQueue(hab, 0); + + /* get access to shared memory */ + DosGetNamedSharedMem((PVOID*)&memptr, MEM_NAME, PAG_READ); + if (!memptr) + WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, + " FreeType/2 is not running!", + "Error", 0, MB_OK | MB_ERROR); + + else { + meminfo = memptr->address; + if (meminfo->signature != 0x46524545) + WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, + " FreeType/2 is not running!", + "Error", 0, MB_OK | MB_ERROR); + else { + flFrameFlags = FCF_TITLEBAR | FCF_SYSMENU | + FCF_TASKLIST ; + + WinRegisterClass(hab, "MyClass", + (PFNWP) ClientWndProc, + CS_SIZEREDRAW, 0); + + hwndFrame = WinCreateStdWindow(HWND_DESKTOP, + WS_VISIBLE, + &flFrameFlags, + "MyClass", "FreeType/2 Heap Usage", + 0, (HMODULE) NULL, + 0, &hwndClient); + + WinSetVisibleRegionNotify(hwndClient, TRUE); + + /* make titlebar text look better */ + WinSetPresParam(WinWindowFromID(hwndFrame, FID_TITLEBAR), + PP_FONTNAMESIZE, 9, (PVOID)"8.Helv"); + + WinSetWindowPos(hwndFrame, NULLHANDLE, 0, 0, 350, 42, + SWP_MOVE | SWP_SIZE | SWP_SHOW); + + while (WinGetMsg(hab, &qmsg, (HWND) NULL, 0, 0)) + WinDispatchMsg(hab, &qmsg); + + WinSetVisibleRegionNotify(hwndClient, FALSE); + } + } + /* free shared memory block */ + DosFreeMem(memptr); + + WinDestroyWindow(hwndFrame); + WinDestroyMsgQueue(hmq); + WinTerminate(hab); +} diff --git a/contrib/ftos2/ifi/ftmem.icc b/contrib/ftos2/ifi/ftmem.icc new file mode 100644 index 0000000..c9991f4 --- /dev/null +++ b/contrib/ftos2/ifi/ftmem.icc @@ -0,0 +1,4 @@ +ftmem.exe: $*.obj + ilink /PM:PM /ST:0x8000 /BAS:0x10000 /E:2 /A:4 $*.obj +ftmem.obj: $*.c + icc -C $*.c diff --git a/contrib/ftos2/ifi/ftmem.ico b/contrib/ftos2/ifi/ftmem.ico new file mode 100644 index 0000000..ab730f5 Binary files /dev/null and b/contrib/ftos2/ifi/ftmem.ico differ diff --git a/contrib/ftos2/ifi/test.c b/contrib/ftos2/ifi/test.c new file mode 100644 index 0000000..b793012 --- /dev/null +++ b/contrib/ftos2/ifi/test.c @@ -0,0 +1,238 @@ + +#include + +#include +#include +#include +#include "32pmifi.h" + +//#define USE_ORIG +#ifdef USE_ORIG + #pragma import (fdhdr, "FONT_DRIVER_DISPATCH_TABLE", "TRUETYPE", 0) +#else + #if defined USE_ATM + #pragma import (fdhdr, "FONT_DRIVER_DISPATCH_TABLE", "PMATM", 0) + #else + #pragma import (fdhdr, "FONT_DRIVER_DISPATCH_TABLE", "FREETYPE", 0) + #endif +#endif + +extern FDHEADER fdhdr; + +char *fontnames[20] = { + "G:\\OS2\\MDOS\\WINOS2\\SYSTEM\\SYMBOL.TTF", + "G:\\OS2\\MDOS\\WINOS2\\SYSTEM\\WINGDING.TTF", + "G:\\PSFONTS\\ARIALB.ttf", + "G:\\PSFONTS\\ARIALI.ttf", + "G:\\PSFONTS\\ARIALZ.ttf", + "G:\\PSFONTS\\COUR.TTF", + "G:\\PSFONTS\\COURB.TTF", + "G:\\PSFONTS\\COURI.TTF", + "G:\\PSFONTS\\COURZ.TTF", + "G:\\PSFONTS\\ARIAL.ttf", + "G:\\PSFONTS\\TIMESB.TTF", + "G:\\PSFONTS\\TIMESI.ttf", + "G:\\PSFONTS\\TIMESZ.ttf", + "G:\\PSFONTS\\TIMES.TTF", + "G:\\PSFONTS\\ARIBLK.ttf", + "G:\\CHINESE\\AVSV.TTF", + "G:\\CHINESE\\MINGLI.TTC", + "D:\\PSFONTS\\TNRMT30.TTF" +}; + +#define FNTNAME1 "\\PSFONTS\\TIMES.TTF" +#ifdef USE_ATM + #define FNTNAME2 "\\PSFONTS\\helv.ofm" +#else + #define FNTNAME2 "\\PSFONTS\\symbol.tTf" +#endif + +#define BUFSIZE 32768 + +void ShowChar(PCHARATTR pca, PBITMAPMETRICS pbmm) { + int i, j; + int bufwidth = ((pbmm->sizlExtent.cx + 31) & -32) / 8; + + for (i =0; i < pbmm->sizlExtent.cy; i++) { + for (j = 0; j < bufwidth * 8; j++) + if (pca->pBuffer[i * bufwidth + j / 8] & (1 << (7-(j % 8)))) + printf("*"); + else + printf(" "); + printf("\n"); + } +} + +void main(int argc, char **argv) +{ + char fname[260]; + PFDDISPATCH pfdisp; + LONG rc; + HFF hff, hff2; /* font file */ + HFC hfc, hfc2; /* font context */ + static IFIMETRICS ifimet[12]; /* IFI metrics */ + CONTEXTINFO ci; + CHARATTR charattr; /* character attributes */ + BITMAPMETRICS bmm; /* bit-map metrics */ + PBYTE buf; + int glyph = 0, i, j; + int numFaces; + int faceIndex = 0; + + switch (argc) { + case 4: + strcpy(fname, argv[1]); + glyph = atoi(argv[2]); + faceIndex = atoi(argv[3]); + break; + + case 2: + glyph = atoi(argv[1]); + case 1: + strcpy(fname, FNTNAME1); + break; + + default: + strcpy(fname, argv[1]); + glyph = atoi(argv[2]); + } + + buf = (PBYTE)malloc(BUFSIZE); + if (strncmp("OS/2 FONT DRIVER", fdhdr.strId, 16)) { + printf("Invalid Font Driver\n"); + return; + } + printf("Font Driver OK, "); + printf("Version %d\n", fdhdr.ulVersion); + printf("Technology: %s\n", fdhdr.szTechnology); + + hff = fdhdr.pfddisp->FdLoadFontFile(fname); + printf("Loading font... HFF = %X\n", hff); + if (hff == (HFF)0xFFFFFFFF) + return; + +/* rc = fdhdr.pfddisp->FdConvertFontFile("G:\\PSFONTS\\TIMES.TTF", + "G:\\PSFONTS", buf); */ + +#if 0 + for (i = 0; i < 18; i++) { + hff = fdhdr.pfddisp->FdLoadFontFile(fontnames[i]); + if (hff == (HFF)-1) { + printf("x"); + continue; + } + numFaces = fdhdr.pfddisp->FdQueryFaces(hff, NULL, 0, -1, 0); + if (numFaces < 0) { + printf("x"); + continue; + } + for (j = 0; j < numFaces; j++) { + rc = fdhdr.pfddisp->FdQueryFaces(hff, &ifimet[0], 238, 1, j); + if (rc < 0) { + printf("x"); + continue; + } + } + + rc = fdhdr.pfddisp->FdUnloadFontFile(hff); + if (rc) + printf("x"); + else + printf("."); + } + printf("\n"); +#endif + + hff = fdhdr.pfddisp->FdLoadFontFile(FNTNAME2); + hff = fdhdr.pfddisp->FdLoadFontFile(fname); + rc = fdhdr.pfddisp->FdUnloadFontFile(hff); + + hff = fdhdr.pfddisp->FdLoadFontFile(fname); + printf("Loading font... HFF = %X\n", hff); + if (hff == (HFF)0xFFFFFFFF) + return; + numFaces = fdhdr.pfddisp->FdQueryFaces(hff, NULL, 0, -1, 0); + printf("Number of faces = %d\n", numFaces); + rc = fdhdr.pfddisp->FdQueryFaces(hff, &ifimet[0], sizeof(IFIMETRICS), numFaces, 0); + printf("Querying faces... RC = %X\n", rc); + hfc = fdhdr.pfddisp->FdOpenFontContext(hff, faceIndex); + printf("Opening context... HFC = %X\n", hfc); + if (hfc == (HFC)0xFFFFFFFF) { + rc = fdhdr.pfddisp->FdUnloadFontFile(hff); + printf("Unloading font... RC = %X\n", rc); + } + ci.cb = sizeof(ci); + ci.fl = 0; +/* ci.sizlPPM.cx = 3618; + ci.sizlPPM.cy = 3622; + ci.pfxSpot.x = 46340; + ci.pfxSpot.y = 46340; + ci.matXform.eM11 = 511; + ci.matXform.eM12 = 0; + ci.matXform.eM21 = 0; + ci.matXform.eM22 = 511; */ + ci.sizlPPM.cx = 3622; + ci.sizlPPM.cy = 3622; + ci.pfxSpot.x = 46340; + ci.pfxSpot.y = 46340; + ci.matXform.eM11 = 768; + ci.matXform.eM12 = 0; + ci.matXform.eM21 = 0; + ci.matXform.eM22 = 768; + + rc = fdhdr.pfddisp->FdQueryFaceAttr(hfc, FD_QUERY_ABC_WIDTHS, buf, + sizeof(ABC_TRIPLETS), NULL, glyph); + printf("Querying face attrs... RC = %d\n", rc); + rc = fdhdr.pfddisp->FdQueryFaceAttr(hfc, FD_QUERY_KERNINGPAIRS, buf, + ifimet[0].cKerningPairs * sizeof(FD_KERNINGPAIRS), + NULL, 0); + + + rc = fdhdr.pfddisp->FdSetFontContext(hfc, &ci); + printf("Setting context... rc = %X\n", rc); + + charattr.cb = sizeof(charattr); + charattr.iQuery = FD_QUERY_BITMAPMETRICS | FD_QUERY_CHARIMAGE; +// charattr.iQuery = FD_QUERY_OUTLINE; + charattr.gi = glyph; + charattr.pBuffer = buf; + charattr.cbLen = BUFSIZE; + if (rc == -1) + return; + rc = fdhdr.pfddisp->FdQueryCharAttr(hfc, &charattr, &bmm); + printf("Querying char attrs... bytes = %d\n", rc); + ShowChar(&charattr, &bmm); + +// rc = fdhdr.pfddisp->FdQueryCharAttr(hfc, &charattr, &bmm, NULL); +// printf("Querying char attrs... bytes = %d\n", rc); + + hff2 = fdhdr.pfddisp->FdLoadFontFile(FNTNAME2); + printf("Loading font... HFF = %X\n", hff2); + if (hff2 == (HFF)0xFFFFFFFF) + return; + + charattr.cbLen = 0; + rc = fdhdr.pfddisp->FdQueryCharAttr(hfc, &charattr, &bmm); + printf("Querying char attrs... bytes = %d\n", rc); + rc = fdhdr.pfddisp->FdQueryFaces(hff2, &ifimet[0], sizeof(ifimet), 1, 0); + printf("Querying faces... RC = %X\n", rc); + hfc2 = fdhdr.pfddisp->FdOpenFontContext(hff2, 0); + printf("Opening context... HFC = %X\n", hfc2); + if (hfc2 == (HFC)0xFFFFFFFF) { + rc = fdhdr.pfddisp->FdUnloadFontFile(hff2); + printf("Unloading font... RC = %X\n", rc); + } + rc = fdhdr.pfddisp->FdCloseFontContext(hfc); + printf("Closing context... RC = %X\n", rc); + rc = fdhdr.pfddisp->FdUnloadFontFile(hff); + printf("Unloading font... RC = %X\n", rc); + rc = fdhdr.pfddisp->FdUnloadFontFile(hff); + printf("Unloading font... RC = %X\n", rc); + + rc = fdhdr.pfddisp->FdCloseFontContext(hfc2); + printf("Closing context... RC = %X\n", rc); + rc = fdhdr.pfddisp->FdUnloadFontFile(hff2); + printf("Unloading font... RC = %X\n", rc); + rc = fdhdr.pfddisp->FdUnloadFontFile(hff2); + printf("Unloading font... RC = %X\n", rc); +} diff --git a/contrib/ftos2/ifi/test.icc b/contrib/ftos2/ifi/test.icc new file mode 100644 index 0000000..36a8f0d --- /dev/null +++ b/contrib/ftos2/ifi/test.icc @@ -0,0 +1,6 @@ +test.exe: $*.obj freetype.lib + ilink /DE /PM:VIO /ST:0x1000 $*.obj freetype.lib +test.obj: $*.c + icc -Ti+ -C -Ss -Sp1 $*.c +freetype.lib: $*.dll + implib $*.lib $*.dll diff --git a/contrib/ftos2/ifi/test.wat b/contrib/ftos2/ifi/test.wat new file mode 100644 index 0000000..20dca18 --- /dev/null +++ b/contrib/ftos2/ifi/test.wat @@ -0,0 +1,4 @@ +test.exe: $*.obj + wlink file $*.obj lib freetype.lib import _fdhdr freetype.FONT_DRIVER_DISPATCH_TABLE +test.obj: $*.c + wcc386 -d2 -zp1 $*.c diff --git a/contrib/ftos2/install.cmd b/contrib/ftos2/install.cmd new file mode 100644 index 0000000..44e7a29 --- /dev/null +++ b/contrib/ftos2/install.cmd @@ -0,0 +1,30 @@ +/* */ +call RxFuncAdd "SysLoadFuncs", "RexxUtil", "SysLoadFuncs" +call SysLoadFuncs + + +say "Warning: This is your last chance to back out. If you do not wish to" +say "continue, please just press ENTER. Otherwise please type ""yes""" + +pull letter +if letter <> "YES" then exit + +/* Find drive where OS/2 is installed */ +bootdrive = SysSearchPath('PATH', 'OS2.INI') +/* say os2path */ +bootdrive = left(bootdrive, 2) + +copy "FREETYPE.DLL " || bootdrive || "\os2\dll" +if rc <> 0 then do + say "Error: Could not copy file!" + pause + exit +end + +app = "PM_Font_Drivers" +key = "TRUETYPE" +val = "\OS2\DLL\FREETYPE.DLL" || d2c(0) + +SysIni('BOTH', app, key, val) +say "Font Driver is installed. Please reboot." +pause diff --git a/contrib/ftos2/lib/arch/os2/Makefile.icc b/contrib/ftos2/lib/arch/os2/Makefile.icc new file mode 100644 index 0000000..7d83f33 --- /dev/null +++ b/contrib/ftos2/lib/arch/os2/Makefile.icc @@ -0,0 +1,72 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for IBM VisualAge C++ under OS/2. +# +# You will need nmake. +# +# Use this file while in the lib directory with the following statement: +# +# nmake -f arch\os2\Makefile.icc +# + +ARCH = arch\os2 +FT_MAKEFILE = $(ARCH)\Makefile.icc +FT_MAKE = $(MAKE) -nologo + +CC = icc +CFLAGS = -Wcnd- -Wpro- -Ss -Sp1 -Rn -Ge- -O+ -G4 -Q+ -Iarch\os2 -I. -Iextend +#CFLAGS = -Wcnd- -Wpro- -Ss -Sp1 -Rn -Ge- -Ti+ Q+ -Iarch\os2 -I. -Iextend + +# NOTE: Optimizations are discarded, as it seems that Visual Age +# is buggy when producing ttraster.obj. The resulting code +# crashes under some circumstances (performing vertical dropout +# control when rendering smoothed outlines)! + +TTFILE = $(ARCH)\os2file.c +TTMEMORY = .\ttmemory.c +TTMUTEX = .\ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +SRC_X = extend\ftxgasp.c extend\ftxkern.c extend\ftxpost.c \ + extend\ftxcmap.c extend\ftxwidth.c +OBJS_X = $(SRC_X:.c=.obj) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c \ + ttgload.c ttinterp.c ttload.c ttobjs.c ttraster.c \ + ttextend.c $(PORT) +OBJS_M = $(SRC_M:.c=.obj) $(OBJS_X) + +SRC_S = $(ARCH)\freetype.c +OBJ_S = $(SRC_S:.c=.obj) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +all: + $(FT_MAKE) -f $(FT_MAKEFILE) LIB_FILES="$(OBJS_S)" libttf.lib + +debug: + $(FT_MAKE) -f $(FT_MAKEFILE) LIB_FILES="$(OBJS_M)" libttf.lib + + +$(OBJ_S): $(SRC_S) $(SRC_M) + $(CC) -C $(CFLAGS) /Fo$@ $*.c + +$(OBJS_X): + $(CC) -C $(CFLAGS) /Fo$@ $*.c + +$(ARCH)\os2file.obj: + $(CC) -C $(CFLAGS) /Fo$@ $*.c + +libttf.lib: $(LIB_FILES) + !ilib /nologo /noignorecase /nobackup $@ -+$?,, + +clean: + -del *.obj + -del extend\*.obj + -del arch\os2\*.obj + +distclean: clean + -del libttf.lib + +# end of Makefile.icc diff --git a/contrib/ftos2/lib/arch/os2/Makefile.wat b/contrib/ftos2/lib/arch/os2/Makefile.wat new file mode 100644 index 0000000..3a4cef6 --- /dev/null +++ b/contrib/ftos2/lib/arch/os2/Makefile.wat @@ -0,0 +1,41 @@ +# This file is part of the FreeType project. +# Modified for FTIFI - Mike +# +# It builds the library and test programs using Watcom C/C++ under OS/2. +# +# You will need nmake!! +# If you can change this makefile to work with wmake, please +# inform me. +# +# Use this file while in the lib directory with the following statement: +# +# nmake -f arch\os2\Makefile.icc + +CC = wcc386 +CFLAGS = -4r -Otexan -zp1 -bd -zc -Iarch\os2 -I. -Iextend + +SRC = ttapi.c ttcache.c ttcalc.c ttcmap.c tterror.c \ + ttfile.c ttgload.c ttinterp.c ttlists.c ttload.c \ + ttmemory.c ttmutex.c ttobjs.c ttraster.c ttextend.c \ + \ + extend\ftxgasp.c extend\ftxkern.c + +OBJ = $(SRC:.c=.obj) + +.c.obj: + $(CC) $(CFLAGS) $*.c + +all: libttf.lib + +libttf.lib: $(OBJ) + -move ft*.obj extend + !wlib -c $@ -+$? + +clean: + -del *.obj + -del extend\*.obj + +distclean: clean + -del libttf.lib + +# end of Makefile.wcc diff --git a/contrib/ftos2/lib/ttmemory.c b/contrib/ftos2/lib/ttmemory.c new file mode 100644 index 0000000..38fd979 --- /dev/null +++ b/contrib/ftos2/lib/ttmemory.c @@ -0,0 +1,385 @@ +/******************************************************************* + * + * ttmemory.c 1.2 + * + * Memory management component (body). + * + * Copyright 1996, 1997 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * Portions Copyright 1998 by Michal Necasek + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * Changes between 1.1 and 1.2: + * + * - the font pool is gone. + * + * - introduced the FREE macro and the Free function for + * future use in destructors. + * + * - Init_FontPool() is now a macro to allow the compilation of + * 'legacy' applications (all four test programs have been updated). + * + * Note: This code was slightly adapted for use in the OS/2 + * Font Driver (FreeType/2). + * + ******************************************************************/ + +#include "ttdebug.h" +#include "ttmemory.h" +#include "ttengine.h" + +#define INCL_DEV +#include +#include + +#include + +#undef DEBUG_MEM + +/* -------------------- debugging defs ----------------------- */ +/* DEBUG_MEM creates a file and logs all actions to it */ + +#ifdef DEBUG_MEM + static HFILE MemLogHandle = NULLHANDLE; + static ULONG Written = 0; + static char log[2048] = ""; + static char buf[2048] = ""; + + +char* itoa10( int i, char* buffer ) { + char* ptr = buffer; + char* rptr = buffer; + char digit; + + if (i == 0) { + buffer[0] = '0'; + buffer[1] = 0; + return buffer; + } + + if (i < 0) { + *ptr = '-'; + ptr++; rptr++; + i = -i; + } + + while (i != 0) { + *ptr = (char) (i % 10 + '0'); + ptr++; + i /= 10; + } + + *ptr = 0; ptr--; + + while (ptr > rptr) { + digit = *ptr; + *ptr = *rptr; + *rptr = digit; + ptr--; + rptr++; + } + + return buffer; +} + +static const char* hexstr = "0123456789abcdef"; + +char* itohex2( int i, char* buffer ) + { + buffer[0] = hexstr[ (i >> 12) & 0xF ]; + buffer[1] = hexstr[ (i >> 8 ) & 0xF ]; + buffer[2] = hexstr[ (i >> 4 ) & 0xF ]; + buffer[3] = hexstr[ (i ) & 0xF ]; + buffer[4] = '\0'; + return buffer; +} + +char* itohex4( long i, char* buffer ) +{ + itohex2( (i >> 16) & 0xFFFF, buffer ); + /* We separate the high and low part with a dot to make it */ + /* more readable */ + buffer[4] = '.'; + itohex2( i & 0xFFFF, buffer+5 ); + return buffer; +} + + #define COPY(s) strcpy(log, s) + #define CAT(s) strcat(log, s) + #define CATI(v) strcat(log, itoa10( (int)v, buf )) + #define CATH(v) strcat(log, itohex4( (long)v, buf )) + #define CATW(v) strcat(log, itohex2( (short)v, buf )) + #define WRITE DosWrite(MemLogHandle, log, strlen(log), &Written) + #define ERRRET(e) { COPY("Error at "); \ + CATI(__LINE__); \ + CAT("\r\n"); \ + WRITE; \ + return(e); \ + } + +#else + + #define COPY(s) + #define CAT(s) + #define CATI(v) + #define CATH(v) + #define CATW(v) + #define WRITE + #define ERRRET(e) return(e); + +#endif /* DEBUG_MEM */ + + +#undef TRACK_MEM +/* TRACK_MEM allows online tracking of memory usage online (via shared */ +/* memory). It is used in conjunction with the FTMEM utility. */ + +#ifdef TRACK_MEM + /* name of shared memory used for memory usage reporting */ + #define MEM_NAME "\\sharemem\\freetype" + + /* structure containing memory usage information */ + typedef struct _INFOSTRUCT { + ULONG signature; /* signature (0x46524545, 'FREE') */ + ULONG used; /* bytes actually used */ + ULONG maxused; /* maximum amount ever used */ + ULONG num_err; /* number of (de)allocation errors */ + } INFOSTRUCT, *PINFOSTRUCT; + + /* structure (in named shared memory) pointing to the above struct */ + typedef struct _INFOPTR { + PINFOSTRUCT address; /* pointer to actual memory info */ + } INFOPTR, *PINFOPTR; + + PINFOSTRUCT meminfo; /* struct in shared memory holding usage info */ + PINFOPTR memptr; +#endif + +/* ----------------------------------------------------------------- + + A brief explanation of the memory allocator : + + - We store the block's size in front of it. The size implies the nature + of the block, and selects a de-allocation scheme.. + + - A note on the memory debugging schemes: logging and online tracking + are independent of each other and none, either or both may be used. + + ----------------------------------------------------------------- */ + + /****************************************************************/ + /* */ + /* Allocate a block of memory */ + /* */ + static + void* ft2_malloc( long size ) + { + long* head; + void* base; + int rc; + + /* add header size */ + size += sizeof(long); + + /* Allocate memory accessible from all processes */ + if (( rc = SSAllocMem( (PVOID)&head, size, 0 ))) + { + COPY( "ft2_malloc: block SSAllocMem failed with rc = " ); + CATH( rc ); + CAT ( "\r\n" ); + WRITE; + return NULL; + } + *head = size; + base = (void*)(head + 1); + #ifdef TRACK_MEM + meminfo->used += size; + if (meminfo->used > meminfo->maxused) + meminfo->maxused = meminfo->used; + #endif + return base; + } + + /****************************************************************/ + /* */ + /* Release a block of memory */ + /* */ + int ft2_free( void* block ) + { + long* head; + long size, offset; + int rc, h; + + if (!block) + return -1; + + head = ((long*)block) - 1; + size = *head; + + if (size <= 0) + { + COPY( "ft2_free: negative size !!\r\n" ); + WRITE; + return -1; + } + + rc = SSFreeMem( (PVOID)head ); + if (rc) + { + COPY( "ft2_free: block SSFreeMem failed with rc = " ); + CATI( rc ); + CAT ( "\r\n" ); + WRITE; + } + #ifdef TRACK_MEM + meminfo->used -= size; + #endif + return rc; + } + +/******************************************************************* + * + * Function : TT_Alloc + * + * Description : Allocates memory from the heap buffer. + * + * Input : Size size of the memory to be allocated + * P pointer to a buffer pointer + * + * Output : Error code. + * + * NOTE: The newly allocated block should _always_ be zeroed + * on return. Many parts of the engine rely on this to + * work properly. + * + ******************************************************************/ + + TT_Error TT_Alloc( long Size, void** P ) + { + if ( Size ) + { + *P = ft2_malloc( Size ); + if (!*P) { + #ifdef TRACK_MEM + meminfo->num_err++; + #endif + return TT_Err_Out_Of_Memory; + } + + /* MEM_Set( *P, 0, Size); */ /* not necessary, SSAllocMem does it */ + } + else + *P = NULL; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Free + * + * Description : Releases a previously allocated block of memory. + * + * Input : P pointer to memory block + * + * Output : Always SUCCESS. + * + * Note : The pointer must _always_ be set to NULL by this function. + * + ******************************************************************/ + + TT_Error TT_Free( void** P ) + { + if ( !P || !*P ) + return TT_Err_Ok; + + if (ft2_free( *P )) { + #ifdef TRACK_MEM + meminfo->num_err++; + #endif + } + *P = NULL; + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTMemory_Init + * + * Description : Initializes the memory. + * + * Output : Always SUCCESS. + * + ******************************************************************/ + + TT_Error TTMemory_Init() + { + int rc; + + #ifdef DEBUG_MEM + ULONG Action; + + DosOpen("C:\\FTMEM.LOG", &MemLogHandle, &Action, 0, FILE_NORMAL, + OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS, + OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_WRITE_THROUGH | + OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYWRITE | OPEN_ACCESS_WRITEONLY, + NULL); + + COPY("FTMEM Init.\r\n"); + WRITE; + + #endif /* DEBUG */ + + #ifdef TRACK_MEM + /* allocate named shared memory and global shared memory */ + + SSAllocMem(&meminfo, 4096, 0); + DosAllocSharedMem((PVOID*)&memptr, MEM_NAME, 4096, fALLOC); + memptr->address = meminfo; + meminfo->signature = 0x46524545; /* 'FREE' */ + meminfo->maxused = 0; + meminfo->used = 0; + #endif /* TRACK */ + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTMemory_Done + * + * Description : Finalizes memory usage. + * + * Output : Always SUCCESS. + * + ******************************************************************/ + + TT_Error TTMemory_Done() + { + /* Never called by the font driver (beats me why). We do not + release the heaps */ + + #ifdef TRACK_MEM + DosFreeMem(memptr); /* free shared memory */ + SSFreeMem(meminfo); + #endif + #ifdef DEBUG_MEM + COPY("FTMEM Done.\r\n"); + WRITE; + DosClose(MemLogHandle); + #endif + return TT_Err_Ok; + } + + +/* END */ diff --git a/contrib/ftos2/limit.cmd b/contrib/ftos2/limit.cmd new file mode 100644 index 0000000..807deda --- /dev/null +++ b/contrib/ftos2/limit.cmd @@ -0,0 +1,63 @@ +/* */ +call RxFuncAdd "SysLoadFuncs", "RexxUtil", "SysLoadFuncs" +call SysLoadFuncs + +Parse Upper Arg a1 a2 + +app = "FreeType/2" +key = "OPENFACES" + +if Arg() = 0 then call usage + +if a1 = 'Q' then call query + +if a1 = 'S' then call set +call usage + +set: + +val = a2 + +if val = '' then do + say 'Invalid limit!' + exit +end + +if val < 8 then do + say 'The lowest acceptable limit is 8!' + pause + exit +end + +szval = val || d2c(0) + +rc = SysIni('USER', app, key, szval) +say rc +if rc = 'ERROR:' then do + say 'Error updating OS2.INI!' + pause + exit +end + +say "Open faces limit updated to " || val || ". Please reboot to activate changes." +pause +exit + +query: +val = SysIni('USER', app, key) +if val = "ERROR:" then val = "not set" +/* strip the terminating NULL character */ +else val = substr(val, 1, pos(d2c(0), val) - 1) + +say 'The current open faces limit is ' || val +pause +exit + +usage: +say 'This program is used to set the limit of concurrently open typefaces for' +say 'FreeType/2. Use lower numbers to limit memory consumption and higher to' +say 'improve performance if you use lots of fonts.' +say +say 'Usage: LIMIT q - query the current limit' +say ' LIMIT s - set limit to (effective on next reboot).' +pause diff --git a/contrib/ftos2/query.cmd b/contrib/ftos2/query.cmd new file mode 100644 index 0000000..532c8e6 --- /dev/null +++ b/contrib/ftos2/query.cmd @@ -0,0 +1,15 @@ +/* */ +call RxFuncAdd "SysLoadFuncs", "RexxUtil", "SysLoadFuncs" +call SysLoadFuncs + +app = "PM_Font_Drivers" +key = "TRUETYPE" + +val = SysIni('USER', app, key) + +if val = "ERROR:" then val = "none" +/* strip the terminating NULL character */ +else val = substr(val, 1, pos(d2c(0), val) - 1) + +say 'The current TrueType driver is ' || val +pause diff --git a/contrib/ftos2/readme.1st b/contrib/ftos2/readme.1st new file mode 100644 index 0000000..ea5f403 --- /dev/null +++ b/contrib/ftos2/readme.1st @@ -0,0 +1,87 @@ +This is the source code from the FreeType/2 OS/2 font driver. +Copyright (C) 1997-1998 Michal Necasek (mike@mendelu.cz). + +Here's a description of the files in this package : + + readme.1st This file + + readme.txt The FreeType/2 Readme + + FAQ The FreeType/2 user faq + + DEVELFAQ The FreeType/2 developer faq. Read it before trying to + compile this program + + install.cmd The FreeType/2 installation script + uninstall.cmd The FreeType/2 uninstallation script + query.cmd A script used to query the name of the current font driver + + limit.cmd The driver controls the number of font files it keeps + opened at the same time, in order to save system resources + and memory (of course, this _doesn't_ limit the number of + opened fonts in PM, it just saves a _lot_ of memory when + many fonts are installed on your system). + + This script let you change this limit. It can be useful + if you use font-intensive applications (like DTP) and + want better performance (to the sake of memory). + + update.cmd The FreeType/2 update script + ifi/ Source code of the FreeType/2 font driver proper + + + lib/ files that must be added to the standard FreeType 1.1 + release. They take the place of the files located in + the corresponding "lib" file. + + lib/ttmemory.c replacement for the FreeType memory + manager component. This one uses the GRE + shared memory segment allocater, and is + required. + + lib/arch/makefile.icc Makefile to compile the FreeType library for + FreeType/2 with Visual Age. You'll need nmake. + + lib/arch/makefile.wat Makefile to compile with Watcom. NOTE that + you'll ALSO need nmake (wmake won't work !!) + + +Here's how to compile the font driver. + +0. Read the DEVELFAQ ! Now ! Then make a WPS backup ! + +1. Get the FreeType library, and copy the "lib" hierarchy into it to + replace the related files (i.e. ttmemory.c and makefiles). + +2. Compile FreeType with the new files, simply go to "freetype/lib" + and type : + + nmake -f arch\os2\makefile.icc for VisualAge + nmake -f arch\os2\makefile.wat for Watcom + +3. Adjust the makefiles in "ifi" to reflect the location of the + library file "libttf.lib" that was generated previously. + +5. Compile the font driver. Go to the "ft_os2/ifi" directory, then type + + nmake -f freetype.icc for VisualAge + nmake -f freetype.wat for Watcom + + You should have created a file called "FreeType.dll". Copy it to + your "ft_os2" directory.. + +6. Run the "install.cmd" script, then reboot after closing all + applications. + +7. When your desktop is back, go to the font palette and try to + install some new TrueType fonts. Enjoy the difference :-) + +8. You can also compile a small memory usage dumper called "ftmem.c" + to know how much memory the driver is using. Simply do + + nmake -f ftmem.icc for VisualAge + nmake -f ftmem.wat for Watcom + + Then launch it. A small window will appear with the current amount + of memory allocated by the driver. + diff --git a/contrib/ftos2/readme.txt b/contrib/ftos2/readme.txt new file mode 100644 index 0000000..a03fd2b --- /dev/null +++ b/contrib/ftos2/readme.txt @@ -0,0 +1,113 @@ + + * * * FreeType/2 * * * + + (Version 1.0, 5. November 1998) + + Copyright (C) 1997,1998 Michal Necasek + Copyright (C) 1997,1998 The FreeType Development Team + + + Motto: "OS/2 is dead? Again? Thanks for telling me, I'd never notice!" + + + *** if you are upgrading from previous version, please see the FAQ (Q15) *** + + +- First a short Q&A: + +Q1: What's this? +A1: This is what OS/2 users have been waiting for only too long - a free, + high-quality TrueType renderer a.k.a. Font Driver conforming to the + OS/2 Intelligent Font Interface specification. It is based on FreeType - + a free portable library for using TrueType fonts. + Please note that although this code is free the FreeType team and + I will cheerfully accept any donations by happy users ;-) (not that I + expect to get any) + +Q2: How do I use this? +A2: Go to OS/2 command line and run INSTALL.CMD from the directory containing + FREETYPE.DLL. This will replace the original IBM TrueType driver if it is + installed. + +Q3: Where's the disclaimer? +A3: No, don't worry, I didn't forget that. I of course provide NO WARRANTY + that this code will work as you expect. Use only at your OWN RISK! + +Q4: What should I do RIGHT NOW? +A4: Before attempting to install this driver, you are STRONGLY advised + to archive your current configuration (Set Desktop Properties/Archive/ + Create archive at each startup, then reboot. Then of course switch archiving + off). It is always possible your system won't boot with the font driver + installed. You can risk it, but I warned you! You know how nasty the + computers can be ;-) + +Q5: What about the license? +A5: This code is distributed under the FreeType license. + It is free and the source code is available as part of the FreeType + distribution. + +Q6: How do I get rid of this? +A6: Ah, right question. Just run UNINSTALL.CMD. That removes the font driver + (not physically, it just isn't used on next startup) and restores the + original TRUETYPE.DLL if it exists. + +Q7: Is there something else? +A7: Yes, be prepared that the fonts just kick ass! You will no longer have + to envy those poor souls still using the so-called 95% OS from THAT + unspeakable company starting with the letter M ;-) + + +- Current features/bugs/limitations: + + Features : - outlines + - scaled/rotated text + - supports printed output + - works with TTCs (TrueType collections) + - national characters (if provided in the font, of course); + should work with all Latin codepages, Cyrillic and Greek. + - partial DBCS support - Traditional Chinese should work about + 98%. Fonts like Times New Roman MT30 should work on all + systems. If you want your language to be supported, you can + apply at and become a Beta tester. + + Bug/feature: - unharmonious glyph spacing in some applications. This seems + to come from OS/2's WYSIWYG glyph placement policy. This + is more or less visible depending on the application. We + can't do a lot about this... At least it's true WYSIWYG and + no nasty surprises when printing. + + + Limitations: - no grayscaling (a.k.a. antialiasing) - this is a limitation + of OS/2, not my code. If OS/2 starts supporting it, I'll + implement it the moment I lay my hands on the specs :) + Unfortunately it most probably won't happen any too soon. + Anyway, you have to bug IBM about this one, not me! + +- Planned features and features under consideration: + - possibly adding even support for Type 1 fonts, but that depends on + further FreeType engine development. Looks quite probable now. + +And finally, thanks go to: + - the FreeType team, the makers of FreeType. Without them, my work would be + impossible. + - especially David Turner of FreeType for his help, advice and support + - Robert Muchsel, I used one or two ideas from his code + - Marc L Cohen, Ken Borgendale and Tetsuro Nishimura from IBM. They provided + me with lots of extremely valuable 'inside' information. + - and last but not least - IBM, for providing us with the wonderful OS/2. + And for giving out the necessary docs for free. If all companies did + that, the world would be a better place. + + +Information on FreeType is available at + http://www.freetype.org + +Please send bug reports/suggestions and comments to : + + freetype-os2@physiol.med.tu-muenchen.de + + +Greetings can also be sent directly to the author at : mike@mendelu.cz + +And if you didn't know, IBM and OS/2 are registered trademarks of the +International Business Machines Corporation. diff --git a/contrib/ftos2/uninst.c b/contrib/ftos2/uninst.c new file mode 100644 index 0000000..da3380b --- /dev/null +++ b/contrib/ftos2/uninst.c @@ -0,0 +1,60 @@ +/* */ +/* UNINST - FreeType/2 uninstaller */ +/* */ +/* Copyright 1998 Michal Necasek */ +/* */ +/* UNINSTALL.CMD rewritten in C - apparently the REXX version fails */ +/* when OS/2 is booted to command line. This causes problems if */ +/* FreeType/2 prevents PM from starting successfully. */ +/* */ +/* Note: This can be compiled as 16-bit app to keep the size down. */ + +#define INCL_NOXLATE_WIN16 +#define INCL_NOXLATE_DOS16 +#define INCL_WINSHELLDATA +#define INCL_DOSMISC +#include + +#include +#include +#include + +char szApp[] = "PM_Font_Drivers"; +char szKey[] = "TRUETYPE"; +char szBuffer[300]; + +void main(void) { + ULONG ulBootDrv; + USHORT usLen = 0; + APIRET rc; + char c; + + usLen = PrfQueryProfileString(HINI_USERPROFILE, szApp, szKey, NULL, + (PVOID)szBuffer, 260L); + + if (!strcmp("\\OS2\\DLL\\FREETYPE.DLL", szBuffer)) { + if(!PrfWriteProfileString(HINI_USERPROFILE, szApp, szKey, NULL)) + goto err; + + printf("FreeType/2 successfully removed.\n"); + printf("Do you wish to restore TRUETYPE.DLL (y/n)? "); + c = getch(); + if (c != 'y' && c != 'Y') + return; + + if(!PrfWriteProfileString(HINI_USERPROFILE, szApp, szKey, + "\\OS2\\DLL\\TRUETYPE.DLL")) + goto err; + + printf("\nTRUETYPE.DLL successfully restored"); + } + else { + printf("FreeType/2 not installed!"); + return; + } + + return; + +err: + printf("Uninstallation failed!"); +} diff --git a/contrib/ftos2/uninstall.cmd b/contrib/ftos2/uninstall.cmd new file mode 100644 index 0000000..bf13f68 --- /dev/null +++ b/contrib/ftos2/uninstall.cmd @@ -0,0 +1,34 @@ +/* */ +call RxFuncAdd "SysLoadFuncs", "RexxUtil", "SysLoadFuncs" +call SysLoadFuncs + + +say "This utility will remove the FreeType/2 font driver and install " +say "the original TRUETYPE.DLL if it exists. If you do not wish to" +say "continue, please just press ENTER. Otherwise please type ""y""" + +pull letter +if letter <> "Y" then exit + +/* Find drive where OS/2 is installed */ +bootdrive = SysSearchPath('PATH', 'OS2.INI') +bootdrive = left(bootdrive, 1) + +app = "PM_Font_Drivers" +key = "TRUETYPE" + +/* look for TRUETYPE.DLL */ +rc = SysFileTree(left(bootdrive,1) || ":\OS2\DLL\TRUETYPE.DLL", "file", "F") + +if file.0 = 1 then do + say "Restoring TRUETYPE.DLL..." + val = "\OS2\DLL\TRUETYPE.DLL" || d2c(0) + SysIni('BOTH', app, key, val) +end +else do + say "Uninstalling FREETYPE.DLL..." + SysIni('BOTH', app, key, "DELETE:") +end + +say "FTIFI is uninstalled. Please reboot." +pause diff --git a/contrib/mac/mac.hqx b/contrib/mac/mac.hqx new file mode 100644 index 0000000..cd33ac5 Binary files /dev/null and b/contrib/mac/mac.hqx differ diff --git a/contrib/ttf2bdf/.cvsignore b/contrib/ttf2bdf/.cvsignore new file mode 100644 index 0000000..f910b83 --- /dev/null +++ b/contrib/ttf2bdf/.cvsignore @@ -0,0 +1,5 @@ +ttf2bdf +config.status +config.cache +config.log +Makefile diff --git a/contrib/ttf2bdf/Makefile.in b/contrib/ttf2bdf/Makefile.in new file mode 100644 index 0000000..e5d5a39 --- /dev/null +++ b/contrib/ttf2bdf/Makefile.in @@ -0,0 +1,74 @@ +# +# $Id: Makefile.in,v 1.4 1998/12/06 18:50:22 mleisher Exp $ +# + +# +# Copyright 1996, 1997, 1998 Computing Research Labs, New Mexico State +# University +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +# OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR +# THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +RM = @RM@ +MKINSTALLDIRS = ../../mkinstalldirs + +CC = @CC@ +CFLAGS = @XX_CFLAGS@ @CFLAGS@ + +SRCS = remap.c ttf2bdf.c +OBJS = remap.o ttf2bdf.o + +# +# Point these at the FreeType source directories. +# +INCS = @CPPFLAGS@ +LIBS = @LIBS@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +mandir = @mandir@ + +all: ttf2bdf + +ttf2bdf: $(OBJS) + $(PURIFY) $(CC) $(STATIC) $(CFLAGS) -o ttf2bdf $(OBJS) $(LIBS) + +clean: + $(RM) -f *.o *BAK *CKP *~ a.out core + +realclean: clean + $(RM) -f ttf2bdf + +distclean: clean + $(RM) -f ttf2bdf config.* Makefile + +.c.o: + $(CC) $(CFLAGS) $(INCS) -c $< -o $@ + +install: ttf2bdf + @$(MKINSTALLDIRS) $(bindir) $(mandir)/man1 + @cp ttf2bdf $(bindir)/ttf2bdf + @cp ttf2bdf.man $(mandir)/man1/ttf2bdf.1 + +uninstall: + @$(RM) -f $(bindir)/ttf2bdf + @$(RM) -f $(mandir)/man1/ttf2bdf.1 + +# end of Makefile diff --git a/contrib/ttf2bdf/README b/contrib/ttf2bdf/README new file mode 100644 index 0000000..f5ac32e --- /dev/null +++ b/contrib/ttf2bdf/README @@ -0,0 +1,315 @@ +# +# $Id: README,v 1.18 1999/08/19 16:30:24 mleisher Exp $ +# + +# +# Copyright 1996, 1997, 1998, 1999 Computing Research Labs, +# New Mexico State University +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +# OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR +# THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +This is version 2.7 of a program to convert TrueType fonts to BDF fonts using +the FreeType renderer. + +BDF fonts can be edited using the XmBDFEditor which is available from (replace +the with the most current version number): + + [Sources] + ftp://crl.nmsu.edu/CLR/multiling/General/xmbdfed.tar.gz + + [Binaries: Linux/Pentium, Solaris, SunOS] + ftp://crl.nmsu.edu/CLR/multiling/General/xmbdfed--ELF.tar.gz + ftp://crl.nmsu.edu/CLR/multiling/General/xmbdfed--SOLARIS.tar.gz + +COMPILING ttf2bdf +----------------- + +1. Pick up the latest FreeType distribution from: + +ftp://ftp.physiol.med.tu-muenchen.de/pub/freetype/devel/freetype-current.tar.gz + +2. Unpack FreeType and build it. + +3. Go into the "contrib/ttf2bdf/" directory and type "make" to build "ttf2bdf". + +RUNNING ttf2bdf +--------------- + +Type the following to get a list of command line options: + + % ttf2bdf -h + +ACKNOWLEDGEMENTS +---------------- + +Thanks go to the following people: + + Robert Wilhelm for pointing out a + crucial problem with the pre-1.0 code. + + Lho Li-Da for pointing out a problem with Big5 and + GB2312 encoding ids being documented incorrectly in the TT docs and a + problem with glyphs that are height 1 or width 1, and a font name problem. + + Adrian Havill for unintentionally pointing out a + missing feature. + + Richard Verhoeven for pointing out a font names problem, + problem with bitmaps missing their last byte in each row, and an invalid + FONT_DESCENT property value. + + Choi Jun Ho for his inspiration from his + implementation that changed some character set names, and added a + number of new command line parameters. + + Pavel Kankovsky for providing some + critical grid fitting and metrics fixes when generating the bitmaps, + adding the code to "auto-detect" bold and italic fonts, removing the + dependency on ttobjs.h, finding some remapping bugs, and other fixes. + + Matti Koskinen for pointing out a problem with using + the code 0xffff. + + Eugene Bobin for contributing the Cyrillic mapping + tables (iso8859.5, koi8.r, windows.1251) and the sample shell scripts for + generating sets of BDF fonts. + + Oleg N. Yakovlev for alerting me to the + problem of certain codes not being loaded correctly in the mapping tables. + + Bertrand Petit for providing additional command line + parameters to allow more control over the XLFD name generated. + + Roman Czyborra for pointing out the need for a + change from UNICODE-2.0 to ISO10646-1 in the font XLFD name. + + Mike Blazer for pointing out the include changes + needed to compile on Windows. + + Solofo Ramangalahy for contributing the ISO8859.1 and + ISO8859.3 mapping tables. + + Antoine Leca for suggesting the exchange of + columns in the mapping table to better fit the mapping table format used by + many. + + Robert Brady for pointing out a problem with the + length of _XFREE86_GLYPH_RANGES properties and an Exceed font compiler. + +CHANGES +------- +Version 2.7 +=========== + 1. Swapped all the columns in the mapping files. + + 2. Changed the mapping table loader to index on the second column instead of + the first. + + 3. Reduced the line length of _XFREE86_GLYPH_RANGES properties to 256 + instead of 512. + +Version 2.6 +=========== + 1. Changed the includes to deal with compilation on Windows. + + 2. Added some new mapping tables. + +Version 2.5 +=========== + 1. Updated the copyright dates. + + 2. Fixed an incorrect parameter for Traditional C compilers. + + 3. Added generation of the _XFREE86_GLYPH_RANGES properties. + +Version 2.4 +=========== + 1. Change all CRLF's, CR's, or LF's in copyright strings to double spaces. + + 2. Changed it so gcc 2.8.1 likes the return type of main() again. + +Version 2.3 +=========== + 1. Changed Makefile.in a bit to make installation more consistent. + + 2. Changed the lower limit for the vertical and horizontal resolutions to be + 10dpi instead of 50dpi. + +Version 2.2 +=========== + 1. Added missing documentation in the manual page. + + 2. Added the `-u' parameter to allow setting the character used to replace + dashes or spaces in the font name. + + 3. Changed the CHARSET_REGISTRY and CHARSET_ENCODING to be "ISO10646-1" + instead of "Unicode-2.0". + + 4. The numGlyphs property comes back incorrect for some fonts, so the loop + cycles through all 65536 possibilities every time now. + +Version 2.1 +=========== + 1. Added patches provided by Bertrand Petit. + + 2. Insured compatibility with FreeType 1.1. + +Version 2.0 +=========== + 1. Created two new subdirectories. One for mapping tables and one for any + other contributed code, scripts, or data. + + 2. Updated Cyrillic mapping files sent by Eugene Bobin. + + 3. Minor fixes to make compatible with the latest version of FreeType. + +Version 1.9 +=========== + 1. Fixed a problem with the first code of a mapping table being lost. + +Version 1.8 +=========== + 1. Added the Unicode->Cyrillic mapping tables provided by Eugene Bobin. + + 2. Created a shell script based on Eugene Bobin's scripts to generate sets + of BDF fonts at one time. + +Version 1.7 +=========== + 1. If a remapping table is provided, code ranges are now expected to be + specified in terms of the codes in the mapping table. + + 2. The glyph generation loop is improved a bit. + +Version 1.6 +=========== + 1. Added two expected keywords REGISTRY and ENCODING in the remap files. + These values are used when the font's XLFD name is generated. + + 2. Added TTF2BDF_VERSION macro used for adding the "Converted by" comment. + + 3. Handle the case of no glyphs being generated. No BDF font is produced. + + 4. Updated for new API with TT_Engine. + +Version 1.5 +=========== + 1. Fixed a problem with updating the average width field of the XLFD + font name. + + 2. Changed things so bitmaps are generated to a temporay file so an + accurate count and metrics can be calculated. + + 3. Changed things so the font header is not generated until the bitmaps + have been generated. This allows accurate calculations of the various + fields needed. + + 4. Added the '-l' command line parameter that allows specification of a + subrange of glyphs to generate. The syntax is the same as that used in + X11 for subranges. See the X11 XLFD documentation, page 9 for more + detail. + + Example: + + % ttf2bdf -l '60 70 80_90' font.ttf -o font.bdf + + The command above will only generate the glyphs for codes 60, 70, + and 80 through 90 inclusive. + + 5. Added the ability to load a mapping table that will remap a font to + another character set. The mapping table should have two columns. + + The first column should be the hexadecimal code of the glyph in the + "cmap" table ttf2bdf is using. The second column should have the + code which should be used in the BDF font. An example mapping file + is provided which will map fonts from Unicode (default cmap table) to + ISO8859-2. + + 6. Fixed grid fitting to avoid dropout in some cases. + + 7. Removed dependency on ttobjs.h by using the new API function for + retrieving strings. + + 8. Removed warning about getpid() on Solaris. + + 9. Rearranged the man page a bit to be more useful. Minor + improvements also done. + + 10. Changed the loop so it does not include 0xffff as a code because + it causes crashes when converting some fonts. + +Version 1.4 [Never released as binaries] +=========== + 1. Changed the names of two MS encodings (Wansung and Johab) to + KSC5601.1987 and KSC5601.1992. + + 2. Added the '-n' command line flag to turn hinting off. + + 3. Added the '-c' command line flag to set the font spacing. + + 4. Added the '-t', '-w', and '-s' command line options to override the + default typeface, weight and slant names. + +Version 1.3 +=========== + 1. Converted to use the new FreeType API. + + 2. Added the '-rh' and '-rv' command line parameters to allow both the + horizontal and vertical resolutions to be set individually. + + 3. Fixed a problem with ignoring undefined glyphs. All undefined were + being rendered which caused missing glyphs on the end. + + 4. Fixed a problem with offset calculations needed to render glyph + bitmaps. + +Version 1.2 +=========== + 1. Fixed a problem with dashes that appear in the font family name causing + parse problems with the XLFD font names. + + 2. Fixed a problem with certain bitmaps missing their final byte on each + row. + + 3. Fixed an incorrect FONT_DESCENT value. + + 4. Changed things around so names can be retrieved in a more general way. + + 5. Fixed a problem with bitmaps not being generated after a certain point. + +Version 1.1 +=========== + 1. Fixed the actual glyph count for the CHARS line. + + 2. Swapped the Big5 and GB2312 XLFD encoding strings because of incorrect TT + specifications. + + 3. Fixed a problem with bitmap generation for glyphs that are width 1 or + height 1. + + 4. Added command line parameters to set the font and render pool memory + sizes in Kilobytes from the command line. + +Version 1.0 +=========== + 1. Initial release. + +mleisher@crl.nmsu.edu (Mark Leisher) +15 October 1997 diff --git a/contrib/ttf2bdf/configure b/contrib/ttf2bdf/configure new file mode 100644 index 0000000..197aaa7 --- /dev/null +++ b/contrib/ttf2bdf/configure @@ -0,0 +1,1357 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=../../lib/freetype.h + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:529: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:559: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:610: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:642: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 653 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:658: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:684: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:689: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:717: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + + +OLDLIBS=$LIBS +LIBS="$LIBS -L../../lib/.libs" +CPPFLAGS="$CPPFLAGS -I../../lib" +echo $ac_n "checking for TT_Init_FreeType in -lttf""... $ac_c" 1>&6 +echo "configure:753: checking for TT_Init_FreeType in -lttf" >&5 +ac_lib_var=`echo ttf'_'TT_Init_FreeType | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lttf $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lttf" +else + echo "$ac_t""no" 1>&6 + + { echo "configure: error: Can't find ttf library! Compile FreeType first." 1>&2; exit 1; } +fi + + + + +if test "x$CC" = xgcc; then + XX_CFLAGS="-Wall -pedantic" +else + case "$host" in + alpha-dec-osf*) + XX_CFLAGS="-std1 -O2 -g3" + ;; + *) + XX_CFLAGS= + ;; + esac +fi + + +# Extract the first word of "rm", so it can be a program name with args. +set dummy rm; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:814: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RM'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RM"; then + ac_cv_prog_RM="$RM" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RM="rm" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +RM="$ac_cv_prog_RM" +if test -n "$RM"; then + echo "$ac_t""$RM" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:842: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:863: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:880: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:897: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + +echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 +echo "configure:922: checking for ANSI C header files" >&5 +if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +#include +#include +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:935: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + ac_cv_header_stdc=yes +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "memchr" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "free" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +if test "$cross_compiling" = yes; then + : +else + cat > conftest.$ac_ext < +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int main () { int i; for (i = 0; i < 256; i++) +if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); +exit (0); } + +EOF +if { (eval echo configure:1002: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + : +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_header_stdc=no +fi +rm -fr conftest* +fi + +fi +fi + +echo "$ac_t""$ac_cv_header_stdc" 1>&6 +if test $ac_cv_header_stdc = yes; then + cat >> confdefs.h <<\EOF +#define STDC_HEADERS 1 +EOF + +fi + +for ac_hdr in unistd.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1029: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1039: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + +echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6 +echo "configure:1067: checking for 8-bit clean memcmp" >&5 +if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_memcmp_clean=no +else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_func_memcmp_clean=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_func_memcmp_clean=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$ac_cv_func_memcmp_clean" 1>&6 +test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.${ac_objext}" + + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir + +trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@CC@%$CC%g +s%@XX_CFLAGS@%$XX_CFLAGS%g +s%@RM@%$RM%g +s%@CPP@%$CPP%g +s%@LIBOBJS@%$LIBOBJS%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/contrib/ttf2bdf/configure.in b/contrib/ttf2bdf/configure.in new file mode 100644 index 0000000..dfe17a2 --- /dev/null +++ b/contrib/ttf2bdf/configure.in @@ -0,0 +1,40 @@ +dnl $Id: configure.in,v 1.1 1998/01/14 21:45:26 mleisher Exp $ +dnl Process this file with autoconf to produce a configure script. + +AC_INIT(../../lib/freetype.h) + +AC_PROG_CC + +OLDLIBS=$LIBS +LIBS="$LIBS -L../../lib/.libs" +CPPFLAGS="$CPPFLAGS -I../../lib" +AC_CHECK_LIB(ttf, TT_Init_FreeType, LIBS="$LIBS -lttf",[ + AC_MSG_ERROR([Can't find ttf library! Compile FreeType first.])]) +AC_SUBST(LIBS) + +dnl get Compiler flags right. + +if test "x$CC" = xgcc; then + XX_CFLAGS="-Wall -pedantic" +else + case "$host" in + alpha-dec-osf*) + XX_CFLAGS="-std1 -O2 -g3" + ;; + *) + XX_CFLAGS= + ;; + esac +fi +AC_SUBST(XX_CFLAGS) + +AC_CHECK_PROG(RM, rm, rm) + +dnl Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS(unistd.h) + +dnl Checks for library functions. +AC_FUNC_MEMCMP + +AC_OUTPUT(Makefile) diff --git a/contrib/ttf2bdf/contrib/KOI2iso_pcf b/contrib/ttf2bdf/contrib/KOI2iso_pcf new file mode 100644 index 0000000..b88caa7 --- /dev/null +++ b/contrib/ttf2bdf/contrib/KOI2iso_pcf @@ -0,0 +1,28 @@ +#!/usr/local/bin/perl +# +# hack a XFLD info - alias all fonts, declared as koi8*, to iso8859-1 +# +# usage: +# cd fontdir; ../ISO2koi < fonts.dir >> fonts.alias +# +# 1996/08/29 - vsv +# +while (<>) { + chop; + ($z, $koi8) = split /[ \t]+/; + $iso = $koi8; + $iso =~ s/-koi8r-1/-iso8859-1/g; + $iso =~ s/-koi8-1/-iso8859-1/g; + $iso =~ s/-koi8-r/-iso8859-1/g; + $iso =~ s/-cronyx-/-adobe-/g; + $iso =~ s/-cronix-/-adobe-/g; + ## $iso =~ s/-cronix-/-hack-/g; + ## $iso =~ s/-cronyx-/-hack-/g; + # Elvis+ fonts... + ## $iso =~ s/-adobe-/-hack-/g; + ## $iso =~ s/-dec-/-hack-/g; + next if ("$iso" !~ /-iso8859-/); + @z = split (/-/, $iso); + # no matter, 10 or 12, must be more then 3-4 ;) + printf ("\"%s\"\t\"%s\"\n", $iso, $koi8) if (@z > 10); +} diff --git a/contrib/ttf2bdf/contrib/creatett b/contrib/ttf2bdf/contrib/creatett new file mode 100644 index 0000000..4dc27c7 --- /dev/null +++ b/contrib/ttf2bdf/contrib/creatett @@ -0,0 +1,60 @@ +#!/bin/csh +# -*- mode:SH; -*- +# +# This script creates series of bdf files from TTF file. +# +# +# Please set up parameters +# +# Font dpi: +set DPI=96 + +# +# TrueType files dir. +set ttf_dir=~/ttf + +# TTF files, please specify only base name +# Script will try to use BolD, Italic and BoldItalic versions of face +set FACES="ARIAL ARIBLK ARIALN TAHOMA TIMES VERDANA" + + +# Output codepage +# koi8.r +# windows.1251 +# iso8859.5 +# iso8859.2 +set LANG_ID=koi8.r + +foreach x ( 7 8 9 10 11 12 14 16 18 20 24 30 50 100 150) +foreach z ( $FACES ) +set y = ${ttf_dir}/${z} +# +# Simple face + if( -e ${y}.TTF ) then + echo ${y} at ${x}pt + ./ttf2bdf -m $LANG_ID -p $x -r $DPI ${y}.TTF | bdftopcf | compress > ${DPI}dpi/${z}${x}.pcf.Z + endif +# +# Bold face + if( -e ${y}BD.TTF ) then + echo Bold ${y} at ${x}pt + ./ttf2bdf -m $LANG_ID -p $x -r $DPI -w bold ${y}BD.TTF | bdftopcf | compress > ${DPI}dpi/${z}bd${x}.pcf.Z + endif +# +# Italic face + if( -e ${y}I.TTF ) then + echo Italic ${y} at ${x}pt + ./ttf2bdf -m $LANG_ID -p $x -r $DPI -s o ${y}I.TTF | bdftopcf | compress >${DPI}dpi/${z}i${x}.pcf.Z + endif +# +# Bold Italic face + if( -e ${y}BI.TTF ) then + echo Bold Italic ${y} at ${x}pt + ./ttf2bdf -m $LANG_ID -p $x -r $DPI -w bold -s o ${y}BI.TTF | bdftopcf | compress > ${DPI}dpi/${z}bi${x}.pcf.Z + endif +end +end + +echo Creating fonts directory... +cd ${DPI}dpi +mkfontdir diff --git a/contrib/ttf2bdf/contrib/creatett.m b/contrib/ttf2bdf/contrib/creatett.m new file mode 100644 index 0000000..da9d6a1 --- /dev/null +++ b/contrib/ttf2bdf/contrib/creatett.m @@ -0,0 +1,59 @@ +#!/bin/csh +# -*- mode:SH; -*- +# +# This script creates series of bdf files from TTF file. +# +# +# Please set up parameters +# +# Font dpi: +set DPI=96 + +# +# TrueType files dir. +set ttf_dir=~/ttf + +# TTF files, please specify only base name +# Script will try to use BolD, Italic and BoldItalic versions of face +set FACES="COUR MONOTYPE" + +# Output codepage +# koi8.r +# windows.1251 +# iso8859.5 +# iso8859.2 +set LANG_ID=koi8.r + +foreach x ( 7 8 9 10 11 12 14 16 18 20 24 30 50 100 150) +foreach z ( $FACES ) +set y = ${ttf_dir}/${z} +# +# Simple face + if( -e ${y}.TTF ) then + echo ${z} at ${x}pt + ./ttf2bdf -c m -m $LANG_ID -p $x -r $DPI ${y}.TTF | bdftopcf | compress > ${DPI}dpi/${z}${x}.pcf.Z + endif +# +# Bold face + if( -e ${y}BD.TTF ) then + echo Bold ${z} at ${x}pt + ./ttf2bdf -c m -m $LANG_ID -p $x -r $DPI -w bold ${y}BD.TTF | bdftopcf | compress > ${DPI}dpi/${z}bd${x}.pcf.Z + endif +# +# Italic face + if( -e ${y}I.TTF ) then + echo Italic ${z} at ${x}pt + ./ttf2bdf -c m -m $LANG_ID -p $x -r $DPI -s o ${y}I.TTF | bdftopcf | compress >${DPI}dpi/${z}i${x}.pcf.Z + endif +# +# Bold Italic face + if( -e ${y}BI.TTF ) then + echo Bold Italic ${z} at ${x}pt + ./ttf2bdf -c m -m $LANG_ID -p $x -r $DPI -w bold -s o ${y}BI.TTF | bdftopcf | compress > ${DPI}dpi/${z}bi${x}.pcf.Z + endif +end +end + +#echo Creating fonts directory... +#cd ${DPI}dpi +#mkfontdir diff --git a/contrib/ttf2bdf/maps/iso8859.1 b/contrib/ttf2bdf/maps/iso8859.1 new file mode 100644 index 0000000..8cc68d4 --- /dev/null +++ b/contrib/ttf2bdf/maps/iso8859.1 @@ -0,0 +1,278 @@ +# +# $Id: iso8859.1,v 1.2 1999/06/16 16:13:11 mleisher Exp $ +# +# SAMPLE TTF2BDF MAPPING TABLE +# +# Mapping table from Unicode to ISO8859-1. Names are from the Unicode +# Character Database on ftp.unicode.org. +# +# Two keywords are used to specify the character set registry and encoding: +# REGISTRY and ENCODING. These will be used when creating the XLFD name +# for the font. +# +# Column 1 is the ISO8859-1 value, and column 2 is the Unicode value. The +# columns can be separated by tabs or whitespace, and only the first two +# columns are used. +# +# Empty lines and lines starting with '#' are ignored. +# +# NOTE: made with material from "The ISO 8859 Alphabet Soup" --solofo +# +REGISTRY ISO8859 +ENCODING 1 +0x00 0x0000 # +0x01 0x0001 # +0x02 0x0002 # +0x03 0x0003 # +0x04 0x0004 # +0x05 0x0005 # +0x06 0x0006 # +0x07 0x0007 # +0x08 0x0008 # +0x09 0x0009 # +0x0A 0x000A # +0x0B 0x000B # +0x0C 0x000C # +0x0D 0x000D # +0x0E 0x000E # +0x0F 0x000F # +0x10 0x0010 # +0x11 0x0011 # +0x12 0x0012 # +0x13 0x0013 # +0x14 0x0014 # +0x15 0x0015 # +0x16 0x0016 # +0x17 0x0017 # +0x18 0x0018 # +0x19 0x0019 # +0x1A 0x001A # +0x1B 0x001B # +0x1C 0x001C # +0x1D 0x001D # +0x1E 0x001E # +0x1F 0x001F # +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x00A1 # INVERTED EXCLAMATION MARK +0xA2 0x00A2 # CENT SIGN +0xA3 0x00A3 # POUND SIGN +0xA4 0x00A4 # CURRENCY SIGN +0xA5 0x00A5 # YEN SIGN +0xA6 0x00A6 # BROKEN BAR +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x00AA # FEMININE ORDINAL INDICATOR +0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC # NOT SIGN +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x00AE # REGISTERED SIGN +0xAF 0x00AF # MACRON +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x00B2 # SUPERSCRIPT TWO +0xB3 0x00B3 # SUPERSCRIPT THREE +0xB4 0x00B4 # ACUTE ACCENT +0xB5 0x00B5 # MICRO SIGN +0xB6 0x00B6 # PILCROW SIGN +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x00B8 # CEDILLA +0xB9 0x00B9 # SUPERSCRIPT ONE +0xBA 0x00BA # MASCULINE ORDINAL INDICATOR +0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x00BC # VULGAR FRACTION ONE QUARTER +0xBD 0x00BD # VULGAR FRACTION ONE HALF +0xBE 0x00BE # VULGAR FRACTION THREE QUARTERS +0xBF 0x00BF # INVERTED QUESTION MARK +0xC0 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE +0xC6 0x00C6 # LATIN CAPITAL LETTER AE +0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS +0xD0 0x00D0 # LATIN CAPITAL LETTER ETH +0xD1 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE +0xD2 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 # MULTIPLICATION SIGN +0xD8 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE +0xD9 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x00DD # LATIN CAPITAL LETTER Y WITH ACUTE +0xDE 0x00DE # LATIN CAPITAL LETTER THORN +0xDF 0x00DF # LATIN SMALL LETTER SHARP S +0xE0 0x00E0 # LATIN SMALL LETTER A WITH GRAVE +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x00E3 # LATIN SMALL LETTER A WITH TILDE +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE +0xE6 0x00E6 # LATIN SMALL LETTER AE +0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x00E8 # LATIN SMALL LETTER E WITH GRAVE +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x00EC # LATIN SMALL LETTER I WITH GRAVE +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS +0xF0 0x00F0 # LATIN SMALL LETTER ETH +0xF1 0x00F1 # LATIN SMALL LETTER N WITH TILDE +0xF2 0x00F2 # LATIN SMALL LETTER O WITH GRAVE +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 # DIVISION SIGN +0xF8 0x00F8 # LATIN SMALL LETTER O WITH STROKE +0xF9 0x00F9 # LATIN SMALL LETTER U WITH GRAVE +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x00FD # LATIN SMALL LETTER Y WITH ACUTE +0xFE 0x00FE # LATIN SMALL LETTER THORN +0xFF 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS diff --git a/contrib/ttf2bdf/maps/iso8859.2 b/contrib/ttf2bdf/maps/iso8859.2 new file mode 100644 index 0000000..52af12a --- /dev/null +++ b/contrib/ttf2bdf/maps/iso8859.2 @@ -0,0 +1,276 @@ +# +# $Id: iso8859.2,v 1.2 1999/06/16 16:13:11 mleisher Exp $ +# +# SAMPLE TTF2BDF MAPPING TABLE +# +# Mapping table from Unicode to ISO8859-2. Names are from the Unicode +# Character Database on ftp.unicode.org. +# +# Two keywords are used to specify the character set registry and encoding: +# REGISTRY and ENCODING. These will be used when creating the XLFD name +# for the font. +# +# Column 1 is the ISO8859-2 value, and column 2 is the Unicode value. The +# columns can be separated by tabs or whitespace, and only the first two +# columns are used. +# +# Empty lines and lines starting with '#' are ignored. +# +REGISTRY ISO8859 +ENCODING 2 +0x00 0x0000 # +0x01 0x0001 # +0x02 0x0002 # +0x03 0x0003 # +0x04 0x0004 # +0x05 0x0005 # +0x06 0x0006 # +0x07 0x0007 # +0x08 0x0008 # +0x09 0x0009 # +0x0A 0x000A # +0x0B 0x000B # +0x0C 0x000C # +0x0D 0x000D # +0x0E 0x000E # +0x0F 0x000F # +0x10 0x0010 # +0x11 0x0011 # +0x12 0x0012 # +0x13 0x0013 # +0x14 0x0014 # +0x15 0x0015 # +0x16 0x0016 # +0x17 0x0017 # +0x18 0x0018 # +0x19 0x0019 # +0x1A 0x001A # +0x1B 0x001B # +0x1C 0x001C # +0x1D 0x001D # +0x1E 0x001E # +0x1F 0x001F # +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x0104 # LATIN CAPITAL LETTER A WITH OGONEK +0xA2 0x02D8 # BREVE +0xA3 0x0141 # LATIN CAPITAL LETTER L WITH STROKE +0xA4 0x00A4 # CURRENCY SIGN +0xA5 0x013D # LATIN CAPITAL LETTER L WITH CARON +0xA6 0x015A # LATIN CAPITAL LETTER S WITH ACUTE +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x0160 # LATIN CAPITAL LETTER S WITH CARON +0xAA 0x015E # LATIN CAPITAL LETTER S WITH CEDILLA +0xAB 0x0164 # LATIN CAPITAL LETTER T WITH CARON +0xAC 0x0179 # LATIN CAPITAL LETTER Z WITH ACUTE +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x017D # LATIN CAPITAL LETTER Z WITH CARON +0xAF 0x017B # LATIN CAPITAL LETTER Z WITH DOT ABOVE +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x0105 # LATIN SMALL LETTER A WITH OGONEK +0xB2 0x02DB # OGONEK +0xB3 0x0142 # LATIN SMALL LETTER L WITH STROKE +0xB4 0x00B4 # ACUTE ACCENT +0xB5 0x013E # LATIN SMALL LETTER L WITH CARON +0xB6 0x015B # LATIN SMALL LETTER S WITH ACUTE +0xB7 0x02C7 # CARON +0xB8 0x00B8 # CEDILLA +0xB9 0x0161 # LATIN SMALL LETTER S WITH CARON +0xBA 0x015F # LATIN SMALL LETTER S WITH CEDILLA +0xBB 0x0165 # LATIN SMALL LETTER T WITH CARON +0xBC 0x017A # LATIN SMALL LETTER Z WITH ACUTE +0xBD 0x02DD # DOUBLE ACUTE ACCENT +0xBE 0x017E # LATIN SMALL LETTER Z WITH CARON +0xBF 0x017C # LATIN SMALL LETTER Z WITH DOT ABOVE +0xC0 0x0154 # LATIN CAPITAL LETTER R WITH ACUTE +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x0102 # LATIN CAPITAL LETTER A WITH BREVE +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x0139 # LATIN CAPITAL LETTER L WITH ACUTE +0xC6 0x0106 # LATIN CAPITAL LETTER C WITH ACUTE +0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x010C # LATIN CAPITAL LETTER C WITH CARON +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x0118 # LATIN CAPITAL LETTER E WITH OGONEK +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x011A # LATIN CAPITAL LETTER E WITH CARON +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x010E # LATIN CAPITAL LETTER D WITH CARON +0xD0 0x0110 # LATIN CAPITAL LETTER D WITH STROKE +0xD1 0x0143 # LATIN CAPITAL LETTER N WITH ACUTE +0xD2 0x0147 # LATIN CAPITAL LETTER N WITH CARON +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x0150 # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 # MULTIPLICATION SIGN +0xD8 0x0158 # LATIN CAPITAL LETTER R WITH CARON +0xD9 0x016E # LATIN CAPITAL LETTER U WITH RING ABOVE +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x0170 # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x00DD # LATIN CAPITAL LETTER Y WITH ACUTE +0xDE 0x0162 # LATIN CAPITAL LETTER T WITH CEDILLA +0xDF 0x00DF # LATIN SMALL LETTER SHARP S +0xE0 0x0155 # LATIN SMALL LETTER R WITH ACUTE +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x0103 # LATIN SMALL LETTER A WITH BREVE +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x013A # LATIN SMALL LETTER L WITH ACUTE +0xE6 0x0107 # LATIN SMALL LETTER C WITH ACUTE +0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x010D # LATIN SMALL LETTER C WITH CARON +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x0119 # LATIN SMALL LETTER E WITH OGONEK +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x011B # LATIN SMALL LETTER E WITH CARON +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x010F # LATIN SMALL LETTER D WITH CARON +0xF0 0x0111 # LATIN SMALL LETTER D WITH STROKE +0xF1 0x0144 # LATIN SMALL LETTER N WITH ACUTE +0xF2 0x0148 # LATIN SMALL LETTER N WITH CARON +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x0151 # LATIN SMALL LETTER O WITH DOUBLE ACUTE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 # DIVISION SIGN +0xF8 0x0159 # LATIN SMALL LETTER R WITH CARON +0xF9 0x016F # LATIN SMALL LETTER U WITH RING ABOVE +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x0171 # LATIN SMALL LETTER U WITH DOUBLE ACUTE +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x00FD # LATIN SMALL LETTER Y WITH ACUTE +0xFE 0x0163 # LATIN SMALL LETTER T WITH CEDILLA +0xFF 0x02D9 # DOT ABOVE diff --git a/contrib/ttf2bdf/maps/iso8859.3 b/contrib/ttf2bdf/maps/iso8859.3 new file mode 100644 index 0000000..548b3ca --- /dev/null +++ b/contrib/ttf2bdf/maps/iso8859.3 @@ -0,0 +1,271 @@ +# +# $Id: iso8859.3,v 1.2 1999/06/16 16:13:11 mleisher Exp $ +# +# SAMPLE TTF2BDF MAPPING TABLE +# +# Mapping table from Unicode to ISO8859-3. Names are from the Unicode +# Character Database on ftp.unicode.org. +# +# Two keywords are used to specify the character set registry and encoding: +# REGISTRY and ENCODING. These will be used when creating the XLFD name +# for the font. +# +# Column 1 is the ISO8859-3 value, and column 2 is the Unicode value. The +# columns can be separated by tabs or whitespace, and only the first two +# columns are used. +# +# Empty lines and lines starting with '#' are ignored. +# +# NOTE: prepared with material from "The ISO 8859 Alphabet Soup" +# +REGISTRY ISO8859 +ENCODING 3 +0x00 0x0000 # +0x01 0x0001 # +0x02 0x0002 # +0x03 0x0003 # +0x04 0x0004 # +0x05 0x0005 # +0x06 0x0006 # +0x07 0x0007 # +0x08 0x0008 # +0x09 0x0009 # +0x0A 0x000A # +0x0B 0x000B # +0x0C 0x000C # +0x0D 0x000D # +0x0E 0x000E # +0x0F 0x000F # +0x10 0x0010 # +0x11 0x0011 # +0x12 0x0012 # +0x13 0x0013 # +0x14 0x0014 # +0x15 0x0015 # +0x16 0x0016 # +0x17 0x0017 # +0x18 0x0018 # +0x19 0x0019 # +0x1A 0x001A # +0x1B 0x001B # +0x1C 0x001C # +0x1D 0x001D # +0x1E 0x001E # +0x1F 0x001F # +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x0126 # LATIN CAPITAL LETTER H WITH STROKE +0xA2 0x02D8 # BREVE +0xA3 0x00A3 # POUND SIGN +0xA4 0x00A4 # CURRENCY SIGN +0xA6 0x0124 # LATIN CAPITAL LETTER H WITH CIRCUMFLEX +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x0130 # LATIN CAPITAL LETTER I WITH DOT ABOVE +0xAA 0x015E # LATIN CAPITAL LETTER S WITH CEDILLA +0xAB 0x011E # LATIN CAPITAL LETTER G WITH BREVE +0xAC 0x0134 # LATIN CAPITAL LETTER J WITH CIRCUMFLEX +0xAD 0x00AD # SOFT HYPHEN +0xAF 0x017B # LATIN CAPITAL LETTER Z WITH DOT ABOVE +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x0127 # LATIN SMALL LETTER H WITH STROKE +0xB2 0x00B2 # SUPERSCRIPT TWO +0xB3 0x00B3 # SUPERSCRIPT THREE +0xB4 0x00B4 # ACUTE ACCENT +0xB5 0x00B5 # MICRO SIGN +0xB6 0x0125 # LATIN SMALL LETTER H WITH CIRCUMFLEX +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x00B8 # CEDILLA +0xB9 0x0131 # LATIN SMALL LETTER DOTLESS I +0xBA 0x015F # LATIN SMALL LETTER S WITH CEDILLA +0xBB 0x011F # LATIN SMALL LETTER G WITH BREVE +0xBC 0x0135 # LATIN SMALL LETTER J WITH CIRCUMFLEX +0xBD 0x00BD # VULGAR FRACTION ONE HALF +0xBF 0x017C # LATIN SMALL LETTER Z WITH DOT ABOVE +0xC0 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x010A # LATIN CAPITAL LETTER C WITH DOT ABOVE +0xC6 0x0108 # LATIN CAPITAL LETTER C WITH CIRCUMFLEX +0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS +0xD1 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE +0xD2 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x0120 # LATIN CAPITAL LETTER G WITH DOT ABOVE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 # MULTIPLICATION SIGN +0xD8 0x011C # LATIN CAPITAL LETTER G WITH CIRCUMFLEX +0xD9 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x016C # LATIN CAPITAL LETTER U WITH BREVE +0xDE 0x015C # LATIN CAPITAL LETTER S WITH CIRCUMFLEX +0xDF 0x00DF # LATIN SMALL LETTER SHARP S +0xE0 0x00E0 # LATIN SMALL LETTER A WITH GRAVE +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x010B # LATIN SMALL LETTER C WITH DOT ABOVE +0xE6 0x0109 # LATIN SMALL LETTER C WITH CIRCUMFLEX +0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x00E8 # LATIN SMALL LETTER E WITH GRAVE +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x00EC # LATIN SMALL LETTER I WITH GRAVE +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS +0xF1 0x00F1 # LATIN SMALL LETTER N WITH TILDE +0xF2 0x00F2 # LATIN SMALL LETTER O WITH GRAVE +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x0121 # LATIN SMALL LETTER G WITH DOT ABOVE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 # DIVISION SIGN +0xF8 0x011D # LATIN SMALL LETTER G WITH CIRCUMFLEX +0xF9 0x00F9 # LATIN SMALL LETTER U WITH GRAVE +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x016D # LATIN SMALL LETTER U WITH BREVE +0xFE 0x015D # LATIN SMALL LETTER S WITH CIRCUMFLEX +0xFF 0x02D9 # DOT ABOVE diff --git a/contrib/ttf2bdf/maps/iso8859.5 b/contrib/ttf2bdf/maps/iso8859.5 new file mode 100644 index 0000000..69eac5a --- /dev/null +++ b/contrib/ttf2bdf/maps/iso8859.5 @@ -0,0 +1,265 @@ +#/* +# * Unicode 2.0 -> iso8859-5 +# * +# * 04 Jan 98 | Eugene Bobin, +# * +# * Modified 16 June 99 Mark Leisher +# */ +REGISTRY ISO8859 +ENCODING 5 +0x00 0x0000 # +0x01 0x0001 # +0x02 0x0002 # +0x03 0x0003 # +0x04 0x0004 # +0x05 0x0005 # +0x06 0x0006 # +0x07 0x0007 # +0x08 0x0008 # +0x09 0x0009 # +0x0A 0x000A # +0x0B 0x000B # +0x0C 0x000C # +0x0D 0x000D # +0x0E 0x000E # +0x0F 0x000F # +0x10 0x0010 # +0x11 0x0011 # +0x12 0x0012 # +0x13 0x0013 # +0x14 0x0014 # +0x15 0x0015 # +0x16 0x0016 # +0x17 0x0017 # +0x18 0x0018 # +0x19 0x0019 # +0x1A 0x001A # +0x1B 0x001B # +0x1C 0x001C # +0x1D 0x001D # +0x1E 0x001E # +0x1F 0x001F # +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x0401 # CYRILLIC CAPITAL LETTER IO /* ³ */ +0xA2 0x00A2 # CENT SIGN +0xA3 0x00A3 # POUND SIGN +0xA4 0x00A4 # CURRENCY SIGN +0xA5 0x00A5 # YEN SIGN +0xA6 0x00A6 # BROKEN BAR +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x00AA # FEMININE ORDINAL INDICATOR +0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC # NOT SIGN +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x00AE # REGISTERED SIGN +0xAF 0x00AF # MACRON +0xB0 0x0410 # CYRILLIC CAPITAL LETTER A /* á */ +0xB1 0x0411 # CYRILLIC CAPITAL LETTER BE /* â */ +0xB2 0x0412 # CYRILLIC CAPITAL LETTER VE /* ÷ */ +0xB3 0x0413 # CYRILLIC CAPITAL LETTER GHE /* ç */ +0xB4 0x0414 # CYRILLIC CAPITAL LETTER DE /* ä */ +0xB5 0x0415 # CYRILLIC CAPITAL LETTER IE /* å */ +0xB6 0x0416 # CYRILLIC CAPITAL LETTER ZHE /* ö */ +0xB7 0x0417 # CYRILLIC CAPITAL LETTER ZE /* ú */ +0xB8 0x0418 # CYRILLIC CAPITAL LETTER I /* é */ +0xB9 0x0419 # CYRILLIC CAPITAL LETTER SHORT I /* ê */ +0xBA 0x041A # CYRILLIC CAPITAL LETTER KA /* ë */ +0xBB 0x041B # CYRILLIC CAPITAL LETTER EL /* ì */ +0xBC 0x041C # CYRILLIC CAPITAL LETTER EM /* í */ +0xBD 0x041D # CYRILLIC CAPITAL LETTER EN /* î */ +0xBE 0x041E # CYRILLIC CAPITAL LETTER O /* ï */ +0xBF 0x041F # CYRILLIC CAPITAL LETTER PE /* ð */ +0xC0 0x0420 # CYRILLIC CAPITAL LETTER ER /* ò */ +0xC1 0x0421 # CYRILLIC CAPITAL LETTER ES /* ó */ +0xC2 0x0422 # CYRILLIC CAPITAL LETTER TE /* ô */ +0xC3 0x0423 # CYRILLIC CAPITAL LETTER U /* õ */ +0xC4 0x0424 # CYRILLIC CAPITAL LETTER EF /* æ */ +0xC5 0x0425 # CYRILLIC CAPITAL LETTER HA /* è */ +0xC6 0x0426 # CYRILLIC CAPITAL LETTER TSE /* ã */ +0xC7 0x0427 # CYRILLIC CAPITAL LETTER CHE /* þ */ +0xC8 0x0428 # CYRILLIC CAPITAL LETTER SHA /* û */ +0xC9 0x0429 # CYRILLIC CAPITAL LETTER SHCHA /* ý */ +0xCA 0x042A # CYRILLIC CAPITAL LETTER HARD SIGN /* ÿ */ +0xCB 0x042B # CYRILLIC CAPITAL LETTER YERU /* ù */ +0xCC 0x042C # CYRILLIC CAPITAL LETTER SOFT SIGN /* ø */ +0xCD 0x042D # CYRILLIC CAPITAL LETTER E /* ü */ +0xCE 0x042E # CYRILLIC CAPITAL LETTER YU /* à */ +0xCF 0x042F # CYRILLIC CAPITAL LETTER YA /* ñ */ +0xD0 0x0430 # CYRILLIC SMALL LETTER A /* Á */ +0xD1 0x0431 # CYRILLIC SMALL LETTER BE /* Â */ +0xD2 0x0432 # CYRILLIC SMALL LETTER VE /* × */ +0xD3 0x0433 # CYRILLIC SMALL LETTER GHE /* Ç */ +0xD4 0x0434 # CYRILLIC SMALL LETTER DE /* Ä */ +0xD5 0x0435 # CYRILLIC SMALL LETTER IE /* Å */ +0xD6 0x0436 # CYRILLIC SMALL LETTER ZHE /* Ö */ +0xD7 0x0437 # CYRILLIC SMALL LETTER ZE /* Ú */ +0xD8 0x0438 # CYRILLIC SMALL LETTER I /* É */ +0xD9 0x0439 # CYRILLIC SMALL LETTER SHORT I /* Ê */ +0xDA 0x043A # CYRILLIC SMALL LETTER KA /* Ë */ +0xDB 0x043B # CYRILLIC SMALL LETTER EL /* Ì */ +0xDC 0x043C # CYRILLIC SMALL LETTER EM /* Í */ +0xDD 0x043D # CYRILLIC SMALL LETTER EN /* Î */ +0xDE 0x043E # CYRILLIC SMALL LETTER O /* Ï */ +0xDF 0x043F # CYRILLIC SMALL LETTER PE /* Ð */ +0xE0 0x0440 # CYRILLIC SMALL LETTER ER /* Ò */ +0xE1 0x0441 # CYRILLIC SMALL LETTER ES /* Ó */ +0xE2 0x0442 # CYRILLIC SMALL LETTER TE /* Ô */ +0xE3 0x0443 # CYRILLIC SMALL LETTER U /* Õ */ +0xE4 0x0444 # CYRILLIC SMALL LETTER EF /* Æ */ +0xE5 0x0445 # CYRILLIC SMALL LETTER HA /* È */ +0xE6 0x0446 # CYRILLIC SMALL LETTER TSE /* Ã */ +0xE7 0x0447 # CYRILLIC SMALL LETTER CHE /* Þ */ +0xE8 0x0448 # CYRILLIC SMALL LETTER SHA /* Û */ +0xE9 0x0449 # CYRILLIC SMALL LETTER SHCHA /* Ý */ +0xEA 0x044A # CYRILLIC SMALL LETTER HARD SIGN /* ß */ +0xEB 0x044B # CYRILLIC SMALL LETTER YERU /* Ù */ +0xEC 0x044C # CYRILLIC SMALL LETTER SOFT SIGN /* Ø */ +0xED 0x044D # CYRILLIC SMALL LETTER E /* Ü */ +0xEE 0x044E # CYRILLIC SMALL LETTER YU /* À */ +0xEF 0x044F # CYRILLIC SMALL LETTER YA /* Ñ */ +0xF0 0x00F0 # LATIN SMALL LETTER ETH +0xF1 0x0451 # CYRILLIC SMALL LETTER IO /* £ */ +0xF2 0x00F2 # LATIN SMALL LETTER O WITH GRAVE +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 # DIVISION SIGN +0xF8 0x00F8 # LATIN SMALL LETTER O WITH STROKE +0xF9 0x00F9 # LATIN SMALL LETTER U WITH GRAVE +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x00FD # LATIN SMALL LETTER Y WITH ACUTE +0xFE 0x00FE # LATIN SMALL LETTER THORN +0xFF 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS diff --git a/contrib/ttf2bdf/maps/koi8.r b/contrib/ttf2bdf/maps/koi8.r new file mode 100644 index 0000000..aa16705 --- /dev/null +++ b/contrib/ttf2bdf/maps/koi8.r @@ -0,0 +1,232 @@ +#/* +# * Unicode 2.0 -> KOI8-R +# * +# * 11 Jan 97 | Eugene Bobin, +# * +# * Modified 16 June 99 Mark Leisher +# */ +REGISTRY KOI8 +ENCODING R +0x00 0x0000 # +0x01 0x0001 # +0x02 0x0002 # +0x03 0x0003 # +0x04 0x0004 # +0x05 0x0005 # +0x06 0x0006 # +0x07 0x0007 # +0x08 0x0008 # +0x09 0x0009 # +0x0A 0x000A # +0x0B 0x000B # +0x0C 0x000C # +0x0D 0x000D # +0x0E 0x000E # +0x0F 0x000F # +0x10 0x0010 # +0x11 0x0011 # +0x12 0x0012 # +0x13 0x0013 # +0x14 0x0014 # +0x15 0x0015 # +0x16 0x0016 # +0x17 0x0017 # +0x18 0x0018 # +0x19 0x0019 # +0x1A 0x001A # +0x1B 0x001B # +0x1C 0x001C # +0x1D 0x001D # +0x1E 0x001E # +0x1F 0x001F # +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x00A1 # INVERTED EXCLAMATION MARK +0xA2 0x00A2 # CENT SIGN +0xA3 0x0451 # CYRILLIC SMALL LETTER IO /* £ */ +0xA4 0x00A4 # CURRENCY SIGN +0xA5 0x00A5 # YEN SIGN +0xA6 0x00A6 # BROKEN BAR +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x00AA # FEMININE ORDINAL INDICATOR +0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC # NOT SIGN +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x00AE # REGISTERED SIGN +0xAF 0x00AF # MACRON +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x00B2 # SUPERSCRIPT TWO +0xB3 0x0401 # CYRILLIC CAPITAL LETTER IO /* ³ */ +0xB4 0x00B4 # ACUTE ACCENT +0xB5 0x00B5 # MICRO SIGN +0xB6 0x00B6 # PILCROW SIGN +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x00B8 # CEDILLA +0xB9 0x00B9 # SUPERSCRIPT ONE +0xBA 0x00BA # MASCULINE ORDINAL INDICATOR +0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x00BC # VULGAR FRACTION ONE QUARTER +0xBD 0x00BD # VULGAR FRACTION ONE HALF +0xBE 0x00BE # VULGAR FRACTION THREE QUARTERS +0xBF 0x00BF # INVERTED QUESTION MARK +0xC0 0x044E # CYRILLIC SMALL LETTER YU /* À */ +0xC1 0x0430 # CYRILLIC SMALL LETTER A /* Á */ +0xC2 0x0431 # CYRILLIC SMALL LETTER BE /* Â */ +0xC3 0x0446 # CYRILLIC SMALL LETTER TSE /* Ã */ +0xC4 0x0434 # CYRILLIC SMALL LETTER DE /* Ä */ +0xC5 0x0435 # CYRILLIC SMALL LETTER IE /* Å */ +0xC6 0x0444 # CYRILLIC SMALL LETTER EF /* Æ */ +0xC7 0x0433 # CYRILLIC SMALL LETTER GHE /* Ç */ +0xC8 0x0445 # CYRILLIC SMALL LETTER HA /* È */ +0xC9 0x0438 # CYRILLIC SMALL LETTER I /* É */ +0xCA 0x0439 # CYRILLIC SMALL LETTER SHORT I /* Ê */ +0xCB 0x043A # CYRILLIC SMALL LETTER KA /* Ë */ +0xCC 0x043B # CYRILLIC SMALL LETTER EL /* Ì */ +0xCD 0x043C # CYRILLIC SMALL LETTER EM /* Í */ +0xCE 0x043D # CYRILLIC SMALL LETTER EN /* Î */ +0xCF 0x043E # CYRILLIC SMALL LETTER O /* Ï */ +0xD0 0x043F # CYRILLIC SMALL LETTER PE /* Ð */ +0xD1 0x044F # CYRILLIC SMALL LETTER YA /* Ñ */ +0xD2 0x0440 # CYRILLIC SMALL LETTER ER /* Ò */ +0xD3 0x0441 # CYRILLIC SMALL LETTER ES /* Ó */ +0xD4 0x0442 # CYRILLIC SMALL LETTER TE /* Ô */ +0xD5 0x0443 # CYRILLIC SMALL LETTER U /* Õ */ +0xD6 0x0436 # CYRILLIC SMALL LETTER ZHE /* Ö */ +0xD7 0x0432 # CYRILLIC SMALL LETTER VE /* × */ +0xD8 0x044C # CYRILLIC SMALL LETTER SOFT SIGN /* Ø */ +0xD9 0x044B # CYRILLIC SMALL LETTER YERU /* Ù */ +0xDA 0x0437 # CYRILLIC SMALL LETTER ZE /* Ú */ +0xDB 0x0448 # CYRILLIC SMALL LETTER SHA /* Û */ +0xDC 0x044D # CYRILLIC SMALL LETTER E /* Ü */ +0xDD 0x0449 # CYRILLIC SMALL LETTER SHCHA /* Ý */ +0xDE 0x0447 # CYRILLIC SMALL LETTER CHE /* Þ */ +0xDF 0x044A # CYRILLIC SMALL LETTER HARD SIGN /* ß */ +0xE0 0x042E # CYRILLIC CAPITAL LETTER YU /* à */ +0xE1 0x0410 # CYRILLIC CAPITAL LETTER A /* á */ +0xE2 0x0411 # CYRILLIC CAPITAL LETTER BE /* â */ +0xE3 0x0426 # CYRILLIC CAPITAL LETTER TSE /* ã */ +0xE4 0x0414 # CYRILLIC CAPITAL LETTER DE /* ä */ +0xE5 0x0415 # CYRILLIC CAPITAL LETTER IE /* å */ +0xE6 0x0424 # CYRILLIC CAPITAL LETTER EF /* æ */ +0xE7 0x0413 # CYRILLIC CAPITAL LETTER GHE /* ç */ +0xE8 0x0425 # CYRILLIC CAPITAL LETTER HA /* è */ +0xE9 0x0418 # CYRILLIC CAPITAL LETTER I /* é */ +0xEA 0x0419 # CYRILLIC CAPITAL LETTER SHORT I /* ê */ +0xEB 0x041A # CYRILLIC CAPITAL LETTER KA /* ë */ +0xEC 0x041B # CYRILLIC CAPITAL LETTER EL /* ì */ +0xED 0x041C # CYRILLIC CAPITAL LETTER EM /* í */ +0xEE 0x041D # CYRILLIC CAPITAL LETTER EN /* î */ +0xEF 0x041E # CYRILLIC CAPITAL LETTER O /* ï */ +0xF0 0x041F # CYRILLIC CAPITAL LETTER PE /* ð */ +0xF1 0x042F # CYRILLIC CAPITAL LETTER YA /* ñ */ +0xF2 0x0420 # CYRILLIC CAPITAL LETTER ER /* ò */ +0xF3 0x0421 # CYRILLIC CAPITAL LETTER ES /* ó */ +0xF4 0x0422 # CYRILLIC CAPITAL LETTER TE /* ô */ +0xF5 0x0423 # CYRILLIC CAPITAL LETTER U /* õ */ +0xF6 0x0416 # CYRILLIC CAPITAL LETTER ZHE /* ö */ +0xF7 0x0412 # CYRILLIC CAPITAL LETTER VE /* ÷ */ +0xF8 0x042C # CYRILLIC CAPITAL LETTER SOFT SIGN /* ø */ +0xF9 0x042B # CYRILLIC CAPITAL LETTER YERU /* ù */ +0xFA 0x0417 # CYRILLIC CAPITAL LETTER ZE /* ú */ +0xFB 0x0428 # CYRILLIC CAPITAL LETTER SHA /* û */ +0xFC 0x042D # CYRILLIC CAPITAL LETTER E /* ü */ +0xFD 0x0429 # CYRILLIC CAPITAL LETTER SHCHA /* ý */ +0xFE 0x0427 # CYRILLIC CAPITAL LETTER CHE /* þ */ +0xFF 0x042A # CYRILLIC CAPITAL LETTER HARD SIGN /* ÿ */ diff --git a/contrib/ttf2bdf/maps/windows.1251 b/contrib/ttf2bdf/maps/windows.1251 new file mode 100644 index 0000000..ec3e34c --- /dev/null +++ b/contrib/ttf2bdf/maps/windows.1251 @@ -0,0 +1,233 @@ +#/* +# * Unicode 2.0 -> Windows CP_1251 (Must Die ;) +# * +# * 11 Jan 97 | Eugene Bobin, +# * +# * Modified 16 June 99 Mark Leisher +# */ +# +REGISTRY WINDOWS +ENCODING 1251 +0x00 0x0000 # +0x01 0x0001 # +0x02 0x0002 # +0x03 0x0003 # +0x04 0x0004 # +0x05 0x0005 # +0x06 0x0006 # +0x07 0x0007 # +0x08 0x0008 # +0x09 0x0009 # +0x0A 0x000A # +0x0B 0x000B # +0x0C 0x000C # +0x0D 0x000D # +0x0E 0x000E # +0x0F 0x000F # +0x10 0x0010 # +0x11 0x0011 # +0x12 0x0012 # +0x13 0x0013 # +0x14 0x0014 # +0x15 0x0015 # +0x16 0x0016 # +0x17 0x0017 # +0x18 0x0018 # +0x19 0x0019 # +0x1A 0x001A # +0x1B 0x001B # +0x1C 0x001C # +0x1D 0x001D # +0x1E 0x001E # +0x1F 0x001F # +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x00A1 # INVERTED EXCLAMATION MARK +0xA2 0x00A2 # CENT SIGN +0xA3 0x0451 # CYRILLIC SMALL LETTER IO /* £ */ +0xA4 0x00A4 # CURRENCY SIGN +0xA5 0x00A5 # YEN SIGN +0xA6 0x00A6 # BROKEN BAR +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x00AA # FEMININE ORDINAL INDICATOR +0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC # NOT SIGN +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x00AE # REGISTERED SIGN +0xAF 0x00AF # MACRON +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x00B2 # SUPERSCRIPT TWO +0xB3 0x0401 # CYRILLIC CAPITAL LETTER IO /* ³ */ +0xB4 0x00B4 # ACUTE ACCENT +0xB5 0x00B5 # MICRO SIGN +0xB6 0x00B6 # PILCROW SIGN +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x00B8 # CEDILLA +0xB9 0x00B9 # SUPERSCRIPT ONE +0xBA 0x00BA # MASCULINE ORDINAL INDICATOR +0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x00BC # VULGAR FRACTION ONE QUARTER +0xBD 0x00BD # VULGAR FRACTION ONE HALF +0xBE 0x00BE # VULGAR FRACTION THREE QUARTERS +0xBF 0x00BF # INVERTED QUESTION MARK +0xC0 0x044E # CYRILLIC SMALL LETTER YU /* À */ +0xC1 0x0430 # CYRILLIC SMALL LETTER A /* Á */ +0xC2 0x0431 # CYRILLIC SMALL LETTER BE /* Â */ +0xC3 0x0446 # CYRILLIC SMALL LETTER TSE /* Ã */ +0xC4 0x0434 # CYRILLIC SMALL LETTER DE /* Ä */ +0xC5 0x0435 # CYRILLIC SMALL LETTER IE /* Å */ +0xC6 0x0444 # CYRILLIC SMALL LETTER EF /* Æ */ +0xC7 0x0433 # CYRILLIC SMALL LETTER GHE /* Ç */ +0xC8 0x0445 # CYRILLIC SMALL LETTER HA /* È */ +0xC9 0x0438 # CYRILLIC SMALL LETTER I /* É */ +0xCA 0x0439 # CYRILLIC SMALL LETTER SHORT I /* Ê */ +0xCB 0x043A # CYRILLIC SMALL LETTER KA /* Ë */ +0xCC 0x043B # CYRILLIC SMALL LETTER EL /* Ì */ +0xCD 0x043C # CYRILLIC SMALL LETTER EM /* Í */ +0xCE 0x043D # CYRILLIC SMALL LETTER EN /* Î */ +0xCF 0x043E # CYRILLIC SMALL LETTER O /* Ï */ +0xD0 0x043F # CYRILLIC SMALL LETTER PE /* Ð */ +0xD1 0x044F # CYRILLIC SMALL LETTER YA /* Ñ */ +0xD2 0x0440 # CYRILLIC SMALL LETTER ER /* Ò */ +0xD3 0x0441 # CYRILLIC SMALL LETTER ES /* Ó */ +0xD4 0x0442 # CYRILLIC SMALL LETTER TE /* Ô */ +0xD5 0x0443 # CYRILLIC SMALL LETTER U /* Õ */ +0xD6 0x0436 # CYRILLIC SMALL LETTER ZHE /* Ö */ +0xD7 0x0432 # CYRILLIC SMALL LETTER VE /* × */ +0xD8 0x044C # CYRILLIC SMALL LETTER SOFT SIGN /* Ø */ +0xD9 0x044B # CYRILLIC SMALL LETTER YERU /* Ù */ +0xDA 0x0437 # CYRILLIC SMALL LETTER ZE /* Ú */ +0xDB 0x0448 # CYRILLIC SMALL LETTER SHA /* Û */ +0xDC 0x044D # CYRILLIC SMALL LETTER E /* Ü */ +0xDD 0x0449 # CYRILLIC SMALL LETTER SHCHA /* Ý */ +0xDE 0x0447 # CYRILLIC SMALL LETTER CHE /* Þ */ +0xDF 0x044A # CYRILLIC SMALL LETTER HARD SIGN /* ß */ +0xE0 0x042E # CYRILLIC CAPITAL LETTER YU /* à */ +0xE1 0x0410 # CYRILLIC CAPITAL LETTER A /* á */ +0xE2 0x0411 # CYRILLIC CAPITAL LETTER BE /* â */ +0xE3 0x0426 # CYRILLIC CAPITAL LETTER TSE /* ã */ +0xE4 0x0414 # CYRILLIC CAPITAL LETTER DE /* ä */ +0xE5 0x0415 # CYRILLIC CAPITAL LETTER IE /* å */ +0xE6 0x0424 # CYRILLIC CAPITAL LETTER EF /* æ */ +0xE7 0x0413 # CYRILLIC CAPITAL LETTER GHE /* ç */ +0xE8 0x0425 # CYRILLIC CAPITAL LETTER HA /* è */ +0xE9 0x0418 # CYRILLIC CAPITAL LETTER I /* é */ +0xEA 0x0419 # CYRILLIC CAPITAL LETTER SHORT I /* ê */ +0xEB 0x041A # CYRILLIC CAPITAL LETTER KA /* ë */ +0xEC 0x041B # CYRILLIC CAPITAL LETTER EL /* ì */ +0xED 0x041C # CYRILLIC CAPITAL LETTER EM /* í */ +0xEE 0x041D # CYRILLIC CAPITAL LETTER EN /* î */ +0xEF 0x041E # CYRILLIC CAPITAL LETTER O /* ï */ +0xF0 0x041F # CYRILLIC CAPITAL LETTER PE /* ð */ +0xF1 0x042F # CYRILLIC CAPITAL LETTER YA /* ñ */ +0xF2 0x0420 # CYRILLIC CAPITAL LETTER ER /* ò */ +0xF3 0x0421 # CYRILLIC CAPITAL LETTER ES /* ó */ +0xF4 0x0422 # CYRILLIC CAPITAL LETTER TE /* ô */ +0xF5 0x0423 # CYRILLIC CAPITAL LETTER U /* õ */ +0xF6 0x0416 # CYRILLIC CAPITAL LETTER ZHE /* ö */ +0xF7 0x0412 # CYRILLIC CAPITAL LETTER VE /* ÷ */ +0xF8 0x042C # CYRILLIC CAPITAL LETTER SOFT SIGN /* ø */ +0xF9 0x042B # CYRILLIC CAPITAL LETTER YERU /* ù */ +0xFA 0x0417 # CYRILLIC CAPITAL LETTER ZE /* ú */ +0xFB 0x0428 # CYRILLIC CAPITAL LETTER SHA /* û */ +0xFC 0x042D # CYRILLIC CAPITAL LETTER E /* ü */ +0xFD 0x0429 # CYRILLIC CAPITAL LETTER SHCHA /* ý */ +0xFE 0x0427 # CYRILLIC CAPITAL LETTER CHE /* þ */ +0xFF 0x042A # CYRILLIC CAPITAL LETTER HARD SIGN /* ÿ */ diff --git a/contrib/ttf2bdf/remap.c b/contrib/ttf2bdf/remap.c new file mode 100644 index 0000000..3555a0f --- /dev/null +++ b/contrib/ttf2bdf/remap.c @@ -0,0 +1,690 @@ +/* + * Copyright 1996, 1997, 1998, 1999 Computing Research Labs, + * New Mexico State University + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef lint +#ifdef __GNUC__ +static char rcsid[] __attribute__ ((unused)) = "$Id: remap.c,v 1.9 1999/06/16 16:13:11 mleisher Exp $"; +#else +static char rcsid[] = "$Id: remap.c,v 1.9 1999/06/16 16:13:11 mleisher Exp $"; +#endif +#endif + +#include +#include + +#ifdef WIN32 +#include +#else +#include +#include +#endif + +/* + * Structure for managing simple lists in place. + */ +typedef struct { + unsigned char *bfield; + unsigned long bsize; + unsigned long bused; + unsigned char **field; + unsigned long size; + unsigned long used; +} list_t; + +/* + * Callback type used with the high speed text file reader function. + */ +typedef int (*scanlines_callback_t)( +#ifdef __STDC__ + unsigned char *line, + unsigned long linelen, + unsigned long lineno, + void *client_data +#endif +); + +/* + * Various utility routines. + */ + +#define setsbit(m, cc) (m[(cc) >> 3] |= (1 << ((cc) & 7))) +#define sbitset(m, cc) (m[(cc) >> 3] & (1 << ((cc) & 7))) + +/* + * An empty string for empty fields. + */ +static unsigned char empty[1] = { 0 }; + +/* + * Assume the line is NULL terminated and that the `list' parameter was + * initialized the first time it was used. + */ +static void +#ifdef __STDC__ +splitline(unsigned char *separators, unsigned char *line, + unsigned long linelen, list_t *list) +#else +splitline(separators, line, linelen, list) +unsigned char *separators, *line; +unsigned long linelen; +list_t *list; +#endif +{ + int mult, final_empty; + unsigned char *sp, *ep, *end; + unsigned char seps[32]; + + /* + * Initialize the list. + */ + list->used = list->bused = 0; + + /* + * If the line is empty, then simply return. + */ + if (linelen == 0 || line[0] == 0) + return; + + /* + * If the `separators' parameter is NULL or empty, split the list into + * individual bytes. + */ + if (separators == 0 || *separators == 0) { + if (linelen > list->bsize) { + if (list->bsize) + list->bfield = (unsigned char *) malloc(linelen); + else + list->bfield = (unsigned char *) realloc(list->bfield, linelen); + list->bsize = linelen; + } + list->bused = linelen; + (void) memcpy(list->bfield, line, linelen); + return; + } + + /* + * Prepare the separator bitmap. + */ + (void) memset((char *) seps, 0, 32); + + /* + * If the very last character of the separator string is a plus, then set + * the `mult' flag to indicate that multiple separators should be + * collapsed into one. + */ + for (mult = 0, sp = separators; sp && *sp; sp++) { + if (*sp == '+' && *(sp + 1) == 0) + mult = 1; + else + setsbit(seps, *sp); + } + + /* + * Break the line up into fields. + */ + for (final_empty = 0, sp = ep = line, end = sp + linelen; + sp < end && *sp;) { + /* + * Collect everything that is not a separator. + */ + for (; ep < end && *ep && !sbitset(seps, *ep); ep++) ; + + /* + * Resize the list if necessary. + */ + if (list->used == list->size) { + if (list->size == 0) + list->field = (unsigned char **) + malloc(sizeof(unsigned char *) << 3); + else + list->field = (unsigned char **) + realloc((char *) list->field, + sizeof(unsigned char *) * (list->size + 8)); + + list->size += 8; + } + + /* + * Assign the field appropriately. + */ + list->field[list->used++] = (ep > sp) ? sp : empty; + + sp = ep; + if (mult) { + /* + * If multiple separators should be collapsed, do it now by + * setting all the separator characters to 0. + */ + for (; ep < end && *ep && sbitset(seps, *ep); ep++) + *ep = 0; + } else + /* + * Don't collapse multiple separators by making them 0, so just + * make the one encountered 0. + */ + *ep++ = 0; + final_empty = (ep > sp && *ep == 0); + sp = ep; + } + + /* + * Finally, NULL terminate the list. + */ + if (list->used + final_empty + 1 >= list->size) { + if (list->used == list->size) { + if (list->size == 0) + list->field = (unsigned char **) + malloc(sizeof(unsigned char *) << 3); + else + list->field = (unsigned char **) + realloc((unsigned char *) list->field, + sizeof(char *) * (list->size + 8)); + list->size += 8; + } + } + if (final_empty) + list->field[list->used++] = empty; + + if (list->used == list->size) { + if (list->size == 0) + list->field = (unsigned char **) + malloc(sizeof(unsigned char *) << 3); + else + list->field = (unsigned char **) + realloc((char *) list->field, + sizeof(unsigned char *) * (list->size + 8)); + list->size += 8; + } + list->field[list->used] = 0; +} + +static int +#ifdef __STDC__ +scanlines(int fd, scanlines_callback_t callback, void *client_data, + unsigned long *lineno) +#else +scanlines(fd, callback, client_data, lineno) +int fd; +scanlines_callback_t callback; +void *client_data; +unsigned long *lineno; +#endif +{ + unsigned long lno; + int n, res, done, refill, bytes, hold; + char *ls, *le, *pp, *pe, *hp; + char buf[65536]; + + if (callback == 0) + return -1; + + lno = 1; + (void) memset(buf, 0, 65536); + res = done = 0; + pp = ls = le = buf; + bytes = 65536; + while (!done && (n = read(fd, pp, bytes)) > 0) { + /* + * Determine the new end of the buffer pages. + */ + pe = pp + n; + + for (refill = 0; done == 0 && refill == 0; ) { + while (le < pe && *le != '\n' && *le != '\r') + le++; + + if (le == pe) { + /* + * Hit the end of the last page in the buffer. + * Need to find out how many pages to shift + * and how many pages need to be read in. + * Adjust the line start and end pointers down + * to point to the right places in the pages. + */ + pp = buf + (((ls - buf) >> 13) << 13); + n = pp - buf; + ls -= n; + le -= n; + n = pe - pp; + (void) memcpy(buf, pp, n); + pp = buf + n; + bytes = 65536 - n; + refill = 1; + } else { + /* + * Temporarily NULL terminate the line. + */ + hp = le; + hold = *le; + *le = 0; + + if (callback && *ls != '#' && *ls != 0x1a && le > ls && + (res = (*callback)((unsigned char *) ls, le - ls, lno, + client_data)) != 0) + done = 1; + else { + ls = ++le; + /* + * Handle the case of DOS CRLF sequences. + */ + if (le < pe && hold == '\n' && *le =='\r') + ls = ++le; + } + + /* + * Increment the line number. + */ + lno++; + + /* + * Restore the character at the end of the line. + */ + *hp = hold; + } + } + } + + /* + * Return with the last line number processed. + */ + *lineno = lno; + + return res; +} + +static unsigned char a2i[128] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static unsigned char odigits[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static unsigned char ddigits[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static unsigned char hdigits[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, + 0x7e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +#define isdigok(m, d) (m[(d) >> 3] & (1 << ((d) & 7))) + +static unsigned short +#ifdef __STDC__ +my_atous(unsigned char *s, unsigned char **end, int base) +#else +my_atous(s, end, base) +unsigned char *s, **end; +int base; +#endif +{ + unsigned short v; + unsigned char *dmap; + + if (s == 0 || *s == 0) + return 0; + + /* + * Make sure the radix is something recognizable. Default to 10. + */ + switch (base) { + case 8: dmap = odigits; break; + case 16: dmap = hdigits; break; + default: base = 10; dmap = ddigits; break; + } + + /* + * Check for the special hex prefix. + */ + if (*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X')) { + base = 16; + dmap = hdigits; + s += 2; + } + + for (v = 0; isdigok(dmap, *s); s++) + v = (v * base) + a2i[(int) *s]; + + if (end != 0) + *end = s; + + return v; +} + +/******************************************************************** + * + * Routines to load, unload, and use mapping tables to remap BDF fonts + * generated using ttf2bdf. + * + ********************************************************************/ + +/* + * Strings used to store the registry and encoding values specified + * in the mapping table. + */ +static char *registry; +static char *encoding; + +/* + * Trie node structure. + */ +typedef struct { + unsigned short key; /* Key value. */ + unsigned short val; /* Data for the key. */ + unsigned long sibs; /* Offset of siblings from trie beginning. */ + unsigned long kids; /* Offset of children from trie beginning. */ +} node_t; + +/* + * The trie used for remapping codes. + */ +static node_t *nodes; +static unsigned long nodes_size = 0; +static unsigned long nodes_used = 0; + +/* + * Gets the next available node in the trie. + */ +static unsigned long +#ifdef __STDC__ +getnode(unsigned short key) +#else +getnode(key) +unsigned short key; +#endif +{ + unsigned long loc; + node_t *np; + + if (nodes_used == nodes_size) { + if (nodes_size == 0) + nodes = (node_t *) malloc(sizeof(node_t) << 7); + else + nodes = (node_t *) realloc((char *) nodes, sizeof(node_t) * + (nodes_size + 128)); + np = nodes + nodes_size; + nodes_size += 128; + (void) memset((char *) np, 0, sizeof(node_t) << 7); + } + + loc = nodes_used++; + np = nodes + loc; + np->kids = np->sibs = 0; + np->key = key; + return loc; +} + +/* + * Inserts a node in the trie. + */ +static void +#ifdef __STDC__ +trie_insert(unsigned short key, unsigned short val) +#else +trie_insert(key, val) +unsigned short key, val; +#endif +{ + unsigned long i, n, t, l; + unsigned short codes[2]; + + /* + * Convert the incoming key into two codes to make the trie lookup more + * efficient. + */ + codes[0] = (key >> 8) & 0xff; + codes[1] = key & 0xff; + + for (i = t = 0; i < 2; i++) { + if (nodes[t].kids == 0) { + n = getnode(codes[i]); + nodes[t].kids = t = n; + } else if (nodes[nodes[t].kids].key == codes[i]) + t = nodes[t].kids; + else if (nodes[nodes[t].kids].key > codes[i]) { + n = getnode(codes[i]); + nodes[n].sibs = nodes[t].kids; + nodes[t].kids = t = n; + } else { + t = nodes[t].kids; + for (l = t; nodes[t].sibs && nodes[t].key < codes[i]; ) { + l = t; + t = nodes[t].sibs; + } + if (nodes[t].key < codes[i]) { + n = getnode(codes[i]); + nodes[t].sibs = t = n; + } else if (nodes[t].key > codes[i]) { + n = getnode(codes[i]); + nodes[n].sibs = t; + nodes[l].sibs = t = n; + } + } + } + + /* + * Set the value in the leaf node. + */ + nodes[t].val = val; +} + +/* + * List used by the routine that parses the map lines. + */ +static list_t list; + +/* + * Routine to parse each line of the mapping file. + */ +static int +#ifdef __STDC__ +add_mapping(unsigned char *line, unsigned long linelen, unsigned long lineno, + void *client_data) +#else +add_mapping(line, linelen, lineno, client_data) +unsigned char *line; +unsigned long linelen, lineno; +void *client_data; +#endif +{ + unsigned short key, val; + + /* + * Split the line into parts separted by one or more spaces or tabs. + */ + splitline((unsigned char *) " \t+", line, linelen, &list); + + /* + * Check to see if the line starts with one of the keywords. + */ + if (memcmp((char *) list.field[0], "REGISTRY", 8) == 0) { + /* + * Collect the XLFD CHARSET_REGISTRY value. + */ + if (registry != 0) + free((char *) registry); + if ((val = strlen((char *) list.field[1])) == 0) + registry = 0; + else { + registry = (char *) malloc(val + 1); + (void) memcpy(registry, (char *) list.field[1], val + 1); + } + return 0; + } + + if (memcmp((char *) list.field[0], "ENCODING", 8) == 0) { + /* + * Collect the XLFD CHARSET_ENCODING value. + */ + if (encoding != 0) + free((char *) encoding); + if ((val = strlen((char *) list.field[1])) == 0) + encoding = 0; + else { + encoding = (char *) malloc(val + 1); + (void) memcpy(encoding, (char *) list.field[1], val + 1); + } + return 0; + } + + /* + * Get the second field value as the key (the Unicode value). Always + * assume the values are in hex. + */ + key = my_atous(list.field[1], 0, 16); + val = my_atous(list.field[0], 0, 16); + + trie_insert(key, val); + + return 0; +} + +/******************************************************************** + * + * API for mapping table support. + * + ********************************************************************/ + +int +#ifdef __STDC__ +ttf2bdf_load_map(FILE *in) +#else +ttf2bdf_load_map(in) +FILE *in; +#endif +{ + unsigned long lineno; + + /* + * Allocate some nodes initially. + */ + if (nodes_size == 0) { + nodes = (node_t *) malloc(sizeof(node_t) << 7); + nodes_size = 128; + } + + /* + * Reset the trie in case more than one gets loaded for some reason. + */ + if (nodes_size > 0) + (void) memset((char *) nodes, 0, sizeof(node_t) * nodes_size); + nodes_used = 1; + + return scanlines(fileno(in), add_mapping, 0, &lineno); +} + +/* + * Routine that deallocates the mapping trie. + */ +void +#ifdef __STDC__ +ttf2bdf_free_map(void) +#else +ttf2bdf_free_map() +#endif +{ + if (registry != 0) + free((char *) registry); + if (encoding != 0) + free((char *) encoding); + registry = encoding = 0; + + if (list.size > 0) + free((char *) list.field); + list.size = list.used = 0; + + if (nodes_size > 0) + free((char *) nodes); + nodes_size = nodes_used = 0; +} + +/* + * The routine that actually remaps the code by looking it up in the trie. + */ +int +#ifdef __STDC__ +ttf2bdf_remap(unsigned short *code) +#else +ttf2bdf_remap(code) +unsigned short *code; +#endif +{ + unsigned long i, n, t; + unsigned short c, codes[2]; + + /* + * If no mapping table was loaded, then simply return the code. + */ + if (nodes_used == 0) + return 1; + + c = *code; + codes[0] = (c >> 8) & 0xff; + codes[1] = c & 0xff; + + for (i = n = 0; i < 2; i++) { + t = nodes[n].kids; + if (t == 0) + return 0; + for (; nodes[t].sibs && nodes[t].key != codes[i]; t = nodes[t].sibs); + if (nodes[t].key != codes[i]) + return 0; + n = t; + } + + *code = nodes[n].val; + return 1; +} + +void +#ifdef __STDC__ +ttf2bdf_remap_charset(char **registry_name, char **encoding_name) +#else +ttf2bdf_remap_charset(registry_name, encoding_name) +char **registry_name, **encoding_name; +#endif +{ + if (registry_name != 0) + *registry_name = registry; + if (encoding_name != 0) + *encoding_name = encoding; +} diff --git a/contrib/ttf2bdf/remap.h b/contrib/ttf2bdf/remap.h new file mode 100644 index 0000000..15ded54 --- /dev/null +++ b/contrib/ttf2bdf/remap.h @@ -0,0 +1,64 @@ +/* + * Copyright 1996, 1997, 1998, 1999 Computing Research Labs, + * New Mexico State University + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _h_remap +#define _h_remap + +/* + * $Id: remap.h,v 1.4 1999/05/03 17:07:04 mleisher Exp $ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int ttf2bdf_load_map( +#ifdef __STDC__ + FILE *in +#endif +); + +extern void ttf2bdf_free_map( +#ifdef __STDC__ + void +#endif +); + +extern int ttf2bdf_remap( +#ifdef __STDC__ + unsigned short *code +#endif +); + +extern void ttf2bdf_remap_charset( +#ifdef __STDC__ + char **registry_name, + char **encoding_name +#endif +); + +#ifdef __cplusplus +} +#endif + +#endif /* _h_remap */ diff --git a/contrib/ttf2bdf/ttf2bdf.c b/contrib/ttf2bdf/ttf2bdf.c new file mode 100644 index 0000000..903fc18 --- /dev/null +++ b/contrib/ttf2bdf/ttf2bdf.c @@ -0,0 +1,1581 @@ +/* + * Copyright 1996, 1997, 1998, 1999 Computing Research Labs, + * New Mexico State University + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef lint +#ifdef __GNUC__ +static char rcsid[] __attribute__ ((unused)) = "$Id: ttf2bdf.c,v 1.25 1999/10/21 16:31:54 mleisher Exp $"; +#else +static char rcsid[] = "$Id: ttf2bdf.c,v 1.25 1999/10/21 16:31:54 mleisher Exp $"; +#endif +#endif + +#include + +#ifdef WIN32 +#include +#else +#include +#include +#endif + +#include + +#include "freetype.h" + +/* + * Include the remapping support. + */ +#include "remap.h" + +/************************************************************************** + * + * Macros. + * + **************************************************************************/ + +/* + * The version of ttf2bdf. + */ +#define TTF2BDF_VERSION "2.8" + +/* + * Set the default values used to generate a BDF font. + */ +#ifndef DEFAULT_PLATFORM_ID +#define DEFAULT_PLATFORM_ID 3 +#endif + +#ifndef DEFAULT_ENCODING_ID +#define DEFAULT_ENCODING_ID 1 +#endif + +#ifndef DEFAULT_POINT_SIZE +#define DEFAULT_POINT_SIZE 12 +#endif + +#ifndef DEFAULT_RESOLUTION +#define DEFAULT_RESOLUTION 100 +#endif + +/* + * Used as a fallback for XLFD names where the character set/encoding can not + * be determined. + */ +#ifndef DEFAULT_XLFD_CSET +#define DEFAULT_XLFD_CSET "-FontSpecific-0" +#endif + +/* + * nameID macros for getting strings from the TT font. + */ +#define TTF_COPYRIGHT 0 +#define TTF_TYPEFACE 1 +#define TTF_PSNAME 6 + +#ifndef MAX +#define MAX(h,i) ((h) > (i) ? (h) : (i)) +#endif + +#ifndef MIN +#define MIN(l,o) ((l) < (o) ? (l) : (o)) +#endif + +/************************************************************************** + * + * General globals set from command line. + * + **************************************************************************/ + +/* + * The program name. + */ +static char *prog; + +/* + * The flag indicating whether messages should be printed or not. + */ +static int verbose = 0; + +/* + * Flags used when loading glyphs. + */ +static int load_flags = TTLOAD_SCALE_GLYPH | TTLOAD_HINT_GLYPH; + +/* + * The default platform and encoding ID's. + */ +static int pid = DEFAULT_PLATFORM_ID; +static int eid = DEFAULT_ENCODING_ID; + +/* + * Default point size and resolutions. + */ +static int point_size = DEFAULT_POINT_SIZE; +static int hres = DEFAULT_RESOLUTION; +static int vres = DEFAULT_RESOLUTION; + +/* + * The user supplied foundry name to use in the XLFD name. + */ +static char *foundry_name = 0; + +/* + * The user supplied typeface name to use in the XLFD name. + */ +static char *face_name = 0; + +/* + * The user supplied weight name to use in the XLFD name. + */ +static char *weight_name = 0; + +/* + * The user supplied slant name to use in the XLFD name. + */ +static char *slant_name = 0; + +/* + * The user supplied width name to use in the XLFD name. + */ +static char *width_name = 0; + +/* + * The user supplied additional style name to use in the XLFD name. + */ +static char *style_name = 0; + +/* + * The user supplied spacing (p = proportional, c = character cell, + * m = monospace). + */ +static int spacing = 0; + +/* + * The dash character to use in the names retrieved from the font. Default is + * the space. + */ +static int dashchar = ' '; + +/* + * Flag, bitmask, and max code for generating a subset of the glyphs in a font. + */ +static int do_subset = 0; +static unsigned short maxcode; +static unsigned long subset[2048]; + +/* + * The flag that indicates the remapping table should be used to + * reencode the font. + */ +static int do_remap = 0; + +/************************************************************************** + * + * Internal globals. + * + **************************************************************************/ + +/* + * Structure used for calculating the font bounding box as the glyphs are + * generated. + */ +typedef struct { + short minlb; + short maxlb; + short maxrb; + short maxas; + short maxds; + short rbearing; +} bbx_t; + +static bbx_t bbx; + +/* + * The buffer used to transfer the temporary file to the actual output file. + */ +#define TTF2BDF_IOBUFSIZ 8192 +static char iobuf[TTF2BDF_IOBUFSIZ]; + +/* + * The Units Per Em value used in numerous places. + */ +static TT_UShort upm; + +/* + * A flag indicating if a CMap was found or not. + */ +static TT_UShort nocmap; + +/* + * The scaling factor needed to compute the SWIDTH (scalable width) value + * for BDF glyphs. + */ +static double swscale; + +/* + * Mac encoding names used when creating the BDF XLFD font name. + */ +static char *mac_encodings[] = { + "-MacRoman-0", "-MacJapanese-0", "-MacChinese-0", "-MacKorean-0", + "-MacArabic-0", "-MacHebrew-0", "-MacGreek-0", "-MacRussian-0", + "-MacRSymbol-0", "-MacDevanagari-0", "-MacGurmukhi-0", "-MacGujarati-0", + "-MacOriya-0", "-MacBengali-0", "-MacTamil-0", "-MacTelugu-0", + "-MacKannada-0", "-MacMalayalam-0", "-MacSinhalese-0", "-MacBurmese-0", + "-MacKhmer-0", "-MacThai-0", "-MacLaotian-0", "-MacGeorgian-0", + "-MacArmenian-0", "-MacMaldivian-0", "-MacTibetan-0", "-MacMongolian-0", + "-MacGeez-0", "-MacSlavic-0", "-MacVietnamese-0","-MacSindhi-0", + "-MacUninterp-0" +}; +static int num_mac_encodings = sizeof(mac_encodings) / + sizeof(mac_encodings[0]); + +/* + * ISO encoding names used when creating the BDF XLFD font name. + */ +static char *iso_encodings[] = { + "-ASCII-0", "-ISO10646-0", "-ISO8859-1" +}; +static int num_iso_encodings = sizeof(iso_encodings) / + sizeof(iso_encodings[0]); + +/* + * Microsoft encoding names used when creating the BDF XLFD font name. + */ +static char *ms_encodings[] = { + "-Symbol-0", "-ISO10646-1", "-ShiftJIS-0", "-GB2312.1980-0", "-Big5-0", + "-KSC5601.1987-0", "-KSC5601.1992-0" +}; +static int num_ms_encodings = sizeof(ms_encodings) / + sizeof(ms_encodings[0]); + +/* + * The propery names for all the XLFD properties. + */ +static char *xlfd_props[] = { + "FOUNDRY", + "FAMILY_NAME", + "WEIGHT_NAME", + "SLANT", + "SETWIDTH_NAME", + "ADD_STYLE_NAME", + "PIXEL_SIZE", + "POINT_SIZE", + "RESOLUTION_X", + "RESOLUTION_Y", + "SPACING", + "AVERAGE_WIDTH", + "CHARSET_REGISTRY", + "CHARSET_ENCODING", +}; + +/************************************************************************** + * + * Freetype globals. + * + **************************************************************************/ + +static TT_Engine engine; +static TT_Face face; +static TT_Face_Properties properties; + +static TT_Instance instance; + +static TT_Glyph glyph; +static TT_Glyph_Metrics metrics; +static TT_Instance_Metrics imetrics; + +static TT_Raster_Map raster; + +static TT_CharMap cmap; + +/************************************************************************** + * + * Freetype related code. + * + **************************************************************************/ + +/* + * A generic routine to get a name from the TT name table. This routine + * always looks for English language names and checks three possibilities: + * 1. English names with the MS Unicode encoding ID. + * 2. English names with the MS unknown encoding ID. + * 3. English names with the Apple Unicode encoding ID. + * + * The particular name ID mut be provided (e.g. nameID = 0 for copyright + * string, nameID = 6 for Postscript name, nameID = 1 for typeface name. + * + * If the `dash' flag is non-zero, all dashes (-) in the name will be replaced + * with the character passed. + * + * Returns the number of bytes added. + */ +static int +#ifdef __STDC__ +ttf_get_english_name(char *name, int nameID, int dash) +#else +ttf_get_english_name(name, nameID, dash) +char *name; +int nameID, dash; +#endif +{ + TT_UShort slen; + int i, j, encid, nrec; + unsigned short nrPlatformID, nrEncodingID, nrLanguageID, nrNameID; + char *s; + + nrec = TT_Get_Name_Count(face); + + for (encid = 1, j = 0; j < 2; j++, encid--) { + /* + * Locate one of the MS English font names. + */ + for (i = 0; i < nrec; i++) { + TT_Get_Name_ID(face, i, &nrPlatformID, &nrEncodingID, + &nrLanguageID, &nrNameID); + if (nrPlatformID == 3 && + nrEncodingID == encid && + nrNameID == nameID && + (nrLanguageID == 0x0409 || nrLanguageID == 0x0809 || + nrLanguageID == 0x0c09 || nrLanguageID == 0x1009 || + nrLanguageID == 0x1409 || nrLanguageID == 0x1809)) { + TT_Get_Name_String(face, i, &s, &slen); + break; + } + } + + if (i < nrec) { + /* + * Found one of the MS English font names. The name is by + * definition encoded in Unicode, so copy every second byte into + * the `name' parameter, assuming there is enough space. + */ + for (i = 1; s != 0 && i < slen; i += 2) { + if (dash) + *name++ = (s[i] == '-' || s[i] == ' ') ? dash : s[i]; + else if (s[i] == '\r' || s[i] == '\n') { + if (s[i] == '\r' && i + 2 < slen && s[i + 2] == '\n') + i += 2; + *name++ = ' '; + *name++ = ' '; + } else + *name++ = s[i]; + } + *name = 0; + return (slen >> 1); + } + } + + /* + * No MS English name found, attempt to find an Apple Unicode English + * name. + */ + for (i = 0; i < nrec; i++) { + TT_Get_Name_ID(face, i, &nrPlatformID, &nrEncodingID, + &nrLanguageID, &nrNameID); + if (nrPlatformID == 0 && nrLanguageID == 0 && + nrNameID == nameID) { + TT_Get_Name_String(face, i, &s, &slen); + break; + } + } + + if (i < nrec) { + /* + * Found the Apple Unicode English name. The name is by definition + * encoded in Unicode, so copy every second byte into the `name' + * parameter, assuming there is enough space. + */ + for (i = 1; s != 0 && i < slen; i += 2) { + if (dash) + *name++ = (s[i] == '-' || s[i] == ' ') ? dash : s[i]; + else if (s[i] == '\r' || s[i] == '\n') { + if (s[i] == '\r' && i + 2 < slen && s[i + 2] == '\n') + i += 2; + *name++ = ' '; + *name++ = ' '; + } else + *name++ = s[i]; + } + *name = 0; + return (slen >> 1); + } + + return 0; +} + +/************************************************************************** + * + * General code. + * + **************************************************************************/ + +/* + * Create an XLFD name. Assumes there is enough space in the string passed + * to fit a reasonably long XLFD name into, up to the 256 byte maximum. + */ +static void +#ifdef __STDC__ +make_xlfd_name(char *name, TT_Long awidth, int ismono) +#else +make_xlfd_name(name, awidth, ismono) +char *name; +TT_Long awidth; +int ismono; +#endif +{ + TT_Long i; + TT_ULong val; + char *r, *e; + double dr, dp; + + /* + * Default the foundry name to "FreeType" in honor of the project and + * because the foundry name is too difficult to automatically determine + * from the names in TT fonts. But the user can provide his own. + */ + if (foundry_name == 0) { + (void) strcpy(name, "-FreeType"); + name += 9; + } else { + *(name++)='-'; + strcpy(name,foundry_name); + name+=strlen(foundry_name); + } + + /* + * Add the typeface name from the font. The fallback default will be + * "Unknown". + */ + *name++ = '-'; + if (face_name == 0) { + if((i = ttf_get_english_name(name, TTF_TYPEFACE, dashchar))) + name += i; + else { + (void) strcpy(name, "Unknown"); + name += 7; + } + } else { + (void) strcpy(name, face_name); + name += strlen(face_name); + } + + /* + * Add the weight name. The default will be "Medium". + */ + if (weight_name != 0) { + sprintf(name, "-%s", weight_name); + name += strlen(weight_name) + 1; + } else { + if (properties.os2->fsSelection & 0x20) { + (void) strcpy(name, "-Bold"); + name += 5; + } else { + (void) strcpy(name, "-Medium"); + name += 7; + } + } + + /* + * Add the slant name. The default will be 'R'. + */ + if (slant_name) { + sprintf(name, "-%s", slant_name); + name += strlen(slant_name) + 1; + } else { + *name++ = '-'; + if (properties.os2->fsSelection & 0x01) + *name++ = 'I'; + else + *name++ = 'R'; + } + + /* + * Default the setwidth name to "Normal" but user can specify one. + */ + if (width_name == 0) { + (void) strcpy(name, "-Normal"); + name += 7; + } else { + *(name++)='-'; + strcpy(name,width_name); + name+=strlen(width_name); + } + + /* + * Default the additional style name to NULL but user can specify one. + */ + *name++ = '-'; + if (style_name != 0) { + strcpy(name,style_name); + name+=strlen(style_name); + } + + /* + * Determine the pixel size from the point size and resolution. + */ + dr = (double) vres; + dp = (double) (point_size * 10); + val = (unsigned long) (((dp * dr) / 722.7) + 0.5); + + /* + * Set the pixel size, point size, and resolution. + */ + sprintf(name, "-%ld-%d-%d-%d", val, point_size * 10, hres, vres); + name += strlen(name); + + switch (spacing) { + case 'p': case 'P': spacing = 'P'; break; + case 'm': case 'M': spacing = 'M'; break; + case 'c': case 'C': spacing = 'C'; break; + default: spacing = 0; break; + } + + /* + * Set the spacing. + */ + if (!spacing) + spacing = (ismono) ? 'M' : 'P'; + *name++ = '-'; + *name++ = spacing; + + /* + * Add the average width. + */ + sprintf(name, "-%ld", awidth); + name += strlen(name); + + /* + * Check to see if the remapping table specified a registry and encoding + * and use those if they both exist. + */ + ttf2bdf_remap_charset(&r, &e); + if (r != 0 && e != 0) { + sprintf(name, "-%s-%s", r, e); + return; + } + + /* + * If the cmap for the platform and encoding id was not found, or the + * platform id is unknown, assume the character set registry and encoding + * are the XLFD default. + */ + if (nocmap || pid > 3) + (void) strcpy(name, DEFAULT_XLFD_CSET); + else { + /* + * Finally, determine the character set registry and encoding from the + * platform and encoding ID. + */ + switch (pid) { + case 0: + /* + * Apple Unicode platform, so "Unicode-2.0" is the default. + */ + (void) strcpy(name, "-Unicode-2.0"); + break; + case 1: + /* + * Macintosh platform, so choose from the Macintosh encoding + * strings. + */ + if (eid < 0 || eid >= num_mac_encodings) + (void) strcpy(name, DEFAULT_XLFD_CSET); + else + (void) strcpy(name, mac_encodings[eid]); + break; + case 2: + /* + * ISO platform, so choose from the ISO encoding strings. + */ + if (eid < 0 || eid >= num_iso_encodings) + (void) strcpy(name, DEFAULT_XLFD_CSET); + else + (void) strcpy(name, iso_encodings[eid]); + break; + case 3: + /* + * Microsoft platform, so choose from the MS encoding strings. + */ + if (eid < 0 || eid >= num_ms_encodings) + (void) strcpy(name, DEFAULT_XLFD_CSET); + else + (void) strcpy(name, ms_encodings[eid]); + break; + } + } +} + +static int +#ifdef __STDC__ +generate_font(FILE *out, char *iname, char *oname) +#else +generate_font(out, iname, oname) +FILE *out; +char *iname, *oname; +#endif +{ + int eof, ismono, i; + FILE *tmp; + TT_Short maxx, maxy, minx, miny, xoff, yoff, dwidth, swidth; + TT_Short y_off, x_off; + TT_UShort sx, sy, ex, ey, wd, ht; + TT_Long code, idx, ng, aw; + TT_UShort remapped_code; + unsigned char *bmap; + double dw; + char *xp, xlfd[256]; + char *tmpdir, tmpfile[BUFSIZ]; + + /* + * Open a temporary file to store the bitmaps in until the exact number + * of bitmaps are known. + */ + if ((tmpdir = getenv("TMPDIR")) == 0) + tmpdir = "/tmp"; + sprintf(tmpfile, "%s/ttf2bdf%ld", tmpdir, (long) getpid()); + if ((tmp = fopen(tmpfile, "w")) == 0) { + fprintf(stderr, "%s: unable to open temporary file '%s'.\n", + prog, tmpfile); + return -1; + } + + /* + * Calculate the scale factor for the SWIDTH field. + */ + swscale = ((double) vres) * ((double) point_size); + + /* + * Calculate the font bounding box again so enough storage for the largest + * bitmap can be allocated. + */ + minx = (properties.header->xMin * imetrics.x_ppem) / upm; + miny = (properties.header->yMin * imetrics.y_ppem) / upm; + maxx = (properties.header->xMax * imetrics.x_ppem) / upm; + maxy = (properties.header->yMax * imetrics.y_ppem) / upm; + + maxx -= minx; ++maxx; + maxy -= miny; ++maxy; + + /* + * Initialize the flag that tracks if the font is monowidth or not and + * initialize the glyph width variable that is used for testing for a + * monowidth font. + */ + wd = 0xffff; + ismono = 1; + + /* + * Use the upward flow because the version of FreeType being used when + * this was written did not support TT_Flow_Down. This insures that this + * routine will not mess up if TT_Flow_Down is implemented at some point. + */ + raster.flow = TT_Flow_Up; + raster.width = maxx; + raster.rows = maxy; + raster.cols = (maxx + 7) >> 3; + raster.size = raster.cols * raster.rows; + raster.bitmap = (void *) malloc(raster.size); + + for (ng = code = 0, eof = 0, aw = 0; eof != EOF && code < 0xffff; code++) { + + /* + * If a remap is indicated, attempt to remap the code. If a remapped + * code is not found, then skip generating the glyph. + */ + remapped_code = (TT_UShort) code; + if (do_remap && !ttf2bdf_remap(&remapped_code)) + continue; + + /* + * If a subset is being generated and the code is greater than the max + * code of the subset, break out of the loop to avoid doing any more + * work. + */ + if (do_subset && remapped_code > maxcode) + break; + + /* + * If a subset is being generated and the index is not in the subset + * bitmap, just continue. + */ + if (do_subset && + !(subset[remapped_code >> 5] & (1 << (remapped_code & 31)))) + continue; + + if (nocmap) { + if (code >= properties.num_Glyphs) + + /* + * At this point, all the glyphs are done. + */ + break; + idx = code; + } else + idx = TT_Char_Index(cmap, code); + + /* + * If the glyph could not be loaded for some reason, or a subset is + * being generated and the index is not in the subset bitmap, just + * continue. + */ + + if (idx <= 0 || TT_Load_Glyph(instance, glyph, idx, load_flags)) + continue; + + (void) TT_Get_Glyph_Metrics(glyph, &metrics); + + /* + * Clear the raster bitmap. + */ + (void) memset((char *) raster.bitmap, 0, raster.size); + + /* + * Grid fit to determine the x and y offsets that will force the + * bitmap to fit into the storage provided. + */ + xoff = (63 - metrics.bbox.xMin) & -64; + yoff = (63 - metrics.bbox.yMin) & -64; + + /* + * If the bitmap cannot be generated, simply continue. + */ + if (TT_Get_Glyph_Bitmap(glyph, &raster, xoff, yoff)) + continue; + + /* + * Determine the DWIDTH (device width, or advance width in TT terms) + * and the SWIDTH (scalable width) values. + */ + dwidth = metrics.advance >> 6; + dw = (double) dwidth; + swidth = (TT_Short) ((dw * 72000.0) / swscale); + + /* + * Determine the actual bounding box of the glyph bitmap. Do not + * forget that the glyph is rendered upside down! + */ + sx = ey = 0xffff; + sy = ex = 0; + bmap = (unsigned char *) raster.bitmap; + for (miny = 0; miny < raster.rows; miny++) { + for (minx = 0; minx < raster.width; minx++) { + if (bmap[(miny * raster.cols) + (minx >> 3)] & + (0x80 >> (minx & 7))) { + if (minx < sx) + sx = minx; + if (minx > ex) + ex = minx; + if (miny > sy) + sy = miny; + if (miny < ey) + ey = miny; + } + } + } + + /* + * If the glyph is actually an empty bitmap, set the size to 0 all + * around. + */ + if (sx == 0xffff && ey == 0xffff && sy == 0 && ex == 0) + sx = ex = sy = ey = 0; + + /* + * Increment the number of glyphs generated. + */ + ng++; + + /* + * Test to see if the font is going to be monowidth or not by + * comparing the current glyph width against the last one. + */ + if (ismono && (ex - sx) + 1 != wd) + ismono = 0; + + /* + * Adjust the font bounding box. + */ + wd = (ex - sx) + 1; + ht = (sy - ey) + 1; + x_off = sx - (xoff >> 6); + y_off = ey - (yoff >> 6); + + bbx.maxas = MAX(bbx.maxas, ht + y_off); + bbx.maxds = MAX(bbx.maxds, -y_off); + bbx.rbearing = wd + x_off; + bbx.maxrb = MAX(bbx.maxrb, bbx.rbearing); + bbx.minlb = MIN(bbx.minlb, x_off); + bbx.maxlb = MAX(bbx.maxlb, x_off); + + /* + * Add to the average width accumulator. + */ + aw += wd; + + /* + * Print the bitmap header. + */ + fprintf(tmp, "STARTCHAR %04lX\nENCODING %ld\n", code, + (long) remapped_code); + fprintf(tmp, "SWIDTH %hd 0\n", swidth); + fprintf(tmp, "DWIDTH %hd 0\n", dwidth); + fprintf(tmp, "BBX %hd %hd %hd %hd\n", wd, ht, x_off, y_off); + + /* + * Check for an error return here in case the temporary file system + * fills up or the file is deleted while it is being used. + */ + eof = fprintf(tmp, "BITMAP\n"); + + /* + * Now collect the bits so they can be printed. + */ + for (miny = sy; eof != EOF && miny >= ey; miny--) { + for (idx = 0, minx = sx; eof != EOF && minx <= ex; minx++) { + if (minx > sx && ((minx - sx) & 7) == 0) { + /* + * Print the next byte. + */ + eof = fprintf(tmp, "%02lX", idx & 0xff); + idx = 0; + } + if (bmap[(miny * raster.cols) + (minx >> 3)] & + (0x80 >> (minx & 7))) + idx |= 0x80 >> ((minx - sx) & 7); + } + if (eof != EOF) + /* + * Because of the structure of the loop, the last byte should + * always be printed. + */ + fprintf(tmp, "%02lX\n", idx & 0xff); + } + if (eof != EOF) + fprintf(tmp, "ENDCHAR\n"); + } + + fclose(tmp); + + /* + * If a write error occured, delete the temporary file and issue an error + * message. + */ + if (eof == EOF) { + (void) unlink(tmpfile); + fprintf(stderr, "%s: problem writing to temporary file '%s'.\n", + prog, tmpfile); + if (raster.size > 0) + free((char *) raster.bitmap); + return -1; + } + + /* + * If no characters were generated, just unlink the temp file and issue a + * warning. + */ + if (ng == 0) { + (void) unlink(tmpfile); + fprintf(stderr, "%s: no glyphs generated from '%s'.\n", prog, iname); + if (raster.size > 0) + free((char *) raster.bitmap); + return -1; + } + + /* + * Reopen the temporary file so it can be copied to the actual output + * file. + */ + if ((tmp = fopen(tmpfile, "r")) == 0) { + /* + * Unable to open the file for read, so attempt to delete it and issue + * an error message. + */ + (void) unlink(tmpfile); + fprintf(stderr, "%s: unable to open temporary file '%s' for read.\n", + prog, tmpfile); + if (raster.size > 0) + free((char *) raster.bitmap); + return -1; + } + + /* + * Free up the raster storage. + */ + if (raster.size > 0) + free((char *) raster.bitmap); + + /* + * Calculate the average width. + */ + aw = (TT_Long) ((((double) aw / (double) ng) + 0.5) * 10.0); + + /* + * Generate the XLFD font name. + */ + make_xlfd_name(xlfd, aw, ismono); + + /* + * Start writing the font out. + */ + fprintf(out, "STARTFONT 2.1\n"); + + /* + * Add the vanity comments. + */ + fprintf(out, "COMMENT\n"); + fprintf(out, "COMMENT Converted from TrueType font \"%s\" by \"%s %s\".\n", + iname, prog, TTF2BDF_VERSION); + fprintf(out, "COMMENT\n"); + + fprintf(out, "FONT %s\n", xlfd); + fprintf(out, "SIZE %d %d %d\n", point_size, hres, vres); + + /* + * Generate the font bounding box. + */ + fprintf(out, "FONTBOUNDINGBOX %hd %hd %hd %hd\n", + bbx.maxrb - bbx.minlb, bbx.maxas + bbx.maxds, + bbx.minlb, -bbx.maxds); + + /* + * Print the properties. + */ + fprintf(out, "STARTPROPERTIES %hd\n", 19); + + /* + * Print the font properties from the XLFD name. + */ + for (i = 0, xp = xlfd; i < 14; i++) { + /* + * Print the XLFD property name. + */ + fprintf(out, "%s ", xlfd_props[i]); + + /* + * Make sure the ATOM properties are wrapped in double quotes. + */ + if (i < 6 || i == 10 || i > 11) + putc('"', out); + + /* + * Skip the leading '-' in the XLFD name. + */ + xp++; + + /* + * Skip until the next '-' or NULL. + */ + for (; *xp && *xp != '-'; xp++) + putc(*xp, out); + + /* + * Make sure the ATOM properties are wrapped in double quotes. + */ + if (i < 6 || i == 10 || i > 11) + putc('"', out); + + putc('\n', out); + } + + /* + * Make sure to add the FONT_ASCENT and FONT_DESCENT properties + * because X11 can not live without them. + */ + fprintf(out, "FONT_ASCENT %hd\nFONT_DESCENT %hd\n", + (properties.horizontal->Ascender * imetrics.y_ppem) / upm, + -((properties.horizontal->Descender * imetrics.y_ppem) / upm)); + + /* + * Get the copyright string from the font. + */ + (void) ttf_get_english_name(xlfd, TTF_COPYRIGHT, 0); + fprintf(out, "COPYRIGHT \"%s\"\n", xlfd); + + /* + * Last, print the two user-defined properties _TTF_FONTFILE and + * _TTF_PSNAME. _TTF_FONTFILE provides a reference to the original TT + * font file which some systems can take advantage of, and _TTF_PSNAME + * provides the Postscript name of the font if it exists. + */ + (void) ttf_get_english_name(xlfd, TTF_PSNAME, 0); + fprintf(out, "_TTF_FONTFILE \"%s\"\n_TTF_PSNAME \"%s\"\n", iname, xlfd); + + fprintf(out, "ENDPROPERTIES\n"); + + /* + * Print the actual number of glyphs to the output file. + */ + eof = fprintf(out, "CHARS %ld\n", ng); + + /* + * Copy the temporary file to the output file. + */ + while (eof != EOF && (ng = fread(iobuf, 1, TTF2BDF_IOBUFSIZ, tmp))) { + if (fwrite(iobuf, 1, ng, out) == 0) + eof = EOF; + } + + /* + * Close the temporary file and delete it. + */ + fclose(tmp); + (void) unlink(tmpfile); + + /* + * If an error occured when writing to the output file, issue a warning + * and return. + */ + if (eof == EOF) { + fprintf(stderr, "%s: problem writing to output file '%s'.\n", + prog, oname); + if (raster.size > 0) + free((char *) raster.bitmap); + return -1; + } + + /* + * End the font and do memory cleanup on the glyph and raster structures. + */ + eof = fprintf(out, "ENDFONT\n"); + + return eof; +} + +static int +#ifdef __STDC__ +generate_bdf(FILE *out, char *iname, char *oname) +#else +generate_bdf(out, iname, oname) +FILE *out; +char *iname, *oname; +#endif +{ + TT_Long i; + TT_UShort p, e; + + /* + * Get the requested cmap. + */ + for (i = 0; i < TT_Get_CharMap_Count(face); i++) { + if (!TT_Get_CharMap_ID(face, i, &p, &e) && + p == pid && e == eid) + break; + } + if (i == TT_Get_CharMap_Count(face) && pid == 3 && eid == 1) { + /* + * Make a special case when this fails with pid == 3 and eid == 1. + * Change to eid == 0 and try again. This captures the two possible + * cases for MS fonts. Some other method should be used to cycle + * through all the alternatives later. + */ + for (i = 0; i < TT_Get_CharMap_Count(face); i++) { + if (!TT_Get_CharMap_ID(face, i, &p, &e) && + p == pid && e == 0) + break; + } + if (i < TT_Get_CharMap_Count(face)) { + if (!TT_Get_CharMap(face, i, &cmap)) + eid = 0; + else + nocmap = 1; + } + } else { + /* + * A CMap was found for the platform and encoding IDs. + */ + if (i < TT_Get_CharMap_Count(face) && TT_Get_CharMap(face, i, &cmap)) + nocmap = 1; + else + nocmap = 0; + } + + if (nocmap && verbose) { + fprintf(stderr, + "%s: no character map for platform %d encoding %d. ", + prog, pid, eid); + fprintf(stderr, "Generating all glyphs.\n"); + } + + /* + * Now go through and generate the glyph bitmaps themselves. + */ + return generate_font(out, iname, oname); +} + +#define isdig(cc) ((cc) >= '0' && (cc) <= '9') + +/* + * Routine to parse a subset specification supplied on the command line. + * The syntax for this specification is the same as the syntax used for + * the XLFD font names (XLFD documentation, page 9). + * + * Example: + * + * "60 70 80_90" means the glyphs at codes 60, 70, and between 80 and + * 90 inclusive. + */ +static void +#ifdef __STDC__ +parse_subset(char *s) +#else +parse_subset(s) +char *s; +#endif +{ + long l, r; + + /* + * Make sure to clear the flag and bitmap in case more than one subset is + * specified on the command line. + */ + maxcode = 0; + do_subset = 0; + (void) memset((char *) subset, 0, sizeof(unsigned long) * 2048); + + while (*s) { + /* + * Collect the next code value. + */ + for (l = r = 0; *s && isdig(*s); s++) + l = (l * 10) + (*s - '0'); + + /* + * If the next character is an '_', advance and collect the end of the + * specified range. + */ + if (*s == '_') { + s++; + for (; *s && isdig(*s); s++) + r = (r * 10) + (*s - '0'); + } else + r = l; + + /* + * Add the range just collected to the subset bitmap and set the flag + * that indicates a subset is wanted. + */ + for (; l <= r; l++) { + do_subset = 1; + subset[l >> 5] |= (1 << (l & 31)); + if (l > maxcode) + maxcode = l; + } + + /* + * Skip all non-digit characters. + */ + while (*s && !isdig(*s)) + s++; + } +} + +static void +#ifdef __STDC__ +usage(int eval) +#else +usage(eval) +int eval; +#endif +{ + fprintf(stderr, "Usage: %s [options below] font.ttf\n", prog); + fprintf(stderr, "-h\t\tThis message.\n"); + fprintf(stderr, "-v\t\tPrint warning messages during conversion.\n"); + fprintf(stderr, + "-l \"subset\"\tSpecify a subset of glyphs to generate.\n"); + fprintf(stderr, "-m mapfile\tGlyph reencoding file.\n"); + fprintf(stderr, "-n\t\tTurn off glyph hinting.\n"); + fprintf(stderr, + "-c c\t\tSet the character spacing (default: from font).\n"); + fprintf(stderr, + "-f name\t\tSet the foundry name (default: freetype).\n"); + fprintf(stderr, + "-t name\t\tSet the typeface name (default: from font).\n"); + fprintf(stderr, "-w name\t\tSet the weight name (default: Medium).\n"); + fprintf(stderr, "-s name\t\tSet the slant name (default: R).\n"); + fprintf(stderr, "-k name\t\tSet the width name (default: Normal).\n"); + fprintf(stderr, + "-d name\t\tSet the additional style name (default: empty).\n"); + fprintf(stderr, "-u char\t\tSet the character to replace '-' in names "); + fprintf(stderr, "(default: space).\n"); + fprintf(stderr, + "-pid id\t\tSet the platform ID for encoding (default: %d).\n", + DEFAULT_PLATFORM_ID); + fprintf(stderr, + "-eid id\t\tSet the encoding ID for encoding (default: %d).\n", + DEFAULT_ENCODING_ID); + fprintf(stderr, "-p n\t\tSet the point size (default: %dpt).\n", + DEFAULT_POINT_SIZE); + fprintf(stderr, "-r n\t\tSet the horizontal and vertical resolution "); + fprintf(stderr, "(default: %ddpi).\n", DEFAULT_RESOLUTION); + fprintf(stderr, "-rh n\t\tSet the horizontal resolution "); + fprintf(stderr, "(default: %ddpi)\n", DEFAULT_RESOLUTION); + fprintf(stderr, "-rv n\t\tSet the vertical resolution "); + fprintf(stderr, "(default: %ddpi)\n", DEFAULT_RESOLUTION); + fprintf(stderr, + "-o outfile\tSet the output filename (default: stdout).\n"); + exit(eval); +} + +int +#ifdef __STDC__ +main(int argc, char *argv[]) +#else +main(argc, argv) +int argc; +char *argv[]; +#endif +{ + int res; + char *infile, *outfile, *iname, *oname; + FILE *out, *mapin; + + if ((prog = strrchr(argv[0], '/'))) + prog++; + else + prog = argv[0]; + + out = stdout; + infile = outfile = 0; + + argc--; + argv++; + + while (argc > 0) { + if (argv[0][0] == '-') { + switch (argv[0][1]) { + case 'v': case 'V': + verbose = 1; + break; + case 'l': case 'L': + argc--; + argv++; + parse_subset(argv[0]); + break; + case 'n': case 'N': + load_flags &= ~TTLOAD_HINT_GLYPH; + break; + case 'c': case 'C': + argc--; + argv++; + spacing = argv[0][0]; + break; + case 't': case 'T': + argc--; + argv++; + face_name = argv[0]; + break; + case 'w': case 'W': + argc--; + argv++; + weight_name = argv[0]; + break; + case 's': case 'S': + argc--; + argv++; + slant_name = argv[0]; + break; + case 'k': case 'K': + argc--; + argv++; + width_name = argv[0]; + break; + case 'd': case 'D': + argc--; + argv++; + style_name = argv[0]; + break; + case 'f': case 'F': + argc--; + argv++; + foundry_name = argv[0]; + break; + case 'u': case 'U': + argc--; + argv++; + dashchar = argv[0][0]; + break; + case 'p': case 'P': + res = argv[0][2]; + argc--; + argv++; + if (res == 'i' || res == 'I') + /* + * Set the platform ID. + */ + pid = atoi(argv[0]); + else + /* + * Set the point size. + */ + point_size = atoi(argv[0]); + break; + case 'e': case 'E': + /* + * Set the encoding ID. + */ + argc--; + argv++; + eid = atoi(argv[0]); + break; + case 'r': + /* + * Set the horizontal and vertical resolutions. + */ + if (argv[0][2] == 'h') + hres = atoi(argv[1]); + else if (argv[0][2] == 'v') + vres = atoi(argv[1]); + else + hres = vres = atoi(argv[1]); + argc--; + argv++; + break; + case 'm': case 'M': + /* + * Try to load a remap table. + */ + argc--; + argv++; + + /* + * Always reset the `do_remap' variable here in case more than + * one map file appears on the command line. + */ + do_remap = 0; + if ((mapin = fopen(argv[0], "r")) == 0) + fprintf(stderr, "%s: unable to open the remap table '%s'.\n", + prog, argv[0]); + else { + if (ttf2bdf_load_map(mapin) < 0) { + fprintf(stderr, + "%s: problem loading remap table '%s'.\n", + prog, argv[0]); + do_remap = 0; + } else + do_remap = 1; + fclose(mapin); + } + break; + case 'o': case 'O': + /* + * Set the output file name. + */ + argc--; + argv++; + outfile = argv[0]; + break; + default: + usage(1); + } + } else + /* + * Set the input file name. + */ + infile = argv[0]; + + argc--; + argv++; + } + + /* + * Validate the values passed on the command line. + */ + if (infile == 0) { + fprintf(stderr, "%s: no input file provided.\n", prog); + usage(1); + } + /* + * Set the input filename that will be passed to the generator + * routine. + */ + if ((iname = strrchr(infile, '/'))) + iname++; + else + iname = infile; + + /* + * Check the platform and encoding IDs. + */ + if (pid < 0 || pid > 255) { + fprintf(stderr, "%s: invalid platform ID '%d'.\n", prog, pid); + exit(1); + } + if (eid < 0 || eid > 65535) { + fprintf(stderr, "%s: invalid encoding ID '%d'.\n", prog, eid); + exit(1); + } + + /* + * Arbitrarily limit the point size to a minimum of 2pt and maximum of + * 256pt. + */ + if (point_size < 2 || point_size > 256) { + fprintf(stderr, "%s: invalid point size '%dpt'.\n", prog, point_size); + exit(1); + } + + /* + * Arbitrarily limit the resolutions to a minimum of 10dpi and a maximum + * of 1200dpi. + */ + if (hres < 10 || hres > 1200) { + fprintf(stderr, "%s: invalid horizontal resolution '%ddpi'.\n", + prog, hres); + exit(1); + } + if (vres < 10 || vres > 1200) { + fprintf(stderr, "%s: invalid vertical resolution '%ddpi'.\n", + prog, vres); + exit(1); + } + + /* + * Open the output file if specified. + */ + if (outfile != 0) { + /* + * Attempt to open the output file. + */ + if ((out = fopen(outfile, "w")) == 0) { + fprintf(stderr, "%s: unable to open the output file '%s'.\n", + prog, outfile); + exit(1); + } + /* + * Set the output filename to be passed to the generator routine. + */ + if ((oname = strrchr(outfile, '/'))) + oname++; + else + oname = outfile; + } else + /* + * Set the default output file name to . + */ + oname = ""; + + /* + * Intialize Freetype. + */ + if ((res = TT_Init_FreeType(&engine))) { + /* + * Close the output file. + */ + if (out != stdout) { + fclose(out); + (void) unlink(outfile); + } + fprintf(stderr, "%s[%d]: unable to initialize renderer.\n", + prog, res); + exit(1); + } + + /* + * Open the input file. + */ + if ((res = TT_Open_Face(engine, infile, &face))) { + if (out != stdout) { + fclose(out); + (void) unlink(outfile); + } + fprintf(stderr, "%s[%d]: unable to open input file '%s'.\n", + prog, res, infile); + exit(1); + } + + /* + * Create a new instance. + */ + if ((res = TT_New_Instance(face, &instance))) { + (void) TT_Close_Face(face); + if (out != stdout) { + fclose(out); + (void) unlink(outfile); + } + fprintf(stderr, "%s[%d]: unable to create instance.\n", + prog, res); + exit(1); + } + + /* + * Set the instance resolution and point size and the relevant + * metrics. + */ + (void) TT_Set_Instance_Resolutions(instance, hres, vres); + (void) TT_Set_Instance_CharSize(instance, point_size*64); + (void) TT_Get_Instance_Metrics(instance, &imetrics); + + /* + * Get the face properties and set the global units per em value for + * convenience. + */ + (void) TT_Get_Face_Properties(face, &properties); + upm = properties.header->Units_Per_EM; + + /* + * Create a new glyph container. + */ + if ((res = TT_New_Glyph(face, &glyph))) { + (void) TT_Done_Instance(instance); + (void) TT_Close_Face(face); + if (out != stdout) { + fclose(out); + (void) unlink(outfile); + } + fprintf(stderr, "%s[%d]: unable to create glyph.\n", + prog, res); + exit(1); + } + + /* + * Generate the BDF font from the TrueType font. + */ + res = generate_bdf(out, iname, oname); + + /* + * Free up the mapping table if one was loaded. + */ + ttf2bdf_free_map(); + + /* + * Close the input and output files. + */ + (void) TT_Close_Face(face); + if (out != stdout) { + fclose(out); + if (res < 0) + /* + * An error occured when generating the font, so delete the + * output file. + */ + (void) unlink(outfile); + } + + /* + * Shut down the renderer. + */ + (void) TT_Done_FreeType(engine); + + exit(res); + + return 0; +} diff --git a/contrib/ttf2bdf/ttf2bdf.man b/contrib/ttf2bdf/ttf2bdf.man new file mode 100644 index 0000000..8ae0554 --- /dev/null +++ b/contrib/ttf2bdf/ttf2bdf.man @@ -0,0 +1,196 @@ +.\" +.\" $Id: ttf2bdf.man,v 1.14 1999/10/21 16:31:54 mleisher Exp $ +.\" +.TH TTF2BDF 1 "21 October 1999" "X Version 11" +.SH NAME +ttf2bdf \- TrueType to BDF font converter + +.SH SYNOPSIS +.B ttf2bdf +[\fIoptions\fP] [\fIfont.ttf\fP] + +.SH DESCRIPTION +.I ttf2bdf +will convert a TrueType font to a BDF font using the FreeType renderer. + +.SH OPTIONS +.I ttf2bdf +accepts the following command line arguments: + +.PP +.TP 8 +.I -v +print warning messages when the font is converted. +.PP +.TP 8 +.I -p n +set the desired point size (see default value by running the program with the +-h option). +.PP +.TP 8 +.I -r n +set both the horizontal and the vertical resolution (see default value by +running the program with the -h option). The minimum is 10dpi and the maximum +is 1200dpi. +.PP +.TP 8 +.I -rh n +set the horizontal resolution (see default value by running the program with +the -h option). The minimum is 10dpi and the maximum is 1200dpi. +.PP +.TP 8 +.I -rv n +set the vertical resolution (see default value by running the program with +the -h option). The minimum is 10dpi and the maximum is 1200dpi. +.PP +.TP 8 +.I -o outfile +sets the output filename (default output is to stdout). +.PP +.TP 8 +.I -pid id +set the platform id for selecting the character map (see default value by +running the program with the -h option). +.PP +.TP 8 +.I -eid id +set the encoding id for selecting the character map (see default value by +running the program with the -h option). +.PP +.TP 8 +.I -c c +set the character spacing. This should be one of `P' for proportional, +`M' for monospace, or `C' for character cell. By default, the spacing +of a font will be automatically determined to be either `M' or `P' +according to values provided in the font. +.PP +.TP 8 +.I -f name +set the foundry name used in the XLFD name. The default value is +`Freetype'. +.PP +.TP 8 +.I -t name +set the typeface name used in the XLFD name. By default, +.I ttf2bdf +will attempt to get a name from the font first and then it will use the +name supplied with this command line option, and if all else fails, it +will use the name `Unknown'. +.PP +.TP 8 +.I -w name +set the weight name used in the XLFD name. If this value is not +supplied, the default value is assumed to be `Medium'. Some common +values for this are `Thin', `Delicate', `ExtraLight', `Light', `Normal', +`Medium', `SemiCondensed', `Condensed', `SemiBold', `Bold', `Heavy', +`ExtraBold', and `ExtraHeavy'. +.PP +.TP 8 +.I -s name +set the slant name used in the XLFD name. If this value is not +supplied, the default value is assumed to be `R', for Roman. Some common +values for this are `R' for Roman, `I' for Italic, `O' for Oblique, `RI' +for Reverse Italic, and `RO' for Reverse Oblique. +.PP +.TP 8 +.I -k name +set the width name used in the XLFD name. The default is `Normal'. +.PP +.TP 8 +.I -d name +set the additional style name used in the XLFD name. The default is an empty +string. +.PP +.TP 8 +.I -u char +set the character used to replace the dashes/spaces in a font name. The +default is the space character. +.PP +.TP 8 +.I -l subset +define a list of character codes which will be used to select a subset +of glyphs from the font. The syntax of the subset string is the same +as the syntax for selecting subsets in X11 XLFD font names. Example: +.sp +% ttf2bdf -l '60 70 80_90' font.ttf -o font.bdf +.sp +The command above will only generate the glyphs for codes 60, 70, and 80 +through 90 inclusive. Glyphs that are not in the subset are not +generated. +.PP +.TP 8 +.I -m mapfile +specifies a mapping file which will reencode the BDF font when it is +generated. Any glyphs with codes that do not have a mapping will not +be generated. +.sp +The remapping file should begin with two lines, one which starts with +REGISTRY followed by the character set registry and one which starts +with ENCODING followed by the encoding. An example from the +iso8859.2 file: +.sp +REGISTRY ISO8859 +.br +ENCODING 2 +.sp +The remapping data should be two columns of hexadecimal numbers, separated by +spaces or tabs. The first column should have the code which should be used in +the BDF font. The second column should be the hexadecimal code of the glyph +in the "cmap" table ttf2bdf is using. An example mapping file is provided +which will map fonts from Unicode (the default "cmap" table) to ISO8859-2. +.sp +Unicode is not the only option. If you choose another platform and +encoding ID on the command line, then the remapping is assumed to map +from the chosen platform and encoding to some other character set. + +.SH "SEE ALSO" +xmbdfed(1), xfed(1), bdftopcf(1), bdftosnf(1) +.br +\fIGlyph Bitmap Distribution Format (BDF) Specification\fP, Application +Note 5005, Adobe System Inc, 1993 +.br +\fIX Logical Font Description Conventions\fP, X Consortium + +.SH ACKNOWLEDGMENTS + +The FreeType project for providing the renderer! +.br +Robert Wilhelm for pointing out a +crucial problem with the pre-1.0 code. +.br +Lho Li-Da for problem reports. +.br +Adrian Havill for unintentionally pointing out a +missing feature. +.br +Richard Verhoeven for problem reports and patches. +.br +Choi Jun Ho whose implementation provided some +nice new features. +.br +Pavel Kankovsky for providing some +critical metrics fixes and other improvements. +.br +Matti Koskinen for pointing out a problem. +.br +Eugene Bobin for mapping tables and shell scripts. +.br +Oleg N. Yakovlev for pointing out a problem. +.br +Bertrand Petit for additional functionality. +.br +Roman Czyborra for pointing out some problems. +.br +Mike Blazer for some Window's compilation advice. +.br +Solofo Ramangalahy for contributing some mapping +tables. +Antoine Leca for mapping table suggestions. +.SH AUTHOR +Mark Leisher +.br +Computing Research Lab +.br +New Mexico State University +.br +Email: mleisher@crl.nmsu.edu diff --git a/contrib/ttf2pfb/.cvsignore b/contrib/ttf2pfb/.cvsignore new file mode 100644 index 0000000..bcb2ec2 --- /dev/null +++ b/contrib/ttf2pfb/.cvsignore @@ -0,0 +1,3 @@ +t1asm +ttf2pfb +Makefile diff --git a/contrib/ttf2pfb/Makefile.emx b/contrib/ttf2pfb/Makefile.emx new file mode 100644 index 0000000..72968c8 --- /dev/null +++ b/contrib/ttf2pfb/Makefile.emx @@ -0,0 +1,16 @@ +# Makefile for ttf2pfb and t1asm + +all: ttf2pfb.exe t1asm.exe + + +ttf2pfb.exe: ttf2pfb.o + gcc -O -o ttf2pfb.exe ttf2pfb.o -lttf + +ttf2pfb.o: ttf2pfb.c + gcc -O -c ttf2pfb.c + +t1asm.exe: t1asm.o + gcc -O -o t1asm.exe t1asm.o -lttf + +t1asm.o: t1asm.c + gcc -O -c t1asm.c diff --git a/contrib/ttf2pfb/Makefile.in b/contrib/ttf2pfb/Makefile.in new file mode 100644 index 0000000..a6d42c8 --- /dev/null +++ b/contrib/ttf2pfb/Makefile.in @@ -0,0 +1,74 @@ +# Makefile for ttf2pfb +# +# This Makefile assumes that you've already built and installed +# the FreeType library. + +VPATH = @srcdir@ +srcdir = @srcdir@ + +RM = @RM@ +RMF = @RM@ -f + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ + +CC = @CC@ +CPP = @CPP@ + +LIBTOOL = ../../libtool +MKINSTALLDIRS = $(srcdir)/../../mkinstalldirs + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +mandir = @mandir@ + +CFLAGS = @CFLAGS@ @XX_CFLAGS@ +CPPFLAGS = @CPPFLAGS@ @DEFS@ +FT_CFLAGS = $(CFLAGS) $(CPPFLAGS) +LDFLAGS = @LDFLAGS@ @LIBS@ +LIBDIR = ../../lib + +SRC = t1asm.c ttf2pfb.c + +PROGRAMS = t1asm ttf2pfb + +default all: $(PROGRAMS) + +t1asm: t1asm.c + $(CC) $(CFLAGS) -o $@ $< + +ttf2pfb: ttf2pfb.o $(LIBDIR)/libttf.la + $(LIBTOOL) --mode=link $(CC) $(FT_CFLAGS) -o $@ $< \ + $(LIBDIR)/libttf.la $(LDFLAGS) + +clean: + $(RMF) *.o *BAK *CKP *~ a.out core + +realclean: clean + $(RMF) $(PROGRAMS) + $(RM) -rf .libs/ + +distclean: realclean + $(RMF) *~ *.orig core *.core + $(RMF) config.cache config.log config.status Makefile + +.c.o: + $(CC) -c $(FT_CFLAGS) $< + +install: $(PROGRAMS) + $(MKINSTALLDIRS) $(bindir) + for P in $(PROGRAMS) ; do \ + $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$P $(bindir)/$$P ; \ + done + $(INSTALL_PROGRAM) $(srcdir)/getafm $(bindir)/getafm + +uninstall: + -for P in $(PROGRAMS) ; do \ + $(LIBTOOL) --mode=uninstall $(RM) $(bindir)/$$P ; \ + done + +.PHONY: all clean realclean distclean install uninstall + +# end of Makefile diff --git a/contrib/ttf2pfb/TODO b/contrib/ttf2pfb/TODO new file mode 100644 index 0000000..57dda25 --- /dev/null +++ b/contrib/ttf2pfb/TODO @@ -0,0 +1,40 @@ +ttf2pfb is oriented towards support for CJK fonts containing several +thousand glyphs to be splitted into subfonts with 256 characters each usable +by TeX. Nevertheless, it is quite generic and works with normal ttf files +too. + +Some features are still missing or should be added for convenience: + +. Documentation. ttf2pbf explains itself; t1asm is a filter which converts + the (disassembled) pseudo font created by ttf2pfb into a real PFA font + (or PFB if you use the `-b' command line switch). + + Example for an ordinary font: + + ttf2pfb -v -m -enc Uni-T1.enc -f FooBar -o foobar.ps foobar.ttf + t1asm -b < foobar.ps > foobar.pfb + printafm foobar.pfb > foobar.afm + afm2tfm foobar.afm + + Example for a CJK font in Big 5 encoding to be used with the CJK package + for LaTeX (note that the call creates just the first subfont): + + ttf2pfb -c -pid 3 -eid 4 -plane 1 -f FooBar01 -o foobar01.ps foobar.ttf + t1asm -b < foobar01.ps > foobar01.pfb + printafm foobar01.pfb > foobar01.afm + afm2tfm foobar01.afm + +. Inclusion of t1asm and t1binary into ttf2pfb so that ttf2pfb can directly + produce PFA and PFB files. + +. Overlapping outlines produce incorrect shapes: The overlapping areas + appear white instead of black. + +. A more flexible encoding file format (maybe similar to ttf2tfm) which can + handle glyph names. + +. [t1asm has been slightly patched to allow partial font downloading with + dvips.] + +. Note that compiling ttf2pfb with `-O2' doesn't work, most probably due to + a compiler bug (we've tested with gcc 2.7.2.1 and 2.7.2.3). diff --git a/contrib/ttf2pfb/Uni-T1.enc b/contrib/ttf2pfb/Uni-T1.enc new file mode 100644 index 0000000..2eaddb6 --- /dev/null +++ b/contrib/ttf2pfb/Uni-T1.enc @@ -0,0 +1,397 @@ +# +# This file is a hack to provide some mapping for standard (non-CJK) +# TrueType fonts. It is intended as an intermediate step towards a +# `correct' implementation as in ttf2tfm. +# +# Here, we have Unicode to LaTeX's T1 encoding. An example call would be +# +# ttf2pfb -m -enc Uni-T1.enc ... +# +# Glyph names which can't be represented in Unicode have the character code +# 0xfffe. + + +# 0x00 + +0x00: + 0x60 # /grave + 0xb4 # /acute +0x02: + 0xc6 # /circumflex + 0xdc # /tilde + +0x00: + 0xa8 # /dieresis +0x02: + 0xdd # /hungarumlaut + 0xda # /ring + 0xc7 # /caron + + 0xd8 # /breve + 0xc9 # /macron + 0xd9 # /dotaccent +0x00: + 0xb8 # /cedilla + +0x02: + 0xdb # /ogonek +0x20: + 0x1a # /quotesinglbase + 0x39 # /guilsinglleft + 0x3a # /guilsinglright + +# 0x10 + + 0x1c # /quotedblleft + 0x1d # /quotedblright + 0x1e # /quotedblbase +0x00: + 0xab # /guillemotleft + + 0xbb # /guillemotright +0x20: + 0x13 # /endash + 0x14 # /emdash +0xff: + 0xfe # /compwordmark + + 0xfe # /perthousandzero +0x01: + 0x31 # /dotlessi +0xff: + 0xfe # /dotlessj + 0xfe # /ff + +0xf0: + 0x01 # /fi + 0x02 # /fl +0xff: + 0xfe # /ffi + 0xfe # /ffl + +# 0x20 + + 0xfe # /visualspace +0x00: + 0x21 # /exclam + 0x22 # /quotedbl + 0x23 # /numbersign + + 0x24 # /dollar + 0x25 # /percent + 0x26 # /ampersand +0x20: + 0x19 # /quoteright + +0x00: + 0x28 # /parenleft + 0x29 # /parenright + 0x2a # /asterisk + 0x2b # /plus + + 0x2c # /comma + 0x2d # /hyphen + 0x2e # /period + 0x2f # /slash + +# 0x30 + + 0x30 # /zero + 0x31 # /one + 0x32 # /two + 0x33 # /three + + 0x34 # /four + 0x35 # /five + 0x36 # /six + 0x37 # /seven + + 0x38 # /eight + 0x39 # /nine + 0x3a # /colon + 0x3b # /semicolon + + 0x3c # /less + 0x3d # /equal + 0x3e # /greater + 0x3f # /question + +# 0x40 + + 0x40 # /at + 0x41 # /A + 0x42 # /B + 0x43 # /C + + 0x44 # /D + 0x45 # /E + 0x46 # /F + 0x47 # /G + + 0x48 # /H + 0x49 # /I + 0x4a # /J + 0x4b # /K + + 0x4c # /L + 0x4d # /M + 0x4e # /N + 0x4f # /O + +# 0x50 + + 0x50 # /P + 0x51 # /Q + 0x52 # /R + 0x53 # /S + + 0x54 # /T + 0x55 # /U + 0x56 # /V + 0x57 # /W + + 0x58 # /X + 0x59 # /Y + 0x5a # /Z + 0x5b # /bracketleft + + 0x5c # /backslash + 0x5d # /bracketright + 0x5e # /asciicircum + 0x5f # /underscore + +# 0x60 + +0x20: + 0x18 # /quoteleft +0x00: + 0x61 # /a + 0x62 # /b + 0x63 # /c + + 0x64 # /d + 0x65 # /e + 0x66 # /f + 0x67 # /g + + 0x68 # /h + 0x69 # /i + 0x6a # /j + 0x6b # /k + + 0x6c # /l + 0x6d # /m + 0x6e # /n + 0x6f # /o + +# 0x70 + + 0x70 # /p + 0x71 # /q + 0x72 # /r + 0x73 # /s + + 0x74 # /t + 0x75 # /u + 0x76 # /v + 0x77 # /w + + 0x78 # /x + 0x79 # /y + 0x7a # /z + 0x7b # /braceleft + + 0x7c # /bar + 0x7d # /braceright + 0x7e # /asciitilde + 0x2d # /hyphen + +# 0x80 + +0x01: + 0x02 # /Abreve + 0x04 # /Aogonek + 0x06 # /Cacute + 0x0c # /Ccaron + + 0x0e # /Dcaron + 0x1a # /Ecaron + 0x18 # /Eogonek + 0x1e # /Gbreve + + 0x39 # /Lacute + 0x3d # /Lcaron + 0x41 # /Lslash + 0x43 # /Nacute + + 0x47 # /Ncaron + 0x4a # /Eng + 0x50 # /Odblacute + 0x54 # /Racute + +# 0x90 + + 0x58 # /Rcaron + 0x5a # /Sacute + 0x60 # /Scaron + 0x5e # /Scedilla + + 0x64 # /Tcaron + 0x62 # /Tcedilla + 0x70 # /Udblacute + 0x6e # /Uring + + 0x78 # /Ydieresis + 0x79 # /Zacute + 0x7d # /Zcaron + 0x7b # /Zdot + + 0x32 # /IJ + 0x30 # /Idot + 0x11 # /dmacron +0x00: + 0xa7 # /section + +# 0xA0 + +0x01: + 0x03 # /abreve + 0x05 # /aogonek + 0x07 # /cacute + 0x0d # /ccaron + + 0x0f # /dcaron + 0x1b # /ecaron + 0x19 # /eogonek + 0x1f # /gbreve + + 0x3a # /lacute + 0x3e # /lcaron + 0x42 # /lslash + 0x44 # /nacute + + 0x48 # /ncaron + 0x4b # /eng + 0x51 # /odblacute + 0x55 # /racute + +# 0xB0 + + 0x59 # /rcaron + 0x5b # /sacute + 0x61 # /scaron + 0x5f # /scedilla + + 0x65 # /tcaron + 0x63 # /tcedilla + 0x71 # /udblacute + 0x6f # /uring + +0x00: + 0xff # /ydieresis +0x01: + 0x7a # /zacute + 0x7e # /zcaron + 0x7c # /zdot + + 0x33 # /ij +0x00: + 0xa1 # /exclamdown + 0xbf # /questiondown + 0xa3 # /sterling + +# 0xC0 + + 0xc0 # /Agrave + 0xc1 # /Aacute + 0xc2 # /Acircumflex + 0xc3 # /Atilde + + 0xc4 # /Adieresis + 0xc5 # /Aring + 0xc6 # /AE + 0xc7 # /Ccedilla + + 0xc8 # /Egrave + 0xc9 # /Eacute + 0xca # /Ecircumflex + 0xcb # /Edieresis + + 0xcc # /Igrave + 0xcd # /Iacute + 0xce # /Icircumflex + 0xcf # /Idieresis + +# 0xD0 + + 0xd0 # /Eth + 0xd1 # /Ntilde + 0xd2 # /Ograve + 0xd3 # /Oacute + + 0xd4 # /Ocircumflex + 0xd5 # /Otilde + 0xd6 # /Odieresis +0x01: + 0x52 # /OE + +0x00: + 0xd8 # /Oslash + 0xd9 # /Ugrave + 0xda # /Uacute + 0xdb # /Ucircumflex + + 0xdc # /Udieresis + 0xdd # /Yacute + 0xde # /Thorn +0xff: + 0xfe # /Germandbls + +# 0xE0 + +0x00: + 0xe0 # /agrave + 0xe1 # /aacute + 0xe2 # /acircumflex + 0xe3 # /atilde + + 0xe4 # /adieresis + 0xe5 # /aring + 0xe6 # /ae + 0xe7 # /ccedilla + + 0xe8 # /egrave + 0xe9 # /eacute + 0xea # /ecircumflex + 0xeb # /edieresis + + 0xec # /igrave + 0xed # /iacute + 0xee # /icircumflex + 0xef # /idieresis + +# 0xF0 + + 0xf0 # /eth + 0xf1 # /ntilde + 0xf2 # /ograve + 0xf3 # /oacute + + 0xf4 # /ocircumflex + 0xf5 # /otilde + 0xf6 # /odieresis +0x01: + 0x53 # /oe + +0x00: + 0xf8 # /oslash + 0xf9 # /ugrave + 0xfa # /uacute + 0xfb # /ucircumflex + + 0xfc # /udieresis + 0xfd # /yacute + 0xfe # /thorn + 0xdf # /germandbls + +#eof diff --git a/contrib/ttf2pfb/configure b/contrib/ttf2pfb/configure new file mode 100644 index 0000000..7ec8072 --- /dev/null +++ b/contrib/ttf2pfb/configure @@ -0,0 +1,1553 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=../../lib/freetype.h + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + +# Do some error checking and defaulting for the host and target type. +# The inputs are: +# configure --host=HOST --target=TARGET --build=BUILD NONOPT +# +# The rules are: +# 1. You are not allowed to specify --host, --target, and nonopt at the +# same time. +# 2. Host defaults to nonopt. +# 3. If nonopt is not specified, then host defaults to the current host, +# as determined by config.guess. +# 4. Target and build default to nonopt. +# 5. If nonopt is not specified, then target and build default to host. + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +case $host---$target---$nonopt in +NONE---*---* | *---NONE---* | *---*---NONE) ;; +*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; +esac + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:573: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking target system type""... $ac_c" 1>&6 +echo "configure:594: checking target system type" >&5 + +target_alias=$target +case "$target_alias" in +NONE) + case $nonopt in + NONE) target_alias=$host_alias ;; + *) target_alias=$nonopt ;; + esac ;; +esac + +target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` +target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$target" 1>&6 + +echo $ac_n "checking build system type""... $ac_c" 1>&6 +echo "configure:612: checking build system type" >&5 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&6 + +test "$host_alias" != "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:638: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:668: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:719: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:751: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 762 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:767: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:793: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:798: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:826: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:858: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:879: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:896: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:913: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + + +CFLAGS="-g -O -DDEBUG" +OLDLIBS=$LIBS +LIBS="$LIBS -L../../lib/.libs" +CPPFLAGS="-I$srcdir/../../lib $CPPFLAGS" +echo $ac_n "checking for TT_Init_FreeType in -lttf""... $ac_c" 1>&6 +echo "configure:943: checking for TT_Init_FreeType in -lttf" >&5 +ac_lib_var=`echo ttf'_'TT_Init_FreeType | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lttf $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lttf" +else + echo "$ac_t""no" 1>&6 + + { echo "configure: error: Can't find ttf library! Compile FreeType first." 1>&2; exit 1; } +fi + +LIBS=$OLDLIBS + + +if test "x$CC" = xgcc; then + XX_CFLAGS="-Wall -ansi -pedantic" +else + case "$host" in + alpha-dec-osf*) + XX_CFLAGS="-std1 -O2 -g3" + ;; + *) + XX_CFLAGS= + ;; + esac +fi + + +# Extract the first word of "rm", so it can be a program name with args. +set dummy rm; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1004: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RM'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RM"; then + ac_cv_prog_RM="$RM" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RM="rm" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +RM="$ac_cv_prog_RM" +if test -n "$RM"; then + echo "$ac_t""$RM" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:1042: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6 +echo "configure:1096: checking whether struct tm is in sys/time.h or time.h" >&5 +if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +int main() { +struct tm *tp; tp->tm_sec; +; return 0; } +EOF +if { (eval echo configure:1109: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_struct_tm=time.h +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_struct_tm=sys/time.h +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_struct_tm" 1>&6 +if test $ac_cv_struct_tm = sys/time.h; then + cat >> confdefs.h <<\EOF +#define TM_IN_SYS_TIME 1 +EOF + +fi + + +echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 +echo "configure:1131: checking for ANSI C header files" >&5 +if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +#include +#include +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1144: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + ac_cv_header_stdc=yes +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "memchr" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "free" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +if test "$cross_compiling" = yes; then + : +else + cat > conftest.$ac_ext < +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int main () { int i; for (i = 0; i < 256; i++) +if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); +exit (0); } + +EOF +if { (eval echo configure:1211: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + : +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_header_stdc=no +fi +rm -fr conftest* +fi + +fi +fi + +echo "$ac_t""$ac_cv_header_stdc" 1>&6 +if test $ac_cv_header_stdc = yes; then + cat >> confdefs.h <<\EOF +#define STDC_HEADERS 1 +EOF + +fi + +for ac_hdr in unistd.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1238: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1248: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@target@%$target%g +s%@target_alias@%$target_alias%g +s%@target_cpu@%$target_cpu%g +s%@target_vendor@%$target_vendor%g +s%@target_os@%$target_os%g +s%@build@%$build%g +s%@build_alias@%$build_alias%g +s%@build_cpu@%$build_cpu%g +s%@build_vendor@%$build_vendor%g +s%@build_os@%$build_os%g +s%@CC@%$CC%g +s%@CPP@%$CPP%g +s%@XX_CFLAGS@%$XX_CFLAGS%g +s%@RM@%$RM%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + + diff --git a/contrib/ttf2pfb/configure.in b/contrib/ttf2pfb/configure.in new file mode 100644 index 0000000..3b02f0a --- /dev/null +++ b/contrib/ttf2pfb/configure.in @@ -0,0 +1,45 @@ +dnl Process this file with autoconf to produce a configure script. + +AC_INIT(../../lib/freetype.h) + +AC_CANONICAL_SYSTEM + +AC_PROG_CC +AC_PROG_CPP + +CFLAGS="-g -O -DDEBUG" +OLDLIBS=$LIBS +LIBS="$LIBS -L../../lib/.libs" +CPPFLAGS="-I$srcdir/../../lib $CPPFLAGS" +AC_CHECK_LIB(ttf, TT_Init_FreeType, LIBS="$LIBS -lttf",[ + AC_MSG_ERROR([Can't find ttf library! Compile FreeType first.])]) +LIBS=$OLDLIBS + +dnl get Compiler flags right. + +if test "x$CC" = xgcc; then + XX_CFLAGS="-Wall -ansi -pedantic" +else + case "$host" in + alpha-dec-osf*) + XX_CFLAGS="-std1 -O2 -g3" + ;; + *) + XX_CFLAGS= + ;; + esac +fi +AC_SUBST(XX_CFLAGS) + +AC_CHECK_PROG(RM, rm, rm) +AC_PROG_INSTALL + +AC_STRUCT_TM + +dnl Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS(unistd.h) + +AC_OUTPUT(Makefile) + +dnl end of configure.in diff --git a/contrib/ttf2pfb/getafm b/contrib/ttf2pfb/getafm new file mode 100644 index 0000000..fc35c1c --- /dev/null +++ b/contrib/ttf2pfb/getafm @@ -0,0 +1,364 @@ +#!/bin/sh + +if [ $# -ne 1 ]; then + echo "usage: $0 font-name | gsnd -q - >font-name.afm" >&2 + exit 1 +fi + +cat << EOF +%! +% produce .afm for $1 +% (c) 1993 by Robert Joop +% inspired by two other versions of this theme which are +% getafm 1.00 (c) AJCD +% and getafm.ps by an unknown author, +% modified by J. Daniel Smith +% +% modified by Joachim H. Kaiser : +% - suggest a quiet gs run in usage +% - get font version info (from 'version', not 'Version') +% - add copyright field to output + +% Metrics dictionary code added by AJCD, 7/6/93 + +/getafmdict 100 dict dup begin + + /buf 256 string def + /buf2 16 string def + + /prany % dict dictname printname -> dict + { + 2 index 2 index cvn known + { + print % printname + ( ) print + 1 index exch cvn get = + } + { + (Comment /FontInfo contains no /) print + 2 copy eq + { + = % printname + pop % dictname + } + { + exch + print % dictname + (, therefore no ) print + = % printname + } + ifelse + } + ifelse + } + bind def + + /printfontname + { + (FontName)dup prany + } + bind def + + /printfontinfo + { + dup /FontInfo known + { + dup /FontInfo get + (FullName)dup prany + (FamilyName)dup prany + (Weight)dup prany + (ItalicAngle)dup prany + (isFixedPitch)(IsFixedPitch) prany + (UnderlinePosition)dup prany + (UnderlineThickness)dup prany + (version)(Version) prany + (Notice)dup prany + (Copyright)dup prany + pop + } + { + (Comment Font lacks a /FontInfo!)= + } + ifelse + } + bind def + + /prbbox % llx lly urx ury -> - + { + 4 1 roll 3 1 roll exch % swap top 4 elements + 4 { ( ) print buf cvs print } repeat + } + bind def + + /getbbox % fontdict chardict character -> fontdict chardict llx lly urx ury + { + gsave + 2 index setfont 0 0 moveto + false charpath flattenpath pathbbox + grestore + } + bind def + + /printmiscinfo + { + dup /FontBBox known + { + (FontBBox) print + dup /FontBBox get aload pop prbbox ()= + } + { + (Comment missing required /FontBBox)= + quit + } + ifelse + 2 copy exch get + dup /H known + 1 index /x known and + 1 index /d known and + 1 index /p known and + dup /looksRoman exch def + { + (CapHeight ) print + (H) getbbox + ceiling cvi = pop pop pop + (XHeight ) print + (x) getbbox + ceiling cvi = pop pop pop + (Ascender ) print + (d) getbbox + ceiling cvi = pop pop pop + (Descender ) print + (p) getbbox + pop pop floor cvi = pop + } + { + (Comment font doesn't contain H, x, d and p; therefore no CapHeight, XHeight, Ascender and Descender)= + } + ifelse + pop + dup /Encoding get + [ + [ (ISOLatin1Encoding) /ISOLatin1Encoding ] + [ (AdobeStandardEncoding) /StandardEncoding ] + ] + { + aload pop dup where + { + exch get 2 index eq + { + (EncodingScheme ) print + buf cvs = + } + { + pop + } + ifelse + } + { + pop pop + } + ifelse + } + forall + pop + } + bind def + + /printcharmetric + { + % chardictname fontdict charnamedict encoding charindex charname + + 4 index dup length dict dup begin exch + { + 1 index /FID ne + 2 index /UniqueID ne + and + { + 1 index /Encoding eq { 256 array copy } if + def + } + { pop pop } + ifelse + } + forall + end + dup /Encoding get 32 3 index put + /f2 exch definefont + setfont + + (C ) print + 1 index buf cvs print + + ( ; WX ) print +% Metrics entries are: +% 1 number: which is the character width +% an array of 2 numbers: which are the left sidebearing and width +% an array of 4 numbers: x & y left sidebearing, width and height + dup 5 index % /charname fontdict + dup /Metrics known { + /Metrics get exch 2 copy known { + get dup type /arraytype eq { + dup length 2 eq + {1 get} {2 get} ifelse + } if + round cvi buf cvs print + } { + pop pop ( ) stringwidth pop round cvi buf cvs print + } ifelse + } { + pop pop ( ) stringwidth pop round cvi buf cvs print + } ifelse + + ( ; N ) print + dup buf cvs print + + ( ; B) print + gsave + newpath 0 0 moveto + ( ) true charpath flattenpath pathbbox + grestore + 2 { ceiling cvi 4 1 roll } repeat + 2 { floor cvi 4 1 roll } repeat + prbbox + + looksRoman + { + [ + [ /f [ /i /f /l ] ] + [ /ff [ /i /l ] ] + ] + { + aload pop 1 index 3 index eq + { + { + 1 index buf cvs + length + 1 index buf2 cvs dup length + 2 index add + buf + 4 2 roll putinterval + buf 0 + 3 -1 roll getinterval + dup cvn + 7 index + exch known + { + exch + ( ; L ) print + buf2 cvs print + ( ) print + print + } + { + pop pop + } + ifelse + } + forall + pop + } + { + pop pop + } + ifelse + } + forall + } + if + pop + + ( ;)= + } + bind def + + /printcharmetrics + { + (StartCharMetrics ) print + 2 copy exch get length 1 sub buf cvs = + + 256 dict dup begin + 1 index /Encoding get + { null def } + forall + end + % chardictname fontdict charnamedict + 1 index /Encoding get + 0 1 255 + { + % encoding index + 2 copy get + dup /.notdef eq { pop } { printcharmetric } ifelse + pop % index + } for + + -1 + 3 index 5 index get + { + pop + dup /.notdef eq + { pop } + { + % chardictname fontdict charnamedict encoding charindex charname + dup 4 index exch known + { pop } + { printcharmetric } + ifelse + } + ifelse + } + forall + % charnamedict encoding index + pop pop pop + + (EndCharMetrics)= + } + bind def + + /printfontmetrics + { + (StartFontMetrics 3.0)= + (Comment Produced by getafm 3.0 (which is by rj@rainbow.in-berlin.de))= + + printfontname + printfontinfo + printmiscinfo + printcharmetrics + + (EndFontMetrics)= + } + bind def + +end def + +/getafm +{ + getafmdict begin + save exch + findfont 1000 scalefont + + null + [ /CharDefs /CharData /CharProcs /CharStrings ] + { + 2 index 1 index known { exch } if + pop + } + forall + dup null eq + { + (can't find dictionary with character data!)= + quit + } + if + exch % dictname fontdict + + printfontmetrics + + pop pop + restore + end +} +bind def + +/$1 getafm + +EOF diff --git a/contrib/ttf2pfb/t1asm.c b/contrib/ttf2pfb/t1asm.c new file mode 100644 index 0000000..5b63aab --- /dev/null +++ b/contrib/ttf2pfb/t1asm.c @@ -0,0 +1,529 @@ +/* t1asm +** +** This program `assembles' Adobe Type-1 font programs in pseudo-PostScript +** form into either PFB or PFA format. The human readable/editable input is +** charstring- and eexec-encrypted as specified in the `Adobe Type 1 Font +** Format' version 1.1 (the `black book'). There is a companion program, +** t1disasm, which `disassembles' PFB and PFA files into a pseudo-PostScript +** file. +** +** Copyright (c) 1992 by I. Lee Hetherington, all rights reserved. +** +** Permission is hereby granted to use, modify, and distribute this program +** for any purpose provided this copyright notice and the one below remain +** intact. +** +** author: I. Lee Hetherington (ilh@lcs.mit.edu) +*/ + +#ifndef lint +static char sccsid[] = + "@(#) t1asm.c 1.2 10:09:46 5/22/92"; +static char copyright[] = + "@(#) Copyright (c) 1992 by I. Lee Hetherington, all rights reserved."; +#endif + +/* Note: this is ANSI C. */ + +#include +#include +#include +#include + +#ifdef MSDOS +#define WB "wb" +#else +#define WB "w" +#endif + +#define BANNER "This is t1asm 1.2.\n" +#define LINESIZE 256 + +#define MAXBLOCKLEN ((1<<17)-6) +#define MINBLOCKLEN ((1<<8)-6) + +#define MARKER 128 +#define ASCII 1 +#define BINARY 2 +#define DONE 3 + +typedef unsigned char byte; + +static FILE *ifp = stdin; +static FILE *ofp = stdout; + +/* flags */ +static int pfb = 0; +static int active = 0; +static int start_charstring = 0; +static int in_eexec = 0; + +static char line[LINESIZE + 1]; + +/* lenIV and charstring start command */ +static int lenIV = 4; +static char cs_start[10]; + +/* for charstring buffering */ +static byte charstring_buf[65535]; +static byte *charstring_bp; + +/* for PFB block buffering */ +static byte blockbuf[MAXBLOCKLEN]; +static int blocklen = MAXBLOCKLEN; +static int blockpos = -1; +static int blocktyp = ASCII; + +/* decryption stuff */ +static unsigned short er, cr; +static unsigned short c1 = 52845, c2 = 22719; + +/* table of charstring commands */ +static struct command { + char *name; + int one, two; +} command_table[] = { + { "callothersubr", 12, 16 }, + { "callsubr", 10, -1 }, + { "closepath", 9, -1 }, + { "div", 12, 12 }, + { "dotsection", 12, 0 }, + { "endchar", 14, -1 }, + { "escape", 12, -1 }, + { "hlineto", 6, -1 }, + { "hmoveto", 22, -1 }, + { "hsbw", 13, -1 }, + { "hstem", 1, -1 }, + { "hstem3", 12, 2 }, + { "hvcurveto", 31, -1 }, + { "pop", 12, 17 }, + { "return", 11, -1 }, + { "rlineto", 5, -1 }, + { "rmoveto", 21, -1 }, + { "rrcurveto", 8, -1 }, + { "sbw", 12, 7 }, + { "seac", 12, 6 }, + { "setcurrentpoint", 12, 33 }, + { "vhcurveto", 30, -1 }, + { "vlineto", 7, -1 }, + { "vmoveto", 4, -1 }, + { "vstem", 3, -1 }, + { "vstem3", 12, 1 }, +}; /* alphabetical */ + +/* Two separate decryption functions because eexec and charstring decryption + must proceed in parallel. */ + +static byte eencrypt(byte plain) +{ + byte cipher; + + cipher = (plain ^ (er >> 8)); + er = (cipher + er) * c1 + c2; + return cipher; +} + +static byte cencrypt(byte plain) +{ + byte cipher; + + cipher = (plain ^ (cr >> 8)); + cr = (cipher + cr) * c1 + c2; + return cipher; +} + +/* This function flushes a buffered PFB block. */ + +static void output_block() +{ + int i; + + /* output four-byte block length */ + fputc(blockpos & 0xff, ofp); + fputc((blockpos >> 8) & 0xff, ofp); + fputc((blockpos >> 16) & 0xff, ofp); + fputc((blockpos >> 24) & 0xff, ofp); + + /* output block data */ + for (i = 0; i < blockpos; i++) + fputc(blockbuf[i], ofp); + + /* mark block buffer empty and uninitialized */ + blockpos = -1; +} + +/* This function outputs a single byte. If output is in PFB format then output + is buffered through blockbuf[]. If output is in PFA format, then output + will be hexadecimal if in_eexec is set, ASCII otherwise. */ + +static void output_byte(byte b) +{ + static char *hexchar = "0123456789ABCDEF"; + static int hexcol = 0; + + if (pfb) { + /* PFB */ + if (blockpos < 0) { + fputc(MARKER, ofp); + fputc(blocktyp, ofp); + blockpos = 0; + } + blockbuf[blockpos++] = b; + if (blockpos == blocklen) + output_block(); + } else { + /* PFA */ + if (in_eexec) { + /* trim hexadecimal lines to 64 columns */ + if (hexcol >= 64) { + fputc('\n', ofp); + hexcol = 0; + } + fputc(hexchar[(b >> 4) & 0xf], ofp); + fputc(hexchar[b & 0xf], ofp); + hexcol += 2; + } else { + fputc(b, ofp); + } + } +} + +/* This function outputs a byte through possible eexec encryption. */ + +static void eexec_byte(byte b) +{ + if (in_eexec) + output_byte(eencrypt(b)); + else + output_byte(b); +} + +/* This function outputs a null-terminated string through possible eexec + encryption. */ + +static void eexec_string(char *string) +{ + while (*string) + eexec_byte((byte) *string++); +} + +/* This function gets ready for the eexec-encrypted data. If output is in + PFB format then flush current ASCII block and get ready for binary block. + We start encryption with four random (zero) bytes. */ + +static void eexec_start() +{ + eexec_string(line); + if (pfb) { + output_block(); + blocktyp = BINARY; + } + + in_eexec = 1; + er = 55665; + eexec_byte(0); + eexec_byte(0); + eexec_byte(0); + eexec_byte(0); +} + +/* This function wraps-up the eexec-encrypted data and writes ASCII trailer. + If output is in PFB format then this entails flushing binary block and + starting an ASCII block. */ + +static void eexec_end() +{ + int i, j; + + if (pfb) { + output_block(); + blocktyp = ASCII; + } else { + fputc('\n', ofp); + } + in_eexec = 0; + for (i = 0; i < 7; i++) { + for (j = 0; j < 64; j++) + eexec_byte('0'); + eexec_byte('\n'); + } + eexec_string("cleartomark\n"); + if (pfb) { + output_block(); + fputc(MARKER, ofp); + fputc(DONE, ofp); + } +} + +/* This function returns an input line of characters. A line is terminated by + length (including terminating null) greater than LINESIZE, a newline \n, or + when active (looking for charstrings) by '{'. When terminated by a newline + the newline is put into line[]. When terminated by '{', the '{' is not put + into line[], and the flag start_charstring is set to 1. */ + +static void getline() +{ + int c; + char *p = line; + int comment = 0; + + start_charstring = 0; + while (p < line + LINESIZE) { + c = fgetc(ifp); + if (c == EOF) + break; + if (c == '%') + comment = 1; + if (active && !comment && c == '{') { + start_charstring = 1; + break; + } + *p++ = (char) c; + if (c == '\n') + break; + } + *p = '\0'; +} + +/* This function is used by the binary search, bsearch(), for command names in + the command table. */ + +static int command_compare(const void *key, const void *item) +{ + return strcmp((char *) key, ((struct command *) item)->name); +} + +/* This function returns 1 if the string is an integer and 0 otherwise. */ + +static int is_integer(char *string) +{ + if (isdigit(string[0]) || string[0] == '-' || string[0] == '+') { + while (*++string && isdigit(*string)) + ; /* deliberately empty */ + if (!*string) + return 1; + } + return 0; +} + +/* This function initializes charstring encryption. Note that this is called + at the beginning of every charstring. */ + +static void charstring_start() +{ + int i; + + charstring_bp = charstring_buf; + cr = 4330; + for (i = 0; i < lenIV; i++) + *charstring_bp++ = cencrypt((byte) 0); +} + +/* This function encrypts and buffers a single byte of charstring data. */ + +static void charstring_byte(v) + int v; +{ + byte b = ((unsigned int)v) & 0xff; + + if (charstring_bp - charstring_buf > sizeof(charstring_buf)) { + fprintf(stderr, "error: charstring_buf full (%d bytes)\n", + sizeof(charstring_buf)); + exit(1); + } + *charstring_bp++ = cencrypt(b); +} + +/* This function outputs buffered, encrypted charstring data through possible + eexec encryption. */ + +static void charstring_end() +{ + byte *bp; + + sprintf(line, "%d %s ", charstring_bp - charstring_buf, cs_start); + eexec_string(line); + for (bp = charstring_buf; bp < charstring_bp; bp++) + eexec_byte(*bp); +} + +/* This function generates the charstring representation of an integer. */ + +static void charstring_int(int num) +{ + int x; + + if (num >= -107 && num <= 107) { + charstring_byte(num + 139); + } else if (num >= 108 && num <= 1131) { + x = num - 108; + charstring_byte(x / 256 + 247); + charstring_byte(x % 256); + } else if (num >= -1131 && num <= -108) { + x = abs(num) - 108; + charstring_byte(x / 256 + 251); + charstring_byte(x % 256); + } else if (num >= (-2147483647-1) && num <= 2147483647) { + charstring_byte(255); + charstring_byte(num >> 24); + charstring_byte(num >> 16); + charstring_byte(num >> 8); + charstring_byte(num); + } else { + fprintf(stderr, + "error: cannot format the integer %d, too large\n", num); + exit(1); + } +} + +/* This function parses an entire charstring into integers and commands, + outputting bytes through the charstring buffer. */ + +static void parse_charstring() +{ + struct command *cp; + + charstring_start(); + while (fscanf(ifp, "%s", line) == 1) { + if (line[0] == '%') { + /* eat comment to end of line */ + while (fgetc(ifp) != '\n' && !feof(ifp)) + ; /* deliberately empty */ + continue; + } + if (line[0] == '}') + break; + if (is_integer(line)) { + charstring_int(atoi(line)); + } else { + cp = (struct command *) + bsearch((void *) line, (void *) command_table, + sizeof(command_table) / sizeof(struct command), + sizeof(struct command), + command_compare); + if (cp) { + charstring_byte(cp->one); + if (cp->two >= 0) + charstring_byte(cp->two); + } else { + fprintf(stderr, "error: cannot use `%s' in charstring\n", cp->name); + exit(1); + } + } + } + charstring_end(); +} + +static void usage() +{ + fprintf(stderr, + "usage: t1asm [-b] [-l block-length] [input [output]]\n"); + fprintf(stderr, + "\n-b means output in PFB format, otherwise PFA format.\n"); + fprintf(stderr, + "The block length applies to the length of blocks in the\n"); + fprintf(stderr, + "PFB output file; the default is to use the largest possible.\n"); + exit(1); +} + + +int main(int argc, char **argv) +{ + char *p, *q, *r; + int c; + + extern char *optarg; + extern int optind; + extern int getopt(int argc, char **argv, char *optstring); + + fprintf(stderr, "%s", BANNER); + + /* interpret command line arguments using getopt */ + while ((c = getopt(argc, argv, "bl:")) != -1) + switch (c) { + case 'b': + pfb = 1; + break; + case 'l': + blocklen = atoi(optarg); + if (blocklen < MINBLOCKLEN) { + blocklen = MINBLOCKLEN; + fprintf(stderr, + "warning: using minimum block length of %d\n", + blocklen); + } else if (blocklen > MAXBLOCKLEN) { + blocklen = MAXBLOCKLEN; + fprintf(stderr, + "warning: using maximum block length of %d\n", + blocklen); + } + break; + default: + usage(); + break; + } + if (argc - optind > 2) + usage(); + + /* possibly open input & output files */ + if (argc - optind >= 1) { + ifp = fopen(argv[optind], "r"); + if (!ifp) { + fprintf(stderr, "error: cannot open %s for reading\n", argv[1]); + exit(1); + } + } + if (argc - optind >= 2) { + ofp = fopen(argv[optind + 1], WB); + if (!ofp) { + fprintf(stderr, "error: cannot open %s for writing\n", argv[2]); + exit(1); + } + } + + /* Finally, we loop until no more input. Some special things to look for + are the `currentfile eexec' line, the beginning of the `/Subrs' + definition, the definition of `/lenIV', and the definition of the + charstring start command which has `...string currentfile...' in it. */ + + while (!feof(ifp) && !ferror(ifp)) { + getline(); + if (strcmp(line, "currentfile eexec\n") == 0) { + eexec_start(); + continue; + } else if (strstr(line, "/Subrs") && isspace(line[6])) { + active = 1; + } else if ((p = strstr(line, "/lenIV"))) { + sscanf(p, "%*s %d", &lenIV); + } else if ((p = strstr(line, "string currentfile"))) { + /* locate the name of the charstring start command */ + *p = '\0'; /* damage line[] */ + q = strrchr(line, '/'); + if (q) { + r = cs_start; + ++q; + while (!isspace(*q) && *q != '{') + *r++ = *q++; + *r = '\0'; + } + *p = 's'; /* repair line[] */ + } + /* output line data */ + eexec_string(line); + if (start_charstring) { + if (!cs_start[0]) { + fprintf(stderr, "error: couldn't find charstring start command\n"); + exit(1); + } + parse_charstring(); + } + } + eexec_end(); + + fclose(ifp); + fclose(ofp); + + return 0; +} + diff --git a/contrib/ttf2pfb/ttf2pfb.c b/contrib/ttf2pfb/ttf2pfb.c new file mode 100644 index 0000000..8295eee --- /dev/null +++ b/contrib/ttf2pfb/ttf2pfb.c @@ -0,0 +1,1725 @@ +/* + * ttf2pfb.c -- TrueType to PostScript Type 1 Font converter. + * + * Author: Chun-Yu Lee + * Maintainer: Werner Lemberg + * + * The generated output is in a raw Type 1 Font format. An encoder + * (e.g. t1asm or t1binary) is needed to convert it into PFA or PFB format. + * + * This program was adapted from the ntu2cjk package (which was part of the + * LaTeX2e CJK package (by Werner Lemberg )). + * + * + * Modified by Joachim H. Kaiser to include real glyph + * names and other font infos (see PS_Head function). + * The test programs of the FreeType distribution have been heavily used as + * templates. + * + */ + +/* + * Requirements: + * - the FreeType library. + * - t1asm or a similar converter if PFA or PFB format is required. + * - getafm or a similar program if AFM font metrics are required. + * - afm2tfm or a similar program if TFM font metrics are required. + * - for compact fonts: the CJK package for typesetting LaTeX documents. + * - dvips 5.66 or higher if self-contained PostScript document + * outputs with partially downloaded fonts are required. Note that + * the partial download code in dvips is still buggy, causing strange + * error messages during loading of the created PS fonts. + * - Ghostscript 3.33 or newer (this is optional). + */ + +#include +#include +#include +#include +#include +#include +#ifdef TM_IN_SYS_TIME +#include +#endif +#include + +#include "freetype.h" +#include "extend/ftxpost.h" /* we are in the FreeType package tree */ + +char rcsid[] = "$Id: ttf2pfb.c,v 1.13 1999/08/20 13:14:26 werner Exp $"; + + +#define PID_UNICODE 3 +#define EID_UNICODE 1 +#define PID_SJIS 3 +#define EID_SJIS 2 +#define PID_GB 3 +#define EID_GB 3 +#define PID_BIG5 3 +#define EID_BIG5 4 +#define PID_KS 3 /* KS is also called Wansung */ +#define EID_KS 5 +#define PID_JOHAB 3 +#define EID_JOHAB 6 + +/* Set default values */ +#ifndef DEFAULT_PLATFORM_ID +#define DEFAULT_PLATFORM_ID PID_UNICODE /* MS platform */ +#endif + +#ifndef DEFAULT_ENCODING_ID +#define DEFAULT_ENCODING_ID EID_UNICODE +#endif + +/* The possible values for the `force_enc' variable. */ +typedef enum enc_type_ +{ + GB = 1, Big5, JIS, KS, Johab, SJIS, X +} enc_type; + +/* A variable to enforce a certain font encoding (if > 0). */ +enc_type force_enc = 0; + + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef FAILURE +#define FAILURE -1 +#endif + + +#define LINELEN 40 /* max # of columns of code range file */ +#define NAMELEN 80 /* max length of name used from LookUp */ + + +/* + * Flags and globals + */ + +int verbose = FALSE; /* messages should be printed or not. */ +int compact = FALSE; /* generate compact font? */ +int keep = FALSE; /* keep output font in case of error? */ +int mapping = FALSE; /* use encoding file as mapping? */ +float fontShift = 0; + +#ifndef UShort +typedef unsigned short UShort; +#endif +#ifndef UChar +typedef unsigned char UChar; +#endif + +#define TT_Flag_On_Curve 1 + +/* default platform and encoding ID's. */ +int pid = DEFAULT_PLATFORM_ID; +int eid = DEFAULT_ENCODING_ID; + + +char* prog; /* program name */ + + +/* for orthogonality with fprintf */ +#define Fputs(_string_) fprintf(out, "%s\n", _string_) + + +/* Postscript font related defines and functions */ +TT_F26Dot6 lastpsx, lastpsy; + +#define Coord(x) (int)(x) +#define PS_LastPt(x, y) lastpsx = x; lastpsy = y +#define PS_Moveto(x, y) \ + fprintf(out, "%d %d rmoveto\n", \ + Coord(x - lastpsx), Coord(y - lastpsy)); \ + PS_LastPt(x, y) +#define PS_Lineto(x, y) \ + fprintf(out, "%d %d rlineto\n", \ + Coord(x - lastpsx), Coord(y - lastpsy)); \ + PS_LastPt(x, y) + + +/* + * Freetype globals. + */ + +TT_Engine engine; +TT_Face face; +TT_Instance instance; +TT_Glyph glyph; +TT_CharMap cmap; +TT_Error error; +TT_Post post; + +TT_Outline outline; +TT_Glyph_Metrics metrics; +TT_Face_Properties properties; + + +/* + * Data structures defined for encoding vectors + */ + +/* + * A code range file for the encoding vector of a font contains code + * range pairs, each pair a line. The values for the begin and end of the + * ranges are separated by ` - '. Note that the spaces before and after the + * minus sign are significant. The possible syntax is as follows: + * + * (Note that code ranges must appear in ascending order.) + * + * 1. Absolute range, i.e., the code is at least a two-byte number, e.g.: + * + * 0xA140 - 0xA17E + * 41280 - 41342 + * 0xE00000 - 0xE000FF + * + * The first two lines represent the same range. + * + * 2. Relative range, i.e., the code is a one-byte number. If the line ends + * with a colon `:', it designates the high byte(s) range, otherwise the + * low byte range. If there is no high byte(s) range declared before the low + * byte range, the last defined high byte(s) range or `0x00 - 0x00:' will be + * used. e.g.: + * + * 0xA1 - 0xFE: + * 0x40 - 0x7E + * 0xA1 - 0xFE + * + * which is Big-5 Encoding. + * + * 3. Single code. Similar to absolute or relative range but the second + * number of the range is the same as the first number. E.g.: + * + * 0xA141 == 0xA141 - 0xA141 + * 0xA1: == 0xA1 - 0xA1: + * 0xA1 == 0xA1 - 0xA1 + * + * 4. If the high byte range is declared and there is no low byte range + * declared consecutively, the assumed low byte range is `0x00 - 0xFF'. + * + * 5. Comment line. A line starting with a hash mark `#' followed by any + * characters up to the end of the line is ignored. Blank lines are also + * discarded. + */ + +typedef struct _EVHigh +{ + UShort start, end; +} EVHigh; + +typedef struct _EVLow +{ + UChar start, end; +} EVLow; + +typedef struct _EVcRange +{ + EVHigh high; + UShort numLowRanges; + EVLow* low; +} EVcRange; + +typedef struct _EncVec +{ + UShort numCodeRanges; + EVcRange* codeRange; +} EncVec; + +/* Select encoding vector with respect to pid and eid */ +EncVec* eVecMap[5][10]; + +/* Select encoding vector with respect to force_enc */ +EncVec* eVecMap_force[10]; + + +/*************/ +/* Functions */ +/*************/ + + +void +mesg(const char *msg, ...) +{ + va_list ap; + + va_start(ap, msg); + vfprintf(stderr, msg, ap); + va_end(ap); +} + + +/* + * Usage. + */ + +void +Usage(int eval) +{ +#ifdef DEBUG + mesg("Usage: %s [-h][-v][-c][-k][-m][-d charcode][-l][-ng][-nc]\n", prog); +#else + mesg("Usage: %s [-h][-v][-c][-k][-m]\n", prog); +#endif + mesg("\t[-pid id] [-eid id] [-force enc] [-enc file]\n"); + mesg("\t[-plane pl] [-f fname] [-uid id] [-s shift]\n"); + mesg("\t[-o output] [-ttf font.ttf | font.ttf]\n"); + mesg("-h\t\tThis message.\n"); + mesg("-v\t\tPrint messages during conversion.\n"); + mesg("-c\t\tCompact font"); + mesg(" (256 chars per font; useful for the CJK package).\n"); + mesg("-k\t\tKeep output file in case of error.\n"); + mesg("-m\t\tUse encoding file as mapping file.\n"); +#ifdef DEBUG + mesg("-d charcode\tDebug CharString for the given character code.\n"); + mesg("-l\t\tDisplay point labels.\n"); + mesg("-ng\t\tDo not show glyph outline.\n"); + mesg("-nc\t\tDo not show control paths.\n"); +#endif + mesg("-pid id\t\tSet the platform ID [%d].\n", DEFAULT_PLATFORM_ID); + mesg("-eid id\t\tSet the encoding ID [%d].\n", DEFAULT_ENCODING_ID); + mesg("\t\t(Use a strange pid,eid pair to list all possible pid,eid)\n"); + mesg("-force enc\tForce a certain encoding [none].\n"); + mesg("\t\t(Possible values are `GB', `JIS', `KS', `SJIS', and `X').\n"); + mesg("-enc file\tFile contains code ranges [none].\n"); + mesg("-plane pl\tA single font plane [0x0].\n"); + mesg("-f fname\tFont name [UNKNOWN].\n"); + mesg("-uid id\t\tUnique font ID, for private fonts 4000000-4999999 [4999999].\n"); + mesg("-s shift\tY-offset factor [%5.3f].\n", fontShift); + mesg("-o outfile\tSet the output filename [stdout].\n"); + mesg("-ttf ttfpath\tThe TTF font pathname.\n"); + + exit(eval); +} + + +void +fatal(const char *msg, + ...) +{ + va_list ap; + + va_start(ap, msg); + fprintf(stderr, "%s: ", prog); + vfprintf(stderr, msg, ap); + fprintf(stderr, "\n"); + va_end(ap); + exit(FAILURE); +} + + +void +fatal_error(const char *msg, + ...) +{ + va_list ap; + + va_start(ap, msg); + fprintf(stderr, "%s: Error code 0x%04lx: ", prog, error); + vfprintf(stderr, msg, ap); + fprintf(stderr, "\n"); + va_end(ap); + exit(FAILURE); +} + + +/* + * Reallocate a pointer. + */ + +void * +re_alloc(void* ptr, + size_t size, + char* sub) +{ + register void* value = realloc(ptr, size); + + if (value == NULL) + fatal("%s: Virtual memory exhausted", sub); + return value; +} + + +/* + * We have to introduce the `dummy' integer to assure correct handling of + * the stack. Using `UShort' as the first parameter may fail in case + * this type is promoted to a different type (as happens e.g. under + * emx for DOS). + */ + +EncVec* +Alloc_EncVec(int dummy, + ...) +{ + va_list vp; + EncVec* encVec = NULL; + EVcRange* cRange = NULL; + EVLow* evLow = NULL; + UShort numCR, numLows; + int i, j; + + va_start(vp, dummy); + numCR = va_arg(vp, UShort); + + encVec = re_alloc(encVec, 1 * sizeof (EncVec), "Alloc_EncVec"); + encVec->numCodeRanges = numCR; + + cRange = re_alloc(cRange, numCR * sizeof (EVcRange), "Alloc_EncVec"); + for (i = 0; i < numCR; i++) + { + (cRange + i)->high.start = va_arg(vp, UShort); + (cRange + i)->high.end = va_arg(vp, UShort); + (cRange + i)->numLowRanges = numLows = va_arg(vp, UShort); + evLow = NULL; + evLow = re_alloc(evLow, numLows * sizeof (EVLow), "Alloc_EncVec"); + for (j = 0; j < numLows; j++) + { + (evLow + j)->start = va_arg(vp, UChar); + (evLow + j)->end = va_arg(vp, UChar); + } + (cRange + i)->low = evLow; + } + encVec->codeRange = cRange; + + va_end(vp); + return encVec; +} + + +void +Known_Encodings(void) +{ + EncVec* encVec; + + /* Big-5 encoding */ + encVec = Alloc_EncVec(1, + 1, 0xA1, 0xFE, + 2, 0x40, 0x7E, 0xA1, 0xFE); + eVecMap[PID_BIG5][EID_BIG5] = encVec; + eVecMap_force[Big5] = encVec; + + /* GB encoding */ + encVec = Alloc_EncVec(2, + 1, 0xA1, 0xF7, + 1, 0xA1, 0xFE); + eVecMap[PID_GB][EID_GB] = encVec; + eVecMap_force[GB] = encVec; + + /* KS encoding */ + encVec = Alloc_EncVec(3, + 1, 0xA1, 0xFE, + 1, 0xA1, 0xFE); + eVecMap[PID_KS][EID_KS] = encVec; + eVecMap_force[KS] = encVec; + + /* Johab encoding */ + encVec = Alloc_EncVec(4, + 3, 0x84, 0xD3, + 2, 0x41, 0x7E, + 0x81, 0xFE, + 0xD8, 0xDE, + 2, 0x31, 0x7E, + 0x91, 0xFE, + 0xE0, 0xF9, + 2, 0x31, 0x7E, + 0x91, 0xFE); + eVecMap[PID_JOHAB][EID_JOHAB] = encVec; + eVecMap_force[Johab] = encVec; + + /* JIS encoding */ + encVec = Alloc_EncVec(5, + 1, 0xA1, 0xF4, + 1, 0xA1, 0xFE); + eVecMap_force[JIS] = encVec; + eVecMap_force[X] = encVec; /* will be internally translated to SJIS */ + + /* Unicode encoding */ + encVec = Alloc_EncVec(6, + 1, 0x00, 0xFF, + 1, 0x00, 0xFF); + eVecMap[PID_UNICODE][EID_UNICODE] = encVec; + + /* SJIS encoding */ + encVec = Alloc_EncVec(7, + 3, 0x0, 0x0, + 1, 0xA1, 0xDF, + 0x81, 0x9F, + 2, 0x40, 0x7E, + 0x80, 0xFC, + 0xE0, 0xEF, + 2, 0x40, 0x7E, + 0x80, 0xFC); + eVecMap[PID_SJIS][EID_SJIS] = encVec; + eVecMap_force[SJIS] = encVec; +} + + +/* + * Convert JIS to SJIS encoding. + */ + +UShort +JIS_to_SJIS(UShort code) +{ + UShort index; + UShort cc0 = (code >> 8) & 0xFF; + UShort cc1 = code & 0xFF; + + index = (cc0 - 0xa1) * (0xfe - 0xa1 + 1) + (cc1 - 0xa1); + cc0 = index / ((0x7e - 0x40 + 1) + (0xfc - 0x80 + 1)); + cc1 = index % ((0x7e - 0x40 + 1) + (0xfc - 0x80 + 1)); + if (cc0 < (0x9f - 0x81 + 1)) + cc0 += 0x81; + else + cc0 += 0xe0 - (0x9f - 0x81 + 1); + if (cc1 < (0x7e - 0x40 + 1)) + cc1 += 0x40; + else + cc1 += 0x80 - (0x7E - 0x40 + 1); + + return (cc0 << 8) + cc1; +} + + +/* + * Open TTF file and select cmap. + */ + +int +Init_Font_Engine(char* infile) +{ + UShort cmapindex, platformID, encodingID, num_cmap; + + if (verbose) + printf("Initializing TrueType font engine...\n"); + + /* initialization of the FreeType engine */ + error = TT_Init_FreeType(&engine); + if (error) + fatal_error("Couldn't initialize FreeType engine"); + + /* initialization of the post extension */ + error = TT_Init_Post_Extension(engine); + if (error) + fatal_error("Couldn't initialize the post extension"); + + /* open the input file */ + error = TT_Open_Face(engine, infile, &face); + if (error) + fatal_error("Unable to open input file `%s'", infile); + + /* load full post table */ + error = TT_Load_PS_Names(face, &post); + if (error) + fatal_error("Unable to load post table"); + + /* get face properties */ + TT_Get_Face_Properties(face, &properties); + + /* Load the instance. */ + error = TT_New_Instance(face, &instance); + if (error) + fatal_error("Couldn't create instance"); + + error = TT_Set_Instance_Resolutions(instance, 600, 600); + if (error) + fatal_error("Error setting resolutions"); + + error = TT_Set_Instance_CharSize(instance, 120 * 64); + if (error) + fatal_error("Error setting character size"); + + error = TT_New_Glyph(face, &glyph); + if (error) + fatal_error("Couldn't create new glyph"); + + /* Get the requested cmap. */ + num_cmap = TT_Get_CharMap_Count(face); + for (cmapindex = 0; cmapindex < num_cmap; cmapindex++) + { + TT_Get_CharMap_ID(face, cmapindex, &platformID, &encodingID); + if (platformID == pid && encodingID == eid) + break; + } + if (cmapindex == num_cmap) + { + mesg("Possible platform and encoding ID pairs:"); + for (cmapindex = 0; cmapindex < num_cmap; cmapindex++) + { + TT_Get_CharMap_ID(face, cmapindex, &platformID, &encodingID); + mesg(" (%d, %d)", platformID, encodingID); + } + mesg ("\n"); + fatal("No character map for given platform %d, encoding %d", pid, eid); + } + + /* malloc for glyph data */ + error = TT_Get_CharMap(face, cmapindex, &cmap); + if (error) + fatal_error("Cannot load cmap"); + + return TRUE; +} + + +/* + * Get font infos: name, version, copyright. + */ + +char* +LookUp_Name(int index) +{ + UShort platform, encoding, language, id; + char* string; + UShort string_len; + UShort i, n; + + n = properties.num_Names; + + for (i = 0; i < n; i++) + { + TT_Get_Name_ID(face, i, &platform, &encoding, &language, &id); + TT_Get_Name_String(face, i, &string, &string_len); + + if (id == index) + break; + } + i = (string_len > NAMELEN) ? NAMELEN : string_len; + string[i] = '\0'; + return string; +} + + +/* + * Load a glyph's outline and metrics. + */ + +int +LoadTrueTypeChar(int idx) +{ + TT_Matrix scale = {(1 << 16) / 64, 0, 0, (1 << 16) / 64}; + + error = TT_Load_Glyph(instance, glyph, idx, TTLOAD_DEFAULT); + if (error) + fatal_error("Load glyph"); + + error = TT_Get_Glyph_Outline(glyph, &outline); + if (error) + fatal_error("Get glyph outlines"); + + TT_Transform_Outline(&outline, &scale); + + error = TT_Get_Glyph_Metrics(glyph, &metrics); + if (error) + fatal_error("Get glyph_metrics"); + + return TRUE; +} + + +/* + * Get PS name of a glyph. + */ + +char* +PS_GlyphName(UShort idx, + UShort code) +{ + char *glyphname = ".notdef"; + static char CJK_glyphname[8]; + + if (compact) + { + sprintf(CJK_glyphname, "cjk%04X", code); + glyphname = CJK_glyphname; + } + else + { + if (idx) + TT_Get_PS_Name(face, idx, &glyphname); + } + + return glyphname; +} + + +/* + * Header of Type 1 font. + */ + +void +PS_Head(FILE *out, + int plane, + EncVec* planeEV, + char* font, + int UID) +{ + EVcRange* cRange = planeEV->codeRange; + UShort numCR = planeEV->numCodeRanges; + int cjk = 0, nGlyph = 0, irange; + EVLow* pLow = cRange->low; + UShort nLow = cRange->numLowRanges; + int ipl, ilow, ich; + int idx; + UShort code; + time_t curtime; + struct tm *loctime; + char text[NAMELEN]; + char fam_name[NAMELEN]; + char* version; + char fullname[NAMELEN]; + char copyright[NAMELEN]; + + /* Get the current time with local representation */ + curtime = time(NULL); + loctime = localtime(&curtime); + + /* Get font infos: family name, version, notice */ + strcpy(fullname, LookUp_Name(6)); + strcpy(fam_name, LookUp_Name(1)); + strcpy(text, LookUp_Name(5)); + version = &text[strcspn(text, "1234567890.")]; + version[strspn(version, "1234567890.")] = '\0'; + strcpy(copyright, LookUp_Name(0)); + + fprintf(out, "%%!FontType1-1.0: %s %s\n", font, version); + fprintf(out, "%%%%Creator: %s, ", prog); + fprintf(out, "%s\n", rcsid); + fprintf(out, "%%%%CreationDate: %s", asctime(loctime)); + + Fputs("%%VMusage: 030000 030000"); + Fputs("11 dict begin"); + Fputs("/FontInfo 8 dict dup begin"); + fprintf(out, "/version (%s) readonly def\n", version); + fprintf(out, "/Copyright (%s) readonly def\n", copyright); + fprintf(out, "/Notice (Plane %d) readonly def\n", plane); + fprintf(out, "/FullName (%s) readonly def\n", fullname); + fprintf(out, "/FamilyName (%s) readonly def\n", fam_name); + Fputs("/Weight (Regular) readonly def"); + Fputs("/ItalicAngle 0 def"); + Fputs("/isFixedPitch false def"); + /* Fputs("/UnderlineThickness 50 def"); */ + Fputs("end readonly def"); + fprintf(out, "/FontName /%s def\n", font); + Fputs("/PaintType 0 def"); + Fputs("/FontType 1 def"); + + if (fontShift == 0) + Fputs("/FontMatrix [0.001 0 0 0.001 0 0] readonly def"); + else + fprintf(out, "/FontMatrix [0.001 0 0 0.001 0 %5.3f] readonly def\n", + fontShift); + + Fputs("/Encoding 256 array"); + Fputs("0 1 255 {1 index exch /.notdef put} for"); + /* encoding vector */ + for (irange = 0; irange < numCR; irange++, cRange++) + { + pLow = cRange->low; + nLow = cRange->numLowRanges; + for (ipl = cRange->high.start; ipl <= cRange->high.end; ipl++) + { + if (nLow == 0) + { + nGlyph = 0x100; + for (ich = 0; ich <= 0xff; ich++) + { + code = ipl<<8 | ich; + idx = TT_Char_Index(cmap, code); + fprintf(out, "dup %d /%s put\n", ich, PS_GlyphName(idx, code)); + } + } + else + { + for (ilow = 0; ilow < nLow; ilow++, pLow++) + { + if (!compact && !mapping) + cjk = pLow->start; + nGlyph += pLow->end - pLow->start + 1; + for (ich = pLow->start; ich <= pLow->end; ich++, cjk++) + { + code = ipl<<8 | ich; + idx = TT_Char_Index(cmap, code); + fprintf(out, "dup %d /%s put\n", cjk, PS_GlyphName(idx, code)); + if (mapping && cjk == 0xFF) + goto done; + } + } + } + } + } + +done: + + Fputs("readonly def"); + Fputs("/FontBBox [0 -300 1000 1000] readonly def"); + fprintf(out, "/UniqueID %d def\n",UID); + Fputs("currentdict end"); + Fputs("currentfile eexec"); + + Fputs("dup /Private 8 dict dup begin"); + Fputs("/-| { string currentfile exch readstring pop } executeonly def"); + Fputs("/|- { noaccess def } executeonly def"); + Fputs("/| { noaccess put } executeonly def"); + Fputs("/BlueValues [ ] |-"); + Fputs("/ForceBold true def"); + Fputs("/LanguageGroup 1 def"); + Fputs("/RndStemUp false def"); + Fputs("/MinFeature{16 16} |-"); + /* Fputs("/password 5839 def"); */ + fprintf(out, "/UniqueID %d def\n",UID); + + Fputs("/Subrs 4 array"); + Fputs("dup 0 { 3 0 callothersubr pop pop setcurrentpoint return } |"); + Fputs("dup 1 { 0 1 callothersubr return } |"); + Fputs("dup 2 { 0 2 callothersubr return } |"); + Fputs("dup 3 { return } |"); + Fputs("|-"); + + fprintf(out, "2 index /CharStrings %d dict dup begin\n", nGlyph + 1); +} + + +/* + * Tail of Type 1 font. + */ + +void +PS_Tail(FILE *out) +{ + Fputs("/.notdef { 0 250 hsbw endchar } |-"); + Fputs("end end readonly put noaccess put"); + Fputs("dup /FontName get exch definefont pop"); + Fputs("mark currentfile closefile"); +} + + +/* + * Use the `rrcurveto' command on more than one `off' points. + */ + +void +PS_Curveto(FILE *out, + TT_F26Dot6 x, + TT_F26Dot6 y, + int s, + int e) +{ + int N, i; + TT_F26Dot6 sx[3], sy[3], cx[4], cy[4]; + + N = e - s + 1; + cx[0] = lastpsx; cy[0] = lastpsy; + if (s == e) + { + cx[1] = (2 * outline.points[s].x + outline.points[s - 1].x) / 3; + cy[1] = (2 * outline.points[s].y + outline.points[s - 1].y) / 3; + cx[2] = (2 * outline.points[s].x + x) / 3; + cy[2] = (2 * outline.points[s].y + y) / 3; + cx[3] = x; + cy[3] = y; + + fprintf(out, "%d %d %d %d %d %d rrcurveto\n", + Coord(cx[1] - cx[0]), Coord(cy[1] - cy[0]), + Coord(cx[2] - cx[1]), Coord(cy[2] - cy[1]), + Coord(cx[3] - cx[2]), Coord(cy[3] - cy[2])); + } + else + { + for(i = 0; i < N; i++) + { + sx[0] = (i == 0) ? + outline.points[s - 1].x : + (outline.points[i + s].x + outline.points[i + s - 1].x) / 2; + sy[0] = (i == 0) ? + outline.points[s - 1].y : + (outline.points[i + s].y + outline.points[i + s - 1].y) / 2; + sx[1] = outline.points[s + i].x; + sy[1] = outline.points[s + i].y; + sx[2] = (i == N - 1) ? + x : + (outline.points[s + i].x + outline.points[s + i + 1].x) / 2; + sy[2] = (i == N - 1) ? + y : + (outline.points[s + i].y + outline.points[s + i + 1].y) / 2; + + cx[1] = (2 * sx[1] + sx[0]) / 3; + cy[1] = (2 * sy[1] + sy[0]) / 3; + cx[2] = (2 * sx[1] + sx[2]) / 3; + cy[2] = (2 * sy[1] + sy[2]) / 3; + cx[3] = sx[2]; + cy[3] = sy[2]; + + fprintf(out, "%d %d %d %d %d %d rrcurveto\n", + Coord(cx[1] - cx[0]), Coord(cy[1] - cy[0]), + Coord(cx[2] - cx[1]), Coord(cy[2] - cy[1]), + Coord(cx[3] - cx[2]), Coord(cy[3] - cy[2])); + + cx[0] = cx[3]; + cy[0] = cy[3]; + } + } + PS_LastPt(x, y); +} + + +#ifdef DEBUG +int debug_Char_Code = 0xFFFF; +FILE* tmpout; +int showlabel = FALSE; +int no_glyph = FALSE; +int no_control= FALSE; + +#define Fputps(_msg_) fprintf(tmpout, "%s\n", _msg_) + + +void +tmp_out(FILE* tmpout) +{ + int i, j; + + Fputps("%!PS"); + Fputps("%%% CharString debugging program."); + Fputps("%%% Generated by: ttf2pfb $Revision: 1.13 $"); + Fputps("%%% plot char-string (pathes defined in /cjkxxxx)"); + Fputps(""); + Fputps("%%% user-defined parameter"); + Fputps("/scalefactor .6 def"); + Fputps("%% 0 black, 1 white"); + Fputps("/glyph-outline-gray 0 def"); + Fputps("/control-point-gray 0.7 def"); + Fputps(""); + Fputps("%%% calculate shifts and scale factor"); + Fputps("currentpagedevice /PageSize get dup"); + Fputps("0 get /pagewidth exch def"); + Fputps("1 get /pageheight exch def"); + Fputps(""); + fprintf(tmpout, + "/llx %d.0 def /lly %d.0 def /urx %d.0 def /ury %d.0 def\n", + Coord(metrics.bbox.xMin / 64), Coord(metrics.bbox.yMin / 64), + Coord(metrics.bbox.xMax / 64), Coord(metrics.bbox.yMax / 64)); + Fputps("/olwidth urx llx sub def"); + Fputps("/olheight ury lly sub def"); + Fputps(""); + Fputps("/scale scalefactor pagewidth mul olwidth div def"); + Fputps("/xshift pagewidth 1 scalefactor sub mul 2 div def"); + Fputps("/yshift pageheight olheight scale mul sub 2 div def"); + Fputps(""); + Fputps("%% save old gray-scale value"); + Fputps("/oldgray currentgray def"); + Fputps(""); + Fputps("%%% for point sequence label"); + Fputps("/TimesRoman 8 selectfont"); + Fputps("/i++ {i /i i 1 add def} def"); + Fputps("/itos {4 string cvs} def"); + Fputps("/point {2 copy i++ 3 1 roll 5 3 roll} def"); + Fputps("/drawlabel"); + Fputps(" {{moveto dup 0 eq {exit}"); + Fputps(" {itos show} ifelse} loop pop} def"); + Fputps("/nodrawlabel {clear} def"); + Fputps("/i 0 def"); + Fputps(""); + Fputps("%%% for drawing glyph paths, redefine commands used in CharString"); + Fputps("%% scaled to proper size"); + Fputps("/addr {scale mul 3 -1 roll add 3 1 roll"); + Fputps(" scale mul add exch 2 copy} def"); + if (no_glyph) + { + Fputps("/rmoveto {addr pop pop point} def"); + Fputps("/rlineto {addr pop pop point} def"); + Fputps("/rrcurveto {8 4 roll addr 8 -2 roll addr 8 -2 roll addr"); + Fputps(" 8 2 roll 6 {pop} repeat point} def"); + } + else + { + Fputps("/rmoveto {addr moveto point} def"); + Fputps("/rlineto {addr lineto point} def"); + Fputps("/rrcurveto {8 4 roll addr 8 -2 roll addr 8 -2 roll addr"); + Fputps(" 8 2 roll curveto point} def"); + } + Fputps("/hsbw {pop pop"); + Fputps(" xshift llx scale mul sub"); + Fputps(" yshift lly scale mul sub} def"); + Fputps("/endchar {stroke pop pop} def"); + Fputps(""); + Fputps("%%% for drawing control paths"); + Fputps("/T {pop lly sub scale mul yshift add exch"); + Fputps(" llx sub scale mul xshift add exch } def"); + Fputps("/mt {T 2 copy moveto} def"); + if (no_control) + Fputps("/lt {T} def"); + else + Fputps("/lt {T 2 copy lineto} def"); + Fputps(""); + Fputps("1 setlinecap 1 setlinejoin"); + Fputps("%%% draw control points and paths"); + Fputps("control-point-gray setgray"); + + for (i = 0, j = 0; i < outline.n_contours; i++) + { + Fputps(""); + fprintf(tmpout, + "%d %d %d %d mt\n", + j, + Coord(outline.points[j].x), Coord(outline.points[j].y), + outline.flags[j]); + j++; + for (; j <= outline.contours[i]; j++) + fprintf(tmpout, + "%d %d %d %d lt\n", + j, + Coord(outline.points[j].x), Coord(outline.points[j].y), + outline.flags[j]); + Fputps("closepath"); + } + Fputps("stroke"); + if (showlabel && !no_control) + Fputps("drawlabel"); + else + Fputps("nodrawlabel"); + Fputps(""); + Fputps("%%% draw glyph outlines"); + Fputps("glyph-outline-gray setgray"); + Fputps(""); +} +#endif + + +/* + * Construct CharString of a glyph. + */ + +short +PS_CharString(FILE *out, + UShort char_Code) +{ + int idx, i, j; + UShort start_offpt, end_offpt = 0, fst; +#if DEBUG + FILE* oldout = out; + int loop = 1; +#endif + + if (force_enc == X) + char_Code = JIS_to_SJIS(char_Code); + + idx = TT_Char_Index(cmap, char_Code); + if (idx == 0) + return FALSE; + + if (!LoadTrueTypeChar(idx)) + fatal("Couldn't load character with index %d (code %d)", idx, char_Code); + + if (verbose) + printf("0x%04x (%05d): %s\n", + char_Code, idx, PS_GlyphName(idx, char_Code)); + + /* Begin string */ + fprintf(out, "/%s {\n", PS_GlyphName(idx, char_Code)); + +#ifdef DEBUG + if (char_Code == debug_Char_Code) + { + tmp_out(tmpout); + out = tmpout; + loop = 0; + } + for (; loop < 2; loop++) + { +#endif + + /* coordinates are all relative to (0,0) in FreeType */ + fprintf(out, "0 %d hsbw\n", (int)(metrics.advance / 64)); + + /* Initialize ending contour point, relative coordinates */ + lastpsx = lastpsy = 0; + + for (i = 0, j = 0; i < outline.n_contours; i++) + { + fst = j; + PS_Moveto(outline.points[j].x, outline.points[j].y); + j++; + + start_offpt = 0; /* start at least 1 */ + + /* + * data pts for all contours stored in one array. + * each round j init at last j + 1 + */ + + /* + * start_offpt means start of off points. + * 0 means no off points in record. + * N means the position of the off point. + * end_offpt means the ending off point. + * lastx, lasty is the last ON point from which Curve and Line + * shall start. + */ + + /* + * start with j=0. into loop, j=1. + * if pt[1] off, if start_offpt == 0, toggle start_offpt + * next j=2. if on, now start_off != 0, run Curveto. + * if pt[1] on, start_off == 0, will run Lineto. + */ + + for (; j <= outline.contours[i]; j++) + { + if (!(outline.flags[j] & TT_Flag_On_Curve)) + { + if (!start_offpt) + start_offpt = end_offpt = j; + else + end_offpt++; + } + else + { /* On Curve */ + if (start_offpt) + { + /* + * start_offpt stuck at j, end_offpt++. + * end_offpt - start_offpt gives no of off pts. + * start_offpt gives start of sequence. + * why need outline.xCoord[j] outline.yCoord[j]? + */ + + PS_Curveto(out, + outline.points[j].x, outline.points[j].y, + start_offpt, end_offpt); + start_offpt = 0; + + /* + * also use start_offpt as indicator to save one variable!! + * after curveto, reset condition. + */ + } + else + PS_Lineto(outline.points[j].x, outline.points[j].y); + } + } + + /* + * looks like closepath fst = first, i.e. go back to first + */ + + if (start_offpt) + PS_Curveto(out, + outline.points[fst].x, outline.points[fst].y, + start_offpt, end_offpt); + else + Fputs("closepath"); + } + + Fputs("endchar"); + +#if DEBUG + out = oldout; + } + if (char_Code == debug_Char_Code) + { + if (showlabel && !no_glyph) + Fputps("drawlabel"); + else + Fputps("nodrawlabel"); + Fputps(""); + Fputps("%%% end of drawing"); + Fputps("oldgray setgray"); + Fputps("showpage"); + fclose(tmpout); + } +#endif + + Fputs(" } |-"); + return TRUE; +} + + +/* + * Get code ranges of an encoding scheme either from + * the eVecMap or a code range file. + */ + +EncVec* +Get_EncVec(FILE *enc) +{ + EncVec* encVec = NULL; + EVcRange* cRange = NULL; + EVLow* lByte = NULL; + UShort numCR = 0, numLow = 0; + int start, end; + int buflen = LINELEN, numAssigned; + char buf[LINELEN]; + + if (force_enc != 0) + return eVecMap_force[force_enc]; + + if (enc == NULL && eVecMap[pid][eid] != NULL) + return eVecMap[pid][eid]; + + /* parse each code range line */ + while (fgets(buf, buflen, enc) != NULL) + { + if (buf[0] != '#' && buf[0] != '\n') + { + if (strrchr(buf,':') != NULL) + { + /* if there is no high value declared before low value */ + if (lByte != NULL) + { + if (cRange == NULL) + { + /* default code range `0x00-0x00:' */ + cRange = re_alloc(cRange, ++numCR * sizeof (EVcRange), + "Get_EncVec"); + cRange->high.start = cRange->high.end = 0; + } + /* Assign the last low value */ + (cRange + numCR - 1)->low = lByte; + (cRange + numCR - 1)->numLowRanges = numLow; + } + + /* New high byte range */ + cRange = re_alloc(cRange, ++numCR * sizeof (EVcRange), "Get_EncVec"); + (cRange + numCR - 1)->numLowRanges = numLow = 0; + lByte = NULL; + + /* Parse code range */ + numAssigned = sscanf(buf, "%i %*40s %i", &start, &end); + if (numAssigned <= 0 || numAssigned > 2) + { + mesg("%s: Get_EncVec: Invalid high code range.\n", prog); + return NULL; + } + else + { + (cRange + numCR - 1)->high.start = start; + if (numAssigned == 1) + (cRange + numCR - 1)->high.end = start; + else + (cRange + numCR - 1)->high.end = end; + } + } + else + { + lByte = re_alloc(lByte, ++numLow * sizeof (EVLow), "Get_EncVec"); + numAssigned = sscanf(buf, "%i %*40s %i", &start, &end); + if (numAssigned <= 0 || numAssigned > 2) + { + mesg("%s: Get_EncVec: Invalid long code range.\n", prog); + return NULL; + } + else + { + (lByte + numLow - 1)->start = start; + if (numAssigned == 1) + (lByte + numLow - 1)->end = start; + else + (lByte + numLow - 1)->end = end; + } + } + } + } + + if (cRange == NULL) + { + cRange = re_alloc(cRange, ++numCR * sizeof (EVcRange), "Get_EncVec"); + cRange->high.start = cRange->high.end = 0; + cRange->numLowRanges = 0; + } + + if (lByte != NULL) + { + (cRange + numCR - 1)->low = lByte; + (cRange + numCR - 1)->numLowRanges = numLow; + } + + encVec = re_alloc(encVec, 1 * sizeof (EncVec), "Get_EncVec"); + encVec->numCodeRanges = numCR; + encVec->codeRange = cRange; + return encVec; +} + + +/* + * Match code ranges by a font plane. + */ + +EncVec* +Get_PlaneEV(EncVec* encVec, + int plane) +{ + UShort numCR = encVec->numCodeRanges; + EVcRange* cRange = encVec->codeRange; + + EncVec* encV = NULL; + EVcRange* planeCR = NULL; + EVLow* planeLow = NULL; + UShort nCR = 0, nLow = 0; + + int icr; + + if (compact) + { + int iChar = 0; /* summed # of chars */ + int nChar = (plane-1) * 256; /* the first char code ranges recorded */ + int recording = 0; + + /* if compact, plane starts from 1 to be */ + /* compatible with the CJK package */ + if (plane < 1 || plane > 99) + fatal("Get_PlaneEV: Given plane out of range"); + + for (icr = 0; icr < numCR; icr++, cRange++) + { + UShort numLow = cRange->numLowRanges; + int ipl; + + for (ipl = cRange->high.start; ipl <= cRange->high.end; ipl++) + { + EVLow* pLow = cRange->low; + int ilow; + + if (recording) + { /* if we have made a hit */ + if (planeLow != NULL) + { /* if low byte range has not been saved */ + (planeCR + nCR - 1)->low = planeLow; + (planeCR + nCR - 1)->numLowRanges = nLow; + planeLow = NULL; + } + + /* each new plane starts a EVcRange if */ + /* iChar is still less than nChar */ + if (iChar <= nChar) + { + planeCR = re_alloc(planeCR, ++nCR * sizeof (EVcRange), + "Get_PlaneEV"); + (planeCR + nCR - 1)->high.start = + (planeCR + nCR - 1)->high.end = ipl; + (planeCR + nCR - 1)->numLowRanges = nLow = 0; + } + } + + /* scan each low byte range */ + for (ilow = 0; ilow < (numLow == 0 ? 1 : numLow); ilow++, pLow++) + { + int start, end, nLowChar; + + if (numLow == 0) + { /* default range */ + start = 0x0; + end = 0xff; + } + else + { + start = pLow->start; + end = pLow->end; + } + nLowChar = end - start + 1; + if (iChar + nLowChar > nChar) + { /* a hit! */ + int bchar = start + nChar - iChar; + if (planeCR == NULL) + { + /* the first time code range is recorded */ + planeCR = re_alloc(planeCR, ++nCR * sizeof (EVcRange), + "Get_PlaneEV"); + (planeCR + nCR - 1)->high.start = ipl; + (planeCR + nCR - 1)->high.end = ipl; + } + + /* adjust range boundary */ + if (recording == 0) + start = bchar; + else + end = bchar; + nChar += 0xff; + + /* recording starts */ + recording++; + } + + iChar += nLowChar; /* next range */ + + if (recording) + { + /* a new low range */ + if (iChar <= nChar) + { + planeLow = re_alloc(planeLow, ++nLow * sizeof (EVLow), + "Get_PlaneEV"); + (planeLow + nLow - 1)->start = start; + (planeLow + nLow - 1)->end = end; + } + if (recording > 1 || iChar > nChar) + { + /* beyond recording range */ + (planeCR + nCR - 1)->numLowRanges = nLow; + (planeCR + nCR - 1)->low = planeLow; + encV = re_alloc(encV, 1 * sizeof (EncVec), "Get_PlaneEV"); + encV->numCodeRanges = nCR; + encV->codeRange = planeCR; + return encV; + } + } + } + } + } + /* we must finalize the ranges */ + if (recording) + { + (planeCR + nCR - 1)->numLowRanges = nLow; + (planeCR + nCR - 1)->low = planeLow; + encV = re_alloc(encV, 1 * sizeof (EncVec), "Get_PlaneEV"); + encV->numCodeRanges = nCR; + encV->codeRange = planeCR; + return encV; + } + } + else + { + for (icr = 0; icr < numCR; icr++, cRange++) + { + if (plane >= cRange->high.start && plane <= cRange->high.end) + { + encV = re_alloc(encV, 1 * sizeof (EncVec), "Get_PlaneEV"); + planeCR = re_alloc(planeCR, 1 * sizeof (EVcRange), "Get_PlaneEV"); + + planeCR->high.start = planeCR->high.end = plane; + planeCR->numLowRanges = cRange->numLowRanges; + planeCR->low = cRange->low; + encV->numCodeRanges = 1; + encV->codeRange = planeCR; + return encV; + } + } + } + return NULL; +} + + +/* + * The main subroutine for generating Type 1 fonts. + * One subfont per call. + */ + +short +Generate_Font(FILE *out, + int plane, + FILE *enc, + char *fname, + int UID) +{ + EncVec* encVec = Get_EncVec(enc); + EncVec* planeEncVec; + EVcRange* cRange; + UShort numCR; + UShort code; + int ilow, iplan, ichar, irange; + + if (verbose) + printf("Generating fonts...\n\n"); + + if (encVec == NULL) + return FALSE; + if (mapping) + planeEncVec = encVec; + else + if ((planeEncVec = Get_PlaneEV(encVec, plane)) == NULL) + { + mesg("%s: Can't find encoding vector for the font plane 0x%X.\n", + prog, plane); + return FALSE; + } + + /* Header of Type1 font */ + PS_Head(out, plane, planeEncVec, fname, UID); + + numCR = planeEncVec->numCodeRanges; + cRange = planeEncVec->codeRange; + + for (irange = 0; irange < numCR; irange++, cRange++) + { + EVLow* pLow = cRange->low; + UShort nLow = cRange->numLowRanges; + + for (iplan = cRange->high.start; iplan <= cRange->high.end; iplan++) + { + if (nLow == 0) + { + for (ichar = 0; ichar <= 0xff; ichar++) + { + code = iplan << 8 | ichar; + PS_CharString(out, code); + } + } + else + { + for (ilow = 0; ilow < nLow; ilow++, pLow++) + { + for (ichar = pLow->start; ichar <= pLow->end; ichar++) + { + code = iplan << 8 | ichar; + PS_CharString(out, code); + } + } + } + } + } + PS_Tail(out); + + return TRUE; +} + + +/* + * Main: process options, file I/O, etc. + */ + +int +main(int argc, + char *argv[]) +{ + char *infile, *outfile, *encFile, *fname = "UNKNOWN"; + FILE *out, *enc; + int result, plane = 0, UID = 4999999; + + if ((prog = strrchr(argv[0], '/'))) + prog++; + else + prog = argv[0]; + + /* set up known encoding vectors */ + Known_Encodings(); + + out = stdout; + enc = NULL; + infile = outfile = encFile = NULL; + + argc--; + argv++; + + while (argc > 0) + { + if (argv[0][0] == '-') + { + switch (argv[0][1]) + { + case 'v': + case 'V': + verbose = TRUE; + break; + case 'c': + case 'C': + compact = TRUE; + break; + case 'k': + case 'K': + keep = TRUE; + break; + case 'm': + case 'M': + mapping = TRUE; + break; + case 'p': + case 'P': + result = argv[0][2]; + argc--; + argv++; + if (result == 'i' || result == 'I') + { + /* Set the platform ID. Assumed upper bound is 64 */ + if ((pid = atoi(argv[0])) < 0 || pid > 64) + /* Check the platform and encoding IDs. */ + fatal("Invalid platform ID %d", pid); + } + else if (result == 'l' || result == 'L') + { + result = 0; + while (argv[0][result] == '0' && + toupper(argv[0][result + 1]) != 'X') + result++; /* no octal number */ + sscanf(&argv[0][result], "%i", &plane); + } + break; + case 'e': + case 'E': + result = argv[0][2]; + argc--; + argv++; + if (result == 'i' || result == 'I') + { + /* Set the encoding ID. */ + if ((eid = atoi(argv[0])) < 0 || eid > 64) + fatal("Invalid encoding ID %d", eid); + } + else if (result == 'n' || result == 'N') + encFile = argv[0]; + break; + case 'u': + case 'U': + argc--; + argv++; + UID = atoi(argv[0]); + break; + case 'f': + case 'F': + result = argv[0][2]; + argc--; + argv++; + if (result == '\0') + fname = argv[0]; + else if (result == 'o' || result == 'O') + { + switch (argv[0][0]) + { + case 'g': + case 'G': + force_enc = GB; + break; + case 'k': + case 'K': + force_enc = KS; + break; + case 'b': + case 'B': + force_enc = Big5; + break; + case 'j': + case 'J': + result = argv[0][1]; + if (result == 'o' || result == 'O') + force_enc = Johab; + else + force_enc = JIS; + break; + case 's': + case 'S': + force_enc = SJIS; + break; + case 'x': + case 'X': + force_enc = X; + } + } + break; + case 't': /* Get the TTF file name. */ + case 'T': + argc--; + argv++; + infile = argv[0]; + break; + case 'o': /* Set the output file name. */ + case 'O': + argc--; + argv++; + outfile = argv[0]; + break; + case 's': /* shift font bbox up or down */ + case 'S': + argc--; + argv++; + sscanf(argv[0], "%f", &fontShift); + break; +#ifdef DEBUG + case 'd': /* character code for debugging */ + case 'D': + argc--; + argv++; + sscanf(argv[0], "%i", &debug_Char_Code); + tmpout = fopen("ch-debug.ps", "wt"); + mesg("You have specified the character code 0x%04x for debugging.\n", + debug_Char_Code); + mesg("A PostScript program named `ch-debug.ps' will be created.\n"); + break; + case 'l': + case 'L': + showlabel = TRUE; + break; + case 'n': + case 'N': + result = argv[0][2]; + if (result == 'g' || result == 'G') + no_glyph = TRUE; + else if (result == 'c' || result == 'C') + no_control = TRUE; + break; +#endif + default: + Usage(1); + } + } + else + /* Set the input file name. */ + infile = argv[0]; + + argc--; + argv++; + } + + /* Open the output file if specified. */ + if (outfile != NULL) + /* Attempt to open the output file. */ + if ((out = fopen(outfile, "wt")) == 0) + { + fatal("Unable to open the output file `%s'", outfile); + exit(FAILURE); + } + + /* Validate the values passed on the command line. */ + if (infile == NULL) + { + mesg("%s: No input TTF file provided\n", prog); + Usage(1); + } + + if (encFile != NULL) + { + if ((enc = fopen(encFile, "rt")) == 0) + fatal("No input code range file"); + } + + /* Initialize font engine */ + if (!Init_Font_Engine(infile)) + { + if (out != stdout) + { + fclose(out); + if (!keep) + (void)unlink(outfile); + } + exit(FAILURE); + } + + /* Generate the disassembled PFB font from the TrueType font */ + if (Generate_Font(out, plane, enc, fname, UID)) + result = 0; + else + result = 2; + + if (out != stdout) + { + fclose(out); + if (result != 0) + { + mesg("%s: An error occurred while generating the font", prog); + if (!keep) + (void)unlink(outfile); + } + } + + TT_Close_Face(face); + TT_Done_FreeType(engine); + + exit(result); + + return 0; /* never reached */ +} + + +/* end of ttf2pfb.c */ diff --git a/contrib/ttf2pk/.cvsignore b/contrib/ttf2pk/.cvsignore new file mode 100644 index 0000000..1db72e5 --- /dev/null +++ b/contrib/ttf2pk/.cvsignore @@ -0,0 +1,8 @@ +ttf2tfm +ttf2pk +.libs +MakeSub +config.status +config.cache +config.log +Makefile diff --git a/contrib/ttf2pk/BUGS b/contrib/ttf2pk/BUGS new file mode 100644 index 0000000..af531e4 --- /dev/null +++ b/contrib/ttf2pk/BUGS @@ -0,0 +1,3 @@ + +Some characters (Arial A) have a bounding box that extends outside the +character width... such a character will get an italic correction. diff --git a/contrib/ttf2pk/MakeSub.in b/contrib/ttf2pk/MakeSub.in new file mode 100644 index 0000000..948f13b --- /dev/null +++ b/contrib/ttf2pk/MakeSub.in @@ -0,0 +1,6 @@ +# This file is part of the ttf2pk package + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +mandir = @mandir@ diff --git a/contrib/ttf2pk/Makefile.dm b/contrib/ttf2pk/Makefile.dm new file mode 100644 index 0000000..9c14745 --- /dev/null +++ b/contrib/ttf2pk/Makefile.dm @@ -0,0 +1,71 @@ +# Makefile for ttf2pk -- loyer@enst.fr, wl@gnu.org +# +# This Makefile assumes that you've already built and installed +# the FreeType library. +# +# It builds the ttf2pk and ttf2tfm for emx-gcc. +# +# You will need dmake. +# +# Use this file while with the following statement: +# +# dmake -r -f Makefile.dm + + +.IMPORT: COMSPEC +SHELL := $(COMSPEC) +SHELLFLAGS := /c +GROUPSHELL := $(SHELL) +GROUPFLAGS := $(SHELLFLAGS) +GROUPSUFFIX := .bat +SHELLMETAS := *"?<>&| + +CC = gcc +LIBDIR = ../../lib +INCDIR = -I$(LIBDIR) -I. + +# CFLAGS = -Wall -O2 -g $(INCDIR) -fbounds-checking -DHAVE_EMTEXDIR -DMSDOS +CFLAGS = -Wall -O2 -s $(INCDIR) -DHAVE_EMTEXDIR -DMSDOS + +SRC = case.c emdir.c emtexdir.c errormsg.c filesrch.c ligkern.c newobj.c \ + parse.c pklib.c subfont.c texenc.c tfmaux.c ttf2pk.c ttf2tfm.c \ + ttfaux.c ttfenc.c ttflib.c vplaux.c + +ttf2pkobjs = emdir.o emtexdir.o errormsg.o filesrch.o ligkern.o newobj.o \ + parse.o pklib.o subfont.o texenc.o ttf2pk.o ttfenc.o ttflib.o +ttf2tfmobjs = case.o emdir.o emtexdir.o errormsg.o filesrch.o ligkern.o \ + newobj.o parse.o subfont.o texenc.o tfmaux.o ttf2tfm.o \ + ttfaux.o ttfenc.o vplaux.o + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +%.exe: + $(CC) $(CFLAGS) -o $@ @$(mktmp $(&:t"\n")\n) + + +PROGRAMS = ttf2pk.exe ttf2tfm.exe + +.PHONY: all clean distclean + + +all: $(PROGRAMS) + +ttf2pk.exe: $(ttf2pkobjs) $(LIBDIR)/libttf.a +ttf2tfm.exe: $(ttf2tfmobjs) $(LIBDIR)/libttf.a + + +clean: +-[ + del *.o +] + +distclean: clean +-[ + del dep.end + del *.exe + del core +] + +#end of Makefile.dm diff --git a/contrib/ttf2pk/Makefile.in b/contrib/ttf2pk/Makefile.in new file mode 100644 index 0000000..af7e495 --- /dev/null +++ b/contrib/ttf2pk/Makefile.in @@ -0,0 +1,116 @@ +# Makefile for ttf2pk -- loyer@enst.fr, wl@gnu.org +# +# This Makefile assumes that you've already built and installed +# the FreeType library. + +VPATH = @srcdir@ +srcdir = @srcdir@ + +RM = @RM@ +RMF = @RM@ -f +RMDIR = @RMDIR@ + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ + +CC = @CC@ +CPP = @CPP@ + +LIBTOOL = ../../libtool +MKINSTALLDIRS = $(srcdir)/../../mkinstalldirs + +include MakeSub + +CFLAGS = @CFLAGS@ @XX_CFLAGS@ +CPPFLAGS = @CPPFLAGS@ @DEFS@ +FT_CFLAGS = $(CFLAGS) $(CPPFLAGS) +LDFLAGS = @LDFLAGS@ @LIBS@ +LIBDIR = ../../lib + +SRC = $(srcdir)/case.c \ + $(srcdir)/errormsg.c \ + $(srcdir)/filesrch.c \ + $(srcdir)/ligkern.c \ + $(srcdir)/newobj.c \ + $(srcdir)/parse.c \ + $(srcdir)/pklib.c \ + $(srcdir)/subfont.c \ + $(srcdir)/texenc.c \ + $(srcdir)/tfmaux.c \ + $(srcdir)/ttf2pk.c \ + $(srcdir)/ttf2tfm.c \ + $(srcdir)/ttfaux.c \ + $(srcdir)/ttfenc.c \ + $(srcdir)/ttflib.c \ + $(srcdir)/vplaux.c + +ttf2pkobjs = errormsg.o filesrch.o ligkern.o newobj.o parse.o pklib.o \ + subfont.o texenc.o ttf2pk.o ttfenc.o ttflib.o +ttf2tfmobjs = case.o errormsg.o filesrch.o ligkern.o newobj.o parse.o \ + subfont.o texenc.o tfmaux.o ttf2tfm.o ttfaux.o ttfenc.o \ + vplaux.o + + +.c.o: + $(CC) -c $(FT_CFLAGS) $< + + +PROGRAMS = ttf2pk ttf2tfm + +default all: $(PROGRAMS) + +ttf2pk: $(ttf2pkobjs) $(LIBDIR)/libttf.la + $(LIBTOOL) --mode=link $(CC) $(FT_CFLAGS) -o ttf2pk $(ttf2pkobjs) \ + $(LIBDIR)/libttf.la $(LDFLAGS) + +ttf2tfm: $(ttf2tfmobjs) $(LIBDIR)/libttf.la + $(LIBTOOL) --mode=link $(CC) $(FT_CFLAGS) -o ttf2tfm $(ttf2tfmobjs) \ + $(LIBDIR)/libttf.la $(LDFLAGS) + +install: $(PROGRAMS) + $(MKINSTALLDIRS) $(bindir) $(mandir)/man1 + for P in $(PROGRAMS) ; do \ + $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$P $(bindir)/$$P ; \ + $(INSTALL_DATA) $(srcdir)/$$P.1 $(mandir)/man1 ; \ + done + +uninstall: + -for P in $(PROGRAMS) ; do \ + $(LIBTOOL) --mode=uninstall $(RM) $(bindir)/$$P ; \ + $(RMF) $(mandir)/man1/$$P.1 ; \ + done + +clean: do_clean + +distclean: do_clean + -$(RMF) dep.end $(PROGRAMS) + -$(RMF) *~ *.orig core *.core + -$(RMF) config.cache config.log config.status Makefile MakeSub + -$(RMF) .libs/* + -$(RMDIR) .libs + +do_clean: + -$(RMF) *.o + + +depend: + (echo '/^#.* PUT NO STUFF BELOW/,$$d' ; echo w ; echo q) | \ + ed - Makefile + echo '# Dependencies generated by make depend: PUT NO STUFF BELOW' \ + >> Makefile + for file in $(SRC) ; do \ + $(CPP) $(CPPFLAGS) $$file | \ + sed -n -e 's|^# [1-9][0-9]* "\([^/].*\.h\)".*|\1|p' \ + -e 's|^# [1-9][0-9]* "\($(srcdir)/.*\.h\)".*|\1|p' | \ + sed -e 's|/\./|.|g' -e "s/^/`basename $$file .c`.o: /" ; \ + done | \ + sort -u | \ + awk '{ if (LINE == 1) \ + { line = last = $$1 } \ + else if ($$1 != last) \ + { print line ; line = last = $$1 } \ + line = line " " $$2 } \ + END { print line }' >> Makefile + +# Dependencies generated by make depend: PUT NO STUFF BELOW diff --git a/contrib/ttf2pk/README b/contrib/ttf2pk/README new file mode 100644 index 0000000..a9439d7 --- /dev/null +++ b/contrib/ttf2pk/README @@ -0,0 +1,104 @@ +This directory contains ttf2tfm and ttf2pk, two utilities based on + + afm2tfm (dvipsk distribution), + gsftopkk (dvipsk distribution), + and the FreeType rasterizer for TrueType fonts. + + +Compile the FreeType library first! It is recommended to use the kpathsea +library if you want to use the programs with web2c resp. teTeX. Source files +for emTeX-like search routines are included; similarly, support for MiKTeX +file searching routines is available if `MIKTEX' is defined during +compilation. Nevertheless, as a last resort, you can compile both programs +without a search library too. + +The kpathsea library is *not* part of the ttf2pk package (see notes below). + + + +Under UNIX-like systems say + + ./configure --prefix=/usr/local/TeX --with-kpathsea-dir= + make + make install + +for a normal compilation and installation. Replace `/usr/local/TeX' with a +path to your TeX distribution. + + +[Note 1: + Try to find `libkpathsea.*' on your system. Use the directory above this + one as the argument for --with-kpathsea-dir. This should work in most + cases. If you can't find the library, you probably have a web2c package + with statically linked binaries. This means that you have to get the web2c + sources from CTAN, configure it with something like + + ./configure --prefix=/usr/local/TeX --datadir=/usr/local/TeX \ + --enable-shared --disable-static + + according to your setup; then change to the kpathsea directory and say + `make' and `make install' (Do the latter with caution not to overwrite + binaries like kpsewhich). + + It even works with the source tree from the TeX Live CD 3! You just have + to add a proper --srcdir option to the configure script. + + Unfortunately, teTeX-0.4 uses a very old kpathsea library version without + automatical shared-library support, thus you have to install the static + libraries: + + .) unpack the sources (basically you need only the contents of kpse-2.6 + and the two subdirs `kpathsea' and `make'. + + .) say + + ./configure --prefix=... + make + + in the kpse-2.6 directory + + .) say + + make install-library + + in the kpathsea subdirectory. See Note 2 also. + + DON'T USE A NEWER KPATHSEA VERSION IF YOU USE teTeX 0.4 BINARIES! Newer + kpathsea versions are not compatible with version 2.6. + + Note 2: + It seems that c-auto.h created during the kpathsea library compiling + process won't be installed for some older web2c versions. You should add + it manually, i.e., copy /kpathsea/c-auto.h to the + location where the other kpathsea header files have been installed. + + Note 3: + If you want to use the --srcdir option of the configure script, you must + compile FreeType with --srcdir too. You have to use the same directory + structure to make it work (i.e., if you have said for FreeType + `./configure --srcdir=foo', and you are in the `bar' directory, FreeType's + configure script will generate all the needed subdirs for compiling + FreeType. You've then manually to add the directory `bar/contrib/ttf2pk'; + there you should start to say ./configure --srcdir=foo/contrib/ttf2pk').] + + + +Use Makefile.dm for emx + dmake and say + + dmake -r -f Makefile.dm + +[Note: It should work with djgpp too, but I haven't tested this.] + + +ttf2pk and ttf2tfm are already part of MiKTeX. + + + +Primary author of afm2tfm: T. Rokicki, +Primary author of gsftopk: P.Vojta +Primary author of the kpathsea library, + afm2tfm/gsftopk adaptation: K. Berry. + +-- +Frederic Loyer +Werner Lemberg diff --git a/contrib/ttf2pk/TODO b/contrib/ttf2pk/TODO new file mode 100644 index 0000000..474f407 --- /dev/null +++ b/contrib/ttf2pk/TODO @@ -0,0 +1,22 @@ +. multiple configuration files similar to newer versions of gsftopk(k). + +. support for different horizontal and vertical resolutions. + +. character composition via the vpl file. + +. using GSUB for accessing small caps (if available). + +. enabling -v and -V at the same time. + +. Omega support + +. afm output + +. possibility to create `real' fonts, i.e., avoiding virtual fonts for small + caps etc. -- some dvi previewers still can't handle virtual fonts. Due to + the huge amount of work to support this it is rather unlikely that I'll do + it. + +. using hash tables to store glyph names for better performance + +. show replacement glyphs too in glyph listings diff --git a/contrib/ttf2pk/c-auto.h b/contrib/ttf2pk/c-auto.h new file mode 100644 index 0000000..efc07e6 --- /dev/null +++ b/contrib/ttf2pk/c-auto.h @@ -0,0 +1,23 @@ +/* + * c-auto.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef C_AUTO_H +#define C_AUTO_H + +/* + * We need to get kpathsea's configuration file. + */ + +#include "kpathsea/c-auto.h" + +#endif /* C_AUTO_H */ + + +/* end */ diff --git a/contrib/ttf2pk/case.c b/contrib/ttf2pk/case.c new file mode 100644 index 0000000..6bb0ce8 --- /dev/null +++ b/contrib/ttf2pk/case.c @@ -0,0 +1,179 @@ +/* + * case.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#include /* for definition of NULL */ + +#include "case.h" + + +/* This is a table of uppercase/lowercase pairs which can't be deduced */ +/* by lowercasing the uppercase Adobe glyph name. */ +/* It has been extracted from the ucs2ps.um database compiled by */ +/* Bjorn Brox . */ + +Case casetable[] = +{ + {"afii10017", "afii10065"}, + {"afii10018", "afii10066"}, + {"afii10019", "afii10067"}, + {"afii10020", "afii10068"}, + {"afii10021", "afii10069"}, + {"afii10022", "afii10070"}, + {"afii10023", "afii10071"}, + {"afii10024", "afii10072"}, + {"afii10025", "afii10073"}, + {"afii10026", "afii10074"}, + {"afii10027", "afii10075"}, + {"afii10028", "afii10076"}, + {"afii10029", "afii10077"}, + {"afii10030", "afii10078"}, + {"afii10031", "afii10079"}, + {"afii10032", "afii10080"}, + {"afii10033", "afii10081"}, + {"afii10034", "afii10082"}, + {"afii10035", "afii10083"}, + {"afii10036", "afii10084"}, + {"afii10037", "afii10085"}, + {"afii10038", "afii10086"}, + {"afii10039", "afii10087"}, + {"afii10040", "afii10088"}, + {"afii10041", "afii10089"}, + {"afii10042", "afii10090"}, + {"afii10043", "afii10091"}, + {"afii10044", "afii10092"}, + {"afii10045", "afii10093"}, + {"afii10046", "afii10094"}, + {"afii10047", "afii10095"}, + {"afii10048", "afii10096"}, + {"afii10049", "afii10097"}, + {"afii10050", "afii10098"}, + {"afii10051", "afii10099"}, + {"afii10052", "afii10100"}, + {"afii10053", "afii10101"}, + {"afii10054", "afii10102"}, + {"afii10055", "afii10103"}, + {"afii10056", "afii10104"}, + {"afii10057", "afii10105"}, + {"afii10058", "afii10106"}, + {"afii10059", "afii10107"}, + {"afii10060", "afii10108"}, + {"afii10061", "afii10109"}, + {"afii10062", "afii10110"}, + {"afii10145", "afii10193"}, + {"afii10146", "afii10194"}, + {"afii10147", "afii10195"}, + {"afii10148", "afii10196"}, + {"afii10149", "afii10197"}, + {"afii10152", "afii10200"}, + {"afii10202", "afii10154"}, + {"afii10155", "afii10203"}, + {"afii10156", "afii10204"}, + {"afii10157", "afii10205"}, + {"afii10158", "afii10206"}, + {"afii10160", "afii10208"}, + {"afii10161", "afii10209"}, + {"afii10162", "afii10210"}, + {"afii10163", "afii10211"}, + {"afii10164", "afii10212"}, + {"afii10166", "afii10214"}, + {"afii10167", "afii10215"}, + {"afii10168", "afii10216"}, + {"afii10170", "afii10218"}, + {"afii10171", "afii10219"}, + {"afii10172", "afii10220"}, + {"afii10173", "afii10221"}, + {"afii10174", "afii10222"}, + {"afii10176", "afii10224"}, + {"afii10178", "afii10226"}, + {"afii10179", "afii10227"}, + {"afii10181", "afii10229"}, + {"afii10182", "afii10230"}, + {"afii10184", "afii10232"}, + {"afii10185", "afii10233"}, + {"afii10187", "afii10235"}, + {"afii10188", "afii10236"}, + {"afii10190", "afii10238"}, + {"afii10785", "afii10833"}, + {"afii10786", "afii10834"}, + {"afii10787", "afii10835"}, + {"afii10795", "afii10843"}, + {"afii10798", "afii10846"}, + {"afii10799", "afii10847"}, + {"afii10800", "afii10848"}, + {"afii10801", "afii10849"}, + {"afii64308", "afii64436"}, + {"afii10803", "afii10851"}, + {"afii10808", "afii10856"}, + {"afii10809", "afii10857"}, + {"afii10810", "afii10858"}, + {"afii10811", "afii10859"}, + {"afii10817", "afii10865"}, + {"afii10818", "afii10866"}, + {"afii10819", "afii10867"}, + {"afii10822", "afii10870"}, + {"afii10827", "afii10875"}, + {"afii10914", "afii10962"}, + {"afii10920", "afii10968"}, + {"afii10924", "afii10972"}, + {"afii10927", "afii10975"}, + {"afii10929", "afii10977"}, + {"afii10930", "afii10978"}, + {"afii10931", "afii10979"}, + {"afii10932", "afii10980"}, + {"afii10934", "afii10982"}, + {"afii10943", "afii10991"}, + {"afii10944", "afii10992"}, + {"afii10951", "afii10967"}, +/*{? "ash"} */ + {"Beta", "beta1"}, + {"Bhook", "bhooktop"}, + {"Chook", "chooktop"}, +/*{"Oopen" "cturn" ?} */ + {"Dbar1", "dbar"}, + {"Dhook", "dhooktop"}, + {"Dmacron", "dmacron3"}, + {"Dslash", "dmacron"}, + {"I", "dotlessi"}, + {"J", "dotlessj"}, +/*{"Dbar", "drighttail" ?} */ +/*{"Dbar" "drthook" ?} */ +/*{"Dslash", ?} */ + {"Fhook", "fscript"}, + {"Ghook", "ghooktop"}, + {"Ibar", "ibarred"}, + {"I", "iundotted"}, + {"Kappa", "kappa1"}, + {"Khook", "khooktop"}, + {"S", "longs"}, + {"mcapturn", "mturn"}, + {"mcapturn", "mturned"}, + {"Mu", "mu1"}, + {"Nhook", "nlefthookatleft"}, + {"Nhook", "nlftlfthook"}, + {"Obar", "obarred"}, + {"Pi", "omega1"}, + {"Phi", "phi1"}, + {"Phi", "philatin"}, + {"Pi", "pi1"}, + {"Rho", "rho1"}, + {"Sigma", "sigma1"}, + {"Sigma", "sigmafinal"}, + {"Sigma", "sigmalunate"}, + {"S", "slong"}, + {"Theta", "theta1"}, + {"Thook", "thooktop"}, + {"Trthook", "trighttail"}, + {"Upsilon2", "upsilon"}, + {"Vcursive", "vscript"}, + {NULL, NULL} +}; + + +/* end */ diff --git a/contrib/ttf2pk/case.h b/contrib/ttf2pk/case.h new file mode 100644 index 0000000..ad39ef7 --- /dev/null +++ b/contrib/ttf2pk/case.h @@ -0,0 +1,27 @@ +/* + * case.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef CASE_H +#define CASE_H + +struct _Case +{ + char *upper; + char *lower; +}; +typedef struct _Case Case; + + +extern Case casetable[]; + +#endif /* CASE_H */ + + +/* end */ diff --git a/contrib/ttf2pk/configure b/contrib/ttf2pk/configure new file mode 100644 index 0000000..4f7bff9 --- /dev/null +++ b/contrib/ttf2pk/configure @@ -0,0 +1,1700 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --with-kpathsea-dir=DIR Location of the kpathsea base dir (/usr/local)" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=../../lib/freetype.h + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + +# Do some error checking and defaulting for the host and target type. +# The inputs are: +# configure --host=HOST --target=TARGET --build=BUILD NONOPT +# +# The rules are: +# 1. You are not allowed to specify --host, --target, and nonopt at the +# same time. +# 2. Host defaults to nonopt. +# 3. If nonopt is not specified, then host defaults to the current host, +# as determined by config.guess. +# 4. Target and build default to nonopt. +# 5. If nonopt is not specified, then target and build default to host. + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +case $host---$target---$nonopt in +NONE---*---* | *---NONE---* | *---*---NONE) ;; +*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; +esac + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:575: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking target system type""... $ac_c" 1>&6 +echo "configure:596: checking target system type" >&5 + +target_alias=$target +case "$target_alias" in +NONE) + case $nonopt in + NONE) target_alias=$host_alias ;; + *) target_alias=$nonopt ;; + esac ;; +esac + +target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` +target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$target" 1>&6 + +echo $ac_n "checking build system type""... $ac_c" 1>&6 +echo "configure:614: checking build system type" >&5 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&6 + +test "$host_alias" != "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:640: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:670: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:721: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:753: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 764 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:769: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:795: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:800: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:828: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:860: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:881: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:898: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:915: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + + +# Check whether --with-kpathsea-dir or --without-kpathsea-dir was given. +if test "${with_kpathsea_dir+set}" = set; then + withval="$with_kpathsea_dir" + + if test x$withval = xyes; then + echo "configure: warning: Usage is: --with-kpathsea-dir=basedir" 1>&2 + else + if test x$withval = xno; then + echo "configure: warning: Usage is: --with-kpathsea-dir=basedir" 1>&2 + else + kpathsea_dir=$withval + fi + fi + +fi + + +if test -n "$kpathsea_dir"; then + LIBS="$LIBS -L$kpathsea_dir/lib" + CPPFLAGS="$CPPFLAGS -I$kpathsea_dir/include -I$srcdir" + + echo $ac_n "checking for kpse_set_program_name in -lkpathsea""... $ac_c" 1>&6 +echo "configure:962: checking for kpse_set_program_name in -lkpathsea" >&5 +ac_lib_var=`echo kpathsea'_'kpse_set_program_name | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lkpathsea $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + +else + echo "$ac_t""no" 1>&6 +cat >> confdefs.h <<\EOF +#define OLD_KPATHSEA 1 +EOF + +fi + + + echo $ac_n "checking for kpse_init_prog in -lkpathsea""... $ac_c" 1>&6 +echo "configure:1007: checking for kpse_init_prog in -lkpathsea" >&5 +ac_lib_var=`echo kpathsea'_'kpse_init_prog | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lkpathsea $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo kpathsea | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 + + { echo "configure: error: Can't find kpathsea library! Use --with-kpathsea-dir option." 1>&2; exit 1; } +fi + + + ac_safe=`echo "kpathsea/kpathsea.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for kpathsea/kpathsea.h""... $ac_c" 1>&6 +echo "configure:1058: checking for kpathsea/kpathsea.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1068: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + +else + echo "$ac_t""no" 1>&6 +cat >> confdefs.h <<\EOF +#define VERY_OLD_KPATHSEA 1 +EOF + +fi + + + ac_safe=`echo "kpathsea/c-auto.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for kpathsea/c-auto.h""... $ac_c" 1>&6 +echo "configure:1096: checking for kpathsea/c-auto.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1106: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 + + { echo "configure: error: Can't find kpathsea include files! Use --with-kpathsea-dir option." 1>&2; exit 1; } +fi + +else + CPPFLAGS="$CPPFLAGS -I$srcdir" +fi + +echo $ac_n "checking for floor in -lm""... $ac_c" 1>&6 +echo "configure:1134: checking for floor in -lm" >&5 +ac_lib_var=`echo m'_'floor | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lm $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo m | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + +echo $ac_n "checking for gettext in -lintl""... $ac_c" 1>&6 +echo "configure:1181: checking for gettext in -lintl" >&5 +ac_lib_var=`echo intl'_'gettext | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lintl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo intl | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + + +OLDLIBS=$LIBS +LIBS="$LIBS -L../../lib/.libs" +CPPFLAGS="-I$srcdir/../../lib $CPPFLAGS" +echo $ac_n "checking for TT_Init_FreeType in -lttf""... $ac_c" 1>&6 +echo "configure:1232: checking for TT_Init_FreeType in -lttf" >&5 +ac_lib_var=`echo ttf'_'TT_Init_FreeType | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lttf $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lttf" +else + echo "$ac_t""no" 1>&6 + + { echo "configure: error: Can't find ttf library! Compile FreeType first." 1>&2; exit 1; } +fi + +LIBS=$OLDLIBS + + +if test "x$CC" = xgcc; then + XX_CFLAGS="-Wall -pedantic" +else + case "$host" in + alpha-dec-osf*) + XX_CFLAGS="-std1 -O2 -g3" + ;; + *) + XX_CFLAGS= + ;; + esac +fi + + +# Extract the first word of "rm", so it can be a program name with args. +set dummy rm; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1293: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RM'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RM"; then + ac_cv_prog_RM="$RM" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RM="rm" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +RM="$ac_cv_prog_RM" +if test -n "$RM"; then + echo "$ac_t""$RM" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Extract the first word of "rmdir", so it can be a program name with args. +set dummy rmdir; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1322: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RMDIR'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RMDIR"; then + ac_cv_prog_RMDIR="$RMDIR" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RMDIR="rmdir" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +RMDIR="$ac_cv_prog_RMDIR" +if test -n "$RMDIR"; then + echo "$ac_t""$RMDIR" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:1360: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +if test -z "$kpathsea_dir"; then + echo "configure: warning: + + The binaries will be compiled without file search library support! + For kpathsea support use the --with-kpathsea-dir option. + " 1>&2 +fi + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile MakeSub" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@target@%$target%g +s%@target_alias@%$target_alias%g +s%@target_cpu@%$target_cpu%g +s%@target_vendor@%$target_vendor%g +s%@target_os@%$target_os%g +s%@build@%$build%g +s%@build_alias@%$build_alias%g +s%@build_cpu@%$build_cpu%g +s%@build_vendor@%$build_vendor%g +s%@build_os@%$build_os%g +s%@CC@%$CC%g +s%@CPP@%$CPP%g +s%@XX_CFLAGS@%$XX_CFLAGS%g +s%@RM@%$RM%g +s%@RMDIR@%$RMDIR%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + + diff --git a/contrib/ttf2pk/configure.in b/contrib/ttf2pk/configure.in new file mode 100644 index 0000000..44ae470 --- /dev/null +++ b/contrib/ttf2pk/configure.in @@ -0,0 +1,87 @@ +dnl This file is part of the ttf2pk package + +dnl Process this file with autoconf to produce a configure script. + +dnl Some tests are omitted since we assume that you've built the +dnl FreeType library successfully. + +AC_INIT(../../lib/freetype.h) + +AC_CANONICAL_SYSTEM + +AC_PROG_CC +AC_PROG_CPP + +AC_ARG_WITH(kpathsea-dir, + [ --with-kpathsea-dir=DIR Location of the kpathsea base dir (/usr/local)],[ + if test x$withval = xyes; then + AC_MSG_WARN(Usage is: --with-kpathsea-dir=basedir) + else + if test x$withval = xno; then + AC_MSG_WARN(Usage is: --with-kpathsea-dir=basedir) + else + kpathsea_dir=$withval + fi + fi +]) + +if test -n "$kpathsea_dir"; then + LIBS="$LIBS -L$kpathsea_dir/lib" + CPPFLAGS="$CPPFLAGS -I$kpathsea_dir/include -I$srcdir" + + dnl the function kpse_set_program_name() is available since kpathsea 3.2 + AC_CHECK_LIB(kpathsea, kpse_set_program_name, [[]], AC_DEFINE(OLD_KPATHSEA)) + + AC_CHECK_LIB(kpathsea, kpse_init_prog, ,[ + AC_MSG_ERROR([Can't find kpathsea library! Use --with-kpathsea-dir option.])]) + + dnl the header file kpathsea.h doesn't exist in kpathsea 2.6 and before + AC_CHECK_HEADER(kpathsea/kpathsea.h, [[]], AC_DEFINE(VERY_OLD_KPATHSEA)) + + AC_CHECK_HEADER(kpathsea/c-auto.h, ,[ + AC_MSG_ERROR([Can't find kpathsea include files! Use --with-kpathsea-dir option.])]) +else + CPPFLAGS="$CPPFLAGS -I$srcdir" +fi + +AC_CHECK_LIB(m, floor) +AC_CHECK_LIB(intl, gettext) + +OLDLIBS=$LIBS +LIBS="$LIBS -L../../lib/.libs" +CPPFLAGS="-I$srcdir/../../lib $CPPFLAGS" +AC_CHECK_LIB(ttf, TT_Init_FreeType, LIBS="$LIBS -lttf",[ + AC_MSG_ERROR([Can't find ttf library! Compile FreeType first.])]) +LIBS=$OLDLIBS + +dnl get Compiler flags right. + +if test "x$CC" = xgcc; then + XX_CFLAGS="-Wall -pedantic" +else + case "$host" in + alpha-dec-osf*) + XX_CFLAGS="-std1 -O2 -g3" + ;; + *) + XX_CFLAGS= + ;; + esac +fi +AC_SUBST(XX_CFLAGS) + +AC_CHECK_PROG(RM, rm, rm) +AC_CHECK_PROG(RMDIR, rmdir, rmdir) +AC_PROG_INSTALL + +if test -z "$kpathsea_dir"; then + AC_MSG_WARN([ + + The binaries will be compiled without file search library support! + For kpathsea support use the --with-kpathsea-dir option. + ]) +fi + +AC_OUTPUT(Makefile MakeSub) + +dnl end of configure.in diff --git a/contrib/ttf2pk/data/Big5.sfd b/contrib/ttf2pk/data/Big5.sfd new file mode 100644 index 0000000..54a2e60 --- /dev/null +++ b/contrib/ttf2pk/data/Big5.sfd @@ -0,0 +1,65 @@ +# Big5.sfd +# +# subfont numbers for Big 5 encoding and its corresponding code ranges +# to be used with the CJK package for LaTeX. + +01 0xA140_0xA17E 0xA1A1_0xA1FE 0xA240_0xA27E 0xA2A1_0xA2C4 +02 0xA2C5_0xA2FE 0xA340_0xA37E 0xA3A1_0xA3FE 0xA440_0xA468 +03 0xA469_0xA47E 0xA4A1_0xA4FE 0xA540_0xA57E 0xA5A1_0xA5ED +04 0xA5EE_0xA5FE 0xA640_0xA67E 0xA6A1_0xA6FE 0xA740_0xA77E 0xA7A1_0xA7B3 +05 0xA7B4_0xA7FE 0xA840_0xA87E 0xA8A1_0xA8FE 0xA940_0xA957 +06 0xA958_0xA97E 0xA9A1_0xA9FE 0xAA40_0xAA7E 0xAAA1_0xAADC +07 0xAADD_0xAAFE 0xAB40_0xAB7E 0xABA1_0xABFE 0xAC40_0xAC7E 0xACA1_0xACA2 +08 0xACA3_0xACFE 0xAD40_0xAD7E 0xADA1_0xADFE 0xAE40_0xAE46 +09 0xAE47_0xAE7E 0xAEA1_0xAEFE 0xAF40_0xAF7E 0xAFA1_0xAFCB +10 0xAFCC_0xAFFE 0xB040_0xB07E 0xB0A1_0xB0FE 0xB140_0xB16F +11 0xB170_0xB17E 0xB1A1_0xB1FE 0xB240_0xB27E 0xB2A1_0xB2F4 +12 0xB2F5_0xB2FE 0xB340_0xB37E 0xB3A1_0xB3FE 0xB440_0xB47E 0xB4A1_0xB4BA +13 0xB4BB_0xB4FE 0xB540_0xB57E 0xB5A1_0xB5FE 0xB640_0xB65E +14 0xB65F_0xB67E 0xB6A1_0xB6FE 0xB740_0xB77E 0xB7A1_0xB7E3 +15 0xB7E4_0xB7FE 0xB840_0xB87E 0xB8A1_0xB8FE 0xB940_0xB97E 0xB9A1_0xB9A9 +16 0xB9AA_0xB9FE 0xBA40_0xBA7E 0xBAA1_0xBAFE 0xBB40_0xBB4D +17 0xBB4E_0xBB7E 0xBBA1_0xBBFE 0xBC40_0xBC7E 0xBCA1_0xBCD2 +18 0xBCD3_0xBCFE 0xBD40_0xBD7E 0xBDA1_0xBDFE 0xBE40_0xBE76 +19 0xBE77_0xBE7E 0xBEA1_0xBEFE 0xBF40_0xBF7E 0xBFA1_0xBFFB +20 0xBFFC_0xBFFE 0xC040_0xC07E 0xC0A1_0xC0FE 0xC140_0xC17E 0xC1A1_0xC1C1 +21 0xC1C2_0xC1FE 0xC240_0xC27E 0xC2A1_0xC2FE 0xC340_0xC365 +22 0xC366_0xC37E 0xC3A1_0xC3FE 0xC440_0xC47E 0xC4A1_0xC4EA +23 0xC4EB_0xC4FE 0xC540_0xC57E 0xC5A1_0xC5FE 0xC640_0xC67E 0xC6A1_0xC6B0 +24 0xC6B1_0xC6FE 0xC740_0xC77E 0xC7A1_0xC7FE 0xC840_0xC854 +25 0xC855_0xC87E 0xC8A1_0xC8FE 0xC940_0xC97E 0xC9A1_0xC9D9 +26 0xC9DA_0xC9FE 0xCA40_0xCA7E 0xCAA1_0xCAFE 0xCB40_0xCB7D +27 0xCB7E 0xCBA1_0xCBFE 0xCC40_0xCC7E 0xCCA1_0xCCFE 0xCD40_0xCD43 +28 0xCD44_0xCD7E 0xCDA1_0xCDFE 0xCE40_0xCE7E 0xCEA1_0xCEC8 +29 0xCEC9_0xCEFE 0xCF40_0xCF7E 0xCFA1_0xCFFE 0xD040_0xD06C +30 0xD06D_0xD07E 0xD0A1_0xD0FE 0xD140_0xD17E 0xD1A1_0xD1F1 +31 0xD1F2_0xD1FE 0xD240_0xD27E 0xD2A1_0xD2FE 0xD340_0xD37E 0xD3A1_0xD3B7 +32 0xD3B8_0xD3FE 0xD440_0xD47E 0xD4A1_0xD4FE 0xD540_0xD55B +33 0xD55C_0xD57E 0xD5A1_0xD5FE 0xD640_0xD67E 0xD6A1_0xD6E0 +34 0xD6E1_0xD6FE 0xD740_0xD77E 0xD7A1_0xD7FE 0xD840_0xD87E 0xD8A1_0xD8A6 +35 0xD8A7_0xD8FE 0xD940_0xD97E 0xD9A1_0xD9FE 0xDA40_0xDA4A +36 0xDA4B_0xDA7E 0xDAA1_0xDAFE 0xDB40_0xDB7E 0xDBA1_0xDBCF +37 0xDBD0_0xDBFE 0xDC40_0xDC7E 0xDCA1_0xDCFE 0xDD40_0xDD73 +38 0xDD74_0xDD7E 0xDDA1_0xDDFE 0xDE40_0xDE7E 0xDEA1_0xDEF8 +39 0xDEF9_0xDEFE 0xDF40_0xDF7E 0xDFA1_0xDFFE 0xE040_0xE07E 0xE0A1_0xE0BE +40 0xE0BF_0xE0FE 0xE140_0xE17E 0xE1A1_0xE1FE 0xE240_0xE262 +41 0xE263_0xE27E 0xE2A1_0xE2FE 0xE340_0xE37E 0xE3A1_0xE3E7 +42 0xE3E8_0xE3FE 0xE440_0xE47E 0xE4A1_0xE4FE 0xE540_0xE57E 0xE5A1_0xE5AD +43 0xE5AE_0xE5FE 0xE640_0xE67E 0xE6A1_0xE6FE 0xE740_0xE751 +44 0xE752_0xE77E 0xE7A1_0xE7FE 0xE840_0xE87E 0xE8A1_0xE8D6 +45 0xE8D7_0xE8FE 0xE940_0xE97E 0xE9A1_0xE9FE 0xEA40_0xEA7A +46 0xEA7B_0xEA7E 0xEAA1_0xEAFE 0xEB40_0xEB7E 0xEBA1_0xEBFE 0xEC40 +47 0xEC41_0xEC7E 0xECA1_0xECFE 0xED40_0xED7E 0xEDA1_0xEDC5 +48 0xEDC6_0xEDFE 0xEE40_0xEE7E 0xEEA1_0xEEFE 0xEF40_0xEF69 +49 0xEF6A_0xEF7E 0xEFA1_0xEFFE 0xF040_0xF07E 0xF0A1_0xF0EE +50 0xF0EF_0xF0FE 0xF140_0xF17E 0xF1A1_0xF1FE 0xF240_0xF27E 0xF2A1_0xF2B4 +51 0xF2B5_0xF2FE 0xF340_0xF37E 0xF3A1_0xF3FE 0xF440_0xF458 +52 0xF459_0xF47E 0xF4A1_0xF4FE 0xF540_0xF57E 0xF5A1_0xF5DD +53 0xF5DE_0xF5FE 0xF640_0xF67E 0xF6A1_0xF6FE 0xF740_0xF77E 0xF7A1_0xF7A3 +54 0xF7A4_0xF7FE 0xF840_0xF87E 0xF8A1_0xF8FE 0xF940_0xF947 +55 0xF948_0xF97E 0xF9A1_0xF9FE 0xFA40_0xFA7E 0xFAA1_0xFACC +56 0xFACD_0xFAFE 0xFB40_0xFB7E 0xFBA1_0xFBFE 0xFC40_0xFC70 +57 0xFC71_0xFC7E 0xFCA1_0xFCFE 0xFD40_0xFD7E 0xFDA1_0xFDF5 +58 0xFDF6_0xFDFE 0xFE40_0xFE7E 0xFEA1_0xFEFE + +# eof diff --git a/contrib/ttf2pk/data/ET5.enc b/contrib/ttf2pk/data/ET5.enc new file mode 100644 index 0000000..dc47f88 --- /dev/null +++ b/contrib/ttf2pk/data/ET5.enc @@ -0,0 +1,119 @@ +% ET5.enc +% +% +% This is LaTeX ET5 encoding for Vietnamese. +% +% +% LIGKERN question quoteleft =: questiondown ; +% LIGKERN exclam quoteleft =: exclamdown ; +% LIGKERN hyphen hyphen =: endash ; +% LIGKERN endash hyphen =: emdash ; +% LIGKERN quoteleft quoteleft =: quotedblleft ; +% LIGKERN quoteright quoteright =: quotedblright ; +% LIGKERN comma comma =: quotedblbase ; +% +% LIGKERN f i =: fi ; +% LIGKERN f l =: fl ; +% LIGKERN f f =: ff ; +% LIGKERN ff i =: ffi ; +% LIGKERN ff l =: ffl ; +% +% We blow away kerns to and from spaces (TeX doesn't have a +% space) and also remove any kerns from the numbers. +% +% LIGKERN space {} * ; * {} space ; +% LIGKERN zero {} * ; * {} zero ; +% LIGKERN one {} * ; * {} one ; +% LIGKERN two {} * ; * {} two ; +% LIGKERN three {} * ; * {} three ; +% LIGKERN four {} * ; * {} four ; +% LIGKERN five {} * ; * {} five ; +% LIGKERN six {} * ; * {} six ; +% LIGKERN seven {} * ; * {} seven ; +% LIGKERN eight {} * ; * {} eight ; +% LIGKERN nine {} * ; * {} nine ; + +/ET5encoding [ +% 0x00 + /Abrevehookabove /Abrevetilde /Acircumflextilde /Yhookabove + /Ytilde /Ydotbelow /Sigma /Upsilon + /Phi /Psi /Omega /ff + /fi /fl /ffi /ffl +% 0x10 + /dotlessi /dotlessj /grave /acute + /caron /breve /macron /ring + /cedilla /germandbls /ae /oe + /oslash /AE /OE /Oslash +% 0x20 + /.notdef /exclam /quotedblright /numbersign + /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus + /comma /hyphen /period /slash +% 0x30 + /zero /one /two /three + /four /five /six /seven + /eight /nine /colon /semicolon + /exclamdown /equal /questiondown /question +% 0x40 + /at /A /B /C + /D /E /F /G + /H /I /J /K + /L /M /N /O +% 0x50 + /P /Q /R /S + /T /U /V /W + /X /Y /Z /bracketleft + /quotedblleft /bracketright /circumflex /dotaccent +% 0x60 + /quoteleft /a /b /c + /d /e /f /g + /h /i /j /k + /l /m /n /o +% 0x70 + /p /q /r /s + /t /u /v /w + /x /y /z /endash + /emdash /hungarumlaut /tilde /dieresis +% 0x80 + /Adotbelow /Abreveacute /Abrevegrave /Abrevedotbelow + /Acircumflexacute /Acircumflexgrave /Acircumflexhookabove /Acircumflexdotbelow + /Etilde /Edotbelow /Ecircumflexacute /Ecircumflexgrave + /Ecircumflexhookabove /Ecircumflextilde /Ecircumflexdotbelow /Ocircumflexacute +% 0x90 + /Ocircumflexgrave /Ocircumflexhookabove /Ocircumflextilde /Ocircumflexdotbelow + /Ohorndotbelow /Ohornacute /Ohorngrave /Ohornhookabove + /Idotbelow /Ohookabove /Odotbelow /Ihookabove + /Uhookabove /Utilde /Udotbelow /Ygrave +% 0xA0 + /Otilde /abreveacute /abrevegrave /abrevedotbelow + /acircumflexacute /acircumflexgrave /acircumflexhookabove /acircumflexdotbelow + /etilde /edotbelow /ecircumflexacute /ecircumflexgrave + /ecircumflexhookabove /ecircumflextilde /ecircumflexdotbelow /ocircumflexacute +% 0xB0 + /ocircumflexgrave /ocircumflexhookabove /ocircumflextilde /Ohorntilde + /Ohorn /ocircumflexdotbelow /ohorngrave /ohornhookabove + /idotbelow /Uhorndotbelow /Uhornacute /Uhorngrave + /Uhornhookabove /ohorn /ohornacute /Uhorn +% 0xC0 + /Agrave /Aacute /Acircumflex /Atilde + /Ahookabove /Abreve /abrevehookabove /abrevetilde + /Egrave /Eacute /Ecircumflex /Ehookabove + /Igrave /Iacute /Itilde /ygrave +% 0xD0 + /Dbar /uhornacute /Ograve /Oacute + /Ocircumflex /adotbelow /yhookabove /uhorngrave + /uhornhookabove /Ugrave /Uacute /ytilde + /ydotbelow /Yacute /ohorntilde /uhorn +% 0xE0 + /agrave /aacute /acircumflex /atilde + /ahookabove /abreve /uhorntilde /acircumflextilde + /egrave /eacute /ecircumflex /ehookabove + /igrave /iacute /itilde /ihookabove +% 0xF0 + /dbar /uhorndotbelow /ograve /oacute + /ocircumflex /otilde /ohookabove /odotbelow + /udotbelow /ugrave /uacute /utilde + /uhookabove /yacute /ohorndotbelow /Uhorntilde +] def + +% eof diff --git a/contrib/ttf2pk/data/EUC.sfd b/contrib/ttf2pk/data/EUC.sfd new file mode 100644 index 0000000..5a148da --- /dev/null +++ b/contrib/ttf2pk/data/EUC.sfd @@ -0,0 +1,49 @@ +# EUC.sfd +# +# subfont numbers for character sets in EUC encoding and its corresponding +# code ranges to be used with the CJK package for LaTeX. +# +# Examples for such character sets: +# +# GB 2312-1980, +# KS X 1001:1992 (=KS C 5601-1992), +# JIS X 0208:1997, +# CNS 11643-1992 planes 1-7. + +01 0xA1A1_0xA1FE 0xA2A1_0xA2FE 0xA3A1_0xA3E4 +02 0xA3E5_0xA3FE 0xA4A1_0xA4FE 0xA5A1_0xA5FE 0xA6A1_0xA6CA +03 0xA6CB_0xA6FE 0xA7A1_0xA7FE 0xA8A1_0xA8FE 0xA9A1_0xA9B0 +04 0xA9B1_0xA9FE 0xAAA1_0xAAFE 0xABA1_0xABF4 +05 0xABF5_0xABFE 0xACA1_0xACFE 0xADA1_0xADFE 0xAEA1_0xAEDA +06 0xAEDB_0xAEFE 0xAFA1_0xAFFE 0xB0A1_0xB0FE 0xB1A1_0xB1C0 +07 0xB1C1_0xB1FE 0xB2A1_0xB2FE 0xB3A1_0xB3FE 0xB4A1_0xB4A6 +08 0xB4A7_0xB4FE 0xB5A1_0xB5FE 0xB6A1_0xB6EA +09 0xB6EB_0xB6FE 0xB7A1_0xB7FE 0xB8A1_0xB8FE 0xB9A1_0xB9D0 +10 0xB9D1_0xB9FE 0xBAA1_0xBAFE 0xBBA1_0xBBFE 0xBCA1_0xBCB6 +11 0xBCB7_0xBCFE 0xBDA1_0xBDFE 0xBEA1_0xBEFA +12 0xBEFB_0xBEFE 0xBFA1_0xBFFE 0xC0A1_0xC0FE 0xC1A1_0xC1E0 +13 0xC1E1_0xC1FE 0xC2A1_0xC2FE 0xC3A1_0xC3FE 0xC4A1_0xC4C6 +14 0xC4C7_0xC4FE 0xC5A1_0xC5FE 0xC6A1_0xC6FE 0xC7A1_0xC7AC +15 0xC7AD_0xC7FE 0xC8A1_0xC8FE 0xC9A1_0xC9F0 +16 0xC9F1_0xC9FE 0xCAA1_0xCAFE 0xCBA1_0xCBFE 0xCCA1_0xCCD6 +17 0xCCD7_0xCCFE 0xCDA1_0xCDFE 0xCEA1_0xCEFE 0xCFA1_0xCFBC +18 0xCFBD_0xCFFE 0xD0A1_0xD0FE 0xD1A1_0xD1FE 0xD2A1_0xD2A2 +19 0xD2A3_0xD2FE 0xD3A1_0xD3FE 0xD4A1_0xD4E6 +20 0xD4E7_0xD4FE 0xD5A1_0xD5FE 0xD6A1_0xD6FE 0xD7A1_0xD7CC +21 0xD7CD_0xD7FE 0xD8A1_0xD8FE 0xD9A1_0xD9FE 0xDAA1_0xDAB2 +22 0xDAB3_0xDAFE 0xDBA1_0xDBFE 0xDCA1_0xDCF6 +23 0xDCF7_0xDCFE 0xDDA1_0xDDFE 0xDEA1_0xDEFE 0xDFA1_0xDFDC +24 0xDFDD_0xDFFE 0xE0A1_0xE0FE 0xE1A1_0xE1FE 0xE2A1_0xE2C2 +25 0xE2C3_0xE2FE 0xE3A1_0xE3FE 0xE4A1_0xE4FE 0xE5A1_0xE5A8 +26 0xE5A9_0xE5FE 0xE6A1_0xE6FE 0xE7A1_0xE7EC +27 0xE7ED_0xE7FE 0xE8A1_0xE8FE 0xE9A1_0xE9FE 0xEAA1_0xEAD2 +28 0xEAD3_0xEAFE 0xEBA1_0xEBFE 0xECA1_0xECFE 0xEDA1_0xEDB8 +29 0xEDB9_0xEDFE 0xEEA1_0xEEFE 0xEFA1_0xEFFC +30 0xEFFD_0xEFFE 0xF0A1_0xF0FE 0xF1A1_0xF1FE 0xF2A1_0xF2E2 +31 0xF2E3_0xF2FE 0xF3A1_0xF3FE 0xF4A1_0xF4FE 0xF5A1_0xF5C8 +32 0xF5C9_0xF5FE 0xF6A1_0xF6FE 0xF7A1_0xF7FE 0xF8A1_0xF8AE +33 0xF8AF_0xF8FE 0xF9A1_0xF9FE 0xFAA1_0xFAF2 +34 0xFAF3_0xFAFE 0xFBA1_0xFBFE 0xFCA1_0xFCFE 0xFDA1_0xFDD8 +35 0xFDD9_0xFDFE 0xFEA1_0xFEFE + +# eof diff --git a/contrib/ttf2pk/data/SJIS.sfd b/contrib/ttf2pk/data/SJIS.sfd new file mode 100644 index 0000000..cf7387b --- /dev/null +++ b/contrib/ttf2pk/data/SJIS.sfd @@ -0,0 +1,52 @@ +# SJIS.sfd +# +# subfont numbers for SJIS encoding and its corresponding code ranges +# to be used with the CJK package for LaTeX. + +01 0x8140_0x817E 0x8180_0x81FC 0x8240_0x827E 0x8280_0x8284 +02 0x8285_0x82FC 0x8340_0x837E 0x8380_0x83C8 +03 0x83C9_0x83FC 0x8440_0x847E 0x8480_0x84FC 0x8540_0x854F +04 0x8550_0x857E 0x8580_0x85FC 0x8640_0x867E 0x8680_0x8694 +05 0x8695_0x86FC 0x8740_0x877E 0x8780_0x87D8 +06 0x87D9_0x87FC 0x8840_0x887E 0x8880_0x88FC 0x8940_0x895F +07 0x8960_0x897E 0x8980_0x89FC 0x8A40_0x8A7E 0x8A80_0x8AA4 +08 0x8AA5_0x8AFC 0x8B40_0x8B7E 0x8B80_0x8BE8 +09 0x8BE9_0x8BFC 0x8C40_0x8C7E 0x8C80_0x8CFC 0x8D40_0x8D6F +10 0x8D70_0x8D7E 0x8D80_0x8DFC 0x8E40_0x8E7E 0x8E80_0x8EB4 +11 0x8EB5_0x8EFC 0x8F40_0x8F7E 0x8F80_0x8FF8 +12 0x8FF9_0x8FFC 0x9040_0x907E 0x9080_0x90FC 0x9140_0x917E 0x9180 +13 0x9181_0x91FC 0x9240_0x927E 0x9280_0x92C4 +14 0x92C5_0x92FC 0x9340_0x937E 0x9380_0x93FC 0x9440_0x944B +15 0x944C_0x947E 0x9480_0x94FC 0x9540_0x957E 0x9580_0x9590 +16 0x9591_0x95FC 0x9640_0x967E 0x9680_0x96D4 +17 0x96D5_0x96FC 0x9740_0x977E 0x9780_0x97FC 0x9840_0x985B +18 0x985C_0x987E 0x9880_0x98FC 0x9940_0x997E 0x9980_0x99A0 +19 0x99A1_0x99FC 0x9A40_0x9A7E 0x9A80_0x9AE4 +20 0x9AE5_0x9AFC 0x9B40_0x9B7E 0x9B80_0x9BFC 0x9C40_0x9C6B +21 0x9C6C_0x9C7E 0x9C80_0x9CFC 0x9D40_0x9D7E 0x9D80_0x9DB0 +22 0x9DB1_0x9DFC 0x9E40_0x9E7E 0x9E80_0x9EF4 +23 0x9EF5_0x9EFC 0x9F40_0x9F7E 0x9F80_0x9FFC 0xE040_0xE07B +24 0xE07C_0xE07E 0xE080_0xE0FC 0xE140_0xE17E 0xE180_0xE1C0 +25 0xE1C1_0xE1FC 0xE240_0xE27E 0xE280_0xE2FC 0xE340_0xE347 +26 0xE348_0xE37E 0xE380_0xE3FC 0xE440_0xE47E 0xE480_0xE48C +27 0xE48D_0xE4FC 0xE540_0xE57E 0xE580_0xE5D0 +28 0xE5D1_0xE5FC 0xE640_0xE67E 0xE680_0xE6FC 0xE740_0xE757 +29 0xE758_0xE77E 0xE780_0xE7FC 0xE840_0xE87E 0xE880_0xE89C +30 0xE89D_0xE8FC 0xE940_0xE97E 0xE980_0xE9E0 +31 0xE9E1_0xE9FC 0xEA40_0xEA7E 0xEA80_0xEAFC 0xEB40_0xEB67 +32 0xEB68_0xEB7E 0xEB80_0xEBFC 0xEC40_0xEC7E 0xEC80_0xECAC +33 0xECAD_0xECFC 0xED40_0xED7E 0xED80_0xEDF0 +34 0xEDF1_0xEDFC 0xEE40_0xEE7E 0xEE80_0xEEFC 0xEF40_0xEF77 +35 0xEF78_0xEF7E 0xEF80_0xEFFC 0xF040_0xF07E 0xF080_0xF0BC +36 0xF0BD_0xF0FC 0xF140_0xF17E 0xF180_0xF1FC 0xF240_0xF243 +37 0xF244_0xF27E 0xF280_0xF2FC 0xF340_0xF37E 0xF380_0xF388 +38 0xF389_0xF3FC 0xF440_0xF47E 0xF480_0xF4CC +39 0xF4CD_0xF4FC 0xF540_0xF57E 0xF580_0xF5FC 0xF640_0xF653 +40 0xF654_0xF67E 0xF680_0xF6FC 0xF740_0xF77E 0xF780_0xF798 +41 0xF799_0xF7FC 0xF840_0xF87E 0xF880_0xF8DC +42 0xF8DD_0xF8FC 0xF940_0xF97E 0xF980_0xF9FC 0xFA40_0xFA63 +43 0xFA64_0xFA7E 0xFA80_0xFAFC 0xFB40_0xFB7E 0xFB80_0xFBA8 +44 0xFBA9_0xFBFC 0xFC40_0xFC7E 0xFC80_0xFCEC +45 0xFCED_0xFCFC + +# eof diff --git a/contrib/ttf2pk/data/T1-WGL4.enc b/contrib/ttf2pk/data/T1-WGL4.enc new file mode 100644 index 0000000..064c723 --- /dev/null +++ b/contrib/ttf2pk/data/T1-WGL4.enc @@ -0,0 +1,128 @@ +% T1-WGL4.enc +% +% +% This is LaTeX T1 encoding for WGL4 encoded TrueType fonts +% (e.g. from Windows 95) +% +% +% Note that /hyphen appears twice (for the T1 code points `hyphen' 0x2d +% and `hyphenchar' 0x7f). +% +% +% LIGKERN space l =: lslash ; +% LIGKERN space L =: Lslash ; +% LIGKERN question quoteleft =: questiondown ; +% LIGKERN exclam quoteleft =: exclamdown ; +% LIGKERN hyphen hyphen =: endash ; +% LIGKERN endash hyphen =: emdash ; +% LIGKERN quoteleft quoteleft =: quotedblleft ; +% LIGKERN quoteright quoteright =: quotedblright ; +% LIGKERN comma comma =: quotedblbase ; +% LIGKERN less less =: guillemotleft ; +% LIGKERN greater greater =: guillemotright ; +% +% LIGKERN f i =: fi ; +% LIGKERN f l =: fl ; +% LIGKERN f f =: ff ; +% LIGKERN ff i =: ffi ; +% LIGKERN ff l =: ffl ; +% +% We blow away kerns to and from spaces (TeX doesn't have a +% space) and also remove any kerns from the numbers. +% +% LIGKERN space {} * ; * {} space ; +% LIGKERN zero {} * ; * {} zero ; +% LIGKERN one {} * ; * {} one ; +% LIGKERN two {} * ; * {} two ; +% LIGKERN three {} * ; * {} three ; +% LIGKERN four {} * ; * {} four ; +% LIGKERN five {} * ; * {} five ; +% LIGKERN six {} * ; * {} six ; +% LIGKERN seven {} * ; * {} seven ; +% LIGKERN eight {} * ; * {} eight ; +% LIGKERN nine {} * ; * {} nine ; + +/T1Encoding [ % now 256 chars follow +% 0x00 + /grave /acute /circumflex /tilde + /dieresis /hungarumlaut /ring /caron + /breve /macron /dotaccent /cedilla + /ogonek /quotesinglbase /guilsinglleft /guilsinglright +% 0x10 + /quotedblleft /quotedblright /quotedblbase /guillemotleft + /guillemotright /endash /emdash /compwordmark + /perthousandzero /dotlessi /dotlessj /ff + /fi /fl /ffi /ffl +% 0x20 + /visualspace /exclam /quotedbl /numbersign + /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus + /comma /hyphen /period /slash +% 0x30 + /zero /one /two /three + /four /five /six /seven + /eight /nine /colon /semicolon + /less /equal /greater /question +% 0x40 + /at /A /B /C + /D /E /F /G + /H /I /J /K + /L /M /N /O +% 0x50 + /P /Q /R /S + /T /U /V /W + /X /Y /Z /bracketleft + /backslash /bracketright /asciicircum /underscore +% 0x60 + /quoteleft /a /b /c + /d /e /f /g + /h /i /j /k + /l /m /n /o +% 0x70 + /p /q /r /s + /t /u /v /w + /x /y /z /braceleft + /bar /braceright /asciitilde /hyphen +% 0x80 + /Abreve /Aogonek /Cacute /Ccaron + /Dcaron /Ecaron /Eogonek /Gbreve + /Lacute /Lcaron /Lslash /Nacute + /Ncaron /Eng /Odblacute /Racute +% 0x90 + /Rcaron /Sacute /Scaron /Scedilla + /Tcaron /Tcedilla /Udblacute /Uring + /Ydieresis /Zacute /Zcaron /Zdot + /IJ /Idot /dmacron /section +% 0xA0 + /abreve /aogonek /cacute /ccaron + /dcaron /ecaron /eogonek /gbreve + /lacute /lcaron /lslash /nacute + /ncaron /eng /odblacute /racute +% 0xB0 + /rcaron /sacute /scaron /scedilla + /tcaron /tcedilla /udblacute /uring + /ydieresis /zacute /zcaron /zdot + /ij /exclamdown /questiondown /sterling +% 0xC0 + /Agrave /Aacute /Acircumflex /Atilde + /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis + /Igrave /Iacute /Icircumflex /Idieresis +% 0xD0 + /Eth /Ntilde /Ograve /Oacute + /Ocircumflex /Otilde /Odieresis /OE + /Oslash /Ugrave /Uacute /Ucircumflex + /Udieresis /Yacute /Thorn /Germandbls +% 0xE0 + /agrave /aacute /acircumflex /atilde + /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis + /igrave /iacute /icircumflex /idieresis +% 0xF0 + /eth /ntilde /ograve /oacute + /ocircumflex /otilde /odieresis /oe + /oslash /ugrave /uacute /ucircumflex + /udieresis /yacute /thorn /germandbls +] def + +% eof diff --git a/contrib/ttf2pk/data/UBg5plus.sfd b/contrib/ttf2pk/data/UBg5plus.sfd new file mode 100644 index 0000000..a8f1972 --- /dev/null +++ b/contrib/ttf2pk/data/UBg5plus.sfd @@ -0,0 +1,3002 @@ +# UBg5plus.sfd +# +# subfont numbers for Big 5+ encoding and its corresponding code ranges +# to be used with the CJK package for LaTeX. +# +# The input encoding is Unicode. + +01 0x8488 0x8710 0x871F 0x870F 0x88D3 0x8C87 0x8CC6 0x90CC \ + 0x916D 0x9258 0x9242 0x9268 0x9269 0x9243 0x9247 0x959D \ + 0x96CF 0x97F4 0x9809 0x98AB 0x98FB 0x9AAC 0x9AAE 0x9AAA \ + 0x9B5C 0x50DF 0x5619 0x560A 0x589A 0x5D85 0x5E56 0x5E51 \ + 0x5FB1 0x645A 0x6463 0x669B 0x66A3 0x669E 0x69B8 0x69BA \ + 0x69C7 0x69D7 0x6B70 0x6B9D 0x6F16 0x6F24 0x6F45 0x7179 \ + 0x717A 0x7254 0x757C 0x757B 0x7612 0x76B6 0x76E0 0x7773 \ + 0x7772 0x7770 0x789D 0x7A27 0x7A35 0x7BA2 0x7B89 0x4E28 \ + 0x4E05 0x4E04 0x4E2A 0x4E87 0x4E49 0x51E2 0x4E46 0x4E8F \ + 0x4EBC 0x4EBE 0x5166 0x51E3 0x5204 0x529C 0x5344 0x5F51 \ + 0x961D 0x4E63 0x4E62 0x4EA3 0x5185 0x4EC5 0x4ECF 0x4ECE \ + 0x4ECC 0x5184 0x5186 0x51E4 0x5205 0x529E 0x529D 0x52FD \ + 0x7BA5 0x7CB6 0x7DA5 0x7DC3 0x7FAB 0x8025 0x8059 0x8185 \ + 0x818E 0x84BE 0x84A6 0x872F 0x89A0 0x8A97 0x8C8B 0x8F0F \ + 0x9275 0x929F 0x95A6 0x969A 0x9757 0x97F7 0x98B0 0x99C6 \ + 0x50FA 0x5285 0x5643 0x563C 0x5BED 0x5C35 0x5F47 0x616D \ + 0x69F5 0x6A03 0x6A65 0x6B75 0x6F56 0x6F98 0x6F68 0x7234 \ + 0x7245 0x735C 0x7356 0x78BF 0x78BD 0x78E4 0x7A34 0x7A36 \ + 0x7BBA 0x7BBC 0x7BC8 0x7BC3 0x7BB6 0x7BC2 0x7BC5 0x7BBD \ + 0x7BB0 0x7BBB 0x7E04 0x81F1 0x8522 0x8538 0x8532 0x8510 \ + 0x854F 0x877C 0x890D 0x8908 0x8D9E 0x8F28 0x8F21 0x9066 \ + 0x906C 0x90F6 0x92EC 0x92BA 0x92E3 0x92BD 0x95B4 0x97D1 \ + 0x9823 0x990B 0x9AB2 0x9ADB 0x9B73 0x9B6E 0x9B65 0x9B6A \ + 0x9B6D 0x9D0B 0x9E76 0x9F11 0x5119 0x5675 0x596F 0x61A5 \ + 0x61A0 0x65B4 0x65D8 0x66C2 0x6BA8 0x6F83 0x6FC5 0x71CD \ + 0x729C 0x7499 0x7639 0x762E 0x769F 0x76A0 0x7794 0x77AE \ + 0x78E6 0x7ABC 0x7BD6 0x7CCF 0x7E18 0x806D 0x8190 0x8552 \ + 0x8550 0x87A0 0x8786 0x8795 0x8860 0x8928 0x8920 0x89A8 \ + 0x8E3A 0x9194 0x9311 0x9337 0x9343 0x96A6 0x9795 0x9796 \ + 0x9825 0x9926 0x9934 0x9B8A 0x9B7F 0x9D11 0x9ED9 0x9F3C \ + 0x5123 0x512C 0x5295 0x5688 0x568B 0x61E1 0x61D7 0x65A3 \ + 0x66D3 0x6A8B 0x6BAC 0x7374 0x7640 0x5300 0x533A 0x5346 +02 0x535D 0x5386 0x53B7 0x53CC 0x53CE 0x5721 0x5E00 0x5F0C \ + 0x6237 0x6238 0x6535 0x738D 0x4E97 0x4EE0 0x4EE7 0x4EE6 \ + 0x56D8 0x518B 0x518C 0x5199 0x51E5 0x520B 0x5304 0x5303 \ + 0x5307 0x531E 0x535F 0x536D 0x5389 0x53BA 0x7641 0x76E8 \ + 0x78F6 0x7900 0x7A59 0x7A55 0x7AF4 0x7C04 0x7C15 0x7BF5 \ + 0x81C1 0x857D 0x85A5 0x893A 0x8E51 0x9198 0x9381 0x936F \ + 0x9842 0x9937 0x9BA9 0x9BA7 0x9BAC 0x9B9C 0x9D3C 0x9D1C \ + 0x9D3A 0x9D32 0x9D34 0x9F3F 0x5EEB 0x61D5 0x6502 0x7012 \ + 0x7585 0x7654 0x7655 0x76A7 0x76A8 0x790F 0x7CE4 0x7CE5 \ + 0x7E65 0x7E4E 0x7F82 0x802D 0x85CA 0x85BC 0x8CFF 0x91A6 \ + 0x93B6 0x93AB 0x97A7 0x983E 0x9BBC 0x9BB7 0x9BBE 0x9D62 \ + 0x9E8F 0x9ECB 0x56A9 0x5913 0x5BF4 0x61EC 0x61EF 0x6AD6 \ + 0x7209 0x7379 0x74C6 0x77C3 0x791F 0x7A65 0x7AC6 0x7C3A \ + 0x7CEB 0x7F84 0x85E0 0x85F3 0x881E 0x89B4 0x89F9 0x8B44 \ + 0x8E71 0x8E6E 0x8E79 0x8EC4 0x908C 0x93C9 0x97B0 0x985A \ + 0x9946 0x9AC3 0x9B0F 0x9BF4 0x9BFA 0x9BDD 0x9BED 0x9BEF \ + 0x9E96 0x9EB3 0x9EE2 0x9F8F 0x56B1 0x5B41 0x6AF6 0x6AF2 \ + 0x7588 0x8267 0x860E 0x8D0E 0x91B6 0x942F 0x97E0 0x97DB \ + 0x9861 0x9A33 0x9C0F 0x9C11 0x9C03 0x9C01 0x9C16 0x9D93 \ + 0x535B 0x56BF 0x5DCE 0x76AC 0x77D2 0x7C52 0x8B76 0x8EC7 \ + 0x9434 0x943E 0x97BC 0x9B39 0x9C2A 0x9C26 0x9C27 0x9DC0 \ + 0x9DC9 0x9EEC 0x9F68 0x8032 0x8031 0x89FD 0x908E 0x97C2 \ + 0x9A4B 0x9B1C 0x9B1B 0x9C42 0x56D0 0x56CF 0x5DDA 0x66EA \ + 0x8B89 0x9458 0x9DE7 0x53D0 0x53F6 0x53F7 0x53F9 0x53F4 \ + 0x5724 0x5904 0x5918 0x5932 0x5930 0x5934 0x5975 0x5B82 \ + 0x5BF9 0x5C14 0x5E81 0x5E83 0x5F0D 0x5F52 0x5FCA 0x5FC7 \ + 0x6239 0x624F 0x65E7 0x672F 0x6B7A 0x6C39 0x6C37 0x6C44 \ + 0x6C45 0x738C 0x9093 0x9092 0x9DEA 0x9DF1 0x9F44 0x9F6D \ + 0x5DD9 0x883A 0x8975 0x9A5D 0x9C64 0x9E0A 0x9F73 0x77E1 \ + 0x9B2D 0x9E0C 0x9F1F 0x7C70 0x9479 0x974A 0x7E9D 0x9960 \ + 0x9F9E 0x9EF8 0x9F3A 0x9F7D 0x9F96 0x6729 0x5E07 0x5FCB \ + 0x52B7 0x52B8 0x52B6 0x52BA 0x6306 0x6B85 0x8C38 0x7309 +03 0x8A2F 0x52DC 0x5921 0x5E3F 0x7B3F 0x83D0 0x86E7 0x6117 \ + 0x8714 0x88D1 0x8CCB 0x8EED 0x52EC 0x52E8 0x7527 0x798C \ + 0x7991 0x8660 0x9904 0x999B 0x729F 0x8770 0x8E37 0x9703 \ + 0x52F6 0x64CC 0x764A 0x7AB9 0x7BD7 0x999F 0x9B8D 0x9E77 \ + 0x764B 0x76A2 0x87F1 0x9BBA 0x8804 0x9BD8 0x9D7C 0x7C46 \ + 0x9D8D 0x957E 0x9C20 0x9C22 0x9C1E 0x8970 0x9C43 0x9DE0 \ + 0x9459 0x9C72 0x6530 0x72DD 0x6804 0x82FF 0x8FEC 0x53DE \ + 0x5A30 0x5BB2 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0x4E21 0x4E20 0x4E22 0x4E68 0x4E89 0x4E98 0x4EF9 \ + 0x4EEF 0x4EF8 0x4F06 0x4F03 0x4EFC 0x4EEE 0x4F16 0x4F28 \ + 0x4F1C 0x4F07 0x4F1A 0x4EFA 0x4F17 0x514A 0x5172 0x51B4 \ + 0x51B3 0x51B2 0x51E8 0x5214 0x520F 0x5215 0x5218 0x52A8 \ + 0x534B 0x534F 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +04 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x5350 \ + 0x538B 0x53BE 0x53D2 0x5416 0x53FF 0x5400 0x5405 0x5413 \ + 0x5415 0x56E3 0x5735 0x5736 0x5731 0x5732 0x58EE 0x5905 \ + 0x4E54 0x5936 0x597A 0x5986 0x5B86 0x5F53 0x5C18 0x5C3D \ + 0x5C78 0x5C80 0x5E08 0x5EF5 0x5F0E 0x5FD3 0x5FDA 0x5FDB \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x620F 0x625D 0x625F \ + 0x6267 0x6257 0x9F50 0x65EB 0x65EA 0x6737 0x6732 0x6736 +05 0x6B22 0x6BCE 0x6C58 0x6C51 0x6C77 0x6C3C 0x6C5A 0x6C53 \ + 0x706F 0x7072 0x706E 0x7073 0x72B1 0x72B2 0x738F 0x793C \ + 0x808D 0x808E 0x827B 0x8D71 0x8FB9 0x9096 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0x909A 0x4E24 0x4E71 0x4E9C 0x4F45 \ + 0x4F4A 0x4F39 0x4F37 0x4F32 0x4F42 0x4F44 0x4F4B 0x4F40 \ + 0x4F35 0x4F31 0x5151 0x5150 0x514E 0x519D 0x51B5 0x51B8 \ + 0x51EC 0x5223 0x5227 0x5226 0x521F 0x522B 0x5220 0x52B4 \ + 0x52B3 0x5325 0x533B 0x5374 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +06 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0x544D 0x543A 0x5444 0x544C 0x5423 0x541A 0x5432 \ + 0x544B 0x5421 0x5434 0x5449 0x5450 0x5422 0x543F 0x5451 \ + 0x545A 0x542F 0x56E9 0x56F2 0x56F3 0x56EF 0x56ED 0x56EC \ + 0x56E6 0x5748 0x5744 0x573F 0x573C 0x5753 0x5756 0x575F \ + 0x5743 0x5758 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +07 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x5757 \ + 0x5746 0x573D 0x5742 0x5754 0x5755 0x58F1 0x58F2 0x58F0 \ + 0x590B 0x9EA6 0x56F1 0x593D 0x5994 0x598C 0x599C 0x599F \ + 0x599B 0x5989 0x599A 0x6588 0x5B8D 0x5BFE 0x5BFF 0x5BFD \ + 0x5C2B 0x5C84 0x5C8E 0x5C9C 0x5C85 0x5DF5 0x5E09 0x5E0B \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x5E92 0x5E90 0x5F03 \ + 0x5F1E 0x5F63 0x5FE7 0x5FFE 0x5FE6 0x5FDC 0x5FCE 0x5FFC \ + 0x5FDF 0x5FEC 0x5FF6 0x5FF2 0x5FF0 0x5FF9 0x6213 0x623B +08 0x623C 0x6282 0x6278 0x628B 0x629E 0x62A5 0x629B 0x629C \ + 0x6299 0x628D 0x6285 0x629D 0x6275 0x65F6 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0x66F5 0x675B 0x6754 0x6752 0x6758 \ + 0x6744 0x674A 0x6761 0x6C7F 0x6C91 0x6C9E 0x6C6E 0x6C7C \ + 0x6C9F 0x6C75 0x6C56 0x6CA2 0x6C79 0x6CA1 0x6CAA 0x6CA0 \ + 0x7079 0x7077 0x707E 0x7075 0x707B 0x7264 0x72BB 0x72BC \ + 0x72C7 0x72B9 0x72BE 0x72B6 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +09 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0x7398 0x7593 0x7680 0x7683 0x76C0 0x76C1 0x77F4 \ + 0x77F5 0x7ACC 0x7ACD 0x7CFA 0x809F 0x8091 0x8097 0x8094 \ + 0x8286 0x828C 0x8295 0x866C 0x8FBE 0x8FC7 0x8FC1 0x90A9 \ + 0x90A4 0x90A8 0x9627 0x9626 0x962B 0x9633 0x9634 0x9629 \ + 0x4E3D 0x4E9D 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +10 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x4F93 \ + 0x4F8A 0x4F6D 0x4F8E 0x4FA0 0x4FA2 0x4FA1 0x4F9F 0x4FA3 \ + 0x4F72 0x4F8C 0x5156 0x5190 0x51ED 0x51FE 0x522F 0x523C \ + 0x5234 0x5239 0x52B9 0x52B5 0x52BF 0x5355 0x5376 0x537A \ + 0x5393 0x53C1 0x53C2 0x53D5 0x5485 0x545F 0x5493 0x5489 \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x8038 0x8081 \ + 0x8158 0x8A24 0x8DC3 0x51F2 0x55B6 0x5EC3 0x7861 0x7A01 \ + 0x8849 0x8999 0x921F 0x5313 0x55E0 0x6139 0x6ED7 0x733D \ + 0x9775 0x7FE4 0x8088 0x5655 0x617F 0x71D7 0x8666 0x8F3A \ + 0x933D 0x64F5 0x7F80 0x8D01 0x58E1 0x7CE9 0x81CB 0x95D9 \ + 0x6707 0x9A47 0x7674 0x5301 0x53FA 0x9F99 0x6C49 0x8FB7 \ + 0x4F29 0x534E 0x5C81 0x5F10 0x6268 0x6742 0x6740 0x51EA \ + 0x6C62 0x7391 0x8FBB 0x8FBC 0x56E8 0x575B 0x5C97 0x6762 \ + 0x62A4 0x6766 0x6CA3 0x707F 0x77F6 0x5479 0x9EFE 0x548F \ + 0x5469 0x546D 0x5494 0x546A 0x548A 0x56FD 0x56FB 0x56F8 \ + 0x56FC 0x56F6 0x5765 0x5781 0x5763 0x5767 0x576E 0x5778 \ + 0x577F 0x58F3 0x594B 0x594C 0x59AD 0x59C4 0x59C2 0x59B0 +11 0x59BF 0x59C9 0x59B8 0x59AC 0x59B7 0x59D7 0x8FC8 0x4FAB \ + 0x5C2D 0x549C 0x5788 0x62C3 0x6619 0x67A1 0x67A6 0x77FE \ + 0x7F57 0x82C5 0x8FDF 0x8FDC 0x4FE4 0x551B 0x57AA 0x57AB \ + 0x5BA9 0x6811 0x7551 0x7553 0x7818 0x7AD7 0x7C7E 0x867E \ + 0x5266 0x5520 0x5521 0x57D7 0x5BBE 0x6857 0x7F3C 0x8273 \ + 0x96BE 0x66FA 0x5A72 0x68BD 0x6E15 0x7413 0x74F8 0x7B3D \ + 0x76D8 0x79FC 0x7B39 0x7D4B 0x83B9 0x86CF 0x8EAE 0x96EB \ + 0x55B0 0x5840 0x5842 0x692B 0x6916 0x691B 0x6927 0x6BF5 \ + 0x6E82 0x6E7A 0x7129 0x7CAB 0x7CAC 0x83F7 0x9596 0x55F1 \ + 0x5F41 0x698A 0x698C 0x6980 0x697F 0x789C 0x7B7B 0x90D2 \ + 0x95A0 0x51A9 0x7195 0x7198 0x7478 0x78B9 0x7A33 0x7CC0 \ + 0x7CC1 0x8744 0x9064 0x9277 0x92AF 0x5E64 0x6A2B 0x6F46 \ + 0x6F9A 0x92F2 0x9B79 0x567A 0x5F5C 0x65D9 0x6A72 0x6A78 \ + 0x6B5A 0x8EBE 0x933B 0x9340 0x933A 0x9B96 0x71F5 0x7A50 \ + 0x9387 0x9385 0x9BB1 0x9D47 0x93B9 0x93BF 0x9BCF 0x9D64 \ + 0x9EBF 0x89B8 0x9BF3 0x7C4F 0x9425 0x95E6 0x9C2F 0x6B0C \ + 0x9C47 0x7936 0x6B15 0x53B5 0x4F66 0x4F68 0x4FE7 0x503F \ + 0x50A6 0x510F 0x523E 0x5324 0x5365 0x539B 0x517F 0x54CB \ + 0x5573 0x5571 0x556B 0x55F4 0x5622 0x5620 0x5692 0x56BA \ + 0x5691 0x56B0 0x5759 0x578A 0x580F 0x5812 0x5813 0x5847 \ + 0x589B 0x5900 0x594D 0x5B60 0x5B96 0x5B9E 0x5B94 0x5B9F \ + 0x5B9D 0x5C00 0x5C19 0x5C49 0x5C4A 0x5CBB 0x5CC1 0x5CB9 \ + 0x5C9E 0x5CB4 0x5CBA 0x5DF6 0x5E13 0x5E12 0x5E77 0x5E98 \ + 0x5E99 0x5E9D 0x5EF8 0x5EF9 0x5F06 0x5F21 0x5F25 0x5F55 \ + 0x5F84 0x5F83 0x6030 0x6007 0x5AD1 0x5AD3 0x5B67 0x5C57 \ + 0x5C77 0x5CD5 0x5D75 0x5D8E 0x5DA5 0x5DB6 0x5DBF 0x5E65 \ + 0x5ECD 0x5EED 0x5F94 0x5F9A 0x5FBA 0x6125 0x6150 0x62A3 \ + 0x6360 0x6364 0x63B6 0x6403 0x64B6 0x651A 0x7A25 0x5C21 \ + 0x66E2 0x6702 0x67A4 0x67AC 0x6810 0x6806 0x685E 0x685A \ + 0x692C 0x6929 0x6A2D 0x6A77 0x6A7A 0x6ACA 0x6AE6 0x6AF5 \ + 0x6B0D 0x6B0E 0x6BDC 0x6BDD 0x6BF6 0x6C1E 0x6C63 0x6DA5 \ + 0x6E0F 0x6E8A 0x6E84 0x6E8B 0x6E7C 0x6F4C 0x6F48 0x6F49 +12 0x6F9D 0x6F99 0x6FF8 0x702E 0x702D 0x705C 0x79CC 0x70BF \ + 0x70EA 0x70E5 0x7111 0x7112 0x713F 0x7139 0x713B 0x713D \ + 0x7177 0x7175 0x7176 0x7171 0x7196 0x7193 0x71B4 0x71DD \ + 0x71DE 0x720E 0x5911 0x7218 0x7347 0x7348 0x73EF 0x7412 \ + 0x743B 0x74A4 0x748D 0x74B4 0x7673 0x7677 0x76BC 0x7819 \ + 0x781B 0x783D 0x7853 0x7854 0x7858 0x78B7 0x78D8 0x78EE \ + 0x7922 0x794D 0x7986 0x7999 0x79A3 0x79BC 0x7AA7 0x7B37 \ + 0x7B59 0x7BD0 0x7C2F 0x7C32 0x7C42 0x7C4E 0x7C68 0x7CA9 \ + 0x7CED 0x7DD0 0x7E07 0x7DD3 0x7E64 0x7F40 0x8041 0x8063 \ + 0x80BB 0x6711 0x6725 0x8248 0x8310 0x8362 0x8312 0x8421 \ + 0x841E 0x84E2 0x84DE 0x84E1 0x8573 0x85D4 0x85F5 0x8637 \ + 0x8645 0x8672 0x874A 0x87A9 0x87A5 0x87F5 0x8834 0x8850 \ + 0x8887 0x6036 0x5FE9 0x603D 0x6008 0x62BA 0x62B2 0x62B7 \ + 0x62E4 0x62A7 0x62D5 0x62E1 0x62DD 0x62A6 0x62C1 0x62C5 \ + 0x62C0 0x62DF 0x62E0 0x62DE 0x6589 0x65A6 0x65BA 0x65FF \ + 0x6617 0x6618 0x6601 0x65FE 0x670C 0x676B 0x6796 0x6782 \ + 0x678A 0x67A3 0x8954 0x8984 0x8B03 0x8C52 0x8CD8 0x8D0C \ + 0x8D18 0x8DB0 0x8EBC 0x8ED5 0x8FAA 0x909C 0x915C 0x922B \ + 0x9221 0x9273 0x92F4 0x92F5 0x933F 0x9342 0x9386 0x93BE \ + 0x93BC 0x93BD 0x93F1 0x93F2 0x93EF 0x9422 0x9423 0x9424 \ + 0x9467 0x9466 0x9597 0x95CE 0x95E7 0x973B 0x974D 0x98E4 \ + 0x9942 0x9B1D 0x9B98 0x9D49 0x6449 0x5E71 0x5E85 0x61D3 \ + 0x990E 0x8002 0x781E 0x5528 0x5572 0x55BA 0x55F0 0x55EE \ + 0x56B8 0x56B9 0x56C4 0x8053 0x92B0 0x4E13 0x4E1A 0x4E1B \ + 0x4E1C 0x4E1D 0x4E25 0x4E27 0x4E2C 0x4E34 0x4E3A 0x4E3E \ + 0x4E4C 0x4E50 0x4E60 0x4E61 0x4E66 0x4E70 0x4E78 0x4E9A \ + 0x4EA7 0x4EA9 0x4EAA 0x4EB5 0x4EB8 0x4EBB 0x4EBF 0x4ED1 \ + 0x4ED3 0x4EEA 0x4EEB 0x4EEC 0x4F1E 0x4F1F 0x4F20 0x4F21 \ + 0x4F23 0x4F24 0x4F25 0x4F26 0x4F27 0x4F2A 0x4F2B 0x4F65 \ + 0x4FA5 0x4FA6 0x4FA7 0x4FA8 0x4FA9 0x4FAA 0x4FAC 0x4FE6 \ + 0x4FE8 0x4FEA 0x4FEB 0x4FED 0x503A 0x503D 0x503E 0x507E \ + 0x507F 0x50A4 0x50A5 0x50A7 0x50A8 0x50A9 0x5170 0x5174 +13 0x517B 0x517D 0x5181 0x519A 0x519B 0x519C 0x51A7 0x51AE \ + 0x51AF 0x51BB 0x51EB 0x51EF 0x51FB 0x51FC 0x51FF 0x520D \ + 0x5219 0x521A 0x521B 0x522C 0x522D 0x523F 0x5240 0x5242 \ + 0x5250 0x5251 0x528F 0x52A1 0x52A2 0x52B2 0x52CB 0x67A2 \ + 0x678F 0x67F9 0x6780 0x6B26 0x6B27 0x6B68 0x6B69 0x6B81 \ + 0x6BB4 0x6BD1 0x6C1C 0x6C97 0x6C6C 0x6CDF 0x6CEA 0x6CE4 \ + 0x6CD8 0x6CB2 0x6CCE 0x6CC8 0x708B 0x7088 0x7090 0x708F \ + 0x7087 0x7089 0x708D 0x7081 0x708C 0x7240 0x7265 0x7266 \ + 0x52DA 0x5326 0x532E 0x5356 0x5362 0x536B 0x5385 0x538C \ + 0x538D 0x5390 0x5395 0x53A2 0x53A3 0x53BF 0x53C6 0x53C7 \ + 0x53D1 0x53D8 0x53FE 0x5417 0x5452 0x5453 0x5456 0x5457 \ + 0x5458 0x5459 0x545B 0x545C 0x5497 0x5499 0x549B 0x549D \ + 0x54D1 0x54D2 0x54D3 0x54D4 0x54D5 0x54D7 0x54D9 0x54DC \ + 0x54DD 0x54DF 0x551D 0x551E 0x5522 0x5523 0x5524 0x5525 \ + 0x5567 0x556C 0x556D 0x556E 0x556F 0x5570 0x5574 0x5578 \ + 0x5579 0x55B7 0x55B9 0x55BC 0x55BE 0x55EB 0x55EC 0x55F3 \ + 0x55F5 0x5621 0x5623 0x5624 0x5625 0x565C 0x565D 0x567C \ + 0x56A1 0x56A3 0x56A4 0x56D6 0x56E2 0x56F4 0x56F5 0x56FE \ + 0x5706 0x5719 0x5739 0x573A 0x575A 0x575C 0x575D 0x575E \ + 0x5760 0x5784 0x5785 0x57AD 0x57AF 0x57B1 0x57B2 0x57D8 \ + 0x57D9 0x57DA 0x5811 0x5816 0x5846 0x5899 0x58B6 0x58CB \ + 0x58EA 0x58F6 0x58F8 0x5907 0x5939 0x593A 0x5941 0x5942 \ + 0x5956 0x5987 0x5988 0x59A9 0x59AA 0x59AB 0x5A05 0x5A06 \ + 0x5A07 0x5A08 0x5A32 0x5A34 0x5A74 0x5A76 0x5AAD 0x5AD2 \ + 0x5AD4 0x5AF1 0x5AF2 0x5B59 0x5B6D 0x5BA0 0x5BA1 0x5BAA \ + 0x5BBD 0x5BFB 0x5BFC 0x5C1C 0x5C1D 0x5C27 0x5C34 0x5C42 \ + 0x5C43 0x5C66 0x5C72 0x5C7F 0x5C82 0x5C83 0x5C96 0x5C98 \ + 0x5C99 0x5C9A 0x5C9B 0x5CBD 0x5CBF 0x7268 0x72CD 0x72D3 \ + 0x72DB 0x72CF 0x73A7 0x73A3 0x739E 0x73AF 0x73AA 0x739C \ + 0x7542 0x7544 0x753B 0x7541 0x759B 0x759E 0x79C4 0x79C3 \ + 0x79C6 0x79C7 0x79CA 0x7ACF 0x7C76 0x7C74 0x7CFF 0x7CFC \ + 0x7F59 0x80A8 0x80B0 0x80B3 0x80A4 0x80B6 0x5CC2 0x5CC3 +14 0x5CC4 0x5CE3 0x5CE4 0x5CE7 0x5D02 0x5D03 0x5D04 0x5D05 \ + 0x5D2D 0x5D58 0x5D5A 0x5D5D 0x5DC5 0x5DEF 0x5E05 0x5E0F \ + 0x5E10 0x5E1C 0x5E26 0x5E27 0x5E31 0x5E3B 0x5E3C 0x5E86 \ + 0x5E91 0x5E93 0x5E94 0x5E9E 0x5E9F 0x5EBC 0x5F20 0x5F2A \ + 0x5F5F 0x5F68 0x5F7B 0x5F95 0x6001 0x6002 0x6003 0x6004 \ + 0x6005 0x6006 0x603B 0x603C 0x603F 0x6076 0x6078 0x6079 \ + 0x607A 0x607B 0x607D 0x60AB 0x60AC 0x60AD 0x60AF 0x60EB \ + 0x60EC 0x60ED 0x60EF 0x6124 0x6126 0x6151 0x61D1 0x61D2 \ + 0x61D4 0x6206 0x620B 0x6217 0x6269 0x626A 0x626B 0x626C \ + 0x629F 0x62A0 0x62A1 0x62A2 0x62E2 0x62E3 0x62E6 0x62E7 \ + 0x62E8 0x62E9 0x631A 0x631C 0x631D 0x631E 0x6320 0x6322 \ + 0x6324 0x6325 0x6326 0x635E 0x635F 0x6361 0x6362 0x6363 \ + 0x63B3 0x63B7 0x63B8 0x63B9 0x63BC 0x63FB 0x63FC 0x63FD \ + 0x63FF 0x6400 0x6401 0x6402 0x6404 0x6405 0x6444 0x6445 \ + 0x6448 0x644A 0x6484 0x64B5 0x64B7 0x64B8 0x64BA 0x64DD \ + 0x64DE 0x6512 0x6569 0x6586 0x658F 0x6593 0x65A9 0x65F7 \ + 0x65F8 0x663D 0x663E 0x6653 0x6654 0x6655 0x6656 0x6682 \ + 0x66A7 0x6743 0x6767 0x6768 0x6769 0x67A5 0x67A7 0x67A8 \ + 0x67AA 0x67AB 0x67AD 0x67FD 0x6807 0x6808 0x6809 0x680A \ + 0x680B 0x680C 0x680E 0x80A7 0x80AC 0x80A6 0x5367 0x820E \ + 0x82C4 0x833E 0x829C 0x82AA 0x82C9 0x82A6 0x82B2 0x8FCC \ + 0x8FD9 0x8FCA 0x8FD8 0x8FCF 0x90B7 0x90AD 0x90B9 0x9637 \ + 0x9641 0x963E 0x9751 0x9763 0x4E57 0x4E79 0x4EB2 0x4EB0 \ + 0x4EAF 0x4EB1 0x4FD2 0x4FD5 0x680F 0x6860 0x6861 0x6862 \ + 0x6864 0x6865 0x6866 0x6868 0x6869 0x686A 0x68BE 0x68BF \ + 0x68C0 0x691D 0x691F 0x6920 0x6924 0x692D 0x6984 0x6987 \ + 0x6988 0x6989 0x69DA 0x69DB 0x69DC 0x69DF 0x69E0 0x6A2F \ + 0x6A31 0x6A79 0x6A7C 0x6AA9 0x6B7C 0x6B87 0x6B92 0x6B93 \ + 0x6B9A 0x6BC2 0x6BD5 0x6BD9 0x6C07 0x6C22 0x6C29 0x6C47 \ + 0x6C48 0x6C64 0x6CA4 0x6CA5 0x6CA6 0x6CA7 0x6CA8 0x6CA9 \ + 0x6CF6 0x6CF7 0x6CF8 0x6CFA 0x6CFB 0x6CFC 0x6CFD 0x6CFE \ + 0x6D46 0x6D47 0x6D48 0x6D49 0x6D4A 0x6D4B 0x6D4D 0x6D4E +15 0x6D4F 0x6D50 0x6D51 0x6D52 0x6D53 0x6D54 0x6D55 0x6D9D \ + 0x6D9F 0x6DA0 0x6DA1 0x6DA2 0x6DA3 0x6DA4 0x6DA6 0x6DA7 \ + 0x6DA8 0x6DA9 0x6E0D 0x6E0E 0x6E10 0x6E11 0x6E14 0x6E16 \ + 0x6E81 0x6E83 0x6E85 0x6E87 0x6EDF 0x6EE0 0x6EE1 0x6EE2 \ + 0x6EE4 0x6EE5 0x6EE7 0x6EEA 0x6F47 0x6F4B 0x6F4D 0x6F9B \ + 0x6F9C 0x6FD1 0x6FD2 0x704F 0x706D 0x7080 0x709C 0x709D \ + 0x709E 0x70BC 0x70BD 0x70C1 0x70C2 0x70C3 0x70E6 0x70E7 \ + 0x70E8 0x70E9 0x70EB 0x70EC 0x70ED 0x7115 0x7116 0x7118 \ + 0x7140 0x71F7 0x7231 0x7237 0x724D 0x7275 0x728A 0x72B7 \ + 0x72B8 0x72C8 0x72DE 0x72EE 0x72EF 0x72F0 0x72F1 0x72F2 \ + 0x7303 0x7321 0x736D 0x7399 0x739A 0x739B 0x73AE 0x73B0 \ + 0x73B1 0x4FBE 0x4FB8 0x4FB0 0x4FB1 0x4FC8 0x4FC6 0x4FCC \ + 0x4FE5 0x4FE3 0x4FB4 0x516A 0x519F 0x51C1 0x51C2 0x51C3 \ + 0x5245 0x5248 0x524F 0x52C5 0x52CA 0x52C4 0x5327 0x5358 \ + 0x537D 0x53DD 0x53DC 0x53DA 0x53D9 0x54B9 0x54D0 0x54B4 \ + 0x54CA 0x54A3 0x73D1 0x73F0 0x73F2 0x740E 0x740F 0x7410 \ + 0x7437 0x7477 0x748E 0x74D2 0x7519 0x7534 0x7535 0x7545 \ + 0x758D 0x7596 0x759F 0x75A0 0x75A1 0x75AC 0x75AD 0x75AE \ + 0x75AF 0x75C8 0x75C9 0x75D6 0x75E8 0x75EA 0x75EB 0x7605 \ + 0x7617 0x7618 0x762A 0x762B 0x763E 0x763F 0x765D 0x765E \ + 0x7663 0x7666 0x766B 0x7691 0x76B1 0x76B2 0x76CF 0x76D0 \ + 0x76D1 0x770D 0x772C 0x7750 0x7751 0x7786 0x7792 0x7793 \ + 0x77CB 0x77EB 0x77FF 0x7800 0x7801 0x7816 0x7817 0x781A \ + 0x781C 0x7839 0x783B 0x783E 0x7840 0x7841 0x7855 0x7856 \ + 0x7857 0x7859 0x785A 0x785B 0x7875 0x7877 0x789B 0x78D7 \ + 0x78D9 0x7903 0x7933 0x7943 0x794E 0x796F 0x7978 0x79EF \ + 0x79FE 0x7A06 0x7A23 0x7A51 0x7A52 0x7A5E 0x7A77 0x7A8D \ + 0x7A8E 0x7A9C 0x7A9D 0x7AA5 0x7AA6 0x7AAD 0x7AD6 0x7ADE \ + 0x7B03 0x7B15 0x7B3A 0x7B3C 0x7B3E 0x7B5A 0x7B5B 0x7B5C \ + 0x7B7C 0x7B7E 0x7B7F 0x7B80 0x7BA6 0x7BA7 0x7BA8 0x7BA9 \ + 0x7BAB 0x7BD1 0x7BD3 0x7BEE 0x7BEF 0x7C16 0x7C41 0x7CAA \ + 0x7CF9 0x7D27 0x7D77 0x7DD4 0x7E06 0x7E9F 0x7EA0 0x7EA1 +16 0x7EA2 0x7EA3 0x7EA4 0x7EA5 0x7EA6 0x7EA7 0x7EA8 0x7EA9 \ + 0x7EAA 0x7EAB 0x7EAC 0x7EAD 0x7EAE 0x7EAF 0x7EB0 0x7EB1 \ + 0x7EB2 0x7EB3 0x7EB4 0x7EB5 0x7EB6 0x7EB7 0x7EB8 0x54DA \ + 0x54A4 0x54B2 0x549E 0x549F 0x54B5 0x54CD 0x54CC 0x5700 \ + 0x57AC 0x5791 0x578E 0x578D 0x5792 0x57A1 0x5790 0x57A6 \ + 0x57A8 0x579C 0x5796 0x57A7 0x58F5 0x5909 0x5908 0x5952 \ + 0x59DF 0x59EB 0x59EF 0x59F0 0x59D5 0x5A0D 0x5A04 0x59F9 \ + 0x7EB9 0x7EBA 0x7EBB 0x7EBC 0x7EBD 0x7EBE 0x7EBF 0x7EC0 \ + 0x7EC1 0x7EC2 0x7EC3 0x7EC4 0x7EC5 0x7EC6 0x7EC7 0x7EC8 \ + 0x7EC9 0x7ECA 0x7ECB 0x7ECC 0x7ECD 0x7ECE 0x7ECF 0x7ED0 \ + 0x7ED1 0x7ED2 0x7ED3 0x7ED4 0x7ED5 0x7ED6 0x7ED7 0x7ED8 \ + 0x7ED9 0x7EDA 0x7EDB 0x7EDC 0x7EDD 0x7EDE 0x7EDF 0x7EE0 \ + 0x7EE1 0x7EE2 0x7EE3 0x7EE4 0x7EE5 0x7EE6 0x7EE7 0x7EE8 \ + 0x7EE9 0x7EEA 0x7EEB 0x7EEC 0x7EED 0x7EEE 0x7EEF 0x7EF0 \ + 0x7EF1 0x7EF2 0x7EF3 0x7EF4 0x7EF5 0x7EF6 0x7EF7 0x7EF8 \ + 0x7EF9 0x7EFA 0x7EFB 0x7EFC 0x7EFD 0x7EFE 0x7EFF 0x7F00 \ + 0x7F01 0x7F02 0x7F03 0x7F04 0x7F05 0x7F06 0x7F07 0x7F08 \ + 0x7F09 0x7F0A 0x7F0B 0x7F0C 0x7F0D 0x7F0E 0x7F0F 0x7F10 \ + 0x7F11 0x7F12 0x7F13 0x7F14 0x7F15 0x7F16 0x7F17 0x7F18 \ + 0x7F19 0x7F1A 0x7F1B 0x7F1C 0x7F1D 0x7F1E 0x7F1F 0x7F20 \ + 0x7F21 0x7F22 0x7F23 0x7F24 0x7F25 0x7F26 0x7F27 0x7F28 \ + 0x7F29 0x7F2A 0x7F2B 0x7F2C 0x7F2D 0x7F2E 0x7F2F 0x7F30 \ + 0x7F31 0x7F32 0x7F33 0x7F34 0x7F35 0x7F42 0x7F49 0x7F56 \ + 0x7F5A 0x7F74 0x7F81 0x7F9F 0x7FD8 0x7FD9 0x7FDA 0x8022 \ + 0x8027 0x8042 0x804B 0x804C 0x804D 0x8054 0x8069 0x8080 \ + 0x8083 0x80A0 0x80BC 0x80BD 0x80BE 0x80BF 0x80C0 0x80C1 \ + 0x80E7 0x80E8 0x80E9 0x80EA 0x80EB 0x5A02 0x59F8 0x59E2 \ + 0x59D9 0x59E7 0x5B6A 0x5BAB 0x5C1B 0x5C2F 0x663C 0x5CD1 \ + 0x5CDC 0x5CE6 0x5CE1 0x5CCD 0x5CE2 0x5CDD 0x5CE5 0x5DFB \ + 0x5DFA 0x5E1E 0x5EA1 0x5EFC 0x5EFB 0x5F2F 0x5F66 0x605C \ + 0x604E 0x6051 0x6023 0x6031 0x607C 0x6060 0x80EC 0x810C \ + 0x810D 0x810E 0x810F 0x8110 0x8111 0x8112 0x8113 0x8132 +17 0x8136 0x8137 0x8138 0x8156 0x8159 0x815A 0x817B 0x817C \ + 0x817E 0x8191 0x81A5 0x81B6 0x81DC 0x8206 0x8223 0x8230 \ + 0x8231 0x823B 0x823E 0x8254 0x8270 0x8282 0x8288 0x8297 \ + 0x82C7 0x82C8 0x82CB 0x82CC 0x82CD 0x82CE 0x82CF 0x830F \ + 0x8311 0x8313 0x8314 0x8315 0x8359 0x835A 0x835B 0x835C \ + 0x835D 0x835E 0x835F 0x8360 0x8361 0x8364 0x8365 0x8366 \ + 0x8367 0x8368 0x8369 0x836A 0x836B 0x836C 0x836D 0x836E \ + 0x836F 0x83B2 0x83B3 0x83B4 0x83B6 0x83B8 0x83BA 0x83BC \ + 0x841A 0x841C 0x841D 0x8424 0x8425 0x8426 0x8427 0x8428 \ + 0x8487 0x8489 0x848C 0x84DD 0x84DF 0x84E0 0x84E3 0x84E5 \ + 0x84E6 0x8537 0x8539 0x853A 0x853C 0x8572 0x8574 0x85D3 \ + 0x8614 0x864F 0x867F 0x8680 0x8681 0x8682 0x8683 0x86AC \ + 0x86F0 0x86F1 0x86F2 0x86F3 0x86F4 0x8717 0x8748 0x877E \ + 0x8780 0x87A8 0x87CF 0x8854 0x8865 0x886C 0x8885 0x8886 \ + 0x88AD 0x88AF 0x88C6 0x88C7 0x88C8 0x88E2 0x88E3 0x88E4 \ + 0x88E5 0x8934 0x8947 0x8955 0x8980 0x89C1 0x89C2 0x89C3 \ + 0x89C4 0x89C5 0x89C6 0x89C7 0x89C8 0x89C9 0x89CA 0x89CB \ + 0x89CC 0x89CD 0x89CE 0x89CF 0x89D0 0x89D1 0x89DE 0x89EF \ + 0x8A01 0x8A1A 0x8A5F 0x604A 0x6061 0x6218 0x631F 0x6317 \ + 0x62EA 0x6321 0x6304 0x6305 0x6531 0x6544 0x6540 0x6542 \ + 0x65BE 0x6629 0x661B 0x6623 0x662C 0x661A 0x6630 0x663B \ + 0x661E 0x6637 0x6638 0x670E 0x67E8 0x67D6 0x67C7 0x67BC \ + 0x6852 0x67BF 0x67D5 0x67FE 0x8A8A 0x8BA0 0x8BA1 0x8BA2 \ + 0x8BA3 0x8BA4 0x8BA5 0x8BA6 0x8BA7 0x8BA8 0x8BA9 0x8BAA \ + 0x8BAB 0x8BAC 0x8BAD 0x8BAE 0x8BAF 0x8BB0 0x8BB1 0x8BB2 \ + 0x8BB3 0x8BB4 0x8BB5 0x8BB6 0x8BB7 0x8BB8 0x8BB9 0x8BBA \ + 0x8BBB 0x8BBC 0x8BBD 0x8BBE 0x8BBF 0x8BC0 0x8BC1 0x8BC2 \ + 0x8BC3 0x8BC4 0x8BC5 0x8BC6 0x8BC7 0x8BC8 0x8BC9 0x8BCA \ + 0x8BCB 0x8BCC 0x8BCD 0x8BCE 0x8BCF 0x8BD0 0x8BD1 0x8BD2 \ + 0x8BD3 0x8BD4 0x8BD5 0x8BD6 0x8BD7 0x8BD8 0x8BD9 0x8BDA \ + 0x8BDB 0x8BDC 0x8BDD 0x8BDE 0x8BDF 0x8BE0 0x8BE1 0x8BE2 \ + 0x8BE3 0x8BE4 0x8BE5 0x8BE6 0x8BE7 0x8BE8 0x8BE9 0x8BEA +18 0x8BEB 0x8BEC 0x8BED 0x8BEE 0x8BEF 0x8BF0 0x8BF1 0x8BF2 \ + 0x8BF3 0x8BF4 0x8BF5 0x8BF6 0x8BF7 0x8BF8 0x8BF9 0x8BFA \ + 0x8BFB 0x8BFC 0x8BFD 0x8BFE 0x8BFF 0x8C00 0x8C01 0x8C02 \ + 0x8C03 0x8C04 0x8C05 0x8C06 0x8C07 0x8C08 0x8C09 0x8C0A \ + 0x8C0B 0x8C0C 0x8C0D 0x8C0E 0x8C0F 0x8C10 0x8C11 0x8C12 \ + 0x8C13 0x8C14 0x8C15 0x8C16 0x8C17 0x8C18 0x8C19 0x8C1A \ + 0x8C1B 0x8C1C 0x8C1D 0x8C1E 0x8C1F 0x8C20 0x8C21 0x8C22 \ + 0x8C23 0x8C24 0x8C25 0x8C26 0x8C27 0x8C28 0x8C29 0x8C2A \ + 0x8C2B 0x8C2C 0x8C2D 0x8C2E 0x8C2F 0x8C30 0x8C31 0x8C32 \ + 0x8C33 0x8C34 0x8C35 0x8C36 0x8C6E 0x8D1D 0x8D1E 0x8D1F \ + 0x8D20 0x8363 0x67FB 0x67B1 0x6801 0x6805 0x6800 0x67D7 \ + 0x6B2A 0x6B6B 0x6BE1 0x6D23 0x6CFF 0x6D14 0x6D05 0x6D13 \ + 0x6D06 0x6D21 0x6D15 0x6CAF 0x6CF4 0x6D02 0x6D45 0x6D26 \ + 0x6D44 0x6D24 0x70A5 0x70A3 0x70A2 0x70BB 0x70A0 0x70AA \ + 0x70A8 0x70B6 0x8D21 0x8D22 0x8D23 0x8D24 0x8D25 0x8D26 \ + 0x8D27 0x8D28 0x8D29 0x8D2A 0x8D2B 0x8D2C 0x8D2D 0x8D2E \ + 0x8D2F 0x8D30 0x8D31 0x8D32 0x8D33 0x8D34 0x8D35 0x8D36 \ + 0x8D37 0x8D38 0x8D39 0x8D3A 0x8D3B 0x8D3C 0x8D3D 0x8D3E \ + 0x8D3F 0x8D40 0x8D41 0x8D42 0x8D43 0x8D44 0x8D45 0x8D46 \ + 0x8D47 0x8D48 0x8D49 0x8D4A 0x8D4B 0x8D4C 0x8D4D 0x8D4E \ + 0x8D4F 0x8D50 0x8D51 0x8D52 0x8D53 0x8D54 0x8D55 0x8D56 \ + 0x8D57 0x8D58 0x8D59 0x8D5A 0x8D5B 0x8D5C 0x8D5D 0x8D5E \ + 0x8D5F 0x8D60 0x8D61 0x8D62 0x8D63 0x8D6A 0x8D75 0x8DB1 \ + 0x8DB8 0x8DC4 0x8DDE 0x8DF6 0x8DF7 0x8DF8 0x8DF9 0x8DFB \ + 0x8E0C 0x8E0E 0x8E2C 0x8E2D 0x8E2F 0x8E52 0x8E7E 0x8E7F \ + 0x8E80 0x8E8F 0x8E9C 0x8ECE 0x8F66 0x8F67 0x8F68 0x8F69 \ + 0x8F6A 0x8F6B 0x8F6C 0x8F6D 0x8F6E 0x8F6F 0x8F70 0x8F71 \ + 0x8F72 0x8F73 0x8F74 0x8F75 0x8F76 0x8F77 0x8F78 0x8F79 \ + 0x8F7A 0x8F7B 0x8F7C 0x8F7D 0x8F7E 0x8F7F 0x8F80 0x8F81 \ + 0x8F82 0x8F83 0x8F84 0x8F85 0x8F86 0x8F87 0x8F88 0x8F89 \ + 0x8F8A 0x8F8B 0x8F8C 0x8F8D 0x8F8E 0x8F8F 0x8F90 0x8F91 \ + 0x8F92 0x8F93 0x8F94 0x8F95 0x8F96 0x8F97 0x8F98 0x8F99 +19 0x8F9A 0x8FA9 0x8FAB 0x8FBD 0x8FDB 0x8FDD 0x8FDE 0x8FF3 \ + 0x900A 0x9026 0x9057 0x909D 0x90AC 0x90BA 0x90BB 0x70B2 \ + 0x70A7 0x70B9 0x722E 0x723C 0x726D 0x72E7 0x72ED 0x72EC \ + 0x72E5 0x72E2 0x73C4 0x73BD 0x73CF 0x73C9 0x73C1 0x73D0 \ + 0x73CE 0x74ED 0x74EB 0x74EF 0x7549 0x7550 0x7546 0x754A \ + 0x754D 0x75A6 0x75A8 0x76C7 0x76FF 0x76FD 0x77E6 0x780A \ + 0x90CF 0x90D0 0x90D1 0x90D3 0x90E6 0x90E7 0x90F8 0x9142 \ + 0x915D 0x915E 0x9166 0x9171 0x917D 0x917E 0x917F 0x91CA \ + 0x91D2 0x91FA 0x922A 0x9274 0x933E 0x9341 0x93F0 0x9426 \ + 0x9485 0x9486 0x9487 0x9488 0x9489 0x948A 0x948B 0x948C \ + 0x948D 0x948E 0x948F 0x9490 0x9491 0x9492 0x9493 0x9494 \ + 0x9495 0x9496 0x9497 0x9498 0x9499 0x949A 0x949B 0x949C \ + 0x949D 0x949E 0x949F 0x94A0 0x94A1 0x94A2 0x94A3 0x94A4 \ + 0x94A5 0x94A6 0x94A7 0x94A8 0x94A9 0x94AA 0x94AB 0x94AC \ + 0x94AD 0x94AE 0x94AF 0x94B0 0x94B1 0x94B2 0x94B3 0x94B4 \ + 0x94B5 0x94B6 0x94B7 0x94B8 0x94B9 0x94BA 0x94BB 0x94BC \ + 0x94BD 0x94BE 0x94BF 0x94C0 0x94C1 0x94C2 0x94C3 0x94C4 \ + 0x94C5 0x94C6 0x94C7 0x94C8 0x94C9 0x94CA 0x94CB 0x94CC \ + 0x94CD 0x94CE 0x94CF 0x94D0 0x94D1 0x94D2 0x94D3 0x94D4 \ + 0x94D5 0x94D6 0x94D7 0x94D8 0x94D9 0x94DA 0x94DB 0x94DC \ + 0x94DD 0x94DE 0x94DF 0x94E0 0x94E1 0x94E2 0x94E3 0x94E4 \ + 0x94E5 0x94E6 0x94E7 0x94E8 0x94E9 0x94EA 0x94EB 0x94EC \ + 0x94ED 0x94EE 0x94EF 0x94F0 0x94F1 0x94F2 0x94F3 0x94F4 \ + 0x94F5 0x94F6 0x94F7 0x94F8 0x94F9 0x94FA 0x94FB 0x94FC \ + 0x94FD 0x94FE 0x94FF 0x9500 0x9501 0x9502 0x9503 0x9504 \ + 0x9505 0x9506 0x9507 0x9508 0x9509 0x7804 0x780B 0x7807 \ + 0x7815 0x7808 0x79D3 0x79D4 0x79D0 0x79D7 0x7A7C 0x7A7D \ + 0x7A83 0x7A82 0x7AD4 0x7AD5 0x7AD3 0x7AD0 0x7AD2 0x7AFE \ + 0x7AFC 0x7C77 0x7C7C 0x7C7B 0x7F8F 0x80D3 0x80CB 0x80D2 \ + 0x8109 0x80E2 0x80DF 0x80C6 0x8224 0x82F7 0x950A 0x950B \ + 0x950C 0x950D 0x950E 0x950F 0x9510 0x9511 0x9512 0x9513 \ + 0x9514 0x9515 0x9516 0x9517 0x9518 0x9519 0x951A 0x951B +20 0x951C 0x951D 0x951E 0x951F 0x9520 0x9521 0x9522 0x9523 \ + 0x9524 0x9525 0x9526 0x9527 0x9528 0x9529 0x952A 0x952B \ + 0x952C 0x952D 0x952E 0x952F 0x9530 0x9531 0x9532 0x9533 \ + 0x9534 0x9535 0x9536 0x9537 0x9538 0x9539 0x953A 0x953B \ + 0x953C 0x953D 0x953E 0x953F 0x9540 0x9541 0x9542 0x9543 \ + 0x9544 0x9545 0x9546 0x9547 0x9548 0x9549 0x954A 0x954B \ + 0x954C 0x954D 0x954E 0x954F 0x9550 0x9551 0x9552 0x9553 \ + 0x9554 0x9555 0x9556 0x9557 0x9558 0x9559 0x955A 0x955B \ + 0x955C 0x955D 0x955E 0x955F 0x9560 0x9561 0x9562 0x9563 \ + 0x9564 0x9565 0x9566 0x9567 0x9568 0x9569 0x956A 0x956B \ + 0x956C 0x956D 0x956E 0x956F 0x9570 0x9571 0x9572 0x9573 \ + 0x9574 0x9575 0x9576 0x957F 0x95E8 0x95E9 0x95EA 0x95EB \ + 0x95EC 0x95ED 0x95EE 0x95EF 0x95F0 0x95F1 0x95F2 0x95F3 \ + 0x95F4 0x95F5 0x95F6 0x95F7 0x95F8 0x95F9 0x95FA 0x95FB \ + 0x95FC 0x95FD 0x95FE 0x95FF 0x9600 0x9601 0x9602 0x9603 \ + 0x9604 0x9605 0x9606 0x9607 0x9608 0x9609 0x960A 0x960B \ + 0x960C 0x960D 0x960E 0x960F 0x9610 0x9611 0x9612 0x9613 \ + 0x9614 0x9615 0x9616 0x82D8 0x82DD 0x82F8 0x82FC 0x82E9 \ + 0x82EE 0x82D0 0x830E 0x82E2 0x830B 0x82FD 0x5179 0x8676 \ + 0x8678 0x8675 0x867D 0x8842 0x8866 0x898C 0x8A05 0x8A06 \ + 0x8C9F 0x8FF1 0x8FE7 0x8FE9 0x8FEF 0x90C2 0x90BC 0x90C6 \ + 0x90C0 0x90CD 0x90C9 0x90C4 0x9617 0x9618 0x9619 0x961A \ + 0x961B 0x961F 0x9635 0x9636 0x9645 0x9646 0x9647 0x9648 \ + 0x9649 0x9667 0x9668 0x9669 0x9690 0x96E0 0x96F3 0x96FE \ + 0x9701 0x972D 0x9753 0x9754 0x9765 0x9791 0x9792 0x97AF \ + 0x97E6 0x97E7 0x97E8 0x97E9 0x97EA 0x97EB 0x97EC 0x9875 \ + 0x9876 0x9877 0x9878 0x9879 0x987A 0x987B 0x987C 0x987D \ + 0x987E 0x987F 0x9880 0x9881 0x9882 0x9883 0x9884 0x9885 \ + 0x9886 0x9887 0x9888 0x9889 0x988A 0x988B 0x988C 0x988D \ + 0x988E 0x988F 0x9890 0x9891 0x9892 0x9893 0x9894 0x9895 \ + 0x9896 0x9897 0x9898 0x9899 0x989A 0x989B 0x989C 0x989D \ + 0x989E 0x989F 0x98A0 0x98A1 0x98A2 0x98A3 0x98A4 0x98A5 +21 0x98A6 0x98A7 0x98CE 0x98CF 0x98D0 0x98D1 0x98D2 0x98D3 \ + 0x98D4 0x98D5 0x98D6 0x98D7 0x98D8 0x98D9 0x98DA 0x98DE \ + 0x98E0 0x98E8 0x990D 0x990F 0x9962 0x9963 0x9964 0x9965 \ + 0x9966 0x9967 0x9968 0x9969 0x996A 0x996B 0x996C 0x996D \ + 0x996E 0x996F 0x9970 0x9971 0x9972 0x9973 0x9974 0x9975 \ + 0x9976 0x9977 0x9978 0x9979 0x997A 0x997B 0x997C 0x997D \ + 0x997E 0x997F 0x9980 0x9981 0x9982 0x9983 0x9984 0x9985 \ + 0x9986 0x9987 0x9988 0x9989 0x998A 0x998B 0x998C 0x998D \ + 0x998E 0x998F 0x9990 0x9991 0x9992 0x9993 0x9994 0x9995 \ + 0x9A6C 0x9581 0x9CEC 0x5032 0x4FF9 0x501D 0x4FFF 0x5004 \ + 0x4FF0 0x5003 0x5002 0x4FFC 0x4FF2 0x5024 0x5008 0x5036 \ + 0x502E 0x5010 0x5038 0x5039 0x4FFD 0x5056 0x4FFB 0x51A3 \ + 0x51A6 0x51A1 0x51C7 0x51C9 0x5260 0x5264 0x5259 0x5265 \ + 0x5267 0x5257 0x9A6D 0x9A6E 0x9A6F 0x9A70 0x9A71 0x9A72 \ + 0x9A73 0x9A74 0x9A75 0x9A76 0x9A77 0x9A78 0x9A79 0x9A7A \ + 0x9A7B 0x9A7C 0x9A7D 0x9A7E 0x9A7F 0x9A80 0x9A81 0x9A82 \ + 0x9A83 0x9A84 0x9A85 0x9A86 0x9A87 0x9A88 0x9A89 0x9A8A \ + 0x9A8B 0x9A8C 0x9A8D 0x9A8E 0x9A8F 0x9A90 0x9A91 0x9A92 \ + 0x9A93 0x9A94 0x9A95 0x9A96 0x9A97 0x9A98 0x9A99 0x9A9A \ + 0x9A9B 0x9A9C 0x9A9D 0x9A9E 0x9A9F 0x9AA0 0x9AA1 0x9AA2 \ + 0x9AA3 0x9AA4 0x9AA5 0x9AA6 0x9AA7 0x9ACB 0x9ACC 0x9B13 \ + 0x9B47 0x9C7C 0x9C7D 0x9C7E 0x9C7F 0x9C80 0x9C81 0x9C82 \ + 0x9C83 0x9C84 0x9C85 0x9C86 0x9C87 0x9C88 0x9C89 0x9C8A \ + 0x9C8B 0x9C8C 0x9C8D 0x9C8E 0x9C8F 0x9C90 0x9C91 0x9C92 \ + 0x9C93 0x9C94 0x9C95 0x9C96 0x9C97 0x9C98 0x9C99 0x9C9A \ + 0x9C9B 0x9C9C 0x9C9D 0x9C9E 0x9C9F 0x9CA0 0x9CA1 0x9CA2 \ + 0x9CA3 0x9CA4 0x9CA5 0x9CA6 0x9CA7 0x9CA8 0x9CA9 0x9CAA \ + 0x9CAB 0x9CAC 0x9CAD 0x9CAE 0x9CAF 0x9CB0 0x9CB1 0x9CB2 \ + 0x9CB3 0x9CB4 0x9CB5 0x9CB6 0x9CB7 0x9CB8 0x9CB9 0x9CBA \ + 0x9CBB 0x9CBC 0x9CBD 0x9CBE 0x9CBF 0x9CC0 0x9CC1 0x9CC2 \ + 0x9CC3 0x9CC4 0x9CC5 0x9CC6 0x9CC7 0x9CC8 0x9CC9 0x9CCA \ + 0x9CCB 0x9CCC 0x9CCD 0x9CCE 0x9CCF 0x9CD0 0x9CD1 0x9CD2 +22 0x9CD3 0x9CD4 0x9CD5 0x9CD6 0x9CD7 0x9CD8 0x9CD9 0x5263 \ + 0x5253 0x52CF 0x52CE 0x52D0 0x52D1 0x52CC 0x550D 0x54F4 \ + 0x5513 0x54EF 0x54F5 0x54F9 0x5502 0x5500 0x5518 0x54F0 \ + 0x54F6 0x5519 0x5705 0x57C9 0x57B7 0x57CD 0x57BE 0x57BB \ + 0x57DB 0x57C8 0x57C4 0x57C5 0x57D1 0x57CA 0x57C0 0x5A21 \ + 0x9CDA 0x9CDB 0x9CDC 0x9CDD 0x9CDE 0x9CDF 0x9CE0 0x9CE1 \ + 0x9CE2 0x9CE3 0x9CE4 0x9E1F 0x9E20 0x9E21 0x9E22 0x9E23 \ + 0x9E24 0x9E25 0x9E26 0x9E27 0x9E28 0x9E29 0x9E2A 0x9E2B \ + 0x9E2C 0x9E2D 0x9E2E 0x9E2F 0x9E30 0x9E31 0x9E32 0x9E33 \ + 0x9E34 0x9E35 0x9E36 0x9E37 0x9E38 0x9E39 0x9E3A 0x9E3B \ + 0x9E3C 0x9E3D 0x9E3E 0x9E3F 0x9E40 0x9E41 0x9E42 0x9E43 \ + 0x9E44 0x9E45 0x9E46 0x9E47 0x9E48 0x9E49 0x9E4A 0x9E4B \ + 0x9E4C 0x9E4D 0x9E4E 0x9E4F 0x9E50 0x9E51 0x9E52 0x9E53 \ + 0x9E54 0x9E55 0x9E56 0x9E57 0x9E58 0x9E59 0x9E5A 0x9E5B \ + 0x9E5C 0x9E5D 0x9E5E 0x9E5F 0x9E60 0x9E61 0x9E62 0x9E63 \ + 0x9E64 0x9E65 0x9E66 0x9E67 0x9E68 0x9E69 0x9E6A 0x9E6B \ + 0x9E6C 0x9E6D 0x9E6E 0x9E6F 0x9E70 0x9E71 0x9E72 0x9E73 \ + 0x9E74 0x9E7E 0x9EC9 0x9EE1 0x9EE9 0x9EEA 0x9F0B 0x9F0C \ + 0x9F0D 0x9F51 0x9F7F 0x9F80 0x9F81 0x9F82 0x9F83 0x9F84 \ + 0x9F85 0x9F86 0x9F87 0x9F88 0x9F89 0x9F8A 0x9F8B 0x9F8C \ + 0x9F9A 0x9F9B 0x9F9F 0x4E06 0x4E37 0x4E44 0x4E4A 0x4E55 \ + 0x4E5B 0x4E64 0x4E65 0x4E67 0x4E6B 0x4E6C 0x4E6D 0x4E6E \ + 0x4E6F 0x4E72 0x4E76 0x4E77 0x4E7A 0x4E7B 0x4E7C 0x4E7D \ + 0x4E8A 0x4E90 0x4EBD 0x4ED2 0x4EED 0x4FA4 0x4FAD 0x503B \ + 0x50F2 0x516F 0x517A 0x51E6 0x51E7 0x5A2A 0x5A1D 0x5A0B \ + 0x5A22 0x5A24 0x5A14 0x5A31 0x5A2F 0x5A1A 0x5A12 0x5A26 \ + 0x5BBC 0x5BBB 0x5BB7 0x5C05 0x5C06 0x5C52 0x5C53 0x5CFA \ + 0x5CEB 0x5CF3 0x5CF5 0x5CE9 0x5CEF 0x5E2A 0x5E30 0x5E2E \ + 0x5E2C 0x5E2F 0x5EAF 0x5EA9 0x5EFD 0x5F32 0x51E9 0x5271 \ + 0x5302 0x5381 0x5391 0x53BC 0x5414 0x5455 0x54D8 0x54DB \ + 0x551C 0x551F 0x5569 0x55B8 0x55BD 0x55ED 0x561A 0x565B \ + 0x56A2 0x56CE 0x56D5 0x5726 0x5737 0x5738 0x5786 0x5789 +23 0x57B0 0x57B3 0x57D6 0x5815 0x5841 0x586E 0x5870 0x58B8 \ + 0x58B9 0x58CC 0x58D7 0x58E5 0x58ED 0x591E 0x593B 0x5B36 \ + 0x5B5E 0x5B91 0x5BC9 0x5C02 0x5C26 0x5C2E 0x5C32 0x5C76 \ + 0x5CBC 0x5CBE 0x5CC5 0x5CE0 0x5D2B 0x5D5C 0x5D76 0x5DEA \ + 0x5DEC 0x5DED 0x5DFC 0x5E49 0x5EE4 0x5F09 0x5F16 0x5F45 \ + 0x5FC6 0x603A 0x603E 0x6077 0x6184 0x61F4 0x6244 0x6255 \ + 0x6256 0x62E5 0x6318 0x6327 0x63B4 0x63B5 0x63BB 0x6442 \ + 0x655B 0x657D 0x657E 0x65C0 0x65D5 0x663F 0x6683 0x66FB \ + 0x66FD 0x6730 0x6741 0x6763 0x6764 0x67A0 0x67A9 0x6802 \ + 0x6803 0x680D 0x685B 0x685C 0x685D 0x685F 0x6863 0x6867 \ + 0x688D 0x68BA 0x68BB 0x68BC 0x68C2 0x6919 0x691A 0x6921 \ + 0x6922 0x6923 0x6926 0x6928 0x697E 0x6981 0x698B 0x69DD \ + 0x69DE 0x6A2E 0x6A30 0x6A73 0x6A74 0x6A75 0x6A7B 0x6AC9 \ + 0x6AE4 0x6AF7 0x6B05 0x6B1F 0x6BA9 0x6BB1 0x6BDF 0x6BEE \ + 0x6C0E 0x6C17 0x6C35 0x6C3A 0x6C3D 0x6D4C 0x6D9C 0x6D9E \ + 0x6E13 0x6E7F 0x6E8C 0x6EDE 0x6FF9 0x704E 0x7050 0x7114 \ + 0x713C 0x713E 0x7155 0x5F8E 0x5F93 0x5F8F 0x604F 0x6099 \ + 0x607E 0x6074 0x604B 0x6073 0x6075 0x6056 0x60A9 0x608B \ + 0x60A6 0x6093 0x60AE 0x609E 0x60A7 0x6245 0x632E 0x6352 \ + 0x6330 0x635B 0x6319 0x631B 0x6331 0x635D 0x6337 0x6335 \ + 0x6353 0x635C 0x633F 0x654B 0x7173 0x71F6 0x7233 0x725C \ + 0x72A0 0x731F 0x7320 0x7339 0x7363 0x7364 0x73F1 0x7411 \ + 0x748F 0x7491 0x74E7 0x74F0 0x74F1 0x74F2 0x74FC 0x7505 \ + 0x753C 0x7552 0x7560 0x7569 0x7573 0x7574 0x7582 0x7597 \ + 0x75E9 0x7604 0x7606 0x764D 0x767A 0x770C 0x77C8 0x783A \ + 0x783C 0x783F 0x7872 0x7873 0x7874 0x78B5 0x78B6 0x78F5 \ + 0x7916 0x7934 0x793B 0x7985 0x79F4 0x79FD 0x7A24 0x7A43 \ + 0x7A5D 0x7A63 0x7AC3 0x7B02 0x7B07 0x7B5D 0x7B7A 0x7B7D \ + 0x7B9A 0x7BAA 0x7BCF 0x7BD2 0x7C13 0x7C14 0x7C17 0x7C31 \ + 0x7C61 0x7C82 0x7C8F 0x7C90 0x7CAD 0x7CD8 0x7D26 0x7D9A \ + 0x7D9B 0x7DD5 0x7E05 0x7E28 0x7E4A 0x7E4B 0x7E67 0x7E83 \ + 0x7E90 0x7F53 0x7FAA 0x8062 0x810B 0x8133 0x8135 0x8157 +24 0x81A4 0x81D3 0x8217 0x822E 0x824D 0x825D 0x8260 0x827A \ + 0x82C6 0x83B1 0x83B5 0x83BB 0x8419 0x8420 0x8422 0x8485 \ + 0x848A 0x848B 0x84D9 0x84DC 0x8536 0x85AD 0x85AE 0x8612 \ + 0x8630 0x8644 0x86AB 0x86CD 0x86CE 0x86EF 0x8749 0x874B \ + 0x877F 0x87A6 0x87A7 0x87D0 0x8864 0x88AE 0x88B0 0x88C3 \ + 0x88C4 0x88C5 0x8904 0x891C 0x891D 0x8945 0x8968 0x8977 \ + 0x8A33 0x8A89 0x8AAD 0x8AAE 0x8ADA 0x8B21 0x8B5B 0x8B72 \ + 0x8B8F 0x8CCE 0x8DE5 0x8DF5 0x8E7D 0x8E9B 0x8EB5 0x8EBB \ + 0x8EC5 0x658B 0x659A 0x6650 0x6646 0x664E 0x6640 0x664B \ + 0x6648 0x6660 0x6644 0x664D 0x6837 0x6824 0x681B 0x6836 \ + 0x682C 0x6819 0x6856 0x6847 0x683E 0x681E 0x6815 0x6822 \ + 0x6827 0x6859 0x6858 0x6855 0x6830 0x6823 0x6B2E 0x6B2B \ + 0x6B30 0x6B6C 0x8EC8 0x8EE2 0x8EE3 0x8F0C 0x8F4C 0x8FBA \ + 0x8FDA 0x8FF2 0x9027 0x9039 0x9056 0x9065 0x915B 0x9197 \ + 0x91A4 0x91B8 0x91C8 0x91E1 0x91FB 0x91FC 0x9228 0x9229 \ + 0x922C 0x9271 0x9344 0x93BA 0x9421 0x9441 0x9453 0x958A \ + 0x95AA 0x95CF 0x9665 0x9666 0x967A 0x974C 0x974E 0x974F \ + 0x9771 0x9786 0x9790 0x982C 0x98AA 0x98B4 0x98C5 0x98EE \ + 0x99C5 0x99F2 0x9A12 0x9A13 0x9A28 0x9AC5 0x9B36 0x9B5E \ + 0x9B78 0x9B97 0x9BB2 0x9BB4 0x9BCE 0x9BD0 0x9BD1 0x9BF1 \ + 0x9BF2 0x9BF5 0x9C18 0x9C19 0x9C1A 0x9C30 0x9C5A 0x9C5B \ + 0x9C5C 0x9C69 0x9C6A 0x9C6B 0x9C70 0x9CF0 0x9D0E 0x9D2B \ + 0x9D2C 0x9D46 0x9D48 0x9D65 0x9D8E 0x9D8F 0x9DAB 0x9DC6 \ + 0x9E78 0x9EB8 0x9EB9 0x9EBA 0x9F21 0x9F62 0xFFFE 0xFFFE \ + 0x3000 0xFF0C 0x3001 0x3002 0xFF0E 0x2027 0xFF1B 0xFF1A \ + 0xFF1F 0xFF01 0xFE30 0x2026 0x2025 0xFE50 0xFE51 0xFE52 \ + 0x00B7 0xFE54 0xFE55 0xFE56 0xFE57 0xFF5C 0x2015 0xFE31 \ + 0x2014 0xFE33 0x2574 0xFE34 0xFE4F 0xFF08 0xFF09 0xFE35 \ + 0xFE36 0xFF5B 0xFF5D 0xFE37 0xFE38 0x3014 0x3015 0xFE39 \ + 0xFE3A 0x3010 0x3011 0xFE3B 0xFE3C 0x300A 0x300B 0xFE3D \ + 0xFE3E 0x3008 0x3009 0xFE3F 0xFE40 0x300C 0x300D 0xFE41 \ + 0xFE42 0x300E 0x300F 0xFE43 0xFE44 0xFE59 0xFE5A 0x6B8B +25 0x6BE9 0x6BEA 0x6BE5 0x6D6B 0x6D73 0x6D57 0x6D5D 0x6D56 \ + 0x6D8F 0x6D5B 0x6D1C 0x6D9A 0x6D9B 0x6D99 0x6D81 0x6D71 \ + 0x6D72 0x6D5C 0x6D96 0x70C4 0x70DB 0x70CC 0x70D0 0x70E3 \ + 0x70DF 0x70D6 0x70EE 0x70D5 0x727A 0x72F5 0x7302 0x73E2 \ + 0xFE5B 0xFE5C 0xFE5D 0xFE5E 0x2018 0x2019 0x201C 0x201D \ + 0x301D 0x301E 0x2035 0x2032 0xFF03 0xFF06 0xFF0A 0x203B \ + 0x00A7 0x3003 0x25CB 0x25CF 0x25B3 0x25B2 0x25CE 0x2606 \ + 0x2605 0x25C7 0x25C6 0x25A1 0x25A0 0x25BD 0x25BC 0x32A3 \ + 0x2105 0x203E 0xFFE3 0xFF3F 0x02CD 0xFE49 0xFE4A 0xFE4D \ + 0xFE4E 0xFE4B 0xFE4C 0xFE5F 0xFE60 0xFE61 0xFF0B 0xFF0D \ + 0x00D7 0x00F7 0x00B1 0x221A 0xFF1C 0xFF1E 0xFF1D 0x2266 \ + 0x2267 0x2260 0x221E 0x2252 0x2261 0xFE62 0xFE63 0xFE64 \ + 0xFE65 0xFE66 0xFF5E 0x2229 0x222A 0x22A5 0x2220 0x221F \ + 0x22BF 0x33D2 0x33D1 0x222B 0x222E 0x2235 0x2234 0x2640 \ + 0x2642 0x2295 0x2299 0x2191 0x2193 0x2190 0x2192 0x2196 \ + 0x2197 0x2199 0x2198 0x2225 0x2223 0xFF0F 0xFF3C 0x2215 \ + 0xFE68 0xFF04 0xFFE5 0x3012 0xFFE0 0xFFE1 0xFF05 0xFF20 \ + 0x2103 0x2109 0xFE69 0xFE6A 0xFE6B 0x33D5 0x339C 0x339D \ + 0x339E 0x33CE 0x33A1 0x338E 0x338F 0x33C4 0x00B0 0x5159 \ + 0x515B 0x515E 0x515D 0x5161 0x5163 0x55E7 0x74E9 0x7CCE \ + 0x2581 0x2582 0x2583 0x2584 0x2585 0x2586 0x2587 0x2588 \ + 0x258F 0x258E 0x258D 0x258C 0x258B 0x258A 0x2589 0x253C \ + 0x2534 0x252C 0x2524 0x251C 0x2594 0x2500 0x2502 0x2595 \ + 0x250C 0x2510 0x2514 0x2518 0x256D 0x73EC 0x73D5 0x73F9 \ + 0x73DF 0x73E6 0x73E4 0x73E1 0x74F3 0x7556 0x7555 0x7558 \ + 0x7557 0x755E 0x75C3 0x75B4 0x75B1 0x76CB 0x76CC 0x772A \ + 0x7716 0x770F 0x773F 0x772B 0x770E 0x7724 0x7721 0x7718 \ + 0x77DD 0x7824 0x7836 0x7958 0x7959 0x7962 0x256E 0x2570 \ + 0x256F 0x2501 0x251D 0x253F 0x2525 0x25E2 0x25E3 0x25E5 \ + 0x25E4 0x2571 0x2572 0x2573 0xFF10 0xFF11 0xFF12 0xFF13 \ + 0xFF14 0xFF15 0xFF16 0xFF17 0xFF18 0xFF19 0x2160 0x2161 \ + 0x2162 0x2163 0x2164 0x2165 0x2166 0x2167 0x2168 0x2169 +26 0x3021 0x3022 0x3023 0x3024 0x3025 0x3026 0x3027 0x3028 \ + 0x3029 0x5341 0x5344 0x5345 0xFF21 0xFF22 0xFF23 0xFF24 \ + 0xFF25 0xFF26 0xFF27 0xFF28 0xFF29 0xFF2A 0xFF2B 0xFF2C \ + 0xFF2D 0xFF2E 0xFF2F 0xFF30 0xFF31 0xFF32 0xFF33 0xFF34 \ + 0xFF35 0xFF36 0xFF37 0xFF38 0xFF39 0xFF3A 0xFF41 0xFF42 \ + 0xFF43 0xFF44 0xFF45 0xFF46 0xFF47 0xFF48 0xFF49 0xFF4A \ + 0xFF4B 0xFF4C 0xFF4D 0xFF4E 0xFF4F 0xFF50 0xFF51 0xFF52 \ + 0xFF53 0xFF54 0xFF55 0xFF56 0xFF57 0xFF58 0xFF59 0xFF5A \ + 0x0391 0x0392 0x0393 0x0394 0x0395 0x0396 0x0397 0x0398 \ + 0x0399 0x039A 0x039B 0x039C 0x039D 0x039E 0x039F 0x03A0 \ + 0x03A1 0x03A3 0x03A4 0x03A5 0x03A6 0x03A7 0x03A8 0x03A9 \ + 0x03B1 0x03B2 0x03B3 0x03B4 0x03B5 0x03B6 0x03B7 0x03B8 \ + 0x03B9 0x03BA 0x03BB 0x03BC 0x03BD 0x03BE 0x03BF 0x03C0 \ + 0x03C1 0x03C3 0x03C4 0x03C5 0x03C6 0x03C7 0x03C8 0x03C9 \ + 0x3105 0x3106 0x3107 0x3108 0x3109 0x310A 0x310B 0x310C \ + 0x310D 0x310E 0x310F 0x79DA 0x79D9 0x79E1 0x79E5 0x79E8 \ + 0x79DB 0x79E2 0x79F0 0x7ADA 0x7ADD 0x7ADB 0x7ADC 0x7B0D \ + 0x7B0B 0x7B14 0x7C8E 0x7C86 0x7C87 0x7C83 0x7C8B 0x7D24 \ + 0x7D25 0x7F62 0x7F93 0x7F99 0x7F97 0x7FC4 0x7FC6 0x800A \ + 0x8040 0x803C 0x803B 0x80F6 0x3110 0x3111 0x3112 0x3113 \ + 0x3114 0x3115 0x3116 0x3117 0x3118 0x3119 0x311A 0x311B \ + 0x311C 0x311D 0x311E 0x311F 0x3120 0x3121 0x3122 0x3123 \ + 0x3124 0x3125 0x3126 0x3127 0x3128 0x3129 0x02D9 0x02C9 \ + 0x02CA 0x02C7 0x02CB 0x2400 0x2401 0x2402 0x2403 0x2404 \ + 0x2405 0x2406 0x2407 0x2408 0x2409 0x240A 0x240B 0x240C \ + 0x240D 0x240E 0x240F 0x2410 0x2411 0x2412 0x2413 0x2414 \ + 0x2415 0x2416 0x2417 0x2418 0x2419 0x241A 0x241B 0x241C \ + 0x241D 0x241E 0x241F 0x2421 0x532C 0x5359 0x5368 0x537E \ + 0x53A1 0x555B 0x5542 0x5547 0x553D 0x5560 0x57EB 0x595F \ + 0x5B6F 0x5C5A 0x5FA2 0x5F9D 0x5FA3 0x60C2 0x60A5 0x621C \ + 0x621D 0x6395 0x639A 0x63A6 0x6550 0x6552 0x65C8 0x6658 \ + 0x6888 0x6BB8 0x4E00 0x4E59 0x4E01 0x4E03 0x4E43 0x4E5D +27 0x4E86 0x4E8C 0x4EBA 0x513F 0x5165 0x516B 0x51E0 0x5200 \ + 0x5201 0x529B 0x5315 0x5341 0x535C 0x53C8 0x4E09 0x4E0B \ + 0x4E08 0x4E0A 0x4E2B 0x4E38 0x51E1 0x4E45 0x4E48 0x4E5F \ + 0x4E5E 0x4E8E 0x4EA1 0x5140 0x5203 0x52FA 0x5343 0x53C9 \ + 0x53E3 0x571F 0x58EB 0x5915 0x5927 0x5973 0x5B50 0x5B51 \ + 0x5B53 0x5BF8 0x5C0F 0x5C22 0x5C38 0x5C71 0x5DDD 0x5DE5 \ + 0x5DF1 0x5DF2 0x5DF3 0x5DFE 0x5E72 0x5EFE 0x5F0B 0x5F13 \ + 0x624D 0x80FF 0x80EE 0x8104 0x8103 0x8107 0x80F7 0x822D \ + 0x8227 0x8229 0x831F 0x8357 0x8321 0x8318 0x8358 0x8684 \ + 0x869F 0x869B 0x8689 0x86A6 0x8692 0x868F 0x86A0 0x884F \ + 0x8878 0x887A 0x886E 0x887B 0x8884 0x8873 0x8A0D 0x8A0B \ + 0x8A19 0x8ED0 0x4E11 0x4E10 0x4E0D 0x4E2D 0x4E30 0x4E39 \ + 0x4E4B 0x5C39 0x4E88 0x4E91 0x4E95 0x4E92 0x4E94 0x4EA2 \ + 0x4EC1 0x4EC0 0x4EC3 0x4EC6 0x4EC7 0x4ECD 0x4ECA 0x4ECB \ + 0x4EC4 0x5143 0x5141 0x5167 0x516D 0x516E 0x516C 0x5197 \ + 0x51F6 0x5206 0x5207 0x5208 0x52FB 0x52FE 0x52FF 0x5316 \ + 0x5339 0x5348 0x5347 0x5345 0x535E 0x5384 0x53CB 0x53CA \ + 0x53CD 0x58EC 0x5929 0x592B 0x592A 0x592D 0x5B54 0x5C11 \ + 0x5C24 0x5C3A 0x5C6F 0x5DF4 0x5E7B 0x5EFF 0x5F14 0x5F15 \ + 0x5FC3 0x6208 0x6236 0x624B 0x624E 0x652F 0x6587 0x6597 \ + 0x65A4 0x65B9 0x65E5 0x66F0 0x6708 0x6728 0x6B20 0x6B62 \ + 0x6B79 0x6BCB 0x6BD4 0x6BDB 0x6C0F 0x6C34 0x706B 0x722A \ + 0x7236 0x723B 0x7247 0x7259 0x725B 0x72AC 0x738B 0x4E19 \ + 0x4E16 0x4E15 0x4E14 0x4E18 0x4E3B 0x4E4D 0x4E4F 0x4E4E \ + 0x4EE5 0x4ED8 0x4ED4 0x4ED5 0x4ED6 0x4ED7 0x4EE3 0x4EE4 \ + 0x4ED9 0x4EDE 0x5145 0x5144 0x5189 0x518A 0x51AC 0x51F9 \ + 0x51FA 0x51F8 0x520A 0x52A0 0x529F 0x5305 0x5306 0x5317 \ + 0x531D 0x4EDF 0x534A 0x5349 0x5361 0x5360 0x536F 0x536E \ + 0x53BB 0x53EF 0x53E4 0x53F3 0x53EC 0x53EE 0x53E9 0x53E8 \ + 0x53FC 0x53F8 0x53F5 0x53EB 0x53E6 0x53EA 0x53F2 0x53F1 \ + 0x53F0 0x53E5 0x53ED 0x53FB 0x56DB 0x56DA 0x5916 0x8FF9 \ + 0x9009 0x9008 0x90DE 0x9151 0x91DB 0x91DF 0x91DE 0x91D6 +28 0x91E0 0x9585 0x9660 0x9659 0x9656 0x96BD 0x5042 0x5059 \ + 0x5044 0x5066 0x5052 0x5054 0x5071 0x5050 0x507B 0x507C \ + 0x5058 0x5079 0x506C 0x5078 0x51A8 0x51D1 0x51CF 0x5268 \ + 0x592E 0x5931 0x5974 0x5976 0x5B55 0x5B83 0x5C3C 0x5DE8 \ + 0x5DE7 0x5DE6 0x5E02 0x5E03 0x5E73 0x5E7C 0x5F01 0x5F18 \ + 0x5F17 0x5FC5 0x620A 0x6253 0x6254 0x6252 0x6251 0x65A5 \ + 0x65E6 0x672E 0x672C 0x672A 0x672B 0x672D 0x6B63 0x6BCD \ + 0x6C11 0x6C10 0x6C38 0x6C41 0x6C40 0x6C3E 0x72AF 0x7384 \ + 0x7389 0x74DC 0x74E6 0x7518 0x751F 0x7528 0x7529 0x7530 \ + 0x7531 0x7532 0x7533 0x758B 0x767D 0x76AE 0x76BF 0x76EE \ + 0x77DB 0x77E2 0x77F3 0x793A 0x79BE 0x7A74 0x7ACB 0x4E1E \ + 0x4E1F 0x4E52 0x4E53 0x4E69 0x4E99 0x4EA4 0x4EA6 0x4EA5 \ + 0x4EFF 0x4F09 0x4F19 0x4F0A 0x4F15 0x4F0D 0x4F10 0x4F11 \ + 0x4F0F 0x4EF2 0x4EF6 0x4EFB 0x4EF0 0x4EF3 0x4EFD 0x4F01 \ + 0x4F0B 0x5149 0x5147 0x5146 0x5148 0x5168 0x5171 0x518D \ + 0x51B0 0x5217 0x5211 0x5212 0x520E 0x5216 0x52A3 0x5308 \ + 0x5321 0x5320 0x5370 0x5371 0x5409 0x540F 0x540C 0x540A \ + 0x5410 0x5401 0x540B 0x5404 0x5411 0x540D 0x5408 0x5403 \ + 0x540E 0x5406 0x5412 0x56E0 0x56DE 0x56DD 0x5733 0x5730 \ + 0x5728 0x572D 0x572C 0x572F 0x5729 0x5919 0x591A 0x5937 \ + 0x5938 0x5984 0x5978 0x5983 0x597D 0x5979 0x5982 0x5981 \ + 0x5B57 0x5B58 0x5B87 0x5B88 0x5B85 0x5B89 0x5BFA 0x5C16 \ + 0x5C79 0x5DDE 0x5E06 0x5E76 0x5E74 0x5276 0x52D4 0x53A0 \ + 0x53C4 0x5558 0x554C 0x5568 0x5549 0x555D 0x5529 0x5554 \ + 0x5553 0x555A 0x553A 0x553F 0x552B 0x57EA 0x57EF 0x57DD \ + 0x57FE 0x57DE 0x57E6 0x57E8 0x57FF 0x5803 0x58F7 0x68A6 \ + 0x591F 0x595B 0x595D 0x595E 0x5A2B 0x5A3B 0x5F0F 0x5F1B \ + 0x5FD9 0x5FD6 0x620E 0x620C 0x620D 0x6210 0x6263 0x625B \ + 0x6258 0x6536 0x65E9 0x65E8 0x65EC 0x65ED 0x66F2 0x66F3 \ + 0x6709 0x673D 0x6734 0x6731 0x6735 0x6B21 0x6B64 0x6B7B \ + 0x6C16 0x6C5D 0x6C57 0x6C59 0x6C5F 0x6C60 0x6C50 0x6C55 \ + 0x6C61 0x6C5B 0x6C4D 0x6C4E 0x7070 0x725F 0x725D 0x767E +29 0x7AF9 0x7C73 0x7CF8 0x7F36 0x7F8A 0x7FBD 0x8001 0x8003 \ + 0x800C 0x8012 0x8033 0x807F 0x8089 0x808B 0x808C 0x81E3 \ + 0x81EA 0x81F3 0x81FC 0x820C 0x821B 0x821F 0x826E 0x8272 \ + 0x827E 0x866B 0x8840 0x884C 0x8863 0x897F 0x9621 0x4E32 \ + 0x4EA8 0x4F4D 0x4F4F 0x4F47 0x4F57 0x4F5E 0x4F34 0x4F5B \ + 0x4F55 0x4F30 0x4F50 0x4F51 0x4F3D 0x4F3A 0x4F38 0x4F43 \ + 0x4F54 0x4F3C 0x4F46 0x4F63 0x4F5C 0x4F60 0x4F2F 0x4F4E \ + 0x4F36 0x4F59 0x4F5D 0x4F48 0x4F5A 0x514C 0x514B 0x514D \ + 0x5175 0x51B6 0x51B7 0x5225 0x5224 0x5229 0x522A 0x5228 \ + 0x52AB 0x52A9 0x52AA 0x52AC 0x5323 0x5373 0x5375 0x541D \ + 0x542D 0x541E 0x543E 0x5426 0x544E 0x5427 0x5446 0x5443 \ + 0x5433 0x5448 0x5442 0x541B 0x5429 0x544A 0x5439 0x543B \ + 0x5438 0x542E 0x5435 0x5436 0x5420 0x543C 0x5440 0x5431 \ + 0x542B 0x541F 0x542C 0x56EA 0x56F0 0x56E4 0x56EB 0x574A \ + 0x5751 0x5740 0x574D 0x5A61 0x5A3A 0x5A6E 0x5A4B 0x5A6B \ + 0x5A45 0x5A4E 0x5A68 0x5A3D 0x5A71 0x5A3F 0x5A6F 0x5A75 \ + 0x5A73 0x5A2C 0x5A59 0x5A54 0x5A4F 0x5A63 0x5BC8 0x5BC3 \ + 0x5C5B 0x5C61 0x5D21 0x5D0A 0x5D09 0x5D2C 0x5D08 0x5D2A \ + 0x5D15 0x5D10 0x5D13 0x5D2F 0x5747 0x574E 0x573E 0x5750 \ + 0x574F 0x573B 0x58EF 0x593E 0x599D 0x5992 0x59A8 0x599E \ + 0x59A3 0x5999 0x5996 0x598D 0x59A4 0x5993 0x598A 0x59A5 \ + 0x5B5D 0x5B5C 0x5B5A 0x5B5B 0x5B8C 0x5B8B 0x5B8F 0x5C2C \ + 0x5C40 0x5C41 0x5C3F 0x5C3E 0x5C90 0x5C91 0x5C94 0x5C8C \ + 0x5DEB 0x5E0C 0x5E8F 0x5E87 0x5E8A 0x5EF7 0x5F04 0x5F1F \ + 0x5F64 0x5F62 0x5F77 0x5F79 0x5FD8 0x5FCC 0x5FD7 0x5FCD \ + 0x5FF1 0x5FEB 0x5FF8 0x5FEA 0x6212 0x6211 0x6284 0x6297 \ + 0x6296 0x6280 0x6276 0x6289 0x626D 0x628A 0x627C 0x627E \ + 0x6279 0x6273 0x6292 0x626F 0x6298 0x626E 0x6295 0x6293 \ + 0x6291 0x6286 0x6539 0x653B 0x6538 0x65F1 0x66F4 0x675F \ + 0x674E 0x674F 0x6750 0x6751 0x675C 0x6756 0x675E 0x6749 \ + 0x6746 0x6760 0x6753 0x6757 0x6B65 0x6BCF 0x6C42 0x6C5E \ + 0x6C99 0x6C81 0x6C88 0x6C89 0x6C85 0x6C9B 0x6C6A 0x6C7A +30 0x6C90 0x6C70 0x6C8C 0x6C68 0x6C96 0x6C92 0x6C7D 0x6C83 \ + 0x6C72 0x6C7E 0x6C74 0x6C86 0x6C76 0x6C8D 0x6C94 0x6C98 \ + 0x6C82 0x7076 0x707C 0x707D 0x7078 0x7262 0x7261 0x7260 \ + 0x72C4 0x72C2 0x7396 0x752C 0x752B 0x7537 0x7538 0x7682 \ + 0x76EF 0x77E3 0x79C1 0x79C0 0x79BF 0x7A76 0x7CFB 0x7F55 \ + 0x8096 0x8093 0x809D 0x8098 0x809B 0x809A 0x80B2 0x826F \ + 0x8292 0x5D18 0x5DE3 0x5E39 0x5E35 0x5E3A 0x5E32 0x5EBB \ + 0x5EBA 0x5F34 0x5F39 0x6098 0x60D0 0x60D7 0x60AA 0x60A1 \ + 0x60A4 0x60EE 0x60E7 0x60E8 0x60DE 0x637E 0x638B 0x6379 \ + 0x6386 0x6393 0x6373 0x636A 0x636C 0x637F 0x63B2 0x63BA \ + 0x6366 0x6374 0x828B 0x828D 0x898B 0x89D2 0x8A00 0x8C37 \ + 0x8C46 0x8C55 0x8C9D 0x8D64 0x8D70 0x8DB3 0x8EAB 0x8ECA \ + 0x8F9B 0x8FB0 0x8FC2 0x8FC6 0x8FC5 0x8FC4 0x5DE1 0x9091 \ + 0x90A2 0x90AA 0x90A6 0x90A3 0x9149 0x91C6 0x91CC 0x9632 \ + 0x962E 0x9631 0x962A 0x962C 0x4E26 0x4E56 0x4E73 0x4E8B \ + 0x4E9B 0x4E9E 0x4EAB 0x4EAC 0x4F6F 0x4F9D 0x4F8D 0x4F73 \ + 0x4F7F 0x4F6C 0x4F9B 0x4F8B 0x4F86 0x4F83 0x4F70 0x4F75 \ + 0x4F88 0x4F69 0x4F7B 0x4F96 0x4F7E 0x4F8F 0x4F91 0x4F7A \ + 0x5154 0x5152 0x5155 0x5169 0x5177 0x5176 0x5178 0x51BD \ + 0x51FD 0x523B 0x5238 0x5237 0x523A 0x5230 0x522E 0x5236 \ + 0x5241 0x52BE 0x52BB 0x5352 0x5354 0x5353 0x5351 0x5366 \ + 0x5377 0x5378 0x5379 0x53D6 0x53D4 0x53D7 0x5473 0x5475 \ + 0x5496 0x5478 0x5495 0x5480 0x547B 0x5477 0x5484 0x5492 \ + 0x5486 0x547C 0x5490 0x5471 0x5476 0x548C 0x549A 0x5462 \ + 0x5468 0x548B 0x547D 0x548E 0x56FA 0x5783 0x5777 0x576A \ + 0x5769 0x5761 0x5766 0x5764 0x577C 0x591C 0x5949 0x5947 \ + 0x5948 0x5944 0x5954 0x59BE 0x59BB 0x59D4 0x59B9 0x59AE \ + 0x59D1 0x59C6 0x59D0 0x59CD 0x59CB 0x59D3 0x59CA 0x59AF \ + 0x59B3 0x59D2 0x59C5 0x5B5F 0x5B64 0x5B63 0x5B97 0x5B9A \ + 0x5B98 0x5B9C 0x5B99 0x5B9B 0x5C1A 0x5C48 0x5C45 0x655A \ + 0x654E 0x654D 0x658D 0x658E 0x65AD 0x65C7 0x65CA 0x65C9 \ + 0x65E3 0x6657 0x6663 0x6667 0x671A 0x6719 0x6716 0x689E +31 0x68B6 0x6898 0x6873 0x689A 0x688E 0x68B7 0x68DB 0x68A5 \ + 0x686C 0x68C1 0x6884 0x6895 0x687A 0x6899 0x68B8 0x68B9 \ + 0x5C46 0x5CB7 0x5CA1 0x5CB8 0x5CA9 0x5CAB 0x5CB1 0x5CB3 \ + 0x5E18 0x5E1A 0x5E16 0x5E15 0x5E1B 0x5E11 0x5E78 0x5E9A \ + 0x5E97 0x5E9C 0x5E95 0x5E96 0x5EF6 0x5F26 0x5F27 0x5F29 \ + 0x5F80 0x5F81 0x5F7F 0x5F7C 0x5FDD 0x5FE0 0x5FFD 0x5FF5 \ + 0x5FFF 0x600F 0x6014 0x602F 0x6035 0x6016 0x602A 0x6015 \ + 0x6021 0x6027 0x6029 0x602B 0x601B 0x6216 0x6215 0x623F \ + 0x623E 0x6240 0x627F 0x62C9 0x62CC 0x62C4 0x62BF 0x62C2 \ + 0x62B9 0x62D2 0x62DB 0x62AB 0x62D3 0x62D4 0x62CB 0x62C8 \ + 0x62A8 0x62BD 0x62BC 0x62D0 0x62D9 0x62C7 0x62CD 0x62B5 \ + 0x62DA 0x62B1 0x62D8 0x62D6 0x62D7 0x62C6 0x62AC 0x62CE \ + 0x653E 0x65A7 0x65BC 0x65FA 0x6614 0x6613 0x660C 0x6606 \ + 0x6602 0x660E 0x6600 0x660F 0x6615 0x660A 0x6607 0x670D \ + 0x670B 0x676D 0x678B 0x6795 0x6771 0x679C 0x6773 0x6777 \ + 0x6787 0x679D 0x6797 0x676F 0x6770 0x677F 0x6789 0x677E \ + 0x6790 0x6775 0x679A 0x6793 0x677C 0x676A 0x6772 0x6B23 \ + 0x6B66 0x6B67 0x6B7F 0x6C13 0x6C1B 0x6CE3 0x6CE8 0x6CF3 \ + 0x6CB1 0x6CCC 0x6CE5 0x6CB3 0x6CBD 0x6CBE 0x6CBC 0x6CE2 \ + 0x6CAB 0x6CD5 0x6CD3 0x6CB8 0x6CC4 0x6CB9 0x6CC1 0x6CAE \ + 0x6CD7 0x6CC5 0x6CF1 0x6CBF 0x6CBB 0x6CE1 0x6CDB 0x6CCA \ + 0x6CAC 0x6CEF 0x6CDC 0x6CD6 0x6CE0 0x6870 0x6B35 0x6B90 \ + 0x6BBB 0x6BED 0x6DC1 0x6DC3 0x6DCE 0x6DAD 0x6E04 0x6DB9 \ + 0x6DE7 0x6E08 0x6E06 0x6E0A 0x6DB0 0x6DF8 0x6E0C 0x6DB1 \ + 0x6E02 0x6E07 0x6E09 0x6E01 0x6E17 0x6DFF 0x6E12 0x7103 \ + 0x7107 0x7101 0x70F5 0x70F1 0x7108 0x70F2 0x7095 0x708E \ + 0x7092 0x708A 0x7099 0x722C 0x722D 0x7238 0x7248 0x7267 \ + 0x7269 0x72C0 0x72CE 0x72D9 0x72D7 0x72D0 0x73A9 0x73A8 \ + 0x739F 0x73AB 0x73A5 0x753D 0x759D 0x7599 0x759A 0x7684 \ + 0x76C2 0x76F2 0x76F4 0x77E5 0x77FD 0x793E 0x7940 0x7941 \ + 0x79C9 0x79C8 0x7A7A 0x7A79 0x7AFA 0x7CFE 0x7F54 0x7F8C \ + 0x7F8B 0x8005 0x80BA 0x80A5 0x80A2 0x80B1 0x80A1 0x80AB +32 0x80A9 0x80B4 0x80AA 0x80AF 0x81E5 0x81FE 0x820D 0x82B3 \ + 0x829D 0x8299 0x82AD 0x82BD 0x829F 0x82B9 0x82B1 0x82AC \ + 0x82A5 0x82AF 0x82B8 0x82A3 0x82B0 0x82BE 0x82B7 0x864E \ + 0x8671 0x521D 0x8868 0x8ECB 0x8FCE 0x8FD4 0x8FD1 0x90B5 \ + 0x90B8 0x90B1 0x90B6 0x91C7 0x91D1 0x9577 0x9580 0x961C \ + 0x9640 0x963F 0x963B 0x9644 0x9642 0x96B9 0x96E8 0x9752 \ + 0x975E 0x4E9F 0x4EAD 0x4EAE 0x4FE1 0x4FB5 0x4FAF 0x4FBF \ + 0x4FE0 0x4FD1 0x4FCF 0x4FDD 0x4FC3 0x4FB6 0x4FD8 0x4FDF \ + 0x4FCA 0x4FD7 0x4FAE 0x4FD0 0x4FC4 0x4FC2 0x4FDA 0x4FCE \ + 0x4FDE 0x4FB7 0x5157 0x5192 0x5191 0x51A0 0x524E 0x5243 \ + 0x524A 0x524D 0x524C 0x524B 0x5247 0x52C7 0x52C9 0x52C3 \ + 0x52C1 0x530D 0x5357 0x537B 0x539A 0x53DB 0x54AC 0x54C0 \ + 0x54A8 0x54CE 0x54C9 0x54B8 0x54A6 0x54B3 0x54C7 0x54C2 \ + 0x54BD 0x54AA 0x54C1 0x710F 0x70FE 0x731A 0x7310 0x730E \ + 0x7402 0x73F3 0x73FB 0x751B 0x7523 0x7561 0x7568 0x7567 \ + 0x75D3 0x7690 0x76D5 0x76D7 0x76D6 0x7730 0x7726 0x7740 \ + 0x771E 0x7847 0x784B 0x7851 0x784F 0x7842 0x7846 0x796E \ + 0x796C 0x79F2 0x79F1 0x79F5 0x54C4 0x54C8 0x54AF 0x54AB \ + 0x54B1 0x54BB 0x54A9 0x54A7 0x54BF 0x56FF 0x5782 0x578B \ + 0x57A0 0x57A3 0x57A2 0x57CE 0x57AE 0x5793 0x5955 0x5951 \ + 0x594F 0x594E 0x5950 0x59DC 0x59D8 0x59FF 0x59E3 0x59E8 \ + 0x5A03 0x59E5 0x59EA 0x59DA 0x59E6 0x5A01 0x59FB 0x5B69 \ + 0x5BA3 0x5BA6 0x5BA4 0x5BA2 0x5BA5 0x5C01 0x5C4E 0x5C4F \ + 0x5C4D 0x5C4B 0x5CD9 0x5CD2 0x5DF7 0x5E1D 0x5E25 0x5E1F \ + 0x5E7D 0x5EA0 0x5EA6 0x5EFA 0x5F08 0x5F2D 0x5F65 0x5F88 \ + 0x5F85 0x5F8A 0x5F8B 0x5F87 0x5F8C 0x5F89 0x6012 0x601D \ + 0x6020 0x6025 0x600E 0x6028 0x604D 0x6070 0x6068 0x6062 \ + 0x6046 0x6043 0x606C 0x606B 0x606A 0x6064 0x6241 0x62DC \ + 0x6316 0x6309 0x62FC 0x62ED 0x6301 0x62EE 0x62FD 0x6307 \ + 0x62F1 0x62F7 0x62EF 0x62EC 0x62FE 0x62F4 0x6311 0x6302 \ + 0x653F 0x6545 0x65AB 0x65BD 0x65E2 0x6625 0x662D 0x6620 \ + 0x6627 0x662F 0x661F 0x6628 0x6631 0x6624 0x66F7 0x67FF +33 0x67D3 0x67F1 0x67D4 0x67D0 0x67EC 0x67B6 0x67AF 0x67F5 \ + 0x67E9 0x67EF 0x67C4 0x67D1 0x67B4 0x67DA 0x67E5 0x67B8 \ + 0x67CF 0x67DE 0x67F3 0x67B0 0x67D9 0x67E2 0x67DD 0x67D2 \ + 0x6B6A 0x6B83 0x6B86 0x6BB5 0x6BD2 0x6BD7 0x6C1F 0x6CC9 \ + 0x6D0B 0x6D32 0x6D2A 0x6D41 0x6D25 0x6D0C 0x6D31 0x6D1E \ + 0x6D17 0x79F3 0x79F9 0x7A9A 0x7A93 0x7A91 0x7AE1 0x7B21 \ + 0x7B1C 0x7B16 0x7B17 0x7B36 0x7B1F 0x7C93 0x7C99 0x7C9A \ + 0x7C9C 0x7D49 0x7D34 0x7D37 0x7D2D 0x7D4C 0x7D48 0x7F3B \ + 0x8008 0x801A 0x801D 0x8049 0x8045 0x8044 0x7C9B 0x812A \ + 0x812E 0x8131 0x6D3B 0x6D3D 0x6D3E 0x6D36 0x6D1B 0x6CF5 \ + 0x6D39 0x6D27 0x6D38 0x6D29 0x6D2E 0x6D35 0x6D0E 0x6D2B \ + 0x70AB 0x70BA 0x70B3 0x70AC 0x70AF 0x70AD 0x70B8 0x70AE \ + 0x70A4 0x7230 0x7272 0x726F 0x7274 0x72E9 0x72E0 0x72E1 \ + 0x73B7 0x73CA 0x73BB 0x73B2 0x73CD 0x73C0 0x73B3 0x751A \ + 0x752D 0x754F 0x754C 0x754E 0x754B 0x75AB 0x75A4 0x75A5 \ + 0x75A2 0x75A3 0x7678 0x7686 0x7687 0x7688 0x76C8 0x76C6 \ + 0x76C3 0x76C5 0x7701 0x76F9 0x76F8 0x7709 0x770B 0x76FE \ + 0x76FC 0x7707 0x77DC 0x7802 0x7814 0x780C 0x780D 0x7946 \ + 0x7949 0x7948 0x7947 0x79B9 0x79BA 0x79D1 0x79D2 0x79CB \ + 0x7A7F 0x7A81 0x7AFF 0x7AFD 0x7C7D 0x7D02 0x7D05 0x7D00 \ + 0x7D09 0x7D07 0x7D04 0x7D06 0x7F38 0x7F8E 0x7FBF 0x8004 \ + 0x8010 0x800D 0x8011 0x8036 0x80D6 0x80E5 0x80DA 0x80C3 \ + 0x80C4 0x80CC 0x80E1 0x80DB 0x80CE 0x80DE 0x80E4 0x80DD \ + 0x81F4 0x8222 0x82E7 0x8303 0x8305 0x82E3 0x82DB 0x82E6 \ + 0x8304 0x82E5 0x8302 0x8309 0x82D2 0x82D7 0x82F1 0x8301 \ + 0x82DC 0x82D4 0x82D1 0x82DE 0x82D3 0x82DF 0x82EF 0x8306 \ + 0x8650 0x8679 0x867B 0x867A 0x884D 0x886B 0x8981 0x89D4 \ + 0x8A08 0x8A02 0x8A03 0x8C9E 0x8CA0 0x8D74 0x8D73 0x8DB4 \ + 0x8ECD 0x8ECC 0x8FF0 0x8FE6 0x8FE2 0x8FEA 0x8FE5 0x811A \ + 0x8134 0x8117 0x831D 0x8371 0x8384 0x8380 0x8372 0x83A1 \ + 0x8379 0x8391 0x839F 0x83AD 0x8323 0x8385 0x839C 0x83B7 \ + 0x8658 0x865A 0x8657 0x86B2 0x86AE 0x8845 0x889C 0x8894 +34 0x88A3 0x888F 0x88A5 0x88A9 0x88A6 0x888A 0x88A0 0x8890 \ + 0x8FED 0x8FEB 0x8FE4 0x8FE8 0x90CA 0x90CE 0x90C1 0x90C3 \ + 0x914B 0x914A 0x91CD 0x9582 0x9650 0x964B 0x964C 0x964D \ + 0x9762 0x9769 0x97CB 0x97ED 0x97F3 0x9801 0x98A8 0x98DB \ + 0x98DF 0x9996 0x9999 0x4E58 0x4EB3 0x500C 0x500D 0x5023 \ + 0x4FEF 0x5026 0x5025 0x4FF8 0x5029 0x5016 0x5006 0x503C \ + 0x501F 0x501A 0x5012 0x5011 0x4FFA 0x5000 0x5014 0x5028 \ + 0x4FF1 0x5021 0x500B 0x5019 0x5018 0x4FF3 0x4FEE 0x502D \ + 0x502A 0x4FFE 0x502B 0x5009 0x517C 0x51A4 0x51A5 0x51A2 \ + 0x51CD 0x51CC 0x51C6 0x51CB 0x5256 0x525C 0x5254 0x525B \ + 0x525D 0x532A 0x537F 0x539F 0x539D 0x53DF 0x54E8 0x5510 \ + 0x5501 0x5537 0x54FC 0x54E5 0x54F2 0x5506 0x54FA 0x5514 \ + 0x54E9 0x54ED 0x54E1 0x5509 0x54EE 0x54EA 0x54E6 0x5527 \ + 0x5507 0x54FD 0x550F 0x5703 0x5704 0x57C2 0x57D4 0x57CB \ + 0x57C3 0x5809 0x590F 0x5957 0x5958 0x595A 0x5A11 0x5A18 \ + 0x5A1C 0x5A1F 0x5A1B 0x5A13 0x59EC 0x5A20 0x5A23 0x5A29 \ + 0x5A25 0x5A0C 0x5A09 0x5B6B 0x5C58 0x5BB0 0x5BB3 0x5BB6 \ + 0x5BB4 0x5BAE 0x5BB5 0x5BB9 0x5BB8 0x5C04 0x5C51 0x5C55 \ + 0x5C50 0x5CED 0x5CFD 0x5CFB 0x5CEA 0x5CE8 0x5CF0 0x5CF6 \ + 0x5D01 0x5CF4 0x5DEE 0x5E2D 0x5E2B 0x5EAB 0x5EAD 0x5EA7 \ + 0x5F31 0x5F92 0x5F91 0x5F90 0x6059 0x8992 0x8991 0x8994 \ + 0x8A26 0x8A32 0x8A28 0x8A1C 0x8A2B 0x8A20 0x8A29 0x8A21 \ + 0x8C3A 0x8C5B 0x8C58 0x8C7C 0x8CA6 0x8CAE 0x8CAD 0x8D65 \ + 0x8D7E 0x8D7C 0x8D7F 0x8D7A 0x8DBD 0x8DC0 0x8DBB 0x8EAD \ + 0x8EAF 0x8ED6 0x8ED9 0x9012 0x900E 0x9025 0x6063 0x6065 \ + 0x6050 0x6055 0x606D 0x6069 0x606F 0x6084 0x609F 0x609A \ + 0x608D 0x6094 0x608C 0x6085 0x6096 0x6247 0x62F3 0x6308 \ + 0x62FF 0x634E 0x633E 0x632F 0x6355 0x6342 0x6346 0x634F \ + 0x6349 0x633A 0x6350 0x633D 0x632A 0x632B 0x6328 0x634D \ + 0x634C 0x6548 0x6549 0x6599 0x65C1 0x65C5 0x6642 0x6649 \ + 0x664F 0x6643 0x6652 0x664C 0x6645 0x6641 0x66F8 0x6714 \ + 0x6715 0x6717 0x6821 0x6838 0x6848 0x6846 0x6853 0x6839 +35 0x6842 0x6854 0x6829 0x68B3 0x6817 0x684C 0x6851 0x683D \ + 0x67F4 0x6850 0x6840 0x683C 0x6843 0x682A 0x6845 0x6813 \ + 0x6818 0x6841 0x6B8A 0x6B89 0x6BB7 0x6C23 0x6C27 0x6C28 \ + 0x6C26 0x6C24 0x6CF0 0x6D6A 0x6D95 0x6D88 0x6D87 0x6D66 \ + 0x6D78 0x6D77 0x6D59 0x6D93 0x6D6C 0x6D89 0x6D6E 0x6D5A \ + 0x6D74 0x6D69 0x6D8C 0x6D8A 0x6D79 0x6D85 0x6D65 0x6D94 \ + 0x70CA 0x70D8 0x70E4 0x70D9 0x70C8 0x70CF 0x7239 0x7279 \ + 0x72FC 0x72F9 0x72FD 0x72F8 0x72F7 0x7386 0x73ED 0x7409 \ + 0x73EE 0x73E0 0x73EA 0x73DE 0x7554 0x755D 0x755C 0x755A \ + 0x7559 0x75BE 0x75C5 0x75C7 0x75B2 0x75B3 0x75BD 0x75BC \ + 0x75B9 0x75C2 0x75B8 0x768B 0x76B0 0x76CA 0x76CD 0x76CE \ + 0x7729 0x771F 0x7720 0x7728 0x77E9 0x7830 0x7827 0x7838 \ + 0x781D 0x7834 0x7837 0x9013 0x90EE 0x90AB 0x90F7 0x9159 \ + 0x9154 0x91F2 0x91F0 0x91E5 0x91F6 0x9587 0x965A 0x966E \ + 0x9679 0x98E1 0x98E6 0x9EC4 0x9ED2 0x4E80 0x4E81 0x508F \ + 0x5097 0x5088 0x5089 0x5081 0x5160 0x5E42 0x51D3 0x51D2 \ + 0x51D6 0x5273 0x5270 0x53A8 0x7825 0x782D 0x7820 0x781F \ + 0x7832 0x7955 0x7950 0x7960 0x795F 0x7956 0x795E 0x795D \ + 0x7957 0x795A 0x79E4 0x79E3 0x79E7 0x79DF 0x79E6 0x79E9 \ + 0x79D8 0x7A84 0x7A88 0x7AD9 0x7B06 0x7B11 0x7C89 0x7D21 \ + 0x7D17 0x7D0B 0x7D0A 0x7D20 0x7D22 0x7D14 0x7D10 0x7D15 \ + 0x7D1A 0x7D1C 0x7D0D 0x7D19 0x7D1B 0x7F3A 0x7F5F 0x7F94 \ + 0x7FC5 0x7FC1 0x8006 0x8018 0x8015 0x8019 0x8017 0x803D \ + 0x803F 0x80F1 0x8102 0x80F0 0x8105 0x80ED 0x80F4 0x8106 \ + 0x80F8 0x80F3 0x8108 0x80FD 0x810A 0x80FC 0x80EF 0x81ED \ + 0x81EC 0x8200 0x8210 0x822A 0x822B 0x8228 0x822C 0x82BB \ + 0x832B 0x8352 0x8354 0x834A 0x8338 0x8350 0x8349 0x8335 \ + 0x8334 0x834F 0x8332 0x8339 0x8336 0x8317 0x8340 0x8331 \ + 0x8328 0x8343 0x8654 0x868A 0x86AA 0x8693 0x86A4 0x86A9 \ + 0x868C 0x86A3 0x869C 0x8870 0x8877 0x8881 0x8882 0x887D \ + 0x8879 0x8A18 0x8A10 0x8A0E 0x8A0C 0x8A15 0x8A0A 0x8A17 \ + 0x8A13 0x8A16 0x8A0F 0x8A11 0x8C48 0x8C7A 0x8C79 0x8CA1 +36 0x8CA2 0x8D77 0x8EAC 0x8ED2 0x8ED4 0x8ECF 0x8FB1 0x9001 \ + 0x9006 0x8FF7 0x9000 0x8FFA 0x8FF4 0x9003 0x8FFD 0x9005 \ + 0x8FF8 0x9095 0x90E1 0x90DD 0x90E2 0x9152 0x914D 0x914C \ + 0x91D8 0x91DD 0x91D7 0x91DC 0x91D9 0x9583 0x9662 0x9663 \ + 0x9661 0x53A6 0x53C5 0x5597 0x55DE 0x5596 0x55B4 0x5585 \ + 0x559B 0x55A0 0x5559 0x5586 0x55AF 0x557A 0x559E 0x55A9 \ + 0x570F 0x570E 0x581A 0x581F 0x583C 0x5818 0x583E 0x5826 \ + 0x583A 0x5822 0x58FB 0x5963 0x5964 0x5AA8 0x5AA3 0x5A82 \ + 0x5A88 0x5AA1 0x965B 0x965D 0x9664 0x9658 0x965E 0x96BB \ + 0x98E2 0x99AC 0x9AA8 0x9AD8 0x9B25 0x9B32 0x9B3C 0x4E7E \ + 0x507A 0x507D 0x505C 0x5047 0x5043 0x504C 0x505A 0x5049 \ + 0x5065 0x5076 0x504E 0x5055 0x5075 0x5074 0x5077 0x504F \ + 0x500F 0x506F 0x506D 0x515C 0x5195 0x51F0 0x526A 0x526F \ + 0x52D2 0x52D9 0x52D8 0x52D5 0x5310 0x530F 0x5319 0x533F \ + 0x5340 0x533E 0x53C3 0x66FC 0x5546 0x556A 0x5566 0x5544 \ + 0x555E 0x5561 0x5543 0x554A 0x5531 0x5556 0x554F 0x5555 \ + 0x552F 0x5564 0x5538 0x552E 0x555C 0x552C 0x5563 0x5533 \ + 0x5541 0x5557 0x5708 0x570B 0x5709 0x57DF 0x5805 0x580A \ + 0x5806 0x57E0 0x57E4 0x57FA 0x5802 0x5835 0x57F7 0x57F9 \ + 0x5920 0x5962 0x5A36 0x5A41 0x5A49 0x5A66 0x5A6A 0x5A40 \ + 0x5A3C 0x5A62 0x5A5A 0x5A46 0x5A4A 0x5B70 0x5BC7 0x5BC5 \ + 0x5BC4 0x5BC2 0x5BBF 0x5BC6 0x5C09 0x5C08 0x5C07 0x5C60 \ + 0x5C5C 0x5C5D 0x5D07 0x5D06 0x5D0E 0x5D1B 0x5D16 0x5D22 \ + 0x5D11 0x5D29 0x5D14 0x5D19 0x5D24 0x5D27 0x5D17 0x5DE2 \ + 0x5E38 0x5E36 0x5E33 0x5E37 0x5EB7 0x5EB8 0x5EB6 0x5EB5 \ + 0x5EBE 0x5F35 0x5F37 0x5F57 0x5F6C 0x5F69 0x5F6B 0x5F97 \ + 0x5F99 0x5F9E 0x5F98 0x5FA1 0x5FA0 0x5F9C 0x607F 0x60A3 \ + 0x6089 0x60A0 0x60A8 0x60CB 0x60B4 0x60E6 0x60BD 0x5A85 \ + 0x5A98 0x5A99 0x5A89 0x5A81 0x5A96 0x5A80 0x5A91 0x5ACF \ + 0x5A87 0x5AA0 0x5A79 0x5A86 0x5AAB 0x5AAA 0x5AA4 0x5A8D \ + 0x5A7E 0x5BD5 0x5C1E 0x5C5F 0x5C5E 0x5D44 0x5D3E 0x5D48 \ + 0x5D1C 0x5D5B 0x5D4D 0x5D57 0x5D53 0x5D4F 0x5D3B 0x5D46 +37 0x60C5 0x60BB 0x60B5 0x60DC 0x60BC 0x60D8 0x60D5 0x60C6 \ + 0x60DF 0x60B8 0x60DA 0x60C7 0x621A 0x621B 0x6248 0x63A0 \ + 0x63A7 0x6372 0x6396 0x63A2 0x63A5 0x6377 0x6367 0x6398 \ + 0x63AA 0x6371 0x63A9 0x6389 0x6383 0x639B 0x636B 0x63A8 \ + 0x6384 0x6388 0x6399 0x63A1 0x63AC 0x6392 0x638F 0x6380 \ + 0x637B 0x6369 0x6368 0x637A 0x655D 0x6556 0x6551 0x6559 \ + 0x6557 0x555F 0x654F 0x6558 0x6555 0x6554 0x659C 0x659B \ + 0x65AC 0x65CF 0x65CB 0x65CC 0x65CE 0x665D 0x665A 0x6664 \ + 0x6668 0x6666 0x665E 0x66F9 0x52D7 0x671B 0x6881 0x68AF \ + 0x68A2 0x6893 0x68B5 0x687F 0x6876 0x68B1 0x68A7 0x6897 \ + 0x68B0 0x6883 0x68C4 0x68AD 0x6886 0x6885 0x6894 0x689D \ + 0x68A8 0x689F 0x68A1 0x6882 0x6B32 0x6BBA 0x6BEB 0x6BEC \ + 0x6C2B 0x6D8E 0x6DBC 0x6DF3 0x6DD9 0x6DB2 0x6DE1 0x6DCC \ + 0x6DE4 0x6DFB 0x6DFA 0x6E05 0x6DC7 0x6DCB 0x6DAF 0x6DD1 \ + 0x6DAE 0x6DDE 0x6DF9 0x6DB8 0x6DF7 0x6DF5 0x6DC5 0x6DD2 \ + 0x6E1A 0x6DB5 0x6DDA 0x6DEB 0x6DD8 0x6DEA 0x6DF1 0x6DEE \ + 0x6DE8 0x6DC6 0x6DC4 0x6DAA 0x6DEC 0x6DBF 0x6DE6 0x70F9 \ + 0x7109 0x710A 0x70FD 0x70EF 0x723D 0x727D 0x7281 0x731C \ + 0x731B 0x7316 0x7313 0x7319 0x7387 0x7405 0x740A 0x7403 \ + 0x7406 0x73FE 0x740D 0x74E0 0x74F6 0x5E46 0x5E47 0x5E48 \ + 0x5EC0 0x5EBD 0x5EBF 0x5F11 0x5F3E 0x5F3B 0x5F3A 0x5FA7 \ + 0x60EA 0x6107 0x6122 0x610C 0x60B3 0x60D6 0x60D2 0x60E3 \ + 0x60E5 0x60E9 0x6111 0x60FD 0x611E 0x6120 0x6121 0x621E \ + 0x63E2 0x63DE 0x63E6 0x63F8 0x63FE 0x63C1 0x74F7 0x751C \ + 0x7522 0x7565 0x7566 0x7562 0x7570 0x758F 0x75D4 0x75D5 \ + 0x75B5 0x75CA 0x75CD 0x768E 0x76D4 0x76D2 0x76DB 0x7737 \ + 0x773E 0x773C 0x7736 0x7738 0x773A 0x786B 0x7843 0x784E \ + 0x7965 0x7968 0x796D 0x79FB 0x7A92 0x7A95 0x7B20 0x7B28 \ + 0x7B1B 0x7B2C 0x7B26 0x7B19 0x7B1E 0x7B2E 0x7C92 0x7C97 \ + 0x7C95 0x7D46 0x7D43 0x7D71 0x7D2E 0x7D39 0x7D3C 0x7D40 \ + 0x7D30 0x7D33 0x7D44 0x7D2F 0x7D42 0x7D32 0x7D31 0x7F3D \ + 0x7F9E 0x7F9A 0x7FCC 0x7FCE 0x7FD2 0x801C 0x804A 0x8046 +38 0x812F 0x8116 0x8123 0x812B 0x8129 0x8130 0x8124 0x8202 \ + 0x8235 0x8237 0x8236 0x8239 0x838E 0x839E 0x8398 0x8378 \ + 0x83A2 0x8396 0x83BD 0x83AB 0x8392 0x838A 0x8393 0x8389 \ + 0x83A0 0x8377 0x837B 0x837C 0x8386 0x83A7 0x8655 0x5F6A \ + 0x86C7 0x86C0 0x86B6 0x86C4 0x86B5 0x86C6 0x86CB 0x86B1 \ + 0x86AF 0x86C9 0x8853 0x889E 0x8888 0x88AB 0x8892 0x8896 \ + 0x888D 0x888B 0x8993 0x898F 0x8A2A 0x8A1D 0x8A23 0x8A25 \ + 0x8A31 0x8A2D 0x8A1F 0x8A1B 0x8A22 0x8C49 0x8C5A 0x8CA9 \ + 0x8CAC 0x8CAB 0x8CA8 0x8CAA 0x8CA7 0x8D67 0x8D66 0x8DBE \ + 0x8DBA 0x8EDB 0x8EDF 0x9019 0x900D 0x901A 0x9017 0x9023 \ + 0x901F 0x901D 0x9010 0x9015 0x901E 0x9020 0x900F 0x9022 \ + 0x9016 0x901B 0x9014 0x63BF 0x63F7 0x63D1 0x655F 0x6560 \ + 0x6561 0x65D1 0x667D 0x666B 0x667F 0x6673 0x6681 0x666D \ + 0x6669 0x671E 0x68ED 0x6903 0x68FE 0x68E5 0x691E 0x6902 \ + 0x6909 0x68CA 0x6900 0x6901 0x6918 0x68E2 0x68CF 0x692E \ + 0x68C5 0x68FF 0x691C 0x68C3 0x90E8 0x90ED 0x90FD 0x9157 \ + 0x91CE 0x91F5 0x91E6 0x91E3 0x91E7 0x91ED 0x91E9 0x9589 \ + 0x966A 0x9675 0x9673 0x9678 0x9670 0x9674 0x9676 0x9677 \ + 0x966C 0x96C0 0x96EA 0x96E9 0x7AE0 0x7ADF 0x9802 0x9803 \ + 0x9B5A 0x9CE5 0x9E75 0x9E7F 0x9EA5 0x9EBB 0x50A2 0x508D \ + 0x5085 0x5099 0x5091 0x5080 0x5096 0x5098 0x509A 0x6700 \ + 0x51F1 0x5272 0x5274 0x5275 0x5269 0x52DE 0x52DD 0x52DB \ + 0x535A 0x53A5 0x557B 0x5580 0x55A7 0x557C 0x558A 0x559D \ + 0x5598 0x5582 0x559C 0x55AA 0x5594 0x5587 0x558B 0x5583 \ + 0x55B3 0x55AE 0x559F 0x553E 0x55B2 0x559A 0x55BB 0x55AC \ + 0x55B1 0x557E 0x5589 0x55AB 0x5599 0x570D 0x582F 0x582A \ + 0x5834 0x5824 0x5830 0x5831 0x5821 0x581D 0x5820 0x58F9 \ + 0x58FA 0x5960 0x5A77 0x5A9A 0x5A7F 0x5A92 0x5A9B 0x5AA7 \ + 0x5B73 0x5B71 0x5BD2 0x5BCC 0x5BD3 0x5BD0 0x5C0A 0x5C0B \ + 0x5C31 0x5D4C 0x5D50 0x5D34 0x5D47 0x5DFD 0x5E45 0x5E3D \ + 0x5E40 0x5E43 0x5E7E 0x5ECA 0x5EC1 0x5EC2 0x5EC4 0x5F3C \ + 0x5F6D 0x5FA9 0x5FAA 0x5FA8 0x60D1 0x60E1 0x60B2 0x60B6 +39 0x60E0 0x611C 0x6123 0x60FA 0x6115 0x60F0 0x60FB 0x60F4 \ + 0x6168 0x60F1 0x610E 0x60F6 0x6109 0x6100 0x6112 0x621F \ + 0x6249 0x63A3 0x638C 0x63CF 0x63C0 0x63E9 0x63C9 0x63C6 \ + 0x63CD 0x6B6F 0x6B6E 0x6BBE 0x6BF4 0x6C2D 0x6DB6 0x6E75 \ + 0x6E1E 0x6E18 0x6E48 0x6E4F 0x6E42 0x6E6A 0x6E70 0x6DFE \ + 0x6E6D 0x6E7B 0x6E7E 0x6E59 0x6E57 0x6E80 0x6E50 0x6E29 \ + 0x6E76 0x6E2A 0x6E4C 0x712A 0x7135 0x712C 0x7137 0x711D \ + 0x7138 0x7134 0x63D2 0x63E3 0x63D0 0x63E1 0x63D6 0x63ED \ + 0x63EE 0x6376 0x63F4 0x63EA 0x63DB 0x6452 0x63DA 0x63F9 \ + 0x655E 0x6566 0x6562 0x6563 0x6591 0x6590 0x65AF 0x666E \ + 0x6670 0x6674 0x6676 0x666F 0x6691 0x667A 0x667E 0x6677 \ + 0x66FE 0x66FF 0x671F 0x671D 0x68FA 0x68D5 0x68E0 0x68D8 \ + 0x68D7 0x6905 0x68DF 0x68F5 0x68EE 0x68E7 0x68F9 0x68D2 \ + 0x68F2 0x68E3 0x68CB 0x68CD 0x690D 0x6912 0x690E 0x68C9 \ + 0x68DA 0x696E 0x68FB 0x6B3E 0x6B3A 0x6B3D 0x6B98 0x6B96 \ + 0x6BBC 0x6BEF 0x6C2E 0x6C2F 0x6C2C 0x6E2F 0x6E38 0x6E54 \ + 0x6E21 0x6E32 0x6E67 0x6E4A 0x6E20 0x6E25 0x6E23 0x6E1B \ + 0x6E5B 0x6E58 0x6E24 0x6E56 0x6E6E 0x6E2D 0x6E26 0x6E6F \ + 0x6E34 0x6E4D 0x6E3A 0x6E2C 0x6E43 0x6E1D 0x6E3E 0x6ECB \ + 0x6E89 0x6E19 0x6E4E 0x6E63 0x6E44 0x6E72 0x6E69 0x6E5F \ + 0x7119 0x711A 0x7126 0x7130 0x7121 0x7136 0x716E 0x711C \ + 0x724C 0x7284 0x7280 0x7336 0x7325 0x7334 0x7329 0x743A \ + 0x742A 0x7433 0x7422 0x7425 0x7435 0x7436 0x7434 0x742F \ + 0x741B 0x7426 0x7428 0x7525 0x7526 0x756B 0x756A 0x75E2 \ + 0x75DB 0x75E3 0x75D9 0x75D8 0x75DE 0x75E0 0x767B 0x767C \ + 0x7696 0x7693 0x76B4 0x76DC 0x774F 0x77ED 0x785D 0x786C \ + 0x786F 0x7A0D 0x7A08 0x7A0B 0x7A05 0x7A00 0x7A98 0x712B \ + 0x7133 0x7127 0x7124 0x712D 0x7232 0x7283 0x7282 0x7287 \ + 0x7306 0x7324 0x7338 0x732A 0x732C 0x732B 0x732F 0x7328 \ + 0x7417 0x7419 0x7438 0x741F 0x7414 0x743C 0x73F7 0x741C \ + 0x7415 0x7418 0x7439 0x74F9 0x7524 0x756E 0x756D 0x7571 \ + 0x7A97 0x7A96 0x7AE5 0x7AE3 0x7B49 0x7B56 0x7B46 0x7B50 +40 0x7B52 0x7B54 0x7B4D 0x7B4B 0x7B4F 0x7B51 0x7C9F 0x7CA5 \ + 0x7D5E 0x7D50 0x7D68 0x7D55 0x7D2B 0x7D6E 0x7D72 0x7D61 \ + 0x7D66 0x7D62 0x7D70 0x7D73 0x5584 0x7FD4 0x7FD5 0x800B \ + 0x8052 0x8085 0x8155 0x8154 0x814B 0x8151 0x814E 0x8139 \ + 0x8146 0x813E 0x814C 0x8153 0x8174 0x8212 0x821C 0x83E9 \ + 0x8403 0x83F8 0x840D 0x83E0 0x83C5 0x840B 0x83C1 0x83EF \ + 0x83F1 0x83F4 0x8457 0x840A 0x83F0 0x840C 0x83CC 0x83FD \ + 0x83F2 0x83CA 0x8438 0x840E 0x8404 0x83DC 0x8407 0x83D4 \ + 0x83DF 0x865B 0x86DF 0x86D9 0x86ED 0x86D4 0x86DB 0x86E4 \ + 0x86D0 0x86DE 0x8857 0x88C1 0x88C2 0x88B1 0x8983 0x8996 \ + 0x8A3B 0x8A60 0x8A55 0x8A5E 0x8A3C 0x8A41 0x8A54 0x8A5B \ + 0x8A50 0x8A46 0x8A34 0x8A3A 0x8A36 0x8A56 0x8C61 0x8C82 \ + 0x8CAF 0x8CBC 0x8CB3 0x8CBD 0x8CC1 0x8CBB 0x8CC0 0x8CB4 \ + 0x8CB7 0x8CB6 0x8CBF 0x8CB8 0x8D8A 0x8D85 0x8D81 0x8DCE \ + 0x8DDD 0x8DCB 0x8DDA 0x8DD1 0x8DCC 0x8DDB 0x8DC6 0x8EFB \ + 0x8EF8 0x8EFC 0x8F9C 0x902E 0x9035 0x9031 0x9038 0x9032 \ + 0x9036 0x9102 0x90F5 0x9109 0x90FE 0x9163 0x9165 0x91CF \ + 0x9214 0x9215 0x9223 0x9209 0x921E 0x920D 0x9210 0x9207 \ + 0x9211 0x9594 0x958F 0x958B 0x9591 0x758E 0x75E5 0x7694 \ + 0x76B3 0x76D9 0x7748 0x7749 0x7743 0x7742 0x77DF 0x7863 \ + 0x7876 0x785F 0x7866 0x7966 0x7971 0x7976 0x7984 0x7975 \ + 0x79FF 0x7A07 0x7A0E 0x7A09 0x7AE7 0x7AE2 0x7B55 0x7B43 \ + 0x7B57 0x7B6C 0x7B42 0x7B53 0x7B41 0x7CA0 0x9593 0x9592 \ + 0x958E 0x968A 0x968E 0x968B 0x967D 0x9685 0x9686 0x968D \ + 0x9672 0x9684 0x96C1 0x96C5 0x96C4 0x96C6 0x96C7 0x96EF \ + 0x96F2 0x97CC 0x9805 0x9806 0x9808 0x98E7 0x98EA 0x98EF \ + 0x98E9 0x98F2 0x98ED 0x99AE 0x99AD 0x9EC3 0x9ECD 0x9ED1 \ + 0x4E82 0x50AD 0x50B5 0x50B2 0x50B3 0x50C5 0x50BE 0x50AC \ + 0x50B7 0x50BB 0x50AF 0x50C7 0x527F 0x5277 0x527D 0x52DF \ + 0x52E6 0x52E4 0x52E2 0x52E3 0x532F 0x55DF 0x55E8 0x55D3 \ + 0x55E6 0x55CE 0x55DC 0x55C7 0x55D1 0x55E3 0x55E4 0x55EF \ + 0x55DA 0x55E1 0x55C5 0x55C6 0x55E5 0x55C9 0x5712 0x5713 +41 0x585E 0x5851 0x5858 0x5857 0x585A 0x5854 0x586B 0x584C \ + 0x586D 0x584A 0x5862 0x5852 0x584B 0x5967 0x5AC1 0x5AC9 \ + 0x5ACC 0x5ABE 0x5ABD 0x5ABC 0x5AB3 0x5AC2 0x5AB2 0x5D69 \ + 0x5D6F 0x5E4C 0x5E79 0x5EC9 0x5EC8 0x5F12 0x5F59 0x5FAC \ + 0x5FAE 0x611A 0x610F 0x6148 0x611F 0x60F3 0x611B 0x60F9 \ + 0x6101 0x6108 0x614E 0x614C 0x6144 0x614D 0x613E 0x6134 \ + 0x6127 0x610D 0x6106 0x6137 0x6221 0x6222 0x6413 0x643E \ + 0x641E 0x642A 0x642D 0x643D 0x642C 0x640F 0x641C 0x6414 \ + 0x640D 0x6436 0x6416 0x6417 0x6406 0x656C 0x659F 0x65B0 \ + 0x6697 0x6689 0x6687 0x6688 0x6696 0x6684 0x6698 0x668D \ + 0x6703 0x6994 0x696D 0x7CA6 0x7CA4 0x7D74 0x7D59 0x7D60 \ + 0x7D57 0x7D6C 0x7D7E 0x7D64 0x7D5A 0x7D5D 0x7D76 0x7D4D \ + 0x7D75 0x7FD3 0x7FD6 0x8060 0x804E 0x8145 0x813B 0x8148 \ + 0x8142 0x8149 0x8140 0x8114 0x8141 0x81EF 0x81F6 0x8203 \ + 0x83ED 0x83DA 0x8418 0x83D2 0x695A 0x6977 0x6960 0x6954 \ + 0x6975 0x6930 0x6982 0x694A 0x6968 0x696B 0x695E 0x6953 \ + 0x6979 0x6986 0x695D 0x6963 0x695B 0x6B47 0x6B72 0x6BC0 \ + 0x6BBF 0x6BD3 0x6BFD 0x6EA2 0x6EAF 0x6ED3 0x6EB6 0x6EC2 \ + 0x6E90 0x6E9D 0x6EC7 0x6EC5 0x6EA5 0x6E98 0x6EBC 0x6EBA \ + 0x6EAB 0x6ED1 0x6E96 0x6E9C 0x6EC4 0x6ED4 0x6EAA 0x6EA7 \ + 0x6EB4 0x714E 0x7159 0x7169 0x7164 0x7149 0x7167 0x715C \ + 0x716C 0x7166 0x714C 0x7165 0x715E 0x7146 0x7168 0x7156 \ + 0x723A 0x7252 0x7337 0x7345 0x733F 0x733E 0x746F 0x745A \ + 0x7455 0x745F 0x745E 0x7441 0x743F 0x7459 0x745B 0x745C \ + 0x7576 0x7578 0x7600 0x75F0 0x7601 0x75F2 0x75F1 0x75FA \ + 0x75FF 0x75F4 0x75F3 0x76DE 0x76DF 0x775B 0x776B 0x7766 \ + 0x775E 0x7763 0x7779 0x776A 0x776C 0x775C 0x7765 0x7768 \ + 0x7762 0x77EE 0x788E 0x78B0 0x7897 0x7898 0x788C 0x7889 \ + 0x787C 0x7891 0x7893 0x787F 0x797A 0x797F 0x7981 0x842C \ + 0x79BD 0x7A1C 0x7A1A 0x7A20 0x7A14 0x7A1F 0x7A1E 0x7A9F \ + 0x7AA0 0x7B77 0x7BC0 0x7B60 0x7B6E 0x7B67 0x7CB1 0x7CB3 \ + 0x7CB5 0x7D93 0x7D79 0x7D91 0x7D81 0x7D8F 0x7D5B 0x7F6E +42 0x7F69 0x7F6A 0x7F72 0x7FA9 0x7FA8 0x7FA4 0x8056 0x8058 \ + 0x8086 0x8084 0x8171 0x8170 0x8178 0x8165 0x816E 0x8173 \ + 0x816B 0x8408 0x8400 0x8417 0x8346 0x8414 0x83D3 0x8405 \ + 0x841F 0x8402 0x8416 0x83CD 0x83E6 0x865D 0x86D5 0x86E1 \ + 0x86EE 0x8847 0x8846 0x88BB 0x88BF 0x88B4 0x88B5 0x899A \ + 0x8A43 0x8A5A 0x8A35 0x8A38 0x8A42 0x8A49 0x8A5D 0x8A4B \ + 0x8A3D 0x8C60 0x8179 0x817A 0x8166 0x8205 0x8247 0x8482 \ + 0x8477 0x843D 0x8431 0x8475 0x8466 0x846B 0x8449 0x846C \ + 0x845B 0x843C 0x8435 0x8461 0x8463 0x8469 0x846D 0x8446 \ + 0x865E 0x865C 0x865F 0x86F9 0x8713 0x8708 0x8707 0x8700 \ + 0x86FE 0x86FB 0x8702 0x8703 0x8706 0x870A 0x8859 0x88DF \ + 0x88D4 0x88D9 0x88DC 0x88D8 0x88DD 0x88E1 0x88CA 0x88D5 \ + 0x88D2 0x899C 0x89E3 0x8A6B 0x8A72 0x8A73 0x8A66 0x8A69 \ + 0x8A70 0x8A87 0x8A7C 0x8A63 0x8AA0 0x8A71 0x8A85 0x8A6D \ + 0x8A62 0x8A6E 0x8A6C 0x8A79 0x8A7B 0x8A3E 0x8A68 0x8C62 \ + 0x8C8A 0x8C89 0x8CCA 0x8CC7 0x8CC8 0x8CC4 0x8CB2 0x8CC3 \ + 0x8CC2 0x8CC5 0x8DE1 0x8DDF 0x8DE8 0x8DEF 0x8DF3 0x8DFA \ + 0x8DEA 0x8DE4 0x8DE6 0x8EB2 0x8F03 0x8F09 0x8EFE 0x8F0A \ + 0x8F9F 0x8FB2 0x904B 0x904A 0x9053 0x9042 0x9054 0x903C \ + 0x9055 0x9050 0x9047 0x904F 0x904E 0x904D 0x9051 0x903E \ + 0x9041 0x9112 0x9117 0x916C 0x916A 0x9169 0x91C9 0x9237 \ + 0x9257 0x9238 0x923D 0x9240 0x923E 0x925B 0x924B 0x9264 \ + 0x9251 0x9234 0x9249 0x924D 0x9245 0x9239 0x923F 0x925A \ + 0x9598 0x9698 0x9694 0x9695 0x96CD 0x96CB 0x96C9 0x96CA \ + 0x96F7 0x96FB 0x96F9 0x96F6 0x9756 0x9774 0x9776 0x9810 \ + 0x9811 0x9813 0x980A 0x9812 0x980C 0x98FC 0x98F4 0x8C5E \ + 0x8C7F 0x8C7E 0x8C83 0x8CB1 0x8D87 0x8D88 0x8D83 0x8D86 \ + 0x8D8B 0x8D82 0x8DCA 0x8DD2 0x8DD4 0x8DC9 0x8EB0 0x8EF2 \ + 0x8EE4 0x8EF3 0x8EEA 0x8EFD 0x8F9D 0x902B 0x902A 0x9028 \ + 0x9029 0x902C 0x903A 0x9030 0x9037 0x903B 0x910A 0x91FE \ + 0x98FD 0x98FE 0x99B3 0x99B1 0x99B4 0x9AE1 0x9CE9 0x9E82 \ + 0x9F0E 0x9F13 0x9F20 0x50E7 0x50EE 0x50E5 0x50D6 0x50ED +43 0x50DA 0x50D5 0x50CF 0x50D1 0x50F1 0x50CE 0x50E9 0x5162 \ + 0x51F3 0x5283 0x5282 0x5331 0x53AD 0x55FE 0x5600 0x561B \ + 0x5617 0x55FD 0x5614 0x5606 0x5609 0x560D 0x560E 0x55F7 \ + 0x5616 0x561F 0x5608 0x5610 0x55F6 0x5718 0x5716 0x5875 \ + 0x587E 0x5883 0x5893 0x588A 0x5879 0x5885 0x587D 0x58FD \ + 0x5925 0x5922 0x5924 0x596A 0x5969 0x5AE1 0x5AE6 0x5AE9 \ + 0x5AD7 0x5AD6 0x5AD8 0x5AE3 0x5B75 0x5BDE 0x5BE7 0x5BE1 \ + 0x5BE5 0x5BE6 0x5BE8 0x5BE2 0x5BE4 0x5BDF 0x5C0D 0x5C62 \ + 0x5D84 0x5D87 0x5E5B 0x5E63 0x5E55 0x5E57 0x5E54 0x5ED3 \ + 0x5ED6 0x5F0A 0x5F46 0x5F70 0x5FB9 0x6147 0x613F 0x614B \ + 0x6177 0x6162 0x6163 0x615F 0x615A 0x6158 0x6175 0x622A \ + 0x6487 0x6458 0x6454 0x64A4 0x6478 0x645F 0x647A 0x6451 \ + 0x6467 0x6434 0x646D 0x647B 0x6572 0x65A1 0x65D7 0x65D6 \ + 0x66A2 0x66A8 0x669D 0x699C 0x69A8 0x6995 0x69C1 0x69AE \ + 0x69D3 0x69CB 0x699B 0x69B7 0x69BB 0x69AB 0x69B4 0x69D0 \ + 0x69CD 0x69AD 0x69CC 0x69A6 0x69C3 0x69A3 0x6B49 0x6B4C \ + 0x6C33 0x6F33 0x6F14 0x6EFE 0x6F13 0x6EF4 0x6F29 0x6F3E \ + 0x6F20 0x6F2C 0x6F0F 0x6F02 0x6F22 0x9220 0x920B 0x9218 \ + 0x9222 0x921B 0x9208 0x920E 0x9213 0x9595 0x968C 0x967B \ + 0x967F 0x9681 0x9682 0x96EE 0x96ED 0x96EC 0x975F 0x976F \ + 0x976D 0x98F0 0x9AA9 0x9AE0 0x4EB7 0x50CC 0x50BC 0x50AA \ + 0x50B9 0x50AB 0x50C3 0x50CD 0x517E 0x527E 0x6EFF 0x6EEF \ + 0x6F06 0x6F31 0x6F38 0x6F32 0x6F23 0x6F15 0x6F2B 0x6F2F \ + 0x6F88 0x6F2A 0x6EEC 0x6F01 0x6EF2 0x6ECC 0x6EF7 0x7194 \ + 0x7199 0x717D 0x718A 0x7184 0x7192 0x723E 0x7292 0x7296 \ + 0x7344 0x7350 0x7464 0x7463 0x746A 0x7470 0x746D 0x7504 \ + 0x7591 0x7627 0x760D 0x760B 0x7609 0x7613 0x76E1 0x76E3 \ + 0x7784 0x777D 0x777F 0x7761 0x78C1 0x789F 0x78A7 0x78B3 \ + 0x78A9 0x78A3 0x798E 0x798F 0x798D 0x7A2E 0x7A31 0x7AAA \ + 0x7AA9 0x7AED 0x7AEF 0x7BA1 0x7B95 0x7B8B 0x7B75 0x7B97 \ + 0x7B9D 0x7B94 0x7B8F 0x7BB8 0x7B87 0x7B84 0x7CB9 0x7CBD \ + 0x7CBE 0x7DBB 0x7DB0 0x7D9C 0x7DBD 0x7DBE 0x7DA0 0x7DCA +44 0x7DB4 0x7DB2 0x7DB1 0x7DBA 0x7DA2 0x7DBF 0x7DB5 0x7DB8 \ + 0x7DAD 0x7DD2 0x7DC7 0x7DAC 0x7F70 0x7FE0 0x7FE1 0x7FDF \ + 0x805E 0x805A 0x8087 0x8150 0x8180 0x818F 0x8188 0x818A \ + 0x817F 0x8182 0x81E7 0x81FA 0x8207 0x8214 0x821E 0x824B \ + 0x84C9 0x84BF 0x84C6 0x84C4 0x8499 0x849E 0x84B2 0x849C \ + 0x84CB 0x84B8 0x84C0 0x84D3 0x8490 0x84BC 0x84D1 0x84CA \ + 0x873F 0x871C 0x873B 0x8722 0x8725 0x8734 0x8718 0x8755 \ + 0x8737 0x8729 0x88F3 0x8902 0x88F4 0x88F9 0x88F8 0x88FD \ + 0x88E8 0x891A 0x88EF 0x8AA6 0x8A8C 0x8A9E 0x8AA3 0x8A8D \ + 0x8AA1 0x8A93 0x8AA4 0x5279 0x52E1 0x52E0 0x52E7 0x5380 \ + 0x53AB 0x53AA 0x53A9 0x53E0 0x55EA 0x55D7 0x55C1 0x5715 \ + 0x586C 0x585C 0x5850 0x5861 0x586A 0x5869 0x5856 0x5860 \ + 0x5866 0x585F 0x5923 0x5966 0x5968 0x5ACE 0x5AC5 0x5AC3 \ + 0x5AD0 0x5B74 0x5B76 0x5BDC 0x8AAA 0x8AA5 0x8AA8 0x8A98 \ + 0x8A91 0x8A9A 0x8AA7 0x8C6A 0x8C8D 0x8C8C 0x8CD3 0x8CD1 \ + 0x8CD2 0x8D6B 0x8D99 0x8D95 0x8DFC 0x8F14 0x8F12 0x8F15 \ + 0x8F13 0x8FA3 0x9060 0x9058 0x905C 0x9063 0x9059 0x905E \ + 0x9062 0x905D 0x905B 0x9119 0x9118 0x911E 0x9175 0x9178 \ + 0x9177 0x9174 0x9278 0x9280 0x9285 0x9298 0x9296 0x927B \ + 0x9293 0x929C 0x92A8 0x927C 0x9291 0x95A1 0x95A8 0x95A9 \ + 0x95A3 0x95A5 0x95A4 0x9699 0x969C 0x969B 0x96CC 0x96D2 \ + 0x9700 0x977C 0x9785 0x97F6 0x9817 0x9818 0x98AF 0x98B1 \ + 0x9903 0x9905 0x990C 0x9909 0x99C1 0x9AAF 0x9AB0 0x9AE6 \ + 0x9B41 0x9B42 0x9CF4 0x9CF6 0x9CF3 0x9EBC 0x9F3B 0x9F4A \ + 0x5104 0x5100 0x50FB 0x50F5 0x50F9 0x5102 0x5108 0x5109 \ + 0x5105 0x51DC 0x5287 0x5288 0x5289 0x528D 0x528A 0x52F0 \ + 0x53B2 0x562E 0x563B 0x5639 0x5632 0x563F 0x5634 0x5629 \ + 0x5653 0x564E 0x5657 0x5674 0x5636 0x562F 0x5630 0x5880 \ + 0x589F 0x589E 0x58B3 0x589C 0x58AE 0x58A9 0x58A6 0x596D \ + 0x5B09 0x5AFB 0x5B0B 0x5AF5 0x5B0C 0x5B08 0x5BEE 0x5BEC \ + 0x5BE9 0x5BEB 0x5C64 0x5C65 0x5D9D 0x5D94 0x5E62 0x5E5F \ + 0x5E61 0x5EE2 0x5EDA 0x5EDF 0x5EDD 0x5EE3 0x5EE0 0x5F48 +45 0x5F71 0x5FB7 0x5FB5 0x6176 0x6167 0x616E 0x615D 0x6155 \ + 0x6182 0x5BD7 0x5BDA 0x5BDB 0x5C20 0x5D6D 0x5D66 0x5D64 \ + 0x5D6E 0x5D60 0x5F42 0x5F5A 0x5F6E 0x6130 0x613A 0x612A \ + 0x6143 0x6119 0x6131 0x613D 0x6408 0x6432 0x6438 0x6431 \ + 0x6419 0x6411 0x6429 0x641D 0x643C 0x6446 0x6447 0x643A \ + 0x6407 0x656B 0x617C 0x6170 0x616B 0x617E 0x61A7 0x6190 \ + 0x61AB 0x618E 0x61AC 0x619A 0x61A4 0x6194 0x61AE 0x622E \ + 0x6469 0x646F 0x6479 0x649E 0x64B2 0x6488 0x6490 0x64B0 \ + 0x64A5 0x6493 0x6495 0x64A9 0x6492 0x64AE 0x64AD 0x64AB \ + 0x649A 0x64AC 0x6499 0x64A2 0x64B3 0x6575 0x6577 0x6578 \ + 0x66AE 0x66AB 0x66B4 0x66B1 0x6A23 0x6A1F 0x69E8 0x6A01 \ + 0x6A1E 0x6A19 0x69FD 0x6A21 0x6A13 0x6A0A 0x69F3 0x6A02 \ + 0x6A05 0x69ED 0x6A11 0x6B50 0x6B4E 0x6BA4 0x6BC5 0x6BC6 \ + 0x6F3F 0x6F7C 0x6F84 0x6F51 0x6F66 0x6F54 0x6F86 0x6F6D \ + 0x6F5B 0x6F78 0x6F6E 0x6F8E 0x6F7A 0x6F70 0x6F64 0x6F97 \ + 0x6F58 0x6ED5 0x6F6F 0x6F60 0x6F5F 0x719F 0x71AC 0x71B1 \ + 0x71A8 0x7256 0x729B 0x734E 0x7357 0x7469 0x748B 0x7483 \ + 0x747E 0x7480 0x757F 0x7620 0x7629 0x761F 0x7624 0x7626 \ + 0x7621 0x7622 0x769A 0x76BA 0x76E4 0x778E 0x7787 0x778C \ + 0x7791 0x778B 0x78CB 0x78C5 0x78BA 0x78CA 0x78BE 0x78D5 \ + 0x78BC 0x78D0 0x7A3F 0x7A3C 0x7A40 0x7A3D 0x7A37 0x7A3B \ + 0x7AAF 0x7AAE 0x7BAD 0x7BB1 0x7BC4 0x7BB4 0x7BC6 0x7BC7 \ + 0x7BC1 0x7BA0 0x7BCC 0x7CCA 0x7DE0 0x7DF4 0x7DEF 0x7DFB \ + 0x7DD8 0x7DEC 0x7DDD 0x7DE8 0x7DE3 0x7DDA 0x7DDE 0x7DE9 \ + 0x7D9E 0x7DD9 0x7DF2 0x7DF9 0x7F75 0x7F77 0x7FAF 0x6570 \ + 0x656D 0x65E4 0x6693 0x668F 0x6692 0x668E 0x6946 0x6931 \ + 0x693E 0x697C 0x6943 0x6973 0x6955 0x6985 0x694D 0x6950 \ + 0x6947 0x6967 0x6936 0x6964 0x6961 0x697D 0x6B44 0x6B40 \ + 0x6B71 0x6B73 0x6B9C 0x6BC1 0x6BFA 0x6C31 0x6C32 0x6EB8 \ + 0x7FE9 0x8026 0x819B 0x819C 0x819D 0x81A0 0x819A 0x8198 \ + 0x8517 0x853D 0x851A 0x84EE 0x852C 0x852D 0x8513 0x8511 \ + 0x8523 0x8521 0x8514 0x84EC 0x8525 0x84FF 0x8506 0x8782 +46 0x8774 0x8776 0x8760 0x8766 0x8778 0x8768 0x8759 0x8757 \ + 0x874C 0x8753 0x885B 0x885D 0x8910 0x8907 0x8912 0x8913 \ + 0x8915 0x890A 0x8ABC 0x8AD2 0x8AC7 0x8AC4 0x8A95 0x8ACB \ + 0x8AF8 0x8AB2 0x8AC9 0x8AC2 0x8ABF 0x8AB0 0x8AD6 0x8ACD \ + 0x8AB6 0x8AB9 0x8ADB 0x8C4C 0x8C4E 0x8C6C 0x8CE0 0x8CDE \ + 0x8CE6 0x8CE4 0x8CEC 0x8CED 0x8CE2 0x8CE3 0x8CDC 0x8CEA \ + 0x8CE1 0x8D6D 0x8D9F 0x8DA3 0x8E2B 0x8E10 0x8E1D 0x8E22 \ + 0x8E0F 0x8E29 0x8E1F 0x8E21 0x8E1E 0x8EBA 0x8F1D 0x8F1B \ + 0x8F1F 0x8F29 0x8F26 0x8F2A 0x8F1C 0x8F1E 0x8F25 0x9069 \ + 0x906E 0x9068 0x906D 0x9077 0x9130 0x912D 0x9127 0x9131 \ + 0x9187 0x9189 0x918B 0x9183 0x92C5 0x92BB 0x92B7 0x92EA \ + 0x92AC 0x92E4 0x92C1 0x92B3 0x92BC 0x92D2 0x92C7 0x92F0 \ + 0x92B2 0x95AD 0x95B1 0x9704 0x9706 0x9707 0x9709 0x9760 \ + 0x978D 0x978B 0x978F 0x9821 0x982B 0x981C 0x98B3 0x990A \ + 0x9913 0x9912 0x9918 0x99DD 0x99D0 0x99DF 0x99DB 0x99D1 \ + 0x99D5 0x99D2 0x99D9 0x9AB7 0x9AEE 0x9AEF 0x9B27 0x9B45 \ + 0x9B44 0x9B77 0x9B6F 0x9D06 0x9D09 0x6EA8 0x6E91 0x6EBB \ + 0x6E9A 0x6EA9 0x6EB5 0x6E6C 0x6EE8 0x6EDD 0x6EDA 0x6EE6 \ + 0x6EAC 0x6ED9 0x6EE3 0x6EE9 0x6EDB 0x716F 0x7148 0x714A \ + 0x716B 0x714F 0x7157 0x7174 0x7145 0x7151 0x716D 0x7251 \ + 0x7250 0x724E 0x7341 0x732E 0x7346 0x7427 0x9D03 0x9EA9 \ + 0x9EBE 0x9ECE 0x58A8 0x9F52 0x5112 0x5118 0x5114 0x5110 \ + 0x5115 0x5180 0x51AA 0x51DD 0x5291 0x5293 0x52F3 0x5659 \ + 0x566B 0x5679 0x5669 0x5664 0x5678 0x566A 0x5668 0x5665 \ + 0x5671 0x566F 0x566C 0x5662 0x5676 0x58C1 0x58BE 0x58C7 \ + 0x58C5 0x596E 0x5B1D 0x5B34 0x5B78 0x5BF0 0x5C0E 0x5F4A \ + 0x61B2 0x6191 0x61A9 0x618A 0x61CD 0x61B6 0x61BE 0x61CA \ + 0x61C8 0x6230 0x64C5 0x64C1 0x64CB 0x64BB 0x64BC 0x64DA \ + 0x64C4 0x64C7 0x64C2 0x64CD 0x64BF 0x64D2 0x64D4 0x64BE \ + 0x6574 0x66C6 0x66C9 0x66B9 0x66C4 0x66C7 0x66B8 0x6A3D \ + 0x6A38 0x6A3A 0x6A59 0x6A6B 0x6A58 0x6A39 0x6A44 0x6A62 \ + 0x6A61 0x6A4B 0x6A47 0x6A35 0x6A5F 0x6A48 0x6B59 0x6B77 +47 0x6C05 0x6FC2 0x6FB1 0x6FA1 0x6FC3 0x6FA4 0x6FC1 0x6FA7 \ + 0x6FB3 0x6FC0 0x6FB9 0x6FB6 0x6FA6 0x6FA0 0x6FB4 0x71BE \ + 0x71C9 0x71D0 0x71D2 0x71C8 0x71D5 0x71B9 0x71CE 0x71D9 \ + 0x71DC 0x71C3 0x71C4 0x7368 0x749C 0x74A3 0x7498 0x749F \ + 0x749E 0x74E2 0x750C 0x750D 0x7634 0x7638 0x763A 0x76E7 \ + 0x76E5 0x77A0 0x779E 0x779F 0x77A5 0x78E8 0x78DA 0x78EC \ + 0x78E7 0x79A6 0x7A4D 0x7A4E 0x7A46 0x7A4C 0x7A4B 0x7ABA \ + 0x7BD9 0x7C11 0x7BC9 0x7BE4 0x7BDB 0x7BE1 0x7BE9 0x7BE6 \ + 0x7CD5 0x7CD6 0x7E0A 0x7448 0x7453 0x743D 0x745D 0x7456 \ + 0x741E 0x7447 0x7443 0x7458 0x7449 0x744C 0x7445 0x743E \ + 0x7501 0x751E 0x757A 0x75EE 0x7602 0x7697 0x7698 0x775D \ + 0x7764 0x7753 0x7758 0x7882 0x7890 0x788A 0x787A 0x787D \ + 0x788B 0x7878 0x788D 0x7888 0x7E11 0x7E08 0x7E1B 0x7E23 \ + 0x7E1E 0x7E1D 0x7E09 0x7E10 0x7F79 0x7FB2 0x7FF0 0x7FF1 \ + 0x7FEE 0x8028 0x81B3 0x81A9 0x81A8 0x81FB 0x8208 0x8258 \ + 0x8259 0x854A 0x8559 0x8548 0x8568 0x8569 0x8543 0x8549 \ + 0x856D 0x856A 0x855E 0x8783 0x879F 0x879E 0x87A2 0x878D \ + 0x8861 0x892A 0x8932 0x8925 0x892B 0x8921 0x89AA 0x89A6 \ + 0x8AE6 0x8AFA 0x8AEB 0x8AF1 0x8B00 0x8ADC 0x8AE7 0x8AEE \ + 0x8AFE 0x8B01 0x8B02 0x8AF7 0x8AED 0x8AF3 0x8AF6 0x8AFC \ + 0x8C6B 0x8C6D 0x8C93 0x8CF4 0x8E44 0x8E31 0x8E34 0x8E42 \ + 0x8E39 0x8E35 0x8F3B 0x8F2F 0x8F38 0x8F33 0x8FA8 0x8FA6 \ + 0x9075 0x9074 0x9078 0x9072 0x907C 0x907A 0x9134 0x9192 \ + 0x9320 0x9336 0x92F8 0x9333 0x932F 0x9322 0x92FC 0x932B \ + 0x9304 0x931A 0x9310 0x9326 0x9321 0x9315 0x932E 0x9319 \ + 0x95BB 0x96A7 0x96A8 0x96AA 0x96D5 0x970E 0x9711 0x9716 \ + 0x970D 0x9713 0x970F 0x975B 0x975C 0x9766 0x9798 0x9830 \ + 0x9838 0x983B 0x9837 0x982D 0x9839 0x9824 0x9910 0x9928 \ + 0x991E 0x991B 0x9921 0x991A 0x99ED 0x99E2 0x99F1 0x9AB8 \ + 0x9ABC 0x9AFB 0x9AED 0x9B28 0x9B91 0x9D15 0x9D23 0x9D26 \ + 0x9D28 0x9D12 0x9D1B 0x9ED8 0x9ED4 0x9F8D 0x9F9C 0x512A \ + 0x511F 0x5121 0x5132 0x52F5 0x568E 0x5680 0x5690 0x5685 +48 0x5687 0x7892 0x797E 0x7983 0x7980 0x7A0F 0x7A1D 0x7AA1 \ + 0x7AA4 0x7AE9 0x7AEA 0x7B62 0x7B6B 0x7B5E 0x7B79 0x7B6F \ + 0x7B68 0x7CAE 0x7CB0 0x7D90 0x7D8A 0x7D8B 0x7D99 0x7D95 \ + 0x7D87 0x7D78 0x7D97 0x7D89 0x7D98 0x7FA3 0x7FDD 0x8057 \ + 0x8163 0x816A 0x568F 0x58D5 0x58D3 0x58D1 0x58CE 0x5B30 \ + 0x5B2A 0x5B24 0x5B7A 0x5C37 0x5C68 0x5DBC 0x5DBA 0x5DBD \ + 0x5DB8 0x5E6B 0x5F4C 0x5FBD 0x61C9 0x61C2 0x61C7 0x61E6 \ + 0x61CB 0x6232 0x6234 0x64CE 0x64CA 0x64D8 0x64E0 0x64F0 \ + 0x64E6 0x64EC 0x64F1 0x64E2 0x64ED 0x6582 0x6583 0x66D9 \ + 0x66D6 0x6A80 0x6A94 0x6A84 0x6AA2 0x6A9C 0x6ADB 0x6AA3 \ + 0x6A7E 0x6A97 0x6A90 0x6AA0 0x6B5C 0x6BAE 0x6BDA 0x6C08 \ + 0x6FD8 0x6FF1 0x6FDF 0x6FE0 0x6FDB 0x6FE4 0x6FEB 0x6FEF \ + 0x6F80 0x6FEC 0x6FE1 0x6FE9 0x6FD5 0x6FEE 0x6FF0 0x71E7 \ + 0x71DF 0x71EE 0x71E6 0x71E5 0x71ED 0x71EC 0x71F4 0x71E0 \ + 0x7235 0x7246 0x7370 0x7372 0x74A9 0x74B0 0x74A6 0x74A8 \ + 0x7646 0x7642 0x764C 0x76EA 0x77B3 0x77AA 0x77B0 0x77AC \ + 0x77A7 0x77AD 0x77EF 0x78F7 0x78FA 0x78F4 0x78EF 0x7901 \ + 0x79A7 0x79AA 0x7A57 0x7ABF 0x7C07 0x7C0D 0x7BFE 0x7BF7 \ + 0x7C0C 0x7BE0 0x7CE0 0x7CDC 0x7CDE 0x7CE2 0x7CDF 0x7CD9 \ + 0x7CDD 0x7E2E 0x7E3E 0x7E46 0x7E37 0x7E32 0x7E43 0x7E2B \ + 0x7E3D 0x7E31 0x7E45 0x7E41 0x7E34 0x7E39 0x7E48 0x7E35 \ + 0x7E3F 0x7E2F 0x7F44 0x7FF3 0x7FFC 0x8071 0x8072 0x8070 \ + 0x806F 0x8073 0x81C6 0x81C3 0x81BA 0x81C2 0x81C0 0x81BF \ + 0x81BD 0x81C9 0x81BE 0x81E8 0x8209 0x8271 0x85AA 0x816C \ + 0x815D 0x8175 0x815F 0x817D 0x816D 0x8241 0x844F 0x8484 \ + 0x847F 0x8448 0x842A 0x847B 0x8472 0x8464 0x842E 0x845C \ + 0x8453 0x8441 0x84C8 0x8462 0x8480 0x843E 0x8483 0x8471 \ + 0x844A 0x8455 0x8458 0x86FC 0x86FD 0x8715 0x8716 0x86FF \ + 0x8584 0x857E 0x859C 0x8591 0x8594 0x85AF 0x859B 0x8587 \ + 0x85A8 0x858A 0x8667 0x87C0 0x87D1 0x87B3 0x87D2 0x87C6 \ + 0x87AB 0x87BB 0x87BA 0x87C8 0x87CB 0x893B 0x8936 0x8944 \ + 0x8938 0x893D 0x89AC 0x8B0E 0x8B17 0x8B19 0x8B1B 0x8B0A +49 0x8B20 0x8B1D 0x8B04 0x8B10 0x8C41 0x8C3F 0x8C73 0x8CFA \ + 0x8CFD 0x8CFC 0x8CF8 0x8CFB 0x8DA8 0x8E49 0x8E4B 0x8E48 \ + 0x8E4A 0x8F44 0x8F3E 0x8F42 0x8F45 0x8F3F 0x907F 0x907D \ + 0x9084 0x9081 0x9082 0x9080 0x9139 0x91A3 0x919E 0x919C \ + 0x934D 0x9382 0x9328 0x9375 0x934A 0x9365 0x934B 0x9318 \ + 0x937E 0x936C 0x935B 0x9370 0x935A 0x9354 0x95CA 0x95CB \ + 0x95CC 0x95C8 0x95C6 0x96B1 0x96B8 0x96D6 0x971C 0x971E \ + 0x97A0 0x97D3 0x9846 0x98B6 0x9935 0x9A01 0x99FF 0x9BAE \ + 0x9BAB 0x9BAA 0x9BAD 0x9D3B 0x9D3F 0x9E8B 0x9ECF 0x9EDE \ + 0x9EDC 0x9EDD 0x9EDB 0x9F3E 0x9F4B 0x53E2 0x5695 0x56AE \ + 0x58D9 0x58D8 0x5B38 0x5F5E 0x61E3 0x6233 0x64F4 0x64F2 \ + 0x64FE 0x6506 0x64FA 0x64FB 0x64F7 0x65B7 0x66DC 0x6726 \ + 0x6AB3 0x6AAC 0x6AC3 0x6ABB 0x6AB8 0x6AC2 0x6AAE 0x6AAF \ + 0x6B5F 0x6B78 0x6BAF 0x7009 0x700B 0x6FFE 0x7006 0x6FFA \ + 0x7011 0x700F 0x71FB 0x71FC 0x71FE 0x71F8 0x7377 0x7375 \ + 0x74A7 0x74BF 0x7515 0x7656 0x7658 0x8858 0x88E0 0x89E7 \ + 0x8A6A 0x8A80 0x8A6F 0x8A65 0x8A78 0x8A7D 0x8A88 0x8A64 \ + 0x8A7E 0x8A67 0x8C63 0x8C88 0x8CCD 0x8CC9 0x8DED 0x8EB1 \ + 0x8F04 0x8F9E 0x8FA0 0x9043 0x9046 0x9048 0x9045 0x9040 \ + 0x904C 0x910C 0x9113 0x9115 0x916B 0x9167 0x7652 0x77BD \ + 0x77BF 0x77BB 0x77BC 0x790E 0x79AE 0x7A61 0x7A62 0x7A60 \ + 0x7AC4 0x7AC5 0x7C2B 0x7C27 0x7C2A 0x7C1E 0x7C23 0x7C21 \ + 0x7CE7 0x7E54 0x7E55 0x7E5E 0x7E5A 0x7E61 0x7E52 0x7E59 \ + 0x7F48 0x7FF9 0x7FFB 0x8077 0x8076 0x81CD 0x81CF 0x820A \ + 0x85CF 0x85A9 0x85CD 0x85D0 0x85C9 0x85B0 0x85BA 0x85B9 \ + 0x85A6 0x87EF 0x87EC 0x87F2 0x87E0 0x8986 0x89B2 0x89F4 \ + 0x8B28 0x8B39 0x8B2C 0x8B2B 0x8C50 0x8D05 0x8E59 0x8E63 \ + 0x8E66 0x8E64 0x8E5F 0x8E55 0x8EC0 0x8F49 0x8F4D 0x9087 \ + 0x9083 0x9088 0x91AB 0x91AC 0x91D0 0x9394 0x938A 0x9396 \ + 0x93A2 0x93B3 0x93AE 0x93AC 0x93B0 0x9398 0x939A 0x9397 \ + 0x95D4 0x95D6 0x95D0 0x95D5 0x96E2 0x96DC 0x96D9 0x96DB \ + 0x96DE 0x9724 0x97A3 0x97A6 0x97AD 0x97F9 0x984D 0x984F +50 0x984C 0x984E 0x9853 0x98BA 0x993E 0x993F 0x993D 0x992E \ + 0x99A5 0x9A0E 0x9AC1 0x9B03 0x9B06 0x9B4F 0x9B4E 0x9B4D \ + 0x9BCA 0x9BC9 0x9BFD 0x9BC8 0x9BC0 0x9D51 0x9D5D 0x9D60 \ + 0x9EE0 0x9F15 0x9F2C 0x5133 0x56A5 0x58DE 0x58DF 0x58E2 \ + 0x5BF5 0x9F90 0x5EEC 0x61F2 0x61F7 0x61F6 0x61F5 0x6500 \ + 0x650F 0x66E0 0x66DD 0x6AE5 0x6ADD 0x6ADA 0x6AD3 0x701B \ + 0x701F 0x7028 0x701A 0x701D 0x7015 0x7018 0x7206 0x720D \ + 0x7258 0x72A2 0x7378 0x925D 0x9255 0x9235 0x9259 0x922F \ + 0x923C 0x928F 0x925C 0x926A 0x9262 0x925F 0x926B 0x926E \ + 0x923B 0x9244 0x9241 0x959A 0x9599 0x968F 0x9696 0x96F4 \ + 0x96FC 0x9755 0x9779 0x97EE 0x97F5 0x980B 0x98F3 0x98F7 \ + 0x98FF 0x98F5 0x98EC 0x98F1 0x737A 0x74BD 0x74CA 0x74E3 \ + 0x7587 0x7586 0x765F 0x7661 0x77C7 0x7919 0x79B1 0x7A6B \ + 0x7A69 0x7C3E 0x7C3F 0x7C38 0x7C3D 0x7C37 0x7C40 0x7E6B \ + 0x7E6D 0x7E79 0x7E69 0x7E6A 0x7F85 0x7E73 0x7FB6 0x7FB9 \ + 0x7FB8 0x81D8 0x85E9 0x85DD 0x85EA 0x85D5 0x85E4 0x85E5 \ + 0x85F7 0x87FB 0x8805 0x880D 0x87F9 0x87FE 0x8960 0x895F \ + 0x8956 0x895E 0x8B41 0x8B5C 0x8B58 0x8B49 0x8B5A 0x8B4E \ + 0x8B4F 0x8B46 0x8B59 0x8D08 0x8D0A 0x8E7C 0x8E72 0x8E87 \ + 0x8E76 0x8E6C 0x8E7A 0x8E74 0x8F54 0x8F4E 0x8FAD 0x908A \ + 0x908B 0x91B1 0x91AE 0x93E1 0x93D1 0x93DF 0x93C3 0x93C8 \ + 0x93DC 0x93DD 0x93D6 0x93E2 0x93CD 0x93D8 0x93E4 0x93D7 \ + 0x93E8 0x95DC 0x96B4 0x96E3 0x972A 0x9727 0x9761 0x97DC \ + 0x97FB 0x985E 0x9858 0x985B 0x98BC 0x9945 0x9949 0x9A16 \ + 0x9A19 0x9B0D 0x9BE8 0x9BE7 0x9BD6 0x9BDB 0x9D89 0x9D61 \ + 0x9D72 0x9D6A 0x9D6C 0x9E92 0x9E97 0x9E93 0x9EB4 0x52F8 \ + 0x56A8 0x56B7 0x56B6 0x56B4 0x56BC 0x58E4 0x5B40 0x5B43 \ + 0x5B7D 0x5BF6 0x5DC9 0x61F8 0x61FA 0x6518 0x6514 0x6519 \ + 0x66E6 0x6727 0x6AEC 0x703E 0x7030 0x7032 0x7210 0x737B \ + 0x74CF 0x7662 0x7665 0x7926 0x792A 0x792C 0x792B 0x7AC7 \ + 0x7AF6 0x7C4C 0x7C43 0x7C4D 0x7CEF 0x7CF0 0x8FAE 0x7E7D \ + 0x7E7C 0x999A 0x9AE2 0x9B3D 0x9B5D 0x9CE8 0x9CEB 0x9CEF +51 0x9CEE 0x9E81 0x9F14 0x50D0 0x50D9 0x50DC 0x50D8 0x50E1 \ + 0x50EB 0x50F4 0x50E2 0x50DE 0x51F4 0x52ED 0x52EA 0x5332 \ + 0x53AE 0x53B0 0x55FB 0x5603 0x560B 0x5607 0x55F8 0x5628 \ + 0x561E 0x5618 0x7E82 0x7F4C 0x8000 0x81DA 0x8266 0x85FB \ + 0x85F9 0x8611 0x85FA 0x8606 0x860B 0x8607 0x860A 0x8814 \ + 0x8815 0x8964 0x89BA 0x89F8 0x8B70 0x8B6C 0x8B66 0x8B6F \ + 0x8B5F 0x8B6B 0x8D0F 0x8D0D 0x8E89 0x8E81 0x8E85 0x8E82 \ + 0x91B4 0x91CB 0x9418 0x9403 0x93FD 0x95E1 0x9730 0x98C4 \ + 0x9952 0x9951 0x99A8 0x9A2B 0x9A30 0x9A37 0x9A35 0x9C13 \ + 0x9C0D 0x9E79 0x9EB5 0x9EE8 0x9F2F 0x9F5F 0x9F63 0x9F61 \ + 0x5137 0x5138 0x56C1 0x56C0 0x56C2 0x5914 0x5C6C 0x5DCD \ + 0x61FC 0x61FE 0x651D 0x651C 0x6595 0x66E9 0x6AFB 0x6B04 \ + 0x6AFA 0x6BB2 0x704C 0x721B 0x72A7 0x74D6 0x74D4 0x7669 \ + 0x77D3 0x7C50 0x7E8F 0x7E8C 0x7FBC 0x8617 0x862D 0x861A \ + 0x8823 0x8822 0x8821 0x881F 0x896A 0x896C 0x89BD 0x8B74 \ + 0x8B77 0x8B7D 0x8D13 0x8E8A 0x8E8D 0x8E8B 0x8F5F 0x8FAF \ + 0x91BA 0x942E 0x9433 0x9435 0x943A 0x9438 0x9432 0x942B \ + 0x95E2 0x9738 0x9739 0x9732 0x97FF 0x9867 0x9865 0x9957 \ + 0x9A45 0x9A43 0x9A40 0x9A3E 0x9ACF 0x9B54 0x9B51 0x9C2D \ + 0x9C25 0x9DAF 0x9DB4 0x9DC2 0x9DB8 0x9E9D 0x9EEF 0x9F19 \ + 0x9F5C 0x9F66 0x9F67 0x513C 0x513B 0x56C8 0x56CA 0x56C9 \ + 0x5B7F 0x5DD4 0x5DD2 0x5F4E 0x61FF 0x6524 0x6B0A 0x6B61 \ + 0x7051 0x7058 0x7380 0x74E4 0x758A 0x766E 0x766C 0x5611 \ + 0x5651 0x5605 0x5717 0x5892 0x588C 0x5878 0x5884 0x5873 \ + 0x58AD 0x5897 0x5895 0x5877 0x5872 0x5896 0x588D 0x5910 \ + 0x596C 0x5AE7 0x5AE4 0x5AEF 0x5626 0x5AF0 0x5D7B 0x5D83 \ + 0x5D8B 0x5D8C 0x5D78 0x5E52 0x5ED0 0x5ECF 0x5FB3 0x5FB4 \ + 0x79B3 0x7C60 0x7C5F 0x807E 0x807D 0x81DF 0x8972 0x896F \ + 0x89FC 0x8B80 0x8D16 0x8D17 0x8E91 0x8E93 0x8F61 0x9148 \ + 0x9444 0x9451 0x9452 0x973D 0x973E 0x97C3 0x97C1 0x986B \ + 0x9955 0x9A55 0x9A4D 0x9AD2 0x9B1A 0x9C49 0x9C31 0x9C3E \ + 0x9C3B 0x9DD3 0x9DD7 0x9F34 0x9F6C 0x9F6A 0x9F94 0x56CC +52 0x5DD6 0x6200 0x6523 0x652B 0x652A 0x66EC 0x6B10 0x74DA \ + 0x7ACA 0x7C64 0x7C63 0x7C65 0x7E93 0x7E96 0x7E94 0x81E2 \ + 0x8638 0x863F 0x8831 0x8B8A 0x9090 0x908F 0x9463 0x9460 \ + 0x9464 0x9768 0x986F 0x995C 0x9A5A 0x9A5B 0x9A57 0x9AD3 \ + 0x9AD4 0x9AD1 0x9C54 0x9C57 0x9C56 0x9DE5 0x9E9F 0x9EF4 \ + 0x56D1 0x58E9 0x652C 0x705E 0x7671 0x7672 0x77D7 0x7F50 \ + 0x7F88 0x8836 0x8839 0x8862 0x8B93 0x8B92 0x8B96 0x8277 \ + 0x8D1B 0x91C0 0x946A 0x9742 0x9748 0x9744 0x97C6 0x9870 \ + 0x9A5F 0x9B22 0x9B58 0x9C5F 0x9DF9 0x9DFA 0x9E7C 0x9E7D \ + 0x9F07 0x9F77 0x9F72 0x5EF3 0x6B16 0x7063 0x7C6C 0x7C6E \ + 0x883B 0x89C0 0x8EA1 0x91C1 0x9472 0x9470 0x9871 0x995E \ + 0x9AD6 0x9B23 0x9ECC 0x7064 0x77DA 0x8B9A 0x9477 0x97C9 \ + 0x9A62 0x9A65 0x7E9C 0x8B9C 0x8EAA 0x91C5 0x947D 0x947E \ + 0x947C 0x9C77 0x9C78 0x9EF7 0x8C54 0x947F 0x9E1A 0x7228 \ + 0x9A6A 0x9B31 0x9E1B 0x9E1E 0x7C72 0x617B 0x616F 0x6181 \ + 0x613C 0x6142 0x6138 0x6133 0x6160 0x6169 0x617D 0x6186 \ + 0x622C 0x6228 0x644C 0x6457 0x647C 0x6455 0x6462 0x6471 \ + 0x646A 0x6456 0x643B 0x6481 0x644F 0x647E 0x6464 0x6571 \ + 0x66A5 0x669A 0x669C 0x66A6 0x66A4 0x698F 0x2460 0x2461 \ + 0x2462 0x2463 0x2464 0x2465 0x2466 0x2467 0x2468 0x2469 \ + 0x2474 0x2475 0x2476 0x2477 0x2478 0x2479 0x247A 0x247B \ + 0x247C 0x247D 0x2170 0x2171 0x2172 0x2173 0x2174 0x2175 \ + 0x2176 0x2177 0x2178 0x2179 0x4E36 0x4E3F 0x4E85 0x4EA0 \ + 0x5182 0x5196 0x51AB 0x52F9 0x5338 0x5369 0x53B6 0x590A \ + 0x5B80 0x5DDB 0x5E7A 0x5E7F 0x5EF4 0x5F50 0x5F61 0x6534 \ + 0x65E0 0x7592 0x7676 0x8FB5 0x96B6 0x5902 0xFF3E 0x30FD \ + 0x30FE 0x309D 0x309E 0xFF02 0x309B 0x309C 0x30FB 0x3007 \ + 0x30FC 0xFF3B 0xFF3D 0x273D 0x3041 0x3042 0x3043 0x3044 \ + 0x3045 0x3046 0x3047 0x3048 0x3049 0x304A 0x304B 0x304C \ + 0x304D 0x304E 0x304F 0x3050 0x3051 0x3052 0x3053 0x3054 \ + 0x3055 0x3056 0x3057 0x3058 0x3059 0x305A 0x305B 0x305C \ + 0x305D 0x305E 0x305F 0x3060 0x3061 0x3062 0x3063 0x3064 +53 0x3065 0x3066 0x3067 0x3068 0x3069 0x306A 0x306B 0x306C \ + 0x306D 0x306E 0x306F 0x3070 0x3071 0x3072 0x3073 0x3074 \ + 0x3075 0x3076 0x3077 0x3078 0x3079 0x307A 0x307B 0x307C \ + 0x307D 0x307E 0x307F 0x3080 0x3081 0x3082 0x3083 0x3084 \ + 0x3085 0x3086 0x3087 0x3088 0x3089 0x308A 0x308B 0x308C \ + 0x308D 0x308E 0x308F 0x3090 0x3091 0x3092 0x3093 0x30A1 \ + 0x30A2 0x30A3 0x30A4 0x69C5 0x69C8 0x6992 0x69B2 0x69E3 \ + 0x69C0 0x69D6 0x69D1 0x699F 0x69A2 0x69D2 0x69E1 0x69D5 \ + 0x699D 0x6998 0x6B74 0x6BA1 0x6EF0 0x6EF3 0x6F1B 0x6F0C \ + 0x6F1D 0x6F34 0x6F28 0x6F17 0x6F44 0x6F42 0x6F04 0x6F11 \ + 0x6EFA 0x6F4A 0x7191 0x718E 0x30A5 0x30A6 0x30A7 0x30A8 \ + 0x30A9 0x30AA 0x30AB 0x30AC 0x30AD 0x30AE 0x30AF 0x30B0 \ + 0x30B1 0x30B2 0x30B3 0x30B4 0x30B5 0x30B6 0x30B7 0x30B8 \ + 0x30B9 0x30BA 0x30BB 0x30BC 0x30BD 0x30BE 0x30BF 0x30C0 \ + 0x30C1 0x30C2 0x30C3 0x30C4 0x30C5 0x30C6 0x30C7 0x30C8 \ + 0x30C9 0x30CA 0x30CB 0x30CC 0x30CD 0x30CE 0x30CF 0x30D0 \ + 0x30D1 0x30D2 0x30D3 0x30D4 0x30D5 0x30D6 0x30D7 0x30D8 \ + 0x30D9 0x30DA 0x30DB 0x30DC 0x30DD 0x30DE 0x30DF 0x30E0 \ + 0x30E1 0x30E2 0x30E3 0x30E4 0x30E5 0x30E6 0x30E7 0x30E8 \ + 0x30E9 0x30EA 0x30EB 0x30EC 0x30ED 0x30EE 0x30EF 0x30F0 \ + 0x30F1 0x30F2 0x30F3 0x30F4 0x30F5 0x30F6 0x6BB9 0x6E0B \ + 0x7105 0x7314 0x7304 0x7305 0x7315 0x730D 0x772E 0x7741 \ + 0x77EA 0x7844 0x7B29 0x7B27 0x7C9D 0x7FC8 0x8126 0x811C \ + 0x8128 0x8370 0x8382 0x83AC 0x86AD 0x86CA 0x8851 0x889D \ + 0x8990 0x89D8 0x89D7 0x8A2E 0x8C59 0x8EDA 0x9033 0x9018 \ + 0x91EF 0x9AD9 0x4EB4 0x50A0 0x5090 0x5086 0x5084 0x508A \ + 0x509F 0x50A1 0x5093 0x51D5 0x5590 0x5710 0x5817 0x5844 \ + 0x582B 0x5845 0x5965 0x5BCF 0x5D56 0x5D54 0x5F3D 0x5FA4 \ + 0x63EC 0x63FA 0x63D4 0x6675 0x671C 0x68D9 0x6BF1 0x6E37 \ + 0x6E7D 0x6E86 0x74FA 0x7572 0x75DC 0x7867 0x7977 0x7A9B \ + 0x7D2A 0x718B 0x718D 0x717F 0x718C 0x717E 0x717C 0x7183 \ + 0x7188 0x7294 0x7355 0x7353 0x734F 0x7354 0x746C 0x7465 +54 0x7466 0x7461 0x746B 0x7468 0x7476 0x7460 0x7474 0x7506 \ + 0x760E 0x7607 0x76B9 0x76B7 0x76E2 0x7774 0x7777 0x7776 \ + 0x7775 0x7778 0x7D65 0x7F64 0x8020 0x8120 0x813C 0x813F \ + 0x81F0 0x81F5 0x8415 0x83BE 0x86E5 0x86D2 0x86E0 0x88B3 \ + 0x8A53 0x8A37 0x8A47 0x8A5C 0x8EF0 0x921D 0x976B 0x50C0 \ + 0x52E5 0x53AF 0x55D8 0x5711 0x5867 0x5843 0x5BDD 0x5D70 \ + 0x5D6A 0x5D74 0x5D5F 0x5D61 0x5D73 0x5E50 0x5F3F 0x5FB0 \ + 0x6135 0x612D 0x6102 0x6226 0x656E 0x65B1 0x65D4 0x6685 \ + 0x6972 0x693A 0x6EAD 0x6E95 0x7243 0x728F 0x7575 0x75EC \ + 0x7757 0x797B 0x7A21 0x7A16 0x7AE8 0x7B6A 0x7B5F 0x7D82 \ + 0x8055 0x8168 0x8246 0x8243 0x8481 0x847C 0x846A 0x9170 \ + 0x50D2 0x9B62 0x6F8A 0x8772 0x9AF0 0x9EA8 0x5292 0x878C \ + 0x9ABA 0x9B81 0x9384 0x9AFF 0x9BB3 0x9BB0 0x9EC7 0x9721 \ + 0x7C36 0x8B5E 0x9401 0x941D 0x994A 0x8B73 0x9DD4 0x77D6 \ + 0x4E42 0x4E5C 0x51F5 0x531A 0x5382 0x4E07 0x4E0C 0x4E47 \ + 0x4E8D 0x56D7 0x5140 0x5C6E 0x5F73 0x4E0F 0x5187 0x4E0E \ + 0x4E2E 0x4E93 0x4EC2 0x4EC9 0x4EC8 0x5198 0x52FC 0x536C \ + 0x53B9 0x5720 0x5903 0x592C 0x5C10 0x5DFF 0x65E1 0x6BB3 \ + 0x6BCC 0x6C14 0x723F 0x4E31 0x4E3C 0x4EE8 0x4EDC 0x4EE9 \ + 0x4EE1 0x4EDD 0x4EDA 0x520C 0x531C 0x534C 0x5722 0x5723 \ + 0x5917 0x592F 0x5B81 0x5B84 0x5C12 0x5C3B 0x5C74 0x5C73 \ + 0x5E04 0x5E80 0x5E82 0x5FC9 0x6209 0x6250 0x6C15 0x7771 \ + 0x777A 0x715B 0x777B 0x78A6 0x78AE 0x78B8 0x78B1 0x78AF \ + 0x7989 0x7987 0x7A29 0x7A2A 0x7A2D 0x7A2C 0x7A32 0x7AEC \ + 0x7AF0 0x7B81 0x7B9E 0x7B83 0x7B92 0x7BA3 0x7B9F 0x7B93 \ + 0x7B86 0x7CB8 0x7CB7 0x7DC8 0x7DB6 0x7DD1 0x7DA8 0x7DAB \ + 0x6C36 0x6C43 0x6C3F 0x6C3B 0x72AE 0x72B0 0x738A 0x79B8 \ + 0x808A 0x961E 0x4F0E 0x4F18 0x4F2C 0x4EF5 0x4F14 0x4EF1 \ + 0x4F00 0x4EF7 0x4F08 0x4F1D 0x4F02 0x4F05 0x4F22 0x4F13 \ + 0x4F04 0x4EF4 0x4F12 0x51B1 0x5213 0x5209 0x5210 0x52A6 \ + 0x5322 0x531F 0x534D 0x538A 0x5407 0x56E1 0x56DF 0x572E \ + 0x572A 0x5734 0x593C 0x5980 0x597C 0x5985 0x597B 0x597E +55 0x5977 0x597F 0x5B56 0x5C15 0x5C25 0x5C7C 0x5C7A 0x5C7B \ + 0x5C7E 0x5DDF 0x5E75 0x5E84 0x5F02 0x5F1A 0x5F74 0x5FD5 \ + 0x5FD4 0x5FCF 0x625C 0x625E 0x6264 0x6261 0x6266 0x6262 \ + 0x6259 0x6260 0x625A 0x6265 0x65EF 0x65EE 0x673E 0x6739 \ + 0x6738 0x673B 0x673A 0x673F 0x673C 0x6733 0x6C18 0x6C46 \ + 0x6C52 0x6C5C 0x6C4F 0x6C4A 0x6C54 0x6C4B 0x6C4C 0x7071 \ + 0x725E 0x72B4 0x72B5 0x738E 0x752A 0x767F 0x7A75 0x7F51 \ + 0x8278 0x827C 0x8280 0x827D 0x827F 0x864D 0x897E 0x9099 \ + 0x9097 0x9098 0x909B 0x9094 0x9622 0x9624 0x9620 0x9623 \ + 0x4F56 0x4F3B 0x4F62 0x4F49 0x4F53 0x4F64 0x4F3E 0x4F67 \ + 0x4F52 0x4F5F 0x4F41 0x4F58 0x4F2D 0x4F33 0x4F3F 0x4F61 \ + 0x518F 0x51B9 0x521C 0x521E 0x5221 0x52AD 0x52AE 0x5309 \ + 0x5363 0x5372 0x538E 0x538F 0x5430 0x5437 0x542A 0x5454 \ + 0x5445 0x5419 0x541C 0x5425 0x5418 0x7DB3 0x7DCD 0x7DCF \ + 0x7DA4 0x7F41 0x7F6F 0x7F71 0x8023 0x805B 0x8061 0x805F \ + 0x8181 0x8184 0x8213 0x824A 0x824C 0x84BD 0x8495 0x8492 \ + 0x84C3 0x8496 0x84A5 0x84B5 0x84B3 0x84A3 0x84E4 0x84D8 \ + 0x84D5 0x84B7 0x84AD 0x84DA 0x8493 0x8736 0x543D 0x544F \ + 0x5441 0x5428 0x5424 0x5447 0x56EE 0x56E7 0x56E5 0x5741 \ + 0x5745 0x574C 0x5749 0x574B 0x5752 0x5906 0x5940 0x59A6 \ + 0x5998 0x59A0 0x5997 0x598E 0x59A2 0x5990 0x598F 0x59A7 \ + 0x59A1 0x5B8E 0x5B92 0x5C28 0x5C2A 0x5C8D 0x5C8F 0x5C88 \ + 0x5C8B 0x5C89 0x5C92 0x5C8A 0x5C86 0x5C93 0x5C95 0x5DE0 \ + 0x5E0A 0x5E0E 0x5E8B 0x5E89 0x5E8C 0x5E88 0x5E8D 0x5F05 \ + 0x5F1D 0x5F78 0x5F76 0x5FD2 0x5FD1 0x5FD0 0x5FED 0x5FE8 \ + 0x5FEE 0x5FF3 0x5FE1 0x5FE4 0x5FE3 0x5FFA 0x5FEF 0x5FF7 \ + 0x5FFB 0x6000 0x5FF4 0x623A 0x6283 0x628C 0x628E 0x628F \ + 0x6294 0x6287 0x6271 0x627B 0x627A 0x6270 0x6281 0x6288 \ + 0x6277 0x627D 0x6272 0x6274 0x6537 0x65F0 0x65F4 0x65F3 \ + 0x65F2 0x65F5 0x6745 0x6747 0x6759 0x6755 0x674C 0x6748 \ + 0x675D 0x674D 0x675A 0x674B 0x6BD0 0x6C19 0x6C1A 0x6C78 \ + 0x6C67 0x6C6B 0x6C84 0x6C8B 0x6C8F 0x6C71 0x6C6F 0x6C69 +56 0x6C9A 0x6C6D 0x6C87 0x6C95 0x6C9C 0x6C66 0x6C73 0x6C65 \ + 0x6C7B 0x6C8E 0x7074 0x707A 0x7263 0x72BF 0x72BD 0x72C3 \ + 0x72C6 0x72C1 0x72BA 0x72C5 0x7395 0x7397 0x7393 0x7394 \ + 0x7392 0x753A 0x7539 0x7594 0x7595 0x7681 0x793D 0x8034 \ + 0x8095 0x8099 0x8090 0x8092 0x809C 0x8290 0x828F 0x8285 \ + 0x828E 0x8291 0x8293 0x873D 0x872B 0x8747 0x8739 0x8745 \ + 0x871D 0x88FF 0x88EA 0x88F5 0x8900 0x88ED 0x8903 0x88E9 \ + 0x89EA 0x8A9B 0x8A8E 0x8AA2 0x8A9C 0x8A94 0x8A90 0x8AA9 \ + 0x8AAC 0x8A9F 0x8A9D 0x8C67 0x8CD0 0x8CD6 0x8CD4 0x8D98 \ + 0x8D9A 0x8D97 0x8E0B 0x8E08 0x828A 0x8283 0x8284 0x8C78 \ + 0x8FC9 0x8FBF 0x909F 0x90A1 0x90A5 0x909E 0x90A7 0x90A0 \ + 0x9630 0x9628 0x962F 0x962D 0x4E33 0x4F98 0x4F7C 0x4F85 \ + 0x4F7D 0x4F80 0x4F87 0x4F76 0x4F74 0x4F89 0x4F84 0x4F77 \ + 0x4F4C 0x4F97 0x4F6A 0x4F9A 0x4F79 0x4F81 0x4F78 0x4F90 \ + 0x4F9C 0x4F94 0x4F9E 0x4F92 0x4F82 0x4F95 0x4F6B 0x4F6E \ + 0x519E 0x51BC 0x51BE 0x5235 0x5232 0x5233 0x5246 0x5231 \ + 0x52BC 0x530A 0x530B 0x533C 0x5392 0x5394 0x5487 0x547F \ + 0x5481 0x5491 0x5482 0x5488 0x546B 0x547A 0x547E 0x5465 \ + 0x546C 0x5474 0x5466 0x548D 0x546F 0x5461 0x5460 0x5498 \ + 0x5463 0x5467 0x5464 0x56F7 0x56F9 0x576F 0x5772 0x576D \ + 0x576B 0x5771 0x5770 0x5776 0x5780 0x5775 0x577B 0x5773 \ + 0x5774 0x5762 0x5768 0x577D 0x590C 0x5945 0x59B5 0x59BA \ + 0x59CF 0x59CE 0x59B2 0x59CC 0x59C1 0x59B6 0x59BC 0x59C3 \ + 0x59D6 0x59B1 0x59BD 0x59C0 0x59C8 0x59B4 0x59C7 0x5B62 \ + 0x5B65 0x5B93 0x5B95 0x5C44 0x5C47 0x5CAE 0x5CA4 0x5CA0 \ + 0x5CB5 0x5CAF 0x5CA8 0x5CAC 0x5C9F 0x5CA3 0x5CAD 0x5CA2 \ + 0x5CAA 0x5CA7 0x5C9D 0x5CA5 0x5CB6 0x5CB0 0x5CA6 0x5E17 \ + 0x5E14 0x5E19 0x5F28 0x5F22 0x5F23 0x5F24 0x5F54 0x5F82 \ + 0x5F7E 0x5F7D 0x5FDE 0x5FE5 0x602D 0x6026 0x6019 0x6032 \ + 0x600B 0x8E01 0x8EB4 0x8EB3 0x8FA1 0x8FA2 0x905A 0x9061 \ + 0x905F 0x9125 0x917B 0x9176 0x917C 0x9289 0x92F6 0x92B1 \ + 0x92AD 0x9292 0x9281 0x9284 0x92AE 0x9290 0x929E 0x95A2 +57 0x95A7 0x96A0 0x969D 0x969F 0x96D0 0x96D1 0x9759 0x9764 \ + 0x9819 0x9814 0x6034 0x600A 0x6017 0x6033 0x601A 0x601E \ + 0x602C 0x6022 0x600D 0x6010 0x602E 0x6013 0x6011 0x600C \ + 0x6009 0x601C 0x6214 0x623D 0x62AD 0x62B4 0x62D1 0x62BE \ + 0x62AA 0x62B6 0x62CA 0x62AE 0x62B3 0x62AF 0x62BB 0x62A9 \ + 0x62B0 0x62B8 0x653D 0x65A8 0x65BB 0x6609 0x65FC 0x6604 \ + 0x6612 0x6608 0x65FB 0x6603 0x660B 0x660D 0x6605 0x65FD \ + 0x6611 0x6610 0x66F6 0x670A 0x6785 0x676C 0x678E 0x6792 \ + 0x6776 0x677B 0x6798 0x6786 0x6784 0x6774 0x678D 0x678C \ + 0x677A 0x679F 0x6791 0x6799 0x6783 0x677D 0x6781 0x6778 \ + 0x6779 0x6794 0x6B25 0x6B80 0x6B7E 0x6BDE 0x6C1D 0x6C93 \ + 0x6CEC 0x6CEB 0x6CEE 0x6CD9 0x6CB6 0x6CD4 0x6CAD 0x6CE7 \ + 0x6CB7 0x6CD0 0x6CC2 0x6CBA 0x6CC3 0x6CC6 0x6CED 0x6CF2 \ + 0x6CD2 0x6CDD 0x6CB4 0x6C8A 0x6C9D 0x6C80 0x6CDE 0x6CC0 \ + 0x6D30 0x6CCD 0x6CC7 0x6CB0 0x6CF9 0x6CCF 0x6CE9 0x6CD1 \ + 0x7094 0x7098 0x7085 0x7093 0x7086 0x7084 0x7091 0x7096 \ + 0x7082 0x709A 0x7083 0x726A 0x72D6 0x72CB 0x72D8 0x72C9 \ + 0x72DC 0x72D2 0x72D4 0x72DA 0x72CC 0x72D1 0x73A4 0x73A1 \ + 0x73AD 0x73A6 0x73A2 0x73A0 0x73AC 0x739D 0x74DD 0x74E8 \ + 0x753F 0x7540 0x753E 0x758C 0x7598 0x76AF 0x76F3 0x76F1 \ + 0x76F0 0x76F5 0x77F8 0x77FC 0x77F9 0x77FB 0x77FA 0x9815 \ + 0x981A 0x9906 0x98F8 0x9901 0x99BE 0x99BC 0x99B7 0x99B6 \ + 0x99C0 0x99B8 0x99C4 0x99BF 0x9ADA 0x9AE4 0x9AE9 0x9AE8 \ + 0x9AEA 0x9AE5 0x9B26 0x9B40 0x9EBD 0x510E 0x50F7 0x50FC \ + 0x510D 0x5101 0x51DA 0x51D9 0x51DB 0x5286 0x528E 0x52EE \ + 0x77F7 0x7942 0x793F 0x79C5 0x7A78 0x7A7B 0x7AFB 0x7C75 \ + 0x7CFD 0x8035 0x808F 0x80AE 0x80A3 0x80B8 0x80B5 0x80AD \ + 0x8220 0x82A0 0x82C0 0x82AB 0x829A 0x8298 0x829B 0x82B5 \ + 0x82A7 0x82AE 0x82BC 0x829E 0x82BA 0x82B4 0x82A8 0x82A1 \ + 0x82A9 0x82C2 0x82A4 0x82C3 0x82B6 0x82A2 0x8670 0x866F \ + 0x866D 0x866E 0x8C56 0x8FD2 0x8FCB 0x8FD3 0x8FCD 0x8FD6 \ + 0x8FD5 0x8FD7 0x90B2 0x90B4 0x90AF 0x90B3 0x90B0 0x9639 +58 0x963D 0x963C 0x963A 0x9643 0x4FCD 0x4FC5 0x4FD3 0x4FB2 \ + 0x4FC9 0x4FCB 0x4FC1 0x4FD4 0x4FDC 0x4FD9 0x4FBB 0x4FB3 \ + 0x4FDB 0x4FC7 0x4FD6 0x4FBA 0x4FC0 0x4FB9 0x4FEC 0x5244 \ + 0x5249 0x52C0 0x52C2 0x533D 0x537C 0x5397 0x5396 0x5399 \ + 0x5398 0x54BA 0x54A1 0x54AD 0x54A5 0x54CF 0x54C3 0x830D \ + 0x54B7 0x54AE 0x54D6 0x54B6 0x54C5 0x54C6 0x54A0 0x5470 \ + 0x54BC 0x54A2 0x54BE 0x5472 0x54DE 0x54B0 0x57B5 0x579E \ + 0x579F 0x57A4 0x578C 0x5797 0x579D 0x579B 0x5794 0x5798 \ + 0x578F 0x5799 0x57A5 0x579A 0x5795 0x58F4 0x590D 0x5953 \ + 0x59E1 0x59DE 0x59EE 0x5A00 0x59F1 0x59DD 0x59FA 0x59FD \ + 0x59FC 0x59F6 0x59E4 0x59F2 0x59F7 0x59DB 0x59E9 0x59F3 \ + 0x59F5 0x59E0 0x59FE 0x59F4 0x59ED 0x5BA8 0x5C4C 0x5CD0 \ + 0x5CD8 0x5CCC 0x5CD7 0x5CCB 0x5CDB 0x5333 0x53B1 0x5647 \ + 0x562D 0x5654 0x564B 0x5652 0x5631 0x5644 0x5656 0x5650 \ + 0x562B 0x564D 0x5637 0x564F 0x58A2 0x58B7 0x58B2 0x58AA \ + 0x58B5 0x58B0 0x58B4 0x58A4 0x58A7 0x5926 0x5AFE 0x5B04 \ + 0x5AFC 0x5B06 0x5B0A 0x5B0D 0x5B00 0x5B0E 0x5CDE 0x5CDA \ + 0x5CC9 0x5CC7 0x5CCA 0x5CD6 0x5CD3 0x5CD4 0x5CCF 0x5CC8 \ + 0x5CC6 0x5CCE 0x5CDF 0x5CF8 0x5DF9 0x5E21 0x5E22 0x5E23 \ + 0x5E20 0x5E24 0x5EB0 0x5EA4 0x5EA2 0x5E9B 0x5EA3 0x5EA5 \ + 0x5F07 0x5F2E 0x5F56 0x5F86 0x6037 0x6039 0x6054 0x6072 \ + 0x605E 0x6045 0x6053 0x6047 0x6049 0x605B 0x604C 0x6040 \ + 0x6042 0x605F 0x6024 0x6044 0x6058 0x6066 0x606E 0x6242 \ + 0x6243 0x62CF 0x630D 0x630B 0x62F5 0x630E 0x6303 0x62EB \ + 0x62F9 0x630F 0x630C 0x62F8 0x62F6 0x6300 0x6313 0x6314 \ + 0x62FA 0x6315 0x62FB 0x62F0 0x6541 0x6543 0x65AA 0x65BF \ + 0x6636 0x6621 0x6632 0x6635 0x661C 0x6626 0x6622 0x6633 \ + 0x662B 0x663A 0x661D 0x6634 0x6639 0x662E 0x670F 0x6710 \ + 0x67C1 0x67F2 0x67C8 0x67BA 0x67DC 0x67BB 0x67F8 0x67D8 \ + 0x67C0 0x67B7 0x67C5 0x67EB 0x67E4 0x67DF 0x67B5 0x67CD \ + 0x67B3 0x67F7 0x67F6 0x67EE 0x67E3 0x67C2 0x67B9 0x67CE \ + 0x67E7 0x67F0 0x67B2 0x67FC 0x67C6 0x67ED 0x67CC 0x67AE +59 0x67E6 0x67DB 0x67FA 0x67C9 0x67CA 0x67C3 0x67EA 0x67CB \ + 0x6B28 0x6B82 0x6B84 0x6BB6 0x6BD6 0x6BD8 0x6BE0 0x6C20 \ + 0x6C21 0x6D28 0x6D34 0x6D2D 0x6D1F 0x6D3C 0x6D3F 0x6D12 \ + 0x6D0A 0x6CDA 0x6D33 0x6D04 0x6D19 0x6D3A 0x6D1A 0x6D11 \ + 0x6D00 0x6D1D 0x6D42 0x5D91 0x5D8F 0x5D90 0x5D98 0x5DA4 \ + 0x5D9B 0x5DA3 0x5D96 0x5DE4 0x5E5A 0x5E5E 0x5FB8 0x6157 \ + 0x615C 0x61A6 0x6195 0x6188 0x61A3 0x618F 0x6164 0x6159 \ + 0x6178 0x6185 0x6187 0x619E 0x6198 0x619C 0x622F 0x6480 \ + 0x649B 0x648E 0x648D 0x6494 0x6D01 0x6D18 0x6D37 0x6D03 \ + 0x6D0F 0x6D40 0x6D07 0x6D20 0x6D2C 0x6D08 0x6D22 0x6D09 \ + 0x6D10 0x70B7 0x709F 0x70BE 0x70B1 0x70B0 0x70A1 0x70B4 \ + 0x70B5 0x70A9 0x7241 0x7249 0x724A 0x726C 0x7270 0x7273 \ + 0x726E 0x72CA 0x72E4 0x72E8 0x72EB 0x72DF 0x72EA 0x72E6 \ + 0x72E3 0x7385 0x73CC 0x73C2 0x73C8 0x73C5 0x73B9 0x73B6 \ + 0x73B5 0x73B4 0x73EB 0x73BF 0x73C7 0x73BE 0x73C3 0x73C6 \ + 0x73B8 0x73CB 0x74EC 0x74EE 0x752E 0x7547 0x7548 0x75A7 \ + 0x75AA 0x7679 0x76C4 0x7708 0x7703 0x7704 0x7705 0x770A \ + 0x76F7 0x76FB 0x76FA 0x77E7 0x77E8 0x7806 0x7811 0x7812 \ + 0x7805 0x7810 0x780F 0x780E 0x7809 0x7803 0x7813 0x794A \ + 0x794C 0x794B 0x7945 0x7944 0x79D5 0x79CD 0x79CF 0x79D6 \ + 0x79CE 0x7A80 0x7A7E 0x7AD1 0x7B00 0x7B01 0x7C7A 0x7C78 \ + 0x7C79 0x7C7F 0x7C80 0x7C81 0x7D03 0x7D08 0x7D01 0x7F58 \ + 0x7F91 0x7F8D 0x7FBE 0x8007 0x800E 0x800F 0x8014 0x8037 \ + 0x80D8 0x80C7 0x80E0 0x80D1 0x80C8 0x80C2 0x80D0 0x80C5 \ + 0x80E3 0x80D9 0x80DC 0x80CA 0x80D5 0x80C9 0x80CF 0x80D7 \ + 0x80E6 0x80CD 0x81FF 0x8221 0x8294 0x82D9 0x82FE 0x82F9 \ + 0x8307 0x82E8 0x8300 0x82D5 0x833A 0x82EB 0x82D6 0x82F4 \ + 0x82EC 0x82E1 0x82F2 0x82F5 0x830C 0x82FB 0x82F6 0x82F0 \ + 0x82EA 0x64C6 0x64A8 0x6483 0x64B9 0x6486 0x64B4 0x64AF \ + 0x6491 0x64AA 0x64A1 0x64A7 0x66B6 0x66B3 0x66BC 0x66AC \ + 0x66AD 0x6A0E 0x6A1C 0x6A1A 0x6A0B 0x69EF 0x6A0C 0x69F0 \ + 0x6A22 0x69D8 0x6A12 0x69FA 0x6A2A 0x6A10 0x6A29 0x69F9 +60 0x69EA 0x6A2C 0x82E4 0x82E0 0x82FA 0x82F3 0x82ED 0x8677 \ + 0x8674 0x867C 0x8673 0x8841 0x884E 0x8867 0x886A 0x8869 \ + 0x89D3 0x8A04 0x8A07 0x8D72 0x8FE3 0x8FE1 0x8FEE 0x8FE0 \ + 0x90F1 0x90BD 0x90BF 0x90D5 0x90C5 0x90BE 0x90C7 0x90CB \ + 0x90C8 0x91D4 0x91D3 0x9654 0x964F 0x9651 0x9653 0x964A \ + 0x964E 0x501E 0x5005 0x5007 0x5013 0x5022 0x5030 0x501B \ + 0x4FF5 0x4FF4 0x5033 0x5037 0x502C 0x4FF6 0x4FF7 0x5017 \ + 0x501C 0x5020 0x5027 0x5035 0x502F 0x5031 0x500E 0x515A \ + 0x5194 0x5193 0x51CA 0x51C4 0x51C5 0x51C8 0x51CE 0x5261 \ + 0x525A 0x5252 0x525E 0x525F 0x5255 0x5262 0x52CD 0x530E \ + 0x539E 0x5526 0x54E2 0x5517 0x5512 0x54E7 0x54F3 0x54E4 \ + 0x551A 0x54FF 0x5504 0x5508 0x54EB 0x5511 0x5505 0x54F1 \ + 0x550A 0x54FB 0x54F7 0x54F8 0x54E0 0x550E 0x5503 0x550B \ + 0x5701 0x5702 0x57CC 0x5832 0x57D5 0x57D2 0x57BA 0x57C6 \ + 0x57BD 0x57BC 0x57B8 0x57B6 0x57BF 0x57C7 0x57D0 0x57B9 \ + 0x57C1 0x590E 0x594A 0x5A19 0x5A16 0x5A2D 0x5A2E 0x5A15 \ + 0x5A0F 0x5A17 0x5A0A 0x5A1E 0x5A33 0x5B6C 0x5BA7 0x5BAD \ + 0x5BAC 0x5C03 0x5C56 0x5C54 0x5CEC 0x5CFF 0x5CEE 0x5CF1 \ + 0x5CF7 0x5D00 0x5CF9 0x5E29 0x5E28 0x5EA8 0x5EAE 0x5EAA \ + 0x5EAC 0x5F33 0x5F30 0x5F67 0x605D 0x605A 0x6067 0x6A24 \ + 0x69E9 0x6B52 0x6B4F 0x6B53 0x6F10 0x6F65 0x6F75 0x6FD0 \ + 0x6F5C 0x6F3D 0x6F71 0x6F91 0x6F0B 0x6F79 0x6F81 0x6F8F \ + 0x6F59 0x6F74 0x71AE 0x71A3 0x71AD 0x71AB 0x71A6 0x71A2 \ + 0x52F2 0x7257 0x7255 0x7299 0x734B 0x747A 0x748C 0x7484 \ + 0x6041 0x60A2 0x6088 0x6080 0x6092 0x6081 0x609D 0x6083 \ + 0x6095 0x609B 0x6097 0x6087 0x609C 0x608E 0x6219 0x6246 \ + 0x62F2 0x6310 0x6356 0x632C 0x6344 0x6345 0x6336 0x6343 \ + 0x63E4 0x6339 0x634B 0x634A 0x633C 0x6329 0x6341 0x6334 \ + 0x6358 0x6354 0x6359 0x632D 0x6347 0x6333 0x635A 0x6351 \ + 0x6338 0x6357 0x6340 0x6348 0x654A 0x6546 0x65C6 0x65C3 \ + 0x65C4 0x65C2 0x664A 0x665F 0x6647 0x6651 0x6712 0x6713 \ + 0x681F 0x681A 0x6849 0x6832 0x6833 0x683B 0x684B 0x684F +61 0x6816 0x6831 0x681C 0x6835 0x682B 0x682D 0x682F 0x684E \ + 0x6844 0x6834 0x681D 0x6812 0x6814 0x6826 0x6828 0x682E \ + 0x684D 0x683A 0x6825 0x6820 0x6B2C 0x6B2F 0x6B2D 0x6B31 \ + 0x6B34 0x6B6D 0x8082 0x6B88 0x6BE6 0x6BE4 0x6BE8 0x6BE3 \ + 0x6BE2 0x6BE7 0x6C25 0x6D7A 0x6D63 0x6D64 0x6D76 0x6D0D \ + 0x6D61 0x6D92 0x6D58 0x6D62 0x6D6D 0x6D6F 0x6D91 0x6D8D \ + 0x6DEF 0x6D7F 0x6D86 0x6D5E 0x6D67 0x6D60 0x6D97 0x6D70 \ + 0x6D7C 0x6D5F 0x6D82 0x6D98 0x6D2F 0x6D68 0x6D8B 0x6D7E \ + 0x6D80 0x6D84 0x6D16 0x6D83 0x6D7B 0x6D7D 0x6D75 0x6D90 \ + 0x70DC 0x70D3 0x70D1 0x70DD 0x70CB 0x7F39 0x70E2 0x70D7 \ + 0x70D2 0x70DE 0x70E0 0x70D4 0x70CD 0x70C5 0x70C6 0x70C7 \ + 0x70DA 0x70CE 0x70E1 0x7242 0x7278 0x7482 0x7493 0x747B \ + 0x7509 0x778A 0x7790 0x78C6 0x78D3 0x78C0 0x78D2 0x78C7 \ + 0x78C2 0x799F 0x799D 0x799E 0x7A41 0x7A38 0x7A3A 0x7A42 \ + 0x7A3E 0x7AB0 0x7BAE 0x7BB3 0x7BBF 0x7BCD 0x7BB2 0x7CC4 \ + 0x7CCD 0x7CC2 0x7CC6 0x7CC3 0x7CC9 0x7CC7 0x7277 0x7276 \ + 0x7300 0x72FA 0x72F4 0x72FE 0x72F6 0x72F3 0x72FB 0x7301 \ + 0x73D3 0x73D9 0x73E5 0x73D6 0x73BC 0x73E7 0x73E3 0x73E9 \ + 0x73DC 0x73D2 0x73DB 0x73D4 0x73DD 0x73DA 0x73D7 0x73D8 \ + 0x73E8 0x74DE 0x74DF 0x74F4 0x74F5 0x7521 0x755B 0x755F \ + 0x75B0 0x75C1 0x75BB 0x75C4 0x75C0 0x75BF 0x75B6 0x75BA \ + 0x768A 0x76C9 0x771D 0x771B 0x7710 0x7713 0x7712 0x7723 \ + 0x7711 0x7715 0x7719 0x771A 0x7722 0x7727 0x7823 0x782C \ + 0x7822 0x7835 0x782F 0x7828 0x782E 0x782B 0x7821 0x7829 \ + 0x7833 0x782A 0x7831 0x7954 0x795B 0x794F 0x795C 0x7953 \ + 0x7952 0x7951 0x79EB 0x79EC 0x79E0 0x79EE 0x79ED 0x79EA \ + 0x79DC 0x79DE 0x79DD 0x7A86 0x7A89 0x7A85 0x7A8B 0x7A8C \ + 0x7A8A 0x7A87 0x7AD8 0x7B10 0x7B04 0x7B13 0x7B05 0x7B0F \ + 0x7B08 0x7B0A 0x7B0E 0x7B09 0x7B12 0x7C84 0x7C91 0x7C8A \ + 0x7C8C 0x7C88 0x7C8D 0x7C85 0x7D1E 0x7D1D 0x7D11 0x7D0E \ + 0x7D18 0x7D16 0x7D13 0x7D1F 0x7D12 0x7D0F 0x7D0C 0x7F5C \ + 0x7F61 0x7F5E 0x7F60 0x7F5D 0x7F5B 0x7F96 0x7F92 0x7FC3 +62 0x7FC2 0x7FC0 0x8016 0x803E 0x8039 0x80FA 0x80F2 0x80F9 \ + 0x80F5 0x8101 0x80FB 0x8100 0x8201 0x822F 0x8225 0x8333 \ + 0x832D 0x8344 0x8319 0x8351 0x8325 0x8356 0x833F 0x8341 \ + 0x8326 0x831C 0x8322 0x7DF8 0x7DED 0x7DE2 0x7DDC 0x7E02 \ + 0x7E01 0x7DD6 0x7DE4 0x7DFE 0x7E00 0x7DFC 0x7DFD 0x7DF5 \ + 0x7DFF 0x7DEB 0x7DE5 0x7F78 0x7FAE 0x7FE7 0x8065 0x806A \ + 0x8066 0x8068 0x806B 0x8194 0x81A1 0x8192 0x8196 0x8193 \ + 0x8501 0x84F8 0x84F5 0x8504 0x8342 0x834E 0x831B 0x832A \ + 0x8308 0x833C 0x834D 0x8316 0x8324 0x8320 0x8337 0x832F \ + 0x8329 0x8347 0x8345 0x834C 0x8353 0x831E 0x832C 0x834B \ + 0x8327 0x8348 0x8653 0x8652 0x86A2 0x86A8 0x8696 0x868D \ + 0x8691 0x869E 0x8687 0x8697 0x8686 0x868B 0x869A 0x8685 \ + 0x86A5 0x8699 0x86A1 0x86A7 0x8695 0x8698 0x868E 0x869D \ + 0x8690 0x8694 0x8843 0x8844 0x886D 0x8875 0x8876 0x8872 \ + 0x8880 0x8871 0x887F 0x886F 0x8883 0x887E 0x8874 0x887C \ + 0x8A12 0x8C47 0x8C57 0x8C7B 0x8CA4 0x8CA3 0x8D76 0x8D78 \ + 0x8DB5 0x8DB7 0x8DB6 0x8ED1 0x8ED3 0x8FFE 0x8FF5 0x9002 \ + 0x8FFF 0x8FFB 0x9004 0x8FFC 0x8FF6 0x90D6 0x90E0 0x90D9 \ + 0x90DA 0x90E3 0x90DF 0x90E5 0x90D8 0x90DB 0x90D7 0x90DC \ + 0x90E4 0x9150 0x914E 0x914F 0x91D5 0x91E2 0x91DA 0x965C \ + 0x965F 0x96BC 0x98E3 0x9ADF 0x9B2F 0x4E7F 0x5070 0x506A \ + 0x5061 0x505E 0x5060 0x5053 0x504B 0x505D 0x5072 0x5048 \ + 0x504D 0x5041 0x505B 0x504A 0x5062 0x5015 0x5045 0x505F \ + 0x5069 0x506B 0x5063 0x5064 0x5046 0x5040 0x506E 0x5073 \ + 0x5057 0x5051 0x51D0 0x526B 0x526D 0x526C 0x526E 0x52D6 \ + 0x52D3 0x532D 0x539C 0x5575 0x5576 0x553C 0x554D 0x5550 \ + 0x5534 0x552A 0x5551 0x5562 0x5536 0x5535 0x5530 0x5552 \ + 0x5545 0x851B 0x8503 0x8533 0x8534 0x84ED 0x8535 0x8505 \ + 0x877D 0x8771 0x885C 0x88E6 0x890F 0x891B 0x89A9 0x89A5 \ + 0x89EE 0x8AB1 0x8ACC 0x8ACE 0x8AB7 0x8AB5 0x8AE9 0x8AB4 \ + 0x8AB3 0x8AC1 0x8AAF 0x8ACA 0x8AD0 0x8C8E 0x8CE9 0x8CDB \ + 0x8CEB 0x8DA4 0x550C 0x5532 0x5565 0x554E 0x5539 0x5548 +63 0x552D 0x553B 0x5540 0x554B 0x570A 0x5707 0x57FB 0x5814 \ + 0x57E2 0x57F6 0x57DC 0x57F4 0x5800 0x57ED 0x57FD 0x5808 \ + 0x57F8 0x580B 0x57F3 0x57CF 0x5807 0x57EE 0x57E3 0x57F2 \ + 0x57E5 0x57EC 0x57E1 0x580E 0x57FC 0x5810 0x57E7 0x5801 \ + 0x580C 0x57F1 0x57E9 0x57F0 0x580D 0x5804 0x595C 0x5A60 \ + 0x5A58 0x5A55 0x5A67 0x5A5E 0x5A38 0x5A35 0x5A6D 0x5A50 \ + 0x5A5F 0x5A65 0x5A6C 0x5A53 0x5A64 0x5A57 0x5A43 0x5A5D \ + 0x5A52 0x5A44 0x5A5B 0x5A48 0x5A8E 0x5A3E 0x5A4D 0x5A39 \ + 0x5A4C 0x5A70 0x5A69 0x5A47 0x5A51 0x5A56 0x5A42 0x5A5C \ + 0x5B72 0x5B6E 0x5BC1 0x5BC0 0x5C59 0x5D1E 0x5D0B 0x5D1D \ + 0x5D1A 0x5D20 0x5D0C 0x5D28 0x5D0D 0x5D26 0x5D25 0x5D0F \ + 0x5D30 0x5D12 0x5D23 0x5D1F 0x5D2E 0x5E3E 0x5E34 0x5EB1 \ + 0x5EB4 0x5EB9 0x5EB2 0x5EB3 0x5F36 0x5F38 0x5F9B 0x5F96 \ + 0x5F9F 0x608A 0x6090 0x6086 0x60BE 0x60B0 0x60BA 0x60D3 \ + 0x60D4 0x60CF 0x60E4 0x60D9 0x60DD 0x60C8 0x60B1 0x60DB \ + 0x60B7 0x60CA 0x60BF 0x60C3 0x60CD 0x60C0 0x6332 0x6365 \ + 0x638A 0x6382 0x637D 0x63BD 0x639E 0x63AD 0x639D 0x6397 \ + 0x63AB 0x638E 0x636F 0x6387 0x6390 0x636E 0x63AF 0x6375 \ + 0x639C 0x636D 0x63AE 0x637C 0x63A4 0x633B 0x639F 0x8DA2 \ + 0x8D9D 0x8E2A 0x8E28 0x8EB8 0x8EB6 0x8EB9 0x8EB7 0x8F22 \ + 0x8F2B 0x8F27 0x8F19 0x8FA4 0x8FB3 0x9071 0x906A 0x9188 \ + 0x918C 0x92BF 0x92B8 0x92BE 0x92DC 0x92E5 0x92D4 0x92D6 \ + 0x92DA 0x92ED 0x92F3 0x92DB 0x92E2 0x92EB 0x95AF 0x95B2 \ + 0x6378 0x6385 0x6381 0x6391 0x638D 0x6370 0x6553 0x65CD \ + 0x6665 0x6661 0x665B 0x6659 0x665C 0x6662 0x6718 0x6879 \ + 0x6887 0x6890 0x689C 0x686D 0x686E 0x68AE 0x68AB 0x6956 \ + 0x686F 0x68A3 0x68AC 0x68A9 0x6875 0x6874 0x68B2 0x688F \ + 0x6877 0x6892 0x687C 0x686B 0x6872 0x68AA 0x6880 0x6871 \ + 0x687E 0x689B 0x6896 0x688B 0x68A0 0x6889 0x68A4 0x6878 \ + 0x687B 0x6891 0x688C 0x688A 0x687D 0x6B36 0x6B33 0x6B37 \ + 0x6B38 0x6B91 0x6B8F 0x6B8D 0x6B8E 0x6B8C 0x6C2A 0x6DC0 \ + 0x6DAB 0x6DB4 0x6DB3 0x6E74 0x6DAC 0x6DE9 0x6DE2 0x6DB7 +64 0x6DF6 0x6DD4 0x6E00 0x6DC8 0x6DE0 0x6DDF 0x6DD6 0x6DBE \ + 0x6DE5 0x6DDC 0x6DDD 0x6DDB 0x6DF4 0x6DCA 0x6DBD 0x6DED \ + 0x6DF0 0x6DBA 0x6DD5 0x6DC2 0x6DCF 0x6DC9 0x6DD0 0x6DF2 \ + 0x6DD3 0x6DFD 0x6DD7 0x6DCD 0x6DE3 0x6DBB 0x70FA 0x710D \ + 0x70F7 0x7117 0x70F4 0x710C 0x70F0 0x7104 0x70F3 0x7110 \ + 0x70FC 0x70FF 0x7106 0x7113 0x7100 0x70F8 0x70F6 0x710B \ + 0x7102 0x710E 0x727E 0x727B 0x727C 0x727F 0x731D 0x7317 \ + 0x7307 0x7311 0x7318 0x730A 0x7308 0x72FF 0x730F 0x731E \ + 0x7388 0x73F6 0x73F8 0x73F5 0x7404 0x7401 0x73FD 0x7407 \ + 0x7400 0x73FA 0x73FC 0x73FF 0x740C 0x740B 0x73F4 0x7408 \ + 0x7564 0x7563 0x75CE 0x75D2 0x75CF 0x95B3 0x96A3 0x96A5 \ + 0x970A 0x9787 0x9789 0x978C 0x97EF 0x982A 0x9822 0x981F \ + 0x9919 0x99CA 0x99DA 0x99DE 0x99C8 0x99E0 0x9AB6 0x9AB5 \ + 0x9AF4 0x9B6B 0x9B69 0x9B72 0x9B63 0x9D0D 0x9D01 0x9D0C \ + 0x9CF8 0x9CFE 0x9D02 0x9E84 0x9EAB 0x9EAA 0x75CB 0x75CC \ + 0x75D1 0x75D0 0x768F 0x7689 0x76D3 0x7739 0x772F 0x772D \ + 0x7731 0x7732 0x7734 0x7733 0x773D 0x7725 0x773B 0x7735 \ + 0x7848 0x7852 0x7849 0x784D 0x784A 0x784C 0x7826 0x7845 \ + 0x7850 0x7964 0x7967 0x7969 0x796A 0x7963 0x796B 0x7961 \ + 0x79BB 0x79FA 0x79F8 0x79F6 0x79F7 0x7A8F 0x7A94 0x7A90 \ + 0x7B35 0x7B47 0x7B34 0x7B25 0x7B30 0x7B22 0x7B24 0x7B33 \ + 0x7B18 0x7B2A 0x7B1D 0x7B31 0x7B2B 0x7B2D 0x7B2F 0x7B32 \ + 0x7B38 0x7B1A 0x7B23 0x7C94 0x7C98 0x7C96 0x7CA3 0x7D35 \ + 0x7D3D 0x7D38 0x7D36 0x7D3A 0x7D45 0x7D2C 0x7D29 0x7D41 \ + 0x7D47 0x7D3E 0x7D3F 0x7D4A 0x7D3B 0x7D28 0x7F63 0x7F95 \ + 0x7F9C 0x7F9D 0x7F9B 0x7FCA 0x7FCB 0x7FCD 0x7FD0 0x7FD1 \ + 0x7FC7 0x7FCF 0x7FC9 0x801F 0x801E 0x801B 0x8047 0x8043 \ + 0x8048 0x8118 0x8125 0x8119 0x811B 0x812D 0x811F 0x812C \ + 0x811E 0x8121 0x8115 0x8127 0x811D 0x8122 0x8211 0x8238 \ + 0x8233 0x823A 0x8234 0x8232 0x8274 0x8390 0x83A3 0x83A8 \ + 0x838D 0x837A 0x8373 0x83A4 0x8374 0x838F 0x8381 0x8395 \ + 0x8399 0x8375 0x8394 0x83A9 0x837D 0x8383 0x838C 0x839D +65 0x839B 0x83AA 0x838B 0x837E 0x83A5 0x83AF 0x8388 0x8397 \ + 0x83B0 0x837F 0x83A6 0x8387 0x83AE 0x8376 0x839A 0x8659 \ + 0x8656 0x86BF 0x86B7 0x511D 0x5116 0x512B 0x511E 0x511B \ + 0x5290 0x5294 0x5314 0x5667 0x567B 0x565F 0x5661 0x58C3 \ + 0x58CA 0x58C0 0x58C4 0x5901 0x5B1F 0x5B18 0x5B11 0x5B15 \ + 0x5B12 0x5B1C 0x5B22 0x5B79 0x5DA6 0x5DB3 0x5DAB 0x5EEA \ + 0x5F5B 0x61B7 0x61CE 0x61B9 0x86C2 0x86C1 0x86C5 0x86BA \ + 0x86B0 0x86C8 0x86B9 0x86B3 0x86B8 0x86CC 0x86B4 0x86BB \ + 0x86BC 0x86C3 0x86BD 0x86BE 0x8852 0x8889 0x8895 0x88A8 \ + 0x88A2 0x88AA 0x889A 0x8891 0x88A1 0x889F 0x8898 0x88A7 \ + 0x8899 0x889B 0x8897 0x88A4 0x88AC 0x888C 0x8893 0x888E \ + 0x8982 0x89D6 0x89D9 0x89D5 0x8A30 0x8A27 0x8A2C 0x8A1E \ + 0x8C39 0x8C3B 0x8C5C 0x8C5D 0x8C7D 0x8CA5 0x8D7D 0x8D7B \ + 0x8D79 0x8DBC 0x8DC2 0x8DB9 0x8DBF 0x8DC1 0x8ED8 0x8EDE \ + 0x8EDD 0x8EDC 0x8ED7 0x8EE0 0x8EE1 0x9024 0x900B 0x9011 \ + 0x901C 0x900C 0x9021 0x90EF 0x90EA 0x90F0 0x90F4 0x90F2 \ + 0x90F3 0x90D4 0x90EB 0x90EC 0x90E9 0x9156 0x9158 0x915A \ + 0x9153 0x9155 0x91EC 0x91F4 0x91F1 0x91F3 0x91F8 0x91E4 \ + 0x91F9 0x91EA 0x91EB 0x91F7 0x91E8 0x91EE 0x957A 0x9586 \ + 0x9588 0x967C 0x966D 0x966B 0x9671 0x966F 0x96BF 0x976A \ + 0x9804 0x98E5 0x9997 0x509B 0x5095 0x5094 0x509E 0x508B \ + 0x50A3 0x5083 0x508C 0x508E 0x509D 0x5068 0x509C 0x5092 \ + 0x5082 0x5087 0x515F 0x51D4 0x5312 0x5311 0x53A4 0x53A7 \ + 0x5591 0x55A8 0x55A5 0x55AD 0x5577 0x5645 0x55A2 0x5593 \ + 0x5588 0x558F 0x55B5 0x5581 0x55A3 0x5592 0x55A4 0x557D \ + 0x558C 0x55A6 0x557F 0x5595 0x55A1 0x558E 0x570C 0x5829 \ + 0x5837 0x61BD 0x61CF 0x61C0 0x6199 0x6197 0x61BB 0x61D0 \ + 0x61C4 0x6231 0x64D3 0x64C0 0x64DC 0x64D1 0x64C8 0x64D5 \ + 0x66C3 0x66BF 0x66C5 0x66CD 0x66C1 0x6706 0x6724 0x6A63 \ + 0x6A42 0x6A52 0x6A43 0x6A33 0x6A6C 0x6A57 0x6A4C 0x6A6E \ + 0x6A37 0x6A71 0x5819 0x581E 0x5827 0x5823 0x5828 0x57F5 \ + 0x5848 0x5825 0x581C 0x581B 0x5833 0x583F 0x5836 0x582E +66 0x5839 0x5838 0x582D 0x582C 0x583B 0x5961 0x5AAF 0x5A94 \ + 0x5A9F 0x5A7A 0x5AA2 0x5A9E 0x5A78 0x5AA6 0x5A7C 0x5AA5 \ + 0x5AAC 0x5A95 0x5AAE 0x5A37 0x5A84 0x5A8A 0x5A97 0x5A83 \ + 0x5A8B 0x5AA9 0x5A7B 0x5A7D 0x5A8C 0x5A9C 0x5A8F 0x5A93 \ + 0x5A9D 0x5BEA 0x5BCD 0x5BCB 0x5BD4 0x5BD1 0x5BCA 0x5BCE \ + 0x5C0C 0x5C30 0x5D37 0x5D43 0x5D6B 0x5D41 0x5D4B 0x5D3F \ + 0x5D35 0x5D51 0x5D4E 0x5D55 0x5D33 0x5D3A 0x5D52 0x5D3D \ + 0x5D31 0x5D59 0x5D42 0x5D39 0x5D49 0x5D38 0x5D3C 0x5D32 \ + 0x5D36 0x5D40 0x5D45 0x5E44 0x5E41 0x5F58 0x5FA6 0x5FA5 \ + 0x5FAB 0x60C9 0x60B9 0x60CC 0x60E2 0x60CE 0x60C4 0x6114 \ + 0x60F2 0x610A 0x6116 0x6105 0x60F5 0x6113 0x60F8 0x60FC \ + 0x60FE 0x60C1 0x6103 0x6118 0x611D 0x6110 0x60FF 0x6104 \ + 0x610B 0x624A 0x6394 0x63B1 0x63B0 0x63CE 0x63E5 0x63E8 \ + 0x63EF 0x63C3 0x649D 0x63F3 0x63CA 0x63E0 0x63F6 0x63D5 \ + 0x63F2 0x63F5 0x6461 0x63DF 0x63BE 0x63DD 0x63DC 0x63C4 \ + 0x63D8 0x63D3 0x63C2 0x63C7 0x63CC 0x63CB 0x63C8 0x63F0 \ + 0x63D7 0x63D9 0x6532 0x6567 0x656A 0x6564 0x655C 0x6568 \ + 0x6565 0x658C 0x659D 0x659E 0x65AE 0x65D0 0x65D2 0x6A4A \ + 0x6A36 0x6A53 0x6A45 0x6A70 0x6A5C 0x6B58 0x6B57 0x6FBB \ + 0x6FBE 0x6FB5 0x6FD3 0x6F9F 0x6FB7 0x6FF5 0x71B7 0x71BB \ + 0x71D1 0x71BA 0x71B6 0x71CC 0x71D3 0x749B 0x7496 0x74A2 \ + 0x749D 0x750A 0x750E 0x7581 0x762C 0x7637 0x7636 0x763B \ + 0x667C 0x666C 0x667B 0x6680 0x6671 0x6679 0x666A 0x6672 \ + 0x6701 0x690C 0x68D3 0x6904 0x68DC 0x692A 0x68EC 0x68EA \ + 0x68F1 0x690F 0x68D6 0x68F7 0x68EB 0x68E4 0x68F6 0x6913 \ + 0x6910 0x68F3 0x68E1 0x6907 0x68CC 0x6908 0x6970 0x68B4 \ + 0x6911 0x68EF 0x68C6 0x6914 0x68F8 0x68D0 0x68FD 0x68FC \ + 0x68E8 0x690B 0x690A 0x6917 0x68CE 0x68C8 0x68DD 0x68DE \ + 0x68E6 0x68F4 0x68D1 0x6906 0x68D4 0x68E9 0x6915 0x6925 \ + 0x68C7 0x6B39 0x6B3B 0x6B3F 0x6B3C 0x6B94 0x6B97 0x6B99 \ + 0x6B95 0x6BBD 0x6BF0 0x6BF2 0x6BF3 0x6C30 0x6DFC 0x6E46 \ + 0x6E47 0x6E1F 0x6E49 0x6E88 0x6E3C 0x6E3D 0x6E45 0x6E62 +67 0x6E2B 0x6E3F 0x6E41 0x6E5D 0x6E73 0x6E1C 0x6E33 0x6E4B \ + 0x6E40 0x6E51 0x6E3B 0x6E03 0x6E2E 0x6E5E 0x6E68 0x6E5C \ + 0x6E61 0x6E31 0x6E28 0x6E60 0x6E71 0x6E6B 0x6E39 0x6E22 \ + 0x6E30 0x6E53 0x6E65 0x6E27 0x6E78 0x6E64 0x6E77 0x6E55 \ + 0x6E79 0x6E52 0x6E66 0x6E35 0x6E36 0x6E5A 0x7120 0x711E \ + 0x712F 0x70FB 0x712E 0x7131 0x7123 0x7125 0x7122 0x7132 \ + 0x711F 0x7128 0x713A 0x711B 0x724B 0x725A 0x7288 0x7289 \ + 0x7286 0x7285 0x728B 0x7312 0x730B 0x7330 0x7322 0x7331 \ + 0x7333 0x7327 0x7332 0x732D 0x7326 0x7323 0x7335 0x730C \ + 0x742E 0x742C 0x7430 0x742B 0x7416 0x76A1 0x7798 0x7796 \ + 0x78D6 0x78EB 0x78DC 0x79A5 0x79A9 0x9834 0x7A53 0x7A45 \ + 0x7A4F 0x7ABD 0x7ABB 0x7AF1 0x7BEC 0x7BED 0x7CD3 0x7CE1 \ + 0x7E19 0x7E27 0x7E26 0x806E 0x81AF 0x81AD 0x81AA 0x8218 \ + 0x856F 0x854C 0x8542 0x855C 0x8570 0x855F 0x741A 0x7421 \ + 0x742D 0x7431 0x7424 0x7423 0x741D 0x7429 0x7420 0x7432 \ + 0x74FB 0x752F 0x756F 0x756C 0x75E7 0x75DA 0x75E1 0x75E6 \ + 0x75DD 0x75DF 0x75E4 0x75D7 0x7695 0x7692 0x76DA 0x7746 \ + 0x7747 0x7744 0x774D 0x7745 0x774A 0x774E 0x774B 0x774C \ + 0x77DE 0x77EC 0x7860 0x7864 0x7865 0x785C 0x786D 0x7871 \ + 0x786A 0x786E 0x7870 0x7869 0x7868 0x785E 0x7862 0x7974 \ + 0x7973 0x7972 0x7970 0x7A02 0x7A0A 0x7A03 0x7A0C 0x7A04 \ + 0x7A99 0x7AE6 0x7AE4 0x7B4A 0x7B3B 0x7B44 0x7B48 0x7B4C \ + 0x7B4E 0x7B40 0x7B58 0x7B45 0x7CA2 0x7C9E 0x7CA8 0x7CA1 \ + 0x7D58 0x7D6F 0x7D63 0x7D53 0x7D56 0x7D67 0x7D6A 0x7D4F \ + 0x7D6D 0x7D5C 0x7D6B 0x7D52 0x7D54 0x7D69 0x7D51 0x7D5F \ + 0x7D4E 0x7F3E 0x7F3F 0x7F65 0x7F66 0x7FA2 0x7FA0 0x7FA1 \ + 0x7FD7 0x8051 0x804F 0x8050 0x80FE 0x80D4 0x8143 0x814A \ + 0x8152 0x814F 0x8147 0x813D 0x814D 0x813A 0x81E6 0x81EE \ + 0x81F7 0x81F8 0x81F9 0x8204 0x823C 0x823D 0x823F 0x8275 \ + 0x833B 0x83CF 0x83F9 0x8423 0x83C0 0x83E8 0x8412 0x83E7 \ + 0x83E4 0x83FC 0x83F6 0x8410 0x83C6 0x83C8 0x83EB 0x83E3 \ + 0x83BF 0x8401 0x83DD 0x83E5 0x83D8 0x83FF 0x83E1 0x83CB +68 0x83CE 0x83D6 0x83F5 0x83C9 0x8409 0x840F 0x83DE 0x8411 \ + 0x8406 0x83C2 0x83F3 0x855A 0x854B 0x853F 0x878A 0x878B \ + 0x87A1 0x878E 0x8799 0x885E 0x885F 0x8924 0x89A7 0x8AEA \ + 0x8AFD 0x8AF9 0x8AE3 0x8AE5 0x8AEC 0x8CF2 0x8CEF 0x8DA6 \ + 0x8E3B 0x8E43 0x8E32 0x8F31 0x8F30 0x8F2D 0x8F3C 0x8FA7 \ + 0x8FA5 0x9137 0x9195 0x918E 0x83D5 0x83FA 0x83C7 0x83D1 \ + 0x83EA 0x8413 0x83C3 0x83EC 0x83EE 0x83C4 0x83FB 0x83D7 \ + 0x83E2 0x841B 0x83DB 0x83FE 0x86D8 0x86E2 0x86E6 0x86D3 \ + 0x86E3 0x86DA 0x86EA 0x86DD 0x86EB 0x86DC 0x86EC 0x86E9 \ + 0x86D7 0x86E8 0x86D1 0x8848 0x8856 0x8855 0x88BA 0x88D7 \ + 0x88B9 0x88B8 0x88C0 0x88BE 0x88B6 0x88BC 0x88B7 0x88BD \ + 0x88B2 0x8901 0x88C9 0x8995 0x8998 0x8997 0x89DD 0x89DA \ + 0x89DB 0x8A4E 0x8A4D 0x8A39 0x8A59 0x8A40 0x8A57 0x8A58 \ + 0x8A44 0x8A45 0x8A52 0x8A48 0x8A51 0x8A4A 0x8A4C 0x8A4F \ + 0x8C5F 0x8C81 0x8C80 0x8CBA 0x8CBE 0x8CB0 0x8CB9 0x8CB5 \ + 0x8D84 0x8D80 0x8D89 0x8DD8 0x8DD3 0x8DCD 0x8DC7 0x8DD6 \ + 0x8DDC 0x8DCF 0x8DD5 0x8DD9 0x8DC8 0x8DD7 0x8DC5 0x8EEF \ + 0x8EF7 0x8EFA 0x8EF9 0x8EE6 0x8EEE 0x8EE5 0x8EF5 0x8EE7 \ + 0x8EE8 0x8EF6 0x8EEB 0x8EF1 0x8EEC 0x8EF4 0x8EE9 0x902D \ + 0x9034 0x902F 0x9106 0x912C 0x9104 0x90FF 0x90FC 0x9108 \ + 0x90F9 0x90FB 0x9101 0x9100 0x9107 0x9105 0x9103 0x9161 \ + 0x9164 0x915F 0x9162 0x9160 0x9201 0x920A 0x9225 0x9203 \ + 0x921A 0x9226 0x920F 0x920C 0x9200 0x9212 0x91FF 0x91FD \ + 0x9206 0x9204 0x9227 0x9202 0x921C 0x9224 0x9219 0x9217 \ + 0x9205 0x9216 0x957B 0x958D 0x958C 0x9590 0x9687 0x967E \ + 0x9688 0x9196 0x9345 0x930A 0x92FD 0x9317 0x931C 0x9307 \ + 0x9331 0x9332 0x932C 0x9330 0x9303 0x9305 0x95C2 0x95B8 \ + 0x95C1 0x96AB 0x96B7 0x9715 0x9714 0x970C 0x9717 0x9793 \ + 0x97D2 0x9836 0x9831 0x9833 0x983C 0x982E 0x983A 0x983D \ + 0x98B5 0x9922 0x9689 0x9683 0x9680 0x96C2 0x96C8 0x96C3 \ + 0x96F1 0x96F0 0x976C 0x9770 0x976E 0x9807 0x98A9 0x98EB \ + 0x9CE6 0x9EF9 0x4E83 0x4E84 0x4EB6 0x50BD 0x50BF 0x50C6 +69 0x50AE 0x50C4 0x50CA 0x50B4 0x50C8 0x50C2 0x50B0 0x50C1 \ + 0x50BA 0x50B1 0x50CB 0x50C9 0x50B6 0x50B8 0x51D7 0x527A \ + 0x5278 0x527B 0x527C 0x55C3 0x55DB 0x55CC 0x55D0 0x55CB \ + 0x55CA 0x55DD 0x55C0 0x55D4 0x55C4 0x55E9 0x55BF 0x55D2 \ + 0x558D 0x55CF 0x55D5 0x55E2 0x55D6 0x55C8 0x55F2 0x55CD \ + 0x55D9 0x55C2 0x5714 0x5853 0x5868 0x5864 0x584F 0x584D \ + 0x5849 0x586F 0x5855 0x584E 0x585D 0x5859 0x5865 0x585B \ + 0x583D 0x5863 0x5871 0x58FC 0x5AC7 0x5AC4 0x5ACB 0x5ABA \ + 0x5AB8 0x5AB1 0x5AB5 0x5AB0 0x5ABF 0x5AC8 0x5ABB 0x5AC6 \ + 0x5AB7 0x5AC0 0x5ACA 0x5AB4 0x5AB6 0x5ACD 0x5AB9 0x5A90 \ + 0x5BD6 0x5BD8 0x5BD9 0x5C1F 0x5C33 0x5D71 0x5D63 0x5D4A \ + 0x5D65 0x5D72 0x5D6C 0x5D5E 0x5D68 0x5D67 0x5D62 0x5DF0 \ + 0x5E4F 0x5E4E 0x5E4A 0x5E4D 0x5E4B 0x5EC5 0x5ECC 0x5EC6 \ + 0x5ECB 0x5EC7 0x5F40 0x5FAF 0x5FAD 0x60F7 0x6149 0x614A \ + 0x612B 0x6145 0x6136 0x6132 0x612E 0x6146 0x612F 0x614F \ + 0x6129 0x6140 0x6220 0x9168 0x6223 0x6225 0x6224 0x63C5 \ + 0x63F1 0x63EB 0x6410 0x6412 0x6409 0x6420 0x6424 0x9923 \ + 0x9920 0x991C 0x991D 0x99A0 0x99EF 0x99E8 0x99EB 0x99E1 \ + 0x99E6 0x9AF8 0x9AF5 0x9B83 0x9B94 0x9B84 0x9B8B 0x9B8F \ + 0x9B8C 0x9B89 0x9B8E 0x9D24 0x9D0F 0x9D13 0x9D0A 0x9D2A \ + 0x9D1A 0x9D27 0x9D16 0x9D21 0x9E85 0x9EAC 0x9EC6 0x9EC5 \ + 0x6433 0x6443 0x641F 0x6415 0x6418 0x6439 0x6437 0x6422 \ + 0x6423 0x640C 0x6426 0x6430 0x6428 0x6441 0x6435 0x642F \ + 0x640A 0x641A 0x6440 0x6425 0x6427 0x640B 0x63E7 0x641B \ + 0x642E 0x6421 0x640E 0x656F 0x6592 0x65D3 0x6686 0x668C \ + 0x6695 0x6690 0x668B 0x668A 0x6699 0x6694 0x6678 0x6720 \ + 0x6966 0x695F 0x6938 0x694E 0x6962 0x6971 0x693F 0x6945 \ + 0x696A 0x6939 0x6942 0x6957 0x6959 0x697A 0x6948 0x6949 \ + 0x6935 0x696C 0x6933 0x693D 0x6965 0x68F0 0x6978 0x6934 \ + 0x6969 0x6940 0x696F 0x6944 0x6976 0x6958 0x6941 0x6974 \ + 0x694C 0x693B 0x694B 0x6937 0x695C 0x694F 0x6951 0x6932 \ + 0x6952 0x692F 0x697B 0x693C 0x6B46 0x6B45 0x6B43 0x6B42 +70 0x6B48 0x6B41 0x6B9B 0x55C0 0x6BFB 0x6BFC 0x6BF9 0x6BF7 \ + 0x6BF8 0x6E9B 0x6ED6 0x6EC8 0x6E8F 0x6EC0 0x6E9F 0x6E93 \ + 0x6E94 0x6EA0 0x6EB1 0x6EB9 0x6EC6 0x6ED2 0x6EBD 0x6EC1 \ + 0x6E9E 0x6EC9 0x6EB7 0x6EB0 0x6ECD 0x6EA6 0x6ECF 0x6EB2 \ + 0x6EBE 0x6EC3 0x6EDC 0x6ED8 0x6E99 0x6E92 0x6E8E 0x6E8D \ + 0x6EA4 0x6EA1 0x6EBF 0x6EB3 0x6ED0 0x6ECA 0x6E97 0x6EAE \ + 0x6EA3 0x7147 0x7154 0x7152 0x7163 0x7160 0x7141 0x715D \ + 0x7162 0x7172 0x7178 0x716A 0x7161 0x7142 0x7158 0x7143 \ + 0x714B 0x7170 0x715F 0x7150 0x7153 0x9ED7 0x9F53 0x5128 \ + 0x5127 0x51DF 0x5335 0x53B3 0x568A 0x567D 0x5689 0x58CD \ + 0x58D0 0x5B2B 0x5B33 0x5B29 0x5B35 0x5B31 0x5B37 0x5C36 \ + 0x5DBE 0x5DB9 0x5DBB 0x61E2 0x61DB 0x61DD 0x61DC 0x61DA \ + 0x61D9 0x64DF 0x64E1 0x64EE 0x65B5 0x66D4 0x7144 0x714D \ + 0x715A 0x724F 0x728D 0x728C 0x7291 0x7290 0x728E 0x733C \ + 0x7342 0x733B 0x733A 0x7340 0x734A 0x7349 0x7444 0x744A \ + 0x744B 0x7452 0x7451 0x7457 0x7440 0x744F 0x7450 0x744E \ + 0x7442 0x7446 0x744D 0x7454 0x74E1 0x74FF 0x74FE 0x74FD \ + 0x751D 0x7579 0x7577 0x6983 0x75EF 0x760F 0x7603 0x75F7 \ + 0x75FE 0x75FC 0x75F9 0x75F8 0x7610 0x75FB 0x75F6 0x75ED \ + 0x75F5 0x75FD 0x7699 0x76B5 0x76DD 0x7755 0x775F 0x7760 \ + 0x7752 0x7756 0x775A 0x7769 0x7767 0x7754 0x7759 0x776D \ + 0x77E0 0x7887 0x789A 0x7894 0x788F 0x7884 0x7895 0x7885 \ + 0x7886 0x78A1 0x7883 0x7879 0x7899 0x7880 0x7896 0x787B \ + 0x797C 0x7982 0x797D 0x7979 0x7A11 0x7A18 0x7A19 0x7A12 \ + 0x7A17 0x7A15 0x7A22 0x7A13 0x7A1B 0x7A10 0x7AA3 0x7AA2 \ + 0x7A9E 0x7AEB 0x7B66 0x7B64 0x7B6D 0x7B74 0x7B69 0x7B72 \ + 0x7B65 0x7B73 0x7B71 0x7B70 0x7B61 0x7B78 0x7B76 0x7B63 \ + 0x7CB2 0x7CB4 0x7CAF 0x7D88 0x7D86 0x7D80 0x7D8D 0x7D7F \ + 0x7D85 0x7D7A 0x7D8E 0x7D7B 0x7D83 0x7D7C 0x7D8C 0x7D94 \ + 0x7D84 0x7D7D 0x7D92 0x7F6D 0x7F6B 0x7F67 0x7F68 0x7F6C \ + 0x7FA6 0x7FA5 0x7FA7 0x7FDB 0x7FDC 0x8021 0x8164 0x8160 \ + 0x8177 0x815C 0x8169 0x815B 0x8162 0x8172 0x6721 0x815E +71 0x8176 0x8167 0x816F 0x66D5 0x66D0 0x66D1 0x66CE 0x66D7 \ + 0x6A7D 0x6A8A 0x6AA7 0x6A99 0x6A82 0x6A88 0x6A86 0x6A98 \ + 0x6A9D 0x6A8F 0x6AAA 0x6B5D 0x6C0A 0x6FD7 0x6FD6 0x6FE5 \ + 0x6FD9 0x6FDA 0x6FEA 0x6FF6 0x71E3 0x71E9 0x71EB 0x71EF \ + 0x71F3 0x71EA 0x7371 0x74AE 0x8144 0x8161 0x821D 0x8249 \ + 0x8244 0x8240 0x8242 0x8245 0x84F1 0x843F 0x8456 0x8476 \ + 0x8479 0x848F 0x848D 0x8465 0x8451 0x8440 0x8486 0x8467 \ + 0x8430 0x844D 0x847D 0x845A 0x8459 0x8474 0x8473 0x845D \ + 0x8507 0x845E 0x8437 0x843A 0x8434 0x847A 0x8443 0x8478 \ + 0x8432 0x8445 0x8429 0x83D9 0x844B 0x842F 0x8442 0x842D \ + 0x845F 0x8470 0x8439 0x844E 0x844C 0x8452 0x846F 0x84C5 \ + 0x848E 0x843B 0x8447 0x8436 0x8433 0x8468 0x847E 0x8444 \ + 0x842B 0x8460 0x8454 0x846E 0x8450 0x870B 0x8704 0x86F7 \ + 0x870C 0x86FA 0x86D6 0x86F5 0x874D 0x86F8 0x870E 0x8709 \ + 0x8701 0x86F6 0x870D 0x8705 0x88D6 0x88CB 0x88CD 0x88CE \ + 0x88DE 0x88DB 0x88DA 0x88CC 0x88D0 0x8985 0x899B 0x89DF \ + 0x89E5 0x89E4 0x89E1 0x89E0 0x89E2 0x89DC 0x89E6 0x8A76 \ + 0x8A86 0x8A7F 0x8A61 0x8A3F 0x8A77 0x8A82 0x8A84 0x8A75 \ + 0x8A83 0x8A81 0x8A74 0x8A7A 0x8C3C 0x8C4B 0x8C4A 0x8C65 \ + 0x8C64 0x8C66 0x8C86 0x8C84 0x8C85 0x8CCC 0x8D68 0x8D69 \ + 0x8D91 0x8D8C 0x8D8E 0x8D8F 0x8D8D 0x8D93 0x8D94 0x8D90 \ + 0x8D92 0x8DF0 0x8DE0 0x8DEC 0x8DF1 0x8DEE 0x8DD0 0x8DE9 \ + 0x8DE3 0x8DE2 0x8DE7 0x8DF2 0x8DEB 0x8DF4 0x8F06 0x8EFF \ + 0x8F01 0x8F00 0x8F05 0x8F07 0x8F08 0x8F02 0x8F0B 0x9052 \ + 0x903F 0x74B3 0x74AC 0x7583 0x7645 0x764E 0x7644 0x76A3 \ + 0x76A5 0x77A6 0x77A4 0x77A9 0x77AF 0x78F0 0x78F8 0x78F1 \ + 0x7A49 0x7AC2 0x7AF2 0x7AF3 0x7BFA 0x7BF6 0x7BFC 0x7C18 \ + 0x7C08 0x7C12 0x7CDB 0x7CDA 0x7E2C 0x7E4D 0x7F46 0x7FF6 \ + 0x802B 0x8074 0x9044 0x9049 0x903D 0x9110 0x910D 0x910F \ + 0x9111 0x9116 0x9114 0x910B 0x910E 0x916E 0x916F 0x9248 \ + 0x9252 0x9230 0x923A 0x9266 0x9233 0x9265 0x925E 0x9283 \ + 0x922E 0x924A 0x9246 0x926D 0x926C 0x924F 0x9260 0x9267 +72 0x926F 0x9236 0x9261 0x9270 0x9231 0x9254 0x9263 0x9250 \ + 0x9272 0x924E 0x9253 0x924C 0x9256 0x9232 0x959F 0x959C \ + 0x959E 0x959B 0x9692 0x9693 0x9691 0x9697 0x96CE 0x96FA \ + 0x96FD 0x96F8 0x96F5 0x9773 0x9777 0x9778 0x9772 0x980F \ + 0x980D 0x980E 0x98AC 0x98F6 0x98F9 0x99AF 0x99B2 0x99B0 \ + 0x99B5 0x9AAD 0x9AAB 0x9B5B 0x9CEA 0x9CED 0x9CE7 0x9E80 \ + 0x9EFD 0x50E6 0x50D4 0x50D7 0x50E8 0x50F3 0x50DB 0x50EA \ + 0x50DD 0x50E4 0x50D3 0x50EC 0x50F0 0x50EF 0x50E3 0x50E0 \ + 0x51D8 0x5280 0x5281 0x52E9 0x52EB 0x5330 0x53AC 0x5627 \ + 0x5615 0x560C 0x5612 0x55FC 0x560F 0x561C 0x5601 0x5613 \ + 0x5602 0x55FA 0x561D 0x5604 0x55FF 0x55F9 0x5889 0x587C \ + 0x5890 0x5898 0x5886 0x5881 0x587F 0x5874 0x588B 0x587A \ + 0x5887 0x5891 0x588E 0x5876 0x5882 0x5888 0x587B 0x5894 \ + 0x588F 0x58FE 0x596B 0x5ADC 0x5AEE 0x5AE5 0x5AD5 0x5AEA \ + 0x5ADA 0x5AED 0x5AEB 0x5AF3 0x5AE2 0x5AE0 0x5ADB 0x5AEC \ + 0x5ADE 0x5ADD 0x5AD9 0x5AE8 0x5ADF 0x5B77 0x5BE0 0x81B8 \ + 0x81C8 0x8592 0x8593 0x857F 0x85AB 0x8597 0x85AC 0x87CE \ + 0x87CD 0x87C1 0x87B1 0x87C7 0x8940 0x893F 0x8939 0x8943 \ + 0x89AB 0x8B1F 0x8B09 0x8B0C 0x8C40 0x8C96 0x8CF6 0x8CF7 \ + 0x8E46 0x8E4F 0x8F3D 0x8F41 0x9366 0x9378 0x935D 0x9369 \ + 0x5BE3 0x5C63 0x5D82 0x5D80 0x5D7D 0x5D86 0x5D7A 0x5D81 \ + 0x5D77 0x5D8A 0x5D89 0x5D88 0x5D7E 0x5D7C 0x5D8D 0x5D79 \ + 0x5D7F 0x5E58 0x5E59 0x5E53 0x5ED8 0x5ED1 0x5ED7 0x5ECE \ + 0x5EDC 0x5ED5 0x5ED9 0x5ED2 0x5ED4 0x5F44 0x5F43 0x5F6F \ + 0x5FB6 0x612C 0x6128 0x6141 0x615E 0x6171 0x6173 0x6152 \ + 0x6153 0x6172 0x616C 0x6180 0x6174 0x6154 0x617A 0x615B \ + 0x6165 0x613B 0x616A 0x6161 0x6156 0x6229 0x6227 0x622B \ + 0x642B 0x644D 0x645B 0x645D 0x6474 0x6476 0x6472 0x6473 \ + 0x647D 0x6475 0x6466 0x64A6 0x644E 0x6482 0x645E 0x645C \ + 0x644B 0x6453 0x6460 0x6450 0x647F 0x643F 0x646C 0x646B \ + 0x6459 0x6465 0x6477 0x6573 0x65A0 0x66A1 0x66A0 0x669F \ + 0x6705 0x6704 0x6722 0x69B1 0x69B6 0x69C9 0x69A0 0x69CE +73 0x6996 0x69B0 0x69AC 0x69BC 0x6991 0x6999 0x698E 0x69A7 \ + 0x698D 0x69A9 0x69BE 0x69AF 0x69BF 0x69C4 0x69BD 0x69A4 \ + 0x69D4 0x69B9 0x69CA 0x699A 0x69CF 0x69B3 0x6993 0x69AA \ + 0x69A1 0x699E 0x69D9 0x6997 0x6990 0x69C2 0x69B5 0x69A5 \ + 0x69C6 0x6B4A 0x6B4D 0x6B4B 0x6B9E 0x6B9F 0x6BA0 0x6BC3 \ + 0x6BC4 0x6BFE 0x6ECE 0x6EF5 0x6EF1 0x6F03 0x6F25 0x6EF8 \ + 0x6F37 0x6EFB 0x6F2E 0x6F09 0x6F4E 0x6F19 0x6F1A 0x6F27 \ + 0x6F18 0x6F3B 0x6F12 0x6EED 0x6F0A 0x9374 0x937D 0x936E \ + 0x9372 0x9373 0x9362 0x9348 0x9353 0x935F 0x9368 0x937F \ + 0x936B 0x95C4 0x96AF 0x96AD 0x96B2 0x971A 0x971B 0x979B \ + 0x979F 0x9840 0x9847 0x98B7 0x99A2 0x9A00 0x99F3 0x99F5 \ + 0x9ABD 0x9B00 0x9B02 0x9B34 0x9B49 0x9B9F 0x6F36 0x6F73 \ + 0x6EF9 0x6EEE 0x6F2D 0x6F40 0x6F30 0x6F3C 0x6F35 0x6EEB \ + 0x6F07 0x6F0E 0x6F43 0x6F05 0x6EFD 0x6EF6 0x6F39 0x6F1C \ + 0x6EFC 0x6F3A 0x6F1F 0x6F0D 0x6F1E 0x6F08 0x6F21 0x7187 \ + 0x7190 0x7189 0x7180 0x7185 0x7182 0x718F 0x717B 0x7186 \ + 0x7181 0x7197 0x7244 0x7253 0x7297 0x7295 0x7293 0x7343 \ + 0x734D 0x7351 0x734C 0x7462 0x7473 0x7471 0x7475 0x7472 \ + 0x7467 0x746E 0x7500 0x7502 0x7503 0x757D 0x7590 0x7616 \ + 0x7608 0x760C 0x7615 0x7611 0x760A 0x7614 0x76B8 0x7781 \ + 0x777C 0x7785 0x7782 0x776E 0x7780 0x776F 0x777E 0x7783 \ + 0x78B2 0x78AA 0x78B4 0x78AD 0x78A8 0x787E 0x78AB 0x789E \ + 0x78A5 0x78A0 0x78AC 0x78A2 0x78A4 0x7998 0x798A 0x798B \ + 0x7996 0x7995 0x7994 0x7993 0x7997 0x7988 0x7992 0x7990 \ + 0x7A2B 0x7A4A 0x7A30 0x7A2F 0x7A28 0x7A26 0x7AA8 0x7AAB \ + 0x7AAC 0x7AEE 0x7B88 0x7B9C 0x7B8A 0x7B91 0x7B90 0x7B96 \ + 0x7B8D 0x7B8C 0x7B9B 0x7B8E 0x7B85 0x7B98 0x5284 0x7B99 \ + 0x7BA4 0x7B82 0x7CBB 0x7CBF 0x7CBC 0x7CBA 0x7DA7 0x7DB7 \ + 0x7DC2 0x7DA3 0x7DAA 0x7DC1 0x7DC0 0x7DC5 0x7D9D 0x7DCE \ + 0x7DC4 0x7DC6 0x7DCB 0x7DCC 0x7DAF 0x7DB9 0x7D96 0x7DBC \ + 0x7D9F 0x7DA6 0x7DAE 0x7DA9 0x7DA1 0x7DC9 0x7F73 0x7FE2 \ + 0x7FE3 0x7FE5 0x7FDE 0x9BA3 0x9BCD 0x9B99 0x9B9D 0x9D39 +74 0x9D44 0x9D35 0x9EAF 0x512F 0x9F8E 0x569F 0x569B 0x569E \ + 0x5696 0x5694 0x56A0 0x5B3B 0x5B3A 0x5DC1 0x5F4D 0x5F5D \ + 0x61F3 0x64F6 0x64E5 0x64EA 0x64E7 0x6505 0x64F9 0x6AAB \ + 0x6AED 0x6AB2 0x6AB0 0x6AB5 0x8024 0x805D 0x805C 0x8189 \ + 0x8186 0x8183 0x8187 0x818D 0x818C 0x818B 0x8215 0x8497 \ + 0x84A4 0x84A1 0x849F 0x84BA 0x84CE 0x84C2 0x84AC 0x84AE \ + 0x84AB 0x84B9 0x84B4 0x84C1 0x84CD 0x84AA 0x849A 0x84B1 \ + 0x84D0 0x849D 0x84A7 0x84BB 0x84A2 0x8494 0x84C7 0x84CC \ + 0x849B 0x84A9 0x84AF 0x84A8 0x84D6 0x8498 0x84B6 0x84CF \ + 0x84A0 0x84D7 0x84D4 0x84D2 0x84DB 0x84B0 0x8491 0x8661 \ + 0x8733 0x8723 0x8728 0x876B 0x8740 0x872E 0x871E 0x8721 \ + 0x8719 0x871B 0x8743 0x872C 0x8741 0x873E 0x8746 0x8720 \ + 0x8732 0x872A 0x872D 0x873C 0x8712 0x873A 0x8731 0x8735 \ + 0x8742 0x8726 0x8727 0x8738 0x8724 0x871A 0x8730 0x8711 \ + 0x88F7 0x88E7 0x88F1 0x88F2 0x88FA 0x88FE 0x88EE 0x88FC \ + 0x88F6 0x88FB 0x88F0 0x88EC 0x88EB 0x899D 0x89A1 0x899F \ + 0x899E 0x89E9 0x89EB 0x89E8 0x8AAB 0x8A99 0x8A8B 0x8A92 \ + 0x8A8F 0x8A96 0x8C3D 0x8C68 0x8C69 0x8CD5 0x8CCF 0x8CD7 \ + 0x8D96 0x8E09 0x8E02 0x8DFF 0x8E0D 0x8DFD 0x8E0A 0x8E03 \ + 0x8E07 0x8E06 0x8E05 0x8DFE 0x8E00 0x8E04 0x8F10 0x8F11 \ + 0x8F0E 0x8F0D 0x9123 0x911C 0x9120 0x9122 0x911F 0x911D \ + 0x911A 0x9124 0x9121 0x911B 0x917A 0x9172 0x9179 0x9173 \ + 0x92A5 0x92A4 0x9276 0x929B 0x927A 0x92A0 0x9294 0x92AA \ + 0x928D 0x6ABE 0x6AC1 0x6AC8 0x6AC0 0x6ABC 0x6AB1 0x6AC4 \ + 0x6ABF 0x7008 0x7003 0x6FFD 0x7010 0x7002 0x7013 0x71FA \ + 0x7200 0x74B9 0x74BC 0x765B 0x7651 0x764F 0x76EB 0x77B8 \ + 0x77B9 0x77C1 0x77C0 0x77BE 0x790B 0x7907 0x790A 0x7908 \ + 0x790D 0x7906 0x92A6 0x929A 0x92AB 0x9279 0x9297 0x927F \ + 0x92A3 0x92EE 0x928E 0x9282 0x9295 0x92A2 0x927D 0x9288 \ + 0x92A1 0x928A 0x9286 0x928C 0x9299 0x92A7 0x927E 0x9287 \ + 0x92A9 0x929D 0x928B 0x922D 0x969E 0x96A1 0x96FF 0x9758 \ + 0x977D 0x977A 0x977E 0x9783 0x9780 0x9782 0x977B 0x9784 +75 0x9781 0x977F 0x97CE 0x97CD 0x9816 0x98AD 0x98AE 0x9902 \ + 0x9900 0x9907 0x999D 0x999C 0x99C3 0x99B9 0x99BB 0x99BA \ + 0x99C2 0x99BD 0x99C7 0x9AB1 0x9AE3 0x9AE7 0x9B3E 0x9B3F \ + 0x9B60 0x9B61 0x9B5F 0x9CF1 0x9CF2 0x9CF5 0x9EA7 0x50FF \ + 0x5103 0x5130 0x50F8 0x5106 0x5107 0x50F6 0x50FE 0x510B \ + 0x510C 0x50FD 0x510A 0x528B 0x528C 0x52F1 0x52EF 0x5648 \ + 0x5642 0x564C 0x5635 0x5641 0x564A 0x5649 0x5646 0x5658 \ + 0x565A 0x5640 0x5633 0x563D 0x562C 0x563E 0x5638 0x562A \ + 0x563A 0x571A 0x58AB 0x589D 0x58B1 0x58A0 0x58A3 0x58AF \ + 0x58AC 0x58A5 0x58A1 0x58FF 0x5AFF 0x5AF4 0x5AFD 0x5AF7 \ + 0x5AF6 0x5B03 0x5AF8 0x5B02 0x5AF9 0x5B01 0x5B07 0x5B05 \ + 0x5B0F 0x5C67 0x5D99 0x5D97 0x5D9F 0x5D92 0x5DA2 0x5D93 \ + 0x5D95 0x5DA0 0x5D9C 0x5DA1 0x5D9A 0x5D9E 0x5E69 0x5E5D \ + 0x5E60 0x5E5C 0x7DF3 0x5EDB 0x5EDE 0x5EE1 0x5F49 0x5FB2 \ + 0x618B 0x6183 0x6179 0x61B1 0x61B0 0x61A2 0x6189 0x7915 \ + 0x79AF 0x7AF5 0x7C2E 0x7C1B 0x7C1A 0x7C24 0x7CE6 0x7CE3 \ + 0x7E5D 0x7E4F 0x7E66 0x7E5B 0x7F47 0x7FB4 0x7FFA 0x802E \ + 0x81CE 0x8219 0x85CC 0x85B2 0x85BB 0x85C1 0x87E9 0x87EE \ + 0x87F0 0x87D6 0x880E 0x87DA 0x8948 0x894A 0x894E 0x894D \ + 0x619B 0x6193 0x61AF 0x61AD 0x619F 0x6192 0x61AA 0x61A1 \ + 0x618D 0x6166 0x61B3 0x622D 0x646E 0x6470 0x6496 0x64A0 \ + 0x6485 0x6497 0x649C 0x648F 0x648B 0x648A 0x648C 0x64A3 \ + 0x649F 0x6468 0x64B1 0x6498 0x6576 0x657A 0x6579 0x657B \ + 0x65B2 0x65B3 0x66B5 0x66B0 0x66A9 0x66B2 0x66B7 0x66AA \ + 0x66AF 0x6A00 0x6A06 0x6A17 0x69E5 0x69F8 0x6A15 0x69F1 \ + 0x69E4 0x6A20 0x69FF 0x69EC 0x69E2 0x6A1B 0x6A1D 0x69FE \ + 0x6A27 0x69F2 0x69EE 0x6A14 0x69F7 0x69E7 0x6A40 0x6A08 \ + 0x69E6 0x69FB 0x6A0D 0x69FC 0x69EB 0x6A09 0x6A04 0x6A18 \ + 0x6A25 0x6A0F 0x69F6 0x6A26 0x6A07 0x69F4 0x6A16 0x6B51 \ + 0x6BA5 0x6BA3 0x6BA2 0x6BA6 0x6C01 0x6C00 0x6BFF 0x6C02 \ + 0x6F41 0x6F26 0x6F7E 0x6F87 0x6FC6 0x6F92 0x6F8D 0x6F89 \ + 0x6F8C 0x6F62 0x6F4F 0x6F85 0x6F5A 0x6F96 0x6F76 0x6F6C +76 0x6F82 0x6F55 0x6F72 0x6F52 0x6F50 0x6F57 0x6F94 0x6F93 \ + 0x6F5D 0x6F00 0x6F61 0x6F6B 0x6F7D 0x6F67 0x6F90 0x6F53 \ + 0x6F8B 0x6F69 0x6F7F 0x6F95 0x6F63 0x6F77 0x6F6A 0x6F7B \ + 0x71B2 0x71AF 0x719B 0x71B0 0x71A0 0x719A 0x71A9 0x71B5 \ + 0x719D 0x71A5 0x719E 0x71A4 0x71A1 0x71AA 0x719C 0x71A7 \ + 0x71B3 0x7298 0x729A 0x7358 0x7352 0x735E 0x735F 0x7360 \ + 0x735D 0x735B 0x7361 0x735A 0x7359 0x89B1 0x89B0 0x89B3 \ + 0x8B38 0x8B32 0x8B2D 0x8B34 0x8B29 0x8C74 0x8D03 0x8DA9 \ + 0x8E58 0x8EBF 0x8EC1 0x8F4A 0x8FAC 0x9089 0x913D 0x913C \ + 0x91A9 0x93A0 0x9390 0x9393 0x938B 0x93AD 0x93BB 0x93B8 \ + 0x939C 0x95D8 0x95D7 0x975D 0x97A9 0x97DA 0x7362 0x7487 \ + 0x7489 0x748A 0x7486 0x7481 0x747D 0x7485 0x7488 0x747C \ + 0x7479 0x7508 0x7507 0x757E 0x7625 0x761E 0x7619 0x761D \ + 0x761C 0x7623 0x761A 0x7628 0x761B 0x769C 0x769D 0x769E \ + 0x769B 0x778D 0x778F 0x7789 0x7788 0x78CD 0x78BB 0x78CF \ + 0x78CC 0x78D1 0x78CE 0x78D4 0x78C8 0x78C3 0x78C4 0x78C9 \ + 0x799A 0x79A1 0x79A0 0x799C 0x79A2 0x799B 0x6B76 0x7A39 \ + 0x7AB2 0x7AB4 0x7AB3 0x7BB7 0x7BCB 0x7BBE 0x7BAC 0x7BCE \ + 0x7BAF 0x7BB9 0x7BCA 0x7BB5 0x7CC5 0x7CC8 0x7CCC 0x7CCB \ + 0x7DF7 0x7DDB 0x7DEA 0x7DE7 0x7DD7 0x7DE1 0x7E03 0x7DFA \ + 0x7DE6 0x7DF6 0x7DF1 0x7DF0 0x7DEE 0x7DDF 0x7F76 0x7FAC \ + 0x7FB0 0x7FAD 0x7FED 0x7FEB 0x7FEA 0x7FEC 0x7FE6 0x7FE8 \ + 0x8064 0x8067 0x81A3 0x819F 0x819E 0x8195 0x81A2 0x8199 \ + 0x8197 0x8216 0x824F 0x8253 0x8252 0x8250 0x824E 0x8251 \ + 0x8524 0x853B 0x850F 0x8500 0x8529 0x850E 0x8509 0x850D \ + 0x851F 0x850A 0x8527 0x851C 0x84FB 0x852B 0x84FA 0x8508 \ + 0x850C 0x84F4 0x852A 0x84F2 0x8515 0x84F7 0x84EB 0x84F3 \ + 0x84FC 0x8512 0x84EA 0x84E9 0x8516 0x84FE 0x8528 0x851D \ + 0x852E 0x8502 0x84FD 0x851E 0x84F6 0x8531 0x8526 0x84E7 \ + 0x84E8 0x84F0 0x84EF 0x84F9 0x8518 0x8520 0x8530 0x850B \ + 0x8519 0x852F 0x8662 0x9854 0x9855 0x984B 0x983F 0x98B9 \ + 0x9938 0x9936 0x9940 0x993B 0x9939 0x99A4 0x9A08 0x9A0C +77 0x9A10 0x9B07 0x9BD2 0x9BC2 0x9BBB 0x9BCC 0x9BCB 0x9D4D \ + 0x9D63 0x9D4E 0x9D50 0x9D55 0x9D5E 0x9E90 0x9EB2 0x9EB1 \ + 0x9ECA 0x9F02 0x9F27 0x9F26 0x8756 0x8763 0x8764 0x8777 \ + 0x87E1 0x8773 0x8758 0x8754 0x875B 0x8752 0x8761 0x875A \ + 0x8751 0x875E 0x876D 0x876A 0x8750 0x874E 0x875F 0x875D \ + 0x876F 0x876C 0x877A 0x876E 0x875C 0x8765 0x874F 0x877B \ + 0x8775 0x8762 0x8767 0x8769 0x885A 0x8905 0x890C 0x8914 \ + 0x890B 0x8917 0x8918 0x8919 0x8906 0x8916 0x8911 0x890E \ + 0x8909 0x89A2 0x89A4 0x89A3 0x89ED 0x89F0 0x89EC 0x8ACF \ + 0x8AC6 0x8AB8 0x8AD3 0x8AD1 0x8AD4 0x8AD5 0x8ABB 0x8AD7 \ + 0x8ABE 0x8AC0 0x8AC5 0x8AD8 0x8AC3 0x8ABA 0x8ABD 0x8AD9 \ + 0x8C3E 0x8C4D 0x8C8F 0x8CE5 0x8CDF 0x8CD9 0x8CE8 0x8CDA \ + 0x8CDD 0x8CE7 0x8DA0 0x8D9C 0x8DA1 0x8D9B 0x8E20 0x8E23 \ + 0x8E25 0x8E24 0x8E2E 0x8E15 0x8E1B 0x8E16 0x8E11 0x8E19 \ + 0x8E26 0x8E27 0x8E14 0x8E12 0x8E18 0x8E13 0x8E1C 0x8E17 \ + 0x8E1A 0x8F2C 0x8F24 0x8F18 0x8F1A 0x8F20 0x8F23 0x8F16 \ + 0x8F17 0x9073 0x9070 0x906F 0x9067 0x906B 0x912F 0x912B \ + 0x9129 0x912A 0x9132 0x9126 0x912E 0x9185 0x9186 0x918A \ + 0x9181 0x9182 0x9184 0x9180 0x92D0 0x92C3 0x92C4 0x92C0 \ + 0x92D9 0x92B6 0x92CF 0x92F1 0x92DF 0x92D8 0x92E9 0x92D7 \ + 0x92DD 0x92CC 0x92EF 0x92C2 0x92E8 0x92CA 0x92C8 0x92CE \ + 0x92E6 0x92CD 0x92D5 0x92C9 0x92E0 0x92DE 0x92E7 0x92D1 \ + 0x92D3 0x56AF 0x58E0 0x58DC 0x5B39 0x5B7C 0x5BF3 0x5C6B \ + 0x5DC4 0x650B 0x6508 0x650A 0x65DC 0x66E1 0x66DF 0x6ACE \ + 0x6AD4 0x6AE3 0x6AD7 0x6AE2 0x6AD8 0x6AD5 0x6AD2 0x701E \ + 0x702C 0x7025 0x6FF3 0x7204 0x7208 0x7215 0x74C4 0x74C9 \ + 0x74C7 0x74C8 0x92B5 0x92E1 0x92C6 0x92B4 0x957C 0x95AC \ + 0x95AB 0x95AE 0x95B0 0x96A4 0x96A2 0x96D3 0x9705 0x9708 \ + 0x9702 0x975A 0x978A 0x978E 0x9788 0x97D0 0x97CF 0x981E \ + 0x981D 0x9826 0x9829 0x9828 0x9820 0x981B 0x9827 0x98B2 \ + 0x9908 0x98FA 0x9911 0x9914 0x9916 0x9917 0x9915 0x99DC \ + 0x99CD 0x99CF 0x99D3 0x99D4 0x99CE 0x99C9 0x99D6 0x99D8 +78 0x99CB 0x99D7 0x99CC 0x9AB3 0x9AEC 0x9AEB 0x9AF3 0x9AF2 \ + 0x9AF1 0x9B46 0x9B43 0x9B67 0x9B74 0x9B71 0x9B66 0x9B76 \ + 0x9B75 0x9B70 0x9B68 0x9B64 0x9B6C 0x9CFC 0x9CFA 0x9CFD \ + 0x9CFF 0x9CF7 0x9D07 0x9D00 0x9CF9 0x9CFB 0x9D08 0x9D05 \ + 0x9D04 0x9E83 0x9ED3 0x9F0F 0x9F10 0x511C 0x5113 0x5117 \ + 0x511A 0x5111 0x51DE 0x5334 0x53E1 0x5670 0x5660 0x566E \ + 0x5673 0x5666 0x5663 0x566D 0x5672 0x565E 0x5677 0x571C \ + 0x571B 0x58C8 0x58BD 0x58C9 0x58BF 0x58BA 0x58C2 0x58BC \ + 0x58C6 0x5B17 0x5B19 0x5B1B 0x5B21 0x5B14 0x5B13 0x5B10 \ + 0x5B16 0x5B28 0x5B1A 0x5B20 0x5B1E 0x5BEF 0x5DAC 0x5DB1 \ + 0x5DA9 0x5DA7 0x5DB5 0x5DB0 0x5DAE 0x5DAA 0x5DA8 0x5DB2 \ + 0x5DAD 0x5DAF 0x5DB4 0x5E67 0x5E68 0x5E66 0x5E6F 0x5EE9 \ + 0x5EE7 0x5EE6 0x5EE8 0x5EE5 0x5F4B 0x5FBC 0x619D 0x61A8 \ + 0x6196 0x61C5 0x61B4 0x61C6 0x61C1 0x61CC 0x61BA 0x76A9 \ + 0x77C6 0x77C5 0x7918 0x791A 0x7920 0x7A66 0x7A64 0x7A6A \ + 0x7C35 0x7C34 0x7E6C 0x7E6E 0x7E71 0x81D4 0x81D6 0x821A \ + 0x8262 0x8265 0x8276 0x85DB 0x85D6 0x85E7 0x85F4 0x87FD \ + 0x87D5 0x8807 0x880F 0x87F8 0x8987 0x89B5 0x89F5 0x8B3F \ + 0x61BF 0x61B8 0x618C 0x64D7 0x64D6 0x64D0 0x64CF 0x64C9 \ + 0x64BD 0x6489 0x64C3 0x64DB 0x64F3 0x64D9 0x6533 0x657F \ + 0x657C 0x65A2 0x66C8 0x66BE 0x66C0 0x66CA 0x66CB 0x66CF \ + 0x66BD 0x66BB 0x66BA 0x66CC 0x6723 0x6A34 0x6A66 0x6A49 \ + 0x6A67 0x6A32 0x6A68 0x6A3E 0x6A5D 0x6A6D 0x6A76 0x6A5B \ + 0x6A51 0x6A28 0x6A5A 0x6A3B 0x6A3F 0x6A41 0x6A6A 0x6A64 \ + 0x6A50 0x6A4F 0x6A54 0x6A6F 0x6A69 0x6A60 0x6A3C 0x6A5E \ + 0x6A56 0x6A55 0x6A4D 0x6A4E 0x6A46 0x6B55 0x6B54 0x6B56 \ + 0x6BA7 0x6BAA 0x6BAB 0x6BC8 0x6BC7 0x6C04 0x6C03 0x6C06 \ + 0x6FAD 0x6FCB 0x6FA3 0x6FC7 0x6FBC 0x6FCE 0x6FC8 0x6F5E \ + 0x6FC4 0x6FBD 0x6F9E 0x6FCA 0x6FA8 0x7004 0x6FA5 0x6FAE \ + 0x6FBA 0x6FAC 0x6FAA 0x6FCF 0x6FBF 0x6FB8 0x6FA2 0x6FC9 \ + 0x6FAB 0x6FCD 0x6FAF 0x6FB2 0x6FB0 0x71C5 0x71C2 0x71BF \ + 0x71B8 0x71D6 0x71C0 0x71C1 0x71CB 0x71D4 0x71CA 0x71C7 +79 0x71CF 0x71BD 0x71D8 0x71BC 0x71C6 0x71DA 0x71DB 0x729D \ + 0x729E 0x7369 0x7366 0x7367 0x736C 0x7365 0x736B 0x736A \ + 0x747F 0x749A 0x74A0 0x7494 0x7492 0x7495 0x74A1 0x750B \ + 0x7580 0x762F 0x762D 0x7631 0x763D 0x7633 0x763C 0x7635 \ + 0x7632 0x7630 0x76BB 0x76E6 0x779A 0x779D 0x77A1 0x779C \ + 0x779B 0x77A2 0x77A3 0x7795 0x7799 0x8B43 0x8B4C 0x8D0B \ + 0x8E6B 0x8E68 0x8E70 0x8E75 0x8E77 0x8EC3 0x93E9 0x93EA \ + 0x93CB 0x93C5 0x93C6 0x93ED 0x93D3 0x93E5 0x93DB 0x93EB \ + 0x93E0 0x93C1 0x95DD 0x97B2 0x97B4 0x97B1 0x97B5 0x97F2 \ + 0x9856 0x9944 0x9A26 0x9A1F 0x9A18 0x9A21 0x7797 0x78DD \ + 0x78E9 0x78E5 0x78EA 0x78DE 0x78E3 0x78DB 0x78E1 0x78E2 \ + 0x78ED 0x78DF 0x78E0 0x79A4 0x7A44 0x7A48 0x7A47 0x7AB6 \ + 0x7AB8 0x7AB5 0x7AB1 0x7AB7 0x7BDE 0x7BE3 0x7BE7 0x7BDD \ + 0x7BD5 0x7BE5 0x7BDA 0x7BE8 0x7BF9 0x7BD4 0x7BEA 0x7BE2 \ + 0x7BDC 0x7BEB 0x7BD8 0x7BDF 0x7CD2 0x7CD4 0x7CD7 0x7CD0 \ + 0x7CD1 0x7E12 0x7E21 0x7E17 0x7E0C 0x7E1F 0x7E20 0x7E13 \ + 0x7E0E 0x7E1C 0x7E15 0x7E1A 0x7E22 0x7E0B 0x7E0F 0x7E16 \ + 0x7E0D 0x7E14 0x7E25 0x7E24 0x7F43 0x7F7B 0x7F7C 0x7F7A \ + 0x7FB1 0x7FEF 0x802A 0x8029 0x806C 0x81B1 0x81A6 0x81AE \ + 0x81B9 0x81B5 0x81AB 0x81B0 0x81AC 0x81B4 0x81B2 0x81B7 \ + 0x81A7 0x81F2 0x8255 0x8256 0x8257 0x8556 0x8545 0x856B \ + 0x854D 0x8553 0x8561 0x8558 0x8540 0x8546 0x8564 0x8541 \ + 0x8562 0x8544 0x8551 0x8547 0x8563 0x853E 0x855B 0x8571 \ + 0x854E 0x856E 0x8575 0x8555 0x8567 0x8560 0x858C 0x8566 \ + 0x855D 0x8554 0x8565 0x856C 0x8663 0x8665 0x8664 0x879B \ + 0x878F 0x8797 0x8793 0x8792 0x8788 0x8781 0x8796 0x8798 \ + 0x8779 0x8787 0x87A3 0x8785 0x8790 0x8791 0x879D 0x8784 \ + 0x8794 0x879C 0x879A 0x8789 0x891E 0x8926 0x8930 0x892D \ + 0x892E 0x8927 0x8931 0x8922 0x8929 0x8923 0x892F 0x892C \ + 0x891F 0x89F1 0x8AE0 0x9A17 0x9B09 0x9BC5 0x9BDF 0x9BE3 \ + 0x9BE9 0x9BEE 0x9D66 0x9D7A 0x9D6E 0x9D91 0x9D83 0x9D76 \ + 0x9D7E 0x9D6D 0x9E95 0x9EE3 0x9F03 0x9F04 0x9F17 0x5136 +80 0x5336 0x5B42 0x5B44 0x5B46 0x5B7E 0x5DCA 0x5DC8 0x5DCC \ + 0x5EF0 0x6585 0x66E5 0x66E7 0x8AE2 0x8AF2 0x8AF4 0x8AF5 \ + 0x8ADD 0x8B14 0x8AE4 0x8ADF 0x8AF0 0x8AC8 0x8ADE 0x8AE1 \ + 0x8AE8 0x8AFF 0x8AEF 0x8AFB 0x8C91 0x8C92 0x8C90 0x8CF5 \ + 0x8CEE 0x8CF1 0x8CF0 0x8CF3 0x8D6C 0x8D6E 0x8DA5 0x8DA7 \ + 0x8E33 0x8E3E 0x8E38 0x8E40 0x8E45 0x8E36 0x8E3C 0x8E3D \ + 0x8E41 0x8E30 0x8E3F 0x8EBD 0x8F36 0x8F2E 0x8F35 0x8F32 \ + 0x8F39 0x8F37 0x8F34 0x9076 0x9079 0x907B 0x9086 0x90FA \ + 0x9133 0x9135 0x9136 0x9193 0x9190 0x9191 0x918D 0x918F \ + 0x9327 0x931E 0x9308 0x931F 0x9306 0x930F 0x937A 0x9338 \ + 0x933C 0x931B 0x9323 0x9312 0x9301 0x9346 0x932D 0x930E \ + 0x930D 0x92CB 0x931D 0x92FA 0x9325 0x9313 0x92F9 0x92F7 \ + 0x9334 0x9302 0x9324 0x92FF 0x9329 0x9339 0x9335 0x932A \ + 0x9314 0x930C 0x930B 0x92FE 0x9309 0x9300 0x92FB 0x9316 \ + 0x95BC 0x95CD 0x95BE 0x95B9 0x95BA 0x95B6 0x95BF 0x95B5 \ + 0x95BD 0x96A9 0x96D4 0x970B 0x9712 0x9710 0x9799 0x9797 \ + 0x9794 0x97F0 0x97F8 0x9835 0x982F 0x9832 0x9924 0x991F \ + 0x9927 0x9929 0x999E 0x99EE 0x99EC 0x99E5 0x99E4 0x99F0 \ + 0x99E3 0x99EA 0x99E9 0x99E7 0x9AB9 0x9ABF 0x9AB4 0x9ABB \ + 0x9AF6 0x9AFA 0x9AF9 0x9AF7 0x9B33 0x9B80 0x9B85 0x9B87 \ + 0x9B7C 0x9B7E 0x9B7B 0x9B82 0x9B93 0x9B92 0x9B90 0x9B7A \ + 0x9B95 0x6AF4 0x6AE9 0x703D 0x7036 0x7216 0x7212 0x720F \ + 0x7217 0x7211 0x720B 0x74CD 0x74D0 0x74CC 0x74CE 0x74D1 \ + 0x7589 0x7A6F 0x7C4B 0x7C44 0x7C55 0x7E7F 0x8B71 0x802F \ + 0x807A 0x807B 0x807C 0x85FC 0x8610 0x8602 0x85EE 0x8603 \ + 0x860D 0x8613 0x9B7D 0x9B88 0x9D25 0x9D17 0x9D20 0x9D1E \ + 0x9D14 0x9D29 0x9D1D 0x9D18 0x9D22 0x9D10 0x9D19 0x9D1F \ + 0x9E88 0x9E86 0x9E87 0x9EAE 0x9EAD 0x9ED5 0x9ED6 0x9EFA \ + 0x9F12 0x9F3D 0x5126 0x5125 0x5122 0x5124 0x5120 0x5129 \ + 0x52F4 0x5693 0x568C 0x568D 0x5686 0x5684 0x5683 0x567E \ + 0x5682 0x567F 0x5681 0x58D6 0x58D4 0x58CF 0x58D2 0x5B2D \ + 0x5B25 0x5B32 0x5B23 0x5B2C 0x5B27 0x5B26 0x5B2F 0x5B2E +81 0x5B7B 0x5BF1 0x5BF2 0x5DB7 0x5E6C 0x5E6A 0x5FBE 0x5FBB \ + 0x61C3 0x61B5 0x61BC 0x61E7 0x61E0 0x61E5 0x61E4 0x61E8 \ + 0x61DE 0x64EF 0x64E9 0x64E3 0x64EB 0x64E4 0x64E8 0x6581 \ + 0x6580 0x65B6 0x65DA 0x66D2 0x6A8D 0x6A96 0x6A81 0x6AA5 \ + 0x6A89 0x6A9F 0x6A9B 0x6AA1 0x6A9E 0x6A87 0x6A93 0x6A8E \ + 0x6A95 0x6A83 0x6AA8 0x6AA4 0x6A91 0x6A7F 0x6AA6 0x6A9A \ + 0x6A85 0x6A8C 0x6A92 0x6B5B 0x6BAD 0x6C09 0x6FCC 0x6FA9 \ + 0x6FF4 0x6FD4 0x6FE3 0x6FDC 0x6FED 0x6FE7 0x6FE6 0x6FDE \ + 0x6FF2 0x6FDD 0x6FE2 0x6FE8 0x71E1 0x71F1 0x71E8 0x71F2 \ + 0x71E4 0x71F0 0x71E2 0x7373 0x736E 0x736F 0x7497 0x74B2 \ + 0x74AB 0x7490 0x74AA 0x74AD 0x74B1 0x74A5 0x74AF 0x7510 \ + 0x7511 0x7512 0x750F 0x7584 0x7643 0x7648 0x7649 0x7647 \ + 0x76A4 0x76E9 0x77B5 0x77AB 0x77B2 0x77B7 0x77B6 0x8608 \ + 0x860F 0x8818 0x8812 0x8967 0x8965 0x89BB 0x8B69 0x8B62 \ + 0x8B6E 0x8B61 0x8B64 0x8B4D 0x8C51 0x8E83 0x8EC6 0x941F \ + 0x9404 0x9417 0x9408 0x9405 0x93F3 0x941E 0x9402 0x941A \ + 0x941B 0x9427 0x941C 0x96B5 0x9733 0x9734 0x9731 0x97B8 \ + 0x77B4 0x77B1 0x77A8 0x77F0 0x78F3 0x78FD 0x7902 0x78FB \ + 0x78FC 0x78F2 0x7905 0x78F9 0x78FE 0x7904 0x79AB 0x79A8 \ + 0x7A5C 0x7A5B 0x7A56 0x7A58 0x7A54 0x7A5A 0x7ABE 0x7AC0 \ + 0x7AC1 0x7C05 0x7C0F 0x7BF2 0x7C00 0x7BFF 0x7BFB 0x7C0E \ + 0x7BF4 0x7C0B 0x7BF3 0x7C02 0x7C09 0x7C03 0x7C01 0x7BF8 \ + 0x7BFD 0x7C06 0x7BF0 0x7BF1 0x7C10 0x7C0A 0x7CE8 0x7E2D \ + 0x7E3C 0x7E42 0x7E33 0x9848 0x7E38 0x7E2A 0x7E49 0x7E40 \ + 0x7E47 0x7E29 0x7E4C 0x7E30 0x7E3B 0x7E36 0x7E44 0x7E3A \ + 0x7F45 0x7F7F 0x7F7E 0x7F7D 0x7FF4 0x7FF2 0x802C 0x81BB \ + 0x81C4 0x81CC 0x81CA 0x81C5 0x81C7 0x81BC 0x81E9 0x825B \ + 0x825A 0x825C 0x8583 0x8580 0x858F 0x85A7 0x8595 0x85A0 \ + 0x858B 0x85A3 0x857B 0x85A4 0x859A 0x859E 0x8577 0x857C \ + 0x8589 0x85A1 0x857A 0x8578 0x8557 0x858E 0x8596 0x8586 \ + 0x858D 0x8599 0x859D 0x8581 0x85A2 0x8582 0x8588 0x8585 \ + 0x8579 0x8576 0x8598 0x8590 0x859F 0x8668 0x87BE 0x87AA +82 0x87AD 0x87C5 0x87B0 0x87AC 0x87B9 0x87B5 0x87BC 0x87AE \ + 0x87C9 0x87C3 0x87C2 0x87CC 0x87B7 0x87AF 0x87C4 0x87CA \ + 0x87B4 0x87B6 0x87BF 0x87B8 0x87BD 0x87DE 0x87B2 0x8935 \ + 0x8933 0x893C 0x893E 0x8941 0x8952 0x8937 0x8942 0x89AD \ + 0x89AF 0x89AE 0x89F2 0x89F3 0x8B1E 0x97BA 0x97FC 0x98C3 \ + 0x994D 0x9A2F 0x9AC9 0x9AC8 0x9AC4 0x9B2A 0x9B38 0x9B50 \ + 0x9C0A 0x9BFB 0x9C04 0x9BFC 0x9BFE 0x9C02 0x9BF6 0x9C1B \ + 0x9BF9 0x9C15 0x9C10 0x9BFF 0x9C00 0x9C0C 0x9D95 0x9DA5 \ + 0x9E98 0x9EC1 0x9F5A 0x5164 0x56BB 0x58E6 0x8B18 0x8B16 \ + 0x8B11 0x8B05 0x8B0B 0x8B22 0x8B0F 0x8B12 0x8B15 0x8B07 \ + 0x8B0D 0x8B08 0x8B06 0x8B1C 0x8B13 0x8B1A 0x8C4F 0x8C70 \ + 0x8C72 0x8C71 0x8C6F 0x8C95 0x8C94 0x8CF9 0x8D6F 0x8E4E \ + 0x8E4D 0x8E53 0x8E50 0x8E4C 0x8E47 0x8F43 0x8F40 0x9085 \ + 0x907E 0x9138 0x919A 0x91A2 0x919B 0x9199 0x919F 0x91A1 \ + 0x919D 0x91A0 0x93A1 0x9383 0x93AF 0x9364 0x9356 0x9347 \ + 0x937C 0x9358 0x935C 0x9376 0x9349 0x9350 0x9351 0x9360 \ + 0x936D 0x938F 0x934C 0x936A 0x9379 0x9357 0x9355 0x9352 \ + 0x934F 0x9371 0x9377 0x937B 0x9361 0x935E 0x9363 0x9367 \ + 0x9380 0x934E 0x9359 0x95C7 0x95C0 0x95C9 0x95C3 0x95C5 \ + 0x95B7 0x96AE 0x96B0 0x96AC 0x9720 0x971F 0x9718 0x971D \ + 0x9719 0x979A 0x97A1 0x979C 0x979E 0x979D 0x97D5 0x97D4 \ + 0x97F1 0x9841 0x9844 0x984A 0x9849 0x9845 0x9843 0x9925 \ + 0x992B 0x992C 0x992A 0x9933 0x9932 0x992F 0x992D 0x9931 \ + 0x9930 0x9998 0x99A3 0x99A1 0x9A02 0x99FA 0x99F4 0x99F7 \ + 0x99F9 0x99F8 0x99F6 0x99FB 0x99FD 0x99FE 0x99FC 0x9A03 \ + 0x9ABE 0x9AFE 0x9AFD 0x9B01 0x9AFC 0x9B48 0x9B9A 0x9BA8 \ + 0x9B9E 0x9B9B 0x9BA6 0x9BA1 0x9BA5 0x9BA4 0x9B86 0x9BA2 \ + 0x9BA0 0x9BAF 0x9D33 0x9D41 0x9D67 0x9D36 0x9D2E 0x9D2F \ + 0x9D31 0x9D38 0x9D30 0x5B49 0x5BF7 0x5DD0 0x5FC2 0x6511 \ + 0x6AFF 0x6AFE 0x6AFD 0x6B01 0x704B 0x704D 0x7047 0x74D3 \ + 0x7668 0x7667 0x77D1 0x7930 0x7932 0x792E 0x9F9D 0x7AC9 \ + 0x7AC8 0x7C56 0x7C51 0x7E85 0x7E89 0x7E8E 0x7E84 0x826A +83 0x862B 0x862F 0x8628 0x8616 0x9D45 0x9D42 0x9D43 0x9D3E \ + 0x9D37 0x9D40 0x9D3D 0x7FF5 0x9D2D 0x9E8A 0x9E89 0x9E8D \ + 0x9EB0 0x9EC8 0x9EDA 0x9EFB 0x9EFF 0x9F24 0x9F23 0x9F22 \ + 0x9F54 0x9FA0 0x5131 0x512D 0x512E 0x5698 0x569C 0x5697 \ + 0x569A 0x569D 0x5699 0x5970 0x5B3C 0x5C69 0x5C6A 0x5DC0 \ + 0x5E6D 0x5E6E 0x61D8 0x61DF 0x61ED 0x61EE 0x61F1 0x61EA \ + 0x61F0 0x61EB 0x61D6 0x61E9 0x64FF 0x6504 0x64FD 0x64F8 \ + 0x6501 0x6503 0x64FC 0x6594 0x65DB 0x66DA 0x66DB 0x66D8 \ + 0x6AC5 0x6AB9 0x6ABD 0x6AE1 0x6AC6 0x6ABA 0x6AB6 0x6AB7 \ + 0x6AC7 0x6AB4 0x6AAD 0x6B5E 0x6BC9 0x6C0B 0x7007 0x700C \ + 0x700D 0x7001 0x7005 0x7014 0x700E 0x6FFF 0x7000 0x6FFB \ + 0x7026 0x6FFC 0x6FF7 0x700A 0x7201 0x71FF 0x71F9 0x7203 \ + 0x71FD 0x7376 0x74B8 0x74C0 0x74B5 0x74C1 0x74BE 0x74B6 \ + 0x74BB 0x74C2 0x7514 0x7513 0x765C 0x7664 0x7659 0x7650 \ + 0x7653 0x7657 0x765A 0x76A6 0x76BD 0x76EC 0x77C2 0x77BA \ + 0x78FF 0x790C 0x7913 0x7914 0x7909 0x7910 0x7912 0x7911 \ + 0x79AD 0x79AC 0x7A5F 0x7C1C 0x7C29 0x7C19 0x7C20 0x7C1F \ + 0x7C2D 0x7C1D 0x7C26 0x7C28 0x7C22 0x7C25 0x7C30 0x7E5C \ + 0x7E50 0x7E56 0x7E63 0x7E58 0x7E62 0x7E5F 0x7E51 0x7E60 \ + 0x7E57 0x7E53 0x7FB5 0x7FB3 0x7FF7 0x7FF8 0x8075 0x81D1 \ + 0x81D2 0x8615 0x861D 0x881A 0x89BC 0x8B75 0x8B7C 0x8D11 \ + 0x8D12 0x8F5C 0x91BB 0x93F4 0x942D 0x96E4 0x9737 0x9736 \ + 0x9767 0x97BE 0x97BD 0x97E2 0x9868 0x9866 0x98C8 0x98CA \ + 0x98C7 0x98DC 0x994F 0x99A9 0x9A3C 0x9A3B 0x9ACE 0x9B14 \ + 0x9B53 0x9C2E 0x81D0 0x825F 0x825E 0x85B4 0x85C6 0x85C0 \ + 0x85C3 0x85C2 0x85B3 0x85B5 0x85BD 0x85C7 0x85C4 0x85BF \ + 0x85CB 0x85CE 0x85C8 0x85C5 0x85B1 0x85B6 0x85D2 0x8624 \ + 0x85B8 0x85B7 0x85BE 0x8669 0x87E7 0x87E6 0x87E2 0x87DB \ + 0x87EB 0x87EA 0x87E5 0x87DF 0x87F3 0x87E4 0x87D4 0x87DC \ + 0x87D3 0x87ED 0x87D8 0x87E3 0x87A4 0x87D7 0x87D9 0x8801 \ + 0x87F4 0x87E8 0x87DD 0x8953 0x894B 0x894F 0x894C 0x8946 \ + 0x8950 0x8951 0x8949 0x8B2A 0x8B27 0x8B23 0x8B33 0x8B30 +84 0x8B35 0x8B47 0x8B2F 0x8B3C 0x8B3E 0x8B31 0x8B25 0x8B37 \ + 0x8B26 0x8B36 0x8B2E 0x8B24 0x8B3B 0x8B3D 0x8B3A 0x8C42 \ + 0x8C75 0x8C99 0x8C98 0x8C97 0x8CFE 0x8D04 0x8D02 0x8D00 \ + 0x8E5C 0x8E62 0x8E60 0x8E57 0x8E56 0x8E5E 0x8E65 0x8E67 \ + 0x8E5B 0x8E5A 0x8E61 0x8E5D 0x8E69 0x8E54 0x8F46 0x8F47 \ + 0x8F48 0x8F4B 0x9128 0x913A 0x913B 0x913E 0x91A8 0x91A5 \ + 0x91A7 0x91AF 0x91AA 0x93B5 0x938C 0x9392 0x93B7 0x939B \ + 0x939D 0x9389 0x93A7 0x938E 0x93AA 0x939E 0x93A6 0x9395 \ + 0x9388 0x9399 0x939F 0x938D 0x93B1 0x9391 0x93B2 0x93A4 \ + 0x93A8 0x93B4 0x93A3 0x93A5 0x95D2 0x95D3 0x95D1 0x96B3 \ + 0x96D7 0x96DA 0x5DC2 0x96DF 0x96D8 0x96DD 0x9723 0x9722 \ + 0x9725 0x97AC 0x97AE 0x97A8 0x97AB 0x97A4 0x97AA 0x9C1F \ + 0x9DB0 0x9DBD 0x9DAE 0x9DC4 0x9E7B 0x9E9E 0x9F05 0x9F69 \ + 0x9FA1 0x56C7 0x571D 0x5B4A 0x5DD3 0x5F72 0x6202 0x6235 \ + 0x6527 0x651E 0x651F 0x6B07 0x6B06 0x7054 0x721C 0x7220 \ + 0x7AF8 0x7C5D 0x7C58 0x7E92 0x7F4E 0x8827 0x8B81 0x8B83 \ + 0x97A2 0x97A5 0x97D7 0x97D9 0x97D6 0x97D8 0x97FA 0x9850 \ + 0x9851 0x9852 0x98B8 0x9941 0x993C 0x993A 0x9A0F 0x9A0B \ + 0x9A09 0x9A0D 0x9A04 0x9A11 0x9A0A 0x9A05 0x9A07 0x9A06 \ + 0x9AC0 0x9ADC 0x9B08 0x9B04 0x9B05 0x9B29 0x9B35 0x9B4A \ + 0x9B4C 0x9B4B 0x9BC7 0x9BC6 0x9BC3 0x9BBF 0x9BC1 0x9BB5 \ + 0x9BB8 0x9BD3 0x9BB6 0x9BC4 0x9BB9 0x9BBD 0x9D5C 0x9D53 \ + 0x9D4F 0x9D4A 0x9D5B 0x9D4B 0x9D59 0x9D56 0x9D4C 0x9D57 \ + 0x9D52 0x9D54 0x9D5F 0x9D58 0x9D5A 0x9E8E 0x9E8C 0x9EDF \ + 0x9F01 0x9F00 0x9F16 0x9F25 0x9F2B 0x9F2A 0x9F29 0x9F28 \ + 0x9F4C 0x9F55 0x5134 0x5135 0x5296 0x52F7 0x53B4 0x56AB \ + 0x56AD 0x56A6 0x56A7 0x56AA 0x56AC 0x58DA 0x58DD 0x58DB \ + 0x5912 0x5B3D 0x5B3E 0x5B3F 0x5DC3 0x5E70 0x5FBF 0x61FB \ + 0x6507 0x6510 0x650D 0x6509 0x650C 0x650E 0x6584 0x65DE \ + 0x65DD 0x66DE 0x6AE7 0x6AE0 0x6ACC 0x6AD1 0x6AD9 0x6ACB \ + 0x6ADF 0x6ADC 0x6AD0 0x6AEB 0x6ACF 0x6ACD 0x6ADE 0x6B60 \ + 0x6BB0 0x6C0C 0x7019 0x7027 0x7020 0x7016 0x702B 0x7021 +85 0x7022 0x7023 0x7029 0x7017 0x7024 0x701C 0x702A 0x720C \ + 0x720A 0x7207 0x7202 0x7205 0x72A5 0x72A6 0x72A4 0x72A3 \ + 0x72A1 0x74CB 0x74C5 0x74B7 0x74C3 0x7516 0x7660 0x77C9 \ + 0x77CA 0x77C4 0x77F1 0x791D 0x791B 0x8C44 0x9442 0x944D \ + 0x9454 0x944E 0x9443 0x973C 0x9740 0x97C0 0x995A 0x9A51 \ + 0x9ADD 0x9C38 0x9C45 0x9C3A 0x9C35 0x9EF1 0x9F93 0x529A \ + 0x8641 0x5DD7 0x6528 0x7053 0x7059 0x7221 0x766F 0x7937 \ + 0x79B5 0x7C62 0x7C5E 0x7CF5 0x863D 0x882D 0x7921 0x791C \ + 0x7917 0x791E 0x79B0 0x7A67 0x7A68 0x7C33 0x7C3C 0x7C39 \ + 0x7C2C 0x7C3B 0x7CEC 0x7CEA 0x7E76 0x7E75 0x7E78 0x7E70 \ + 0x7E77 0x7E6F 0x7E7A 0x7E72 0x7E74 0x7E68 0x7F4B 0x7F4A \ + 0x7F83 0x7F86 0x7FB7 0x7FFD 0x7FFE 0x8078 0x81D7 0x81D5 \ + 0x8264 0x8261 0x8263 0x85EB 0x85F1 0x85ED 0x85D9 0x85E1 \ + 0x85E8 0x85DA 0x85D7 0x85EC 0x85F2 0x85F8 0x85D8 0x85DF \ + 0x85E3 0x85DC 0x85D1 0x85F0 0x85E6 0x85EF 0x85DE 0x85E2 \ + 0x8800 0x87FA 0x8803 0x87F6 0x87F7 0x8809 0x880C 0x880B \ + 0x8806 0x87FC 0x8808 0x87FF 0x880A 0x8802 0x8962 0x895A \ + 0x895B 0x8957 0x8961 0x895C 0x8958 0x895D 0x8959 0x8988 \ + 0x89B7 0x89B6 0x89F6 0x8B50 0x8B48 0x8B4A 0x8B40 0x8B53 \ + 0x8B56 0x8B54 0x8B4B 0x8B55 0x8B51 0x8B42 0x8B52 0x8B57 \ + 0x8C43 0x8C77 0x8C76 0x8C9A 0x8D06 0x8D07 0x8D09 0x8DAC \ + 0x8DAA 0x8DAD 0x8DAB 0x8E6D 0x8E78 0x8E73 0x8E6A 0x8E6F \ + 0x8E7B 0x8EC2 0x8F52 0x8F51 0x8F4F 0x8F50 0x8F53 0x8FB4 \ + 0x9140 0x913F 0x91B0 0x91AD 0x93DE 0x93C7 0x93CF 0x93C2 \ + 0x93DA 0x93D0 0x93F9 0x93EC 0x93CC 0x93D9 0x93A9 0x93E6 \ + 0x93CA 0x93D4 0x93EE 0x93E3 0x93D5 0x93C4 0x93CE 0x93C0 \ + 0x93D2 0x93E7 0x957D 0x95DA 0x95DB 0x96E1 0x9729 0x972B \ + 0x972C 0x9728 0x9726 0x8989 0x8B8D 0x8B87 0x8B90 0x8D1A \ + 0x8E99 0x945F 0x9456 0x9461 0x945B 0x945A 0x945C 0x9465 \ + 0x9741 0x986E 0x986C 0x986D 0x99AA 0x9A5C 0x9A58 0x9ADE \ + 0x9C4F 0x9C51 0x9C53 0x9DFC 0x9F39 0x513E 0x56D2 0x5B4F \ + 0x6B14 0x7A72 0x7A73 0x8B91 0x97B3 0x97B7 0x97B6 0x97DD +86 0x97DE 0x97DF 0x985C 0x9859 0x985D 0x9857 0x98BF 0x98BD \ + 0x98BB 0x98BE 0x9948 0x9947 0x9943 0x99A6 0x99A7 0x9A1A \ + 0x9A15 0x9A25 0x9A1D 0x9A24 0x9A1B 0x9A22 0x9A20 0x9A27 \ + 0x9A23 0x9A1E 0x9A1C 0x9A14 0x9AC2 0x9B0B 0x9B0A 0x9B0E \ + 0x9B0C 0x9B37 0x9BEA 0x9BEB 0x9BE0 0x9BDE 0x9BE4 0x9BE6 \ + 0x9BE2 0x9BF0 0x9BD4 0x9BD7 0x9BEC 0x9BDC 0x9BD9 0x9BE5 \ + 0x9BD5 0x9BE1 0x9BDA 0x9D77 0x9D81 0x9D8A 0x9D84 0x9D88 \ + 0x9D71 0x9D80 0x9D78 0x9D86 0x9D8B 0x9D8C 0x9D7D 0x9D6B \ + 0x9D74 0x9D75 0x9D70 0x9D69 0x9D85 0x9D73 0x9D7B 0x9D82 \ + 0x9D6F 0x9D79 0x9D7F 0x9D87 0x9D68 0x9E94 0x9E91 0x9EC0 \ + 0x9EFC 0x9F2D 0x9F40 0x9F41 0x9F4D 0x9F56 0x9F57 0x9F58 \ + 0x5337 0x56B2 0x56B5 0x56B3 0x58E3 0x5B45 0x5DC6 0x5DC7 \ + 0x5EEE 0x5EEF 0x5FC0 0x5FC1 0x61F9 0x6517 0x6516 0x6515 \ + 0x6513 0x65DF 0x66E8 0x66E3 0x66E4 0x6AF3 0x6AF0 0x6AEA \ + 0x6AE8 0x6AF9 0x6AF1 0x6AEE 0x6AEF 0x703C 0x7035 0x702F \ + 0x7037 0x7034 0x7031 0x7042 0x7038 0x703F 0x703A 0x7039 \ + 0x7040 0x703B 0x7033 0x7041 0x7213 0x7214 0x72A8 0x737D \ + 0x737C 0x74BA 0x76AB 0x76AA 0x76BE 0x76ED 0x77CC 0x77CE \ + 0x77CF 0x77CD 0x77F2 0x7925 0x7923 0x7927 0x7928 0x7924 \ + 0x7929 0x91BF 0x946C 0x96E6 0x9745 0x97C8 0x97E4 0x995D \ + 0x9B21 0x9B2C 0x9B57 0x9C5D 0x9C61 0x9C65 0x9E08 0x9F45 \ + 0x6205 0x66EF 0x6B1B 0x6B1D 0x7225 0x7224 0x7C6D 0x8642 \ + 0x8649 0x8978 0x898A 0x8B97 0x8C9B 0x8D1C 0x8EA2 0x9C6C \ + 0x9C6F 0x9E0E 0x79B2 0x7A6E 0x7A6C 0x7A6D 0x7AF7 0x7C49 \ + 0x7C48 0x7C4A 0x7C47 0x7C45 0x7CEE 0x7E7B 0x7E7E 0x7E81 \ + 0x7E80 0x7FBA 0x7FFF 0x8079 0x81DB 0x81D9 0x820B 0x8268 \ + 0x8269 0x8622 0x85FF 0x8601 0x85FE 0x861B 0x8600 0x85F6 \ + 0x8604 0x8609 0x8605 0x860C 0x85FD 0x8819 0x8810 0x8811 \ + 0x8817 0x8813 0x8816 0x8963 0x8966 0x89B9 0x89F7 0x8B60 \ + 0x8B6A 0x8B5D 0x8B68 0x8B63 0x8B65 0x8B67 0x8B6D 0x8DAE \ + 0x8E86 0x8E88 0x8E84 0x8F59 0x8F56 0x8F57 0x8F55 0x8F58 \ + 0x8F5A 0x908D 0x9143 0x9141 0x91B7 0x91B5 0x91B2 0x91B3 +87 0x940B 0x9413 0x93FB 0x9420 0x940F 0x9414 0x93FE 0x9415 \ + 0x9410 0x9428 0x9419 0x940D 0x93F5 0x9400 0x93F7 0x9407 \ + 0x940E 0x9416 0x9412 0x93FA 0x9409 0x93F8 0x940A 0x93FF \ + 0x93FC 0x940C 0x93F6 0x9411 0x9406 0x95DE 0x95E0 0x95DF \ + 0x972E 0x972F 0x97B9 0x97BB 0x97FD 0x97FE 0x9860 0x9862 \ + 0x9863 0x985F 0x98C1 0x98C2 0x9950 0x994E 0x9959 0x994C \ + 0x994B 0x9953 0x9A32 0x9A34 0x9A31 0x9A2C 0x9A2A 0x9A36 \ + 0x9A29 0x9A2E 0x9A38 0x9A2D 0x9AC7 0x9ACA 0x9AC6 0x9B10 \ + 0x9B12 0x9B11 0x9C0B 0x9C08 0x9BF7 0x9C05 0x9C12 0x9BF8 \ + 0x9C40 0x9C07 0x9C0E 0x9C06 0x9C17 0x9C14 0x9C09 0x9D9F \ + 0x9D99 0x9DA4 0x9D9D 0x9D92 0x9D98 0x9D90 0x9D9B 0x9F08 \ + 0x9F1D 0x9FA3 0x5F60 0x6B1C 0x7CF3 0x8B9B 0x8EA7 0x91C4 \ + 0x947A 0x9A61 0x9A63 0x9AD7 0x9C76 0x9FA5 0x7067 0x72AB \ + 0x864A 0x897D 0x8B9D 0x8C53 0x8F65 0x947B 0x98CD 0x98DD \ + 0x9B30 0x9E16 0x96E7 0x9E18 0x9EA2 0x9F7C 0x7E9E 0x9484 \ + 0x9DA0 0x9D94 0x9D9C 0x9DAA 0x9D97 0x9DA1 0x9D9A 0x9DA2 \ + 0x9DA8 0x9D9E 0x9DA3 0x9DBF 0x9DA9 0x9D96 0x9DA6 0x9DA7 \ + 0x9E99 0x9E9B 0x9E9A 0x9EE5 0x9EE4 0x9EE7 0x9EE6 0x9F30 \ + 0x9F2E 0x9F5B 0x9F60 0x9F5E 0x9F5D 0x9F59 0x9F91 0x513A \ + 0x5139 0x5298 0x5297 0x56C3 0x56BD 0x56BE 0x5B48 0x5B47 \ + 0x5DCB 0x5DCF 0x5EF1 0x61FD 0x651B 0x6B02 0x6AFC 0x6B03 \ + 0x6AF8 0x6B00 0x7043 0x7044 0x704A 0x7048 0x7049 0x7045 \ + 0x7046 0x721D 0x721A 0x7219 0x737E 0x7517 0x766A 0x77D0 \ + 0x792D 0x7931 0x792F 0x7C54 0x7C53 0x7CF2 0x7E8A 0x7E87 \ + 0x7E88 0x7E8B 0x7E86 0x7E8D 0x7F4D 0x7FBB 0x8030 0x81DD \ + 0x8618 0x862A 0x8626 0x861F 0x8623 0x861C 0x8619 0x8627 \ + 0x862E 0x8621 0x8620 0x8629 0x861E 0x8625 0x8829 0x881D \ + 0x881B 0x8820 0x8824 0x881C 0x882B 0x884A 0x896D 0x8969 \ + 0x896E 0x896B 0x89FA 0x8B79 0x8B78 0x8B45 0x8B7A 0x8B7B \ + 0x8D10 0x8D14 0x8DAF 0x8E8E 0x8E8C 0x8F5E 0x8F5B 0x8F5D \ + 0x9146 0x9144 0x9145 0x91B9 0x943F 0x943B 0x9436 0x9429 \ + 0x943D 0x943C 0x9430 0x9439 0x942A 0x9437 0x942C 0x9440 +88 0x9431 0x95E5 0x95E4 0x95E3 0x9735 0x973A 0x97BF 0x97E1 \ + 0x9864 0x98C9 0x98C6 0x98C0 0x9958 0x9956 0x9A39 0x9A3D \ + 0x9A46 0x9A44 0x9A42 0x9A41 0x9A3A 0x9E1C 0x7C71 0x97CA \ + 0x9EA3 0x9C7B 0x9F97 0x9750 0x4E40 0x4E41 0x4E5A 0x4E02 \ + 0x4E29 0x5202 0x5DDC 0x5342 0x536A 0x5B52 0x5FC4 0x624C \ + 0x72AD 0x4E12 0x4E2F 0x4E96 0x4ED0 0x5142 0x5183 0x5383 \ + 0x53B8 0x5928 0x5C23 0x5E01 0x5F00 0x706C 0x9A3F 0x9ACD \ + 0x9B15 0x9B17 0x9B18 0x9B16 0x9B3A 0x9B52 0x9C2B 0x9C1D \ + 0x9C1C 0x9C2C 0x9C23 0x9C28 0x9C29 0x9C24 0x9C21 0x9DB7 \ + 0x9DB6 0x9DBC 0x9DC1 0x9DC7 0x9DCA 0x9DCF 0x9DBE 0x9DC5 \ + 0x9DC3 0x9DBB 0x9DB5 0x9DCE 0x9DB9 0x9DBA 0x9DAC 0x9DC8 \ + 0x9DB1 0x9DAD 0x9DCC 0x9DB3 0x9DCD 0x9DB2 0x9E7A 0x9E9C \ + 0x9EEB 0x9EEE 0x9EED 0x9F1B 0x9F18 0x9F1A 0x9F31 0x9F4E \ + 0x9F65 0x9F64 0x9F92 0x4EB9 0x56C6 0x56C5 0x56CB 0x5971 \ + 0x5B4B 0x5B4C 0x5DD5 0x5DD1 0x5EF2 0x6521 0x6520 0x6526 \ + 0x6522 0x6B0B 0x6B08 0x6B09 0x6C0D 0x7055 0x7056 0x7057 \ + 0x7052 0x721E 0x721F 0x72A9 0x737F 0x74D8 0x74D5 0x74D9 \ + 0x74D7 0x766D 0x76AD 0x7935 0x79B4 0x7A70 0x7A71 0x7C57 \ + 0x7C5C 0x7C59 0x7C5B 0x7C5A 0x7CF4 0x7CF1 0x7E91 0x7F4F \ + 0x7F87 0x81DE 0x826B 0x8634 0x8635 0x8633 0x862C 0x8632 \ + 0x8636 0x882C 0x8828 0x8826 0x882A 0x8825 0x8971 0x89BF \ + 0x89BE 0x89FB 0x8B7E 0x8B84 0x8B82 0x8B86 0x8B85 0x8B7F \ + 0x8D15 0x8E95 0x8E94 0x8E9A 0x8E92 0x8E90 0x8E96 0x8E97 \ + 0x8F60 0x8F62 0x9147 0x944C 0x9450 0x944A 0x944B 0x944F \ + 0x9447 0x9445 0x9448 0x9449 0x9446 0x973F 0x97E3 0x986A \ + 0x9869 0x98CB 0x9954 0x995B 0x9A4E 0x9A53 0x9A54 0x9A4C \ + 0x9A4F 0x9A48 0x9A4A 0x722B 0x5188 0x8279 0x8FB6 0x4E17 \ + 0x4EE2 0x4EDB 0x51AD 0x51F7 0x531B 0x5388 0x5387 0x53CF \ + 0x53FD 0x53E7 0x56DC 0x56D9 0x5725 0x5727 0x5933 0x5C13 \ + 0x5C75 0x66F1 0x7F52 0x4E51 0x4E6A 0x4F0C 0x4EFE 0x4F1B \ + 0x5173 0x518E 0x52A5 0x52A7 0x9A49 0x9A52 0x9A50 0x9AD0 \ + 0x9B19 0x9B2B 0x9B3B 0x9B56 0x9B55 0x9C46 0x9C48 0x9C3F +89 0x9C44 0x9C39 0x9C33 0x9C41 0x9C3C 0x9C37 0x9C34 0x9C32 \ + 0x9C3D 0x9C36 0x9DDB 0x9DD2 0x9DDE 0x9DDA 0x9DCB 0x9DD0 \ + 0x9DDC 0x9DD1 0x9DDF 0x9DE9 0x9DD9 0x9DD8 0x9DD6 0x9DF5 \ + 0x9DD5 0x9DDD 0x9EB6 0x9EF0 0x9F35 0x9F33 0x9F32 0x9F42 \ + 0x9F6B 0x9F95 0x9FA2 0x513D 0x5299 0x58E8 0x58E7 0x5972 \ + 0x5B4D 0x5DD8 0x882F 0x5F4F 0x6201 0x6203 0x6204 0x6529 \ + 0x6525 0x6596 0x66EB 0x6B11 0x6B12 0x6B0F 0x6BCA 0x705B \ + 0x705A 0x7222 0x7382 0x7381 0x7383 0x7670 0x77D4 0x7C67 \ + 0x7C66 0x7E95 0x826C 0x863A 0x8640 0x8639 0x863C 0x8631 \ + 0x863B 0x863E 0x8830 0x8832 0x882E 0x8833 0x8976 0x8974 \ + 0x8973 0x89FE 0x8B8C 0x8B8E 0x8B8B 0x8B88 0x8C45 0x8D19 \ + 0x8E98 0x8F64 0x8F63 0x91BC 0x9462 0x9455 0x945D 0x9457 \ + 0x945E 0x97C4 0x97C5 0x9800 0x9A56 0x9A59 0x9B1E 0x9B1F \ + 0x9B20 0x9C52 0x9C58 0x9C50 0x9C4A 0x9C4D 0x9C4B 0x9C55 \ + 0x9C59 0x9C4C 0x9C4E 0x9DFB 0x9DF7 0x9DEF 0x9DE3 0x9DEB \ + 0x9DF8 0x9DE4 0x9DF6 0x9DE1 0x9DEE 0x9DE6 0x9DF2 0x9DF0 \ + 0x9DE2 0x9DEC 0x9DF4 0x9DF3 0x9DE8 0x9DED 0x9EC2 0x9ED0 \ + 0x9EF2 0x9EF3 0x9F06 0x9F1C 0x9F38 0x9F37 0x9F36 0x9F43 \ + 0x9F4F 0x52A4 0x53BD 0x5402 0x572B 0x591B 0x5935 0x5C17 \ + 0x5C70 0x5C7D 0x5DE9 0x5F19 0x5F1C 0x5F75 0x5FC8 0x6C12 \ + 0x72B3 0x7390 0x7536 0x8281 0x8FB8 0x4E23 0x4F2E 0x514F \ + 0x51BA 0x5222 0x52AF 0x52B0 0x52B1 0x5364 0x53D3 0x593F \ + 0x598B 0x5991 0x9F71 0x9F70 0x9F6E 0x9F6F 0x56D3 0x56CD \ + 0x5B4E 0x5C6D 0x652D 0x66ED 0x66EE 0x6B13 0x705F 0x7061 \ + 0x705D 0x7060 0x7223 0x74DB 0x74E5 0x77D5 0x7938 0x79B7 \ + 0x79B6 0x7C6A 0x7E97 0x7F89 0x826D 0x8643 0x8838 0x8837 \ + 0x8835 0x884B 0x8B94 0x8B95 0x8E9E 0x8E9F 0x8EA0 0x8E9D \ + 0x91BE 0x91BD 0x91C2 0x946B 0x9468 0x9469 0x96E5 0x9746 \ + 0x9743 0x9747 0x97C7 0x97E5 0x9A5E 0x9AD5 0x9B59 0x9C63 \ + 0x9C67 0x9C66 0x9C62 0x9C5E 0x9C60 0x9E02 0x9DFE 0x9E07 \ + 0x9E03 0x9E06 0x9E05 0x9E00 0x9E01 0x9E09 0x9DFF 0x9DFD \ + 0x9E04 0x9EA0 0x9F1E 0x9F46 0x9F74 0x9F75 0x9F76 0x56D4 +90 0x652E 0x65B8 0x6B18 0x6B19 0x6B17 0x6B1A 0x7062 0x7226 \ + 0x72AA 0x77D8 0x77D9 0x7939 0x7C69 0x7C6B 0x7CF6 0x7E9A \ + 0x7E98 0x7E9B 0x7E99 0x81E0 0x81E1 0x8646 0x8647 0x8648 \ + 0x8979 0x897A 0x897C 0x897B 0x89FF 0x8B98 0x8B99 0x8EA5 \ + 0x8EA4 0x8EA3 0x946E 0x946D 0x946F 0x9471 0x9473 0x9749 \ + 0x9872 0x995F 0x9C68 0x9C6E 0x9C6D 0x9E0B 0x9E0D 0x9E10 \ + 0x9E0F 0x9E12 0x9E11 0x9EA1 0x9EF5 0x9F09 0x9F47 0x9F78 \ + 0x9F7B 0x9F7A 0x9F79 0x571E 0x7066 0x7C6F 0x883C 0x8DB2 \ + 0x8EA6 0x91C3 0x9474 0x9478 0x9476 0x9475 0x9A60 0x9C74 \ + 0x9C73 0x9C71 0x9C75 0x9E14 0x9E13 0x9EF6 0x9F0A 0x5995 \ + 0x5B8A 0x5C87 0x5E0D 0x5E8E 0x5F7A 0x6290 0x629A 0x653C \ + 0x653A 0x6598 0x6765 0x79C2 0x809E 0x81EB 0x8289 0x8296 \ + 0x8287 0x8FC0 0x8FC3 0x9578 0x9625 0x4E75 0x4E74 0x4F99 \ + 0x4F71 0x5153 0x51BF 0x51C0 0x51EE 0x523D 0x52BD 0x530C \ + 0x9FA4 0x7068 0x7065 0x7CF7 0x866A 0x883E 0x883D 0x883F \ + 0x8B9E 0x8C9C 0x8EA9 0x8EC9 0x974B 0x9873 0x9874 0x98CC \ + 0x9961 0x99AB 0x9A64 0x9A66 0x9A67 0x9B24 0x9E15 0x9E17 \ + 0x9F48 0x6207 0x6B1E 0x7227 0x864C 0x8EA8 0x9482 0x9480 \ + 0x9481 0x9A69 0x9A68 0x9B2E 0x9E19 0x7229 0x864B 0x8B9F \ + 0x9483 0x9C79 0x9EB7 0x7675 0x9A6B 0x9C7A 0x9E1D 0x7069 \ + 0x706A 0x9EA4 0x9F7E 0x9F49 0x9F98 0x7881 0x92B9 0x88CF \ + 0x58BB 0x6052 0x7CA7 0x5AFA 0x2554 0x2566 0x2557 0x2560 \ + 0x256C 0x2563 0x255A 0x2569 0x255D 0x2552 0x2564 0x2555 \ + 0x255E 0x256A 0x2561 0x2558 0x2567 0x255B 0x2553 0x2565 \ + 0x2556 0x255F 0x256B 0x2562 0x2559 0x2568 0x255C 0x2551 \ + 0x2550 0x2554 0x2557 0x255A 0x255D 0x2588 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +91 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x7F37 0x53C0 0x546E \ + 0x5483 0x545E 0x545D 0x577E 0x5779 0x577A 0x576C 0x5787 \ + 0x591D 0x5946 0x5943 0x5B61 0x5B66 0x5B90 0x5C29 0x5CB2 \ + 0x5CC0 0x601F 0x5FE2 0x6616 0x65F9 0x6788 0x679B 0x676E \ + 0x679E 0x6B24 0x6B7D 0x6CE6 0x6CCB 0x6CB5 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0x7097 0x709B 0x726B 0x72D5 0x7543 \ + 0x759C 0x77E4 0x7ACE 0x8013 0x80B7 0x80B9 0x81E4 0x81FD \ + 0x820F 0x82BF 0x82CA 0x82C1 0x8FD0 0x90AE 0x9638 0x4FBC \ + 0x4FE9 0x4FBD 0x4FE2 0x5158 0x52C6 0x52C8 0x5328 0x5329 \ + 0x57B4 0x57A9 0x5B68 0x5F2B 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +92 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0x5F8D 0x6018 0x6057 0x6048 0x6038 0x6071 0x6312 \ + 0x630A 0x6323 0x662A 0x67E0 0x67BE 0x6B29 0x6D43 0x70A6 \ + 0x70C0 0x722F 0x7271 0x74EA 0x7520 0x75A9 0x7685 0x7706 \ + 0x76F6 0x7700 0x7702 0x8009 0x82DA 0x830A 0x9655 0x9652 \ + 0x4E35 0x5034 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +93 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x5001 \ + 0x500A 0x5258 0x532B 0x54EC 0x5515 0x54FE 0x54E3 0x5516 \ + 0x57D3 0x5959 0x5A27 0x5A28 0x5A10 0x5A0E 0x5BAF 0x5BBA \ + 0x5BB1 0x5CFC 0x5CF2 0x5CFE 0x5DF8 0x5F2C 0x6082 0x6091 \ + 0x608F 0x6547 0x654C 0x658A 0x67E1 0x684A 0x683F 0x67BD \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +94 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x70C9 0x73BA 0x75C6 \ + 0x75B7 0x768C 0x768D 0x7717 0x771C 0x7714 0x7B0C 0x7D23 \ + 0x7F98 0x7F90 0x803A 0x8226 0x832E 0x8355 0x831A 0x833D \ + 0x8330 0x8651 0x8688 0x898E 0x898D 0x8A09 0x8A14 0x9007 \ + 0x9579 0x9584 0x9657 0x96BA 0x5067 0x5318 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE + +# eof diff --git a/contrib/ttf2pk/data/UBig5.sfd b/contrib/ttf2pk/data/UBig5.sfd new file mode 100644 index 0000000..84cae62 --- /dev/null +++ b/contrib/ttf2pk/data/UBig5.sfd @@ -0,0 +1,1854 @@ +# UBig5.sfd +# +# subfont numbers for Big 5 encoding and its corresponding code ranges +# to be used with the CJK package for LaTeX. +# +# The input encoding is Unicode. + +01 0x3000 0xFF0C 0x3001 0x3002 0xFF0E 0x2022 0xFF1B 0xFF1A \ + 0xFF1F 0xFF01 0xFE30 0x2026 0x2025 0xFE50 0xFF64 0xFE52 \ + 0x00B7 0xFE54 0xFE55 0xFE56 0xFE57 0xFF5C 0x2013 0xFE31 \ + 0x2014 0xFE33 0xFFFD 0xFE34 0xFE4F 0xFF08 0xFF09 0xFE35 \ + 0xFE36 0xFF5B 0xFF5D 0xFE37 0xFE38 0x3014 0x3015 0xFE39 \ + 0xFE3A 0x3010 0x3011 0xFE3B 0xFE3C 0x300A 0x300B 0xFE3D \ + 0xFE3E 0x3008 0x3009 0xFE3F 0xFE40 0x300C 0x300D 0xFE41 \ + 0xFE42 0x300E 0x300F 0xFE43 0xFE44 0xFE59 0xFE5A 0xFE5B \ + 0xFE5C 0xFE5D 0xFE5E 0x2018 0x2019 0x201C 0x201D 0x301D \ + 0x301E 0x2035 0x2032 0xFF03 0xFF06 0xFF0A 0x203B 0x00A7 \ + 0x3003 0x25CB 0x25CF 0x25B3 0x25B2 0x25CE 0x2606 0x2605 \ + 0x25C7 0x25C6 0x25A1 0x25A0 0x25BD 0x25BC 0x32A3 0x2105 \ + 0x203E 0xFFFD 0xFF3F 0xFFFD 0xFE49 0xFE4A 0xFE4D 0xFE4E \ + 0xFE4B 0xFE4C 0xFE5F 0xFE60 0xFE61 0xFF0B 0xFF0D 0x00D7 \ + 0x00F7 0x00B1 0x221A 0xFF1C 0xFF1E 0xFF1D 0x2266 0x2267 \ + 0x2260 0x221E 0x2252 0x2261 0xFE62 0xFE63 0xFE64 0xFE65 \ + 0xFE66 0x223C 0x2229 0x222A 0x22A5 0x2220 0x221F 0x22BF \ + 0x33D2 0x33D1 0x222B 0x222E 0x2235 0x2234 0x2640 0x2642 \ + 0x2641 0x2609 0x2191 0x2193 0x2190 0x2192 0x2196 0x2197 \ + 0x2199 0x2198 0x2225 0x2223 0xFFFD 0xFFFD 0xFF0F 0xFF3C \ + 0xFF04 0x00A5 0x3012 0x00A2 0x00A3 0xFF05 0xFF20 0x2103 \ + 0x2109 0xFE69 0xFE6A 0xFE6B 0x33D5 0x339C 0x339D 0x339E \ + 0x33CE 0x33A1 0x338E 0x338F 0x33C4 0x00B0 0x5159 0x515B \ + 0x515E 0x515D 0x5161 0x5163 0x55E7 0x74E9 0x7CCE 0x2581 \ + 0x2582 0x2583 0x2584 0x2585 0x2586 0x2587 0x2588 0x258F \ + 0x258E 0x258D 0x258C 0x258B 0x258A 0x2589 0x253C 0x2534 \ + 0x252C 0x2524 0x251C 0x2594 0x2500 0x2502 0x2595 0x250C \ + 0x2510 0x2514 0x2518 0x256D 0x256E 0x2570 0x256F 0x2550 \ + 0x255E 0x256A 0x2561 0x25E2 0x25E3 0x25E5 0x25E4 0x2571 \ + 0x2572 0x2573 0xFF10 0xFF11 0xFF12 0xFF13 0xFF14 0xFF15 \ + 0xFF16 0xFF17 0xFF18 0xFF19 0x2160 0x2161 0x2162 0x2163 \ + 0x2164 0x2165 0x2166 0x2167 0x2168 0x2169 0x3021 0x3022 +02 0x3023 0x3024 0x3025 0x3026 0x3027 0x3028 0x3029 0xFFFD \ + 0x5344 0xFFFD 0xFF21 0xFF22 0xFF23 0xFF24 0xFF25 0xFF26 \ + 0xFF27 0xFF28 0xFF29 0xFF2A 0xFF2B 0xFF2C 0xFF2D 0xFF2E \ + 0xFF2F 0xFF30 0xFF31 0xFF32 0xFF33 0xFF34 0xFF35 0xFF36 \ + 0xFF37 0xFF38 0xFF39 0xFF3A 0xFF41 0xFF42 0xFF43 0xFF44 \ + 0xFF45 0xFF46 0xFF47 0xFF48 0xFF49 0xFF4A 0xFF4B 0xFF4C \ + 0xFF4D 0xFF4E 0xFF4F 0xFF50 0xFF51 0xFF52 0xFF53 0xFF54 \ + 0xFF55 0xFF56 0xFF57 0xFF58 0xFF59 0xFF5A 0x0391 0x0392 \ + 0x0393 0x0394 0x0395 0x0396 0x0397 0x0398 0x0399 0x039A \ + 0x039B 0x039C 0x039D 0x039E 0x039F 0x03A0 0x03A1 0x03A3 \ + 0x03A4 0x03A5 0x03A6 0x03A7 0x03A8 0x03A9 0x03B1 0x03B2 \ + 0x03B3 0x03B4 0x03B5 0x03B6 0x03B7 0x03B8 0x03B9 0x03BA \ + 0x03BB 0x03BC 0x03BD 0x03BE 0x03BF 0x03C0 0x03C1 0x03C3 \ + 0x03C4 0x03C5 0x03C6 0x03C7 0x03C8 0x03C9 0x3105 0x3106 \ + 0x3107 0x3108 0x3109 0x310A 0x310B 0x310C 0x310D 0x310E \ + 0x310F 0x3110 0x3111 0x3112 0x3113 0x3114 0x3115 0x3116 \ + 0x3117 0x3118 0x3119 0x311A 0x311B 0x311C 0x311D 0x311E \ + 0x311F 0x3120 0x3121 0x3122 0x3123 0x3124 0x3125 0x3126 \ + 0x3127 0x3128 0x3129 0x02D9 0x02C9 0x02CA 0x02C7 0x02CB \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x4E00 \ + 0x4E59 0x4E01 0x4E03 0x4E43 0x4E5D 0x4E86 0x4E8C 0x4EBA \ + 0x513F 0x5165 0x516B 0x51E0 0x5200 0x5201 0x529B 0x5315 \ + 0x5341 0x535C 0x53C8 0x4E09 0x4E0B 0x4E08 0x4E0A 0x4E2B \ + 0x4E38 0x51E1 0x4E45 0x4E48 0x4E5F 0x4E5E 0x4E8E 0x4EA1 \ + 0x5140 0x5203 0x52FA 0x5343 0x53C9 0x53E3 0x571F 0x58EB +03 0x5915 0x5927 0x5973 0x5B50 0x5B51 0x5B53 0x5BF8 0x5C0F \ + 0x5C22 0x5C38 0x5C71 0x5DDD 0x5DE5 0x5DF1 0x5DF2 0x5DF3 \ + 0x5DFE 0x5E72 0x5EFE 0x5F0B 0x5F13 0x624D 0x4E11 0x4E10 \ + 0x4E0D 0x4E2D 0x4E30 0x4E39 0x4E4B 0x5C39 0x4E88 0x4E91 \ + 0x4E95 0x4E92 0x4E94 0x4EA2 0x4EC1 0x4EC0 0x4EC3 0x4EC6 \ + 0x4EC7 0x4ECD 0x4ECA 0x4ECB 0x4EC4 0x5143 0x5141 0x5167 \ + 0x516D 0x516E 0x516C 0x5197 0x51F6 0x5206 0x5207 0x5208 \ + 0x52FB 0x52FE 0x52FF 0x5316 0x5339 0x5348 0x5347 0x5345 \ + 0x535E 0x5384 0x53CB 0x53CA 0x53CD 0x58EC 0x5929 0x592B \ + 0x592A 0x592D 0x5B54 0x5C11 0x5C24 0x5C3A 0x5C6F 0x5DF4 \ + 0x5E7B 0x5EFF 0x5F14 0x5F15 0x5FC3 0x6208 0x6236 0x624B \ + 0x624E 0x652F 0x6587 0x6597 0x65A4 0x65B9 0x65E5 0x66F0 \ + 0x6708 0x6728 0x6B20 0x6B62 0x6B79 0x6BCB 0x6BD4 0x6BDB \ + 0x6C0F 0x6C34 0x706B 0x722A 0x7236 0x723B 0x7247 0x7259 \ + 0x725B 0x72AC 0x738B 0x4E19 0x4E16 0x4E15 0x4E14 0x4E18 \ + 0x4E3B 0x4E4D 0x4E4F 0x4E4E 0x4EE5 0x4ED8 0x4ED4 0x4ED5 \ + 0x4ED6 0x4ED7 0x4EE3 0x4EE4 0x4ED9 0x4EDE 0x5145 0x5144 \ + 0x5189 0x518A 0x51AC 0x51F9 0x51FA 0x51F8 0x520A 0x52A0 \ + 0x529F 0x5305 0x5306 0x5317 0x531D 0x4EDF 0x534A 0x5349 \ + 0x5361 0x5360 0x536F 0x536E 0x53BB 0x53EF 0x53E4 0x53F3 \ + 0x53EC 0x53EE 0x53E9 0x53E8 0x53FC 0x53F8 0x53F5 0x53EB \ + 0x53E6 0x53EA 0x53F2 0x53F1 0x53F0 0x53E5 0x53ED 0x53FB \ + 0x56DB 0x56DA 0x5916 0x592E 0x5931 0x5974 0x5976 0x5B55 \ + 0x5B83 0x5C3C 0x5DE8 0x5DE7 0x5DE6 0x5E02 0x5E03 0x5E73 \ + 0x5E7C 0x5F01 0x5F18 0x5F17 0x5FC5 0x620A 0x6253 0x6254 \ + 0x6252 0x6251 0x65A5 0x65E6 0x672E 0x672C 0x672A 0x672B \ + 0x672D 0x6B63 0x6BCD 0x6C11 0x6C10 0x6C38 0x6C41 0x6C40 \ + 0x6C3E 0x72AF 0x7384 0x7389 0x74DC 0x74E6 0x7518 0x751F \ + 0x7528 0x7529 0x7530 0x7531 0x7532 0x7533 0x758B 0x767D \ + 0x76AE 0x76BF 0x76EE 0x77DB 0x77E2 0x77F3 0x793A 0x79BE \ + 0x7A74 0x7ACB 0x4E1E 0x4E1F 0x4E52 0x4E53 0x4E69 0x4E99 \ + 0x4EA4 0x4EA6 0x4EA5 0x4EFF 0x4F09 0x4F19 0x4F0A 0x4F15 +04 0x4F0D 0x4F10 0x4F11 0x4F0F 0x4EF2 0x4EF6 0x4EFB 0x4EF0 \ + 0x4EF3 0x4EFD 0x4F01 0x4F0B 0x5149 0x5147 0x5146 0x5148 \ + 0x5168 0x5171 0x518D 0x51B0 0x5217 0x5211 0x5212 0x520E \ + 0x5216 0x52A3 0x5308 0x5321 0x5320 0x5370 0x5371 0x5409 \ + 0x540F 0x540C 0x540A 0x5410 0x5401 0x540B 0x5404 0x5411 \ + 0x540D 0x5408 0x5403 0x540E 0x5406 0x5412 0x56E0 0x56DE \ + 0x56DD 0x5733 0x5730 0x5728 0x572D 0x572C 0x572F 0x5729 \ + 0x5919 0x591A 0x5937 0x5938 0x5984 0x5978 0x5983 0x597D \ + 0x5979 0x5982 0x5981 0x5B57 0x5B58 0x5B87 0x5B88 0x5B85 \ + 0x5B89 0x5BFA 0x5C16 0x5C79 0x5DDE 0x5E06 0x5E76 0x5E74 \ + 0x5F0F 0x5F1B 0x5FD9 0x5FD6 0x620E 0x620C 0x620D 0x6210 \ + 0x6263 0x625B 0x6258 0x6536 0x65E9 0x65E8 0x65EC 0x65ED \ + 0x66F2 0x66F3 0x6709 0x673D 0x6734 0x6731 0x6735 0x6B21 \ + 0x6B64 0x6B7B 0x6C16 0x6C5D 0x6C57 0x6C59 0x6C5F 0x6C60 \ + 0x6C50 0x6C55 0x6C61 0x6C5B 0x6C4D 0x6C4E 0x7070 0x725F \ + 0x725D 0x767E 0x7AF9 0x7C73 0x7CF8 0x7F36 0x7F8A 0x7FBD \ + 0x8001 0x8003 0x800C 0x8012 0x8033 0x807F 0x8089 0x808B \ + 0x808C 0x81E3 0x81EA 0x81F3 0x81FC 0x820C 0x821B 0x821F \ + 0x826E 0x8272 0x827E 0x866B 0x8840 0x884C 0x8863 0x897F \ + 0x9621 0x4E32 0x4EA8 0x4F4D 0x4F4F 0x4F47 0x4F57 0x4F5E \ + 0x4F34 0x4F5B 0x4F55 0x4F30 0x4F50 0x4F51 0x4F3D 0x4F3A \ + 0x4F38 0x4F43 0x4F54 0x4F3C 0x4F46 0x4F63 0x4F5C 0x4F60 \ + 0x4F2F 0x4F4E 0x4F36 0x4F59 0x4F5D 0x4F48 0x4F5A 0x514C \ + 0x514B 0x514D 0x5175 0x51B6 0x51B7 0x5225 0x5224 0x5229 \ + 0x522A 0x5228 0x52AB 0x52A9 0x52AA 0x52AC 0x5323 0x5373 \ + 0x5375 0x541D 0x542D 0x541E 0x543E 0x5426 0x544E 0x5427 \ + 0x5446 0x5443 0x5433 0x5448 0x5442 0x541B 0x5429 0x544A \ + 0x5439 0x543B 0x5438 0x542E 0x5435 0x5436 0x5420 0x543C \ + 0x5440 0x5431 0x542B 0x541F 0x542C 0x56EA 0x56F0 0x56E4 \ + 0x56EB 0x574A 0x5751 0x5740 0x574D 0x5747 0x574E 0x573E \ + 0x5750 0x574F 0x573B 0x58EF 0x593E 0x599D 0x5992 0x59A8 \ + 0x599E 0x59A3 0x5999 0x5996 0x598D 0x59A4 0x5993 0x598A +05 0x59A5 0x5B5D 0x5B5C 0x5B5A 0x5B5B 0x5B8C 0x5B8B 0x5B8F \ + 0x5C2C 0x5C40 0x5C41 0x5C3F 0x5C3E 0x5C90 0x5C91 0x5C94 \ + 0x5C8C 0x5DEB 0x5E0C 0x5E8F 0x5E87 0x5E8A 0x5EF7 0x5F04 \ + 0x5F1F 0x5F64 0x5F62 0x5F77 0x5F79 0x5FD8 0x5FCC 0x5FD7 \ + 0x5FCD 0x5FF1 0x5FEB 0x5FF8 0x5FEA 0x6212 0x6211 0x6284 \ + 0x6297 0x6296 0x6280 0x6276 0x6289 0x626D 0x628A 0x627C \ + 0x627E 0x6279 0x6273 0x6292 0x626F 0x6298 0x626E 0x6295 \ + 0x6293 0x6291 0x6286 0x6539 0x653B 0x6538 0x65F1 0x66F4 \ + 0x675F 0x674E 0x674F 0x6750 0x6751 0x675C 0x6756 0x675E \ + 0x6749 0x6746 0x6760 0x6753 0x6757 0x6B65 0x6BCF 0x6C42 \ + 0x6C5E 0x6C99 0x6C81 0x6C88 0x6C89 0x6C85 0x6C9B 0x6C6A \ + 0x6C7A 0x6C90 0x6C70 0x6C8C 0x6C68 0x6C96 0x6C92 0x6C7D \ + 0x6C83 0x6C72 0x6C7E 0x6C74 0x6C86 0x6C76 0x6C8D 0x6C94 \ + 0x6C98 0x6C82 0x7076 0x707C 0x707D 0x7078 0x7262 0x7261 \ + 0x7260 0x72C4 0x72C2 0x7396 0x752C 0x752B 0x7537 0x7538 \ + 0x7682 0x76EF 0x77E3 0x79C1 0x79C0 0x79BF 0x7A76 0x7CFB \ + 0x7F55 0x8096 0x8093 0x809D 0x8098 0x809B 0x809A 0x80B2 \ + 0x826F 0x8292 0x828B 0x828D 0x898B 0x89D2 0x8A00 0x8C37 \ + 0x8C46 0x8C55 0x8C9D 0x8D64 0x8D70 0x8DB3 0x8EAB 0x8ECA \ + 0x8F9B 0x8FB0 0x8FC2 0x8FC6 0x8FC5 0x8FC4 0x5DE1 0x9091 \ + 0x90A2 0x90AA 0x90A6 0x90A3 0x9149 0x91C6 0x91CC 0x9632 \ + 0x962E 0x9631 0x962A 0x962C 0x4E26 0x4E56 0x4E73 0x4E8B \ + 0x4E9B 0x4E9E 0x4EAB 0x4EAC 0x4F6F 0x4F9D 0x4F8D 0x4F73 \ + 0x4F7F 0x4F6C 0x4F9B 0x4F8B 0x4F86 0x4F83 0x4F70 0x4F75 \ + 0x4F88 0x4F69 0x4F7B 0x4F96 0x4F7E 0x4F8F 0x4F91 0x4F7A \ + 0x5154 0x5152 0x5155 0x5169 0x5177 0x5176 0x5178 0x51BD \ + 0x51FD 0x523B 0x5238 0x5237 0x523A 0x5230 0x522E 0x5236 \ + 0x5241 0x52BE 0x52BB 0x5352 0x5354 0x5353 0x5351 0x5366 \ + 0x5377 0x5378 0x5379 0x53D6 0x53D4 0x53D7 0x5473 0x5475 \ + 0x5496 0x5478 0x5495 0x5480 0x547B 0x5477 0x5484 0x5492 \ + 0x5486 0x547C 0x5490 0x5471 0x5476 0x548C 0x549A 0x5462 \ + 0x5468 0x548B 0x547D 0x548E 0x56FA 0x5783 0x5777 0x576A +06 0x5769 0x5761 0x5766 0x5764 0x577C 0x591C 0x5949 0x5947 \ + 0x5948 0x5944 0x5954 0x59BE 0x59BB 0x59D4 0x59B9 0x59AE \ + 0x59D1 0x59C6 0x59D0 0x59CD 0x59CB 0x59D3 0x59CA 0x59AF \ + 0x59B3 0x59D2 0x59C5 0x5B5F 0x5B64 0x5B63 0x5B97 0x5B9A \ + 0x5B98 0x5B9C 0x5B99 0x5B9B 0x5C1A 0x5C48 0x5C45 0x5C46 \ + 0x5CB7 0x5CA1 0x5CB8 0x5CA9 0x5CAB 0x5CB1 0x5CB3 0x5E18 \ + 0x5E1A 0x5E16 0x5E15 0x5E1B 0x5E11 0x5E78 0x5E9A 0x5E97 \ + 0x5E9C 0x5E95 0x5E96 0x5EF6 0x5F26 0x5F27 0x5F29 0x5F80 \ + 0x5F81 0x5F7F 0x5F7C 0x5FDD 0x5FE0 0x5FFD 0x5FF5 0x5FFF \ + 0x600F 0x6014 0x602F 0x6035 0x6016 0x602A 0x6015 0x6021 \ + 0x6027 0x6029 0x602B 0x601B 0x6216 0x6215 0x623F 0x623E \ + 0x6240 0x627F 0x62C9 0x62CC 0x62C4 0x62BF 0x62C2 0x62B9 \ + 0x62D2 0x62DB 0x62AB 0x62D3 0x62D4 0x62CB 0x62C8 0x62A8 \ + 0x62BD 0x62BC 0x62D0 0x62D9 0x62C7 0x62CD 0x62B5 0x62DA \ + 0x62B1 0x62D8 0x62D6 0x62D7 0x62C6 0x62AC 0x62CE 0x653E \ + 0x65A7 0x65BC 0x65FA 0x6614 0x6613 0x660C 0x6606 0x6602 \ + 0x660E 0x6600 0x660F 0x6615 0x660A 0x6607 0x670D 0x670B \ + 0x676D 0x678B 0x6795 0x6771 0x679C 0x6773 0x6777 0x6787 \ + 0x679D 0x6797 0x676F 0x6770 0x677F 0x6789 0x677E 0x6790 \ + 0x6775 0x679A 0x6793 0x677C 0x676A 0x6772 0x6B23 0x6B66 \ + 0x6B67 0x6B7F 0x6C13 0x6C1B 0x6CE3 0x6CE8 0x6CF3 0x6CB1 \ + 0x6CCC 0x6CE5 0x6CB3 0x6CBD 0x6CBE 0x6CBC 0x6CE2 0x6CAB \ + 0x6CD5 0x6CD3 0x6CB8 0x6CC4 0x6CB9 0x6CC1 0x6CAE 0x6CD7 \ + 0x6CC5 0x6CF1 0x6CBF 0x6CBB 0x6CE1 0x6CDB 0x6CCA 0x6CAC \ + 0x6CEF 0x6CDC 0x6CD6 0x6CE0 0x7095 0x708E 0x7092 0x708A \ + 0x7099 0x722C 0x722D 0x7238 0x7248 0x7267 0x7269 0x72C0 \ + 0x72CE 0x72D9 0x72D7 0x72D0 0x73A9 0x73A8 0x739F 0x73AB \ + 0x73A5 0x753D 0x759D 0x7599 0x759A 0x7684 0x76C2 0x76F2 \ + 0x76F4 0x77E5 0x77FD 0x793E 0x7940 0x7941 0x79C9 0x79C8 \ + 0x7A7A 0x7A79 0x7AFA 0x7CFE 0x7F54 0x7F8C 0x7F8B 0x8005 \ + 0x80BA 0x80A5 0x80A2 0x80B1 0x80A1 0x80AB 0x80A9 0x80B4 \ + 0x80AA 0x80AF 0x81E5 0x81FE 0x820D 0x82B3 0x829D 0x8299 +07 0x82AD 0x82BD 0x829F 0x82B9 0x82B1 0x82AC 0x82A5 0x82AF \ + 0x82B8 0x82A3 0x82B0 0x82BE 0x82B7 0x864E 0x8671 0x521D \ + 0x8868 0x8ECB 0x8FCE 0x8FD4 0x8FD1 0x90B5 0x90B8 0x90B1 \ + 0x90B6 0x91C7 0x91D1 0x9577 0x9580 0x961C 0x9640 0x963F \ + 0x963B 0x9644 0x9642 0x96B9 0x96E8 0x9752 0x975E 0x4E9F \ + 0x4EAD 0x4EAE 0x4FE1 0x4FB5 0x4FAF 0x4FBF 0x4FE0 0x4FD1 \ + 0x4FCF 0x4FDD 0x4FC3 0x4FB6 0x4FD8 0x4FDF 0x4FCA 0x4FD7 \ + 0x4FAE 0x4FD0 0x4FC4 0x4FC2 0x4FDA 0x4FCE 0x4FDE 0x4FB7 \ + 0x5157 0x5192 0x5191 0x51A0 0x524E 0x5243 0x524A 0x524D \ + 0x524C 0x524B 0x5247 0x52C7 0x52C9 0x52C3 0x52C1 0x530D \ + 0x5357 0x537B 0x539A 0x53DB 0x54AC 0x54C0 0x54A8 0x54CE \ + 0x54C9 0x54B8 0x54A6 0x54B3 0x54C7 0x54C2 0x54BD 0x54AA \ + 0x54C1 0x54C4 0x54C8 0x54AF 0x54AB 0x54B1 0x54BB 0x54A9 \ + 0x54A7 0x54BF 0x56FF 0x5782 0x578B 0x57A0 0x57A3 0x57A2 \ + 0x57CE 0x57AE 0x5793 0x5955 0x5951 0x594F 0x594E 0x5950 \ + 0x59DC 0x59D8 0x59FF 0x59E3 0x59E8 0x5A03 0x59E5 0x59EA \ + 0x59DA 0x59E6 0x5A01 0x59FB 0x5B69 0x5BA3 0x5BA6 0x5BA4 \ + 0x5BA2 0x5BA5 0x5C01 0x5C4E 0x5C4F 0x5C4D 0x5C4B 0x5CD9 \ + 0x5CD2 0x5DF7 0x5E1D 0x5E25 0x5E1F 0x5E7D 0x5EA0 0x5EA6 \ + 0x5EFA 0x5F08 0x5F2D 0x5F65 0x5F88 0x5F85 0x5F8A 0x5F8B \ + 0x5F87 0x5F8C 0x5F89 0x6012 0x601D 0x6020 0x6025 0x600E \ + 0x6028 0x604D 0x6070 0x6068 0x6062 0x6046 0x6043 0x606C \ + 0x606B 0x606A 0x6064 0x6241 0x62DC 0x6316 0x6309 0x62FC \ + 0x62ED 0x6301 0x62EE 0x62FD 0x6307 0x62F1 0x62F7 0x62EF \ + 0x62EC 0x62FE 0x62F4 0x6311 0x6302 0x653F 0x6545 0x65AB \ + 0x65BD 0x65E2 0x6625 0x662D 0x6620 0x6627 0x662F 0x661F \ + 0x6628 0x6631 0x6624 0x66F7 0x67FF 0x67D3 0x67F1 0x67D4 \ + 0x67D0 0x67EC 0x67B6 0x67AF 0x67F5 0x67E9 0x67EF 0x67C4 \ + 0x67D1 0x67B4 0x67DA 0x67E5 0x67B8 0x67CF 0x67DE 0x67F3 \ + 0x67B0 0x67D9 0x67E2 0x67DD 0x67D2 0x6B6A 0x6B83 0x6B86 \ + 0x6BB5 0x6BD2 0x6BD7 0x6C1F 0x6CC9 0x6D0B 0x6D32 0x6D2A \ + 0x6D41 0x6D25 0x6D0C 0x6D31 0x6D1E 0x6D17 0x6D3B 0x6D3D +08 0x6D3E 0x6D36 0x6D1B 0x6CF5 0x6D39 0x6D27 0x6D38 0x6D29 \ + 0x6D2E 0x6D35 0x6D0E 0x6D2B 0x70AB 0x70BA 0x70B3 0x70AC \ + 0x70AF 0x70AD 0x70B8 0x70AE 0x70A4 0x7230 0x7272 0x726F \ + 0x7274 0x72E9 0x72E0 0x72E1 0x73B7 0x73CA 0x73BB 0x73B2 \ + 0x73CD 0x73C0 0x73B3 0x751A 0x752D 0x754F 0x754C 0x754E \ + 0x754B 0x75AB 0x75A4 0x75A5 0x75A2 0x75A3 0x7678 0x7686 \ + 0x7687 0x7688 0x76C8 0x76C6 0x76C3 0x76C5 0x7701 0x76F9 \ + 0x76F8 0x7709 0x770B 0x76FE 0x76FC 0x7707 0x77DC 0x7802 \ + 0x7814 0x780C 0x780D 0x7946 0x7949 0x7948 0x7947 0x79B9 \ + 0x79BA 0x79D1 0x79D2 0x79CB 0x7A7F 0x7A81 0x7AFF 0x7AFD \ + 0x7C7D 0x7D02 0x7D05 0x7D00 0x7D09 0x7D07 0x7D04 0x7D06 \ + 0x7F38 0x7F8E 0x7FBF 0x8004 0x8010 0x800D 0x8011 0x8036 \ + 0x80D6 0x80E5 0x80DA 0x80C3 0x80C4 0x80CC 0x80E1 0x80DB \ + 0x80CE 0x80DE 0x80E4 0x80DD 0x81F4 0x8222 0x82E7 0x8303 \ + 0x8305 0x82E3 0x82DB 0x82E6 0x8304 0x82E5 0x8302 0x8309 \ + 0x82D2 0x82D7 0x82F1 0x8301 0x82DC 0x82D4 0x82D1 0x82DE \ + 0x82D3 0x82DF 0x82EF 0x8306 0x8650 0x8679 0x867B 0x867A \ + 0x884D 0x886B 0x8981 0x89D4 0x8A08 0x8A02 0x8A03 0x8C9E \ + 0x8CA0 0x8D74 0x8D73 0x8DB4 0x8ECD 0x8ECC 0x8FF0 0x8FE6 \ + 0x8FE2 0x8FEA 0x8FE5 0x8FED 0x8FEB 0x8FE4 0x8FE8 0x90CA \ + 0x90CE 0x90C1 0x90C3 0x914B 0x914A 0x91CD 0x9582 0x9650 \ + 0x964B 0x964C 0x964D 0x9762 0x9769 0x97CB 0x97ED 0x97F3 \ + 0x9801 0x98A8 0x98DB 0x98DF 0x9996 0x9999 0x4E58 0x4EB3 \ + 0x500C 0x500D 0x5023 0x4FEF 0x5026 0x5025 0x4FF8 0x5029 \ + 0x5016 0x5006 0x503C 0x501F 0x501A 0x5012 0x5011 0x4FFA \ + 0x5000 0x5014 0x5028 0x4FF1 0x5021 0x500B 0x5019 0x5018 \ + 0x4FF3 0x4FEE 0x502D 0x502A 0x4FFE 0x502B 0x5009 0x517C \ + 0x51A4 0x51A5 0x51A2 0x51CD 0x51CC 0x51C6 0x51CB 0x5256 \ + 0x525C 0x5254 0x525B 0x525D 0x532A 0x537F 0x539F 0x539D \ + 0x53DF 0x54E8 0x5510 0x5501 0x5537 0x54FC 0x54E5 0x54F2 \ + 0x5506 0x54FA 0x5514 0x54E9 0x54ED 0x54E1 0x5509 0x54EE \ + 0x54EA 0x54E6 0x5527 0x5507 0x54FD 0x550F 0x5703 0x5704 +09 0x57C2 0x57D4 0x57CB 0x57C3 0x5809 0x590F 0x5957 0x5958 \ + 0x595A 0x5A11 0x5A18 0x5A1C 0x5A1F 0x5A1B 0x5A13 0x59EC \ + 0x5A20 0x5A23 0x5A29 0x5A25 0x5A0C 0x5A09 0x5B6B 0x5C58 \ + 0x5BB0 0x5BB3 0x5BB6 0x5BB4 0x5BAE 0x5BB5 0x5BB9 0x5BB8 \ + 0x5C04 0x5C51 0x5C55 0x5C50 0x5CED 0x5CFD 0x5CFB 0x5CEA \ + 0x5CE8 0x5CF0 0x5CF6 0x5D01 0x5CF4 0x5DEE 0x5E2D 0x5E2B \ + 0x5EAB 0x5EAD 0x5EA7 0x5F31 0x5F92 0x5F91 0x5F90 0x6059 \ + 0x6063 0x6065 0x6050 0x6055 0x606D 0x6069 0x606F 0x6084 \ + 0x609F 0x609A 0x608D 0x6094 0x608C 0x6085 0x6096 0x6247 \ + 0x62F3 0x6308 0x62FF 0x634E 0x633E 0x632F 0x6355 0x6342 \ + 0x6346 0x634F 0x6349 0x633A 0x6350 0x633D 0x632A 0x632B \ + 0x6328 0x634D 0x634C 0x6548 0x6549 0x6599 0x65C1 0x65C5 \ + 0x6642 0x6649 0x664F 0x6643 0x6652 0x664C 0x6645 0x6641 \ + 0x66F8 0x6714 0x6715 0x6717 0x6821 0x6838 0x6848 0x6846 \ + 0x6853 0x6839 0x6842 0x6854 0x6829 0x68B3 0x6817 0x684C \ + 0x6851 0x683D 0x67F4 0x6850 0x6840 0x683C 0x6843 0x682A \ + 0x6845 0x6813 0x6818 0x6841 0x6B8A 0x6B89 0x6BB7 0x6C23 \ + 0x6C27 0x6C28 0x6C26 0x6C24 0x6CF0 0x6D6A 0x6D95 0x6D88 \ + 0x6D87 0x6D66 0x6D78 0x6D77 0x6D59 0x6D93 0x6D6C 0x6D89 \ + 0x6D6E 0x6D5A 0x6D74 0x6D69 0x6D8C 0x6D8A 0x6D79 0x6D85 \ + 0x6D65 0x6D94 0x70CA 0x70D8 0x70E4 0x70D9 0x70C8 0x70CF \ + 0x7239 0x7279 0x72FC 0x72F9 0x72FD 0x72F8 0x72F7 0x7386 \ + 0x73ED 0x7409 0x73EE 0x73E0 0x73EA 0x73DE 0x7554 0x755D \ + 0x755C 0x755A 0x7559 0x75BE 0x75C5 0x75C7 0x75B2 0x75B3 \ + 0x75BD 0x75BC 0x75B9 0x75C2 0x75B8 0x768B 0x76B0 0x76CA \ + 0x76CD 0x76CE 0x7729 0x771F 0x7720 0x7728 0x77E9 0x7830 \ + 0x7827 0x7838 0x781D 0x7834 0x7837 0x7825 0x782D 0x7820 \ + 0x781F 0x7832 0x7955 0x7950 0x7960 0x795F 0x7956 0x795E \ + 0x795D 0x7957 0x795A 0x79E4 0x79E3 0x79E7 0x79DF 0x79E6 \ + 0x79E9 0x79D8 0x7A84 0x7A88 0x7AD9 0x7B06 0x7B11 0x7C89 \ + 0x7D21 0x7D17 0x7D0B 0x7D0A 0x7D20 0x7D22 0x7D14 0x7D10 \ + 0x7D15 0x7D1A 0x7D1C 0x7D0D 0x7D19 0x7D1B 0x7F3A 0x7F5F +10 0x7F94 0x7FC5 0x7FC1 0x8006 0x8018 0x8015 0x8019 0x8017 \ + 0x803D 0x803F 0x80F1 0x8102 0x80F0 0x8105 0x80ED 0x80F4 \ + 0x8106 0x80F8 0x80F3 0x8108 0x80FD 0x810A 0x80FC 0x80EF \ + 0x81ED 0x81EC 0x8200 0x8210 0x822A 0x822B 0x8228 0x822C \ + 0x82BB 0x832B 0x8352 0x8354 0x834A 0x8338 0x8350 0x8349 \ + 0x8335 0x8334 0x834F 0x8332 0x8339 0x8336 0x8317 0x8340 \ + 0x8331 0x8328 0x8343 0x8654 0x868A 0x86AA 0x8693 0x86A4 \ + 0x86A9 0x868C 0x86A3 0x869C 0x8870 0x8877 0x8881 0x8882 \ + 0x887D 0x8879 0x8A18 0x8A10 0x8A0E 0x8A0C 0x8A15 0x8A0A \ + 0x8A17 0x8A13 0x8A16 0x8A0F 0x8A11 0x8C48 0x8C7A 0x8C79 \ + 0x8CA1 0x8CA2 0x8D77 0x8EAC 0x8ED2 0x8ED4 0x8ECF 0x8FB1 \ + 0x9001 0x9006 0x8FF7 0x9000 0x8FFA 0x8FF4 0x9003 0x8FFD \ + 0x9005 0x8FF8 0x9095 0x90E1 0x90DD 0x90E2 0x9152 0x914D \ + 0x914C 0x91D8 0x91DD 0x91D7 0x91DC 0x91D9 0x9583 0x9662 \ + 0x9663 0x9661 0x965B 0x965D 0x9664 0x9658 0x965E 0x96BB \ + 0x98E2 0x99AC 0x9AA8 0x9AD8 0x9B25 0x9B32 0x9B3C 0x4E7E \ + 0x507A 0x507D 0x505C 0x5047 0x5043 0x504C 0x505A 0x5049 \ + 0x5065 0x5076 0x504E 0x5055 0x5075 0x5074 0x5077 0x504F \ + 0x500F 0x506F 0x506D 0x515C 0x5195 0x51F0 0x526A 0x526F \ + 0x52D2 0x52D9 0x52D8 0x52D5 0x5310 0x530F 0x5319 0x533F \ + 0x5340 0x533E 0x53C3 0x66FC 0x5546 0x556A 0x5566 0x5544 \ + 0x555E 0x5561 0x5543 0x554A 0x5531 0x5556 0x554F 0x5555 \ + 0x552F 0x5564 0x5538 0x552E 0x555C 0x552C 0x5563 0x5533 \ + 0x5541 0x5557 0x5708 0x570B 0x5709 0x57DF 0x5805 0x580A \ + 0x5806 0x57E0 0x57E4 0x57FA 0x5802 0x5835 0x57F7 0x57F9 \ + 0x5920 0x5962 0x5A36 0x5A41 0x5A49 0x5A66 0x5A6A 0x5A40 \ + 0x5A3C 0x5A62 0x5A5A 0x5A46 0x5A4A 0x5B70 0x5BC7 0x5BC5 \ + 0x5BC4 0x5BC2 0x5BBF 0x5BC6 0x5C09 0x5C08 0x5C07 0x5C60 \ + 0x5C5C 0x5C5D 0x5D07 0x5D06 0x5D0E 0x5D1B 0x5D16 0x5D22 \ + 0x5D11 0x5D29 0x5D14 0x5D19 0x5D24 0x5D27 0x5D17 0x5DE2 \ + 0x5E38 0x5E36 0x5E33 0x5E37 0x5EB7 0x5EB8 0x5EB6 0x5EB5 \ + 0x5EBE 0x5F35 0x5F37 0x5F57 0x5F6C 0x5F69 0x5F6B 0x5F97 +11 0x5F99 0x5F9E 0x5F98 0x5FA1 0x5FA0 0x5F9C 0x607F 0x60A3 \ + 0x6089 0x60A0 0x60A8 0x60CB 0x60B4 0x60E6 0x60BD 0x60C5 \ + 0x60BB 0x60B5 0x60DC 0x60BC 0x60D8 0x60D5 0x60C6 0x60DF \ + 0x60B8 0x60DA 0x60C7 0x621A 0x621B 0x6248 0x63A0 0x63A7 \ + 0x6372 0x6396 0x63A2 0x63A5 0x6377 0x6367 0x6398 0x63AA \ + 0x6371 0x63A9 0x6389 0x6383 0x639B 0x636B 0x63A8 0x6384 \ + 0x6388 0x6399 0x63A1 0x63AC 0x6392 0x638F 0x6380 0x637B \ + 0x6369 0x6368 0x637A 0x655D 0x6556 0x6551 0x6559 0x6557 \ + 0x555F 0x654F 0x6558 0x6555 0x6554 0x659C 0x659B 0x65AC \ + 0x65CF 0x65CB 0x65CC 0x65CE 0x665D 0x665A 0x6664 0x6668 \ + 0x6666 0x665E 0x66F9 0x52D7 0x671B 0x6881 0x68AF 0x68A2 \ + 0x6893 0x68B5 0x687F 0x6876 0x68B1 0x68A7 0x6897 0x68B0 \ + 0x6883 0x68C4 0x68AD 0x6886 0x6885 0x6894 0x689D 0x68A8 \ + 0x689F 0x68A1 0x6882 0x6B32 0x6BBA 0x6BEB 0x6BEC 0x6C2B \ + 0x6D8E 0x6DBC 0x6DF3 0x6DD9 0x6DB2 0x6DE1 0x6DCC 0x6DE4 \ + 0x6DFB 0x6DFA 0x6E05 0x6DC7 0x6DCB 0x6DAF 0x6DD1 0x6DAE \ + 0x6DDE 0x6DF9 0x6DB8 0x6DF7 0x6DF5 0x6DC5 0x6DD2 0x6E1A \ + 0x6DB5 0x6DDA 0x6DEB 0x6DD8 0x6DEA 0x6DF1 0x6DEE 0x6DE8 \ + 0x6DC6 0x6DC4 0x6DAA 0x6DEC 0x6DBF 0x6DE6 0x70F9 0x7109 \ + 0x710A 0x70FD 0x70EF 0x723D 0x727D 0x7281 0x731C 0x731B \ + 0x7316 0x7313 0x7319 0x7387 0x7405 0x740A 0x7403 0x7406 \ + 0x73FE 0x740D 0x74E0 0x74F6 0x74F7 0x751C 0x7522 0x7565 \ + 0x7566 0x7562 0x7570 0x758F 0x75D4 0x75D5 0x75B5 0x75CA \ + 0x75CD 0x768E 0x76D4 0x76D2 0x76DB 0x7737 0x773E 0x773C \ + 0x7736 0x7738 0x773A 0x786B 0x7843 0x784E 0x7965 0x7968 \ + 0x796D 0x79FB 0x7A92 0x7A95 0x7B20 0x7B28 0x7B1B 0x7B2C \ + 0x7B26 0x7B19 0x7B1E 0x7B2E 0x7C92 0x7C97 0x7C95 0x7D46 \ + 0x7D43 0x7D71 0x7D2E 0x7D39 0x7D3C 0x7D40 0x7D30 0x7D33 \ + 0x7D44 0x7D2F 0x7D42 0x7D32 0x7D31 0x7F3D 0x7F9E 0x7F9A \ + 0x7FCC 0x7FCE 0x7FD2 0x801C 0x804A 0x8046 0x812F 0x8116 \ + 0x8123 0x812B 0x8129 0x8130 0x8124 0x8202 0x8235 0x8237 \ + 0x8236 0x8239 0x838E 0x839E 0x8398 0x8378 0x83A2 0x8396 +12 0x83BD 0x83AB 0x8392 0x838A 0x8393 0x8389 0x83A0 0x8377 \ + 0x837B 0x837C 0x8386 0x83A7 0x8655 0x5F6A 0x86C7 0x86C0 \ + 0x86B6 0x86C4 0x86B5 0x86C6 0x86CB 0x86B1 0x86AF 0x86C9 \ + 0x8853 0x889E 0x8888 0x88AB 0x8892 0x8896 0x888D 0x888B \ + 0x8993 0x898F 0x8A2A 0x8A1D 0x8A23 0x8A25 0x8A31 0x8A2D \ + 0x8A1F 0x8A1B 0x8A22 0x8C49 0x8C5A 0x8CA9 0x8CAC 0x8CAB \ + 0x8CA8 0x8CAA 0x8CA7 0x8D67 0x8D66 0x8DBE 0x8DBA 0x8EDB \ + 0x8EDF 0x9019 0x900D 0x901A 0x9017 0x9023 0x901F 0x901D \ + 0x9010 0x9015 0x901E 0x9020 0x900F 0x9022 0x9016 0x901B \ + 0x9014 0x90E8 0x90ED 0x90FD 0x9157 0x91CE 0x91F5 0x91E6 \ + 0x91E3 0x91E7 0x91ED 0x91E9 0x9589 0x966A 0x9675 0x9673 \ + 0x9678 0x9670 0x9674 0x9676 0x9677 0x966C 0x96C0 0x96EA \ + 0x96E9 0x7AE0 0x7ADF 0x9802 0x9803 0x9B5A 0x9CE5 0x9E75 \ + 0x9E7F 0x9EA5 0x9EBB 0x50A2 0x508D 0x5085 0x5099 0x5091 \ + 0x5080 0x5096 0x5098 0x509A 0x6700 0x51F1 0x5272 0x5274 \ + 0x5275 0x5269 0x52DE 0x52DD 0x52DB 0x535A 0x53A5 0x557B \ + 0x5580 0x55A7 0x557C 0x558A 0x559D 0x5598 0x5582 0x559C \ + 0x55AA 0x5594 0x5587 0x558B 0x5583 0x55B3 0x55AE 0x559F \ + 0x553E 0x55B2 0x559A 0x55BB 0x55AC 0x55B1 0x557E 0x5589 \ + 0x55AB 0x5599 0x570D 0x582F 0x582A 0x5834 0x5824 0x5830 \ + 0x5831 0x5821 0x581D 0x5820 0x58F9 0x58FA 0x5960 0x5A77 \ + 0x5A9A 0x5A7F 0x5A92 0x5A9B 0x5AA7 0x5B73 0x5B71 0x5BD2 \ + 0x5BCC 0x5BD3 0x5BD0 0x5C0A 0x5C0B 0x5C31 0x5D4C 0x5D50 \ + 0x5D34 0x5D47 0x5DFD 0x5E45 0x5E3D 0x5E40 0x5E43 0x5E7E \ + 0x5ECA 0x5EC1 0x5EC2 0x5EC4 0x5F3C 0x5F6D 0x5FA9 0x5FAA \ + 0x5FA8 0x60D1 0x60E1 0x60B2 0x60B6 0x60E0 0x611C 0x6123 \ + 0x60FA 0x6115 0x60F0 0x60FB 0x60F4 0x6168 0x60F1 0x610E \ + 0x60F6 0x6109 0x6100 0x6112 0x621F 0x6249 0x63A3 0x638C \ + 0x63CF 0x63C0 0x63E9 0x63C9 0x63C6 0x63CD 0x63D2 0x63E3 \ + 0x63D0 0x63E1 0x63D6 0x63ED 0x63EE 0x6376 0x63F4 0x63EA \ + 0x63DB 0x6452 0x63DA 0x63F9 0x655E 0x6566 0x6562 0x6563 \ + 0x6591 0x6590 0x65AF 0x666E 0x6670 0x6674 0x6676 0x666F +13 0x6691 0x667A 0x667E 0x6677 0x66FE 0x66FF 0x671F 0x671D \ + 0x68FA 0x68D5 0x68E0 0x68D8 0x68D7 0x6905 0x68DF 0x68F5 \ + 0x68EE 0x68E7 0x68F9 0x68D2 0x68F2 0x68E3 0x68CB 0x68CD \ + 0x690D 0x6912 0x690E 0x68C9 0x68DA 0x696E 0x68FB 0x6B3E \ + 0x6B3A 0x6B3D 0x6B98 0x6B96 0x6BBC 0x6BEF 0x6C2E 0x6C2F \ + 0x6C2C 0x6E2F 0x6E38 0x6E54 0x6E21 0x6E32 0x6E67 0x6E4A \ + 0x6E20 0x6E25 0x6E23 0x6E1B 0x6E5B 0x6E58 0x6E24 0x6E56 \ + 0x6E6E 0x6E2D 0x6E26 0x6E6F 0x6E34 0x6E4D 0x6E3A 0x6E2C \ + 0x6E43 0x6E1D 0x6E3E 0x6ECB 0x6E89 0x6E19 0x6E4E 0x6E63 \ + 0x6E44 0x6E72 0x6E69 0x6E5F 0x7119 0x711A 0x7126 0x7130 \ + 0x7121 0x7136 0x716E 0x711C 0x724C 0x7284 0x7280 0x7336 \ + 0x7325 0x7334 0x7329 0x743A 0x742A 0x7433 0x7422 0x7425 \ + 0x7435 0x7436 0x7434 0x742F 0x741B 0x7426 0x7428 0x7525 \ + 0x7526 0x756B 0x756A 0x75E2 0x75DB 0x75E3 0x75D9 0x75D8 \ + 0x75DE 0x75E0 0x767B 0x767C 0x7696 0x7693 0x76B4 0x76DC \ + 0x774F 0x77ED 0x785D 0x786C 0x786F 0x7A0D 0x7A08 0x7A0B \ + 0x7A05 0x7A00 0x7A98 0x7A97 0x7A96 0x7AE5 0x7AE3 0x7B49 \ + 0x7B56 0x7B46 0x7B50 0x7B52 0x7B54 0x7B4D 0x7B4B 0x7B4F \ + 0x7B51 0x7C9F 0x7CA5 0x7D5E 0x7D50 0x7D68 0x7D55 0x7D2B \ + 0x7D6E 0x7D72 0x7D61 0x7D66 0x7D62 0x7D70 0x7D73 0x5584 \ + 0x7FD4 0x7FD5 0x800B 0x8052 0x8085 0x8155 0x8154 0x814B \ + 0x8151 0x814E 0x8139 0x8146 0x813E 0x814C 0x8153 0x8174 \ + 0x8212 0x821C 0x83E9 0x8403 0x83F8 0x840D 0x83E0 0x83C5 \ + 0x840B 0x83C1 0x83EF 0x83F1 0x83F4 0x8457 0x840A 0x83F0 \ + 0x840C 0x83CC 0x83FD 0x83F2 0x83CA 0x8438 0x840E 0x8404 \ + 0x83DC 0x8407 0x83D4 0x83DF 0x865B 0x86DF 0x86D9 0x86ED \ + 0x86D4 0x86DB 0x86E4 0x86D0 0x86DE 0x8857 0x88C1 0x88C2 \ + 0x88B1 0x8983 0x8996 0x8A3B 0x8A60 0x8A55 0x8A5E 0x8A3C \ + 0x8A41 0x8A54 0x8A5B 0x8A50 0x8A46 0x8A34 0x8A3A 0x8A36 \ + 0x8A56 0x8C61 0x8C82 0x8CAF 0x8CBC 0x8CB3 0x8CBD 0x8CC1 \ + 0x8CBB 0x8CC0 0x8CB4 0x8CB7 0x8CB6 0x8CBF 0x8CB8 0x8D8A \ + 0x8D85 0x8D81 0x8DCE 0x8DDD 0x8DCB 0x8DDA 0x8DD1 0x8DCC +14 0x8DDB 0x8DC6 0x8EFB 0x8EF8 0x8EFC 0x8F9C 0x902E 0x9035 \ + 0x9031 0x9038 0x9032 0x9036 0x9102 0x90F5 0x9109 0x90FE \ + 0x9163 0x9165 0x91CF 0x9214 0x9215 0x9223 0x9209 0x921E \ + 0x920D 0x9210 0x9207 0x9211 0x9594 0x958F 0x958B 0x9591 \ + 0x9593 0x9592 0x958E 0x968A 0x968E 0x968B 0x967D 0x9685 \ + 0x9686 0x968D 0x9672 0x9684 0x96C1 0x96C5 0x96C4 0x96C6 \ + 0x96C7 0x96EF 0x96F2 0x97CC 0x9805 0x9806 0x9808 0x98E7 \ + 0x98EA 0x98EF 0x98E9 0x98F2 0x98ED 0x99AE 0x99AD 0x9EC3 \ + 0x9ECD 0x9ED1 0x4E82 0x50AD 0x50B5 0x50B2 0x50B3 0x50C5 \ + 0x50BE 0x50AC 0x50B7 0x50BB 0x50AF 0x50C7 0x527F 0x5277 \ + 0x527D 0x52DF 0x52E6 0x52E4 0x52E2 0x52E3 0x532F 0x55DF \ + 0x55E8 0x55D3 0x55E6 0x55CE 0x55DC 0x55C7 0x55D1 0x55E3 \ + 0x55E4 0x55EF 0x55DA 0x55E1 0x55C5 0x55C6 0x55E5 0x55C9 \ + 0x5712 0x5713 0x585E 0x5851 0x5858 0x5857 0x585A 0x5854 \ + 0x586B 0x584C 0x586D 0x584A 0x5862 0x5852 0x584B 0x5967 \ + 0x5AC1 0x5AC9 0x5ACC 0x5ABE 0x5ABD 0x5ABC 0x5AB3 0x5AC2 \ + 0x5AB2 0x5D69 0x5D6F 0x5E4C 0x5E79 0x5EC9 0x5EC8 0x5F12 \ + 0x5F59 0x5FAC 0x5FAE 0x611A 0x610F 0x6148 0x611F 0x60F3 \ + 0x611B 0x60F9 0x6101 0x6108 0x614E 0x614C 0x6144 0x614D \ + 0x613E 0x6134 0x6127 0x610D 0x6106 0x6137 0x6221 0x6222 \ + 0x6413 0x643E 0x641E 0x642A 0x642D 0x643D 0x642C 0x640F \ + 0x641C 0x6414 0x640D 0x6436 0x6416 0x6417 0x6406 0x656C \ + 0x659F 0x65B0 0x6697 0x6689 0x6687 0x6688 0x6696 0x6684 \ + 0x6698 0x668D 0x6703 0x6994 0x696D 0x695A 0x6977 0x6960 \ + 0x6954 0x6975 0x6930 0x6982 0x694A 0x6968 0x696B 0x695E \ + 0x6953 0x6979 0x6986 0x695D 0x6963 0x695B 0x6B47 0x6B72 \ + 0x6BC0 0x6BBF 0x6BD3 0x6BFD 0x6EA2 0x6EAF 0x6ED3 0x6EB6 \ + 0x6EC2 0x6E90 0x6E9D 0x6EC7 0x6EC5 0x6EA5 0x6E98 0x6EBC \ + 0x6EBA 0x6EAB 0x6ED1 0x6E96 0x6E9C 0x6EC4 0x6ED4 0x6EAA \ + 0x6EA7 0x6EB4 0x714E 0x7159 0x7169 0x7164 0x7149 0x7167 \ + 0x715C 0x716C 0x7166 0x714C 0x7165 0x715E 0x7146 0x7168 \ + 0x7156 0x723A 0x7252 0x7337 0x7345 0x733F 0x733E 0x746F +15 0x745A 0x7455 0x745F 0x745E 0x7441 0x743F 0x7459 0x745B \ + 0x745C 0x7576 0x7578 0x7600 0x75F0 0x7601 0x75F2 0x75F1 \ + 0x75FA 0x75FF 0x75F4 0x75F3 0x76DE 0x76DF 0x775B 0x776B \ + 0x7766 0x775E 0x7763 0x7779 0x776A 0x776C 0x775C 0x7765 \ + 0x7768 0x7762 0x77EE 0x788E 0x78B0 0x7897 0x7898 0x788C \ + 0x7889 0x787C 0x7891 0x7893 0x787F 0x797A 0x797F 0x7981 \ + 0x842C 0x79BD 0x7A1C 0x7A1A 0x7A20 0x7A14 0x7A1F 0x7A1E \ + 0x7A9F 0x7AA0 0x7B77 0x7BC0 0x7B60 0x7B6E 0x7B67 0x7CB1 \ + 0x7CB3 0x7CB5 0x7D93 0x7D79 0x7D91 0x7D81 0x7D8F 0x7D5B \ + 0x7F6E 0x7F69 0x7F6A 0x7F72 0x7FA9 0x7FA8 0x7FA4 0x8056 \ + 0x8058 0x8086 0x8084 0x8171 0x8170 0x8178 0x8165 0x816E \ + 0x8173 0x816B 0x8179 0x817A 0x8166 0x8205 0x8247 0x8482 \ + 0x8477 0x843D 0x8431 0x8475 0x8466 0x846B 0x8449 0x846C \ + 0x845B 0x843C 0x8435 0x8461 0x8463 0x8469 0x846D 0x8446 \ + 0x865E 0x865C 0x865F 0x86F9 0x8713 0x8708 0x8707 0x8700 \ + 0x86FE 0x86FB 0x8702 0x8703 0x8706 0x870A 0x8859 0x88DF \ + 0x88D4 0x88D9 0x88DC 0x88D8 0x88DD 0x88E1 0x88CA 0x88D5 \ + 0x88D2 0x899C 0x89E3 0x8A6B 0x8A72 0x8A73 0x8A66 0x8A69 \ + 0x8A70 0x8A87 0x8A7C 0x8A63 0x8AA0 0x8A71 0x8A85 0x8A6D \ + 0x8A62 0x8A6E 0x8A6C 0x8A79 0x8A7B 0x8A3E 0x8A68 0x8C62 \ + 0x8C8A 0x8C89 0x8CCA 0x8CC7 0x8CC8 0x8CC4 0x8CB2 0x8CC3 \ + 0x8CC2 0x8CC5 0x8DE1 0x8DDF 0x8DE8 0x8DEF 0x8DF3 0x8DFA \ + 0x8DEA 0x8DE4 0x8DE6 0x8EB2 0x8F03 0x8F09 0x8EFE 0x8F0A \ + 0x8F9F 0x8FB2 0x904B 0x904A 0x9053 0x9042 0x9054 0x903C \ + 0x9055 0x9050 0x9047 0x904F 0x904E 0x904D 0x9051 0x903E \ + 0x9041 0x9112 0x9117 0x916C 0x916A 0x9169 0x91C9 0x9237 \ + 0x9257 0x9238 0x923D 0x9240 0x923E 0x925B 0x924B 0x9264 \ + 0x9251 0x9234 0x9249 0x924D 0x9245 0x9239 0x923F 0x925A \ + 0x9598 0x9698 0x9694 0x9695 0x96CD 0x96CB 0x96C9 0x96CA \ + 0x96F7 0x96FB 0x96F9 0x96F6 0x9756 0x9774 0x9776 0x9810 \ + 0x9811 0x9813 0x980A 0x9812 0x980C 0x98FC 0x98F4 0x98FD \ + 0x98FE 0x99B3 0x99B1 0x99B4 0x9AE1 0x9CE9 0x9E82 0x9F0E +16 0x9F13 0x9F20 0x50E7 0x50EE 0x50E5 0x50D6 0x50ED 0x50DA \ + 0x50D5 0x50CF 0x50D1 0x50F1 0x50CE 0x50E9 0x5162 0x51F3 \ + 0x5283 0x5282 0x5331 0x53AD 0x55FE 0x5600 0x561B 0x5617 \ + 0x55FD 0x5614 0x5606 0x5609 0x560D 0x560E 0x55F7 0x5616 \ + 0x561F 0x5608 0x5610 0x55F6 0x5718 0x5716 0x5875 0x587E \ + 0x5883 0x5893 0x588A 0x5879 0x5885 0x587D 0x58FD 0x5925 \ + 0x5922 0x5924 0x596A 0x5969 0x5AE1 0x5AE6 0x5AE9 0x5AD7 \ + 0x5AD6 0x5AD8 0x5AE3 0x5B75 0x5BDE 0x5BE7 0x5BE1 0x5BE5 \ + 0x5BE6 0x5BE8 0x5BE2 0x5BE4 0x5BDF 0x5C0D 0x5C62 0x5D84 \ + 0x5D87 0x5E5B 0x5E63 0x5E55 0x5E57 0x5E54 0x5ED3 0x5ED6 \ + 0x5F0A 0x5F46 0x5F70 0x5FB9 0x6147 0x613F 0x614B 0x6177 \ + 0x6162 0x6163 0x615F 0x615A 0x6158 0x6175 0x622A 0x6487 \ + 0x6458 0x6454 0x64A4 0x6478 0x645F 0x647A 0x6451 0x6467 \ + 0x6434 0x646D 0x647B 0x6572 0x65A1 0x65D7 0x65D6 0x66A2 \ + 0x66A8 0x669D 0x699C 0x69A8 0x6995 0x69C1 0x69AE 0x69D3 \ + 0x69CB 0x699B 0x69B7 0x69BB 0x69AB 0x69B4 0x69D0 0x69CD \ + 0x69AD 0x69CC 0x69A6 0x69C3 0x69A3 0x6B49 0x6B4C 0x6C33 \ + 0x6F33 0x6F14 0x6EFE 0x6F13 0x6EF4 0x6F29 0x6F3E 0x6F20 \ + 0x6F2C 0x6F0F 0x6F02 0x6F22 0x6EFF 0x6EEF 0x6F06 0x6F31 \ + 0x6F38 0x6F32 0x6F23 0x6F15 0x6F2B 0x6F2F 0x6F88 0x6F2A \ + 0x6EEC 0x6F01 0x6EF2 0x6ECC 0x6EF7 0x7194 0x7199 0x717D \ + 0x718A 0x7184 0x7192 0x723E 0x7292 0x7296 0x7344 0x7350 \ + 0x7464 0x7463 0x746A 0x7470 0x746D 0x7504 0x7591 0x7627 \ + 0x760D 0x760B 0x7609 0x7613 0x76E1 0x76E3 0x7784 0x777D \ + 0x777F 0x7761 0x78C1 0x789F 0x78A7 0x78B3 0x78A9 0x78A3 \ + 0x798E 0x798F 0x798D 0x7A2E 0x7A31 0x7AAA 0x7AA9 0x7AED \ + 0x7AEF 0x7BA1 0x7B95 0x7B8B 0x7B75 0x7B97 0x7B9D 0x7B94 \ + 0x7B8F 0x7BB8 0x7B87 0x7B84 0x7CB9 0x7CBD 0x7CBE 0x7DBB \ + 0x7DB0 0x7D9C 0x7DBD 0x7DBE 0x7DA0 0x7DCA 0x7DB4 0x7DB2 \ + 0x7DB1 0x7DBA 0x7DA2 0x7DBF 0x7DB5 0x7DB8 0x7DAD 0x7DD2 \ + 0x7DC7 0x7DAC 0x7F70 0x7FE0 0x7FE1 0x7FDF 0x805E 0x805A \ + 0x8087 0x8150 0x8180 0x818F 0x8188 0x818A 0x817F 0x8182 +17 0x81E7 0x81FA 0x8207 0x8214 0x821E 0x824B 0x84C9 0x84BF \ + 0x84C6 0x84C4 0x8499 0x849E 0x84B2 0x849C 0x84CB 0x84B8 \ + 0x84C0 0x84D3 0x8490 0x84BC 0x84D1 0x84CA 0x873F 0x871C \ + 0x873B 0x8722 0x8725 0x8734 0x8718 0x8755 0x8737 0x8729 \ + 0x88F3 0x8902 0x88F4 0x88F9 0x88F8 0x88FD 0x88E8 0x891A \ + 0x88EF 0x8AA6 0x8A8C 0x8A9E 0x8AA3 0x8A8D 0x8AA1 0x8A93 \ + 0x8AA4 0x8AAA 0x8AA5 0x8AA8 0x8A98 0x8A91 0x8A9A 0x8AA7 \ + 0x8C6A 0x8C8D 0x8C8C 0x8CD3 0x8CD1 0x8CD2 0x8D6B 0x8D99 \ + 0x8D95 0x8DFC 0x8F14 0x8F12 0x8F15 0x8F13 0x8FA3 0x9060 \ + 0x9058 0x905C 0x9063 0x9059 0x905E 0x9062 0x905D 0x905B \ + 0x9119 0x9118 0x911E 0x9175 0x9178 0x9177 0x9174 0x9278 \ + 0x9280 0x9285 0x9298 0x9296 0x927B 0x9293 0x929C 0x92A8 \ + 0x927C 0x9291 0x95A1 0x95A8 0x95A9 0x95A3 0x95A5 0x95A4 \ + 0x9699 0x969C 0x969B 0x96CC 0x96D2 0x9700 0x977C 0x9785 \ + 0x97F6 0x9817 0x9818 0x98AF 0x98B1 0x9903 0x9905 0x990C \ + 0x9909 0x99C1 0x9AAF 0x9AB0 0x9AE6 0x9B41 0x9B42 0x9CF4 \ + 0x9CF6 0x9CF3 0x9EBC 0x9F3B 0x9F4A 0x5104 0x5100 0x50FB \ + 0x50F5 0x50F9 0x5102 0x5108 0x5109 0x5105 0x51DC 0x5287 \ + 0x5288 0x5289 0x528D 0x528A 0x52F0 0x53B2 0x562E 0x563B \ + 0x5639 0x5632 0x563F 0x5634 0x5629 0x5653 0x564E 0x5657 \ + 0x5674 0x5636 0x562F 0x5630 0x5880 0x589F 0x589E 0x58B3 \ + 0x589C 0x58AE 0x58A9 0x58A6 0x596D 0x5B09 0x5AFB 0x5B0B \ + 0x5AF5 0x5B0C 0x5B08 0x5BEE 0x5BEC 0x5BE9 0x5BEB 0x5C64 \ + 0x5C65 0x5D9D 0x5D94 0x5E62 0x5E5F 0x5E61 0x5EE2 0x5EDA \ + 0x5EDF 0x5EDD 0x5EE3 0x5EE0 0x5F48 0x5F71 0x5FB7 0x5FB5 \ + 0x6176 0x6167 0x616E 0x615D 0x6155 0x6182 0x617C 0x6170 \ + 0x616B 0x617E 0x61A7 0x6190 0x61AB 0x618E 0x61AC 0x619A \ + 0x61A4 0x6194 0x61AE 0x622E 0x6469 0x646F 0x6479 0x649E \ + 0x64B2 0x6488 0x6490 0x64B0 0x64A5 0x6493 0x6495 0x64A9 \ + 0x6492 0x64AE 0x64AD 0x64AB 0x649A 0x64AC 0x6499 0x64A2 \ + 0x64B3 0x6575 0x6577 0x6578 0x66AE 0x66AB 0x66B4 0x66B1 \ + 0x6A23 0x6A1F 0x69E8 0x6A01 0x6A1E 0x6A19 0x69FD 0x6A21 +18 0x6A13 0x6A0A 0x69F3 0x6A02 0x6A05 0x69ED 0x6A11 0x6B50 \ + 0x6B4E 0x6BA4 0x6BC5 0x6BC6 0x6F3F 0x6F7C 0x6F84 0x6F51 \ + 0x6F66 0x6F54 0x6F86 0x6F6D 0x6F5B 0x6F78 0x6F6E 0x6F8E \ + 0x6F7A 0x6F70 0x6F64 0x6F97 0x6F58 0x6ED5 0x6F6F 0x6F60 \ + 0x6F5F 0x719F 0x71AC 0x71B1 0x71A8 0x7256 0x729B 0x734E \ + 0x7357 0x7469 0x748B 0x7483 0x747E 0x7480 0x757F 0x7620 \ + 0x7629 0x761F 0x7624 0x7626 0x7621 0x7622 0x769A 0x76BA \ + 0x76E4 0x778E 0x7787 0x778C 0x7791 0x778B 0x78CB 0x78C5 \ + 0x78BA 0x78CA 0x78BE 0x78D5 0x78BC 0x78D0 0x7A3F 0x7A3C \ + 0x7A40 0x7A3D 0x7A37 0x7A3B 0x7AAF 0x7AAE 0x7BAD 0x7BB1 \ + 0x7BC4 0x7BB4 0x7BC6 0x7BC7 0x7BC1 0x7BA0 0x7BCC 0x7CCA \ + 0x7DE0 0x7DF4 0x7DEF 0x7DFB 0x7DD8 0x7DEC 0x7DDD 0x7DE8 \ + 0x7DE3 0x7DDA 0x7DDE 0x7DE9 0x7D9E 0x7DD9 0x7DF2 0x7DF9 \ + 0x7F75 0x7F77 0x7FAF 0x7FE9 0x8026 0x819B 0x819C 0x819D \ + 0x81A0 0x819A 0x8198 0x8517 0x853D 0x851A 0x84EE 0x852C \ + 0x852D 0x8513 0x8511 0x8523 0x8521 0x8514 0x84EC 0x8525 \ + 0x84FF 0x8506 0x8782 0x8774 0x8776 0x8760 0x8766 0x8778 \ + 0x8768 0x8759 0x8757 0x874C 0x8753 0x885B 0x885D 0x8910 \ + 0x8907 0x8912 0x8913 0x8915 0x890A 0x8ABC 0x8AD2 0x8AC7 \ + 0x8AC4 0x8A95 0x8ACB 0x8AF8 0x8AB2 0x8AC9 0x8AC2 0x8ABF \ + 0x8AB0 0x8AD6 0x8ACD 0x8AB6 0x8AB9 0x8ADB 0x8C4C 0x8C4E \ + 0x8C6C 0x8CE0 0x8CDE 0x8CE6 0x8CE4 0x8CEC 0x8CED 0x8CE2 \ + 0x8CE3 0x8CDC 0x8CEA 0x8CE1 0x8D6D 0x8D9F 0x8DA3 0x8E2B \ + 0x8E10 0x8E1D 0x8E22 0x8E0F 0x8E29 0x8E1F 0x8E21 0x8E1E \ + 0x8EBA 0x8F1D 0x8F1B 0x8F1F 0x8F29 0x8F26 0x8F2A 0x8F1C \ + 0x8F1E 0x8F25 0x9069 0x906E 0x9068 0x906D 0x9077 0x9130 \ + 0x912D 0x9127 0x9131 0x9187 0x9189 0x918B 0x9183 0x92C5 \ + 0x92BB 0x92B7 0x92EA 0x92AC 0x92E4 0x92C1 0x92B3 0x92BC \ + 0x92D2 0x92C7 0x92F0 0x92B2 0x95AD 0x95B1 0x9704 0x9706 \ + 0x9707 0x9709 0x9760 0x978D 0x978B 0x978F 0x9821 0x982B \ + 0x981C 0x98B3 0x990A 0x9913 0x9912 0x9918 0x99DD 0x99D0 \ + 0x99DF 0x99DB 0x99D1 0x99D5 0x99D2 0x99D9 0x9AB7 0x9AEE +19 0x9AEF 0x9B27 0x9B45 0x9B44 0x9B77 0x9B6F 0x9D06 0x9D09 \ + 0x9D03 0x9EA9 0x9EBE 0x9ECE 0x58A8 0x9F52 0x5112 0x5118 \ + 0x5114 0x5110 0x5115 0x5180 0x51AA 0x51DD 0x5291 0x5293 \ + 0x52F3 0x5659 0x566B 0x5679 0x5669 0x5664 0x5678 0x566A \ + 0x5668 0x5665 0x5671 0x566F 0x566C 0x5662 0x5676 0x58C1 \ + 0x58BE 0x58C7 0x58C5 0x596E 0x5B1D 0x5B34 0x5B78 0x5BF0 \ + 0x5C0E 0x5F4A 0x61B2 0x6191 0x61A9 0x618A 0x61CD 0x61B6 \ + 0x61BE 0x61CA 0x61C8 0x6230 0x64C5 0x64C1 0x64CB 0x64BB \ + 0x64BC 0x64DA 0x64C4 0x64C7 0x64C2 0x64CD 0x64BF 0x64D2 \ + 0x64D4 0x64BE 0x6574 0x66C6 0x66C9 0x66B9 0x66C4 0x66C7 \ + 0x66B8 0x6A3D 0x6A38 0x6A3A 0x6A59 0x6A6B 0x6A58 0x6A39 \ + 0x6A44 0x6A62 0x6A61 0x6A4B 0x6A47 0x6A35 0x6A5F 0x6A48 \ + 0x6B59 0x6B77 0x6C05 0x6FC2 0x6FB1 0x6FA1 0x6FC3 0x6FA4 \ + 0x6FC1 0x6FA7 0x6FB3 0x6FC0 0x6FB9 0x6FB6 0x6FA6 0x6FA0 \ + 0x6FB4 0x71BE 0x71C9 0x71D0 0x71D2 0x71C8 0x71D5 0x71B9 \ + 0x71CE 0x71D9 0x71DC 0x71C3 0x71C4 0x7368 0x749C 0x74A3 \ + 0x7498 0x749F 0x749E 0x74E2 0x750C 0x750D 0x7634 0x7638 \ + 0x763A 0x76E7 0x76E5 0x77A0 0x779E 0x779F 0x77A5 0x78E8 \ + 0x78DA 0x78EC 0x78E7 0x79A6 0x7A4D 0x7A4E 0x7A46 0x7A4C \ + 0x7A4B 0x7ABA 0x7BD9 0x7C11 0x7BC9 0x7BE4 0x7BDB 0x7BE1 \ + 0x7BE9 0x7BE6 0x7CD5 0x7CD6 0x7E0A 0x7E11 0x7E08 0x7E1B \ + 0x7E23 0x7E1E 0x7E1D 0x7E09 0x7E10 0x7F79 0x7FB2 0x7FF0 \ + 0x7FF1 0x7FEE 0x8028 0x81B3 0x81A9 0x81A8 0x81FB 0x8208 \ + 0x8258 0x8259 0x854A 0x8559 0x8548 0x8568 0x8569 0x8543 \ + 0x8549 0x856D 0x856A 0x855E 0x8783 0x879F 0x879E 0x87A2 \ + 0x878D 0x8861 0x892A 0x8932 0x8925 0x892B 0x8921 0x89AA \ + 0x89A6 0x8AE6 0x8AFA 0x8AEB 0x8AF1 0x8B00 0x8ADC 0x8AE7 \ + 0x8AEE 0x8AFE 0x8B01 0x8B02 0x8AF7 0x8AED 0x8AF3 0x8AF6 \ + 0x8AFC 0x8C6B 0x8C6D 0x8C93 0x8CF4 0x8E44 0x8E31 0x8E34 \ + 0x8E42 0x8E39 0x8E35 0x8F3B 0x8F2F 0x8F38 0x8F33 0x8FA8 \ + 0x8FA6 0x9075 0x9074 0x9078 0x9072 0x907C 0x907A 0x9134 \ + 0x9192 0x9320 0x9336 0x92F8 0x9333 0x932F 0x9322 0x92FC +20 0x932B 0x9304 0x931A 0x9310 0x9326 0x9321 0x9315 0x932E \ + 0x9319 0x95BB 0x96A7 0x96A8 0x96AA 0x96D5 0x970E 0x9711 \ + 0x9716 0x970D 0x9713 0x970F 0x975B 0x975C 0x9766 0x9798 \ + 0x9830 0x9838 0x983B 0x9837 0x982D 0x9839 0x9824 0x9910 \ + 0x9928 0x991E 0x991B 0x9921 0x991A 0x99ED 0x99E2 0x99F1 \ + 0x9AB8 0x9ABC 0x9AFB 0x9AED 0x9B28 0x9B91 0x9D15 0x9D23 \ + 0x9D26 0x9D28 0x9D12 0x9D1B 0x9ED8 0x9ED4 0x9F8D 0x9F9C \ + 0x512A 0x511F 0x5121 0x5132 0x52F5 0x568E 0x5680 0x5690 \ + 0x5685 0x5687 0x568F 0x58D5 0x58D3 0x58D1 0x58CE 0x5B30 \ + 0x5B2A 0x5B24 0x5B7A 0x5C37 0x5C68 0x5DBC 0x5DBA 0x5DBD \ + 0x5DB8 0x5E6B 0x5F4C 0x5FBD 0x61C9 0x61C2 0x61C7 0x61E6 \ + 0x61CB 0x6232 0x6234 0x64CE 0x64CA 0x64D8 0x64E0 0x64F0 \ + 0x64E6 0x64EC 0x64F1 0x64E2 0x64ED 0x6582 0x6583 0x66D9 \ + 0x66D6 0x6A80 0x6A94 0x6A84 0x6AA2 0x6A9C 0x6ADB 0x6AA3 \ + 0x6A7E 0x6A97 0x6A90 0x6AA0 0x6B5C 0x6BAE 0x6BDA 0x6C08 \ + 0x6FD8 0x6FF1 0x6FDF 0x6FE0 0x6FDB 0x6FE4 0x6FEB 0x6FEF \ + 0x6F80 0x6FEC 0x6FE1 0x6FE9 0x6FD5 0x6FEE 0x6FF0 0x71E7 \ + 0x71DF 0x71EE 0x71E6 0x71E5 0x71ED 0x71EC 0x71F4 0x71E0 \ + 0x7235 0x7246 0x7370 0x7372 0x74A9 0x74B0 0x74A6 0x74A8 \ + 0x7646 0x7642 0x764C 0x76EA 0x77B3 0x77AA 0x77B0 0x77AC \ + 0x77A7 0x77AD 0x77EF 0x78F7 0x78FA 0x78F4 0x78EF 0x7901 \ + 0x79A7 0x79AA 0x7A57 0x7ABF 0x7C07 0x7C0D 0x7BFE 0x7BF7 \ + 0x7C0C 0x7BE0 0x7CE0 0x7CDC 0x7CDE 0x7CE2 0x7CDF 0x7CD9 \ + 0x7CDD 0x7E2E 0x7E3E 0x7E46 0x7E37 0x7E32 0x7E43 0x7E2B \ + 0x7E3D 0x7E31 0x7E45 0x7E41 0x7E34 0x7E39 0x7E48 0x7E35 \ + 0x7E3F 0x7E2F 0x7F44 0x7FF3 0x7FFC 0x8071 0x8072 0x8070 \ + 0x806F 0x8073 0x81C6 0x81C3 0x81BA 0x81C2 0x81C0 0x81BF \ + 0x81BD 0x81C9 0x81BE 0x81E8 0x8209 0x8271 0x85AA 0x8584 \ + 0x857E 0x859C 0x8591 0x8594 0x85AF 0x859B 0x8587 0x85A8 \ + 0x858A 0x8667 0x87C0 0x87D1 0x87B3 0x87D2 0x87C6 0x87AB \ + 0x87BB 0x87BA 0x87C8 0x87CB 0x893B 0x8936 0x8944 0x8938 \ + 0x893D 0x89AC 0x8B0E 0x8B17 0x8B19 0x8B1B 0x8B0A 0x8B20 +21 0x8B1D 0x8B04 0x8B10 0x8C41 0x8C3F 0x8C73 0x8CFA 0x8CFD \ + 0x8CFC 0x8CF8 0x8CFB 0x8DA8 0x8E49 0x8E4B 0x8E48 0x8E4A \ + 0x8F44 0x8F3E 0x8F42 0x8F45 0x8F3F 0x907F 0x907D 0x9084 \ + 0x9081 0x9082 0x9080 0x9139 0x91A3 0x919E 0x919C 0x934D \ + 0x9382 0x9328 0x9375 0x934A 0x9365 0x934B 0x9318 0x937E \ + 0x936C 0x935B 0x9370 0x935A 0x9354 0x95CA 0x95CB 0x95CC \ + 0x95C8 0x95C6 0x96B1 0x96B8 0x96D6 0x971C 0x971E 0x97A0 \ + 0x97D3 0x9846 0x98B6 0x9935 0x9A01 0x99FF 0x9BAE 0x9BAB \ + 0x9BAA 0x9BAD 0x9D3B 0x9D3F 0x9E8B 0x9ECF 0x9EDE 0x9EDC \ + 0x9EDD 0x9EDB 0x9F3E 0x9F4B 0x53E2 0x5695 0x56AE 0x58D9 \ + 0x58D8 0x5B38 0x5F5D 0x61E3 0x6233 0x64F4 0x64F2 0x64FE \ + 0x6506 0x64FA 0x64FB 0x64F7 0x65B7 0x66DC 0x6726 0x6AB3 \ + 0x6AAC 0x6AC3 0x6ABB 0x6AB8 0x6AC2 0x6AAE 0x6AAF 0x6B5F \ + 0x6B78 0x6BAF 0x7009 0x700B 0x6FFE 0x7006 0x6FFA 0x7011 \ + 0x700F 0x71FB 0x71FC 0x71FE 0x71F8 0x7377 0x7375 0x74A7 \ + 0x74BF 0x7515 0x7656 0x7658 0x7652 0x77BD 0x77BF 0x77BB \ + 0x77BC 0x790E 0x79AE 0x7A61 0x7A62 0x7A60 0x7AC4 0x7AC5 \ + 0x7C2B 0x7C27 0x7C2A 0x7C1E 0x7C23 0x7C21 0x7CE7 0x7E54 \ + 0x7E55 0x7E5E 0x7E5A 0x7E61 0x7E52 0x7E59 0x7F48 0x7FF9 \ + 0x7FFB 0x8077 0x8076 0x81CD 0x81CF 0x820A 0x85CF 0x85A9 \ + 0x85CD 0x85D0 0x85C9 0x85B0 0x85BA 0x85B9 0x85A6 0x87EF \ + 0x87EC 0x87F2 0x87E0 0x8986 0x89B2 0x89F4 0x8B28 0x8B39 \ + 0x8B2C 0x8B2B 0x8C50 0x8D05 0x8E59 0x8E63 0x8E66 0x8E64 \ + 0x8E5F 0x8E55 0x8EC0 0x8F49 0x8F4D 0x9087 0x9083 0x9088 \ + 0x91AB 0x91AC 0x91D0 0x9394 0x938A 0x9396 0x93A2 0x93B3 \ + 0x93AE 0x93AC 0x93B0 0x9398 0x939A 0x9397 0x95D4 0x95D6 \ + 0x95D0 0x95D5 0x96E2 0x96DC 0x96D9 0x96DB 0x96DE 0x9724 \ + 0x97A3 0x97A6 0x97AD 0x97F9 0x984D 0x984F 0x984C 0x984E \ + 0x9853 0x98BA 0x993E 0x993F 0x993D 0x992E 0x99A5 0x9A0E \ + 0x9AC1 0x9B03 0x9B06 0x9B4F 0x9B4E 0x9B4D 0x9BCA 0x9BC9 \ + 0x9BFD 0x9BC8 0x9BC0 0x9D51 0x9D5D 0x9D60 0x9EE0 0x9F15 \ + 0x9F2C 0x5133 0x56A5 0x58DE 0x58DF 0x58E2 0x5BF5 0x9F90 +22 0x5EEC 0x61F2 0x61F7 0x61F6 0x61F5 0x6500 0x650F 0x66E0 \ + 0x66DD 0x6AE5 0x6ADD 0x6ADA 0x6AD3 0x701B 0x701F 0x7028 \ + 0x701A 0x701D 0x7015 0x7018 0x7206 0x720D 0x7258 0x72A2 \ + 0x7378 0x737A 0x74BD 0x74CA 0x74E3 0x7587 0x7586 0x765F \ + 0x7661 0x77C7 0x7919 0x79B1 0x7A6B 0x7A69 0x7C3E 0x7C3F \ + 0x7C38 0x7C3D 0x7C37 0x7C40 0x7E6B 0x7E6D 0x7E79 0x7E69 \ + 0x7E6A 0x7F85 0x7E73 0x7FB6 0x7FB9 0x7FB8 0x81D8 0x85E9 \ + 0x85DD 0x85EA 0x85D5 0x85E4 0x85E5 0x85F7 0x87FB 0x8805 \ + 0x880D 0x87F9 0x87FE 0x8960 0x895F 0x8956 0x895E 0x8B41 \ + 0x8B5C 0x8B58 0x8B49 0x8B5A 0x8B4E 0x8B4F 0x8B46 0x8B59 \ + 0x8D08 0x8D0A 0x8E7C 0x8E72 0x8E87 0x8E76 0x8E6C 0x8E7A \ + 0x8E74 0x8F54 0x8F4E 0x8FAD 0x908A 0x908B 0x91B1 0x91AE \ + 0x93E1 0x93D1 0x93DF 0x93C3 0x93C8 0x93DC 0x93DD 0x93D6 \ + 0x93E2 0x93CD 0x93D8 0x93E4 0x93D7 0x93E8 0x95DC 0x96B4 \ + 0x96E3 0x972A 0x9727 0x9761 0x97DC 0x97FB 0x985E 0x9858 \ + 0x985B 0x98BC 0x9945 0x9949 0x9A16 0x9A19 0x9B0D 0x9BE8 \ + 0x9BE7 0x9BD6 0x9BDB 0x9D89 0x9D61 0x9D72 0x9D6A 0x9D6C \ + 0x9E92 0x9E97 0x9E93 0x9EB4 0x52F8 0x56A8 0x56B7 0x56B6 \ + 0x56B4 0x56BC 0x58E4 0x5B40 0x5B43 0x5B7D 0x5BF6 0x5DC9 \ + 0x61F8 0x61FA 0x6518 0x6514 0x6519 0x66E6 0x6727 0x6AEC \ + 0x703E 0x7030 0x7032 0x7210 0x737B 0x74CF 0x7662 0x7665 \ + 0x7926 0x792A 0x792C 0x792B 0x7AC7 0x7AF6 0x7C4C 0x7C43 \ + 0x7C4D 0x7CEF 0x7CF0 0x8FAE 0x7E7D 0x7E7C 0x7E82 0x7F4C \ + 0x8000 0x81DA 0x8266 0x85FB 0x85F9 0x8611 0x85FA 0x8606 \ + 0x860B 0x8607 0x860A 0x8814 0x8815 0x8964 0x89BA 0x89F8 \ + 0x8B70 0x8B6C 0x8B66 0x8B6F 0x8B5F 0x8B6B 0x8D0F 0x8D0D \ + 0x8E89 0x8E81 0x8E85 0x8E82 0x91B4 0x91CB 0x9418 0x9403 \ + 0x93FD 0x95E1 0x9730 0x98C4 0x9952 0x9951 0x99A8 0x9A2B \ + 0x9A30 0x9A37 0x9A35 0x9C13 0x9C0D 0x9E79 0x9EB5 0x9EE8 \ + 0x9F2F 0x9F5F 0x9F63 0x9F61 0x5137 0x5138 0x56C1 0x56C0 \ + 0x56C2 0x5914 0x5C6C 0x5DCD 0x61FC 0x61FE 0x651D 0x651C \ + 0x6595 0x66E9 0x6AFB 0x6B04 0x6AFA 0x6BB2 0x704C 0x721B +23 0x72A7 0x74D6 0x74D4 0x7669 0x77D3 0x7C50 0x7E8F 0x7E8C \ + 0x7FBC 0x8617 0x862D 0x861A 0x8823 0x8822 0x8821 0x881F \ + 0x896A 0x896C 0x89BD 0x8B74 0x8B77 0x8B7D 0x8D13 0x8E8A \ + 0x8E8D 0x8E8B 0x8F5F 0x8FAF 0x91BA 0x942E 0x9433 0x9435 \ + 0x943A 0x9438 0x9432 0x942B 0x95E2 0x9738 0x9739 0x9732 \ + 0x97FF 0x9867 0x9865 0x9957 0x9A45 0x9A43 0x9A40 0x9A3E \ + 0x9ACF 0x9B54 0x9B51 0x9C2D 0x9C25 0x9DAF 0x9DB4 0x9DC2 \ + 0x9DB8 0x9E9D 0x9EEF 0x9F19 0x9F5C 0x9F66 0x9F67 0x513C \ + 0x513B 0x56C8 0x56CA 0x56C9 0x5B7F 0x5DD4 0x5DD2 0x5F4E \ + 0x61FF 0x6524 0x6B0A 0x6B61 0x7051 0x7058 0x7380 0x74E4 \ + 0x758A 0x766E 0x766C 0x79B3 0x7C60 0x7C5F 0x807E 0x807D \ + 0x81DF 0x8972 0x896F 0x89FC 0x8B80 0x8D16 0x8D17 0x8E91 \ + 0x8E93 0x8F61 0x9148 0x9444 0x9451 0x9452 0x973D 0x973E \ + 0x97C3 0x97C1 0x986B 0x9955 0x9A55 0x9A4D 0x9AD2 0x9B1A \ + 0x9C49 0x9C31 0x9C3E 0x9C3B 0x9DD3 0x9DD7 0x9F34 0x9F6C \ + 0x9F6A 0x9F94 0x56CC 0x5DD6 0x6200 0x6523 0x652B 0x652A \ + 0x66EC 0x6B10 0x74DA 0x7ACA 0x7C64 0x7C63 0x7C65 0x7E93 \ + 0x7E96 0x7E94 0x81E2 0x8638 0x863F 0x8831 0x8B8A 0x9090 \ + 0x908F 0x9463 0x9460 0x9464 0x9768 0x986F 0x995C 0x9A5A \ + 0x9A5B 0x9A57 0x9AD3 0x9AD4 0x9AD1 0x9C54 0x9C57 0x9C56 \ + 0x9DE5 0x9E9F 0x9EF4 0x56D1 0x58E9 0x652C 0x705E 0x7671 \ + 0x7672 0x77D7 0x7F50 0x7F88 0x8836 0x8839 0x8862 0x8B93 \ + 0x8B92 0x8B96 0x8277 0x8D1B 0x91C0 0x946A 0x9742 0x9748 \ + 0x9744 0x97C6 0x9870 0x9A5F 0x9B22 0x9B58 0x9C5F 0x9DF9 \ + 0x9DFA 0x9E7C 0x9E7D 0x9F07 0x9F77 0x9F72 0x5EF3 0x6B16 \ + 0x7063 0x7C6C 0x7C6E 0x883B 0x89C0 0x8EA1 0x91C1 0x9472 \ + 0x9470 0x9871 0x995E 0x9AD6 0x9B23 0x9ECC 0x7064 0x77DA \ + 0x8B9A 0x9477 0x97C9 0x9A62 0x9A65 0x7E9C 0x8B9C 0x8EAA \ + 0x91C5 0x947D 0x947E 0x947C 0x9C77 0x9C78 0x9EF7 0x8C54 \ + 0x947F 0x9E1A 0x7228 0x9A6A 0x9B31 0x9E1B 0x9E1E 0x7C72 \ + 0x30FE 0x309D 0x309E 0x3005 0x3041 0x3042 0x3043 0x3044 \ + 0x3045 0x3046 0x3047 0x3048 0x3049 0x304A 0x304B 0x304C +24 0x304D 0x304E 0x304F 0x3050 0x3051 0x3052 0x3053 0x3054 \ + 0x3055 0x3056 0x3057 0x3058 0x3059 0x305A 0x305B 0x305C \ + 0x305D 0x305E 0x305F 0x3060 0x3061 0x3062 0x3063 0x3064 \ + 0x3065 0x3066 0x3067 0x3068 0x3069 0x306A 0x306B 0x306C \ + 0x306D 0x306E 0x306F 0x3070 0x3071 0x3072 0x3073 0x3074 \ + 0x3075 0x3076 0x3077 0x3078 0x3079 0x307A 0x307B 0x307C \ + 0x307D 0x307E 0x307F 0x3080 0x3081 0x3082 0x3083 0x3084 \ + 0x3085 0x3086 0x3087 0x3088 0x3089 0x308A 0x308B 0x308C \ + 0x308D 0x308E 0x308F 0x3090 0x3091 0x3092 0x3093 0x30A1 \ + 0x30A2 0x30A3 0x30A4 0x30A5 0x30A6 0x30A7 0x30A8 0x30A9 \ + 0x30AA 0x30AB 0x30AC 0x30AD 0x30AE 0x30AF 0x30B0 0x30B1 \ + 0x30B2 0x30B3 0x30B4 0x30B5 0x30B6 0x30B7 0x30B8 0x30B9 \ + 0x30BA 0x30BB 0x30BC 0x30BD 0x30BE 0x30BF 0x30C0 0x30C1 \ + 0x30C2 0x30C3 0x30C4 0x30C5 0x30C6 0x30C7 0x30C8 0x30C9 \ + 0x30CA 0x30CB 0x30CC 0x30CD 0x30CE 0x30CF 0x30D0 0x30D1 \ + 0x30D2 0x30D3 0x30D4 0x30D5 0x30D6 0x30D7 0x30D8 0x30D9 \ + 0x30DA 0x30DB 0x30DC 0x30DD 0x30DE 0x30DF 0x30E0 0x30E1 \ + 0x30E2 0x30E3 0x30E4 0x30E5 0x30E6 0x30E7 0x30E8 0x30E9 \ + 0x30EA 0x30EB 0x30EC 0x30ED 0x30EE 0x30EF 0x30F0 0x30F1 \ + 0x30F2 0x30F3 0x30F4 0x30F5 0x30F6 0x0414 0x0415 0x0401 \ + 0x0416 0x0417 0x0418 0x0419 0x041A 0x041B 0x041C 0x0423 \ + 0x0424 0x0425 0x0426 0x0427 0x0428 0x0429 0x042A 0x042B \ + 0x042C 0x042D 0x042E 0x042F 0x0430 0x0431 0x0432 0x0433 \ + 0x0434 0x0435 0x0451 0x0436 0x0437 0x0438 0x0439 0x043A \ + 0x043B 0x043C 0x043D 0x043E 0x043F 0x0440 0x0441 0x0442 \ + 0x0443 0x0444 0x0445 0x0446 0x0447 0x0448 0x0449 0x044A \ + 0x044B 0x044C 0x044D 0x044E 0x044F 0x2460 0x2461 0x2462 \ + 0x2463 0x2464 0x2465 0x2466 0x2467 0x2468 0x2469 0x2474 \ + 0x2475 0x2476 0x2477 0x2478 0x2479 0x247A 0x247B 0x247C \ + 0x247D 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +25 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0x4E42 0x4E5C 0x51F5 0x531A 0x5382 0x4E07 0x4E0C 0x4E47 \ + 0x4E8D 0x56D7 0xFA0C 0x5C6E 0x5F73 0x4E0F 0x5187 0x4E0E \ + 0x4E2E 0x4E93 0x4EC2 0x4EC9 0x4EC8 0x5198 0x52FC 0x536C \ + 0x53B9 0x5720 0x5903 0x592C 0x5C10 0x5DFF 0x65E1 0x6BB3 \ + 0x6BCC 0x6C14 0x723F 0x4E31 0x4E3C 0x4EE8 0x4EDC 0x4EE9 \ + 0x4EE1 0x4EDD 0x4EDA 0x520C 0x531C 0x534C 0x5722 0x5723 \ + 0x5917 0x592F 0x5B81 0x5B84 0x5C12 0x5C3B 0x5C74 0x5C73 \ + 0x5E04 0x5E80 0x5E82 0x5FC9 0x6209 0x6250 0x6C15 0x6C36 \ + 0x6C43 0x6C3F 0x6C3B 0x72AE 0x72B0 0x738A 0x79B8 0x808A \ + 0x961E 0x4F0E 0x4F18 0x4F2C 0x4EF5 0x4F14 0x4EF1 0x4F00 \ + 0x4EF7 0x4F08 0x4F1D 0x4F02 0x4F05 0x4F22 0x4F13 0x4F04 \ + 0x4EF4 0x4F12 0x51B1 0x5213 0x5209 0x5210 0x52A6 0x5322 \ + 0x531F 0x534D 0x538A 0x5407 0x56E1 0x56DF 0x572E 0x572A \ + 0x5734 0x593C 0x5980 0x597C 0x5985 0x597B 0x597E 0x5977 \ + 0x597F 0x5B56 0x5C15 0x5C25 0x5C7C 0x5C7A 0x5C7B 0x5C7E +26 0x5DDF 0x5E75 0x5E84 0x5F02 0x5F1A 0x5F74 0x5FD5 0x5FD4 \ + 0x5FCF 0x625C 0x625E 0x6264 0x6261 0x6266 0x6262 0x6259 \ + 0x6260 0x625A 0x6265 0x65EF 0x65EE 0x673E 0x6739 0x6738 \ + 0x673B 0x673A 0x673F 0x673C 0x6733 0x6C18 0x6C46 0x6C52 \ + 0x6C5C 0x6C4F 0x6C4A 0x6C54 0x6C4B 0x6C4C 0x7071 0x725E \ + 0x72B4 0x72B5 0x738E 0x752A 0x767F 0x7A75 0x7F51 0x8278 \ + 0x827C 0x8280 0x827D 0x827F 0x864D 0x897E 0x9099 0x9097 \ + 0x9098 0x909B 0x9094 0x9622 0x9624 0x9620 0x9623 0x4F56 \ + 0x4F3B 0x4F62 0x4F49 0x4F53 0x4F64 0x4F3E 0x4F67 0x4F52 \ + 0x4F5F 0x4F41 0x4F58 0x4F2D 0x4F33 0x4F3F 0x4F61 0x518F \ + 0x51B9 0x521C 0x521E 0x5221 0x52AD 0x52AE 0x5309 0x5363 \ + 0x5372 0x538E 0x538F 0x5430 0x5437 0x542A 0x5454 0x5445 \ + 0x5419 0x541C 0x5425 0x5418 0x543D 0x544F 0x5441 0x5428 \ + 0x5424 0x5447 0x56EE 0x56E7 0x56E5 0x5741 0x5745 0x574C \ + 0x5749 0x574B 0x5752 0x5906 0x5940 0x59A6 0x5998 0x59A0 \ + 0x5997 0x598E 0x59A2 0x5990 0x598F 0x59A7 0x59A1 0x5B8E \ + 0x5B92 0x5C28 0x5C2A 0x5C8D 0x5C8F 0x5C88 0x5C8B 0x5C89 \ + 0x5C92 0x5C8A 0x5C86 0x5C93 0x5C95 0x5DE0 0x5E0A 0x5E0E \ + 0x5E8B 0x5E89 0x5E8C 0x5E88 0x5E8D 0x5F05 0x5F1D 0x5F78 \ + 0x5F76 0x5FD2 0x5FD1 0x5FD0 0x5FED 0x5FE8 0x5FEE 0x5FF3 \ + 0x5FE1 0x5FE4 0x5FE3 0x5FFA 0x5FEF 0x5FF7 0x5FFB 0x6000 \ + 0x5FF4 0x623A 0x6283 0x628C 0x628E 0x628F 0x6294 0x6287 \ + 0x6271 0x627B 0x627A 0x6270 0x6281 0x6288 0x6277 0x627D \ + 0x6272 0x6274 0x6537 0x65F0 0x65F4 0x65F3 0x65F2 0x65F5 \ + 0x6745 0x6747 0x6759 0x6755 0x674C 0x6748 0x675D 0x674D \ + 0x675A 0x674B 0x6BD0 0x6C19 0x6C1A 0x6C78 0x6C67 0x6C6B \ + 0x6C84 0x6C8B 0x6C8F 0x6C71 0x6C6F 0x6C69 0x6C9A 0x6C6D \ + 0x6C87 0x6C95 0x6C9C 0x6C66 0x6C73 0x6C65 0x6C7B 0x6C8E \ + 0x7074 0x707A 0x7263 0x72BF 0x72BD 0x72C3 0x72C6 0x72C1 \ + 0x72BA 0x72C5 0x7395 0x7397 0x7393 0x7394 0x7392 0x753A \ + 0x7539 0x7594 0x7595 0x7681 0x793D 0x8034 0x8095 0x8099 \ + 0x8090 0x8092 0x809C 0x8290 0x828F 0x8285 0x828E 0x8291 +27 0x8293 0x828A 0x8283 0x8284 0x8C78 0x8FC9 0x8FBF 0x909F \ + 0x90A1 0x90A5 0x909E 0x90A7 0x90A0 0x9630 0x9628 0x962F \ + 0x962D 0x4E33 0x4F98 0x4F7C 0x4F85 0x4F7D 0x4F80 0x4F87 \ + 0x4F76 0x4F74 0x4F89 0x4F84 0x4F77 0x4F4C 0x4F97 0x4F6A \ + 0x4F9A 0x4F79 0x4F81 0x4F78 0x4F90 0x4F9C 0x4F94 0x4F9E \ + 0x4F92 0x4F82 0x4F95 0x4F6B 0x4F6E 0x519E 0x51BC 0x51BE \ + 0x5235 0x5232 0x5233 0x5246 0x5231 0x52BC 0x530A 0x530B \ + 0x533C 0x5392 0x5394 0x5487 0x547F 0x5481 0x5491 0x5482 \ + 0x5488 0x546B 0x547A 0x547E 0x5465 0x546C 0x5474 0x5466 \ + 0x548D 0x546F 0x5461 0x5460 0x5498 0x5463 0x5467 0x5464 \ + 0x56F7 0x56F9 0x576F 0x5772 0x576D 0x576B 0x5771 0x5770 \ + 0x5776 0x5780 0x5775 0x577B 0x5773 0x5774 0x5762 0x5768 \ + 0x577D 0x590C 0x5945 0x59B5 0x59BA 0x59CF 0x59CE 0x59B2 \ + 0x59CC 0x59C1 0x59B6 0x59BC 0x59C3 0x59D6 0x59B1 0x59BD \ + 0x59C0 0x59C8 0x59B4 0x59C7 0x5B62 0x5B65 0x5B93 0x5B95 \ + 0x5C44 0x5C47 0x5CAE 0x5CA4 0x5CA0 0x5CB5 0x5CAF 0x5CA8 \ + 0x5CAC 0x5C9F 0x5CA3 0x5CAD 0x5CA2 0x5CAA 0x5CA7 0x5C9D \ + 0x5CA5 0x5CB6 0x5CB0 0x5CA6 0x5E17 0x5E14 0x5E19 0x5F28 \ + 0x5F22 0x5F23 0x5F24 0x5F54 0x5F82 0x5F7E 0x5F7D 0x5FDE \ + 0x5FE5 0x602D 0x6026 0x6019 0x6032 0x600B 0x6034 0x600A \ + 0x6017 0x6033 0x601A 0x601E 0x602C 0x6022 0x600D 0x6010 \ + 0x602E 0x6013 0x6011 0x600C 0x6009 0x601C 0x6214 0x623D \ + 0x62AD 0x62B4 0x62D1 0x62BE 0x62AA 0x62B6 0x62CA 0x62AE \ + 0x62B3 0x62AF 0x62BB 0x62A9 0x62B0 0x62B8 0x653D 0x65A8 \ + 0x65BB 0x6609 0x65FC 0x6604 0x6612 0x6608 0x65FB 0x6603 \ + 0x660B 0x660D 0x6605 0x65FD 0x6611 0x6610 0x66F6 0x670A \ + 0x6785 0x676C 0x678E 0x6792 0x6776 0x677B 0x6798 0x6786 \ + 0x6784 0x6774 0x678D 0x678C 0x677A 0x679F 0x6791 0x6799 \ + 0x6783 0x677D 0x6781 0x6778 0x6779 0x6794 0x6B25 0x6B80 \ + 0x6B7E 0x6BDE 0x6C1D 0x6C93 0x6CEC 0x6CEB 0x6CEE 0x6CD9 \ + 0x6CB6 0x6CD4 0x6CAD 0x6CE7 0x6CB7 0x6CD0 0x6CC2 0x6CBA \ + 0x6CC3 0x6CC6 0x6CED 0x6CF2 0x6CD2 0x6CDD 0x6CB4 0x6C8A +28 0x6C9D 0x6C80 0x6CDE 0x6CC0 0x6D30 0x6CCD 0x6CC7 0x6CB0 \ + 0x6CF9 0x6CCF 0x6CE9 0x6CD1 0x7094 0x7098 0x7085 0x7093 \ + 0x7086 0x7084 0x7091 0x7096 0x7082 0x709A 0x7083 0x726A \ + 0x72D6 0x72CB 0x72D8 0x72C9 0x72DC 0x72D2 0x72D4 0x72DA \ + 0x72CC 0x72D1 0x73A4 0x73A1 0x73AD 0x73A6 0x73A2 0x73A0 \ + 0x73AC 0x739D 0x74DD 0x74E8 0x753F 0x7540 0x753E 0x758C \ + 0x7598 0x76AF 0x76F3 0x76F1 0x76F0 0x76F5 0x77F8 0x77FC \ + 0x77F9 0x77FB 0x77FA 0x77F7 0x7942 0x793F 0x79C5 0x7A78 \ + 0x7A7B 0x7AFB 0x7C75 0x7CFD 0x8035 0x808F 0x80AE 0x80A3 \ + 0x80B8 0x80B5 0x80AD 0x8220 0x82A0 0x82C0 0x82AB 0x829A \ + 0x8298 0x829B 0x82B5 0x82A7 0x82AE 0x82BC 0x829E 0x82BA \ + 0x82B4 0x82A8 0x82A1 0x82A9 0x82C2 0x82A4 0x82C3 0x82B6 \ + 0x82A2 0x8670 0x866F 0x866D 0x866E 0x8C56 0x8FD2 0x8FCB \ + 0x8FD3 0x8FCD 0x8FD6 0x8FD5 0x8FD7 0x90B2 0x90B4 0x90AF \ + 0x90B3 0x90B0 0x9639 0x963D 0x963C 0x963A 0x9643 0x4FCD \ + 0x4FC5 0x4FD3 0x4FB2 0x4FC9 0x4FCB 0x4FC1 0x4FD4 0x4FDC \ + 0x4FD9 0x4FBB 0x4FB3 0x4FDB 0x4FC7 0x4FD6 0x4FBA 0x4FC0 \ + 0x4FB9 0x4FEC 0x5244 0x5249 0x52C0 0x52C2 0x533D 0x537C \ + 0x5397 0x5396 0x5399 0x5398 0x54BA 0x54A1 0x54AD 0x54A5 \ + 0x54CF 0x54C3 0x830D 0x54B7 0x54AE 0x54D6 0x54B6 0x54C5 \ + 0x54C6 0x54A0 0x5470 0x54BC 0x54A2 0x54BE 0x5472 0x54DE \ + 0x54B0 0x57B5 0x579E 0x579F 0x57A4 0x578C 0x5797 0x579D \ + 0x579B 0x5794 0x5798 0x578F 0x5799 0x57A5 0x579A 0x5795 \ + 0x58F4 0x590D 0x5953 0x59E1 0x59DE 0x59EE 0x5A00 0x59F1 \ + 0x59DD 0x59FA 0x59FD 0x59FC 0x59F6 0x59E4 0x59F2 0x59F7 \ + 0x59DB 0x59E9 0x59F3 0x59F5 0x59E0 0x59FE 0x59F4 0x59ED \ + 0x5BA8 0x5C4C 0x5CD0 0x5CD8 0x5CCC 0x5CD7 0x5CCB 0x5CDB \ + 0x5CDE 0x5CDA 0x5CC9 0x5CC7 0x5CCA 0x5CD6 0x5CD3 0x5CD4 \ + 0x5CCF 0x5CC8 0x5CC6 0x5CCE 0x5CDF 0x5CF8 0x5DF9 0x5E21 \ + 0x5E22 0x5E23 0x5E20 0x5E24 0x5EB0 0x5EA4 0x5EA2 0x5E9B \ + 0x5EA3 0x5EA5 0x5F07 0x5F2E 0x5F56 0x5F86 0x6037 0x6039 \ + 0x6054 0x6072 0x605E 0x6045 0x6053 0x6047 0x6049 0x605B +29 0x604C 0x6040 0x6042 0x605F 0x6024 0x6044 0x6058 0x6066 \ + 0x606E 0x6242 0x6243 0x62CF 0x630D 0x630B 0x62F5 0x630E \ + 0x6303 0x62EB 0x62F9 0x630F 0x630C 0x62F8 0x62F6 0x6300 \ + 0x6313 0x6314 0x62FA 0x6315 0x62FB 0x62F0 0x6541 0x6543 \ + 0x65AA 0x65BF 0x6636 0x6621 0x6632 0x6635 0x661C 0x6626 \ + 0x6622 0x6633 0x662B 0x663A 0x661D 0x6634 0x6639 0x662E \ + 0x670F 0x6710 0x67C1 0x67F2 0x67C8 0x67BA 0x67DC 0x67BB \ + 0x67F8 0x67D8 0x67C0 0x67B7 0x67C5 0x67EB 0x67E4 0x67DF \ + 0x67B5 0x67CD 0x67B3 0x67F7 0x67F6 0x67EE 0x67E3 0x67C2 \ + 0x67B9 0x67CE 0x67E7 0x67F0 0x67B2 0x67FC 0x67C6 0x67ED \ + 0x67CC 0x67AE 0x67E6 0x67DB 0x67FA 0x67C9 0x67CA 0x67C3 \ + 0x67EA 0x67CB 0x6B28 0x6B82 0x6B84 0x6BB6 0x6BD6 0x6BD8 \ + 0x6BE0 0x6C20 0x6C21 0x6D28 0x6D34 0x6D2D 0x6D1F 0x6D3C \ + 0x6D3F 0x6D12 0x6D0A 0x6CDA 0x6D33 0x6D04 0x6D19 0x6D3A \ + 0x6D1A 0x6D11 0x6D00 0x6D1D 0x6D42 0x6D01 0x6D18 0x6D37 \ + 0x6D03 0x6D0F 0x6D40 0x6D07 0x6D20 0x6D2C 0x6D08 0x6D22 \ + 0x6D09 0x6D10 0x70B7 0x709F 0x70BE 0x70B1 0x70B0 0x70A1 \ + 0x70B4 0x70B5 0x70A9 0x7241 0x7249 0x724A 0x726C 0x7270 \ + 0x7273 0x726E 0x72CA 0x72E4 0x72E8 0x72EB 0x72DF 0x72EA \ + 0x72E6 0x72E3 0x7385 0x73CC 0x73C2 0x73C8 0x73C5 0x73B9 \ + 0x73B6 0x73B5 0x73B4 0x73EB 0x73BF 0x73C7 0x73BE 0x73C3 \ + 0x73C6 0x73B8 0x73CB 0x74EC 0x74EE 0x752E 0x7547 0x7548 \ + 0x75A7 0x75AA 0x7679 0x76C4 0x7708 0x7703 0x7704 0x7705 \ + 0x770A 0x76F7 0x76FB 0x76FA 0x77E7 0x77E8 0x7806 0x7811 \ + 0x7812 0x7805 0x7810 0x780F 0x780E 0x7809 0x7803 0x7813 \ + 0x794A 0x794C 0x794B 0x7945 0x7944 0x79D5 0x79CD 0x79CF \ + 0x79D6 0x79CE 0x7A80 0x7A7E 0x7AD1 0x7B00 0x7B01 0x7C7A \ + 0x7C78 0x7C79 0x7C7F 0x7C80 0x7C81 0x7D03 0x7D08 0x7D01 \ + 0x7F58 0x7F91 0x7F8D 0x7FBE 0x8007 0x800E 0x800F 0x8014 \ + 0x8037 0x80D8 0x80C7 0x80E0 0x80D1 0x80C8 0x80C2 0x80D0 \ + 0x80C5 0x80E3 0x80D9 0x80DC 0x80CA 0x80D5 0x80C9 0x80CF \ + 0x80D7 0x80E6 0x80CD 0x81FF 0x8221 0x8294 0x82D9 0x82FE +30 0x82F9 0x8307 0x82E8 0x8300 0x82D5 0x833A 0x82EB 0x82D6 \ + 0x82F4 0x82EC 0x82E1 0x82F2 0x82F5 0x830C 0x82FB 0x82F6 \ + 0x82F0 0x82EA 0x82E4 0x82E0 0x82FA 0x82F3 0x82ED 0x8677 \ + 0x8674 0x867C 0x8673 0x8841 0x884E 0x8867 0x886A 0x8869 \ + 0x89D3 0x8A04 0x8A07 0x8D72 0x8FE3 0x8FE1 0x8FEE 0x8FE0 \ + 0x90F1 0x90BD 0x90BF 0x90D5 0x90C5 0x90BE 0x90C7 0x90CB \ + 0x90C8 0x91D4 0x91D3 0x9654 0x964F 0x9651 0x9653 0x964A \ + 0x964E 0x501E 0x5005 0x5007 0x5013 0x5022 0x5030 0x501B \ + 0x4FF5 0x4FF4 0x5033 0x5037 0x502C 0x4FF6 0x4FF7 0x5017 \ + 0x501C 0x5020 0x5027 0x5035 0x502F 0x5031 0x500E 0x515A \ + 0x5194 0x5193 0x51CA 0x51C4 0x51C5 0x51C8 0x51CE 0x5261 \ + 0x525A 0x5252 0x525E 0x525F 0x5255 0x5262 0x52CD 0x530E \ + 0x539E 0x5526 0x54E2 0x5517 0x5512 0x54E7 0x54F3 0x54E4 \ + 0x551A 0x54FF 0x5504 0x5508 0x54EB 0x5511 0x5505 0x54F1 \ + 0x550A 0x54FB 0x54F7 0x54F8 0x54E0 0x550E 0x5503 0x550B \ + 0x5701 0x5702 0x57CC 0x5832 0x57D5 0x57D2 0x57BA 0x57C6 \ + 0x57BD 0x57BC 0x57B8 0x57B6 0x57BF 0x57C7 0x57D0 0x57B9 \ + 0x57C1 0x590E 0x594A 0x5A19 0x5A16 0x5A2D 0x5A2E 0x5A15 \ + 0x5A0F 0x5A17 0x5A0A 0x5A1E 0x5A33 0x5B6C 0x5BA7 0x5BAD \ + 0x5BAC 0x5C03 0x5C56 0x5C54 0x5CEC 0x5CFF 0x5CEE 0x5CF1 \ + 0x5CF7 0x5D00 0x5CF9 0x5E29 0x5E28 0x5EA8 0x5EAE 0x5EAA \ + 0x5EAC 0x5F33 0x5F30 0x5F67 0x605D 0x605A 0x6067 0x6041 \ + 0x60A2 0x6088 0x6080 0x6092 0x6081 0x609D 0x6083 0x6095 \ + 0x609B 0x6097 0x6087 0x609C 0x608E 0x6219 0x6246 0x62F2 \ + 0x6310 0x6356 0x632C 0x6344 0x6345 0x6336 0x6343 0x63E4 \ + 0x6339 0x634B 0x634A 0x633C 0x6329 0x6341 0x6334 0x6358 \ + 0x6354 0x6359 0x632D 0x6347 0x6333 0x635A 0x6351 0x6338 \ + 0x6357 0x6340 0x6348 0x654A 0x6546 0x65C6 0x65C3 0x65C4 \ + 0x65C2 0x664A 0x665F 0x6647 0x6651 0x6712 0x6713 0x681F \ + 0x681A 0x6849 0x6832 0x6833 0x683B 0x684B 0x684F 0x6816 \ + 0x6831 0x681C 0x6835 0x682B 0x682D 0x682F 0x684E 0x6844 \ + 0x6834 0x681D 0x6812 0x6814 0x6826 0x6828 0x682E 0x684D +31 0x683A 0x6825 0x6820 0x6B2C 0x6B2F 0x6B2D 0x6B31 0x6B34 \ + 0x6B6D 0x8082 0x6B88 0x6BE6 0x6BE4 0x6BE8 0x6BE3 0x6BE2 \ + 0x6BE7 0x6C25 0x6D7A 0x6D63 0x6D64 0x6D76 0x6D0D 0x6D61 \ + 0x6D92 0x6D58 0x6D62 0x6D6D 0x6D6F 0x6D91 0x6D8D 0x6DEF \ + 0x6D7F 0x6D86 0x6D5E 0x6D67 0x6D60 0x6D97 0x6D70 0x6D7C \ + 0x6D5F 0x6D82 0x6D98 0x6D2F 0x6D68 0x6D8B 0x6D7E 0x6D80 \ + 0x6D84 0x6D16 0x6D83 0x6D7B 0x6D7D 0x6D75 0x6D90 0x70DC \ + 0x70D3 0x70D1 0x70DD 0x70CB 0x7F39 0x70E2 0x70D7 0x70D2 \ + 0x70DE 0x70E0 0x70D4 0x70CD 0x70C5 0x70C6 0x70C7 0x70DA \ + 0x70CE 0x70E1 0x7242 0x7278 0x7277 0x7276 0x7300 0x72FA \ + 0x72F4 0x72FE 0x72F6 0x72F3 0x72FB 0x7301 0x73D3 0x73D9 \ + 0x73E5 0x73D6 0x73BC 0x73E7 0x73E3 0x73E9 0x73DC 0x73D2 \ + 0x73DB 0x73D4 0x73DD 0x73DA 0x73D7 0x73D8 0x73E8 0x74DE \ + 0x74DF 0x74F4 0x74F5 0x7521 0x755B 0x755F 0x75B0 0x75C1 \ + 0x75BB 0x75C4 0x75C0 0x75BF 0x75B6 0x75BA 0x768A 0x76C9 \ + 0x771D 0x771B 0x7710 0x7713 0x7712 0x7723 0x7711 0x7715 \ + 0x7719 0x771A 0x7722 0x7727 0x7823 0x782C 0x7822 0x7835 \ + 0x782F 0x7828 0x782E 0x782B 0x7821 0x7829 0x7833 0x782A \ + 0x7831 0x7954 0x795B 0x794F 0x795C 0x7953 0x7952 0x7951 \ + 0x79EB 0x79EC 0x79E0 0x79EE 0x79ED 0x79EA 0x79DC 0x79DE \ + 0x79DD 0x7A86 0x7A89 0x7A85 0x7A8B 0x7A8C 0x7A8A 0x7A87 \ + 0x7AD8 0x7B10 0x7B04 0x7B13 0x7B05 0x7B0F 0x7B08 0x7B0A \ + 0x7B0E 0x7B09 0x7B12 0x7C84 0x7C91 0x7C8A 0x7C8C 0x7C88 \ + 0x7C8D 0x7C85 0x7D1E 0x7D1D 0x7D11 0x7D0E 0x7D18 0x7D16 \ + 0x7D13 0x7D1F 0x7D12 0x7D0F 0x7D0C 0x7F5C 0x7F61 0x7F5E \ + 0x7F60 0x7F5D 0x7F5B 0x7F96 0x7F92 0x7FC3 0x7FC2 0x7FC0 \ + 0x8016 0x803E 0x8039 0x80FA 0x80F2 0x80F9 0x80F5 0x8101 \ + 0x80FB 0x8100 0x8201 0x822F 0x8225 0x8333 0x832D 0x8344 \ + 0x8319 0x8351 0x8325 0x8356 0x833F 0x8341 0x8326 0x831C \ + 0x8322 0x8342 0x834E 0x831B 0x832A 0x8308 0x833C 0x834D \ + 0x8316 0x8324 0x8320 0x8337 0x832F 0x8329 0x8347 0x8345 \ + 0x834C 0x8353 0x831E 0x832C 0x834B 0x8327 0x8348 0x8653 +32 0x8652 0x86A2 0x86A8 0x8696 0x868D 0x8691 0x869E 0x8687 \ + 0x8697 0x8686 0x868B 0x869A 0x8685 0x86A5 0x8699 0x86A1 \ + 0x86A7 0x8695 0x8698 0x868E 0x869D 0x8690 0x8694 0x8843 \ + 0x8844 0x886D 0x8875 0x8876 0x8872 0x8880 0x8871 0x887F \ + 0x886F 0x8883 0x887E 0x8874 0x887C 0x8A12 0x8C47 0x8C57 \ + 0x8C7B 0x8CA4 0x8CA3 0x8D76 0x8D78 0x8DB5 0x8DB7 0x8DB6 \ + 0x8ED1 0x8ED3 0x8FFE 0x8FF5 0x9002 0x8FFF 0x8FFB 0x9004 \ + 0x8FFC 0x8FF6 0x90D6 0x90E0 0x90D9 0x90DA 0x90E3 0x90DF \ + 0x90E5 0x90D8 0x90DB 0x90D7 0x90DC 0x90E4 0x9150 0x914E \ + 0x914F 0x91D5 0x91E2 0x91DA 0x965C 0x965F 0x96BC 0x98E3 \ + 0x9ADF 0x9B2F 0x4E7F 0x5070 0x506A 0x5061 0x505E 0x5060 \ + 0x5053 0x504B 0x505D 0x5072 0x5048 0x504D 0x5041 0x505B \ + 0x504A 0x5062 0x5015 0x5045 0x505F 0x5069 0x506B 0x5063 \ + 0x5064 0x5046 0x5040 0x506E 0x5073 0x5057 0x5051 0x51D0 \ + 0x526B 0x526D 0x526C 0x526E 0x52D6 0x52D3 0x532D 0x539C \ + 0x5575 0x5576 0x553C 0x554D 0x5550 0x5534 0x552A 0x5551 \ + 0x5562 0x5536 0x5535 0x5530 0x5552 0x5545 0x550C 0x5532 \ + 0x5565 0x554E 0x5539 0x5548 0x552D 0x553B 0x5540 0x554B \ + 0x570A 0x5707 0x57FB 0x5814 0x57E2 0x57F6 0x57DC 0x57F4 \ + 0x5800 0x57ED 0x57FD 0x5808 0x57F8 0x580B 0x57F3 0x57CF \ + 0x5807 0x57EE 0x57E3 0x57F2 0x57E5 0x57EC 0x57E1 0x580E \ + 0x57FC 0x5810 0x57E7 0x5801 0x580C 0x57F1 0x57E9 0x57F0 \ + 0x580D 0x5804 0x595C 0x5A60 0x5A58 0x5A55 0x5A67 0x5A5E \ + 0x5A38 0x5A35 0x5A6D 0x5A50 0x5A5F 0x5A65 0x5A6C 0x5A53 \ + 0x5A64 0x5A57 0x5A43 0x5A5D 0x5A52 0x5A44 0x5A5B 0x5A48 \ + 0x5A8E 0x5A3E 0x5A4D 0x5A39 0x5A4C 0x5A70 0x5A69 0x5A47 \ + 0x5A51 0x5A56 0x5A42 0x5A5C 0x5B72 0x5B6E 0x5BC1 0x5BC0 \ + 0x5C59 0x5D1E 0x5D0B 0x5D1D 0x5D1A 0x5D20 0x5D0C 0x5D28 \ + 0x5D0D 0x5D26 0x5D25 0x5D0F 0x5D30 0x5D12 0x5D23 0x5D1F \ + 0x5D2E 0x5E3E 0x5E34 0x5EB1 0x5EB4 0x5EB9 0x5EB2 0x5EB3 \ + 0x5F36 0x5F38 0x5F9B 0x5F96 0x5F9F 0x608A 0x6090 0x6086 \ + 0x60BE 0x60B0 0x60BA 0x60D3 0x60D4 0x60CF 0x60E4 0x60D9 +33 0x60DD 0x60C8 0x60B1 0x60DB 0x60B7 0x60CA 0x60BF 0x60C3 \ + 0x60CD 0x60C0 0x6332 0x6365 0x638A 0x6382 0x637D 0x63BD \ + 0x639E 0x63AD 0x639D 0x6397 0x63AB 0x638E 0x636F 0x6387 \ + 0x6390 0x636E 0x63AF 0x6375 0x639C 0x636D 0x63AE 0x637C \ + 0x63A4 0x633B 0x639F 0x6378 0x6385 0x6381 0x6391 0x638D \ + 0x6370 0x6553 0x65CD 0x6665 0x6661 0x665B 0x6659 0x665C \ + 0x6662 0x6718 0x6879 0x6887 0x6890 0x689C 0x686D 0x686E \ + 0x68AE 0x68AB 0x6956 0x686F 0x68A3 0x68AC 0x68A9 0x6875 \ + 0x6874 0x68B2 0x688F 0x6877 0x6892 0x687C 0x686B 0x6872 \ + 0x68AA 0x6880 0x6871 0x687E 0x689B 0x6896 0x688B 0x68A0 \ + 0x6889 0x68A4 0x6878 0x687B 0x6891 0x688C 0x688A 0x687D \ + 0x6B36 0x6B33 0x6B37 0x6B38 0x6B91 0x6B8F 0x6B8D 0x6B8E \ + 0x6B8C 0x6C2A 0x6DC0 0x6DAB 0x6DB4 0x6DB3 0x6E74 0x6DAC \ + 0x6DE9 0x6DE2 0x6DB7 0x6DF6 0x6DD4 0x6E00 0x6DC8 0x6DE0 \ + 0x6DDF 0x6DD6 0x6DBE 0x6DE5 0x6DDC 0x6DDD 0x6DDB 0x6DF4 \ + 0x6DCA 0x6DBD 0x6DED 0x6DF0 0x6DBA 0x6DD5 0x6DC2 0x6DCF \ + 0x6DC9 0x6DD0 0x6DF2 0x6DD3 0x6DFD 0x6DD7 0x6DCD 0x6DE3 \ + 0x6DBB 0x70FA 0x710D 0x70F7 0x7117 0x70F4 0x710C 0x70F0 \ + 0x7104 0x70F3 0x7110 0x70FC 0x70FF 0x7106 0x7113 0x7100 \ + 0x70F8 0x70F6 0x710B 0x7102 0x710E 0x727E 0x727B 0x727C \ + 0x727F 0x731D 0x7317 0x7307 0x7311 0x7318 0x730A 0x7308 \ + 0x72FF 0x730F 0x731E 0x7388 0x73F6 0x73F8 0x73F5 0x7404 \ + 0x7401 0x73FD 0x7407 0x7400 0x73FA 0x73FC 0x73FF 0x740C \ + 0x740B 0x73F4 0x7408 0x7564 0x7563 0x75CE 0x75D2 0x75CF \ + 0x75CB 0x75CC 0x75D1 0x75D0 0x768F 0x7689 0x76D3 0x7739 \ + 0x772F 0x772D 0x7731 0x7732 0x7734 0x7733 0x773D 0x7725 \ + 0x773B 0x7735 0x7848 0x7852 0x7849 0x784D 0x784A 0x784C \ + 0x7826 0x7845 0x7850 0x7964 0x7967 0x7969 0x796A 0x7963 \ + 0x796B 0x7961 0x79BB 0x79FA 0x79F8 0x79F6 0x79F7 0x7A8F \ + 0x7A94 0x7A90 0x7B35 0x7B47 0x7B34 0x7B25 0x7B30 0x7B22 \ + 0x7B24 0x7B33 0x7B18 0x7B2A 0x7B1D 0x7B31 0x7B2B 0x7B2D \ + 0x7B2F 0x7B32 0x7B38 0x7B1A 0x7B23 0x7C94 0x7C98 0x7C96 +34 0x7CA3 0x7D35 0x7D3D 0x7D38 0x7D36 0x7D3A 0x7D45 0x7D2C \ + 0x7D29 0x7D41 0x7D47 0x7D3E 0x7D3F 0x7D4A 0x7D3B 0x7D28 \ + 0x7F63 0x7F95 0x7F9C 0x7F9D 0x7F9B 0x7FCA 0x7FCB 0x7FCD \ + 0x7FD0 0x7FD1 0x7FC7 0x7FCF 0x7FC9 0x801F 0x801E 0x801B \ + 0x8047 0x8043 0x8048 0x8118 0x8125 0x8119 0x811B 0x812D \ + 0x811F 0x812C 0x811E 0x8121 0x8115 0x8127 0x811D 0x8122 \ + 0x8211 0x8238 0x8233 0x823A 0x8234 0x8232 0x8274 0x8390 \ + 0x83A3 0x83A8 0x838D 0x837A 0x8373 0x83A4 0x8374 0x838F \ + 0x8381 0x8395 0x8399 0x8375 0x8394 0x83A9 0x837D 0x8383 \ + 0x838C 0x839D 0x839B 0x83AA 0x838B 0x837E 0x83A5 0x83AF \ + 0x8388 0x8397 0x83B0 0x837F 0x83A6 0x8387 0x83AE 0x8376 \ + 0x839A 0x8659 0x8656 0x86BF 0x86B7 0x86C2 0x86C1 0x86C5 \ + 0x86BA 0x86B0 0x86C8 0x86B9 0x86B3 0x86B8 0x86CC 0x86B4 \ + 0x86BB 0x86BC 0x86C3 0x86BD 0x86BE 0x8852 0x8889 0x8895 \ + 0x88A8 0x88A2 0x88AA 0x889A 0x8891 0x88A1 0x889F 0x8898 \ + 0x88A7 0x8899 0x889B 0x8897 0x88A4 0x88AC 0x888C 0x8893 \ + 0x888E 0x8982 0x89D6 0x89D9 0x89D5 0x8A30 0x8A27 0x8A2C \ + 0x8A1E 0x8C39 0x8C3B 0x8C5C 0x8C5D 0x8C7D 0x8CA5 0x8D7D \ + 0x8D7B 0x8D79 0x8DBC 0x8DC2 0x8DB9 0x8DBF 0x8DC1 0x8ED8 \ + 0x8EDE 0x8EDD 0x8EDC 0x8ED7 0x8EE0 0x8EE1 0x9024 0x900B \ + 0x9011 0x901C 0x900C 0x9021 0x90EF 0x90EA 0x90F0 0x90F4 \ + 0x90F2 0x90F3 0x90D4 0x90EB 0x90EC 0x90E9 0x9156 0x9158 \ + 0x915A 0x9153 0x9155 0x91EC 0x91F4 0x91F1 0x91F3 0x91F8 \ + 0x91E4 0x91F9 0x91EA 0x91EB 0x91F7 0x91E8 0x91EE 0x957A \ + 0x9586 0x9588 0x967C 0x966D 0x966B 0x9671 0x966F 0x96BF \ + 0x976A 0x9804 0x98E5 0x9997 0x509B 0x5095 0x5094 0x509E \ + 0x508B 0x50A3 0x5083 0x508C 0x508E 0x509D 0x5068 0x509C \ + 0x5092 0x5082 0x5087 0x515F 0x51D4 0x5312 0x5311 0x53A4 \ + 0x53A7 0x5591 0x55A8 0x55A5 0x55AD 0x5577 0x5645 0x55A2 \ + 0x5593 0x5588 0x558F 0x55B5 0x5581 0x55A3 0x5592 0x55A4 \ + 0x557D 0x558C 0x55A6 0x557F 0x5595 0x55A1 0x558E 0x570C \ + 0x5829 0x5837 0x5819 0x581E 0x5827 0x5823 0x5828 0x57F5 +35 0x5848 0x5825 0x581C 0x581B 0x5833 0x583F 0x5836 0x582E \ + 0x5839 0x5838 0x582D 0x582C 0x583B 0x5961 0x5AAF 0x5A94 \ + 0x5A9F 0x5A7A 0x5AA2 0x5A9E 0x5A78 0x5AA6 0x5A7C 0x5AA5 \ + 0x5AAC 0x5A95 0x5AAE 0x5A37 0x5A84 0x5A8A 0x5A97 0x5A83 \ + 0x5A8B 0x5AA9 0x5A7B 0x5A7D 0x5A8C 0x5A9C 0x5A8F 0x5A93 \ + 0x5A9D 0x5BEA 0x5BCD 0x5BCB 0x5BD4 0x5BD1 0x5BCA 0x5BCE \ + 0x5C0C 0x5C30 0x5D37 0x5D43 0x5D6B 0x5D41 0x5D4B 0x5D3F \ + 0x5D35 0x5D51 0x5D4E 0x5D55 0x5D33 0x5D3A 0x5D52 0x5D3D \ + 0x5D31 0x5D59 0x5D42 0x5D39 0x5D49 0x5D38 0x5D3C 0x5D32 \ + 0x5D36 0x5D40 0x5D45 0x5E44 0x5E41 0x5F58 0x5FA6 0x5FA5 \ + 0x5FAB 0x60C9 0x60B9 0x60CC 0x60E2 0x60CE 0x60C4 0x6114 \ + 0x60F2 0x610A 0x6116 0x6105 0x60F5 0x6113 0x60F8 0x60FC \ + 0x60FE 0x60C1 0x6103 0x6118 0x611D 0x6110 0x60FF 0x6104 \ + 0x610B 0x624A 0x6394 0x63B1 0x63B0 0x63CE 0x63E5 0x63E8 \ + 0x63EF 0x63C3 0x649D 0x63F3 0x63CA 0x63E0 0x63F6 0x63D5 \ + 0x63F2 0x63F5 0x6461 0x63DF 0x63BE 0x63DD 0x63DC 0x63C4 \ + 0x63D8 0x63D3 0x63C2 0x63C7 0x63CC 0x63CB 0x63C8 0x63F0 \ + 0x63D7 0x63D9 0x6532 0x6567 0x656A 0x6564 0x655C 0x6568 \ + 0x6565 0x658C 0x659D 0x659E 0x65AE 0x65D0 0x65D2 0x667C \ + 0x666C 0x667B 0x6680 0x6671 0x6679 0x666A 0x6672 0x6701 \ + 0x690C 0x68D3 0x6904 0x68DC 0x692A 0x68EC 0x68EA 0x68F1 \ + 0x690F 0x68D6 0x68F7 0x68EB 0x68E4 0x68F6 0x6913 0x6910 \ + 0x68F3 0x68E1 0x6907 0x68CC 0x6908 0x6970 0x68B4 0x6911 \ + 0x68EF 0x68C6 0x6914 0x68F8 0x68D0 0x68FD 0x68FC 0x68E8 \ + 0x690B 0x690A 0x6917 0x68CE 0x68C8 0x68DD 0x68DE 0x68E6 \ + 0x68F4 0x68D1 0x6906 0x68D4 0x68E9 0x6915 0x6925 0x68C7 \ + 0x6B39 0x6B3B 0x6B3F 0x6B3C 0x6B94 0x6B97 0x6B99 0x6B95 \ + 0x6BBD 0x6BF0 0x6BF2 0x6BF3 0x6C30 0x6DFC 0x6E46 0x6E47 \ + 0x6E1F 0x6E49 0x6E88 0x6E3C 0x6E3D 0x6E45 0x6E62 0x6E2B \ + 0x6E3F 0x6E41 0x6E5D 0x6E73 0x6E1C 0x6E33 0x6E4B 0x6E40 \ + 0x6E51 0x6E3B 0x6E03 0x6E2E 0x6E5E 0x6E68 0x6E5C 0x6E61 \ + 0x6E31 0x6E28 0x6E60 0x6E71 0x6E6B 0x6E39 0x6E22 0x6E30 +36 0x6E53 0x6E65 0x6E27 0x6E78 0x6E64 0x6E77 0x6E55 0x6E79 \ + 0x6E52 0x6E66 0x6E35 0x6E36 0x6E5A 0x7120 0x711E 0x712F \ + 0x70FB 0x712E 0x7131 0x7123 0x7125 0x7122 0x7132 0x711F \ + 0x7128 0x713A 0x711B 0x724B 0x725A 0x7288 0x7289 0x7286 \ + 0x7285 0x728B 0x7312 0x730B 0x7330 0x7322 0x7331 0x7333 \ + 0x7327 0x7332 0x732D 0x7326 0x7323 0x7335 0x730C 0x742E \ + 0x742C 0x7430 0x742B 0x7416 0x741A 0x7421 0x742D 0x7431 \ + 0x7424 0x7423 0x741D 0x7429 0x7420 0x7432 0x74FB 0x752F \ + 0x756F 0x756C 0x75E7 0x75DA 0x75E1 0x75E6 0x75DD 0x75DF \ + 0x75E4 0x75D7 0x7695 0x7692 0x76DA 0x7746 0x7747 0x7744 \ + 0x774D 0x7745 0x774A 0x774E 0x774B 0x774C 0x77DE 0x77EC \ + 0x7860 0x7864 0x7865 0x785C 0x786D 0x7871 0x786A 0x786E \ + 0x7870 0x7869 0x7868 0x785E 0x7862 0x7974 0x7973 0x7972 \ + 0x7970 0x7A02 0x7A0A 0x7A03 0x7A0C 0x7A04 0x7A99 0x7AE6 \ + 0x7AE4 0x7B4A 0x7B3B 0x7B44 0x7B48 0x7B4C 0x7B4E 0x7B40 \ + 0x7B58 0x7B45 0x7CA2 0x7C9E 0x7CA8 0x7CA1 0x7D58 0x7D6F \ + 0x7D63 0x7D53 0x7D56 0x7D67 0x7D6A 0x7D4F 0x7D6D 0x7D5C \ + 0x7D6B 0x7D52 0x7D54 0x7D69 0x7D51 0x7D5F 0x7D4E 0x7F3E \ + 0x7F3F 0x7F65 0x7F66 0x7FA2 0x7FA0 0x7FA1 0x7FD7 0x8051 \ + 0x804F 0x8050 0x80FE 0x80D4 0x8143 0x814A 0x8152 0x814F \ + 0x8147 0x813D 0x814D 0x813A 0x81E6 0x81EE 0x81F7 0x81F8 \ + 0x81F9 0x8204 0x823C 0x823D 0x823F 0x8275 0x833B 0x83CF \ + 0x83F9 0x8423 0x83C0 0x83E8 0x8412 0x83E7 0x83E4 0x83FC \ + 0x83F6 0x8410 0x83C6 0x83C8 0x83EB 0x83E3 0x83BF 0x8401 \ + 0x83DD 0x83E5 0x83D8 0x83FF 0x83E1 0x83CB 0x83CE 0x83D6 \ + 0x83F5 0x83C9 0x8409 0x840F 0x83DE 0x8411 0x8406 0x83C2 \ + 0x83F3 0x83D5 0x83FA 0x83C7 0x83D1 0x83EA 0x8413 0x83C3 \ + 0x83EC 0x83EE 0x83C4 0x83FB 0x83D7 0x83E2 0x841B 0x83DB \ + 0x83FE 0x86D8 0x86E2 0x86E6 0x86D3 0x86E3 0x86DA 0x86EA \ + 0x86DD 0x86EB 0x86DC 0x86EC 0x86E9 0x86D7 0x86E8 0x86D1 \ + 0x8848 0x8856 0x8855 0x88BA 0x88D7 0x88B9 0x88B8 0x88C0 \ + 0x88BE 0x88B6 0x88BC 0x88B7 0x88BD 0x88B2 0x8901 0x88C9 +37 0x8995 0x8998 0x8997 0x89DD 0x89DA 0x89DB 0x8A4E 0x8A4D \ + 0x8A39 0x8A59 0x8A40 0x8A57 0x8A58 0x8A44 0x8A45 0x8A52 \ + 0x8A48 0x8A51 0x8A4A 0x8A4C 0x8A4F 0x8C5F 0x8C81 0x8C80 \ + 0x8CBA 0x8CBE 0x8CB0 0x8CB9 0x8CB5 0x8D84 0x8D80 0x8D89 \ + 0x8DD8 0x8DD3 0x8DCD 0x8DC7 0x8DD6 0x8DDC 0x8DCF 0x8DD5 \ + 0x8DD9 0x8DC8 0x8DD7 0x8DC5 0x8EEF 0x8EF7 0x8EFA 0x8EF9 \ + 0x8EE6 0x8EEE 0x8EE5 0x8EF5 0x8EE7 0x8EE8 0x8EF6 0x8EEB \ + 0x8EF1 0x8EEC 0x8EF4 0x8EE9 0x902D 0x9034 0x902F 0x9106 \ + 0x912C 0x9104 0x90FF 0x90FC 0x9108 0x90F9 0x90FB 0x9101 \ + 0x9100 0x9107 0x9105 0x9103 0x9161 0x9164 0x915F 0x9162 \ + 0x9160 0x9201 0x920A 0x9225 0x9203 0x921A 0x9226 0x920F \ + 0x920C 0x9200 0x9212 0x91FF 0x91FD 0x9206 0x9204 0x9227 \ + 0x9202 0x921C 0x9224 0x9219 0x9217 0x9205 0x9216 0x957B \ + 0x958D 0x958C 0x9590 0x9687 0x967E 0x9688 0x9689 0x9683 \ + 0x9680 0x96C2 0x96C8 0x96C3 0x96F1 0x96F0 0x976C 0x9770 \ + 0x976E 0x9807 0x98A9 0x98EB 0x9CE6 0x9EF9 0x4E83 0x4E84 \ + 0x4EB6 0x50BD 0x50BF 0x50C6 0x50AE 0x50C4 0x50CA 0x50B4 \ + 0x50C8 0x50C2 0x50B0 0x50C1 0x50BA 0x50B1 0x50CB 0x50C9 \ + 0x50B6 0x50B8 0x51D7 0x527A 0x5278 0x527B 0x527C 0x55C3 \ + 0x55DB 0x55CC 0x55D0 0x55CB 0x55CA 0x55DD 0x55C0 0x55D4 \ + 0x55C4 0x55E9 0x55BF 0x55D2 0x558D 0x55CF 0x55D5 0x55E2 \ + 0x55D6 0x55C8 0x55F2 0x55CD 0x55D9 0x55C2 0x5714 0x5853 \ + 0x5868 0x5864 0x584F 0x584D 0x5849 0x586F 0x5855 0x584E \ + 0x585D 0x5859 0x5865 0x585B 0x583D 0x5863 0x5871 0x58FC \ + 0x5AC7 0x5AC4 0x5ACB 0x5ABA 0x5AB8 0x5AB1 0x5AB5 0x5AB0 \ + 0x5ABF 0x5AC8 0x5ABB 0x5AC6 0x5AB7 0x5AC0 0x5ACA 0x5AB4 \ + 0x5AB6 0x5ACD 0x5AB9 0x5A90 0x5BD6 0x5BD8 0x5BD9 0x5C1F \ + 0x5C33 0x5D71 0x5D63 0x5D4A 0x5D65 0x5D72 0x5D6C 0x5D5E \ + 0x5D68 0x5D67 0x5D62 0x5DF0 0x5E4F 0x5E4E 0x5E4A 0x5E4D \ + 0x5E4B 0x5EC5 0x5ECC 0x5EC6 0x5ECB 0x5EC7 0x5F40 0x5FAF \ + 0x5FAD 0x60F7 0x6149 0x614A 0x612B 0x6145 0x6136 0x6132 \ + 0x612E 0x6146 0x612F 0x614F 0x6129 0x6140 0x6220 0x9168 +38 0x6223 0x6225 0x6224 0x63C5 0x63F1 0x63EB 0x6410 0x6412 \ + 0x6409 0x6420 0x6424 0x6433 0x6443 0x641F 0x6415 0x6418 \ + 0x6439 0x6437 0x6422 0x6423 0x640C 0x6426 0x6430 0x6428 \ + 0x6441 0x6435 0x642F 0x640A 0x641A 0x6440 0x6425 0x6427 \ + 0x640B 0x63E7 0x641B 0x642E 0x6421 0x640E 0x656F 0x6592 \ + 0x65D3 0x6686 0x668C 0x6695 0x6690 0x668B 0x668A 0x6699 \ + 0x6694 0x6678 0x6720 0x6966 0x695F 0x6938 0x694E 0x6962 \ + 0x6971 0x693F 0x6945 0x696A 0x6939 0x6942 0x6957 0x6959 \ + 0x697A 0x6948 0x6949 0x6935 0x696C 0x6933 0x693D 0x6965 \ + 0x68F0 0x6978 0x6934 0x6969 0x6940 0x696F 0x6944 0x6976 \ + 0x6958 0x6941 0x6974 0x694C 0x693B 0x694B 0x6937 0x695C \ + 0x694F 0x6951 0x6932 0x6952 0x692F 0x697B 0x693C 0x6B46 \ + 0x6B45 0x6B43 0x6B42 0x6B48 0x6B41 0x6B9B 0xFA0D 0x6BFB \ + 0x6BFC 0x6BF9 0x6BF7 0x6BF8 0x6E9B 0x6ED6 0x6EC8 0x6E8F \ + 0x6EC0 0x6E9F 0x6E93 0x6E94 0x6EA0 0x6EB1 0x6EB9 0x6EC6 \ + 0x6ED2 0x6EBD 0x6EC1 0x6E9E 0x6EC9 0x6EB7 0x6EB0 0x6ECD \ + 0x6EA6 0x6ECF 0x6EB2 0x6EBE 0x6EC3 0x6EDC 0x6ED8 0x6E99 \ + 0x6E92 0x6E8E 0x6E8D 0x6EA4 0x6EA1 0x6EBF 0x6EB3 0x6ED0 \ + 0x6ECA 0x6E97 0x6EAE 0x6EA3 0x7147 0x7154 0x7152 0x7163 \ + 0x7160 0x7141 0x715D 0x7162 0x7172 0x7178 0x716A 0x7161 \ + 0x7142 0x7158 0x7143 0x714B 0x7170 0x715F 0x7150 0x7153 \ + 0x7144 0x714D 0x715A 0x724F 0x728D 0x728C 0x7291 0x7290 \ + 0x728E 0x733C 0x7342 0x733B 0x733A 0x7340 0x734A 0x7349 \ + 0x7444 0x744A 0x744B 0x7452 0x7451 0x7457 0x7440 0x744F \ + 0x7450 0x744E 0x7442 0x7446 0x744D 0x7454 0x74E1 0x74FF \ + 0x74FE 0x74FD 0x751D 0x7579 0x7577 0x6983 0x75EF 0x760F \ + 0x7603 0x75F7 0x75FE 0x75FC 0x75F9 0x75F8 0x7610 0x75FB \ + 0x75F6 0x75ED 0x75F5 0x75FD 0x7699 0x76B5 0x76DD 0x7755 \ + 0x775F 0x7760 0x7752 0x7756 0x775A 0x7769 0x7767 0x7754 \ + 0x7759 0x776D 0x77E0 0x7887 0x789A 0x7894 0x788F 0x7884 \ + 0x7895 0x7885 0x7886 0x78A1 0x7883 0x7879 0x7899 0x7880 \ + 0x7896 0x787B 0x797C 0x7982 0x797D 0x7979 0x7A11 0x7A18 +39 0x7A19 0x7A12 0x7A17 0x7A15 0x7A22 0x7A13 0x7A1B 0x7A10 \ + 0x7AA3 0x7AA2 0x7A9E 0x7AEB 0x7B66 0x7B64 0x7B6D 0x7B74 \ + 0x7B69 0x7B72 0x7B65 0x7B73 0x7B71 0x7B70 0x7B61 0x7B78 \ + 0x7B76 0x7B63 0x7CB2 0x7CB4 0x7CAF 0x7D88 0x7D86 0x7D80 \ + 0x7D8D 0x7D7F 0x7D85 0x7D7A 0x7D8E 0x7D7B 0x7D83 0x7D7C \ + 0x7D8C 0x7D94 0x7D84 0x7D7D 0x7D92 0x7F6D 0x7F6B 0x7F67 \ + 0x7F68 0x7F6C 0x7FA6 0x7FA5 0x7FA7 0x7FDB 0x7FDC 0x8021 \ + 0x8164 0x8160 0x8177 0x815C 0x8169 0x815B 0x8162 0x8172 \ + 0x6721 0x815E 0x8176 0x8167 0x816F 0x8144 0x8161 0x821D \ + 0x8249 0x8244 0x8240 0x8242 0x8245 0x84F1 0x843F 0x8456 \ + 0x8476 0x8479 0x848F 0x848D 0x8465 0x8451 0x8440 0x8486 \ + 0x8467 0x8430 0x844D 0x847D 0x845A 0x8459 0x8474 0x8473 \ + 0x845D 0x8507 0x845E 0x8437 0x843A 0x8434 0x847A 0x8443 \ + 0x8478 0x8432 0x8445 0x8429 0x83D9 0x844B 0x842F 0x8442 \ + 0x842D 0x845F 0x8470 0x8439 0x844E 0x844C 0x8452 0x846F \ + 0x84C5 0x848E 0x843B 0x8447 0x8436 0x8433 0x8468 0x847E \ + 0x8444 0x842B 0x8460 0x8454 0x846E 0x8450 0x870B 0x8704 \ + 0x86F7 0x870C 0x86FA 0x86D6 0x86F5 0x874D 0x86F8 0x870E \ + 0x8709 0x8701 0x86F6 0x870D 0x8705 0x88D6 0x88CB 0x88CD \ + 0x88CE 0x88DE 0x88DB 0x88DA 0x88CC 0x88D0 0x8985 0x899B \ + 0x89DF 0x89E5 0x89E4 0x89E1 0x89E0 0x89E2 0x89DC 0x89E6 \ + 0x8A76 0x8A86 0x8A7F 0x8A61 0x8A3F 0x8A77 0x8A82 0x8A84 \ + 0x8A75 0x8A83 0x8A81 0x8A74 0x8A7A 0x8C3C 0x8C4B 0x8C4A \ + 0x8C65 0x8C64 0x8C66 0x8C86 0x8C84 0x8C85 0x8CCC 0x8D68 \ + 0x8D69 0x8D91 0x8D8C 0x8D8E 0x8D8F 0x8D8D 0x8D93 0x8D94 \ + 0x8D90 0x8D92 0x8DF0 0x8DE0 0x8DEC 0x8DF1 0x8DEE 0x8DD0 \ + 0x8DE9 0x8DE3 0x8DE2 0x8DE7 0x8DF2 0x8DEB 0x8DF4 0x8F06 \ + 0x8EFF 0x8F01 0x8F00 0x8F05 0x8F07 0x8F08 0x8F02 0x8F0B \ + 0x9052 0x903F 0x9044 0x9049 0x903D 0x9110 0x910D 0x910F \ + 0x9111 0x9116 0x9114 0x910B 0x910E 0x916E 0x916F 0x9248 \ + 0x9252 0x9230 0x923A 0x9266 0x9233 0x9265 0x925E 0x9283 \ + 0x922E 0x924A 0x9246 0x926D 0x926C 0x924F 0x9260 0x9267 +40 0x926F 0x9236 0x9261 0x9270 0x9231 0x9254 0x9263 0x9250 \ + 0x9272 0x924E 0x9253 0x924C 0x9256 0x9232 0x959F 0x959C \ + 0x959E 0x959B 0x9692 0x9693 0x9691 0x9697 0x96CE 0x96FA \ + 0x96FD 0x96F8 0x96F5 0x9773 0x9777 0x9778 0x9772 0x980F \ + 0x980D 0x980E 0x98AC 0x98F6 0x98F9 0x99AF 0x99B2 0x99B0 \ + 0x99B5 0x9AAD 0x9AAB 0x9B5B 0x9CEA 0x9CED 0x9CE7 0x9E80 \ + 0x9EFD 0x50E6 0x50D4 0x50D7 0x50E8 0x50F3 0x50DB 0x50EA \ + 0x50DD 0x50E4 0x50D3 0x50EC 0x50F0 0x50EF 0x50E3 0x50E0 \ + 0x51D8 0x5280 0x5281 0x52E9 0x52EB 0x5330 0x53AC 0x5627 \ + 0x5615 0x560C 0x5612 0x55FC 0x560F 0x561C 0x5601 0x5613 \ + 0x5602 0x55FA 0x561D 0x5604 0x55FF 0x55F9 0x5889 0x587C \ + 0x5890 0x5898 0x5886 0x5881 0x587F 0x5874 0x588B 0x587A \ + 0x5887 0x5891 0x588E 0x5876 0x5882 0x5888 0x587B 0x5894 \ + 0x588F 0x58FE 0x596B 0x5ADC 0x5AEE 0x5AE5 0x5AD5 0x5AEA \ + 0x5ADA 0x5AED 0x5AEB 0x5AF3 0x5AE2 0x5AE0 0x5ADB 0x5AEC \ + 0x5ADE 0x5ADD 0x5AD9 0x5AE8 0x5ADF 0x5B77 0x5BE0 0x5BE3 \ + 0x5C63 0x5D82 0x5D80 0x5D7D 0x5D86 0x5D7A 0x5D81 0x5D77 \ + 0x5D8A 0x5D89 0x5D88 0x5D7E 0x5D7C 0x5D8D 0x5D79 0x5D7F \ + 0x5E58 0x5E59 0x5E53 0x5ED8 0x5ED1 0x5ED7 0x5ECE 0x5EDC \ + 0x5ED5 0x5ED9 0x5ED2 0x5ED4 0x5F44 0x5F43 0x5F6F 0x5FB6 \ + 0x612C 0x6128 0x6141 0x615E 0x6171 0x6173 0x6152 0x6153 \ + 0x6172 0x616C 0x6180 0x6174 0x6154 0x617A 0x615B 0x6165 \ + 0x613B 0x616A 0x6161 0x6156 0x6229 0x6227 0x622B 0x642B \ + 0x644D 0x645B 0x645D 0x6474 0x6476 0x6472 0x6473 0x647D \ + 0x6475 0x6466 0x64A6 0x644E 0x6482 0x645E 0x645C 0x644B \ + 0x6453 0x6460 0x6450 0x647F 0x643F 0x646C 0x646B 0x6459 \ + 0x6465 0x6477 0x6573 0x65A0 0x66A1 0x66A0 0x669F 0x6705 \ + 0x6704 0x6722 0x69B1 0x69B6 0x69C9 0x69A0 0x69CE 0x6996 \ + 0x69B0 0x69AC 0x69BC 0x6991 0x6999 0x698E 0x69A7 0x698D \ + 0x69A9 0x69BE 0x69AF 0x69BF 0x69C4 0x69BD 0x69A4 0x69D4 \ + 0x69B9 0x69CA 0x699A 0x69CF 0x69B3 0x6993 0x69AA 0x69A1 \ + 0x699E 0x69D9 0x6997 0x6990 0x69C2 0x69B5 0x69A5 0x69C6 +41 0x6B4A 0x6B4D 0x6B4B 0x6B9E 0x6B9F 0x6BA0 0x6BC3 0x6BC4 \ + 0x6BFE 0x6ECE 0x6EF5 0x6EF1 0x6F03 0x6F25 0x6EF8 0x6F37 \ + 0x6EFB 0x6F2E 0x6F09 0x6F4E 0x6F19 0x6F1A 0x6F27 0x6F18 \ + 0x6F3B 0x6F12 0x6EED 0x6F0A 0x6F36 0x6F73 0x6EF9 0x6EEE \ + 0x6F2D 0x6F40 0x6F30 0x6F3C 0x6F35 0x6EEB 0x6F07 0x6F0E \ + 0x6F43 0x6F05 0x6EFD 0x6EF6 0x6F39 0x6F1C 0x6EFC 0x6F3A \ + 0x6F1F 0x6F0D 0x6F1E 0x6F08 0x6F21 0x7187 0x7190 0x7189 \ + 0x7180 0x7185 0x7182 0x718F 0x717B 0x7186 0x7181 0x7197 \ + 0x7244 0x7253 0x7297 0x7295 0x7293 0x7343 0x734D 0x7351 \ + 0x734C 0x7462 0x7473 0x7471 0x7475 0x7472 0x7467 0x746E \ + 0x7500 0x7502 0x7503 0x757D 0x7590 0x7616 0x7608 0x760C \ + 0x7615 0x7611 0x760A 0x7614 0x76B8 0x7781 0x777C 0x7785 \ + 0x7782 0x776E 0x7780 0x776F 0x777E 0x7783 0x78B2 0x78AA \ + 0x78B4 0x78AD 0x78A8 0x787E 0x78AB 0x789E 0x78A5 0x78A0 \ + 0x78AC 0x78A2 0x78A4 0x7998 0x798A 0x798B 0x7996 0x7995 \ + 0x7994 0x7993 0x7997 0x7988 0x7992 0x7990 0x7A2B 0x7A4A \ + 0x7A30 0x7A2F 0x7A28 0x7A26 0x7AA8 0x7AAB 0x7AAC 0x7AEE \ + 0x7B88 0x7B9C 0x7B8A 0x7B91 0x7B90 0x7B96 0x7B8D 0x7B8C \ + 0x7B9B 0x7B8E 0x7B85 0x7B98 0x5284 0x7B99 0x7BA4 0x7B82 \ + 0x7CBB 0x7CBF 0x7CBC 0x7CBA 0x7DA7 0x7DB7 0x7DC2 0x7DA3 \ + 0x7DAA 0x7DC1 0x7DC0 0x7DC5 0x7D9D 0x7DCE 0x7DC4 0x7DC6 \ + 0x7DCB 0x7DCC 0x7DAF 0x7DB9 0x7D96 0x7DBC 0x7D9F 0x7DA6 \ + 0x7DAE 0x7DA9 0x7DA1 0x7DC9 0x7F73 0x7FE2 0x7FE3 0x7FE5 \ + 0x7FDE 0x8024 0x805D 0x805C 0x8189 0x8186 0x8183 0x8187 \ + 0x818D 0x818C 0x818B 0x8215 0x8497 0x84A4 0x84A1 0x849F \ + 0x84BA 0x84CE 0x84C2 0x84AC 0x84AE 0x84AB 0x84B9 0x84B4 \ + 0x84C1 0x84CD 0x84AA 0x849A 0x84B1 0x84D0 0x849D 0x84A7 \ + 0x84BB 0x84A2 0x8494 0x84C7 0x84CC 0x849B 0x84A9 0x84AF \ + 0x84A8 0x84D6 0x8498 0x84B6 0x84CF 0x84A0 0x84D7 0x84D4 \ + 0x84D2 0x84DB 0x84B0 0x8491 0x8661 0x8733 0x8723 0x8728 \ + 0x876B 0x8740 0x872E 0x871E 0x8721 0x8719 0x871B 0x8743 \ + 0x872C 0x8741 0x873E 0x8746 0x8720 0x8732 0x872A 0x872D +42 0x873C 0x8712 0x873A 0x8731 0x8735 0x8742 0x8726 0x8727 \ + 0x8738 0x8724 0x871A 0x8730 0x8711 0x88F7 0x88E7 0x88F1 \ + 0x88F2 0x88FA 0x88FE 0x88EE 0x88FC 0x88F6 0x88FB 0x88F0 \ + 0x88EC 0x88EB 0x899D 0x89A1 0x899F 0x899E 0x89E9 0x89EB \ + 0x89E8 0x8AAB 0x8A99 0x8A8B 0x8A92 0x8A8F 0x8A96 0x8C3D \ + 0x8C68 0x8C69 0x8CD5 0x8CCF 0x8CD7 0x8D96 0x8E09 0x8E02 \ + 0x8DFF 0x8E0D 0x8DFD 0x8E0A 0x8E03 0x8E07 0x8E06 0x8E05 \ + 0x8DFE 0x8E00 0x8E04 0x8F10 0x8F11 0x8F0E 0x8F0D 0x9123 \ + 0x911C 0x9120 0x9122 0x911F 0x911D 0x911A 0x9124 0x9121 \ + 0x911B 0x917A 0x9172 0x9179 0x9173 0x92A5 0x92A4 0x9276 \ + 0x929B 0x927A 0x92A0 0x9294 0x92AA 0x928D 0x92A6 0x929A \ + 0x92AB 0x9279 0x9297 0x927F 0x92A3 0x92EE 0x928E 0x9282 \ + 0x9295 0x92A2 0x927D 0x9288 0x92A1 0x928A 0x9286 0x928C \ + 0x9299 0x92A7 0x927E 0x9287 0x92A9 0x929D 0x928B 0x922D \ + 0x969E 0x96A1 0x96FF 0x9758 0x977D 0x977A 0x977E 0x9783 \ + 0x9780 0x9782 0x977B 0x9784 0x9781 0x977F 0x97CE 0x97CD \ + 0x9816 0x98AD 0x98AE 0x9902 0x9900 0x9907 0x999D 0x999C \ + 0x99C3 0x99B9 0x99BB 0x99BA 0x99C2 0x99BD 0x99C7 0x9AB1 \ + 0x9AE3 0x9AE7 0x9B3E 0x9B3F 0x9B60 0x9B61 0x9B5F 0x9CF1 \ + 0x9CF2 0x9CF5 0x9EA7 0x50FF 0x5103 0x5130 0x50F8 0x5106 \ + 0x5107 0x50F6 0x50FE 0x510B 0x510C 0x50FD 0x510A 0x528B \ + 0x528C 0x52F1 0x52EF 0x5648 0x5642 0x564C 0x5635 0x5641 \ + 0x564A 0x5649 0x5646 0x5658 0x565A 0x5640 0x5633 0x563D \ + 0x562C 0x563E 0x5638 0x562A 0x563A 0x571A 0x58AB 0x589D \ + 0x58B1 0x58A0 0x58A3 0x58AF 0x58AC 0x58A5 0x58A1 0x58FF \ + 0x5AFF 0x5AF4 0x5AFD 0x5AF7 0x5AF6 0x5B03 0x5AF8 0x5B02 \ + 0x5AF9 0x5B01 0x5B07 0x5B05 0x5B0F 0x5C67 0x5D99 0x5D97 \ + 0x5D9F 0x5D92 0x5DA2 0x5D93 0x5D95 0x5DA0 0x5D9C 0x5DA1 \ + 0x5D9A 0x5D9E 0x5E69 0x5E5D 0x5E60 0x5E5C 0x7DF3 0x5EDB \ + 0x5EDE 0x5EE1 0x5F49 0x5FB2 0x618B 0x6183 0x6179 0x61B1 \ + 0x61B0 0x61A2 0x6189 0x619B 0x6193 0x61AF 0x61AD 0x619F \ + 0x6192 0x61AA 0x61A1 0x618D 0x6166 0x61B3 0x622D 0x646E +43 0x6470 0x6496 0x64A0 0x6485 0x6497 0x649C 0x648F 0x648B \ + 0x648A 0x648C 0x64A3 0x649F 0x6468 0x64B1 0x6498 0x6576 \ + 0x657A 0x6579 0x657B 0x65B2 0x65B3 0x66B5 0x66B0 0x66A9 \ + 0x66B2 0x66B7 0x66AA 0x66AF 0x6A00 0x6A06 0x6A17 0x69E5 \ + 0x69F8 0x6A15 0x69F1 0x69E4 0x6A20 0x69FF 0x69EC 0x69E2 \ + 0x6A1B 0x6A1D 0x69FE 0x6A27 0x69F2 0x69EE 0x6A14 0x69F7 \ + 0x69E7 0x6A40 0x6A08 0x69E6 0x69FB 0x6A0D 0x69FC 0x69EB \ + 0x6A09 0x6A04 0x6A18 0x6A25 0x6A0F 0x69F6 0x6A26 0x6A07 \ + 0x69F4 0x6A16 0x6B51 0x6BA5 0x6BA3 0x6BA2 0x6BA6 0x6C01 \ + 0x6C00 0x6BFF 0x6C02 0x6F41 0x6F26 0x6F7E 0x6F87 0x6FC6 \ + 0x6F92 0x6F8D 0x6F89 0x6F8C 0x6F62 0x6F4F 0x6F85 0x6F5A \ + 0x6F96 0x6F76 0x6F6C 0x6F82 0x6F55 0x6F72 0x6F52 0x6F50 \ + 0x6F57 0x6F94 0x6F93 0x6F5D 0x6F00 0x6F61 0x6F6B 0x6F7D \ + 0x6F67 0x6F90 0x6F53 0x6F8B 0x6F69 0x6F7F 0x6F95 0x6F63 \ + 0x6F77 0x6F6A 0x6F7B 0x71B2 0x71AF 0x719B 0x71B0 0x71A0 \ + 0x719A 0x71A9 0x71B5 0x719D 0x71A5 0x719E 0x71A4 0x71A1 \ + 0x71AA 0x719C 0x71A7 0x71B3 0x7298 0x729A 0x7358 0x7352 \ + 0x735E 0x735F 0x7360 0x735D 0x735B 0x7361 0x735A 0x7359 \ + 0x7362 0x7487 0x7489 0x748A 0x7486 0x7481 0x747D 0x7485 \ + 0x7488 0x747C 0x7479 0x7508 0x7507 0x757E 0x7625 0x761E \ + 0x7619 0x761D 0x761C 0x7623 0x761A 0x7628 0x761B 0x769C \ + 0x769D 0x769E 0x769B 0x778D 0x778F 0x7789 0x7788 0x78CD \ + 0x78BB 0x78CF 0x78CC 0x78D1 0x78CE 0x78D4 0x78C8 0x78C3 \ + 0x78C4 0x78C9 0x799A 0x79A1 0x79A0 0x799C 0x79A2 0x799B \ + 0x6B76 0x7A39 0x7AB2 0x7AB4 0x7AB3 0x7BB7 0x7BCB 0x7BBE \ + 0x7BAC 0x7BCE 0x7BAF 0x7BB9 0x7BCA 0x7BB5 0x7CC5 0x7CC8 \ + 0x7CCC 0x7CCB 0x7DF7 0x7DDB 0x7DEA 0x7DE7 0x7DD7 0x7DE1 \ + 0x7E03 0x7DFA 0x7DE6 0x7DF6 0x7DF1 0x7DF0 0x7DEE 0x7DDF \ + 0x7F76 0x7FAC 0x7FB0 0x7FAD 0x7FED 0x7FEB 0x7FEA 0x7FEC \ + 0x7FE6 0x7FE8 0x8064 0x8067 0x81A3 0x819F 0x819E 0x8195 \ + 0x81A2 0x8199 0x8197 0x8216 0x824F 0x8253 0x8252 0x8250 \ + 0x824E 0x8251 0x8524 0x853B 0x850F 0x8500 0x8529 0x850E +44 0x8509 0x850D 0x851F 0x850A 0x8527 0x851C 0x84FB 0x852B \ + 0x84FA 0x8508 0x850C 0x84F4 0x852A 0x84F2 0x8515 0x84F7 \ + 0x84EB 0x84F3 0x84FC 0x8512 0x84EA 0x84E9 0x8516 0x84FE \ + 0x8528 0x851D 0x852E 0x8502 0x84FD 0x851E 0x84F6 0x8531 \ + 0x8526 0x84E7 0x84E8 0x84F0 0x84EF 0x84F9 0x8518 0x8520 \ + 0x8530 0x850B 0x8519 0x852F 0x8662 0x8756 0x8763 0x8764 \ + 0x8777 0x87E1 0x8773 0x8758 0x8754 0x875B 0x8752 0x8761 \ + 0x875A 0x8751 0x875E 0x876D 0x876A 0x8750 0x874E 0x875F \ + 0x875D 0x876F 0x876C 0x877A 0x876E 0x875C 0x8765 0x874F \ + 0x877B 0x8775 0x8762 0x8767 0x8769 0x885A 0x8905 0x890C \ + 0x8914 0x890B 0x8917 0x8918 0x8919 0x8906 0x8916 0x8911 \ + 0x890E 0x8909 0x89A2 0x89A4 0x89A3 0x89ED 0x89F0 0x89EC \ + 0x8ACF 0x8AC6 0x8AB8 0x8AD3 0x8AD1 0x8AD4 0x8AD5 0x8ABB \ + 0x8AD7 0x8ABE 0x8AC0 0x8AC5 0x8AD8 0x8AC3 0x8ABA 0x8ABD \ + 0x8AD9 0x8C3E 0x8C4D 0x8C8F 0x8CE5 0x8CDF 0x8CD9 0x8CE8 \ + 0x8CDA 0x8CDD 0x8CE7 0x8DA0 0x8D9C 0x8DA1 0x8D9B 0x8E20 \ + 0x8E23 0x8E25 0x8E24 0x8E2E 0x8E15 0x8E1B 0x8E16 0x8E11 \ + 0x8E19 0x8E26 0x8E27 0x8E14 0x8E12 0x8E18 0x8E13 0x8E1C \ + 0x8E17 0x8E1A 0x8F2C 0x8F24 0x8F18 0x8F1A 0x8F20 0x8F23 \ + 0x8F16 0x8F17 0x9073 0x9070 0x906F 0x9067 0x906B 0x912F \ + 0x912B 0x9129 0x912A 0x9132 0x9126 0x912E 0x9185 0x9186 \ + 0x918A 0x9181 0x9182 0x9184 0x9180 0x92D0 0x92C3 0x92C4 \ + 0x92C0 0x92D9 0x92B6 0x92CF 0x92F1 0x92DF 0x92D8 0x92E9 \ + 0x92D7 0x92DD 0x92CC 0x92EF 0x92C2 0x92E8 0x92CA 0x92C8 \ + 0x92CE 0x92E6 0x92CD 0x92D5 0x92C9 0x92E0 0x92DE 0x92E7 \ + 0x92D1 0x92D3 0x92B5 0x92E1 0x92C6 0x92B4 0x957C 0x95AC \ + 0x95AB 0x95AE 0x95B0 0x96A4 0x96A2 0x96D3 0x9705 0x9708 \ + 0x9702 0x975A 0x978A 0x978E 0x9788 0x97D0 0x97CF 0x981E \ + 0x981D 0x9826 0x9829 0x9828 0x9820 0x981B 0x9827 0x98B2 \ + 0x9908 0x98FA 0x9911 0x9914 0x9916 0x9917 0x9915 0x99DC \ + 0x99CD 0x99CF 0x99D3 0x99D4 0x99CE 0x99C9 0x99D6 0x99D8 \ + 0x99CB 0x99D7 0x99CC 0x9AB3 0x9AEC 0x9AEB 0x9AF3 0x9AF2 +45 0x9AF1 0x9B46 0x9B43 0x9B67 0x9B74 0x9B71 0x9B66 0x9B76 \ + 0x9B75 0x9B70 0x9B68 0x9B64 0x9B6C 0x9CFC 0x9CFA 0x9CFD \ + 0x9CFF 0x9CF7 0x9D07 0x9D00 0x9CF9 0x9CFB 0x9D08 0x9D05 \ + 0x9D04 0x9E83 0x9ED3 0x9F0F 0x9F10 0x511C 0x5113 0x5117 \ + 0x511A 0x5111 0x51DE 0x5334 0x53E1 0x5670 0x5660 0x566E \ + 0x5673 0x5666 0x5663 0x566D 0x5672 0x565E 0x5677 0x571C \ + 0x571B 0x58C8 0x58BD 0x58C9 0x58BF 0x58BA 0x58C2 0x58BC \ + 0x58C6 0x5B17 0x5B19 0x5B1B 0x5B21 0x5B14 0x5B13 0x5B10 \ + 0x5B16 0x5B28 0x5B1A 0x5B20 0x5B1E 0x5BEF 0x5DAC 0x5DB1 \ + 0x5DA9 0x5DA7 0x5DB5 0x5DB0 0x5DAE 0x5DAA 0x5DA8 0x5DB2 \ + 0x5DAD 0x5DAF 0x5DB4 0x5E67 0x5E68 0x5E66 0x5E6F 0x5EE9 \ + 0x5EE7 0x5EE6 0x5EE8 0x5EE5 0x5F4B 0x5FBC 0x619D 0x61A8 \ + 0x6196 0x61C5 0x61B4 0x61C6 0x61C1 0x61CC 0x61BA 0x61BF \ + 0x61B8 0x618C 0x64D7 0x64D6 0x64D0 0x64CF 0x64C9 0x64BD \ + 0x6489 0x64C3 0x64DB 0x64F3 0x64D9 0x6533 0x657F 0x657C \ + 0x65A2 0x66C8 0x66BE 0x66C0 0x66CA 0x66CB 0x66CF 0x66BD \ + 0x66BB 0x66BA 0x66CC 0x6723 0x6A34 0x6A66 0x6A49 0x6A67 \ + 0x6A32 0x6A68 0x6A3E 0x6A5D 0x6A6D 0x6A76 0x6A5B 0x6A51 \ + 0x6A28 0x6A5A 0x6A3B 0x6A3F 0x6A41 0x6A6A 0x6A64 0x6A50 \ + 0x6A4F 0x6A54 0x6A6F 0x6A69 0x6A60 0x6A3C 0x6A5E 0x6A56 \ + 0x6A55 0x6A4D 0x6A4E 0x6A46 0x6B55 0x6B54 0x6B56 0x6BA7 \ + 0x6BAA 0x6BAB 0x6BC8 0x6BC7 0x6C04 0x6C03 0x6C06 0x6FAD \ + 0x6FCB 0x6FA3 0x6FC7 0x6FBC 0x6FCE 0x6FC8 0x6F5E 0x6FC4 \ + 0x6FBD 0x6F9E 0x6FCA 0x6FA8 0x7004 0x6FA5 0x6FAE 0x6FBA \ + 0x6FAC 0x6FAA 0x6FCF 0x6FBF 0x6FB8 0x6FA2 0x6FC9 0x6FAB \ + 0x6FCD 0x6FAF 0x6FB2 0x6FB0 0x71C5 0x71C2 0x71BF 0x71B8 \ + 0x71D6 0x71C0 0x71C1 0x71CB 0x71D4 0x71CA 0x71C7 0x71CF \ + 0x71BD 0x71D8 0x71BC 0x71C6 0x71DA 0x71DB 0x729D 0x729E \ + 0x7369 0x7366 0x7367 0x736C 0x7365 0x736B 0x736A 0x747F \ + 0x749A 0x74A0 0x7494 0x7492 0x7495 0x74A1 0x750B 0x7580 \ + 0x762F 0x762D 0x7631 0x763D 0x7633 0x763C 0x7635 0x7632 \ + 0x7630 0x76BB 0x76E6 0x779A 0x779D 0x77A1 0x779C 0x779B +46 0x77A2 0x77A3 0x7795 0x7799 0x7797 0x78DD 0x78E9 0x78E5 \ + 0x78EA 0x78DE 0x78E3 0x78DB 0x78E1 0x78E2 0x78ED 0x78DF \ + 0x78E0 0x79A4 0x7A44 0x7A48 0x7A47 0x7AB6 0x7AB8 0x7AB5 \ + 0x7AB1 0x7AB7 0x7BDE 0x7BE3 0x7BE7 0x7BDD 0x7BD5 0x7BE5 \ + 0x7BDA 0x7BE8 0x7BF9 0x7BD4 0x7BEA 0x7BE2 0x7BDC 0x7BEB \ + 0x7BD8 0x7BDF 0x7CD2 0x7CD4 0x7CD7 0x7CD0 0x7CD1 0x7E12 \ + 0x7E21 0x7E17 0x7E0C 0x7E1F 0x7E20 0x7E13 0x7E0E 0x7E1C \ + 0x7E15 0x7E1A 0x7E22 0x7E0B 0x7E0F 0x7E16 0x7E0D 0x7E14 \ + 0x7E25 0x7E24 0x7F43 0x7F7B 0x7F7C 0x7F7A 0x7FB1 0x7FEF \ + 0x802A 0x8029 0x806C 0x81B1 0x81A6 0x81AE 0x81B9 0x81B5 \ + 0x81AB 0x81B0 0x81AC 0x81B4 0x81B2 0x81B7 0x81A7 0x81F2 \ + 0x8255 0x8256 0x8257 0x8556 0x8545 0x856B 0x854D 0x8553 \ + 0x8561 0x8558 0x8540 0x8546 0x8564 0x8541 0x8562 0x8544 \ + 0x8551 0x8547 0x8563 0x853E 0x855B 0x8571 0x854E 0x856E \ + 0x8575 0x8555 0x8567 0x8560 0x858C 0x8566 0x855D 0x8554 \ + 0x8565 0x856C 0x8663 0x8665 0x8664 0x879B 0x878F 0x8797 \ + 0x8793 0x8792 0x8788 0x8781 0x8796 0x8798 0x8779 0x8787 \ + 0x87A3 0x8785 0x8790 0x8791 0x879D 0x8784 0x8794 0x879C \ + 0x879A 0x8789 0x891E 0x8926 0x8930 0x892D 0x892E 0x8927 \ + 0x8931 0x8922 0x8929 0x8923 0x892F 0x892C 0x891F 0x89F1 \ + 0x8AE0 0x8AE2 0x8AF2 0x8AF4 0x8AF5 0x8ADD 0x8B14 0x8AE4 \ + 0x8ADF 0x8AF0 0x8AC8 0x8ADE 0x8AE1 0x8AE8 0x8AFF 0x8AEF \ + 0x8AFB 0x8C91 0x8C92 0x8C90 0x8CF5 0x8CEE 0x8CF1 0x8CF0 \ + 0x8CF3 0x8D6C 0x8D6E 0x8DA5 0x8DA7 0x8E33 0x8E3E 0x8E38 \ + 0x8E40 0x8E45 0x8E36 0x8E3C 0x8E3D 0x8E41 0x8E30 0x8E3F \ + 0x8EBD 0x8F36 0x8F2E 0x8F35 0x8F32 0x8F39 0x8F37 0x8F34 \ + 0x9076 0x9079 0x907B 0x9086 0x90FA 0x9133 0x9135 0x9136 \ + 0x9193 0x9190 0x9191 0x918D 0x918F 0x9327 0x931E 0x9308 \ + 0x931F 0x9306 0x930F 0x937A 0x9338 0x933C 0x931B 0x9323 \ + 0x9312 0x9301 0x9346 0x932D 0x930E 0x930D 0x92CB 0x931D \ + 0x92FA 0x9325 0x9313 0x92F9 0x92F7 0x9334 0x9302 0x9324 \ + 0x92FF 0x9329 0x9339 0x9335 0x932A 0x9314 0x930C 0x930B +47 0x92FE 0x9309 0x9300 0x92FB 0x9316 0x95BC 0x95CD 0x95BE \ + 0x95B9 0x95BA 0x95B6 0x95BF 0x95B5 0x95BD 0x96A9 0x96D4 \ + 0x970B 0x9712 0x9710 0x9799 0x9797 0x9794 0x97F0 0x97F8 \ + 0x9835 0x982F 0x9832 0x9924 0x991F 0x9927 0x9929 0x999E \ + 0x99EE 0x99EC 0x99E5 0x99E4 0x99F0 0x99E3 0x99EA 0x99E9 \ + 0x99E7 0x9AB9 0x9ABF 0x9AB4 0x9ABB 0x9AF6 0x9AFA 0x9AF9 \ + 0x9AF7 0x9B33 0x9B80 0x9B85 0x9B87 0x9B7C 0x9B7E 0x9B7B \ + 0x9B82 0x9B93 0x9B92 0x9B90 0x9B7A 0x9B95 0x9B7D 0x9B88 \ + 0x9D25 0x9D17 0x9D20 0x9D1E 0x9D14 0x9D29 0x9D1D 0x9D18 \ + 0x9D22 0x9D10 0x9D19 0x9D1F 0x9E88 0x9E86 0x9E87 0x9EAE \ + 0x9EAD 0x9ED5 0x9ED6 0x9EFA 0x9F12 0x9F3D 0x5126 0x5125 \ + 0x5122 0x5124 0x5120 0x5129 0x52F4 0x5693 0x568C 0x568D \ + 0x5686 0x5684 0x5683 0x567E 0x5682 0x567F 0x5681 0x58D6 \ + 0x58D4 0x58CF 0x58D2 0x5B2D 0x5B25 0x5B32 0x5B23 0x5B2C \ + 0x5B27 0x5B26 0x5B2F 0x5B2E 0x5B7B 0x5BF1 0x5BF2 0x5DB7 \ + 0x5E6C 0x5E6A 0x5FBE 0x5FBB 0x61C3 0x61B5 0x61BC 0x61E7 \ + 0x61E0 0x61E5 0x61E4 0x61E8 0x61DE 0x64EF 0x64E9 0x64E3 \ + 0x64EB 0x64E4 0x64E8 0x6581 0x6580 0x65B6 0x65DA 0x66D2 \ + 0x6A8D 0x6A96 0x6A81 0x6AA5 0x6A89 0x6A9F 0x6A9B 0x6AA1 \ + 0x6A9E 0x6A87 0x6A93 0x6A8E 0x6A95 0x6A83 0x6AA8 0x6AA4 \ + 0x6A91 0x6A7F 0x6AA6 0x6A9A 0x6A85 0x6A8C 0x6A92 0x6B5B \ + 0x6BAD 0x6C09 0x6FCC 0x6FA9 0x6FF4 0x6FD4 0x6FE3 0x6FDC \ + 0x6FED 0x6FE7 0x6FE6 0x6FDE 0x6FF2 0x6FDD 0x6FE2 0x6FE8 \ + 0x71E1 0x71F1 0x71E8 0x71F2 0x71E4 0x71F0 0x71E2 0x7373 \ + 0x736E 0x736F 0x7497 0x74B2 0x74AB 0x7490 0x74AA 0x74AD \ + 0x74B1 0x74A5 0x74AF 0x7510 0x7511 0x7512 0x750F 0x7584 \ + 0x7643 0x7648 0x7649 0x7647 0x76A4 0x76E9 0x77B5 0x77AB \ + 0x77B2 0x77B7 0x77B6 0x77B4 0x77B1 0x77A8 0x77F0 0x78F3 \ + 0x78FD 0x7902 0x78FB 0x78FC 0x78F2 0x7905 0x78F9 0x78FE \ + 0x7904 0x79AB 0x79A8 0x7A5C 0x7A5B 0x7A56 0x7A58 0x7A54 \ + 0x7A5A 0x7ABE 0x7AC0 0x7AC1 0x7C05 0x7C0F 0x7BF2 0x7C00 \ + 0x7BFF 0x7BFB 0x7C0E 0x7BF4 0x7C0B 0x7BF3 0x7C02 0x7C09 +48 0x7C03 0x7C01 0x7BF8 0x7BFD 0x7C06 0x7BF0 0x7BF1 0x7C10 \ + 0x7C0A 0x7CE8 0x7E2D 0x7E3C 0x7E42 0x7E33 0x9848 0x7E38 \ + 0x7E2A 0x7E49 0x7E40 0x7E47 0x7E29 0x7E4C 0x7E30 0x7E3B \ + 0x7E36 0x7E44 0x7E3A 0x7F45 0x7F7F 0x7F7E 0x7F7D 0x7FF4 \ + 0x7FF2 0x802C 0x81BB 0x81C4 0x81CC 0x81CA 0x81C5 0x81C7 \ + 0x81BC 0x81E9 0x825B 0x825A 0x825C 0x8583 0x8580 0x858F \ + 0x85A7 0x8595 0x85A0 0x858B 0x85A3 0x857B 0x85A4 0x859A \ + 0x859E 0x8577 0x857C 0x8589 0x85A1 0x857A 0x8578 0x8557 \ + 0x858E 0x8596 0x8586 0x858D 0x8599 0x859D 0x8581 0x85A2 \ + 0x8582 0x8588 0x8585 0x8579 0x8576 0x8598 0x8590 0x859F \ + 0x8668 0x87BE 0x87AA 0x87AD 0x87C5 0x87B0 0x87AC 0x87B9 \ + 0x87B5 0x87BC 0x87AE 0x87C9 0x87C3 0x87C2 0x87CC 0x87B7 \ + 0x87AF 0x87C4 0x87CA 0x87B4 0x87B6 0x87BF 0x87B8 0x87BD \ + 0x87DE 0x87B2 0x8935 0x8933 0x893C 0x893E 0x8941 0x8952 \ + 0x8937 0x8942 0x89AD 0x89AF 0x89AE 0x89F2 0x89F3 0x8B1E \ + 0x8B18 0x8B16 0x8B11 0x8B05 0x8B0B 0x8B22 0x8B0F 0x8B12 \ + 0x8B15 0x8B07 0x8B0D 0x8B08 0x8B06 0x8B1C 0x8B13 0x8B1A \ + 0x8C4F 0x8C70 0x8C72 0x8C71 0x8C6F 0x8C95 0x8C94 0x8CF9 \ + 0x8D6F 0x8E4E 0x8E4D 0x8E53 0x8E50 0x8E4C 0x8E47 0x8F43 \ + 0x8F40 0x9085 0x907E 0x9138 0x919A 0x91A2 0x919B 0x9199 \ + 0x919F 0x91A1 0x919D 0x91A0 0x93A1 0x9383 0x93AF 0x9364 \ + 0x9356 0x9347 0x937C 0x9358 0x935C 0x9376 0x9349 0x9350 \ + 0x9351 0x9360 0x936D 0x938F 0x934C 0x936A 0x9379 0x9357 \ + 0x9355 0x9352 0x934F 0x9371 0x9377 0x937B 0x9361 0x935E \ + 0x9363 0x9367 0x9380 0x934E 0x9359 0x95C7 0x95C0 0x95C9 \ + 0x95C3 0x95C5 0x95B7 0x96AE 0x96B0 0x96AC 0x9720 0x971F \ + 0x9718 0x971D 0x9719 0x979A 0x97A1 0x979C 0x979E 0x979D \ + 0x97D5 0x97D4 0x97F1 0x9841 0x9844 0x984A 0x9849 0x9845 \ + 0x9843 0x9925 0x992B 0x992C 0x992A 0x9933 0x9932 0x992F \ + 0x992D 0x9931 0x9930 0x9998 0x99A3 0x99A1 0x9A02 0x99FA \ + 0x99F4 0x99F7 0x99F9 0x99F8 0x99F6 0x99FB 0x99FD 0x99FE \ + 0x99FC 0x9A03 0x9ABE 0x9AFE 0x9AFD 0x9B01 0x9AFC 0x9B48 +49 0x9B9A 0x9BA8 0x9B9E 0x9B9B 0x9BA6 0x9BA1 0x9BA5 0x9BA4 \ + 0x9B86 0x9BA2 0x9BA0 0x9BAF 0x9D33 0x9D41 0x9D67 0x9D36 \ + 0x9D2E 0x9D2F 0x9D31 0x9D38 0x9D30 0x9D45 0x9D42 0x9D43 \ + 0x9D3E 0x9D37 0x9D40 0x9D3D 0x7FF5 0x9D2D 0x9E8A 0x9E89 \ + 0x9E8D 0x9EB0 0x9EC8 0x9EDA 0x9EFB 0x9EFF 0x9F24 0x9F23 \ + 0x9F22 0x9F54 0x9FA0 0x5131 0x512D 0x512E 0x5698 0x569C \ + 0x5697 0x569A 0x569D 0x5699 0x5970 0x5B3C 0x5C69 0x5C6A \ + 0x5DC0 0x5E6D 0x5E6E 0x61D8 0x61DF 0x61ED 0x61EE 0x61F1 \ + 0x61EA 0x61F0 0x61EB 0x61D6 0x61E9 0x64FF 0x6504 0x64FD \ + 0x64F8 0x6501 0x6503 0x64FC 0x6594 0x65DB 0x66DA 0x66DB \ + 0x66D8 0x6AC5 0x6AB9 0x6ABD 0x6AE1 0x6AC6 0x6ABA 0x6AB6 \ + 0x6AB7 0x6AC7 0x6AB4 0x6AAD 0x6B5E 0x6BC9 0x6C0B 0x7007 \ + 0x700C 0x700D 0x7001 0x7005 0x7014 0x700E 0x6FFF 0x7000 \ + 0x6FFB 0x7026 0x6FFC 0x6FF7 0x700A 0x7201 0x71FF 0x71F9 \ + 0x7203 0x71FD 0x7376 0x74B8 0x74C0 0x74B5 0x74C1 0x74BE \ + 0x74B6 0x74BB 0x74C2 0x7514 0x7513 0x765C 0x7664 0x7659 \ + 0x7650 0x7653 0x7657 0x765A 0x76A6 0x76BD 0x76EC 0x77C2 \ + 0x77BA 0x78FF 0x790C 0x7913 0x7914 0x7909 0x7910 0x7912 \ + 0x7911 0x79AD 0x79AC 0x7A5F 0x7C1C 0x7C29 0x7C19 0x7C20 \ + 0x7C1F 0x7C2D 0x7C1D 0x7C26 0x7C28 0x7C22 0x7C25 0x7C30 \ + 0x7E5C 0x7E50 0x7E56 0x7E63 0x7E58 0x7E62 0x7E5F 0x7E51 \ + 0x7E60 0x7E57 0x7E53 0x7FB5 0x7FB3 0x7FF7 0x7FF8 0x8075 \ + 0x81D1 0x81D2 0x81D0 0x825F 0x825E 0x85B4 0x85C6 0x85C0 \ + 0x85C3 0x85C2 0x85B3 0x85B5 0x85BD 0x85C7 0x85C4 0x85BF \ + 0x85CB 0x85CE 0x85C8 0x85C5 0x85B1 0x85B6 0x85D2 0x8624 \ + 0x85B8 0x85B7 0x85BE 0x8669 0x87E7 0x87E6 0x87E2 0x87DB \ + 0x87EB 0x87EA 0x87E5 0x87DF 0x87F3 0x87E4 0x87D4 0x87DC \ + 0x87D3 0x87ED 0x87D8 0x87E3 0x87A4 0x87D7 0x87D9 0x8801 \ + 0x87F4 0x87E8 0x87DD 0x8953 0x894B 0x894F 0x894C 0x8946 \ + 0x8950 0x8951 0x8949 0x8B2A 0x8B27 0x8B23 0x8B33 0x8B30 \ + 0x8B35 0x8B47 0x8B2F 0x8B3C 0x8B3E 0x8B31 0x8B25 0x8B37 \ + 0x8B26 0x8B36 0x8B2E 0x8B24 0x8B3B 0x8B3D 0x8B3A 0x8C42 +50 0x8C75 0x8C99 0x8C98 0x8C97 0x8CFE 0x8D04 0x8D02 0x8D00 \ + 0x8E5C 0x8E62 0x8E60 0x8E57 0x8E56 0x8E5E 0x8E65 0x8E67 \ + 0x8E5B 0x8E5A 0x8E61 0x8E5D 0x8E69 0x8E54 0x8F46 0x8F47 \ + 0x8F48 0x8F4B 0x9128 0x913A 0x913B 0x913E 0x91A8 0x91A5 \ + 0x91A7 0x91AF 0x91AA 0x93B5 0x938C 0x9392 0x93B7 0x939B \ + 0x939D 0x9389 0x93A7 0x938E 0x93AA 0x939E 0x93A6 0x9395 \ + 0x9388 0x9399 0x939F 0x938D 0x93B1 0x9391 0x93B2 0x93A4 \ + 0x93A8 0x93B4 0x93A3 0x93A5 0x95D2 0x95D3 0x95D1 0x96B3 \ + 0x96D7 0x96DA 0x5DC2 0x96DF 0x96D8 0x96DD 0x9723 0x9722 \ + 0x9725 0x97AC 0x97AE 0x97A8 0x97AB 0x97A4 0x97AA 0x97A2 \ + 0x97A5 0x97D7 0x97D9 0x97D6 0x97D8 0x97FA 0x9850 0x9851 \ + 0x9852 0x98B8 0x9941 0x993C 0x993A 0x9A0F 0x9A0B 0x9A09 \ + 0x9A0D 0x9A04 0x9A11 0x9A0A 0x9A05 0x9A07 0x9A06 0x9AC0 \ + 0x9ADC 0x9B08 0x9B04 0x9B05 0x9B29 0x9B35 0x9B4A 0x9B4C \ + 0x9B4B 0x9BC7 0x9BC6 0x9BC3 0x9BBF 0x9BC1 0x9BB5 0x9BB8 \ + 0x9BD3 0x9BB6 0x9BC4 0x9BB9 0x9BBD 0x9D5C 0x9D53 0x9D4F \ + 0x9D4A 0x9D5B 0x9D4B 0x9D59 0x9D56 0x9D4C 0x9D57 0x9D52 \ + 0x9D54 0x9D5F 0x9D58 0x9D5A 0x9E8E 0x9E8C 0x9EDF 0x9F01 \ + 0x9F00 0x9F16 0x9F25 0x9F2B 0x9F2A 0x9F29 0x9F28 0x9F4C \ + 0x9F55 0x5134 0x5135 0x5296 0x52F7 0x53B4 0x56AB 0x56AD \ + 0x56A6 0x56A7 0x56AA 0x56AC 0x58DA 0x58DD 0x58DB 0x5912 \ + 0x5B3D 0x5B3E 0x5B3F 0x5DC3 0x5E70 0x5FBF 0x61FB 0x6507 \ + 0x6510 0x650D 0x6509 0x650C 0x650E 0x6584 0x65DE 0x65DD \ + 0x66DE 0x6AE7 0x6AE0 0x6ACC 0x6AD1 0x6AD9 0x6ACB 0x6ADF \ + 0x6ADC 0x6AD0 0x6AEB 0x6ACF 0x6ACD 0x6ADE 0x6B60 0x6BB0 \ + 0x6C0C 0x7019 0x7027 0x7020 0x7016 0x702B 0x7021 0x7022 \ + 0x7023 0x7029 0x7017 0x7024 0x701C 0x702A 0x720C 0x720A \ + 0x7207 0x7202 0x7205 0x72A5 0x72A6 0x72A4 0x72A3 0x72A1 \ + 0x74CB 0x74C5 0x74B7 0x74C3 0x7516 0x7660 0x77C9 0x77CA \ + 0x77C4 0x77F1 0x791D 0x791B 0x7921 0x791C 0x7917 0x791E \ + 0x79B0 0x7A67 0x7A68 0x7C33 0x7C3C 0x7C39 0x7C2C 0x7C3B \ + 0x7CEC 0x7CEA 0x7E76 0x7E75 0x7E78 0x7E70 0x7E77 0x7E6F +51 0x7E7A 0x7E72 0x7E74 0x7E68 0x7F4B 0x7F4A 0x7F83 0x7F86 \ + 0x7FB7 0x7FFD 0x7FFE 0x8078 0x81D7 0x81D5 0x8264 0x8261 \ + 0x8263 0x85EB 0x85F1 0x85ED 0x85D9 0x85E1 0x85E8 0x85DA \ + 0x85D7 0x85EC 0x85F2 0x85F8 0x85D8 0x85DF 0x85E3 0x85DC \ + 0x85D1 0x85F0 0x85E6 0x85EF 0x85DE 0x85E2 0x8800 0x87FA \ + 0x8803 0x87F6 0x87F7 0x8809 0x880C 0x880B 0x8806 0x87FC \ + 0x8808 0x87FF 0x880A 0x8802 0x8962 0x895A 0x895B 0x8957 \ + 0x8961 0x895C 0x8958 0x895D 0x8959 0x8988 0x89B7 0x89B6 \ + 0x89F6 0x8B50 0x8B48 0x8B4A 0x8B40 0x8B53 0x8B56 0x8B54 \ + 0x8B4B 0x8B55 0x8B51 0x8B42 0x8B52 0x8B57 0x8C43 0x8C77 \ + 0x8C76 0x8C9A 0x8D06 0x8D07 0x8D09 0x8DAC 0x8DAA 0x8DAD \ + 0x8DAB 0x8E6D 0x8E78 0x8E73 0x8E6A 0x8E6F 0x8E7B 0x8EC2 \ + 0x8F52 0x8F51 0x8F4F 0x8F50 0x8F53 0x8FB4 0x9140 0x913F \ + 0x91B0 0x91AD 0x93DE 0x93C7 0x93CF 0x93C2 0x93DA 0x93D0 \ + 0x93F9 0x93EC 0x93CC 0x93D9 0x93A9 0x93E6 0x93CA 0x93D4 \ + 0x93EE 0x93E3 0x93D5 0x93C4 0x93CE 0x93C0 0x93D2 0x93E7 \ + 0x957D 0x95DA 0x95DB 0x96E1 0x9729 0x972B 0x972C 0x9728 \ + 0x9726 0x97B3 0x97B7 0x97B6 0x97DD 0x97DE 0x97DF 0x985C \ + 0x9859 0x985D 0x9857 0x98BF 0x98BD 0x98BB 0x98BE 0x9948 \ + 0x9947 0x9943 0x99A6 0x99A7 0x9A1A 0x9A15 0x9A25 0x9A1D \ + 0x9A24 0x9A1B 0x9A22 0x9A20 0x9A27 0x9A23 0x9A1E 0x9A1C \ + 0x9A14 0x9AC2 0x9B0B 0x9B0A 0x9B0E 0x9B0C 0x9B37 0x9BEA \ + 0x9BEB 0x9BE0 0x9BDE 0x9BE4 0x9BE6 0x9BE2 0x9BF0 0x9BD4 \ + 0x9BD7 0x9BEC 0x9BDC 0x9BD9 0x9BE5 0x9BD5 0x9BE1 0x9BDA \ + 0x9D77 0x9D81 0x9D8A 0x9D84 0x9D88 0x9D71 0x9D80 0x9D78 \ + 0x9D86 0x9D8B 0x9D8C 0x9D7D 0x9D6B 0x9D74 0x9D75 0x9D70 \ + 0x9D69 0x9D85 0x9D73 0x9D7B 0x9D82 0x9D6F 0x9D79 0x9D7F \ + 0x9D87 0x9D68 0x9E94 0x9E91 0x9EC0 0x9EFC 0x9F2D 0x9F40 \ + 0x9F41 0x9F4D 0x9F56 0x9F57 0x9F58 0x5337 0x56B2 0x56B5 \ + 0x56B3 0x58E3 0x5B45 0x5DC6 0x5DC7 0x5EEE 0x5EEF 0x5FC0 \ + 0x5FC1 0x61F9 0x6517 0x6516 0x6515 0x6513 0x65DF 0x66E8 \ + 0x66E3 0x66E4 0x6AF3 0x6AF0 0x6AEA 0x6AE8 0x6AF9 0x6AF1 +52 0x6AEE 0x6AEF 0x703C 0x7035 0x702F 0x7037 0x7034 0x7031 \ + 0x7042 0x7038 0x703F 0x703A 0x7039 0x7040 0x703B 0x7033 \ + 0x7041 0x7213 0x7214 0x72A8 0x737D 0x737C 0x74BA 0x76AB \ + 0x76AA 0x76BE 0x76ED 0x77CC 0x77CE 0x77CF 0x77CD 0x77F2 \ + 0x7925 0x7923 0x7927 0x7928 0x7924 0x7929 0x79B2 0x7A6E \ + 0x7A6C 0x7A6D 0x7AF7 0x7C49 0x7C48 0x7C4A 0x7C47 0x7C45 \ + 0x7CEE 0x7E7B 0x7E7E 0x7E81 0x7E80 0x7FBA 0x7FFF 0x8079 \ + 0x81DB 0x81D9 0x820B 0x8268 0x8269 0x8622 0x85FF 0x8601 \ + 0x85FE 0x861B 0x8600 0x85F6 0x8604 0x8609 0x8605 0x860C \ + 0x85FD 0x8819 0x8810 0x8811 0x8817 0x8813 0x8816 0x8963 \ + 0x8966 0x89B9 0x89F7 0x8B60 0x8B6A 0x8B5D 0x8B68 0x8B63 \ + 0x8B65 0x8B67 0x8B6D 0x8DAE 0x8E86 0x8E88 0x8E84 0x8F59 \ + 0x8F56 0x8F57 0x8F55 0x8F58 0x8F5A 0x908D 0x9143 0x9141 \ + 0x91B7 0x91B5 0x91B2 0x91B3 0x940B 0x9413 0x93FB 0x9420 \ + 0x940F 0x9414 0x93FE 0x9415 0x9410 0x9428 0x9419 0x940D \ + 0x93F5 0x9400 0x93F7 0x9407 0x940E 0x9416 0x9412 0x93FA \ + 0x9409 0x93F8 0x940A 0x93FF 0x93FC 0x940C 0x93F6 0x9411 \ + 0x9406 0x95DE 0x95E0 0x95DF 0x972E 0x972F 0x97B9 0x97BB \ + 0x97FD 0x97FE 0x9860 0x9862 0x9863 0x985F 0x98C1 0x98C2 \ + 0x9950 0x994E 0x9959 0x994C 0x994B 0x9953 0x9A32 0x9A34 \ + 0x9A31 0x9A2C 0x9A2A 0x9A36 0x9A29 0x9A2E 0x9A38 0x9A2D \ + 0x9AC7 0x9ACA 0x9AC6 0x9B10 0x9B12 0x9B11 0x9C0B 0x9C08 \ + 0x9BF7 0x9C05 0x9C12 0x9BF8 0x9C40 0x9C07 0x9C0E 0x9C06 \ + 0x9C17 0x9C14 0x9C09 0x9D9F 0x9D99 0x9DA4 0x9D9D 0x9D92 \ + 0x9D98 0x9D90 0x9D9B 0x9DA0 0x9D94 0x9D9C 0x9DAA 0x9D97 \ + 0x9DA1 0x9D9A 0x9DA2 0x9DA8 0x9D9E 0x9DA3 0x9DBF 0x9DA9 \ + 0x9D96 0x9DA6 0x9DA7 0x9E99 0x9E9B 0x9E9A 0x9EE5 0x9EE4 \ + 0x9EE7 0x9EE6 0x9F30 0x9F2E 0x9F5B 0x9F60 0x9F5E 0x9F5D \ + 0x9F59 0x9F91 0x513A 0x5139 0x5298 0x5297 0x56C3 0x56BD \ + 0x56BE 0x5B48 0x5B47 0x5DCB 0x5DCF 0x5EF1 0x61FD 0x651B \ + 0x6B02 0x6AFC 0x6B03 0x6AF8 0x6B00 0x7043 0x7044 0x704A \ + 0x7048 0x7049 0x7045 0x7046 0x721D 0x721A 0x7219 0x737E +53 0x7517 0x766A 0x77D0 0x792D 0x7931 0x792F 0x7C54 0x7C53 \ + 0x7CF2 0x7E8A 0x7E87 0x7E88 0x7E8B 0x7E86 0x7E8D 0x7F4D \ + 0x7FBB 0x8030 0x81DD 0x8618 0x862A 0x8626 0x861F 0x8623 \ + 0x861C 0x8619 0x8627 0x862E 0x8621 0x8620 0x8629 0x861E \ + 0x8625 0x8829 0x881D 0x881B 0x8820 0x8824 0x881C 0x882B \ + 0x884A 0x896D 0x8969 0x896E 0x896B 0x89FA 0x8B79 0x8B78 \ + 0x8B45 0x8B7A 0x8B7B 0x8D10 0x8D14 0x8DAF 0x8E8E 0x8E8C \ + 0x8F5E 0x8F5B 0x8F5D 0x9146 0x9144 0x9145 0x91B9 0x943F \ + 0x943B 0x9436 0x9429 0x943D 0x943C 0x9430 0x9439 0x942A \ + 0x9437 0x942C 0x9440 0x9431 0x95E5 0x95E4 0x95E3 0x9735 \ + 0x973A 0x97BF 0x97E1 0x9864 0x98C9 0x98C6 0x98C0 0x9958 \ + 0x9956 0x9A39 0x9A3D 0x9A46 0x9A44 0x9A42 0x9A41 0x9A3A \ + 0x9A3F 0x9ACD 0x9B15 0x9B17 0x9B18 0x9B16 0x9B3A 0x9B52 \ + 0x9C2B 0x9C1D 0x9C1C 0x9C2C 0x9C23 0x9C28 0x9C29 0x9C24 \ + 0x9C21 0x9DB7 0x9DB6 0x9DBC 0x9DC1 0x9DC7 0x9DCA 0x9DCF \ + 0x9DBE 0x9DC5 0x9DC3 0x9DBB 0x9DB5 0x9DCE 0x9DB9 0x9DBA \ + 0x9DAC 0x9DC8 0x9DB1 0x9DAD 0x9DCC 0x9DB3 0x9DCD 0x9DB2 \ + 0x9E7A 0x9E9C 0x9EEB 0x9EEE 0x9EED 0x9F1B 0x9F18 0x9F1A \ + 0x9F31 0x9F4E 0x9F65 0x9F64 0x9F92 0x4EB9 0x56C6 0x56C5 \ + 0x56CB 0x5971 0x5B4B 0x5B4C 0x5DD5 0x5DD1 0x5EF2 0x6521 \ + 0x6520 0x6526 0x6522 0x6B0B 0x6B08 0x6B09 0x6C0D 0x7055 \ + 0x7056 0x7057 0x7052 0x721E 0x721F 0x72A9 0x737F 0x74D8 \ + 0x74D5 0x74D9 0x74D7 0x766D 0x76AD 0x7935 0x79B4 0x7A70 \ + 0x7A71 0x7C57 0x7C5C 0x7C59 0x7C5B 0x7C5A 0x7CF4 0x7CF1 \ + 0x7E91 0x7F4F 0x7F87 0x81DE 0x826B 0x8634 0x8635 0x8633 \ + 0x862C 0x8632 0x8636 0x882C 0x8828 0x8826 0x882A 0x8825 \ + 0x8971 0x89BF 0x89BE 0x89FB 0x8B7E 0x8B84 0x8B82 0x8B86 \ + 0x8B85 0x8B7F 0x8D15 0x8E95 0x8E94 0x8E9A 0x8E92 0x8E90 \ + 0x8E96 0x8E97 0x8F60 0x8F62 0x9147 0x944C 0x9450 0x944A \ + 0x944B 0x944F 0x9447 0x9445 0x9448 0x9449 0x9446 0x973F \ + 0x97E3 0x986A 0x9869 0x98CB 0x9954 0x995B 0x9A4E 0x9A53 \ + 0x9A54 0x9A4C 0x9A4F 0x9A48 0x9A4A 0x9A49 0x9A52 0x9A50 +54 0x9AD0 0x9B19 0x9B2B 0x9B3B 0x9B56 0x9B55 0x9C46 0x9C48 \ + 0x9C3F 0x9C44 0x9C39 0x9C33 0x9C41 0x9C3C 0x9C37 0x9C34 \ + 0x9C32 0x9C3D 0x9C36 0x9DDB 0x9DD2 0x9DDE 0x9DDA 0x9DCB \ + 0x9DD0 0x9DDC 0x9DD1 0x9DDF 0x9DE9 0x9DD9 0x9DD8 0x9DD6 \ + 0x9DF5 0x9DD5 0x9DDD 0x9EB6 0x9EF0 0x9F35 0x9F33 0x9F32 \ + 0x9F42 0x9F6B 0x9F95 0x9FA2 0x513D 0x5299 0x58E8 0x58E7 \ + 0x5972 0x5B4D 0x5DD8 0x882F 0x5F4F 0x6201 0x6203 0x6204 \ + 0x6529 0x6525 0x6596 0x66EB 0x6B11 0x6B12 0x6B0F 0x6BCA \ + 0x705B 0x705A 0x7222 0x7382 0x7381 0x7383 0x7670 0x77D4 \ + 0x7C67 0x7C66 0x7E95 0x826C 0x863A 0x8640 0x8639 0x863C \ + 0x8631 0x863B 0x863E 0x8830 0x8832 0x882E 0x8833 0x8976 \ + 0x8974 0x8973 0x89FE 0x8B8C 0x8B8E 0x8B8B 0x8B88 0x8C45 \ + 0x8D19 0x8E98 0x8F64 0x8F63 0x91BC 0x9462 0x9455 0x945D \ + 0x9457 0x945E 0x97C4 0x97C5 0x9800 0x9A56 0x9A59 0x9B1E \ + 0x9B1F 0x9B20 0x9C52 0x9C58 0x9C50 0x9C4A 0x9C4D 0x9C4B \ + 0x9C55 0x9C59 0x9C4C 0x9C4E 0x9DFB 0x9DF7 0x9DEF 0x9DE3 \ + 0x9DEB 0x9DF8 0x9DE4 0x9DF6 0x9DE1 0x9DEE 0x9DE6 0x9DF2 \ + 0x9DF0 0x9DE2 0x9DEC 0x9DF4 0x9DF3 0x9DE8 0x9DED 0x9EC2 \ + 0x9ED0 0x9EF2 0x9EF3 0x9F06 0x9F1C 0x9F38 0x9F37 0x9F36 \ + 0x9F43 0x9F4F 0x9F71 0x9F70 0x9F6E 0x9F6F 0x56D3 0x56CD \ + 0x5B4E 0x5C6D 0x652D 0x66ED 0x66EE 0x6B13 0x705F 0x7061 \ + 0x705D 0x7060 0x7223 0x74DB 0x74E5 0x77D5 0x7938 0x79B7 \ + 0x79B6 0x7C6A 0x7E97 0x7F89 0x826D 0x8643 0x8838 0x8837 \ + 0x8835 0x884B 0x8B94 0x8B95 0x8E9E 0x8E9F 0x8EA0 0x8E9D \ + 0x91BE 0x91BD 0x91C2 0x946B 0x9468 0x9469 0x96E5 0x9746 \ + 0x9743 0x9747 0x97C7 0x97E5 0x9A5E 0x9AD5 0x9B59 0x9C63 \ + 0x9C67 0x9C66 0x9C62 0x9C5E 0x9C60 0x9E02 0x9DFE 0x9E07 \ + 0x9E03 0x9E06 0x9E05 0x9E00 0x9E01 0x9E09 0x9DFF 0x9DFD \ + 0x9E04 0x9EA0 0x9F1E 0x9F46 0x9F74 0x9F75 0x9F76 0x56D4 \ + 0x652E 0x65B8 0x6B18 0x6B19 0x6B17 0x6B1A 0x7062 0x7226 \ + 0x72AA 0x77D8 0x77D9 0x7939 0x7C69 0x7C6B 0x7CF6 0x7E9A \ + 0x7E98 0x7E9B 0x7E99 0x81E0 0x81E1 0x8646 0x8647 0x8648 +55 0x8979 0x897A 0x897C 0x897B 0x89FF 0x8B98 0x8B99 0x8EA5 \ + 0x8EA4 0x8EA3 0x946E 0x946D 0x946F 0x9471 0x9473 0x9749 \ + 0x9872 0x995F 0x9C68 0x9C6E 0x9C6D 0x9E0B 0x9E0D 0x9E10 \ + 0x9E0F 0x9E12 0x9E11 0x9EA1 0x9EF5 0x9F09 0x9F47 0x9F78 \ + 0x9F7B 0x9F7A 0x9F79 0x571E 0x7066 0x7C6F 0x883C 0x8DB2 \ + 0x8EA6 0x91C3 0x9474 0x9478 0x9476 0x9475 0x9A60 0x9C74 \ + 0x9C73 0x9C71 0x9C75 0x9E14 0x9E13 0x9EF6 0x9F0A 0x9FA4 \ + 0x7068 0x7065 0x7CF7 0x866A 0x883E 0x883D 0x883F 0x8B9E \ + 0x8C9C 0x8EA9 0x8EC9 0x974B 0x9873 0x9874 0x98CC 0x9961 \ + 0x99AB 0x9A64 0x9A66 0x9A67 0x9B24 0x9E15 0x9E17 0x9F48 \ + 0x6207 0x6B1E 0x7227 0x864C 0x8EA8 0x9482 0x9480 0x9481 \ + 0x9A69 0x9A68 0x9B2E 0x9E19 0x7229 0x864B 0x8B9F 0x9483 \ + 0x9C79 0x9EB7 0x7675 0x9A6B 0x9C7A 0x9E1D 0x7069 0x706A \ + 0x9EA4 0x9F7E 0x9F49 0x9F98 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +56 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +57 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +58 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE + +# eof diff --git a/contrib/ttf2pk/data/UGB.sfd b/contrib/ttf2pk/data/UGB.sfd new file mode 100644 index 0000000..136c6e7 --- /dev/null +++ b/contrib/ttf2pk/data/UGB.sfd @@ -0,0 +1,1114 @@ +# UGB.sfd +# +# subfont numbers for GB 2312 encoding and its corresponding code ranges +# to be used with the CJK package for LaTeX. +# +# The input encoding is Unicode. + +01 0x3000 0x3001 0x3002 0x30FB 0x02C9 0x02C7 0x00A8 0x3003 \ + 0x3005 0x2015 0xFF5E 0x2225 0x2026 0x2018 0x2019 0x201C \ + 0x201D 0x3014 0x3015 0x3008 0x3009 0x300A 0x300B 0x300C \ + 0x300D 0x300E 0x300F 0x3016 0x3017 0x3010 0x3011 0x00B1 \ + 0x00D7 0x00F7 0x2236 0x2227 0x2228 0x2211 0x220F 0x222A \ + 0x2229 0x2208 0x2237 0x221A 0x22A5 0x2225 0x2220 0x2312 \ + 0x2299 0x222B 0x222E 0x2261 0x224C 0x2248 0x223D 0x221D \ + 0x2260 0x226E 0x226F 0x2264 0x2265 0x221E 0x2235 0x2234 \ + 0x2642 0x2640 0x00B0 0x2032 0x2033 0x2103 0xFF04 0x00A4 \ + 0xFFE0 0xFFE1 0x2030 0x00A7 0x2116 0x2606 0x2605 0x25CB \ + 0x25CF 0x25CE 0x25C7 0x25C6 0x25A1 0x25A0 0x25B3 0x25B2 \ + 0x203B 0x2192 0x2190 0x2191 0x2193 0x3013 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x2488 0x2489 \ + 0x248A 0x248B 0x248C 0x248D 0x248E 0x248F 0x2490 0x2491 \ + 0x2492 0x2493 0x2494 0x2495 0x2496 0x2497 0x2498 0x2499 \ + 0x249A 0x249B 0x2474 0x2475 0x2476 0x2477 0x2478 0x2479 \ + 0x247A 0x247B 0x247C 0x247D 0x247E 0x247F 0x2480 0x2481 \ + 0x2482 0x2483 0x2484 0x2485 0x2486 0x2487 0x2460 0x2461 \ + 0x2462 0x2463 0x2464 0x2465 0x2466 0x2467 0x2468 0x2469 \ + 0xFFFE 0xFFFE 0x3220 0x3221 0x3222 0x3223 0x3224 0x3225 \ + 0x3226 0x3227 0x3228 0x3229 0xFFFE 0xFFFE 0x2160 0x2161 \ + 0x2162 0x2163 0x2164 0x2165 0x2166 0x2167 0x2168 0x2169 \ + 0x216A 0x216B 0xFFFE 0xFFFE 0xFF01 0xFF02 0xFF03 0xFFE5 \ + 0xFF05 0xFF06 0xFF07 0xFF08 0xFF09 0xFF0A 0xFF0B 0xFF0C \ + 0xFF0D 0xFF0E 0xFF0F 0xFF10 0xFF11 0xFF12 0xFF13 0xFF14 \ + 0xFF15 0xFF16 0xFF17 0xFF18 0xFF19 0xFF1A 0xFF1B 0xFF1C \ + 0xFF1D 0xFF1E 0xFF1F 0xFF20 0xFF21 0xFF22 0xFF23 0xFF24 \ + 0xFF25 0xFF26 0xFF27 0xFF28 0xFF29 0xFF2A 0xFF2B 0xFF2C \ + 0xFF2D 0xFF2E 0xFF2F 0xFF30 0xFF31 0xFF32 0xFF33 0xFF34 \ + 0xFF35 0xFF36 0xFF37 0xFF38 0xFF39 0xFF3A 0xFF3B 0xFF3C \ + 0xFF3D 0xFF3E 0xFF3F 0xFF40 0xFF41 0xFF42 0xFF43 0xFF44 +02 0xFF45 0xFF46 0xFF47 0xFF48 0xFF49 0xFF4A 0xFF4B 0xFF4C \ + 0xFF4D 0xFF4E 0xFF4F 0xFF50 0xFF51 0xFF52 0xFF53 0xFF54 \ + 0xFF55 0xFF56 0xFF57 0xFF58 0xFF59 0xFF5A 0xFF5B 0xFF5C \ + 0xFF5D 0xFFE3 0x3041 0x3042 0x3043 0x3044 0x3045 0x3046 \ + 0x3047 0x3048 0x3049 0x304A 0x304B 0x304C 0x304D 0x304E \ + 0x304F 0x3050 0x3051 0x3052 0x3053 0x3054 0x3055 0x3056 \ + 0x3057 0x3058 0x3059 0x305A 0x305B 0x305C 0x305D 0x305E \ + 0x305F 0x3060 0x3061 0x3062 0x3063 0x3064 0x3065 0x3066 \ + 0x3067 0x3068 0x3069 0x306A 0x306B 0x306C 0x306D 0x306E \ + 0x306F 0x3070 0x3071 0x3072 0x3073 0x3074 0x3075 0x3076 \ + 0x3077 0x3078 0x3079 0x307A 0x307B 0x307C 0x307D 0x307E \ + 0x307F 0x3080 0x3081 0x3082 0x3083 0x3084 0x3085 0x3086 \ + 0x3087 0x3088 0x3089 0x308A 0x308B 0x308C 0x308D 0x308E \ + 0x308F 0x3090 0x3091 0x3092 0x3093 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0x30A1 0x30A2 0x30A3 0x30A4 0x30A5 0x30A6 0x30A7 0x30A8 \ + 0x30A9 0x30AA 0x30AB 0x30AC 0x30AD 0x30AE 0x30AF 0x30B0 \ + 0x30B1 0x30B2 0x30B3 0x30B4 0x30B5 0x30B6 0x30B7 0x30B8 \ + 0x30B9 0x30BA 0x30BB 0x30BC 0x30BD 0x30BE 0x30BF 0x30C0 \ + 0x30C1 0x30C2 0x30C3 0x30C4 0x30C5 0x30C6 0x30C7 0x30C8 \ + 0x30C9 0x30CA 0x30CB 0x30CC 0x30CD 0x30CE 0x30CF 0x30D0 \ + 0x30D1 0x30D2 0x30D3 0x30D4 0x30D5 0x30D6 0x30D7 0x30D8 \ + 0x30D9 0x30DA 0x30DB 0x30DC 0x30DD 0x30DE 0x30DF 0x30E0 \ + 0x30E1 0x30E2 0x30E3 0x30E4 0x30E5 0x30E6 0x30E7 0x30E8 \ + 0x30E9 0x30EA 0x30EB 0x30EC 0x30ED 0x30EE 0x30EF 0x30F0 \ + 0x30F1 0x30F2 0x30F3 0x30F4 0x30F5 0x30F6 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x0391 0x0392 \ + 0x0393 0x0394 0x0395 0x0396 0x0397 0x0398 0x0399 0x039A \ + 0x039B 0x039C 0x039D 0x039E 0x039F 0x03A0 0x03A1 0x03A3 \ + 0x03A4 0x03A5 0x03A6 0x03A7 0x03A8 0x03A9 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x03B1 0x03B2 \ + 0x03B3 0x03B4 0x03B5 0x03B6 0x03B7 0x03B8 0x03B9 0x03BA +03 0x03BB 0x03BC 0x03BD 0x03BE 0x03BF 0x03C0 0x03C1 0x03C3 \ + 0x03C4 0x03C5 0x03C6 0x03C7 0x03C8 0x03C9 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x0410 0x0411 0x0412 0x0413 \ + 0x0414 0x0415 0x0401 0x0416 0x0417 0x0418 0x0419 0x041A \ + 0x041B 0x041C 0x041D 0x041E 0x041F 0x0420 0x0421 0x0422 \ + 0x0423 0x0424 0x0425 0x0426 0x0427 0x0428 0x0429 0x042A \ + 0x042B 0x042C 0x042D 0x042E 0x042F 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x0430 0x0431 0x0432 0x0433 \ + 0x0434 0x0435 0x0451 0x0436 0x0437 0x0438 0x0439 0x043A \ + 0x043B 0x043C 0x043D 0x043E 0x043F 0x0440 0x0441 0x0442 \ + 0x0443 0x0444 0x0445 0x0446 0x0447 0x0448 0x0449 0x044A \ + 0x044B 0x044C 0x044D 0x044E 0x044F 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x0101 0x00E1 0x01CE 0x00E0 0x0113 0x00E9 \ + 0x011B 0x00E8 0x012B 0x00ED 0x01D0 0x00EC 0x014D 0x00F3 \ + 0x01D2 0x00F2 0x016B 0x00FA 0x01D4 0x00F9 0x01D6 0x01D8 \ + 0x01DA 0x01DC 0x00FC 0x00EA 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x3105 0x3106 \ + 0x3107 0x3108 0x3109 0x310A 0x310B 0x310C 0x310D 0x310E \ + 0x310F 0x3110 0x3111 0x3112 0x3113 0x3114 0x3115 0x3116 \ + 0x3117 0x3118 0x3119 0x311A 0x311B 0x311C 0x311D 0x311E \ + 0x311F 0x3120 0x3121 0x3122 0x3123 0x3124 0x3125 0x3126 \ + 0x3127 0x3128 0x3129 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0x2500 0x2501 0x2502 0x2503 0x2504 \ + 0x2505 0x2506 0x2507 0x2508 0x2509 0x250A 0x250B 0x250C +04 0x250D 0x250E 0x250F 0x2510 0x2511 0x2512 0x2513 0x2514 \ + 0x2515 0x2516 0x2517 0x2518 0x2519 0x251A 0x251B 0x251C \ + 0x251D 0x251E 0x251F 0x2520 0x2521 0x2522 0x2523 0x2524 \ + 0x2525 0x2526 0x2527 0x2528 0x2529 0x252A 0x252B 0x252C \ + 0x252D 0x252E 0x252F 0x2530 0x2531 0x2532 0x2533 0x2534 \ + 0x2535 0x2536 0x2537 0x2538 0x2539 0x253A 0x253B 0x253C \ + 0x253D 0x253E 0x253F 0x2540 0x2541 0x2542 0x2543 0x2544 \ + 0x2545 0x2546 0x2547 0x2548 0x2549 0x254A 0x254B 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +05 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +06 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x554A 0x963F 0x57C3 0x6328 0x54CE 0x5509 \ + 0x54C0 0x7691 0x764C 0x853C 0x77EE 0x827E 0x788D 0x7231 \ + 0x9698 0x978D 0x6C28 0x5B89 0x4FFA 0x6309 0x6697 0x5CB8 \ + 0x80FA 0x6848 0x80AE 0x6602 0x76CE 0x51F9 0x6556 0x71AC \ + 0x7FF1 0x8884 0x50B2 0x5965 0x61CA 0x6FB3 0x82AD 0x634C \ + 0x6252 0x53ED 0x5427 0x7B06 0x516B 0x75A4 0x5DF4 0x62D4 \ + 0x8DCB 0x9776 0x628A 0x8019 0x575D 0x9738 0x7F62 0x7238 \ + 0x767D 0x67CF 0x767E 0x6446 0x4F70 0x8D25 0x62DC 0x7A17 \ + 0x6591 0x73ED 0x642C 0x6273 0x822C 0x9881 0x677F 0x7248 \ + 0x626E 0x62CC 0x4F34 0x74E3 0x534A 0x529E 0x7ECA 0x90A6 \ + 0x5E2E 0x6886 0x699C 0x8180 0x7ED1 0x68D2 0x78C5 0x868C \ + 0x9551 0x508D 0x8C24 0x82DE 0x80DE 0x5305 0x8912 0x5265 \ + 0x8584 0x96F9 0x4FDD 0x5821 0x9971 0x5B9D 0x62B1 0x62A5 \ + 0x66B4 0x8C79 0x9C8D 0x7206 0x676F 0x7891 0x60B2 0x5351 \ + 0x5317 0x8F88 0x80CC 0x8D1D 0x94A1 0x500D 0x72C8 0x5907 \ + 0x60EB 0x7119 0x88AB 0x5954 0x82EF 0x672C 0x7B28 0x5D29 +07 0x7EF7 0x752D 0x6CF5 0x8E66 0x8FF8 0x903C 0x9F3B 0x6BD4 \ + 0x9119 0x7B14 0x5F7C 0x78A7 0x84D6 0x853D 0x6BD5 0x6BD9 \ + 0x6BD6 0x5E01 0x5E87 0x75F9 0x95ED 0x655D 0x5F0A 0x5FC5 \ + 0x8F9F 0x58C1 0x81C2 0x907F 0x965B 0x97AD 0x8FB9 0x7F16 \ + 0x8D2C 0x6241 0x4FBF 0x53D8 0x535E 0x8FA8 0x8FA9 0x8FAB \ + 0x904D 0x6807 0x5F6A 0x8198 0x8868 0x9CD6 0x618B 0x522B \ + 0x762A 0x5F6C 0x658C 0x6FD2 0x6EE8 0x5BBE 0x6448 0x5175 \ + 0x51B0 0x67C4 0x4E19 0x79C9 0x997C 0x70B3 0x75C5 0x5E76 \ + 0x73BB 0x83E0 0x64AD 0x62E8 0x94B5 0x6CE2 0x535A 0x52C3 \ + 0x640F 0x94C2 0x7B94 0x4F2F 0x5E1B 0x8236 0x8116 0x818A \ + 0x6E24 0x6CCA 0x9A73 0x6355 0x535C 0x54FA 0x8865 0x57E0 \ + 0x4E0D 0x5E03 0x6B65 0x7C3F 0x90E8 0x6016 0x64E6 0x731C \ + 0x88C1 0x6750 0x624D 0x8D22 0x776C 0x8E29 0x91C7 0x5F69 \ + 0x83DC 0x8521 0x9910 0x53C2 0x8695 0x6B8B 0x60ED 0x60E8 \ + 0x707F 0x82CD 0x8231 0x4ED3 0x6CA7 0x85CF 0x64CD 0x7CD9 \ + 0x69FD 0x66F9 0x8349 0x5395 0x7B56 0x4FA7 0x518C 0x6D4B \ + 0x5C42 0x8E6D 0x63D2 0x53C9 0x832C 0x8336 0x67E5 0x78B4 \ + 0x643D 0x5BDF 0x5C94 0x5DEE 0x8BE7 0x62C6 0x67F4 0x8C7A \ + 0x6400 0x63BA 0x8749 0x998B 0x8C17 0x7F20 0x94F2 0x4EA7 \ + 0x9610 0x98A4 0x660C 0x7316 0x573A 0x5C1D 0x5E38 0x957F \ + 0x507F 0x80A0 0x5382 0x655E 0x7545 0x5531 0x5021 0x8D85 \ + 0x6284 0x949E 0x671D 0x5632 0x6F6E 0x5DE2 0x5435 0x7092 \ + 0x8F66 0x626F 0x64A4 0x63A3 0x5F7B 0x6F88 0x90F4 0x81E3 \ + 0x8FB0 0x5C18 0x6668 0x5FF1 0x6C89 0x9648 0x8D81 0x886C \ + 0x6491 0x79F0 0x57CE 0x6A59 0x6210 0x5448 0x4E58 0x7A0B \ + 0x60E9 0x6F84 0x8BDA 0x627F 0x901E 0x9A8B 0x79E4 0x5403 \ + 0x75F4 0x6301 0x5319 0x6C60 0x8FDF 0x5F1B 0x9A70 0x803B \ + 0x9F7F 0x4F88 0x5C3A 0x8D64 0x7FC5 0x65A5 0x70BD 0x5145 \ + 0x51B2 0x866B 0x5D07 0x5BA0 0x62BD 0x916C 0x7574 0x8E0C \ + 0x7A20 0x6101 0x7B79 0x4EC7 0x7EF8 0x7785 0x4E11 0x81ED \ + 0x521D 0x51FA 0x6A71 0x53A8 0x8E87 0x9504 0x96CF 0x6EC1 \ + 0x9664 0x695A 0x7840 0x50A8 0x77D7 0x6410 0x89E6 0x5904 +08 0x63E3 0x5DDD 0x7A7F 0x693D 0x4F20 0x8239 0x5598 0x4E32 \ + 0x75AE 0x7A97 0x5E62 0x5E8A 0x95EF 0x521B 0x5439 0x708A \ + 0x6376 0x9524 0x5782 0x6625 0x693F 0x9187 0x5507 0x6DF3 \ + 0x7EAF 0x8822 0x6233 0x7EF0 0x75B5 0x8328 0x78C1 0x96CC \ + 0x8F9E 0x6148 0x74F7 0x8BCD 0x6B64 0x523A 0x8D50 0x6B21 \ + 0x806A 0x8471 0x56F1 0x5306 0x4ECE 0x4E1B 0x51D1 0x7C97 \ + 0x918B 0x7C07 0x4FC3 0x8E7F 0x7BE1 0x7A9C 0x6467 0x5D14 \ + 0x50AC 0x8106 0x7601 0x7CB9 0x6DEC 0x7FE0 0x6751 0x5B58 \ + 0x5BF8 0x78CB 0x64AE 0x6413 0x63AA 0x632B 0x9519 0x642D \ + 0x8FBE 0x7B54 0x7629 0x6253 0x5927 0x5446 0x6B79 0x50A3 \ + 0x6234 0x5E26 0x6B86 0x4EE3 0x8D37 0x888B 0x5F85 0x902E \ + 0x6020 0x803D 0x62C5 0x4E39 0x5355 0x90F8 0x63B8 0x80C6 \ + 0x65E6 0x6C2E 0x4F46 0x60EE 0x6DE1 0x8BDE 0x5F39 0x86CB \ + 0x5F53 0x6321 0x515A 0x8361 0x6863 0x5200 0x6363 0x8E48 \ + 0x5012 0x5C9B 0x7977 0x5BFC 0x5230 0x7A3B 0x60BC 0x9053 \ + 0x76D7 0x5FB7 0x5F97 0x7684 0x8E6C 0x706F 0x767B 0x7B49 \ + 0x77AA 0x51F3 0x9093 0x5824 0x4F4E 0x6EF4 0x8FEA 0x654C \ + 0x7B1B 0x72C4 0x6DA4 0x7FDF 0x5AE1 0x62B5 0x5E95 0x5730 \ + 0x8482 0x7B2C 0x5E1D 0x5F1F 0x9012 0x7F14 0x98A0 0x6382 \ + 0x6EC7 0x7898 0x70B9 0x5178 0x975B 0x57AB 0x7535 0x4F43 \ + 0x7538 0x5E97 0x60E6 0x5960 0x6DC0 0x6BBF 0x7889 0x53FC \ + 0x96D5 0x51CB 0x5201 0x6389 0x540A 0x9493 0x8C03 0x8DCC \ + 0x7239 0x789F 0x8776 0x8FED 0x8C0D 0x53E0 0x4E01 0x76EF \ + 0x53EE 0x9489 0x9876 0x9F0E 0x952D 0x5B9A 0x8BA2 0x4E22 \ + 0x4E1C 0x51AC 0x8463 0x61C2 0x52A8 0x680B 0x4F97 0x606B \ + 0x51BB 0x6D1E 0x515C 0x6296 0x6597 0x9661 0x8C46 0x9017 \ + 0x75D8 0x90FD 0x7763 0x6BD2 0x728A 0x72EC 0x8BFB 0x5835 \ + 0x7779 0x8D4C 0x675C 0x9540 0x809A 0x5EA6 0x6E21 0x5992 \ + 0x7AEF 0x77ED 0x953B 0x6BB5 0x65AD 0x7F0E 0x5806 0x5151 \ + 0x961F 0x5BF9 0x58A9 0x5428 0x8E72 0x6566 0x987F 0x56E4 \ + 0x949D 0x76FE 0x9041 0x6387 0x54C6 0x591A 0x593A 0x579B \ + 0x8EB2 0x6735 0x8DFA 0x8235 0x5241 0x60F0 0x5815 0x86FE +09 0x5CE8 0x9E45 0x4FC4 0x989D 0x8BB9 0x5A25 0x6076 0x5384 \ + 0x627C 0x904F 0x9102 0x997F 0x6069 0x800C 0x513F 0x8033 \ + 0x5C14 0x9975 0x6D31 0x4E8C 0x8D30 0x53D1 0x7F5A 0x7B4F \ + 0x4F10 0x4E4F 0x9600 0x6CD5 0x73D0 0x85E9 0x5E06 0x756A \ + 0x7FFB 0x6A0A 0x77FE 0x9492 0x7E41 0x51E1 0x70E6 0x53CD \ + 0x8FD4 0x8303 0x8D29 0x72AF 0x996D 0x6CDB 0x574A 0x82B3 \ + 0x65B9 0x80AA 0x623F 0x9632 0x59A8 0x4EFF 0x8BBF 0x7EBA \ + 0x653E 0x83F2 0x975E 0x5561 0x98DE 0x80A5 0x532A 0x8BFD \ + 0x5420 0x80BA 0x5E9F 0x6CB8 0x8D39 0x82AC 0x915A 0x5429 \ + 0x6C1B 0x5206 0x7EB7 0x575F 0x711A 0x6C7E 0x7C89 0x594B \ + 0x4EFD 0x5FFF 0x6124 0x7CAA 0x4E30 0x5C01 0x67AB 0x8702 \ + 0x5CF0 0x950B 0x98CE 0x75AF 0x70FD 0x9022 0x51AF 0x7F1D \ + 0x8BBD 0x5949 0x51E4 0x4F5B 0x5426 0x592B 0x6577 0x80A4 \ + 0x5B75 0x6276 0x62C2 0x8F90 0x5E45 0x6C1F 0x7B26 0x4F0F \ + 0x4FD8 0x670D 0x6D6E 0x6DAA 0x798F 0x88B1 0x5F17 0x752B \ + 0x629A 0x8F85 0x4FEF 0x91DC 0x65A7 0x812F 0x8151 0x5E9C \ + 0x8150 0x8D74 0x526F 0x8986 0x8D4B 0x590D 0x5085 0x4ED8 \ + 0x961C 0x7236 0x8179 0x8D1F 0x5BCC 0x8BA3 0x9644 0x5987 \ + 0x7F1A 0x5490 0x5676 0x560E 0x8BE5 0x6539 0x6982 0x9499 \ + 0x76D6 0x6E89 0x5E72 0x7518 0x6746 0x67D1 0x7AFF 0x809D \ + 0x8D76 0x611F 0x79C6 0x6562 0x8D63 0x5188 0x521A 0x94A2 \ + 0x7F38 0x809B 0x7EB2 0x5C97 0x6E2F 0x6760 0x7BD9 0x768B \ + 0x9AD8 0x818F 0x7F94 0x7CD5 0x641E 0x9550 0x7A3F 0x544A \ + 0x54E5 0x6B4C 0x6401 0x6208 0x9E3D 0x80F3 0x7599 0x5272 \ + 0x9769 0x845B 0x683C 0x86E4 0x9601 0x9694 0x94EC 0x4E2A \ + 0x5404 0x7ED9 0x6839 0x8DDF 0x8015 0x66F4 0x5E9A 0x7FB9 \ + 0x57C2 0x803F 0x6897 0x5DE5 0x653B 0x529F 0x606D 0x9F9A \ + 0x4F9B 0x8EAC 0x516C 0x5BAB 0x5F13 0x5DE9 0x6C5E 0x62F1 \ + 0x8D21 0x5171 0x94A9 0x52FE 0x6C9F 0x82DF 0x72D7 0x57A2 \ + 0x6784 0x8D2D 0x591F 0x8F9C 0x83C7 0x5495 0x7B8D 0x4F30 \ + 0x6CBD 0x5B64 0x59D1 0x9F13 0x53E4 0x86CA 0x9AA8 0x8C37 \ + 0x80A1 0x6545 0x987E 0x56FA 0x96C7 0x522E 0x74DC 0x5250 +10 0x5BE1 0x6302 0x8902 0x4E56 0x62D0 0x602A 0x68FA 0x5173 \ + 0x5B98 0x51A0 0x89C2 0x7BA1 0x9986 0x7F50 0x60EF 0x704C \ + 0x8D2F 0x5149 0x5E7F 0x901B 0x7470 0x89C4 0x572D 0x7845 \ + 0x5F52 0x9F9F 0x95FA 0x8F68 0x9B3C 0x8BE1 0x7678 0x6842 \ + 0x67DC 0x8DEA 0x8D35 0x523D 0x8F8A 0x6EDA 0x68CD 0x9505 \ + 0x90ED 0x56FD 0x679C 0x88F9 0x8FC7 0x54C8 0x9AB8 0x5B69 \ + 0x6D77 0x6C26 0x4EA5 0x5BB3 0x9A87 0x9163 0x61A8 0x90AF \ + 0x97E9 0x542B 0x6DB5 0x5BD2 0x51FD 0x558A 0x7F55 0x7FF0 \ + 0x64BC 0x634D 0x65F1 0x61BE 0x608D 0x710A 0x6C57 0x6C49 \ + 0x592F 0x676D 0x822A 0x58D5 0x568E 0x8C6A 0x6BEB 0x90DD \ + 0x597D 0x8017 0x53F7 0x6D69 0x5475 0x559D 0x8377 0x83CF \ + 0x6838 0x79BE 0x548C 0x4F55 0x5408 0x76D2 0x8C89 0x9602 \ + 0x6CB3 0x6DB8 0x8D6B 0x8910 0x9E64 0x8D3A 0x563F 0x9ED1 \ + 0x75D5 0x5F88 0x72E0 0x6068 0x54FC 0x4EA8 0x6A2A 0x8861 \ + 0x6052 0x8F70 0x54C4 0x70D8 0x8679 0x9E3F 0x6D2A 0x5B8F \ + 0x5F18 0x7EA2 0x5589 0x4FAF 0x7334 0x543C 0x539A 0x5019 \ + 0x540E 0x547C 0x4E4E 0x5FFD 0x745A 0x58F6 0x846B 0x80E1 \ + 0x8774 0x72D0 0x7CCA 0x6E56 0x5F27 0x864E 0x552C 0x62A4 \ + 0x4E92 0x6CAA 0x6237 0x82B1 0x54D7 0x534E 0x733E 0x6ED1 \ + 0x753B 0x5212 0x5316 0x8BDD 0x69D0 0x5F8A 0x6000 0x6DEE \ + 0x574F 0x6B22 0x73AF 0x6853 0x8FD8 0x7F13 0x6362 0x60A3 \ + 0x5524 0x75EA 0x8C62 0x7115 0x6DA3 0x5BA6 0x5E7B 0x8352 \ + 0x614C 0x9EC4 0x78FA 0x8757 0x7C27 0x7687 0x51F0 0x60F6 \ + 0x714C 0x6643 0x5E4C 0x604D 0x8C0E 0x7070 0x6325 0x8F89 \ + 0x5FBD 0x6062 0x86D4 0x56DE 0x6BC1 0x6094 0x6167 0x5349 \ + 0x60E0 0x6666 0x8D3F 0x79FD 0x4F1A 0x70E9 0x6C47 0x8BB3 \ + 0x8BF2 0x7ED8 0x8364 0x660F 0x5A5A 0x9B42 0x6D51 0x6DF7 \ + 0x8C41 0x6D3B 0x4F19 0x706B 0x83B7 0x6216 0x60D1 0x970D \ + 0x8D27 0x7978 0x51FB 0x573E 0x57FA 0x673A 0x7578 0x7A3D \ + 0x79EF 0x7B95 0x808C 0x9965 0x8FF9 0x6FC0 0x8BA5 0x9E21 \ + 0x59EC 0x7EE9 0x7F09 0x5409 0x6781 0x68D8 0x8F91 0x7C4D \ + 0x96C6 0x53CA 0x6025 0x75BE 0x6C72 0x5373 0x5AC9 0x7EA7 +11 0x6324 0x51E0 0x810A 0x5DF1 0x84DF 0x6280 0x5180 0x5B63 \ + 0x4F0E 0x796D 0x5242 0x60B8 0x6D4E 0x5BC4 0x5BC2 0x8BA1 \ + 0x8BB0 0x65E2 0x5FCC 0x9645 0x5993 0x7EE7 0x7EAA 0x5609 \ + 0x67B7 0x5939 0x4F73 0x5BB6 0x52A0 0x835A 0x988A 0x8D3E \ + 0x7532 0x94BE 0x5047 0x7A3C 0x4EF7 0x67B6 0x9A7E 0x5AC1 \ + 0x6B7C 0x76D1 0x575A 0x5C16 0x7B3A 0x95F4 0x714E 0x517C \ + 0x80A9 0x8270 0x5978 0x7F04 0x8327 0x68C0 0x67EC 0x78B1 \ + 0x7877 0x62E3 0x6361 0x7B80 0x4FED 0x526A 0x51CF 0x8350 \ + 0x69DB 0x9274 0x8DF5 0x8D31 0x89C1 0x952E 0x7BAD 0x4EF6 \ + 0x5065 0x8230 0x5251 0x996F 0x6E10 0x6E85 0x6DA7 0x5EFA \ + 0x50F5 0x59DC 0x5C06 0x6D46 0x6C5F 0x7586 0x848B 0x6868 \ + 0x5956 0x8BB2 0x5320 0x9171 0x964D 0x8549 0x6912 0x7901 \ + 0x7126 0x80F6 0x4EA4 0x90CA 0x6D47 0x9A84 0x5A07 0x56BC \ + 0x6405 0x94F0 0x77EB 0x4FA5 0x811A 0x72E1 0x89D2 0x997A \ + 0x7F34 0x7EDE 0x527F 0x6559 0x9175 0x8F7F 0x8F83 0x53EB \ + 0x7A96 0x63ED 0x63A5 0x7686 0x79F8 0x8857 0x9636 0x622A \ + 0x52AB 0x8282 0x6854 0x6770 0x6377 0x776B 0x7AED 0x6D01 \ + 0x7ED3 0x89E3 0x59D0 0x6212 0x85C9 0x82A5 0x754C 0x501F \ + 0x4ECB 0x75A5 0x8BEB 0x5C4A 0x5DFE 0x7B4B 0x65A4 0x91D1 \ + 0x4ECA 0x6D25 0x895F 0x7D27 0x9526 0x4EC5 0x8C28 0x8FDB \ + 0x9773 0x664B 0x7981 0x8FD1 0x70EC 0x6D78 0x5C3D 0x52B2 \ + 0x8346 0x5162 0x830E 0x775B 0x6676 0x9CB8 0x4EAC 0x60CA \ + 0x7CBE 0x7CB3 0x7ECF 0x4E95 0x8B66 0x666F 0x9888 0x9759 \ + 0x5883 0x656C 0x955C 0x5F84 0x75C9 0x9756 0x7ADF 0x7ADE \ + 0x51C0 0x70AF 0x7A98 0x63EA 0x7A76 0x7EA0 0x7396 0x97ED \ + 0x4E45 0x7078 0x4E5D 0x9152 0x53A9 0x6551 0x65E7 0x81FC \ + 0x8205 0x548E 0x5C31 0x759A 0x97A0 0x62D8 0x72D9 0x75BD \ + 0x5C45 0x9A79 0x83CA 0x5C40 0x5480 0x77E9 0x4E3E 0x6CAE \ + 0x805A 0x62D2 0x636E 0x5DE8 0x5177 0x8DDD 0x8E1E 0x952F \ + 0x4FF1 0x53E5 0x60E7 0x70AC 0x5267 0x6350 0x9E43 0x5A1F \ + 0x5026 0x7737 0x5377 0x7EE2 0x6485 0x652B 0x6289 0x6398 \ + 0x5014 0x7235 0x89C9 0x51B3 0x8BC0 0x7EDD 0x5747 0x83CC +12 0x94A7 0x519B 0x541B 0x5CFB 0x4FCA 0x7AE3 0x6D5A 0x90E1 \ + 0x9A8F 0x5580 0x5496 0x5361 0x54AF 0x5F00 0x63E9 0x6977 \ + 0x51EF 0x6168 0x520A 0x582A 0x52D8 0x574E 0x780D 0x770B \ + 0x5EB7 0x6177 0x7CE0 0x625B 0x6297 0x4EA2 0x7095 0x8003 \ + 0x62F7 0x70E4 0x9760 0x5777 0x82DB 0x67EF 0x68F5 0x78D5 \ + 0x9897 0x79D1 0x58F3 0x54B3 0x53EF 0x6E34 0x514B 0x523B \ + 0x5BA2 0x8BFE 0x80AF 0x5543 0x57A6 0x6073 0x5751 0x542D \ + 0x7A7A 0x6050 0x5B54 0x63A7 0x62A0 0x53E3 0x6263 0x5BC7 \ + 0x67AF 0x54ED 0x7A9F 0x82E6 0x9177 0x5E93 0x88E4 0x5938 \ + 0x57AE 0x630E 0x8DE8 0x80EF 0x5757 0x7B77 0x4FA9 0x5FEB \ + 0x5BBD 0x6B3E 0x5321 0x7B50 0x72C2 0x6846 0x77FF 0x7736 \ + 0x65F7 0x51B5 0x4E8F 0x76D4 0x5CBF 0x7AA5 0x8475 0x594E \ + 0x9B41 0x5080 0x9988 0x6127 0x6E83 0x5764 0x6606 0x6346 \ + 0x56F0 0x62EC 0x6269 0x5ED3 0x9614 0x5783 0x62C9 0x5587 \ + 0x8721 0x814A 0x8FA3 0x5566 0x83B1 0x6765 0x8D56 0x84DD \ + 0x5A6A 0x680F 0x62E6 0x7BEE 0x9611 0x5170 0x6F9C 0x8C30 \ + 0x63FD 0x89C8 0x61D2 0x7F06 0x70C2 0x6EE5 0x7405 0x6994 \ + 0x72FC 0x5ECA 0x90CE 0x6717 0x6D6A 0x635E 0x52B3 0x7262 \ + 0x8001 0x4F6C 0x59E5 0x916A 0x70D9 0x6D9D 0x52D2 0x4E50 \ + 0x96F7 0x956D 0x857E 0x78CA 0x7D2F 0x5121 0x5792 0x64C2 \ + 0x808B 0x7C7B 0x6CEA 0x68F1 0x695E 0x51B7 0x5398 0x68A8 \ + 0x7281 0x9ECE 0x7BF1 0x72F8 0x79BB 0x6F13 0x7406 0x674E \ + 0x91CC 0x9CA4 0x793C 0x8389 0x8354 0x540F 0x6817 0x4E3D \ + 0x5389 0x52B1 0x783E 0x5386 0x5229 0x5088 0x4F8B 0x4FD0 \ + 0x75E2 0x7ACB 0x7C92 0x6CA5 0x96B6 0x529B 0x7483 0x54E9 \ + 0x4FE9 0x8054 0x83B2 0x8FDE 0x9570 0x5EC9 0x601C 0x6D9F \ + 0x5E18 0x655B 0x8138 0x94FE 0x604B 0x70BC 0x7EC3 0x7CAE \ + 0x51C9 0x6881 0x7CB1 0x826F 0x4E24 0x8F86 0x91CF 0x667E \ + 0x4EAE 0x8C05 0x64A9 0x804A 0x50DA 0x7597 0x71CE 0x5BE5 \ + 0x8FBD 0x6F66 0x4E86 0x6482 0x9563 0x5ED6 0x6599 0x5217 \ + 0x88C2 0x70C8 0x52A3 0x730E 0x7433 0x6797 0x78F7 0x9716 \ + 0x4E34 0x90BB 0x9CDE 0x6DCB 0x51DB 0x8D41 0x541D 0x62CE +13 0x73B2 0x83F1 0x96F6 0x9F84 0x94C3 0x4F36 0x7F9A 0x51CC \ + 0x7075 0x9675 0x5CAD 0x9886 0x53E6 0x4EE4 0x6E9C 0x7409 \ + 0x69B4 0x786B 0x998F 0x7559 0x5218 0x7624 0x6D41 0x67F3 \ + 0x516D 0x9F99 0x804B 0x5499 0x7B3C 0x7ABF 0x9686 0x5784 \ + 0x62E2 0x9647 0x697C 0x5A04 0x6402 0x7BD3 0x6F0F 0x964B \ + 0x82A6 0x5362 0x9885 0x5E90 0x7089 0x63B3 0x5364 0x864F \ + 0x9C81 0x9E93 0x788C 0x9732 0x8DEF 0x8D42 0x9E7F 0x6F5E \ + 0x7984 0x5F55 0x9646 0x622E 0x9A74 0x5415 0x94DD 0x4FA3 \ + 0x65C5 0x5C65 0x5C61 0x7F15 0x8651 0x6C2F 0x5F8B 0x7387 \ + 0x6EE4 0x7EFF 0x5CE6 0x631B 0x5B6A 0x6EE6 0x5375 0x4E71 \ + 0x63A0 0x7565 0x62A1 0x8F6E 0x4F26 0x4ED1 0x6CA6 0x7EB6 \ + 0x8BBA 0x841D 0x87BA 0x7F57 0x903B 0x9523 0x7BA9 0x9AA1 \ + 0x88F8 0x843D 0x6D1B 0x9A86 0x7EDC 0x5988 0x9EBB 0x739B \ + 0x7801 0x8682 0x9A6C 0x9A82 0x561B 0x5417 0x57CB 0x4E70 \ + 0x9EA6 0x5356 0x8FC8 0x8109 0x7792 0x9992 0x86EE 0x6EE1 \ + 0x8513 0x66FC 0x6162 0x6F2B 0x8C29 0x8292 0x832B 0x76F2 \ + 0x6C13 0x5FD9 0x83BD 0x732B 0x8305 0x951A 0x6BDB 0x77DB \ + 0x94C6 0x536F 0x8302 0x5192 0x5E3D 0x8C8C 0x8D38 0x4E48 \ + 0x73AB 0x679A 0x6885 0x9176 0x9709 0x7164 0x6CA1 0x7709 \ + 0x5A92 0x9541 0x6BCF 0x7F8E 0x6627 0x5BD0 0x59B9 0x5A9A \ + 0x95E8 0x95F7 0x4EEC 0x840C 0x8499 0x6AAC 0x76DF 0x9530 \ + 0x731B 0x68A6 0x5B5F 0x772F 0x919A 0x9761 0x7CDC 0x8FF7 \ + 0x8C1C 0x5F25 0x7C73 0x79D8 0x89C5 0x6CCC 0x871C 0x5BC6 \ + 0x5E42 0x68C9 0x7720 0x7EF5 0x5195 0x514D 0x52C9 0x5A29 \ + 0x7F05 0x9762 0x82D7 0x63CF 0x7784 0x85D0 0x79D2 0x6E3A \ + 0x5E99 0x5999 0x8511 0x706D 0x6C11 0x62BF 0x76BF 0x654F \ + 0x60AF 0x95FD 0x660E 0x879F 0x9E23 0x94ED 0x540D 0x547D \ + 0x8C2C 0x6478 0x6479 0x8611 0x6A21 0x819C 0x78E8 0x6469 \ + 0x9B54 0x62B9 0x672B 0x83AB 0x58A8 0x9ED8 0x6CAB 0x6F20 \ + 0x5BDE 0x964C 0x8C0B 0x725F 0x67D0 0x62C7 0x7261 0x4EA9 \ + 0x59C6 0x6BCD 0x5893 0x66AE 0x5E55 0x52DF 0x6155 0x6728 \ + 0x76EE 0x7766 0x7267 0x7A46 0x62FF 0x54EA 0x5450 0x94A0 +14 0x90A3 0x5A1C 0x7EB3 0x6C16 0x4E43 0x5976 0x8010 0x5948 \ + 0x5357 0x7537 0x96BE 0x56CA 0x6320 0x8111 0x607C 0x95F9 \ + 0x6DD6 0x5462 0x9981 0x5185 0x5AE9 0x80FD 0x59AE 0x9713 \ + 0x502A 0x6CE5 0x5C3C 0x62DF 0x4F60 0x533F 0x817B 0x9006 \ + 0x6EBA 0x852B 0x62C8 0x5E74 0x78BE 0x64B5 0x637B 0x5FF5 \ + 0x5A18 0x917F 0x9E1F 0x5C3F 0x634F 0x8042 0x5B7D 0x556E \ + 0x954A 0x954D 0x6D85 0x60A8 0x67E0 0x72DE 0x51DD 0x5B81 \ + 0x62E7 0x6CDE 0x725B 0x626D 0x94AE 0x7EBD 0x8113 0x6D53 \ + 0x519C 0x5F04 0x5974 0x52AA 0x6012 0x5973 0x6696 0x8650 \ + 0x759F 0x632A 0x61E6 0x7CEF 0x8BFA 0x54E6 0x6B27 0x9E25 \ + 0x6BB4 0x85D5 0x5455 0x5076 0x6CA4 0x556A 0x8DB4 0x722C \ + 0x5E15 0x6015 0x7436 0x62CD 0x6392 0x724C 0x5F98 0x6E43 \ + 0x6D3E 0x6500 0x6F58 0x76D8 0x78D0 0x76FC 0x7554 0x5224 \ + 0x53DB 0x4E53 0x5E9E 0x65C1 0x802A 0x80D6 0x629B 0x5486 \ + 0x5228 0x70AE 0x888D 0x8DD1 0x6CE1 0x5478 0x80DA 0x57F9 \ + 0x88F4 0x8D54 0x966A 0x914D 0x4F69 0x6C9B 0x55B7 0x76C6 \ + 0x7830 0x62A8 0x70F9 0x6F8E 0x5F6D 0x84EC 0x68DA 0x787C \ + 0x7BF7 0x81A8 0x670B 0x9E4F 0x6367 0x78B0 0x576F 0x7812 \ + 0x9739 0x6279 0x62AB 0x5288 0x7435 0x6BD7 0x5564 0x813E \ + 0x75B2 0x76AE 0x5339 0x75DE 0x50FB 0x5C41 0x8B6C 0x7BC7 \ + 0x504F 0x7247 0x9A97 0x98D8 0x6F02 0x74E2 0x7968 0x6487 \ + 0x77A5 0x62FC 0x9891 0x8D2B 0x54C1 0x8058 0x4E52 0x576A \ + 0x82F9 0x840D 0x5E73 0x51ED 0x74F6 0x8BC4 0x5C4F 0x5761 \ + 0x6CFC 0x9887 0x5A46 0x7834 0x9B44 0x8FEB 0x7C95 0x5256 \ + 0x6251 0x94FA 0x4EC6 0x8386 0x8461 0x83E9 0x84B2 0x57D4 \ + 0x6734 0x5703 0x666E 0x6D66 0x8C31 0x66DD 0x7011 0x671F \ + 0x6B3A 0x6816 0x621A 0x59BB 0x4E03 0x51C4 0x6F06 0x67D2 \ + 0x6C8F 0x5176 0x68CB 0x5947 0x6B67 0x7566 0x5D0E 0x8110 \ + 0x9F50 0x65D7 0x7948 0x7941 0x9A91 0x8D77 0x5C82 0x4E5E \ + 0x4F01 0x542F 0x5951 0x780C 0x5668 0x6C14 0x8FC4 0x5F03 \ + 0x6C7D 0x6CE3 0x8BAB 0x6390 0x6070 0x6D3D 0x7275 0x6266 \ + 0x948E 0x94C5 0x5343 0x8FC1 0x7B7E 0x4EDF 0x8C26 0x4E7E +15 0x9ED4 0x94B1 0x94B3 0x524D 0x6F5C 0x9063 0x6D45 0x8C34 \ + 0x5811 0x5D4C 0x6B20 0x6B49 0x67AA 0x545B 0x8154 0x7F8C \ + 0x5899 0x8537 0x5F3A 0x62A2 0x6A47 0x9539 0x6572 0x6084 \ + 0x6865 0x77A7 0x4E54 0x4FA8 0x5DE7 0x9798 0x64AC 0x7FD8 \ + 0x5CED 0x4FCF 0x7A8D 0x5207 0x8304 0x4E14 0x602F 0x7A83 \ + 0x94A6 0x4FB5 0x4EB2 0x79E6 0x7434 0x52E4 0x82B9 0x64D2 \ + 0x79BD 0x5BDD 0x6C81 0x9752 0x8F7B 0x6C22 0x503E 0x537F \ + 0x6E05 0x64CE 0x6674 0x6C30 0x60C5 0x9877 0x8BF7 0x5E86 \ + 0x743C 0x7A77 0x79CB 0x4E18 0x90B1 0x7403 0x6C42 0x56DA \ + 0x914B 0x6CC5 0x8D8B 0x533A 0x86C6 0x66F2 0x8EAF 0x5C48 \ + 0x9A71 0x6E20 0x53D6 0x5A36 0x9F8B 0x8DA3 0x53BB 0x5708 \ + 0x98A7 0x6743 0x919B 0x6CC9 0x5168 0x75CA 0x62F3 0x72AC \ + 0x5238 0x529D 0x7F3A 0x7094 0x7638 0x5374 0x9E4A 0x69B7 \ + 0x786E 0x96C0 0x88D9 0x7FA4 0x7136 0x71C3 0x5189 0x67D3 \ + 0x74E4 0x58E4 0x6518 0x56B7 0x8BA9 0x9976 0x6270 0x7ED5 \ + 0x60F9 0x70ED 0x58EC 0x4EC1 0x4EBA 0x5FCD 0x97E7 0x4EFB \ + 0x8BA4 0x5203 0x598A 0x7EAB 0x6254 0x4ECD 0x65E5 0x620E \ + 0x8338 0x84C9 0x8363 0x878D 0x7194 0x6EB6 0x5BB9 0x7ED2 \ + 0x5197 0x63C9 0x67D4 0x8089 0x8339 0x8815 0x5112 0x5B7A \ + 0x5982 0x8FB1 0x4E73 0x6C5D 0x5165 0x8925 0x8F6F 0x962E \ + 0x854A 0x745E 0x9510 0x95F0 0x6DA6 0x82E5 0x5F31 0x6492 \ + 0x6D12 0x8428 0x816E 0x9CC3 0x585E 0x8D5B 0x4E09 0x53C1 \ + 0x4F1E 0x6563 0x6851 0x55D3 0x4E27 0x6414 0x9A9A 0x626B \ + 0x5AC2 0x745F 0x8272 0x6DA9 0x68EE 0x50E7 0x838E 0x7802 \ + 0x6740 0x5239 0x6C99 0x7EB1 0x50BB 0x5565 0x715E 0x7B5B \ + 0x6652 0x73CA 0x82EB 0x6749 0x5C71 0x5220 0x717D 0x886B \ + 0x95EA 0x9655 0x64C5 0x8D61 0x81B3 0x5584 0x6C55 0x6247 \ + 0x7F2E 0x5892 0x4F24 0x5546 0x8D4F 0x664C 0x4E0A 0x5C1A \ + 0x88F3 0x68A2 0x634E 0x7A0D 0x70E7 0x828D 0x52FA 0x97F6 \ + 0x5C11 0x54E8 0x90B5 0x7ECD 0x5962 0x8D4A 0x86C7 0x820C \ + 0x820D 0x8D66 0x6444 0x5C04 0x6151 0x6D89 0x793E 0x8BBE \ + 0x7837 0x7533 0x547B 0x4F38 0x8EAB 0x6DF1 0x5A20 0x7EC5 +16 0x795E 0x6C88 0x5BA1 0x5A76 0x751A 0x80BE 0x614E 0x6E17 \ + 0x58F0 0x751F 0x7525 0x7272 0x5347 0x7EF3 0x7701 0x76DB \ + 0x5269 0x80DC 0x5723 0x5E08 0x5931 0x72EE 0x65BD 0x6E7F \ + 0x8BD7 0x5C38 0x8671 0x5341 0x77F3 0x62FE 0x65F6 0x4EC0 \ + 0x98DF 0x8680 0x5B9E 0x8BC6 0x53F2 0x77E2 0x4F7F 0x5C4E \ + 0x9A76 0x59CB 0x5F0F 0x793A 0x58EB 0x4E16 0x67FF 0x4E8B \ + 0x62ED 0x8A93 0x901D 0x52BF 0x662F 0x55DC 0x566C 0x9002 \ + 0x4ED5 0x4F8D 0x91CA 0x9970 0x6C0F 0x5E02 0x6043 0x5BA4 \ + 0x89C6 0x8BD5 0x6536 0x624B 0x9996 0x5B88 0x5BFF 0x6388 \ + 0x552E 0x53D7 0x7626 0x517D 0x852C 0x67A2 0x68B3 0x6B8A \ + 0x6292 0x8F93 0x53D4 0x8212 0x6DD1 0x758F 0x4E66 0x8D4E \ + 0x5B70 0x719F 0x85AF 0x6691 0x66D9 0x7F72 0x8700 0x9ECD \ + 0x9F20 0x5C5E 0x672F 0x8FF0 0x6811 0x675F 0x620D 0x7AD6 \ + 0x5885 0x5EB6 0x6570 0x6F31 0x6055 0x5237 0x800D 0x6454 \ + 0x8870 0x7529 0x5E05 0x6813 0x62F4 0x971C 0x53CC 0x723D \ + 0x8C01 0x6C34 0x7761 0x7A0E 0x542E 0x77AC 0x987A 0x821C \ + 0x8BF4 0x7855 0x6714 0x70C1 0x65AF 0x6495 0x5636 0x601D \ + 0x79C1 0x53F8 0x4E1D 0x6B7B 0x8086 0x5BFA 0x55E3 0x56DB \ + 0x4F3A 0x4F3C 0x9972 0x5DF3 0x677E 0x8038 0x6002 0x9882 \ + 0x9001 0x5B8B 0x8BBC 0x8BF5 0x641C 0x8258 0x64DE 0x55FD \ + 0x82CF 0x9165 0x4FD7 0x7D20 0x901F 0x7C9F 0x50F3 0x5851 \ + 0x6EAF 0x5BBF 0x8BC9 0x8083 0x9178 0x849C 0x7B97 0x867D \ + 0x968B 0x968F 0x7EE5 0x9AD3 0x788E 0x5C81 0x7A57 0x9042 \ + 0x96A7 0x795F 0x5B59 0x635F 0x7B0B 0x84D1 0x68AD 0x5506 \ + 0x7F29 0x7410 0x7D22 0x9501 0x6240 0x584C 0x4ED6 0x5B83 \ + 0x5979 0x5854 0x736D 0x631E 0x8E4B 0x8E0F 0x80CE 0x82D4 \ + 0x62AC 0x53F0 0x6CF0 0x915E 0x592A 0x6001 0x6C70 0x574D \ + 0x644A 0x8D2A 0x762B 0x6EE9 0x575B 0x6A80 0x75F0 0x6F6D \ + 0x8C2D 0x8C08 0x5766 0x6BEF 0x8892 0x78B3 0x63A2 0x53F9 \ + 0x70AD 0x6C64 0x5858 0x642A 0x5802 0x68E0 0x819B 0x5510 \ + 0x7CD6 0x5018 0x8EBA 0x6DCC 0x8D9F 0x70EB 0x638F 0x6D9B \ + 0x6ED4 0x7EE6 0x8404 0x6843 0x9003 0x6DD8 0x9676 0x8BA8 +17 0x5957 0x7279 0x85E4 0x817E 0x75BC 0x8A8A 0x68AF 0x5254 \ + 0x8E22 0x9511 0x63D0 0x9898 0x8E44 0x557C 0x4F53 0x66FF \ + 0x568F 0x60D5 0x6D95 0x5243 0x5C49 0x5929 0x6DFB 0x586B \ + 0x7530 0x751C 0x606C 0x8214 0x8146 0x6311 0x6761 0x8FE2 \ + 0x773A 0x8DF3 0x8D34 0x94C1 0x5E16 0x5385 0x542C 0x70C3 \ + 0x6C40 0x5EF7 0x505C 0x4EAD 0x5EAD 0x633A 0x8247 0x901A \ + 0x6850 0x916E 0x77B3 0x540C 0x94DC 0x5F64 0x7AE5 0x6876 \ + 0x6345 0x7B52 0x7EDF 0x75DB 0x5077 0x6295 0x5934 0x900F \ + 0x51F8 0x79C3 0x7A81 0x56FE 0x5F92 0x9014 0x6D82 0x5C60 \ + 0x571F 0x5410 0x5154 0x6E4D 0x56E2 0x63A8 0x9893 0x817F \ + 0x8715 0x892A 0x9000 0x541E 0x5C6F 0x81C0 0x62D6 0x6258 \ + 0x8131 0x9E35 0x9640 0x9A6E 0x9A7C 0x692D 0x59A5 0x62D3 \ + 0x553E 0x6316 0x54C7 0x86D9 0x6D3C 0x5A03 0x74E6 0x889C \ + 0x6B6A 0x5916 0x8C4C 0x5F2F 0x6E7E 0x73A9 0x987D 0x4E38 \ + 0x70F7 0x5B8C 0x7897 0x633D 0x665A 0x7696 0x60CB 0x5B9B \ + 0x5A49 0x4E07 0x8155 0x6C6A 0x738B 0x4EA1 0x6789 0x7F51 \ + 0x5F80 0x65FA 0x671B 0x5FD8 0x5984 0x5A01 0x5DCD 0x5FAE \ + 0x5371 0x97E6 0x8FDD 0x6845 0x56F4 0x552F 0x60DF 0x4E3A \ + 0x6F4D 0x7EF4 0x82C7 0x840E 0x59D4 0x4F1F 0x4F2A 0x5C3E \ + 0x7EAC 0x672A 0x851A 0x5473 0x754F 0x80C3 0x5582 0x9B4F \ + 0x4F4D 0x6E2D 0x8C13 0x5C09 0x6170 0x536B 0x761F 0x6E29 \ + 0x868A 0x6587 0x95FB 0x7EB9 0x543B 0x7A33 0x7D0A 0x95EE \ + 0x55E1 0x7FC1 0x74EE 0x631D 0x8717 0x6DA1 0x7A9D 0x6211 \ + 0x65A1 0x5367 0x63E1 0x6C83 0x5DEB 0x545C 0x94A8 0x4E4C \ + 0x6C61 0x8BEC 0x5C4B 0x65E0 0x829C 0x68A7 0x543E 0x5434 \ + 0x6BCB 0x6B66 0x4E94 0x6342 0x5348 0x821E 0x4F0D 0x4FAE \ + 0x575E 0x620A 0x96FE 0x6664 0x7269 0x52FF 0x52A1 0x609F \ + 0x8BEF 0x6614 0x7199 0x6790 0x897F 0x7852 0x77FD 0x6670 \ + 0x563B 0x5438 0x9521 0x727A 0x7A00 0x606F 0x5E0C 0x6089 \ + 0x819D 0x5915 0x60DC 0x7184 0x70EF 0x6EAA 0x6C50 0x7280 \ + 0x6A84 0x88AD 0x5E2D 0x4E60 0x5AB3 0x559C 0x94E3 0x6D17 \ + 0x7CFB 0x9699 0x620F 0x7EC6 0x778E 0x867E 0x5323 0x971E +18 0x8F96 0x6687 0x5CE1 0x4FA0 0x72ED 0x4E0B 0x53A6 0x590F \ + 0x5413 0x6380 0x9528 0x5148 0x4ED9 0x9C9C 0x7EA4 0x54B8 \ + 0x8D24 0x8854 0x8237 0x95F2 0x6D8E 0x5F26 0x5ACC 0x663E \ + 0x9669 0x73B0 0x732E 0x53BF 0x817A 0x9985 0x7FA1 0x5BAA \ + 0x9677 0x9650 0x7EBF 0x76F8 0x53A2 0x9576 0x9999 0x7BB1 \ + 0x8944 0x6E58 0x4E61 0x7FD4 0x7965 0x8BE6 0x60F3 0x54CD \ + 0x4EAB 0x9879 0x5DF7 0x6A61 0x50CF 0x5411 0x8C61 0x8427 \ + 0x785D 0x9704 0x524A 0x54EE 0x56A3 0x9500 0x6D88 0x5BB5 \ + 0x6DC6 0x6653 0x5C0F 0x5B5D 0x6821 0x8096 0x5578 0x7B11 \ + 0x6548 0x6954 0x4E9B 0x6B47 0x874E 0x978B 0x534F 0x631F \ + 0x643A 0x90AA 0x659C 0x80C1 0x8C10 0x5199 0x68B0 0x5378 \ + 0x87F9 0x61C8 0x6CC4 0x6CFB 0x8C22 0x5C51 0x85AA 0x82AF \ + 0x950C 0x6B23 0x8F9B 0x65B0 0x5FFB 0x5FC3 0x4FE1 0x8845 \ + 0x661F 0x8165 0x7329 0x60FA 0x5174 0x5211 0x578B 0x5F62 \ + 0x90A2 0x884C 0x9192 0x5E78 0x674F 0x6027 0x59D3 0x5144 \ + 0x51F6 0x80F8 0x5308 0x6C79 0x96C4 0x718A 0x4F11 0x4FEE \ + 0x7F9E 0x673D 0x55C5 0x9508 0x79C0 0x8896 0x7EE3 0x589F \ + 0x620C 0x9700 0x865A 0x5618 0x987B 0x5F90 0x8BB8 0x84C4 \ + 0x9157 0x53D9 0x65ED 0x5E8F 0x755C 0x6064 0x7D6E 0x5A7F \ + 0x7EEA 0x7EED 0x8F69 0x55A7 0x5BA3 0x60AC 0x65CB 0x7384 \ + 0x9009 0x7663 0x7729 0x7EDA 0x9774 0x859B 0x5B66 0x7A74 \ + 0x96EA 0x8840 0x52CB 0x718F 0x5FAA 0x65EC 0x8BE2 0x5BFB \ + 0x9A6F 0x5DE1 0x6B89 0x6C5B 0x8BAD 0x8BAF 0x900A 0x8FC5 \ + 0x538B 0x62BC 0x9E26 0x9E2D 0x5440 0x4E2B 0x82BD 0x7259 \ + 0x869C 0x5D16 0x8859 0x6DAF 0x96C5 0x54D1 0x4E9A 0x8BB6 \ + 0x7109 0x54BD 0x9609 0x70DF 0x6DF9 0x76D0 0x4E25 0x7814 \ + 0x8712 0x5CA9 0x5EF6 0x8A00 0x989C 0x960E 0x708E 0x6CBF \ + 0x5944 0x63A9 0x773C 0x884D 0x6F14 0x8273 0x5830 0x71D5 \ + 0x538C 0x781A 0x96C1 0x5501 0x5F66 0x7130 0x5BB4 0x8C1A \ + 0x9A8C 0x6B83 0x592E 0x9E2F 0x79E7 0x6768 0x626C 0x4F6F \ + 0x75A1 0x7F8A 0x6D0B 0x9633 0x6C27 0x4EF0 0x75D2 0x517B \ + 0x6837 0x6F3E 0x9080 0x8170 0x5996 0x7476 0x6447 0x5C27 +19 0x9065 0x7A91 0x8C23 0x59DA 0x54AC 0x8200 0x836F 0x8981 \ + 0x8000 0x6930 0x564E 0x8036 0x7237 0x91CE 0x51B6 0x4E5F \ + 0x9875 0x6396 0x4E1A 0x53F6 0x66F3 0x814B 0x591C 0x6DB2 \ + 0x4E00 0x58F9 0x533B 0x63D6 0x94F1 0x4F9D 0x4F0A 0x8863 \ + 0x9890 0x5937 0x9057 0x79FB 0x4EEA 0x80F0 0x7591 0x6C82 \ + 0x5B9C 0x59E8 0x5F5D 0x6905 0x8681 0x501A 0x5DF2 0x4E59 \ + 0x77E3 0x4EE5 0x827A 0x6291 0x6613 0x9091 0x5C79 0x4EBF \ + 0x5F79 0x81C6 0x9038 0x8084 0x75AB 0x4EA6 0x88D4 0x610F \ + 0x6BC5 0x5FC6 0x4E49 0x76CA 0x6EA2 0x8BE3 0x8BAE 0x8C0A \ + 0x8BD1 0x5F02 0x7FFC 0x7FCC 0x7ECE 0x8335 0x836B 0x56E0 \ + 0x6BB7 0x97F3 0x9634 0x59FB 0x541F 0x94F6 0x6DEB 0x5BC5 \ + 0x996E 0x5C39 0x5F15 0x9690 0x5370 0x82F1 0x6A31 0x5A74 \ + 0x9E70 0x5E94 0x7F28 0x83B9 0x8424 0x8425 0x8367 0x8747 \ + 0x8FCE 0x8D62 0x76C8 0x5F71 0x9896 0x786C 0x6620 0x54DF \ + 0x62E5 0x4F63 0x81C3 0x75C8 0x5EB8 0x96CD 0x8E0A 0x86F9 \ + 0x548F 0x6CF3 0x6D8C 0x6C38 0x607F 0x52C7 0x7528 0x5E7D \ + 0x4F18 0x60A0 0x5FE7 0x5C24 0x7531 0x90AE 0x94C0 0x72B9 \ + 0x6CB9 0x6E38 0x9149 0x6709 0x53CB 0x53F3 0x4F51 0x91C9 \ + 0x8BF1 0x53C8 0x5E7C 0x8FC2 0x6DE4 0x4E8E 0x76C2 0x6986 \ + 0x865E 0x611A 0x8206 0x4F59 0x4FDE 0x903E 0x9C7C 0x6109 \ + 0x6E1D 0x6E14 0x9685 0x4E88 0x5A31 0x96E8 0x4E0E 0x5C7F \ + 0x79B9 0x5B87 0x8BED 0x7FBD 0x7389 0x57DF 0x828B 0x90C1 \ + 0x5401 0x9047 0x55BB 0x5CEA 0x5FA1 0x6108 0x6B32 0x72F1 \ + 0x80B2 0x8A89 0x6D74 0x5BD3 0x88D5 0x9884 0x8C6B 0x9A6D \ + 0x9E33 0x6E0A 0x51A4 0x5143 0x57A3 0x8881 0x539F 0x63F4 \ + 0x8F95 0x56ED 0x5458 0x5706 0x733F 0x6E90 0x7F18 0x8FDC \ + 0x82D1 0x613F 0x6028 0x9662 0x66F0 0x7EA6 0x8D8A 0x8DC3 \ + 0x94A5 0x5CB3 0x7CA4 0x6708 0x60A6 0x9605 0x8018 0x4E91 \ + 0x90E7 0x5300 0x9668 0x5141 0x8FD0 0x8574 0x915D 0x6655 \ + 0x97F5 0x5B55 0x531D 0x7838 0x6742 0x683D 0x54C9 0x707E \ + 0x5BB0 0x8F7D 0x518D 0x5728 0x54B1 0x6512 0x6682 0x8D5E \ + 0x8D43 0x810F 0x846C 0x906D 0x7CDF 0x51FF 0x85FB 0x67A3 +20 0x65E9 0x6FA1 0x86A4 0x8E81 0x566A 0x9020 0x7682 0x7076 \ + 0x71E5 0x8D23 0x62E9 0x5219 0x6CFD 0x8D3C 0x600E 0x589E \ + 0x618E 0x66FE 0x8D60 0x624E 0x55B3 0x6E23 0x672D 0x8F67 \ + 0x94E1 0x95F8 0x7728 0x6805 0x69A8 0x548B 0x4E4D 0x70B8 \ + 0x8BC8 0x6458 0x658B 0x5B85 0x7A84 0x503A 0x5BE8 0x77BB \ + 0x6BE1 0x8A79 0x7C98 0x6CBE 0x76CF 0x65A9 0x8F97 0x5D2D \ + 0x5C55 0x8638 0x6808 0x5360 0x6218 0x7AD9 0x6E5B 0x7EFD \ + 0x6A1F 0x7AE0 0x5F70 0x6F33 0x5F20 0x638C 0x6DA8 0x6756 \ + 0x4E08 0x5E10 0x8D26 0x4ED7 0x80C0 0x7634 0x969C 0x62DB \ + 0x662D 0x627E 0x6CBC 0x8D75 0x7167 0x7F69 0x5146 0x8087 \ + 0x53EC 0x906E 0x6298 0x54F2 0x86F0 0x8F99 0x8005 0x9517 \ + 0x8517 0x8FD9 0x6D59 0x73CD 0x659F 0x771F 0x7504 0x7827 \ + 0x81FB 0x8D1E 0x9488 0x4FA6 0x6795 0x75B9 0x8BCA 0x9707 \ + 0x632F 0x9547 0x9635 0x84B8 0x6323 0x7741 0x5F81 0x72F0 \ + 0x4E89 0x6014 0x6574 0x62EF 0x6B63 0x653F 0x5E27 0x75C7 \ + 0x90D1 0x8BC1 0x829D 0x679D 0x652F 0x5431 0x8718 0x77E5 \ + 0x80A2 0x8102 0x6C41 0x4E4B 0x7EC7 0x804C 0x76F4 0x690D \ + 0x6B96 0x6267 0x503C 0x4F84 0x5740 0x6307 0x6B62 0x8DBE \ + 0x53EA 0x65E8 0x7EB8 0x5FD7 0x631A 0x63B7 0x81F3 0x81F4 \ + 0x7F6E 0x5E1C 0x5CD9 0x5236 0x667A 0x79E9 0x7A1A 0x8D28 \ + 0x7099 0x75D4 0x6EDE 0x6CBB 0x7A92 0x4E2D 0x76C5 0x5FE0 \ + 0x949F 0x8877 0x7EC8 0x79CD 0x80BF 0x91CD 0x4EF2 0x4F17 \ + 0x821F 0x5468 0x5DDE 0x6D32 0x8BCC 0x7CA5 0x8F74 0x8098 \ + 0x5E1A 0x5492 0x76B1 0x5B99 0x663C 0x9AA4 0x73E0 0x682A \ + 0x86DB 0x6731 0x732A 0x8BF8 0x8BDB 0x9010 0x7AF9 0x70DB \ + 0x716E 0x62C4 0x77A9 0x5631 0x4E3B 0x8457 0x67F1 0x52A9 \ + 0x86C0 0x8D2E 0x94F8 0x7B51 0x4F4F 0x6CE8 0x795D 0x9A7B \ + 0x6293 0x722A 0x62FD 0x4E13 0x7816 0x8F6C 0x64B0 0x8D5A \ + 0x7BC6 0x6869 0x5E84 0x88C5 0x5986 0x649E 0x58EE 0x72B6 \ + 0x690E 0x9525 0x8FFD 0x8D58 0x5760 0x7F00 0x8C06 0x51C6 \ + 0x6349 0x62D9 0x5353 0x684C 0x7422 0x8301 0x914C 0x5544 \ + 0x7740 0x707C 0x6D4A 0x5179 0x54A8 0x8D44 0x59FF 0x6ECB +21 0x6DC4 0x5B5C 0x7D2B 0x4ED4 0x7C7D 0x6ED3 0x5B50 0x81EA \ + 0x6E0D 0x5B57 0x9B03 0x68D5 0x8E2A 0x5B97 0x7EFC 0x603B \ + 0x7EB5 0x90B9 0x8D70 0x594F 0x63CD 0x79DF 0x8DB3 0x5352 \ + 0x65CF 0x7956 0x8BC5 0x963B 0x7EC4 0x94BB 0x7E82 0x5634 \ + 0x9189 0x6700 0x7F6A 0x5C0A 0x9075 0x6628 0x5DE6 0x4F50 \ + 0x67DE 0x505A 0x4F5C 0x5750 0x5EA7 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x4E8D 0x4E0C 0x5140 0x4E10 0x5EFF 0x5345 \ + 0x4E15 0x4E98 0x4E1E 0x9B32 0x5B6C 0x5669 0x4E28 0x79BA \ + 0x4E3F 0x5315 0x4E47 0x592D 0x723B 0x536E 0x6C10 0x56DF \ + 0x80E4 0x9997 0x6BD3 0x777E 0x9F17 0x4E36 0x4E9F 0x9F10 \ + 0x4E5C 0x4E69 0x4E93 0x8288 0x5B5B 0x556C 0x560F 0x4EC4 \ + 0x538D 0x539D 0x53A3 0x53A5 0x53AE 0x9765 0x8D5D 0x531A \ + 0x53F5 0x5326 0x532E 0x533E 0x8D5C 0x5366 0x5363 0x5202 \ + 0x5208 0x520E 0x522D 0x5233 0x523F 0x5240 0x524C 0x525E \ + 0x5261 0x525C 0x84AF 0x527D 0x5282 0x5281 0x5290 0x5293 \ + 0x5182 0x7F54 0x4EBB 0x4EC3 0x4EC9 0x4EC2 0x4EE8 0x4EE1 \ + 0x4EEB 0x4EDE 0x4F1B 0x4EF3 0x4F22 0x4F64 0x4EF5 0x4F25 \ + 0x4F27 0x4F09 0x4F2B 0x4F5E 0x4F67 0x6538 0x4F5A 0x4F5D \ + 0x4F5F 0x4F57 0x4F32 0x4F3D 0x4F76 0x4F74 0x4F91 0x4F89 \ + 0x4F83 0x4F8F 0x4F7E 0x4F7B 0x4FAA 0x4F7C 0x4FAC 0x4F94 \ + 0x4FE6 0x4FE8 0x4FEA 0x4FC5 0x4FDA 0x4FE3 0x4FDC 0x4FD1 \ + 0x4FDF 0x4FF8 0x5029 0x504C 0x4FF3 0x502C 0x500F 0x502E \ + 0x502D 0x4FFE 0x501C 0x500C 0x5025 0x5028 0x507E 0x5043 \ + 0x5055 0x5048 0x504E 0x506C 0x507B 0x50A5 0x50A7 0x50A9 \ + 0x50BA 0x50D6 0x5106 0x50ED 0x50EC 0x50E6 0x50EE 0x5107 \ + 0x510B 0x4EDD 0x6C3D 0x4F58 0x4F65 0x4FCE 0x9FA0 0x6C46 \ + 0x7C74 0x516E 0x5DFD 0x9EC9 0x9998 0x5181 0x5914 0x52F9 \ + 0x530D 0x8A07 0x5310 0x51EB 0x5919 0x5155 0x4EA0 0x5156 \ + 0x4EB3 0x886E 0x88A4 0x4EB5 0x8114 0x88D2 0x7980 0x5B34 \ + 0x8803 0x7FB8 0x51AB 0x51B1 0x51BD 0x51BC 0x51C7 0x5196 \ + 0x51A2 0x51A5 0x8BA0 0x8BA6 0x8BA7 0x8BAA 0x8BB4 0x8BB5 \ + 0x8BB7 0x8BC2 0x8BC3 0x8BCB 0x8BCF 0x8BCE 0x8BD2 0x8BD3 +22 0x8BD4 0x8BD6 0x8BD8 0x8BD9 0x8BDC 0x8BDF 0x8BE0 0x8BE4 \ + 0x8BE8 0x8BE9 0x8BEE 0x8BF0 0x8BF3 0x8BF6 0x8BF9 0x8BFC \ + 0x8BFF 0x8C00 0x8C02 0x8C04 0x8C07 0x8C0C 0x8C0F 0x8C11 \ + 0x8C12 0x8C14 0x8C15 0x8C16 0x8C19 0x8C1B 0x8C18 0x8C1D \ + 0x8C1F 0x8C20 0x8C21 0x8C25 0x8C27 0x8C2A 0x8C2B 0x8C2E \ + 0x8C2F 0x8C32 0x8C33 0x8C35 0x8C36 0x5369 0x537A 0x961D \ + 0x9622 0x9621 0x9631 0x962A 0x963D 0x963C 0x9642 0x9649 \ + 0x9654 0x965F 0x9667 0x966C 0x9672 0x9674 0x9688 0x968D \ + 0x9697 0x96B0 0x9097 0x909B 0x909D 0x9099 0x90AC 0x90A1 \ + 0x90B4 0x90B3 0x90B6 0x90BA 0x90B8 0x90B0 0x90CF 0x90C5 \ + 0x90BE 0x90D0 0x90C4 0x90C7 0x90D3 0x90E6 0x90E2 0x90DC \ + 0x90D7 0x90DB 0x90EB 0x90EF 0x90FE 0x9104 0x9122 0x911E \ + 0x9123 0x9131 0x912F 0x9139 0x9143 0x9146 0x520D 0x5942 \ + 0x52A2 0x52AC 0x52AD 0x52BE 0x54FF 0x52D0 0x52D6 0x52F0 \ + 0x53DF 0x71EE 0x77CD 0x5EF4 0x51F5 0x51FC 0x9B2F 0x53B6 \ + 0x5F01 0x755A 0x5DEF 0x574C 0x57A9 0x57A1 0x587E 0x58BC \ + 0x58C5 0x58D1 0x5729 0x572C 0x572A 0x5733 0x5739 0x572E \ + 0x572F 0x575C 0x573B 0x5742 0x5769 0x5785 0x576B 0x5786 \ + 0x577C 0x577B 0x5768 0x576D 0x5776 0x5773 0x57AD 0x57A4 \ + 0x578C 0x57B2 0x57CF 0x57A7 0x57B4 0x5793 0x57A0 0x57D5 \ + 0x57D8 0x57DA 0x57D9 0x57D2 0x57B8 0x57F4 0x57EF 0x57F8 \ + 0x57E4 0x57DD 0x580B 0x580D 0x57FD 0x57ED 0x5800 0x581E \ + 0x5819 0x5844 0x5820 0x5865 0x586C 0x5881 0x5889 0x589A \ + 0x5880 0x99A8 0x9F19 0x61FF 0x8279 0x827D 0x827F 0x828F \ + 0x828A 0x82A8 0x8284 0x828E 0x8291 0x8297 0x8299 0x82AB \ + 0x82B8 0x82BE 0x82B0 0x82C8 0x82CA 0x82E3 0x8298 0x82B7 \ + 0x82AE 0x82CB 0x82CC 0x82C1 0x82A9 0x82B4 0x82A1 0x82AA \ + 0x829F 0x82C4 0x82CE 0x82A4 0x82E1 0x8309 0x82F7 0x82E4 \ + 0x830F 0x8307 0x82DC 0x82F4 0x82D2 0x82D8 0x830C 0x82FB \ + 0x82D3 0x8311 0x831A 0x8306 0x8314 0x8315 0x82E0 0x82D5 \ + 0x831C 0x8351 0x835B 0x835C 0x8308 0x8392 0x833C 0x8334 \ + 0x8331 0x839B 0x835E 0x832F 0x834F 0x8347 0x8343 0x835F +23 0x8340 0x8317 0x8360 0x832D 0x833A 0x8333 0x8366 0x8365 \ + 0x8368 0x831B 0x8369 0x836C 0x836A 0x836D 0x836E 0x83B0 \ + 0x8378 0x83B3 0x83B4 0x83A0 0x83AA 0x8393 0x839C 0x8385 \ + 0x837C 0x83B6 0x83A9 0x837D 0x83B8 0x837B 0x8398 0x839E \ + 0x83A8 0x83BA 0x83BC 0x83C1 0x8401 0x83E5 0x83D8 0x5807 \ + 0x8418 0x840B 0x83DD 0x83FD 0x83D6 0x841C 0x8438 0x8411 \ + 0x8406 0x83D4 0x83DF 0x840F 0x8403 0x83F8 0x83F9 0x83EA \ + 0x83C5 0x83C0 0x8426 0x83F0 0x83E1 0x845C 0x8451 0x845A \ + 0x8459 0x8473 0x8487 0x8488 0x847A 0x8489 0x8478 0x843C \ + 0x8446 0x8469 0x8476 0x848C 0x848E 0x8431 0x846D 0x84C1 \ + 0x84CD 0x84D0 0x84E6 0x84BD 0x84D3 0x84CA 0x84BF 0x84BA \ + 0x84E0 0x84A1 0x84B9 0x84B4 0x8497 0x84E5 0x84E3 0x850C \ + 0x750D 0x8538 0x84F0 0x8539 0x851F 0x853A 0x8556 0x853B \ + 0x84FF 0x84FC 0x8559 0x8548 0x8568 0x8564 0x855E 0x857A \ + 0x77A2 0x8543 0x8572 0x857B 0x85A4 0x85A8 0x8587 0x858F \ + 0x8579 0x85AE 0x859C 0x8585 0x85B9 0x85B7 0x85B0 0x85D3 \ + 0x85C1 0x85DC 0x85FF 0x8627 0x8605 0x8629 0x8616 0x863C \ + 0x5EFE 0x5F08 0x593C 0x5941 0x8037 0x5955 0x595A 0x5958 \ + 0x530F 0x5C22 0x5C25 0x5C2C 0x5C34 0x624C 0x626A 0x629F \ + 0x62BB 0x62CA 0x62DA 0x62D7 0x62EE 0x6322 0x62F6 0x6339 \ + 0x634B 0x6343 0x63AD 0x63F6 0x6371 0x637A 0x638E 0x63B4 \ + 0x636D 0x63AC 0x638A 0x6369 0x63AE 0x63BC 0x63F2 0x63F8 \ + 0x63E0 0x63FF 0x63C4 0x63DE 0x63CE 0x6452 0x63C6 0x63BE \ + 0x6445 0x6441 0x640B 0x641B 0x6420 0x640C 0x6426 0x6421 \ + 0x645E 0x6484 0x646D 0x6496 0x647A 0x64B7 0x64B8 0x6499 \ + 0x64BA 0x64C0 0x64D0 0x64D7 0x64E4 0x64E2 0x6509 0x6525 \ + 0x652E 0x5F0B 0x5FD2 0x7519 0x5F11 0x535F 0x53F1 0x53FD \ + 0x53E9 0x53E8 0x53FB 0x5412 0x5416 0x5406 0x544B 0x5452 \ + 0x5453 0x5454 0x5456 0x5443 0x5421 0x5457 0x5459 0x5423 \ + 0x5432 0x5482 0x5494 0x5477 0x5471 0x5464 0x549A 0x549B \ + 0x5484 0x5476 0x5466 0x549D 0x54D0 0x54AD 0x54C2 0x54B4 \ + 0x54D2 0x54A7 0x54A6 0x54D3 0x54D4 0x5472 0x54A3 0x54D5 +24 0x54BB 0x54BF 0x54CC 0x54D9 0x54DA 0x54DC 0x54A9 0x54AA \ + 0x54A4 0x54DD 0x54CF 0x54DE 0x551B 0x54E7 0x5520 0x54FD \ + 0x5514 0x54F3 0x5522 0x5523 0x550F 0x5511 0x5527 0x552A \ + 0x5567 0x558F 0x55B5 0x5549 0x556D 0x5541 0x5555 0x553F \ + 0x5550 0x553C 0x5537 0x5556 0x5575 0x5576 0x5577 0x5533 \ + 0x5530 0x555C 0x558B 0x55D2 0x5583 0x55B1 0x55B9 0x5588 \ + 0x5581 0x559F 0x557E 0x55D6 0x5591 0x557B 0x55DF 0x55BD \ + 0x55BE 0x5594 0x5599 0x55EA 0x55F7 0x55C9 0x561F 0x55D1 \ + 0x55EB 0x55EC 0x55D4 0x55E6 0x55DD 0x55C4 0x55EF 0x55E5 \ + 0x55F2 0x55F3 0x55CC 0x55CD 0x55E8 0x55F5 0x55E4 0x8F94 \ + 0x561E 0x5608 0x560C 0x5601 0x5624 0x5623 0x55FE 0x5600 \ + 0x5627 0x562D 0x5658 0x5639 0x5657 0x562C 0x564D 0x5662 \ + 0x5659 0x565C 0x564C 0x5654 0x5686 0x5664 0x5671 0x566B \ + 0x567B 0x567C 0x5685 0x5693 0x56AF 0x56D4 0x56D7 0x56DD \ + 0x56E1 0x56F5 0x56EB 0x56F9 0x56FF 0x5704 0x570A 0x5709 \ + 0x571C 0x5E0F 0x5E19 0x5E14 0x5E11 0x5E31 0x5E3B 0x5E3C \ + 0x5E37 0x5E44 0x5E54 0x5E5B 0x5E5E 0x5E61 0x5C8C 0x5C7A \ + 0x5C8D 0x5C90 0x5C96 0x5C88 0x5C98 0x5C99 0x5C91 0x5C9A \ + 0x5C9C 0x5CB5 0x5CA2 0x5CBD 0x5CAC 0x5CAB 0x5CB1 0x5CA3 \ + 0x5CC1 0x5CB7 0x5CC4 0x5CD2 0x5CE4 0x5CCB 0x5CE5 0x5D02 \ + 0x5D03 0x5D27 0x5D26 0x5D2E 0x5D24 0x5D1E 0x5D06 0x5D1B \ + 0x5D58 0x5D3E 0x5D34 0x5D3D 0x5D6C 0x5D5B 0x5D6F 0x5D5D \ + 0x5D6B 0x5D4B 0x5D4A 0x5D69 0x5D74 0x5D82 0x5D99 0x5D9D \ + 0x8C73 0x5DB7 0x5DC5 0x5F73 0x5F77 0x5F82 0x5F87 0x5F89 \ + 0x5F8C 0x5F95 0x5F99 0x5F9C 0x5FA8 0x5FAD 0x5FB5 0x5FBC \ + 0x8862 0x5F61 0x72AD 0x72B0 0x72B4 0x72B7 0x72B8 0x72C3 \ + 0x72C1 0x72CE 0x72CD 0x72D2 0x72E8 0x72EF 0x72E9 0x72F2 \ + 0x72F4 0x72F7 0x7301 0x72F3 0x7303 0x72FA 0x72FB 0x7317 \ + 0x7313 0x7321 0x730A 0x731E 0x731D 0x7315 0x7322 0x7339 \ + 0x7325 0x732C 0x7338 0x7331 0x7350 0x734D 0x7357 0x7360 \ + 0x736C 0x736F 0x737E 0x821B 0x5925 0x98E7 0x5924 0x5902 \ + 0x9963 0x9967 0x9968 0x9969 0x996A 0x996B 0x996C 0x9974 +25 0x9977 0x997D 0x9980 0x9984 0x9987 0x998A 0x998D 0x9990 \ + 0x9991 0x9993 0x9994 0x9995 0x5E80 0x5E91 0x5E8B 0x5E96 \ + 0x5EA5 0x5EA0 0x5EB9 0x5EB5 0x5EBE 0x5EB3 0x8D53 0x5ED2 \ + 0x5ED1 0x5EDB 0x5EE8 0x5EEA 0x81BA 0x5FC4 0x5FC9 0x5FD6 \ + 0x5FCF 0x6003 0x5FEE 0x6004 0x5FE1 0x5FE4 0x5FFE 0x6005 \ + 0x6006 0x5FEA 0x5FED 0x5FF8 0x6019 0x6035 0x6026 0x601B \ + 0x600F 0x600D 0x6029 0x602B 0x600A 0x603F 0x6021 0x6078 \ + 0x6079 0x607B 0x607A 0x6042 0x606A 0x607D 0x6096 0x609A \ + 0x60AD 0x609D 0x6083 0x6092 0x608C 0x609B 0x60EC 0x60BB \ + 0x60B1 0x60DD 0x60D8 0x60C6 0x60DA 0x60B4 0x6120 0x6126 \ + 0x6115 0x6123 0x60F4 0x6100 0x610E 0x612B 0x614A 0x6175 \ + 0x61AC 0x6194 0x61A7 0x61B7 0x61D4 0x61F5 0x5FDD 0x96B3 \ + 0x95E9 0x95EB 0x95F1 0x95F3 0x95F5 0x95F6 0x95FC 0x95FE \ + 0x9603 0x9604 0x9606 0x9608 0x960A 0x960B 0x960C 0x960D \ + 0x960F 0x9612 0x9615 0x9616 0x9617 0x9619 0x961A 0x4E2C \ + 0x723F 0x6215 0x6C35 0x6C54 0x6C5C 0x6C4A 0x6CA3 0x6C85 \ + 0x6C90 0x6C94 0x6C8C 0x6C68 0x6C69 0x6C74 0x6C76 0x6C86 \ + 0x6CA9 0x6CD0 0x6CD4 0x6CAD 0x6CF7 0x6CF8 0x6CF1 0x6CD7 \ + 0x6CB2 0x6CE0 0x6CD6 0x6CFA 0x6CEB 0x6CEE 0x6CB1 0x6CD3 \ + 0x6CEF 0x6CFE 0x6D39 0x6D27 0x6D0C 0x6D43 0x6D48 0x6D07 \ + 0x6D04 0x6D19 0x6D0E 0x6D2B 0x6D4D 0x6D2E 0x6D35 0x6D1A \ + 0x6D4F 0x6D52 0x6D54 0x6D33 0x6D91 0x6D6F 0x6D9E 0x6DA0 \ + 0x6D5E 0x6D93 0x6D94 0x6D5C 0x6D60 0x6D7C 0x6D63 0x6E1A \ + 0x6DC7 0x6DC5 0x6DDE 0x6E0E 0x6DBF 0x6DE0 0x6E11 0x6DE6 \ + 0x6DDD 0x6DD9 0x6E16 0x6DAB 0x6E0C 0x6DAE 0x6E2B 0x6E6E \ + 0x6E4E 0x6E6B 0x6EB2 0x6E5F 0x6E86 0x6E53 0x6E54 0x6E32 \ + 0x6E25 0x6E44 0x6EDF 0x6EB1 0x6E98 0x6EE0 0x6F2D 0x6EE2 \ + 0x6EA5 0x6EA7 0x6EBD 0x6EBB 0x6EB7 0x6ED7 0x6EB4 0x6ECF \ + 0x6E8F 0x6EC2 0x6E9F 0x6F62 0x6F46 0x6F47 0x6F24 0x6F15 \ + 0x6EF9 0x6F2F 0x6F36 0x6F4B 0x6F74 0x6F2A 0x6F09 0x6F29 \ + 0x6F89 0x6F8D 0x6F8C 0x6F78 0x6F72 0x6F7C 0x6F7A 0x6FD1 \ + 0x6FC9 0x6FA7 0x6FB9 0x6FB6 0x6FC2 0x6FE1 0x6FEE 0x6FDE +26 0x6FE0 0x6FEF 0x701A 0x7023 0x701B 0x7039 0x7035 0x704F \ + 0x705E 0x5B80 0x5B84 0x5B95 0x5B93 0x5BA5 0x5BB8 0x752F \ + 0x9A9E 0x6434 0x5BE4 0x5BEE 0x8930 0x5BF0 0x8E47 0x8B07 \ + 0x8FB6 0x8FD3 0x8FD5 0x8FE5 0x8FEE 0x8FE4 0x8FE9 0x8FE6 \ + 0x8FF3 0x8FE8 0x9005 0x9004 0x900B 0x9026 0x9011 0x900D \ + 0x9016 0x9021 0x9035 0x9036 0x902D 0x902F 0x9044 0x9051 \ + 0x9052 0x9050 0x9068 0x9058 0x9062 0x905B 0x66B9 0x9074 \ + 0x907D 0x9082 0x9088 0x9083 0x908B 0x5F50 0x5F57 0x5F56 \ + 0x5F58 0x5C3B 0x54AB 0x5C50 0x5C59 0x5B71 0x5C63 0x5C66 \ + 0x7FBC 0x5F2A 0x5F29 0x5F2D 0x8274 0x5F3C 0x9B3B 0x5C6E \ + 0x5981 0x5983 0x598D 0x59A9 0x59AA 0x59A3 0x5997 0x59CA \ + 0x59AB 0x599E 0x59A4 0x59D2 0x59B2 0x59AF 0x59D7 0x59BE \ + 0x5A05 0x5A06 0x59DD 0x5A08 0x59E3 0x59D8 0x59F9 0x5A0C \ + 0x5A09 0x5A32 0x5A34 0x5A11 0x5A23 0x5A13 0x5A40 0x5A67 \ + 0x5A4A 0x5A55 0x5A3C 0x5A62 0x5A75 0x80EC 0x5AAA 0x5A9B \ + 0x5A77 0x5A7A 0x5ABE 0x5AEB 0x5AB2 0x5AD2 0x5AD4 0x5AB8 \ + 0x5AE0 0x5AE3 0x5AF1 0x5AD6 0x5AE6 0x5AD8 0x5ADC 0x5B09 \ + 0x5B17 0x5B16 0x5B32 0x5B37 0x5B40 0x5C15 0x5C1C 0x5B5A \ + 0x5B65 0x5B73 0x5B51 0x5B53 0x5B62 0x9A75 0x9A77 0x9A78 \ + 0x9A7A 0x9A7F 0x9A7D 0x9A80 0x9A81 0x9A85 0x9A88 0x9A8A \ + 0x9A90 0x9A92 0x9A93 0x9A96 0x9A98 0x9A9B 0x9A9C 0x9A9D \ + 0x9A9F 0x9AA0 0x9AA2 0x9AA3 0x9AA5 0x9AA7 0x7E9F 0x7EA1 \ + 0x7EA3 0x7EA5 0x7EA8 0x7EA9 0x7EAD 0x7EB0 0x7EBE 0x7EC0 \ + 0x7EC1 0x7EC2 0x7EC9 0x7ECB 0x7ECC 0x7ED0 0x7ED4 0x7ED7 \ + 0x7EDB 0x7EE0 0x7EE1 0x7EE8 0x7EEB 0x7EEE 0x7EEF 0x7EF1 \ + 0x7EF2 0x7F0D 0x7EF6 0x7EFA 0x7EFB 0x7EFE 0x7F01 0x7F02 \ + 0x7F03 0x7F07 0x7F08 0x7F0B 0x7F0C 0x7F0F 0x7F11 0x7F12 \ + 0x7F17 0x7F19 0x7F1C 0x7F1B 0x7F1F 0x7F21 0x7F22 0x7F23 \ + 0x7F24 0x7F25 0x7F26 0x7F27 0x7F2A 0x7F2B 0x7F2C 0x7F2D \ + 0x7F2F 0x7F30 0x7F31 0x7F32 0x7F33 0x7F35 0x5E7A 0x757F \ + 0x5DDB 0x753E 0x9095 0x738E 0x7391 0x73AE 0x73A2 0x739F \ + 0x73CF 0x73C2 0x73D1 0x73B7 0x73B3 0x73C0 0x73C9 0x73C8 +27 0x73E5 0x73D9 0x987C 0x740A 0x73E9 0x73E7 0x73DE 0x73BA \ + 0x73F2 0x740F 0x742A 0x745B 0x7426 0x7425 0x7428 0x7430 \ + 0x742E 0x742C 0x741B 0x741A 0x7441 0x745C 0x7457 0x7455 \ + 0x7459 0x7477 0x746D 0x747E 0x749C 0x748E 0x7480 0x7481 \ + 0x7487 0x748B 0x749E 0x74A8 0x74A9 0x7490 0x74A7 0x74D2 \ + 0x74BA 0x97EA 0x97EB 0x97EC 0x674C 0x6753 0x675E 0x6748 \ + 0x6769 0x67A5 0x6787 0x676A 0x6773 0x6798 0x67A7 0x6775 \ + 0x67A8 0x679E 0x67AD 0x678B 0x6777 0x677C 0x67F0 0x6809 \ + 0x67D8 0x680A 0x67E9 0x67B0 0x680C 0x67D9 0x67B5 0x67DA \ + 0x67B3 0x67DD 0x6800 0x67C3 0x67B8 0x67E2 0x680E 0x67C1 \ + 0x67FD 0x6832 0x6833 0x6860 0x6861 0x684E 0x6862 0x6844 \ + 0x6864 0x6883 0x681D 0x6855 0x6866 0x6841 0x6867 0x6840 \ + 0x683E 0x684A 0x6849 0x6829 0x68B5 0x688F 0x6874 0x6877 \ + 0x6893 0x686B 0x68C2 0x696E 0x68FC 0x691F 0x6920 0x68F9 \ + 0x6924 0x68F0 0x690B 0x6901 0x6957 0x68E3 0x6910 0x6971 \ + 0x6939 0x6960 0x6942 0x695D 0x6984 0x696B 0x6980 0x6998 \ + 0x6978 0x6934 0x69CC 0x6987 0x6988 0x69CE 0x6989 0x6966 \ + 0x6963 0x6979 0x699B 0x69A7 0x69BB 0x69AB 0x69AD 0x69D4 \ + 0x69B1 0x69C1 0x69CA 0x69DF 0x6995 0x69E0 0x698D 0x69FF \ + 0x6A2F 0x69ED 0x6A17 0x6A18 0x6A65 0x69F2 0x6A44 0x6A3E \ + 0x6AA0 0x6A50 0x6A5B 0x6A35 0x6A8E 0x6A79 0x6A3D 0x6A28 \ + 0x6A58 0x6A7C 0x6A91 0x6A90 0x6AA9 0x6A97 0x6AAB 0x7337 \ + 0x7352 0x6B81 0x6B82 0x6B87 0x6B84 0x6B92 0x6B93 0x6B8D \ + 0x6B9A 0x6B9B 0x6BA1 0x6BAA 0x8F6B 0x8F6D 0x8F71 0x8F72 \ + 0x8F73 0x8F75 0x8F76 0x8F78 0x8F77 0x8F79 0x8F7A 0x8F7C \ + 0x8F7E 0x8F81 0x8F82 0x8F84 0x8F87 0x8F8B 0x8F8D 0x8F8E \ + 0x8F8F 0x8F98 0x8F9A 0x8ECE 0x620B 0x6217 0x621B 0x621F \ + 0x6222 0x6221 0x6225 0x6224 0x622C 0x81E7 0x74EF 0x74F4 \ + 0x74FF 0x750F 0x7511 0x7513 0x6534 0x65EE 0x65EF 0x65F0 \ + 0x660A 0x6619 0x6772 0x6603 0x6615 0x6600 0x7085 0x66F7 \ + 0x661D 0x6634 0x6631 0x6636 0x6635 0x8006 0x665F 0x6654 \ + 0x6641 0x664F 0x6656 0x6661 0x6657 0x6677 0x6684 0x668C +28 0x66A7 0x669D 0x66BE 0x66DB 0x66DC 0x66E6 0x66E9 0x8D32 \ + 0x8D33 0x8D36 0x8D3B 0x8D3D 0x8D40 0x8D45 0x8D46 0x8D48 \ + 0x8D49 0x8D47 0x8D4D 0x8D55 0x8D59 0x89C7 0x89CA 0x89CB \ + 0x89CC 0x89CE 0x89CF 0x89D0 0x89D1 0x726E 0x729F 0x725D \ + 0x7266 0x726F 0x727E 0x727F 0x7284 0x728B 0x728D 0x728F \ + 0x7292 0x6308 0x6332 0x63B0 0x643F 0x64D8 0x8004 0x6BEA \ + 0x6BF3 0x6BFD 0x6BF5 0x6BF9 0x6C05 0x6C07 0x6C06 0x6C0D \ + 0x6C15 0x6C18 0x6C19 0x6C1A 0x6C21 0x6C29 0x6C24 0x6C2A \ + 0x6C32 0x6535 0x6555 0x656B 0x724D 0x7252 0x7256 0x7230 \ + 0x8662 0x5216 0x809F 0x809C 0x8093 0x80BC 0x670A 0x80BD \ + 0x80B1 0x80AB 0x80AD 0x80B4 0x80B7 0x80E7 0x80E8 0x80E9 \ + 0x80EA 0x80DB 0x80C2 0x80C4 0x80D9 0x80CD 0x80D7 0x6710 \ + 0x80DD 0x80EB 0x80F1 0x80F4 0x80ED 0x810D 0x810E 0x80F2 \ + 0x80FC 0x6715 0x8112 0x8C5A 0x8136 0x811E 0x812C 0x8118 \ + 0x8132 0x8148 0x814C 0x8153 0x8174 0x8159 0x815A 0x8171 \ + 0x8160 0x8169 0x817C 0x817D 0x816D 0x8167 0x584D 0x5AB5 \ + 0x8188 0x8182 0x8191 0x6ED5 0x81A3 0x81AA 0x81CC 0x6726 \ + 0x81CA 0x81BB 0x81C1 0x81A6 0x6B24 0x6B37 0x6B39 0x6B43 \ + 0x6B46 0x6B59 0x98D1 0x98D2 0x98D3 0x98D5 0x98D9 0x98DA \ + 0x6BB3 0x5F40 0x6BC2 0x89F3 0x6590 0x9F51 0x6593 0x65BC \ + 0x65C6 0x65C4 0x65C3 0x65CC 0x65CE 0x65D2 0x65D6 0x7080 \ + 0x709C 0x7096 0x709D 0x70BB 0x70C0 0x70B7 0x70AB 0x70B1 \ + 0x70E8 0x70CA 0x7110 0x7113 0x7116 0x712F 0x7131 0x7173 \ + 0x715C 0x7168 0x7145 0x7172 0x714A 0x7178 0x717A 0x7198 \ + 0x71B3 0x71B5 0x71A8 0x71A0 0x71E0 0x71D4 0x71E7 0x71F9 \ + 0x721D 0x7228 0x706C 0x7118 0x7166 0x71B9 0x623E 0x623D \ + 0x6243 0x6248 0x6249 0x793B 0x7940 0x7946 0x7949 0x795B \ + 0x795C 0x7953 0x795A 0x7962 0x7957 0x7960 0x796F 0x7967 \ + 0x797A 0x7985 0x798A 0x799A 0x79A7 0x79B3 0x5FD1 0x5FD0 \ + 0x603C 0x605D 0x605A 0x6067 0x6041 0x6059 0x6063 0x60AB \ + 0x6106 0x610D 0x615D 0x61A9 0x619D 0x61CB 0x61D1 0x6206 \ + 0x8080 0x807F 0x6C93 0x6CF6 0x6DFC 0x77F6 0x77F8 0x7800 +29 0x7809 0x7817 0x7818 0x7811 0x65AB 0x782D 0x781C 0x781D \ + 0x7839 0x783A 0x783B 0x781F 0x783C 0x7825 0x782C 0x7823 \ + 0x7829 0x784E 0x786D 0x7856 0x7857 0x7826 0x7850 0x7847 \ + 0x784C 0x786A 0x789B 0x7893 0x789A 0x7887 0x789C 0x78A1 \ + 0x78A3 0x78B2 0x78B9 0x78A5 0x78D4 0x78D9 0x78C9 0x78EC \ + 0x78F2 0x7905 0x78F4 0x7913 0x7924 0x791E 0x7934 0x9F9B \ + 0x9EF9 0x9EFB 0x9EFC 0x76F1 0x7704 0x770D 0x76F9 0x7707 \ + 0x7708 0x771A 0x7722 0x7719 0x772D 0x7726 0x7735 0x7738 \ + 0x7750 0x7751 0x7747 0x7743 0x775A 0x7768 0x7762 0x7765 \ + 0x777F 0x778D 0x777D 0x7780 0x778C 0x7791 0x779F 0x77A0 \ + 0x77B0 0x77B5 0x77BD 0x753A 0x7540 0x754E 0x754B 0x7548 \ + 0x755B 0x7572 0x7579 0x7583 0x7F58 0x7F61 0x7F5F 0x8A48 \ + 0x7F68 0x7F74 0x7F71 0x7F79 0x7F81 0x7F7E 0x76CD 0x76E5 \ + 0x8832 0x9485 0x9486 0x9487 0x948B 0x948A 0x948C 0x948D \ + 0x948F 0x9490 0x9494 0x9497 0x9495 0x949A 0x949B 0x949C \ + 0x94A3 0x94A4 0x94AB 0x94AA 0x94AD 0x94AC 0x94AF 0x94B0 \ + 0x94B2 0x94B4 0x94B6 0x94B7 0x94B8 0x94B9 0x94BA 0x94BC \ + 0x94BD 0x94BF 0x94C4 0x94C8 0x94C9 0x94CA 0x94CB 0x94CC \ + 0x94CD 0x94CE 0x94D0 0x94D1 0x94D2 0x94D5 0x94D6 0x94D7 \ + 0x94D9 0x94D8 0x94DB 0x94DE 0x94DF 0x94E0 0x94E2 0x94E4 \ + 0x94E5 0x94E7 0x94E8 0x94EA 0x94E9 0x94EB 0x94EE 0x94EF \ + 0x94F3 0x94F4 0x94F5 0x94F7 0x94F9 0x94FC 0x94FD 0x94FF \ + 0x9503 0x9502 0x9506 0x9507 0x9509 0x950A 0x950D 0x950E \ + 0x950F 0x9512 0x9513 0x9514 0x9515 0x9516 0x9518 0x951B \ + 0x951D 0x951E 0x951F 0x9522 0x952A 0x952B 0x9529 0x952C \ + 0x9531 0x9532 0x9534 0x9536 0x9537 0x9538 0x953C 0x953E \ + 0x953F 0x9542 0x9535 0x9544 0x9545 0x9546 0x9549 0x954C \ + 0x954E 0x954F 0x9552 0x9553 0x9554 0x9556 0x9557 0x9558 \ + 0x9559 0x955B 0x955E 0x955F 0x955D 0x9561 0x9562 0x9564 \ + 0x9565 0x9566 0x9567 0x9568 0x9569 0x956A 0x956B 0x956C \ + 0x956F 0x9571 0x9572 0x9573 0x953A 0x77E7 0x77EC 0x96C9 \ + 0x79D5 0x79ED 0x79E3 0x79EB 0x7A06 0x5D47 0x7A03 0x7A02 +30 0x7A1E 0x7A14 0x7A39 0x7A37 0x7A51 0x9ECF 0x99A5 0x7A70 \ + 0x7688 0x768E 0x7693 0x7699 0x76A4 0x74DE 0x74E0 0x752C \ + 0x9E20 0x9E22 0x9E28 0x9E29 0x9E2A 0x9E2B 0x9E2C 0x9E32 \ + 0x9E31 0x9E36 0x9E38 0x9E37 0x9E39 0x9E3A 0x9E3E 0x9E41 \ + 0x9E42 0x9E44 0x9E46 0x9E47 0x9E48 0x9E49 0x9E4B 0x9E4C \ + 0x9E4E 0x9E51 0x9E55 0x9E57 0x9E5A 0x9E5B 0x9E5C 0x9E5E \ + 0x9E63 0x9E66 0x9E67 0x9E68 0x9E69 0x9E6A 0x9E6B 0x9E6C \ + 0x9E71 0x9E6D 0x9E73 0x7592 0x7594 0x7596 0x75A0 0x759D \ + 0x75AC 0x75A3 0x75B3 0x75B4 0x75B8 0x75C4 0x75B1 0x75B0 \ + 0x75C3 0x75C2 0x75D6 0x75CD 0x75E3 0x75E8 0x75E6 0x75E4 \ + 0x75EB 0x75E7 0x7603 0x75F1 0x75FC 0x75FF 0x7610 0x7600 \ + 0x7605 0x760C 0x7617 0x760A 0x7625 0x7618 0x7615 0x7619 \ + 0x761B 0x763C 0x7622 0x7620 0x7640 0x762D 0x7630 0x763F \ + 0x7635 0x7643 0x763E 0x7633 0x764D 0x765E 0x7654 0x765C \ + 0x7656 0x766B 0x766F 0x7FCA 0x7AE6 0x7A78 0x7A79 0x7A80 \ + 0x7A86 0x7A88 0x7A95 0x7AA6 0x7AA0 0x7AAC 0x7AA8 0x7AAD \ + 0x7AB3 0x8864 0x8869 0x8872 0x887D 0x887F 0x8882 0x88A2 \ + 0x88C6 0x88B7 0x88BC 0x88C9 0x88E2 0x88CE 0x88E3 0x88E5 \ + 0x88F1 0x891A 0x88FC 0x88E8 0x88FE 0x88F0 0x8921 0x8919 \ + 0x8913 0x891B 0x890A 0x8934 0x892B 0x8936 0x8941 0x8966 \ + 0x897B 0x758B 0x80E5 0x76B2 0x76B4 0x77DC 0x8012 0x8014 \ + 0x8016 0x801C 0x8020 0x8022 0x8025 0x8026 0x8027 0x8029 \ + 0x8028 0x8031 0x800B 0x8035 0x8043 0x8046 0x804D 0x8052 \ + 0x8069 0x8071 0x8983 0x9878 0x9880 0x9883 0x9889 0x988C \ + 0x988D 0x988F 0x9894 0x989A 0x989B 0x989E 0x989F 0x98A1 \ + 0x98A2 0x98A5 0x98A6 0x864D 0x8654 0x866C 0x866E 0x867F \ + 0x867A 0x867C 0x867B 0x86A8 0x868D 0x868B 0x86AC 0x869D \ + 0x86A7 0x86A3 0x86AA 0x8693 0x86A9 0x86B6 0x86C4 0x86B5 \ + 0x86CE 0x86B0 0x86BA 0x86B1 0x86AF 0x86C9 0x86CF 0x86B4 \ + 0x86E9 0x86F1 0x86F2 0x86ED 0x86F3 0x86D0 0x8713 0x86DE \ + 0x86F4 0x86DF 0x86D8 0x86D1 0x8703 0x8707 0x86F8 0x8708 \ + 0x870A 0x870D 0x8709 0x8723 0x873B 0x871E 0x8725 0x872E +31 0x871A 0x873E 0x8748 0x8734 0x8731 0x8729 0x8737 0x873F \ + 0x8782 0x8722 0x877D 0x877E 0x877B 0x8760 0x8770 0x874C \ + 0x876E 0x878B 0x8753 0x8763 0x877C 0x8764 0x8759 0x8765 \ + 0x8793 0x87AF 0x87A8 0x87D2 0x87C6 0x8788 0x8785 0x87AD \ + 0x8797 0x8783 0x87AB 0x87E5 0x87AC 0x87B5 0x87B3 0x87CB \ + 0x87D3 0x87BD 0x87D1 0x87C0 0x87CA 0x87DB 0x87EA 0x87E0 \ + 0x87EE 0x8816 0x8813 0x87FE 0x880A 0x881B 0x8821 0x8839 \ + 0x883C 0x7F36 0x7F42 0x7F44 0x7F45 0x8210 0x7AFA 0x7AFD \ + 0x7B08 0x7B03 0x7B04 0x7B15 0x7B0A 0x7B2B 0x7B0F 0x7B47 \ + 0x7B38 0x7B2A 0x7B19 0x7B2E 0x7B31 0x7B20 0x7B25 0x7B24 \ + 0x7B33 0x7B3E 0x7B1E 0x7B58 0x7B5A 0x7B45 0x7B75 0x7B4C \ + 0x7B5D 0x7B60 0x7B6E 0x7B7B 0x7B62 0x7B72 0x7B71 0x7B90 \ + 0x7BA6 0x7BA7 0x7BB8 0x7BAC 0x7B9D 0x7BA8 0x7B85 0x7BAA \ + 0x7B9C 0x7BA2 0x7BAB 0x7BB4 0x7BD1 0x7BC1 0x7BCC 0x7BDD \ + 0x7BDA 0x7BE5 0x7BE6 0x7BEA 0x7C0C 0x7BFE 0x7BFC 0x7C0F \ + 0x7C16 0x7C0B 0x7C1F 0x7C2A 0x7C26 0x7C38 0x7C41 0x7C40 \ + 0x81FE 0x8201 0x8202 0x8204 0x81EC 0x8844 0x8221 0x8222 \ + 0x8223 0x822D 0x822F 0x8228 0x822B 0x8238 0x823B 0x8233 \ + 0x8234 0x823E 0x8244 0x8249 0x824B 0x824F 0x825A 0x825F \ + 0x8268 0x887E 0x8885 0x8888 0x88D8 0x88DF 0x895E 0x7F9D \ + 0x7F9F 0x7FA7 0x7FAF 0x7FB0 0x7FB2 0x7C7C 0x6549 0x7C91 \ + 0x7C9D 0x7C9C 0x7C9E 0x7CA2 0x7CB2 0x7CBC 0x7CBD 0x7CC1 \ + 0x7CC7 0x7CCC 0x7CCD 0x7CC8 0x7CC5 0x7CD7 0x7CE8 0x826E \ + 0x66A8 0x7FBF 0x7FCE 0x7FD5 0x7FE5 0x7FE1 0x7FE6 0x7FE9 \ + 0x7FEE 0x7FF3 0x7CF8 0x7D77 0x7DA6 0x7DAE 0x7E47 0x7E9B \ + 0x9EB8 0x9EB4 0x8D73 0x8D84 0x8D94 0x8D91 0x8DB1 0x8D67 \ + 0x8D6D 0x8C47 0x8C49 0x914A 0x9150 0x914E 0x914F 0x9164 \ + 0x9162 0x9161 0x9170 0x9169 0x916F 0x917D 0x917E 0x9172 \ + 0x9174 0x9179 0x918C 0x9185 0x9190 0x918D 0x9191 0x91A2 \ + 0x91A3 0x91AA 0x91AD 0x91AE 0x91AF 0x91B5 0x91B4 0x91BA \ + 0x8C55 0x9E7E 0x8DB8 0x8DEB 0x8E05 0x8E59 0x8E69 0x8DB5 \ + 0x8DBF 0x8DBC 0x8DBA 0x8DC4 0x8DD6 0x8DD7 0x8DDA 0x8DDE +32 0x8DCE 0x8DCF 0x8DDB 0x8DC6 0x8DEC 0x8DF7 0x8DF8 0x8DE3 \ + 0x8DF9 0x8DFB 0x8DE4 0x8E09 0x8DFD 0x8E14 0x8E1D 0x8E1F \ + 0x8E2C 0x8E2E 0x8E23 0x8E2F 0x8E3A 0x8E40 0x8E39 0x8E35 \ + 0x8E3D 0x8E31 0x8E49 0x8E41 0x8E42 0x8E51 0x8E52 0x8E4A \ + 0x8E70 0x8E76 0x8E7C 0x8E6F 0x8E74 0x8E85 0x8E8F 0x8E94 \ + 0x8E90 0x8E9C 0x8E9E 0x8C78 0x8C82 0x8C8A 0x8C85 0x8C98 \ + 0x8C94 0x659B 0x89D6 0x89DE 0x89DA 0x89DC 0x89E5 0x89EB \ + 0x89EF 0x8A3E 0x8B26 0x9753 0x96E9 0x96F3 0x96EF 0x9706 \ + 0x9701 0x9708 0x970F 0x970E 0x972A 0x972D 0x9730 0x973E \ + 0x9F80 0x9F83 0x9F85 0x9F86 0x9F87 0x9F88 0x9F89 0x9F8A \ + 0x9F8C 0x9EFE 0x9F0B 0x9F0D 0x96B9 0x96BC 0x96BD 0x96CE \ + 0x96D2 0x77BF 0x96E0 0x928E 0x92AE 0x92C8 0x933E 0x936A \ + 0x93CA 0x938F 0x943E 0x946B 0x9C7F 0x9C82 0x9C85 0x9C86 \ + 0x9C87 0x9C88 0x7A23 0x9C8B 0x9C8E 0x9C90 0x9C91 0x9C92 \ + 0x9C94 0x9C95 0x9C9A 0x9C9B 0x9C9E 0x9C9F 0x9CA0 0x9CA1 \ + 0x9CA2 0x9CA3 0x9CA5 0x9CA6 0x9CA7 0x9CA8 0x9CA9 0x9CAB \ + 0x9CAD 0x9CAE 0x9CB0 0x9CB1 0x9CB2 0x9CB3 0x9CB4 0x9CB5 \ + 0x9CB6 0x9CB7 0x9CBA 0x9CBB 0x9CBC 0x9CBD 0x9CC4 0x9CC5 \ + 0x9CC6 0x9CC7 0x9CCA 0x9CCB 0x9CCC 0x9CCD 0x9CCE 0x9CCF \ + 0x9CD0 0x9CD3 0x9CD4 0x9CD5 0x9CD7 0x9CD8 0x9CD9 0x9CDC \ + 0x9CDD 0x9CDF 0x9CE2 0x977C 0x9785 0x9791 0x9792 0x9794 \ + 0x97AF 0x97AB 0x97A3 0x97B2 0x97B4 0x9AB1 0x9AB0 0x9AB7 \ + 0x9E58 0x9AB6 0x9ABA 0x9ABC 0x9AC1 0x9AC0 0x9AC5 0x9AC2 \ + 0x9ACB 0x9ACC 0x9AD1 0x9B45 0x9B43 0x9B47 0x9B49 0x9B48 \ + 0x9B4D 0x9B51 0x98E8 0x990D 0x992E 0x9955 0x9954 0x9ADF \ + 0x9AE1 0x9AE6 0x9AEF 0x9AEB 0x9AFB 0x9AED 0x9AF9 0x9B08 \ + 0x9B0F 0x9B13 0x9B1F 0x9B23 0x9EBD 0x9EBE 0x7E3B 0x9E82 \ + 0x9E87 0x9E88 0x9E8B 0x9E92 0x93D6 0x9E9D 0x9E9F 0x9EDB \ + 0x9EDC 0x9EDD 0x9EE0 0x9EDF 0x9EE2 0x9EE9 0x9EE7 0x9EE5 \ + 0x9EEA 0x9EEF 0x9F22 0x9F2C 0x9F2F 0x9F39 0x9F37 0x9F3D \ + 0x9F3E 0x9F44 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +33 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +34 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +35 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE + +# eof diff --git a/contrib/ttf2pk/data/UGBK.sfd b/contrib/ttf2pk/data/UGBK.sfd new file mode 100644 index 0000000..6fc99c9 --- /dev/null +++ b/contrib/ttf2pk/data/UGBK.sfd @@ -0,0 +1,3002 @@ +# UGBK.sfd +# +# subfont numbers for GBK encoding and its corresponding code ranges +# to be used with the CJK package for LaTeX. +# +# The input encoding is Unicode. + +01 0x4E02 0x4E04 0x4E05 0x4E06 0x4E0F 0x4E12 0x4E17 0x4E1F \ + 0x4E20 0x4E21 0x4E23 0x4E26 0x4E29 0x4E2E 0x4E2F 0x4E31 \ + 0x4E33 0x4E35 0x4E37 0x4E3C 0x4E40 0x4E41 0x4E42 0x4E44 \ + 0x4E46 0x4E4A 0x4E51 0x4E55 0x4E57 0x4E5A 0x4E5B 0x4E62 \ + 0x4E63 0x4E64 0x4E65 0x4E67 0x4E68 0x4E6A 0x4E6B 0x4E6C \ + 0x4E6D 0x4E6E 0x4E6F 0x4E72 0x4E74 0x4E75 0x4E76 0x4E77 \ + 0x4E78 0x4E79 0x4E7A 0x4E7B 0x4E7C 0x4E7D 0x4E7F 0x4E80 \ + 0x4E81 0x4E82 0x4E83 0x4E84 0x4E85 0x4E87 0x4E8A 0x4E90 \ + 0x4E96 0x4E97 0x4E99 0x4E9C 0x4E9D 0x4E9E 0x4EA3 0x4EAA \ + 0x4EAF 0x4EB0 0x4EB1 0x4EB4 0x4EB6 0x4EB7 0x4EB8 0x4EB9 \ + 0x4EBC 0x4EBD 0x4EBE 0x4EC8 0x4ECC 0x4ECF 0x4ED0 0x4ED2 \ + 0x4EDA 0x4EDB 0x4EDC 0x4EE0 0x4EE2 0x4EE6 0x4EE7 0x4EE9 \ + 0x4EED 0x4EEE 0x4EEF 0x4EF1 0x4EF4 0x4EF8 0x4EF9 0x4EFA \ + 0x4EFC 0x4EFE 0x4F00 0x4F02 0x4F03 0x4F04 0x4F05 0x4F06 \ + 0x4F07 0x4F08 0x4F0B 0x4F0C 0x4F12 0x4F13 0x4F14 0x4F15 \ + 0x4F16 0x4F1C 0x4F1D 0x4F21 0x4F23 0x4F28 0x4F29 0x4F2C \ + 0x4F2D 0x4F2E 0x4F31 0x4F33 0x4F35 0x4F37 0x4F39 0x4F3B \ + 0x4F3E 0x4F3F 0x4F40 0x4F41 0x4F42 0x4F44 0x4F45 0x4F47 \ + 0x4F48 0x4F49 0x4F4A 0x4F4B 0x4F4C 0x4F52 0x4F54 0x4F56 \ + 0x4F61 0x4F62 0x4F66 0x4F68 0x4F6A 0x4F6B 0x4F6D 0x4F6E \ + 0x4F71 0x4F72 0x4F75 0x4F77 0x4F78 0x4F79 0x4F7A 0x4F7D \ + 0x4F80 0x4F81 0x4F82 0x4F85 0x4F86 0x4F87 0x4F8A 0x4F8C \ + 0x4F8E 0x4F90 0x4F92 0x4F93 0x4F95 0x4F96 0x4F98 0x4F99 \ + 0x4F9A 0x4F9C 0x4F9E 0x4F9F 0x4FA1 0x4FA2 0x4FA4 0x4FAB \ + 0x4FAD 0x4FB0 0x4FB1 0x4FB2 0x4FB3 0x4FB4 0x4FB6 0x4FB7 \ + 0x4FB8 0x4FB9 0x4FBA 0x4FBB 0x4FBC 0x4FBD 0x4FBE 0x4FC0 \ + 0x4FC1 0x4FC2 0x4FC6 0x4FC7 0x4FC8 0x4FC9 0x4FCB 0x4FCC \ + 0x4FCD 0x4FD2 0x4FD3 0x4FD4 0x4FD5 0x4FD6 0x4FD9 0x4FDB \ + 0x4FE0 0x4FE2 0x4FE4 0x4FE5 0x4FE7 0x4FEB 0x4FEC 0x4FF0 \ + 0x4FF2 0x4FF4 0x4FF5 0x4FF6 0x4FF7 0x4FF9 0x4FFB 0x4FFC \ + 0x4FFD 0x4FFF 0x5000 0x5001 0x5002 0x5003 0x5004 0x5005 \ + 0x5006 0x5007 0x5008 0x5009 0x500A 0x500B 0x500E 0x5010 +02 0x5011 0x5013 0x5015 0x5016 0x5017 0x501B 0x501D 0x501E \ + 0x5020 0x5022 0x5023 0x5024 0x5027 0x502B 0x502F 0x5030 \ + 0x5031 0x5032 0x5033 0x5034 0x5035 0x5036 0x5037 0x5038 \ + 0x5039 0x503B 0x503D 0x503F 0x5040 0x5041 0x5042 0x5044 \ + 0x5045 0x5046 0x5049 0x504A 0x504B 0x504D 0x5050 0x5051 \ + 0x5052 0x5053 0x5054 0x5056 0x5057 0x5058 0x5059 0x505B \ + 0x505D 0x505E 0x505F 0x5060 0x5061 0x5062 0x5063 0x5064 \ + 0x5066 0x5067 0x5068 0x5069 0x506A 0x506B 0x506D 0x506E \ + 0x506F 0x5070 0x5071 0x5072 0x5073 0x5074 0x5075 0x5078 \ + 0x5079 0x507A 0x507C 0x507D 0x5081 0x5082 0x5083 0x5084 \ + 0x5086 0x5087 0x5089 0x508A 0x508B 0x508C 0x508E 0x508F \ + 0x5090 0x5091 0x5092 0x5093 0x5094 0x5095 0x5096 0x5097 \ + 0x5098 0x5099 0x509A 0x509B 0x509C 0x509D 0x509E 0x509F \ + 0x50A0 0x50A1 0x50A2 0x50A4 0x50A6 0x50AA 0x50AB 0x50AD \ + 0x50AE 0x50AF 0x50B0 0x50B1 0x50B3 0x50B4 0x50B5 0x50B6 \ + 0x50B7 0x50B8 0x50B9 0x50BC 0x50BD 0x50BE 0x50BF 0x50C0 \ + 0x50C1 0x50C2 0x50C3 0x50C4 0x50C5 0x50C6 0x50C7 0x50C8 \ + 0x50C9 0x50CA 0x50CB 0x50CC 0x50CD 0x50CE 0x50D0 0x50D1 \ + 0x50D2 0x50D3 0x50D4 0x50D5 0x50D7 0x50D8 0x50D9 0x50DB \ + 0x50DC 0x50DD 0x50DE 0x50DF 0x50E0 0x50E1 0x50E2 0x50E3 \ + 0x50E4 0x50E5 0x50E8 0x50E9 0x50EA 0x50EB 0x50EF 0x50F0 \ + 0x50F1 0x50F2 0x50F4 0x50F6 0x50F7 0x50F8 0x50F9 0x50FA \ + 0x50FC 0x50FD 0x50FE 0x50FF 0x5100 0x5101 0x5102 0x5103 \ + 0x5104 0x5105 0x5108 0x5109 0x510A 0x510C 0x510D 0x510E \ + 0x510F 0x5110 0x5111 0x5113 0x5114 0x5115 0x5116 0x5117 \ + 0x5118 0x5119 0x511A 0x511B 0x511C 0x511D 0x511E 0x511F \ + 0x5120 0x5122 0x5123 0x5124 0x5125 0x5126 0x5127 0x5128 \ + 0x5129 0x512A 0x512B 0x512C 0x512D 0x512E 0x512F 0x5130 \ + 0x5131 0x5132 0x5133 0x5134 0x5135 0x5136 0x5137 0x5138 \ + 0x5139 0x513A 0x513B 0x513C 0x513D 0x513E 0x5142 0x5147 \ + 0x514A 0x514C 0x514E 0x514F 0x5150 0x5152 0x5153 0x5157 \ + 0x5158 0x5159 0x515B 0x515D 0x515E 0x515F 0x5160 0x5161 +03 0x5163 0x5164 0x5166 0x5167 0x5169 0x516A 0x516F 0x5172 \ + 0x517A 0x517E 0x517F 0x5183 0x5184 0x5186 0x5187 0x518A \ + 0x518B 0x518E 0x518F 0x5190 0x5191 0x5193 0x5194 0x5198 \ + 0x519A 0x519D 0x519E 0x519F 0x51A1 0x51A3 0x51A6 0x51A7 \ + 0x51A8 0x51A9 0x51AA 0x51AD 0x51AE 0x51B4 0x51B8 0x51B9 \ + 0x51BA 0x51BE 0x51BF 0x51C1 0x51C2 0x51C3 0x51C5 0x51C8 \ + 0x51CA 0x51CD 0x51CE 0x51D0 0x51D2 0x51D3 0x51D4 0x51D5 \ + 0x51D6 0x51D7 0x51D8 0x51D9 0x51DA 0x51DC 0x51DE 0x51DF \ + 0x51E2 0x51E3 0x51E5 0x51E6 0x51E7 0x51E8 0x51E9 0x51EA \ + 0x51EC 0x51EE 0x51F1 0x51F2 0x51F4 0x51F7 0x51FE 0x5204 \ + 0x5205 0x5209 0x520B 0x520C 0x520F 0x5210 0x5213 0x5214 \ + 0x5215 0x521C 0x521E 0x521F 0x5221 0x5222 0x5223 0x5225 \ + 0x5226 0x5227 0x522A 0x522C 0x522F 0x5231 0x5232 0x5234 \ + 0x5235 0x523C 0x523E 0x5244 0x5245 0x5246 0x5247 0x5248 \ + 0x5249 0x524B 0x524E 0x524F 0x5252 0x5253 0x5255 0x5257 \ + 0x5258 0x5259 0x525A 0x525B 0x525D 0x525F 0x5260 0x5262 \ + 0x5263 0x5264 0x5266 0x5268 0x526B 0x526C 0x526D 0x526E \ + 0x5270 0x5271 0x5273 0x5274 0x5275 0x5276 0x5277 0x5278 \ + 0x5279 0x527A 0x527B 0x527C 0x527E 0x5280 0x5283 0x5284 \ + 0x5285 0x5286 0x5287 0x5289 0x528A 0x528B 0x528C 0x528D \ + 0x528E 0x528F 0x5291 0x5292 0x5294 0x5295 0x5296 0x5297 \ + 0x5298 0x5299 0x529A 0x529C 0x52A4 0x52A5 0x52A6 0x52A7 \ + 0x52AE 0x52AF 0x52B0 0x52B4 0x52B5 0x52B6 0x52B7 0x52B8 \ + 0x52B9 0x52BA 0x52BB 0x52BC 0x52BD 0x52C0 0x52C1 0x52C2 \ + 0x52C4 0x52C5 0x52C6 0x52C8 0x52CA 0x52CC 0x52CD 0x52CE \ + 0x52CF 0x52D1 0x52D3 0x52D4 0x52D5 0x52D7 0x52D9 0x52DA \ + 0x52DB 0x52DC 0x52DD 0x52DE 0x52E0 0x52E1 0x52E2 0x52E3 \ + 0x52E5 0x52E6 0x52E7 0x52E8 0x52E9 0x52EA 0x52EB 0x52EC \ + 0x52ED 0x52EE 0x52EF 0x52F1 0x52F2 0x52F3 0x52F4 0x52F5 \ + 0x52F6 0x52F7 0x52F8 0x52FB 0x52FC 0x52FD 0x5301 0x5302 \ + 0x5303 0x5304 0x5307 0x5309 0x530A 0x530B 0x530C 0x530E \ + 0x5311 0x5312 0x5313 0x5314 0x5318 0x531B 0x531C 0x531E +04 0x531F 0x5322 0x5324 0x5325 0x5327 0x5328 0x5329 0x532B \ + 0x532C 0x532D 0x532F 0x5330 0x5331 0x5332 0x5333 0x5334 \ + 0x5335 0x5336 0x5337 0x5338 0x533C 0x533D 0x5340 0x5342 \ + 0x5344 0x5346 0x534B 0x534C 0x534D 0x5350 0x5354 0x5358 \ + 0x5359 0x535B 0x535D 0x5365 0x5368 0x536A 0x536C 0x536D \ + 0x5372 0x5376 0x5379 0x537B 0x537C 0x537D 0x537E 0x5380 \ + 0x5381 0x5383 0x5387 0x5388 0x538A 0x538E 0x538F 0x5390 \ + 0x5391 0x5392 0x5393 0x5394 0x5396 0x5397 0x5399 0x539B \ + 0x539C 0x539E 0x53A0 0x53A1 0x53A4 0x53A7 0x53AA 0x53AB \ + 0x53AC 0x53AD 0x53AF 0x53B0 0x53B1 0x53B2 0x53B3 0x53B4 \ + 0x53B5 0x53B7 0x53B8 0x53B9 0x53BA 0x53BC 0x53BD 0x53BE \ + 0x53C0 0x53C3 0x53C4 0x53C5 0x53C6 0x53C7 0x53CE 0x53CF \ + 0x53D0 0x53D2 0x53D3 0x53D5 0x53DA 0x53DC 0x53DD 0x53DE \ + 0x53E1 0x53E2 0x53E7 0x53F4 0x53FA 0x53FE 0x53FF 0x5400 \ + 0x5402 0x5405 0x5407 0x540B 0x5414 0x5418 0x5419 0x541A \ + 0x541C 0x5422 0x5424 0x5425 0x542A 0x5430 0x5433 0x5436 \ + 0x5437 0x543A 0x543D 0x543F 0x5441 0x5442 0x5444 0x5445 \ + 0x5447 0x5449 0x544C 0x544D 0x544E 0x544F 0x5451 0x545A \ + 0x545D 0x545E 0x545F 0x5460 0x5461 0x5463 0x5465 0x5467 \ + 0x5469 0x546A 0x546B 0x546C 0x546D 0x546E 0x546F 0x5470 \ + 0x5474 0x5479 0x547A 0x547E 0x547F 0x5481 0x5483 0x5485 \ + 0x5487 0x5488 0x5489 0x548A 0x548D 0x5491 0x5493 0x5497 \ + 0x5498 0x549C 0x549E 0x549F 0x54A0 0x54A1 0x54A2 0x54A5 \ + 0x54AE 0x54B0 0x54B2 0x54B5 0x54B6 0x54B7 0x54B9 0x54BA \ + 0x54BC 0x54BE 0x54C3 0x54C5 0x54CA 0x54CB 0x54D6 0x54D8 \ + 0x54DB 0x54E0 0x54E1 0x54E2 0x54E3 0x54E4 0x54EB 0x54EC \ + 0x54EF 0x54F0 0x54F1 0x54F4 0x54F5 0x54F6 0x54F7 0x54F8 \ + 0x54F9 0x54FB 0x54FE 0x5500 0x5502 0x5503 0x5504 0x5505 \ + 0x5508 0x550A 0x550B 0x550C 0x550D 0x550E 0x5512 0x5513 \ + 0x5515 0x5516 0x5517 0x5518 0x5519 0x551A 0x551C 0x551D \ + 0x551E 0x551F 0x5521 0x5525 0x5526 0x5528 0x5529 0x552B \ + 0x552D 0x5532 0x5534 0x5535 0x5536 0x5538 0x5539 0x553A +05 0x553B 0x553D 0x5540 0x5542 0x5545 0x5547 0x5548 0x554B \ + 0x554C 0x554D 0x554E 0x554F 0x5551 0x5552 0x5553 0x5554 \ + 0x5557 0x5558 0x5559 0x555A 0x555B 0x555D 0x555E 0x555F \ + 0x5560 0x5562 0x5563 0x5568 0x5569 0x556B 0x556F 0x5570 \ + 0x5571 0x5572 0x5573 0x5574 0x5579 0x557A 0x557D 0x557F \ + 0x5585 0x5586 0x558C 0x558D 0x558E 0x5590 0x5592 0x5593 \ + 0x5595 0x5596 0x5597 0x559A 0x559B 0x559E 0x55A0 0x55A1 \ + 0x55A2 0x55A3 0x55A4 0x55A5 0x55A6 0x55A8 0x55A9 0x55AA \ + 0x55AB 0x55AC 0x55AD 0x55AE 0x55AF 0x55B0 0x55B2 0x55B4 \ + 0x55B6 0x55B8 0x55BA 0x55BC 0x55BF 0x55C0 0x55C1 0x55C2 \ + 0x55C3 0x55C6 0x55C7 0x55C8 0x55CA 0x55CB 0x55CE 0x55CF \ + 0x55D0 0x55D5 0x55D7 0x55D8 0x55D9 0x55DA 0x55DB 0x55DE \ + 0x55E0 0x55E2 0x55E7 0x55E9 0x55ED 0x55EE 0x55F0 0x55F1 \ + 0x55F4 0x55F6 0x55F8 0x55F9 0x55FA 0x55FB 0x55FC 0x55FF \ + 0x5602 0x5603 0x5604 0x5605 0x5606 0x5607 0x560A 0x560B \ + 0x560D 0x5610 0x5611 0x5612 0x5613 0x5614 0x5615 0x5616 \ + 0x5617 0x5619 0x561A 0x561C 0x561D 0x5620 0x5621 0x5622 \ + 0x5625 0x5626 0x5628 0x5629 0x562A 0x562B 0x562E 0x562F \ + 0x5630 0x5633 0x5635 0x5637 0x5638 0x563A 0x563C 0x563D \ + 0x563E 0x5640 0x5641 0x5642 0x5643 0x5644 0x5645 0x5646 \ + 0x5647 0x5648 0x5649 0x564A 0x564B 0x564F 0x5650 0x5651 \ + 0x5652 0x5653 0x5655 0x5656 0x565A 0x565B 0x565D 0x565E \ + 0x565F 0x5660 0x5661 0x5663 0x5665 0x5666 0x5667 0x566D \ + 0x566E 0x566F 0x5670 0x5672 0x5673 0x5674 0x5675 0x5677 \ + 0x5678 0x5679 0x567A 0x567D 0x567E 0x567F 0x5680 0x5681 \ + 0x5682 0x5683 0x5684 0x5687 0x5688 0x5689 0x568A 0x568B \ + 0x568C 0x568D 0x5690 0x5691 0x5692 0x5694 0x5695 0x5696 \ + 0x5697 0x5698 0x5699 0x569A 0x569B 0x569C 0x569D 0x569E \ + 0x569F 0x56A0 0x56A1 0x56A2 0x56A4 0x56A5 0x56A6 0x56A7 \ + 0x56A8 0x56A9 0x56AA 0x56AB 0x56AC 0x56AD 0x56AE 0x56B0 \ + 0x56B1 0x56B2 0x56B3 0x56B4 0x56B5 0x56B6 0x56B8 0x56B9 \ + 0x56BA 0x56BB 0x56BD 0x56BE 0x56BF 0x56C0 0x56C1 0x56C2 +06 0x56C3 0x56C4 0x56C5 0x56C6 0x56C7 0x56C8 0x56C9 0x56CB \ + 0x56CC 0x56CD 0x56CE 0x56CF 0x56D0 0x56D1 0x56D2 0x56D3 \ + 0x56D5 0x56D6 0x56D8 0x56D9 0x56DC 0x56E3 0x56E5 0x56E6 \ + 0x56E7 0x56E8 0x56E9 0x56EA 0x56EC 0x56EE 0x56EF 0x56F2 \ + 0x56F3 0x56F6 0x56F7 0x56F8 0x56FB 0x56FC 0x5700 0x5701 \ + 0x5702 0x5705 0x5707 0x570B 0x570C 0x570D 0x570E 0x570F \ + 0x5710 0x5711 0x5712 0x5713 0x5714 0x5715 0x5716 0x5717 \ + 0x5718 0x5719 0x571A 0x571B 0x571D 0x571E 0x5720 0x5721 \ + 0x5722 0x5724 0x5725 0x5726 0x5727 0x572B 0x5731 0x5732 \ + 0x5734 0x5735 0x5736 0x5737 0x5738 0x573C 0x573D 0x573F \ + 0x5741 0x5743 0x5744 0x5745 0x5746 0x5748 0x5749 0x574B \ + 0x5752 0x5753 0x5754 0x5755 0x5756 0x5758 0x5759 0x5762 \ + 0x5763 0x5765 0x5767 0x576C 0x576E 0x5770 0x5771 0x5772 \ + 0x5774 0x5775 0x5778 0x5779 0x577A 0x577D 0x577E 0x577F \ + 0x5780 0x5781 0x5787 0x5788 0x5789 0x578A 0x578D 0x578E \ + 0x578F 0x5790 0x5791 0x5794 0x5795 0x5796 0x5797 0x5798 \ + 0x5799 0x579A 0x579C 0x579D 0x579E 0x579F 0x57A5 0x57A8 \ + 0x57AA 0x57AC 0x57AF 0x57B0 0x57B1 0x57B3 0x57B5 0x57B6 \ + 0x57B7 0x57B9 0x57BA 0x57BB 0x57BC 0x57BD 0x57BE 0x57BF \ + 0x57C0 0x57C1 0x57C4 0x57C5 0x57C6 0x57C7 0x57C8 0x57C9 \ + 0x57CA 0x57CC 0x57CD 0x57D0 0x57D1 0x57D3 0x57D6 0x57D7 \ + 0x57DB 0x57DC 0x57DE 0x57E1 0x57E2 0x57E3 0x57E5 0x57E6 \ + 0x57E7 0x57E8 0x57E9 0x57EA 0x57EB 0x57EC 0x57EE 0x57F0 \ + 0x57F1 0x57F2 0x57F3 0x57F5 0x57F6 0x57F7 0x57FB 0x57FC \ + 0x57FE 0x57FF 0x5801 0x5803 0x5804 0x5805 0x5808 0x5809 \ + 0x580A 0x580C 0x580E 0x580F 0x5810 0x5812 0x5813 0x5814 \ + 0x5816 0x5817 0x5818 0x581A 0x581B 0x581C 0x581D 0x581F \ + 0x5822 0x5823 0x5825 0x5826 0x5827 0x5828 0x5829 0x582B \ + 0x582C 0x582D 0x582E 0x582F 0x5831 0x5832 0x5833 0x5834 \ + 0x5836 0x5837 0x5838 0x5839 0x583A 0x583B 0x583C 0x583D \ + 0x583E 0x583F 0x5840 0x5841 0x5842 0x5843 0x5845 0x5846 \ + 0x5847 0x5848 0x5849 0x584A 0x584B 0x584E 0x584F 0x5850 +07 0x5852 0x5853 0x5855 0x5856 0x5857 0x5859 0x585A 0x585B \ + 0x585C 0x585D 0x585F 0x5860 0x5861 0x5862 0x5863 0x5864 \ + 0x5866 0x5867 0x5868 0x5869 0x586A 0x586D 0x586E 0x586F \ + 0x5870 0x5871 0x5872 0x5873 0x5874 0x5875 0x5876 0x5877 \ + 0x5878 0x5879 0x587A 0x587B 0x587C 0x587D 0x587F 0x5882 \ + 0x5884 0x5886 0x5887 0x5888 0x588A 0x588B 0x588C 0x588D \ + 0x588E 0x588F 0x5890 0x5891 0x5894 0x5895 0x5896 0x5897 \ + 0x5898 0x589B 0x589C 0x589D 0x58A0 0x58A1 0x58A2 0x58A3 \ + 0x58A4 0x58A5 0x58A6 0x58A7 0x58AA 0x58AB 0x58AC 0x58AD \ + 0x58AE 0x58AF 0x58B0 0x58B1 0x58B2 0x58B3 0x58B4 0x58B5 \ + 0x58B6 0x58B7 0x58B8 0x58B9 0x58BA 0x58BB 0x58BD 0x58BE \ + 0x58BF 0x58C0 0x58C2 0x58C3 0x58C4 0x58C6 0x58C7 0x58C8 \ + 0x58C9 0x58CA 0x58CB 0x58CC 0x58CD 0x58CE 0x58CF 0x58D0 \ + 0x58D2 0x58D3 0x58D4 0x58D6 0x58D7 0x58D8 0x58D9 0x58DA \ + 0x58DB 0x58DC 0x58DD 0x58DE 0x58DF 0x58E0 0x58E1 0x58E2 \ + 0x58E3 0x58E5 0x58E6 0x58E7 0x58E8 0x58E9 0x58EA 0x58ED \ + 0x58EF 0x58F1 0x58F2 0x58F4 0x58F5 0x58F7 0x58F8 0x58FA \ + 0x58FB 0x58FC 0x58FD 0x58FE 0x58FF 0x5900 0x5901 0x5903 \ + 0x5905 0x5906 0x5908 0x5909 0x590A 0x590B 0x590C 0x590E \ + 0x5910 0x5911 0x5912 0x5913 0x5917 0x5918 0x591B 0x591D \ + 0x591E 0x5920 0x5921 0x5922 0x5923 0x5926 0x5928 0x592C \ + 0x5930 0x5932 0x5933 0x5935 0x5936 0x593B 0x593D 0x593E \ + 0x593F 0x5940 0x5943 0x5945 0x5946 0x594A 0x594C 0x594D \ + 0x5950 0x5952 0x5953 0x5959 0x595B 0x595C 0x595D 0x595E \ + 0x595F 0x5961 0x5963 0x5964 0x5966 0x5967 0x5968 0x5969 \ + 0x596A 0x596B 0x596C 0x596D 0x596E 0x596F 0x5970 0x5971 \ + 0x5972 0x5975 0x5977 0x597A 0x597B 0x597C 0x597E 0x597F \ + 0x5980 0x5985 0x5989 0x598B 0x598C 0x598E 0x598F 0x5990 \ + 0x5991 0x5994 0x5995 0x5998 0x599A 0x599B 0x599C 0x599D \ + 0x599F 0x59A0 0x59A1 0x59A2 0x59A6 0x59A7 0x59AC 0x59AD \ + 0x59B0 0x59B1 0x59B3 0x59B4 0x59B5 0x59B6 0x59B7 0x59B8 \ + 0x59BA 0x59BC 0x59BD 0x59BF 0x59C0 0x59C1 0x59C2 0x59C3 +08 0x59C4 0x59C5 0x59C7 0x59C8 0x59C9 0x59CC 0x59CD 0x59CE \ + 0x59CF 0x59D5 0x59D6 0x59D9 0x59DB 0x59DE 0x59DF 0x59E0 \ + 0x59E1 0x59E2 0x59E4 0x59E6 0x59E7 0x59E9 0x59EA 0x59EB \ + 0x59ED 0x59EE 0x59EF 0x59F0 0x59F1 0x59F2 0x59F3 0x59F4 \ + 0x59F5 0x59F6 0x59F7 0x59F8 0x59FA 0x59FC 0x59FD 0x59FE \ + 0x5A00 0x5A02 0x5A0A 0x5A0B 0x5A0D 0x5A0E 0x5A0F 0x5A10 \ + 0x5A12 0x5A14 0x5A15 0x5A16 0x5A17 0x5A19 0x5A1A 0x5A1B \ + 0x5A1D 0x5A1E 0x5A21 0x5A22 0x5A24 0x5A26 0x5A27 0x5A28 \ + 0x5A2A 0x5A2B 0x5A2C 0x5A2D 0x5A2E 0x5A2F 0x5A30 0x5A33 \ + 0x5A35 0x5A37 0x5A38 0x5A39 0x5A3A 0x5A3B 0x5A3D 0x5A3E \ + 0x5A3F 0x5A41 0x5A42 0x5A43 0x5A44 0x5A45 0x5A47 0x5A48 \ + 0x5A4B 0x5A4C 0x5A4D 0x5A4E 0x5A4F 0x5A50 0x5A51 0x5A52 \ + 0x5A53 0x5A54 0x5A56 0x5A57 0x5A58 0x5A59 0x5A5B 0x5A5C \ + 0x5A5D 0x5A5E 0x5A5F 0x5A60 0x5A61 0x5A63 0x5A64 0x5A65 \ + 0x5A66 0x5A68 0x5A69 0x5A6B 0x5A6C 0x5A6D 0x5A6E 0x5A6F \ + 0x5A70 0x5A71 0x5A72 0x5A73 0x5A78 0x5A79 0x5A7B 0x5A7C \ + 0x5A7D 0x5A7E 0x5A80 0x5A81 0x5A82 0x5A83 0x5A84 0x5A85 \ + 0x5A86 0x5A87 0x5A88 0x5A89 0x5A8A 0x5A8B 0x5A8C 0x5A8D \ + 0x5A8E 0x5A8F 0x5A90 0x5A91 0x5A93 0x5A94 0x5A95 0x5A96 \ + 0x5A97 0x5A98 0x5A99 0x5A9C 0x5A9D 0x5A9E 0x5A9F 0x5AA0 \ + 0x5AA1 0x5AA2 0x5AA3 0x5AA4 0x5AA5 0x5AA6 0x5AA7 0x5AA8 \ + 0x5AA9 0x5AAB 0x5AAC 0x5AAD 0x5AAE 0x5AAF 0x5AB0 0x5AB1 \ + 0x5AB4 0x5AB6 0x5AB7 0x5AB9 0x5ABA 0x5ABB 0x5ABC 0x5ABD \ + 0x5ABF 0x5AC0 0x5AC3 0x5AC4 0x5AC5 0x5AC6 0x5AC7 0x5AC8 \ + 0x5ACA 0x5ACB 0x5ACD 0x5ACE 0x5ACF 0x5AD0 0x5AD1 0x5AD3 \ + 0x5AD5 0x5AD7 0x5AD9 0x5ADA 0x5ADB 0x5ADD 0x5ADE 0x5ADF \ + 0x5AE2 0x5AE4 0x5AE5 0x5AE7 0x5AE8 0x5AEA 0x5AEC 0x5AED \ + 0x5AEE 0x5AEF 0x5AF0 0x5AF2 0x5AF3 0x5AF4 0x5AF5 0x5AF6 \ + 0x5AF7 0x5AF8 0x5AF9 0x5AFA 0x5AFB 0x5AFC 0x5AFD 0x5AFE \ + 0x5AFF 0x5B00 0x5B01 0x5B02 0x5B03 0x5B04 0x5B05 0x5B06 \ + 0x5B07 0x5B08 0x5B0A 0x5B0B 0x5B0C 0x5B0D 0x5B0E 0x5B0F \ + 0x5B10 0x5B11 0x5B12 0x5B13 0x5B14 0x5B15 0x5B18 0x5B19 +09 0x5B1A 0x5B1B 0x5B1C 0x5B1D 0x5B1E 0x5B1F 0x5B20 0x5B21 \ + 0x5B22 0x5B23 0x5B24 0x5B25 0x5B26 0x5B27 0x5B28 0x5B29 \ + 0x5B2A 0x5B2B 0x5B2C 0x5B2D 0x5B2E 0x5B2F 0x5B30 0x5B31 \ + 0x5B33 0x5B35 0x5B36 0x5B38 0x5B39 0x5B3A 0x5B3B 0x5B3C \ + 0x5B3D 0x5B3E 0x5B3F 0x5B41 0x5B42 0x5B43 0x5B44 0x5B45 \ + 0x5B46 0x5B47 0x5B48 0x5B49 0x5B4A 0x5B4B 0x5B4C 0x5B4D \ + 0x5B4E 0x5B4F 0x5B52 0x5B56 0x5B5E 0x5B60 0x5B61 0x5B67 \ + 0x5B68 0x5B6B 0x5B6D 0x5B6E 0x5B6F 0x5B72 0x5B74 0x5B76 \ + 0x5B77 0x5B78 0x5B79 0x5B7B 0x5B7C 0x5B7E 0x5B7F 0x5B82 \ + 0x5B86 0x5B8A 0x5B8D 0x5B8E 0x5B90 0x5B91 0x5B92 0x5B94 \ + 0x5B96 0x5B9F 0x5BA7 0x5BA8 0x5BA9 0x5BAC 0x5BAD 0x5BAE \ + 0x5BAF 0x5BB1 0x5BB2 0x5BB7 0x5BBA 0x5BBB 0x5BBC 0x5BC0 \ + 0x5BC1 0x5BC3 0x5BC8 0x5BC9 0x5BCA 0x5BCB 0x5BCD 0x5BCE \ + 0x5BCF 0x5BD1 0x5BD4 0x5BD5 0x5BD6 0x5BD7 0x5BD8 0x5BD9 \ + 0x5BDA 0x5BDB 0x5BDC 0x5BE0 0x5BE2 0x5BE3 0x5BE6 0x5BE7 \ + 0x5BE9 0x5BEA 0x5BEB 0x5BEC 0x5BED 0x5BEF 0x5BF1 0x5BF2 \ + 0x5BF3 0x5BF4 0x5BF5 0x5BF6 0x5BF7 0x5BFD 0x5BFE 0x5C00 \ + 0x5C02 0x5C03 0x5C05 0x5C07 0x5C08 0x5C0B 0x5C0C 0x5C0D \ + 0x5C0E 0x5C10 0x5C12 0x5C13 0x5C17 0x5C19 0x5C1B 0x5C1E \ + 0x5C1F 0x5C20 0x5C21 0x5C23 0x5C26 0x5C28 0x5C29 0x5C2A \ + 0x5C2B 0x5C2D 0x5C2E 0x5C2F 0x5C30 0x5C32 0x5C33 0x5C35 \ + 0x5C36 0x5C37 0x5C43 0x5C44 0x5C46 0x5C47 0x5C4C 0x5C4D \ + 0x5C52 0x5C53 0x5C54 0x5C56 0x5C57 0x5C58 0x5C5A 0x5C5B \ + 0x5C5C 0x5C5D 0x5C5F 0x5C62 0x5C64 0x5C67 0x5C68 0x5C69 \ + 0x5C6A 0x5C6B 0x5C6C 0x5C6D 0x5C70 0x5C72 0x5C73 0x5C74 \ + 0x5C75 0x5C76 0x5C77 0x5C78 0x5C7B 0x5C7C 0x5C7D 0x5C7E \ + 0x5C80 0x5C83 0x5C84 0x5C85 0x5C86 0x5C87 0x5C89 0x5C8A \ + 0x5C8B 0x5C8E 0x5C8F 0x5C92 0x5C93 0x5C95 0x5C9D 0x5C9E \ + 0x5C9F 0x5CA0 0x5CA1 0x5CA4 0x5CA5 0x5CA6 0x5CA7 0x5CA8 \ + 0x5CAA 0x5CAE 0x5CAF 0x5CB0 0x5CB2 0x5CB4 0x5CB6 0x5CB9 \ + 0x5CBA 0x5CBB 0x5CBC 0x5CBE 0x5CC0 0x5CC2 0x5CC3 0x5CC5 \ + 0x5CC6 0x5CC7 0x5CC8 0x5CC9 0x5CCA 0x5CCC 0x5CCD 0x5CCE +10 0x5CCF 0x5CD0 0x5CD1 0x5CD3 0x5CD4 0x5CD5 0x5CD6 0x5CD7 \ + 0x5CD8 0x5CDA 0x5CDB 0x5CDC 0x5CDD 0x5CDE 0x5CDF 0x5CE0 \ + 0x5CE2 0x5CE3 0x5CE7 0x5CE9 0x5CEB 0x5CEC 0x5CEE 0x5CEF \ + 0x5CF1 0x5CF2 0x5CF3 0x5CF4 0x5CF5 0x5CF6 0x5CF7 0x5CF8 \ + 0x5CF9 0x5CFA 0x5CFC 0x5CFD 0x5CFE 0x5CFF 0x5D00 0x5D01 \ + 0x5D04 0x5D05 0x5D08 0x5D09 0x5D0A 0x5D0B 0x5D0C 0x5D0D \ + 0x5D0F 0x5D10 0x5D11 0x5D12 0x5D13 0x5D15 0x5D17 0x5D18 \ + 0x5D19 0x5D1A 0x5D1C 0x5D1D 0x5D1F 0x5D20 0x5D21 0x5D22 \ + 0x5D23 0x5D25 0x5D28 0x5D2A 0x5D2B 0x5D2C 0x5D2F 0x5D30 \ + 0x5D31 0x5D32 0x5D33 0x5D35 0x5D36 0x5D37 0x5D38 0x5D39 \ + 0x5D3A 0x5D3B 0x5D3C 0x5D3F 0x5D40 0x5D41 0x5D42 0x5D43 \ + 0x5D44 0x5D45 0x5D46 0x5D48 0x5D49 0x5D4D 0x5D4E 0x5D4F \ + 0x5D50 0x5D51 0x5D52 0x5D53 0x5D54 0x5D55 0x5D56 0x5D57 \ + 0x5D59 0x5D5A 0x5D5C 0x5D5E 0x5D5F 0x5D60 0x5D61 0x5D62 \ + 0x5D63 0x5D64 0x5D65 0x5D66 0x5D67 0x5D68 0x5D6A 0x5D6D \ + 0x5D6E 0x5D70 0x5D71 0x5D72 0x5D73 0x5D75 0x5D76 0x5D77 \ + 0x5D78 0x5D79 0x5D7A 0x5D7B 0x5D7C 0x5D7D 0x5D7E 0x5D7F \ + 0x5D80 0x5D81 0x5D83 0x5D84 0x5D85 0x5D86 0x5D87 0x5D88 \ + 0x5D89 0x5D8A 0x5D8B 0x5D8C 0x5D8D 0x5D8E 0x5D8F 0x5D90 \ + 0x5D91 0x5D92 0x5D93 0x5D94 0x5D95 0x5D96 0x5D97 0x5D98 \ + 0x5D9A 0x5D9B 0x5D9C 0x5D9E 0x5D9F 0x5DA0 0x5DA1 0x5DA2 \ + 0x5DA3 0x5DA4 0x5DA5 0x5DA6 0x5DA7 0x5DA8 0x5DA9 0x5DAA \ + 0x5DAB 0x5DAC 0x5DAD 0x5DAE 0x5DAF 0x5DB0 0x5DB1 0x5DB2 \ + 0x5DB3 0x5DB4 0x5DB5 0x5DB6 0x5DB8 0x5DB9 0x5DBA 0x5DBB \ + 0x5DBC 0x5DBD 0x5DBE 0x5DBF 0x5DC0 0x5DC1 0x5DC2 0x5DC3 \ + 0x5DC4 0x5DC6 0x5DC7 0x5DC8 0x5DC9 0x5DCA 0x5DCB 0x5DCC \ + 0x5DCE 0x5DCF 0x5DD0 0x5DD1 0x5DD2 0x5DD3 0x5DD4 0x5DD5 \ + 0x5DD6 0x5DD7 0x5DD8 0x5DD9 0x5DDA 0x5DDC 0x5DDF 0x5DE0 \ + 0x5DE3 0x5DE4 0x5DEA 0x5DEC 0x5DED 0x5DF0 0x5DF5 0x5DF6 \ + 0x5DF8 0x5DF9 0x5DFA 0x5DFB 0x5DFC 0x5DFF 0x5E00 0x5E04 \ + 0x5E07 0x5E09 0x5E0A 0x5E0B 0x5E0D 0x5E0E 0x5E12 0x5E13 \ + 0x5E17 0x5E1E 0x5E1F 0x5E20 0x5E21 0x5E22 0x5E23 0x5E24 +11 0x5E25 0x5E28 0x5E29 0x5E2A 0x5E2B 0x5E2C 0x5E2F 0x5E30 \ + 0x5E32 0x5E33 0x5E34 0x5E35 0x5E36 0x5E39 0x5E3A 0x5E3E \ + 0x5E3F 0x5E40 0x5E41 0x5E43 0x5E46 0x5E47 0x5E48 0x5E49 \ + 0x5E4A 0x5E4B 0x5E4D 0x5E4E 0x5E4F 0x5E50 0x5E51 0x5E52 \ + 0x5E53 0x5E56 0x5E57 0x5E58 0x5E59 0x5E5A 0x5E5C 0x5E5D \ + 0x5E5F 0x5E60 0x5E63 0x5E64 0x5E65 0x5E66 0x5E67 0x5E68 \ + 0x5E69 0x5E6A 0x5E6B 0x5E6C 0x5E6D 0x5E6E 0x5E6F 0x5E70 \ + 0x5E71 0x5E75 0x5E77 0x5E79 0x5E7E 0x5E81 0x5E82 0x5E83 \ + 0x5E85 0x5E88 0x5E89 0x5E8C 0x5E8D 0x5E8E 0x5E92 0x5E98 \ + 0x5E9B 0x5E9D 0x5EA1 0x5EA2 0x5EA3 0x5EA4 0x5EA8 0x5EA9 \ + 0x5EAA 0x5EAB 0x5EAC 0x5EAE 0x5EAF 0x5EB0 0x5EB1 0x5EB2 \ + 0x5EB4 0x5EBA 0x5EBB 0x5EBC 0x5EBD 0x5EBF 0x5EC0 0x5EC1 \ + 0x5EC2 0x5EC3 0x5EC4 0x5EC5 0x5EC6 0x5EC7 0x5EC8 0x5ECB \ + 0x5ECC 0x5ECD 0x5ECE 0x5ECF 0x5ED0 0x5ED4 0x5ED5 0x5ED7 \ + 0x5ED8 0x5ED9 0x5EDA 0x5EDC 0x5EDD 0x5EDE 0x5EDF 0x5EE0 \ + 0x5EE1 0x5EE2 0x5EE3 0x5EE4 0x5EE5 0x5EE6 0x5EE7 0x5EE9 \ + 0x5EEB 0x5EEC 0x5EED 0x5EEE 0x5EEF 0x5EF0 0x5EF1 0x5EF2 \ + 0x5EF3 0x5EF5 0x5EF8 0x5EF9 0x5EFB 0x5EFC 0x5EFD 0x5F05 \ + 0x5F06 0x5F07 0x5F09 0x5F0C 0x5F0D 0x5F0E 0x5F10 0x5F12 \ + 0x5F14 0x5F16 0x5F19 0x5F1A 0x5F1C 0x5F1D 0x5F1E 0x5F21 \ + 0x5F22 0x5F23 0x5F24 0x5F28 0x5F2B 0x5F2C 0x5F2E 0x5F30 \ + 0x5F32 0x5F33 0x5F34 0x5F35 0x5F36 0x5F37 0x5F38 0x5F3B \ + 0x5F3D 0x5F3E 0x5F3F 0x5F41 0x5F42 0x5F43 0x5F44 0x5F45 \ + 0x5F46 0x5F47 0x5F48 0x5F49 0x5F4A 0x5F4B 0x5F4C 0x5F4D \ + 0x5F4E 0x5F4F 0x5F51 0x5F54 0x5F59 0x5F5A 0x5F5B 0x5F5C \ + 0x5F5E 0x5F5F 0x5F60 0x5F63 0x5F65 0x5F67 0x5F68 0x5F6B \ + 0x5F6E 0x5F6F 0x5F72 0x5F74 0x5F75 0x5F76 0x5F78 0x5F7A \ + 0x5F7D 0x5F7E 0x5F7F 0x5F83 0x5F86 0x5F8D 0x5F8E 0x5F8F \ + 0x5F91 0x5F93 0x5F94 0x5F96 0x5F9A 0x5F9B 0x5F9D 0x5F9E \ + 0x5F9F 0x5FA0 0x5FA2 0x5FA3 0x5FA4 0x5FA5 0x5FA6 0x5FA7 \ + 0x5FA9 0x5FAB 0x5FAC 0x5FAF 0x5FB0 0x5FB1 0x5FB2 0x5FB3 \ + 0x5FB4 0x5FB6 0x5FB8 0x5FB9 0x5FBA 0x5FBB 0x5FBE 0x5FBF +12 0x5FC0 0x5FC1 0x5FC2 0x5FC7 0x5FC8 0x5FCA 0x5FCB 0x5FCE \ + 0x5FD3 0x5FD4 0x5FD5 0x5FDA 0x5FDB 0x5FDC 0x5FDE 0x5FDF \ + 0x5FE2 0x5FE3 0x5FE5 0x5FE6 0x5FE8 0x5FE9 0x5FEC 0x5FEF \ + 0x5FF0 0x5FF2 0x5FF3 0x5FF4 0x5FF6 0x5FF7 0x5FF9 0x5FFA \ + 0x5FFC 0x6007 0x6008 0x6009 0x600B 0x600C 0x6010 0x6011 \ + 0x6013 0x6017 0x6018 0x601A 0x601E 0x601F 0x6022 0x6023 \ + 0x6024 0x602C 0x602D 0x602E 0x6030 0x6031 0x6032 0x6033 \ + 0x6034 0x6036 0x6037 0x6038 0x6039 0x603A 0x603D 0x603E \ + 0x6040 0x6044 0x6045 0x6046 0x6047 0x6048 0x6049 0x604A \ + 0x604C 0x604E 0x604F 0x6051 0x6053 0x6054 0x6056 0x6057 \ + 0x6058 0x605B 0x605C 0x605E 0x605F 0x6060 0x6061 0x6065 \ + 0x6066 0x606E 0x6071 0x6072 0x6074 0x6075 0x6077 0x607E \ + 0x6080 0x6081 0x6082 0x6085 0x6086 0x6087 0x6088 0x608A \ + 0x608B 0x608E 0x608F 0x6090 0x6091 0x6093 0x6095 0x6097 \ + 0x6098 0x6099 0x609C 0x609E 0x60A1 0x60A2 0x60A4 0x60A5 \ + 0x60A7 0x60A9 0x60AA 0x60AE 0x60B0 0x60B3 0x60B5 0x60B6 \ + 0x60B7 0x60B9 0x60BA 0x60BD 0x60BE 0x60BF 0x60C0 0x60C1 \ + 0x60C2 0x60C3 0x60C4 0x60C7 0x60C8 0x60C9 0x60CC 0x60CD \ + 0x60CE 0x60CF 0x60D0 0x60D2 0x60D3 0x60D4 0x60D6 0x60D7 \ + 0x60D9 0x60DB 0x60DE 0x60E1 0x60E2 0x60E3 0x60E4 0x60E5 \ + 0x60EA 0x60F1 0x60F2 0x60F5 0x60F7 0x60F8 0x60FB 0x60FC \ + 0x60FD 0x60FE 0x60FF 0x6102 0x6103 0x6104 0x6105 0x6107 \ + 0x610A 0x610B 0x610C 0x6110 0x6111 0x6112 0x6113 0x6114 \ + 0x6116 0x6117 0x6118 0x6119 0x611B 0x611C 0x611D 0x611E \ + 0x6121 0x6122 0x6125 0x6128 0x6129 0x612A 0x612C 0x612D \ + 0x612E 0x612F 0x6130 0x6131 0x6132 0x6133 0x6134 0x6135 \ + 0x6136 0x6137 0x6138 0x6139 0x613A 0x613B 0x613C 0x613D \ + 0x613E 0x6140 0x6141 0x6142 0x6143 0x6144 0x6145 0x6146 \ + 0x6147 0x6149 0x614B 0x614D 0x614F 0x6150 0x6152 0x6153 \ + 0x6154 0x6156 0x6157 0x6158 0x6159 0x615A 0x615B 0x615C \ + 0x615E 0x615F 0x6160 0x6161 0x6163 0x6164 0x6165 0x6166 \ + 0x6169 0x616A 0x616B 0x616C 0x616D 0x616E 0x616F 0x6171 +13 0x6172 0x6173 0x6174 0x6176 0x6178 0x6179 0x617A 0x617B \ + 0x617C 0x617D 0x617E 0x617F 0x6180 0x6181 0x6182 0x6183 \ + 0x6184 0x6185 0x6186 0x6187 0x6188 0x6189 0x618A 0x618C \ + 0x618D 0x618F 0x6190 0x6191 0x6192 0x6193 0x6195 0x6196 \ + 0x6197 0x6198 0x6199 0x619A 0x619B 0x619C 0x619E 0x619F \ + 0x61A0 0x61A1 0x61A2 0x61A3 0x61A4 0x61A5 0x61A6 0x61AA \ + 0x61AB 0x61AD 0x61AE 0x61AF 0x61B0 0x61B1 0x61B2 0x61B3 \ + 0x61B4 0x61B5 0x61B6 0x61B8 0x61B9 0x61BA 0x61BB 0x61BC \ + 0x61BD 0x61BF 0x61C0 0x61C1 0x61C3 0x61C4 0x61C5 0x61C6 \ + 0x61C7 0x61C9 0x61CC 0x61CD 0x61CE 0x61CF 0x61D0 0x61D3 \ + 0x61D5 0x61D6 0x61D7 0x61D8 0x61D9 0x61DA 0x61DB 0x61DC \ + 0x61DD 0x61DE 0x61DF 0x61E0 0x61E1 0x61E2 0x61E3 0x61E4 \ + 0x61E5 0x61E7 0x61E8 0x61E9 0x61EA 0x61EB 0x61EC 0x61ED \ + 0x61EE 0x61EF 0x61F0 0x61F1 0x61F2 0x61F3 0x61F4 0x61F6 \ + 0x61F7 0x61F8 0x61F9 0x61FA 0x61FB 0x61FC 0x61FD 0x61FE \ + 0x6200 0x6201 0x6202 0x6203 0x6204 0x6205 0x6207 0x6209 \ + 0x6213 0x6214 0x6219 0x621C 0x621D 0x621E 0x6220 0x6223 \ + 0x6226 0x6227 0x6228 0x6229 0x622B 0x622D 0x622F 0x6230 \ + 0x6231 0x6232 0x6235 0x6236 0x6238 0x6239 0x623A 0x623B \ + 0x623C 0x6242 0x6244 0x6245 0x6246 0x624A 0x624F 0x6250 \ + 0x6255 0x6256 0x6257 0x6259 0x625A 0x625C 0x625D 0x625E \ + 0x625F 0x6260 0x6261 0x6262 0x6264 0x6265 0x6268 0x6271 \ + 0x6272 0x6274 0x6275 0x6277 0x6278 0x627A 0x627B 0x627D \ + 0x6281 0x6282 0x6283 0x6285 0x6286 0x6287 0x6288 0x628B \ + 0x628C 0x628D 0x628E 0x628F 0x6290 0x6294 0x6299 0x629C \ + 0x629D 0x629E 0x62A3 0x62A6 0x62A7 0x62A9 0x62AA 0x62AD \ + 0x62AE 0x62AF 0x62B0 0x62B2 0x62B3 0x62B4 0x62B6 0x62B7 \ + 0x62B8 0x62BA 0x62BE 0x62C0 0x62C1 0x62C3 0x62CB 0x62CF \ + 0x62D1 0x62D5 0x62DD 0x62DE 0x62E0 0x62E1 0x62E4 0x62EA \ + 0x62EB 0x62F0 0x62F2 0x62F5 0x62F8 0x62F9 0x62FA 0x62FB \ + 0x6300 0x6303 0x6304 0x6305 0x6306 0x630A 0x630B 0x630C \ + 0x630D 0x630F 0x6310 0x6312 0x6313 0x6314 0x6315 0x6317 +14 0x6318 0x6319 0x631C 0x6326 0x6327 0x6329 0x632C 0x632D \ + 0x632E 0x6330 0x6331 0x6333 0x6334 0x6335 0x6336 0x6337 \ + 0x6338 0x633B 0x633C 0x633E 0x633F 0x6340 0x6341 0x6344 \ + 0x6347 0x6348 0x634A 0x6351 0x6352 0x6353 0x6354 0x6356 \ + 0x6357 0x6358 0x6359 0x635A 0x635B 0x635C 0x635D 0x6360 \ + 0x6364 0x6365 0x6366 0x6368 0x636A 0x636B 0x636C 0x636F \ + 0x6370 0x6372 0x6373 0x6374 0x6375 0x6378 0x6379 0x637C \ + 0x637D 0x637E 0x637F 0x6381 0x6383 0x6384 0x6385 0x6386 \ + 0x638B 0x638D 0x6391 0x6393 0x6394 0x6395 0x6397 0x6399 \ + 0x639A 0x639B 0x639C 0x639D 0x639E 0x639F 0x63A1 0x63A4 \ + 0x63A6 0x63AB 0x63AF 0x63B1 0x63B2 0x63B5 0x63B6 0x63B9 \ + 0x63BB 0x63BD 0x63BF 0x63C0 0x63C1 0x63C2 0x63C3 0x63C5 \ + 0x63C7 0x63C8 0x63CA 0x63CB 0x63CC 0x63D1 0x63D3 0x63D4 \ + 0x63D5 0x63D7 0x63D8 0x63D9 0x63DA 0x63DB 0x63DC 0x63DD \ + 0x63DF 0x63E2 0x63E4 0x63E5 0x63E6 0x63E7 0x63E8 0x63EB \ + 0x63EC 0x63EE 0x63EF 0x63F0 0x63F1 0x63F3 0x63F5 0x63F7 \ + 0x63F9 0x63FA 0x63FB 0x63FC 0x63FE 0x6403 0x6404 0x6406 \ + 0x6407 0x6408 0x6409 0x640A 0x640D 0x640E 0x6411 0x6412 \ + 0x6415 0x6416 0x6417 0x6418 0x6419 0x641A 0x641D 0x641F \ + 0x6422 0x6423 0x6424 0x6425 0x6427 0x6428 0x6429 0x642B \ + 0x642E 0x642F 0x6430 0x6431 0x6432 0x6433 0x6435 0x6436 \ + 0x6437 0x6438 0x6439 0x643B 0x643C 0x643E 0x6440 0x6442 \ + 0x6443 0x6449 0x644B 0x644C 0x644D 0x644E 0x644F 0x6450 \ + 0x6451 0x6453 0x6455 0x6456 0x6457 0x6459 0x645A 0x645B \ + 0x645C 0x645D 0x645F 0x6460 0x6461 0x6462 0x6463 0x6464 \ + 0x6465 0x6466 0x6468 0x646A 0x646B 0x646C 0x646E 0x646F \ + 0x6470 0x6471 0x6472 0x6473 0x6474 0x6475 0x6476 0x6477 \ + 0x647B 0x647C 0x647D 0x647E 0x647F 0x6480 0x6481 0x6483 \ + 0x6486 0x6488 0x6489 0x648A 0x648B 0x648C 0x648D 0x648E \ + 0x648F 0x6490 0x6493 0x6494 0x6497 0x6498 0x649A 0x649B \ + 0x649C 0x649D 0x649F 0x64A0 0x64A1 0x64A2 0x64A3 0x64A5 \ + 0x64A6 0x64A7 0x64A8 0x64AA 0x64AB 0x64AF 0x64B1 0x64B2 +15 0x64B3 0x64B4 0x64B6 0x64B9 0x64BB 0x64BD 0x64BE 0x64BF \ + 0x64C1 0x64C3 0x64C4 0x64C6 0x64C7 0x64C8 0x64C9 0x64CA \ + 0x64CB 0x64CC 0x64CF 0x64D1 0x64D3 0x64D4 0x64D5 0x64D6 \ + 0x64D9 0x64DA 0x64DB 0x64DC 0x64DD 0x64DF 0x64E0 0x64E1 \ + 0x64E3 0x64E5 0x64E7 0x64E8 0x64E9 0x64EA 0x64EB 0x64EC \ + 0x64ED 0x64EE 0x64EF 0x64F0 0x64F1 0x64F2 0x64F3 0x64F4 \ + 0x64F5 0x64F6 0x64F7 0x64F8 0x64F9 0x64FA 0x64FB 0x64FC \ + 0x64FD 0x64FE 0x64FF 0x6501 0x6502 0x6503 0x6504 0x6505 \ + 0x6506 0x6507 0x6508 0x650A 0x650B 0x650C 0x650D 0x650E \ + 0x650F 0x6510 0x6511 0x6513 0x6514 0x6515 0x6516 0x6517 \ + 0x6519 0x651A 0x651B 0x651C 0x651D 0x651E 0x651F 0x6520 \ + 0x6521 0x6522 0x6523 0x6524 0x6526 0x6527 0x6528 0x6529 \ + 0x652A 0x652C 0x652D 0x6530 0x6531 0x6532 0x6533 0x6537 \ + 0x653A 0x653C 0x653D 0x6540 0x6541 0x6542 0x6543 0x6544 \ + 0x6546 0x6547 0x654A 0x654B 0x654D 0x654E 0x6550 0x6552 \ + 0x6553 0x6554 0x6557 0x6558 0x655A 0x655C 0x655F 0x6560 \ + 0x6561 0x6564 0x6565 0x6567 0x6568 0x6569 0x656A 0x656D \ + 0x656E 0x656F 0x6571 0x6573 0x6575 0x6576 0x6578 0x6579 \ + 0x657A 0x657B 0x657C 0x657D 0x657E 0x657F 0x6580 0x6581 \ + 0x6582 0x6583 0x6584 0x6585 0x6586 0x6588 0x6589 0x658A \ + 0x658D 0x658E 0x658F 0x6592 0x6594 0x6595 0x6596 0x6598 \ + 0x659A 0x659D 0x659E 0x65A0 0x65A2 0x65A3 0x65A6 0x65A8 \ + 0x65AA 0x65AC 0x65AE 0x65B1 0x65B2 0x65B3 0x65B4 0x65B5 \ + 0x65B6 0x65B7 0x65B8 0x65BA 0x65BB 0x65BE 0x65BF 0x65C0 \ + 0x65C2 0x65C7 0x65C8 0x65C9 0x65CA 0x65CD 0x65D0 0x65D1 \ + 0x65D3 0x65D4 0x65D5 0x65D8 0x65D9 0x65DA 0x65DB 0x65DC \ + 0x65DD 0x65DE 0x65DF 0x65E1 0x65E3 0x65E4 0x65EA 0x65EB \ + 0x65F2 0x65F3 0x65F4 0x65F5 0x65F8 0x65F9 0x65FB 0x65FC \ + 0x65FD 0x65FE 0x65FF 0x6601 0x6604 0x6605 0x6607 0x6608 \ + 0x6609 0x660B 0x660D 0x6610 0x6611 0x6612 0x6616 0x6617 \ + 0x6618 0x661A 0x661B 0x661C 0x661E 0x6621 0x6622 0x6623 \ + 0x6624 0x6626 0x6629 0x662A 0x662B 0x662C 0x662E 0x6630 +16 0x6632 0x6633 0x6637 0x6638 0x6639 0x663A 0x663B 0x663D \ + 0x663F 0x6640 0x6642 0x6644 0x6645 0x6646 0x6647 0x6648 \ + 0x6649 0x664A 0x664D 0x664E 0x6650 0x6651 0x6658 0x6659 \ + 0x665B 0x665C 0x665D 0x665E 0x6660 0x6662 0x6663 0x6665 \ + 0x6667 0x6669 0x666A 0x666B 0x666C 0x666D 0x6671 0x6672 \ + 0x6673 0x6675 0x6678 0x6679 0x667B 0x667C 0x667D 0x667F \ + 0x6680 0x6681 0x6683 0x6685 0x6686 0x6688 0x6689 0x668A \ + 0x668B 0x668D 0x668E 0x668F 0x6690 0x6692 0x6693 0x6694 \ + 0x6695 0x6698 0x6699 0x669A 0x669B 0x669C 0x669E 0x669F \ + 0x66A0 0x66A1 0x66A2 0x66A3 0x66A4 0x66A5 0x66A6 0x66A9 \ + 0x66AA 0x66AB 0x66AC 0x66AD 0x66AF 0x66B0 0x66B1 0x66B2 \ + 0x66B3 0x66B5 0x66B6 0x66B7 0x66B8 0x66BA 0x66BB 0x66BC \ + 0x66BD 0x66BF 0x66C0 0x66C1 0x66C2 0x66C3 0x66C4 0x66C5 \ + 0x66C6 0x66C7 0x66C8 0x66C9 0x66CA 0x66CB 0x66CC 0x66CD \ + 0x66CE 0x66CF 0x66D0 0x66D1 0x66D2 0x66D3 0x66D4 0x66D5 \ + 0x66D6 0x66D7 0x66D8 0x66DA 0x66DE 0x66DF 0x66E0 0x66E1 \ + 0x66E2 0x66E3 0x66E4 0x66E5 0x66E7 0x66E8 0x66EA 0x66EB \ + 0x66EC 0x66ED 0x66EE 0x66EF 0x66F1 0x66F5 0x66F6 0x66F8 \ + 0x66FA 0x66FB 0x66FD 0x6701 0x6702 0x6703 0x6704 0x6705 \ + 0x6706 0x6707 0x670C 0x670E 0x670F 0x6711 0x6712 0x6713 \ + 0x6716 0x6718 0x6719 0x671A 0x671C 0x671E 0x6720 0x6721 \ + 0x6722 0x6723 0x6724 0x6725 0x6727 0x6729 0x672E 0x6730 \ + 0x6732 0x6733 0x6736 0x6737 0x6738 0x6739 0x673B 0x673C \ + 0x673E 0x673F 0x6741 0x6744 0x6745 0x6747 0x674A 0x674B \ + 0x674D 0x6752 0x6754 0x6755 0x6757 0x6758 0x6759 0x675A \ + 0x675B 0x675D 0x6762 0x6763 0x6764 0x6766 0x6767 0x676B \ + 0x676C 0x676E 0x6771 0x6774 0x6776 0x6778 0x6779 0x677A \ + 0x677B 0x677D 0x6780 0x6782 0x6783 0x6785 0x6786 0x6788 \ + 0x678A 0x678C 0x678D 0x678E 0x678F 0x6791 0x6792 0x6793 \ + 0x6794 0x6796 0x6799 0x679B 0x679F 0x67A0 0x67A1 0x67A4 \ + 0x67A6 0x67A9 0x67AC 0x67AE 0x67B1 0x67B2 0x67B4 0x67B9 \ + 0x67BA 0x67BB 0x67BC 0x67BD 0x67BE 0x67BF 0x67C0 0x67C2 +17 0x67C5 0x67C6 0x67C7 0x67C8 0x67C9 0x67CA 0x67CB 0x67CC \ + 0x67CD 0x67CE 0x67D5 0x67D6 0x67D7 0x67DB 0x67DF 0x67E1 \ + 0x67E3 0x67E4 0x67E6 0x67E7 0x67E8 0x67EA 0x67EB 0x67ED \ + 0x67EE 0x67F2 0x67F5 0x67F6 0x67F7 0x67F8 0x67F9 0x67FA \ + 0x67FB 0x67FC 0x67FE 0x6801 0x6802 0x6803 0x6804 0x6806 \ + 0x680D 0x6810 0x6812 0x6814 0x6815 0x6818 0x6819 0x681A \ + 0x681B 0x681C 0x681E 0x681F 0x6820 0x6822 0x6823 0x6824 \ + 0x6825 0x6826 0x6827 0x6828 0x682B 0x682C 0x682D 0x682E \ + 0x682F 0x6830 0x6831 0x6834 0x6835 0x6836 0x683A 0x683B \ + 0x683F 0x6847 0x684B 0x684D 0x684F 0x6852 0x6856 0x6857 \ + 0x6858 0x6859 0x685A 0x685B 0x685C 0x685D 0x685E 0x685F \ + 0x686A 0x686C 0x686D 0x686E 0x686F 0x6870 0x6871 0x6872 \ + 0x6873 0x6875 0x6878 0x6879 0x687A 0x687B 0x687C 0x687D \ + 0x687E 0x687F 0x6880 0x6882 0x6884 0x6887 0x6888 0x6889 \ + 0x688A 0x688B 0x688C 0x688D 0x688E 0x6890 0x6891 0x6892 \ + 0x6894 0x6895 0x6896 0x6898 0x6899 0x689A 0x689B 0x689C \ + 0x689D 0x689E 0x689F 0x68A0 0x68A1 0x68A3 0x68A4 0x68A5 \ + 0x68A9 0x68AA 0x68AB 0x68AC 0x68AE 0x68B1 0x68B2 0x68B4 \ + 0x68B6 0x68B7 0x68B8 0x68B9 0x68BA 0x68BB 0x68BC 0x68BD \ + 0x68BE 0x68BF 0x68C1 0x68C3 0x68C4 0x68C5 0x68C6 0x68C7 \ + 0x68C8 0x68CA 0x68CC 0x68CE 0x68CF 0x68D0 0x68D1 0x68D3 \ + 0x68D4 0x68D6 0x68D7 0x68D9 0x68DB 0x68DC 0x68DD 0x68DE \ + 0x68DF 0x68E1 0x68E2 0x68E4 0x68E5 0x68E6 0x68E7 0x68E8 \ + 0x68E9 0x68EA 0x68EB 0x68EC 0x68ED 0x68EF 0x68F2 0x68F3 \ + 0x68F4 0x68F6 0x68F7 0x68F8 0x68FB 0x68FD 0x68FE 0x68FF \ + 0x6900 0x6902 0x6903 0x6904 0x6906 0x6907 0x6908 0x6909 \ + 0x690A 0x690C 0x690F 0x6911 0x6913 0x6914 0x6915 0x6916 \ + 0x6917 0x6918 0x6919 0x691A 0x691B 0x691C 0x691D 0x691E \ + 0x6921 0x6922 0x6923 0x6925 0x6926 0x6927 0x6928 0x6929 \ + 0x692A 0x692B 0x692C 0x692E 0x692F 0x6931 0x6932 0x6933 \ + 0x6935 0x6936 0x6937 0x6938 0x693A 0x693B 0x693C 0x693E \ + 0x6940 0x6941 0x6943 0x6944 0x6945 0x6946 0x6947 0x6948 +18 0x6949 0x694A 0x694B 0x694C 0x694D 0x694E 0x694F 0x6950 \ + 0x6951 0x6952 0x6953 0x6955 0x6956 0x6958 0x6959 0x695B \ + 0x695C 0x695F 0x6961 0x6962 0x6964 0x6965 0x6967 0x6968 \ + 0x6969 0x696A 0x696C 0x696D 0x696F 0x6970 0x6972 0x6973 \ + 0x6974 0x6975 0x6976 0x697A 0x697B 0x697D 0x697E 0x697F \ + 0x6981 0x6983 0x6985 0x698A 0x698B 0x698C 0x698E 0x698F \ + 0x6990 0x6991 0x6992 0x6993 0x6996 0x6997 0x6999 0x699A \ + 0x699D 0x699E 0x699F 0x69A0 0x69A1 0x69A2 0x69A3 0x69A4 \ + 0x69A5 0x69A6 0x69A9 0x69AA 0x69AC 0x69AE 0x69AF 0x69B0 \ + 0x69B2 0x69B3 0x69B5 0x69B6 0x69B8 0x69B9 0x69BA 0x69BC \ + 0x69BD 0x69BE 0x69BF 0x69C0 0x69C2 0x69C3 0x69C4 0x69C5 \ + 0x69C6 0x69C7 0x69C8 0x69C9 0x69CB 0x69CD 0x69CF 0x69D1 \ + 0x69D2 0x69D3 0x69D5 0x69D6 0x69D7 0x69D8 0x69D9 0x69DA \ + 0x69DC 0x69DD 0x69DE 0x69E1 0x69E2 0x69E3 0x69E4 0x69E5 \ + 0x69E6 0x69E7 0x69E8 0x69E9 0x69EA 0x69EB 0x69EC 0x69EE \ + 0x69EF 0x69F0 0x69F1 0x69F3 0x69F4 0x69F5 0x69F6 0x69F7 \ + 0x69F8 0x69F9 0x69FA 0x69FB 0x69FC 0x69FE 0x6A00 0x6A01 \ + 0x6A02 0x6A03 0x6A04 0x6A05 0x6A06 0x6A07 0x6A08 0x6A09 \ + 0x6A0B 0x6A0C 0x6A0D 0x6A0E 0x6A0F 0x6A10 0x6A11 0x6A12 \ + 0x6A13 0x6A14 0x6A15 0x6A16 0x6A19 0x6A1A 0x6A1B 0x6A1C \ + 0x6A1D 0x6A1E 0x6A20 0x6A22 0x6A23 0x6A24 0x6A25 0x6A26 \ + 0x6A27 0x6A29 0x6A2B 0x6A2C 0x6A2D 0x6A2E 0x6A30 0x6A32 \ + 0x6A33 0x6A34 0x6A36 0x6A37 0x6A38 0x6A39 0x6A3A 0x6A3B \ + 0x6A3C 0x6A3F 0x6A40 0x6A41 0x6A42 0x6A43 0x6A45 0x6A46 \ + 0x6A48 0x6A49 0x6A4A 0x6A4B 0x6A4C 0x6A4D 0x6A4E 0x6A4F \ + 0x6A51 0x6A52 0x6A53 0x6A54 0x6A55 0x6A56 0x6A57 0x6A5A \ + 0x6A5C 0x6A5D 0x6A5E 0x6A5F 0x6A60 0x6A62 0x6A63 0x6A64 \ + 0x6A66 0x6A67 0x6A68 0x6A69 0x6A6A 0x6A6B 0x6A6C 0x6A6D \ + 0x6A6E 0x6A6F 0x6A70 0x6A72 0x6A73 0x6A74 0x6A75 0x6A76 \ + 0x6A77 0x6A78 0x6A7A 0x6A7B 0x6A7D 0x6A7E 0x6A7F 0x6A81 \ + 0x6A82 0x6A83 0x6A85 0x6A86 0x6A87 0x6A88 0x6A89 0x6A8A \ + 0x6A8B 0x6A8C 0x6A8D 0x6A8F 0x6A92 0x6A93 0x6A94 0x6A95 +19 0x6A96 0x6A98 0x6A99 0x6A9A 0x6A9B 0x6A9C 0x6A9D 0x6A9E \ + 0x6A9F 0x6AA1 0x6AA2 0x6AA3 0x6AA4 0x6AA5 0x6AA6 0x6AA7 \ + 0x6AA8 0x6AAA 0x6AAD 0x6AAE 0x6AAF 0x6AB0 0x6AB1 0x6AB2 \ + 0x6AB3 0x6AB4 0x6AB5 0x6AB6 0x6AB7 0x6AB8 0x6AB9 0x6ABA \ + 0x6ABB 0x6ABC 0x6ABD 0x6ABE 0x6ABF 0x6AC0 0x6AC1 0x6AC2 \ + 0x6AC3 0x6AC4 0x6AC5 0x6AC6 0x6AC7 0x6AC8 0x6AC9 0x6ACA \ + 0x6ACB 0x6ACC 0x6ACD 0x6ACE 0x6ACF 0x6AD0 0x6AD1 0x6AD2 \ + 0x6AD3 0x6AD4 0x6AD5 0x6AD6 0x6AD7 0x6AD8 0x6AD9 0x6ADA \ + 0x6ADB 0x6ADC 0x6ADD 0x6ADE 0x6ADF 0x6AE0 0x6AE1 0x6AE2 \ + 0x6AE3 0x6AE4 0x6AE5 0x6AE6 0x6AE7 0x6AE8 0x6AE9 0x6AEA \ + 0x6AEB 0x6AEC 0x6AED 0x6AEE 0x6AEF 0x6AF0 0x6AF1 0x6AF2 \ + 0x6AF3 0x6AF4 0x6AF5 0x6AF6 0x6AF7 0x6AF8 0x6AF9 0x6AFA \ + 0x6AFB 0x6AFC 0x6AFD 0x6AFE 0x6AFF 0x6B00 0x6B01 0x6B02 \ + 0x6B03 0x6B04 0x6B05 0x6B06 0x6B07 0x6B08 0x6B09 0x6B0A \ + 0x6B0B 0x6B0C 0x6B0D 0x6B0E 0x6B0F 0x6B10 0x6B11 0x6B12 \ + 0x6B13 0x6B14 0x6B15 0x6B16 0x6B17 0x6B18 0x6B19 0x6B1A \ + 0x6B1B 0x6B1C 0x6B1D 0x6B1E 0x6B1F 0x6B25 0x6B26 0x6B28 \ + 0x6B29 0x6B2A 0x6B2B 0x6B2C 0x6B2D 0x6B2E 0x6B2F 0x6B30 \ + 0x6B31 0x6B33 0x6B34 0x6B35 0x6B36 0x6B38 0x6B3B 0x6B3C \ + 0x6B3D 0x6B3F 0x6B40 0x6B41 0x6B42 0x6B44 0x6B45 0x6B48 \ + 0x6B4A 0x6B4B 0x6B4D 0x6B4E 0x6B4F 0x6B50 0x6B51 0x6B52 \ + 0x6B53 0x6B54 0x6B55 0x6B56 0x6B57 0x6B58 0x6B5A 0x6B5B \ + 0x6B5C 0x6B5D 0x6B5E 0x6B5F 0x6B60 0x6B61 0x6B68 0x6B69 \ + 0x6B6B 0x6B6C 0x6B6D 0x6B6E 0x6B6F 0x6B70 0x6B71 0x6B72 \ + 0x6B73 0x6B74 0x6B75 0x6B76 0x6B77 0x6B78 0x6B7A 0x6B7D \ + 0x6B7E 0x6B7F 0x6B80 0x6B85 0x6B88 0x6B8C 0x6B8E 0x6B8F \ + 0x6B90 0x6B91 0x6B94 0x6B95 0x6B97 0x6B98 0x6B99 0x6B9C \ + 0x6B9D 0x6B9E 0x6B9F 0x6BA0 0x6BA2 0x6BA3 0x6BA4 0x6BA5 \ + 0x6BA6 0x6BA7 0x6BA8 0x6BA9 0x6BAB 0x6BAC 0x6BAD 0x6BAE \ + 0x6BAF 0x6BB0 0x6BB1 0x6BB2 0x6BB6 0x6BB8 0x6BB9 0x6BBA \ + 0x6BBB 0x6BBC 0x6BBD 0x6BBE 0x6BC0 0x6BC3 0x6BC4 0x6BC6 \ + 0x6BC7 0x6BC8 0x6BC9 0x6BCA 0x6BCC 0x6BCE 0x6BD0 0x6BD1 +20 0x6BD8 0x6BDA 0x6BDC 0x6BDD 0x6BDE 0x6BDF 0x6BE0 0x6BE2 \ + 0x6BE3 0x6BE4 0x6BE5 0x6BE6 0x6BE7 0x6BE8 0x6BE9 0x6BEC \ + 0x6BED 0x6BEE 0x6BF0 0x6BF1 0x6BF2 0x6BF4 0x6BF6 0x6BF7 \ + 0x6BF8 0x6BFA 0x6BFB 0x6BFC 0x6BFE 0x6BFF 0x6C00 0x6C01 \ + 0x6C02 0x6C03 0x6C04 0x6C08 0x6C09 0x6C0A 0x6C0B 0x6C0C \ + 0x6C0E 0x6C12 0x6C17 0x6C1C 0x6C1D 0x6C1E 0x6C20 0x6C23 \ + 0x6C25 0x6C2B 0x6C2C 0x6C2D 0x6C31 0x6C33 0x6C36 0x6C37 \ + 0x6C39 0x6C3A 0x6C3B 0x6C3C 0x6C3E 0x6C3F 0x6C43 0x6C44 \ + 0x6C45 0x6C48 0x6C4B 0x6C4C 0x6C4D 0x6C4E 0x6C4F 0x6C51 \ + 0x6C52 0x6C53 0x6C56 0x6C58 0x6C59 0x6C5A 0x6C62 0x6C63 \ + 0x6C65 0x6C66 0x6C67 0x6C6B 0x6C6C 0x6C6D 0x6C6E 0x6C6F \ + 0x6C71 0x6C73 0x6C75 0x6C77 0x6C78 0x6C7A 0x6C7B 0x6C7C \ + 0x6C7F 0x6C80 0x6C84 0x6C87 0x6C8A 0x6C8B 0x6C8D 0x6C8E \ + 0x6C91 0x6C92 0x6C95 0x6C96 0x6C97 0x6C98 0x6C9A 0x6C9C \ + 0x6C9D 0x6C9E 0x6CA0 0x6CA2 0x6CA8 0x6CAC 0x6CAF 0x6CB0 \ + 0x6CB4 0x6CB5 0x6CB6 0x6CB7 0x6CBA 0x6CC0 0x6CC1 0x6CC2 \ + 0x6CC3 0x6CC6 0x6CC7 0x6CC8 0x6CCB 0x6CCD 0x6CCE 0x6CCF \ + 0x6CD1 0x6CD2 0x6CD8 0x6CD9 0x6CDA 0x6CDC 0x6CDD 0x6CDF \ + 0x6CE4 0x6CE6 0x6CE7 0x6CE9 0x6CEC 0x6CED 0x6CF2 0x6CF4 \ + 0x6CF9 0x6CFF 0x6D00 0x6D02 0x6D03 0x6D05 0x6D06 0x6D08 \ + 0x6D09 0x6D0A 0x6D0D 0x6D0F 0x6D10 0x6D11 0x6D13 0x6D14 \ + 0x6D15 0x6D16 0x6D18 0x6D1C 0x6D1D 0x6D1F 0x6D20 0x6D21 \ + 0x6D22 0x6D23 0x6D24 0x6D26 0x6D28 0x6D29 0x6D2C 0x6D2D \ + 0x6D2F 0x6D30 0x6D34 0x6D36 0x6D37 0x6D38 0x6D3A 0x6D3F \ + 0x6D40 0x6D42 0x6D44 0x6D49 0x6D4C 0x6D50 0x6D55 0x6D56 \ + 0x6D57 0x6D58 0x6D5B 0x6D5D 0x6D5F 0x6D61 0x6D62 0x6D64 \ + 0x6D65 0x6D67 0x6D68 0x6D6B 0x6D6C 0x6D6D 0x6D70 0x6D71 \ + 0x6D72 0x6D73 0x6D75 0x6D76 0x6D79 0x6D7A 0x6D7B 0x6D7D \ + 0x6D7E 0x6D7F 0x6D80 0x6D81 0x6D83 0x6D84 0x6D86 0x6D87 \ + 0x6D8A 0x6D8B 0x6D8D 0x6D8F 0x6D90 0x6D92 0x6D96 0x6D97 \ + 0x6D98 0x6D99 0x6D9A 0x6D9C 0x6DA2 0x6DA5 0x6DAC 0x6DAD \ + 0x6DB0 0x6DB1 0x6DB3 0x6DB4 0x6DB6 0x6DB7 0x6DB9 0x6DBA +21 0x6DBB 0x6DBC 0x6DBD 0x6DBE 0x6DC1 0x6DC2 0x6DC3 0x6DC8 \ + 0x6DC9 0x6DCA 0x6DCD 0x6DCE 0x6DCF 0x6DD0 0x6DD2 0x6DD3 \ + 0x6DD4 0x6DD5 0x6DD7 0x6DDA 0x6DDB 0x6DDC 0x6DDF 0x6DE2 \ + 0x6DE3 0x6DE5 0x6DE7 0x6DE8 0x6DE9 0x6DEA 0x6DED 0x6DEF \ + 0x6DF0 0x6DF2 0x6DF4 0x6DF5 0x6DF6 0x6DF8 0x6DFA 0x6DFD \ + 0x6DFE 0x6DFF 0x6E00 0x6E01 0x6E02 0x6E03 0x6E04 0x6E06 \ + 0x6E07 0x6E08 0x6E09 0x6E0B 0x6E0F 0x6E12 0x6E13 0x6E15 \ + 0x6E18 0x6E19 0x6E1B 0x6E1C 0x6E1E 0x6E1F 0x6E22 0x6E26 \ + 0x6E27 0x6E28 0x6E2A 0x6E2C 0x6E2E 0x6E30 0x6E31 0x6E33 \ + 0x6E35 0x6E36 0x6E37 0x6E39 0x6E3B 0x6E3C 0x6E3D 0x6E3E \ + 0x6E3F 0x6E40 0x6E41 0x6E42 0x6E45 0x6E46 0x6E47 0x6E48 \ + 0x6E49 0x6E4A 0x6E4B 0x6E4C 0x6E4F 0x6E50 0x6E51 0x6E52 \ + 0x6E55 0x6E57 0x6E59 0x6E5A 0x6E5C 0x6E5D 0x6E5E 0x6E60 \ + 0x6E61 0x6E62 0x6E63 0x6E64 0x6E65 0x6E66 0x6E67 0x6E68 \ + 0x6E69 0x6E6A 0x6E6C 0x6E6D 0x6E6F 0x6E70 0x6E71 0x6E72 \ + 0x6E73 0x6E74 0x6E75 0x6E76 0x6E77 0x6E78 0x6E79 0x6E7A \ + 0x6E7B 0x6E7C 0x6E7D 0x6E80 0x6E81 0x6E82 0x6E84 0x6E87 \ + 0x6E88 0x6E8A 0x6E8B 0x6E8C 0x6E8D 0x6E8E 0x6E91 0x6E92 \ + 0x6E93 0x6E94 0x6E95 0x6E96 0x6E97 0x6E99 0x6E9A 0x6E9B \ + 0x6E9D 0x6E9E 0x6EA0 0x6EA1 0x6EA3 0x6EA4 0x6EA6 0x6EA8 \ + 0x6EA9 0x6EAB 0x6EAC 0x6EAD 0x6EAE 0x6EB0 0x6EB3 0x6EB5 \ + 0x6EB8 0x6EB9 0x6EBC 0x6EBE 0x6EBF 0x6EC0 0x6EC3 0x6EC4 \ + 0x6EC5 0x6EC6 0x6EC8 0x6EC9 0x6ECA 0x6ECC 0x6ECD 0x6ECE \ + 0x6ED0 0x6ED2 0x6ED6 0x6ED8 0x6ED9 0x6EDB 0x6EDC 0x6EDD \ + 0x6EE3 0x6EE7 0x6EEA 0x6EEB 0x6EEC 0x6EED 0x6EEE 0x6EEF \ + 0x6EF0 0x6EF1 0x6EF2 0x6EF3 0x6EF5 0x6EF6 0x6EF7 0x6EF8 \ + 0x6EFA 0x6EFB 0x6EFC 0x6EFD 0x6EFE 0x6EFF 0x6F00 0x6F01 \ + 0x6F03 0x6F04 0x6F05 0x6F07 0x6F08 0x6F0A 0x6F0B 0x6F0C \ + 0x6F0D 0x6F0E 0x6F10 0x6F11 0x6F12 0x6F16 0x6F17 0x6F18 \ + 0x6F19 0x6F1A 0x6F1B 0x6F1C 0x6F1D 0x6F1E 0x6F1F 0x6F21 \ + 0x6F22 0x6F23 0x6F25 0x6F26 0x6F27 0x6F28 0x6F2C 0x6F2E \ + 0x6F30 0x6F32 0x6F34 0x6F35 0x6F37 0x6F38 0x6F39 0x6F3A +22 0x6F3B 0x6F3C 0x6F3D 0x6F3F 0x6F40 0x6F41 0x6F42 0x6F43 \ + 0x6F44 0x6F45 0x6F48 0x6F49 0x6F4A 0x6F4C 0x6F4E 0x6F4F \ + 0x6F50 0x6F51 0x6F52 0x6F53 0x6F54 0x6F55 0x6F56 0x6F57 \ + 0x6F59 0x6F5A 0x6F5B 0x6F5D 0x6F5F 0x6F60 0x6F61 0x6F63 \ + 0x6F64 0x6F65 0x6F67 0x6F68 0x6F69 0x6F6A 0x6F6B 0x6F6C \ + 0x6F6F 0x6F70 0x6F71 0x6F73 0x6F75 0x6F76 0x6F77 0x6F79 \ + 0x6F7B 0x6F7D 0x6F7E 0x6F7F 0x6F80 0x6F81 0x6F82 0x6F83 \ + 0x6F85 0x6F86 0x6F87 0x6F8A 0x6F8B 0x6F8F 0x6F90 0x6F91 \ + 0x6F92 0x6F93 0x6F94 0x6F95 0x6F96 0x6F97 0x6F98 0x6F99 \ + 0x6F9A 0x6F9B 0x6F9D 0x6F9E 0x6F9F 0x6FA0 0x6FA2 0x6FA3 \ + 0x6FA4 0x6FA5 0x6FA6 0x6FA8 0x6FA9 0x6FAA 0x6FAB 0x6FAC \ + 0x6FAD 0x6FAE 0x6FAF 0x6FB0 0x6FB1 0x6FB2 0x6FB4 0x6FB5 \ + 0x6FB7 0x6FB8 0x6FBA 0x6FBB 0x6FBC 0x6FBD 0x6FBE 0x6FBF \ + 0x6FC1 0x6FC3 0x6FC4 0x6FC5 0x6FC6 0x6FC7 0x6FC8 0x6FCA \ + 0x6FCB 0x6FCC 0x6FCD 0x6FCE 0x6FCF 0x6FD0 0x6FD3 0x6FD4 \ + 0x6FD5 0x6FD6 0x6FD7 0x6FD8 0x6FD9 0x6FDA 0x6FDB 0x6FDC \ + 0x6FDD 0x6FDF 0x6FE2 0x6FE3 0x6FE4 0x6FE5 0x6FE6 0x6FE7 \ + 0x6FE8 0x6FE9 0x6FEA 0x6FEB 0x6FEC 0x6FED 0x6FF0 0x6FF1 \ + 0x6FF2 0x6FF3 0x6FF4 0x6FF5 0x6FF6 0x6FF7 0x6FF8 0x6FF9 \ + 0x6FFA 0x6FFB 0x6FFC 0x6FFD 0x6FFE 0x6FFF 0x7000 0x7001 \ + 0x7002 0x7003 0x7004 0x7005 0x7006 0x7007 0x7008 0x7009 \ + 0x700A 0x700B 0x700C 0x700D 0x700E 0x700F 0x7010 0x7012 \ + 0x7013 0x7014 0x7015 0x7016 0x7017 0x7018 0x7019 0x701C \ + 0x701D 0x701E 0x701F 0x7020 0x7021 0x7022 0x7024 0x7025 \ + 0x7026 0x7027 0x7028 0x7029 0x702A 0x702B 0x702C 0x702D \ + 0x702E 0x702F 0x7030 0x7031 0x7032 0x7033 0x7034 0x7036 \ + 0x7037 0x7038 0x703A 0x703B 0x703C 0x703D 0x703E 0x703F \ + 0x7040 0x7041 0x7042 0x7043 0x7044 0x7045 0x7046 0x7047 \ + 0x7048 0x7049 0x704A 0x704B 0x704D 0x704E 0x7050 0x7051 \ + 0x7052 0x7053 0x7054 0x7055 0x7056 0x7057 0x7058 0x7059 \ + 0x705A 0x705B 0x705C 0x705D 0x705F 0x7060 0x7061 0x7062 \ + 0x7063 0x7064 0x7065 0x7066 0x7067 0x7068 0x7069 0x706A +23 0x706E 0x7071 0x7072 0x7073 0x7074 0x7077 0x7079 0x707A \ + 0x707B 0x707D 0x7081 0x7082 0x7083 0x7084 0x7086 0x7087 \ + 0x7088 0x708B 0x708C 0x708D 0x708F 0x7090 0x7091 0x7093 \ + 0x7097 0x7098 0x709A 0x709B 0x709E 0x709F 0x70A0 0x70A1 \ + 0x70A2 0x70A3 0x70A4 0x70A5 0x70A6 0x70A7 0x70A8 0x70A9 \ + 0x70AA 0x70B0 0x70B2 0x70B4 0x70B5 0x70B6 0x70BA 0x70BE \ + 0x70BF 0x70C4 0x70C5 0x70C6 0x70C7 0x70C9 0x70CB 0x70CC \ + 0x70CD 0x70CE 0x70CF 0x70D0 0x70D1 0x70D2 0x70D3 0x70D4 \ + 0x70D5 0x70D6 0x70D7 0x70DA 0x70DC 0x70DD 0x70DE 0x70E0 \ + 0x70E1 0x70E2 0x70E3 0x70E5 0x70EA 0x70EE 0x70F0 0x70F1 \ + 0x70F2 0x70F3 0x70F4 0x70F5 0x70F6 0x70F8 0x70FA 0x70FB \ + 0x70FC 0x70FE 0x70FF 0x7100 0x7101 0x7102 0x7103 0x7104 \ + 0x7105 0x7106 0x7107 0x7108 0x710B 0x710C 0x710D 0x710E \ + 0x710F 0x7111 0x7112 0x7114 0x7117 0x711B 0x711C 0x711D \ + 0x711E 0x711F 0x7120 0x7121 0x7122 0x7123 0x7124 0x7125 \ + 0x7127 0x7128 0x7129 0x712A 0x712B 0x712C 0x712D 0x712E \ + 0x7132 0x7133 0x7134 0x7135 0x7137 0x7138 0x7139 0x713A \ + 0x713B 0x713C 0x713D 0x713E 0x713F 0x7140 0x7141 0x7142 \ + 0x7143 0x7144 0x7146 0x7147 0x7148 0x7149 0x714B 0x714D \ + 0x714F 0x7150 0x7151 0x7152 0x7153 0x7154 0x7155 0x7156 \ + 0x7157 0x7158 0x7159 0x715A 0x715B 0x715D 0x715F 0x7160 \ + 0x7161 0x7162 0x7163 0x7165 0x7169 0x716A 0x716B 0x716C \ + 0x716D 0x716F 0x7170 0x7171 0x7174 0x7175 0x7176 0x7177 \ + 0x7179 0x717B 0x717C 0x717E 0x717F 0x7180 0x7181 0x7182 \ + 0x7183 0x7185 0x7186 0x7187 0x7188 0x7189 0x718B 0x718C \ + 0x718D 0x718E 0x7190 0x7191 0x7192 0x7193 0x7195 0x7196 \ + 0x7197 0x719A 0x719B 0x719C 0x719D 0x719E 0x71A1 0x71A2 \ + 0x71A3 0x71A4 0x71A5 0x71A6 0x71A7 0x71A9 0x71AA 0x71AB \ + 0x71AD 0x71AE 0x71AF 0x71B0 0x71B1 0x71B2 0x71B4 0x71B6 \ + 0x71B7 0x71B8 0x71BA 0x71BB 0x71BC 0x71BD 0x71BE 0x71BF \ + 0x71C0 0x71C1 0x71C2 0x71C4 0x71C5 0x71C6 0x71C7 0x71C8 \ + 0x71C9 0x71CA 0x71CB 0x71CC 0x71CD 0x71CF 0x71D0 0x71D1 +24 0x71D2 0x71D3 0x71D6 0x71D7 0x71D8 0x71D9 0x71DA 0x71DB \ + 0x71DC 0x71DD 0x71DE 0x71DF 0x71E1 0x71E2 0x71E3 0x71E4 \ + 0x71E6 0x71E8 0x71E9 0x71EA 0x71EB 0x71EC 0x71ED 0x71EF \ + 0x71F0 0x71F1 0x71F2 0x71F3 0x71F4 0x71F5 0x71F6 0x71F7 \ + 0x71F8 0x71FA 0x71FB 0x71FC 0x71FD 0x71FE 0x71FF 0x7200 \ + 0x7201 0x7202 0x7203 0x7204 0x7205 0x7207 0x7208 0x7209 \ + 0x720A 0x720B 0x720C 0x720D 0x720E 0x720F 0x7210 0x7211 \ + 0x7212 0x7213 0x7214 0x7215 0x7216 0x7217 0x7218 0x7219 \ + 0x721A 0x721B 0x721C 0x721E 0x721F 0x7220 0x7221 0x7222 \ + 0x7223 0x7224 0x7225 0x7226 0x7227 0x7229 0x722B 0x722D \ + 0x722E 0x722F 0x7232 0x7233 0x7234 0x723A 0x723C 0x723E \ + 0x7240 0x7241 0x7242 0x7243 0x7244 0x7245 0x7246 0x7249 \ + 0x724A 0x724B 0x724E 0x724F 0x7250 0x7251 0x7253 0x7254 \ + 0x7255 0x7257 0x7258 0x725A 0x725C 0x725E 0x7260 0x7263 \ + 0x7264 0x7265 0x7268 0x726A 0x726B 0x726C 0x726D 0x7270 \ + 0x7271 0x7273 0x7274 0x7276 0x7277 0x7278 0x727B 0x727C \ + 0x727D 0x7282 0x7283 0x7285 0x7286 0x7287 0x7288 0x7289 \ + 0x728C 0x728E 0x7290 0x7291 0x7293 0x7294 0x7295 0x7296 \ + 0x7297 0x7298 0x7299 0x729A 0x729B 0x729C 0x729D 0x729E \ + 0x72A0 0x72A1 0x72A2 0x72A3 0x72A4 0x72A5 0x72A6 0x72A7 \ + 0x72A8 0x72A9 0x72AA 0x72AB 0x72AE 0x72B1 0x72B2 0x72B3 \ + 0x72B5 0x72BA 0x72BB 0x72BC 0x72BD 0x72BE 0x72BF 0x72C0 \ + 0x72C5 0x72C6 0x72C7 0x72C9 0x72CA 0x72CB 0x72CC 0x72CF \ + 0x72D1 0x72D3 0x72D4 0x72D5 0x72D6 0x72D8 0x72DA 0x72DB \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +25 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0x3000 0x3001 0x3002 0x00B7 0x02C9 0x02C7 0x00A8 0x3003 \ + 0x3005 0x2015 0xFF5E 0x2016 0x2026 0x2018 0x2019 0x201C \ + 0x201D 0x3014 0x3015 0x3008 0x3009 0x300A 0x300B 0x300C \ + 0x300D 0x300E 0x300F 0x3016 0x3017 0x3010 0x3011 0x00B1 \ + 0x00D7 0x00F7 0x2236 0x2227 0x2228 0x2211 0x220F 0x222A \ + 0x2229 0x2208 0x2237 0x221A 0x22A5 0x2225 0x2220 0x2312 \ + 0x2299 0x222B 0x222E 0x2261 0x224C 0x2248 0x223D 0x221D \ + 0x2260 0x226E 0x226F 0x2264 0x2265 0x221E 0x2235 0x2234 \ + 0x2642 0x2640 0x00B0 0x2032 0x2033 0x2103 0xFF04 0x00A4 \ + 0xFFE0 0xFFE1 0x2030 0x00A7 0x2116 0x2606 0x2605 0x25CB \ + 0x25CF 0x25CE 0x25C7 0x25C6 0x25A1 0x25A0 0x25B3 0x25B2 \ + 0x203B 0x2192 0x2190 0x2191 0x2193 0x3013 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x2170 0x2171 \ + 0x2172 0x2173 0x2174 0x2175 0x2176 0x2177 0x2178 0x2179 \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x2488 0x2489 \ + 0x248A 0x248B 0x248C 0x248D 0x248E 0x248F 0x2490 0x2491 \ + 0x2492 0x2493 0x2494 0x2495 0x2496 0x2497 0x2498 0x2499 +26 0x249A 0x249B 0x2474 0x2475 0x2476 0x2477 0x2478 0x2479 \ + 0x247A 0x247B 0x247C 0x247D 0x247E 0x247F 0x2480 0x2481 \ + 0x2482 0x2483 0x2484 0x2485 0x2486 0x2487 0x2460 0x2461 \ + 0x2462 0x2463 0x2464 0x2465 0x2466 0x2467 0x2468 0x2469 \ + 0xFFFE 0xFFFE 0x3220 0x3221 0x3222 0x3223 0x3224 0x3225 \ + 0x3226 0x3227 0x3228 0x3229 0xFFFE 0xFFFE 0x2160 0x2161 \ + 0x2162 0x2163 0x2164 0x2165 0x2166 0x2167 0x2168 0x2169 \ + 0x216A 0x216B 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFF01 0xFF02 0xFF03 0xFFE5 \ + 0xFF05 0xFF06 0xFF07 0xFF08 0xFF09 0xFF0A 0xFF0B 0xFF0C \ + 0xFF0D 0xFF0E 0xFF0F 0xFF10 0xFF11 0xFF12 0xFF13 0xFF14 \ + 0xFF15 0xFF16 0xFF17 0xFF18 0xFF19 0xFF1A 0xFF1B 0xFF1C \ + 0xFF1D 0xFF1E 0xFF1F 0xFF20 0xFF21 0xFF22 0xFF23 0xFF24 \ + 0xFF25 0xFF26 0xFF27 0xFF28 0xFF29 0xFF2A 0xFF2B 0xFF2C \ + 0xFF2D 0xFF2E 0xFF2F 0xFF30 0xFF31 0xFF32 0xFF33 0xFF34 \ + 0xFF35 0xFF36 0xFF37 0xFF38 0xFF39 0xFF3A 0xFF3B 0xFF3C \ + 0xFF3D 0xFF3E 0xFF3F 0xFF40 0xFF41 0xFF42 0xFF43 0xFF44 \ + 0xFF45 0xFF46 0xFF47 0xFF48 0xFF49 0xFF4A 0xFF4B 0xFF4C \ + 0xFF4D 0xFF4E 0xFF4F 0xFF50 0xFF51 0xFF52 0xFF53 0xFF54 \ + 0xFF55 0xFF56 0xFF57 0xFF58 0xFF59 0xFF5A 0xFF5B 0xFF5C \ + 0xFF5D 0xFFE3 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +27 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x3041 0x3042 0x3043 0x3044 0x3045 0x3046 \ + 0x3047 0x3048 0x3049 0x304A 0x304B 0x304C 0x304D 0x304E \ + 0x304F 0x3050 0x3051 0x3052 0x3053 0x3054 0x3055 0x3056 \ + 0x3057 0x3058 0x3059 0x305A 0x305B 0x305C 0x305D 0x305E \ + 0x305F 0x3060 0x3061 0x3062 0x3063 0x3064 0x3065 0x3066 \ + 0x3067 0x3068 0x3069 0x306A 0x306B 0x306C 0x306D 0x306E \ + 0x306F 0x3070 0x3071 0x3072 0x3073 0x3074 0x3075 0x3076 \ + 0x3077 0x3078 0x3079 0x307A 0x307B 0x307C 0x307D 0x307E \ + 0x307F 0x3080 0x3081 0x3082 0x3083 0x3084 0x3085 0x3086 \ + 0x3087 0x3088 0x3089 0x308A 0x308B 0x308C 0x308D 0x308E \ + 0x308F 0x3090 0x3091 0x3092 0x3093 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +28 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0x30A1 0x30A2 0x30A3 0x30A4 0x30A5 0x30A6 0x30A7 0x30A8 \ + 0x30A9 0x30AA 0x30AB 0x30AC 0x30AD 0x30AE 0x30AF 0x30B0 \ + 0x30B1 0x30B2 0x30B3 0x30B4 0x30B5 0x30B6 0x30B7 0x30B8 \ + 0x30B9 0x30BA 0x30BB 0x30BC 0x30BD 0x30BE 0x30BF 0x30C0 \ + 0x30C1 0x30C2 0x30C3 0x30C4 0x30C5 0x30C6 0x30C7 0x30C8 \ + 0x30C9 0x30CA 0x30CB 0x30CC 0x30CD 0x30CE 0x30CF 0x30D0 \ + 0x30D1 0x30D2 0x30D3 0x30D4 0x30D5 0x30D6 0x30D7 0x30D8 \ + 0x30D9 0x30DA 0x30DB 0x30DC 0x30DD 0x30DE 0x30DF 0x30E0 \ + 0x30E1 0x30E2 0x30E3 0x30E4 0x30E5 0x30E6 0x30E7 0x30E8 \ + 0x30E9 0x30EA 0x30EB 0x30EC 0x30ED 0x30EE 0x30EF 0x30F0 \ + 0x30F1 0x30F2 0x30F3 0x30F4 0x30F5 0x30F6 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x0391 0x0392 \ + 0x0393 0x0394 0x0395 0x0396 0x0397 0x0398 0x0399 0x039A \ + 0x039B 0x039C 0x039D 0x039E 0x039F 0x03A0 0x03A1 0x03A3 \ + 0x03A4 0x03A5 0x03A6 0x03A7 0x03A8 0x03A9 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x03B1 0x03B2 \ + 0x03B3 0x03B4 0x03B5 0x03B6 0x03B7 0x03B8 0x03B9 0x03BA +29 0x03BB 0x03BC 0x03BD 0x03BE 0x03BF 0x03C0 0x03C1 0x03C3 \ + 0x03C4 0x03C5 0x03C6 0x03C7 0x03C8 0x03C9 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFE35 0xFE36 0xFE39 \ + 0xFE3A 0xFE3F 0xFE40 0xFE3D 0xFE3E 0xFE41 0xFE42 0xFE43 \ + 0xFE44 0xFFFE 0xFFFE 0xFE3B 0xFE3C 0xFE37 0xFE38 0xFE31 \ + 0xFFFE 0xFE33 0xFE34 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x0410 0x0411 0x0412 0x0413 \ + 0x0414 0x0415 0x0401 0x0416 0x0417 0x0418 0x0419 0x041A \ + 0x041B 0x041C 0x041D 0x041E 0x041F 0x0420 0x0421 0x0422 \ + 0x0423 0x0424 0x0425 0x0426 0x0427 0x0428 0x0429 0x042A \ + 0x042B 0x042C 0x042D 0x042E 0x042F 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x0430 0x0431 0x0432 0x0433 \ + 0x0434 0x0435 0x0451 0x0436 0x0437 0x0438 0x0439 0x043A \ + 0x043B 0x043C 0x043D 0x043E 0x043F 0x0440 0x0441 0x0442 \ + 0x0443 0x0444 0x0445 0x0446 0x0447 0x0448 0x0449 0x044A \ + 0x044B 0x044C 0x044D 0x044E 0x044F 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x02CA 0x02CB 0x02D9 0x2013 0x2014 0x2025 \ + 0x2035 0x2105 0x2109 0x2196 0x2197 0x2198 0x2199 0x2215 +30 0x221F 0x2223 0x2252 0x2266 0x2267 0x22BF 0x2550 0x2551 \ + 0x2552 0x2553 0x2554 0x2555 0x2556 0x2557 0x2558 0x2559 \ + 0x255A 0x255B 0x255C 0x255D 0x255E 0x255F 0x2560 0x2561 \ + 0x2562 0x2563 0x2564 0x2565 0x2566 0x2567 0x2568 0x2569 \ + 0x256A 0x256B 0x256C 0x256D 0x256E 0x256F 0x2570 0x2571 \ + 0x2572 0x2573 0x2581 0x2582 0x2583 0x2584 0x2585 0x2586 \ + 0x2587 0x2588 0x2589 0x258A 0x258B 0x258C 0x258D 0x258E \ + 0x258F 0x2593 0x2594 0x2595 0x25BC 0x25BD 0x25E2 0x25E3 \ + 0x25E4 0x25E5 0x2609 0x2295 0x3012 0x301D 0x301E 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x0101 0x00E1 0x01CE 0x00E0 0x0113 0x00E9 \ + 0x011B 0x00E8 0x012B 0x00ED 0x01D0 0x00EC 0x014D 0x00F3 \ + 0x01D2 0x00F2 0x016B 0x00FA 0x01D4 0x00F9 0x01D6 0x01D8 \ + 0x01DA 0x01DC 0x00FC 0x00EA 0x0251 0xE7C7 0x0144 0x0148 \ + 0xE7C8 0x0261 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x3105 0x3106 \ + 0x3107 0x3108 0x3109 0x310A 0x310B 0x310C 0x310D 0x310E \ + 0x310F 0x3110 0x3111 0x3112 0x3113 0x3114 0x3115 0x3116 \ + 0x3117 0x3118 0x3119 0x311A 0x311B 0x311C 0x311D 0x311E \ + 0x311F 0x3120 0x3121 0x3122 0x3123 0x3124 0x3125 0x3126 \ + 0x3127 0x3128 0x3129 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0x3021 0x3022 0x3023 0x3024 0x3025 0x3026 0x3027 0x3028 \ + 0x3029 0x32A3 0x338E 0x338F 0x339C 0x339D 0x339E 0x33A1 \ + 0x33C4 0x33CE 0x33D1 0x33D2 0x33D5 0xFE30 0xFFE2 0xFFE4 \ + 0xFFFE 0x2121 0x3231 0xFFFE 0x2010 0xFFFE 0xFFFE 0xFFFE \ + 0x30FC 0x309B 0x309C 0x30FD 0x30FE 0x3006 0x309D 0x309E \ + 0xFE49 0xFE4A 0xFE4B 0xFE4C 0xFE4D 0xFE4E 0xFE4F 0xFE50 \ + 0xFE51 0xFE52 0xFE54 0xFE55 0xFE56 0xFE57 0xFE59 0xFE5A \ + 0xFE5B 0xFE5C 0xFE5D 0xFE5E 0xFE5F 0xFE60 0xFE61 0xFE62 \ + 0xFE63 0xFE64 0xFE65 0xFE66 0xFE68 0xFE69 0xFE6A 0xFE6B \ + 0xE7E7 0xE7E8 0xE7E9 0xE7EA 0xE7EB 0xE7EC 0xE7ED 0xE7EE +31 0xE7EF 0xE7F0 0xE7F1 0xE7F2 0xE7F3 0x3007 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0x2500 0x2501 0x2502 0x2503 0x2504 \ + 0x2505 0x2506 0x2507 0x2508 0x2509 0x250A 0x250B 0x250C \ + 0x250D 0x250E 0x250F 0x2510 0x2511 0x2512 0x2513 0x2514 \ + 0x2515 0x2516 0x2517 0x2518 0x2519 0x251A 0x251B 0x251C \ + 0x251D 0x251E 0x251F 0x2520 0x2521 0x2522 0x2523 0x2524 \ + 0x2525 0x2526 0x2527 0x2528 0x2529 0x252A 0x252B 0x252C \ + 0x252D 0x252E 0x252F 0x2530 0x2531 0x2532 0x2533 0x2534 \ + 0x2535 0x2536 0x2537 0x2538 0x2539 0x253A 0x253B 0x253C \ + 0x253D 0x253E 0x253F 0x2540 0x2541 0x2542 0x2543 0x2544 \ + 0x2545 0x2546 0x2547 0x2548 0x2549 0x254A 0x254B 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x72DC 0x72DD \ + 0x72DF 0x72E2 0x72E3 0x72E4 0x72E5 0x72E6 0x72E7 0x72EA \ + 0x72EB 0x72F5 0x72F6 0x72F9 0x72FD 0x72FE 0x72FF 0x7300 \ + 0x7302 0x7304 0x7305 0x7306 0x7307 0x7308 0x7309 0x730B \ + 0x730C 0x730D 0x730F 0x7310 0x7311 0x7312 0x7314 0x7318 \ + 0x7319 0x731A 0x731F 0x7320 0x7323 0x7324 0x7326 0x7327 \ + 0x7328 0x732D 0x732F 0x7330 0x7332 0x7333 0x7335 0x7336 \ + 0x733A 0x733B 0x733C 0x733D 0x7340 0x7341 0x7342 0x7343 \ + 0x7344 0x7345 0x7346 0x7347 0x7348 0x7349 0x734A 0x734B \ + 0x734C 0x734E 0x734F 0x7351 0x7353 0x7354 0x7355 0x7356 \ + 0x7358 0x7359 0x735A 0x735B 0x735C 0x735D 0x735E 0x735F \ + 0x7361 0x7362 0x7363 0x7364 0x7365 0x7366 0x7367 0x7368 \ + 0x7369 0x736A 0x736B 0x736E 0x7370 0x7371 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +32 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x7372 0x7373 0x7374 0x7375 \ + 0x7376 0x7377 0x7378 0x7379 0x737A 0x737B 0x737C 0x737D \ + 0x737F 0x7380 0x7381 0x7382 0x7383 0x7385 0x7386 0x7388 \ + 0x738A 0x738C 0x738D 0x738F 0x7390 0x7392 0x7393 0x7394 \ + 0x7395 0x7397 0x7398 0x7399 0x739A 0x739C 0x739D 0x739E \ + 0x73A0 0x73A1 0x73A3 0x73A4 0x73A5 0x73A6 0x73A7 0x73A8 \ + 0x73AA 0x73AC 0x73AD 0x73B1 0x73B4 0x73B5 0x73B6 0x73B8 \ + 0x73B9 0x73BC 0x73BD 0x73BE 0x73BF 0x73C1 0x73C3 0x73C4 \ + 0x73C5 0x73C6 0x73C7 0x73CB 0x73CC 0x73CE 0x73D2 0x73D3 \ + 0x73D4 0x73D5 0x73D6 0x73D7 0x73D8 0x73DA 0x73DB 0x73DC \ + 0x73DD 0x73DF 0x73E1 0x73E2 0x73E3 0x73E4 0x73E6 0x73E8 \ + 0x73EA 0x73EB 0x73EC 0x73EE 0x73EF 0x73F0 0x73F1 0x73F3 \ + 0x73F4 0x73F5 0x73F6 0x73F7 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x73F8 0x73F9 0x73FA 0x73FB 0x73FC 0x73FD \ + 0x73FE 0x73FF 0x7400 0x7401 0x7402 0x7404 0x7407 0x7408 \ + 0x740B 0x740C 0x740D 0x740E 0x7411 0x7412 0x7413 0x7414 +33 0x7415 0x7416 0x7417 0x7418 0x7419 0x741C 0x741D 0x741E \ + 0x741F 0x7420 0x7421 0x7423 0x7424 0x7427 0x7429 0x742B \ + 0x742D 0x742F 0x7431 0x7432 0x7437 0x7438 0x7439 0x743A \ + 0x743B 0x743D 0x743E 0x743F 0x7440 0x7442 0x7443 0x7444 \ + 0x7445 0x7446 0x7447 0x7448 0x7449 0x744A 0x744B 0x744C \ + 0x744D 0x744E 0x744F 0x7450 0x7451 0x7452 0x7453 0x7454 \ + 0x7456 0x7458 0x745D 0x7460 0x7461 0x7462 0x7463 0x7464 \ + 0x7465 0x7466 0x7467 0x7468 0x7469 0x746A 0x746B 0x746C \ + 0x746E 0x746F 0x7471 0x7472 0x7473 0x7474 0x7475 0x7478 \ + 0x7479 0x747A 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0x747B 0x747C 0x747D 0x747F 0x7482 0x7484 0x7485 0x7486 \ + 0x7488 0x7489 0x748A 0x748C 0x748D 0x748F 0x7491 0x7492 \ + 0x7493 0x7494 0x7495 0x7496 0x7497 0x7498 0x7499 0x749A \ + 0x749B 0x749D 0x749F 0x74A0 0x74A1 0x74A2 0x74A3 0x74A4 \ + 0x74A5 0x74A6 0x74AA 0x74AB 0x74AC 0x74AD 0x74AE 0x74AF \ + 0x74B0 0x74B1 0x74B2 0x74B3 0x74B4 0x74B5 0x74B6 0x74B7 \ + 0x74B8 0x74B9 0x74BB 0x74BC 0x74BD 0x74BE 0x74BF 0x74C0 \ + 0x74C1 0x74C2 0x74C3 0x74C4 0x74C5 0x74C6 0x74C7 0x74C8 \ + 0x74C9 0x74CA 0x74CB 0x74CC 0x74CD 0x74CE 0x74CF 0x74D0 \ + 0x74D1 0x74D3 0x74D4 0x74D5 0x74D6 0x74D7 0x74D8 0x74D9 \ + 0x74DA 0x74DB 0x74DD 0x74DF 0x74E1 0x74E5 0x74E7 0x74E8 +34 0x74E9 0x74EA 0x74EB 0x74EC 0x74ED 0x74F0 0x74F1 0x74F2 \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x74F3 0x74F5 \ + 0x74F8 0x74F9 0x74FA 0x74FB 0x74FC 0x74FD 0x74FE 0x7500 \ + 0x7501 0x7502 0x7503 0x7505 0x7506 0x7507 0x7508 0x7509 \ + 0x750A 0x750B 0x750C 0x750E 0x7510 0x7512 0x7514 0x7515 \ + 0x7516 0x7517 0x751B 0x751D 0x751E 0x7520 0x7521 0x7522 \ + 0x7523 0x7524 0x7526 0x7527 0x752A 0x752E 0x7534 0x7536 \ + 0x7539 0x753C 0x753D 0x753F 0x7541 0x7542 0x7543 0x7544 \ + 0x7546 0x7547 0x7549 0x754A 0x754D 0x7550 0x7551 0x7552 \ + 0x7553 0x7555 0x7556 0x7557 0x7558 0x755D 0x755E 0x755F \ + 0x7560 0x7561 0x7562 0x7563 0x7564 0x7567 0x7568 0x7569 \ + 0x756B 0x756C 0x756D 0x756E 0x756F 0x7570 0x7571 0x7573 \ + 0x7575 0x7576 0x7577 0x757A 0x757B 0x757C 0x757D 0x757E \ + 0x7580 0x7581 0x7582 0x7584 0x7585 0x7587 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +35 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x7588 0x7589 0x758A 0x758C \ + 0x758D 0x758E 0x7590 0x7593 0x7595 0x7598 0x759B 0x759C \ + 0x759E 0x75A2 0x75A6 0x75A7 0x75A8 0x75A9 0x75AA 0x75AD \ + 0x75B6 0x75B7 0x75BA 0x75BB 0x75BF 0x75C0 0x75C1 0x75C6 \ + 0x75CB 0x75CC 0x75CE 0x75CF 0x75D0 0x75D1 0x75D3 0x75D7 \ + 0x75D9 0x75DA 0x75DC 0x75DD 0x75DF 0x75E0 0x75E1 0x75E5 \ + 0x75E9 0x75EC 0x75ED 0x75EE 0x75EF 0x75F2 0x75F3 0x75F5 \ + 0x75F6 0x75F7 0x75F8 0x75FA 0x75FB 0x75FD 0x75FE 0x7602 \ + 0x7604 0x7606 0x7607 0x7608 0x7609 0x760B 0x760D 0x760E \ + 0x760F 0x7611 0x7612 0x7613 0x7614 0x7616 0x761A 0x761C \ + 0x761D 0x761E 0x7621 0x7623 0x7627 0x7628 0x762C 0x762E \ + 0x762F 0x7631 0x7632 0x7636 0x7637 0x7639 0x763A 0x763B \ + 0x763D 0x7641 0x7642 0x7644 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x7645 0x7646 0x7647 0x7648 0x7649 0x764A \ + 0x764B 0x764E 0x764F 0x7650 0x7651 0x7652 0x7653 0x7655 \ + 0x7657 0x7658 0x7659 0x765A 0x765B 0x765D 0x765F 0x7660 \ + 0x7661 0x7662 0x7664 0x7665 0x7666 0x7667 0x7668 0x7669 +36 0x766A 0x766C 0x766D 0x766E 0x7670 0x7671 0x7672 0x7673 \ + 0x7674 0x7675 0x7676 0x7677 0x7679 0x767A 0x767C 0x767F \ + 0x7680 0x7681 0x7683 0x7685 0x7689 0x768A 0x768C 0x768D \ + 0x768F 0x7690 0x7692 0x7694 0x7695 0x7697 0x7698 0x769A \ + 0x769B 0x769C 0x769D 0x769E 0x769F 0x76A0 0x76A1 0x76A2 \ + 0x76A3 0x76A5 0x76A6 0x76A7 0x76A8 0x76A9 0x76AA 0x76AB \ + 0x76AC 0x76AD 0x76AF 0x76B0 0x76B3 0x76B5 0x76B6 0x76B7 \ + 0x76B8 0x76B9 0x76BA 0x76BB 0x76BC 0x76BD 0x76BE 0x76C0 \ + 0x76C1 0x76C3 0x554A 0x963F 0x57C3 0x6328 0x54CE 0x5509 \ + 0x54C0 0x7691 0x764C 0x853C 0x77EE 0x827E 0x788D 0x7231 \ + 0x9698 0x978D 0x6C28 0x5B89 0x4FFA 0x6309 0x6697 0x5CB8 \ + 0x80FA 0x6848 0x80AE 0x6602 0x76CE 0x51F9 0x6556 0x71AC \ + 0x7FF1 0x8884 0x50B2 0x5965 0x61CA 0x6FB3 0x82AD 0x634C \ + 0x6252 0x53ED 0x5427 0x7B06 0x516B 0x75A4 0x5DF4 0x62D4 \ + 0x8DCB 0x9776 0x628A 0x8019 0x575D 0x9738 0x7F62 0x7238 \ + 0x767D 0x67CF 0x767E 0x6446 0x4F70 0x8D25 0x62DC 0x7A17 \ + 0x6591 0x73ED 0x642C 0x6273 0x822C 0x9881 0x677F 0x7248 \ + 0x626E 0x62CC 0x4F34 0x74E3 0x534A 0x529E 0x7ECA 0x90A6 \ + 0x5E2E 0x6886 0x699C 0x8180 0x7ED1 0x68D2 0x78C5 0x868C \ + 0x9551 0x508D 0x8C24 0x82DE 0x80DE 0x5305 0x8912 0x5265 \ + 0x76C4 0x76C7 0x76C9 0x76CB 0x76CC 0x76D3 0x76D5 0x76D9 \ + 0x76DA 0x76DC 0x76DD 0x76DE 0x76E0 0x76E1 0x76E2 0x76E3 \ + 0x76E4 0x76E6 0x76E7 0x76E8 0x76E9 0x76EA 0x76EB 0x76EC \ + 0x76ED 0x76F0 0x76F3 0x76F5 0x76F6 0x76F7 0x76FA 0x76FB \ + 0x76FD 0x76FF 0x7700 0x7702 0x7703 0x7705 0x7706 0x770A \ + 0x770C 0x770E 0x770F 0x7710 0x7711 0x7712 0x7713 0x7714 \ + 0x7715 0x7716 0x7717 0x7718 0x771B 0x771C 0x771D 0x771E \ + 0x7721 0x7723 0x7724 0x7725 0x7727 0x772A 0x772B 0x772C \ + 0x772E 0x7730 0x7731 0x7732 0x7733 0x7734 0x7739 0x773B \ + 0x773D 0x773E 0x773F 0x7742 0x7744 0x7745 0x7746 0x7748 \ + 0x7749 0x774A 0x774B 0x774C 0x774D 0x774E 0x774F 0x7752 \ + 0x7753 0x7754 0x7755 0x7756 0x7757 0x7758 0x7759 0x775C +37 0x8584 0x96F9 0x4FDD 0x5821 0x9971 0x5B9D 0x62B1 0x62A5 \ + 0x66B4 0x8C79 0x9C8D 0x7206 0x676F 0x7891 0x60B2 0x5351 \ + 0x5317 0x8F88 0x80CC 0x8D1D 0x94A1 0x500D 0x72C8 0x5907 \ + 0x60EB 0x7119 0x88AB 0x5954 0x82EF 0x672C 0x7B28 0x5D29 \ + 0x7EF7 0x752D 0x6CF5 0x8E66 0x8FF8 0x903C 0x9F3B 0x6BD4 \ + 0x9119 0x7B14 0x5F7C 0x78A7 0x84D6 0x853D 0x6BD5 0x6BD9 \ + 0x6BD6 0x5E01 0x5E87 0x75F9 0x95ED 0x655D 0x5F0A 0x5FC5 \ + 0x8F9F 0x58C1 0x81C2 0x907F 0x965B 0x97AD 0x8FB9 0x7F16 \ + 0x8D2C 0x6241 0x4FBF 0x53D8 0x535E 0x8FA8 0x8FA9 0x8FAB \ + 0x904D 0x6807 0x5F6A 0x8198 0x8868 0x9CD6 0x618B 0x522B \ + 0x762A 0x5F6C 0x658C 0x6FD2 0x6EE8 0x5BBE 0x6448 0x5175 \ + 0x51B0 0x67C4 0x4E19 0x79C9 0x997C 0x70B3 0x775D 0x775E \ + 0x775F 0x7760 0x7764 0x7767 0x7769 0x776A 0x776D 0x776E \ + 0x776F 0x7770 0x7771 0x7772 0x7773 0x7774 0x7775 0x7776 \ + 0x7777 0x7778 0x777A 0x777B 0x777C 0x7781 0x7782 0x7783 \ + 0x7786 0x7787 0x7788 0x7789 0x778A 0x778B 0x778F 0x7790 \ + 0x7793 0x7794 0x7795 0x7796 0x7797 0x7798 0x7799 0x779A \ + 0x779B 0x779C 0x779D 0x779E 0x77A1 0x77A3 0x77A4 0x77A6 \ + 0x77A8 0x77AB 0x77AD 0x77AE 0x77AF 0x77B1 0x77B2 0x77B4 \ + 0x77B6 0x77B7 0x77B8 0x77B9 0x77BA 0x77BC 0x77BE 0x77C0 \ + 0x77C1 0x77C2 0x77C3 0x77C4 0x77C5 0x77C6 0x77C7 0x77C8 \ + 0x77C9 0x77CA 0x77CB 0x77CC 0x77CE 0x77CF 0x77D0 0x77D1 \ + 0x77D2 0x77D3 0x77D4 0x77D5 0x77D6 0x77D8 0x77D9 0x77DA \ + 0x77DD 0x77DE 0x77DF 0x77E0 0x77E1 0x77E4 0x75C5 0x5E76 \ + 0x73BB 0x83E0 0x64AD 0x62E8 0x94B5 0x6CE2 0x535A 0x52C3 \ + 0x640F 0x94C2 0x7B94 0x4F2F 0x5E1B 0x8236 0x8116 0x818A \ + 0x6E24 0x6CCA 0x9A73 0x6355 0x535C 0x54FA 0x8865 0x57E0 \ + 0x4E0D 0x5E03 0x6B65 0x7C3F 0x90E8 0x6016 0x64E6 0x731C \ + 0x88C1 0x6750 0x624D 0x8D22 0x776C 0x8E29 0x91C7 0x5F69 \ + 0x83DC 0x8521 0x9910 0x53C2 0x8695 0x6B8B 0x60ED 0x60E8 \ + 0x707F 0x82CD 0x8231 0x4ED3 0x6CA7 0x85CF 0x64CD 0x7CD9 \ + 0x69FD 0x66F9 0x8349 0x5395 0x7B56 0x4FA7 0x518C 0x6D4B +38 0x5C42 0x8E6D 0x63D2 0x53C9 0x832C 0x8336 0x67E5 0x78B4 \ + 0x643D 0x5BDF 0x5C94 0x5DEE 0x8BE7 0x62C6 0x67F4 0x8C7A \ + 0x6400 0x63BA 0x8749 0x998B 0x8C17 0x7F20 0x94F2 0x4EA7 \ + 0x9610 0x98A4 0x660C 0x7316 0x77E6 0x77E8 0x77EA 0x77EF \ + 0x77F0 0x77F1 0x77F2 0x77F4 0x77F5 0x77F7 0x77F9 0x77FA \ + 0x77FB 0x77FC 0x7803 0x7804 0x7805 0x7806 0x7807 0x7808 \ + 0x780A 0x780B 0x780E 0x780F 0x7810 0x7813 0x7815 0x7819 \ + 0x781B 0x781E 0x7820 0x7821 0x7822 0x7824 0x7828 0x782A \ + 0x782B 0x782E 0x782F 0x7831 0x7832 0x7833 0x7835 0x7836 \ + 0x783D 0x783F 0x7841 0x7842 0x7843 0x7844 0x7846 0x7848 \ + 0x7849 0x784A 0x784B 0x784D 0x784F 0x7851 0x7853 0x7854 \ + 0x7858 0x7859 0x785A 0x785B 0x785C 0x785E 0x785F 0x7860 \ + 0x7861 0x7862 0x7863 0x7864 0x7865 0x7866 0x7867 0x7868 \ + 0x7869 0x786F 0x7870 0x7871 0x7872 0x7873 0x7874 0x7875 \ + 0x7876 0x7878 0x7879 0x787A 0x787B 0x787D 0x787E 0x787F \ + 0x7880 0x7881 0x7882 0x7883 0x573A 0x5C1D 0x5E38 0x957F \ + 0x507F 0x80A0 0x5382 0x655E 0x7545 0x5531 0x5021 0x8D85 \ + 0x6284 0x949E 0x671D 0x5632 0x6F6E 0x5DE2 0x5435 0x7092 \ + 0x8F66 0x626F 0x64A4 0x63A3 0x5F7B 0x6F88 0x90F4 0x81E3 \ + 0x8FB0 0x5C18 0x6668 0x5FF1 0x6C89 0x9648 0x8D81 0x886C \ + 0x6491 0x79F0 0x57CE 0x6A59 0x6210 0x5448 0x4E58 0x7A0B \ + 0x60E9 0x6F84 0x8BDA 0x627F 0x901E 0x9A8B 0x79E4 0x5403 \ + 0x75F4 0x6301 0x5319 0x6C60 0x8FDF 0x5F1B 0x9A70 0x803B \ + 0x9F7F 0x4F88 0x5C3A 0x8D64 0x7FC5 0x65A5 0x70BD 0x5145 \ + 0x51B2 0x866B 0x5D07 0x5BA0 0x62BD 0x916C 0x7574 0x8E0C \ + 0x7A20 0x6101 0x7B79 0x4EC7 0x7EF8 0x7785 0x4E11 0x81ED \ + 0x521D 0x51FA 0x6A71 0x53A8 0x8E87 0x9504 0x96CF 0x6EC1 \ + 0x9664 0x695A 0x7884 0x7885 0x7886 0x7888 0x788A 0x788B \ + 0x788F 0x7890 0x7892 0x7894 0x7895 0x7896 0x7899 0x789D \ + 0x789E 0x78A0 0x78A2 0x78A4 0x78A6 0x78A8 0x78A9 0x78AA \ + 0x78AB 0x78AC 0x78AD 0x78AE 0x78AF 0x78B5 0x78B6 0x78B7 \ + 0x78B8 0x78BA 0x78BB 0x78BC 0x78BD 0x78BF 0x78C0 0x78C2 +39 0x78C3 0x78C4 0x78C6 0x78C7 0x78C8 0x78CC 0x78CD 0x78CE \ + 0x78CF 0x78D1 0x78D2 0x78D3 0x78D6 0x78D7 0x78D8 0x78DA \ + 0x78DB 0x78DC 0x78DD 0x78DE 0x78DF 0x78E0 0x78E1 0x78E2 \ + 0x78E3 0x78E4 0x78E5 0x78E6 0x78E7 0x78E9 0x78EA 0x78EB \ + 0x78ED 0x78EE 0x78EF 0x78F0 0x78F1 0x78F3 0x78F5 0x78F6 \ + 0x78F8 0x78F9 0x78FB 0x78FC 0x78FD 0x78FE 0x78FF 0x7900 \ + 0x7902 0x7903 0x7904 0x7906 0x7907 0x7908 0x7909 0x790A \ + 0x790B 0x790C 0x7840 0x50A8 0x77D7 0x6410 0x89E6 0x5904 \ + 0x63E3 0x5DDD 0x7A7F 0x693D 0x4F20 0x8239 0x5598 0x4E32 \ + 0x75AE 0x7A97 0x5E62 0x5E8A 0x95EF 0x521B 0x5439 0x708A \ + 0x6376 0x9524 0x5782 0x6625 0x693F 0x9187 0x5507 0x6DF3 \ + 0x7EAF 0x8822 0x6233 0x7EF0 0x75B5 0x8328 0x78C1 0x96CC \ + 0x8F9E 0x6148 0x74F7 0x8BCD 0x6B64 0x523A 0x8D50 0x6B21 \ + 0x806A 0x8471 0x56F1 0x5306 0x4ECE 0x4E1B 0x51D1 0x7C97 \ + 0x918B 0x7C07 0x4FC3 0x8E7F 0x7BE1 0x7A9C 0x6467 0x5D14 \ + 0x50AC 0x8106 0x7601 0x7CB9 0x6DEC 0x7FE0 0x6751 0x5B58 \ + 0x5BF8 0x78CB 0x64AE 0x6413 0x63AA 0x632B 0x9519 0x642D \ + 0x8FBE 0x7B54 0x7629 0x6253 0x5927 0x5446 0x6B79 0x50A3 \ + 0x6234 0x5E26 0x6B86 0x4EE3 0x8D37 0x888B 0x5F85 0x902E \ + 0x790D 0x790E 0x790F 0x7910 0x7911 0x7912 0x7914 0x7915 \ + 0x7916 0x7917 0x7918 0x7919 0x791A 0x791B 0x791C 0x791D \ + 0x791F 0x7920 0x7921 0x7922 0x7923 0x7925 0x7926 0x7927 \ + 0x7928 0x7929 0x792A 0x792B 0x792C 0x792D 0x792E 0x792F \ + 0x7930 0x7931 0x7932 0x7933 0x7935 0x7936 0x7937 0x7938 \ + 0x7939 0x793D 0x793F 0x7942 0x7943 0x7944 0x7945 0x7947 \ + 0x794A 0x794B 0x794C 0x794D 0x794E 0x794F 0x7950 0x7951 \ + 0x7952 0x7954 0x7955 0x7958 0x7959 0x7961 0x7963 0x7964 \ + 0x7966 0x7969 0x796A 0x796B 0x796C 0x796E 0x7970 0x7971 \ + 0x7972 0x7973 0x7974 0x7975 0x7976 0x7979 0x797B 0x797C \ + 0x797D 0x797E 0x797F 0x7982 0x7983 0x7986 0x7987 0x7988 \ + 0x7989 0x798B 0x798C 0x798D 0x798E 0x7990 0x7991 0x7992 \ + 0x6020 0x803D 0x62C5 0x4E39 0x5355 0x90F8 0x63B8 0x80C6 +40 0x65E6 0x6C2E 0x4F46 0x60EE 0x6DE1 0x8BDE 0x5F39 0x86CB \ + 0x5F53 0x6321 0x515A 0x8361 0x6863 0x5200 0x6363 0x8E48 \ + 0x5012 0x5C9B 0x7977 0x5BFC 0x5230 0x7A3B 0x60BC 0x9053 \ + 0x76D7 0x5FB7 0x5F97 0x7684 0x8E6C 0x706F 0x767B 0x7B49 \ + 0x77AA 0x51F3 0x9093 0x5824 0x4F4E 0x6EF4 0x8FEA 0x654C \ + 0x7B1B 0x72C4 0x6DA4 0x7FDF 0x5AE1 0x62B5 0x5E95 0x5730 \ + 0x8482 0x7B2C 0x5E1D 0x5F1F 0x9012 0x7F14 0x98A0 0x6382 \ + 0x6EC7 0x7898 0x70B9 0x5178 0x975B 0x57AB 0x7535 0x4F43 \ + 0x7538 0x5E97 0x60E6 0x5960 0x6DC0 0x6BBF 0x7889 0x53FC \ + 0x96D5 0x51CB 0x5201 0x6389 0x540A 0x9493 0x8C03 0x8DCC \ + 0x7239 0x789F 0x8776 0x8FED 0x8C0D 0x53E0 0x7993 0x7994 \ + 0x7995 0x7996 0x7997 0x7998 0x7999 0x799B 0x799C 0x799D \ + 0x799E 0x799F 0x79A0 0x79A1 0x79A2 0x79A3 0x79A4 0x79A5 \ + 0x79A6 0x79A8 0x79A9 0x79AA 0x79AB 0x79AC 0x79AD 0x79AE \ + 0x79AF 0x79B0 0x79B1 0x79B2 0x79B4 0x79B5 0x79B6 0x79B7 \ + 0x79B8 0x79BC 0x79BF 0x79C2 0x79C4 0x79C5 0x79C7 0x79C8 \ + 0x79CA 0x79CC 0x79CE 0x79CF 0x79D0 0x79D3 0x79D4 0x79D6 \ + 0x79D7 0x79D9 0x79DA 0x79DB 0x79DC 0x79DD 0x79DE 0x79E0 \ + 0x79E1 0x79E2 0x79E5 0x79E8 0x79EA 0x79EC 0x79EE 0x79F1 \ + 0x79F2 0x79F3 0x79F4 0x79F5 0x79F6 0x79F7 0x79F9 0x79FA \ + 0x79FC 0x79FE 0x79FF 0x7A01 0x7A04 0x7A05 0x7A07 0x7A08 \ + 0x7A09 0x7A0A 0x7A0C 0x7A0F 0x7A10 0x7A11 0x7A12 0x7A13 \ + 0x7A15 0x7A16 0x7A18 0x7A19 0x7A1B 0x7A1C 0x4E01 0x76EF \ + 0x53EE 0x9489 0x9876 0x9F0E 0x952D 0x5B9A 0x8BA2 0x4E22 \ + 0x4E1C 0x51AC 0x8463 0x61C2 0x52A8 0x680B 0x4F97 0x606B \ + 0x51BB 0x6D1E 0x515C 0x6296 0x6597 0x9661 0x8C46 0x9017 \ + 0x75D8 0x90FD 0x7763 0x6BD2 0x728A 0x72EC 0x8BFB 0x5835 \ + 0x7779 0x8D4C 0x675C 0x9540 0x809A 0x5EA6 0x6E21 0x5992 \ + 0x7AEF 0x77ED 0x953B 0x6BB5 0x65AD 0x7F0E 0x5806 0x5151 \ + 0x961F 0x5BF9 0x58A9 0x5428 0x8E72 0x6566 0x987F 0x56E4 \ + 0x949D 0x76FE 0x9041 0x6387 0x54C6 0x591A 0x593A 0x579B \ + 0x8EB2 0x6735 0x8DFA 0x8235 0x5241 0x60F0 0x5815 0x86FE +41 0x5CE8 0x9E45 0x4FC4 0x989D 0x8BB9 0x5A25 0x6076 0x5384 \ + 0x627C 0x904F 0x9102 0x997F 0x6069 0x800C 0x513F 0x8033 \ + 0x5C14 0x9975 0x6D31 0x4E8C 0x7A1D 0x7A1F 0x7A21 0x7A22 \ + 0x7A24 0x7A25 0x7A26 0x7A27 0x7A28 0x7A29 0x7A2A 0x7A2B \ + 0x7A2C 0x7A2D 0x7A2E 0x7A2F 0x7A30 0x7A31 0x7A32 0x7A34 \ + 0x7A35 0x7A36 0x7A38 0x7A3A 0x7A3E 0x7A40 0x7A41 0x7A42 \ + 0x7A43 0x7A44 0x7A45 0x7A47 0x7A48 0x7A49 0x7A4A 0x7A4B \ + 0x7A4C 0x7A4D 0x7A4E 0x7A4F 0x7A50 0x7A52 0x7A53 0x7A54 \ + 0x7A55 0x7A56 0x7A58 0x7A59 0x7A5A 0x7A5B 0x7A5C 0x7A5D \ + 0x7A5E 0x7A5F 0x7A60 0x7A61 0x7A62 0x7A63 0x7A64 0x7A65 \ + 0x7A66 0x7A67 0x7A68 0x7A69 0x7A6A 0x7A6B 0x7A6C 0x7A6D \ + 0x7A6E 0x7A6F 0x7A71 0x7A72 0x7A73 0x7A75 0x7A7B 0x7A7C \ + 0x7A7D 0x7A7E 0x7A82 0x7A85 0x7A87 0x7A89 0x7A8A 0x7A8B \ + 0x7A8C 0x7A8E 0x7A8F 0x7A90 0x7A93 0x7A94 0x7A99 0x7A9A \ + 0x7A9B 0x7A9E 0x7AA1 0x7AA2 0x8D30 0x53D1 0x7F5A 0x7B4F \ + 0x4F10 0x4E4F 0x9600 0x6CD5 0x73D0 0x85E9 0x5E06 0x756A \ + 0x7FFB 0x6A0A 0x77FE 0x9492 0x7E41 0x51E1 0x70E6 0x53CD \ + 0x8FD4 0x8303 0x8D29 0x72AF 0x996D 0x6CDB 0x574A 0x82B3 \ + 0x65B9 0x80AA 0x623F 0x9632 0x59A8 0x4EFF 0x8BBF 0x7EBA \ + 0x653E 0x83F2 0x975E 0x5561 0x98DE 0x80A5 0x532A 0x8BFD \ + 0x5420 0x80BA 0x5E9F 0x6CB8 0x8D39 0x82AC 0x915A 0x5429 \ + 0x6C1B 0x5206 0x7EB7 0x575F 0x711A 0x6C7E 0x7C89 0x594B \ + 0x4EFD 0x5FFF 0x6124 0x7CAA 0x4E30 0x5C01 0x67AB 0x8702 \ + 0x5CF0 0x950B 0x98CE 0x75AF 0x70FD 0x9022 0x51AF 0x7F1D \ + 0x8BBD 0x5949 0x51E4 0x4F5B 0x5426 0x592B 0x6577 0x80A4 \ + 0x5B75 0x6276 0x62C2 0x8F90 0x5E45 0x6C1F 0x7B26 0x4F0F \ + 0x4FD8 0x670D 0x7AA3 0x7AA4 0x7AA7 0x7AA9 0x7AAA 0x7AAB \ + 0x7AAE 0x7AAF 0x7AB0 0x7AB1 0x7AB2 0x7AB4 0x7AB5 0x7AB6 \ + 0x7AB7 0x7AB8 0x7AB9 0x7ABA 0x7ABB 0x7ABC 0x7ABD 0x7ABE \ + 0x7AC0 0x7AC1 0x7AC2 0x7AC3 0x7AC4 0x7AC5 0x7AC6 0x7AC7 \ + 0x7AC8 0x7AC9 0x7ACA 0x7ACC 0x7ACD 0x7ACE 0x7ACF 0x7AD0 \ + 0x7AD1 0x7AD2 0x7AD3 0x7AD4 0x7AD5 0x7AD7 0x7AD8 0x7ADA +42 0x7ADB 0x7ADC 0x7ADD 0x7AE1 0x7AE2 0x7AE4 0x7AE7 0x7AE8 \ + 0x7AE9 0x7AEA 0x7AEB 0x7AEC 0x7AEE 0x7AF0 0x7AF1 0x7AF2 \ + 0x7AF3 0x7AF4 0x7AF5 0x7AF6 0x7AF7 0x7AF8 0x7AFB 0x7AFC \ + 0x7AFE 0x7B00 0x7B01 0x7B02 0x7B05 0x7B07 0x7B09 0x7B0C \ + 0x7B0D 0x7B0E 0x7B10 0x7B12 0x7B13 0x7B16 0x7B17 0x7B18 \ + 0x7B1A 0x7B1C 0x7B1D 0x7B1F 0x7B21 0x7B22 0x7B23 0x7B27 \ + 0x7B29 0x7B2D 0x6D6E 0x6DAA 0x798F 0x88B1 0x5F17 0x752B \ + 0x629A 0x8F85 0x4FEF 0x91DC 0x65A7 0x812F 0x8151 0x5E9C \ + 0x8150 0x8D74 0x526F 0x8986 0x8D4B 0x590D 0x5085 0x4ED8 \ + 0x961C 0x7236 0x8179 0x8D1F 0x5BCC 0x8BA3 0x9644 0x5987 \ + 0x7F1A 0x5490 0x5676 0x560E 0x8BE5 0x6539 0x6982 0x9499 \ + 0x76D6 0x6E89 0x5E72 0x7518 0x6746 0x67D1 0x7AFF 0x809D \ + 0x8D76 0x611F 0x79C6 0x6562 0x8D63 0x5188 0x521A 0x94A2 \ + 0x7F38 0x809B 0x7EB2 0x5C97 0x6E2F 0x6760 0x7BD9 0x768B \ + 0x9AD8 0x818F 0x7F94 0x7CD5 0x641E 0x9550 0x7A3F 0x544A \ + 0x54E5 0x6B4C 0x6401 0x6208 0x9E3D 0x80F3 0x7599 0x5272 \ + 0x9769 0x845B 0x683C 0x86E4 0x9601 0x9694 0x94EC 0x4E2A \ + 0x5404 0x7ED9 0x6839 0x8DDF 0x8015 0x66F4 0x5E9A 0x7FB9 \ + 0x7B2F 0x7B30 0x7B32 0x7B34 0x7B35 0x7B36 0x7B37 0x7B39 \ + 0x7B3B 0x7B3D 0x7B3F 0x7B40 0x7B41 0x7B42 0x7B43 0x7B44 \ + 0x7B46 0x7B48 0x7B4A 0x7B4D 0x7B4E 0x7B53 0x7B55 0x7B57 \ + 0x7B59 0x7B5C 0x7B5E 0x7B5F 0x7B61 0x7B63 0x7B64 0x7B65 \ + 0x7B66 0x7B67 0x7B68 0x7B69 0x7B6A 0x7B6B 0x7B6C 0x7B6D \ + 0x7B6F 0x7B70 0x7B73 0x7B74 0x7B76 0x7B78 0x7B7A 0x7B7C \ + 0x7B7D 0x7B7F 0x7B81 0x7B82 0x7B83 0x7B84 0x7B86 0x7B87 \ + 0x7B88 0x7B89 0x7B8A 0x7B8B 0x7B8C 0x7B8E 0x7B8F 0x7B91 \ + 0x7B92 0x7B93 0x7B96 0x7B98 0x7B99 0x7B9A 0x7B9B 0x7B9E \ + 0x7B9F 0x7BA0 0x7BA3 0x7BA4 0x7BA5 0x7BAE 0x7BAF 0x7BB0 \ + 0x7BB2 0x7BB3 0x7BB5 0x7BB6 0x7BB7 0x7BB9 0x7BBA 0x7BBB \ + 0x7BBC 0x7BBD 0x7BBE 0x7BBF 0x7BC0 0x7BC2 0x7BC3 0x7BC4 \ + 0x57C2 0x803F 0x6897 0x5DE5 0x653B 0x529F 0x606D 0x9F9A \ + 0x4F9B 0x8EAC 0x516C 0x5BAB 0x5F13 0x5DE9 0x6C5E 0x62F1 +43 0x8D21 0x5171 0x94A9 0x52FE 0x6C9F 0x82DF 0x72D7 0x57A2 \ + 0x6784 0x8D2D 0x591F 0x8F9C 0x83C7 0x5495 0x7B8D 0x4F30 \ + 0x6CBD 0x5B64 0x59D1 0x9F13 0x53E4 0x86CA 0x9AA8 0x8C37 \ + 0x80A1 0x6545 0x987E 0x56FA 0x96C7 0x522E 0x74DC 0x5250 \ + 0x5BE1 0x6302 0x8902 0x4E56 0x62D0 0x602A 0x68FA 0x5173 \ + 0x5B98 0x51A0 0x89C2 0x7BA1 0x9986 0x7F50 0x60EF 0x704C \ + 0x8D2F 0x5149 0x5E7F 0x901B 0x7470 0x89C4 0x572D 0x7845 \ + 0x5F52 0x9F9F 0x95FA 0x8F68 0x9B3C 0x8BE1 0x7678 0x6842 \ + 0x67DC 0x8DEA 0x8D35 0x523D 0x8F8A 0x6EDA 0x68CD 0x9505 \ + 0x90ED 0x56FD 0x679C 0x88F9 0x8FC7 0x54C8 0x7BC5 0x7BC8 \ + 0x7BC9 0x7BCA 0x7BCB 0x7BCD 0x7BCE 0x7BCF 0x7BD0 0x7BD2 \ + 0x7BD4 0x7BD5 0x7BD6 0x7BD7 0x7BD8 0x7BDB 0x7BDC 0x7BDE \ + 0x7BDF 0x7BE0 0x7BE2 0x7BE3 0x7BE4 0x7BE7 0x7BE8 0x7BE9 \ + 0x7BEB 0x7BEC 0x7BED 0x7BEF 0x7BF0 0x7BF2 0x7BF3 0x7BF4 \ + 0x7BF5 0x7BF6 0x7BF8 0x7BF9 0x7BFA 0x7BFB 0x7BFD 0x7BFF \ + 0x7C00 0x7C01 0x7C02 0x7C03 0x7C04 0x7C05 0x7C06 0x7C08 \ + 0x7C09 0x7C0A 0x7C0D 0x7C0E 0x7C10 0x7C11 0x7C12 0x7C13 \ + 0x7C14 0x7C15 0x7C17 0x7C18 0x7C19 0x7C1A 0x7C1B 0x7C1C \ + 0x7C1D 0x7C1E 0x7C20 0x7C21 0x7C22 0x7C23 0x7C24 0x7C25 \ + 0x7C28 0x7C29 0x7C2B 0x7C2C 0x7C2D 0x7C2E 0x7C2F 0x7C30 \ + 0x7C31 0x7C32 0x7C33 0x7C34 0x7C35 0x7C36 0x7C37 0x7C39 \ + 0x7C3A 0x7C3B 0x7C3C 0x7C3D 0x7C3E 0x7C42 0x9AB8 0x5B69 \ + 0x6D77 0x6C26 0x4EA5 0x5BB3 0x9A87 0x9163 0x61A8 0x90AF \ + 0x97E9 0x542B 0x6DB5 0x5BD2 0x51FD 0x558A 0x7F55 0x7FF0 \ + 0x64BC 0x634D 0x65F1 0x61BE 0x608D 0x710A 0x6C57 0x6C49 \ + 0x592F 0x676D 0x822A 0x58D5 0x568E 0x8C6A 0x6BEB 0x90DD \ + 0x597D 0x8017 0x53F7 0x6D69 0x5475 0x559D 0x8377 0x83CF \ + 0x6838 0x79BE 0x548C 0x4F55 0x5408 0x76D2 0x8C89 0x9602 \ + 0x6CB3 0x6DB8 0x8D6B 0x8910 0x9E64 0x8D3A 0x563F 0x9ED1 \ + 0x75D5 0x5F88 0x72E0 0x6068 0x54FC 0x4EA8 0x6A2A 0x8861 \ + 0x6052 0x8F70 0x54C4 0x70D8 0x8679 0x9E3F 0x6D2A 0x5B8F \ + 0x5F18 0x7EA2 0x5589 0x4FAF 0x7334 0x543C 0x539A 0x5019 +44 0x540E 0x547C 0x4E4E 0x5FFD 0x745A 0x58F6 0x846B 0x80E1 \ + 0x8774 0x72D0 0x7CCA 0x6E56 0x7C43 0x7C44 0x7C45 0x7C46 \ + 0x7C47 0x7C48 0x7C49 0x7C4A 0x7C4B 0x7C4C 0x7C4E 0x7C4F \ + 0x7C50 0x7C51 0x7C52 0x7C53 0x7C54 0x7C55 0x7C56 0x7C57 \ + 0x7C58 0x7C59 0x7C5A 0x7C5B 0x7C5C 0x7C5D 0x7C5E 0x7C5F \ + 0x7C60 0x7C61 0x7C62 0x7C63 0x7C64 0x7C65 0x7C66 0x7C67 \ + 0x7C68 0x7C69 0x7C6A 0x7C6B 0x7C6C 0x7C6D 0x7C6E 0x7C6F \ + 0x7C70 0x7C71 0x7C72 0x7C75 0x7C76 0x7C77 0x7C78 0x7C79 \ + 0x7C7A 0x7C7E 0x7C7F 0x7C80 0x7C81 0x7C82 0x7C83 0x7C84 \ + 0x7C85 0x7C86 0x7C87 0x7C88 0x7C8A 0x7C8B 0x7C8C 0x7C8D \ + 0x7C8E 0x7C8F 0x7C90 0x7C93 0x7C94 0x7C96 0x7C99 0x7C9A \ + 0x7C9B 0x7CA0 0x7CA1 0x7CA3 0x7CA6 0x7CA7 0x7CA8 0x7CA9 \ + 0x7CAB 0x7CAC 0x7CAD 0x7CAF 0x7CB0 0x7CB4 0x7CB5 0x7CB6 \ + 0x7CB7 0x7CB8 0x7CBA 0x7CBB 0x5F27 0x864E 0x552C 0x62A4 \ + 0x4E92 0x6CAA 0x6237 0x82B1 0x54D7 0x534E 0x733E 0x6ED1 \ + 0x753B 0x5212 0x5316 0x8BDD 0x69D0 0x5F8A 0x6000 0x6DEE \ + 0x574F 0x6B22 0x73AF 0x6853 0x8FD8 0x7F13 0x6362 0x60A3 \ + 0x5524 0x75EA 0x8C62 0x7115 0x6DA3 0x5BA6 0x5E7B 0x8352 \ + 0x614C 0x9EC4 0x78FA 0x8757 0x7C27 0x7687 0x51F0 0x60F6 \ + 0x714C 0x6643 0x5E4C 0x604D 0x8C0E 0x7070 0x6325 0x8F89 \ + 0x5FBD 0x6062 0x86D4 0x56DE 0x6BC1 0x6094 0x6167 0x5349 \ + 0x60E0 0x6666 0x8D3F 0x79FD 0x4F1A 0x70E9 0x6C47 0x8BB3 \ + 0x8BF2 0x7ED8 0x8364 0x660F 0x5A5A 0x9B42 0x6D51 0x6DF7 \ + 0x8C41 0x6D3B 0x4F19 0x706B 0x83B7 0x6216 0x60D1 0x970D \ + 0x8D27 0x7978 0x51FB 0x573E 0x57FA 0x673A 0x7578 0x7A3D \ + 0x79EF 0x7B95 0x7CBF 0x7CC0 0x7CC2 0x7CC3 0x7CC4 0x7CC6 \ + 0x7CC9 0x7CCB 0x7CCE 0x7CCF 0x7CD0 0x7CD1 0x7CD2 0x7CD3 \ + 0x7CD4 0x7CD8 0x7CDA 0x7CDB 0x7CDD 0x7CDE 0x7CE1 0x7CE2 \ + 0x7CE3 0x7CE4 0x7CE5 0x7CE6 0x7CE7 0x7CE9 0x7CEA 0x7CEB \ + 0x7CEC 0x7CED 0x7CEE 0x7CF0 0x7CF1 0x7CF2 0x7CF3 0x7CF4 \ + 0x7CF5 0x7CF6 0x7CF7 0x7CF9 0x7CFA 0x7CFC 0x7CFD 0x7CFE \ + 0x7CFF 0x7D00 0x7D01 0x7D02 0x7D03 0x7D04 0x7D05 0x7D06 +45 0x7D07 0x7D08 0x7D09 0x7D0B 0x7D0C 0x7D0D 0x7D0E 0x7D0F \ + 0x7D10 0x7D11 0x7D12 0x7D13 0x7D14 0x7D15 0x7D16 0x7D17 \ + 0x7D18 0x7D19 0x7D1A 0x7D1B 0x7D1C 0x7D1D 0x7D1E 0x7D1F \ + 0x7D21 0x7D23 0x7D24 0x7D25 0x7D26 0x7D28 0x7D29 0x7D2A \ + 0x7D2C 0x7D2D 0x7D2E 0x7D30 0x7D31 0x7D32 0x7D33 0x7D34 \ + 0x7D35 0x7D36 0x808C 0x9965 0x8FF9 0x6FC0 0x8BA5 0x9E21 \ + 0x59EC 0x7EE9 0x7F09 0x5409 0x6781 0x68D8 0x8F91 0x7C4D \ + 0x96C6 0x53CA 0x6025 0x75BE 0x6C72 0x5373 0x5AC9 0x7EA7 \ + 0x6324 0x51E0 0x810A 0x5DF1 0x84DF 0x6280 0x5180 0x5B63 \ + 0x4F0E 0x796D 0x5242 0x60B8 0x6D4E 0x5BC4 0x5BC2 0x8BA1 \ + 0x8BB0 0x65E2 0x5FCC 0x9645 0x5993 0x7EE7 0x7EAA 0x5609 \ + 0x67B7 0x5939 0x4F73 0x5BB6 0x52A0 0x835A 0x988A 0x8D3E \ + 0x7532 0x94BE 0x5047 0x7A3C 0x4EF7 0x67B6 0x9A7E 0x5AC1 \ + 0x6B7C 0x76D1 0x575A 0x5C16 0x7B3A 0x95F4 0x714E 0x517C \ + 0x80A9 0x8270 0x5978 0x7F04 0x8327 0x68C0 0x67EC 0x78B1 \ + 0x7877 0x62E3 0x6361 0x7B80 0x4FED 0x526A 0x51CF 0x8350 \ + 0x69DB 0x9274 0x8DF5 0x8D31 0x89C1 0x952E 0x7BAD 0x4EF6 \ + 0x7D37 0x7D38 0x7D39 0x7D3A 0x7D3B 0x7D3C 0x7D3D 0x7D3E \ + 0x7D3F 0x7D40 0x7D41 0x7D42 0x7D43 0x7D44 0x7D45 0x7D46 \ + 0x7D47 0x7D48 0x7D49 0x7D4A 0x7D4B 0x7D4C 0x7D4D 0x7D4E \ + 0x7D4F 0x7D50 0x7D51 0x7D52 0x7D53 0x7D54 0x7D55 0x7D56 \ + 0x7D57 0x7D58 0x7D59 0x7D5A 0x7D5B 0x7D5C 0x7D5D 0x7D5E \ + 0x7D5F 0x7D60 0x7D61 0x7D62 0x7D63 0x7D64 0x7D65 0x7D66 \ + 0x7D67 0x7D68 0x7D69 0x7D6A 0x7D6B 0x7D6C 0x7D6D 0x7D6F \ + 0x7D70 0x7D71 0x7D72 0x7D73 0x7D74 0x7D75 0x7D76 0x7D78 \ + 0x7D79 0x7D7A 0x7D7B 0x7D7C 0x7D7D 0x7D7E 0x7D7F 0x7D80 \ + 0x7D81 0x7D82 0x7D83 0x7D84 0x7D85 0x7D86 0x7D87 0x7D88 \ + 0x7D89 0x7D8A 0x7D8B 0x7D8C 0x7D8D 0x7D8E 0x7D8F 0x7D90 \ + 0x7D91 0x7D92 0x7D93 0x7D94 0x7D95 0x7D96 0x7D97 0x7D98 \ + 0x5065 0x8230 0x5251 0x996F 0x6E10 0x6E85 0x6DA7 0x5EFA \ + 0x50F5 0x59DC 0x5C06 0x6D46 0x6C5F 0x7586 0x848B 0x6868 \ + 0x5956 0x8BB2 0x5320 0x9171 0x964D 0x8549 0x6912 0x7901 +46 0x7126 0x80F6 0x4EA4 0x90CA 0x6D47 0x9A84 0x5A07 0x56BC \ + 0x6405 0x94F0 0x77EB 0x4FA5 0x811A 0x72E1 0x89D2 0x997A \ + 0x7F34 0x7EDE 0x527F 0x6559 0x9175 0x8F7F 0x8F83 0x53EB \ + 0x7A96 0x63ED 0x63A5 0x7686 0x79F8 0x8857 0x9636 0x622A \ + 0x52AB 0x8282 0x6854 0x6770 0x6377 0x776B 0x7AED 0x6D01 \ + 0x7ED3 0x89E3 0x59D0 0x6212 0x85C9 0x82A5 0x754C 0x501F \ + 0x4ECB 0x75A5 0x8BEB 0x5C4A 0x5DFE 0x7B4B 0x65A4 0x91D1 \ + 0x4ECA 0x6D25 0x895F 0x7D27 0x9526 0x4EC5 0x8C28 0x8FDB \ + 0x9773 0x664B 0x7981 0x8FD1 0x70EC 0x6D78 0x7D99 0x7D9A \ + 0x7D9B 0x7D9C 0x7D9D 0x7D9E 0x7D9F 0x7DA0 0x7DA1 0x7DA2 \ + 0x7DA3 0x7DA4 0x7DA5 0x7DA7 0x7DA8 0x7DA9 0x7DAA 0x7DAB \ + 0x7DAC 0x7DAD 0x7DAF 0x7DB0 0x7DB1 0x7DB2 0x7DB3 0x7DB4 \ + 0x7DB5 0x7DB6 0x7DB7 0x7DB8 0x7DB9 0x7DBA 0x7DBB 0x7DBC \ + 0x7DBD 0x7DBE 0x7DBF 0x7DC0 0x7DC1 0x7DC2 0x7DC3 0x7DC4 \ + 0x7DC5 0x7DC6 0x7DC7 0x7DC8 0x7DC9 0x7DCA 0x7DCB 0x7DCC \ + 0x7DCD 0x7DCE 0x7DCF 0x7DD0 0x7DD1 0x7DD2 0x7DD3 0x7DD4 \ + 0x7DD5 0x7DD6 0x7DD7 0x7DD8 0x7DD9 0x7DDA 0x7DDB 0x7DDC \ + 0x7DDD 0x7DDE 0x7DDF 0x7DE0 0x7DE1 0x7DE2 0x7DE3 0x7DE4 \ + 0x7DE5 0x7DE6 0x7DE7 0x7DE8 0x7DE9 0x7DEA 0x7DEB 0x7DEC \ + 0x7DED 0x7DEE 0x7DEF 0x7DF0 0x7DF1 0x7DF2 0x7DF3 0x7DF4 \ + 0x7DF5 0x7DF6 0x7DF7 0x7DF8 0x7DF9 0x7DFA 0x5C3D 0x52B2 \ + 0x8346 0x5162 0x830E 0x775B 0x6676 0x9CB8 0x4EAC 0x60CA \ + 0x7CBE 0x7CB3 0x7ECF 0x4E95 0x8B66 0x666F 0x9888 0x9759 \ + 0x5883 0x656C 0x955C 0x5F84 0x75C9 0x9756 0x7ADF 0x7ADE \ + 0x51C0 0x70AF 0x7A98 0x63EA 0x7A76 0x7EA0 0x7396 0x97ED \ + 0x4E45 0x7078 0x4E5D 0x9152 0x53A9 0x6551 0x65E7 0x81FC \ + 0x8205 0x548E 0x5C31 0x759A 0x97A0 0x62D8 0x72D9 0x75BD \ + 0x5C45 0x9A79 0x83CA 0x5C40 0x5480 0x77E9 0x4E3E 0x6CAE \ + 0x805A 0x62D2 0x636E 0x5DE8 0x5177 0x8DDD 0x8E1E 0x952F \ + 0x4FF1 0x53E5 0x60E7 0x70AC 0x5267 0x6350 0x9E43 0x5A1F \ + 0x5026 0x7737 0x5377 0x7EE2 0x6485 0x652B 0x6289 0x6398 \ + 0x5014 0x7235 0x89C9 0x51B3 0x8BC0 0x7EDD 0x5747 0x83CC +47 0x94A7 0x519B 0x541B 0x5CFB 0x7DFB 0x7DFC 0x7DFD 0x7DFE \ + 0x7DFF 0x7E00 0x7E01 0x7E02 0x7E03 0x7E04 0x7E05 0x7E06 \ + 0x7E07 0x7E08 0x7E09 0x7E0A 0x7E0B 0x7E0C 0x7E0D 0x7E0E \ + 0x7E0F 0x7E10 0x7E11 0x7E12 0x7E13 0x7E14 0x7E15 0x7E16 \ + 0x7E17 0x7E18 0x7E19 0x7E1A 0x7E1B 0x7E1C 0x7E1D 0x7E1E \ + 0x7E1F 0x7E20 0x7E21 0x7E22 0x7E23 0x7E24 0x7E25 0x7E26 \ + 0x7E27 0x7E28 0x7E29 0x7E2A 0x7E2B 0x7E2C 0x7E2D 0x7E2E \ + 0x7E2F 0x7E30 0x7E31 0x7E32 0x7E33 0x7E34 0x7E35 0x7E36 \ + 0x7E37 0x7E38 0x7E39 0x7E3A 0x7E3C 0x7E3D 0x7E3E 0x7E3F \ + 0x7E40 0x7E42 0x7E43 0x7E44 0x7E45 0x7E46 0x7E48 0x7E49 \ + 0x7E4A 0x7E4B 0x7E4C 0x7E4D 0x7E4E 0x7E4F 0x7E50 0x7E51 \ + 0x7E52 0x7E53 0x7E54 0x7E55 0x7E56 0x7E57 0x7E58 0x7E59 \ + 0x7E5A 0x7E5B 0x7E5C 0x7E5D 0x4FCA 0x7AE3 0x6D5A 0x90E1 \ + 0x9A8F 0x5580 0x5496 0x5361 0x54AF 0x5F00 0x63E9 0x6977 \ + 0x51EF 0x6168 0x520A 0x582A 0x52D8 0x574E 0x780D 0x770B \ + 0x5EB7 0x6177 0x7CE0 0x625B 0x6297 0x4EA2 0x7095 0x8003 \ + 0x62F7 0x70E4 0x9760 0x5777 0x82DB 0x67EF 0x68F5 0x78D5 \ + 0x9897 0x79D1 0x58F3 0x54B3 0x53EF 0x6E34 0x514B 0x523B \ + 0x5BA2 0x8BFE 0x80AF 0x5543 0x57A6 0x6073 0x5751 0x542D \ + 0x7A7A 0x6050 0x5B54 0x63A7 0x62A0 0x53E3 0x6263 0x5BC7 \ + 0x67AF 0x54ED 0x7A9F 0x82E6 0x9177 0x5E93 0x88E4 0x5938 \ + 0x57AE 0x630E 0x8DE8 0x80EF 0x5757 0x7B77 0x4FA9 0x5FEB \ + 0x5BBD 0x6B3E 0x5321 0x7B50 0x72C2 0x6846 0x77FF 0x7736 \ + 0x65F7 0x51B5 0x4E8F 0x76D4 0x5CBF 0x7AA5 0x8475 0x594E \ + 0x9B41 0x5080 0x7E5E 0x7E5F 0x7E60 0x7E61 0x7E62 0x7E63 \ + 0x7E64 0x7E65 0x7E66 0x7E67 0x7E68 0x7E69 0x7E6A 0x7E6B \ + 0x7E6C 0x7E6D 0x7E6E 0x7E6F 0x7E70 0x7E71 0x7E72 0x7E73 \ + 0x7E74 0x7E75 0x7E76 0x7E77 0x7E78 0x7E79 0x7E7A 0x7E7B \ + 0x7E7C 0x7E7D 0x7E7E 0x7E7F 0x7E80 0x7E81 0x7E83 0x7E84 \ + 0x7E85 0x7E86 0x7E87 0x7E88 0x7E89 0x7E8A 0x7E8B 0x7E8C \ + 0x7E8D 0x7E8E 0x7E8F 0x7E90 0x7E91 0x7E92 0x7E93 0x7E94 \ + 0x7E95 0x7E96 0x7E97 0x7E98 0x7E99 0x7E9A 0x7E9C 0x7E9D +48 0x7E9E 0x7EAE 0x7EB4 0x7EBB 0x7EBC 0x7ED6 0x7EE4 0x7EEC \ + 0x7EF9 0x7F0A 0x7F10 0x7F1E 0x7F37 0x7F39 0x7F3B 0x7F3C \ + 0x7F3D 0x7F3E 0x7F3F 0x7F40 0x7F41 0x7F43 0x7F46 0x7F47 \ + 0x7F48 0x7F49 0x7F4A 0x7F4B 0x7F4C 0x7F4D 0x7F4E 0x7F4F \ + 0x7F52 0x7F53 0x9988 0x6127 0x6E83 0x5764 0x6606 0x6346 \ + 0x56F0 0x62EC 0x6269 0x5ED3 0x9614 0x5783 0x62C9 0x5587 \ + 0x8721 0x814A 0x8FA3 0x5566 0x83B1 0x6765 0x8D56 0x84DD \ + 0x5A6A 0x680F 0x62E6 0x7BEE 0x9611 0x5170 0x6F9C 0x8C30 \ + 0x63FD 0x89C8 0x61D2 0x7F06 0x70C2 0x6EE5 0x7405 0x6994 \ + 0x72FC 0x5ECA 0x90CE 0x6717 0x6D6A 0x635E 0x52B3 0x7262 \ + 0x8001 0x4F6C 0x59E5 0x916A 0x70D9 0x6D9D 0x52D2 0x4E50 \ + 0x96F7 0x956D 0x857E 0x78CA 0x7D2F 0x5121 0x5792 0x64C2 \ + 0x808B 0x7C7B 0x6CEA 0x68F1 0x695E 0x51B7 0x5398 0x68A8 \ + 0x7281 0x9ECE 0x7BF1 0x72F8 0x79BB 0x6F13 0x7406 0x674E \ + 0x91CC 0x9CA4 0x793C 0x8389 0x8354 0x540F 0x6817 0x4E3D \ + 0x5389 0x52B1 0x783E 0x5386 0x5229 0x5088 0x4F8B 0x4FD0 \ + 0x7F56 0x7F59 0x7F5B 0x7F5C 0x7F5D 0x7F5E 0x7F60 0x7F63 \ + 0x7F64 0x7F65 0x7F66 0x7F67 0x7F6B 0x7F6C 0x7F6D 0x7F6F \ + 0x7F70 0x7F73 0x7F75 0x7F76 0x7F77 0x7F78 0x7F7A 0x7F7B \ + 0x7F7C 0x7F7D 0x7F7F 0x7F80 0x7F82 0x7F83 0x7F84 0x7F85 \ + 0x7F86 0x7F87 0x7F88 0x7F89 0x7F8B 0x7F8D 0x7F8F 0x7F90 \ + 0x7F91 0x7F92 0x7F93 0x7F95 0x7F96 0x7F97 0x7F98 0x7F99 \ + 0x7F9B 0x7F9C 0x7FA0 0x7FA2 0x7FA3 0x7FA5 0x7FA6 0x7FA8 \ + 0x7FA9 0x7FAA 0x7FAB 0x7FAC 0x7FAD 0x7FAE 0x7FB1 0x7FB3 \ + 0x7FB4 0x7FB5 0x7FB6 0x7FB7 0x7FBA 0x7FBB 0x7FBE 0x7FC0 \ + 0x7FC2 0x7FC3 0x7FC4 0x7FC6 0x7FC7 0x7FC8 0x7FC9 0x7FCB \ + 0x7FCD 0x7FCF 0x7FD0 0x7FD1 0x7FD2 0x7FD3 0x7FD6 0x7FD7 \ + 0x7FD9 0x7FDA 0x7FDB 0x7FDC 0x7FDD 0x7FDE 0x7FE2 0x7FE3 \ + 0x75E2 0x7ACB 0x7C92 0x6CA5 0x96B6 0x529B 0x7483 0x54E9 \ + 0x4FE9 0x8054 0x83B2 0x8FDE 0x9570 0x5EC9 0x601C 0x6D9F \ + 0x5E18 0x655B 0x8138 0x94FE 0x604B 0x70BC 0x7EC3 0x7CAE \ + 0x51C9 0x6881 0x7CB1 0x826F 0x4E24 0x8F86 0x91CF 0x667E +49 0x4EAE 0x8C05 0x64A9 0x804A 0x50DA 0x7597 0x71CE 0x5BE5 \ + 0x8FBD 0x6F66 0x4E86 0x6482 0x9563 0x5ED6 0x6599 0x5217 \ + 0x88C2 0x70C8 0x52A3 0x730E 0x7433 0x6797 0x78F7 0x9716 \ + 0x4E34 0x90BB 0x9CDE 0x6DCB 0x51DB 0x8D41 0x541D 0x62CE \ + 0x73B2 0x83F1 0x96F6 0x9F84 0x94C3 0x4F36 0x7F9A 0x51CC \ + 0x7075 0x9675 0x5CAD 0x9886 0x53E6 0x4EE4 0x6E9C 0x7409 \ + 0x69B4 0x786B 0x998F 0x7559 0x5218 0x7624 0x6D41 0x67F3 \ + 0x516D 0x9F99 0x804B 0x5499 0x7B3C 0x7ABF 0x7FE4 0x7FE7 \ + 0x7FE8 0x7FEA 0x7FEB 0x7FEC 0x7FED 0x7FEF 0x7FF2 0x7FF4 \ + 0x7FF5 0x7FF6 0x7FF7 0x7FF8 0x7FF9 0x7FFA 0x7FFD 0x7FFE \ + 0x7FFF 0x8002 0x8007 0x8008 0x8009 0x800A 0x800E 0x800F \ + 0x8011 0x8013 0x801A 0x801B 0x801D 0x801E 0x801F 0x8021 \ + 0x8023 0x8024 0x802B 0x802C 0x802D 0x802E 0x802F 0x8030 \ + 0x8032 0x8034 0x8039 0x803A 0x803C 0x803E 0x8040 0x8041 \ + 0x8044 0x8045 0x8047 0x8048 0x8049 0x804E 0x804F 0x8050 \ + 0x8051 0x8053 0x8055 0x8056 0x8057 0x8059 0x805B 0x805C \ + 0x805D 0x805E 0x805F 0x8060 0x8061 0x8062 0x8063 0x8064 \ + 0x8065 0x8066 0x8067 0x8068 0x806B 0x806C 0x806D 0x806E \ + 0x806F 0x8070 0x8072 0x8073 0x8074 0x8075 0x8076 0x8077 \ + 0x8078 0x8079 0x807A 0x807B 0x807C 0x807D 0x9686 0x5784 \ + 0x62E2 0x9647 0x697C 0x5A04 0x6402 0x7BD3 0x6F0F 0x964B \ + 0x82A6 0x5362 0x9885 0x5E90 0x7089 0x63B3 0x5364 0x864F \ + 0x9C81 0x9E93 0x788C 0x9732 0x8DEF 0x8D42 0x9E7F 0x6F5E \ + 0x7984 0x5F55 0x9646 0x622E 0x9A74 0x5415 0x94DD 0x4FA3 \ + 0x65C5 0x5C65 0x5C61 0x7F15 0x8651 0x6C2F 0x5F8B 0x7387 \ + 0x6EE4 0x7EFF 0x5CE6 0x631B 0x5B6A 0x6EE6 0x5375 0x4E71 \ + 0x63A0 0x7565 0x62A1 0x8F6E 0x4F26 0x4ED1 0x6CA6 0x7EB6 \ + 0x8BBA 0x841D 0x87BA 0x7F57 0x903B 0x9523 0x7BA9 0x9AA1 \ + 0x88F8 0x843D 0x6D1B 0x9A86 0x7EDC 0x5988 0x9EBB 0x739B \ + 0x7801 0x8682 0x9A6C 0x9A82 0x561B 0x5417 0x57CB 0x4E70 \ + 0x9EA6 0x5356 0x8FC8 0x8109 0x7792 0x9992 0x86EE 0x6EE1 \ + 0x8513 0x66FC 0x6162 0x6F2B 0x807E 0x8081 0x8082 0x8085 +50 0x8088 0x808A 0x808D 0x808E 0x808F 0x8090 0x8091 0x8092 \ + 0x8094 0x8095 0x8097 0x8099 0x809E 0x80A3 0x80A6 0x80A7 \ + 0x80A8 0x80AC 0x80B0 0x80B3 0x80B5 0x80B6 0x80B8 0x80B9 \ + 0x80BB 0x80C5 0x80C7 0x80C8 0x80C9 0x80CA 0x80CB 0x80CF \ + 0x80D0 0x80D1 0x80D2 0x80D3 0x80D4 0x80D5 0x80D8 0x80DF \ + 0x80E0 0x80E2 0x80E3 0x80E6 0x80EE 0x80F5 0x80F7 0x80F9 \ + 0x80FB 0x80FE 0x80FF 0x8100 0x8101 0x8103 0x8104 0x8105 \ + 0x8107 0x8108 0x810B 0x810C 0x8115 0x8117 0x8119 0x811B \ + 0x811C 0x811D 0x811F 0x8120 0x8121 0x8122 0x8123 0x8124 \ + 0x8125 0x8126 0x8127 0x8128 0x8129 0x812A 0x812B 0x812D \ + 0x812E 0x8130 0x8133 0x8134 0x8135 0x8137 0x8139 0x813A \ + 0x813B 0x813C 0x813D 0x813F 0x8C29 0x8292 0x832B 0x76F2 \ + 0x6C13 0x5FD9 0x83BD 0x732B 0x8305 0x951A 0x6BDB 0x77DB \ + 0x94C6 0x536F 0x8302 0x5192 0x5E3D 0x8C8C 0x8D38 0x4E48 \ + 0x73AB 0x679A 0x6885 0x9176 0x9709 0x7164 0x6CA1 0x7709 \ + 0x5A92 0x9541 0x6BCF 0x7F8E 0x6627 0x5BD0 0x59B9 0x5A9A \ + 0x95E8 0x95F7 0x4EEC 0x840C 0x8499 0x6AAC 0x76DF 0x9530 \ + 0x731B 0x68A6 0x5B5F 0x772F 0x919A 0x9761 0x7CDC 0x8FF7 \ + 0x8C1C 0x5F25 0x7C73 0x79D8 0x89C5 0x6CCC 0x871C 0x5BC6 \ + 0x5E42 0x68C9 0x7720 0x7EF5 0x5195 0x514D 0x52C9 0x5A29 \ + 0x7F05 0x9762 0x82D7 0x63CF 0x7784 0x85D0 0x79D2 0x6E3A \ + 0x5E99 0x5999 0x8511 0x706D 0x6C11 0x62BF 0x76BF 0x654F \ + 0x60AF 0x95FD 0x660E 0x879F 0x9E23 0x94ED 0x540D 0x547D \ + 0x8C2C 0x6478 0x8140 0x8141 0x8142 0x8143 0x8144 0x8145 \ + 0x8147 0x8149 0x814D 0x814E 0x814F 0x8152 0x8156 0x8157 \ + 0x8158 0x815B 0x815C 0x815D 0x815E 0x815F 0x8161 0x8162 \ + 0x8163 0x8164 0x8166 0x8168 0x816A 0x816B 0x816C 0x816F \ + 0x8172 0x8173 0x8175 0x8176 0x8177 0x8178 0x8181 0x8183 \ + 0x8184 0x8185 0x8186 0x8187 0x8189 0x818B 0x818C 0x818D \ + 0x818E 0x8190 0x8192 0x8193 0x8194 0x8195 0x8196 0x8197 \ + 0x8199 0x819A 0x819E 0x819F 0x81A0 0x81A1 0x81A2 0x81A4 \ + 0x81A5 0x81A7 0x81A9 0x81AB 0x81AC 0x81AD 0x81AE 0x81AF +51 0x81B0 0x81B1 0x81B2 0x81B4 0x81B5 0x81B6 0x81B7 0x81B8 \ + 0x81B9 0x81BC 0x81BD 0x81BE 0x81BF 0x81C4 0x81C5 0x81C7 \ + 0x81C8 0x81C9 0x81CB 0x81CD 0x81CE 0x81CF 0x81D0 0x81D1 \ + 0x81D2 0x81D3 0x6479 0x8611 0x6A21 0x819C 0x78E8 0x6469 \ + 0x9B54 0x62B9 0x672B 0x83AB 0x58A8 0x9ED8 0x6CAB 0x6F20 \ + 0x5BDE 0x964C 0x8C0B 0x725F 0x67D0 0x62C7 0x7261 0x4EA9 \ + 0x59C6 0x6BCD 0x5893 0x66AE 0x5E55 0x52DF 0x6155 0x6728 \ + 0x76EE 0x7766 0x7267 0x7A46 0x62FF 0x54EA 0x5450 0x94A0 \ + 0x90A3 0x5A1C 0x7EB3 0x6C16 0x4E43 0x5976 0x8010 0x5948 \ + 0x5357 0x7537 0x96BE 0x56CA 0x6320 0x8111 0x607C 0x95F9 \ + 0x6DD6 0x5462 0x9981 0x5185 0x5AE9 0x80FD 0x59AE 0x9713 \ + 0x502A 0x6CE5 0x5C3C 0x62DF 0x4F60 0x533F 0x817B 0x9006 \ + 0x6EBA 0x852B 0x62C8 0x5E74 0x78BE 0x64B5 0x637B 0x5FF5 \ + 0x5A18 0x917F 0x9E1F 0x5C3F 0x634F 0x8042 0x5B7D 0x556E \ + 0x954A 0x954D 0x6D85 0x60A8 0x67E0 0x72DE 0x51DD 0x5B81 \ + 0x81D4 0x81D5 0x81D6 0x81D7 0x81D8 0x81D9 0x81DA 0x81DB \ + 0x81DC 0x81DD 0x81DE 0x81DF 0x81E0 0x81E1 0x81E2 0x81E4 \ + 0x81E5 0x81E6 0x81E8 0x81E9 0x81EB 0x81EE 0x81EF 0x81F0 \ + 0x81F1 0x81F2 0x81F5 0x81F6 0x81F7 0x81F8 0x81F9 0x81FA \ + 0x81FD 0x81FF 0x8203 0x8207 0x8208 0x8209 0x820A 0x820B \ + 0x820E 0x820F 0x8211 0x8213 0x8215 0x8216 0x8217 0x8218 \ + 0x8219 0x821A 0x821D 0x8220 0x8224 0x8225 0x8226 0x8227 \ + 0x8229 0x822E 0x8232 0x823A 0x823C 0x823D 0x823F 0x8240 \ + 0x8241 0x8242 0x8243 0x8245 0x8246 0x8248 0x824A 0x824C \ + 0x824D 0x824E 0x8250 0x8251 0x8252 0x8253 0x8254 0x8255 \ + 0x8256 0x8257 0x8259 0x825B 0x825C 0x825D 0x825E 0x8260 \ + 0x8261 0x8262 0x8263 0x8264 0x8265 0x8266 0x8267 0x8269 \ + 0x62E7 0x6CDE 0x725B 0x626D 0x94AE 0x7EBD 0x8113 0x6D53 \ + 0x519C 0x5F04 0x5974 0x52AA 0x6012 0x5973 0x6696 0x8650 \ + 0x759F 0x632A 0x61E6 0x7CEF 0x8BFA 0x54E6 0x6B27 0x9E25 \ + 0x6BB4 0x85D5 0x5455 0x5076 0x6CA4 0x556A 0x8DB4 0x722C \ + 0x5E15 0x6015 0x7436 0x62CD 0x6392 0x724C 0x5F98 0x6E43 +52 0x6D3E 0x6500 0x6F58 0x76D8 0x78D0 0x76FC 0x7554 0x5224 \ + 0x53DB 0x4E53 0x5E9E 0x65C1 0x802A 0x80D6 0x629B 0x5486 \ + 0x5228 0x70AE 0x888D 0x8DD1 0x6CE1 0x5478 0x80DA 0x57F9 \ + 0x88F4 0x8D54 0x966A 0x914D 0x4F69 0x6C9B 0x55B7 0x76C6 \ + 0x7830 0x62A8 0x70F9 0x6F8E 0x5F6D 0x84EC 0x68DA 0x787C \ + 0x7BF7 0x81A8 0x670B 0x9E4F 0x6367 0x78B0 0x576F 0x7812 \ + 0x9739 0x6279 0x62AB 0x5288 0x7435 0x6BD7 0x826A 0x826B \ + 0x826C 0x826D 0x8271 0x8275 0x8276 0x8277 0x8278 0x827B \ + 0x827C 0x8280 0x8281 0x8283 0x8285 0x8286 0x8287 0x8289 \ + 0x828C 0x8290 0x8293 0x8294 0x8295 0x8296 0x829A 0x829B \ + 0x829E 0x82A0 0x82A2 0x82A3 0x82A7 0x82B2 0x82B5 0x82B6 \ + 0x82BA 0x82BB 0x82BC 0x82BF 0x82C0 0x82C2 0x82C3 0x82C5 \ + 0x82C6 0x82C9 0x82D0 0x82D6 0x82D9 0x82DA 0x82DD 0x82E2 \ + 0x82E7 0x82E8 0x82E9 0x82EA 0x82EC 0x82ED 0x82EE 0x82F0 \ + 0x82F2 0x82F3 0x82F5 0x82F6 0x82F8 0x82FA 0x82FC 0x82FD \ + 0x82FE 0x82FF 0x8300 0x830A 0x830B 0x830D 0x8310 0x8312 \ + 0x8313 0x8316 0x8318 0x8319 0x831D 0x831E 0x831F 0x8320 \ + 0x8321 0x8322 0x8323 0x8324 0x8325 0x8326 0x8329 0x832A \ + 0x832E 0x8330 0x8332 0x8337 0x833B 0x833D 0x5564 0x813E \ + 0x75B2 0x76AE 0x5339 0x75DE 0x50FB 0x5C41 0x8B6C 0x7BC7 \ + 0x504F 0x7247 0x9A97 0x98D8 0x6F02 0x74E2 0x7968 0x6487 \ + 0x77A5 0x62FC 0x9891 0x8D2B 0x54C1 0x8058 0x4E52 0x576A \ + 0x82F9 0x840D 0x5E73 0x51ED 0x74F6 0x8BC4 0x5C4F 0x5761 \ + 0x6CFC 0x9887 0x5A46 0x7834 0x9B44 0x8FEB 0x7C95 0x5256 \ + 0x6251 0x94FA 0x4EC6 0x8386 0x8461 0x83E9 0x84B2 0x57D4 \ + 0x6734 0x5703 0x666E 0x6D66 0x8C31 0x66DD 0x7011 0x671F \ + 0x6B3A 0x6816 0x621A 0x59BB 0x4E03 0x51C4 0x6F06 0x67D2 \ + 0x6C8F 0x5176 0x68CB 0x5947 0x6B67 0x7566 0x5D0E 0x8110 \ + 0x9F50 0x65D7 0x7948 0x7941 0x9A91 0x8D77 0x5C82 0x4E5E \ + 0x4F01 0x542F 0x5951 0x780C 0x5668 0x6C14 0x8FC4 0x5F03 \ + 0x6C7D 0x6CE3 0x8BAB 0x6390 0x833E 0x833F 0x8341 0x8342 \ + 0x8344 0x8345 0x8348 0x834A 0x834B 0x834C 0x834D 0x834E +53 0x8353 0x8355 0x8356 0x8357 0x8358 0x8359 0x835D 0x8362 \ + 0x8370 0x8371 0x8372 0x8373 0x8374 0x8375 0x8376 0x8379 \ + 0x837A 0x837E 0x837F 0x8380 0x8381 0x8382 0x8383 0x8384 \ + 0x8387 0x8388 0x838A 0x838B 0x838C 0x838D 0x838F 0x8390 \ + 0x8391 0x8394 0x8395 0x8396 0x8397 0x8399 0x839A 0x839D \ + 0x839F 0x83A1 0x83A2 0x83A3 0x83A4 0x83A5 0x83A6 0x83A7 \ + 0x83AC 0x83AD 0x83AE 0x83AF 0x83B5 0x83BB 0x83BE 0x83BF \ + 0x83C2 0x83C3 0x83C4 0x83C6 0x83C8 0x83C9 0x83CB 0x83CD \ + 0x83CE 0x83D0 0x83D1 0x83D2 0x83D3 0x83D5 0x83D7 0x83D9 \ + 0x83DA 0x83DB 0x83DE 0x83E2 0x83E3 0x83E4 0x83E6 0x83E7 \ + 0x83E8 0x83EB 0x83EC 0x83ED 0x6070 0x6D3D 0x7275 0x6266 \ + 0x948E 0x94C5 0x5343 0x8FC1 0x7B7E 0x4EDF 0x8C26 0x4E7E \ + 0x9ED4 0x94B1 0x94B3 0x524D 0x6F5C 0x9063 0x6D45 0x8C34 \ + 0x5811 0x5D4C 0x6B20 0x6B49 0x67AA 0x545B 0x8154 0x7F8C \ + 0x5899 0x8537 0x5F3A 0x62A2 0x6A47 0x9539 0x6572 0x6084 \ + 0x6865 0x77A7 0x4E54 0x4FA8 0x5DE7 0x9798 0x64AC 0x7FD8 \ + 0x5CED 0x4FCF 0x7A8D 0x5207 0x8304 0x4E14 0x602F 0x7A83 \ + 0x94A6 0x4FB5 0x4EB2 0x79E6 0x7434 0x52E4 0x82B9 0x64D2 \ + 0x79BD 0x5BDD 0x6C81 0x9752 0x8F7B 0x6C22 0x503E 0x537F \ + 0x6E05 0x64CE 0x6674 0x6C30 0x60C5 0x9877 0x8BF7 0x5E86 \ + 0x743C 0x7A77 0x79CB 0x4E18 0x90B1 0x7403 0x6C42 0x56DA \ + 0x914B 0x6CC5 0x8D8B 0x533A 0x86C6 0x66F2 0x8EAF 0x5C48 \ + 0x9A71 0x6E20 0x83EE 0x83EF 0x83F3 0x83F4 0x83F5 0x83F6 \ + 0x83F7 0x83FA 0x83FB 0x83FC 0x83FE 0x83FF 0x8400 0x8402 \ + 0x8405 0x8407 0x8408 0x8409 0x840A 0x8410 0x8412 0x8413 \ + 0x8414 0x8415 0x8416 0x8417 0x8419 0x841A 0x841B 0x841E \ + 0x841F 0x8420 0x8421 0x8422 0x8423 0x8429 0x842A 0x842B \ + 0x842C 0x842D 0x842E 0x842F 0x8430 0x8432 0x8433 0x8434 \ + 0x8435 0x8436 0x8437 0x8439 0x843A 0x843B 0x843E 0x843F \ + 0x8440 0x8441 0x8442 0x8443 0x8444 0x8445 0x8447 0x8448 \ + 0x8449 0x844A 0x844B 0x844C 0x844D 0x844E 0x844F 0x8450 \ + 0x8452 0x8453 0x8454 0x8455 0x8456 0x8458 0x845D 0x845E +54 0x845F 0x8460 0x8462 0x8464 0x8465 0x8466 0x8467 0x8468 \ + 0x846A 0x846E 0x846F 0x8470 0x8472 0x8474 0x8477 0x8479 \ + 0x847B 0x847C 0x53D6 0x5A36 0x9F8B 0x8DA3 0x53BB 0x5708 \ + 0x98A7 0x6743 0x919B 0x6CC9 0x5168 0x75CA 0x62F3 0x72AC \ + 0x5238 0x529D 0x7F3A 0x7094 0x7638 0x5374 0x9E4A 0x69B7 \ + 0x786E 0x96C0 0x88D9 0x7FA4 0x7136 0x71C3 0x5189 0x67D3 \ + 0x74E4 0x58E4 0x6518 0x56B7 0x8BA9 0x9976 0x6270 0x7ED5 \ + 0x60F9 0x70ED 0x58EC 0x4EC1 0x4EBA 0x5FCD 0x97E7 0x4EFB \ + 0x8BA4 0x5203 0x598A 0x7EAB 0x6254 0x4ECD 0x65E5 0x620E \ + 0x8338 0x84C9 0x8363 0x878D 0x7194 0x6EB6 0x5BB9 0x7ED2 \ + 0x5197 0x63C9 0x67D4 0x8089 0x8339 0x8815 0x5112 0x5B7A \ + 0x5982 0x8FB1 0x4E73 0x6C5D 0x5165 0x8925 0x8F6F 0x962E \ + 0x854A 0x745E 0x9510 0x95F0 0x6DA6 0x82E5 0x5F31 0x6492 \ + 0x6D12 0x8428 0x816E 0x9CC3 0x585E 0x8D5B 0x4E09 0x53C1 \ + 0x847D 0x847E 0x847F 0x8480 0x8481 0x8483 0x8484 0x8485 \ + 0x8486 0x848A 0x848D 0x848F 0x8490 0x8491 0x8492 0x8493 \ + 0x8494 0x8495 0x8496 0x8498 0x849A 0x849B 0x849D 0x849E \ + 0x849F 0x84A0 0x84A2 0x84A3 0x84A4 0x84A5 0x84A6 0x84A7 \ + 0x84A8 0x84A9 0x84AA 0x84AB 0x84AC 0x84AD 0x84AE 0x84B0 \ + 0x84B1 0x84B3 0x84B5 0x84B6 0x84B7 0x84BB 0x84BC 0x84BE \ + 0x84C0 0x84C2 0x84C3 0x84C5 0x84C6 0x84C7 0x84C8 0x84CB \ + 0x84CC 0x84CE 0x84CF 0x84D2 0x84D4 0x84D5 0x84D7 0x84D8 \ + 0x84D9 0x84DA 0x84DB 0x84DC 0x84DE 0x84E1 0x84E2 0x84E4 \ + 0x84E7 0x84E8 0x84E9 0x84EA 0x84EB 0x84ED 0x84EE 0x84EF \ + 0x84F1 0x84F2 0x84F3 0x84F4 0x84F5 0x84F6 0x84F7 0x84F8 \ + 0x84F9 0x84FA 0x84FB 0x84FD 0x84FE 0x8500 0x8501 0x8502 \ + 0x4F1E 0x6563 0x6851 0x55D3 0x4E27 0x6414 0x9A9A 0x626B \ + 0x5AC2 0x745F 0x8272 0x6DA9 0x68EE 0x50E7 0x838E 0x7802 \ + 0x6740 0x5239 0x6C99 0x7EB1 0x50BB 0x5565 0x715E 0x7B5B \ + 0x6652 0x73CA 0x82EB 0x6749 0x5C71 0x5220 0x717D 0x886B \ + 0x95EA 0x9655 0x64C5 0x8D61 0x81B3 0x5584 0x6C55 0x6247 \ + 0x7F2E 0x5892 0x4F24 0x5546 0x8D4F 0x664C 0x4E0A 0x5C1A +55 0x88F3 0x68A2 0x634E 0x7A0D 0x70E7 0x828D 0x52FA 0x97F6 \ + 0x5C11 0x54E8 0x90B5 0x7ECD 0x5962 0x8D4A 0x86C7 0x820C \ + 0x820D 0x8D66 0x6444 0x5C04 0x6151 0x6D89 0x793E 0x8BBE \ + 0x7837 0x7533 0x547B 0x4F38 0x8EAB 0x6DF1 0x5A20 0x7EC5 \ + 0x795E 0x6C88 0x5BA1 0x5A76 0x751A 0x80BE 0x614E 0x6E17 \ + 0x58F0 0x751F 0x7525 0x7272 0x5347 0x7EF3 0x8503 0x8504 \ + 0x8505 0x8506 0x8507 0x8508 0x8509 0x850A 0x850B 0x850D \ + 0x850E 0x850F 0x8510 0x8512 0x8514 0x8515 0x8516 0x8518 \ + 0x8519 0x851B 0x851C 0x851D 0x851E 0x8520 0x8522 0x8523 \ + 0x8524 0x8525 0x8526 0x8527 0x8528 0x8529 0x852A 0x852D \ + 0x852E 0x852F 0x8530 0x8531 0x8532 0x8533 0x8534 0x8535 \ + 0x8536 0x853E 0x853F 0x8540 0x8541 0x8542 0x8544 0x8545 \ + 0x8546 0x8547 0x854B 0x854C 0x854D 0x854E 0x854F 0x8550 \ + 0x8551 0x8552 0x8553 0x8554 0x8555 0x8557 0x8558 0x855A \ + 0x855B 0x855C 0x855D 0x855F 0x8560 0x8561 0x8562 0x8563 \ + 0x8565 0x8566 0x8567 0x8569 0x856A 0x856B 0x856C 0x856D \ + 0x856E 0x856F 0x8570 0x8571 0x8573 0x8575 0x8576 0x8577 \ + 0x8578 0x857C 0x857D 0x857F 0x8580 0x8581 0x7701 0x76DB \ + 0x5269 0x80DC 0x5723 0x5E08 0x5931 0x72EE 0x65BD 0x6E7F \ + 0x8BD7 0x5C38 0x8671 0x5341 0x77F3 0x62FE 0x65F6 0x4EC0 \ + 0x98DF 0x8680 0x5B9E 0x8BC6 0x53F2 0x77E2 0x4F7F 0x5C4E \ + 0x9A76 0x59CB 0x5F0F 0x793A 0x58EB 0x4E16 0x67FF 0x4E8B \ + 0x62ED 0x8A93 0x901D 0x52BF 0x662F 0x55DC 0x566C 0x9002 \ + 0x4ED5 0x4F8D 0x91CA 0x9970 0x6C0F 0x5E02 0x6043 0x5BA4 \ + 0x89C6 0x8BD5 0x6536 0x624B 0x9996 0x5B88 0x5BFF 0x6388 \ + 0x552E 0x53D7 0x7626 0x517D 0x852C 0x67A2 0x68B3 0x6B8A \ + 0x6292 0x8F93 0x53D4 0x8212 0x6DD1 0x758F 0x4E66 0x8D4E \ + 0x5B70 0x719F 0x85AF 0x6691 0x66D9 0x7F72 0x8700 0x9ECD \ + 0x9F20 0x5C5E 0x672F 0x8FF0 0x6811 0x675F 0x620D 0x7AD6 \ + 0x5885 0x5EB6 0x6570 0x6F31 0x8582 0x8583 0x8586 0x8588 \ + 0x8589 0x858A 0x858B 0x858C 0x858D 0x858E 0x8590 0x8591 \ + 0x8592 0x8593 0x8594 0x8595 0x8596 0x8597 0x8598 0x8599 +56 0x859A 0x859D 0x859E 0x859F 0x85A0 0x85A1 0x85A2 0x85A3 \ + 0x85A5 0x85A6 0x85A7 0x85A9 0x85AB 0x85AC 0x85AD 0x85B1 \ + 0x85B2 0x85B3 0x85B4 0x85B5 0x85B6 0x85B8 0x85BA 0x85BB \ + 0x85BC 0x85BD 0x85BE 0x85BF 0x85C0 0x85C2 0x85C3 0x85C4 \ + 0x85C5 0x85C6 0x85C7 0x85C8 0x85CA 0x85CB 0x85CC 0x85CD \ + 0x85CE 0x85D1 0x85D2 0x85D4 0x85D6 0x85D7 0x85D8 0x85D9 \ + 0x85DA 0x85DB 0x85DD 0x85DE 0x85DF 0x85E0 0x85E1 0x85E2 \ + 0x85E3 0x85E5 0x85E6 0x85E7 0x85E8 0x85EA 0x85EB 0x85EC \ + 0x85ED 0x85EE 0x85EF 0x85F0 0x85F1 0x85F2 0x85F3 0x85F4 \ + 0x85F5 0x85F6 0x85F7 0x85F8 0x6055 0x5237 0x800D 0x6454 \ + 0x8870 0x7529 0x5E05 0x6813 0x62F4 0x971C 0x53CC 0x723D \ + 0x8C01 0x6C34 0x7761 0x7A0E 0x542E 0x77AC 0x987A 0x821C \ + 0x8BF4 0x7855 0x6714 0x70C1 0x65AF 0x6495 0x5636 0x601D \ + 0x79C1 0x53F8 0x4E1D 0x6B7B 0x8086 0x5BFA 0x55E3 0x56DB \ + 0x4F3A 0x4F3C 0x9972 0x5DF3 0x677E 0x8038 0x6002 0x9882 \ + 0x9001 0x5B8B 0x8BBC 0x8BF5 0x641C 0x8258 0x64DE 0x55FD \ + 0x82CF 0x9165 0x4FD7 0x7D20 0x901F 0x7C9F 0x50F3 0x5851 \ + 0x6EAF 0x5BBF 0x8BC9 0x8083 0x9178 0x849C 0x7B97 0x867D \ + 0x968B 0x968F 0x7EE5 0x9AD3 0x788E 0x5C81 0x7A57 0x9042 \ + 0x96A7 0x795F 0x5B59 0x635F 0x7B0B 0x84D1 0x68AD 0x5506 \ + 0x7F29 0x7410 0x7D22 0x9501 0x6240 0x584C 0x4ED6 0x5B83 \ + 0x5979 0x5854 0x85F9 0x85FA 0x85FC 0x85FD 0x85FE 0x8600 \ + 0x8601 0x8602 0x8603 0x8604 0x8606 0x8607 0x8608 0x8609 \ + 0x860A 0x860B 0x860C 0x860D 0x860E 0x860F 0x8610 0x8612 \ + 0x8613 0x8614 0x8615 0x8617 0x8618 0x8619 0x861A 0x861B \ + 0x861C 0x861D 0x861E 0x861F 0x8620 0x8621 0x8622 0x8623 \ + 0x8624 0x8625 0x8626 0x8628 0x862A 0x862B 0x862C 0x862D \ + 0x862E 0x862F 0x8630 0x8631 0x8632 0x8633 0x8634 0x8635 \ + 0x8636 0x8637 0x8639 0x863A 0x863B 0x863D 0x863E 0x863F \ + 0x8640 0x8641 0x8642 0x8643 0x8644 0x8645 0x8646 0x8647 \ + 0x8648 0x8649 0x864A 0x864B 0x864C 0x8652 0x8653 0x8655 \ + 0x8656 0x8657 0x8658 0x8659 0x865B 0x865C 0x865D 0x865F +57 0x8660 0x8661 0x8663 0x8664 0x8665 0x8666 0x8667 0x8668 \ + 0x8669 0x866A 0x736D 0x631E 0x8E4B 0x8E0F 0x80CE 0x82D4 \ + 0x62AC 0x53F0 0x6CF0 0x915E 0x592A 0x6001 0x6C70 0x574D \ + 0x644A 0x8D2A 0x762B 0x6EE9 0x575B 0x6A80 0x75F0 0x6F6D \ + 0x8C2D 0x8C08 0x5766 0x6BEF 0x8892 0x78B3 0x63A2 0x53F9 \ + 0x70AD 0x6C64 0x5858 0x642A 0x5802 0x68E0 0x819B 0x5510 \ + 0x7CD6 0x5018 0x8EBA 0x6DCC 0x8D9F 0x70EB 0x638F 0x6D9B \ + 0x6ED4 0x7EE6 0x8404 0x6843 0x9003 0x6DD8 0x9676 0x8BA8 \ + 0x5957 0x7279 0x85E4 0x817E 0x75BC 0x8A8A 0x68AF 0x5254 \ + 0x8E22 0x9511 0x63D0 0x9898 0x8E44 0x557C 0x4F53 0x66FF \ + 0x568F 0x60D5 0x6D95 0x5243 0x5C49 0x5929 0x6DFB 0x586B \ + 0x7530 0x751C 0x606C 0x8214 0x8146 0x6311 0x6761 0x8FE2 \ + 0x773A 0x8DF3 0x8D34 0x94C1 0x5E16 0x5385 0x542C 0x70C3 \ + 0x866D 0x866F 0x8670 0x8672 0x8673 0x8674 0x8675 0x8676 \ + 0x8677 0x8678 0x8683 0x8684 0x8685 0x8686 0x8687 0x8688 \ + 0x8689 0x868E 0x868F 0x8690 0x8691 0x8692 0x8694 0x8696 \ + 0x8697 0x8698 0x8699 0x869A 0x869B 0x869E 0x869F 0x86A0 \ + 0x86A1 0x86A2 0x86A5 0x86A6 0x86AB 0x86AD 0x86AE 0x86B2 \ + 0x86B3 0x86B7 0x86B8 0x86B9 0x86BB 0x86BC 0x86BD 0x86BE \ + 0x86BF 0x86C1 0x86C2 0x86C3 0x86C5 0x86C8 0x86CC 0x86CD \ + 0x86D2 0x86D3 0x86D5 0x86D6 0x86D7 0x86DA 0x86DC 0x86DD \ + 0x86E0 0x86E1 0x86E2 0x86E3 0x86E5 0x86E6 0x86E7 0x86E8 \ + 0x86EA 0x86EB 0x86EC 0x86EF 0x86F5 0x86F6 0x86F7 0x86FA \ + 0x86FB 0x86FC 0x86FD 0x86FF 0x8701 0x8704 0x8705 0x8706 \ + 0x870B 0x870C 0x870E 0x870F 0x8710 0x8711 0x8714 0x8716 \ + 0x6C40 0x5EF7 0x505C 0x4EAD 0x5EAD 0x633A 0x8247 0x901A \ + 0x6850 0x916E 0x77B3 0x540C 0x94DC 0x5F64 0x7AE5 0x6876 \ + 0x6345 0x7B52 0x7EDF 0x75DB 0x5077 0x6295 0x5934 0x900F \ + 0x51F8 0x79C3 0x7A81 0x56FE 0x5F92 0x9014 0x6D82 0x5C60 \ + 0x571F 0x5410 0x5154 0x6E4D 0x56E2 0x63A8 0x9893 0x817F \ + 0x8715 0x892A 0x9000 0x541E 0x5C6F 0x81C0 0x62D6 0x6258 \ + 0x8131 0x9E35 0x9640 0x9A6E 0x9A7C 0x692D 0x59A5 0x62D3 +58 0x553E 0x6316 0x54C7 0x86D9 0x6D3C 0x5A03 0x74E6 0x889C \ + 0x6B6A 0x5916 0x8C4C 0x5F2F 0x6E7E 0x73A9 0x987D 0x4E38 \ + 0x70F7 0x5B8C 0x7897 0x633D 0x665A 0x7696 0x60CB 0x5B9B \ + 0x5A49 0x4E07 0x8155 0x6C6A 0x738B 0x4EA1 0x6789 0x7F51 \ + 0x5F80 0x65FA 0x671B 0x5FD8 0x5984 0x5A01 0x8719 0x871B \ + 0x871D 0x871F 0x8720 0x8724 0x8726 0x8727 0x8728 0x872A \ + 0x872B 0x872C 0x872D 0x872F 0x8730 0x8732 0x8733 0x8735 \ + 0x8736 0x8738 0x8739 0x873A 0x873C 0x873D 0x8740 0x8741 \ + 0x8742 0x8743 0x8744 0x8745 0x8746 0x874A 0x874B 0x874D \ + 0x874F 0x8750 0x8751 0x8752 0x8754 0x8755 0x8756 0x8758 \ + 0x875A 0x875B 0x875C 0x875D 0x875E 0x875F 0x8761 0x8762 \ + 0x8766 0x8767 0x8768 0x8769 0x876A 0x876B 0x876C 0x876D \ + 0x876F 0x8771 0x8772 0x8773 0x8775 0x8777 0x8778 0x8779 \ + 0x877A 0x877F 0x8780 0x8781 0x8784 0x8786 0x8787 0x8789 \ + 0x878A 0x878C 0x878E 0x878F 0x8790 0x8791 0x8792 0x8794 \ + 0x8795 0x8796 0x8798 0x8799 0x879A 0x879B 0x879C 0x879D \ + 0x879E 0x87A0 0x87A1 0x87A2 0x87A3 0x87A4 0x5DCD 0x5FAE \ + 0x5371 0x97E6 0x8FDD 0x6845 0x56F4 0x552F 0x60DF 0x4E3A \ + 0x6F4D 0x7EF4 0x82C7 0x840E 0x59D4 0x4F1F 0x4F2A 0x5C3E \ + 0x7EAC 0x672A 0x851A 0x5473 0x754F 0x80C3 0x5582 0x9B4F \ + 0x4F4D 0x6E2D 0x8C13 0x5C09 0x6170 0x536B 0x761F 0x6E29 \ + 0x868A 0x6587 0x95FB 0x7EB9 0x543B 0x7A33 0x7D0A 0x95EE \ + 0x55E1 0x7FC1 0x74EE 0x631D 0x8717 0x6DA1 0x7A9D 0x6211 \ + 0x65A1 0x5367 0x63E1 0x6C83 0x5DEB 0x545C 0x94A8 0x4E4C \ + 0x6C61 0x8BEC 0x5C4B 0x65E0 0x829C 0x68A7 0x543E 0x5434 \ + 0x6BCB 0x6B66 0x4E94 0x6342 0x5348 0x821E 0x4F0D 0x4FAE \ + 0x575E 0x620A 0x96FE 0x6664 0x7269 0x52FF 0x52A1 0x609F \ + 0x8BEF 0x6614 0x7199 0x6790 0x897F 0x7852 0x77FD 0x6670 \ + 0x563B 0x5438 0x9521 0x727A 0x87A5 0x87A6 0x87A7 0x87A9 \ + 0x87AA 0x87AE 0x87B0 0x87B1 0x87B2 0x87B4 0x87B6 0x87B7 \ + 0x87B8 0x87B9 0x87BB 0x87BC 0x87BE 0x87BF 0x87C1 0x87C2 \ + 0x87C3 0x87C4 0x87C5 0x87C7 0x87C8 0x87C9 0x87CC 0x87CD +59 0x87CE 0x87CF 0x87D0 0x87D4 0x87D5 0x87D6 0x87D7 0x87D8 \ + 0x87D9 0x87DA 0x87DC 0x87DD 0x87DE 0x87DF 0x87E1 0x87E2 \ + 0x87E3 0x87E4 0x87E6 0x87E7 0x87E8 0x87E9 0x87EB 0x87EC \ + 0x87ED 0x87EF 0x87F0 0x87F1 0x87F2 0x87F3 0x87F4 0x87F5 \ + 0x87F6 0x87F7 0x87F8 0x87FA 0x87FB 0x87FC 0x87FD 0x87FF \ + 0x8800 0x8801 0x8802 0x8804 0x8805 0x8806 0x8807 0x8808 \ + 0x8809 0x880B 0x880C 0x880D 0x880E 0x880F 0x8810 0x8811 \ + 0x8812 0x8814 0x8817 0x8818 0x8819 0x881A 0x881C 0x881D \ + 0x881E 0x881F 0x8820 0x8823 0x7A00 0x606F 0x5E0C 0x6089 \ + 0x819D 0x5915 0x60DC 0x7184 0x70EF 0x6EAA 0x6C50 0x7280 \ + 0x6A84 0x88AD 0x5E2D 0x4E60 0x5AB3 0x559C 0x94E3 0x6D17 \ + 0x7CFB 0x9699 0x620F 0x7EC6 0x778E 0x867E 0x5323 0x971E \ + 0x8F96 0x6687 0x5CE1 0x4FA0 0x72ED 0x4E0B 0x53A6 0x590F \ + 0x5413 0x6380 0x9528 0x5148 0x4ED9 0x9C9C 0x7EA4 0x54B8 \ + 0x8D24 0x8854 0x8237 0x95F2 0x6D8E 0x5F26 0x5ACC 0x663E \ + 0x9669 0x73B0 0x732E 0x53BF 0x817A 0x9985 0x7FA1 0x5BAA \ + 0x9677 0x9650 0x7EBF 0x76F8 0x53A2 0x9576 0x9999 0x7BB1 \ + 0x8944 0x6E58 0x4E61 0x7FD4 0x7965 0x8BE6 0x60F3 0x54CD \ + 0x4EAB 0x9879 0x5DF7 0x6A61 0x50CF 0x5411 0x8C61 0x8427 \ + 0x785D 0x9704 0x524A 0x54EE 0x56A3 0x9500 0x6D88 0x5BB5 \ + 0x6DC6 0x6653 0x8824 0x8825 0x8826 0x8827 0x8828 0x8829 \ + 0x882A 0x882B 0x882C 0x882D 0x882E 0x882F 0x8830 0x8831 \ + 0x8833 0x8834 0x8835 0x8836 0x8837 0x8838 0x883A 0x883B \ + 0x883D 0x883E 0x883F 0x8841 0x8842 0x8843 0x8846 0x8847 \ + 0x8848 0x8849 0x884A 0x884B 0x884E 0x884F 0x8850 0x8851 \ + 0x8852 0x8853 0x8855 0x8856 0x8858 0x885A 0x885B 0x885C \ + 0x885D 0x885E 0x885F 0x8860 0x8866 0x8867 0x886A 0x886D \ + 0x886F 0x8871 0x8873 0x8874 0x8875 0x8876 0x8878 0x8879 \ + 0x887A 0x887B 0x887C 0x8880 0x8883 0x8886 0x8887 0x8889 \ + 0x888A 0x888C 0x888E 0x888F 0x8890 0x8891 0x8893 0x8894 \ + 0x8895 0x8897 0x8898 0x8899 0x889A 0x889B 0x889D 0x889E \ + 0x889F 0x88A0 0x88A1 0x88A3 0x88A5 0x88A6 0x88A7 0x88A8 +60 0x88A9 0x88AA 0x5C0F 0x5B5D 0x6821 0x8096 0x5578 0x7B11 \ + 0x6548 0x6954 0x4E9B 0x6B47 0x874E 0x978B 0x534F 0x631F \ + 0x643A 0x90AA 0x659C 0x80C1 0x8C10 0x5199 0x68B0 0x5378 \ + 0x87F9 0x61C8 0x6CC4 0x6CFB 0x8C22 0x5C51 0x85AA 0x82AF \ + 0x950C 0x6B23 0x8F9B 0x65B0 0x5FFB 0x5FC3 0x4FE1 0x8845 \ + 0x661F 0x8165 0x7329 0x60FA 0x5174 0x5211 0x578B 0x5F62 \ + 0x90A2 0x884C 0x9192 0x5E78 0x674F 0x6027 0x59D3 0x5144 \ + 0x51F6 0x80F8 0x5308 0x6C79 0x96C4 0x718A 0x4F11 0x4FEE \ + 0x7F9E 0x673D 0x55C5 0x9508 0x79C0 0x8896 0x7EE3 0x589F \ + 0x620C 0x9700 0x865A 0x5618 0x987B 0x5F90 0x8BB8 0x84C4 \ + 0x9157 0x53D9 0x65ED 0x5E8F 0x755C 0x6064 0x7D6E 0x5A7F \ + 0x7EEA 0x7EED 0x8F69 0x55A7 0x5BA3 0x60AC 0x65CB 0x7384 \ + 0x88AC 0x88AE 0x88AF 0x88B0 0x88B2 0x88B3 0x88B4 0x88B5 \ + 0x88B6 0x88B8 0x88B9 0x88BA 0x88BB 0x88BD 0x88BE 0x88BF \ + 0x88C0 0x88C3 0x88C4 0x88C7 0x88C8 0x88CA 0x88CB 0x88CC \ + 0x88CD 0x88CF 0x88D0 0x88D1 0x88D3 0x88D6 0x88D7 0x88DA \ + 0x88DB 0x88DC 0x88DD 0x88DE 0x88E0 0x88E1 0x88E6 0x88E7 \ + 0x88E9 0x88EA 0x88EB 0x88EC 0x88ED 0x88EE 0x88EF 0x88F2 \ + 0x88F5 0x88F6 0x88F7 0x88FA 0x88FB 0x88FD 0x88FF 0x8900 \ + 0x8901 0x8903 0x8904 0x8905 0x8906 0x8907 0x8908 0x8909 \ + 0x890B 0x890C 0x890D 0x890E 0x890F 0x8911 0x8914 0x8915 \ + 0x8916 0x8917 0x8918 0x891C 0x891D 0x891E 0x891F 0x8920 \ + 0x8922 0x8923 0x8924 0x8926 0x8927 0x8928 0x8929 0x892C \ + 0x892D 0x892E 0x892F 0x8931 0x8932 0x8933 0x8935 0x8937 \ + 0x9009 0x7663 0x7729 0x7EDA 0x9774 0x859B 0x5B66 0x7A74 \ + 0x96EA 0x8840 0x52CB 0x718F 0x5FAA 0x65EC 0x8BE2 0x5BFB \ + 0x9A6F 0x5DE1 0x6B89 0x6C5B 0x8BAD 0x8BAF 0x900A 0x8FC5 \ + 0x538B 0x62BC 0x9E26 0x9E2D 0x5440 0x4E2B 0x82BD 0x7259 \ + 0x869C 0x5D16 0x8859 0x6DAF 0x96C5 0x54D1 0x4E9A 0x8BB6 \ + 0x7109 0x54BD 0x9609 0x70DF 0x6DF9 0x76D0 0x4E25 0x7814 \ + 0x8712 0x5CA9 0x5EF6 0x8A00 0x989C 0x960E 0x708E 0x6CBF \ + 0x5944 0x63A9 0x773C 0x884D 0x6F14 0x8273 0x5830 0x71D5 +61 0x538C 0x781A 0x96C1 0x5501 0x5F66 0x7130 0x5BB4 0x8C1A \ + 0x9A8C 0x6B83 0x592E 0x9E2F 0x79E7 0x6768 0x626C 0x4F6F \ + 0x75A1 0x7F8A 0x6D0B 0x9633 0x6C27 0x4EF0 0x75D2 0x517B \ + 0x6837 0x6F3E 0x9080 0x8170 0x5996 0x7476 0x8938 0x8939 \ + 0x893A 0x893B 0x893C 0x893D 0x893E 0x893F 0x8940 0x8942 \ + 0x8943 0x8945 0x8946 0x8947 0x8948 0x8949 0x894A 0x894B \ + 0x894C 0x894D 0x894E 0x894F 0x8950 0x8951 0x8952 0x8953 \ + 0x8954 0x8955 0x8956 0x8957 0x8958 0x8959 0x895A 0x895B \ + 0x895C 0x895D 0x8960 0x8961 0x8962 0x8963 0x8964 0x8965 \ + 0x8967 0x8968 0x8969 0x896A 0x896B 0x896C 0x896D 0x896E \ + 0x896F 0x8970 0x8971 0x8972 0x8973 0x8974 0x8975 0x8976 \ + 0x8977 0x8978 0x8979 0x897A 0x897C 0x897D 0x897E 0x8980 \ + 0x8982 0x8984 0x8985 0x8987 0x8988 0x8989 0x898A 0x898B \ + 0x898C 0x898D 0x898E 0x898F 0x8990 0x8991 0x8992 0x8993 \ + 0x8994 0x8995 0x8996 0x8997 0x8998 0x8999 0x899A 0x899B \ + 0x899C 0x899D 0x899E 0x899F 0x89A0 0x89A1 0x6447 0x5C27 \ + 0x9065 0x7A91 0x8C23 0x59DA 0x54AC 0x8200 0x836F 0x8981 \ + 0x8000 0x6930 0x564E 0x8036 0x7237 0x91CE 0x51B6 0x4E5F \ + 0x9875 0x6396 0x4E1A 0x53F6 0x66F3 0x814B 0x591C 0x6DB2 \ + 0x4E00 0x58F9 0x533B 0x63D6 0x94F1 0x4F9D 0x4F0A 0x8863 \ + 0x9890 0x5937 0x9057 0x79FB 0x4EEA 0x80F0 0x7591 0x6C82 \ + 0x5B9C 0x59E8 0x5F5D 0x6905 0x8681 0x501A 0x5DF2 0x4E59 \ + 0x77E3 0x4EE5 0x827A 0x6291 0x6613 0x9091 0x5C79 0x4EBF \ + 0x5F79 0x81C6 0x9038 0x8084 0x75AB 0x4EA6 0x88D4 0x610F \ + 0x6BC5 0x5FC6 0x4E49 0x76CA 0x6EA2 0x8BE3 0x8BAE 0x8C0A \ + 0x8BD1 0x5F02 0x7FFC 0x7FCC 0x7ECE 0x8335 0x836B 0x56E0 \ + 0x6BB7 0x97F3 0x9634 0x59FB 0x541F 0x94F6 0x6DEB 0x5BC5 \ + 0x996E 0x5C39 0x5F15 0x9690 0x89A2 0x89A3 0x89A4 0x89A5 \ + 0x89A6 0x89A7 0x89A8 0x89A9 0x89AA 0x89AB 0x89AC 0x89AD \ + 0x89AE 0x89AF 0x89B0 0x89B1 0x89B2 0x89B3 0x89B4 0x89B5 \ + 0x89B6 0x89B7 0x89B8 0x89B9 0x89BA 0x89BB 0x89BC 0x89BD \ + 0x89BE 0x89BF 0x89C0 0x89C3 0x89CD 0x89D3 0x89D4 0x89D5 +62 0x89D7 0x89D8 0x89D9 0x89DB 0x89DD 0x89DF 0x89E0 0x89E1 \ + 0x89E2 0x89E4 0x89E7 0x89E8 0x89E9 0x89EA 0x89EC 0x89ED \ + 0x89EE 0x89F0 0x89F1 0x89F2 0x89F4 0x89F5 0x89F6 0x89F7 \ + 0x89F8 0x89F9 0x89FA 0x89FB 0x89FC 0x89FD 0x89FE 0x89FF \ + 0x8A01 0x8A02 0x8A03 0x8A04 0x8A05 0x8A06 0x8A08 0x8A09 \ + 0x8A0A 0x8A0B 0x8A0C 0x8A0D 0x8A0E 0x8A0F 0x8A10 0x8A11 \ + 0x8A12 0x8A13 0x8A14 0x8A15 0x8A16 0x8A17 0x8A18 0x8A19 \ + 0x8A1A 0x8A1B 0x8A1C 0x8A1D 0x5370 0x82F1 0x6A31 0x5A74 \ + 0x9E70 0x5E94 0x7F28 0x83B9 0x8424 0x8425 0x8367 0x8747 \ + 0x8FCE 0x8D62 0x76C8 0x5F71 0x9896 0x786C 0x6620 0x54DF \ + 0x62E5 0x4F63 0x81C3 0x75C8 0x5EB8 0x96CD 0x8E0A 0x86F9 \ + 0x548F 0x6CF3 0x6D8C 0x6C38 0x607F 0x52C7 0x7528 0x5E7D \ + 0x4F18 0x60A0 0x5FE7 0x5C24 0x7531 0x90AE 0x94C0 0x72B9 \ + 0x6CB9 0x6E38 0x9149 0x6709 0x53CB 0x53F3 0x4F51 0x91C9 \ + 0x8BF1 0x53C8 0x5E7C 0x8FC2 0x6DE4 0x4E8E 0x76C2 0x6986 \ + 0x865E 0x611A 0x8206 0x4F59 0x4FDE 0x903E 0x9C7C 0x6109 \ + 0x6E1D 0x6E14 0x9685 0x4E88 0x5A31 0x96E8 0x4E0E 0x5C7F \ + 0x79B9 0x5B87 0x8BED 0x7FBD 0x7389 0x57DF 0x828B 0x90C1 \ + 0x5401 0x9047 0x55BB 0x5CEA 0x5FA1 0x6108 0x6B32 0x72F1 \ + 0x80B2 0x8A89 0x8A1E 0x8A1F 0x8A20 0x8A21 0x8A22 0x8A23 \ + 0x8A24 0x8A25 0x8A26 0x8A27 0x8A28 0x8A29 0x8A2A 0x8A2B \ + 0x8A2C 0x8A2D 0x8A2E 0x8A2F 0x8A30 0x8A31 0x8A32 0x8A33 \ + 0x8A34 0x8A35 0x8A36 0x8A37 0x8A38 0x8A39 0x8A3A 0x8A3B \ + 0x8A3C 0x8A3D 0x8A3F 0x8A40 0x8A41 0x8A42 0x8A43 0x8A44 \ + 0x8A45 0x8A46 0x8A47 0x8A49 0x8A4A 0x8A4B 0x8A4C 0x8A4D \ + 0x8A4E 0x8A4F 0x8A50 0x8A51 0x8A52 0x8A53 0x8A54 0x8A55 \ + 0x8A56 0x8A57 0x8A58 0x8A59 0x8A5A 0x8A5B 0x8A5C 0x8A5D \ + 0x8A5E 0x8A5F 0x8A60 0x8A61 0x8A62 0x8A63 0x8A64 0x8A65 \ + 0x8A66 0x8A67 0x8A68 0x8A69 0x8A6A 0x8A6B 0x8A6C 0x8A6D \ + 0x8A6E 0x8A6F 0x8A70 0x8A71 0x8A72 0x8A73 0x8A74 0x8A75 \ + 0x8A76 0x8A77 0x8A78 0x8A7A 0x8A7B 0x8A7C 0x8A7D 0x8A7E \ + 0x8A7F 0x8A80 0x6D74 0x5BD3 0x88D5 0x9884 0x8C6B 0x9A6D +63 0x9E33 0x6E0A 0x51A4 0x5143 0x57A3 0x8881 0x539F 0x63F4 \ + 0x8F95 0x56ED 0x5458 0x5706 0x733F 0x6E90 0x7F18 0x8FDC \ + 0x82D1 0x613F 0x6028 0x9662 0x66F0 0x7EA6 0x8D8A 0x8DC3 \ + 0x94A5 0x5CB3 0x7CA4 0x6708 0x60A6 0x9605 0x8018 0x4E91 \ + 0x90E7 0x5300 0x9668 0x5141 0x8FD0 0x8574 0x915D 0x6655 \ + 0x97F5 0x5B55 0x531D 0x7838 0x6742 0x683D 0x54C9 0x707E \ + 0x5BB0 0x8F7D 0x518D 0x5728 0x54B1 0x6512 0x6682 0x8D5E \ + 0x8D43 0x810F 0x846C 0x906D 0x7CDF 0x51FF 0x85FB 0x67A3 \ + 0x65E9 0x6FA1 0x86A4 0x8E81 0x566A 0x9020 0x7682 0x7076 \ + 0x71E5 0x8D23 0x62E9 0x5219 0x6CFD 0x8D3C 0x600E 0x589E \ + 0x618E 0x66FE 0x8D60 0x624E 0x55B3 0x6E23 0x672D 0x8F67 \ + 0x8A81 0x8A82 0x8A83 0x8A84 0x8A85 0x8A86 0x8A87 0x8A88 \ + 0x8A8B 0x8A8C 0x8A8D 0x8A8E 0x8A8F 0x8A90 0x8A91 0x8A92 \ + 0x8A94 0x8A95 0x8A96 0x8A97 0x8A98 0x8A99 0x8A9A 0x8A9B \ + 0x8A9C 0x8A9D 0x8A9E 0x8A9F 0x8AA0 0x8AA1 0x8AA2 0x8AA3 \ + 0x8AA4 0x8AA5 0x8AA6 0x8AA7 0x8AA8 0x8AA9 0x8AAA 0x8AAB \ + 0x8AAC 0x8AAD 0x8AAE 0x8AAF 0x8AB0 0x8AB1 0x8AB2 0x8AB3 \ + 0x8AB4 0x8AB5 0x8AB6 0x8AB7 0x8AB8 0x8AB9 0x8ABA 0x8ABB \ + 0x8ABC 0x8ABD 0x8ABE 0x8ABF 0x8AC0 0x8AC1 0x8AC2 0x8AC3 \ + 0x8AC4 0x8AC5 0x8AC6 0x8AC7 0x8AC8 0x8AC9 0x8ACA 0x8ACB \ + 0x8ACC 0x8ACD 0x8ACE 0x8ACF 0x8AD0 0x8AD1 0x8AD2 0x8AD3 \ + 0x8AD4 0x8AD5 0x8AD6 0x8AD7 0x8AD8 0x8AD9 0x8ADA 0x8ADB \ + 0x8ADC 0x8ADD 0x8ADE 0x8ADF 0x8AE0 0x8AE1 0x8AE2 0x8AE3 \ + 0x94E1 0x95F8 0x7728 0x6805 0x69A8 0x548B 0x4E4D 0x70B8 \ + 0x8BC8 0x6458 0x658B 0x5B85 0x7A84 0x503A 0x5BE8 0x77BB \ + 0x6BE1 0x8A79 0x7C98 0x6CBE 0x76CF 0x65A9 0x8F97 0x5D2D \ + 0x5C55 0x8638 0x6808 0x5360 0x6218 0x7AD9 0x6E5B 0x7EFD \ + 0x6A1F 0x7AE0 0x5F70 0x6F33 0x5F20 0x638C 0x6DA8 0x6756 \ + 0x4E08 0x5E10 0x8D26 0x4ED7 0x80C0 0x7634 0x969C 0x62DB \ + 0x662D 0x627E 0x6CBC 0x8D75 0x7167 0x7F69 0x5146 0x8087 \ + 0x53EC 0x906E 0x6298 0x54F2 0x86F0 0x8F99 0x8005 0x9517 \ + 0x8517 0x8FD9 0x6D59 0x73CD 0x659F 0x771F 0x7504 0x7827 +64 0x81FB 0x8D1E 0x9488 0x4FA6 0x6795 0x75B9 0x8BCA 0x9707 \ + 0x632F 0x9547 0x9635 0x84B8 0x6323 0x7741 0x5F81 0x72F0 \ + 0x4E89 0x6014 0x6574 0x62EF 0x6B63 0x653F 0x8AE4 0x8AE5 \ + 0x8AE6 0x8AE7 0x8AE8 0x8AE9 0x8AEA 0x8AEB 0x8AEC 0x8AED \ + 0x8AEE 0x8AEF 0x8AF0 0x8AF1 0x8AF2 0x8AF3 0x8AF4 0x8AF5 \ + 0x8AF6 0x8AF7 0x8AF8 0x8AF9 0x8AFA 0x8AFB 0x8AFC 0x8AFD \ + 0x8AFE 0x8AFF 0x8B00 0x8B01 0x8B02 0x8B03 0x8B04 0x8B05 \ + 0x8B06 0x8B08 0x8B09 0x8B0A 0x8B0B 0x8B0C 0x8B0D 0x8B0E \ + 0x8B0F 0x8B10 0x8B11 0x8B12 0x8B13 0x8B14 0x8B15 0x8B16 \ + 0x8B17 0x8B18 0x8B19 0x8B1A 0x8B1B 0x8B1C 0x8B1D 0x8B1E \ + 0x8B1F 0x8B20 0x8B21 0x8B22 0x8B23 0x8B24 0x8B25 0x8B27 \ + 0x8B28 0x8B29 0x8B2A 0x8B2B 0x8B2C 0x8B2D 0x8B2E 0x8B2F \ + 0x8B30 0x8B31 0x8B32 0x8B33 0x8B34 0x8B35 0x8B36 0x8B37 \ + 0x8B38 0x8B39 0x8B3A 0x8B3B 0x8B3C 0x8B3D 0x8B3E 0x8B3F \ + 0x8B40 0x8B41 0x8B42 0x8B43 0x8B44 0x8B45 0x5E27 0x75C7 \ + 0x90D1 0x8BC1 0x829D 0x679D 0x652F 0x5431 0x8718 0x77E5 \ + 0x80A2 0x8102 0x6C41 0x4E4B 0x7EC7 0x804C 0x76F4 0x690D \ + 0x6B96 0x6267 0x503C 0x4F84 0x5740 0x6307 0x6B62 0x8DBE \ + 0x53EA 0x65E8 0x7EB8 0x5FD7 0x631A 0x63B7 0x81F3 0x81F4 \ + 0x7F6E 0x5E1C 0x5CD9 0x5236 0x667A 0x79E9 0x7A1A 0x8D28 \ + 0x7099 0x75D4 0x6EDE 0x6CBB 0x7A92 0x4E2D 0x76C5 0x5FE0 \ + 0x949F 0x8877 0x7EC8 0x79CD 0x80BF 0x91CD 0x4EF2 0x4F17 \ + 0x821F 0x5468 0x5DDE 0x6D32 0x8BCC 0x7CA5 0x8F74 0x8098 \ + 0x5E1A 0x5492 0x76B1 0x5B99 0x663C 0x9AA4 0x73E0 0x682A \ + 0x86DB 0x6731 0x732A 0x8BF8 0x8BDB 0x9010 0x7AF9 0x70DB \ + 0x716E 0x62C4 0x77A9 0x5631 0x4E3B 0x8457 0x67F1 0x52A9 \ + 0x86C0 0x8D2E 0x94F8 0x7B51 0x8B46 0x8B47 0x8B48 0x8B49 \ + 0x8B4A 0x8B4B 0x8B4C 0x8B4D 0x8B4E 0x8B4F 0x8B50 0x8B51 \ + 0x8B52 0x8B53 0x8B54 0x8B55 0x8B56 0x8B57 0x8B58 0x8B59 \ + 0x8B5A 0x8B5B 0x8B5C 0x8B5D 0x8B5E 0x8B5F 0x8B60 0x8B61 \ + 0x8B62 0x8B63 0x8B64 0x8B65 0x8B67 0x8B68 0x8B69 0x8B6A \ + 0x8B6B 0x8B6D 0x8B6E 0x8B6F 0x8B70 0x8B71 0x8B72 0x8B73 +65 0x8B74 0x8B75 0x8B76 0x8B77 0x8B78 0x8B79 0x8B7A 0x8B7B \ + 0x8B7C 0x8B7D 0x8B7E 0x8B7F 0x8B80 0x8B81 0x8B82 0x8B83 \ + 0x8B84 0x8B85 0x8B86 0x8B87 0x8B88 0x8B89 0x8B8A 0x8B8B \ + 0x8B8C 0x8B8D 0x8B8E 0x8B8F 0x8B90 0x8B91 0x8B92 0x8B93 \ + 0x8B94 0x8B95 0x8B96 0x8B97 0x8B98 0x8B99 0x8B9A 0x8B9B \ + 0x8B9C 0x8B9D 0x8B9E 0x8B9F 0x8BAC 0x8BB1 0x8BBB 0x8BC7 \ + 0x8BD0 0x8BEA 0x8C09 0x8C1E 0x4F4F 0x6CE8 0x795D 0x9A7B \ + 0x6293 0x722A 0x62FD 0x4E13 0x7816 0x8F6C 0x64B0 0x8D5A \ + 0x7BC6 0x6869 0x5E84 0x88C5 0x5986 0x649E 0x58EE 0x72B6 \ + 0x690E 0x9525 0x8FFD 0x8D58 0x5760 0x7F00 0x8C06 0x51C6 \ + 0x6349 0x62D9 0x5353 0x684C 0x7422 0x8301 0x914C 0x5544 \ + 0x7740 0x707C 0x6D4A 0x5179 0x54A8 0x8D44 0x59FF 0x6ECB \ + 0x6DC4 0x5B5C 0x7D2B 0x4ED4 0x7C7D 0x6ED3 0x5B50 0x81EA \ + 0x6E0D 0x5B57 0x9B03 0x68D5 0x8E2A 0x5B97 0x7EFC 0x603B \ + 0x7EB5 0x90B9 0x8D70 0x594F 0x63CD 0x79DF 0x8DB3 0x5352 \ + 0x65CF 0x7956 0x8BC5 0x963B 0x7EC4 0x94BB 0x7E82 0x5634 \ + 0x9189 0x6700 0x7F6A 0x5C0A 0x9075 0x6628 0x5DE6 0x4F50 \ + 0x67DE 0x505A 0x4F5C 0x5750 0x5EA7 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x8C38 0x8C39 0x8C3A 0x8C3B 0x8C3C 0x8C3D \ + 0x8C3E 0x8C3F 0x8C40 0x8C42 0x8C43 0x8C44 0x8C45 0x8C48 \ + 0x8C4A 0x8C4B 0x8C4D 0x8C4E 0x8C4F 0x8C50 0x8C51 0x8C52 \ + 0x8C53 0x8C54 0x8C56 0x8C57 0x8C58 0x8C59 0x8C5B 0x8C5C \ + 0x8C5D 0x8C5E 0x8C5F 0x8C60 0x8C63 0x8C64 0x8C65 0x8C66 \ + 0x8C67 0x8C68 0x8C69 0x8C6C 0x8C6D 0x8C6E 0x8C6F 0x8C70 \ + 0x8C71 0x8C72 0x8C74 0x8C75 0x8C76 0x8C77 0x8C7B 0x8C7C \ + 0x8C7D 0x8C7E 0x8C7F 0x8C80 0x8C81 0x8C83 0x8C84 0x8C86 \ + 0x8C87 0x8C88 0x8C8B 0x8C8D 0x8C8E 0x8C8F 0x8C90 0x8C91 \ + 0x8C92 0x8C93 0x8C95 0x8C96 0x8C97 0x8C99 0x8C9A 0x8C9B \ + 0x8C9C 0x8C9D 0x8C9E 0x8C9F 0x8CA0 0x8CA1 0x8CA2 0x8CA3 \ + 0x8CA4 0x8CA5 0x8CA6 0x8CA7 0x8CA8 0x8CA9 0x8CAA 0x8CAB \ + 0x8CAC 0x8CAD 0x4E8D 0x4E0C 0x5140 0x4E10 0x5EFF 0x5345 \ + 0x4E15 0x4E98 0x4E1E 0x9B32 0x5B6C 0x5669 0x4E28 0x79BA +66 0x4E3F 0x5315 0x4E47 0x592D 0x723B 0x536E 0x6C10 0x56DF \ + 0x80E4 0x9997 0x6BD3 0x777E 0x9F17 0x4E36 0x4E9F 0x9F10 \ + 0x4E5C 0x4E69 0x4E93 0x8288 0x5B5B 0x556C 0x560F 0x4EC4 \ + 0x538D 0x539D 0x53A3 0x53A5 0x53AE 0x9765 0x8D5D 0x531A \ + 0x53F5 0x5326 0x532E 0x533E 0x8D5C 0x5366 0x5363 0x5202 \ + 0x5208 0x520E 0x522D 0x5233 0x523F 0x5240 0x524C 0x525E \ + 0x5261 0x525C 0x84AF 0x527D 0x5282 0x5281 0x5290 0x5293 \ + 0x5182 0x7F54 0x4EBB 0x4EC3 0x4EC9 0x4EC2 0x4EE8 0x4EE1 \ + 0x4EEB 0x4EDE 0x4F1B 0x4EF3 0x4F22 0x4F64 0x4EF5 0x4F25 \ + 0x4F27 0x4F09 0x4F2B 0x4F5E 0x4F67 0x6538 0x4F5A 0x4F5D \ + 0x8CAE 0x8CAF 0x8CB0 0x8CB1 0x8CB2 0x8CB3 0x8CB4 0x8CB5 \ + 0x8CB6 0x8CB7 0x8CB8 0x8CB9 0x8CBA 0x8CBB 0x8CBC 0x8CBD \ + 0x8CBE 0x8CBF 0x8CC0 0x8CC1 0x8CC2 0x8CC3 0x8CC4 0x8CC5 \ + 0x8CC6 0x8CC7 0x8CC8 0x8CC9 0x8CCA 0x8CCB 0x8CCC 0x8CCD \ + 0x8CCE 0x8CCF 0x8CD0 0x8CD1 0x8CD2 0x8CD3 0x8CD4 0x8CD5 \ + 0x8CD6 0x8CD7 0x8CD8 0x8CD9 0x8CDA 0x8CDB 0x8CDC 0x8CDD \ + 0x8CDE 0x8CDF 0x8CE0 0x8CE1 0x8CE2 0x8CE3 0x8CE4 0x8CE5 \ + 0x8CE6 0x8CE7 0x8CE8 0x8CE9 0x8CEA 0x8CEB 0x8CEC 0x8CED \ + 0x8CEE 0x8CEF 0x8CF0 0x8CF1 0x8CF2 0x8CF3 0x8CF4 0x8CF5 \ + 0x8CF6 0x8CF7 0x8CF8 0x8CF9 0x8CFA 0x8CFB 0x8CFC 0x8CFD \ + 0x8CFE 0x8CFF 0x8D00 0x8D01 0x8D02 0x8D03 0x8D04 0x8D05 \ + 0x8D06 0x8D07 0x8D08 0x8D09 0x8D0A 0x8D0B 0x8D0C 0x8D0D \ + 0x4F5F 0x4F57 0x4F32 0x4F3D 0x4F76 0x4F74 0x4F91 0x4F89 \ + 0x4F83 0x4F8F 0x4F7E 0x4F7B 0x4FAA 0x4F7C 0x4FAC 0x4F94 \ + 0x4FE6 0x4FE8 0x4FEA 0x4FC5 0x4FDA 0x4FE3 0x4FDC 0x4FD1 \ + 0x4FDF 0x4FF8 0x5029 0x504C 0x4FF3 0x502C 0x500F 0x502E \ + 0x502D 0x4FFE 0x501C 0x500C 0x5025 0x5028 0x507E 0x5043 \ + 0x5055 0x5048 0x504E 0x506C 0x507B 0x50A5 0x50A7 0x50A9 \ + 0x50BA 0x50D6 0x5106 0x50ED 0x50EC 0x50E6 0x50EE 0x5107 \ + 0x510B 0x4EDD 0x6C3D 0x4F58 0x4F65 0x4FCE 0x9FA0 0x6C46 \ + 0x7C74 0x516E 0x5DFD 0x9EC9 0x9998 0x5181 0x5914 0x52F9 \ + 0x530D 0x8A07 0x5310 0x51EB 0x5919 0x5155 0x4EA0 0x5156 +67 0x4EB3 0x886E 0x88A4 0x4EB5 0x8114 0x88D2 0x7980 0x5B34 \ + 0x8803 0x7FB8 0x51AB 0x51B1 0x51BD 0x51BC 0x8D0E 0x8D0F \ + 0x8D10 0x8D11 0x8D12 0x8D13 0x8D14 0x8D15 0x8D16 0x8D17 \ + 0x8D18 0x8D19 0x8D1A 0x8D1B 0x8D1C 0x8D20 0x8D51 0x8D52 \ + 0x8D57 0x8D5F 0x8D65 0x8D68 0x8D69 0x8D6A 0x8D6C 0x8D6E \ + 0x8D6F 0x8D71 0x8D72 0x8D78 0x8D79 0x8D7A 0x8D7B 0x8D7C \ + 0x8D7D 0x8D7E 0x8D7F 0x8D80 0x8D82 0x8D83 0x8D86 0x8D87 \ + 0x8D88 0x8D89 0x8D8C 0x8D8D 0x8D8E 0x8D8F 0x8D90 0x8D92 \ + 0x8D93 0x8D95 0x8D96 0x8D97 0x8D98 0x8D99 0x8D9A 0x8D9B \ + 0x8D9C 0x8D9D 0x8D9E 0x8DA0 0x8DA1 0x8DA2 0x8DA4 0x8DA5 \ + 0x8DA6 0x8DA7 0x8DA8 0x8DA9 0x8DAA 0x8DAB 0x8DAC 0x8DAD \ + 0x8DAE 0x8DAF 0x8DB0 0x8DB2 0x8DB6 0x8DB7 0x8DB9 0x8DBB \ + 0x8DBD 0x8DC0 0x8DC1 0x8DC2 0x8DC5 0x8DC7 0x8DC8 0x8DC9 \ + 0x8DCA 0x8DCD 0x8DD0 0x8DD2 0x8DD3 0x8DD4 0x51C7 0x5196 \ + 0x51A2 0x51A5 0x8BA0 0x8BA6 0x8BA7 0x8BAA 0x8BB4 0x8BB5 \ + 0x8BB7 0x8BC2 0x8BC3 0x8BCB 0x8BCF 0x8BCE 0x8BD2 0x8BD3 \ + 0x8BD4 0x8BD6 0x8BD8 0x8BD9 0x8BDC 0x8BDF 0x8BE0 0x8BE4 \ + 0x8BE8 0x8BE9 0x8BEE 0x8BF0 0x8BF3 0x8BF6 0x8BF9 0x8BFC \ + 0x8BFF 0x8C00 0x8C02 0x8C04 0x8C07 0x8C0C 0x8C0F 0x8C11 \ + 0x8C12 0x8C14 0x8C15 0x8C16 0x8C19 0x8C1B 0x8C18 0x8C1D \ + 0x8C1F 0x8C20 0x8C21 0x8C25 0x8C27 0x8C2A 0x8C2B 0x8C2E \ + 0x8C2F 0x8C32 0x8C33 0x8C35 0x8C36 0x5369 0x537A 0x961D \ + 0x9622 0x9621 0x9631 0x962A 0x963D 0x963C 0x9642 0x9649 \ + 0x9654 0x965F 0x9667 0x966C 0x9672 0x9674 0x9688 0x968D \ + 0x9697 0x96B0 0x9097 0x909B 0x909D 0x9099 0x90AC 0x90A1 \ + 0x90B4 0x90B3 0x90B6 0x90BA 0x8DD5 0x8DD8 0x8DD9 0x8DDC \ + 0x8DE0 0x8DE1 0x8DE2 0x8DE5 0x8DE6 0x8DE7 0x8DE9 0x8DED \ + 0x8DEE 0x8DF0 0x8DF1 0x8DF2 0x8DF4 0x8DF6 0x8DFC 0x8DFE \ + 0x8DFF 0x8E00 0x8E01 0x8E02 0x8E03 0x8E04 0x8E06 0x8E07 \ + 0x8E08 0x8E0B 0x8E0D 0x8E0E 0x8E10 0x8E11 0x8E12 0x8E13 \ + 0x8E15 0x8E16 0x8E17 0x8E18 0x8E19 0x8E1A 0x8E1B 0x8E1C \ + 0x8E20 0x8E21 0x8E24 0x8E25 0x8E26 0x8E27 0x8E28 0x8E2B +68 0x8E2D 0x8E30 0x8E32 0x8E33 0x8E34 0x8E36 0x8E37 0x8E38 \ + 0x8E3B 0x8E3C 0x8E3E 0x8E3F 0x8E43 0x8E45 0x8E46 0x8E4C \ + 0x8E4D 0x8E4E 0x8E4F 0x8E50 0x8E53 0x8E54 0x8E55 0x8E56 \ + 0x8E57 0x8E58 0x8E5A 0x8E5B 0x8E5C 0x8E5D 0x8E5E 0x8E5F \ + 0x8E60 0x8E61 0x8E62 0x8E63 0x8E64 0x8E65 0x8E67 0x8E68 \ + 0x8E6A 0x8E6B 0x8E6E 0x8E71 0x90B8 0x90B0 0x90CF 0x90C5 \ + 0x90BE 0x90D0 0x90C4 0x90C7 0x90D3 0x90E6 0x90E2 0x90DC \ + 0x90D7 0x90DB 0x90EB 0x90EF 0x90FE 0x9104 0x9122 0x911E \ + 0x9123 0x9131 0x912F 0x9139 0x9143 0x9146 0x520D 0x5942 \ + 0x52A2 0x52AC 0x52AD 0x52BE 0x54FF 0x52D0 0x52D6 0x52F0 \ + 0x53DF 0x71EE 0x77CD 0x5EF4 0x51F5 0x51FC 0x9B2F 0x53B6 \ + 0x5F01 0x755A 0x5DEF 0x574C 0x57A9 0x57A1 0x587E 0x58BC \ + 0x58C5 0x58D1 0x5729 0x572C 0x572A 0x5733 0x5739 0x572E \ + 0x572F 0x575C 0x573B 0x5742 0x5769 0x5785 0x576B 0x5786 \ + 0x577C 0x577B 0x5768 0x576D 0x5776 0x5773 0x57AD 0x57A4 \ + 0x578C 0x57B2 0x57CF 0x57A7 0x57B4 0x5793 0x57A0 0x57D5 \ + 0x57D8 0x57DA 0x57D9 0x57D2 0x57B8 0x57F4 0x57EF 0x57F8 \ + 0x57E4 0x57DD 0x8E73 0x8E75 0x8E77 0x8E78 0x8E79 0x8E7A \ + 0x8E7B 0x8E7D 0x8E7E 0x8E80 0x8E82 0x8E83 0x8E84 0x8E86 \ + 0x8E88 0x8E89 0x8E8A 0x8E8B 0x8E8C 0x8E8D 0x8E8E 0x8E91 \ + 0x8E92 0x8E93 0x8E95 0x8E96 0x8E97 0x8E98 0x8E99 0x8E9A \ + 0x8E9B 0x8E9D 0x8E9F 0x8EA0 0x8EA1 0x8EA2 0x8EA3 0x8EA4 \ + 0x8EA5 0x8EA6 0x8EA7 0x8EA8 0x8EA9 0x8EAA 0x8EAD 0x8EAE \ + 0x8EB0 0x8EB1 0x8EB3 0x8EB4 0x8EB5 0x8EB6 0x8EB7 0x8EB8 \ + 0x8EB9 0x8EBB 0x8EBC 0x8EBD 0x8EBE 0x8EBF 0x8EC0 0x8EC1 \ + 0x8EC2 0x8EC3 0x8EC4 0x8EC5 0x8EC6 0x8EC7 0x8EC8 0x8EC9 \ + 0x8ECA 0x8ECB 0x8ECC 0x8ECD 0x8ECF 0x8ED0 0x8ED1 0x8ED2 \ + 0x8ED3 0x8ED4 0x8ED5 0x8ED6 0x8ED7 0x8ED8 0x8ED9 0x8EDA \ + 0x8EDB 0x8EDC 0x8EDD 0x8EDE 0x8EDF 0x8EE0 0x8EE1 0x8EE2 \ + 0x8EE3 0x8EE4 0x580B 0x580D 0x57FD 0x57ED 0x5800 0x581E \ + 0x5819 0x5844 0x5820 0x5865 0x586C 0x5881 0x5889 0x589A \ + 0x5880 0x99A8 0x9F19 0x61FF 0x8279 0x827D 0x827F 0x828F +69 0x828A 0x82A8 0x8284 0x828E 0x8291 0x8297 0x8299 0x82AB \ + 0x82B8 0x82BE 0x82B0 0x82C8 0x82CA 0x82E3 0x8298 0x82B7 \ + 0x82AE 0x82CB 0x82CC 0x82C1 0x82A9 0x82B4 0x82A1 0x82AA \ + 0x829F 0x82C4 0x82CE 0x82A4 0x82E1 0x8309 0x82F7 0x82E4 \ + 0x830F 0x8307 0x82DC 0x82F4 0x82D2 0x82D8 0x830C 0x82FB \ + 0x82D3 0x8311 0x831A 0x8306 0x8314 0x8315 0x82E0 0x82D5 \ + 0x831C 0x8351 0x835B 0x835C 0x8308 0x8392 0x833C 0x8334 \ + 0x8331 0x839B 0x835E 0x832F 0x834F 0x8347 0x8343 0x835F \ + 0x8340 0x8317 0x8360 0x832D 0x833A 0x8333 0x8366 0x8365 \ + 0x8EE5 0x8EE6 0x8EE7 0x8EE8 0x8EE9 0x8EEA 0x8EEB 0x8EEC \ + 0x8EED 0x8EEE 0x8EEF 0x8EF0 0x8EF1 0x8EF2 0x8EF3 0x8EF4 \ + 0x8EF5 0x8EF6 0x8EF7 0x8EF8 0x8EF9 0x8EFA 0x8EFB 0x8EFC \ + 0x8EFD 0x8EFE 0x8EFF 0x8F00 0x8F01 0x8F02 0x8F03 0x8F04 \ + 0x8F05 0x8F06 0x8F07 0x8F08 0x8F09 0x8F0A 0x8F0B 0x8F0C \ + 0x8F0D 0x8F0E 0x8F0F 0x8F10 0x8F11 0x8F12 0x8F13 0x8F14 \ + 0x8F15 0x8F16 0x8F17 0x8F18 0x8F19 0x8F1A 0x8F1B 0x8F1C \ + 0x8F1D 0x8F1E 0x8F1F 0x8F20 0x8F21 0x8F22 0x8F23 0x8F24 \ + 0x8F25 0x8F26 0x8F27 0x8F28 0x8F29 0x8F2A 0x8F2B 0x8F2C \ + 0x8F2D 0x8F2E 0x8F2F 0x8F30 0x8F31 0x8F32 0x8F33 0x8F34 \ + 0x8F35 0x8F36 0x8F37 0x8F38 0x8F39 0x8F3A 0x8F3B 0x8F3C \ + 0x8F3D 0x8F3E 0x8F3F 0x8F40 0x8F41 0x8F42 0x8F43 0x8F44 \ + 0x8368 0x831B 0x8369 0x836C 0x836A 0x836D 0x836E 0x83B0 \ + 0x8378 0x83B3 0x83B4 0x83A0 0x83AA 0x8393 0x839C 0x8385 \ + 0x837C 0x83B6 0x83A9 0x837D 0x83B8 0x837B 0x8398 0x839E \ + 0x83A8 0x83BA 0x83BC 0x83C1 0x8401 0x83E5 0x83D8 0x5807 \ + 0x8418 0x840B 0x83DD 0x83FD 0x83D6 0x841C 0x8438 0x8411 \ + 0x8406 0x83D4 0x83DF 0x840F 0x8403 0x83F8 0x83F9 0x83EA \ + 0x83C5 0x83C0 0x8426 0x83F0 0x83E1 0x845C 0x8451 0x845A \ + 0x8459 0x8473 0x8487 0x8488 0x847A 0x8489 0x8478 0x843C \ + 0x8446 0x8469 0x8476 0x848C 0x848E 0x8431 0x846D 0x84C1 \ + 0x84CD 0x84D0 0x84E6 0x84BD 0x84D3 0x84CA 0x84BF 0x84BA \ + 0x84E0 0x84A1 0x84B9 0x84B4 0x8497 0x84E5 0x84E3 0x850C +70 0x750D 0x8538 0x84F0 0x8539 0x851F 0x853A 0x8F45 0x8F46 \ + 0x8F47 0x8F48 0x8F49 0x8F4A 0x8F4B 0x8F4C 0x8F4D 0x8F4E \ + 0x8F4F 0x8F50 0x8F51 0x8F52 0x8F53 0x8F54 0x8F55 0x8F56 \ + 0x8F57 0x8F58 0x8F59 0x8F5A 0x8F5B 0x8F5C 0x8F5D 0x8F5E \ + 0x8F5F 0x8F60 0x8F61 0x8F62 0x8F63 0x8F64 0x8F65 0x8F6A \ + 0x8F80 0x8F8C 0x8F92 0x8F9D 0x8FA0 0x8FA1 0x8FA2 0x8FA4 \ + 0x8FA5 0x8FA6 0x8FA7 0x8FAA 0x8FAC 0x8FAD 0x8FAE 0x8FAF \ + 0x8FB2 0x8FB3 0x8FB4 0x8FB5 0x8FB7 0x8FB8 0x8FBA 0x8FBB \ + 0x8FBC 0x8FBF 0x8FC0 0x8FC3 0x8FC6 0x8FC9 0x8FCA 0x8FCB \ + 0x8FCC 0x8FCD 0x8FCF 0x8FD2 0x8FD6 0x8FD7 0x8FDA 0x8FE0 \ + 0x8FE1 0x8FE3 0x8FE7 0x8FEC 0x8FEF 0x8FF1 0x8FF2 0x8FF4 \ + 0x8FF5 0x8FF6 0x8FFA 0x8FFB 0x8FFC 0x8FFE 0x8FFF 0x9007 \ + 0x9008 0x900C 0x900E 0x9013 0x9015 0x9018 0x8556 0x853B \ + 0x84FF 0x84FC 0x8559 0x8548 0x8568 0x8564 0x855E 0x857A \ + 0x77A2 0x8543 0x8572 0x857B 0x85A4 0x85A8 0x8587 0x858F \ + 0x8579 0x85AE 0x859C 0x8585 0x85B9 0x85B7 0x85B0 0x85D3 \ + 0x85C1 0x85DC 0x85FF 0x8627 0x8605 0x8629 0x8616 0x863C \ + 0x5EFE 0x5F08 0x593C 0x5941 0x8037 0x5955 0x595A 0x5958 \ + 0x530F 0x5C22 0x5C25 0x5C2C 0x5C34 0x624C 0x626A 0x629F \ + 0x62BB 0x62CA 0x62DA 0x62D7 0x62EE 0x6322 0x62F6 0x6339 \ + 0x634B 0x6343 0x63AD 0x63F6 0x6371 0x637A 0x638E 0x63B4 \ + 0x636D 0x63AC 0x638A 0x6369 0x63AE 0x63BC 0x63F2 0x63F8 \ + 0x63E0 0x63FF 0x63C4 0x63DE 0x63CE 0x6452 0x63C6 0x63BE \ + 0x6445 0x6441 0x640B 0x641B 0x6420 0x640C 0x6426 0x6421 \ + 0x645E 0x6484 0x646D 0x6496 0x9019 0x901C 0x9023 0x9024 \ + 0x9025 0x9027 0x9028 0x9029 0x902A 0x902B 0x902C 0x9030 \ + 0x9031 0x9032 0x9033 0x9034 0x9037 0x9039 0x903A 0x903D \ + 0x903F 0x9040 0x9043 0x9045 0x9046 0x9048 0x9049 0x904A \ + 0x904B 0x904C 0x904E 0x9054 0x9055 0x9056 0x9059 0x905A \ + 0x905C 0x905D 0x905E 0x905F 0x9060 0x9061 0x9064 0x9066 \ + 0x9067 0x9069 0x906A 0x906B 0x906C 0x906F 0x9070 0x9071 \ + 0x9072 0x9073 0x9076 0x9077 0x9078 0x9079 0x907A 0x907B +71 0x907C 0x907E 0x9081 0x9084 0x9085 0x9086 0x9087 0x9089 \ + 0x908A 0x908C 0x908D 0x908E 0x908F 0x9090 0x9092 0x9094 \ + 0x9096 0x9098 0x909A 0x909C 0x909E 0x909F 0x90A0 0x90A4 \ + 0x90A5 0x90A7 0x90A8 0x90A9 0x90AB 0x90AD 0x90B2 0x90B7 \ + 0x90BC 0x90BD 0x90BF 0x90C0 0x647A 0x64B7 0x64B8 0x6499 \ + 0x64BA 0x64C0 0x64D0 0x64D7 0x64E4 0x64E2 0x6509 0x6525 \ + 0x652E 0x5F0B 0x5FD2 0x7519 0x5F11 0x535F 0x53F1 0x53FD \ + 0x53E9 0x53E8 0x53FB 0x5412 0x5416 0x5406 0x544B 0x5452 \ + 0x5453 0x5454 0x5456 0x5443 0x5421 0x5457 0x5459 0x5423 \ + 0x5432 0x5482 0x5494 0x5477 0x5471 0x5464 0x549A 0x549B \ + 0x5484 0x5476 0x5466 0x549D 0x54D0 0x54AD 0x54C2 0x54B4 \ + 0x54D2 0x54A7 0x54A6 0x54D3 0x54D4 0x5472 0x54A3 0x54D5 \ + 0x54BB 0x54BF 0x54CC 0x54D9 0x54DA 0x54DC 0x54A9 0x54AA \ + 0x54A4 0x54DD 0x54CF 0x54DE 0x551B 0x54E7 0x5520 0x54FD \ + 0x5514 0x54F3 0x5522 0x5523 0x550F 0x5511 0x5527 0x552A \ + 0x5567 0x558F 0x55B5 0x5549 0x556D 0x5541 0x5555 0x553F \ + 0x5550 0x553C 0x90C2 0x90C3 0x90C6 0x90C8 0x90C9 0x90CB \ + 0x90CC 0x90CD 0x90D2 0x90D4 0x90D5 0x90D6 0x90D8 0x90D9 \ + 0x90DA 0x90DE 0x90DF 0x90E0 0x90E3 0x90E4 0x90E5 0x90E9 \ + 0x90EA 0x90EC 0x90EE 0x90F0 0x90F1 0x90F2 0x90F3 0x90F5 \ + 0x90F6 0x90F7 0x90F9 0x90FA 0x90FB 0x90FC 0x90FF 0x9100 \ + 0x9101 0x9103 0x9105 0x9106 0x9107 0x9108 0x9109 0x910A \ + 0x910B 0x910C 0x910D 0x910E 0x910F 0x9110 0x9111 0x9112 \ + 0x9113 0x9114 0x9115 0x9116 0x9117 0x9118 0x911A 0x911B \ + 0x911C 0x911D 0x911F 0x9120 0x9121 0x9124 0x9125 0x9126 \ + 0x9127 0x9128 0x9129 0x912A 0x912B 0x912C 0x912D 0x912E \ + 0x9130 0x9132 0x9133 0x9134 0x9135 0x9136 0x9137 0x9138 \ + 0x913A 0x913B 0x913C 0x913D 0x913E 0x913F 0x9140 0x9141 \ + 0x9142 0x9144 0x5537 0x5556 0x5575 0x5576 0x5577 0x5533 \ + 0x5530 0x555C 0x558B 0x55D2 0x5583 0x55B1 0x55B9 0x5588 \ + 0x5581 0x559F 0x557E 0x55D6 0x5591 0x557B 0x55DF 0x55BD \ + 0x55BE 0x5594 0x5599 0x55EA 0x55F7 0x55C9 0x561F 0x55D1 +72 0x55EB 0x55EC 0x55D4 0x55E6 0x55DD 0x55C4 0x55EF 0x55E5 \ + 0x55F2 0x55F3 0x55CC 0x55CD 0x55E8 0x55F5 0x55E4 0x8F94 \ + 0x561E 0x5608 0x560C 0x5601 0x5624 0x5623 0x55FE 0x5600 \ + 0x5627 0x562D 0x5658 0x5639 0x5657 0x562C 0x564D 0x5662 \ + 0x5659 0x565C 0x564C 0x5654 0x5686 0x5664 0x5671 0x566B \ + 0x567B 0x567C 0x5685 0x5693 0x56AF 0x56D4 0x56D7 0x56DD \ + 0x56E1 0x56F5 0x56EB 0x56F9 0x56FF 0x5704 0x570A 0x5709 \ + 0x571C 0x5E0F 0x5E19 0x5E14 0x5E11 0x5E31 0x5E3B 0x5E3C \ + 0x9145 0x9147 0x9148 0x9151 0x9153 0x9154 0x9155 0x9156 \ + 0x9158 0x9159 0x915B 0x915C 0x915F 0x9160 0x9166 0x9167 \ + 0x9168 0x916B 0x916D 0x9173 0x917A 0x917B 0x917C 0x9180 \ + 0x9181 0x9182 0x9183 0x9184 0x9186 0x9188 0x918A 0x918E \ + 0x918F 0x9193 0x9194 0x9195 0x9196 0x9197 0x9198 0x9199 \ + 0x919C 0x919D 0x919E 0x919F 0x91A0 0x91A1 0x91A4 0x91A5 \ + 0x91A6 0x91A7 0x91A8 0x91A9 0x91AB 0x91AC 0x91B0 0x91B1 \ + 0x91B2 0x91B3 0x91B6 0x91B7 0x91B8 0x91B9 0x91BB 0x91BC \ + 0x91BD 0x91BE 0x91BF 0x91C0 0x91C1 0x91C2 0x91C3 0x91C4 \ + 0x91C5 0x91C6 0x91C8 0x91CB 0x91D0 0x91D2 0x91D3 0x91D4 \ + 0x91D5 0x91D6 0x91D7 0x91D8 0x91D9 0x91DA 0x91DB 0x91DD \ + 0x91DE 0x91DF 0x91E0 0x91E1 0x91E2 0x91E3 0x91E4 0x91E5 \ + 0x5E37 0x5E44 0x5E54 0x5E5B 0x5E5E 0x5E61 0x5C8C 0x5C7A \ + 0x5C8D 0x5C90 0x5C96 0x5C88 0x5C98 0x5C99 0x5C91 0x5C9A \ + 0x5C9C 0x5CB5 0x5CA2 0x5CBD 0x5CAC 0x5CAB 0x5CB1 0x5CA3 \ + 0x5CC1 0x5CB7 0x5CC4 0x5CD2 0x5CE4 0x5CCB 0x5CE5 0x5D02 \ + 0x5D03 0x5D27 0x5D26 0x5D2E 0x5D24 0x5D1E 0x5D06 0x5D1B \ + 0x5D58 0x5D3E 0x5D34 0x5D3D 0x5D6C 0x5D5B 0x5D6F 0x5D5D \ + 0x5D6B 0x5D4B 0x5D4A 0x5D69 0x5D74 0x5D82 0x5D99 0x5D9D \ + 0x8C73 0x5DB7 0x5DC5 0x5F73 0x5F77 0x5F82 0x5F87 0x5F89 \ + 0x5F8C 0x5F95 0x5F99 0x5F9C 0x5FA8 0x5FAD 0x5FB5 0x5FBC \ + 0x8862 0x5F61 0x72AD 0x72B0 0x72B4 0x72B7 0x72B8 0x72C3 \ + 0x72C1 0x72CE 0x72CD 0x72D2 0x72E8 0x72EF 0x72E9 0x72F2 \ + 0x72F4 0x72F7 0x7301 0x72F3 0x7303 0x72FA 0x91E6 0x91E7 +73 0x91E8 0x91E9 0x91EA 0x91EB 0x91EC 0x91ED 0x91EE 0x91EF \ + 0x91F0 0x91F1 0x91F2 0x91F3 0x91F4 0x91F5 0x91F6 0x91F7 \ + 0x91F8 0x91F9 0x91FA 0x91FB 0x91FC 0x91FD 0x91FE 0x91FF \ + 0x9200 0x9201 0x9202 0x9203 0x9204 0x9205 0x9206 0x9207 \ + 0x9208 0x9209 0x920A 0x920B 0x920C 0x920D 0x920E 0x920F \ + 0x9210 0x9211 0x9212 0x9213 0x9214 0x9215 0x9216 0x9217 \ + 0x9218 0x9219 0x921A 0x921B 0x921C 0x921D 0x921E 0x921F \ + 0x9220 0x9221 0x9222 0x9223 0x9224 0x9225 0x9226 0x9227 \ + 0x9228 0x9229 0x922A 0x922B 0x922C 0x922D 0x922E 0x922F \ + 0x9230 0x9231 0x9232 0x9233 0x9234 0x9235 0x9236 0x9237 \ + 0x9238 0x9239 0x923A 0x923B 0x923C 0x923D 0x923E 0x923F \ + 0x9240 0x9241 0x9242 0x9243 0x9244 0x9245 0x72FB 0x7317 \ + 0x7313 0x7321 0x730A 0x731E 0x731D 0x7315 0x7322 0x7339 \ + 0x7325 0x732C 0x7338 0x7331 0x7350 0x734D 0x7357 0x7360 \ + 0x736C 0x736F 0x737E 0x821B 0x5925 0x98E7 0x5924 0x5902 \ + 0x9963 0x9967 0x9968 0x9969 0x996A 0x996B 0x996C 0x9974 \ + 0x9977 0x997D 0x9980 0x9984 0x9987 0x998A 0x998D 0x9990 \ + 0x9991 0x9993 0x9994 0x9995 0x5E80 0x5E91 0x5E8B 0x5E96 \ + 0x5EA5 0x5EA0 0x5EB9 0x5EB5 0x5EBE 0x5EB3 0x8D53 0x5ED2 \ + 0x5ED1 0x5EDB 0x5EE8 0x5EEA 0x81BA 0x5FC4 0x5FC9 0x5FD6 \ + 0x5FCF 0x6003 0x5FEE 0x6004 0x5FE1 0x5FE4 0x5FFE 0x6005 \ + 0x6006 0x5FEA 0x5FED 0x5FF8 0x6019 0x6035 0x6026 0x601B \ + 0x600F 0x600D 0x6029 0x602B 0x600A 0x603F 0x6021 0x6078 \ + 0x6079 0x607B 0x607A 0x6042 0x9246 0x9247 0x9248 0x9249 \ + 0x924A 0x924B 0x924C 0x924D 0x924E 0x924F 0x9250 0x9251 \ + 0x9252 0x9253 0x9254 0x9255 0x9256 0x9257 0x9258 0x9259 \ + 0x925A 0x925B 0x925C 0x925D 0x925E 0x925F 0x9260 0x9261 \ + 0x9262 0x9263 0x9264 0x9265 0x9266 0x9267 0x9268 0x9269 \ + 0x926A 0x926B 0x926C 0x926D 0x926E 0x926F 0x9270 0x9271 \ + 0x9272 0x9273 0x9275 0x9276 0x9277 0x9278 0x9279 0x927A \ + 0x927B 0x927C 0x927D 0x927E 0x927F 0x9280 0x9281 0x9282 \ + 0x9283 0x9284 0x9285 0x9286 0x9287 0x9288 0x9289 0x928A +74 0x928B 0x928C 0x928D 0x928F 0x9290 0x9291 0x9292 0x9293 \ + 0x9294 0x9295 0x9296 0x9297 0x9298 0x9299 0x929A 0x929B \ + 0x929C 0x929D 0x929E 0x929F 0x92A0 0x92A1 0x92A2 0x92A3 \ + 0x92A4 0x92A5 0x92A6 0x92A7 0x606A 0x607D 0x6096 0x609A \ + 0x60AD 0x609D 0x6083 0x6092 0x608C 0x609B 0x60EC 0x60BB \ + 0x60B1 0x60DD 0x60D8 0x60C6 0x60DA 0x60B4 0x6120 0x6126 \ + 0x6115 0x6123 0x60F4 0x6100 0x610E 0x612B 0x614A 0x6175 \ + 0x61AC 0x6194 0x61A7 0x61B7 0x61D4 0x61F5 0x5FDD 0x96B3 \ + 0x95E9 0x95EB 0x95F1 0x95F3 0x95F5 0x95F6 0x95FC 0x95FE \ + 0x9603 0x9604 0x9606 0x9608 0x960A 0x960B 0x960C 0x960D \ + 0x960F 0x9612 0x9615 0x9616 0x9617 0x9619 0x961A 0x4E2C \ + 0x723F 0x6215 0x6C35 0x6C54 0x6C5C 0x6C4A 0x6CA3 0x6C85 \ + 0x6C90 0x6C94 0x6C8C 0x6C68 0x6C69 0x6C74 0x6C76 0x6C86 \ + 0x6CA9 0x6CD0 0x6CD4 0x6CAD 0x6CF7 0x6CF8 0x6CF1 0x6CD7 \ + 0x6CB2 0x6CE0 0x6CD6 0x6CFA 0x6CEB 0x6CEE 0x6CB1 0x6CD3 \ + 0x6CEF 0x6CFE 0x92A8 0x92A9 0x92AA 0x92AB 0x92AC 0x92AD \ + 0x92AF 0x92B0 0x92B1 0x92B2 0x92B3 0x92B4 0x92B5 0x92B6 \ + 0x92B7 0x92B8 0x92B9 0x92BA 0x92BB 0x92BC 0x92BD 0x92BE \ + 0x92BF 0x92C0 0x92C1 0x92C2 0x92C3 0x92C4 0x92C5 0x92C6 \ + 0x92C7 0x92C9 0x92CA 0x92CB 0x92CC 0x92CD 0x92CE 0x92CF \ + 0x92D0 0x92D1 0x92D2 0x92D3 0x92D4 0x92D5 0x92D6 0x92D7 \ + 0x92D8 0x92D9 0x92DA 0x92DB 0x92DC 0x92DD 0x92DE 0x92DF \ + 0x92E0 0x92E1 0x92E2 0x92E3 0x92E4 0x92E5 0x92E6 0x92E7 \ + 0x92E8 0x92E9 0x92EA 0x92EB 0x92EC 0x92ED 0x92EE 0x92EF \ + 0x92F0 0x92F1 0x92F2 0x92F3 0x92F4 0x92F5 0x92F6 0x92F7 \ + 0x92F8 0x92F9 0x92FA 0x92FB 0x92FC 0x92FD 0x92FE 0x92FF \ + 0x9300 0x9301 0x9302 0x9303 0x9304 0x9305 0x9306 0x9307 \ + 0x9308 0x9309 0x6D39 0x6D27 0x6D0C 0x6D43 0x6D48 0x6D07 \ + 0x6D04 0x6D19 0x6D0E 0x6D2B 0x6D4D 0x6D2E 0x6D35 0x6D1A \ + 0x6D4F 0x6D52 0x6D54 0x6D33 0x6D91 0x6D6F 0x6D9E 0x6DA0 \ + 0x6D5E 0x6D93 0x6D94 0x6D5C 0x6D60 0x6D7C 0x6D63 0x6E1A \ + 0x6DC7 0x6DC5 0x6DDE 0x6E0E 0x6DBF 0x6DE0 0x6E11 0x6DE6 +75 0x6DDD 0x6DD9 0x6E16 0x6DAB 0x6E0C 0x6DAE 0x6E2B 0x6E6E \ + 0x6E4E 0x6E6B 0x6EB2 0x6E5F 0x6E86 0x6E53 0x6E54 0x6E32 \ + 0x6E25 0x6E44 0x6EDF 0x6EB1 0x6E98 0x6EE0 0x6F2D 0x6EE2 \ + 0x6EA5 0x6EA7 0x6EBD 0x6EBB 0x6EB7 0x6ED7 0x6EB4 0x6ECF \ + 0x6E8F 0x6EC2 0x6E9F 0x6F62 0x6F46 0x6F47 0x6F24 0x6F15 \ + 0x6EF9 0x6F2F 0x6F36 0x6F4B 0x6F74 0x6F2A 0x6F09 0x6F29 \ + 0x6F89 0x6F8D 0x6F8C 0x6F78 0x6F72 0x6F7C 0x6F7A 0x6FD1 \ + 0x930A 0x930B 0x930C 0x930D 0x930E 0x930F 0x9310 0x9311 \ + 0x9312 0x9313 0x9314 0x9315 0x9316 0x9317 0x9318 0x9319 \ + 0x931A 0x931B 0x931C 0x931D 0x931E 0x931F 0x9320 0x9321 \ + 0x9322 0x9323 0x9324 0x9325 0x9326 0x9327 0x9328 0x9329 \ + 0x932A 0x932B 0x932C 0x932D 0x932E 0x932F 0x9330 0x9331 \ + 0x9332 0x9333 0x9334 0x9335 0x9336 0x9337 0x9338 0x9339 \ + 0x933A 0x933B 0x933C 0x933D 0x933F 0x9340 0x9341 0x9342 \ + 0x9343 0x9344 0x9345 0x9346 0x9347 0x9348 0x9349 0x934A \ + 0x934B 0x934C 0x934D 0x934E 0x934F 0x9350 0x9351 0x9352 \ + 0x9353 0x9354 0x9355 0x9356 0x9357 0x9358 0x9359 0x935A \ + 0x935B 0x935C 0x935D 0x935E 0x935F 0x9360 0x9361 0x9362 \ + 0x9363 0x9364 0x9365 0x9366 0x9367 0x9368 0x9369 0x936B \ + 0x6FC9 0x6FA7 0x6FB9 0x6FB6 0x6FC2 0x6FE1 0x6FEE 0x6FDE \ + 0x6FE0 0x6FEF 0x701A 0x7023 0x701B 0x7039 0x7035 0x704F \ + 0x705E 0x5B80 0x5B84 0x5B95 0x5B93 0x5BA5 0x5BB8 0x752F \ + 0x9A9E 0x6434 0x5BE4 0x5BEE 0x8930 0x5BF0 0x8E47 0x8B07 \ + 0x8FB6 0x8FD3 0x8FD5 0x8FE5 0x8FEE 0x8FE4 0x8FE9 0x8FE6 \ + 0x8FF3 0x8FE8 0x9005 0x9004 0x900B 0x9026 0x9011 0x900D \ + 0x9016 0x9021 0x9035 0x9036 0x902D 0x902F 0x9044 0x9051 \ + 0x9052 0x9050 0x9068 0x9058 0x9062 0x905B 0x66B9 0x9074 \ + 0x907D 0x9082 0x9088 0x9083 0x908B 0x5F50 0x5F57 0x5F56 \ + 0x5F58 0x5C3B 0x54AB 0x5C50 0x5C59 0x5B71 0x5C63 0x5C66 \ + 0x7FBC 0x5F2A 0x5F29 0x5F2D 0x8274 0x5F3C 0x9B3B 0x5C6E \ + 0x5981 0x5983 0x598D 0x59A9 0x59AA 0x59A3 0x936C 0x936D \ + 0x936E 0x936F 0x9370 0x9371 0x9372 0x9373 0x9374 0x9375 +76 0x9376 0x9377 0x9378 0x9379 0x937A 0x937B 0x937C 0x937D \ + 0x937E 0x937F 0x9380 0x9381 0x9382 0x9383 0x9384 0x9385 \ + 0x9386 0x9387 0x9388 0x9389 0x938A 0x938B 0x938C 0x938D \ + 0x938E 0x9390 0x9391 0x9392 0x9393 0x9394 0x9395 0x9396 \ + 0x9397 0x9398 0x9399 0x939A 0x939B 0x939C 0x939D 0x939E \ + 0x939F 0x93A0 0x93A1 0x93A2 0x93A3 0x93A4 0x93A5 0x93A6 \ + 0x93A7 0x93A8 0x93A9 0x93AA 0x93AB 0x93AC 0x93AD 0x93AE \ + 0x93AF 0x93B0 0x93B1 0x93B2 0x93B3 0x93B4 0x93B5 0x93B6 \ + 0x93B7 0x93B8 0x93B9 0x93BA 0x93BB 0x93BC 0x93BD 0x93BE \ + 0x93BF 0x93C0 0x93C1 0x93C2 0x93C3 0x93C4 0x93C5 0x93C6 \ + 0x93C7 0x93C8 0x93C9 0x93CB 0x93CC 0x93CD 0x5997 0x59CA \ + 0x59AB 0x599E 0x59A4 0x59D2 0x59B2 0x59AF 0x59D7 0x59BE \ + 0x5A05 0x5A06 0x59DD 0x5A08 0x59E3 0x59D8 0x59F9 0x5A0C \ + 0x5A09 0x5A32 0x5A34 0x5A11 0x5A23 0x5A13 0x5A40 0x5A67 \ + 0x5A4A 0x5A55 0x5A3C 0x5A62 0x5A75 0x80EC 0x5AAA 0x5A9B \ + 0x5A77 0x5A7A 0x5ABE 0x5AEB 0x5AB2 0x5AD2 0x5AD4 0x5AB8 \ + 0x5AE0 0x5AE3 0x5AF1 0x5AD6 0x5AE6 0x5AD8 0x5ADC 0x5B09 \ + 0x5B17 0x5B16 0x5B32 0x5B37 0x5B40 0x5C15 0x5C1C 0x5B5A \ + 0x5B65 0x5B73 0x5B51 0x5B53 0x5B62 0x9A75 0x9A77 0x9A78 \ + 0x9A7A 0x9A7F 0x9A7D 0x9A80 0x9A81 0x9A85 0x9A88 0x9A8A \ + 0x9A90 0x9A92 0x9A93 0x9A96 0x9A98 0x9A9B 0x9A9C 0x9A9D \ + 0x9A9F 0x9AA0 0x9AA2 0x9AA3 0x9AA5 0x9AA7 0x7E9F 0x7EA1 \ + 0x7EA3 0x7EA5 0x7EA8 0x7EA9 0x93CE 0x93CF 0x93D0 0x93D1 \ + 0x93D2 0x93D3 0x93D4 0x93D5 0x93D7 0x93D8 0x93D9 0x93DA \ + 0x93DB 0x93DC 0x93DD 0x93DE 0x93DF 0x93E0 0x93E1 0x93E2 \ + 0x93E3 0x93E4 0x93E5 0x93E6 0x93E7 0x93E8 0x93E9 0x93EA \ + 0x93EB 0x93EC 0x93ED 0x93EE 0x93EF 0x93F0 0x93F1 0x93F2 \ + 0x93F3 0x93F4 0x93F5 0x93F6 0x93F7 0x93F8 0x93F9 0x93FA \ + 0x93FB 0x93FC 0x93FD 0x93FE 0x93FF 0x9400 0x9401 0x9402 \ + 0x9403 0x9404 0x9405 0x9406 0x9407 0x9408 0x9409 0x940A \ + 0x940B 0x940C 0x940D 0x940E 0x940F 0x9410 0x9411 0x9412 \ + 0x9413 0x9414 0x9415 0x9416 0x9417 0x9418 0x9419 0x941A +77 0x941B 0x941C 0x941D 0x941E 0x941F 0x9420 0x9421 0x9422 \ + 0x9423 0x9424 0x9425 0x9426 0x9427 0x9428 0x9429 0x942A \ + 0x942B 0x942C 0x942D 0x942E 0x7EAD 0x7EB0 0x7EBE 0x7EC0 \ + 0x7EC1 0x7EC2 0x7EC9 0x7ECB 0x7ECC 0x7ED0 0x7ED4 0x7ED7 \ + 0x7EDB 0x7EE0 0x7EE1 0x7EE8 0x7EEB 0x7EEE 0x7EEF 0x7EF1 \ + 0x7EF2 0x7F0D 0x7EF6 0x7EFA 0x7EFB 0x7EFE 0x7F01 0x7F02 \ + 0x7F03 0x7F07 0x7F08 0x7F0B 0x7F0C 0x7F0F 0x7F11 0x7F12 \ + 0x7F17 0x7F19 0x7F1C 0x7F1B 0x7F1F 0x7F21 0x7F22 0x7F23 \ + 0x7F24 0x7F25 0x7F26 0x7F27 0x7F2A 0x7F2B 0x7F2C 0x7F2D \ + 0x7F2F 0x7F30 0x7F31 0x7F32 0x7F33 0x7F35 0x5E7A 0x757F \ + 0x5DDB 0x753E 0x9095 0x738E 0x7391 0x73AE 0x73A2 0x739F \ + 0x73CF 0x73C2 0x73D1 0x73B7 0x73B3 0x73C0 0x73C9 0x73C8 \ + 0x73E5 0x73D9 0x987C 0x740A 0x73E9 0x73E7 0x73DE 0x73BA \ + 0x73F2 0x740F 0x742A 0x745B 0x7426 0x7425 0x7428 0x7430 \ + 0x742E 0x742C 0x942F 0x9430 0x9431 0x9432 0x9433 0x9434 \ + 0x9435 0x9436 0x9437 0x9438 0x9439 0x943A 0x943B 0x943C \ + 0x943D 0x943F 0x9440 0x9441 0x9442 0x9443 0x9444 0x9445 \ + 0x9446 0x9447 0x9448 0x9449 0x944A 0x944B 0x944C 0x944D \ + 0x944E 0x944F 0x9450 0x9451 0x9452 0x9453 0x9454 0x9455 \ + 0x9456 0x9457 0x9458 0x9459 0x945A 0x945B 0x945C 0x945D \ + 0x945E 0x945F 0x9460 0x9461 0x9462 0x9463 0x9464 0x9465 \ + 0x9466 0x9467 0x9468 0x9469 0x946A 0x946C 0x946D 0x946E \ + 0x946F 0x9470 0x9471 0x9472 0x9473 0x9474 0x9475 0x9476 \ + 0x9477 0x9478 0x9479 0x947A 0x947B 0x947C 0x947D 0x947E \ + 0x947F 0x9480 0x9481 0x9482 0x9483 0x9484 0x9491 0x9496 \ + 0x9498 0x94C7 0x94CF 0x94D3 0x94D4 0x94DA 0x94E6 0x94FB \ + 0x951C 0x9520 0x741B 0x741A 0x7441 0x745C 0x7457 0x7455 \ + 0x7459 0x7477 0x746D 0x747E 0x749C 0x748E 0x7480 0x7481 \ + 0x7487 0x748B 0x749E 0x74A8 0x74A9 0x7490 0x74A7 0x74D2 \ + 0x74BA 0x97EA 0x97EB 0x97EC 0x674C 0x6753 0x675E 0x6748 \ + 0x6769 0x67A5 0x6787 0x676A 0x6773 0x6798 0x67A7 0x6775 \ + 0x67A8 0x679E 0x67AD 0x678B 0x6777 0x677C 0x67F0 0x6809 +78 0x67D8 0x680A 0x67E9 0x67B0 0x680C 0x67D9 0x67B5 0x67DA \ + 0x67B3 0x67DD 0x6800 0x67C3 0x67B8 0x67E2 0x680E 0x67C1 \ + 0x67FD 0x6832 0x6833 0x6860 0x6861 0x684E 0x6862 0x6844 \ + 0x6864 0x6883 0x681D 0x6855 0x6866 0x6841 0x6867 0x6840 \ + 0x683E 0x684A 0x6849 0x6829 0x68B5 0x688F 0x6874 0x6877 \ + 0x6893 0x686B 0x68C2 0x696E 0x68FC 0x691F 0x6920 0x68F9 \ + 0x9527 0x9533 0x953D 0x9543 0x9548 0x954B 0x9555 0x955A \ + 0x9560 0x956E 0x9574 0x9575 0x9577 0x9578 0x9579 0x957A \ + 0x957B 0x957C 0x957D 0x957E 0x9580 0x9581 0x9582 0x9583 \ + 0x9584 0x9585 0x9586 0x9587 0x9588 0x9589 0x958A 0x958B \ + 0x958C 0x958D 0x958E 0x958F 0x9590 0x9591 0x9592 0x9593 \ + 0x9594 0x9595 0x9596 0x9597 0x9598 0x9599 0x959A 0x959B \ + 0x959C 0x959D 0x959E 0x959F 0x95A0 0x95A1 0x95A2 0x95A3 \ + 0x95A4 0x95A5 0x95A6 0x95A7 0x95A8 0x95A9 0x95AA 0x95AB \ + 0x95AC 0x95AD 0x95AE 0x95AF 0x95B0 0x95B1 0x95B2 0x95B3 \ + 0x95B4 0x95B5 0x95B6 0x95B7 0x95B8 0x95B9 0x95BA 0x95BB \ + 0x95BC 0x95BD 0x95BE 0x95BF 0x95C0 0x95C1 0x95C2 0x95C3 \ + 0x95C4 0x95C5 0x95C6 0x95C7 0x95C8 0x95C9 0x95CA 0x95CB \ + 0x6924 0x68F0 0x690B 0x6901 0x6957 0x68E3 0x6910 0x6971 \ + 0x6939 0x6960 0x6942 0x695D 0x6984 0x696B 0x6980 0x6998 \ + 0x6978 0x6934 0x69CC 0x6987 0x6988 0x69CE 0x6989 0x6966 \ + 0x6963 0x6979 0x699B 0x69A7 0x69BB 0x69AB 0x69AD 0x69D4 \ + 0x69B1 0x69C1 0x69CA 0x69DF 0x6995 0x69E0 0x698D 0x69FF \ + 0x6A2F 0x69ED 0x6A17 0x6A18 0x6A65 0x69F2 0x6A44 0x6A3E \ + 0x6AA0 0x6A50 0x6A5B 0x6A35 0x6A8E 0x6A79 0x6A3D 0x6A28 \ + 0x6A58 0x6A7C 0x6A91 0x6A90 0x6AA9 0x6A97 0x6AAB 0x7337 \ + 0x7352 0x6B81 0x6B82 0x6B87 0x6B84 0x6B92 0x6B93 0x6B8D \ + 0x6B9A 0x6B9B 0x6BA1 0x6BAA 0x8F6B 0x8F6D 0x8F71 0x8F72 \ + 0x8F73 0x8F75 0x8F76 0x8F78 0x8F77 0x8F79 0x8F7A 0x8F7C \ + 0x8F7E 0x8F81 0x8F82 0x8F84 0x8F87 0x8F8B 0x95CC 0x95CD \ + 0x95CE 0x95CF 0x95D0 0x95D1 0x95D2 0x95D3 0x95D4 0x95D5 \ + 0x95D6 0x95D7 0x95D8 0x95D9 0x95DA 0x95DB 0x95DC 0x95DD +79 0x95DE 0x95DF 0x95E0 0x95E1 0x95E2 0x95E3 0x95E4 0x95E5 \ + 0x95E6 0x95E7 0x95EC 0x95FF 0x9607 0x9613 0x9618 0x961B \ + 0x961E 0x9620 0x9623 0x9624 0x9625 0x9626 0x9627 0x9628 \ + 0x9629 0x962B 0x962C 0x962D 0x962F 0x9630 0x9637 0x9638 \ + 0x9639 0x963A 0x963E 0x9641 0x9643 0x964A 0x964E 0x964F \ + 0x9651 0x9652 0x9653 0x9656 0x9657 0x9658 0x9659 0x965A \ + 0x965C 0x965D 0x965E 0x9660 0x9663 0x9665 0x9666 0x966B \ + 0x966D 0x966E 0x966F 0x9670 0x9671 0x9673 0x9678 0x9679 \ + 0x967A 0x967B 0x967C 0x967D 0x967E 0x967F 0x9680 0x9681 \ + 0x9682 0x9683 0x9684 0x9687 0x9689 0x968A 0x8F8D 0x8F8E \ + 0x8F8F 0x8F98 0x8F9A 0x8ECE 0x620B 0x6217 0x621B 0x621F \ + 0x6222 0x6221 0x6225 0x6224 0x622C 0x81E7 0x74EF 0x74F4 \ + 0x74FF 0x750F 0x7511 0x7513 0x6534 0x65EE 0x65EF 0x65F0 \ + 0x660A 0x6619 0x6772 0x6603 0x6615 0x6600 0x7085 0x66F7 \ + 0x661D 0x6634 0x6631 0x6636 0x6635 0x8006 0x665F 0x6654 \ + 0x6641 0x664F 0x6656 0x6661 0x6657 0x6677 0x6684 0x668C \ + 0x66A7 0x669D 0x66BE 0x66DB 0x66DC 0x66E6 0x66E9 0x8D32 \ + 0x8D33 0x8D36 0x8D3B 0x8D3D 0x8D40 0x8D45 0x8D46 0x8D48 \ + 0x8D49 0x8D47 0x8D4D 0x8D55 0x8D59 0x89C7 0x89CA 0x89CB \ + 0x89CC 0x89CE 0x89CF 0x89D0 0x89D1 0x726E 0x729F 0x725D \ + 0x7266 0x726F 0x727E 0x727F 0x7284 0x728B 0x728D 0x728F \ + 0x7292 0x6308 0x6332 0x63B0 0x968C 0x968E 0x9691 0x9692 \ + 0x9693 0x9695 0x9696 0x969A 0x969B 0x969D 0x969E 0x969F \ + 0x96A0 0x96A1 0x96A2 0x96A3 0x96A4 0x96A5 0x96A6 0x96A8 \ + 0x96A9 0x96AA 0x96AB 0x96AC 0x96AD 0x96AE 0x96AF 0x96B1 \ + 0x96B2 0x96B4 0x96B5 0x96B7 0x96B8 0x96BA 0x96BB 0x96BF \ + 0x96C2 0x96C3 0x96C8 0x96CA 0x96CB 0x96D0 0x96D1 0x96D3 \ + 0x96D4 0x96D6 0x96D7 0x96D8 0x96D9 0x96DA 0x96DB 0x96DC \ + 0x96DD 0x96DE 0x96DF 0x96E1 0x96E2 0x96E3 0x96E4 0x96E5 \ + 0x96E6 0x96E7 0x96EB 0x96EC 0x96ED 0x96EE 0x96F0 0x96F1 \ + 0x96F2 0x96F4 0x96F5 0x96F8 0x96FA 0x96FB 0x96FC 0x96FD \ + 0x96FF 0x9702 0x9703 0x9705 0x970A 0x970B 0x970C 0x9710 +80 0x9711 0x9712 0x9714 0x9715 0x9717 0x9718 0x9719 0x971A \ + 0x971B 0x971D 0x971F 0x9720 0x643F 0x64D8 0x8004 0x6BEA \ + 0x6BF3 0x6BFD 0x6BF5 0x6BF9 0x6C05 0x6C07 0x6C06 0x6C0D \ + 0x6C15 0x6C18 0x6C19 0x6C1A 0x6C21 0x6C29 0x6C24 0x6C2A \ + 0x6C32 0x6535 0x6555 0x656B 0x724D 0x7252 0x7256 0x7230 \ + 0x8662 0x5216 0x809F 0x809C 0x8093 0x80BC 0x670A 0x80BD \ + 0x80B1 0x80AB 0x80AD 0x80B4 0x80B7 0x80E7 0x80E8 0x80E9 \ + 0x80EA 0x80DB 0x80C2 0x80C4 0x80D9 0x80CD 0x80D7 0x6710 \ + 0x80DD 0x80EB 0x80F1 0x80F4 0x80ED 0x810D 0x810E 0x80F2 \ + 0x80FC 0x6715 0x8112 0x8C5A 0x8136 0x811E 0x812C 0x8118 \ + 0x8132 0x8148 0x814C 0x8153 0x8174 0x8159 0x815A 0x8171 \ + 0x8160 0x8169 0x817C 0x817D 0x816D 0x8167 0x584D 0x5AB5 \ + 0x8188 0x8182 0x8191 0x6ED5 0x81A3 0x81AA 0x81CC 0x6726 \ + 0x81CA 0x81BB 0x9721 0x9722 0x9723 0x9724 0x9725 0x9726 \ + 0x9727 0x9728 0x9729 0x972B 0x972C 0x972E 0x972F 0x9731 \ + 0x9733 0x9734 0x9735 0x9736 0x9737 0x973A 0x973B 0x973C \ + 0x973D 0x973F 0x9740 0x9741 0x9742 0x9743 0x9744 0x9745 \ + 0x9746 0x9747 0x9748 0x9749 0x974A 0x974B 0x974C 0x974D \ + 0x974E 0x974F 0x9750 0x9751 0x9754 0x9755 0x9757 0x9758 \ + 0x975A 0x975C 0x975D 0x975F 0x9763 0x9764 0x9766 0x9767 \ + 0x9768 0x976A 0x976B 0x976C 0x976D 0x976E 0x976F 0x9770 \ + 0x9771 0x9772 0x9775 0x9777 0x9778 0x9779 0x977A 0x977B \ + 0x977D 0x977E 0x977F 0x9780 0x9781 0x9782 0x9783 0x9784 \ + 0x9786 0x9787 0x9788 0x9789 0x978A 0x978C 0x978E 0x978F \ + 0x9790 0x9793 0x9795 0x9796 0x9797 0x9799 0x979A 0x979B \ + 0x979C 0x979D 0x81C1 0x81A6 0x6B24 0x6B37 0x6B39 0x6B43 \ + 0x6B46 0x6B59 0x98D1 0x98D2 0x98D3 0x98D5 0x98D9 0x98DA \ + 0x6BB3 0x5F40 0x6BC2 0x89F3 0x6590 0x9F51 0x6593 0x65BC \ + 0x65C6 0x65C4 0x65C3 0x65CC 0x65CE 0x65D2 0x65D6 0x7080 \ + 0x709C 0x7096 0x709D 0x70BB 0x70C0 0x70B7 0x70AB 0x70B1 \ + 0x70E8 0x70CA 0x7110 0x7113 0x7116 0x712F 0x7131 0x7173 \ + 0x715C 0x7168 0x7145 0x7172 0x714A 0x7178 0x717A 0x7198 +81 0x71B3 0x71B5 0x71A8 0x71A0 0x71E0 0x71D4 0x71E7 0x71F9 \ + 0x721D 0x7228 0x706C 0x7118 0x7166 0x71B9 0x623E 0x623D \ + 0x6243 0x6248 0x6249 0x793B 0x7940 0x7946 0x7949 0x795B \ + 0x795C 0x7953 0x795A 0x7962 0x7957 0x7960 0x796F 0x7967 \ + 0x797A 0x7985 0x798A 0x799A 0x79A7 0x79B3 0x5FD1 0x5FD0 \ + 0x979E 0x979F 0x97A1 0x97A2 0x97A4 0x97A5 0x97A6 0x97A7 \ + 0x97A8 0x97A9 0x97AA 0x97AC 0x97AE 0x97B0 0x97B1 0x97B3 \ + 0x97B5 0x97B6 0x97B7 0x97B8 0x97B9 0x97BA 0x97BB 0x97BC \ + 0x97BD 0x97BE 0x97BF 0x97C0 0x97C1 0x97C2 0x97C3 0x97C4 \ + 0x97C5 0x97C6 0x97C7 0x97C8 0x97C9 0x97CA 0x97CB 0x97CC \ + 0x97CD 0x97CE 0x97CF 0x97D0 0x97D1 0x97D2 0x97D3 0x97D4 \ + 0x97D5 0x97D6 0x97D7 0x97D8 0x97D9 0x97DA 0x97DB 0x97DC \ + 0x97DD 0x97DE 0x97DF 0x97E0 0x97E1 0x97E2 0x97E3 0x97E4 \ + 0x97E5 0x97E8 0x97EE 0x97EF 0x97F0 0x97F1 0x97F2 0x97F4 \ + 0x97F7 0x97F8 0x97F9 0x97FA 0x97FB 0x97FC 0x97FD 0x97FE \ + 0x97FF 0x9800 0x9801 0x9802 0x9803 0x9804 0x9805 0x9806 \ + 0x9807 0x9808 0x9809 0x980A 0x980B 0x980C 0x980D 0x980E \ + 0x603C 0x605D 0x605A 0x6067 0x6041 0x6059 0x6063 0x60AB \ + 0x6106 0x610D 0x615D 0x61A9 0x619D 0x61CB 0x61D1 0x6206 \ + 0x8080 0x807F 0x6C93 0x6CF6 0x6DFC 0x77F6 0x77F8 0x7800 \ + 0x7809 0x7817 0x7818 0x7811 0x65AB 0x782D 0x781C 0x781D \ + 0x7839 0x783A 0x783B 0x781F 0x783C 0x7825 0x782C 0x7823 \ + 0x7829 0x784E 0x786D 0x7856 0x7857 0x7826 0x7850 0x7847 \ + 0x784C 0x786A 0x789B 0x7893 0x789A 0x7887 0x789C 0x78A1 \ + 0x78A3 0x78B2 0x78B9 0x78A5 0x78D4 0x78D9 0x78C9 0x78EC \ + 0x78F2 0x7905 0x78F4 0x7913 0x7924 0x791E 0x7934 0x9F9B \ + 0x9EF9 0x9EFB 0x9EFC 0x76F1 0x7704 0x770D 0x76F9 0x7707 \ + 0x7708 0x771A 0x7722 0x7719 0x772D 0x7726 0x7735 0x7738 \ + 0x7750 0x7751 0x7747 0x7743 0x775A 0x7768 0x980F 0x9810 \ + 0x9811 0x9812 0x9813 0x9814 0x9815 0x9816 0x9817 0x9818 \ + 0x9819 0x981A 0x981B 0x981C 0x981D 0x981E 0x981F 0x9820 \ + 0x9821 0x9822 0x9823 0x9824 0x9825 0x9826 0x9827 0x9828 +82 0x9829 0x982A 0x982B 0x982C 0x982D 0x982E 0x982F 0x9830 \ + 0x9831 0x9832 0x9833 0x9834 0x9835 0x9836 0x9837 0x9838 \ + 0x9839 0x983A 0x983B 0x983C 0x983D 0x983E 0x983F 0x9840 \ + 0x9841 0x9842 0x9843 0x9844 0x9845 0x9846 0x9847 0x9848 \ + 0x9849 0x984A 0x984B 0x984C 0x984D 0x984E 0x984F 0x9850 \ + 0x9851 0x9852 0x9853 0x9854 0x9855 0x9856 0x9857 0x9858 \ + 0x9859 0x985A 0x985B 0x985C 0x985D 0x985E 0x985F 0x9860 \ + 0x9861 0x9862 0x9863 0x9864 0x9865 0x9866 0x9867 0x9868 \ + 0x9869 0x986A 0x986B 0x986C 0x986D 0x986E 0x7762 0x7765 \ + 0x777F 0x778D 0x777D 0x7780 0x778C 0x7791 0x779F 0x77A0 \ + 0x77B0 0x77B5 0x77BD 0x753A 0x7540 0x754E 0x754B 0x7548 \ + 0x755B 0x7572 0x7579 0x7583 0x7F58 0x7F61 0x7F5F 0x8A48 \ + 0x7F68 0x7F74 0x7F71 0x7F79 0x7F81 0x7F7E 0x76CD 0x76E5 \ + 0x8832 0x9485 0x9486 0x9487 0x948B 0x948A 0x948C 0x948D \ + 0x948F 0x9490 0x9494 0x9497 0x9495 0x949A 0x949B 0x949C \ + 0x94A3 0x94A4 0x94AB 0x94AA 0x94AD 0x94AC 0x94AF 0x94B0 \ + 0x94B2 0x94B4 0x94B6 0x94B7 0x94B8 0x94B9 0x94BA 0x94BC \ + 0x94BD 0x94BF 0x94C4 0x94C8 0x94C9 0x94CA 0x94CB 0x94CC \ + 0x94CD 0x94CE 0x94D0 0x94D1 0x94D2 0x94D5 0x94D6 0x94D7 \ + 0x94D9 0x94D8 0x94DB 0x94DE 0x94DF 0x94E0 0x94E2 0x94E4 \ + 0x94E5 0x94E7 0x94E8 0x94EA 0x986F 0x9870 0x9871 0x9872 \ + 0x9873 0x9874 0x988B 0x988E 0x9892 0x9895 0x9899 0x98A3 \ + 0x98A8 0x98A9 0x98AA 0x98AB 0x98AC 0x98AD 0x98AE 0x98AF \ + 0x98B0 0x98B1 0x98B2 0x98B3 0x98B4 0x98B5 0x98B6 0x98B7 \ + 0x98B8 0x98B9 0x98BA 0x98BB 0x98BC 0x98BD 0x98BE 0x98BF \ + 0x98C0 0x98C1 0x98C2 0x98C3 0x98C4 0x98C5 0x98C6 0x98C7 \ + 0x98C8 0x98C9 0x98CA 0x98CB 0x98CC 0x98CD 0x98CF 0x98D0 \ + 0x98D4 0x98D6 0x98D7 0x98DB 0x98DC 0x98DD 0x98E0 0x98E1 \ + 0x98E2 0x98E3 0x98E4 0x98E5 0x98E6 0x98E9 0x98EA 0x98EB \ + 0x98EC 0x98ED 0x98EE 0x98EF 0x98F0 0x98F1 0x98F2 0x98F3 \ + 0x98F4 0x98F5 0x98F6 0x98F7 0x98F8 0x98F9 0x98FA 0x98FB \ + 0x98FC 0x98FD 0x98FE 0x98FF 0x9900 0x9901 0x9902 0x9903 +83 0x9904 0x9905 0x9906 0x9907 0x94E9 0x94EB 0x94EE 0x94EF \ + 0x94F3 0x94F4 0x94F5 0x94F7 0x94F9 0x94FC 0x94FD 0x94FF \ + 0x9503 0x9502 0x9506 0x9507 0x9509 0x950A 0x950D 0x950E \ + 0x950F 0x9512 0x9513 0x9514 0x9515 0x9516 0x9518 0x951B \ + 0x951D 0x951E 0x951F 0x9522 0x952A 0x952B 0x9529 0x952C \ + 0x9531 0x9532 0x9534 0x9536 0x9537 0x9538 0x953C 0x953E \ + 0x953F 0x9542 0x9535 0x9544 0x9545 0x9546 0x9549 0x954C \ + 0x954E 0x954F 0x9552 0x9553 0x9554 0x9556 0x9557 0x9558 \ + 0x9559 0x955B 0x955E 0x955F 0x955D 0x9561 0x9562 0x9564 \ + 0x9565 0x9566 0x9567 0x9568 0x9569 0x956A 0x956B 0x956C \ + 0x956F 0x9571 0x9572 0x9573 0x953A 0x77E7 0x77EC 0x96C9 \ + 0x79D5 0x79ED 0x79E3 0x79EB 0x7A06 0x5D47 0x7A03 0x7A02 \ + 0x7A1E 0x7A14 0x9908 0x9909 0x990A 0x990B 0x990C 0x990E \ + 0x990F 0x9911 0x9912 0x9913 0x9914 0x9915 0x9916 0x9917 \ + 0x9918 0x9919 0x991A 0x991B 0x991C 0x991D 0x991E 0x991F \ + 0x9920 0x9921 0x9922 0x9923 0x9924 0x9925 0x9926 0x9927 \ + 0x9928 0x9929 0x992A 0x992B 0x992C 0x992D 0x992F 0x9930 \ + 0x9931 0x9932 0x9933 0x9934 0x9935 0x9936 0x9937 0x9938 \ + 0x9939 0x993A 0x993B 0x993C 0x993D 0x993E 0x993F 0x9940 \ + 0x9941 0x9942 0x9943 0x9944 0x9945 0x9946 0x9947 0x9948 \ + 0x9949 0x994A 0x994B 0x994C 0x994D 0x994E 0x994F 0x9950 \ + 0x9951 0x9952 0x9953 0x9956 0x9957 0x9958 0x9959 0x995A \ + 0x995B 0x995C 0x995D 0x995E 0x995F 0x9960 0x9961 0x9962 \ + 0x9964 0x9966 0x9973 0x9978 0x9979 0x997B 0x997E 0x9982 \ + 0x9983 0x9989 0x7A39 0x7A37 0x7A51 0x9ECF 0x99A5 0x7A70 \ + 0x7688 0x768E 0x7693 0x7699 0x76A4 0x74DE 0x74E0 0x752C \ + 0x9E20 0x9E22 0x9E28 0x9E29 0x9E2A 0x9E2B 0x9E2C 0x9E32 \ + 0x9E31 0x9E36 0x9E38 0x9E37 0x9E39 0x9E3A 0x9E3E 0x9E41 \ + 0x9E42 0x9E44 0x9E46 0x9E47 0x9E48 0x9E49 0x9E4B 0x9E4C \ + 0x9E4E 0x9E51 0x9E55 0x9E57 0x9E5A 0x9E5B 0x9E5C 0x9E5E \ + 0x9E63 0x9E66 0x9E67 0x9E68 0x9E69 0x9E6A 0x9E6B 0x9E6C \ + 0x9E71 0x9E6D 0x9E73 0x7592 0x7594 0x7596 0x75A0 0x759D +84 0x75AC 0x75A3 0x75B3 0x75B4 0x75B8 0x75C4 0x75B1 0x75B0 \ + 0x75C3 0x75C2 0x75D6 0x75CD 0x75E3 0x75E8 0x75E6 0x75E4 \ + 0x75EB 0x75E7 0x7603 0x75F1 0x75FC 0x75FF 0x7610 0x7600 \ + 0x7605 0x760C 0x7617 0x760A 0x7625 0x7618 0x7615 0x7619 \ + 0x998C 0x998E 0x999A 0x999B 0x999C 0x999D 0x999E 0x999F \ + 0x99A0 0x99A1 0x99A2 0x99A3 0x99A4 0x99A6 0x99A7 0x99A9 \ + 0x99AA 0x99AB 0x99AC 0x99AD 0x99AE 0x99AF 0x99B0 0x99B1 \ + 0x99B2 0x99B3 0x99B4 0x99B5 0x99B6 0x99B7 0x99B8 0x99B9 \ + 0x99BA 0x99BB 0x99BC 0x99BD 0x99BE 0x99BF 0x99C0 0x99C1 \ + 0x99C2 0x99C3 0x99C4 0x99C5 0x99C6 0x99C7 0x99C8 0x99C9 \ + 0x99CA 0x99CB 0x99CC 0x99CD 0x99CE 0x99CF 0x99D0 0x99D1 \ + 0x99D2 0x99D3 0x99D4 0x99D5 0x99D6 0x99D7 0x99D8 0x99D9 \ + 0x99DA 0x99DB 0x99DC 0x99DD 0x99DE 0x99DF 0x99E0 0x99E1 \ + 0x99E2 0x99E3 0x99E4 0x99E5 0x99E6 0x99E7 0x99E8 0x99E9 \ + 0x99EA 0x99EB 0x99EC 0x99ED 0x99EE 0x99EF 0x99F0 0x99F1 \ + 0x99F2 0x99F3 0x99F4 0x99F5 0x99F6 0x99F7 0x99F8 0x99F9 \ + 0x761B 0x763C 0x7622 0x7620 0x7640 0x762D 0x7630 0x763F \ + 0x7635 0x7643 0x763E 0x7633 0x764D 0x765E 0x7654 0x765C \ + 0x7656 0x766B 0x766F 0x7FCA 0x7AE6 0x7A78 0x7A79 0x7A80 \ + 0x7A86 0x7A88 0x7A95 0x7AA6 0x7AA0 0x7AAC 0x7AA8 0x7AAD \ + 0x7AB3 0x8864 0x8869 0x8872 0x887D 0x887F 0x8882 0x88A2 \ + 0x88C6 0x88B7 0x88BC 0x88C9 0x88E2 0x88CE 0x88E3 0x88E5 \ + 0x88F1 0x891A 0x88FC 0x88E8 0x88FE 0x88F0 0x8921 0x8919 \ + 0x8913 0x891B 0x890A 0x8934 0x892B 0x8936 0x8941 0x8966 \ + 0x897B 0x758B 0x80E5 0x76B2 0x76B4 0x77DC 0x8012 0x8014 \ + 0x8016 0x801C 0x8020 0x8022 0x8025 0x8026 0x8027 0x8029 \ + 0x8028 0x8031 0x800B 0x8035 0x8043 0x8046 0x804D 0x8052 \ + 0x8069 0x8071 0x8983 0x9878 0x9880 0x9883 0x99FA 0x99FB \ + 0x99FC 0x99FD 0x99FE 0x99FF 0x9A00 0x9A01 0x9A02 0x9A03 \ + 0x9A04 0x9A05 0x9A06 0x9A07 0x9A08 0x9A09 0x9A0A 0x9A0B \ + 0x9A0C 0x9A0D 0x9A0E 0x9A0F 0x9A10 0x9A11 0x9A12 0x9A13 \ + 0x9A14 0x9A15 0x9A16 0x9A17 0x9A18 0x9A19 0x9A1A 0x9A1B +85 0x9A1C 0x9A1D 0x9A1E 0x9A1F 0x9A20 0x9A21 0x9A22 0x9A23 \ + 0x9A24 0x9A25 0x9A26 0x9A27 0x9A28 0x9A29 0x9A2A 0x9A2B \ + 0x9A2C 0x9A2D 0x9A2E 0x9A2F 0x9A30 0x9A31 0x9A32 0x9A33 \ + 0x9A34 0x9A35 0x9A36 0x9A37 0x9A38 0x9A39 0x9A3A 0x9A3B \ + 0x9A3C 0x9A3D 0x9A3E 0x9A3F 0x9A40 0x9A41 0x9A42 0x9A43 \ + 0x9A44 0x9A45 0x9A46 0x9A47 0x9A48 0x9A49 0x9A4A 0x9A4B \ + 0x9A4C 0x9A4D 0x9A4E 0x9A4F 0x9A50 0x9A51 0x9A52 0x9A53 \ + 0x9A54 0x9A55 0x9A56 0x9A57 0x9A58 0x9A59 0x9889 0x988C \ + 0x988D 0x988F 0x9894 0x989A 0x989B 0x989E 0x989F 0x98A1 \ + 0x98A2 0x98A5 0x98A6 0x864D 0x8654 0x866C 0x866E 0x867F \ + 0x867A 0x867C 0x867B 0x86A8 0x868D 0x868B 0x86AC 0x869D \ + 0x86A7 0x86A3 0x86AA 0x8693 0x86A9 0x86B6 0x86C4 0x86B5 \ + 0x86CE 0x86B0 0x86BA 0x86B1 0x86AF 0x86C9 0x86CF 0x86B4 \ + 0x86E9 0x86F1 0x86F2 0x86ED 0x86F3 0x86D0 0x8713 0x86DE \ + 0x86F4 0x86DF 0x86D8 0x86D1 0x8703 0x8707 0x86F8 0x8708 \ + 0x870A 0x870D 0x8709 0x8723 0x873B 0x871E 0x8725 0x872E \ + 0x871A 0x873E 0x8748 0x8734 0x8731 0x8729 0x8737 0x873F \ + 0x8782 0x8722 0x877D 0x877E 0x877B 0x8760 0x8770 0x874C \ + 0x876E 0x878B 0x8753 0x8763 0x877C 0x8764 0x8759 0x8765 \ + 0x8793 0x87AF 0x87A8 0x87D2 0x9A5A 0x9A5B 0x9A5C 0x9A5D \ + 0x9A5E 0x9A5F 0x9A60 0x9A61 0x9A62 0x9A63 0x9A64 0x9A65 \ + 0x9A66 0x9A67 0x9A68 0x9A69 0x9A6A 0x9A6B 0x9A72 0x9A83 \ + 0x9A89 0x9A8D 0x9A8E 0x9A94 0x9A95 0x9A99 0x9AA6 0x9AA9 \ + 0x9AAA 0x9AAB 0x9AAC 0x9AAD 0x9AAE 0x9AAF 0x9AB2 0x9AB3 \ + 0x9AB4 0x9AB5 0x9AB9 0x9ABB 0x9ABD 0x9ABE 0x9ABF 0x9AC3 \ + 0x9AC4 0x9AC6 0x9AC7 0x9AC8 0x9AC9 0x9ACA 0x9ACD 0x9ACE \ + 0x9ACF 0x9AD0 0x9AD2 0x9AD4 0x9AD5 0x9AD6 0x9AD7 0x9AD9 \ + 0x9ADA 0x9ADB 0x9ADC 0x9ADD 0x9ADE 0x9AE0 0x9AE2 0x9AE3 \ + 0x9AE4 0x9AE5 0x9AE7 0x9AE8 0x9AE9 0x9AEA 0x9AEC 0x9AEE \ + 0x9AF0 0x9AF1 0x9AF2 0x9AF3 0x9AF4 0x9AF5 0x9AF6 0x9AF7 \ + 0x9AF8 0x9AFA 0x9AFC 0x9AFD 0x9AFE 0x9AFF 0x9B00 0x9B01 \ + 0x9B02 0x9B04 0x9B05 0x9B06 0x87C6 0x8788 0x8785 0x87AD +86 0x8797 0x8783 0x87AB 0x87E5 0x87AC 0x87B5 0x87B3 0x87CB \ + 0x87D3 0x87BD 0x87D1 0x87C0 0x87CA 0x87DB 0x87EA 0x87E0 \ + 0x87EE 0x8816 0x8813 0x87FE 0x880A 0x881B 0x8821 0x8839 \ + 0x883C 0x7F36 0x7F42 0x7F44 0x7F45 0x8210 0x7AFA 0x7AFD \ + 0x7B08 0x7B03 0x7B04 0x7B15 0x7B0A 0x7B2B 0x7B0F 0x7B47 \ + 0x7B38 0x7B2A 0x7B19 0x7B2E 0x7B31 0x7B20 0x7B25 0x7B24 \ + 0x7B33 0x7B3E 0x7B1E 0x7B58 0x7B5A 0x7B45 0x7B75 0x7B4C \ + 0x7B5D 0x7B60 0x7B6E 0x7B7B 0x7B62 0x7B72 0x7B71 0x7B90 \ + 0x7BA6 0x7BA7 0x7BB8 0x7BAC 0x7B9D 0x7BA8 0x7B85 0x7BAA \ + 0x7B9C 0x7BA2 0x7BAB 0x7BB4 0x7BD1 0x7BC1 0x7BCC 0x7BDD \ + 0x7BDA 0x7BE5 0x7BE6 0x7BEA 0x7C0C 0x7BFE 0x7BFC 0x7C0F \ + 0x7C16 0x7C0B 0x9B07 0x9B09 0x9B0A 0x9B0B 0x9B0C 0x9B0D \ + 0x9B0E 0x9B10 0x9B11 0x9B12 0x9B14 0x9B15 0x9B16 0x9B17 \ + 0x9B18 0x9B19 0x9B1A 0x9B1B 0x9B1C 0x9B1D 0x9B1E 0x9B20 \ + 0x9B21 0x9B22 0x9B24 0x9B25 0x9B26 0x9B27 0x9B28 0x9B29 \ + 0x9B2A 0x9B2B 0x9B2C 0x9B2D 0x9B2E 0x9B30 0x9B31 0x9B33 \ + 0x9B34 0x9B35 0x9B36 0x9B37 0x9B38 0x9B39 0x9B3A 0x9B3D \ + 0x9B3E 0x9B3F 0x9B40 0x9B46 0x9B4A 0x9B4B 0x9B4C 0x9B4E \ + 0x9B50 0x9B52 0x9B53 0x9B55 0x9B56 0x9B57 0x9B58 0x9B59 \ + 0x9B5A 0x9B5B 0x9B5C 0x9B5D 0x9B5E 0x9B5F 0x9B60 0x9B61 \ + 0x9B62 0x9B63 0x9B64 0x9B65 0x9B66 0x9B67 0x9B68 0x9B69 \ + 0x9B6A 0x9B6B 0x9B6C 0x9B6D 0x9B6E 0x9B6F 0x9B70 0x9B71 \ + 0x9B72 0x9B73 0x9B74 0x9B75 0x9B76 0x9B77 0x9B78 0x9B79 \ + 0x9B7A 0x9B7B 0x7C1F 0x7C2A 0x7C26 0x7C38 0x7C41 0x7C40 \ + 0x81FE 0x8201 0x8202 0x8204 0x81EC 0x8844 0x8221 0x8222 \ + 0x8223 0x822D 0x822F 0x8228 0x822B 0x8238 0x823B 0x8233 \ + 0x8234 0x823E 0x8244 0x8249 0x824B 0x824F 0x825A 0x825F \ + 0x8268 0x887E 0x8885 0x8888 0x88D8 0x88DF 0x895E 0x7F9D \ + 0x7F9F 0x7FA7 0x7FAF 0x7FB0 0x7FB2 0x7C7C 0x6549 0x7C91 \ + 0x7C9D 0x7C9C 0x7C9E 0x7CA2 0x7CB2 0x7CBC 0x7CBD 0x7CC1 \ + 0x7CC7 0x7CCC 0x7CCD 0x7CC8 0x7CC5 0x7CD7 0x7CE8 0x826E \ + 0x66A8 0x7FBF 0x7FCE 0x7FD5 0x7FE5 0x7FE1 0x7FE6 0x7FE9 +87 0x7FEE 0x7FF3 0x7CF8 0x7D77 0x7DA6 0x7DAE 0x7E47 0x7E9B \ + 0x9EB8 0x9EB4 0x8D73 0x8D84 0x8D94 0x8D91 0x8DB1 0x8D67 \ + 0x8D6D 0x8C47 0x8C49 0x914A 0x9150 0x914E 0x914F 0x9164 \ + 0x9B7C 0x9B7D 0x9B7E 0x9B7F 0x9B80 0x9B81 0x9B82 0x9B83 \ + 0x9B84 0x9B85 0x9B86 0x9B87 0x9B88 0x9B89 0x9B8A 0x9B8B \ + 0x9B8C 0x9B8D 0x9B8E 0x9B8F 0x9B90 0x9B91 0x9B92 0x9B93 \ + 0x9B94 0x9B95 0x9B96 0x9B97 0x9B98 0x9B99 0x9B9A 0x9B9B \ + 0x9B9C 0x9B9D 0x9B9E 0x9B9F 0x9BA0 0x9BA1 0x9BA2 0x9BA3 \ + 0x9BA4 0x9BA5 0x9BA6 0x9BA7 0x9BA8 0x9BA9 0x9BAA 0x9BAB \ + 0x9BAC 0x9BAD 0x9BAE 0x9BAF 0x9BB0 0x9BB1 0x9BB2 0x9BB3 \ + 0x9BB4 0x9BB5 0x9BB6 0x9BB7 0x9BB8 0x9BB9 0x9BBA 0x9BBB \ + 0x9BBC 0x9BBD 0x9BBE 0x9BBF 0x9BC0 0x9BC1 0x9BC2 0x9BC3 \ + 0x9BC4 0x9BC5 0x9BC6 0x9BC7 0x9BC8 0x9BC9 0x9BCA 0x9BCB \ + 0x9BCC 0x9BCD 0x9BCE 0x9BCF 0x9BD0 0x9BD1 0x9BD2 0x9BD3 \ + 0x9BD4 0x9BD5 0x9BD6 0x9BD7 0x9BD8 0x9BD9 0x9BDA 0x9BDB \ + 0x9162 0x9161 0x9170 0x9169 0x916F 0x917D 0x917E 0x9172 \ + 0x9174 0x9179 0x918C 0x9185 0x9190 0x918D 0x9191 0x91A2 \ + 0x91A3 0x91AA 0x91AD 0x91AE 0x91AF 0x91B5 0x91B4 0x91BA \ + 0x8C55 0x9E7E 0x8DB8 0x8DEB 0x8E05 0x8E59 0x8E69 0x8DB5 \ + 0x8DBF 0x8DBC 0x8DBA 0x8DC4 0x8DD6 0x8DD7 0x8DDA 0x8DDE \ + 0x8DCE 0x8DCF 0x8DDB 0x8DC6 0x8DEC 0x8DF7 0x8DF8 0x8DE3 \ + 0x8DF9 0x8DFB 0x8DE4 0x8E09 0x8DFD 0x8E14 0x8E1D 0x8E1F \ + 0x8E2C 0x8E2E 0x8E23 0x8E2F 0x8E3A 0x8E40 0x8E39 0x8E35 \ + 0x8E3D 0x8E31 0x8E49 0x8E41 0x8E42 0x8E51 0x8E52 0x8E4A \ + 0x8E70 0x8E76 0x8E7C 0x8E6F 0x8E74 0x8E85 0x8E8F 0x8E94 \ + 0x8E90 0x8E9C 0x8E9E 0x8C78 0x8C82 0x8C8A 0x8C85 0x8C98 \ + 0x8C94 0x659B 0x89D6 0x89DE 0x89DA 0x89DC 0x9BDC 0x9BDD \ + 0x9BDE 0x9BDF 0x9BE0 0x9BE1 0x9BE2 0x9BE3 0x9BE4 0x9BE5 \ + 0x9BE6 0x9BE7 0x9BE8 0x9BE9 0x9BEA 0x9BEB 0x9BEC 0x9BED \ + 0x9BEE 0x9BEF 0x9BF0 0x9BF1 0x9BF2 0x9BF3 0x9BF4 0x9BF5 \ + 0x9BF6 0x9BF7 0x9BF8 0x9BF9 0x9BFA 0x9BFB 0x9BFC 0x9BFD \ + 0x9BFE 0x9BFF 0x9C00 0x9C01 0x9C02 0x9C03 0x9C04 0x9C05 +88 0x9C06 0x9C07 0x9C08 0x9C09 0x9C0A 0x9C0B 0x9C0C 0x9C0D \ + 0x9C0E 0x9C0F 0x9C10 0x9C11 0x9C12 0x9C13 0x9C14 0x9C15 \ + 0x9C16 0x9C17 0x9C18 0x9C19 0x9C1A 0x9C1B 0x9C1C 0x9C1D \ + 0x9C1E 0x9C1F 0x9C20 0x9C21 0x9C22 0x9C23 0x9C24 0x9C25 \ + 0x9C26 0x9C27 0x9C28 0x9C29 0x9C2A 0x9C2B 0x9C2C 0x9C2D \ + 0x9C2E 0x9C2F 0x9C30 0x9C31 0x9C32 0x9C33 0x9C34 0x9C35 \ + 0x9C36 0x9C37 0x9C38 0x9C39 0x9C3A 0x9C3B 0x89E5 0x89EB \ + 0x89EF 0x8A3E 0x8B26 0x9753 0x96E9 0x96F3 0x96EF 0x9706 \ + 0x9701 0x9708 0x970F 0x970E 0x972A 0x972D 0x9730 0x973E \ + 0x9F80 0x9F83 0x9F85 0x9F86 0x9F87 0x9F88 0x9F89 0x9F8A \ + 0x9F8C 0x9EFE 0x9F0B 0x9F0D 0x96B9 0x96BC 0x96BD 0x96CE \ + 0x96D2 0x77BF 0x96E0 0x928E 0x92AE 0x92C8 0x933E 0x936A \ + 0x93CA 0x938F 0x943E 0x946B 0x9C7F 0x9C82 0x9C85 0x9C86 \ + 0x9C87 0x9C88 0x7A23 0x9C8B 0x9C8E 0x9C90 0x9C91 0x9C92 \ + 0x9C94 0x9C95 0x9C9A 0x9C9B 0x9C9E 0x9C9F 0x9CA0 0x9CA1 \ + 0x9CA2 0x9CA3 0x9CA5 0x9CA6 0x9CA7 0x9CA8 0x9CA9 0x9CAB \ + 0x9CAD 0x9CAE 0x9CB0 0x9CB1 0x9CB2 0x9CB3 0x9CB4 0x9CB5 \ + 0x9CB6 0x9CB7 0x9CBA 0x9CBB 0x9CBC 0x9CBD 0x9CC4 0x9CC5 \ + 0x9CC6 0x9CC7 0x9CCA 0x9CCB 0x9C3C 0x9C3D 0x9C3E 0x9C3F \ + 0x9C40 0x9C41 0x9C42 0x9C43 0x9C44 0x9C45 0x9C46 0x9C47 \ + 0x9C48 0x9C49 0x9C4A 0x9C4B 0x9C4C 0x9C4D 0x9C4E 0x9C4F \ + 0x9C50 0x9C51 0x9C52 0x9C53 0x9C54 0x9C55 0x9C56 0x9C57 \ + 0x9C58 0x9C59 0x9C5A 0x9C5B 0x9C5C 0x9C5D 0x9C5E 0x9C5F \ + 0x9C60 0x9C61 0x9C62 0x9C63 0x9C64 0x9C65 0x9C66 0x9C67 \ + 0x9C68 0x9C69 0x9C6A 0x9C6B 0x9C6C 0x9C6D 0x9C6E 0x9C6F \ + 0x9C70 0x9C71 0x9C72 0x9C73 0x9C74 0x9C75 0x9C76 0x9C77 \ + 0x9C78 0x9C79 0x9C7A 0x9C7B 0x9C7D 0x9C7E 0x9C80 0x9C83 \ + 0x9C84 0x9C89 0x9C8A 0x9C8C 0x9C8F 0x9C93 0x9C96 0x9C97 \ + 0x9C98 0x9C99 0x9C9D 0x9CAA 0x9CAC 0x9CAF 0x9CB9 0x9CBE \ + 0x9CBF 0x9CC0 0x9CC1 0x9CC2 0x9CC8 0x9CC9 0x9CD1 0x9CD2 \ + 0x9CDA 0x9CDB 0x9CE0 0x9CE1 0x9CCC 0x9CCD 0x9CCE 0x9CCF \ + 0x9CD0 0x9CD3 0x9CD4 0x9CD5 0x9CD7 0x9CD8 0x9CD9 0x9CDC +89 0x9CDD 0x9CDF 0x9CE2 0x977C 0x9785 0x9791 0x9792 0x9794 \ + 0x97AF 0x97AB 0x97A3 0x97B2 0x97B4 0x9AB1 0x9AB0 0x9AB7 \ + 0x9E58 0x9AB6 0x9ABA 0x9ABC 0x9AC1 0x9AC0 0x9AC5 0x9AC2 \ + 0x9ACB 0x9ACC 0x9AD1 0x9B45 0x9B43 0x9B47 0x9B49 0x9B48 \ + 0x9B4D 0x9B51 0x98E8 0x990D 0x992E 0x9955 0x9954 0x9ADF \ + 0x9AE1 0x9AE6 0x9AEF 0x9AEB 0x9AFB 0x9AED 0x9AF9 0x9B08 \ + 0x9B0F 0x9B13 0x9B1F 0x9B23 0x9EBD 0x9EBE 0x7E3B 0x9E82 \ + 0x9E87 0x9E88 0x9E8B 0x9E92 0x93D6 0x9E9D 0x9E9F 0x9EDB \ + 0x9EDC 0x9EDD 0x9EE0 0x9EDF 0x9EE2 0x9EE9 0x9EE7 0x9EE5 \ + 0x9EEA 0x9EEF 0x9F22 0x9F2C 0x9F2F 0x9F39 0x9F37 0x9F3D \ + 0x9F3E 0x9F44 0x9CE3 0x9CE4 0x9CE5 0x9CE6 0x9CE7 0x9CE8 \ + 0x9CE9 0x9CEA 0x9CEB 0x9CEC 0x9CED 0x9CEE 0x9CEF 0x9CF0 \ + 0x9CF1 0x9CF2 0x9CF3 0x9CF4 0x9CF5 0x9CF6 0x9CF7 0x9CF8 \ + 0x9CF9 0x9CFA 0x9CFB 0x9CFC 0x9CFD 0x9CFE 0x9CFF 0x9D00 \ + 0x9D01 0x9D02 0x9D03 0x9D04 0x9D05 0x9D06 0x9D07 0x9D08 \ + 0x9D09 0x9D0A 0x9D0B 0x9D0C 0x9D0D 0x9D0E 0x9D0F 0x9D10 \ + 0x9D11 0x9D12 0x9D13 0x9D14 0x9D15 0x9D16 0x9D17 0x9D18 \ + 0x9D19 0x9D1A 0x9D1B 0x9D1C 0x9D1D 0x9D1E 0x9D1F 0x9D20 \ + 0x9D21 0x9D22 0x9D23 0x9D24 0x9D25 0x9D26 0x9D27 0x9D28 \ + 0x9D29 0x9D2A 0x9D2B 0x9D2C 0x9D2D 0x9D2E 0x9D2F 0x9D30 \ + 0x9D31 0x9D32 0x9D33 0x9D34 0x9D35 0x9D36 0x9D37 0x9D38 \ + 0x9D39 0x9D3A 0x9D3B 0x9D3C 0x9D3D 0x9D3E 0x9D3F 0x9D40 \ + 0x9D41 0x9D42 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +90 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0x9D43 0x9D44 0x9D45 0x9D46 0x9D47 0x9D48 0x9D49 0x9D4A \ + 0x9D4B 0x9D4C 0x9D4D 0x9D4E 0x9D4F 0x9D50 0x9D51 0x9D52 \ + 0x9D53 0x9D54 0x9D55 0x9D56 0x9D57 0x9D58 0x9D59 0x9D5A \ + 0x9D5B 0x9D5C 0x9D5D 0x9D5E 0x9D5F 0x9D60 0x9D61 0x9D62 \ + 0x9D63 0x9D64 0x9D65 0x9D66 0x9D67 0x9D68 0x9D69 0x9D6A \ + 0x9D6B 0x9D6C 0x9D6D 0x9D6E 0x9D6F 0x9D70 0x9D71 0x9D72 \ + 0x9D73 0x9D74 0x9D75 0x9D76 0x9D77 0x9D78 0x9D79 0x9D7A \ + 0x9D7B 0x9D7C 0x9D7D 0x9D7E 0x9D7F 0x9D80 0x9D81 0x9D82 \ + 0x9D83 0x9D84 0x9D85 0x9D86 0x9D87 0x9D88 0x9D89 0x9D8A \ + 0x9D8B 0x9D8C 0x9D8D 0x9D8E 0x9D8F 0x9D90 0x9D91 0x9D92 \ + 0x9D93 0x9D94 0x9D95 0x9D96 0x9D97 0x9D98 0x9D99 0x9D9A \ + 0x9D9B 0x9D9C 0x9D9D 0x9D9E 0x9D9F 0x9DA0 0x9DA1 0x9DA2 \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x9DA3 0x9DA4 \ + 0x9DA5 0x9DA6 0x9DA7 0x9DA8 0x9DA9 0x9DAA 0x9DAB 0x9DAC \ + 0x9DAD 0x9DAE 0x9DAF 0x9DB0 0x9DB1 0x9DB2 0x9DB3 0x9DB4 \ + 0x9DB5 0x9DB6 0x9DB7 0x9DB8 0x9DB9 0x9DBA 0x9DBB 0x9DBC \ + 0x9DBD 0x9DBE 0x9DBF 0x9DC0 0x9DC1 0x9DC2 0x9DC3 0x9DC4 \ + 0x9DC5 0x9DC6 0x9DC7 0x9DC8 0x9DC9 0x9DCA 0x9DCB 0x9DCC \ + 0x9DCD 0x9DCE 0x9DCF 0x9DD0 0x9DD1 0x9DD2 0x9DD3 0x9DD4 +91 0x9DD5 0x9DD6 0x9DD7 0x9DD8 0x9DD9 0x9DDA 0x9DDB 0x9DDC \ + 0x9DDD 0x9DDE 0x9DDF 0x9DE0 0x9DE1 0x9DE2 0x9DE3 0x9DE4 \ + 0x9DE5 0x9DE6 0x9DE7 0x9DE8 0x9DE9 0x9DEA 0x9DEB 0x9DEC \ + 0x9DED 0x9DEE 0x9DEF 0x9DF0 0x9DF1 0x9DF2 0x9DF3 0x9DF4 \ + 0x9DF5 0x9DF6 0x9DF7 0x9DF8 0x9DF9 0x9DFA 0x9DFB 0x9DFC \ + 0x9DFD 0x9DFE 0x9DFF 0x9E00 0x9E01 0x9E02 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x9E03 0x9E04 0x9E05 0x9E06 \ + 0x9E07 0x9E08 0x9E09 0x9E0A 0x9E0B 0x9E0C 0x9E0D 0x9E0E \ + 0x9E0F 0x9E10 0x9E11 0x9E12 0x9E13 0x9E14 0x9E15 0x9E16 \ + 0x9E17 0x9E18 0x9E19 0x9E1A 0x9E1B 0x9E1C 0x9E1D 0x9E1E \ + 0x9E24 0x9E27 0x9E2E 0x9E30 0x9E34 0x9E3B 0x9E3C 0x9E40 \ + 0x9E4D 0x9E50 0x9E52 0x9E53 0x9E54 0x9E56 0x9E59 0x9E5D \ + 0x9E5F 0x9E60 0x9E61 0x9E62 0x9E65 0x9E6E 0x9E6F 0x9E72 \ + 0x9E74 0x9E75 0x9E76 0x9E77 0x9E78 0x9E79 0x9E7A 0x9E7B \ + 0x9E7C 0x9E7D 0x9E80 0x9E81 0x9E83 0x9E84 0x9E85 0x9E86 \ + 0x9E89 0x9E8A 0x9E8C 0x9E8D 0x9E8E 0x9E8F 0x9E90 0x9E91 \ + 0x9E94 0x9E95 0x9E96 0x9E97 0x9E98 0x9E99 0x9E9A 0x9E9B \ + 0x9E9C 0x9E9E 0x9EA0 0x9EA1 0x9EA2 0x9EA3 0x9EA4 0x9EA5 \ + 0x9EA7 0x9EA8 0x9EA9 0x9EAA 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +92 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x9EAB 0x9EAC 0x9EAD 0x9EAE 0x9EAF 0x9EB0 \ + 0x9EB1 0x9EB2 0x9EB3 0x9EB5 0x9EB6 0x9EB7 0x9EB9 0x9EBA \ + 0x9EBC 0x9EBF 0x9EC0 0x9EC1 0x9EC2 0x9EC3 0x9EC5 0x9EC6 \ + 0x9EC7 0x9EC8 0x9ECA 0x9ECB 0x9ECC 0x9ED0 0x9ED2 0x9ED3 \ + 0x9ED5 0x9ED6 0x9ED7 0x9ED9 0x9EDA 0x9EDE 0x9EE1 0x9EE3 \ + 0x9EE4 0x9EE6 0x9EE8 0x9EEB 0x9EEC 0x9EED 0x9EEE 0x9EF0 \ + 0x9EF1 0x9EF2 0x9EF3 0x9EF4 0x9EF5 0x9EF6 0x9EF7 0x9EF8 \ + 0x9EFA 0x9EFD 0x9EFF 0x9F00 0x9F01 0x9F02 0x9F03 0x9F04 \ + 0x9F05 0x9F06 0x9F07 0x9F08 0x9F09 0x9F0A 0x9F0C 0x9F0F \ + 0x9F11 0x9F12 0x9F14 0x9F15 0x9F16 0x9F18 0x9F1A 0x9F1B \ + 0x9F1C 0x9F1D 0x9F1E 0x9F1F 0x9F21 0x9F23 0x9F24 0x9F25 \ + 0x9F26 0x9F27 0x9F28 0x9F29 0x9F2A 0x9F2B 0x9F2D 0x9F2E \ + 0x9F30 0x9F31 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +93 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0x9F32 0x9F33 0x9F34 0x9F35 0x9F36 0x9F38 0x9F3A 0x9F3C \ + 0x9F3F 0x9F40 0x9F41 0x9F42 0x9F43 0x9F45 0x9F46 0x9F47 \ + 0x9F48 0x9F49 0x9F4A 0x9F4B 0x9F4C 0x9F4D 0x9F4E 0x9F4F \ + 0x9F52 0x9F53 0x9F54 0x9F55 0x9F56 0x9F57 0x9F58 0x9F59 \ + 0x9F5A 0x9F5B 0x9F5C 0x9F5D 0x9F5E 0x9F5F 0x9F60 0x9F61 \ + 0x9F62 0x9F63 0x9F64 0x9F65 0x9F66 0x9F67 0x9F68 0x9F69 \ + 0x9F6A 0x9F6B 0x9F6C 0x9F6D 0x9F6E 0x9F6F 0x9F70 0x9F71 \ + 0x9F72 0x9F73 0x9F74 0x9F75 0x9F76 0x9F77 0x9F78 0x9F79 \ + 0x9F7A 0x9F7B 0x9F7C 0x9F7D 0x9F7E 0x9F81 0x9F82 0x9F8D \ + 0x9F8E 0x9F8F 0x9F90 0x9F91 0x9F92 0x9F93 0x9F94 0x9F95 \ + 0x9F96 0x9F97 0x9F98 0x9F9C 0x9F9D 0x9F9E 0x9FA1 0x9FA2 \ + 0x9FA3 0x9FA4 0x9FA5 0xF92C 0xF979 0xF995 0xF9E7 0xF9F1 \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFA0C 0xFA0D \ + 0xFA0E 0xFA0F 0xFA11 0xFA13 0xFA14 0xFA18 0xFA1F 0xFA20 \ + 0xFA21 0xFA23 0xFA24 0xFA27 0xFA28 0xFA29 0xE815 0xE816 \ + 0xE817 0xE818 0xE819 0xE81A 0xE81B 0xE81C 0xE81D 0xE81E \ + 0xE81F 0xE820 0xE821 0xE822 0xE823 0xE824 0xE825 0xE826 \ + 0xE827 0xE828 0xE829 0xE82A 0xE82B 0xE82C 0xE82D 0xE82E \ + 0xE82F 0xE830 0xE831 0xE832 0xE833 0xE834 0xE835 0xE836 \ + 0xE837 0xE838 0xE839 0xE83A 0xE83B 0xE83C 0xE83D 0xE83E +94 0xE83F 0xE840 0xE841 0xE842 0xE843 0xE844 0xE845 0xE846 \ + 0xE847 0xE848 0xE849 0xE84A 0xE84B 0xE84C 0xE84D 0xE84E \ + 0xE84F 0xE850 0xE851 0xE852 0xE853 0xE854 0xE855 0xE856 \ + 0xE857 0xE858 0xE859 0xE85A 0xE85B 0xE85C 0xE85D 0xE85E \ + 0xE85F 0xE860 0xE861 0xE862 0xE863 0xE864 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE + +# eof diff --git a/contrib/ttf2pk/data/UJIS.sfd b/contrib/ttf2pk/data/UJIS.sfd new file mode 100644 index 0000000..073c49d --- /dev/null +++ b/contrib/ttf2pk/data/UJIS.sfd @@ -0,0 +1,1114 @@ +# UJIS.sfd +# +# subfont numbers for JIS X 0208 encoding and its corresponding code ranges +# to be used with the CJK package for LaTeX. +# +# The input encoding is Unicode. + +01 0x3000 0x3001 0x3002 0xFF0C 0xFF0E 0x30FB 0xFF1A 0xFF1B \ + 0xFF1F 0xFF01 0x309B 0x309C 0x00B4 0xFF40 0x00A8 0xFF3E \ + 0xFFE3 0xFF3F 0x30FD 0x30FE 0x309D 0x309E 0x3003 0x4EDD \ + 0x3005 0x3006 0x3007 0x30FC 0x2015 0x2010 0xFF0F 0x005C \ + 0x301C 0x2016 0xFF5C 0x2026 0x2025 0x2018 0x2019 0x201C \ + 0x201D 0xFF08 0xFF09 0x3014 0x3015 0xFF3B 0xFF3D 0xFF5B \ + 0xFF5D 0x3008 0x3009 0x300A 0x300B 0x300C 0x300D 0x300E \ + 0x300F 0x3010 0x3011 0xFF0B 0x2212 0x00B1 0x00D7 0x00F7 \ + 0xFF1D 0x2260 0xFF1C 0xFF1E 0x2266 0x2267 0x221E 0x2234 \ + 0x2642 0x2640 0x00B0 0x2032 0x2033 0x2103 0xFFE5 0xFF04 \ + 0x00A2 0x00A3 0xFF05 0xFF03 0xFF06 0xFF0A 0xFF20 0x00A7 \ + 0x2606 0x2605 0x25CB 0x25CF 0x25CE 0x25C7 0x25C6 0x25A1 \ + 0x25A0 0x25B3 0x25B2 0x25BD 0x25BC 0x203B 0x3012 0x2192 \ + 0x2190 0x2191 0x2193 0x3013 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x2208 \ + 0x220B 0x2286 0x2287 0x2282 0x2283 0x222A 0x2229 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x2227 \ + 0x2228 0x00AC 0x21D2 0x21D4 0x2200 0x2203 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0x2220 0x22A5 0x2312 0x2202 0x2207 0x2261 0x2252 \ + 0x226A 0x226B 0x221A 0x223D 0x221D 0x2235 0x222B 0x222C \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x212B \ + 0x2030 0x266F 0x266D 0x266A 0x2020 0x2021 0x00B6 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0x25EF 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFF10 0xFF11 0xFF12 0xFF13 0xFF14 \ + 0xFF15 0xFF16 0xFF17 0xFF18 0xFF19 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFF21 0xFF22 0xFF23 0xFF24 \ + 0xFF25 0xFF26 0xFF27 0xFF28 0xFF29 0xFF2A 0xFF2B 0xFF2C \ + 0xFF2D 0xFF2E 0xFF2F 0xFF30 0xFF31 0xFF32 0xFF33 0xFF34 \ + 0xFF35 0xFF36 0xFF37 0xFF38 0xFF39 0xFF3A 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFF41 0xFF42 0xFF43 0xFF44 +02 0xFF45 0xFF46 0xFF47 0xFF48 0xFF49 0xFF4A 0xFF4B 0xFF4C \ + 0xFF4D 0xFF4E 0xFF4F 0xFF50 0xFF51 0xFF52 0xFF53 0xFF54 \ + 0xFF55 0xFF56 0xFF57 0xFF58 0xFF59 0xFF5A 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x3041 0x3042 0x3043 0x3044 0x3045 0x3046 \ + 0x3047 0x3048 0x3049 0x304A 0x304B 0x304C 0x304D 0x304E \ + 0x304F 0x3050 0x3051 0x3052 0x3053 0x3054 0x3055 0x3056 \ + 0x3057 0x3058 0x3059 0x305A 0x305B 0x305C 0x305D 0x305E \ + 0x305F 0x3060 0x3061 0x3062 0x3063 0x3064 0x3065 0x3066 \ + 0x3067 0x3068 0x3069 0x306A 0x306B 0x306C 0x306D 0x306E \ + 0x306F 0x3070 0x3071 0x3072 0x3073 0x3074 0x3075 0x3076 \ + 0x3077 0x3078 0x3079 0x307A 0x307B 0x307C 0x307D 0x307E \ + 0x307F 0x3080 0x3081 0x3082 0x3083 0x3084 0x3085 0x3086 \ + 0x3087 0x3088 0x3089 0x308A 0x308B 0x308C 0x308D 0x308E \ + 0x308F 0x3090 0x3091 0x3092 0x3093 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0x30A1 0x30A2 0x30A3 0x30A4 0x30A5 0x30A6 0x30A7 0x30A8 \ + 0x30A9 0x30AA 0x30AB 0x30AC 0x30AD 0x30AE 0x30AF 0x30B0 \ + 0x30B1 0x30B2 0x30B3 0x30B4 0x30B5 0x30B6 0x30B7 0x30B8 \ + 0x30B9 0x30BA 0x30BB 0x30BC 0x30BD 0x30BE 0x30BF 0x30C0 \ + 0x30C1 0x30C2 0x30C3 0x30C4 0x30C5 0x30C6 0x30C7 0x30C8 \ + 0x30C9 0x30CA 0x30CB 0x30CC 0x30CD 0x30CE 0x30CF 0x30D0 \ + 0x30D1 0x30D2 0x30D3 0x30D4 0x30D5 0x30D6 0x30D7 0x30D8 \ + 0x30D9 0x30DA 0x30DB 0x30DC 0x30DD 0x30DE 0x30DF 0x30E0 \ + 0x30E1 0x30E2 0x30E3 0x30E4 0x30E5 0x30E6 0x30E7 0x30E8 \ + 0x30E9 0x30EA 0x30EB 0x30EC 0x30ED 0x30EE 0x30EF 0x30F0 \ + 0x30F1 0x30F2 0x30F3 0x30F4 0x30F5 0x30F6 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x0391 0x0392 \ + 0x0393 0x0394 0x0395 0x0396 0x0397 0x0398 0x0399 0x039A \ + 0x039B 0x039C 0x039D 0x039E 0x039F 0x03A0 0x03A1 0x03A3 \ + 0x03A4 0x03A5 0x03A6 0x03A7 0x03A8 0x03A9 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x03B1 0x03B2 \ + 0x03B3 0x03B4 0x03B5 0x03B6 0x03B7 0x03B8 0x03B9 0x03BA +03 0x03BB 0x03BC 0x03BD 0x03BE 0x03BF 0x03C0 0x03C1 0x03C3 \ + 0x03C4 0x03C5 0x03C6 0x03C7 0x03C8 0x03C9 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x0410 0x0411 0x0412 0x0413 \ + 0x0414 0x0415 0x0401 0x0416 0x0417 0x0418 0x0419 0x041A \ + 0x041B 0x041C 0x041D 0x041E 0x041F 0x0420 0x0421 0x0422 \ + 0x0423 0x0424 0x0425 0x0426 0x0427 0x0428 0x0429 0x042A \ + 0x042B 0x042C 0x042D 0x042E 0x042F 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x0430 0x0431 0x0432 0x0433 \ + 0x0434 0x0435 0x0451 0x0436 0x0437 0x0438 0x0439 0x043A \ + 0x043B 0x043C 0x043D 0x043E 0x043F 0x0440 0x0441 0x0442 \ + 0x0443 0x0444 0x0445 0x0446 0x0447 0x0448 0x0449 0x044A \ + 0x044B 0x044C 0x044D 0x044E 0x044F 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x2500 0x2502 0x250C 0x2510 0x2518 0x2514 \ + 0x251C 0x252C 0x2524 0x2534 0x253C 0x2501 0x2503 0x250F \ + 0x2513 0x251B 0x2517 0x2523 0x2533 0x252B 0x253B 0x254B \ + 0x2520 0x252F 0x2528 0x2537 0x253F 0x251D 0x2530 0x2525 \ + 0x2538 0x2542 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +04 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +05 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +06 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x4E9C 0x5516 0x5A03 0x963F 0x54C0 0x611B \ + 0x6328 0x59F6 0x9022 0x8475 0x831C 0x7A50 0x60AA 0x63E1 \ + 0x6E25 0x65ED 0x8466 0x82A6 0x9BF5 0x6893 0x5727 0x65A1 \ + 0x6271 0x5B9B 0x59D0 0x867B 0x98F4 0x7D62 0x7DBE 0x9B8E \ + 0x6216 0x7C9F 0x88B7 0x5B89 0x5EB5 0x6309 0x6697 0x6848 \ + 0x95C7 0x978D 0x674F 0x4EE5 0x4F0A 0x4F4D 0x4F9D 0x5049 \ + 0x56F2 0x5937 0x59D4 0x5A01 0x5C09 0x60DF 0x610F 0x6170 \ + 0x6613 0x6905 0x70BA 0x754F 0x7570 0x79FB 0x7DAD 0x7DEF \ + 0x80C3 0x840E 0x8863 0x8B02 0x9055 0x907A 0x533B 0x4E95 \ + 0x4EA5 0x57DF 0x80B2 0x90C1 0x78EF 0x4E00 0x58F1 0x6EA2 \ + 0x9038 0x7A32 0x8328 0x828B 0x9C2F 0x5141 0x5370 0x54BD \ + 0x54E1 0x56E0 0x59FB 0x5F15 0x98F2 0x6DEB 0x80E4 0x852D \ + 0x9662 0x9670 0x96A0 0x97FB 0x540B 0x53F3 0x5B87 0x70CF \ + 0x7FBD 0x8FC2 0x96E8 0x536F 0x9D5C 0x7ABA 0x4E11 0x7893 \ + 0x81FC 0x6E26 0x5618 0x5504 0x6B1D 0x851A 0x9C3B 0x59E5 \ + 0x53A9 0x6D66 0x74DC 0x958F 0x5642 0x4E91 0x904B 0x96F2 +07 0x834F 0x990C 0x53E1 0x55B6 0x5B30 0x5F71 0x6620 0x66F3 \ + 0x6804 0x6C38 0x6CF3 0x6D29 0x745B 0x76C8 0x7A4E 0x9834 \ + 0x82F1 0x885B 0x8A60 0x92ED 0x6DB2 0x75AB 0x76CA 0x99C5 \ + 0x60A6 0x8B01 0x8D8A 0x95B2 0x698E 0x53AD 0x5186 0x5712 \ + 0x5830 0x5944 0x5BB4 0x5EF6 0x6028 0x63A9 0x63F4 0x6CBF \ + 0x6F14 0x708E 0x7114 0x7159 0x71D5 0x733F 0x7E01 0x8276 \ + 0x82D1 0x8597 0x9060 0x925B 0x9D1B 0x5869 0x65BC 0x6C5A \ + 0x7525 0x51F9 0x592E 0x5965 0x5F80 0x5FDC 0x62BC 0x65FA \ + 0x6A2A 0x6B27 0x6BB4 0x738B 0x7FC1 0x8956 0x9D2C 0x9D0E \ + 0x9EC4 0x5CA1 0x6C96 0x837B 0x5104 0x5C4B 0x61B6 0x81C6 \ + 0x6876 0x7261 0x4E59 0x4FFA 0x5378 0x6069 0x6E29 0x7A4F \ + 0x97F3 0x4E0B 0x5316 0x4EEE 0x4F55 0x4F3D 0x4FA1 0x4F73 \ + 0x52A0 0x53EF 0x5609 0x590F 0x5AC1 0x5BB6 0x5BE1 0x79D1 \ + 0x6687 0x679C 0x67B6 0x6B4C 0x6CB3 0x706B 0x73C2 0x798D \ + 0x79BE 0x7A3C 0x7B87 0x82B1 0x82DB 0x8304 0x8377 0x83EF \ + 0x83D3 0x8766 0x8AB2 0x5629 0x8CA8 0x8FE6 0x904E 0x971E \ + 0x868A 0x4FC4 0x5CE8 0x6211 0x7259 0x753B 0x81E5 0x82BD \ + 0x86FE 0x8CC0 0x96C5 0x9913 0x99D5 0x4ECB 0x4F1A 0x89E3 \ + 0x56DE 0x584A 0x58CA 0x5EFB 0x5FEB 0x602A 0x6094 0x6062 \ + 0x61D0 0x6212 0x62D0 0x6539 0x9B41 0x6666 0x68B0 0x6D77 \ + 0x7070 0x754C 0x7686 0x7D75 0x82A5 0x87F9 0x958B 0x968E \ + 0x8C9D 0x51F1 0x52BE 0x5916 0x54B3 0x5BB3 0x5D16 0x6168 \ + 0x6982 0x6DAF 0x788D 0x84CB 0x8857 0x8A72 0x93A7 0x9AB8 \ + 0x6D6C 0x99A8 0x86D9 0x57A3 0x67FF 0x86CE 0x920E 0x5283 \ + 0x5687 0x5404 0x5ED3 0x62E1 0x64B9 0x683C 0x6838 0x6BBB \ + 0x7372 0x78BA 0x7A6B 0x899A 0x89D2 0x8D6B 0x8F03 0x90ED \ + 0x95A3 0x9694 0x9769 0x5B66 0x5CB3 0x697D 0x984D 0x984E \ + 0x639B 0x7B20 0x6A2B 0x6A7F 0x68B6 0x9C0D 0x6F5F 0x5272 \ + 0x559D 0x6070 0x62EC 0x6D3B 0x6E07 0x6ED1 0x845B 0x8910 \ + 0x8F44 0x4E14 0x9C39 0x53F6 0x691B 0x6A3A 0x9784 0x682A \ + 0x515C 0x7AC3 0x84B2 0x91DC 0x938C 0x565B 0x9D28 0x6822 \ + 0x8305 0x8431 0x7CA5 0x5208 0x82C5 0x74E6 0x4E7E 0x4F83 +08 0x51A0 0x5BD2 0x520A 0x52D8 0x52E7 0x5DFB 0x559A 0x582A \ + 0x59E6 0x5B8C 0x5B98 0x5BDB 0x5E72 0x5E79 0x60A3 0x611F \ + 0x6163 0x61BE 0x63DB 0x6562 0x67D1 0x6853 0x68FA 0x6B3E \ + 0x6B53 0x6C57 0x6F22 0x6F97 0x6F45 0x74B0 0x7518 0x76E3 \ + 0x770B 0x7AFF 0x7BA1 0x7C21 0x7DE9 0x7F36 0x7FF0 0x809D \ + 0x8266 0x839E 0x89B3 0x8ACC 0x8CAB 0x9084 0x9451 0x9593 \ + 0x9591 0x95A2 0x9665 0x97D3 0x9928 0x8218 0x4E38 0x542B \ + 0x5CB8 0x5DCC 0x73A9 0x764C 0x773C 0x5CA9 0x7FEB 0x8D0B \ + 0x96C1 0x9811 0x9854 0x9858 0x4F01 0x4F0E 0x5371 0x559C \ + 0x5668 0x57FA 0x5947 0x5B09 0x5BC4 0x5C90 0x5E0C 0x5E7E \ + 0x5FCC 0x63EE 0x673A 0x65D7 0x65E2 0x671F 0x68CB 0x68C4 \ + 0x6A5F 0x5E30 0x6BC5 0x6C17 0x6C7D 0x757F 0x7948 0x5B63 \ + 0x7A00 0x7D00 0x5FBD 0x898F 0x8A18 0x8CB4 0x8D77 0x8ECC \ + 0x8F1D 0x98E2 0x9A0E 0x9B3C 0x4E80 0x507D 0x5100 0x5993 \ + 0x5B9C 0x622F 0x6280 0x64EC 0x6B3A 0x72A0 0x7591 0x7947 \ + 0x7FA9 0x87FB 0x8ABC 0x8B70 0x63AC 0x83CA 0x97A0 0x5409 \ + 0x5403 0x55AB 0x6854 0x6A58 0x8A70 0x7827 0x6775 0x9ECD \ + 0x5374 0x5BA2 0x811A 0x8650 0x9006 0x4E18 0x4E45 0x4EC7 \ + 0x4F11 0x53CA 0x5438 0x5BAE 0x5F13 0x6025 0x6551 0x673D \ + 0x6C42 0x6C72 0x6CE3 0x7078 0x7403 0x7A76 0x7AAE 0x7B08 \ + 0x7D1A 0x7CFE 0x7D66 0x65E7 0x725B 0x53BB 0x5C45 0x5DE8 \ + 0x62D2 0x62E0 0x6319 0x6E20 0x865A 0x8A31 0x8DDD 0x92F8 \ + 0x6F01 0x79A6 0x9B5A 0x4EA8 0x4EAB 0x4EAC 0x4F9B 0x4FA0 \ + 0x50D1 0x5147 0x7AF6 0x5171 0x51F6 0x5354 0x5321 0x537F \ + 0x53EB 0x55AC 0x5883 0x5CE1 0x5F37 0x5F4A 0x602F 0x6050 \ + 0x606D 0x631F 0x6559 0x6A4B 0x6CC1 0x72C2 0x72ED 0x77EF \ + 0x80F8 0x8105 0x8208 0x854E 0x90F7 0x93E1 0x97FF 0x9957 \ + 0x9A5A 0x4EF0 0x51DD 0x5C2D 0x6681 0x696D 0x5C40 0x66F2 \ + 0x6975 0x7389 0x6850 0x7C81 0x50C5 0x52E4 0x5747 0x5DFE \ + 0x9326 0x65A4 0x6B23 0x6B3D 0x7434 0x7981 0x79BD 0x7B4B \ + 0x7DCA 0x82B9 0x83CC 0x887F 0x895F 0x8B39 0x8FD1 0x91D1 \ + 0x541F 0x9280 0x4E5D 0x5036 0x53E5 0x533A 0x72D7 0x7396 +09 0x77E9 0x82E6 0x8EAF 0x99C6 0x99C8 0x99D2 0x5177 0x611A \ + 0x865E 0x55B0 0x7A7A 0x5076 0x5BD3 0x9047 0x9685 0x4E32 \ + 0x6ADB 0x91E7 0x5C51 0x5C48 0x6398 0x7A9F 0x6C93 0x9774 \ + 0x8F61 0x7AAA 0x718A 0x9688 0x7C82 0x6817 0x7E70 0x6851 \ + 0x936C 0x52F2 0x541B 0x85AB 0x8A13 0x7FA4 0x8ECD 0x90E1 \ + 0x5366 0x8888 0x7941 0x4FC2 0x50BE 0x5211 0x5144 0x5553 \ + 0x572D 0x73EA 0x578B 0x5951 0x5F62 0x5F84 0x6075 0x6176 \ + 0x6167 0x61A9 0x63B2 0x643A 0x656C 0x666F 0x6842 0x6E13 \ + 0x7566 0x7A3D 0x7CFB 0x7D4C 0x7D99 0x7E4B 0x7F6B 0x830E \ + 0x834A 0x86CD 0x8A08 0x8A63 0x8B66 0x8EFD 0x981A 0x9D8F \ + 0x82B8 0x8FCE 0x9BE8 0x5287 0x621F 0x6483 0x6FC0 0x9699 \ + 0x6841 0x5091 0x6B20 0x6C7A 0x6F54 0x7A74 0x7D50 0x8840 \ + 0x8A23 0x6708 0x4EF6 0x5039 0x5026 0x5065 0x517C 0x5238 \ + 0x5263 0x55A7 0x570F 0x5805 0x5ACC 0x5EFA 0x61B2 0x61F8 \ + 0x62F3 0x6372 0x691C 0x6A29 0x727D 0x72AC 0x732E 0x7814 \ + 0x786F 0x7D79 0x770C 0x80A9 0x898B 0x8B19 0x8CE2 0x8ED2 \ + 0x9063 0x9375 0x967A 0x9855 0x9A13 0x9E78 0x5143 0x539F \ + 0x53B3 0x5E7B 0x5F26 0x6E1B 0x6E90 0x7384 0x73FE 0x7D43 \ + 0x8237 0x8A00 0x8AFA 0x9650 0x4E4E 0x500B 0x53E4 0x547C \ + 0x56FA 0x59D1 0x5B64 0x5DF1 0x5EAB 0x5F27 0x6238 0x6545 \ + 0x67AF 0x6E56 0x72D0 0x7CCA 0x88B4 0x80A1 0x80E1 0x83F0 \ + 0x864E 0x8A87 0x8DE8 0x9237 0x96C7 0x9867 0x9F13 0x4E94 \ + 0x4E92 0x4F0D 0x5348 0x5449 0x543E 0x5A2F 0x5F8C 0x5FA1 \ + 0x609F 0x68A7 0x6A8E 0x745A 0x7881 0x8A9E 0x8AA4 0x8B77 \ + 0x9190 0x4E5E 0x9BC9 0x4EA4 0x4F7C 0x4FAF 0x5019 0x5016 \ + 0x5149 0x516C 0x529F 0x52B9 0x52FE 0x539A 0x53E3 0x5411 \ + 0x540E 0x5589 0x5751 0x57A2 0x597D 0x5B54 0x5B5D 0x5B8F \ + 0x5DE5 0x5DE7 0x5DF7 0x5E78 0x5E83 0x5E9A 0x5EB7 0x5F18 \ + 0x6052 0x614C 0x6297 0x62D8 0x63A7 0x653B 0x6602 0x6643 \ + 0x66F4 0x676D 0x6821 0x6897 0x69CB 0x6C5F 0x6D2A 0x6D69 \ + 0x6E2F 0x6E9D 0x7532 0x7687 0x786C 0x7A3F 0x7CE0 0x7D05 \ + 0x7D18 0x7D5E 0x7DB1 0x8015 0x8003 0x80AF 0x80B1 0x8154 +10 0x818F 0x822A 0x8352 0x884C 0x8861 0x8B1B 0x8CA2 0x8CFC \ + 0x90CA 0x9175 0x9271 0x783F 0x92FC 0x95A4 0x964D 0x9805 \ + 0x9999 0x9AD8 0x9D3B 0x525B 0x52AB 0x53F7 0x5408 0x58D5 \ + 0x62F7 0x6FE0 0x8C6A 0x8F5F 0x9EB9 0x514B 0x523B 0x544A \ + 0x56FD 0x7A40 0x9177 0x9D60 0x9ED2 0x7344 0x6F09 0x8170 \ + 0x7511 0x5FFD 0x60DA 0x9AA8 0x72DB 0x8FBC 0x6B64 0x9803 \ + 0x4ECA 0x56F0 0x5764 0x58BE 0x5A5A 0x6068 0x61C7 0x660F \ + 0x6606 0x6839 0x68B1 0x6DF7 0x75D5 0x7D3A 0x826E 0x9B42 \ + 0x4E9B 0x4F50 0x53C9 0x5506 0x5D6F 0x5DE6 0x5DEE 0x67FB \ + 0x6C99 0x7473 0x7802 0x8A50 0x9396 0x88DF 0x5750 0x5EA7 \ + 0x632B 0x50B5 0x50AC 0x518D 0x6700 0x54C9 0x585E 0x59BB \ + 0x5BB0 0x5F69 0x624D 0x63A1 0x683D 0x6B73 0x6E08 0x707D \ + 0x91C7 0x7280 0x7815 0x7826 0x796D 0x658E 0x7D30 0x83DC \ + 0x88C1 0x8F09 0x969B 0x5264 0x5728 0x6750 0x7F6A 0x8CA1 \ + 0x51B4 0x5742 0x962A 0x583A 0x698A 0x80B4 0x54B2 0x5D0E \ + 0x57FC 0x7895 0x9DFA 0x4F5C 0x524A 0x548B 0x643E 0x6628 \ + 0x6714 0x67F5 0x7A84 0x7B56 0x7D22 0x932F 0x685C 0x9BAD \ + 0x7B39 0x5319 0x518A 0x5237 0x5BDF 0x62F6 0x64AE 0x64E6 \ + 0x672D 0x6BBA 0x85A9 0x96D1 0x7690 0x9BD6 0x634C 0x9306 \ + 0x9BAB 0x76BF 0x6652 0x4E09 0x5098 0x53C2 0x5C71 0x60E8 \ + 0x6492 0x6563 0x685F 0x71E6 0x73CA 0x7523 0x7B97 0x7E82 \ + 0x8695 0x8B83 0x8CDB 0x9178 0x9910 0x65AC 0x66AB 0x6B8B \ + 0x4ED5 0x4ED4 0x4F3A 0x4F7F 0x523A 0x53F8 0x53F2 0x55E3 \ + 0x56DB 0x58EB 0x59CB 0x59C9 0x59FF 0x5B50 0x5C4D 0x5E02 \ + 0x5E2B 0x5FD7 0x601D 0x6307 0x652F 0x5B5C 0x65AF 0x65BD \ + 0x65E8 0x679D 0x6B62 0x6B7B 0x6C0F 0x7345 0x7949 0x79C1 \ + 0x7CF8 0x7D19 0x7D2B 0x80A2 0x8102 0x81F3 0x8996 0x8A5E \ + 0x8A69 0x8A66 0x8A8C 0x8AEE 0x8CC7 0x8CDC 0x96CC 0x98FC \ + 0x6B6F 0x4E8B 0x4F3C 0x4F8D 0x5150 0x5B57 0x5BFA 0x6148 \ + 0x6301 0x6642 0x6B21 0x6ECB 0x6CBB 0x723E 0x74BD 0x75D4 \ + 0x78C1 0x793A 0x800C 0x8033 0x81EA 0x8494 0x8F9E 0x6C50 \ + 0x9E7F 0x5F0F 0x8B58 0x9D2B 0x7AFA 0x8EF8 0x5B8D 0x96EB +11 0x4E03 0x53F1 0x57F7 0x5931 0x5AC9 0x5BA4 0x6089 0x6E7F \ + 0x6F06 0x75BE 0x8CEA 0x5B9F 0x8500 0x7BE0 0x5072 0x67F4 \ + 0x829D 0x5C61 0x854A 0x7E1E 0x820E 0x5199 0x5C04 0x6368 \ + 0x8D66 0x659C 0x716E 0x793E 0x7D17 0x8005 0x8B1D 0x8ECA \ + 0x906E 0x86C7 0x90AA 0x501F 0x52FA 0x5C3A 0x6753 0x707C \ + 0x7235 0x914C 0x91C8 0x932B 0x82E5 0x5BC2 0x5F31 0x60F9 \ + 0x4E3B 0x53D6 0x5B88 0x624B 0x6731 0x6B8A 0x72E9 0x73E0 \ + 0x7A2E 0x816B 0x8DA3 0x9152 0x9996 0x5112 0x53D7 0x546A \ + 0x5BFF 0x6388 0x6A39 0x7DAC 0x9700 0x56DA 0x53CE 0x5468 \ + 0x5B97 0x5C31 0x5DDE 0x4FEE 0x6101 0x62FE 0x6D32 0x79C0 \ + 0x79CB 0x7D42 0x7E4D 0x7FD2 0x81ED 0x821F 0x8490 0x8846 \ + 0x8972 0x8B90 0x8E74 0x8F2F 0x9031 0x914B 0x916C 0x96C6 \ + 0x919C 0x4EC0 0x4F4F 0x5145 0x5341 0x5F93 0x620E 0x67D4 \ + 0x6C41 0x6E0B 0x7363 0x7E26 0x91CD 0x9283 0x53D4 0x5919 \ + 0x5BBF 0x6DD1 0x795D 0x7E2E 0x7C9B 0x587E 0x719F 0x51FA \ + 0x8853 0x8FF0 0x4FCA 0x5CFB 0x6625 0x77AC 0x7AE3 0x821C \ + 0x99FF 0x51C6 0x5FAA 0x65EC 0x696F 0x6B89 0x6DF3 0x6E96 \ + 0x6F64 0x76FE 0x7D14 0x5DE1 0x9075 0x9187 0x9806 0x51E6 \ + 0x521D 0x6240 0x6691 0x66D9 0x6E1A 0x5EB6 0x7DD2 0x7F72 \ + 0x66F8 0x85AF 0x85F7 0x8AF8 0x52A9 0x53D9 0x5973 0x5E8F \ + 0x5F90 0x6055 0x92E4 0x9664 0x50B7 0x511F 0x52DD 0x5320 \ + 0x5347 0x53EC 0x54E8 0x5546 0x5531 0x5617 0x5968 0x59BE \ + 0x5A3C 0x5BB5 0x5C06 0x5C0F 0x5C11 0x5C1A 0x5E84 0x5E8A \ + 0x5EE0 0x5F70 0x627F 0x6284 0x62DB 0x638C 0x6377 0x6607 \ + 0x660C 0x662D 0x6676 0x677E 0x68A2 0x6A1F 0x6A35 0x6CBC \ + 0x6D88 0x6E09 0x6E58 0x713C 0x7126 0x7167 0x75C7 0x7701 \ + 0x785D 0x7901 0x7965 0x79F0 0x7AE0 0x7B11 0x7CA7 0x7D39 \ + 0x8096 0x83D6 0x848B 0x8549 0x885D 0x88F3 0x8A1F 0x8A3C \ + 0x8A54 0x8A73 0x8C61 0x8CDE 0x91A4 0x9266 0x937E 0x9418 \ + 0x969C 0x9798 0x4E0A 0x4E08 0x4E1E 0x4E57 0x5197 0x5270 \ + 0x57CE 0x5834 0x58CC 0x5B22 0x5E38 0x60C5 0x64FE 0x6761 \ + 0x6756 0x6D44 0x72B6 0x7573 0x7A63 0x84B8 0x8B72 0x91B8 +12 0x9320 0x5631 0x57F4 0x98FE 0x62ED 0x690D 0x6B96 0x71ED \ + 0x7E54 0x8077 0x8272 0x89E6 0x98DF 0x8755 0x8FB1 0x5C3B \ + 0x4F38 0x4FE1 0x4FB5 0x5507 0x5A20 0x5BDD 0x5BE9 0x5FC3 \ + 0x614E 0x632F 0x65B0 0x664B 0x68EE 0x699B 0x6D78 0x6DF1 \ + 0x7533 0x75B9 0x771F 0x795E 0x79E6 0x7D33 0x81E3 0x82AF \ + 0x85AA 0x89AA 0x8A3A 0x8EAB 0x8F9B 0x9032 0x91DD 0x9707 \ + 0x4EBA 0x4EC1 0x5203 0x5875 0x58EC 0x5C0B 0x751A 0x5C3D \ + 0x814E 0x8A0A 0x8FC5 0x9663 0x976D 0x7B25 0x8ACF 0x9808 \ + 0x9162 0x56F3 0x53A8 0x9017 0x5439 0x5782 0x5E25 0x63A8 \ + 0x6C34 0x708A 0x7761 0x7C8B 0x7FE0 0x8870 0x9042 0x9154 \ + 0x9310 0x9318 0x968F 0x745E 0x9AC4 0x5D07 0x5D69 0x6570 \ + 0x67A2 0x8DA8 0x96DB 0x636E 0x6749 0x6919 0x83C5 0x9817 \ + 0x96C0 0x88FE 0x6F84 0x647A 0x5BF8 0x4E16 0x702C 0x755D \ + 0x662F 0x51C4 0x5236 0x52E2 0x59D3 0x5F81 0x6027 0x6210 \ + 0x653F 0x6574 0x661F 0x6674 0x68F2 0x6816 0x6B63 0x6E05 \ + 0x7272 0x751F 0x76DB 0x7CBE 0x8056 0x58F0 0x88FD 0x897F \ + 0x8AA0 0x8A93 0x8ACB 0x901D 0x9192 0x9752 0x9759 0x6589 \ + 0x7A0E 0x8106 0x96BB 0x5E2D 0x60DC 0x621A 0x65A5 0x6614 \ + 0x6790 0x77F3 0x7A4D 0x7C4D 0x7E3E 0x810A 0x8CAC 0x8D64 \ + 0x8DE1 0x8E5F 0x78A9 0x5207 0x62D9 0x63A5 0x6442 0x6298 \ + 0x8A2D 0x7A83 0x7BC0 0x8AAC 0x96EA 0x7D76 0x820C 0x8749 \ + 0x4ED9 0x5148 0x5343 0x5360 0x5BA3 0x5C02 0x5C16 0x5DDD \ + 0x6226 0x6247 0x64B0 0x6813 0x6834 0x6CC9 0x6D45 0x6D17 \ + 0x67D3 0x6F5C 0x714E 0x717D 0x65CB 0x7A7F 0x7BAD 0x7DDA \ + 0x7E4A 0x7FA8 0x817A 0x821B 0x8239 0x85A6 0x8A6E 0x8CCE \ + 0x8DF5 0x9078 0x9077 0x92AD 0x9291 0x9583 0x9BAE 0x524D \ + 0x5584 0x6F38 0x7136 0x5168 0x7985 0x7E55 0x81B3 0x7CCE \ + 0x564C 0x5851 0x5CA8 0x63AA 0x66FE 0x66FD 0x695A 0x72D9 \ + 0x758F 0x758E 0x790E 0x7956 0x79DF 0x7C97 0x7D20 0x7D44 \ + 0x8607 0x8A34 0x963B 0x9061 0x9F20 0x50E7 0x5275 0x53CC \ + 0x53E2 0x5009 0x55AA 0x58EE 0x594F 0x723D 0x5B8B 0x5C64 \ + 0x531D 0x60E3 0x60F3 0x635C 0x6383 0x633F 0x63BB 0x64CD +13 0x65E9 0x66F9 0x5DE3 0x69CD 0x69FD 0x6F15 0x71E5 0x4E89 \ + 0x75E9 0x76F8 0x7A93 0x7CDF 0x7DCF 0x7D9C 0x8061 0x8349 \ + 0x8358 0x846C 0x84BC 0x85FB 0x88C5 0x8D70 0x9001 0x906D \ + 0x9397 0x971C 0x9A12 0x50CF 0x5897 0x618E 0x81D3 0x8535 \ + 0x8D08 0x9020 0x4FC3 0x5074 0x5247 0x5373 0x606F 0x6349 \ + 0x675F 0x6E2C 0x8DB3 0x901F 0x4FD7 0x5C5E 0x8CCA 0x65CF \ + 0x7D9A 0x5352 0x8896 0x5176 0x63C3 0x5B58 0x5B6B 0x5C0A \ + 0x640D 0x6751 0x905C 0x4ED6 0x591A 0x592A 0x6C70 0x8A51 \ + 0x553E 0x5815 0x59A5 0x60F0 0x6253 0x67C1 0x8235 0x6955 \ + 0x9640 0x99C4 0x9A28 0x4F53 0x5806 0x5BFE 0x8010 0x5CB1 \ + 0x5E2F 0x5F85 0x6020 0x614B 0x6234 0x66FF 0x6CF0 0x6EDE \ + 0x80CE 0x817F 0x82D4 0x888B 0x8CB8 0x9000 0x902E 0x968A \ + 0x9EDB 0x9BDB 0x4EE3 0x53F0 0x5927 0x7B2C 0x918D 0x984C \ + 0x9DF9 0x6EDD 0x7027 0x5353 0x5544 0x5B85 0x6258 0x629E \ + 0x62D3 0x6CA2 0x6FEF 0x7422 0x8A17 0x9438 0x6FC1 0x8AFE \ + 0x8338 0x51E7 0x86F8 0x53EA 0x53E9 0x4F46 0x9054 0x8FB0 \ + 0x596A 0x8131 0x5DFD 0x7AEA 0x8FBF 0x68DA 0x8C37 0x72F8 \ + 0x9C48 0x6A3D 0x8AB0 0x4E39 0x5358 0x5606 0x5766 0x62C5 \ + 0x63A2 0x65E6 0x6B4E 0x6DE1 0x6E5B 0x70AD 0x77ED 0x7AEF \ + 0x7BAA 0x7DBB 0x803D 0x80C6 0x86CB 0x8A95 0x935B 0x56E3 \ + 0x58C7 0x5F3E 0x65AD 0x6696 0x6A80 0x6BB5 0x7537 0x8AC7 \ + 0x5024 0x77E5 0x5730 0x5F1B 0x6065 0x667A 0x6C60 0x75F4 \ + 0x7A1A 0x7F6E 0x81F4 0x8718 0x9045 0x99B3 0x7BC9 0x755C \ + 0x7AF9 0x7B51 0x84C4 0x9010 0x79E9 0x7A92 0x8336 0x5AE1 \ + 0x7740 0x4E2D 0x4EF2 0x5B99 0x5FE0 0x62BD 0x663C 0x67F1 \ + 0x6CE8 0x866B 0x8877 0x8A3B 0x914E 0x92F3 0x99D0 0x6A17 \ + 0x7026 0x732A 0x82E7 0x8457 0x8CAF 0x4E01 0x5146 0x51CB \ + 0x558B 0x5BF5 0x5E16 0x5E33 0x5E81 0x5F14 0x5F35 0x5F6B \ + 0x5FB4 0x61F2 0x6311 0x66A2 0x671D 0x6F6E 0x7252 0x753A \ + 0x773A 0x8074 0x8139 0x8178 0x8776 0x8ABF 0x8ADC 0x8D85 \ + 0x8DF3 0x929A 0x9577 0x9802 0x9CE5 0x52C5 0x6357 0x76F4 \ + 0x6715 0x6C88 0x73CD 0x8CC3 0x93AE 0x9673 0x6D25 0x589C +14 0x690E 0x69CC 0x8FFD 0x939A 0x75DB 0x901A 0x585A 0x6802 \ + 0x63B4 0x69FB 0x4F43 0x6F2C 0x67D8 0x8FBB 0x8526 0x7DB4 \ + 0x9354 0x693F 0x6F70 0x576A 0x58F7 0x5B2C 0x7D2C 0x722A \ + 0x540A 0x91E3 0x9DB4 0x4EAD 0x4F4E 0x505C 0x5075 0x5243 \ + 0x8C9E 0x5448 0x5824 0x5B9A 0x5E1D 0x5E95 0x5EAD 0x5EF7 \ + 0x5F1F 0x608C 0x62B5 0x633A 0x63D0 0x68AF 0x6C40 0x7887 \ + 0x798E 0x7A0B 0x7DE0 0x8247 0x8A02 0x8AE6 0x8E44 0x9013 \ + 0x90B8 0x912D 0x91D8 0x9F0E 0x6CE5 0x6458 0x64E2 0x6575 \ + 0x6EF4 0x7684 0x7B1B 0x9069 0x93D1 0x6EBA 0x54F2 0x5FB9 \ + 0x64A4 0x8F4D 0x8FED 0x9244 0x5178 0x586B 0x5929 0x5C55 \ + 0x5E97 0x6DFB 0x7E8F 0x751C 0x8CBC 0x8EE2 0x985B 0x70B9 \ + 0x4F1D 0x6BBF 0x6FB1 0x7530 0x96FB 0x514E 0x5410 0x5835 \ + 0x5857 0x59AC 0x5C60 0x5F92 0x6597 0x675C 0x6E21 0x767B \ + 0x83DF 0x8CED 0x9014 0x90FD 0x934D 0x7825 0x783A 0x52AA \ + 0x5EA6 0x571F 0x5974 0x6012 0x5012 0x515A 0x51AC 0x51CD \ + 0x5200 0x5510 0x5854 0x5858 0x5957 0x5B95 0x5CF6 0x5D8B \ + 0x60BC 0x6295 0x642D 0x6771 0x6843 0x68BC 0x68DF 0x76D7 \ + 0x6DD8 0x6E6F 0x6D9B 0x706F 0x71C8 0x5F53 0x75D8 0x7977 \ + 0x7B49 0x7B54 0x7B52 0x7CD6 0x7D71 0x5230 0x8463 0x8569 \ + 0x85E4 0x8A0E 0x8B04 0x8C46 0x8E0F 0x9003 0x900F 0x9419 \ + 0x9676 0x982D 0x9A30 0x95D8 0x50CD 0x52D5 0x540C 0x5802 \ + 0x5C0E 0x61A7 0x649E 0x6D1E 0x77B3 0x7AE5 0x80F4 0x8404 \ + 0x9053 0x9285 0x5CE0 0x9D07 0x533F 0x5F97 0x5FB3 0x6D9C \ + 0x7279 0x7763 0x79BF 0x7BE4 0x6BD2 0x72EC 0x8AAD 0x6803 \ + 0x6A61 0x51F8 0x7A81 0x6934 0x5C4A 0x9CF6 0x82EB 0x5BC5 \ + 0x9149 0x701E 0x5678 0x5C6F 0x60C7 0x6566 0x6C8C 0x8C5A \ + 0x9041 0x9813 0x5451 0x66C7 0x920D 0x5948 0x90A3 0x5185 \ + 0x4E4D 0x51EA 0x8599 0x8B0E 0x7058 0x637A 0x934B 0x6962 \ + 0x99B4 0x7E04 0x7577 0x5357 0x6960 0x8EDF 0x96E3 0x6C5D \ + 0x4E8C 0x5C3C 0x5F10 0x8FE9 0x5302 0x8CD1 0x8089 0x8679 \ + 0x5EFF 0x65E5 0x4E73 0x5165 0x5982 0x5C3F 0x97EE 0x4EFB \ + 0x598A 0x5FCD 0x8A8D 0x6FE1 0x79B0 0x7962 0x5BE7 0x8471 +15 0x732B 0x71B1 0x5E74 0x5FF5 0x637B 0x649A 0x71C3 0x7C98 \ + 0x4E43 0x5EFC 0x4E4B 0x57DC 0x56A2 0x60A9 0x6FC3 0x7D0D \ + 0x80FD 0x8133 0x81BF 0x8FB2 0x8997 0x86A4 0x5DF4 0x628A \ + 0x64AD 0x8987 0x6777 0x6CE2 0x6D3E 0x7436 0x7834 0x5A46 \ + 0x7F75 0x82AD 0x99AC 0x4FF3 0x5EC3 0x62DD 0x6392 0x6557 \ + 0x676F 0x76C3 0x724C 0x80CC 0x80BA 0x8F29 0x914D 0x500D \ + 0x57F9 0x5A92 0x6885 0x6973 0x7164 0x72FD 0x8CB7 0x58F2 \ + 0x8CE0 0x966A 0x9019 0x877F 0x79E4 0x77E7 0x8429 0x4F2F \ + 0x5265 0x535A 0x62CD 0x67CF 0x6CCA 0x767D 0x7B94 0x7C95 \ + 0x8236 0x8584 0x8FEB 0x66DD 0x6F20 0x7206 0x7E1B 0x83AB \ + 0x99C1 0x9EA6 0x51FD 0x7BB1 0x7872 0x7BB8 0x8087 0x7B48 \ + 0x6AE8 0x5E61 0x808C 0x7551 0x7560 0x516B 0x9262 0x6E8C \ + 0x767A 0x9197 0x9AEA 0x4F10 0x7F70 0x629C 0x7B4F 0x95A5 \ + 0x9CE9 0x567A 0x5859 0x86E4 0x96BC 0x4F34 0x5224 0x534A \ + 0x53CD 0x53DB 0x5E06 0x642C 0x6591 0x677F 0x6C3E 0x6C4E \ + 0x7248 0x72AF 0x73ED 0x7554 0x7E41 0x822C 0x85E9 0x8CA9 \ + 0x7BC4 0x91C6 0x7169 0x9812 0x98EF 0x633D 0x6669 0x756A \ + 0x76E4 0x78D0 0x8543 0x86EE 0x532A 0x5351 0x5426 0x5983 \ + 0x5E87 0x5F7C 0x60B2 0x6249 0x6279 0x62AB 0x6590 0x6BD4 \ + 0x6CCC 0x75B2 0x76AE 0x7891 0x79D8 0x7DCB 0x7F77 0x80A5 \ + 0x88AB 0x8AB9 0x8CBB 0x907F 0x975E 0x98DB 0x6A0B 0x7C38 \ + 0x5099 0x5C3E 0x5FAE 0x6787 0x6BD8 0x7435 0x7709 0x7F8E \ + 0x9F3B 0x67CA 0x7A17 0x5339 0x758B 0x9AED 0x5F66 0x819D \ + 0x83F1 0x8098 0x5F3C 0x5FC5 0x7562 0x7B46 0x903C 0x6867 \ + 0x59EB 0x5A9B 0x7D10 0x767E 0x8B2C 0x4FF5 0x5F6A 0x6A19 \ + 0x6C37 0x6F02 0x74E2 0x7968 0x8868 0x8A55 0x8C79 0x5EDF \ + 0x63CF 0x75C5 0x79D2 0x82D7 0x9328 0x92F2 0x849C 0x86ED \ + 0x9C2D 0x54C1 0x5F6C 0x658C 0x6D5C 0x7015 0x8CA7 0x8CD3 \ + 0x983B 0x654F 0x74F6 0x4E0D 0x4ED8 0x57E0 0x592B 0x5A66 \ + 0x5BCC 0x51A8 0x5E03 0x5E9C 0x6016 0x6276 0x6577 0x65A7 \ + 0x666E 0x6D6E 0x7236 0x7B26 0x8150 0x819A 0x8299 0x8B5C \ + 0x8CA0 0x8CE6 0x8D74 0x961C 0x9644 0x4FAE 0x64AB 0x6B66 +16 0x821E 0x8461 0x856A 0x90E8 0x5C01 0x6953 0x98A8 0x847A \ + 0x8557 0x4F0F 0x526F 0x5FA9 0x5E45 0x670D 0x798F 0x8179 \ + 0x8907 0x8986 0x6DF5 0x5F17 0x6255 0x6CB8 0x4ECF 0x7269 \ + 0x9B92 0x5206 0x543B 0x5674 0x58B3 0x61A4 0x626E 0x711A \ + 0x596E 0x7C89 0x7CDE 0x7D1B 0x96F0 0x6587 0x805E 0x4E19 \ + 0x4F75 0x5175 0x5840 0x5E63 0x5E73 0x5F0A 0x67C4 0x4E26 \ + 0x853D 0x9589 0x965B 0x7C73 0x9801 0x50FB 0x58C1 0x7656 \ + 0x78A7 0x5225 0x77A5 0x8511 0x7B86 0x504F 0x5909 0x7247 \ + 0x7BC7 0x7DE8 0x8FBA 0x8FD4 0x904D 0x4FBF 0x52C9 0x5A29 \ + 0x5F01 0x97AD 0x4FDD 0x8217 0x92EA 0x5703 0x6355 0x6B69 \ + 0x752B 0x88DC 0x8F14 0x7A42 0x52DF 0x5893 0x6155 0x620A \ + 0x66AE 0x6BCD 0x7C3F 0x83E9 0x5023 0x4FF8 0x5305 0x5446 \ + 0x5831 0x5949 0x5B9D 0x5CF0 0x5CEF 0x5D29 0x5E96 0x62B1 \ + 0x6367 0x653E 0x65B9 0x670B 0x6CD5 0x6CE1 0x70F9 0x7832 \ + 0x7E2B 0x80DE 0x82B3 0x840C 0x84EC 0x8702 0x8912 0x8A2A \ + 0x8C4A 0x90A6 0x92D2 0x98FD 0x9CF3 0x9D6C 0x4E4F 0x4EA1 \ + 0x508D 0x5256 0x574A 0x59A8 0x5E3D 0x5FD8 0x5FD9 0x623F \ + 0x66B4 0x671B 0x67D0 0x68D2 0x5192 0x7D21 0x80AA 0x81A8 \ + 0x8B00 0x8C8C 0x8CBF 0x927E 0x9632 0x5420 0x982C 0x5317 \ + 0x50D5 0x535C 0x58A8 0x64B2 0x6734 0x7267 0x7766 0x7A46 \ + 0x91E6 0x52C3 0x6CA1 0x6B86 0x5800 0x5E4C 0x5954 0x672C \ + 0x7FFB 0x51E1 0x76C6 0x6469 0x78E8 0x9B54 0x9EBB 0x57CB \ + 0x59B9 0x6627 0x679A 0x6BCE 0x54E9 0x69D9 0x5E55 0x819C \ + 0x6795 0x9BAA 0x67FE 0x9C52 0x685D 0x4EA6 0x4FE3 0x53C8 \ + 0x62B9 0x672B 0x6CAB 0x8FC4 0x4FAD 0x7E6D 0x9EBF 0x4E07 \ + 0x6162 0x6E80 0x6F2B 0x8513 0x5473 0x672A 0x9B45 0x5DF3 \ + 0x7B95 0x5CAC 0x5BC6 0x871C 0x6E4A 0x84D1 0x7A14 0x8108 \ + 0x5999 0x7C8D 0x6C11 0x7720 0x52D9 0x5922 0x7121 0x725F \ + 0x77DB 0x9727 0x9D61 0x690B 0x5A7F 0x5A18 0x51A5 0x540D \ + 0x547D 0x660E 0x76DF 0x8FF7 0x9298 0x9CF4 0x59EA 0x725D \ + 0x6EC5 0x514D 0x68C9 0x7DBF 0x7DEC 0x9762 0x9EBA 0x6478 \ + 0x6A21 0x8302 0x5984 0x5B5F 0x6BDB 0x731B 0x76F2 0x7DB2 +17 0x8017 0x8499 0x5132 0x6728 0x9ED9 0x76EE 0x6762 0x52FF \ + 0x9905 0x5C24 0x623B 0x7C7E 0x8CB0 0x554F 0x60B6 0x7D0B \ + 0x9580 0x5301 0x4E5F 0x51B6 0x591C 0x723A 0x8036 0x91CE \ + 0x5F25 0x77E2 0x5384 0x5F79 0x7D04 0x85AC 0x8A33 0x8E8D \ + 0x9756 0x67F3 0x85AE 0x9453 0x6109 0x6108 0x6CB9 0x7652 \ + 0x8AED 0x8F38 0x552F 0x4F51 0x512A 0x52C7 0x53CB 0x5BA5 \ + 0x5E7D 0x60A0 0x6182 0x63D6 0x6709 0x67DA 0x6E67 0x6D8C \ + 0x7336 0x7337 0x7531 0x7950 0x88D5 0x8A98 0x904A 0x9091 \ + 0x90F5 0x96C4 0x878D 0x5915 0x4E88 0x4F59 0x4E0E 0x8A89 \ + 0x8F3F 0x9810 0x50AD 0x5E7C 0x5996 0x5BB9 0x5EB8 0x63DA \ + 0x63FA 0x64C1 0x66DC 0x694A 0x69D8 0x6D0B 0x6EB6 0x7194 \ + 0x7528 0x7AAF 0x7F8A 0x8000 0x8449 0x84C9 0x8981 0x8B21 \ + 0x8E0A 0x9065 0x967D 0x990A 0x617E 0x6291 0x6B32 0x6C83 \ + 0x6D74 0x7FCC 0x7FFC 0x6DC0 0x7F85 0x87BA 0x88F8 0x6765 \ + 0x83B1 0x983C 0x96F7 0x6D1B 0x7D61 0x843D 0x916A 0x4E71 \ + 0x5375 0x5D50 0x6B04 0x6FEB 0x85CD 0x862D 0x89A7 0x5229 \ + 0x540F 0x5C65 0x674E 0x68A8 0x7406 0x7483 0x75E2 0x88CF \ + 0x88E1 0x91CC 0x96E2 0x9678 0x5F8B 0x7387 0x7ACB 0x844E \ + 0x63A0 0x7565 0x5289 0x6D41 0x6E9C 0x7409 0x7559 0x786B \ + 0x7C92 0x9686 0x7ADC 0x9F8D 0x4FB6 0x616E 0x65C5 0x865C \ + 0x4E86 0x4EAE 0x50DA 0x4E21 0x51CC 0x5BEE 0x6599 0x6881 \ + 0x6DBC 0x731F 0x7642 0x77AD 0x7A1C 0x7CE7 0x826F 0x8AD2 \ + 0x907C 0x91CF 0x9675 0x9818 0x529B 0x7DD1 0x502B 0x5398 \ + 0x6797 0x6DCB 0x71D0 0x7433 0x81E8 0x8F2A 0x96A3 0x9C57 \ + 0x9E9F 0x7460 0x5841 0x6D99 0x7D2F 0x985E 0x4EE4 0x4F36 \ + 0x4F8B 0x51B7 0x52B1 0x5DBA 0x601C 0x73B2 0x793C 0x82D3 \ + 0x9234 0x96B7 0x96F6 0x970A 0x9E97 0x9F62 0x66A6 0x6B74 \ + 0x5217 0x52A3 0x70C8 0x88C2 0x5EC9 0x604B 0x6190 0x6F23 \ + 0x7149 0x7C3E 0x7DF4 0x806F 0x84EE 0x9023 0x932C 0x5442 \ + 0x9B6F 0x6AD3 0x7089 0x8CC2 0x8DEF 0x9732 0x52B4 0x5A41 \ + 0x5ECA 0x5F04 0x6717 0x697C 0x6994 0x6D6A 0x6F0F 0x7262 \ + 0x72FC 0x7BED 0x8001 0x807E 0x874B 0x90CE 0x516D 0x9E93 +18 0x7984 0x808B 0x9332 0x8AD6 0x502D 0x548C 0x8A71 0x6B6A \ + 0x8CC4 0x8107 0x60D1 0x67A0 0x9DF2 0x4E99 0x4E98 0x9C10 \ + 0x8A6B 0x85C1 0x8568 0x6900 0x6E7E 0x7897 0x8155 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x5F0C 0x4E10 0x4E15 0x4E2A 0x4E31 0x4E36 \ + 0x4E3C 0x4E3F 0x4E42 0x4E56 0x4E58 0x4E82 0x4E85 0x8C6B \ + 0x4E8A 0x8212 0x5F0D 0x4E8E 0x4E9E 0x4E9F 0x4EA0 0x4EA2 \ + 0x4EB0 0x4EB3 0x4EB6 0x4ECE 0x4ECD 0x4EC4 0x4EC6 0x4EC2 \ + 0x4ED7 0x4EDE 0x4EED 0x4EDF 0x4EF7 0x4F09 0x4F5A 0x4F30 \ + 0x4F5B 0x4F5D 0x4F57 0x4F47 0x4F76 0x4F88 0x4F8F 0x4F98 \ + 0x4F7B 0x4F69 0x4F70 0x4F91 0x4F6F 0x4F86 0x4F96 0x5118 \ + 0x4FD4 0x4FDF 0x4FCE 0x4FD8 0x4FDB 0x4FD1 0x4FDA 0x4FD0 \ + 0x4FE4 0x4FE5 0x501A 0x5028 0x5014 0x502A 0x5025 0x5005 \ + 0x4F1C 0x4FF6 0x5021 0x5029 0x502C 0x4FFE 0x4FEF 0x5011 \ + 0x5006 0x5043 0x5047 0x6703 0x5055 0x5050 0x5048 0x505A \ + 0x5056 0x506C 0x5078 0x5080 0x509A 0x5085 0x50B4 0x50B2 \ + 0x50C9 0x50CA 0x50B3 0x50C2 0x50D6 0x50DE 0x50E5 0x50ED \ + 0x50E3 0x50EE 0x50F9 0x50F5 0x5109 0x5101 0x5102 0x5116 \ + 0x5115 0x5114 0x511A 0x5121 0x513A 0x5137 0x513C 0x513B \ + 0x513F 0x5140 0x5152 0x514C 0x5154 0x5162 0x7AF8 0x5169 \ + 0x516A 0x516E 0x5180 0x5182 0x56D8 0x518C 0x5189 0x518F \ + 0x5191 0x5193 0x5195 0x5196 0x51A4 0x51A6 0x51A2 0x51A9 \ + 0x51AA 0x51AB 0x51B3 0x51B1 0x51B2 0x51B0 0x51B5 0x51BD \ + 0x51C5 0x51C9 0x51DB 0x51E0 0x8655 0x51E9 0x51ED 0x51F0 \ + 0x51F5 0x51FE 0x5204 0x520B 0x5214 0x520E 0x5227 0x522A \ + 0x522E 0x5233 0x5239 0x524F 0x5244 0x524B 0x524C 0x525E \ + 0x5254 0x526A 0x5274 0x5269 0x5273 0x527F 0x527D 0x528D \ + 0x5294 0x5292 0x5271 0x5288 0x5291 0x8FA8 0x8FA7 0x52AC +19 0x52AD 0x52BC 0x52B5 0x52C1 0x52CD 0x52D7 0x52DE 0x52E3 \ + 0x52E6 0x98ED 0x52E0 0x52F3 0x52F5 0x52F8 0x52F9 0x5306 \ + 0x5308 0x7538 0x530D 0x5310 0x530F 0x5315 0x531A 0x5323 \ + 0x532F 0x5331 0x5333 0x5338 0x5340 0x5346 0x5345 0x4E17 \ + 0x5349 0x534D 0x51D6 0x535E 0x5369 0x536E 0x5918 0x537B \ + 0x5377 0x5382 0x5396 0x53A0 0x53A6 0x53A5 0x53AE 0x53B0 \ + 0x53B6 0x53C3 0x7C12 0x96D9 0x53DF 0x66FC 0x71EE 0x53EE \ + 0x53E8 0x53ED 0x53FA 0x5401 0x543D 0x5440 0x542C 0x542D \ + 0x543C 0x542E 0x5436 0x5429 0x541D 0x544E 0x548F 0x5475 \ + 0x548E 0x545F 0x5471 0x5477 0x5470 0x5492 0x547B 0x5480 \ + 0x5476 0x5484 0x5490 0x5486 0x54C7 0x54A2 0x54B8 0x54A5 \ + 0x54AC 0x54C4 0x54C8 0x54A8 0x54AB 0x54C2 0x54A4 0x54BE \ + 0x54BC 0x54D8 0x54E5 0x54E6 0x550F 0x5514 0x54FD 0x54EE \ + 0x54ED 0x54FA 0x54E2 0x5539 0x5540 0x5563 0x554C 0x552E \ + 0x555C 0x5545 0x5556 0x5557 0x5538 0x5533 0x555D 0x5599 \ + 0x5580 0x54AF 0x558A 0x559F 0x557B 0x557E 0x5598 0x559E \ + 0x55AE 0x557C 0x5583 0x55A9 0x5587 0x55A8 0x55DA 0x55C5 \ + 0x55DF 0x55C4 0x55DC 0x55E4 0x55D4 0x5614 0x55F7 0x5616 \ + 0x55FE 0x55FD 0x561B 0x55F9 0x564E 0x5650 0x71DF 0x5634 \ + 0x5636 0x5632 0x5638 0x566B 0x5664 0x562F 0x566C 0x566A \ + 0x5686 0x5680 0x568A 0x56A0 0x5694 0x568F 0x56A5 0x56AE \ + 0x56B6 0x56B4 0x56C2 0x56BC 0x56C1 0x56C3 0x56C0 0x56C8 \ + 0x56CE 0x56D1 0x56D3 0x56D7 0x56EE 0x56F9 0x5700 0x56FF \ + 0x5704 0x5709 0x5708 0x570B 0x570D 0x5713 0x5718 0x5716 \ + 0x55C7 0x571C 0x5726 0x5737 0x5738 0x574E 0x573B 0x5740 \ + 0x574F 0x5769 0x57C0 0x5788 0x5761 0x577F 0x5789 0x5793 \ + 0x57A0 0x57B3 0x57A4 0x57AA 0x57B0 0x57C3 0x57C6 0x57D4 \ + 0x57D2 0x57D3 0x580A 0x57D6 0x57E3 0x580B 0x5819 0x581D \ + 0x5872 0x5821 0x5862 0x584B 0x5870 0x6BC0 0x5852 0x583D \ + 0x5879 0x5885 0x58B9 0x589F 0x58AB 0x58BA 0x58DE 0x58BB \ + 0x58B8 0x58AE 0x58C5 0x58D3 0x58D1 0x58D7 0x58D9 0x58D8 \ + 0x58E5 0x58DC 0x58E4 0x58DF 0x58EF 0x58FA 0x58F9 0x58FB +20 0x58FC 0x58FD 0x5902 0x590A 0x5910 0x591B 0x68A6 0x5925 \ + 0x592C 0x592D 0x5932 0x5938 0x593E 0x7AD2 0x5955 0x5950 \ + 0x594E 0x595A 0x5958 0x5962 0x5960 0x5967 0x596C 0x5969 \ + 0x5978 0x5981 0x599D 0x4F5E 0x4FAB 0x59A3 0x59B2 0x59C6 \ + 0x59E8 0x59DC 0x598D 0x59D9 0x59DA 0x5A25 0x5A1F 0x5A11 \ + 0x5A1C 0x5A09 0x5A1A 0x5A40 0x5A6C 0x5A49 0x5A35 0x5A36 \ + 0x5A62 0x5A6A 0x5A9A 0x5ABC 0x5ABE 0x5ACB 0x5AC2 0x5ABD \ + 0x5AE3 0x5AD7 0x5AE6 0x5AE9 0x5AD6 0x5AFA 0x5AFB 0x5B0C \ + 0x5B0B 0x5B16 0x5B32 0x5AD0 0x5B2A 0x5B36 0x5B3E 0x5B43 \ + 0x5B45 0x5B40 0x5B51 0x5B55 0x5B5A 0x5B5B 0x5B65 0x5B69 \ + 0x5B70 0x5B73 0x5B75 0x5B78 0x6588 0x5B7A 0x5B80 0x5B83 \ + 0x5BA6 0x5BB8 0x5BC3 0x5BC7 0x5BC9 0x5BD4 0x5BD0 0x5BE4 \ + 0x5BE6 0x5BE2 0x5BDE 0x5BE5 0x5BEB 0x5BF0 0x5BF6 0x5BF3 \ + 0x5C05 0x5C07 0x5C08 0x5C0D 0x5C13 0x5C20 0x5C22 0x5C28 \ + 0x5C38 0x5C39 0x5C41 0x5C46 0x5C4E 0x5C53 0x5C50 0x5C4F \ + 0x5B71 0x5C6C 0x5C6E 0x4E62 0x5C76 0x5C79 0x5C8C 0x5C91 \ + 0x5C94 0x599B 0x5CAB 0x5CBB 0x5CB6 0x5CBC 0x5CB7 0x5CC5 \ + 0x5CBE 0x5CC7 0x5CD9 0x5CE9 0x5CFD 0x5CFA 0x5CED 0x5D8C \ + 0x5CEA 0x5D0B 0x5D15 0x5D17 0x5D5C 0x5D1F 0x5D1B 0x5D11 \ + 0x5D14 0x5D22 0x5D1A 0x5D19 0x5D18 0x5D4C 0x5D52 0x5D4E \ + 0x5D4B 0x5D6C 0x5D73 0x5D76 0x5D87 0x5D84 0x5D82 0x5DA2 \ + 0x5D9D 0x5DAC 0x5DAE 0x5DBD 0x5D90 0x5DB7 0x5DBC 0x5DC9 \ + 0x5DCD 0x5DD3 0x5DD2 0x5DD6 0x5DDB 0x5DEB 0x5DF2 0x5DF5 \ + 0x5E0B 0x5E1A 0x5E19 0x5E11 0x5E1B 0x5E36 0x5E37 0x5E44 \ + 0x5E43 0x5E40 0x5E4E 0x5E57 0x5E54 0x5E5F 0x5E62 0x5E64 \ + 0x5E47 0x5E75 0x5E76 0x5E7A 0x9EBC 0x5E7F 0x5EA0 0x5EC1 \ + 0x5EC2 0x5EC8 0x5ED0 0x5ECF 0x5ED6 0x5EE3 0x5EDD 0x5EDA \ + 0x5EDB 0x5EE2 0x5EE1 0x5EE8 0x5EE9 0x5EEC 0x5EF1 0x5EF3 \ + 0x5EF0 0x5EF4 0x5EF8 0x5EFE 0x5F03 0x5F09 0x5F5D 0x5F5C \ + 0x5F0B 0x5F11 0x5F16 0x5F29 0x5F2D 0x5F38 0x5F41 0x5F48 \ + 0x5F4C 0x5F4E 0x5F2F 0x5F51 0x5F56 0x5F57 0x5F59 0x5F61 \ + 0x5F6D 0x5F73 0x5F77 0x5F83 0x5F82 0x5F7F 0x5F8A 0x5F88 +21 0x5F91 0x5F87 0x5F9E 0x5F99 0x5F98 0x5FA0 0x5FA8 0x5FAD \ + 0x5FBC 0x5FD6 0x5FFB 0x5FE4 0x5FF8 0x5FF1 0x5FDD 0x60B3 \ + 0x5FFF 0x6021 0x6060 0x6019 0x6010 0x6029 0x600E 0x6031 \ + 0x601B 0x6015 0x602B 0x6026 0x600F 0x603A 0x605A 0x6041 \ + 0x606A 0x6077 0x605F 0x604A 0x6046 0x604D 0x6063 0x6043 \ + 0x6064 0x6042 0x606C 0x606B 0x6059 0x6081 0x608D 0x60E7 \ + 0x6083 0x609A 0x6084 0x609B 0x6096 0x6097 0x6092 0x60A7 \ + 0x608B 0x60E1 0x60B8 0x60E0 0x60D3 0x60B4 0x5FF0 0x60BD \ + 0x60C6 0x60B5 0x60D8 0x614D 0x6115 0x6106 0x60F6 0x60F7 \ + 0x6100 0x60F4 0x60FA 0x6103 0x6121 0x60FB 0x60F1 0x610D \ + 0x610E 0x6147 0x613E 0x6128 0x6127 0x614A 0x613F 0x613C \ + 0x612C 0x6134 0x613D 0x6142 0x6144 0x6173 0x6177 0x6158 \ + 0x6159 0x615A 0x616B 0x6174 0x616F 0x6165 0x6171 0x615F \ + 0x615D 0x6153 0x6175 0x6199 0x6196 0x6187 0x61AC 0x6194 \ + 0x619A 0x618A 0x6191 0x61AB 0x61AE 0x61CC 0x61CA 0x61C9 \ + 0x61F7 0x61C8 0x61C3 0x61C6 0x61BA 0x61CB 0x7F79 0x61CD \ + 0x61E6 0x61E3 0x61F6 0x61FA 0x61F4 0x61FF 0x61FD 0x61FC \ + 0x61FE 0x6200 0x6208 0x6209 0x620D 0x620C 0x6214 0x621B \ + 0x621E 0x6221 0x622A 0x622E 0x6230 0x6232 0x6233 0x6241 \ + 0x624E 0x625E 0x6263 0x625B 0x6260 0x6268 0x627C 0x6282 \ + 0x6289 0x627E 0x6292 0x6293 0x6296 0x62D4 0x6283 0x6294 \ + 0x62D7 0x62D1 0x62BB 0x62CF 0x62FF 0x62C6 0x64D4 0x62C8 \ + 0x62DC 0x62CC 0x62CA 0x62C2 0x62C7 0x629B 0x62C9 0x630C \ + 0x62EE 0x62F1 0x6327 0x6302 0x6308 0x62EF 0x62F5 0x6350 \ + 0x633E 0x634D 0x641C 0x634F 0x6396 0x638E 0x6380 0x63AB \ + 0x6376 0x63A3 0x638F 0x6389 0x639F 0x63B5 0x636B 0x6369 \ + 0x63BE 0x63E9 0x63C0 0x63C6 0x63E3 0x63C9 0x63D2 0x63F6 \ + 0x63C4 0x6416 0x6434 0x6406 0x6413 0x6426 0x6436 0x651D \ + 0x6417 0x6428 0x640F 0x6467 0x646F 0x6476 0x644E 0x652A \ + 0x6495 0x6493 0x64A5 0x64A9 0x6488 0x64BC 0x64DA 0x64D2 \ + 0x64C5 0x64C7 0x64BB 0x64D8 0x64C2 0x64F1 0x64E7 0x8209 \ + 0x64E0 0x64E1 0x62AC 0x64E3 0x64EF 0x652C 0x64F6 0x64F4 +22 0x64F2 0x64FA 0x6500 0x64FD 0x6518 0x651C 0x6505 0x6524 \ + 0x6523 0x652B 0x6534 0x6535 0x6537 0x6536 0x6538 0x754B \ + 0x6548 0x6556 0x6555 0x654D 0x6558 0x655E 0x655D 0x6572 \ + 0x6578 0x6582 0x6583 0x8B8A 0x659B 0x659F 0x65AB 0x65B7 \ + 0x65C3 0x65C6 0x65C1 0x65C4 0x65CC 0x65D2 0x65DB 0x65D9 \ + 0x65E0 0x65E1 0x65F1 0x6772 0x660A 0x6603 0x65FB 0x6773 \ + 0x6635 0x6636 0x6634 0x661C 0x664F 0x6644 0x6649 0x6641 \ + 0x665E 0x665D 0x6664 0x6667 0x6668 0x665F 0x6662 0x6670 \ + 0x6683 0x6688 0x668E 0x6689 0x6684 0x6698 0x669D 0x66C1 \ + 0x66B9 0x66C9 0x66BE 0x66BC 0x66C4 0x66B8 0x66D6 0x66DA \ + 0x66E0 0x663F 0x66E6 0x66E9 0x66F0 0x66F5 0x66F7 0x670F \ + 0x6716 0x671E 0x6726 0x6727 0x9738 0x672E 0x673F 0x6736 \ + 0x6741 0x6738 0x6737 0x6746 0x675E 0x6760 0x6759 0x6763 \ + 0x6764 0x6789 0x6770 0x67A9 0x677C 0x676A 0x678C 0x678B \ + 0x67A6 0x67A1 0x6785 0x67B7 0x67EF 0x67B4 0x67EC 0x67B3 \ + 0x67E9 0x67B8 0x67E4 0x67DE 0x67DD 0x67E2 0x67EE 0x67B9 \ + 0x67CE 0x67C6 0x67E7 0x6A9C 0x681E 0x6846 0x6829 0x6840 \ + 0x684D 0x6832 0x684E 0x68B3 0x682B 0x6859 0x6863 0x6877 \ + 0x687F 0x689F 0x688F 0x68AD 0x6894 0x689D 0x689B 0x6883 \ + 0x6AAE 0x68B9 0x6874 0x68B5 0x68A0 0x68BA 0x690F 0x688D \ + 0x687E 0x6901 0x68CA 0x6908 0x68D8 0x6922 0x6926 0x68E1 \ + 0x690C 0x68CD 0x68D4 0x68E7 0x68D5 0x6936 0x6912 0x6904 \ + 0x68D7 0x68E3 0x6925 0x68F9 0x68E0 0x68EF 0x6928 0x692A \ + 0x691A 0x6923 0x6921 0x68C6 0x6979 0x6977 0x695C 0x6978 \ + 0x696B 0x6954 0x697E 0x696E 0x6939 0x6974 0x693D 0x6959 \ + 0x6930 0x6961 0x695E 0x695D 0x6981 0x696A 0x69B2 0x69AE \ + 0x69D0 0x69BF 0x69C1 0x69D3 0x69BE 0x69CE 0x5BE8 0x69CA \ + 0x69DD 0x69BB 0x69C3 0x69A7 0x6A2E 0x6991 0x69A0 0x699C \ + 0x6995 0x69B4 0x69DE 0x69E8 0x6A02 0x6A1B 0x69FF 0x6B0A \ + 0x69F9 0x69F2 0x69E7 0x6A05 0x69B1 0x6A1E 0x69ED 0x6A14 \ + 0x69EB 0x6A0A 0x6A12 0x6AC1 0x6A23 0x6A13 0x6A44 0x6A0C \ + 0x6A72 0x6A36 0x6A78 0x6A47 0x6A62 0x6A59 0x6A66 0x6A48 +23 0x6A38 0x6A22 0x6A90 0x6A8D 0x6AA0 0x6A84 0x6AA2 0x6AA3 \ + 0x6A97 0x8617 0x6ABB 0x6AC3 0x6AC2 0x6AB8 0x6AB3 0x6AAC \ + 0x6ADE 0x6AD1 0x6ADF 0x6AAA 0x6ADA 0x6AEA 0x6AFB 0x6B05 \ + 0x8616 0x6AFA 0x6B12 0x6B16 0x9B31 0x6B1F 0x6B38 0x6B37 \ + 0x76DC 0x6B39 0x98EE 0x6B47 0x6B43 0x6B49 0x6B50 0x6B59 \ + 0x6B54 0x6B5B 0x6B5F 0x6B61 0x6B78 0x6B79 0x6B7F 0x6B80 \ + 0x6B84 0x6B83 0x6B8D 0x6B98 0x6B95 0x6B9E 0x6BA4 0x6BAA \ + 0x6BAB 0x6BAF 0x6BB2 0x6BB1 0x6BB3 0x6BB7 0x6BBC 0x6BC6 \ + 0x6BCB 0x6BD3 0x6BDF 0x6BEC 0x6BEB 0x6BF3 0x6BEF 0x9EBE \ + 0x6C08 0x6C13 0x6C14 0x6C1B 0x6C24 0x6C23 0x6C5E 0x6C55 \ + 0x6C62 0x6C6A 0x6C82 0x6C8D 0x6C9A 0x6C81 0x6C9B 0x6C7E \ + 0x6C68 0x6C73 0x6C92 0x6C90 0x6CC4 0x6CF1 0x6CD3 0x6CBD \ + 0x6CD7 0x6CC5 0x6CDD 0x6CAE 0x6CB1 0x6CBE 0x6CBA 0x6CDB \ + 0x6CEF 0x6CD9 0x6CEA 0x6D1F 0x884D 0x6D36 0x6D2B 0x6D3D \ + 0x6D38 0x6D19 0x6D35 0x6D33 0x6D12 0x6D0C 0x6D63 0x6D93 \ + 0x6D64 0x6D5A 0x6D79 0x6D59 0x6D8E 0x6D95 0x6FE4 0x6D85 \ + 0x6DF9 0x6E15 0x6E0A 0x6DB5 0x6DC7 0x6DE6 0x6DB8 0x6DC6 \ + 0x6DEC 0x6DDE 0x6DCC 0x6DE8 0x6DD2 0x6DC5 0x6DFA 0x6DD9 \ + 0x6DE4 0x6DD5 0x6DEA 0x6DEE 0x6E2D 0x6E6E 0x6E2E 0x6E19 \ + 0x6E72 0x6E5F 0x6E3E 0x6E23 0x6E6B 0x6E2B 0x6E76 0x6E4D \ + 0x6E1F 0x6E43 0x6E3A 0x6E4E 0x6E24 0x6EFF 0x6E1D 0x6E38 \ + 0x6E82 0x6EAA 0x6E98 0x6EC9 0x6EB7 0x6ED3 0x6EBD 0x6EAF \ + 0x6EC4 0x6EB2 0x6ED4 0x6ED5 0x6E8F 0x6EA5 0x6EC2 0x6E9F \ + 0x6F41 0x6F11 0x704C 0x6EEC 0x6EF8 0x6EFE 0x6F3F 0x6EF2 \ + 0x6F31 0x6EEF 0x6F32 0x6ECC 0x6F3E 0x6F13 0x6EF7 0x6F86 \ + 0x6F7A 0x6F78 0x6F81 0x6F80 0x6F6F 0x6F5B 0x6FF3 0x6F6D \ + 0x6F82 0x6F7C 0x6F58 0x6F8E 0x6F91 0x6FC2 0x6F66 0x6FB3 \ + 0x6FA3 0x6FA1 0x6FA4 0x6FB9 0x6FC6 0x6FAA 0x6FDF 0x6FD5 \ + 0x6FEC 0x6FD4 0x6FD8 0x6FF1 0x6FEE 0x6FDB 0x7009 0x700B \ + 0x6FFA 0x7011 0x7001 0x700F 0x6FFE 0x701B 0x701A 0x6F74 \ + 0x701D 0x7018 0x701F 0x7030 0x703E 0x7032 0x7051 0x7063 \ + 0x7099 0x7092 0x70AF 0x70F1 0x70AC 0x70B8 0x70B3 0x70AE +24 0x70DF 0x70CB 0x70DD 0x70D9 0x7109 0x70FD 0x711C 0x7119 \ + 0x7165 0x7155 0x7188 0x7166 0x7162 0x714C 0x7156 0x716C \ + 0x718F 0x71FB 0x7184 0x7195 0x71A8 0x71AC 0x71D7 0x71B9 \ + 0x71BE 0x71D2 0x71C9 0x71D4 0x71CE 0x71E0 0x71EC 0x71E7 \ + 0x71F5 0x71FC 0x71F9 0x71FF 0x720D 0x7210 0x721B 0x7228 \ + 0x722D 0x722C 0x7230 0x7232 0x723B 0x723C 0x723F 0x7240 \ + 0x7246 0x724B 0x7258 0x7274 0x727E 0x7282 0x7281 0x7287 \ + 0x7292 0x7296 0x72A2 0x72A7 0x72B9 0x72B2 0x72C3 0x72C6 \ + 0x72C4 0x72CE 0x72D2 0x72E2 0x72E0 0x72E1 0x72F9 0x72F7 \ + 0x500F 0x7317 0x730A 0x731C 0x7316 0x731D 0x7334 0x732F \ + 0x7329 0x7325 0x733E 0x734E 0x734F 0x9ED8 0x7357 0x736A \ + 0x7368 0x7370 0x7378 0x7375 0x737B 0x737A 0x73C8 0x73B3 \ + 0x73CE 0x73BB 0x73C0 0x73E5 0x73EE 0x73DE 0x74A2 0x7405 \ + 0x746F 0x7425 0x73F8 0x7432 0x743A 0x7455 0x743F 0x745F \ + 0x7459 0x7441 0x745C 0x7469 0x7470 0x7463 0x746A 0x7476 \ + 0x747E 0x748B 0x749E 0x74A7 0x74CA 0x74CF 0x74D4 0x73F1 \ + 0x74E0 0x74E3 0x74E7 0x74E9 0x74EE 0x74F2 0x74F0 0x74F1 \ + 0x74F8 0x74F7 0x7504 0x7503 0x7505 0x750C 0x750E 0x750D \ + 0x7515 0x7513 0x751E 0x7526 0x752C 0x753C 0x7544 0x754D \ + 0x754A 0x7549 0x755B 0x7546 0x755A 0x7569 0x7564 0x7567 \ + 0x756B 0x756D 0x7578 0x7576 0x7586 0x7587 0x7574 0x758A \ + 0x7589 0x7582 0x7594 0x759A 0x759D 0x75A5 0x75A3 0x75C2 \ + 0x75B3 0x75C3 0x75B5 0x75BD 0x75B8 0x75BC 0x75B1 0x75CD \ + 0x75CA 0x75D2 0x75D9 0x75E3 0x75DE 0x75FE 0x75FF 0x75FC \ + 0x7601 0x75F0 0x75FA 0x75F2 0x75F3 0x760B 0x760D 0x7609 \ + 0x761F 0x7627 0x7620 0x7621 0x7622 0x7624 0x7634 0x7630 \ + 0x763B 0x7647 0x7648 0x7646 0x765C 0x7658 0x7661 0x7662 \ + 0x7668 0x7669 0x766A 0x7667 0x766C 0x7670 0x7672 0x7676 \ + 0x7678 0x767C 0x7680 0x7683 0x7688 0x768B 0x768E 0x7696 \ + 0x7693 0x7699 0x769A 0x76B0 0x76B4 0x76B8 0x76B9 0x76BA \ + 0x76C2 0x76CD 0x76D6 0x76D2 0x76DE 0x76E1 0x76E5 0x76E7 \ + 0x76EA 0x862F 0x76FB 0x7708 0x7707 0x7704 0x7729 0x7724 +25 0x771E 0x7725 0x7726 0x771B 0x7737 0x7738 0x7747 0x775A \ + 0x7768 0x776B 0x775B 0x7765 0x777F 0x777E 0x7779 0x778E \ + 0x778B 0x7791 0x77A0 0x779E 0x77B0 0x77B6 0x77B9 0x77BF \ + 0x77BC 0x77BD 0x77BB 0x77C7 0x77CD 0x77D7 0x77DA 0x77DC \ + 0x77E3 0x77EE 0x77FC 0x780C 0x7812 0x7926 0x7820 0x792A \ + 0x7845 0x788E 0x7874 0x7886 0x787C 0x789A 0x788C 0x78A3 \ + 0x78B5 0x78AA 0x78AF 0x78D1 0x78C6 0x78CB 0x78D4 0x78BE \ + 0x78BC 0x78C5 0x78CA 0x78EC 0x78E7 0x78DA 0x78FD 0x78F4 \ + 0x7907 0x7912 0x7911 0x7919 0x792C 0x792B 0x7940 0x7960 \ + 0x7957 0x795F 0x795A 0x7955 0x7953 0x797A 0x797F 0x798A \ + 0x799D 0x79A7 0x9F4B 0x79AA 0x79AE 0x79B3 0x79B9 0x79BA \ + 0x79C9 0x79D5 0x79E7 0x79EC 0x79E1 0x79E3 0x7A08 0x7A0D \ + 0x7A18 0x7A19 0x7A20 0x7A1F 0x7980 0x7A31 0x7A3B 0x7A3E \ + 0x7A37 0x7A43 0x7A57 0x7A49 0x7A61 0x7A62 0x7A69 0x9F9D \ + 0x7A70 0x7A79 0x7A7D 0x7A88 0x7A97 0x7A95 0x7A98 0x7A96 \ + 0x7AA9 0x7AC8 0x7AB0 0x7AB6 0x7AC5 0x7AC4 0x7ABF 0x9083 \ + 0x7AC7 0x7ACA 0x7ACD 0x7ACF 0x7AD5 0x7AD3 0x7AD9 0x7ADA \ + 0x7ADD 0x7AE1 0x7AE2 0x7AE6 0x7AED 0x7AF0 0x7B02 0x7B0F \ + 0x7B0A 0x7B06 0x7B33 0x7B18 0x7B19 0x7B1E 0x7B35 0x7B28 \ + 0x7B36 0x7B50 0x7B7A 0x7B04 0x7B4D 0x7B0B 0x7B4C 0x7B45 \ + 0x7B75 0x7B65 0x7B74 0x7B67 0x7B70 0x7B71 0x7B6C 0x7B6E \ + 0x7B9D 0x7B98 0x7B9F 0x7B8D 0x7B9C 0x7B9A 0x7B8B 0x7B92 \ + 0x7B8F 0x7B5D 0x7B99 0x7BCB 0x7BC1 0x7BCC 0x7BCF 0x7BB4 \ + 0x7BC6 0x7BDD 0x7BE9 0x7C11 0x7C14 0x7BE6 0x7BE5 0x7C60 \ + 0x7C00 0x7C07 0x7C13 0x7BF3 0x7BF7 0x7C17 0x7C0D 0x7BF6 \ + 0x7C23 0x7C27 0x7C2A 0x7C1F 0x7C37 0x7C2B 0x7C3D 0x7C4C \ + 0x7C43 0x7C54 0x7C4F 0x7C40 0x7C50 0x7C58 0x7C5F 0x7C64 \ + 0x7C56 0x7C65 0x7C6C 0x7C75 0x7C83 0x7C90 0x7CA4 0x7CAD \ + 0x7CA2 0x7CAB 0x7CA1 0x7CA8 0x7CB3 0x7CB2 0x7CB1 0x7CAE \ + 0x7CB9 0x7CBD 0x7CC0 0x7CC5 0x7CC2 0x7CD8 0x7CD2 0x7CDC \ + 0x7CE2 0x9B3B 0x7CEF 0x7CF2 0x7CF4 0x7CF6 0x7CFA 0x7D06 \ + 0x7D02 0x7D1C 0x7D15 0x7D0A 0x7D45 0x7D4B 0x7D2E 0x7D32 +26 0x7D3F 0x7D35 0x7D46 0x7D73 0x7D56 0x7D4E 0x7D72 0x7D68 \ + 0x7D6E 0x7D4F 0x7D63 0x7D93 0x7D89 0x7D5B 0x7D8F 0x7D7D \ + 0x7D9B 0x7DBA 0x7DAE 0x7DA3 0x7DB5 0x7DC7 0x7DBD 0x7DAB \ + 0x7E3D 0x7DA2 0x7DAF 0x7DDC 0x7DB8 0x7D9F 0x7DB0 0x7DD8 \ + 0x7DDD 0x7DE4 0x7DDE 0x7DFB 0x7DF2 0x7DE1 0x7E05 0x7E0A \ + 0x7E23 0x7E21 0x7E12 0x7E31 0x7E1F 0x7E09 0x7E0B 0x7E22 \ + 0x7E46 0x7E66 0x7E3B 0x7E35 0x7E39 0x7E43 0x7E37 0x7E32 \ + 0x7E3A 0x7E67 0x7E5D 0x7E56 0x7E5E 0x7E59 0x7E5A 0x7E79 \ + 0x7E6A 0x7E69 0x7E7C 0x7E7B 0x7E83 0x7DD5 0x7E7D 0x8FAE \ + 0x7E7F 0x7E88 0x7E89 0x7E8C 0x7E92 0x7E90 0x7E93 0x7E94 \ + 0x7E96 0x7E8E 0x7E9B 0x7E9C 0x7F38 0x7F3A 0x7F45 0x7F4C \ + 0x7F4D 0x7F4E 0x7F50 0x7F51 0x7F55 0x7F54 0x7F58 0x7F5F \ + 0x7F60 0x7F68 0x7F69 0x7F67 0x7F78 0x7F82 0x7F86 0x7F83 \ + 0x7F88 0x7F87 0x7F8C 0x7F94 0x7F9E 0x7F9D 0x7F9A 0x7FA3 \ + 0x7FAF 0x7FB2 0x7FB9 0x7FAE 0x7FB6 0x7FB8 0x8B71 0x7FC5 \ + 0x7FC6 0x7FCA 0x7FD5 0x7FD4 0x7FE1 0x7FE6 0x7FE9 0x7FF3 \ + 0x7FF9 0x98DC 0x8006 0x8004 0x800B 0x8012 0x8018 0x8019 \ + 0x801C 0x8021 0x8028 0x803F 0x803B 0x804A 0x8046 0x8052 \ + 0x8058 0x805A 0x805F 0x8062 0x8068 0x8073 0x8072 0x8070 \ + 0x8076 0x8079 0x807D 0x807F 0x8084 0x8086 0x8085 0x809B \ + 0x8093 0x809A 0x80AD 0x5190 0x80AC 0x80DB 0x80E5 0x80D9 \ + 0x80DD 0x80C4 0x80DA 0x80D6 0x8109 0x80EF 0x80F1 0x811B \ + 0x8129 0x8123 0x812F 0x814B 0x968B 0x8146 0x813E 0x8153 \ + 0x8151 0x80FC 0x8171 0x816E 0x8165 0x8166 0x8174 0x8183 \ + 0x8188 0x818A 0x8180 0x8182 0x81A0 0x8195 0x81A4 0x81A3 \ + 0x815F 0x8193 0x81A9 0x81B0 0x81B5 0x81BE 0x81B8 0x81BD \ + 0x81C0 0x81C2 0x81BA 0x81C9 0x81CD 0x81D1 0x81D9 0x81D8 \ + 0x81C8 0x81DA 0x81DF 0x81E0 0x81E7 0x81FA 0x81FB 0x81FE \ + 0x8201 0x8202 0x8205 0x8207 0x820A 0x820D 0x8210 0x8216 \ + 0x8229 0x822B 0x8238 0x8233 0x8240 0x8259 0x8258 0x825D \ + 0x825A 0x825F 0x8264 0x8262 0x8268 0x826A 0x826B 0x822E \ + 0x8271 0x8277 0x8278 0x827E 0x828D 0x8292 0x82AB 0x829F +27 0x82BB 0x82AC 0x82E1 0x82E3 0x82DF 0x82D2 0x82F4 0x82F3 \ + 0x82FA 0x8393 0x8303 0x82FB 0x82F9 0x82DE 0x8306 0x82DC \ + 0x8309 0x82D9 0x8335 0x8334 0x8316 0x8332 0x8331 0x8340 \ + 0x8339 0x8350 0x8345 0x832F 0x832B 0x8317 0x8318 0x8385 \ + 0x839A 0x83AA 0x839F 0x83A2 0x8396 0x8323 0x838E 0x8387 \ + 0x838A 0x837C 0x83B5 0x8373 0x8375 0x83A0 0x8389 0x83A8 \ + 0x83F4 0x8413 0x83EB 0x83CE 0x83FD 0x8403 0x83D8 0x840B \ + 0x83C1 0x83F7 0x8407 0x83E0 0x83F2 0x840D 0x8422 0x8420 \ + 0x83BD 0x8438 0x8506 0x83FB 0x846D 0x842A 0x843C 0x855A \ + 0x8484 0x8477 0x846B 0x84AD 0x846E 0x8482 0x8469 0x8446 \ + 0x842C 0x846F 0x8479 0x8435 0x84CA 0x8462 0x84B9 0x84BF \ + 0x849F 0x84D9 0x84CD 0x84BB 0x84DA 0x84D0 0x84C1 0x84C6 \ + 0x84D6 0x84A1 0x8521 0x84FF 0x84F4 0x8517 0x8518 0x852C \ + 0x851F 0x8515 0x8514 0x84FC 0x8540 0x8563 0x8558 0x8548 \ + 0x8541 0x8602 0x854B 0x8555 0x8580 0x85A4 0x8588 0x8591 \ + 0x858A 0x85A8 0x856D 0x8594 0x859B 0x85EA 0x8587 0x859C \ + 0x8577 0x857E 0x8590 0x85C9 0x85BA 0x85CF 0x85B9 0x85D0 \ + 0x85D5 0x85DD 0x85E5 0x85DC 0x85F9 0x860A 0x8613 0x860B \ + 0x85FE 0x85FA 0x8606 0x8622 0x861A 0x8630 0x863F 0x864D \ + 0x4E55 0x8654 0x865F 0x8667 0x8671 0x8693 0x86A3 0x86A9 \ + 0x86AA 0x868B 0x868C 0x86B6 0x86AF 0x86C4 0x86C6 0x86B0 \ + 0x86C9 0x8823 0x86AB 0x86D4 0x86DE 0x86E9 0x86EC 0x86DF \ + 0x86DB 0x86EF 0x8712 0x8706 0x8708 0x8700 0x8703 0x86FB \ + 0x8711 0x8709 0x870D 0x86F9 0x870A 0x8734 0x873F 0x8737 \ + 0x873B 0x8725 0x8729 0x871A 0x8760 0x875F 0x8778 0x874C \ + 0x874E 0x8774 0x8757 0x8768 0x876E 0x8759 0x8753 0x8763 \ + 0x876A 0x8805 0x87A2 0x879F 0x8782 0x87AF 0x87CB 0x87BD \ + 0x87C0 0x87D0 0x96D6 0x87AB 0x87C4 0x87B3 0x87C7 0x87C6 \ + 0x87BB 0x87EF 0x87F2 0x87E0 0x880F 0x880D 0x87FE 0x87F6 \ + 0x87F7 0x880E 0x87D2 0x8811 0x8816 0x8815 0x8822 0x8821 \ + 0x8831 0x8836 0x8839 0x8827 0x883B 0x8844 0x8842 0x8852 \ + 0x8859 0x885E 0x8862 0x886B 0x8881 0x887E 0x889E 0x8875 +28 0x887D 0x88B5 0x8872 0x8882 0x8897 0x8892 0x88AE 0x8899 \ + 0x88A2 0x888D 0x88A4 0x88B0 0x88BF 0x88B1 0x88C3 0x88C4 \ + 0x88D4 0x88D8 0x88D9 0x88DD 0x88F9 0x8902 0x88FC 0x88F4 \ + 0x88E8 0x88F2 0x8904 0x890C 0x890A 0x8913 0x8943 0x891E \ + 0x8925 0x892A 0x892B 0x8941 0x8944 0x893B 0x8936 0x8938 \ + 0x894C 0x891D 0x8960 0x895E 0x8966 0x8964 0x896D 0x896A \ + 0x896F 0x8974 0x8977 0x897E 0x8983 0x8988 0x898A 0x8993 \ + 0x8998 0x89A1 0x89A9 0x89A6 0x89AC 0x89AF 0x89B2 0x89BA \ + 0x89BD 0x89BF 0x89C0 0x89DA 0x89DC 0x89DD 0x89E7 0x89F4 \ + 0x89F8 0x8A03 0x8A16 0x8A10 0x8A0C 0x8A1B 0x8A1D 0x8A25 \ + 0x8A36 0x8A41 0x8A5B 0x8A52 0x8A46 0x8A48 0x8A7C 0x8A6D \ + 0x8A6C 0x8A62 0x8A85 0x8A82 0x8A84 0x8AA8 0x8AA1 0x8A91 \ + 0x8AA5 0x8AA6 0x8A9A 0x8AA3 0x8AC4 0x8ACD 0x8AC2 0x8ADA \ + 0x8AEB 0x8AF3 0x8AE7 0x8AE4 0x8AF1 0x8B14 0x8AE0 0x8AE2 \ + 0x8AF7 0x8ADE 0x8ADB 0x8B0C 0x8B07 0x8B1A 0x8AE1 0x8B16 \ + 0x8B10 0x8B17 0x8B20 0x8B33 0x97AB 0x8B26 0x8B2B 0x8B3E \ + 0x8B28 0x8B41 0x8B4C 0x8B4F 0x8B4E 0x8B49 0x8B56 0x8B5B \ + 0x8B5A 0x8B6B 0x8B5F 0x8B6C 0x8B6F 0x8B74 0x8B7D 0x8B80 \ + 0x8B8C 0x8B8E 0x8B92 0x8B93 0x8B96 0x8B99 0x8B9A 0x8C3A \ + 0x8C41 0x8C3F 0x8C48 0x8C4C 0x8C4E 0x8C50 0x8C55 0x8C62 \ + 0x8C6C 0x8C78 0x8C7A 0x8C82 0x8C89 0x8C85 0x8C8A 0x8C8D \ + 0x8C8E 0x8C94 0x8C7C 0x8C98 0x621D 0x8CAD 0x8CAA 0x8CBD \ + 0x8CB2 0x8CB3 0x8CAE 0x8CB6 0x8CC8 0x8CC1 0x8CE4 0x8CE3 \ + 0x8CDA 0x8CFD 0x8CFA 0x8CFB 0x8D04 0x8D05 0x8D0A 0x8D07 \ + 0x8D0F 0x8D0D 0x8D10 0x9F4E 0x8D13 0x8CCD 0x8D14 0x8D16 \ + 0x8D67 0x8D6D 0x8D71 0x8D73 0x8D81 0x8D99 0x8DC2 0x8DBE \ + 0x8DBA 0x8DCF 0x8DDA 0x8DD6 0x8DCC 0x8DDB 0x8DCB 0x8DEA \ + 0x8DEB 0x8DDF 0x8DE3 0x8DFC 0x8E08 0x8E09 0x8DFF 0x8E1D \ + 0x8E1E 0x8E10 0x8E1F 0x8E42 0x8E35 0x8E30 0x8E34 0x8E4A \ + 0x8E47 0x8E49 0x8E4C 0x8E50 0x8E48 0x8E59 0x8E64 0x8E60 \ + 0x8E2A 0x8E63 0x8E55 0x8E76 0x8E72 0x8E7C 0x8E81 0x8E87 \ + 0x8E85 0x8E84 0x8E8B 0x8E8A 0x8E93 0x8E91 0x8E94 0x8E99 +29 0x8EAA 0x8EA1 0x8EAC 0x8EB0 0x8EC6 0x8EB1 0x8EBE 0x8EC5 \ + 0x8EC8 0x8ECB 0x8EDB 0x8EE3 0x8EFC 0x8EFB 0x8EEB 0x8EFE \ + 0x8F0A 0x8F05 0x8F15 0x8F12 0x8F19 0x8F13 0x8F1C 0x8F1F \ + 0x8F1B 0x8F0C 0x8F26 0x8F33 0x8F3B 0x8F39 0x8F45 0x8F42 \ + 0x8F3E 0x8F4C 0x8F49 0x8F46 0x8F4E 0x8F57 0x8F5C 0x8F62 \ + 0x8F63 0x8F64 0x8F9C 0x8F9F 0x8FA3 0x8FAD 0x8FAF 0x8FB7 \ + 0x8FDA 0x8FE5 0x8FE2 0x8FEA 0x8FEF 0x9087 0x8FF4 0x9005 \ + 0x8FF9 0x8FFA 0x9011 0x9015 0x9021 0x900D 0x901E 0x9016 \ + 0x900B 0x9027 0x9036 0x9035 0x9039 0x8FF8 0x904F 0x9050 \ + 0x9051 0x9052 0x900E 0x9049 0x903E 0x9056 0x9058 0x905E \ + 0x9068 0x906F 0x9076 0x96A8 0x9072 0x9082 0x907D 0x9081 \ + 0x9080 0x908A 0x9089 0x908F 0x90A8 0x90AF 0x90B1 0x90B5 \ + 0x90E2 0x90E4 0x6248 0x90DB 0x9102 0x9112 0x9119 0x9132 \ + 0x9130 0x914A 0x9156 0x9158 0x9163 0x9165 0x9169 0x9173 \ + 0x9172 0x918B 0x9189 0x9182 0x91A2 0x91AB 0x91AF 0x91AA \ + 0x91B5 0x91B4 0x91BA 0x91C0 0x91C1 0x91C9 0x91CB 0x91D0 \ + 0x91D6 0x91DF 0x91E1 0x91DB 0x91FC 0x91F5 0x91F6 0x921E \ + 0x91FF 0x9214 0x922C 0x9215 0x9211 0x925E 0x9257 0x9245 \ + 0x9249 0x9264 0x9248 0x9295 0x923F 0x924B 0x9250 0x929C \ + 0x9296 0x9293 0x929B 0x925A 0x92CF 0x92B9 0x92B7 0x92E9 \ + 0x930F 0x92FA 0x9344 0x932E 0x9319 0x9322 0x931A 0x9323 \ + 0x933A 0x9335 0x933B 0x935C 0x9360 0x937C 0x936E 0x9356 \ + 0x93B0 0x93AC 0x93AD 0x9394 0x93B9 0x93D6 0x93D7 0x93E8 \ + 0x93E5 0x93D8 0x93C3 0x93DD 0x93D0 0x93C8 0x93E4 0x941A \ + 0x9414 0x9413 0x9403 0x9407 0x9410 0x9436 0x942B 0x9435 \ + 0x9421 0x943A 0x9441 0x9452 0x9444 0x945B 0x9460 0x9462 \ + 0x945E 0x946A 0x9229 0x9470 0x9475 0x9477 0x947D 0x945A \ + 0x947C 0x947E 0x9481 0x947F 0x9582 0x9587 0x958A 0x9594 \ + 0x9596 0x9598 0x9599 0x95A0 0x95A8 0x95A7 0x95AD 0x95BC \ + 0x95BB 0x95B9 0x95BE 0x95CA 0x6FF6 0x95C3 0x95CD 0x95CC \ + 0x95D5 0x95D4 0x95D6 0x95DC 0x95E1 0x95E5 0x95E2 0x9621 \ + 0x9628 0x962E 0x962F 0x9642 0x964C 0x964F 0x964B 0x9677 +30 0x965C 0x965E 0x965D 0x965F 0x9666 0x9672 0x966C 0x968D \ + 0x9698 0x9695 0x9697 0x96AA 0x96A7 0x96B1 0x96B2 0x96B0 \ + 0x96B4 0x96B6 0x96B8 0x96B9 0x96CE 0x96CB 0x96C9 0x96CD \ + 0x894D 0x96DC 0x970D 0x96D5 0x96F9 0x9704 0x9706 0x9708 \ + 0x9713 0x970E 0x9711 0x970F 0x9716 0x9719 0x9724 0x972A \ + 0x9730 0x9739 0x973D 0x973E 0x9744 0x9746 0x9748 0x9742 \ + 0x9749 0x975C 0x9760 0x9764 0x9766 0x9768 0x52D2 0x976B \ + 0x9771 0x9779 0x9785 0x977C 0x9781 0x977A 0x9786 0x978B \ + 0x978F 0x9790 0x979C 0x97A8 0x97A6 0x97A3 0x97B3 0x97B4 \ + 0x97C3 0x97C6 0x97C8 0x97CB 0x97DC 0x97ED 0x9F4F 0x97F2 \ + 0x7ADF 0x97F6 0x97F5 0x980F 0x980C 0x9838 0x9824 0x9821 \ + 0x9837 0x983D 0x9846 0x984F 0x984B 0x986B 0x986F 0x9870 \ + 0x9871 0x9874 0x9873 0x98AA 0x98AF 0x98B1 0x98B6 0x98C4 \ + 0x98C3 0x98C6 0x98E9 0x98EB 0x9903 0x9909 0x9912 0x9914 \ + 0x9918 0x9921 0x991D 0x991E 0x9924 0x9920 0x992C 0x992E \ + 0x993D 0x993E 0x9942 0x9949 0x9945 0x9950 0x994B 0x9951 \ + 0x9952 0x994C 0x9955 0x9997 0x9998 0x99A5 0x99AD 0x99AE \ + 0x99BC 0x99DF 0x99DB 0x99DD 0x99D8 0x99D1 0x99ED 0x99EE \ + 0x99F1 0x99F2 0x99FB 0x99F8 0x9A01 0x9A0F 0x9A05 0x99E2 \ + 0x9A19 0x9A2B 0x9A37 0x9A45 0x9A42 0x9A40 0x9A43 0x9A3E \ + 0x9A55 0x9A4D 0x9A5B 0x9A57 0x9A5F 0x9A62 0x9A65 0x9A64 \ + 0x9A69 0x9A6B 0x9A6A 0x9AAD 0x9AB0 0x9ABC 0x9AC0 0x9ACF \ + 0x9AD1 0x9AD3 0x9AD4 0x9ADE 0x9ADF 0x9AE2 0x9AE3 0x9AE6 \ + 0x9AEF 0x9AEB 0x9AEE 0x9AF4 0x9AF1 0x9AF7 0x9AFB 0x9B06 \ + 0x9B18 0x9B1A 0x9B1F 0x9B22 0x9B23 0x9B25 0x9B27 0x9B28 \ + 0x9B29 0x9B2A 0x9B2E 0x9B2F 0x9B32 0x9B44 0x9B43 0x9B4F \ + 0x9B4D 0x9B4E 0x9B51 0x9B58 0x9B74 0x9B93 0x9B83 0x9B91 \ + 0x9B96 0x9B97 0x9B9F 0x9BA0 0x9BA8 0x9BB4 0x9BC0 0x9BCA \ + 0x9BB9 0x9BC6 0x9BCF 0x9BD1 0x9BD2 0x9BE3 0x9BE2 0x9BE4 \ + 0x9BD4 0x9BE1 0x9C3A 0x9BF2 0x9BF1 0x9BF0 0x9C15 0x9C14 \ + 0x9C09 0x9C13 0x9C0C 0x9C06 0x9C08 0x9C12 0x9C0A 0x9C04 \ + 0x9C2E 0x9C1B 0x9C25 0x9C24 0x9C21 0x9C30 0x9C47 0x9C32 +31 0x9C46 0x9C3E 0x9C5A 0x9C60 0x9C67 0x9C76 0x9C78 0x9CE7 \ + 0x9CEC 0x9CF0 0x9D09 0x9D08 0x9CEB 0x9D03 0x9D06 0x9D2A \ + 0x9D26 0x9DAF 0x9D23 0x9D1F 0x9D44 0x9D15 0x9D12 0x9D41 \ + 0x9D3F 0x9D3E 0x9D46 0x9D48 0x9D5D 0x9D5E 0x9D64 0x9D51 \ + 0x9D50 0x9D59 0x9D72 0x9D89 0x9D87 0x9DAB 0x9D6F 0x9D7A \ + 0x9D9A 0x9DA4 0x9DA9 0x9DB2 0x9DC4 0x9DC1 0x9DBB 0x9DB8 \ + 0x9DBA 0x9DC6 0x9DCF 0x9DC2 0x9DD9 0x9DD3 0x9DF8 0x9DE6 \ + 0x9DED 0x9DEF 0x9DFD 0x9E1A 0x9E1B 0x9E1E 0x9E75 0x9E79 \ + 0x9E7D 0x9E81 0x9E88 0x9E8B 0x9E8C 0x9E92 0x9E95 0x9E91 \ + 0x9E9D 0x9EA5 0x9EA9 0x9EB8 0x9EAA 0x9EAD 0x9761 0x9ECC \ + 0x9ECE 0x9ECF 0x9ED0 0x9ED4 0x9EDC 0x9EDE 0x9EDD 0x9EE0 \ + 0x9EE5 0x9EE8 0x9EEF 0x9EF4 0x9EF6 0x9EF7 0x9EF9 0x9EFB \ + 0x9EFC 0x9EFD 0x9F07 0x9F08 0x76B7 0x9F15 0x9F21 0x9F2C \ + 0x9F3E 0x9F4A 0x9F52 0x9F54 0x9F63 0x9F5F 0x9F60 0x9F61 \ + 0x9F66 0x9F67 0x9F6C 0x9F6A 0x9F77 0x9F72 0x9F76 0x9F95 \ + 0x9F9C 0x9FA0 0x582F 0x69C7 0x9059 0x7464 0x51DC 0x7199 \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +32 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +33 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +34 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +35 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE + +# eof diff --git a/contrib/ttf2pk/data/UKS.sfd b/contrib/ttf2pk/data/UKS.sfd new file mode 100644 index 0000000..c90314a --- /dev/null +++ b/contrib/ttf2pk/data/UKS.sfd @@ -0,0 +1,1114 @@ +# UKS.sfd +# +# subfont numbers for KSC 5601 encoding and its corresponding code ranges +# to be used with the CJK package for LaTeX. +# +# The input encoding is Unicode. + +01 0x3000 0x3001 0x3002 0x00B7 0x2025 0x2026 0x00A8 0x3003 \ + 0x00AD 0x2015 0x2225 0xFF3C 0x223C 0x2018 0x2019 0x201C \ + 0x201D 0x3014 0x3015 0x3008 0x3009 0x300A 0x300B 0x300C \ + 0x300D 0x300E 0x300F 0x3010 0x3011 0x00B1 0x00D7 0x00F7 \ + 0x2260 0x2264 0x2265 0x221E 0x2234 0x00B0 0x2032 0x2033 \ + 0x2103 0x212B 0xFFE0 0xFFE1 0xFFE5 0x2642 0x2640 0x2220 \ + 0x22A5 0x2312 0x2202 0x2207 0x2261 0x2252 0x00A7 0x203B \ + 0x2606 0x2605 0x25CB 0x25CF 0x25CE 0x25C7 0x25C6 0x25A1 \ + 0x25A0 0x25B3 0x25B2 0x25BD 0x25BC 0x2192 0x2190 0x2191 \ + 0x2193 0x2194 0x3013 0x226A 0x226B 0x221A 0x223D 0x221D \ + 0x2235 0x222B 0x222C 0x2208 0x220B 0x2286 0x2287 0x2282 \ + 0x2283 0x222A 0x2229 0x2227 0x2228 0xFFE2 0x21D2 0x21D4 \ + 0x2200 0x2203 0x00B4 0xFF5E 0x02C7 0x02D8 0x02DD 0x02DA \ + 0x02D9 0x00B8 0x02DB 0x00A1 0x00BF 0x02D0 0x222E 0x2211 \ + 0x220F 0x00A4 0x2109 0x2030 0x25C1 0x25C0 0x25B7 0x25B6 \ + 0x2664 0x2660 0x2661 0x2665 0x2667 0x2663 0x2299 0x25C8 \ + 0x25A3 0x25D0 0x25D1 0x2592 0x25A4 0x25A5 0x25A8 0x25A7 \ + 0x25A6 0x25A9 0x2668 0x260F 0x260E 0x261C 0x261E 0x00B6 \ + 0x2020 0x2021 0x2195 0x2197 0x2199 0x2196 0x2198 0x266D \ + 0x2669 0x266A 0x266C 0x327F 0x321C 0x2116 0x33C7 0x2122 \ + 0x33C2 0x33D8 0x2121 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFF01 0xFF02 0xFF03 0xFF04 \ + 0xFF05 0xFF06 0xFF07 0xFF08 0xFF09 0xFF0A 0xFF0B 0xFF0C \ + 0xFF0D 0xFF0E 0xFF0F 0xFF10 0xFF11 0xFF12 0xFF13 0xFF14 \ + 0xFF15 0xFF16 0xFF17 0xFF18 0xFF19 0xFF1A 0xFF1B 0xFF1C \ + 0xFF1D 0xFF1E 0xFF1F 0xFF20 0xFF21 0xFF22 0xFF23 0xFF24 \ + 0xFF25 0xFF26 0xFF27 0xFF28 0xFF29 0xFF2A 0xFF2B 0xFF2C \ + 0xFF2D 0xFF2E 0xFF2F 0xFF30 0xFF31 0xFF32 0xFF33 0xFF34 \ + 0xFF35 0xFF36 0xFF37 0xFF38 0xFF39 0xFF3A 0xFF3B 0xFFE6 \ + 0xFF3D 0xFF3E 0xFF3F 0xFF40 0xFF41 0xFF42 0xFF43 0xFF44 +02 0xFF45 0xFF46 0xFF47 0xFF48 0xFF49 0xFF4A 0xFF4B 0xFF4C \ + 0xFF4D 0xFF4E 0xFF4F 0xFF50 0xFF51 0xFF52 0xFF53 0xFF54 \ + 0xFF55 0xFF56 0xFF57 0xFF58 0xFF59 0xFF5A 0xFF5B 0xFF5C \ + 0xFF5D 0xFFE3 0x3131 0x3132 0x3133 0x3134 0x3135 0x3136 \ + 0x3137 0x3138 0x3139 0x313A 0x313B 0x313C 0x313D 0x313E \ + 0x313F 0x3140 0x3141 0x3142 0x3143 0x3144 0x3145 0x3146 \ + 0x3147 0x3148 0x3149 0x314A 0x314B 0x314C 0x314D 0x314E \ + 0x314F 0x3150 0x3151 0x3152 0x3153 0x3154 0x3155 0x3156 \ + 0x3157 0x3158 0x3159 0x315A 0x315B 0x315C 0x315D 0x315E \ + 0x315F 0x3160 0x3161 0x3162 0x3163 0x3164 0x3165 0x3166 \ + 0x3167 0x3168 0x3169 0x316A 0x316B 0x316C 0x316D 0x316E \ + 0x316F 0x3170 0x3171 0x3172 0x3173 0x3174 0x3175 0x3176 \ + 0x3177 0x3178 0x3179 0x317A 0x317B 0x317C 0x317D 0x317E \ + 0x317F 0x3180 0x3181 0x3182 0x3183 0x3184 0x3185 0x3186 \ + 0x3187 0x3188 0x3189 0x318A 0x318B 0x318C 0x318D 0x318E \ + 0x2170 0x2171 0x2172 0x2173 0x2174 0x2175 0x2176 0x2177 \ + 0x2178 0x2179 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x2160 \ + 0x2161 0x2162 0x2163 0x2164 0x2165 0x2166 0x2167 0x2168 \ + 0x2169 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0x0391 0x0392 0x0393 0x0394 0x0395 0x0396 0x0397 0x0398 \ + 0x0399 0x039A 0x039B 0x039C 0x039D 0x039E 0x039F 0x03A0 \ + 0x03A1 0x03A3 0x03A4 0x03A5 0x03A6 0x03A7 0x03A8 0x03A9 \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0x03B1 0x03B2 0x03B3 0x03B4 0x03B5 0x03B6 0x03B7 0x03B8 \ + 0x03B9 0x03BA 0x03BB 0x03BC 0x03BD 0x03BE 0x03BF 0x03C0 \ + 0x03C1 0x03C3 0x03C4 0x03C5 0x03C6 0x03C7 0x03C8 0x03C9 \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x2500 0x2502 \ + 0x250C 0x2510 0x2518 0x2514 0x251C 0x252C 0x2524 0x2534 \ + 0x253C 0x2501 0x2503 0x250F 0x2513 0x251B 0x2517 0x2523 \ + 0x2533 0x252B 0x253B 0x254B 0x2520 0x252F 0x2528 0x2537 \ + 0x253F 0x251D 0x2530 0x2525 0x2538 0x2542 0x2512 0x2511 \ + 0x251A 0x2519 0x2516 0x2515 0x250E 0x250D 0x251E 0x251F +03 0x2521 0x2522 0x2526 0x2527 0x2529 0x252A 0x252D 0x252E \ + 0x2531 0x2532 0x2535 0x2536 0x2539 0x253A 0x253D 0x253E \ + 0x2540 0x2541 0x2543 0x2544 0x2545 0x2546 0x2547 0x2548 \ + 0x2549 0x254A 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x3395 0x3396 0x3397 0x2113 \ + 0x3398 0x33C4 0x33A3 0x33A4 0x33A5 0x33A6 0x3399 0x339A \ + 0x339B 0x339C 0x339D 0x339E 0x339F 0x33A0 0x33A1 0x33A2 \ + 0x33CA 0x338D 0x338E 0x338F 0x33CF 0x3388 0x3389 0x33C8 \ + 0x33A7 0x33A8 0x33B0 0x33B1 0x33B2 0x33B3 0x33B4 0x33B5 \ + 0x33B6 0x33B7 0x33B8 0x33B9 0x3380 0x3381 0x3382 0x3383 \ + 0x3384 0x33BA 0x33BB 0x33BC 0x33BD 0x33BE 0x33BF 0x3390 \ + 0x3391 0x3392 0x3393 0x3394 0x2126 0x33C0 0x33C1 0x338A \ + 0x338B 0x338C 0x33D6 0x33C5 0x33AD 0x33AE 0x33AF 0x33DB \ + 0x33A9 0x33AA 0x33AB 0x33AC 0x33DD 0x33D0 0x33D3 0x33C3 \ + 0x33C9 0x33DC 0x33C6 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x00C6 0x00D0 0x00AA 0x0126 0xFFFE 0x0132 \ + 0xFFFE 0x013F 0x0141 0x00D8 0x0152 0x00BA 0x00DE 0x0166 \ + 0x014A 0xFFFE 0x3260 0x3261 0x3262 0x3263 0x3264 0x3265 \ + 0x3266 0x3267 0x3268 0x3269 0x326A 0x326B 0x326C 0x326D \ + 0x326E 0x326F 0x3270 0x3271 0x3272 0x3273 0x3274 0x3275 \ + 0x3276 0x3277 0x3278 0x3279 0x327A 0x327B 0x24D0 0x24D1 \ + 0x24D2 0x24D3 0x24D4 0x24D5 0x24D6 0x24D7 0x24D8 0x24D9 \ + 0x24DA 0x24DB 0x24DC 0x24DD 0x24DE 0x24DF 0x24E0 0x24E1 \ + 0x24E2 0x24E3 0x24E4 0x24E5 0x24E6 0x24E7 0x24E8 0x24E9 \ + 0x2460 0x2461 0x2462 0x2463 0x2464 0x2465 0x2466 0x2467 \ + 0x2468 0x2469 0x246A 0x246B 0x246C 0x246D 0x246E 0x00BD \ + 0x2153 0x2154 0x00BC 0x00BE 0x215B 0x215C 0x215D 0x215E \ + 0x00E6 0x0111 0x00F0 0x0127 0x0131 0x0133 0x0138 0x0140 \ + 0x0142 0x00F8 0x0153 0x00DF 0x00FE 0x0167 0x014B 0x0149 +04 0x3200 0x3201 0x3202 0x3203 0x3204 0x3205 0x3206 0x3207 \ + 0x3208 0x3209 0x320A 0x320B 0x320C 0x320D 0x320E 0x320F \ + 0x3210 0x3211 0x3212 0x3213 0x3214 0x3215 0x3216 0x3217 \ + 0x3218 0x3219 0x321A 0x321B 0x249C 0x249D 0x249E 0x249F \ + 0x24A0 0x24A1 0x24A2 0x24A3 0x24A4 0x24A5 0x24A6 0x24A7 \ + 0x24A8 0x24A9 0x24AA 0x24AB 0x24AC 0x24AD 0x24AE 0x24AF \ + 0x24B0 0x24B1 0x24B2 0x24B3 0x24B4 0x24B5 0x2474 0x2475 \ + 0x2476 0x2477 0x2478 0x2479 0x247A 0x247B 0x247C 0x247D \ + 0x247E 0x247F 0x2480 0x2481 0x2482 0x00B9 0x00B2 0x00B3 \ + 0x2074 0x207F 0x2081 0x2082 0x2083 0x2084 0x3041 0x3042 \ + 0x3043 0x3044 0x3045 0x3046 0x3047 0x3048 0x3049 0x304A \ + 0x304B 0x304C 0x304D 0x304E 0x304F 0x3050 0x3051 0x3052 \ + 0x3053 0x3054 0x3055 0x3056 0x3057 0x3058 0x3059 0x305A \ + 0x305B 0x305C 0x305D 0x305E 0x305F 0x3060 0x3061 0x3062 \ + 0x3063 0x3064 0x3065 0x3066 0x3067 0x3068 0x3069 0x306A \ + 0x306B 0x306C 0x306D 0x306E 0x306F 0x3070 0x3071 0x3072 \ + 0x3073 0x3074 0x3075 0x3076 0x3077 0x3078 0x3079 0x307A \ + 0x307B 0x307C 0x307D 0x307E 0x307F 0x3080 0x3081 0x3082 \ + 0x3083 0x3084 0x3085 0x3086 0x3087 0x3088 0x3089 0x308A \ + 0x308B 0x308C 0x308D 0x308E 0x308F 0x3090 0x3091 0x3092 \ + 0x3093 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x30A1 0x30A2 0x30A3 0x30A4 \ + 0x30A5 0x30A6 0x30A7 0x30A8 0x30A9 0x30AA 0x30AB 0x30AC \ + 0x30AD 0x30AE 0x30AF 0x30B0 0x30B1 0x30B2 0x30B3 0x30B4 \ + 0x30B5 0x30B6 0x30B7 0x30B8 0x30B9 0x30BA 0x30BB 0x30BC \ + 0x30BD 0x30BE 0x30BF 0x30C0 0x30C1 0x30C2 0x30C3 0x30C4 \ + 0x30C5 0x30C6 0x30C7 0x30C8 0x30C9 0x30CA 0x30CB 0x30CC \ + 0x30CD 0x30CE 0x30CF 0x30D0 0x30D1 0x30D2 0x30D3 0x30D4 \ + 0x30D5 0x30D6 0x30D7 0x30D8 0x30D9 0x30DA 0x30DB 0x30DC \ + 0x30DD 0x30DE 0x30DF 0x30E0 0x30E1 0x30E2 0x30E3 0x30E4 \ + 0x30E5 0x30E6 0x30E7 0x30E8 0x30E9 0x30EA 0x30EB 0x30EC \ + 0x30ED 0x30EE 0x30EF 0x30F0 0x30F1 0x30F2 0x30F3 0x30F4 +05 0x30F5 0x30F6 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x0410 0x0411 0x0412 0x0413 0x0414 0x0415 \ + 0x0401 0x0416 0x0417 0x0418 0x0419 0x041A 0x041B 0x041C \ + 0x041D 0x041E 0x041F 0x0420 0x0421 0x0422 0x0423 0x0424 \ + 0x0425 0x0426 0x0427 0x0428 0x0429 0x042A 0x042B 0x042C \ + 0x042D 0x042E 0x042F 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x0430 0x0431 0x0432 0x0433 0x0434 0x0435 \ + 0x0451 0x0436 0x0437 0x0438 0x0439 0x043A 0x043B 0x043C \ + 0x043D 0x043E 0x043F 0x0440 0x0441 0x0442 0x0443 0x0444 \ + 0x0445 0x0446 0x0447 0x0448 0x0449 0x044A 0x044B 0x044C \ + 0x044D 0x044E 0x044F 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +06 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xAC00 0xAC01 0xAC04 0xAC07 0xAC08 0xAC09 \ + 0xAC0A 0xAC10 0xAC11 0xAC12 0xAC13 0xAC14 0xAC15 0xAC16 \ + 0xAC17 0xAC19 0xAC1A 0xAC1B 0xAC1C 0xAC1D 0xAC20 0xAC24 \ + 0xAC2C 0xAC2D 0xAC2F 0xAC30 0xAC31 0xAC38 0xAC39 0xAC3C \ + 0xAC40 0xAC4B 0xAC4D 0xAC54 0xAC58 0xAC5C 0xAC70 0xAC71 \ + 0xAC74 0xAC77 0xAC78 0xAC7A 0xAC80 0xAC81 0xAC83 0xAC84 \ + 0xAC85 0xAC86 0xAC89 0xAC8A 0xAC8B 0xAC8C 0xAC90 0xAC94 \ + 0xAC9C 0xAC9D 0xAC9F 0xACA0 0xACA1 0xACA8 0xACA9 0xACAA \ + 0xACAC 0xACAF 0xACB0 0xACB8 0xACB9 0xACBB 0xACBC 0xACBD \ + 0xACC1 0xACC4 0xACC8 0xACCC 0xACD5 0xACD7 0xACE0 0xACE1 \ + 0xACE4 0xACE7 0xACE8 0xACEA 0xACEC 0xACEF 0xACF0 0xACF1 \ + 0xACF3 0xACF5 0xACF6 0xACFC 0xACFD 0xAD00 0xAD04 0xAD06 \ + 0xAD0C 0xAD0D 0xAD0F 0xAD11 0xAD18 0xAD1C 0xAD20 0xAD29 \ + 0xAD2C 0xAD2D 0xAD34 0xAD35 0xAD38 0xAD3C 0xAD44 0xAD45 \ + 0xAD47 0xAD49 0xAD50 0xAD54 0xAD58 0xAD61 0xAD63 0xAD6C \ + 0xAD6D 0xAD70 0xAD73 0xAD74 0xAD75 0xAD76 0xAD7B 0xAD7C +07 0xAD7D 0xAD7F 0xAD81 0xAD82 0xAD88 0xAD89 0xAD8C 0xAD90 \ + 0xAD9C 0xAD9D 0xADA4 0xADB7 0xADC0 0xADC1 0xADC4 0xADC8 \ + 0xADD0 0xADD1 0xADD3 0xADDC 0xADE0 0xADE4 0xADF8 0xADF9 \ + 0xADFC 0xADFF 0xAE00 0xAE01 0xAE08 0xAE09 0xAE0B 0xAE0D \ + 0xAE14 0xAE30 0xAE31 0xAE34 0xAE37 0xAE38 0xAE3A 0xAE40 \ + 0xAE41 0xAE43 0xAE45 0xAE46 0xAE4A 0xAE4C 0xAE4D 0xAE4E \ + 0xAE50 0xAE54 0xAE56 0xAE5C 0xAE5D 0xAE5F 0xAE60 0xAE61 \ + 0xAE65 0xAE68 0xAE69 0xAE6C 0xAE70 0xAE78 0xAE79 0xAE7B \ + 0xAE7C 0xAE7D 0xAE84 0xAE85 0xAE8C 0xAEBC 0xAEBD 0xAEBE \ + 0xAEC0 0xAEC4 0xAECC 0xAECD 0xAECF 0xAED0 0xAED1 0xAED8 \ + 0xAED9 0xAEDC 0xAEE8 0xAEEB 0xAEED 0xAEF4 0xAEF8 0xAEFC \ + 0xAF07 0xAF08 0xAF0D 0xAF10 0xAF2C 0xAF2D 0xAF30 0xAF32 \ + 0xAF34 0xAF3C 0xAF3D 0xAF3F 0xAF41 0xAF42 0xAF43 0xAF48 \ + 0xAF49 0xAF50 0xAF5C 0xAF5D 0xAF64 0xAF65 0xAF79 0xAF80 \ + 0xAF84 0xAF88 0xAF90 0xAF91 0xAF95 0xAF9C 0xAFB8 0xAFB9 \ + 0xAFBC 0xAFC0 0xAFC7 0xAFC8 0xAFC9 0xAFCB 0xAFCD 0xAFCE \ + 0xAFD4 0xAFDC 0xAFE8 0xAFE9 0xAFF0 0xAFF1 0xAFF4 0xAFF8 \ + 0xB000 0xB001 0xB004 0xB00C 0xB010 0xB014 0xB01C 0xB01D \ + 0xB028 0xB044 0xB045 0xB048 0xB04A 0xB04C 0xB04E 0xB053 \ + 0xB054 0xB055 0xB057 0xB059 0xB05D 0xB07C 0xB07D 0xB080 \ + 0xB084 0xB08C 0xB08D 0xB08F 0xB091 0xB098 0xB099 0xB09A \ + 0xB09C 0xB09F 0xB0A0 0xB0A1 0xB0A2 0xB0A8 0xB0A9 0xB0AB \ + 0xB0AC 0xB0AD 0xB0AE 0xB0AF 0xB0B1 0xB0B3 0xB0B4 0xB0B5 \ + 0xB0B8 0xB0BC 0xB0C4 0xB0C5 0xB0C7 0xB0C8 0xB0C9 0xB0D0 \ + 0xB0D1 0xB0D4 0xB0D8 0xB0E0 0xB0E5 0xB108 0xB109 0xB10B \ + 0xB10C 0xB110 0xB112 0xB113 0xB118 0xB119 0xB11B 0xB11C \ + 0xB11D 0xB123 0xB124 0xB125 0xB128 0xB12C 0xB134 0xB135 \ + 0xB137 0xB138 0xB139 0xB140 0xB141 0xB144 0xB148 0xB150 \ + 0xB151 0xB154 0xB155 0xB158 0xB15C 0xB160 0xB178 0xB179 \ + 0xB17C 0xB180 0xB182 0xB188 0xB189 0xB18B 0xB18D 0xB192 \ + 0xB193 0xB194 0xB198 0xB19C 0xB1A8 0xB1CC 0xB1D0 0xB1D4 \ + 0xB1DC 0xB1DD 0xB1DF 0xB1E8 0xB1E9 0xB1EC 0xB1F0 0xB1F9 +08 0xB1FB 0xB1FD 0xB204 0xB205 0xB208 0xB20B 0xB20C 0xB214 \ + 0xB215 0xB217 0xB219 0xB220 0xB234 0xB23C 0xB258 0xB25C \ + 0xB260 0xB268 0xB269 0xB274 0xB275 0xB27C 0xB284 0xB285 \ + 0xB289 0xB290 0xB291 0xB294 0xB298 0xB299 0xB29A 0xB2A0 \ + 0xB2A1 0xB2A3 0xB2A5 0xB2A6 0xB2AA 0xB2AC 0xB2B0 0xB2B4 \ + 0xB2C8 0xB2C9 0xB2CC 0xB2D0 0xB2D2 0xB2D8 0xB2D9 0xB2DB \ + 0xB2DD 0xB2E2 0xB2E4 0xB2E5 0xB2E6 0xB2E8 0xB2EB 0xB2EC \ + 0xB2ED 0xB2EE 0xB2EF 0xB2F3 0xB2F4 0xB2F5 0xB2F7 0xB2F8 \ + 0xB2F9 0xB2FA 0xB2FB 0xB2FF 0xB300 0xB301 0xB304 0xB308 \ + 0xB310 0xB311 0xB313 0xB314 0xB315 0xB31C 0xB354 0xB355 \ + 0xB356 0xB358 0xB35B 0xB35C 0xB35E 0xB35F 0xB364 0xB365 \ + 0xB367 0xB369 0xB36B 0xB36E 0xB370 0xB371 0xB374 0xB378 \ + 0xB380 0xB381 0xB383 0xB384 0xB385 0xB38C 0xB390 0xB394 \ + 0xB3A0 0xB3A1 0xB3A8 0xB3AC 0xB3C4 0xB3C5 0xB3C8 0xB3CB \ + 0xB3CC 0xB3CE 0xB3D0 0xB3D4 0xB3D5 0xB3D7 0xB3D9 0xB3DB \ + 0xB3DD 0xB3E0 0xB3E4 0xB3E8 0xB3FC 0xB410 0xB418 0xB41C \ + 0xB420 0xB428 0xB429 0xB42B 0xB434 0xB450 0xB451 0xB454 \ + 0xB458 0xB460 0xB461 0xB463 0xB465 0xB46C 0xB480 0xB488 \ + 0xB49D 0xB4A4 0xB4A8 0xB4AC 0xB4B5 0xB4B7 0xB4B9 0xB4C0 \ + 0xB4C4 0xB4C8 0xB4D0 0xB4D5 0xB4DC 0xB4DD 0xB4E0 0xB4E3 \ + 0xB4E4 0xB4E6 0xB4EC 0xB4ED 0xB4EF 0xB4F1 0xB4F8 0xB514 \ + 0xB515 0xB518 0xB51B 0xB51C 0xB524 0xB525 0xB527 0xB528 \ + 0xB529 0xB52A 0xB530 0xB531 0xB534 0xB538 0xB540 0xB541 \ + 0xB543 0xB544 0xB545 0xB54B 0xB54C 0xB54D 0xB550 0xB554 \ + 0xB55C 0xB55D 0xB55F 0xB560 0xB561 0xB5A0 0xB5A1 0xB5A4 \ + 0xB5A8 0xB5AA 0xB5AB 0xB5B0 0xB5B1 0xB5B3 0xB5B4 0xB5B5 \ + 0xB5BB 0xB5BC 0xB5BD 0xB5C0 0xB5C4 0xB5CC 0xB5CD 0xB5CF \ + 0xB5D0 0xB5D1 0xB5D8 0xB5EC 0xB610 0xB611 0xB614 0xB618 \ + 0xB625 0xB62C 0xB634 0xB648 0xB664 0xB668 0xB69C 0xB69D \ + 0xB6A0 0xB6A4 0xB6AB 0xB6AC 0xB6B1 0xB6D4 0xB6F0 0xB6F4 \ + 0xB6F8 0xB700 0xB701 0xB705 0xB728 0xB729 0xB72C 0xB72F \ + 0xB730 0xB738 0xB739 0xB73B 0xB744 0xB748 0xB74C 0xB754 +09 0xB755 0xB760 0xB764 0xB768 0xB770 0xB771 0xB773 0xB775 \ + 0xB77C 0xB77D 0xB780 0xB784 0xB78C 0xB78D 0xB78F 0xB790 \ + 0xB791 0xB792 0xB796 0xB797 0xB798 0xB799 0xB79C 0xB7A0 \ + 0xB7A8 0xB7A9 0xB7AB 0xB7AC 0xB7AD 0xB7B4 0xB7B5 0xB7B8 \ + 0xB7C7 0xB7C9 0xB7EC 0xB7ED 0xB7F0 0xB7F4 0xB7FC 0xB7FD \ + 0xB7FF 0xB800 0xB801 0xB807 0xB808 0xB809 0xB80C 0xB810 \ + 0xB818 0xB819 0xB81B 0xB81D 0xB824 0xB825 0xB828 0xB82C \ + 0xB834 0xB835 0xB837 0xB838 0xB839 0xB840 0xB844 0xB851 \ + 0xB853 0xB85C 0xB85D 0xB860 0xB864 0xB86C 0xB86D 0xB86F \ + 0xB871 0xB878 0xB87C 0xB88D 0xB8A8 0xB8B0 0xB8B4 0xB8B8 \ + 0xB8C0 0xB8C1 0xB8C3 0xB8C5 0xB8CC 0xB8D0 0xB8D4 0xB8DD \ + 0xB8DF 0xB8E1 0xB8E8 0xB8E9 0xB8EC 0xB8F0 0xB8F8 0xB8F9 \ + 0xB8FB 0xB8FD 0xB904 0xB918 0xB920 0xB93C 0xB93D 0xB940 \ + 0xB944 0xB94C 0xB94F 0xB951 0xB958 0xB959 0xB95C 0xB960 \ + 0xB968 0xB969 0xB96B 0xB96D 0xB974 0xB975 0xB978 0xB97C \ + 0xB984 0xB985 0xB987 0xB989 0xB98A 0xB98D 0xB98E 0xB9AC \ + 0xB9AD 0xB9B0 0xB9B4 0xB9BC 0xB9BD 0xB9BF 0xB9C1 0xB9C8 \ + 0xB9C9 0xB9CC 0xB9CE 0xB9CF 0xB9D0 0xB9D1 0xB9D2 0xB9D8 \ + 0xB9D9 0xB9DB 0xB9DD 0xB9DE 0xB9E1 0xB9E3 0xB9E4 0xB9E5 \ + 0xB9E8 0xB9EC 0xB9F4 0xB9F5 0xB9F7 0xB9F8 0xB9F9 0xB9FA \ + 0xBA00 0xBA01 0xBA08 0xBA15 0xBA38 0xBA39 0xBA3C 0xBA40 \ + 0xBA42 0xBA48 0xBA49 0xBA4B 0xBA4D 0xBA4E 0xBA53 0xBA54 \ + 0xBA55 0xBA58 0xBA5C 0xBA64 0xBA65 0xBA67 0xBA68 0xBA69 \ + 0xBA70 0xBA71 0xBA74 0xBA78 0xBA83 0xBA84 0xBA85 0xBA87 \ + 0xBA8C 0xBAA8 0xBAA9 0xBAAB 0xBAAC 0xBAB0 0xBAB2 0xBAB8 \ + 0xBAB9 0xBABB 0xBABD 0xBAC4 0xBAC8 0xBAD8 0xBAD9 0xBAFC \ + 0xBB00 0xBB04 0xBB0D 0xBB0F 0xBB11 0xBB18 0xBB1C 0xBB20 \ + 0xBB29 0xBB2B 0xBB34 0xBB35 0xBB36 0xBB38 0xBB3B 0xBB3C \ + 0xBB3D 0xBB3E 0xBB44 0xBB45 0xBB47 0xBB49 0xBB4D 0xBB4F \ + 0xBB50 0xBB54 0xBB58 0xBB61 0xBB63 0xBB6C 0xBB88 0xBB8C \ + 0xBB90 0xBBA4 0xBBA8 0xBBAC 0xBBB4 0xBBB7 0xBBC0 0xBBC4 \ + 0xBBC8 0xBBD0 0xBBD3 0xBBF8 0xBBF9 0xBBFC 0xBBFF 0xBC00 +10 0xBC02 0xBC08 0xBC09 0xBC0B 0xBC0C 0xBC0D 0xBC0F 0xBC11 \ + 0xBC14 0xBC15 0xBC16 0xBC17 0xBC18 0xBC1B 0xBC1C 0xBC1D \ + 0xBC1E 0xBC1F 0xBC24 0xBC25 0xBC27 0xBC29 0xBC2D 0xBC30 \ + 0xBC31 0xBC34 0xBC38 0xBC40 0xBC41 0xBC43 0xBC44 0xBC45 \ + 0xBC49 0xBC4C 0xBC4D 0xBC50 0xBC5D 0xBC84 0xBC85 0xBC88 \ + 0xBC8B 0xBC8C 0xBC8E 0xBC94 0xBC95 0xBC97 0xBC99 0xBC9A \ + 0xBCA0 0xBCA1 0xBCA4 0xBCA7 0xBCA8 0xBCB0 0xBCB1 0xBCB3 \ + 0xBCB4 0xBCB5 0xBCBC 0xBCBD 0xBCC0 0xBCC4 0xBCCD 0xBCCF \ + 0xBCD0 0xBCD1 0xBCD5 0xBCD8 0xBCDC 0xBCF4 0xBCF5 0xBCF6 \ + 0xBCF8 0xBCFC 0xBD04 0xBD05 0xBD07 0xBD09 0xBD10 0xBD14 \ + 0xBD24 0xBD2C 0xBD40 0xBD48 0xBD49 0xBD4C 0xBD50 0xBD58 \ + 0xBD59 0xBD64 0xBD68 0xBD80 0xBD81 0xBD84 0xBD87 0xBD88 \ + 0xBD89 0xBD8A 0xBD90 0xBD91 0xBD93 0xBD95 0xBD99 0xBD9A \ + 0xBD9C 0xBDA4 0xBDB0 0xBDB8 0xBDD4 0xBDD5 0xBDD8 0xBDDC \ + 0xBDE9 0xBDF0 0xBDF4 0xBDF8 0xBE00 0xBE03 0xBE05 0xBE0C \ + 0xBE0D 0xBE10 0xBE14 0xBE1C 0xBE1D 0xBE1F 0xBE44 0xBE45 \ + 0xBE48 0xBE4C 0xBE4E 0xBE54 0xBE55 0xBE57 0xBE59 0xBE5A \ + 0xBE5B 0xBE60 0xBE61 0xBE64 0xBE68 0xBE6A 0xBE70 0xBE71 \ + 0xBE73 0xBE74 0xBE75 0xBE7B 0xBE7C 0xBE7D 0xBE80 0xBE84 \ + 0xBE8C 0xBE8D 0xBE8F 0xBE90 0xBE91 0xBE98 0xBE99 0xBEA8 \ + 0xBED0 0xBED1 0xBED4 0xBED7 0xBED8 0xBEE0 0xBEE3 0xBEE4 \ + 0xBEE5 0xBEEC 0xBF01 0xBF08 0xBF09 0xBF18 0xBF19 0xBF1B \ + 0xBF1C 0xBF1D 0xBF40 0xBF41 0xBF44 0xBF48 0xBF50 0xBF51 \ + 0xBF55 0xBF94 0xBFB0 0xBFC5 0xBFCC 0xBFCD 0xBFD0 0xBFD4 \ + 0xBFDC 0xBFDF 0xBFE1 0xC03C 0xC051 0xC058 0xC05C 0xC060 \ + 0xC068 0xC069 0xC090 0xC091 0xC094 0xC098 0xC0A0 0xC0A1 \ + 0xC0A3 0xC0A5 0xC0AC 0xC0AD 0xC0AF 0xC0B0 0xC0B3 0xC0B4 \ + 0xC0B5 0xC0B6 0xC0BC 0xC0BD 0xC0BF 0xC0C0 0xC0C1 0xC0C5 \ + 0xC0C8 0xC0C9 0xC0CC 0xC0D0 0xC0D8 0xC0D9 0xC0DB 0xC0DC \ + 0xC0DD 0xC0E4 0xC0E5 0xC0E8 0xC0EC 0xC0F4 0xC0F5 0xC0F7 \ + 0xC0F9 0xC100 0xC104 0xC108 0xC110 0xC115 0xC11C 0xC11D \ + 0xC11E 0xC11F 0xC120 0xC123 0xC124 0xC126 0xC127 0xC12C +11 0xC12D 0xC12F 0xC130 0xC131 0xC136 0xC138 0xC139 0xC13C \ + 0xC140 0xC148 0xC149 0xC14B 0xC14C 0xC14D 0xC154 0xC155 \ + 0xC158 0xC15C 0xC164 0xC165 0xC167 0xC168 0xC169 0xC170 \ + 0xC174 0xC178 0xC185 0xC18C 0xC18D 0xC18E 0xC190 0xC194 \ + 0xC196 0xC19C 0xC19D 0xC19F 0xC1A1 0xC1A5 0xC1A8 0xC1A9 \ + 0xC1AC 0xC1B0 0xC1BD 0xC1C4 0xC1C8 0xC1CC 0xC1D4 0xC1D7 \ + 0xC1D8 0xC1E0 0xC1E4 0xC1E8 0xC1F0 0xC1F1 0xC1F3 0xC1FC \ + 0xC1FD 0xC200 0xC204 0xC20C 0xC20D 0xC20F 0xC211 0xC218 \ + 0xC219 0xC21C 0xC21F 0xC220 0xC228 0xC229 0xC22B 0xC22D \ + 0xC22F 0xC231 0xC232 0xC234 0xC248 0xC250 0xC251 0xC254 \ + 0xC258 0xC260 0xC265 0xC26C 0xC26D 0xC270 0xC274 0xC27C \ + 0xC27D 0xC27F 0xC281 0xC288 0xC289 0xC290 0xC298 0xC29B \ + 0xC29D 0xC2A4 0xC2A5 0xC2A8 0xC2AC 0xC2AD 0xC2B4 0xC2B5 \ + 0xC2B7 0xC2B9 0xC2DC 0xC2DD 0xC2E0 0xC2E3 0xC2E4 0xC2EB \ + 0xC2EC 0xC2ED 0xC2EF 0xC2F1 0xC2F6 0xC2F8 0xC2F9 0xC2FB \ + 0xC2FC 0xC300 0xC308 0xC309 0xC30C 0xC30D 0xC313 0xC314 \ + 0xC315 0xC318 0xC31C 0xC324 0xC325 0xC328 0xC329 0xC345 \ + 0xC368 0xC369 0xC36C 0xC370 0xC372 0xC378 0xC379 0xC37C \ + 0xC37D 0xC384 0xC388 0xC38C 0xC3C0 0xC3D8 0xC3D9 0xC3DC \ + 0xC3DF 0xC3E0 0xC3E2 0xC3E8 0xC3E9 0xC3ED 0xC3F4 0xC3F5 \ + 0xC3F8 0xC408 0xC410 0xC424 0xC42C 0xC430 0xC434 0xC43C \ + 0xC43D 0xC448 0xC464 0xC465 0xC468 0xC46C 0xC474 0xC475 \ + 0xC479 0xC480 0xC494 0xC49C 0xC4B8 0xC4BC 0xC4E9 0xC4F0 \ + 0xC4F1 0xC4F4 0xC4F8 0xC4FA 0xC4FF 0xC500 0xC501 0xC50C \ + 0xC510 0xC514 0xC51C 0xC528 0xC529 0xC52C 0xC530 0xC538 \ + 0xC539 0xC53B 0xC53D 0xC544 0xC545 0xC548 0xC549 0xC54A \ + 0xC54C 0xC54D 0xC54E 0xC553 0xC554 0xC555 0xC557 0xC558 \ + 0xC559 0xC55D 0xC55E 0xC560 0xC561 0xC564 0xC568 0xC570 \ + 0xC571 0xC573 0xC574 0xC575 0xC57C 0xC57D 0xC580 0xC584 \ + 0xC587 0xC58C 0xC58D 0xC58F 0xC591 0xC595 0xC597 0xC598 \ + 0xC59C 0xC5A0 0xC5A9 0xC5B4 0xC5B5 0xC5B8 0xC5B9 0xC5BB \ + 0xC5BC 0xC5BD 0xC5BE 0xC5C4 0xC5C5 0xC5C6 0xC5C7 0xC5C8 +12 0xC5C9 0xC5CA 0xC5CC 0xC5CE 0xC5D0 0xC5D1 0xC5D4 0xC5D8 \ + 0xC5E0 0xC5E1 0xC5E3 0xC5E5 0xC5EC 0xC5ED 0xC5EE 0xC5F0 \ + 0xC5F4 0xC5F6 0xC5F7 0xC5FC 0xC5FD 0xC5FE 0xC5FF 0xC600 \ + 0xC601 0xC605 0xC606 0xC607 0xC608 0xC60C 0xC610 0xC618 \ + 0xC619 0xC61B 0xC61C 0xC624 0xC625 0xC628 0xC62C 0xC62D \ + 0xC62E 0xC630 0xC633 0xC634 0xC635 0xC637 0xC639 0xC63B \ + 0xC640 0xC641 0xC644 0xC648 0xC650 0xC651 0xC653 0xC654 \ + 0xC655 0xC65C 0xC65D 0xC660 0xC66C 0xC66F 0xC671 0xC678 \ + 0xC679 0xC67C 0xC680 0xC688 0xC689 0xC68B 0xC68D 0xC694 \ + 0xC695 0xC698 0xC69C 0xC6A4 0xC6A5 0xC6A7 0xC6A9 0xC6B0 \ + 0xC6B1 0xC6B4 0xC6B8 0xC6B9 0xC6BA 0xC6C0 0xC6C1 0xC6C3 \ + 0xC6C5 0xC6CC 0xC6CD 0xC6D0 0xC6D4 0xC6DC 0xC6DD 0xC6E0 \ + 0xC6E1 0xC6E8 0xC6E9 0xC6EC 0xC6F0 0xC6F8 0xC6F9 0xC6FD \ + 0xC704 0xC705 0xC708 0xC70C 0xC714 0xC715 0xC717 0xC719 \ + 0xC720 0xC721 0xC724 0xC728 0xC730 0xC731 0xC733 0xC735 \ + 0xC737 0xC73C 0xC73D 0xC740 0xC744 0xC74A 0xC74C 0xC74D \ + 0xC74F 0xC751 0xC752 0xC753 0xC754 0xC755 0xC756 0xC757 \ + 0xC758 0xC75C 0xC760 0xC768 0xC76B 0xC774 0xC775 0xC778 \ + 0xC77C 0xC77D 0xC77E 0xC783 0xC784 0xC785 0xC787 0xC788 \ + 0xC789 0xC78A 0xC78E 0xC790 0xC791 0xC794 0xC796 0xC797 \ + 0xC798 0xC79A 0xC7A0 0xC7A1 0xC7A3 0xC7A4 0xC7A5 0xC7A6 \ + 0xC7AC 0xC7AD 0xC7B0 0xC7B4 0xC7BC 0xC7BD 0xC7BF 0xC7C0 \ + 0xC7C1 0xC7C8 0xC7C9 0xC7CC 0xC7CE 0xC7D0 0xC7D8 0xC7DD \ + 0xC7E4 0xC7E8 0xC7EC 0xC800 0xC801 0xC804 0xC808 0xC80A \ + 0xC810 0xC811 0xC813 0xC815 0xC816 0xC81C 0xC81D 0xC820 \ + 0xC824 0xC82C 0xC82D 0xC82F 0xC831 0xC838 0xC83C 0xC840 \ + 0xC848 0xC849 0xC84C 0xC84D 0xC854 0xC870 0xC871 0xC874 \ + 0xC878 0xC87A 0xC880 0xC881 0xC883 0xC885 0xC886 0xC887 \ + 0xC88B 0xC88C 0xC88D 0xC894 0xC89D 0xC89F 0xC8A1 0xC8A8 \ + 0xC8BC 0xC8BD 0xC8C4 0xC8C8 0xC8CC 0xC8D4 0xC8D5 0xC8D7 \ + 0xC8D9 0xC8E0 0xC8E1 0xC8E4 0xC8F5 0xC8FC 0xC8FD 0xC900 \ + 0xC904 0xC905 0xC906 0xC90C 0xC90D 0xC90F 0xC911 0xC918 +13 0xC92C 0xC934 0xC950 0xC951 0xC954 0xC958 0xC960 0xC961 \ + 0xC963 0xC96C 0xC970 0xC974 0xC97C 0xC988 0xC989 0xC98C \ + 0xC990 0xC998 0xC999 0xC99B 0xC99D 0xC9C0 0xC9C1 0xC9C4 \ + 0xC9C7 0xC9C8 0xC9CA 0xC9D0 0xC9D1 0xC9D3 0xC9D5 0xC9D6 \ + 0xC9D9 0xC9DA 0xC9DC 0xC9DD 0xC9E0 0xC9E2 0xC9E4 0xC9E7 \ + 0xC9EC 0xC9ED 0xC9EF 0xC9F0 0xC9F1 0xC9F8 0xC9F9 0xC9FC \ + 0xCA00 0xCA08 0xCA09 0xCA0B 0xCA0C 0xCA0D 0xCA14 0xCA18 \ + 0xCA29 0xCA4C 0xCA4D 0xCA50 0xCA54 0xCA5C 0xCA5D 0xCA5F \ + 0xCA60 0xCA61 0xCA68 0xCA7D 0xCA84 0xCA98 0xCABC 0xCABD \ + 0xCAC0 0xCAC4 0xCACC 0xCACD 0xCACF 0xCAD1 0xCAD3 0xCAD8 \ + 0xCAD9 0xCAE0 0xCAEC 0xCAF4 0xCB08 0xCB10 0xCB14 0xCB18 \ + 0xCB20 0xCB21 0xCB41 0xCB48 0xCB49 0xCB4C 0xCB50 0xCB58 \ + 0xCB59 0xCB5D 0xCB64 0xCB78 0xCB79 0xCB9C 0xCBB8 0xCBD4 \ + 0xCBE4 0xCBE7 0xCBE9 0xCC0C 0xCC0D 0xCC10 0xCC14 0xCC1C \ + 0xCC1D 0xCC21 0xCC22 0xCC27 0xCC28 0xCC29 0xCC2C 0xCC2E \ + 0xCC30 0xCC38 0xCC39 0xCC3B 0xCC3C 0xCC3D 0xCC3E 0xCC44 \ + 0xCC45 0xCC48 0xCC4C 0xCC54 0xCC55 0xCC57 0xCC58 0xCC59 \ + 0xCC60 0xCC64 0xCC66 0xCC68 0xCC70 0xCC75 0xCC98 0xCC99 \ + 0xCC9C 0xCCA0 0xCCA8 0xCCA9 0xCCAB 0xCCAC 0xCCAD 0xCCB4 \ + 0xCCB5 0xCCB8 0xCCBC 0xCCC4 0xCCC5 0xCCC7 0xCCC9 0xCCD0 \ + 0xCCD4 0xCCE4 0xCCEC 0xCCF0 0xCD01 0xCD08 0xCD09 0xCD0C \ + 0xCD10 0xCD18 0xCD19 0xCD1B 0xCD1D 0xCD24 0xCD28 0xCD2C \ + 0xCD39 0xCD5C 0xCD60 0xCD64 0xCD6C 0xCD6D 0xCD6F 0xCD71 \ + 0xCD78 0xCD88 0xCD94 0xCD95 0xCD98 0xCD9C 0xCDA4 0xCDA5 \ + 0xCDA7 0xCDA9 0xCDB0 0xCDC4 0xCDCC 0xCDD0 0xCDE8 0xCDEC \ + 0xCDF0 0xCDF8 0xCDF9 0xCDFB 0xCDFD 0xCE04 0xCE08 0xCE0C \ + 0xCE14 0xCE19 0xCE20 0xCE21 0xCE24 0xCE28 0xCE30 0xCE31 \ + 0xCE33 0xCE35 0xCE58 0xCE59 0xCE5C 0xCE5F 0xCE60 0xCE61 \ + 0xCE68 0xCE69 0xCE6B 0xCE6D 0xCE74 0xCE75 0xCE78 0xCE7C \ + 0xCE84 0xCE85 0xCE87 0xCE89 0xCE90 0xCE91 0xCE94 0xCE98 \ + 0xCEA0 0xCEA1 0xCEA3 0xCEA4 0xCEA5 0xCEAC 0xCEAD 0xCEC1 \ + 0xCEE4 0xCEE5 0xCEE8 0xCEEB 0xCEEC 0xCEF4 0xCEF5 0xCEF7 +14 0xCEF8 0xCEF9 0xCF00 0xCF01 0xCF04 0xCF08 0xCF10 0xCF11 \ + 0xCF13 0xCF15 0xCF1C 0xCF20 0xCF24 0xCF2C 0xCF2D 0xCF2F \ + 0xCF30 0xCF31 0xCF38 0xCF54 0xCF55 0xCF58 0xCF5C 0xCF64 \ + 0xCF65 0xCF67 0xCF69 0xCF70 0xCF71 0xCF74 0xCF78 0xCF80 \ + 0xCF85 0xCF8C 0xCFA1 0xCFA8 0xCFB0 0xCFC4 0xCFE0 0xCFE1 \ + 0xCFE4 0xCFE8 0xCFF0 0xCFF1 0xCFF3 0xCFF5 0xCFFC 0xD000 \ + 0xD004 0xD011 0xD018 0xD02D 0xD034 0xD035 0xD038 0xD03C \ + 0xD044 0xD045 0xD047 0xD049 0xD050 0xD054 0xD058 0xD060 \ + 0xD06C 0xD06D 0xD070 0xD074 0xD07C 0xD07D 0xD081 0xD0A4 \ + 0xD0A5 0xD0A8 0xD0AC 0xD0B4 0xD0B5 0xD0B7 0xD0B9 0xD0C0 \ + 0xD0C1 0xD0C4 0xD0C8 0xD0C9 0xD0D0 0xD0D1 0xD0D3 0xD0D4 \ + 0xD0D5 0xD0DC 0xD0DD 0xD0E0 0xD0E4 0xD0EC 0xD0ED 0xD0EF \ + 0xD0F0 0xD0F1 0xD0F8 0xD10D 0xD130 0xD131 0xD134 0xD138 \ + 0xD13A 0xD140 0xD141 0xD143 0xD144 0xD145 0xD14C 0xD14D \ + 0xD150 0xD154 0xD15C 0xD15D 0xD15F 0xD161 0xD168 0xD16C \ + 0xD17C 0xD184 0xD188 0xD1A0 0xD1A1 0xD1A4 0xD1A8 0xD1B0 \ + 0xD1B1 0xD1B3 0xD1B5 0xD1BA 0xD1BC 0xD1C0 0xD1D8 0xD1F4 \ + 0xD1F8 0xD207 0xD209 0xD210 0xD22C 0xD22D 0xD230 0xD234 \ + 0xD23C 0xD23D 0xD23F 0xD241 0xD248 0xD25C 0xD264 0xD280 \ + 0xD281 0xD284 0xD288 0xD290 0xD291 0xD295 0xD29C 0xD2A0 \ + 0xD2A4 0xD2AC 0xD2B1 0xD2B8 0xD2B9 0xD2BC 0xD2BF 0xD2C0 \ + 0xD2C2 0xD2C8 0xD2C9 0xD2CB 0xD2D4 0xD2D8 0xD2DC 0xD2E4 \ + 0xD2E5 0xD2F0 0xD2F1 0xD2F4 0xD2F8 0xD300 0xD301 0xD303 \ + 0xD305 0xD30C 0xD30D 0xD30E 0xD310 0xD314 0xD316 0xD31C \ + 0xD31D 0xD31F 0xD320 0xD321 0xD325 0xD328 0xD329 0xD32C \ + 0xD330 0xD338 0xD339 0xD33B 0xD33C 0xD33D 0xD344 0xD345 \ + 0xD37C 0xD37D 0xD380 0xD384 0xD38C 0xD38D 0xD38F 0xD390 \ + 0xD391 0xD398 0xD399 0xD39C 0xD3A0 0xD3A8 0xD3A9 0xD3AB \ + 0xD3AD 0xD3B4 0xD3B8 0xD3BC 0xD3C4 0xD3C5 0xD3C8 0xD3C9 \ + 0xD3D0 0xD3D8 0xD3E1 0xD3E3 0xD3EC 0xD3ED 0xD3F0 0xD3F4 \ + 0xD3FC 0xD3FD 0xD3FF 0xD401 0xD408 0xD41D 0xD440 0xD444 \ + 0xD45C 0xD460 0xD464 0xD46D 0xD46F 0xD478 0xD479 0xD47C +15 0xD47F 0xD480 0xD482 0xD488 0xD489 0xD48B 0xD48D 0xD494 \ + 0xD4A9 0xD4CC 0xD4D0 0xD4D4 0xD4DC 0xD4DF 0xD4E8 0xD4EC \ + 0xD4F0 0xD4F8 0xD4FB 0xD4FD 0xD504 0xD508 0xD50C 0xD514 \ + 0xD515 0xD517 0xD53C 0xD53D 0xD540 0xD544 0xD54C 0xD54D \ + 0xD54F 0xD551 0xD558 0xD559 0xD55C 0xD560 0xD565 0xD568 \ + 0xD569 0xD56B 0xD56D 0xD574 0xD575 0xD578 0xD57C 0xD584 \ + 0xD585 0xD587 0xD588 0xD589 0xD590 0xD5A5 0xD5C8 0xD5C9 \ + 0xD5CC 0xD5D0 0xD5D2 0xD5D8 0xD5D9 0xD5DB 0xD5DD 0xD5E4 \ + 0xD5E5 0xD5E8 0xD5EC 0xD5F4 0xD5F5 0xD5F7 0xD5F9 0xD600 \ + 0xD601 0xD604 0xD608 0xD610 0xD611 0xD613 0xD614 0xD615 \ + 0xD61C 0xD620 0xD624 0xD62D 0xD638 0xD639 0xD63C 0xD640 \ + 0xD645 0xD648 0xD649 0xD64B 0xD64D 0xD651 0xD654 0xD655 \ + 0xD658 0xD65C 0xD667 0xD669 0xD670 0xD671 0xD674 0xD683 \ + 0xD685 0xD68C 0xD68D 0xD690 0xD694 0xD69D 0xD69F 0xD6A1 \ + 0xD6A8 0xD6AC 0xD6B0 0xD6B9 0xD6BB 0xD6C4 0xD6C5 0xD6C8 \ + 0xD6CC 0xD6D1 0xD6D4 0xD6D7 0xD6D9 0xD6E0 0xD6E4 0xD6E8 \ + 0xD6F0 0xD6F5 0xD6FC 0xD6FD 0xD700 0xD704 0xD711 0xD718 \ + 0xD719 0xD71C 0xD720 0xD728 0xD729 0xD72B 0xD72D 0xD734 \ + 0xD735 0xD738 0xD73C 0xD744 0xD747 0xD749 0xD750 0xD751 \ + 0xD754 0xD756 0xD757 0xD758 0xD759 0xD760 0xD761 0xD763 \ + 0xD765 0xD769 0xD76C 0xD770 0xD774 0xD77C 0xD77D 0xD781 \ + 0xD788 0xD789 0xD78C 0xD790 0xD798 0xD799 0xD79B 0xD79D \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +16 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x4F3D 0x4F73 \ + 0x5047 0x50F9 0x52A0 0x53EF 0x5475 0x54E5 0x5609 0x5AC1 \ + 0x5BB6 0x6687 0x67B6 0x67B7 0x67EF 0x6B4C 0x73C2 0x75C2 \ + 0x7A3C 0x82DB 0x8304 0x8857 0x8888 0x8A36 0x8CC8 0x8DCF \ + 0x8EFB 0x8FE6 0x99D5 0x523B 0x5374 0x5404 0x606A 0x6164 \ + 0x6BBC 0x73CF 0x811A 0x89BA 0x89D2 0x95A3 0x4F83 0x520A \ + 0x58BE 0x5978 0x59E6 0x5E72 0x5E79 0x61C7 0x63C0 0x6746 \ + 0x67EC 0x687F 0x6F97 0x764E 0x770B 0x78F5 0x7A08 0x7AFF \ + 0x7C21 0x809D 0x826E 0x8271 0x8AEB 0x9593 0x4E6B 0x559D \ + 0x66F7 0x6E34 0x78A3 0x7AED 0x845B 0x8910 0x874E 0x97A8 \ + 0x52D8 0x574E 0x582A 0x5D4C 0x611F 0x61BE 0x6221 0x6562 \ + 0x67D1 0x6A44 0x6E1B 0x7518 0x75B3 0x76E3 0x77B0 0x7D3A \ + 0x90AF 0x9451 0x9452 0x9F95 0x5323 0x5CAC 0x7532 0x80DB \ + 0x9240 0x9598 0x525B 0x5808 0x59DC 0x5CA1 0x5D17 0x5EB7 \ + 0x5F3A 0x5F4A 0x6177 0x6C5F 0x757A 0x7586 0x7CE0 0x7D73 \ + 0x7DB1 0x7F8C 0x8154 0x8221 0x8591 0x8941 0x8B1B 0x92FC \ + 0x964D 0x9C47 0x4ECB 0x4EF7 0x500B 0x51F1 0x584F 0x6137 \ + 0x613E 0x6168 0x6539 0x69EA 0x6F11 0x75A5 0x7686 0x76D6 \ + 0x7B87 0x82A5 0x84CB 0xF900 0x93A7 0x958B 0x5580 0x5BA2 \ + 0x5751 0xF901 0x7CB3 0x7FB9 0x91B5 0x5028 0x53BB 0x5C45 \ + 0x5DE8 0x62D2 0x636E 0x64DA 0x64E7 0x6E20 0x70AC 0x795B \ + 0x8DDD 0x8E1E 0xF902 0x907D 0x9245 0x92F8 0x4E7E 0x4EF6 \ + 0x5065 0x5DFE 0x5EFA 0x6106 0x6957 0x8171 0x8654 0x8E47 \ + 0x9375 0x9A2B 0x4E5E 0x5091 0x6770 0x6840 0x5109 0x528D \ + 0x5292 0x6AA2 0x77BC 0x9210 0x9ED4 0x52AB 0x602F 0x8FF2 \ + 0x5048 0x61A9 0x63ED 0x64CA 0x683C 0x6A84 0x6FC0 0x8188 \ + 0x89A1 0x9694 0x5805 0x727D 0x72AC 0x7504 0x7D79 0x7E6D \ + 0x80A9 0x898B 0x8B74 0x9063 0x9D51 0x6289 0x6C7A 0x6F54 \ + 0x7D50 0x7F3A 0x8A23 0x517C 0x614A 0x7B9D 0x8B19 0x9257 \ + 0x938C 0x4EAC 0x4FD3 0x501E 0x50BE 0x5106 0x52C1 0x52CD \ + 0x537F 0x5770 0x5883 0x5E9A 0x5F91 0x6176 0x61AC 0x64CE +17 0x656C 0x666F 0x66BB 0x66F4 0x6897 0x6D87 0x7085 0x70F1 \ + 0x749F 0x74A5 0x74CA 0x75D9 0x786C 0x78EC 0x7ADF 0x7AF6 \ + 0x7D45 0x7D93 0x8015 0x803F 0x811B 0x8396 0x8B66 0x8F15 \ + 0x9015 0x93E1 0x9803 0x9838 0x9A5A 0x9BE8 0x4FC2 0x5553 \ + 0x583A 0x5951 0x5B63 0x5C46 0x60B8 0x6212 0x6842 0x68B0 \ + 0x68E8 0x6EAA 0x754C 0x7678 0x78CE 0x7A3D 0x7CFB 0x7E6B \ + 0x7E7C 0x8A08 0x8AA1 0x8C3F 0x968E 0x9DC4 0x53E4 0x53E9 \ + 0x544A 0x5471 0x56FA 0x59D1 0x5B64 0x5C3B 0x5EAB 0x62F7 \ + 0x6537 0x6545 0x6572 0x66A0 0x67AF 0x69C1 0x6CBD 0x75FC \ + 0x7690 0x777E 0x7A3F 0x7F94 0x8003 0x80A1 0x818F 0x82E6 \ + 0x82FD 0x83F0 0x85C1 0x8831 0x88B4 0x8AA5 0xF903 0x8F9C \ + 0x932E 0x96C7 0x9867 0x9AD8 0x9F13 0x54ED 0x659B 0x66F2 \ + 0x688F 0x7A40 0x8C37 0x9D60 0x56F0 0x5764 0x5D11 0x6606 \ + 0x68B1 0x68CD 0x6EFE 0x7428 0x889E 0x9BE4 0x6C68 0xF904 \ + 0x9AA8 0x4F9B 0x516C 0x5171 0x529F 0x5B54 0x5DE5 0x6050 \ + 0x606D 0x62F1 0x63A7 0x653B 0x73D9 0x7A7A 0x86A3 0x8CA2 \ + 0x978F 0x4E32 0x5BE1 0x6208 0x679C 0x74DC 0x79D1 0x83D3 \ + 0x8A87 0x8AB2 0x8DE8 0x904E 0x934B 0x9846 0x5ED3 0x69E8 \ + 0x85FF 0x90ED 0xF905 0x51A0 0x5B98 0x5BEC 0x6163 0x68FA \ + 0x6B3E 0x704C 0x742F 0x74D8 0x7BA1 0x7F50 0x83C5 0x89C0 \ + 0x8CAB 0x95DC 0x9928 0x522E 0x605D 0x62EC 0x9002 0x4F8A \ + 0x5149 0x5321 0x58D9 0x5EE3 0x66E0 0x6D38 0x709A 0x72C2 \ + 0x73D6 0x7B50 0x80F1 0x945B 0x5366 0x639B 0x7F6B 0x4E56 \ + 0x5080 0x584A 0x58DE 0x602A 0x6127 0x62D0 0x69D0 0x9B41 \ + 0x5B8F 0x7D18 0x80B1 0x8F5F 0x4EA4 0x50D1 0x54AC 0x55AC \ + 0x5B0C 0x5DA0 0x5DE7 0x652A 0x654E 0x6821 0x6A4B 0x72E1 \ + 0x768E 0x77EF 0x7D5E 0x7FF9 0x81A0 0x854E 0x86DF 0x8F03 \ + 0x8F4E 0x90CA 0x9903 0x9A55 0x9BAB 0x4E18 0x4E45 0x4E5D \ + 0x4EC7 0x4FF1 0x5177 0x52FE 0x5340 0x53E3 0x53E5 0x548E \ + 0x5614 0x5775 0x57A2 0x5BC7 0x5D87 0x5ED0 0x61FC 0x62D8 \ + 0x6551 0x67B8 0x67E9 0x69CB 0x6B50 0x6BC6 0x6BEC 0x6C42 \ + 0x6E9D 0x7078 0x72D7 0x7396 0x7403 0x77BF 0x77E9 0x7A76 +18 0x7D7F 0x8009 0x81FC 0x8205 0x820A 0x82DF 0x8862 0x8B33 \ + 0x8CFC 0x8EC0 0x9011 0x90B1 0x9264 0x92B6 0x99D2 0x9A45 \ + 0x9CE9 0x9DD7 0x9F9C 0x570B 0x5C40 0x83CA 0x97A0 0x97AB \ + 0x9EB4 0x541B 0x7A98 0x7FA4 0x88D9 0x8ECD 0x90E1 0x5800 \ + 0x5C48 0x6398 0x7A9F 0x5BAE 0x5F13 0x7A79 0x7AAE 0x828E \ + 0x8EAC 0x5026 0x5238 0x52F8 0x5377 0x5708 0x62F3 0x6372 \ + 0x6B0A 0x6DC3 0x7737 0x53A5 0x7357 0x8568 0x8E76 0x95D5 \ + 0x673A 0x6AC3 0x6F70 0x8A6D 0x8ECC 0x994B 0xF906 0x6677 \ + 0x6B78 0x8CB4 0x9B3C 0xF907 0x53EB 0x572D 0x594E 0x63C6 \ + 0x69FB 0x73EA 0x7845 0x7ABA 0x7AC5 0x7CFE 0x8475 0x898F \ + 0x8D73 0x9035 0x95A8 0x52FB 0x5747 0x7547 0x7B60 0x83CC \ + 0x921E 0xF908 0x6A58 0x514B 0x524B 0x5287 0x621F 0x68D8 \ + 0x6975 0x9699 0x50C5 0x52A4 0x52E4 0x61C3 0x65A4 0x6839 \ + 0x69FF 0x747E 0x7B4B 0x82B9 0x83EB 0x89B2 0x8B39 0x8FD1 \ + 0x9949 0xF909 0x4ECA 0x5997 0x64D2 0x6611 0x6A8E 0x7434 \ + 0x7981 0x79BD 0x82A9 0x887E 0x887F 0x895F 0xF90A 0x9326 \ + 0x4F0B 0x53CA 0x6025 0x6271 0x6C72 0x7D1A 0x7D66 0x4E98 \ + 0x5162 0x77DC 0x80AF 0x4F01 0x4F0E 0x5176 0x5180 0x55DC \ + 0x5668 0x573B 0x57FA 0x57FC 0x5914 0x5947 0x5993 0x5BC4 \ + 0x5C90 0x5D0E 0x5DF1 0x5E7E 0x5FCC 0x6280 0x65D7 0x65E3 \ + 0x671E 0x671F 0x675E 0x68CB 0x68C4 0x6A5F 0x6B3A 0x6C23 \ + 0x6C7D 0x6C82 0x6DC7 0x7398 0x7426 0x742A 0x7482 0x74A3 \ + 0x7578 0x757F 0x7881 0x78EF 0x7941 0x7947 0x7948 0x797A \ + 0x7B95 0x7D00 0x7DBA 0x7F88 0x8006 0x802D 0x808C 0x8A18 \ + 0x8B4F 0x8C48 0x8D77 0x9321 0x9324 0x98E2 0x9951 0x9A0E \ + 0x9A0F 0x9A65 0x9E92 0x7DCA 0x4F76 0x5409 0x62EE 0x6854 \ + 0x91D1 0x55AB 0x513A 0xF90B 0xF90C 0x5A1C 0x61E6 0xF90D \ + 0x62CF 0x62FF 0xF90E 0xF90F 0xF910 0xF911 0xF912 0xF913 \ + 0x90A3 0xF914 0xF915 0xF916 0xF917 0xF918 0x8AFE 0xF919 \ + 0xF91A 0xF91B 0xF91C 0x6696 0xF91D 0x7156 0xF91E 0xF91F \ + 0x96E3 0xF920 0x634F 0x637A 0x5357 0xF921 0x678F 0x6960 \ + 0x6E73 0xF922 0x7537 0xF923 0xF924 0xF925 0x7D0D 0xF926 +19 0xF927 0x8872 0x56CA 0x5A18 0xF928 0xF929 0xF92A 0xF92B \ + 0xF92C 0x4E43 0xF92D 0x5167 0x5948 0x67F0 0x8010 0xF92E \ + 0x5973 0x5E74 0x649A 0x79CA 0x5FF5 0x606C 0x62C8 0x637B \ + 0x5BE7 0x5BD7 0x52AA 0xF92F 0x5974 0x5F29 0x6012 0xF930 \ + 0xF931 0xF932 0x7459 0xF933 0xF934 0xF935 0xF936 0xF937 \ + 0xF938 0x99D1 0xF939 0xF93A 0xF93B 0xF93C 0xF93D 0xF93E \ + 0xF93F 0xF940 0xF941 0xF942 0xF943 0x6FC3 0xF944 0xF945 \ + 0x81BF 0x8FB2 0x60F1 0xF946 0xF947 0x8166 0xF948 0xF949 \ + 0x5C3F 0xF94A 0xF94B 0xF94C 0xF94D 0xF94E 0xF94F 0xF950 \ + 0xF951 0x5AE9 0x8A25 0x677B 0x7D10 0xF952 0xF953 0xF954 \ + 0xF955 0xF956 0xF957 0x80FD 0xF958 0xF959 0x5C3C 0x6CE5 \ + 0x533F 0x6EBA 0x591A 0x8336 0x4E39 0x4EB6 0x4F46 0x55AE \ + 0x5718 0x58C7 0x5F56 0x65B7 0x65E6 0x6A80 0x6BB5 0x6E4D \ + 0x77ED 0x7AEF 0x7C1E 0x7DDE 0x86CB 0x8892 0x9132 0x935B \ + 0x64BB 0x6FBE 0x737A 0x75B8 0x9054 0x5556 0x574D 0x61BA \ + 0x64D4 0x66C7 0x6DE1 0x6E5B 0x6F6D 0x6FB9 0x75F0 0x8043 \ + 0x81BD 0x8541 0x8983 0x8AC7 0x8B5A 0x931F 0x6C93 0x7553 \ + 0x7B54 0x8E0F 0x905D 0x5510 0x5802 0x5858 0x5E62 0x6207 \ + 0x649E 0x68E0 0x7576 0x7CD6 0x87B3 0x9EE8 0x4EE3 0x5788 \ + 0x576E 0x5927 0x5C0D 0x5CB1 0x5E36 0x5F85 0x6234 0x64E1 \ + 0x73B3 0x81FA 0x888B 0x8CB8 0x968A 0x9EDB 0x5B85 0x5FB7 \ + 0x60B3 0x5012 0x5200 0x5230 0x5716 0x5835 0x5857 0x5C0E \ + 0x5C60 0x5CF6 0x5D8B 0x5EA6 0x5F92 0x60BC 0x6311 0x6389 \ + 0x6417 0x6843 0x68F9 0x6AC2 0x6DD8 0x6E21 0x6ED4 0x6FE4 \ + 0x71FE 0x76DC 0x7779 0x79B1 0x7A3B 0x8404 0x89A9 0x8CED \ + 0x8DF3 0x8E48 0x9003 0x9014 0x9053 0x90FD 0x934D 0x9676 \ + 0x97DC 0x6BD2 0x7006 0x7258 0x72A2 0x7368 0x7763 0x79BF \ + 0x7BE4 0x7E9B 0x8B80 0x58A9 0x60C7 0x6566 0x65FD 0x66BE \ + 0x6C8C 0x711E 0x71C9 0x8C5A 0x9813 0x4E6D 0x7A81 0x4EDD \ + 0x51AC 0x51CD 0x52D5 0x540C 0x61A7 0x6771 0x6850 0x68DF \ + 0x6D1E 0x6F7C 0x75BC 0x77B3 0x7AE5 0x80F4 0x8463 0x9285 \ + 0x515C 0x6597 0x675C 0x6793 0x75D8 0x7AC7 0x8373 0xF95A +20 0x8C46 0x9017 0x982D 0x5C6F 0x81C0 0x829A 0x9041 0x906F \ + 0x920D 0x5F97 0x5D9D 0x6A59 0x71C8 0x767B 0x7B49 0x85E4 \ + 0x8B04 0x9127 0x9A30 0x5587 0x61F6 0xF95B 0x7669 0x7F85 \ + 0x863F 0x87BA 0x88F8 0x908F 0xF95C 0x6D1B 0x70D9 0x73DE \ + 0x7D61 0x843D 0xF95D 0x916A 0x99F1 0xF95E 0x4E82 0x5375 \ + 0x6B04 0x6B12 0x703E 0x721B 0x862D 0x9E1E 0x524C 0x8FA3 \ + 0x5D50 0x64E5 0x652C 0x6B16 0x6FEB 0x7C43 0x7E9C 0x85CD \ + 0x8964 0x89BD 0x62C9 0x81D8 0x881F 0x5ECA 0x6717 0x6D6A \ + 0x72FC 0x7405 0x746F 0x8782 0x90DE 0x4F86 0x5D0D 0x5FA0 \ + 0x840A 0x51B7 0x63A0 0x7565 0x4EAE 0x5006 0x5169 0x51C9 \ + 0x6881 0x6A11 0x7CAE 0x7CB1 0x7CE7 0x826F 0x8AD2 0x8F1B \ + 0x91CF 0x4FB6 0x5137 0x52F5 0x5442 0x5EEC 0x616E 0x623E \ + 0x65C5 0x6ADA 0x6FFE 0x792A 0x85DC 0x8823 0x95AD 0x9A62 \ + 0x9A6A 0x9E97 0x9ECE 0x529B 0x66C6 0x6B77 0x701D 0x792B \ + 0x8F62 0x9742 0x6190 0x6200 0x6523 0x6F23 0x7149 0x7489 \ + 0x7DF4 0x806F 0x84EE 0x8F26 0x9023 0x934A 0x51BD 0x5217 \ + 0x52A3 0x6D0C 0x70C8 0x88C2 0x5EC9 0x6582 0x6BAE 0x6FC2 \ + 0x7C3E 0x7375 0x4EE4 0x4F36 0x56F9 0xF95F 0x5CBA 0x5DBA \ + 0x601C 0x73B2 0x7B2D 0x7F9A 0x7FCE 0x8046 0x901E 0x9234 \ + 0x96F6 0x9748 0x9818 0x9F61 0x4F8B 0x6FA7 0x79AE 0x91B4 \ + 0x96B7 0x52DE 0xF960 0x6488 0x64C4 0x6AD3 0x6F5E 0x7018 \ + 0x7210 0x76E7 0x8001 0x8606 0x865C 0x8DEF 0x8F05 0x9732 \ + 0x9B6F 0x9DFA 0x9E75 0x788C 0x797F 0x7DA0 0x83C9 0x9304 \ + 0x9E7F 0x9E93 0x8AD6 0x58DF 0x5F04 0x6727 0x7027 0x74CF \ + 0x7C60 0x807E 0x5121 0x7028 0x7262 0x78CA 0x8CC2 0x8CDA \ + 0x8CF4 0x96F7 0x4E86 0x50DA 0x5BEE 0x5ED6 0x6599 0x71CE \ + 0x7642 0x77AD 0x804A 0x84FC 0x907C 0x9B27 0x9F8D 0x58D8 \ + 0x5A41 0x5C62 0x6A13 0x6DDA 0x6F0F 0x763B 0x7D2F 0x7E37 \ + 0x851E 0x8938 0x93E4 0x964B 0x5289 0x65D2 0x67F3 0x69B4 \ + 0x6D41 0x6E9C 0x700F 0x7409 0x7460 0x7559 0x7624 0x786B \ + 0x8B2C 0x985E 0x516D 0x622E 0x9678 0x4F96 0x502B 0x5D19 \ + 0x6DEA 0x7DB8 0x8F2A 0x5F8B 0x6144 0x6817 0xF961 0x9686 +21 0x52D2 0x808B 0x51DC 0x51CC 0x695E 0x7A1C 0x7DBE 0x83F1 \ + 0x9675 0x4FDA 0x5229 0x5398 0x540F 0x550E 0x5C65 0x60A7 \ + 0x674E 0x68A8 0x6D6C 0x7281 0x72F8 0x7406 0x7483 0xF962 \ + 0x75E2 0x7C6C 0x7F79 0x7FB8 0x8389 0x88CF 0x88E1 0x91CC \ + 0x91D0 0x96E2 0x9BC9 0x541D 0x6F7E 0x71D0 0x7498 0x85FA \ + 0x8EAA 0x96A3 0x9C57 0x9E9F 0x6797 0x6DCB 0x7433 0x81E8 \ + 0x9716 0x782C 0x7ACB 0x7B20 0x7C92 0x6469 0x746A 0x75F2 \ + 0x78BC 0x78E8 0x99AC 0x9B54 0x9EBB 0x5BDE 0x5E55 0x6F20 \ + 0x819C 0x83AB 0x9088 0x4E07 0x534D 0x5A29 0x5DD2 0x5F4E \ + 0x6162 0x633D 0x6669 0x66FC 0x6EFF 0x6F2B 0x7063 0x779E \ + 0x842C 0x8513 0x883B 0x8F13 0x9945 0x9C3B 0x551C 0x62B9 \ + 0x672B 0x6CAB 0x8309 0x896A 0x977A 0x4EA1 0x5984 0x5FD8 \ + 0x5FD9 0x671B 0x7DB2 0x7F54 0x8292 0x832B 0x83BD 0x8F1E \ + 0x9099 0x57CB 0x59B9 0x5A92 0x5BD0 0x6627 0x679A 0x6885 \ + 0x6BCF 0x7164 0x7F75 0x8CB7 0x8CE3 0x9081 0x9B45 0x8108 \ + 0x8C8A 0x964C 0x9A40 0x9EA5 0x5B5F 0x6C13 0x731B 0x76F2 \ + 0x76DF 0x840C 0x51AA 0x8993 0x514D 0x5195 0x52C9 0x68C9 \ + 0x6C94 0x7704 0x7720 0x7DBF 0x7DEC 0x9762 0x9EB5 0x6EC5 \ + 0x8511 0x51A5 0x540D 0x547D 0x660E 0x669D 0x6927 0x6E9F \ + 0x76BF 0x7791 0x8317 0x84C2 0x879F 0x9169 0x9298 0x9CF4 \ + 0x8882 0x4FAE 0x5192 0x52DF 0x59C6 0x5E3D 0x6155 0x6478 \ + 0x6479 0x66AE 0x67D0 0x6A21 0x6BCD 0x6BDB 0x725F 0x7261 \ + 0x7441 0x7738 0x77DB 0x8017 0x82BC 0x8305 0x8B00 0x8B28 \ + 0x8C8C 0x6728 0x6C90 0x7267 0x76EE 0x7766 0x7A46 0x9DA9 \ + 0x6B7F 0x6C92 0x5922 0x6726 0x8499 0x536F 0x5893 0x5999 \ + 0x5EDF 0x63CF 0x6634 0x6773 0x6E3A 0x732B 0x7AD7 0x82D7 \ + 0x9328 0x52D9 0x5DEB 0x61AE 0x61CB 0x620A 0x62C7 0x64AB \ + 0x65E0 0x6959 0x6B66 0x6BCB 0x7121 0x73F7 0x755D 0x7E46 \ + 0x821E 0x8302 0x856A 0x8AA3 0x8CBF 0x9727 0x9D61 0x58A8 \ + 0x9ED8 0x5011 0x520E 0x543B 0x554F 0x6587 0x6C76 0x7D0A \ + 0x7D0B 0x805E 0x868A 0x9580 0x96EF 0x52FF 0x6C95 0x7269 \ + 0x5473 0x5A9A 0x5C3E 0x5D4B 0x5F4C 0x5FAE 0x672A 0x68B6 +22 0x6963 0x6E3C 0x6E44 0x7709 0x7C73 0x7F8E 0x8587 0x8B0E \ + 0x8FF7 0x9761 0x9EF4 0x5CB7 0x60B6 0x610D 0x61AB 0x654F \ + 0x65FB 0x65FC 0x6C11 0x6CEF 0x739F 0x73C9 0x7DE1 0x9594 \ + 0x5BC6 0x871C 0x8B10 0x525D 0x535A 0x62CD 0x640F 0x64B2 \ + 0x6734 0x6A38 0x6CCA 0x73C0 0x749E 0x7B94 0x7C95 0x7E1B \ + 0x818A 0x8236 0x8584 0x8FEB 0x96F9 0x99C1 0x4F34 0x534A \ + 0x53CD 0x53DB 0x62CC 0x642C 0x6500 0x6591 0x69C3 0x6CEE \ + 0x6F58 0x73ED 0x7554 0x7622 0x76E4 0x76FC 0x78D0 0x78FB \ + 0x792C 0x7D46 0x822C 0x87E0 0x8FD4 0x9812 0x98EF 0x52C3 \ + 0x62D4 0x64A5 0x6E24 0x6F51 0x767C 0x8DCB 0x91B1 0x9262 \ + 0x9AEE 0x9B43 0x5023 0x508D 0x574A 0x59A8 0x5C28 0x5E47 \ + 0x5F77 0x623F 0x653E 0x65B9 0x65C1 0x6609 0x678B 0x699C \ + 0x6EC2 0x78C5 0x7D21 0x80AA 0x8180 0x822B 0x82B3 0x84A1 \ + 0x868C 0x8A2A 0x8B17 0x90A6 0x9632 0x9F90 0x500D 0x4FF3 \ + 0xF963 0x57F9 0x5F98 0x62DC 0x6392 0x676F 0x6E43 0x7119 \ + 0x76C3 0x80CC 0x80DA 0x88F4 0x88F5 0x8919 0x8CE0 0x8F29 \ + 0x914D 0x966A 0x4F2F 0x4F70 0x5E1B 0x67CF 0x6822 0x767D \ + 0x767E 0x9B44 0x5E61 0x6A0A 0x7169 0x71D4 0x756A 0xF964 \ + 0x7E41 0x8543 0x85E9 0x98DC 0x4F10 0x7B4F 0x7F70 0x95A5 \ + 0x51E1 0x5E06 0x68B5 0x6C3E 0x6C4E 0x6CDB 0x72AF 0x7BC4 \ + 0x8303 0x6CD5 0x743A 0x50FB 0x5288 0x58C1 0x64D8 0x6A97 \ + 0x74A7 0x7656 0x78A7 0x8617 0x95E2 0x9739 0xF965 0x535E \ + 0x5F01 0x8B8A 0x8FA8 0x8FAF 0x908A 0x5225 0x77A5 0x9C49 \ + 0x9F08 0x4E19 0x5002 0x5175 0x5C5B 0x5E77 0x661E 0x663A \ + 0x67C4 0x68C5 0x70B3 0x7501 0x75C5 0x79C9 0x7ADD 0x8F27 \ + 0x9920 0x9A08 0x4FDD 0x5821 0x5831 0x5BF6 0x666E 0x6B65 \ + 0x6D11 0x6E7A 0x6F7D 0x73E4 0x752B 0x83E9 0x88DC 0x8913 \ + 0x8B5C 0x8F14 0x4F0F 0x50D5 0x5310 0x535C 0x5B93 0x5FA9 \ + 0x670D 0x798F 0x8179 0x832F 0x8514 0x8907 0x8986 0x8F39 \ + 0x8F3B 0x99A5 0x9C12 0x672C 0x4E76 0x4FF8 0x5949 0x5C01 \ + 0x5CEF 0x5CF0 0x6367 0x68D2 0x70FD 0x71A2 0x742B 0x7E2B \ + 0x84EC 0x8702 0x9022 0x92D2 0x9CF3 0x4E0D 0x4ED8 0x4FEF +23 0x5085 0x5256 0x526F 0x5426 0x5490 0x57E0 0x592B 0x5A66 \ + 0x5B5A 0x5B75 0x5BCC 0x5E9C 0xF966 0x6276 0x6577 0x65A7 \ + 0x6D6E 0x6EA5 0x7236 0x7B26 0x7C3F 0x7F36 0x8150 0x8151 \ + 0x819A 0x8240 0x8299 0x83A9 0x8A03 0x8CA0 0x8CE6 0x8CFB \ + 0x8D74 0x8DBA 0x90E8 0x91DC 0x961C 0x9644 0x99D9 0x9CE7 \ + 0x5317 0x5206 0x5429 0x5674 0x58B3 0x5954 0x596E 0x5FFF \ + 0x61A4 0x626E 0x6610 0x6C7E 0x711A 0x76C6 0x7C89 0x7CDE \ + 0x7D1B 0x82AC 0x8CC1 0x96F0 0xF967 0x4F5B 0x5F17 0x5F7F \ + 0x62C2 0x5D29 0x670B 0x68DA 0x787C 0x7E43 0x9D6C 0x4E15 \ + 0x5099 0x5315 0x532A 0x5351 0x5983 0x5A62 0x5E87 0x60B2 \ + 0x618A 0x6249 0x6279 0x6590 0x6787 0x69A7 0x6BD4 0x6BD6 \ + 0x6BD7 0x6BD8 0x6CB8 0xF968 0x7435 0x75FA 0x7812 0x7891 \ + 0x79D5 0x79D8 0x7C83 0x7DCB 0x7FE1 0x80A5 0x813E 0x81C2 \ + 0x83F2 0x871A 0x88E8 0x8AB9 0x8B6C 0x8CBB 0x9119 0x975E \ + 0x98DB 0x9F3B 0x56AC 0x5B2A 0x5F6C 0x658C 0x6AB3 0x6BAF \ + 0x6D5C 0x6FF1 0x7015 0x725D 0x73AD 0x8CA7 0x8CD3 0x983B \ + 0x6191 0x6C37 0x8058 0x9A01 0x4E4D 0x4E8B 0x4E9B 0x4ED5 \ + 0x4F3A 0x4F3C 0x4F7F 0x4FDF 0x50FF 0x53F2 0x53F8 0x5506 \ + 0x55E3 0x56DB 0x58EB 0x5962 0x5A11 0x5BEB 0x5BFA 0x5C04 \ + 0x5DF3 0x5E2B 0x5F99 0x601D 0x6368 0x659C 0x65AF 0x67F6 \ + 0x67FB 0x68AD 0x6B7B 0x6C99 0x6CD7 0x6E23 0x7009 0x7345 \ + 0x7802 0x793E 0x7940 0x7960 0x79C1 0x7BE9 0x7D17 0x7D72 \ + 0x8086 0x820D 0x838E 0x84D1 0x86C7 0x88DF 0x8A50 0x8A5E \ + 0x8B1D 0x8CDC 0x8D66 0x8FAD 0x90AA 0x98FC 0x99DF 0x9E9D \ + 0x524A 0xF969 0x6714 0xF96A 0x5098 0x522A 0x5C71 0x6563 \ + 0x6C55 0x73CA 0x7523 0x759D 0x7B97 0x849C 0x9178 0x9730 \ + 0x4E77 0x6492 0x6BBA 0x715E 0x85A9 0x4E09 0xF96B 0x6749 \ + 0x68EE 0x6E17 0x829F 0x8518 0x886B 0x63F7 0x6F81 0x9212 \ + 0x98AF 0x4E0A 0x50B7 0x50CF 0x511F 0x5546 0x55AA 0x5617 \ + 0x5B40 0x5C19 0x5CE0 0x5E38 0x5E8A 0x5EA0 0x5EC2 0x60F3 \ + 0x6851 0x6A61 0x6E58 0x723D 0x7240 0x72C0 0x76F8 0x7965 \ + 0x7BB1 0x7FD4 0x88F3 0x89F4 0x8A73 0x8C61 0x8CDE 0x971C +24 0x585E 0x74BD 0x8CFD 0x55C7 0xF96C 0x7A61 0x7D22 0x8272 \ + 0x7272 0x751F 0x7525 0xF96D 0x7B19 0x5885 0x58FB 0x5DBC \ + 0x5E8F 0x5EB6 0x5F90 0x6055 0x6292 0x637F 0x654D 0x6691 \ + 0x66D9 0x66F8 0x6816 0x68F2 0x7280 0x745E 0x7B6E 0x7D6E \ + 0x7DD6 0x7F72 0x80E5 0x8212 0x85AF 0x897F 0x8A93 0x901D \ + 0x92E4 0x9ECD 0x9F20 0x5915 0x596D 0x5E2D 0x60DC 0x6614 \ + 0x6673 0x6790 0x6C50 0x6DC5 0x6F5F 0x77F3 0x78A9 0x84C6 \ + 0x91CB 0x932B 0x4ED9 0x50CA 0x5148 0x5584 0x5B0B 0x5BA3 \ + 0x6247 0x657E 0x65CB 0x6E32 0x717D 0x7401 0x7444 0x7487 \ + 0x74BF 0x766C 0x79AA 0x7DDA 0x7E55 0x7FA8 0x817A 0x81B3 \ + 0x8239 0x861A 0x87EC 0x8A75 0x8DE3 0x9078 0x9291 0x9425 \ + 0x994D 0x9BAE 0x5368 0x5C51 0x6954 0x6CC4 0x6D29 0x6E2B \ + 0x820C 0x859B 0x893B 0x8A2D 0x8AAA 0x96EA 0x9F67 0x5261 \ + 0x66B9 0x6BB2 0x7E96 0x87FE 0x8D0D 0x9583 0x965D 0x651D \ + 0x6D89 0x71EE 0xF96E 0x57CE 0x59D3 0x5BAC 0x6027 0x60FA \ + 0x6210 0x661F 0x665F 0x7329 0x73F9 0x76DB 0x7701 0x7B6C \ + 0x8056 0x8072 0x8165 0x8AA0 0x9192 0x4E16 0x52E2 0x6B72 \ + 0x6D17 0x7A05 0x7B39 0x7D30 0xF96F 0x8CB0 0x53EC 0x562F \ + 0x5851 0x5BB5 0x5C0F 0x5C11 0x5DE2 0x6240 0x6383 0x6414 \ + 0x662D 0x68B3 0x6CBC 0x6D88 0x6EAF 0x701F 0x70A4 0x71D2 \ + 0x7526 0x758F 0x758E 0x7619 0x7B11 0x7BE0 0x7C2B 0x7D20 \ + 0x7D39 0x852C 0x856D 0x8607 0x8A34 0x900D 0x9061 0x90B5 \ + 0x92B7 0x97F6 0x9A37 0x4FD7 0x5C6C 0x675F 0x6D91 0x7C9F \ + 0x7E8C 0x8B16 0x8D16 0x901F 0x5B6B 0x5DFD 0x640D 0x84C0 \ + 0x905C 0x98E1 0x7387 0x5B8B 0x609A 0x677E 0x6DDE 0x8A1F \ + 0x8AA6 0x9001 0x980C 0x5237 0xF970 0x7051 0x788E 0x9396 \ + 0x8870 0x91D7 0x4FEE 0x53D7 0x55FD 0x56DA 0x5782 0x58FD \ + 0x5AC2 0x5B88 0x5CAB 0x5CC0 0x5E25 0x6101 0x620D 0x624B \ + 0x6388 0x641C 0x6536 0x6578 0x6A39 0x6B8A 0x6C34 0x6D19 \ + 0x6F31 0x71E7 0x72E9 0x7378 0x7407 0x74B2 0x7626 0x7761 \ + 0x79C0 0x7A57 0x7AEA 0x7CB9 0x7D8F 0x7DAC 0x7E61 0x7F9E \ + 0x8129 0x8331 0x8490 0x84DA 0x85EA 0x8896 0x8AB0 0x8B90 +25 0x8F38 0x9042 0x9083 0x916C 0x9296 0x92B9 0x968B 0x96A7 \ + 0x96A8 0x96D6 0x9700 0x9808 0x9996 0x9AD3 0x9B1A 0x53D4 \ + 0x587E 0x5919 0x5B70 0x5BBF 0x6DD1 0x6F5A 0x719F 0x7421 \ + 0x74B9 0x8085 0x83FD 0x5DE1 0x5F87 0x5FAA 0x6042 0x65EC \ + 0x6812 0x696F 0x6A53 0x6B89 0x6D35 0x6DF3 0x73E3 0x76FE \ + 0x77AC 0x7B4D 0x7D14 0x8123 0x821C 0x8340 0x84F4 0x8563 \ + 0x8A62 0x8AC4 0x9187 0x931E 0x9806 0x99B4 0x620C 0x8853 \ + 0x8FF0 0x9265 0x5D07 0x5D27 0x5D69 0x745F 0x819D 0x8768 \ + 0x6FD5 0x62FE 0x7FD2 0x8936 0x8972 0x4E1E 0x4E58 0x50E7 \ + 0x52DD 0x5347 0x627F 0x6607 0x7E69 0x8805 0x965E 0x4F8D \ + 0x5319 0x5636 0x59CB 0x5AA4 0x5C38 0x5C4E 0x5C4D 0x5E02 \ + 0x5F11 0x6043 0x65BD 0x662F 0x6642 0x67BE 0x67F4 0x731C \ + 0x77E2 0x793A 0x7FC5 0x8494 0x84CD 0x8996 0x8A66 0x8A69 \ + 0x8AE1 0x8C55 0x8C7A 0x57F4 0x5BD4 0x5F0F 0x606F 0x62ED \ + 0x690D 0x6B96 0x6E5C 0x7184 0x7BD2 0x8755 0x8B58 0x8EFE \ + 0x98DF 0x98FE 0x4F38 0x4F81 0x4FE1 0x547B 0x5A20 0x5BB8 \ + 0x613C 0x65B0 0x6668 0x71FC 0x7533 0x795E 0x7D33 0x814E \ + 0x81E3 0x8398 0x85AA 0x85CE 0x8703 0x8A0A 0x8EAB 0x8F9B \ + 0xF971 0x8FC5 0x5931 0x5BA4 0x5BE6 0x6089 0x5BE9 0x5C0B \ + 0x5FC3 0x6C81 0xF972 0x6DF1 0x700B 0x751A 0x82AF 0x8AF6 \ + 0x4EC0 0x5341 0xF973 0x96D9 0x6C0F 0x4E9E 0x4FC4 0x5152 \ + 0x555E 0x5A25 0x5CE8 0x6211 0x7259 0x82BD 0x83AA 0x86FE \ + 0x8859 0x8A1D 0x963F 0x96C5 0x9913 0x9D09 0x9D5D 0x580A \ + 0x5CB3 0x5DBD 0x5E44 0x60E1 0x6115 0x63E1 0x6A02 0x6E25 \ + 0x9102 0x9354 0x984E 0x9C10 0x9F77 0x5B89 0x5CB8 0x6309 \ + 0x664F 0x6848 0x773C 0x96C1 0x978D 0x9854 0x9B9F 0x65A1 \ + 0x8B01 0x8ECB 0x95BC 0x5535 0x5CA9 0x5DD6 0x5EB5 0x6697 \ + 0x764C 0x83F4 0x95C7 0x58D3 0x62BC 0x72CE 0x9D28 0x4EF0 \ + 0x592E 0x600F 0x663B 0x6B83 0x79E7 0x9D26 0x5393 0x54C0 \ + 0x57C3 0x5D16 0x611B 0x66D6 0x6DAF 0x788D 0x827E 0x9698 \ + 0x9744 0x5384 0x627C 0x6396 0x6DB2 0x7E0A 0x814B 0x984D \ + 0x6AFB 0x7F4C 0x9DAF 0x9E1A 0x4E5F 0x503B 0x51B6 0x591C +26 0x60F9 0x63F6 0x6930 0x723A 0x8036 0xF974 0x91CE 0x5F31 \ + 0xF975 0xF976 0x7D04 0x82E5 0x846F 0x84BB 0x85E5 0x8E8D \ + 0xF977 0x4F6F 0xF978 0xF979 0x58E4 0x5B43 0x6059 0x63DA \ + 0x6518 0x656D 0x6698 0xF97A 0x694A 0x6A23 0x6D0B 0x7001 \ + 0x716C 0x75D2 0x760D 0x79B3 0x7A70 0xF97B 0x7F8A 0xF97C \ + 0x8944 0xF97D 0x8B93 0x91C0 0x967D 0xF97E 0x990A 0x5704 \ + 0x5FA1 0x65BC 0x6F01 0x7600 0x79A6 0x8A9E 0x99AD 0x9B5A \ + 0x9F6C 0x5104 0x61B6 0x6291 0x6A8D 0x81C6 0x5043 0x5830 \ + 0x5F66 0x7109 0x8A00 0x8AFA 0x5B7C 0x8616 0x4FFA 0x513C \ + 0x56B4 0x5944 0x63A9 0x6DF9 0x5DAA 0x696D 0x5186 0x4E88 \ + 0x4F59 0xF97F 0xF980 0xF981 0x5982 0xF982 0xF983 0x6B5F \ + 0x6C5D 0xF984 0x74B5 0x7916 0xF985 0x8207 0x8245 0x8339 \ + 0x8F3F 0x8F5D 0xF986 0x9918 0xF987 0xF988 0xF989 0x4EA6 \ + 0xF98A 0x57DF 0x5F79 0x6613 0xF98B 0xF98C 0x75AB 0x7E79 \ + 0x8B6F 0xF98D 0x9006 0x9A5B 0x56A5 0x5827 0x59F8 0x5A1F \ + 0x5BB4 0xF98E 0x5EF6 0xF98F 0xF990 0x6350 0x633B 0xF991 \ + 0x693D 0x6C87 0x6CBF 0x6D8E 0x6D93 0x6DF5 0x6F14 0xF992 \ + 0x70DF 0x7136 0x7159 0xF993 0x71C3 0x71D5 0xF994 0x784F \ + 0x786F 0xF995 0x7B75 0x7DE3 0xF996 0x7E2F 0xF997 0x884D \ + 0x8EDF 0xF998 0xF999 0xF99A 0x925B 0xF99B 0x9CF6 0xF99C \ + 0xF99D 0xF99E 0x6085 0x6D85 0xF99F 0x71B1 0xF9A0 0xF9A1 \ + 0x95B1 0x53AD 0xF9A2 0xF9A3 0xF9A4 0x67D3 0xF9A5 0x708E \ + 0x7130 0x7430 0x8276 0x82D2 0xF9A6 0x95BB 0x9AE5 0x9E7D \ + 0x66C4 0xF9A7 0x71C1 0x8449 0xF9A8 0xF9A9 0x584B 0xF9AA \ + 0xF9AB 0x5DB8 0x5F71 0xF9AC 0x6620 0x668E 0x6979 0x69AE \ + 0x6C38 0x6CF3 0x6E36 0x6F41 0x6FDA 0x701B 0x702F 0x7150 \ + 0x71DF 0x7370 0xF9AD 0x745B 0xF9AE 0x74D4 0x76C8 0x7A4E \ + 0x7E93 0xF9AF 0xF9B0 0x82F1 0x8A60 0x8FCE 0xF9B1 0x9348 \ + 0xF9B2 0x9719 0xF9B3 0xF9B4 0x4E42 0x502A 0xF9B5 0x5208 \ + 0x53E1 0x66F3 0x6C6D 0x6FCA 0x730A 0x777F 0x7A62 0x82AE \ + 0x85DD 0x8602 0xF9B6 0x88D4 0x8A63 0x8B7D 0x8C6B 0xF9B7 \ + 0x92B3 0xF9B8 0x9713 0x9810 0x4E94 0x4F0D 0x4FC9 0x50B2 +27 0x5348 0x543E 0x5433 0x55DA 0x5862 0x58BA 0x5967 0x5A1B \ + 0x5BE4 0x609F 0xF9B9 0x61CA 0x6556 0x65FF 0x6664 0x68A7 \ + 0x6C5A 0x6FB3 0x70CF 0x71AC 0x7352 0x7B7D 0x8708 0x8AA4 \ + 0x9C32 0x9F07 0x5C4B 0x6C83 0x7344 0x7389 0x923A 0x6EAB \ + 0x7465 0x761F 0x7A69 0x7E15 0x860A 0x5140 0x58C5 0x64C1 \ + 0x74EE 0x7515 0x7670 0x7FC1 0x9095 0x96CD 0x9954 0x6E26 \ + 0x74E6 0x7AA9 0x7AAA 0x81E5 0x86D9 0x8778 0x8A1B 0x5A49 \ + 0x5B8C 0x5B9B 0x68A1 0x6900 0x6D63 0x73A9 0x7413 0x742C \ + 0x7897 0x7DE9 0x7FEB 0x8118 0x8155 0x839E 0x8C4C 0x962E \ + 0x9811 0x66F0 0x5F80 0x65FA 0x6789 0x6C6A 0x738B 0x502D \ + 0x5A03 0x6B6A 0x77EE 0x5916 0x5D6C 0x5DCD 0x7325 0x754F \ + 0xF9BA 0xF9BB 0x50E5 0x51F9 0x582F 0x592D 0x5996 0x59DA \ + 0x5BE5 0xF9BC 0xF9BD 0x5DA2 0x62D7 0x6416 0x6493 0x64FE \ + 0xF9BE 0x66DC 0xF9BF 0x6A48 0xF9C0 0x71FF 0x7464 0xF9C1 \ + 0x7A88 0x7AAF 0x7E47 0x7E5E 0x8000 0x8170 0xF9C2 0x87EF \ + 0x8981 0x8B20 0x9059 0xF9C3 0x9080 0x9952 0x617E 0x6B32 \ + 0x6D74 0x7E1F 0x8925 0x8FB1 0x4FD1 0x50AD 0x5197 0x52C7 \ + 0x57C7 0x5889 0x5BB9 0x5EB8 0x6142 0x6995 0x6D8C 0x6E67 \ + 0x6EB6 0x7194 0x7462 0x7528 0x752C 0x8073 0x8338 0x84C9 \ + 0x8E0A 0x9394 0x93DE 0xF9C4 0x4E8E 0x4F51 0x5076 0x512A \ + 0x53C8 0x53CB 0x53F3 0x5B87 0x5BD3 0x5C24 0x611A 0x6182 \ + 0x65F4 0x725B 0x7397 0x7440 0x76C2 0x7950 0x7991 0x79B9 \ + 0x7D06 0x7FBD 0x828B 0x85D5 0x865E 0x8FC2 0x9047 0x90F5 \ + 0x91EA 0x9685 0x96E8 0x96E9 0x52D6 0x5F67 0x65ED 0x6631 \ + 0x682F 0x715C 0x7A36 0x90C1 0x980A 0x4E91 0xF9C5 0x6A52 \ + 0x6B9E 0x6F90 0x7189 0x8018 0x82B8 0x8553 0x904B 0x9695 \ + 0x96F2 0x97FB 0x851A 0x9B31 0x4E90 0x718A 0x96C4 0x5143 \ + 0x539F 0x54E1 0x5713 0x5712 0x57A3 0x5A9B 0x5AC4 0x5BC3 \ + 0x6028 0x613F 0x63F4 0x6C85 0x6D39 0x6E72 0x6E90 0x7230 \ + 0x733F 0x7457 0x82D1 0x8881 0x8F45 0x9060 0xF9C6 0x9662 \ + 0x9858 0x9D1B 0x6708 0x8D8A 0x925E 0x4F4D 0x5049 0x50DE \ + 0x5371 0x570D 0x59D4 0x5A01 0x5C09 0x6170 0x6690 0x6E2D +28 0x7232 0x744B 0x7DEF 0x80C3 0x840E 0x8466 0x853F 0x875F \ + 0x885B 0x8918 0x8B02 0x9055 0x97CB 0x9B4F 0x4E73 0x4F91 \ + 0x5112 0x516A 0xF9C7 0x552F 0x55A9 0x5B7A 0x5BA5 0x5E7C \ + 0x5E7D 0x5EBE 0x60A0 0x60DF 0x6108 0x6109 0x63C4 0x6538 \ + 0x6709 0xF9C8 0x67D4 0x67DA 0xF9C9 0x6961 0x6962 0x6CB9 \ + 0x6D27 0xF9CA 0x6E38 0xF9CB 0x6FE1 0x7336 0x7337 0xF9CC \ + 0x745C 0x7531 0xF9CD 0x7652 0xF9CE 0xF9CF 0x7DAD 0x81FE \ + 0x8438 0x88D5 0x8A98 0x8ADB 0x8AED 0x8E30 0x8E42 0x904A \ + 0x903E 0x907A 0x9149 0x91C9 0x936E 0xF9D0 0xF9D1 0x5809 \ + 0xF9D2 0x6BD3 0x8089 0x80B2 0xF9D3 0xF9D4 0x5141 0x596B \ + 0x5C39 0xF9D5 0xF9D6 0x6F64 0x73A7 0x80E4 0x8D07 0xF9D7 \ + 0x9217 0x958F 0xF9D8 0xF9D9 0xF9DA 0xF9DB 0x807F 0x620E \ + 0x701C 0x7D68 0x878D 0xF9DC 0x57A0 0x6069 0x6147 0x6BB7 \ + 0x8ABE 0x9280 0x96B1 0x4E59 0x541F 0x6DEB 0x852D 0x9670 \ + 0x97F3 0x98EE 0x63D6 0x6CE3 0x9091 0x51DD 0x61C9 0x81BA \ + 0x9DF9 0x4F9D 0x501A 0x5100 0x5B9C 0x610F 0x61FF 0x64EC \ + 0x6905 0x6BC5 0x7591 0x77E3 0x7FA9 0x8264 0x858F 0x87FB \ + 0x8863 0x8ABC 0x8B70 0x91AB 0x4E8C 0x4EE5 0x4F0A 0xF9DD \ + 0xF9DE 0x5937 0x59E8 0xF9DF 0x5DF2 0x5F1B 0x5F5B 0x6021 \ + 0xF9E0 0xF9E1 0xF9E2 0xF9E3 0x723E 0x73E5 0xF9E4 0x7570 \ + 0x75CD 0xF9E5 0x79FB 0xF9E6 0x800C 0x8033 0x8084 0x82E1 \ + 0x8351 0xF9E7 0xF9E8 0x8CBD 0x8CB3 0x9087 0xF9E9 0xF9EA \ + 0x98F4 0x990C 0xF9EB 0xF9EC 0x7037 0x76CA 0x7FCA 0x7FCC \ + 0x7FFC 0x8B1A 0x4EBA 0x4EC1 0x5203 0x5370 0xF9ED 0x54BD \ + 0x56E0 0x59FB 0x5BC5 0x5F15 0x5FCD 0x6E6E 0xF9EE 0xF9EF \ + 0x7D6A 0x8335 0xF9F0 0x8693 0x8A8D 0xF9F1 0x976D 0x9777 \ + 0xF9F2 0xF9F3 0x4E00 0x4F5A 0x4F7E 0x58F9 0x65E5 0x6EA2 \ + 0x9038 0x93B0 0x99B9 0x4EFB 0x58EC 0x598A 0x59D9 0x6041 \ + 0xF9F4 0xF9F5 0x7A14 0xF9F6 0x834F 0x8CC3 0x5165 0x5344 \ + 0xF9F7 0xF9F8 0xF9F9 0x4ECD 0x5269 0x5B55 0x82BF 0x4ED4 \ + 0x523A 0x54A8 0x59C9 0x59FF 0x5B50 0x5B57 0x5B5C 0x6063 \ + 0x6148 0x6ECB 0x7099 0x716E 0x7386 0x74F7 0x75B5 0x78C1 +29 0x7D2B 0x8005 0x81EA 0x8328 0x8517 0x85C9 0x8AEE 0x8CC7 \ + 0x96CC 0x4F5C 0x52FA 0x56BC 0x65AB 0x6628 0x707C 0x70B8 \ + 0x7235 0x7DBD 0x828D 0x914C 0x96C0 0x9D72 0x5B71 0x68E7 \ + 0x6B98 0x6F7A 0x76DE 0x5C91 0x66AB 0x6F5B 0x7BB4 0x7C2A \ + 0x8836 0x96DC 0x4E08 0x4ED7 0x5320 0x5834 0x58BB 0x58EF \ + 0x596C 0x5C07 0x5E33 0x5E84 0x5F35 0x638C 0x66B2 0x6756 \ + 0x6A1F 0x6AA3 0x6B0C 0x6F3F 0x7246 0xF9FA 0x7350 0x748B \ + 0x7AE0 0x7CA7 0x8178 0x81DF 0x81E7 0x838A 0x846C 0x8523 \ + 0x8594 0x85CF 0x88DD 0x8D13 0x91AC 0x9577 0x969C 0x518D \ + 0x54C9 0x5728 0x5BB0 0x624D 0x6750 0x683D 0x6893 0x6E3D \ + 0x6ED3 0x707D 0x7E21 0x88C1 0x8CA1 0x8F09 0x9F4B 0x9F4E \ + 0x722D 0x7B8F 0x8ACD 0x931A 0x4F47 0x4F4E 0x5132 0x5480 \ + 0x59D0 0x5E95 0x62B5 0x6775 0x696E 0x6A17 0x6CAE 0x6E1A \ + 0x72D9 0x732A 0x75BD 0x7BB8 0x7D35 0x82E7 0x83F9 0x8457 \ + 0x85F7 0x8A5B 0x8CAF 0x8E87 0x9019 0x90B8 0x96CE 0x9F5F \ + 0x52E3 0x540A 0x5AE1 0x5BC2 0x6458 0x6575 0x6EF4 0x72C4 \ + 0xF9FB 0x7684 0x7A4D 0x7B1B 0x7C4D 0x7E3E 0x7FDF 0x837B \ + 0x8B2B 0x8CCA 0x8D64 0x8DE1 0x8E5F 0x8FEA 0x8FF9 0x9069 \ + 0x93D1 0x4F43 0x4F7A 0x50B3 0x5168 0x5178 0x524D 0x526A \ + 0x5861 0x587C 0x5960 0x5C08 0x5C55 0x5EDB 0x609B 0x6230 \ + 0x6813 0x6BBF 0x6C08 0x6FB1 0x714E 0x7420 0x7530 0x7538 \ + 0x7551 0x7672 0x7B4C 0x7B8B 0x7BAD 0x7BC6 0x7E8F 0x8A6E \ + 0x8F3E 0x8F49 0x923F 0x9293 0x9322 0x942B 0x96FB 0x985A \ + 0x986B 0x991E 0x5207 0x622A 0x6298 0x6D59 0x7664 0x7ACA \ + 0x7BC0 0x7D76 0x5360 0x5CBE 0x5E97 0x6F38 0x70B9 0x7C98 \ + 0x9711 0x9B8E 0x9EDE 0x63A5 0x647A 0x8776 0x4E01 0x4E95 \ + 0x4EAD 0x505C 0x5075 0x5448 0x59C3 0x5B9A 0x5E40 0x5EAD \ + 0x5EF7 0x5F81 0x60C5 0x633A 0x653F 0x6574 0x65CC 0x6676 \ + 0x6678 0x67FE 0x6968 0x6A89 0x6B63 0x6C40 0x6DC0 0x6DE8 \ + 0x6E1F 0x6E5E 0x701E 0x70A1 0x738E 0x73FD 0x753A 0x775B \ + 0x7887 0x798E 0x7A0B 0x7A7D 0x7CBE 0x7D8E 0x8247 0x8A02 \ + 0x8AEA 0x8C9E 0x912D 0x914A 0x91D8 0x9266 0x92CC 0x9320 +30 0x9706 0x9756 0x975C 0x9802 0x9F0E 0x5236 0x5291 0x557C \ + 0x5824 0x5E1D 0x5F1F 0x608C 0x63D0 0x68AF 0x6FDF 0x796D \ + 0x7B2C 0x81CD 0x85BA 0x88FD 0x8AF8 0x8E44 0x918D 0x9664 \ + 0x969B 0x973D 0x984C 0x9F4A 0x4FCE 0x5146 0x51CB 0x52A9 \ + 0x5632 0x5F14 0x5F6B 0x63AA 0x64CD 0x65E9 0x6641 0x66FA \ + 0x66F9 0x671D 0x689D 0x68D7 0x69FD 0x6F15 0x6F6E 0x7167 \ + 0x71E5 0x722A 0x74AA 0x773A 0x7956 0x795A 0x79DF 0x7A20 \ + 0x7A95 0x7C97 0x7CDF 0x7D44 0x7E70 0x8087 0x85FB 0x86A4 \ + 0x8A54 0x8ABF 0x8D99 0x8E81 0x9020 0x906D 0x91E3 0x963B \ + 0x96D5 0x9CE5 0x65CF 0x7C07 0x8DB3 0x93C3 0x5B58 0x5C0A \ + 0x5352 0x62D9 0x731D 0x5027 0x5B97 0x5F9E 0x60B0 0x616B \ + 0x68D5 0x6DD9 0x742E 0x7A2E 0x7D42 0x7D9C 0x7E31 0x816B \ + 0x8E2A 0x8E35 0x937E 0x9418 0x4F50 0x5750 0x5DE6 0x5EA7 \ + 0x632B 0x7F6A 0x4E3B 0x4F4F 0x4F8F 0x505A 0x59DD 0x80C4 \ + 0x546A 0x5468 0x55FE 0x594F 0x5B99 0x5DDE 0x5EDA 0x665D \ + 0x6731 0x67F1 0x682A 0x6CE8 0x6D32 0x6E4A 0x6F8D 0x70B7 \ + 0x73E0 0x7587 0x7C4C 0x7D02 0x7D2C 0x7DA2 0x821F 0x86DB \ + 0x8A3B 0x8A85 0x8D70 0x8E8A 0x8F33 0x9031 0x914E 0x9152 \ + 0x9444 0x99D0 0x7AF9 0x7CA5 0x4FCA 0x5101 0x51C6 0x57C8 \ + 0x5BEF 0x5CFB 0x6659 0x6A3D 0x6D5A 0x6E96 0x6FEC 0x710C \ + 0x756F 0x7AE3 0x8822 0x9021 0x9075 0x96CB 0x99FF 0x8301 \ + 0x4E2D 0x4EF2 0x8846 0x91CD 0x537D 0x6ADB 0x696B 0x6C41 \ + 0x847A 0x589E 0x618E 0x66FE 0x62EF 0x70DD 0x7511 0x75C7 \ + 0x7E52 0x84B8 0x8B49 0x8D08 0x4E4B 0x53EA 0x54AB 0x5730 \ + 0x5740 0x5FD7 0x6301 0x6307 0x646F 0x652F 0x65E8 0x667A \ + 0x679D 0x67B3 0x6B62 0x6C60 0x6C9A 0x6F2C 0x77E5 0x7825 \ + 0x7949 0x7957 0x7D19 0x80A2 0x8102 0x81F3 0x829D 0x82B7 \ + 0x8718 0x8A8C 0xF9FC 0x8D04 0x8DBE 0x9072 0x76F4 0x7A19 \ + 0x7A37 0x7E54 0x8077 0x5507 0x55D4 0x5875 0x632F 0x6422 \ + 0x6649 0x664B 0x686D 0x699B 0x6B84 0x6D25 0x6EB1 0x73CD \ + 0x7468 0x74A1 0x755B 0x75B9 0x76E1 0x771E 0x778B 0x79E6 \ + 0x7E09 0x7E1D 0x81FB 0x852F 0x8897 0x8A3A 0x8CD1 0x8EEB +31 0x8FB0 0x9032 0x93AD 0x9663 0x9673 0x9707 0x4F84 0x53F1 \ + 0x59EA 0x5AC9 0x5E19 0x684E 0x74C6 0x75BE 0x79E9 0x7A92 \ + 0x81A3 0x86ED 0x8CEA 0x8DCC 0x8FED 0x659F 0x6715 0xF9FD \ + 0x57F7 0x6F57 0x7DDD 0x8F2F 0x93F6 0x96C6 0x5FB5 0x61F2 \ + 0x6F84 0x4E14 0x4F98 0x501F 0x53C9 0x55DF 0x5D6F 0x5DEE \ + 0x6B21 0x6B64 0x78CB 0x7B9A 0xF9FE 0x8E49 0x8ECA 0x906E \ + 0x6349 0x643E 0x7740 0x7A84 0x932F 0x947F 0x9F6A 0x64B0 \ + 0x6FAF 0x71E6 0x74A8 0x74DA 0x7AC4 0x7C12 0x7E82 0x7CB2 \ + 0x7E98 0x8B9A 0x8D0A 0x947D 0x9910 0x994C 0x5239 0x5BDF \ + 0x64E6 0x672D 0x7D2E 0x50ED 0x53C3 0x5879 0x6158 0x6159 \ + 0x61FA 0x65AC 0x7AD9 0x8B92 0x8B96 0x5009 0x5021 0x5275 \ + 0x5531 0x5A3C 0x5EE0 0x5F70 0x6134 0x655E 0x660C 0x6636 \ + 0x66A2 0x69CD 0x6EC4 0x6F32 0x7316 0x7621 0x7A93 0x8139 \ + 0x8259 0x83D6 0x84BC 0x50B5 0x57F0 0x5BC0 0x5BE8 0x5F69 \ + 0x63A1 0x7826 0x7DB5 0x83DC 0x8521 0x91C7 0x91F5 0x518A \ + 0x67F5 0x7B56 0x8CAC 0x51C4 0x59BB 0x60BD 0x8655 0x501C \ + 0xF9FF 0x5254 0x5C3A 0x617D 0x621A 0x62D3 0x64F2 0x65A5 \ + 0x6ECC 0x7620 0x810A 0x8E60 0x965F 0x96BB 0x4EDF 0x5343 \ + 0x5598 0x5929 0x5DDD 0x64C5 0x6CC9 0x6DFA 0x7394 0x7A7F \ + 0x821B 0x85A6 0x8CE4 0x8E10 0x9077 0x91E7 0x95E1 0x9621 \ + 0x97C6 0x51F8 0x54F2 0x5586 0x5FB9 0x64A4 0x6F88 0x7DB4 \ + 0x8F1F 0x8F4D 0x9435 0x50C9 0x5C16 0x6CBE 0x6DFB 0x751B \ + 0x77BB 0x7C3D 0x7C64 0x8A79 0x8AC2 0x581E 0x59BE 0x5E16 \ + 0x6377 0x7252 0x758A 0x776B 0x8ADC 0x8CBC 0x8F12 0x5EF3 \ + 0x6674 0x6DF8 0x807D 0x83C1 0x8ACB 0x9751 0x9BD6 0xFA00 \ + 0x5243 0x66FF 0x6D95 0x6EEF 0x7DE0 0x8AE6 0x902E 0x905E \ + 0x9AD4 0x521D 0x527F 0x54E8 0x6194 0x6284 0x62DB 0x68A2 \ + 0x6912 0x695A 0x6A35 0x7092 0x7126 0x785D 0x7901 0x790E \ + 0x79D2 0x7A0D 0x8096 0x8278 0x82D5 0x8349 0x8549 0x8C82 \ + 0x8D85 0x9162 0x918B 0x91AE 0x4FC3 0x56D1 0x71ED 0x77D7 \ + 0x8700 0x89F8 0x5BF8 0x5FD6 0x6751 0x90A8 0x53E2 0x585A \ + 0x5BF5 0x60A4 0x6181 0x6460 0x7E3D 0x8070 0x8525 0x9283 +32 0x64AE 0x50AC 0x5D14 0x6700 0x589C 0x62BD 0x63A8 0x690E \ + 0x6978 0x6A1E 0x6E6B 0x76BA 0x79CB 0x82BB 0x8429 0x8ACF \ + 0x8DA8 0x8FFD 0x9112 0x914B 0x919C 0x9310 0x9318 0x939A \ + 0x96DB 0x9A36 0x9C0D 0x4E11 0x755C 0x795D 0x7AFA 0x7B51 \ + 0x7BC9 0x7E2E 0x84C4 0x8E59 0x8E74 0x8EF8 0x9010 0x6625 \ + 0x693F 0x7443 0x51FA 0x672E 0x9EDC 0x5145 0x5FE0 0x6C96 \ + 0x87F2 0x885D 0x8877 0x60B4 0x81B5 0x8403 0x8D05 0x53D6 \ + 0x5439 0x5634 0x5A36 0x5C31 0x708A 0x7FE0 0x805A 0x8106 \ + 0x81ED 0x8DA3 0x9189 0x9A5F 0x9DF2 0x5074 0x4EC4 0x53A0 \ + 0x60FB 0x6E2C 0x5C64 0x4F88 0x5024 0x55E4 0x5CD9 0x5E5F \ + 0x6065 0x6894 0x6CBB 0x6DC4 0x71BE 0x75D4 0x75F4 0x7661 \ + 0x7A1A 0x7A49 0x7DC7 0x7DFB 0x7F6E 0x81F4 0x86A9 0x8F1C \ + 0x96C9 0x99B3 0x9F52 0x5247 0x52C5 0x98ED 0x89AA 0x4E03 \ + 0x67D2 0x6F06 0x4FB5 0x5BE2 0x6795 0x6C88 0x6D78 0x741B \ + 0x7827 0x91DD 0x937C 0x87C4 0x79E4 0x7A31 0x5FEB 0x4ED6 \ + 0x54A4 0x553E 0x58AE 0x59A5 0x60F0 0x6253 0x62D6 0x6736 \ + 0x6955 0x8235 0x9640 0x99B1 0x99DD 0x502C 0x5353 0x5544 \ + 0x577C 0xFA01 0x6258 0xFA02 0x64E2 0x666B 0x67DD 0x6FC1 \ + 0x6FEF 0x7422 0x7438 0x8A17 0x9438 0x5451 0x5606 0x5766 \ + 0x5F48 0x619A 0x6B4E 0x7058 0x70AD 0x7DBB 0x8A95 0x596A \ + 0x812B 0x63A2 0x7708 0x803D 0x8CAA 0x5854 0x642D 0x69BB \ + 0x5B95 0x5E11 0x6E6F 0xFA03 0x8569 0x514C 0x53F0 0x592A \ + 0x6020 0x614B 0x6B86 0x6C70 0x6CF0 0x7B1E 0x80CE 0x82D4 \ + 0x8DC6 0x90B0 0x98B1 0xFA04 0x64C7 0x6FA4 0x6491 0x6504 \ + 0x514E 0x5410 0x571F 0x8A0E 0x615F 0x6876 0xFA05 0x75DB \ + 0x7B52 0x7D71 0x901A 0x5806 0x69CC 0x817F 0x892A 0x9000 \ + 0x9839 0x5078 0x5957 0x59AC 0x6295 0x900F 0x9B2A 0x615D \ + 0x7279 0x95D6 0x5761 0x5A46 0x5DF4 0x628A 0x64AD 0x64FA \ + 0x6777 0x6CE2 0x6D3E 0x722C 0x7436 0x7834 0x7F77 0x82AD \ + 0x8DDB 0x9817 0x5224 0x5742 0x677F 0x7248 0x74E3 0x8CA9 \ + 0x8FA6 0x9211 0x962A 0x516B 0x53ED 0x634C 0x4F69 0x5504 \ + 0x6096 0x6557 0x6C9B 0x6D7F 0x724C 0x72FD 0x7A17 0x8987 +33 0x8C9D 0x5F6D 0x6F8E 0x70F9 0x81A8 0x610E 0x4FBF 0x504F \ + 0x6241 0x7247 0x7BC7 0x7DE8 0x7FE9 0x904D 0x97AD 0x9A19 \ + 0x8CB6 0x576A 0x5E73 0x67B0 0x840D 0x8A55 0x5420 0x5B16 \ + 0x5E63 0x5EE2 0x5F0A 0x6583 0x80BA 0x853D 0x9589 0x965B \ + 0x4F48 0x5305 0x530D 0x530F 0x5486 0x54FA 0x5703 0x5E03 \ + 0x6016 0x629B 0x62B1 0x6355 0xFA06 0x6CE1 0x6D66 0x75B1 \ + 0x7832 0x80DE 0x812F 0x82DE 0x8461 0x84B2 0x888D 0x8912 \ + 0x900B 0x92EA 0x98FD 0x9B91 0x5E45 0x66B4 0x66DD 0x7011 \ + 0x7206 0xFA07 0x4FF5 0x527D 0x5F6A 0x6153 0x6753 0x6A19 \ + 0x6F02 0x74E2 0x7968 0x8868 0x8C79 0x98C7 0x98C4 0x9A43 \ + 0x54C1 0x7A1F 0x6953 0x8AF7 0x8C4A 0x98A8 0x99AE 0x5F7C \ + 0x62AB 0x75B2 0x76AE 0x88AB 0x907F 0x9642 0x5339 0x5F3C \ + 0x5FC5 0x6CCC 0x73CC 0x7562 0x758B 0x7B46 0x82FE 0x999D \ + 0x4E4F 0x903C 0x4E0B 0x4F55 0x53A6 0x590F 0x5EC8 0x6630 \ + 0x6CB3 0x7455 0x8377 0x8766 0x8CC0 0x9050 0x971E 0x9C15 \ + 0x58D1 0x5B78 0x8650 0x8B14 0x9DB4 0x5BD2 0x6068 0x608D \ + 0x65F1 0x6C57 0x6F22 0x6FA3 0x701A 0x7F55 0x7FF0 0x9591 \ + 0x9592 0x9650 0x97D3 0x5272 0x8F44 0x51FD 0x542B 0x54B8 \ + 0x5563 0x558A 0x6ABB 0x6DB5 0x7DD8 0x8266 0x929C 0x9677 \ + 0x9E79 0x5408 0x54C8 0x76D2 0x86E4 0x95A4 0x95D4 0x965C \ + 0x4EA2 0x4F09 0x59EE 0x5AE6 0x5DF7 0x6052 0x6297 0x676D \ + 0x6841 0x6C86 0x6E2F 0x7F38 0x809B 0x822A 0xFA08 0xFA09 \ + 0x9805 0x4EA5 0x5055 0x54B3 0x5793 0x595A 0x5B69 0x5BB3 \ + 0x61C8 0x6977 0x6D77 0x7023 0x87F9 0x89E3 0x8A72 0x8AE7 \ + 0x9082 0x99ED 0x9AB8 0x52BE 0x6838 0x5016 0x5E78 0x674F \ + 0x8347 0x884C 0x4EAB 0x5411 0x56AE 0x73E6 0x9115 0x97FF \ + 0x9909 0x9957 0x9999 0x5653 0x589F 0x865B 0x8A31 0x61B2 \ + 0x6AF6 0x737B 0x8ED2 0x6B47 0x96AA 0x9A57 0x5955 0x7200 \ + 0x8D6B 0x9769 0x4FD4 0x5CF4 0x5F26 0x61F8 0x665B 0x6CEB \ + 0x70AB 0x7384 0x73B9 0x73FE 0x7729 0x774D 0x7D43 0x7D62 \ + 0x7E23 0x8237 0x8852 0xFA0A 0x8CE2 0x9249 0x986F 0x5B51 \ + 0x7A74 0x8840 0x9801 0x5ACC 0x4FE0 0x5354 0x593E 0x5CFD +34 0x633E 0x6D79 0x72F9 0x8105 0x8107 0x83A2 0x92CF 0x9830 \ + 0x4EA8 0x5144 0x5211 0x578B 0x5F62 0x6CC2 0x6ECE 0x7005 \ + 0x7050 0x70AF 0x7192 0x73E9 0x7469 0x834A 0x87A2 0x8861 \ + 0x9008 0x90A2 0x93A3 0x99A8 0x516E 0x5F57 0x60E0 0x6167 \ + 0x66B3 0x8559 0x8E4A 0x91AF 0x978B 0x4E4E 0x4E92 0x547C \ + 0x58D5 0x58FA 0x597D 0x5CB5 0x5F27 0x6236 0x6248 0x660A \ + 0x6667 0x6BEB 0x6D69 0x6DCF 0x6E56 0x6EF8 0x6F94 0x6FE0 \ + 0x6FE9 0x705D 0x72D0 0x7425 0x745A 0x74E0 0x7693 0x795C \ + 0x7CCA 0x7E1E 0x80E1 0x82A6 0x846B 0x84BF 0x864E 0x865F \ + 0x8774 0x8B77 0x8C6A 0x93AC 0x9800 0x9865 0x60D1 0x6216 \ + 0x9177 0x5A5A 0x660F 0x6DF7 0x6E3E 0x743F 0x9B42 0x5FFD \ + 0x60DA 0x7B0F 0x54C4 0x5F18 0x6C5E 0x6CD3 0x6D2A 0x70D8 \ + 0x7D05 0x8679 0x8A0C 0x9D3B 0x5316 0x548C 0x5B05 0x6A3A \ + 0x706B 0x7575 0x798D 0x79BE 0x82B1 0x83EF 0x8A71 0x8B41 \ + 0x8CA8 0x9774 0xFA0B 0x64F4 0x652B 0x78BA 0x78BB 0x7A6B \ + 0x4E38 0x559A 0x5950 0x5BA6 0x5E7B 0x60A3 0x63DB 0x6B61 \ + 0x6665 0x6853 0x6E19 0x7165 0x74B0 0x7D08 0x9084 0x9A69 \ + 0x9C25 0x6D3B 0x6ED1 0x733E 0x8C41 0x95CA 0x51F0 0x5E4C \ + 0x5FA8 0x604D 0x60F6 0x6130 0x614C 0x6643 0x6644 0x69A5 \ + 0x6CC1 0x6E5F 0x6EC9 0x6F62 0x714C 0x749C 0x7687 0x7BC1 \ + 0x7C27 0x8352 0x8757 0x9051 0x968D 0x9EC3 0x532F 0x56DE \ + 0x5EFB 0x5F8A 0x6062 0x6094 0x61F7 0x6666 0x6703 0x6A9C \ + 0x6DEE 0x6FAE 0x7070 0x736A 0x7E6A 0x81BE 0x8334 0x86D4 \ + 0x8AA8 0x8CC4 0x5283 0x7372 0x5B96 0x6A6B 0x9404 0x54EE \ + 0x5686 0x5B5D 0x6548 0x6585 0x66C9 0x689F 0x6D8D 0x6DC6 \ + 0x723B 0x80B4 0x9175 0x9A4D 0x4FAF 0x5019 0x539A 0x540E \ + 0x543C 0x5589 0x55C5 0x5E3F 0x5F8C 0x673D 0x7166 0x73DD \ + 0x9005 0x52DB 0x52F3 0x5864 0x58CE 0x7104 0x718F 0x71FB \ + 0x85B0 0x8A13 0x6688 0x85A8 0x55A7 0x6684 0x714A 0x8431 \ + 0x5349 0x5599 0x6BC1 0x5F59 0x5FBD 0x63EE 0x6689 0x7147 \ + 0x8AF1 0x8F1D 0x9EBE 0x4F11 0x643A 0x70CB 0x7566 0x8667 \ + 0x6064 0x8B4E 0x9DF8 0x5147 0x51F6 0x5308 0x6D36 0x80F8 +35 0x9ED1 0x6615 0x6B23 0x7098 0x75D5 0x5403 0x5C79 0x7D07 \ + 0x8A16 0x6B20 0x6B3D 0x6B46 0x5438 0x6070 0x6D3D 0x7FD5 \ + 0x8208 0x50D6 0x51DE 0x559C 0x566B 0x56CD 0x59EC 0x5B09 \ + 0x5E0C 0x6199 0x6198 0x6231 0x665E 0x66E6 0x7199 0x71B9 \ + 0x71BA 0x72A7 0x79A7 0x7A00 0x7FB2 0x8A70 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE + +# eof diff --git a/contrib/ttf2pk/data/Unicode.sfd b/contrib/ttf2pk/data/Unicode.sfd new file mode 100644 index 0000000..fc23b6b --- /dev/null +++ b/contrib/ttf2pk/data/Unicode.sfd @@ -0,0 +1,265 @@ +# Unicode.sfd +# +# subfont numbers for Unicode encoding and its corresponding code ranges +# to be used with the CJK package for LaTeX. + +00 0x0_0xFF +01 0x100_0x1FF +02 0x200_0x2FF +03 0x300_0x3FF +04 0x400_0x4FF +05 0x500_0x5FF +06 0x600_0x6FF +07 0x700_0x7FF +08 0x800_0x8FF +09 0x900_0x9FF +0a 0xA00_0xAFF +0b 0xB00_0xBFF +0c 0xC00_0xCFF +0d 0xD00_0xDFF +0e 0xE00_0xEFF +0f 0xF00_0xFFF +10 0x1000_0x10FF +11 0x1100_0x11FF +12 0x1200_0x12FF +13 0x1300_0x13FF +14 0x1400_0x14FF +15 0x1500_0x15FF +16 0x1600_0x16FF +17 0x1700_0x17FF +18 0x1800_0x18FF +19 0x1900_0x19FF +1a 0x1A00_0x1AFF +1b 0x1B00_0x1BFF +1c 0x1C00_0x1CFF +1d 0x1D00_0x1DFF +1e 0x1E00_0x1EFF +1f 0x1F00_0x1FFF +20 0x2000_0x20FF +21 0x2100_0x21FF +22 0x2200_0x22FF +23 0x2300_0x23FF +24 0x2400_0x24FF +25 0x2500_0x25FF +26 0x2600_0x26FF +27 0x2700_0x27FF +28 0x2800_0x28FF +29 0x2900_0x29FF +2a 0x2A00_0x2AFF +2b 0x2B00_0x2BFF +2c 0x2C00_0x2CFF +2d 0x2D00_0x2DFF +2e 0x2E00_0x2EFF +2f 0x2F00_0x2FFF +30 0x3000_0x30FF +31 0x3100_0x31FF +32 0x3200_0x32FF +33 0x3300_0x33FF +34 0x3400_0x34FF +35 0x3500_0x35FF +36 0x3600_0x36FF +37 0x3700_0x37FF +38 0x3800_0x38FF +39 0x3900_0x39FF +3a 0x3A00_0x3AFF +3b 0x3B00_0x3BFF +3c 0x3C00_0x3CFF +3d 0x3D00_0x3DFF +3e 0x3E00_0x3EFF +3f 0x3F00_0x3FFF +40 0x4000_0x40FF +41 0x4100_0x41FF +42 0x4200_0x42FF +43 0x4300_0x43FF +44 0x4400_0x44FF +45 0x4500_0x45FF +46 0x4600_0x46FF +47 0x4700_0x47FF +48 0x4800_0x48FF +49 0x4900_0x49FF +4a 0x4A00_0x4AFF +4b 0x4B00_0x4BFF +4c 0x4C00_0x4CFF +4d 0x4D00_0x4DFF +4e 0x4E00_0x4EFF +4f 0x4F00_0x4FFF +50 0x5000_0x50FF +51 0x5100_0x51FF +52 0x5200_0x52FF +53 0x5300_0x53FF +54 0x5400_0x54FF +55 0x5500_0x55FF +56 0x5600_0x56FF +57 0x5700_0x57FF +58 0x5800_0x58FF +59 0x5900_0x59FF +5a 0x5A00_0x5AFF +5b 0x5B00_0x5BFF +5c 0x5C00_0x5CFF +5d 0x5D00_0x5DFF +5e 0x5E00_0x5EFF +5f 0x5F00_0x5FFF +60 0x6000_0x60FF +61 0x6100_0x61FF +62 0x6200_0x62FF +63 0x6300_0x63FF +64 0x6400_0x64FF +65 0x6500_0x65FF +66 0x6600_0x66FF +67 0x6700_0x67FF +68 0x6800_0x68FF +69 0x6900_0x69FF +6a 0x6A00_0x6AFF +6b 0x6B00_0x6BFF +6c 0x6C00_0x6CFF +6d 0x6D00_0x6DFF +6e 0x6E00_0x6EFF +6f 0x6F00_0x6FFF +70 0x7000_0x70FF +71 0x7100_0x71FF +72 0x7200_0x72FF +73 0x7300_0x73FF +74 0x7400_0x74FF +75 0x7500_0x75FF +76 0x7600_0x76FF +77 0x7700_0x77FF +78 0x7800_0x78FF +79 0x7900_0x79FF +7a 0x7A00_0x7AFF +7b 0x7B00_0x7BFF +7c 0x7C00_0x7CFF +7d 0x7D00_0x7DFF +7e 0x7E00_0x7EFF +7f 0x7F00_0x7FFF +80 0x8000_0x80FF +81 0x8100_0x81FF +82 0x8200_0x82FF +83 0x8300_0x83FF +84 0x8400_0x84FF +85 0x8500_0x85FF +86 0x8600_0x86FF +87 0x8700_0x87FF +88 0x8800_0x88FF +89 0x8900_0x89FF +8a 0x8A00_0x8AFF +8b 0x8B00_0x8BFF +8c 0x8C00_0x8CFF +8d 0x8D00_0x8DFF +8e 0x8E00_0x8EFF +8f 0x8F00_0x8FFF +90 0x9000_0x90FF +91 0x9100_0x91FF +92 0x9200_0x92FF +93 0x9300_0x93FF +94 0x9400_0x94FF +95 0x9500_0x95FF +96 0x9600_0x96FF +97 0x9700_0x97FF +98 0x9800_0x98FF +99 0x9900_0x99FF +9a 0x9A00_0x9AFF +9b 0x9B00_0x9BFF +9c 0x9C00_0x9CFF +9d 0x9D00_0x9DFF +9e 0x9E00_0x9EFF +9f 0x9F00_0x9FFF +a0 0xA000_0xA0FF +a1 0xA100_0xA1FF +a2 0xA200_0xA2FF +a3 0xA300_0xA3FF +a4 0xA400_0xA4FF +a5 0xA500_0xA5FF +a6 0xA600_0xA6FF +a7 0xA700_0xA7FF +a8 0xA800_0xA8FF +a9 0xA900_0xA9FF +aa 0xAA00_0xAAFF +ab 0xAB00_0xABFF +ac 0xAC00_0xACFF +ad 0xAD00_0xADFF +ae 0xAE00_0xAEFF +af 0xAF00_0xAFFF +b0 0xB000_0xB0FF +b1 0xB100_0xB1FF +b2 0xB200_0xB2FF +b3 0xB300_0xB3FF +b4 0xB400_0xB4FF +b5 0xB500_0xB5FF +b6 0xB600_0xB6FF +b7 0xB700_0xB7FF +b8 0xB800_0xB8FF +b9 0xB900_0xB9FF +ba 0xBA00_0xBAFF +bb 0xBB00_0xBBFF +bc 0xBC00_0xBCFF +bd 0xBD00_0xBDFF +be 0xBE00_0xBEFF +bf 0xBF00_0xBFFF +c0 0xC000_0xC0FF +c1 0xC100_0xC1FF +c2 0xC200_0xC2FF +c3 0xC300_0xC3FF +c4 0xC400_0xC4FF +c5 0xC500_0xC5FF +c6 0xC600_0xC6FF +c7 0xC700_0xC7FF +c8 0xC800_0xC8FF +c9 0xC900_0xC9FF +ca 0xCA00_0xCAFF +cb 0xCB00_0xCBFF +cc 0xCC00_0xCCFF +cd 0xCD00_0xCDFF +ce 0xCE00_0xCEFF +cf 0xCF00_0xCFFF +d0 0xD000_0xD0FF +d1 0xD100_0xD1FF +d2 0xD200_0xD2FF +d3 0xD300_0xD3FF +d4 0xD400_0xD4FF +d5 0xD500_0xD5FF +d6 0xD600_0xD6FF +d7 0xD700_0xD7FF +# Surrogates +# +# d8 0xD800_0xD8FF +# d9 0xD900_0xD9FF +# da 0xDA00_0xDAFF +# db 0xDB00_0xDBFF +dc 0xDC00_0xDCFF +dd 0xDD00_0xDDFF +de 0xDE00_0xDEFF +df 0xDF00_0xDFFF +e0 0xE000_0xE0FF +e1 0xE100_0xE1FF +e2 0xE200_0xE2FF +e3 0xE300_0xE3FF +e4 0xE400_0xE4FF +e5 0xE500_0xE5FF +e6 0xE600_0xE6FF +e7 0xE700_0xE7FF +e8 0xE800_0xE8FF +e9 0xE900_0xE9FF +ea 0xEA00_0xEAFF +eb 0xEB00_0xEBFF +ec 0xEC00_0xECFF +ed 0xED00_0xEDFF +ee 0xEE00_0xEEFF +ef 0xEF00_0xEFFF +f0 0xF000_0xF0FF +f1 0xF100_0xF1FF +f2 0xF200_0xF2FF +f3 0xF300_0xF3FF +f4 0xF400_0xF4FF +f5 0xF500_0xF5FF +f6 0xF600_0xF6FF +f7 0xF700_0xF7FF +f8 0xF800_0xF8FF +f9 0xF900_0xF9FF +fa 0xFA00_0xFAFF +fb 0xFB00_0xFBFF +fc 0xFC00_0xFCFF +fd 0xFD00_0xFDFF +fe 0xFE00_0xFEFF +ff 0xFF00_0xFFFF + +# eof diff --git a/contrib/ttf2pk/data/VPS.rpl b/contrib/ttf2pk/data/VPS.rpl new file mode 100644 index 0000000..cbd179f --- /dev/null +++ b/contrib/ttf2pk/data/VPS.rpl @@ -0,0 +1,244 @@ +% VPS.rpl +% +% +% This file maps VPS encoding for Vietnamese to Adobe glyph names used +% in the file ET5.enc. +% +% VPS is a commonly used program to write Vietnamese. +% +% This file has been tested with the font vpsdlac.ttf using cmap (3,0) + +.c0x0002 Adotbelow +.c0x0003 Acircumflexdotbelow +.c0x0004 Abrevedotbelow +.c0x0005 Edotbelow +.c0x0006 Ecircumflexdotbelow +.c0x0015 Uhorndotbelow +.c0x0019 Ydotbelow +.c0x001c Acircumflextilde +.c0x001d Uhorntilde +.c0x0020 space +.c0x0021 exclam +.c0x0022 quotedbl +.c0x0023 numbersign +.c0x0024 dollar +.c0x0025 percent +.c0x0026 ampersand +.c0x0027 quotesingle +.c0x0028 parenleft +.c0x0029 parenright +.c0x002a asterisk +.c0x002b plus +.c0x002c comma +.c0x002d hyphen +.c0x002e period +.c0x002f slash +.c0x0030 zero +.c0x0031 one +.c0x0032 two +.c0x0033 three +.c0x0034 four +.c0x0035 five +.c0x0036 six +.c0x0037 seven +.c0x0038 eight +.c0x0039 nine +.c0x003a colon +.c0x003b semicolon +.c0x003c less +.c0x003d equal +.c0x003e greater +.c0x003f question +.c0x0040 at +.c0x0041 A +.c0x0042 B +.c0x0043 C +.c0x0044 D +.c0x0045 E +.c0x0046 F +.c0x0047 G +.c0x0048 H +.c0x0049 I +.c0x004a J +.c0x004b K +.c0x004c L +.c0x004d M +.c0x004e N +.c0x004f O +.c0x0050 P +.c0x0051 Q +.c0x0052 R +.c0x0053 S +.c0x0054 T +.c0x0055 U +.c0x0056 V +.c0x0057 W +.c0x0058 X +.c0x0059 Y +.c0x005a Z +.c0x005b bracketleft +.c0x005c backslash +.c0x005d bracketright +.c0x005e asciicircum +.c0x005f underscore +.c0x0060 grave +.c0x0061 a +.c0x0062 b +.c0x0063 c +.c0x0064 d +.c0x0065 e +.c0x0066 f +.c0x0067 g +.c0x0068 h +.c0x0069 i +.c0x006a j +.c0x006b k +.c0x006c l +.c0x006d m +.c0x006e n +.c0x006f o +.c0x0070 p +.c0x0071 q +.c0x0072 r +.c0x0073 s +.c0x0074 t +.c0x0075 u +.c0x0076 v +.c0x0077 w +.c0x0078 x +.c0x0079 y +.c0x007a z +.c0x007b braceleft +.c0x007c bar +.c0x007d braceright +.c0x007e asciitilde +.c0x0080 Agrave +.c0x0081 Ahookabove +.c0x008d Abreveacute +.c0x008e Abrevegrave +.c0x008f Abrevehookabove +.c0x0090 Ecircumflexacute +.c0x009d Ohornacute +.c0x009e Ohorngrave +.c0x00a0 nbspace +.c0x00a1 abreveacute +.c0x00a2 abrevegrave +.c0x00a3 abrevehookabove +.c0x00a4 abrevetilde +.c0x00a5 abrevedotbelow +.c0x00a6 Ohorntilde +.c0x00a7 ohornacute +.c0x00a8 Ugrave +.c0x00a9 ohorngrave +.c0x00aa ohornhookabove +.c0x00ab ohorntilde +.c0x00ac Utilde +.c0x00ad Uhornacute +.c0x00ae ohorndotbelow +.c0x00af Uhorngrave +.c0x00b0 ocircumflexhookabove +.c0x00b1 Uhornhookabove +.c0x00b2 Ygrave +.c0x00b3 Ytilde +.c0x00b4 Iacute +.c0x00b5 Igrave +.c0x00b6 ocircumflexdotbelow +.c0x00b8 Itilde +.c0x00b9 Oacute +.c0x00ba uhornhookabove +.c0x00bb uhorntilde +.c0x00bc Ograve +.c0x00bd Ohookabove +.c0x00be Otilde +.c0x00bf uhorndotbelow +.c0x00c0 acircumflexgrave +.c0x00c1 Aacute +.c0x00c2 Acircumflex +.c0x00c3 acircumflexacute +.c0x00c4 acircumflexhookabove +.c0x00c5 acircumflextilde +.c0x00c6 acircumflexdotbelow +.c0x00c7 dbar +.c0x00c8 ehookabove +.c0x00c9 Eacute +.c0x00ca Ecircumflex +.c0x00cb edotbelow +.c0x00cc ihookabove +.c0x00cd ecircumflextilde +.c0x00ce idotbelow +.c0x00cf ytilde +.c0x00d0 Uhorn +.c0x00d1 Uhookabove +.c0x00d2 ocircumflexgrave +.c0x00d3 ocircumflexacute +.c0x00d4 Ocircumflex +.c0x00d5 ohookabove +.c0x00d6 ohorn +.c0x00d7 Egrave +.c0x00d8 uhorngrave +.c0x00d9 uhornacute +.c0x00da Uacute +.c0x00db utilde +.c0x00dc uhorn +.c0x00dd Yacute +.c0x00de Ehookabove +.c0x00df germandbls +.c0x00e0 agrave +.c0x00e1 aacute +.c0x00e2 acircumflex +.c0x00e3 atilde +.c0x00e4 ahookabove +.c0x00e5 adotbelow +.c0x00e6 abreve +.c0x00e7 ccedilla +.c0x00e8 egrave +.c0x00e9 eacute +.c0x00ea ecircumflex +.c0x00eb etilde +.c0x00ec igrave +.c0x00ed iacute +.c0x00ee icircumflex +.c0x00ef itilde +.c0x00f0 Abrevetilde +.c0x00f1 Dbar +.c0x00f2 ograve +.c0x00f3 oacute +.c0x00f4 ocircumflex +.c0x00f5 otilde +.c0x00f6 odieresis +.c0x00f7 Ohorn +.c0x00f8 udotbelow +.c0x00f9 ugrave +.c0x00fa uacute +.c0x00fb uhookabove +.c0x00fc udieresis +.c0x00fd Yhookabove +.c0x00fe Etilde +.c0x00ff ygrave +.c0x0152 ecircumflexdotbelow +.c0x0153 ydotbelow +.c0x0160 ecircumflexgrave +.c0x0161 yacute +.c0x0178 Ohornhookabove +.c0x0192 Acircumflexacute +.c0x02c6 Abreve +.c0x02dc Ocircumflexhookabove +.c0x2013 Ocircumflexacute +.c0x2014 Ocircumflexgrave +.c0x2018 quoteleft +.c0x2019 quoteright +.c0x201a Atilde +.c0x201c Ecircumflexgrave +.c0x201d Ecircumflexhookabove +.c0x201e Acircumflexgrave +.c0x2020 odotbelow +.c0x2021 ocircumflextilde +.c0x2022 Ecircumflextilde +.c0x2026 Acircumflexhookabove +.c0x2030 ecircumflexacute +.c0x2039 ecircumflexhookabove +.c0x203a yhookabove +.c0x2122 Ocircumflextilde +.c0x2219 Ihookabove + +% eof diff --git a/contrib/ttf2pk/data/ttfonts.map b/contrib/ttf2pk/data/ttfonts.map new file mode 100644 index 0000000..55a7a03 --- /dev/null +++ b/contrib/ttf2pk/data/ttfonts.map @@ -0,0 +1,18 @@ +% These entries are just examples! + +arials arial.ttf Slant=0.25 +arial arial.ttf Slant=0 Extend=1 Pid = 1 Eid = 0 +arialx arial.ttf Slant=0 Extend=1.5 + +times times.ttf Encoding=T1-WGL4.enc \ + .g0xc7=ring .g0xc9=caron .g0xc4=dotlessi +times95 times95.ttf Encoding=T1-WGL4.enc + +ntukai@Big5@ ntu_kai.ttf Pid = 3 Eid = 4 +cyberb@Unicode@ cyberbit.ttf + +% the next entry maps the Unicode encoded font to Big 5 encoding; thus you +% can say \begin{CJK}{Big5}{...} (this is an environment from the CJK +% package for LaTeX). + +mingli@UBig5@ mingliu.ttc Fontindex = 0 diff --git a/contrib/ttf2pk/dvidrv.btm b/contrib/ttf2pk/dvidrv.btm new file mode 100644 index 0000000..aee27a3 --- /dev/null +++ b/contrib/ttf2pk/dvidrv.btm @@ -0,0 +1,334 @@ +:: +:: This is dvidrv.btm, a batch file for 4DOS/4OS2 written by +:: Werner Lemberg partially based on the +:: dvidrv.btm file of the 4allTeX package written by Phons Bloemen. +:: +:: It is a replacement for dvidrv.exe of the emTeX package. +:: +:: Additional features: support of ps2pk +:: support of ttf2pk +:: support of hbf2gf for HBFs (Hanzi bitmap fonts) +:: +:: Only quadratic printer modes are supported for ttf2pk! +:: +:: All needed binaries will be searched in the path. + +iff %# lt 2 then + echo `` + echo Usage: %0 dvi-driver dvi-file [parameters] + quit +endiff + +setlocal + :: we set a default value only if the corresponding environment variable + :: is empty. The `=' must follow the variable name immediately. + alias set_def `iff "%[%@word["=",0,%1]]" eq "" then %+ set %& %+ endiff` + + :: ========================================= + :: ======== User defined variables. ======== + :: ========================================= + :: + :: Can be overridden in the environment (except %ps2pk, %ttf2pk, %hbf2gf, + :: %pre_dpi, and %post_dpi). + + :: Set these values to `no' for the programs you don't want to use. + set ps2pk=yes + set ttf2pk=yes + set hbf2gf=yes + + :: where the PK files will be installed created by ps2pk, ttf2pk, and + :: hbf2gf. + :: dvidrv.btm adds `\modeless\XXXdpi' to this string (see below for the + :: exact string). + set_def pkdir=%emtexdir\pixel\tmp\pk + + :: where the TrueType fonts reside. Supports trailing `!' and `!!'. + set_def ttfonts=%emtexdir\fonts\truetype + :: where auxiliary files of ttf2pk are located. Supports trailing `!' + :: and `!!'. + set_def ttfcfg=%emtexdir\ttf2pk + + :: where the HBF files reside. Supports trailing `!' and `!!'. + set_def hbfonts=%emtexdir\fonts\hbf + :: where the hbf2gf config files are. Supports trailing `!' and `!!'. + set_def hbfcfg=%emtexdir\hbf2gf + + :: the dpi-subdirectory has various forms; the most common are XXXdpi and + :: dpiXXX, e.g. 300dpi and dpi300. Here we define two variables which + :: control this behaviour. + :: [dpiXXX is used for TDS compatible TeX trees.] + set pre_dpi=dpi + set post_dpi= + + :: ================================================ + :: ======== End of user defined variables. ======== + :: ================================================ + + :: the base name for log files etc. + set basename=%@name[%1] + + :: do we run dvips? + iff "%basename" ne "dvips" then + goto nodvips1 + endiff + + :: we delete dvips.mfj if it exists. + del dvips.mfj >& nul + + :: now we run dvips with all supplied parameters. + %& + + :: do we have to generate fonts? + iff exist dvips.mfj then + goto generate_fonts + endiff + + :: else all is done. + goto end + + +:nodvips1 + :: here we call the dvi driver with all supplied parameters. + %& -pj:%basename.mfj + + :: do we have to generate fonts? + iff errorlevel 8 then + goto generate_fonts + endiff + + :: else all is done. + goto end + + +:generate_fonts + gosub call_mfjob + + :: do we run dvips? + iff "%basename" ne "dvips" then + goto nodvips2 + endiff + + :: we now call dvips a second time + %& + + :: since no fonts will be generated in the second run we remove dvips.mfj + del dvips.mfj >& nul + + goto end + + +:nodvips2 + :: we call the dvi driver a second time (without font generation). + %& -pj -fm + + del %basename.mfj >& nul + + goto end + + +:: this is the main subroutine which calls mfjob and then parses the mfjob +:: file for fonts which can be handled by ps2pk, ttf2pk, or hbf2gf. +:call_mfjob + :: this alias prints a message on the screen and writes it into the logfile. + alias echolog=`echo %& | tee /a %basename.mlg` + + echo ======== DVIDRV.BTM logfile ======== > %basename.mlg + echo Commandline: dvidrv.btm %& >> %basename.mlg + echo `` >> %basename.mlg + echo basename=%basename >> %basename.mlg + echo emtexdir=%emtexdir >> %basename.mlg + echo dvidrvfonts=%dvidrvfonts >> %basename.mlg + echo mfinput=%mfinput >> %basename.mlg + echo mfjobopt=%mfjobopt >> %basename.mlg + echo textfm=%textfm >> %basename.mlg + echo psfonts=%psfonts >> %basename.mlg + echo ttfonts=%ttfonts >> %basename.mlg + echo ttfcfg=%ttfcfg >> %basename.mlg + echo hbfonts=%hbfonts >> %basename.mlg + echo hbfcfg=%hbfcfg >> %basename.mlg + echo `` >> %basename.mlg + + iff "%@search[mfjob]" eq "" then + echolog MFJOB not found in the path. + echolog Can't generate PK fonts from METAFONT automatically. + echo `` + quit + endiff + + :: now we call mfjob. + echolog mfjob %mfjobopt -g%basename.mfl %basename.mfj + mfjob %mfjobopt -g%basename.mfl %basename.mfj + iff %? gt 0 then + echolog `` + echolog Something went wrong while running METAFONT. + echolog Look into the log files... + echolog `` + endiff + + :: after running mfjob we scan the mfjob input file for fonts which can + :: be handled by ps2pk, ttf2pk, or hbf2gf. + set lnnr=0 + set totlines=%@lines[%basename.mfj] + + do while %lnnr le %totlines + :: input a line. + set scratch=%@line[%basename.mfj,%lnnr] + set lnnr=%@inc[%lnnr] + + :: get resolutions (METAFONT mode will be ignored). + :: example: + :: mode=lqlores[180 180]; + iff %@index[%scratch,mode] ge 0 then + set temp=%@word["[]",1,%scratch] + set xdpi=%@word[0,%temp] + set ydpi=%@word[1,%temp] + endiff + + :: get fontname and magnification; we then compute the font resolutions + :: (rounded to the nearest integer---there is no necessity to adjust + :: these values further because of possible rounding errors since both + :: emTeX's dvi drivers and dvips check neighbored values too). + :: example: + :: {font=cmr10; mag=0.5;} + iff %@index[%scratch,{font] ge 0 then + set testfont=%@word["=;",1,%scratch] + set temp=%@word["=;",3,%scratch] + :: we use highest arithmetic precision for these calculations. + :: Additionally we write 1/2 instead of 0.5 to avoid problems with + :: countries which use a comma instead of a colon as the decimal + :: separator. + set fontresx=%@int[%@eval[%xdpi*%temp+1/2=8]] + set fontresy=%@int[%@eval[%ydpi*%temp+1/2=8]] + set pksubdir=modeless\%[pre_dpi]%[fontresx]%post_dpi + + set success=0 + + :: check whether %testfont leads to a PS font (we call ps2pkmfj). + iff %success == 0 .and. "%ps2pk" eq "yes" then + gosub call_ps2pk + endiff + + :: check whether %testfont leads to a TrueType font. + iff %success == 0 .and. "%ttf2pk" eq "yes" then + gosub call_ttf2pk + endiff + + :: check whether %testfont leads to a HBF file. + iff %success == 0 .and. "%hbf2gf" eq "yes" then + gosub call_hbf2gf + endiff + endiff + enddo + + iff exist %basename.mfp then + echo `` >> %basename.mlg + echo `` >> %basename.mlg + echo ======== PS2PK logfile ======== >> %basename.mlg + echo `` >> %basename.mlg + type %basename.mfp >> %basename.mlg + echo `` >> %basename.mlg + del %basename.mfp >& nul + endiff + + iff exist %basename.mfl then + echo `` >> %basename.mlg + type %basename.mfl >> %basename.mlg + echo `` >> %basename.mlg + del %basename.mfl >& nul + endiff + + return + + +:call_ttf2pk + iff "%@search[ttf2pk]" eq "" then + echolog TTF2PK not found in the path. + echolog Can't generate PK fonts from TrueType fonts automatically. + echo `` + quit + endiff + + echolog ttf2pk -q -n %testfont %fontresx + ttf2pk -q -n %testfont %fontresx + + iff %? == 0 then + echolog Font %pkdir\%pksubdir\%testfont.pk generated. + mkdir /s %pkdir\%pksubdir >& nul + move %testfont.pk %pkdir\%pksubdir >& nul + set success=1 + elseiff %? == 2 then + echolog (%lnnr/%totlines): Font %testfont is no TrueType font. + set success=0 + else + echolog Error running TTF2PK for font %testfont! + endiff + + return + + +:call_hbf2gf + iff "%@search[hbf2gf]" eq "" then + echolog HBF2GF not found in the path. + echolog Can't generate PK fonts from HBF files automatically. + echo `` + quit + endiff + + echolog hbf2gf -q -p -n %testfont %fontresx %fontresy + hbf2gf -q -p -n %testfont %fontresx %fontresy + + iff %? == 0 then + echolog Font %pkdir\%pksubdir\%testfont.pk generated. + mkdir /s %pkdir\%pksubdir >& nul + gftopk %testfont.gf %testfont.pk + move %testfont.pk %pkdir\%pksubdir >& nul + del %testfont.gf >& nul + set success=1 + elseiff %? == 2 then + echolog (%lnnr/%totlines): Font %testfont is no HBF. + set success=0 + else + echolog Error running HBF2GF for font %testfont! + endiff + + return + + +:call_ps2pk + iff not exist %pkdir\%pksubdir\%testfont.pk then + iff "%@search[ps2pkmfj]" eq "" .or. "%@search[ps2pk]" eq "" then + echolog PS2PKMFJ and/or PS2PK not found in the path. + echolog Can't generate PK fonts from PostScript fonts automatically. + echo `` + quit + endiff + + echolog ps2pkmfj -X%fontresx -Y%fontresy %testfont %testfont.pk + ps2pkmfj -X%fontresx -Y%fontresy %testfont %testfont.pk | input %%pspkline + + iff errorlevel != 1 then + %pspkline >> %basename.mfp + iff %? == 0 then + echolog Font %pkdir\%pksubdir\%testfont.pk generated. + mkdir /s %pkdir\%pksubdir >& nul + move %testfont.pk %pkdir\%pksubdir >& nul + success=1 + else + echolog Error running PS2PK for font %testfont! + endiff + else + echolog (%lnnr/%totlines): Font %testfont is no PS font. + success=0 + endiff + else + echolog Font %pkdir\%pksubdir\%testfont.pk already exists. + endiff + + return + + +:end + +endlocal + +:: ==== end of dvidrv.btm ==== diff --git a/contrib/ttf2pk/dvidrv.doc b/contrib/ttf2pk/dvidrv.doc new file mode 100644 index 0000000..f1ecc5b --- /dev/null +++ b/contrib/ttf2pk/dvidrv.doc @@ -0,0 +1,56 @@ +Using dvidrv.btm [emTeX for DOS and OS/2] +------------------------------------------- + +This batch file does the same as MakeTeXPK does; it is a replacement for +dvidrv.exe of emTeX which can handle ttf2pk, hbf2gf, and ps2pk additionally +(the ps2pk part is untested yet; it uses ps2pkmfj of the 4allTeX +distribution and was basically copied from a similar script, also part of +4allTeX). + +First of all, create and install a set of TFM files as described in the +previous section. + +Then configure the following variables in dvidrv.btm: + + ps2pk ... set it to `yes' if you want to use this program + ttf2pk ... ditto + hbf2gf ... ditto + + pkdir ... the place where PK files created by ps2pk, ttf2pk, + or hbf2gf should go to. dvidrv.btm adds + `\modeless\XXXdpi' resp. `\modeless\dpiXXX' to this + string (depending on the variables `pre_dpi' and + `post_dpi') + + ttfonts ... where the TrueType fonts files reside + ttfcfg ... where the auxiliary data files of ttf2pk reside + + hbfonts ... where the HBF files reside + hbfcfg ... the place where the hbf2gf configuration files are + +The last four variables in the above list support trailing `!' and `!!' for +recursive directory searching (see the dvidrv.doc of the emTeX package for +details). + +Alternatively, you can set these variables in the environment; please note +that no spaces are allowed before and after the equal sign, e.g. + + set foo=bar + +is OK, but + + set foo = bar + +will fail. + +Rename dvidrv.exe to dvidrv.ori or something similar and copy dvidrv.btm to +a directory in the path. + +Don't forget to update the DVIDRVFONTS and TEXTFM environment variables if +necessary. + +Under OS/2 dvips will call mfjob or hbf2gf itself; under DOS it will create +a batch file which must be called afterwards. + + +--- end of dvidrv.doc --- diff --git a/contrib/ttf2pk/emdir.c b/contrib/ttf2pk/emdir.c new file mode 100644 index 0000000..4e759c8 --- /dev/null +++ b/contrib/ttf2pk/emdir.c @@ -0,0 +1,109 @@ +/* emdir.c -- Written by Eberhard Mattes, donated to the public domain */ + +#include "emdir.h" + +#ifdef OS2 + +#undef HPS +#define INCL_DOSFILEMGR +#include +#include + +#define FHDIR(b) (*(HDIR *)(b)->reserved) + +static void fconv (struct ll_findbuffer *dst, const FILEFINDBUF *src) +{ + dst->attr = src->attrFile; + dst->time = *(unsigned *)&src->ftimeLastWrite; + dst->date = *(unsigned *)&src->fdateLastWrite; + dst->size = src->cbFile; + strcpy (dst->name, src->achName); +} + + +int ll_findfirst (const char *path, int attr, struct ll_findbuffer *buffer) +{ + USHORT rc; + ULONG count; + HDIR hdir; + FILEFINDBUF ffbuf; + + hdir = HDIR_CREATE; + count = 1; + rc = DosFindFirst ((PSZ)path, &hdir, attr, &ffbuf, sizeof (ffbuf), + &count, 0L); + if (rc != 0 || count != 1) + return 0; + FHDIR (buffer) = hdir; + fconv (buffer, &ffbuf); + return 1; +} + + +int ll_findnext (struct ll_findbuffer *buffer) +{ + USHORT rc; + ULONG count; + HDIR hdir; + FILEFINDBUF ffbuf; + + hdir = FHDIR (buffer); + count = 1; + rc = DosFindNext (hdir, &ffbuf, sizeof (ffbuf), &count); + if (rc != 0 || count != 1) + { + DosFindClose (hdir); + return 0; + } + fconv (buffer, &ffbuf); + return 1; +} + + +#elif defined(DJGPP) + +/* djgpp support by Hartmut Schirmer (hsc@techfak.uni-kiel.de), May 30, 1997 */ + +#include +#include + +static int ll_attr = 0; +int ll_findnext (struct ll_findbuffer *buffer) +{ + int res; + do { + res = _dos_findnext ((struct find_t *)buffer); + if (res != 0) return 0; + } while ( (buffer->attrib&ll_attr) == 0); + return 1; +} + +int ll_findfirst (const char *path, int attr, struct ll_findbuffer *buffer) +{ + int res; + ll_attr = attr; + res = _dos_findfirst((char *)path, attr, (struct find_t *)buffer); + if (res != 0) return 0; + if ( (buffer->attrib&ll_attr) == 0) + return ll_findnext(buffer); + return 1; +} + +#elif !defined(__EMX__) /* if not OS2 nor DJGPP nor __EMX__ defined */ + +/* Not tested */ + +#include + +int ll_findfirst (const char *path, int attr, struct ll_findbuffer *buffer) +{ + return _dos_findfirst (path, attr, (struct find_t *)buffer) == 0; +} + + +int ll_findnext (struct ll_findbuffer *buffer) +{ + return _dos_findnext ((struct find_t *)buffer) == 0; +} + +#endif diff --git a/contrib/ttf2pk/emdir.h b/contrib/ttf2pk/emdir.h new file mode 100644 index 0000000..0606d47 --- /dev/null +++ b/contrib/ttf2pk/emdir.h @@ -0,0 +1,25 @@ +/* emdir.h -- Written by Eberhard Mattes, donated to the public domain */ + +#if defined(DJGPP) + +/* djgpp support by Hartmut Schirmer (hsc@techfak.uni-kiel.de), May 30, 1997 */ +#include +#define ll_findbuffer find_t +#define attr attrib + +#else + +struct ll_findbuffer +{ + char reserved[21]; + unsigned char attr; + unsigned time; + unsigned date; + long size; + char name[257]; +}; + +#endif + +int ll_findfirst (const char *path, int attr, struct ll_findbuffer *buffer); +int ll_findnext (struct ll_findbuffer *buffer); diff --git a/contrib/ttf2pk/emtexdir.c b/contrib/ttf2pk/emtexdir.c new file mode 100644 index 0000000..9a35570 --- /dev/null +++ b/contrib/ttf2pk/emtexdir.c @@ -0,0 +1,405 @@ +/* emtexdir.c -- written by Eberhard Mattes, donated to the public domain */ + +#if defined (__EMX__) +#include +#else +#include "emdir.h" +#endif +#if defined(DJGPP) || defined(GO32) +#include +#endif +#include +#include +#include +#include +#include "emtexdir.h" + +#define FALSE 0 +#define TRUE 1 + +void (*emtex_dir_find_callback)(const char *name, int ok) = NULL; + +static int setup_add (struct emtex_dir *dst, const char *path) +{ + char *p; + + if (dst->used >= dst->alloc) + { + dst->alloc += 8; + dst->list = realloc (dst->list, dst->alloc * sizeof (*dst->list)); + if (dst->list == NULL) + return (FALSE); + } + p = strdup (path); + if (p == NULL) + return (FALSE); + dst->list[dst->used++] = p; + return (TRUE); +} + + +static int setup_subdir (struct emtex_dir *dst, char *path, size_t add, + unsigned flags, int recurse) +{ + int ok, i, end, len; +#if defined (__EMX__) + struct _find find; +#else + struct ll_findbuffer find; +#endif + + i = dst->used; + strcpy (path + add, "*.*"); +#if defined (__EMX__) + ok = __findfirst (path, 0x10, &find) == 0; +#else + ok = ll_findfirst (path, 0x10, &find); +#endif + while (ok) + { + if ((find.attr & 0x10) + && !(strcmp (find.name, ".") == 0 || strcmp (find.name, "..") == 0)) + { + len = strlen (find.name); + memcpy (path + add, find.name, len); + path[add+len] = '\\'; + path[add+len+1] = 0; + if (!setup_add (dst, path)) + return (FALSE); + } +#if defined (__EMX__) + ok = __findnext (&find) == 0; +#else + ok = ll_findnext (&find); +#endif + } + if (recurse) + { + end = dst->used; + while (i < end) + { + strcpy (path, dst->list[i]); + if (!setup_subdir (dst, path, strlen (path), flags, TRUE)) + return (FALSE); + ++i; + } + } + return (TRUE); +} + + +static int setup_dir (struct emtex_dir *dst, char *path, + const char *base_dir, size_t base_dir_len, + const char *sub_dir, + unsigned flags) +{ + size_t i, len; + + memcpy (path, base_dir, base_dir_len); + i = base_dir_len; + if ((flags & EDS_BANG) && sub_dir == NULL) + { + flags &= ~(EDS_ONESUBDIR|EDS_ALLSUBDIR); + if (i >= 2 && path[i-1] == '!' && path[i-2] == '!') + { + flags |= EDS_ALLSUBDIR; + i -= 2; + } + else if (i >= 1 && path[i-1] == '!') + { + flags |= EDS_ONESUBDIR; + --i; + } + } + if (sub_dir != NULL && *sub_dir != 0) + { + if (i != 0 && path[i-1] != ':' && path[i-1] != '/' && path[i-1] != '\\') + path[i++] = '\\'; + len = strlen (sub_dir); + memcpy (path+i, sub_dir, len); + i += len; + } + if (path[i-1] != ':' && path[i-1] != '/' && path[i-1] != '\\') + path[i++] = '\\'; + path[i] = 0; + if (!setup_add (dst, path)) + return (FALSE); + if (flags & EDS_ALLSUBDIR) + return (setup_subdir (dst, path, i, flags, TRUE)); + else if (flags & EDS_ONESUBDIR) + return (setup_subdir (dst, path, i, flags, FALSE)); + else + return (TRUE); +} + + +/*static */int setup_list (struct emtex_dir *dst, char *path, + const char *list, unsigned flags) +{ + const char *end; + size_t i; + + for (;;) + { + while (*list == ' ' || *list == '\t') + ++list; + if (*list == 0) + return (TRUE); + end = list; + while (*end != 0 && *end != ';') + ++end; + i = end - list; + while (i > 0 && (list[i-1] == ' ' || list[i-1] == '\t')) + --i; + if (i != 0 && !setup_dir (dst, path, list, i, NULL, flags)) + return (FALSE); + if (*end == 0) + return (TRUE); + list = end + 1; + } +} + + +int emtex_dir_setup (struct emtex_dir *ed, const char *env, const char *dir, + unsigned flags) +{ + const char *val; + char path[260]; + + ed->alloc = 0; + ed->used = 0; + ed->list = NULL; + if (env != NULL && (val = getenv (env)) != NULL) + return (setup_list (ed, path, val, flags)); + else if ((val = getenv ("EMTEXDIR")) != NULL) + return (setup_dir (ed, path, val, strlen (val), dir, flags)); + else + return (setup_dir (ed, path, "\\emtex", 6, dir, flags)); +} + + +static void pretty (char *path, unsigned flags) +{ + char *p; + + if (flags & EDF_FSLASH) + for (p = path; *p != 0; ++p) + if (*p == '\\') + *p = '/'; +} + + +#define ADDCHAR(C) \ + if (dst_size < 1) return (EDT_TOOLONG); \ + *dst++ = (C); --dst_size + +int emtex_dir_trunc (char *dst, size_t dst_size, const char *src, + unsigned flags, int method) +{ + int len, truncated, dot; + + if (src[0] != 0 && src[1] == ':') + { + ADDCHAR (src[0]); + ADDCHAR (src[1]); + src += 2; + } + + truncated = FALSE; dot = FALSE; len = 0; + for (;;) + { + switch (*src) + { + case 0: + ADDCHAR (0); + return (truncated ? EDT_CHANGED : EDT_UNCHANGED); + + case ':': + return (EDT_INVALID); + + case '/': + case '\\': + ADDCHAR (*src); + len = 0; dot = FALSE; + break; + + case '.': + if (dot) + return (EDT_INVALID); + ADDCHAR (*src); + + /* ".." is allowed -- don't return EDT_INVALID for the next + dot. */ + + if (!(len == 0 && src[1] == '.' + && (src[2] == 0 || src[2] == '/' || src[2] == '\\'))) + { + len = 0; dot = TRUE; + } + break; + + default: + if (dot && len == 3) + truncated = TRUE; + else if (!dot && len == 8) + { + truncated = TRUE; + if (method == 0) + { + dst[-3] = dst[-2]; + dst[-2] = dst[-1]; + dst[-1] = *src; + } + } + else + { + ADDCHAR (*src); + ++len; + } + break; + } + ++src; + } +} + + +static int find2 (const char *name, unsigned flags) +{ + int ok; + + ok = (access (name, 4) == 0); + if (flags & EDF_TRACE) + emtex_dir_find_callback (name, ok); + return (ok); +} + + +static int find1 (char *path, size_t path_size, const char *dir, + const char *fname, unsigned flags) +{ + char buf[260]; + int method, rc; + size_t len, tmp; + + len = 0; + if (dir != NULL) + { + tmp = strlen (dir); + if (tmp >= sizeof (buf)) + return (FALSE); + memcpy (buf, dir, tmp); + len = tmp; + } + tmp = strlen (fname); + if (len + tmp >= sizeof (buf)) + return (FALSE); + memcpy (buf + len, fname, tmp + 1); + len += tmp; +#if 0 /* wkim */ +/* disabled for Win95's long file name support */ +/* -- Wonkoo Kim (wkim+@pitt.edu), May 18, 1997 */ + if (_osmode == DOS_MODE) + { + rc = emtex_dir_trunc (path, path_size, buf, flags, EDT_5_PLUS_3); + if ((rc == EDT_UNCHANGED || rc == EDT_CHANGED) && find2 (path, flags)) + { + pretty (path, flags); + return (TRUE); + } + rc = emtex_dir_trunc (path, path_size, buf, flags, EDT_8); + if (rc == EDT_CHANGED && find2 (path, flags)) + { + pretty (path, flags); + return (TRUE); + } + return (FALSE); + } + else +#endif /* wkim */ + { + if (len < path_size && find2 (buf, flags)) + { + memcpy (path, buf, len + 1); + pretty (path, flags); + return (TRUE); + } + for (method = 0; method < 2; ++method) + { + rc = emtex_dir_trunc (path, path_size, buf, flags, method); + if (rc == EDT_CHANGED && find2 (path, flags)) + { + pretty (path, flags); + return (TRUE); + } + } + return (FALSE); + } +} + + +int emtex_dir_find (char *path, size_t path_size, + const struct emtex_dir *ed, + const char *fname, unsigned flags) +{ + int i, absp; + const char *p; + + absp = FALSE; + for (p = fname; *p != 0; ++p) + if (*p == ':' || *p == '/' || *p == '\\') + { + absp = TRUE; + break; + } + + if (absp) + return (find1 (path, path_size, NULL, fname, flags)); + + if ((flags & EDF_CWD) && find1 (path, path_size, NULL, fname, flags)) + return (TRUE); + + for (i = 0; i < ed->used; ++i) + if (find1 (path, path_size, ed->list[i], fname, flags)) + return (TRUE); + return (FALSE); +} + + +#if defined (TEST) + +#include + +int main (int argc, char *argv[]) +{ + struct emtex_dir ed; + int i; + unsigned flags1, flags2; + char path[260]; + + if (argc != 6) + { + puts ("Usage: emtexdir "); + return (1); + } + + flags1 = (unsigned)strtol (argv[1], NULL, 0); + flags2 = (unsigned)strtol (argv[2], NULL, 0); + + if (!emtex_dir_setup (&ed, argv[3], argv[4], flags1)) + { + fputs ("emtex_dir_setup failed\n", stderr); + return (2); + } + + printf ("Directories:\n"); + for (i = 0; i < ed.used; ++i) + printf (" %s\n", ed.list[i]); + + if (!emtex_dir_find (path, sizeof (path), &ed, argv[5], flags2)) + puts ("File not found"); + else + printf ("Path: %s\n", path); + return (0); +} + +#endif diff --git a/contrib/ttf2pk/emtexdir.h b/contrib/ttf2pk/emtexdir.h new file mode 100644 index 0000000..a9a986d --- /dev/null +++ b/contrib/ttf2pk/emtexdir.h @@ -0,0 +1,57 @@ +/* emtexdir.h -- written by Eberhard Mattes, donated to the public domain */ + +#if !defined (_EMTEXDIR_H) +#define _EMTEXDIR_H + +#if defined (__cplusplus) +extern "C" { +#endif + + +/* Flags for emtex_dir_setup */ + +#define EDS_ONESUBDIR 0x0001 +#define EDS_ALLSUBDIR 0x0002 +#define EDS_BANG 0x0004 + +/* Flags for emtex_dir_find */ + +#define EDF_CWD 0x0001 +#define EDF_FSLASH 0x0002 +#define EDF_TRACE 0x8000 + +/* Methods for emtex_dir_trunc */ + +#define EDT_5_PLUS_3 0 /* 5+3.3 */ +#define EDT_8 1 /* 8.3 */ + +/* Return values for emtex_dir_trunc */ + +#define EDT_UNCHANGED 0 /* Path name not changed */ +#define EDT_CHANGED 1 /* Path name truncated */ +#define EDT_TOOLONG 2 /* Path name too long */ +#define EDT_INVALID 3 /* Path name invalid */ + +struct emtex_dir +{ + char **list; + int used; + int alloc; +}; + +extern void (*emtex_dir_find_callback)(const char *name, int ok); + +int emtex_dir_setup (struct emtex_dir *ed, const char *env, const char *dir, + unsigned flags); + +int emtex_dir_find (char *path, size_t path_size, const struct emtex_dir *ed, + const char *fname, unsigned flags); + +int emtex_dir_trunc (char *dst, size_t dst_size, const char *src, + unsigned flags, int method); + +#if defined (__cplusplus) +} +#endif + +#endif /* !defined (_EMTEXDIR_H) */ diff --git a/contrib/ttf2pk/errormsg.c b/contrib/ttf2pk/errormsg.c new file mode 100644 index 0000000..3969b12 --- /dev/null +++ b/contrib/ttf2pk/errormsg.c @@ -0,0 +1,96 @@ +/* + * errormsg.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#include +#include /* for size_t */ +#include +#include + +#include "errormsg.h" + + +extern char progname[]; /* the origin of the error/warning message */ + + +/* + * Print error message and quit. + */ + +void +oops(const char *message, + ...) +{ + va_list args; + + + va_start(args, message); + fprintf(stderr, "%s: ERROR: ", progname); + vfprintf(stderr, message, args); + va_end(args); + putc('\n', stderr); + + exit(1); +} + + +/* + * Print error message, a buffer, a '^' at the buffer offset, and quit. + */ + +void +boops(const char *buffer, + size_t offset, + const char *message, + ...) +{ + va_list args; + + + va_start(args, message); + fprintf(stderr, "%s: ERROR: ", progname); + vfprintf(stderr, message, args); + va_end(args); + putc('\n', stderr); + + if (*buffer) + { + fprintf(stderr, "%s\n", buffer); + while (offset) + { + fprintf(stderr, " "); + offset--; + } + fprintf(stderr, "^\n"); + } + + exit(1); +} + + +/* + * Print warning message and continue. + */ + +void +warning(const char *message, + ...) +{ + va_list args; + + + va_start(args, message); + fprintf(stderr, "%s: WARNING: ", progname); + vfprintf(stderr, message, args); + va_end(args); + putc('\n', stderr); +} + + +/* end */ diff --git a/contrib/ttf2pk/errormsg.h b/contrib/ttf2pk/errormsg.h new file mode 100644 index 0000000..d069753 --- /dev/null +++ b/contrib/ttf2pk/errormsg.h @@ -0,0 +1,43 @@ +/* + * errormsg.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef ERRORMSG_H +#define ERRORMSG_H + + +/* + Disable some annoying warnings when you compile with -W3. Namely the + warnings about missing __cdecl specifiers at some places where they are + not really needed because the compiler can generate them. + + This is relevant only if you compile with -Gr option, i.e., use fastcall + calling convention. + + This is needed for fpTeX. + */ + +#ifdef WIN32 +#pragma warning (disable : 4007 4096) +#endif + + +void oops(const char *message, + ...); +void boops(const char *buffer, + size_t offset, + const char *message, + ...); +void warning(const char *message, + ...); + +#endif /* ERRORMSG_H */ + + +/* end */ diff --git a/contrib/ttf2pk/filesrch.c b/contrib/ttf2pk/filesrch.c new file mode 100644 index 0000000..0b1761f --- /dev/null +++ b/contrib/ttf2pk/filesrch.c @@ -0,0 +1,602 @@ +/* + * filesrch.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +/* + * Interface to the system specific TeX file search routines. + */ + +#include /* for size_t */ +#include +#include + +#include "filesrch.h" +#include "newobj.h" + + +/**************************** + * kpathsea library support * + ****************************/ + +#if defined(HAVE_LIBKPATHSEA) + +#ifdef VERY_OLD_KPATHSEA +#include "kpathsea/proginit.h" +#include "kpathsea/progname.h" +#include "kpathsea/tex-glyph.h" +#else +#include "kpathsea/kpathsea.h" +#endif + +#ifdef KPSEDLL +/* this is kpathsea 3.3 and newer */ +extern KPSEDLL char *kpathsea_version_string; +#else +extern DllImport char *kpathsea_version_string; +#endif + +/* + * Initialize kpathsea library; arguments are the full name of the + * executable (e.g. `/usr/bin/ttf2pk') and two identification strings; + * the former for the program itself (to have texmf.cnf constructs like + * `TFMFONTS.ttf2pk'), the latter for the environment (to have environment + * constructs like `TTF2PKMAKEPK'). + */ + +void +TeX_search_init(char *exec_name, + char *program_identifier, + char *env_identifier) +{ +#ifdef OLD_KPATHSEA + kpse_set_progname(exec_name); +#else + kpse_set_program_name(exec_name, program_identifier); +#endif + +#ifdef VERY_OLD_KPATHSEA + kpse_init_prog(env_identifier, 300, "cx", true, "cmr10"); +#else + kpse_init_prog(env_identifier, 300, "cx", "cmr10"); +#endif +} + + +char * +TeX_search_version(void) +{ + return kpathsea_version_string; +} + + +char * +TeX_search_tfm(char **name) +{ + /* no extra extension handling necessary */ + + return kpse_find_file(*name, kpse_tfm_format, True); +} + + +char * +TeX_search_encoding_file(char **name) +{ + handle_extension(name, ".enc"); + +#ifdef OLD_KPATHSEA +#ifdef VERY_OLD_KPATHSEA + return kpse_find_file(*name, kpse_dvips_header_format, True); +#else + return kpse_find_file(*name, kpse_tex_ps_header_format, True); +#endif +#else + return kpse_find_file(*name, kpse_program_text_format, True); +#endif +} + + +char * +TeX_search_replacement_file(char **name) +{ + handle_extension(name, ".rpl"); + +#ifdef OLD_KPATHSEA +#ifdef VERY_OLD_KPATHSEA + return kpse_find_file(*name, kpse_dvips_header_format, True); +#else + return kpse_find_file(*name, kpse_tex_ps_header_format, True); +#endif +#else + return kpse_find_file(*name, kpse_program_text_format, True); +#endif +} + + +char * +TeX_search_sfd_file(char **name) +{ + handle_extension(name, ".sfd"); + +#ifdef OLD_KPATHSEA +#ifdef VERY_OLD_KPATHSEA + return kpse_find_file(*name, kpse_dvips_header_format, True); +#else + return kpse_find_file(*name, kpse_tex_ps_header_format, True); +#endif +#else + return kpse_find_file(*name, kpse_program_text_format, True); +#endif +} + + +char * +TeX_search_config_file(char **name) +{ + /* no extra extension handling necessary */ + +#ifdef OLD_KPATHSEA + return kpse_find_file(*name, kpse_dvips_config_format, True); +#else + return kpse_find_file(*name, kpse_program_text_format, True); +#endif +} + + +char * +TeX_search_ttf_file(char **name) +{ +#ifdef OLD_KPATHSEA + + size_t l; + char* real_name; + + + l = strlen(*name); + handle_extension(name, ".ttf"); +#ifdef VERY_OLD_KPATHSEA + real_name = kpse_find_file(*name, kpse_dvips_header_format, True); +#else + real_name = kpse_find_file(*name, kpse_type1_format, True); +#endif + + /* test for .ttc, but only if no extension was given initially */ + if (!real_name && l != strlen(*name)) + { + (*name)[strlen(*name) - 1] = 'c'; +#ifdef VERY_OLD_KPATHSEA + real_name = kpse_find_file(*name, kpse_dvips_header_format, True); +#else + real_name = kpse_find_file(*name, kpse_type1_format, True); +#endif + } + + return real_name; + +#else /* OLD_KPATHSEA */ + + /* no extra extension handling necessary */ + + return kpse_find_file(*name, kpse_truetype_format, True); + +#endif +} + + +/**************************** + * emtexdir library support * + ****************************/ + +#elif defined(HAVE_EMTEXDIR) + +#include "emtexdir.h" +#include "errormsg.h" + +extern int setup_list(struct emtex_dir *dst, char *path, + const char *list, unsigned flags); + +char emtex_version_string[] = "emTeXdir"; + +struct emtex_dir tfm_path, + enc_path, + rpl_path, + sfd_path, + cfg_path, + ttf_path; + + +/* + * We slightly modify emtex_dir_setup() to output a warning in case + * the environment variable isn't set properly. + */ + +static int +dir_setup(struct emtex_dir *ed, + const char *env, + const char *dir, + unsigned flags) +{ + const char *val; + char path[260]; + + + ed->alloc = 0; + ed->used = 0; + ed->list = NULL; + + if (env != NULL && (val = getenv(env)) != NULL) + return setup_list(ed, path, val, flags); + else + warning("Environment variable %s not set; use current directory.", env); + + return True; +} + + +static char * +file_find(char *name, struct emtex_dir *list) +{ + char buffer[1024]; + + + if (emtex_dir_find(buffer, sizeof (buffer), list, name, EDF_CWD)) + return newstring(buffer); + + return NULL; +} + + +/* + * Initialize emtexdir library; arguments are the full name of the + * executable (e.g. `c:\bin\ttf2pk.exe') and two identification strings; + * the former for the program itself, the latter for the environment. + * We ignore all of them. + */ + +void +TeX_search_init(char *exec_name, + char *program_identifier, + char *env_identifier) +{ + if (!dir_setup(&tfm_path, "TEXTFM", NULL, EDS_BANG)) + oops("Cannot setup search path for tfm files"); + if (!dir_setup(&enc_path, "TTFCFG", NULL, EDS_BANG)) + oops("Cannot setup search path for encoding files"); +#if 0 + if (!dir_setup(&rpl_path, "TTFCFG", NULL, EDS_BANG)) + oops("Cannot setup search path for replacement files"); + if (!dir_setup(&sfd_path, "TTFCFG", NULL, EDS_BANG)) + oops("Cannot setup search path for subfont definition files"); + if (!dir_setup(&cfg_path, "TTFCFG", NULL, EDS_BANG)) + oops("Cannot setup search path for configuration file"); +#else + rpl_path = sfd_path = cfg_path = enc_path; +#endif + if (!dir_setup(&ttf_path, "TTFONTS", NULL, EDS_BANG)) + oops("Cannot setup search path for TrueType font files"); +} + + +char * +TeX_search_version(void) +{ + return emtex_version_string; +} + + +char * +TeX_search_tfm(char **name) +{ + handle_extension(name, ".tfm"); + return file_find(*name, &tfm_path); +} + + +char * +TeX_search_encoding_file(char **name) +{ + handle_extension(name, ".enc"); + return file_find(*name, &enc_path); +} + + +char * +TeX_search_replacement_file(char **name) +{ + handle_extension(name, ".rpl"); + return file_find(*name, &rpl_path); +} + + +char * +TeX_search_sfd_file(char **name) +{ + handle_extension(name, ".sfd"); + return file_find(*name, &sfd_path); +} + + +char * +TeX_search_config_file(char **name) +{ + /* no extra extension handling necessary */ + return file_find(*name, &cfg_path); +} + + +char * +TeX_search_ttf_file(char **name) +{ + size_t l; + char* real_name; + + + l = strlen(*name); + handle_extension(name, ".ttf"); + real_name = file_find(*name, &ttf_path); + + /* test for .ttc, but only if no extension was given initially */ + if (!real_name && l != strlen(*name)) + { + (*name)[strlen(*name) - 1] = 'c'; + real_name = file_find(*name, &ttf_path); + } + + return real_name; +} + + +/************************** + * MiKTeX library support * + **************************/ + +#elif defined(MIKTEX) + +#include "miktex.h" + +void +TeX_search_init(char *exec_name, + char *program_identifier, + char *env_identifier) +{ + /* empty */ +} + + +char * +TeX_search_version(void) +{ + char buf[200]; + + + strcpy(buf, "MiKTeX "); + miktex_get_miktex_version_string_ex(buf + 7, sizeof (buf) - 7); + + return buf; +} + + +char * +TeX_search_tfm(char **name) +{ + char result[_MAX_PATH]; + + + if (!miktex_find_tfm_file(*name, result)) + return 0; + + return strdup(result); +} + + +char * +TeX_search_encoding_file(char **name) +{ + char result[_MAX_PATH]; + + + if (!miktex_find_enc_file(*name, result)) + return 0; + + return strdup(result); +} + + +char * +TeX_search_replacement_file(char **name) +{ + char result[_MAX_PATH]; + + + handle_extension(name, ".rpl"); + if (!miktex_find_input_file("ttf2tfm", *name, result)) + return 0; + + return strdup(result); +} + + +char * +TeX_search_sfd_file(char **name) +{ + char result[_MAX_PATH]; + + + handle_extension(name, ".sfd"); + if (!miktex_find_input_file("ttf2tfm", *name, result)) + return 0; + return strdup(result); +} + + +char * +TeX_search_config_file(char **name) +{ + char result[_MAX_PATH]; + + + if (!miktex_find_input_file("ttf2tfm", *name, result)) + return 0; + return strdup(result); +} + + +char * +TeX_search_ttf_file(char **name) +{ + char result[_MAX_PATH]; + + + if (!miktex_find_ttf_file(*name, result)) + return 0; + return strdup(result); +} + + +/********************** + * no library support * + **********************/ + +#else + +#include + +char version_string[] = "no search library"; + +void +TeX_search_init(char *exec_name, + char *program_identifier, + char *env_identifier) +{ + /* empty */ +} + + +char * +TeX_search_version(void) +{ + return version_string; +} + + +char * +TeX_search_tfm(char **name) +{ + handle_extension(name, ".tfm"); + return *name; +} + + +char * +TeX_search_encoding_file(char **name) +{ + handle_extension(name, ".enc"); + return *name; +} + + +char * +TeX_search_replacement_file(char **name) +{ + handle_extension(name, ".rpl"); + return *name; +} + + +char * +TeX_search_sfd_file(char **name) +{ + handle_extension(name, ".sfd"); + return *name; +} + + +char * +TeX_search_config_file(char **name) +{ + /* no extra extension handling necessary */ + return *name; +} + + +/* we only handle .ttf extension */ + +char * +TeX_search_ttf_file(char **name) +{ + handle_extension(name, ".ttf"); + return *name; +} + +#endif + + + +void +get_tfm_fullname(Font *fnt) +{ + size_t len = 0; + + + if (fnt->fullname) + free(fnt->fullname); + + if (fnt->outname) + len += strlen(fnt->outname); + if (fnt->subfont_name) + len += strlen(fnt->subfont_name); + if (fnt->outname_postfix) + len += strlen(fnt->outname_postfix); + len++; + + fnt->fullname = (char *)mymalloc(len); + fnt->fullname[0] = '\0'; + + if (fnt->outname) + strcat(fnt->fullname, fnt->outname); + if (fnt->subfont_name) + strcat(fnt->fullname, fnt->subfont_name); + if (fnt->outname_postfix) + strcat(fnt->fullname, fnt->outname_postfix); +} + + +/* + * This function takes the address of a pointer to a string allocated + * with malloc() and checks whether it has an extension. If not, a default + * extension given as a second argument will be appended using first + * realloc() and then strcat(). + * + * '/', ':', and '\\' will be recognized as directory separators. + */ + +void +handle_extension(char **stringp, + char *extension) +{ + int i, lastext = -1; + + + for (i = 0; (*stringp)[i]; i++) + if ((*stringp)[i] == '.') + lastext = i; + else if ((*stringp)[i] == '/' || + (*stringp)[i] == ':' || + (*stringp)[i] == '\\') + lastext = -1; + + if (lastext == -1) + { + *stringp = (char *)myrealloc((void *)*stringp, + strlen(*stringp) + strlen(extension) + 1); + strcat(*stringp, extension); + } +} + + +/* end */ diff --git a/contrib/ttf2pk/filesrch.h b/contrib/ttf2pk/filesrch.h new file mode 100644 index 0000000..88dc2d9 --- /dev/null +++ b/contrib/ttf2pk/filesrch.h @@ -0,0 +1,51 @@ +/* + * filesrch.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef FILESRCH_H +#define FILESRCH_H + +#include "ttf2tfm.h" + +/* + * Arguments are the full program name and two identification strings + * (for the program and the environment). + */ + +void TeX_search_init(char *exec_name, + char *program_identifier, + char *env_identifier); + +/* + * The next function returns a version string. + */ + +char *TeX_search_version(void); + +/* + * The following functions take a file name (either relative or absolute), + * probably append a default extension, and return the complete path to the + * file. + */ + +char *TeX_search_tfm(char **name); +char *TeX_search_encoding_file(char **name); +char *TeX_search_replacement_file(char **name); +char *TeX_search_sfd_file(char **name); +char *TeX_search_config_file(char **name); +char *TeX_search_ttf_file(char **name); + +void get_tfm_fullname(Font *fnt); +void handle_extension(char **stringp, + char *extension); + +#endif /* FILESRCH_H */ + + +/* end */ diff --git a/contrib/ttf2pk/ligkern.c b/contrib/ttf2pk/ligkern.c new file mode 100644 index 0000000..922ae40 --- /dev/null +++ b/contrib/ttf2pk/ligkern.c @@ -0,0 +1,275 @@ +/* + * ligkern.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#include +#include +#include /* for size_t */ +#include + +#include "ttf2tfm.h" +#include "ligkern.h" +#include "ttfenc.h" +#include "texenc.h" +#include "newobj.h" +#include "errormsg.h" + + +static char * +paramstring(char **curp) +{ + register char *p, *q; + + + p = *curp; + while (*p && !isspace(*p)) + p++; + q = *curp; + if (*p != '\0') + *p++ = '\0'; + while (isspace(*p)) + p++; + *curp = p; + return q; +} + + +/* + * Some routines to remove kerns that match certain patterns. + */ + +static kern * +rmkernmatch(kern *k, + char *s) +{ + kern *nk; + + + while (k && strcmp(k->succ, s) == 0) + k = k->next; + + if (k) + { + for (nk = k; nk; nk = nk->next) + while (nk->next && strcmp(nk->next->succ, s) == 0) + nk->next = nk->next->next; + } + return k; +} + + +/* + * Recursive to one level. + */ + +static void +rmkern(char *s1, char *s2, + ttfinfo *ti, + Font *fnt) +{ + if (ti == NULL) + { + if (strcmp(s1, "*") == 0) + { + for (ti = fnt->charlist; ti; ti = ti->next) + rmkern(s1, s2, ti, fnt); + return; + } + else + { + ti = findadobe(s1, fnt->charlist); + if (ti == NULL) + return; + } + } + + if (strcmp(s2, "*") == 0) + ti->kerns = NULL; /* drop them on the floor */ + else + ti->kerns = rmkernmatch(ti->kerns, s2); +} + + +/* + * Make the kerning for character S1 equivalent to that for S2. + * If either S1 or S2 do not exist, do nothing. + * If S1 already has kerning, do nothing. + */ + +static void +addkern(char *s1, char *s2, + Font *fnt) +{ + ttfinfo *ti1 = findadobe(s1, fnt->charlist); + ttfinfo *ti2 = findadobe(s2, fnt->charlist); + + + if (ti1 && ti2 && !ti1->kerns) + { + /* Put the new one at the head of the list, since order is immaterial. */ + ttfptr *ap = (ttfptr *)mymalloc(sizeof (ttfptr)); + + + ap->next = ti2->kern_equivs; + ap->ch = ti1; + ti2->kern_equivs = ap; + } +} + + +/* + * Reads a ligkern line, if this is one. Assumes the first character + * passed is `%'. + */ + +void +checkligkern(char *s, Font *fnt) +{ + char *mlist[5]; + char *os; + char *orig_s, *pos; + size_t offset[5]; + int n; + + + os = newstring(s); + orig_s = s; + + s++; + while (isspace(*s)) + s++; + if (strncmp(s, "LIGKERN", 7) == 0) + { + fnt->sawligkern = True; + s += 7; + while (isspace(*s)) + s++; + pos = s; + while (*pos) + { + for (n = 0; n < 5;) + { + if (*pos == '\0') + break; + offset[n] = pos - orig_s; + mlist[n] = paramstring(&pos); + if (strcmp(mlist[n], ";") == 0) + break; + n++; + } + + if (n > 4) + boops(os, pos - orig_s, "Too many parameters in lig kern data."); + if (n < 3) + boops(os, pos - orig_s, "Too few parameters in lig kern data."); + + if (n == 3 && strcmp(mlist[1], "{}") == 0) /* rmkern command */ + rmkern(mlist[0], mlist[2], (ttfinfo *)0, fnt); + else if (n == 3 && strcmp(mlist[1], "<>") == 0) /* addkern */ + addkern(mlist[0], mlist[2], fnt); + else if (n == 3 && strcmp(mlist[0], "||") == 0 && + strcmp(mlist[1], "=") == 0) /* bc command */ + { + ttfinfo *ti = findadobe("||", fnt->charlist); + + + if (fnt->boundarychar != -1) + boops(os, offset[0], "Multiple boundary character commands?"); + if (sscanf(mlist[2], "%d", &n) != 1) + boops(os, offset[2], + "Expected number assignment for boundary char."); + if (n < 0 || n > 0xFF) + boops(os, offset[2], "Boundary character number must be 0..0xFF."); + + fnt->boundarychar = n; + if (ti == NULL) + oops("Internal error: boundary char."); + ti->outcode = n; /* prime the pump, so to speak, for lig/kerns */ + } + else if (n == 4) + { + int op = -1; + ttfinfo *ti; + + + for (n = 0; encligops[n]; n++) + if (strcmp(mlist[2], encligops[n]) == 0) + { + op = n; + break; + } + if (op < 0) + boops(os, offset[2], "Bad ligature op specified."); + + if (NULL != (ti = findadobe(mlist[0], fnt->charlist))) + { + lig *lig; + + + if (findadobe(mlist[2], fnt->charlist)) + /* remove coincident kerns */ + rmkern(mlist[0], mlist[1], ti, fnt); + + if (strcmp(mlist[3], "||") == 0) + boops(os, offset[3], "You can't lig to the boundary character!"); + + if (!fnt->fixedpitch) /* fixed pitch fonts get *0* ligs */ + { + for (lig = ti->ligs; lig; lig = lig->next) + if (strcmp(lig->succ, mlist[1]) == 0) + break; /* we'll re-use this structure */ + + if (lig == NULL) + { + lig = newlig(); + lig->succ = newstring(mlist[1]); + lig->next = ti->ligs; + ti->ligs = lig; + } + lig->sub = newstring(mlist[3]); + lig->op = op; + + if (strcmp(mlist[1], "||") == 0) + { + lig->boundleft = 1; + if (strcmp(mlist[0], "||") == 0) + boops(os, offset[0], + "You can't lig boundarychar boundarychar!"); + } + else + lig->boundleft = 0; + } + } + } + else + boops(os, offset[0], "Bad form in LIGKERN command."); + } + } + + free(os); +} + + +void +getligkerndefaults(Font *fnt) +{ + int i; + char *buffer; + + + for (i = 0; staticligkern[i]; i++) + { + buffer = newstring(staticligkern[i]); + checkligkern(buffer, fnt); + free(buffer); + } +} + + +/* end */ diff --git a/contrib/ttf2pk/ligkern.h b/contrib/ttf2pk/ligkern.h new file mode 100644 index 0000000..2b43a25 --- /dev/null +++ b/contrib/ttf2pk/ligkern.h @@ -0,0 +1,23 @@ +/* + * ligkern.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef LIGKERN_H +#define LIGKERN_H + +#include "ttf2tfm.h" + + +void checkligkern(char *s, Font *fnt); +void getligkerndefaults(Font *fnt); + +#endif /* LIGKERN_H */ + + +/* end */ diff --git a/contrib/ttf2pk/newobj.c b/contrib/ttf2pk/newobj.c new file mode 100644 index 0000000..2d87094 --- /dev/null +++ b/contrib/ttf2pk/newobj.c @@ -0,0 +1,352 @@ +/* + * newobj.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#include +#include /* for size_t */ +#include + +#include "newobj.h" +#include "ttf2tfm.h" +#include "errormsg.h" +#include "texenc.h" + + +void * +mymalloc(size_t len) +{ + void *p; + + +#ifdef SMALLMALLOC + if (len > 65500L) + oops("Cannot allocate more than 64kByte."); +#endif + + if (len) + p = malloc(len); + else + p = malloc(1); + + if (p == NULL) + oops("Out of memory."); + + return p; +} + + +void * +myrealloc(void *oldp, size_t len) +{ + void *p; + + +#ifdef SMALLMALLOC + if (len > 65500L) + oops("Cannot allocate more than 64kByte."); +#endif + + if (len) + p = realloc(oldp, len); + else + p = realloc(oldp, 1); + + if (p == NULL) + oops("Out of memory."); + + return p; +} + + +/* + * This routine gets a line from a file, supporting continuation with + * '\' as the last character on the line. + * + * In case of error, NULL is returned. If EOF is reached a pointer to + * a null string is returned. The final newline will be retained. + */ + +char * +get_line(FILE *f) +{ + size_t linelen, len; + char *buffer; + int c; + + + linelen = 80; + len = 0; + + buffer = (char *)mymalloc(linelen); + + while (1) + { + c = fgetc(f); + buffer[len++] = c; + + if (len == linelen - 1) + { + linelen += 80; + buffer = (char *)myrealloc(buffer, linelen); + } + + again: + switch (c) + { + case '\\': + c = fgetc(f); + if (c == '\n') + { + len--; + break; + } + else + { + buffer[len++] = c; + goto again; + } + case '\n': + buffer[len] = '\0'; + return buffer; + case EOF: + buffer[len - 1] = '\0'; + if (feof(f)) + return buffer; + else + return NULL; + default: + break; + } + } +} + + +/* + * getline() is a wrapper function for get_line(). It returns `False' in + * case of error and expects a pointer to a buffer to store the current + * line. Additionally, the final newline character is stripped. + */ + +Boolean +getline(char **bufferp, FILE *f) +{ + size_t l; + + + *bufferp = get_line(f); + + if (!(*bufferp && **bufferp)) + return 0; + + l = strlen(*bufferp); + if (l > 0) + (*bufferp)[l - 1] = '\0'; + + return 1; +} + + +char * +newstring(char *s) +{ + char *q; + + if (s) + { + q = mymalloc(strlen(s) + 1); + (void)strcpy(q, s); + return q; + } + else + return NULL; +} + + +ttfinfo * +newchar(Font *fnt) +{ + register ttfinfo *ti; + + + ti = (ttfinfo *)mymalloc(sizeof (ttfinfo)); + + ti->next = fnt->charlist; + + ti->charcode = -1; + ti->glyphindex = -1; + ti->incode = -1; + ti->outcode = -1; + ti->adobename = NULL; + + ti->width = -1; + ti->llx = -1; + ti->lly = -1; + ti->urx = -1; + ti->ury = -1; + + ti->ligs = NULL; + ti->kerns = NULL; + ti->kern_equivs = NULL; + ti->pccs = NULL; + + ti->constructed = False; + + ti->wptr = 0; + ti->hptr = 0; + ti->dptr = 0; + ti->iptr = 0; + + fnt->charlist = ti; + + return ti; +} + + +kern * +newkern(void) +{ + register kern *nk; + + + nk = (kern *)mymalloc(sizeof (kern)); + nk->next = NULL; + nk->succ = NULL; + nk->delta = 0; + + return nk; +} + + +pcc * +newpcc(void) +{ + register pcc *np; + + + np = (pcc *)mymalloc(sizeof (pcc)); + np->next = NULL; + np->partname = NULL; + np->xoffset = 0; + np->yoffset = 0; + + return np; +} + + +lig * +newlig(void) +{ + register lig *nl; + + + nl = (lig *)mymalloc(sizeof (lig)); + nl->next = NULL; + nl->succ = NULL; + nl->sub = NULL; + nl->op = 0; /* the default =: op */ + nl->boundleft = 0; + + return nl; +} + + +stringlist * +newstringlist(void) +{ + register stringlist *sl; + + + sl = (stringlist *)mymalloc(sizeof (stringlist)); + sl->next = NULL; + sl->old_name = NULL; + sl->new_name = NULL; + sl->single_replacement = False; + + return sl; +} + + +void +init_font_structure(Font *fnt) +{ + int i; + + + fnt->ttfname = NULL; + + fnt->tfm_path = NULL; + fnt->tfm_ext = NULL; + + fnt->outname = NULL; + fnt->subfont_name = NULL; + fnt->outname_postfix = NULL; + fnt->fullname = NULL; + + fnt->vplout = NULL; + fnt->tfmout = NULL; + + fnt->inencname = NULL; + fnt->inencoding = NULL; + + fnt->replacements = NULL; + fnt->replacementname = NULL; + + fnt->outencname = NULL; + fnt->outencoding = NULL; + + fnt->sfdname = NULL; + + fnt->sawligkern = False; + fnt->subfont_ligs = False; + + fnt->charlist = NULL; + + fnt->boundarychar = -1; + fnt->codingscheme = default_codingscheme; + fnt->titlebuf = NULL; + + fnt->units_per_em = 0; + fnt->italicangle = 0.0; + fnt->fixedpitch = 0; + + fnt->fontindex = 0; + fnt->pid = 3; + fnt->eid = 1; + + fnt->xheight = 400; + fnt->fontspace = 0; + + fnt->y_offset = 0.25; + + fnt->efactor = 1.0; + fnt->slant = 0; + fnt->capheight = 0.8; + fnt->PSnames = No; + fnt->rotate = No; + + fnt->efactorparam = NULL; + fnt->slantparam = NULL; + fnt->fontindexparam = NULL; + fnt->pidparam = NULL; + fnt->eidparam = NULL; + fnt->y_offsetparam = NULL; + + for (i = 0; i < 256; i++) + { + fnt->inencptrs[i] = NULL; + fnt->outencptrs[i] = NULL; + fnt->uppercase[i] = NULL; + fnt->lowercase[i] = NULL; + fnt->sf_code[i] = -1; + fnt->nextout[i] = -1; /* encoding chains have length 0 */ + } +} + + +/* end */ diff --git a/contrib/ttf2pk/newobj.h b/contrib/ttf2pk/newobj.h new file mode 100644 index 0000000..d238361 --- /dev/null +++ b/contrib/ttf2pk/newobj.h @@ -0,0 +1,43 @@ +/* + * newobj.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef NEWOBJ_H +#define NEWOBJ_H + +#include +#include "ttf2tfm.h" + + +#if (defined(MSDOS) && defined(__TURBOC__)) || \ + (defined(OS2) && defined(_MSC_VER)) +#define SMALLMALLOC +#endif + + +void *mymalloc(size_t len); +void *mycalloc(size_t len); +void *myrealloc(void *oldp, size_t len); + +char *get_line(FILE *f); +Boolean getline(char **bufferp, FILE *f); +char *newstring(char *s); + +ttfinfo *newchar(Font *fnt); +kern *newkern(void); +pcc *newpcc(void); +lig *newlig(void); +stringlist *newstringlist(void); + +void init_font_structure(Font *fnt); + +#endif /* NEWOBJ_H */ + + +/* end */ diff --git a/contrib/ttf2pk/parse.c b/contrib/ttf2pk/parse.c new file mode 100644 index 0000000..2426a8e --- /dev/null +++ b/contrib/ttf2pk/parse.c @@ -0,0 +1,304 @@ +/* + * parse.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#include +#include +#include /* for size_t */ +#include +#include + +#include "ttf2tfm.h" +#include "errormsg.h" +#include "newobj.h" +#include "ligkern.h" +#include "texenc.h" +#include "parse.h" +#include "filesrch.h" + + +/* + * Here we get a token from the encoding file. We parse just as much + * PostScript as we expect to find in an encoding file. We allow + * commented lines and names like 0, .notdef, _foo_. We do not allow + * //abc. + * + * `bufferp' is a pointer to the current line; the offset of the beginning + * of the token to be parsed relative to `bufferp' will be returned in + * `offsetp'. On the first call of gettoken() `init' must be set to 1 and + * to 0 on the following calls. + * + * If `ignoreligkern' is `True', no LIGKERN data will be extracted from the + * encoding file. + * + * Don't modify `bufferp'! + * + * The memory management of `bufferp' will be done by gettoken() itself; + * nevertheless, it returns a pointer to the current token which should be + * freed after it has been used. + */ + +static char * +gettoken(char **bufferp, size_t *offsetp, FILE *f, Font *fnt, + Boolean ignoreligkern, Boolean init) +{ + char *p, *q; + char tempchar; + static char *curp; + + + if (init) + curp = NULL; + + while (1) + { + while (curp == NULL || *curp == '\0') + { + if (*bufferp) + free(*bufferp); + + if (getline(bufferp, f) == False) + oops("Premature end in encoding file."); + + curp = *bufferp; + + for (p = *bufferp; *p; p++) + if (*p == '%') + { + if (ignoreligkern == False) + checkligkern(p, fnt); + *p = '\0'; + break; + } + } + + while (isspace(*curp)) + curp++; + + *offsetp = curp - *bufferp; + + if (*curp) + { + if (*curp == '[' || *curp == ']' || + *curp == '{' || *curp == '}') + q = curp++; + else if (*curp == '/' || + *curp == '-' || *curp == '_' || *curp == '.' || + ('0' <= *curp && *curp <= '9') || + ('a' <= *curp && *curp <= 'z') || + ('A' <= *curp && *curp <= 'Z')) + { + q = curp++; + while (*curp == '-' || *curp == '_' || *curp == '.' || + ('0' <= *curp && *curp <= '9') || + ('a' <= *curp && *curp <= 'z') || + ('A' <= *curp && *curp <= 'Z')) + curp++; + } + else + q = curp; + + tempchar = *curp; + *curp = '\0'; + p = newstring(q); + *curp = tempchar; + return p; + } + } +} + + +/* + * This routine reads in an encoding file, given the name. It returns + * the final total structure. It performs a number of consistency checks. + */ + +encoding * +readencoding(char **enc, Font *fnt, Boolean ignoreligkern) +{ + char *real_encname; + FILE *enc_file; + char *p, *q, c; + char *buffer; + char numbuf[9]; + size_t offset; + int i; + long l; + encoding *e = (encoding *)mymalloc(sizeof (encoding)); + + + if (enc && *enc) + { + real_encname = TeX_search_encoding_file(enc); + if (!real_encname) + oops("Cannot find encoding file `%s'.", *enc); + + enc_file = fopen(real_encname, "rt"); + if (enc_file == NULL) + oops("Cannot open encoding file `%s'.", real_encname); + + buffer = NULL; + p = gettoken(&buffer, &offset, enc_file, fnt, ignoreligkern, True); + if (*p != '/' || p[1] == '\0') + boops(buffer, offset, + "First token in encoding must be literal encoding name."); + e->name = newstring(p + 1); + free(p); + + p = gettoken(&buffer, &offset, enc_file, fnt, ignoreligkern, False); + if (strcmp(p, "[")) + boops(buffer, offset, + "Second token in encoding must be mark ([) token."); + free(p); + + for (i = 0; i < 256; i++) + { + p = gettoken(&buffer, &offset, enc_file, fnt, ignoreligkern, False); + if (*p != '/' || p[1] == 0) + boops(buffer, offset, + "Tokens 3 to 257 in encoding must be literal names."); + + /* now we test for a generic code point resp. glyph index value */ + + c = p[2]; + if (p[1] == '.' && (c == 'c' || c == 'g') && '0' <= p[3] && p[3] <= '9') + { + l = strtol(p + 3, &q, 0); + if (*q != '\0' || l < 0 || l > 0xFFFF) + boops(buffer, offset, "Invalid encoding token."); + sprintf(numbuf, ".%c0x%x", c, (unsigned int)l); + e->vec[i] = newstring(numbuf); + } + else + e->vec[i] = newstring(p + 1); + + free(p); + } + + p = gettoken(&buffer, &offset, enc_file, fnt, ignoreligkern, False); + if (strcmp(p, "]")) + boops(buffer, offset, + "Token 258 in encoding must be make-array (])."); + free(p); + + while (getline(&buffer, enc_file)) + { + for (p = buffer; *p; p++) + if (*p == '%') + { + if (ignoreligkern == False) + checkligkern(p, fnt); + *p = '\0'; + break; + } + } + + fclose(enc_file); + + if (ignoreligkern == False && fnt->sawligkern == False) + getligkerndefaults(fnt); + } + else + { + if (ignoreligkern == False) + { + e = &staticencoding; + getligkerndefaults(fnt); + } + else + e = NULL; + } + + return e; +} + + +/* + * We scan a glyph replacement file. + * `%' is the comment character. + */ + +void +get_replacements(Font *fnt) +{ + char *real_replacement_name; + FILE *replacement_file; + char *buffer = NULL, *oldbuffer = NULL; + char *p; + char *old_name, *new_name; + stringlist *sl; + + + if (!fnt->replacementname) + return; + + real_replacement_name = TeX_search_replacement_file(&fnt->replacementname); + if (!real_replacement_name) + oops("Cannot find replacement file `%s'.", fnt->replacementname); + + replacement_file = fopen(real_replacement_name, "rt"); + if (replacement_file == NULL) + oops("Cannot open replacement file `%s'.", real_replacement_name); + + while (getline(&buffer, replacement_file)) + { + for (p = buffer; *p; p++) + if (*p == '%') + { + *p = '\0'; + break; + } + + if (oldbuffer) + free(oldbuffer); + oldbuffer = newstring(buffer); + + p = buffer; + + while (isspace(*p)) + p++; + if (!*p) + continue; + + old_name = p; + + while (*p && !isspace(*p)) + p++; + if (*p) + *p++ = '\0'; + + while (*p && isspace(*p)) + p++; + if (!*p) + boops(oldbuffer, old_name - oldbuffer, "Replacement glyph missing."); + + new_name = p; + + while (*p && !isspace(*p)) + p++; + if (*p) + *p++ = '\0'; + + while (*p && isspace(*p)) + p++; + if (*p) + boops(oldbuffer, p - oldbuffer, "Invalid replacement syntax."); + + sl = newstringlist(); + sl->new_name = newstring(new_name); + sl->old_name = newstring(old_name); + sl->next = fnt->replacements; + fnt->replacements = sl; + } + + fclose(replacement_file); +} + + +/* end */ diff --git a/contrib/ttf2pk/parse.h b/contrib/ttf2pk/parse.h new file mode 100644 index 0000000..0816d4e --- /dev/null +++ b/contrib/ttf2pk/parse.h @@ -0,0 +1,22 @@ +/* + * parse.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef PARSE_H +#define PARSE_H + +#include "ttf2tfm.h" + +encoding *readencoding(char **enc, Font *fnt, Boolean ignoreligkern); +void get_replacements(Font *fnt); + +#endif /* PARSE_H */ + + +/* end */ diff --git a/contrib/ttf2pk/pklib.c b/contrib/ttf2pk/pklib.c new file mode 100644 index 0000000..51c4805 --- /dev/null +++ b/contrib/ttf2pk/pklib.c @@ -0,0 +1,872 @@ +/* + * pklib.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +/* + * This code has been derived from the program gsftopk. + * Here the original copyright. + */ + +/* + * Copyright (c) 1994 Paul Vojta. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#include +#include +#include /* for size_t */ +#include +#include +#include + +#include "newobj.h" +#include "pklib.h" +#include "errormsg.h" +#include "filesrch.h" + +#ifndef MAXPATHLEN +#define MAXPATHLEN 256 +#endif + +#define PK_PRE (char)247 +#define PK_ID 89 +#define PK_POST (char)245 +#define PK_NOP (char)246 + +int dpi; + +FILE *pk_file; + + +/* + * Information from the .tfm file. + */ + +int tfm_lengths[12]; + +#define lh tfm_lengths[1] +#define bc tfm_lengths[2] +#define ec tfm_lengths[3] +#define nw tfm_lengths[4] + +long checksum; +long design; +byte width_index[256]; +long tfm_widths[256]; + +/* + * Information on the bitmap currently being worked on. + */ + +byte *bitmap; +int width; +int skip; +int height; +int hoff; +int voff; +int bytes_wide; +size_t bm_size; +byte *bitmap_end; +int pk_len; + +/* + * Here's the path searching stuff. First the typedefs and variables. + */ + +static char searchpath[MAXPATHLEN + 1]; + +#define HUNKSIZE (MAXPATHLEN + 2) + +struct spacenode /* used for storage of directory names */ +{ + struct spacenode *next; + char *sp_end; /* end of data for this chunk */ + char sp[HUNKSIZE]; +} firstnode; + + + +static FILE * +search_tfm(char **name) +{ + char *p; + FILE *f; + + + p = TeX_search_tfm(name); + if (p == NULL) + return NULL; + strcpy(searchpath, p); + f = fopen(searchpath, "rb"); + return f; +} + + +static long +getlong(FILE *f) +{ + unsigned long value; + + + value = (unsigned long)getc(f) << 24; + value |= (unsigned long)getc(f) << 16; + value |= (unsigned long)getc(f) << 8; + value |= (unsigned long)getc(f); + return value; +} + + +char line[82]; + + +static byte masks[] = {0, 1, 3, 7, 017, 037, 077, 0177, 0377}; + +byte flag; +int pk_dyn_f; +int pk_dyn_g; +int base; /* cost of this character if pk_dyn_f = 0 */ +int deltas[13]; /* cost of increasing pk_dyn_f from i to i+1 */ + + +/* + * Add up statistics for putting out the given shift count. + */ + +static void +tallyup(int n) +{ + int m; + + + if (n > 208) + { + ++base; + n -= 192; + for (m = 0x100; m != 0 && m < n; m <<= 4) + base += 2; + if (m != 0 && (m = (m - n) / 15) < 13) + deltas[m] += 2; + } + else if (n > 13) + ++deltas[(208 - n) / 15]; + else + --deltas[n - 1]; +} + + +/* + * Routines for storing the shift counts. + */ + +static Boolean odd = False; +static byte part; + + +static void +pk_put_nyb(int n) +{ + if (odd) + { + *bitmap_end++ = (part << 4) | n; + odd = False; + } + else + { + part = n; + odd = True; + } +} + + +static void +pk_put_long(int n) +{ + if (n >= 16) + { + pk_put_nyb(0); + pk_put_long(n / 16); + } + pk_put_nyb(n % 16); +} + + +static void +pk_put_count(int n) +{ + if (n > pk_dyn_f) + { + if (n > pk_dyn_g) + pk_put_long(n - pk_dyn_g + 15); + else + { + pk_put_nyb(pk_dyn_f + (n - pk_dyn_f + 15) / 16); + pk_put_nyb((n - pk_dyn_f - 1) % 16); + } + } + else + pk_put_nyb(n); +} + + +static void +trim_bitmap(void) +{ + byte *p; + byte mask; + + + /* clear out garbage bits in bitmap */ + + if (width % 8 != 0) + { + mask = ~masks[8 - width % 8]; + for (p = bitmap + bytes_wide - 1; p < bitmap_end; p += bytes_wide) + *p &= mask; + } + + /* Find the bounding box of the bitmap. */ + + /* trim top */ + + skip = 0; + mask = 0; + + for (;;) + { + if (bitmap >= bitmap_end) /* if bitmap is empty */ + { + width = height = hoff = voff = 0; + return; + } + + p = bitmap + bytes_wide; + while (p > bitmap) + mask |= *--p; + if (mask) + break; + ++skip; + bitmap += bytes_wide; + } + + height -= skip; + voff -= skip; + +#ifdef DEBUG + if (skip < 2 || skip > 3) + printf("Character has %d empty rows at top\n", skip); +#endif + + /* trim bottom */ + + skip = 0; + mask = 0; + + for (;;) + { + p = bitmap_end - bytes_wide; + while (p < bitmap_end) + mask |= *p++; + if (mask) + break; + ++skip; + bitmap_end -= bytes_wide; + } + + height -= skip; + +#ifdef DEBUG + if (skip < 2 || skip > 3) + printf("Character has %d empty rows at bottom\n", skip); +#endif + + /* trim right */ + + skip = 0; + --width; + + for (;;) + { + mask = 0; + for (p = bitmap + width / 8; p < bitmap_end; p += bytes_wide) + mask |= *p; + if (mask & (0x80 >> (width % 8))) + break; + + --width; + ++skip; + } + + ++width; + +#ifdef DEBUG + if (skip < 2 || skip > 3) + printf("Character has %d empty columns at right\n", skip); +#endif + + /* trim left */ + + skip = 0; + + for (;;) + { + mask = 0; + for (p = bitmap + skip / 8; p < bitmap_end; p += bytes_wide) + mask |= *p; + if (mask & (0x80 >> (skip % 8))) + break; + + ++skip; + } + + width -= skip; + hoff -= skip; + +#ifdef DEBUG + if (skip < 2 || skip > 3) + printf("Character has %d empty columns at left\n", skip); +#endif + + bitmap += skip / 8; + skip = skip % 8; +} + + +/* + * Pack the bitmap using the rll method. (Return false if it's better + * to just pack the bits.) + */ + +static Boolean +pk_rll_cvt(void) +{ + static int *counts = NULL; /* area for saving bit counts */ + static int maxcounts = 0; /* size of this area */ + unsigned int ncounts; /* max to allow this time */ + int *nextcount; /* next count value */ + + int *counts_end; /* pointer to end */ + byte *rowptr; + byte *p; + byte mask; + byte *rowdup; /* last row checked for dup */ + byte paint_switch; /* 0 or 0xff */ + int bits_left; /* bits left in row */ + int cost; + int i; + + + /* Allocate space for bit counts. */ + + ncounts = (width * height + 3) / 4; + if (ncounts > maxcounts) + { + if (counts != NULL) + free(counts); + counts = (int *)mymalloc((ncounts + 2) * sizeof (int)); + maxcounts = ncounts; + } + counts_end = counts + ncounts; + + /* Form bit counts and collect statistics */ + + base = 0; + memset(deltas, 0, sizeof (deltas)); + rowdup = NULL; /* last row checked for duplicates */ + p = rowptr = bitmap; + mask = 0x80 >> skip; + flag = 0; + paint_switch = 0; + + if (*p & mask) + { + flag = 8; + paint_switch = 0xff; + } + + bits_left = width; + nextcount = counts; + + while (rowptr < bitmap_end) /* loop over shift counts */ + { + int shift_count = bits_left; + + + for (;;) + { + if (bits_left == 0) + { + if ((p = rowptr += bytes_wide) >= bitmap_end) + break; + mask = 0x80 >> skip; + bits_left = width; + shift_count += width; + } + if (((*p ^ paint_switch) & mask) != 0) + break; + --bits_left; + mask >>= 1; + if (mask == 0) + { + ++p; + while (*p == paint_switch && bits_left >= 8) + { + ++p; + bits_left -= 8; + } + mask = 0x80; + } + } + + if (nextcount >= counts_end) + return False; + shift_count -= bits_left; + *nextcount++ = shift_count; + tallyup(shift_count); + + /* check for duplicate rows */ + if (rowptr != rowdup && bits_left != width) + { + byte *p1 = rowptr; + byte *q = rowptr + bytes_wide; + int repeat_count; + + + while (q < bitmap_end && *p1 == *q) + { + ++p1; + ++q; + } + repeat_count = (p1 - rowptr) / bytes_wide; + if (repeat_count > 0) + { + *nextcount++ = -repeat_count; + if (repeat_count == 1) + --base; + else + { + ++base; + tallyup(repeat_count); + } + rowptr += repeat_count * bytes_wide; + } + rowdup = rowptr; + } + paint_switch = ~paint_switch; + } + +#ifdef DEBUG + /* + * Dump the bitmap + */ + + for (p = bitmap; p < bitmap_end; p += bytes_wide) + { + byte *p1 = p; + int j; + + + mask = 0x80 >> skip; + for (j = 0; j < width; ++j) + { + putchar(*p1 & mask ? '@' : '.'); + if ((mask >>= 1) == 0) + { + mask = 0x80; + ++p1; + } + } + putchar('\n'); + } + putchar('\n'); +#endif + + /* Determine the best pk_dyn_f */ + + pk_dyn_f = 0; + cost = base += 2 * (nextcount - counts); + + for (i = 1; i < 14; ++i) + { + base += deltas[i - 1]; + if (base < cost) + { + pk_dyn_f = i; + cost = base; + } + } + + /* last chance to bail out */ + + if (cost * 4 > width * height) + return False; + + /* Pack the bit counts */ + + pk_dyn_g = 208 - 15 * pk_dyn_f; + flag |= pk_dyn_f << 4; + bitmap_end = bitmap; + *nextcount = 0; + nextcount = counts; + + while (*nextcount != 0) + { + if (*nextcount > 0) + pk_put_count(*nextcount); + else + if (*nextcount == -1) + pk_put_nyb(15); + else + { + pk_put_nyb(14); + pk_put_count(-*nextcount); + } + ++nextcount; + } + + if (odd) + { + pk_put_nyb(0); + ++cost; + } + + if (cost != 2 * (bitmap_end - bitmap)) + printf("Cost miscalculation: expected %d, got %ld\n", + cost, (long)(2 * (bitmap_end - bitmap))); + pk_len = bitmap_end - bitmap; + return True; +} + + +static void +pk_bm_cvt(void) +{ + byte *rowptr; + byte *p; + int blib1; /* bits left in byte */ + int bits_left; /* bits left in row */ + byte *q; + int blib2; + byte nextbyte; + + + flag = 14 << 4; + q = bitmap; + blib2 = 8; + nextbyte = 0; + + for (rowptr = bitmap; rowptr < bitmap_end; rowptr += bytes_wide) + { + p = rowptr; + blib1 = 8 - skip; + bits_left = width; + + if (blib2 != 8) + { + int n; + + + if (blib1 < blib2) + { + nextbyte |= *p << (blib2 - blib1); + n = blib1; + } + else + { + nextbyte |= *p >> (blib1 - blib2); + n = blib2; + } + blib2 -= n; + if ((bits_left -= n) < 0) + { + blib2 -= bits_left; + continue; + } + if ((blib1 -= n) == 0) + { + blib1 = 8; + ++p; + if (blib2 > 0) + { + nextbyte |= *p >> (8 - blib2); + blib1 -= blib2; + bits_left -= blib2; + if (bits_left < 0) + { + blib2 = -bits_left; + continue; + } + } + } + *q++ = nextbyte; + } + + /* fill up whole (destination) bytes */ + + while (bits_left >= 8) + { + nextbyte = *p++ << (8 - blib1); + *q++ = nextbyte | (*p >> blib1); + bits_left -= 8; + } + + /* now do the remainder */ + + nextbyte = *p << (8 - blib1); + if (bits_left > blib1) + nextbyte |= p[1] >> blib1; + blib2 = 8 - bits_left; + } + + if (blib2 != 8) + *q++ = nextbyte; + + pk_len = q - bitmap; +} + + +static void +putshort(short w) +{ + putc(w >> 8, pk_file); + putc(w, pk_file); +} + + +static void +putmed(long w) +{ + putc(w >> 16, pk_file); + putc(w >> 8, pk_file); + putc(w, pk_file); +} + + +static void +putlong(long w) +{ + putc(w >> 24, pk_file); + putc(w >> 16, pk_file); + putc(w >> 8, pk_file); + putc(w, pk_file); +} + + +char +xgetc(FILE *f) +{ + int c; + + + c = getc(f); + if (c == EOF) + oops("Premature end of file."); + return (byte)c; +} + + +/* + * Open and read the tfm file. + */ + +void +TFMopen(char **filename) +{ + FILE *tfm_file; + int i; + int cc; + + + tfm_file = search_tfm(filename); + if (tfm_file == NULL) + oops("Cannot find tfm file."); + + for (i = 0; i < 12; i++) + { + int j; + + + j = (int)((byte)getc(tfm_file)) << 8; + tfm_lengths[i] = j | (int)((byte)xgetc(tfm_file)); + } + + checksum = getlong(tfm_file); + design = getlong(tfm_file); + fseek(tfm_file, 4 * (lh + 6), 0); + + for (cc = bc; cc <= ec; ++cc) + { + width_index[cc] = (byte)xgetc(tfm_file); + + (void)xgetc(tfm_file); + (void)xgetc(tfm_file); + (void)xgetc(tfm_file); + } + + for (i = 0; i < nw; ++i) + tfm_widths[i] = getlong(tfm_file); + + fclose(tfm_file); +} + + +/* + * Create pk file and write preamble. + */ + +void +PKopen(char *filename, + char *ident, + int resolution) +{ + int ppp; + int i; + + + dpi = resolution; + + if ((pk_file = fopen(filename, "wb")) == NULL) + { + perror(filename); + exit(1); + } + + putc(PK_PRE, pk_file); + putc(PK_ID, pk_file); + + i = strlen(ident); + + putc(i, pk_file); + fwrite(ident, 1, i, pk_file); + putlong(design); + putlong(checksum); + ppp = dpi / 72.27 * 65536.0 + 0.5; + putlong(ppp); /* hppp */ + putlong(ppp); /* vppp */ +} + + +void +PKputglyph(int cc, + int llx, int lly, int urx, int ury, + int w, int h, + byte *b) +{ + float char_width; + + long dm; + long tfm_wid; + + + bitmap = b; + width = w; + height = h; + + hoff = -llx; + voff = ury - 2; /* Don't ask me why `-2' */ + /* Fred */ + + if (width != urx - llx || height != ury - lly) + oops("Dimensions do not match: (%d - %d) (%d - %d) <=> %d %d", + llx, lly, urx, ury, width, height); + + bytes_wide = (width + 7) / 8; + bm_size = bytes_wide * height; + bitmap_end = bitmap + bm_size; + + trim_bitmap(); + + if (height == 0 || !pk_rll_cvt()) + pk_bm_cvt(); + + if (!width_index[cc]) + return; + + tfm_wid = tfm_widths[width_index[cc]]; + char_width = tfm_wid / 1048576.0 * design / 1048576.0 * dpi / 72.27; + dm = (long)(char_width + 0.5) - (char_width < -0.5); + + if (pk_len + 8 < 4 * 256 && tfm_wid < (1<<24) && + dm >= 0 && dm < 256 && width < 256 && height < 256 && + hoff >= -128 && hoff < 128 && voff >= -128 && voff < 128) + { + putc(flag | ((pk_len + 8) >> 8), pk_file); + putc(pk_len + 8, pk_file); + putc(cc, pk_file); + putmed(tfm_wid); + putc(dm, pk_file); + putc(width, pk_file); + putc(height, pk_file); + putc(hoff, pk_file); + putc(voff, pk_file); + } + else if (pk_len + 13 < 3 * 65536L && tfm_wid < (1<<24) && + dm >= 0 && dm < 65536L && width < 65536L && height < 65536L && + hoff >= -65536L && hoff < 65536L && + voff >= -65536L && voff < 65536L) + { + putc(flag | 4 | ((pk_len + 13) >> 16), pk_file); + putshort(pk_len + 13); + putc(cc, pk_file); + putmed(tfm_wid); + putshort(dm); + putshort(width); + putshort(height); + putshort(hoff); + putshort(voff); + } + else + { + putc(flag | 7, pk_file); + putlong(pk_len + 28); + putlong(cc); + putlong(tfm_wid); + putlong((long)(char_width * 65536.0 + 0.5) - (char_width < -0.5)); + putlong(0); + putlong(width); + putlong(height); + putlong(hoff); + putlong(voff); + } + fwrite(bitmap, 1, pk_len, pk_file); +} + + +void +PKclose(void) +{ + putc(PK_POST, pk_file); + while (ftell(pk_file) % 4 != 0) + putc(PK_NOP, pk_file); + + fclose(pk_file); +} + + +/* end */ diff --git a/contrib/ttf2pk/pklib.h b/contrib/ttf2pk/pklib.h new file mode 100644 index 0000000..5283603 --- /dev/null +++ b/contrib/ttf2pk/pklib.h @@ -0,0 +1,29 @@ +/* + * pklib.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef PKLIB_H +#define PKLIB_H + +typedef unsigned char byte; + + +void TFMopen(char **filename); + +void PKopen(char *filename, char *ident, int resolution); + +void PKputglyph(int cc, int llx, int lly, int urx, int ury, + int w, int h, byte *b); + +void PKclose(void); + +#endif /* PKLIB_H */ + + +/* end */ diff --git a/contrib/ttf2pk/scripts/README b/contrib/ttf2pk/scripts/README new file mode 100644 index 0000000..aa0f73d --- /dev/null +++ b/contrib/ttf2pk/scripts/README @@ -0,0 +1,8 @@ +In these subdirectories you can find diff files for various TeX +implementations which add support for on-the-fly pk-generation using ttf2pk +and hbf2gf (which is part of the CJK package for LaTeX 2e). + +In case you don't have/want hbf2gf, simply comment out the relevant if-Block +in the script. + +For web2c 7.3 resp. teTeX 1.0 or newer, no patches are needed. diff --git a/contrib/ttf2pk/scripts/teTeX-0.4/MakeTeXPK.diff b/contrib/ttf2pk/scripts/teTeX-0.4/MakeTeXPK.diff new file mode 100644 index 0000000..bc05c4b --- /dev/null +++ b/contrib/ttf2pk/scripts/teTeX-0.4/MakeTeXPK.diff @@ -0,0 +1,63 @@ +--- /root/scripts/teTeX-0.4/MakeTeXPK Sun Feb 23 22:12:05 1997 ++++ /home/ft/freetype/contrib/ttf2pk/scripts/teTeX-0.4/MakeTeXPK Sat Sep 5 07:57:34 1998 +@@ -80,6 +80,9 @@ + : ${MAKETEXDIR=$TEXMF/maketex} + export TEXMF MAKETEXDIR + ++unset cmd ++unset psline ++ + # grep for the font in $PSMAPFILE, if some ps-to-pk is claimed to be supported. + # We have to figure out the name of the base font -- $NAME is probably + # something like pplr, but it's rpplr or pplr0 or pplr8r that's in psfonts.map. +@@ -91,7 +94,40 @@ + # some installations have set up gs in such a way that creating files + # is only allowed if the parameter -DNOSAFER is used: + GS_OPTIONS=-DNOSAFER; export GS_OPTIONS +-else ++fi ++ ++# test for TTF fonts ++if test -z "$cmd"; then ++ ttf2pk -q $NAME $DPI ++ errstatus=$? ++ ++ if test $errstatus -ne 2; then ++ if test $errstatus -ne 0; then ++ echo "ttf2pk failed" >&2 ++ exit 1 ++ fi ++ MODE=ttf2pk # preferred mode for TDS would be `modeless' ++ cmd=true ++ psline=ttf2pk # suppress gftopk call ++ fi ++fi ++ ++# test for HBF fonts ++if test -z "$cmd"; then ++ hbf2gf -q -p $NAME $DPI ++ errstatus=$? ++ ++ if test $errstatus -ne 2; then ++ if test $errstatus -ne 0; then ++ echo "hbf2gf failed" >&2 ++ exit 1 ++ fi ++ MODE=hbf2gf # preferred mode for TDS would be `modeless' ++ cmd=true ++ fi ++fi ++ ++if test -z "$cmd"; then + # If an explicit mode is not supplied, try to guess. You can get a + # list of extant modes from ftp.cs.umb.edu:pub/tex/modes.mf. + if test -z "$MODE" || test "$MODE" = default; then +@@ -141,7 +177,7 @@ + { echo "$progname: could not mkdir $PKDESTDIR."; exit 1; }' + eval "$mdir" + +-echo "$progname: Running $cmd" ++test "$cmd" = true || echo "$progname: Running $cmd" + $cmd &2; exit 1; } + if test -z "$psline"; then + test -r $GFNAME || diff --git a/contrib/ttf2pk/scripts/web2c-6.1/MakeTeXPK.diff b/contrib/ttf2pk/scripts/web2c-6.1/MakeTeXPK.diff new file mode 100644 index 0000000..0536dbc --- /dev/null +++ b/contrib/ttf2pk/scripts/web2c-6.1/MakeTeXPK.diff @@ -0,0 +1,75 @@ +--- MakeTeXPK.orig Sun Aug 16 08:05:07 1998 ++++ MakeTeXPK Tue Aug 18 07:53:57 1998 +@@ -1,5 +1,5 @@ + #!/bin/sh +-# original MakeTeXPK -- make a new PK font, because one wasn't found. ++# MakeTeXPK -- make a new PK font, because one wasn't found. + # Version of 12dec94. + # + # (If you change or delete the word `original' on the previous line, +@@ -142,11 +142,52 @@ + test -d $TEMPDIR || mkdir $TEMPDIR + cd $TEMPDIR || exit 1 + ++unset cmd ++ ++# test for TTF fonts ++if test -z "$cmd"; then ++ ttf2pk -q $NAME $DPI ++ errstatus=$? ++ ++ if test $errstatus -ne 2; then ++ if test $errstatus -ne 0; then ++ echo "ttf2pk failed" >&2 ++ exit 1 ++ fi ++ test -z "$6" && DESTDIR="$DESTROOT/ttf2pk" # preferred mode for TDS ++ # would be `modeless' ++ echo "Successful call to ttf2pk" >&2 ++ cmd=ttf2pk ++ fi ++fi ++ ++# test for HBF fonts ++if test -z "$cmd"; then ++ hbf2gf -q -p $NAME $DPI ++ errstatus=$? ++ ++ if test $errstatus -ne 2; then ++ if test $errstatus -ne 0; then ++ echo "hbf2gf failed" >&2 ++ exit 1 ++ fi ++ test -z "$6" && DESTDIR="$DESTROOT/hbf2gf" # preferred mode for TDS ++ # would be `modeless' ++ echo "Successful call to hbf2gf" >&2 ++ cmd=hbf2gf ++ ++ gftopk ./$GFNAME $PKNAME || exit 1 ++ fi ++fi ++ + # grep for the font in $PSMAPFILE, if some ps-to-pk is claimed to be supported. + # We have to figure out the name of the base font -- $NAME is probably + # something like pplr, but it's rpplr or pplr0 or pplr8r that's in psfonts.map. +-pattern="^r?$NAME"'(0|8r)?([ ]|$)' +-test -n "$ps_to_pk" && egrep "$pattern" $PSMAPFILE >psline ++if test -z "$cmd"; then ++ pattern="^r?$NAME"'(0|8r)?([ ]|$)' ++ test -n "$ps_to_pk" && egrep "$pattern" $PSMAPFILE > psline ++fi ++ + if test -s psline; then + # This is a PostScript font. + MODE=$ps_to_pk +@@ -173,8 +214,9 @@ + export DVIPSHEADERS + echo "$0: Running $cmd" >&2 + $cmd >&2 || { echo "$0: $ps_to_pk failed." >&2; exit 1; } ++fi + +-else ++if test -z "$cmd"; then + # Try Metafont. + MFINPUTS="$MFINPUTS:$SAVEPWD" + export MFINPUTS diff --git a/contrib/ttf2pk/scripts/web2c-6.1/README b/contrib/ttf2pk/scripts/web2c-6.1/README new file mode 100644 index 0000000..eb12bec --- /dev/null +++ b/contrib/ttf2pk/scripts/web2c-6.1/README @@ -0,0 +1 @@ +This is for web2c-6.1 with the patch for kpathsea 2.6 diff --git a/contrib/ttf2pk/scripts/web2c-7.0/MakeTeXPK.diff b/contrib/ttf2pk/scripts/web2c-7.0/MakeTeXPK.diff new file mode 100644 index 0000000..23f7cb5 --- /dev/null +++ b/contrib/ttf2pk/scripts/web2c-7.0/MakeTeXPK.diff @@ -0,0 +1,67 @@ +--- MakeTeXPK.orig Sat Feb 8 15:52:00 1997 ++++ MakeTeXPK Tue Aug 18 07:58:22 1998 +@@ -1,5 +1,5 @@ + #!/bin/sh +-# original MakeTeXPK -- make a new PK font, because one wasn't found. ++# MakeTeXPK -- make a new PK font, because one wasn't found. + # + # (If you change or delete the word `original' on the previous line, + # installation won't write this script over yours.) +@@ -44,15 +44,54 @@ + MODE=$5 + DEST=$6 + ++unset cmd ++ ++# test for TTF fonts ++if test -z "$cmd"; then ++ ttf2pk -q $NAME $DPI ++ errstatus=$? ++ ++ if test $errstatus -ne 2; then ++ if test $errstatus -ne 0; then ++ echo "ttf2pk failed" >&2 ++ exit 1 ++ fi ++ MODE=modeless ++ cmd=true ++ fi ++fi ++ ++# test for HBF fonts ++if test -z "$cmd"; then ++ hbf2gf -q -p $NAME $DPI ++ errstatus=$? ++ ++ if test $errstatus -ne 2; then ++ if test $errstatus -ne 0; then ++ echo "hbf2gf failed" >&2 ++ exit 1 ++ fi ++ MODE=modeless ++ cmd=true ++ fi ++fi ++ ++unset psline ++ + # grep for the font in $PSMAPFILE. These are base font names, such as + # rpplr (the original) or pplr0 (an interim step) or pplr8r (current). +-pattern="^r?$NAME"'(0|8r)?([ ]|$)' +-psline=`egrep "$pattern" $PSMAPFILE` ++if test -z "$cmd"; then ++ pattern="^r?$NAME"'(0|8r)?([ ]|$)' ++ psline=`egrep "$pattern" $PSMAPFILE` ++fi ++ + if test -n "$psline"; then + MODE=modeless + # ps_to_pk set in MakeTeXcommon and/or MakeTeX.site. + cmd="$ps_to_pk $NAME $DPI" +-else ++fi ++ ++if test -z "$cmd"; then + # Check that $BDPI and $MODE are consistent; if not, ignore the mode and + # hope we can correctly guess it from bdpi. (People like to specify the + # resolution on the command line, not the mode so much.) diff --git a/contrib/ttf2pk/scripts/web2c-7.1/MakeTeXPK.diff b/contrib/ttf2pk/scripts/web2c-7.1/MakeTeXPK.diff new file mode 100644 index 0000000..3ca0221 --- /dev/null +++ b/contrib/ttf2pk/scripts/web2c-7.1/MakeTeXPK.diff @@ -0,0 +1,72 @@ +--- MakeTeXPK.orig Fri Oct 31 09:30:54 1997 ++++ MakeTeXPK Tue Aug 18 08:01:33 1998 +@@ -1,5 +1,5 @@ + #!/bin/sh +-# original MakeTeXPK -- make a new PK font, because one wasn't found. ++# MakeTeXPK -- make a new PK font, because one wasn't found. + # + # (If you change or delete the word `original' on the previous line, + # installation won't write this script over yours.) +@@ -57,11 +57,48 @@ + MODE=$5 + DEST=$6 + ++unset cmd ++ ++# test for TTF fonts ++if test -z "$cmd"; then ++ ttf2pk -q $NAME $DPI ++ errstatus=$? ++ ++ if test $errstatus -ne 2; then ++ if test $errstatus -ne 0; then ++ echo "ttf2pk failed" >&2 ++ exit 1 ++ fi ++ MODE=modeless ++ cmd=true ++ fi ++fi ++ ++# test for HBF fonts ++if test -z "$cmd"; then ++ hbf2gf -q -p $NAME $DPI ++ errstatus=$? ++ ++ if test $errstatus -ne 2; then ++ if test $errstatus -ne 0; then ++ echo "hbf2gf failed" >&2 ++ exit 1 ++ fi ++ MODE=modeless ++ cmd=true ++ fi ++fi ++ ++unset psline ++ + # grep for the font in $PSMAPFILE. These are base font names, such as + # rpplr (the original) or pplr0 (an interim step) or pplr8r (current). +-: ${PSMAPFILE=`kpsewhich psfonts.map`} +-pattern="^$NAME"'([ ]|$)' +-psline=`egrep "$pattern" $PSMAPFILE` ++if test -z "$cmd"; then ++ : ${PSMAPFILE=`kpsewhich psfonts.map`} ++ pattern="^$NAME"'([ ]|$)' ++ psline=`egrep "$pattern" $PSMAPFILE` ++fi ++ + if test -n "$psline"; then + MODE=modeless + # ps_to_pk is set in MakeTeX.cnf +@@ -100,7 +137,9 @@ + cmd="$ps_to_pk $NAME $DPI" + ;; + esac +-else ++fi ++ ++if test -z "$cmd"; then + # Check that $BDPI and $MODE are consistent; if not, ignore the mode and + # hope we can correctly guess it from bdpi. (People like to specify the + # resolution on the command line, not the mode so much.) diff --git a/contrib/ttf2pk/scripts/web2c-7.1/README b/contrib/ttf2pk/scripts/web2c-7.1/README new file mode 100644 index 0000000..ae64fa7 --- /dev/null +++ b/contrib/ttf2pk/scripts/web2c-7.1/README @@ -0,0 +1 @@ +The patch works with web2c-7.0 too (expect a fuzz offset). diff --git a/contrib/ttf2pk/scripts/web2c-7.2/mktexpk.diff b/contrib/ttf2pk/scripts/web2c-7.2/mktexpk.diff new file mode 100644 index 0000000..bc215d0 --- /dev/null +++ b/contrib/ttf2pk/scripts/web2c-7.2/mktexpk.diff @@ -0,0 +1,72 @@ +--- mktexpk.orig Fri Feb 20 16:23:22 1998 ++++ mktexpk Tue Aug 18 08:04:40 1998 +@@ -1,5 +1,5 @@ + #!/bin/sh +-# original mktexpk -- make a new PK font, because one wasn't found. ++# mktexpk -- make a new PK font, because one wasn't found. + # + # (If you change or delete the word `original' on the previous line, + # installation won't write this script over yours.) +@@ -73,11 +73,48 @@ + + NAME=$1 + ++unset cmd ++ ++# test for TTF fonts ++if test -z "$cmd"; then ++ ttf2pk -q $NAME $DPI ++ errstatus=$? ++ ++ if test $errstatus -ne 2; then ++ if test $errstatus -ne 0; then ++ echo "ttf2pk failed" >&2 ++ exit 1 ++ fi ++ MODE=modeless ++ cmd=true ++ fi ++fi ++ ++# test for HBF fonts ++if test -z "$cmd"; then ++ hbf2gf -q -p $NAME $DPI ++ errstatus=$? ++ ++ if test $errstatus -ne 2; then ++ if test $errstatus -ne 0; then ++ echo "hbf2gf failed" >&2 ++ exit 1 ++ fi ++ MODE=modeless ++ cmd=true ++ fi ++fi ++ ++unset psline ++ + # grep for the font in $PSMAPFILE. These are base font names, such as + # rpplr (the original) or pplr0 (an interim step) or pplr8r (current). +-: ${PSMAPFILE=`kpsewhich psfonts.map`} +-pattern="^$NAME"'([ ]|$)' +-psline=`egrep "$pattern" $PSMAPFILE` ++if test -z "$cmd"; then ++ : ${PSMAPFILE=`kpsewhich psfonts.map`} ++ pattern="^$NAME"'([ ]|$)' ++ psline=`egrep "$pattern" $PSMAPFILE` ++fi ++ + if test -n "$psline"; then + MODE=modeless + # ps_to_pk is set in mktex.opt +@@ -116,7 +153,9 @@ + cmd="$ps_to_pk $NAME $DPI" + ;; + esac +-else ++fi ++ ++if test -z "$cmd"; then + # Check that $BDPI and $MODE are consistent; if not, ignore the mode and + # hope we can correctly guess it from bdpi. (People like to specify the + # resolution on the command line, not the mode so much.) diff --git a/contrib/ttf2pk/subfont.c b/contrib/ttf2pk/subfont.c new file mode 100644 index 0000000..0380773 --- /dev/null +++ b/contrib/ttf2pk/subfont.c @@ -0,0 +1,264 @@ +/* + * subfont.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#include +#include +#include /* for size_t */ +#include +#include + +#include "filesrch.h" +#include "subfont.h" +#include "newobj.h" +#include "errormsg.h" + + +static char *real_sfd_name; +static FILE *sfd; + + +/* + * Initialize subfont functionality. The argument is the subfont + * definition file name. If `fatal' is `True', the routine exits + * with an error. If `fatal' is `False', a warning message is emitted + * and `False' returned if an error occurs; in case of success `True' + * will be returned. + */ + +Boolean +init_sfd(Font *fnt, Boolean fatal) +{ + real_sfd_name = TeX_search_sfd_file(&(fnt->sfdname)); + if (!real_sfd_name) + { + if (fatal) + oops("Cannot find subfont definition file `%s'.", fnt->sfdname); + else + { + warning("Cannot find subfont definition file `%s'.", fnt->sfdname); + return False; + } + } + + sfd = fopen(real_sfd_name, "rt"); + if (sfd == NULL) + { + if (fatal) + oops("Cannot open subfont definition file `%s'.", fnt->sfdname); + else + { + warning("Cannot open subfont definition file `%s'.", fnt->sfdname); + return False; + } + } + + return True; +} + + +/* + * This function fills the font structure sequentially with subfont + * entries; it returns `False' if no more subfont entries are available, + * `True' otherwise. + * + * fnt->subfont_name must be set to NULL before the first call. + * + * The subset parser was inspired by ttf2bdf.c . + */ + +Boolean +get_sfd(Font *fnt) +{ + long i, offset; + long begin, end = -1; + char *buffer, *oldbuffer, *bufp, *bufp2, *bufp3; + + + for (i = 0; i < 256; i++) + fnt->sf_code[i] = -1; + +again: + + buffer = get_line(sfd); + if (!buffer) + oops("Error reading subfont definition file `%s'.", real_sfd_name); + if (!*buffer) + return False; + + oldbuffer = newstring(buffer); + bufp = buffer; + offset = 0; + + while (*bufp) /* remove comment */ + { + if (*bufp == '#') + { + bufp++; + break; + } + bufp++; + } + *(--bufp) = '\0'; /* remove final newline character */ + + bufp = buffer; + + while (isspace(*bufp)) + bufp++; + + if (*bufp == '\0') /* empty line? */ + { + free(buffer); + free(oldbuffer); + goto again; + } + + while (*bufp && !isspace(*bufp)) /* subfont name */ + bufp++; + *(bufp++) = '\0'; + + while (isspace(*bufp)) + bufp++; + + if (*bufp == '\0') + oops("Invalid subfont entry in `%s'.", real_sfd_name); + + if (fnt->subfont_name) + free(fnt->subfont_name); + fnt->subfont_name = newstring(buffer); + + while (1) + { + bufp3 = bufp; + + begin = strtol(bufp, &bufp2, 0); + + if (bufp == bufp2 || begin < 0 || begin > 0xFFFF) + boops(oldbuffer, bufp - buffer, + "Invalid subfont range or offset entry."); + + if (*bufp2 == ':') /* offset */ + { + offset = begin; + if (offset > 0xFF) + boops(oldbuffer, bufp - buffer, "Invalid subfont offset."); + + bufp = bufp2 + 1; + + while (isspace(*bufp)) + bufp++; + + continue; + } + else if (*bufp2 == '_') /* range */ + { + bufp = bufp2 + 1; + if (!isdigit(*bufp)) + boops(oldbuffer, bufp - buffer, "Invalid subfont range entry."); + + end = strtol(bufp, &bufp2, 0); + + if (bufp == bufp2 || end < 0 || end > 0xFFFFL) + boops(oldbuffer, bufp - buffer, "Invalid subfont range entry."); + if (*bufp2 && !isspace(*bufp2)) + boops(oldbuffer, bufp2 - buffer, "Invalid subfont range entry."); + if (end < begin) + boops(oldbuffer, bufp - buffer, "End of subfont range too small."); + if (offset + (end - begin) > 255) + boops(oldbuffer, bufp3 - buffer, + "Subfont range too large for current offset (%i).", offset); + } + else if (isspace(*bufp2) || !*bufp2) /* single value */ + end = begin; + else + boops(oldbuffer, bufp2 - buffer, "Invalid subfont range entry."); + + for (i = begin; i <= end; i++) + { + if (fnt->sf_code[offset] != -1) + boops(oldbuffer, bufp3 - buffer, "Overlapping subfont ranges."); + + fnt->sf_code[offset++] = i; + } + + bufp = bufp2; + + while (isspace(*bufp)) + bufp++; + + if (!*bufp) + break; + } + + free(buffer); + free(oldbuffer); + + return True; +} + + +void +close_sfd(void) +{ + if (sfd) + fclose(sfd); +} + + +/* + * We extract the subfont definition file name. The name must + * be embedded between two `@' characters. If there is no sfd file, + * `sfd_begin' is set to -1. + * + * The `@' characters will be replaced with null characters. + */ + +void +handle_sfd(char *s, int *sfd_begin, int *postfix_begin) +{ + size_t len; + int i; + Boolean have_atsign; + + + have_atsign = False; + len = strlen(s); + *sfd_begin = -1; + *postfix_begin = -1; + + for (i = 0; s[i]; i++) + { + if (s[i] == '@') + { + if (have_atsign) + { + *postfix_begin = i + 1; + + s[i] = '\0'; + break; + } + have_atsign = True; + *sfd_begin = i + 1; + + s[i] = '\0'; + } + } + + if (*sfd_begin != -1 && + (*postfix_begin == -1 || *postfix_begin < *sfd_begin + 2)) + oops("Invalid subfont definition file name."); + + if (*postfix_begin > -1) + for (i = *postfix_begin; s[i]; i++) + if (s[i] == '/' || s[i] == ':' || s[i] == '\\' || s[i] == '@') + oops("`/', `:', `\\', and `@' not allowed after second `@'."); +} + + +/* end */ diff --git a/contrib/ttf2pk/subfont.h b/contrib/ttf2pk/subfont.h new file mode 100644 index 0000000..db1948c --- /dev/null +++ b/contrib/ttf2pk/subfont.h @@ -0,0 +1,26 @@ +/* + * subfont.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef SUBFONT_H +#define SUBFONT_H + +#include "ttf2tfm.h" + + +Boolean init_sfd(Font *fnt, Boolean fatal); +Boolean get_sfd(Font *fnt); +void close_sfd(void); + +void handle_sfd(char *s, int *sfd_begin, int *postfix_begin); + +#endif /* SUBFONT_H */ + + +/* end */ diff --git a/contrib/ttf2pk/texenc.c b/contrib/ttf2pk/texenc.c new file mode 100644 index 0000000..aa09657 --- /dev/null +++ b/contrib/ttf2pk/texenc.c @@ -0,0 +1,203 @@ +/* + * texenc.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#include /* for definition of NULL */ + +#include "ttf2tfm.h" +#include "texenc.h" + + +encoding staticencoding = +{ + "TeX text", + {"Gamma", "Delta", "Theta", "Lambda", + "Xi", "Pi", "Sigma", "Upsilon", + "Phi", "Psi", "Omega", "arrowup", + "arrowdown", "quotesingle", "exclamdown", "questiondown", + + "dotlessi", "dotlessj", "grave", "acute", + "caron", "breve", "macron", "ring", + "cedilla", "germandbls", "ae", "oe", + "oslash", "AE", "OE", "Oslash", + + "space", "exclam", "quotedbl", "numbersign", + "dollar", "percent", "ampersand", "quoteright", + "parenleft", "parenright", "asterisk", "plus", + "comma", "hyphen", "period", "slash", + + "zero", "one", "two", "three", + "four", "five", "six", "seven", + "eight", "nine", "colon", "semicolon", + "less", "equal", "greater", "question", + + "at", "A", "B", "C", + "D", "E", "F", "G", + "H", "I", "J", "K", + "L", "M", "N", "O", + + "P", "Q", "R", "S", + "T", "U", "V", "W", + "X", "Y", "Z", "bracketleft", + "backslash", "bracketright", "circumflex", "underscore", + + "quoteleft", "a", "b", "c", + "d", "e", "f", "g", + "h", "i", "j", "k", + "l", "m", "n", "o", + + "p", "q", "r", "s", + "t", "u", "v", "w", + "x", "y", "z", "braceleft", + "bar", "braceright", "tilde", "dieresis", + + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + } +}; + + +/* + * It's easier to put this in static storage and parse it as we go + * than to build the structures ourselves. + * + * The semicolons in the LIGKERN lines must be left isolated. + */ + +char *staticligkern[] = +{ + "% LIGKERN space l =: lslash ; space L =: Lslash ;", + "% LIGKERN question quoteleft =: questiondown ;", + "% LIGKERN exclam quoteleft =: exclamdown ;", + "% LIGKERN hyphen hyphen =: endash ; endash hyphen =: emdash ;", + "% LIGKERN quoteleft quoteleft =: quotedblleft ;", + "% LIGKERN quoteright quoteright =: quotedblright ;", + "% LIGKERN space {} * ; * {} space ; zero {} * ; * {} zero ;", + "% LIGKERN one {} * ; * {} one ; two {} * ; * {} two ;", + "% LIGKERN three {} * ; * {} three ; four {} * ; * {} four ;", + "% LIGKERN five {} * ; * {} five ; six {} * ; * {} six ;", + "% LIGKERN seven {} * ; * {} seven ; eight {} * ; * {} eight ;", + "% LIGKERN nine {} * ; * {} nine ;", + + /* + * Kern accented characters the same way as their base. + */ + + "% LIGKERN Aacute <> A ; aacute <> a ;", + "% LIGKERN Acircumflex <> A ; acircumflex <> a ;", + "% LIGKERN Adieresis <> A ; adieresis <> a ;", + "% LIGKERN Agrave <> A ; agrave <> a ;", + "% LIGKERN Aring <> A ; aring <> a ;", + "% LIGKERN Atilde <> A ; atilde <> a ;", + "% LIGKERN Ccedilla <> C ; ccedilla <> c ;", + "% LIGKERN Eacute <> E ; eacute <> e ;", + "% LIGKERN Ecircumflex <> E ; ecircumflex <> e ;", + "% LIGKERN Edieresis <> E ; edieresis <> e ;", + "% LIGKERN Egrave <> E ; egrave <> e ;", + "% LIGKERN Iacute <> I ; iacute <> i ;", + "% LIGKERN Icircumflex <> I ; icircumflex <> i ;", + "% LIGKERN Idieresis <> I ; idieresis <> i ;", + "% LIGKERN Igrave <> I ; igrave <> i ;", + "% LIGKERN Ntilde <> N ; ntilde <> n ;", + "% LIGKERN Oacute <> O ; oacute <> o ;", + "% LIGKERN Ocircumflex <> O ; ocircumflex <> o ;", + "% LIGKERN Odieresis <> O ; odieresis <> o ;", + "% LIGKERN Ograve <> O ; ograve <> o ;", + "% LIGKERN Oslash <> O ; oslash <> o ;", + "% LIGKERN Otilde <> O ; otilde <> o ;", + "% LIGKERN Scaron <> S ; scaron <> s ;", + "% LIGKERN Uacute <> U ; uacute <> u ;", + "% LIGKERN Ucircumflex <> U ; ucircumflex <> u ;", + "% LIGKERN Udieresis <> U ; udieresis <> u ;", + "% LIGKERN Ugrave <> U ; ugrave <> u ;", + "% LIGKERN Yacute <> Y ; yacute <> y ;", + "% LIGKERN Ydieresis <> Y ; ydieresis <> y ;", + "% LIGKERN Zcaron <> Z ; zcaron <> z ;", + + /* lig commands for default ligatures */ + + "% LIGKERN f i =: fi ; f l =: fl ; f f =: ff ; ff i =: ffi ;", + "% LIGKERN ff l =: ffl ;", + NULL +}; + +/* + * The above layout corresponds to TeX Typewriter Type and is compatible + * with TeX Text because the position of ligatures is immaterial. + */ + + +/* + * These are the eight ligature ops, in VPL terms and in METAFONT terms. + */ + +char *vplligops[] = +{ + "LIG", "/LIG", "/LIG>", "LIG/", "LIG/>", "/LIG/", "/LIG/>", "/LIG/>>", 0 +}; + +char *encligops[] = +{ + "=:", "|=:", "|=:>", "=:|", "=:|>", "|=:|", "|=:|>", "|=:|>>", 0 +}; + + +/* + * For TeX we want to compute a character height that works properly + * with accents. The following list of accents doesn't need to be + * complete. + */ + +/* + * We only do this if the xheight has a reasonable value (>50). + */ + +char *accents[] = {"acute", "tilde", "caron", "dieresis", NULL}; + +char default_codingscheme[] = "Unspecified"; + + +/* end */ diff --git a/contrib/ttf2pk/texenc.h b/contrib/ttf2pk/texenc.h new file mode 100644 index 0000000..4df8339 --- /dev/null +++ b/contrib/ttf2pk/texenc.h @@ -0,0 +1,28 @@ +/* + * texenc.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef TEXENC_H +#define TEXENC_H + +#include "ttf2tfm.h" + + +extern encoding staticencoding; +extern char *staticligkern[]; +extern char *vplligops[]; +extern char *encligops[]; +extern char *accents[]; + +extern char default_codingscheme[]; + +#endif /* TEXENC_H */ + + +/* end */ diff --git a/contrib/ttf2pk/tfmaux.c b/contrib/ttf2pk/tfmaux.c new file mode 100644 index 0000000..4befc95 --- /dev/null +++ b/contrib/ttf2pk/tfmaux.c @@ -0,0 +1,579 @@ +/* + * tfmaux.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#include +#include +#include +#include + +#include "ttf2tfm.h" +#include "newobj.h" +#include "tfmaux.h" +#include "errormsg.h" + + +#undef PI +#define PI 3.14159265358979323846264338327 + + +struct sf /* we need this for subfont ligatures */ +{ + long sf_code; + int position; +}; + + +static long nextd; /* smallest value that will give a different mincover */ + + +static int lf, lh, nw, nh, nd, ni, nl, nk, ne, np; +static int bc, ec; + +static long *header, *charinfo, + *width, *height, *depth, + *ligkern, *kerns, *tparam, + *italic; + + +static int source[257]; /* utility variables for sorting tfm arrays */ +static int unsort[257]; + + +/* + * A simple function for sorting sf_array (in inverse order) + */ + +static int +compare_sf(const void *a, const void *b) +{ + return (int)(((struct sf *)b)->sf_code - ((struct sf *)a)->sf_code); +} + + +/* + * The next routine simply scales something. + * Input is in TFM units per em. Output is in FIXFACTORths of units + * per em. We use 1 em = 1000 TFM units. + */ + +static long +scale(long what) +{ + return ((what / 1000) * FIXFACTOR) + + (((what % 1000) * FIXFACTOR) + 500) / 1000; +} + + +/* + * Next we need a routine to reduce the number of distinct dimensions + * in a TFM file. Given an array what[0]..what[oldn-1], we want to + * group its elements into newn clusters, in such a way that the maximum + * difference between elements of a cluster is as small as possible. + * Furthermore, what[0]=0, and this value must remain in a cluster by + * itself. Data such as `0 4 6 7 9' with newn=3 shows that an iterative + * scheme in which 6 is first clustered with 7 will not work. So we + * borrow a neat algorithm from METAFONT to find the true optimum. + * Memory location what[oldn] is set to 0x7FFFFFFFL for convenience. + */ + + +/* + * Tells how many clusters result, given max difference d. + */ + +static int +mincover(long *what, + register long d) +{ + register int m; + register long l; + register long *p; + + + nextd = 0x7FFFFFFFL; + p = what+1; + m = 1; + + while (*p < 0x7FFFFFFFL) + { + m++; + l = *p; + while (*++p <= l + d) + ; + if (*p - l < nextd) + nextd = *p - l; + } + return m; +} + + +static void +remap(long *what, + int oldn, + int newn, + int *source, + int *unsort) +{ + register int i, j; + register long d, l; + + what[oldn] = 0x7FFFFFFFL; + for (i = oldn-1; i > 0; i--) + { + d = what[i]; + for (j = i; what[j+1] < d; j++) + { + what[j] = what[j+1]; + source[j] = source[j+1]; + } + what[j] = d; + source[j] = i; + } + + i = mincover(what, 0L); + d = nextd; + while (mincover(what, d + d) > newn) + d += d; + while (mincover(what, d) > newn) + d = nextd; + + i = 1; + j = 0; + while (i < oldn) + { + j++; + l = what[i]; + unsort[source[i]] = j; + while (what[++i] <= l + d) + { + unsort[source[i]] = j; + if (i - j == oldn - newn) + d = 0; + } + what[j] = (l + what[i-1])/2; + } +} + + +void +write16(register short what, + register FILE *out) +{ + (void)fputc(what >> 8, out); + (void)fputc(what & 0xFF, out); +} + + +void +writearr(register long *p, + register int n, + register FILE *out) +{ + while (n) + { + write16((short)(*p >> 16), out); + write16((short)(*p & 65535), out); + p++; + n--; + } +} + + +void +writesarr(long *what, + int len, + FILE *out) +{ + register long *p; + int i; + + + p = what; + i = len; + while (i) + { + *p = scale(*p); + (void)scale(*p); /* need this kludge for some compilers */ + p++; + i--; + } + writearr(what, len, out); +} + + +static long * +makebcpl(register long *p, + register char *s, + register int n) +{ + register long t; + register long sc; + + + if (strlen(s) < n) + n = strlen(s); + t = ((long)n) << 24; + sc = 16; + + while (n > 0) + { + t |= ((long)(*(unsigned char *)s++)) << sc; + sc -= 8; + if (sc < 0) + { + *p++ = t; + t = 0; + sc = 24; + } + n--; + } + if (t) + *p++ = t; + + return p; +} + + +static long +checksum(ttfinfo **array) +{ + int i; + unsigned long s1 = 0, s2 = 0; + char *p; + ttfinfo *ti; + + + for (i = 0; i < 256; i++) + if (NULL != (ti = array[i])) + { + s1 = ((s1 << 1) ^ (s1 >> 31)) ^ ti->width; /* cyclic left shift */ + s1 &= 0xFFFFFFFF; /* in case we're on a 64-bit machine */ + + for (p = ti->adobename; *p; p++) + s2 = (s2 * 3) + *p; + } + + s1 = (s1 << 1) ^ s2; + return s1; +} + + +int +transform(register int x, register int y, + float ef, float sl) +{ + register double acc; + + + acc = ef * x + sl * y; + return (int)(acc >= 0 ? floor(acc + 0.5) : ceil(acc - 0.5)); +} + + +int +buildtfm(Font *fnt) +{ + register int i, j; + register ttfinfo *ti; + int byte1, old_byte1, byte2; + long cksum; + double Slant; + char buffer[256]; + struct sf sf_array[256]; + + + if (fnt->subfont_ligs) + { + for (i = 0; i < 256; i++) + { + ti = fnt->inencptrs[i]; + if (ti) + { + sf_array[i].sf_code = ti->charcode; + sf_array[i].position = i; + } + else + { + sf_array[i].sf_code = -1; + sf_array[i].position = -1; + } + } + /* we sort the subfont character codes before we build a ligkern list */ + qsort(sf_array, 256, sizeof (struct sf), compare_sf); + + /* we need to create dummy characters for the ligatures in case the + character slots of the affected codes are unused */ + i = 0; + while (i < 256 && sf_array[i].sf_code > -1) + { + byte1 = sf_array[i].sf_code >> 8; + byte2 = sf_array[i].sf_code & 0xFF; + if (!fnt->inencptrs[byte1]) + { + ti = newchar(fnt); + ti->llx = ti->lly = 0; + ti->urx = ti->ury = 0; + ti->width = 0; + fnt->inencptrs[byte1] = ti; + ti->incode = byte1; + ti->adobename = ".dummy"; + } + if (!fnt->inencptrs[byte2]) + { + ti = newchar(fnt); + ti->llx = ti->lly = 0; + ti->urx = ti->ury = 0; + ti->width = 0; + fnt->inencptrs[byte2] = ti; + ti->incode = byte2; + ti->adobename = ".dummy"; + } + i++; + } + } + + for (i = 0; i <= 0xFF && fnt->inencptrs[i] == NULL; i++) + ; + bc = i; + for (i = 0xFF; i >= 0 && fnt->inencptrs[i] == NULL; i--) + ; + ec = i; + + if (ec < bc) + { + if (fnt->sfdname) + return 0; + else + oops("No TTF characters."); + } + + header = (long *)mymalloc(40000L); + cksum = checksum(fnt->inencptrs); + header[0] = cksum; + header[1] = 0xA00000; /* 10pt design size */ + + (void)makebcpl(header + 2, fnt->codingscheme, 39); + (void)makebcpl(header + 12, fnt->fullname, 19); + + /* 4 bytes are left free for the unused FACE value */ + + buffer[0] = '\0'; + strncat(buffer, "Created by `", 12); + strncat(buffer, fnt->titlebuf, 255 - 12 - 1); + strncat(buffer, "'", 1); + charinfo = makebcpl(header + 18, buffer, 255); + lh = charinfo - header; + + width = charinfo + (ec - bc + 1); + width[0] = 0; + nw = 1; + + for (i = bc; i <= ec; i++) + if (NULL != (ti = fnt->inencptrs[i])) + { + width[nw] = ti->width; + for (j = 1; width[j] != ti->width; j++) + ; + ti->wptr = j; + if (j == nw) + nw++; + } + if (nw > 256) + oops("256 chars with different widths."); + + depth = width + nw; + depth[0] = 0; + nd = 1; + + for (i = bc; i <= ec; i++) + if (NULL != (ti = fnt->inencptrs[i])) + { + depth[nd] = -ti->lly; + for (j = 0; depth[j] != -ti->lly; j++) + ; + ti->dptr = j; + if (j == nd) + nd++; + } + + if (nd > 16) + { + remap(depth, nd, 16, source, unsort); + nd = 16; + for (i = bc; i <= ec; i++) + if (NULL != (ti = fnt->inencptrs[i])) + ti->dptr = unsort[ti->dptr]; + } + + height = depth + nd; + height[0] = 0; + nh = 1; + + for (i = bc; i <= ec; i++) + if (NULL != (ti = fnt->inencptrs[i])) + { + height[nh] = ti->ury; + for (j = 0; height[j] != ti->ury; j++) + ; + ti->hptr = j; + if (j == nh) + nh++; + } + + if (nh > 16) + { + remap(height, nh, 16, source, unsort); + nh = 16; + for (i = bc; i <= ec; i++) + if (NULL != (ti = fnt->inencptrs[i])) + ti->hptr = unsort[ti->hptr]; + } + + italic = height + nh; + italic[0] = 0; + ni = 1; + + for (i = bc; i <= ec; i++) + if (NULL != (ti = fnt->inencptrs[i])) + { + italic[ni] = ti->urx - ti->width; + if (italic[ni] < 0) + italic[ni] = 0; + for (j = 0; italic[j] != italic[ni]; j++) + ; + ti->iptr = j; + if (j == ni) + ni++; + } + + if (ni > 64) + { + remap(italic, ni, 64, source, unsort); + ni = 64; + for (i = bc; i <= ec; i++) + if (NULL != (ti = fnt->inencptrs[i])) + ti->iptr = unsort[ti->iptr]; + } + + for (i = bc; i <= ec; i++) + if (NULL != (ti = fnt->inencptrs[i])) + charinfo[i - bc] = ((long)(ti->wptr) << 24) + + ((long)(ti->hptr) << 20) + + ((long)(ti->dptr) << 16) + + ((long)(ti->iptr) << 10); + else + charinfo[i - bc] = 0; + + ligkern = italic + ni; + nl = 0; + + if (fnt->subfont_ligs) + { + /* Now we build the ligature list. The ligature consisting of character + code byte1 + byte2 should yield the actual character. The fonts of + the HLaTeX package for Korean use this mechanism. */ + + old_byte1 = -1; + while (nl < 256 && sf_array[nl].sf_code > -1) + { + byte1 = sf_array[nl].sf_code >> 8; + byte2 = sf_array[nl].sf_code & 0xFF; + if (byte1 != old_byte1) + { + charinfo[byte1 - bc] += 0x100L + /* set the lig tag */ + nl; /* set the position in array */ + if (old_byte1 > -1) + ligkern[nl - 1] |= 0x80000000L; /* set the STOP byte in previous + ligkern command */ + } + + ligkern[nl] = ((long)byte2 << 16) + + (long)sf_array[nl].position; + old_byte1 = byte1; + nl++; + } + ligkern[nl - 1] |= 0x80000000L; + } + + kerns = ligkern + nl; + nk = 0; /* kerns are omitted from raw TeX font */ + + Slant = fnt->slant - fnt->efactor * tan(fnt->italicangle * (PI / 180.0)); + + tparam = kerns + nk; + tparam[0] = (long)(FIXFACTOR * Slant + 0.5); + tparam[1] = scale((long)fnt->fontspace); + tparam[2] = (fnt->fixedpitch ? 0 : scale((long)(300 * fnt->efactor + 0.5))); + tparam[3] = (fnt->fixedpitch ? 0 : scale((long)(100 * fnt->efactor + 0.5))); + tparam[4] = scale((long)fnt->xheight); + tparam[5] = scale((long)(1000 * fnt->efactor + 0.5)); + np = 6; + + return 1; +} + + +void +writetfm(Font *fnt) +{ + FILE *out; + char *tfm_name; + int len = 0; + + + if (fnt->tfm_path) + len += strlen(fnt->tfm_path); + len += strlen(fnt->fullname); + len += strlen(fnt->tfm_ext); + len++; + + tfm_name = (char *)mymalloc(len); + tfm_name[0] = '\0'; + if (fnt->tfm_path) + strcat(tfm_name, fnt->tfm_path); + strcat(tfm_name, fnt->fullname); + strcat(tfm_name, fnt->tfm_ext); + + if ((out = fopen(tfm_name, "wb")) == NULL) + oops("Cannot open tfm file `%s'.", tfm_name); + + free(tfm_name); + + + lf = 6 + lh + (ec - bc + 1) + nw + nh + nd + ni + nl + nk + ne + np; + + write16(lf, out); + write16(lh, out); + write16(bc, out); + write16(ec, out); + write16(nw, out); + write16(nh, out); + write16(nd, out); + write16(ni, out); + write16(nl, out); + write16(nk, out); + write16(ne, out); + write16(np, out); + writearr(header, lh, out); + writearr(charinfo, ec - bc + 1, out); + writesarr(width, nw, out); + writesarr(height, nh, out); + writesarr(depth, nd, out); + writesarr(italic, ni, out); + writearr(ligkern, nl, out); + writesarr(kerns, nk, out); + writearr(tparam, np, out); + + free(header); + fclose(out); +} + + +/* end */ diff --git a/contrib/ttf2pk/tfmaux.h b/contrib/ttf2pk/tfmaux.h new file mode 100644 index 0000000..1a951e4 --- /dev/null +++ b/contrib/ttf2pk/tfmaux.h @@ -0,0 +1,28 @@ +/* + * tfmaux.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef TFMAUX_H +#define TFMAUX_H + +#include "ttf2tfm.h" + + +#define FIXFACTOR (0x100000L) /* 2^{20}, the unit fixnum */ + + +int transform(int x, int y, float ef, float sl); + +int buildtfm(Font *fnt); +void writetfm(Font *fnt); + +#endif /* TFMAUX_H */ + + +/* end */ diff --git a/contrib/ttf2pk/ttf2pk.1 b/contrib/ttf2pk/ttf2pk.1 new file mode 100644 index 0000000..64d5ece --- /dev/null +++ b/contrib/ttf2pk/ttf2pk.1 @@ -0,0 +1,289 @@ +.\" man page for ttf2pk +. +.TH TTF2PK 1 15-Aug-1999 "FreeType version 1.3" +.SH NAME +ttf2pk \- convert a TrueType font into TeX's PK format +.SH SYNOPSIS +.na +.nh +.B ttf2pk +.RB [ -q ] +.RB [ -n ] +.I "\%font-name \%resolution" +.br +.B ttf2pk +.B -t +.RB [ -q ] +.I \%font-name +.br +.B "ttf2pk --version" +| +.B --help +.ad +.hy +. +. +. +.\" ==== +.\" ==== macro definitions +.\" ==== +. +.\" here we define \TeX for troff and nroff +.if t .ds TX \fRT\\h'-0.1667m'\\v'0.20v'E\\v'-0.20v'\\h'-0.125m'X\fP +.if n .ds TX TeX +. +.\" and here the same for \LaTeX +.if t \{\ +.ie '\*(.T'dvi' \ +.ds LX \fRL\h'-0.36m'\v'-0.15v'\s-3A\s0\h'-0.15m'\v'0.15v'\fP\*(TX +.el .ds LX \fRL\h'-0.36m'\v'-0.22v'\s-2A\s0\h'-0.15m'\v'0.22v'\fP\*(TX +.\} +.if n .ds LX LaTeX +. +.\" \LaTeXe +.\" note that we need \vareps for TeX instead of \eps which can only be +.\" accessed with the \N escape sequence (in the Math Italic font) +.if t \{\ +.ie '\*(.T'dvi' .ds LE \*(LX\h'0.15m'2\v'0.20v'\f(MI\N'34'\fP\v'-0.20v' +.el .ds LE \*(LX\h'0.15m'2\v'0.20v'\(*e\v'-0.20v' +.\} +.if n .ds LE LaTeX\ 2e +. +.\" a typewriter font +.if t \{\ +.de C +\fC\\$1\fP\\$2 +.. +.\} +.if n \{\ +.de C +\\$1\\$2 +.. +.\} +. +.\" ==== +.\" ==== end of macro definitions +.\" ==== +. +. +. +.SH DESCRIPTION +This program converts a TrueType font into a +.C PK +file; the created font can then be used with \*(TX +or \*(LX. +.PP +All TrueType fonts to be used must be registered in a configuration +file called +.C \%ttfonts.map ; +it specifies how to handle each font. +CJKV (Chinese/Japanese/Korean/old Vietnamese) subfonts as created by +.B ttf2tfm +are also supported. +.PP +.B ttf2pk +always assumes 10pt as the design size for the written \*(TX +font. +. +. +.SH PARAMETERS +.TP +.B -q +This optional switch makes +.B ttf2pk +quiet. +It suppresses any informational output except warning and error +messages. +.TP +.B -n +Use only `\c +.C \&.pk ' +as the extension instead of `\c +.C \&. \c +.RI < \%resolution >\c +.C pk '. +.TP +.B -t +Test for the existence of +.IR \%font-name . +Returns 0 on success and prints out the corresponding line in +.C \%ttfonts.map +(provided the +.B -q +switch isn't set). +.TP +.I font-name +The \*(TX +name of the font. +.B ttf2pk +looks this name up in a configuration file called +.C \%ttfonts.map +for further information how to process the font. +.TP +.I resolution +The resolution, given in dots per inch. +Currently the horizontal resolution is equal to the vertical +resolution. +The design size is always assumed to be 10pt. +.TP +.B --version +Shows the current version of +.B ttf2pk +and the used file search library (e.g.\ \c +.BR kpathsea ). +.TP +.B --help +Shows usage information. +.PP +Environment variables for file searching are described in the manual page +of +.BR ttf2tfm . +. +. +.SH "THE CONFIGURATION FILE" +.B ttf2pk +uses, similar to +.BR dvips , +a font definition file called +.C \%ttfonts.map . +The parameters specified to +.B ttf2tfm +are here preserved\(em\c +.B ttf2tfm +writes out to standard output, as the last line, a proper +configuration entry for +.C \%ttfonts.map . +.PP +As an example, a call to +.PP +.in +2m +.C "ttf2tfm arial -p T1.enc -s 0.25 -P 1 -E 0 arials" +.PP +will produce the following line: +.PP +.in +2m +.C "arials arial Slant=0.25 Pid=1 Eid=0 Encoding=T1.enc" +.PP +See +.BR ttf2tfm (1) +and +.BR afm2tfm (1) +of the +.B dvips +package for a detailed description of encoding files. +.PP +Here a table listing the various +.B ttf2tfm +parameters and the corresponding +.C \%ttfonts.map +entries: +.PP +.in +4m +.ta 2i +-s Slant +.br +-e Extend +.br +-p Encoding +.br +-f Fontindex +.br +-P Pid +.br +-E Eid +.br +-n PS=Yes +.br +-N PS=Only +.br +-R Replacement +.br +-x Rotate=Yes +.br +-y Y-Offset +.PP +Single replacement glyph names given to +.B ttf2tfm +with `\c +.BI -r \ old-glyphname\ new-glyphname\c +\&' +are directly specified with `\c +.IR old-glyphname = new-glyphname '. +They will be ignored if in subfont mode or if no encoding file is given. +.PP +One additional parameter in +.C \%ttfonts.map +is unique to +.BR ttf2pk : +`Hinting', which can take the values `On' or `Off'. +Some fonts (e.g.\ the CJK part of +.C \%cyberbit.ttf ) +are rendered incorrectly if hinting is activated. +Default is `On' (you can also use `Yes', `No', `1', and `0'). +.PP +For a description of subfonts (i.e., entries of the form `\c +.I \c +.C @\c +.I \c +.C @ ') +please refer to +.BR ttf2tfm (1). +.PP +The format of +.C \%ttfonts.map +is simple. +Each line defines a font; first comes the \*(TX +font name, then its TrueType font file name, followed by the +parameters in any order. +Case is significant (even for parameter names); the parameters are +separated from its values by an equal sign, with whitespace possibly +surrounding it. +.B ttf2pk +reads in +.C \%ttfonts.map +line by line, continuing until the \*(TX +font specified on the command line is found, otherwise the programs +exits with error code\ 2. +Thus you can use any character invalid in a \*(TX +font name to start a comment line. +.PP +You can use `\\' as the final character of a line to indicate that the +input is continued on the next line. +The backslash and the following newline character will be removed. +.PP +.B ttf2pk +will abort if it can't find or read the \*(TX +font metrics file of the given \*(TX +font name. +. +. +.SH "RETURN VALUE" +If the call was successful, 0\ will be returned. +In case of error, the return value is\ 1. +Finally, if the font can't be found in +.C \%ttfonts.map , +2\ is returned. +This simplifies the inclusion of +.B ttf2pk +into scripts like +.B mktexpk +for automatic font generation. +. +. +.SH "SEE ALSO" +.BR ttf2tfm (1), +.BR afm2tfm (1) +. +. +.SH AVAILABILITY +.B ttf2pk +is part of the FreeType package, a high quality TrueType rendering +library. +. +. +.SH AUTHORS +Werner LEMBERG +.C +.br +Fr\('ed\('eric LOYER +.C diff --git a/contrib/ttf2pk/ttf2pk.c b/contrib/ttf2pk/ttf2pk.c new file mode 100644 index 0000000..593f844 --- /dev/null +++ b/contrib/ttf2pk/ttf2pk.c @@ -0,0 +1,592 @@ +/* + * ttf2pk.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#include +#include +#include /* for size_t */ +#include +#include +#include + + +#include "ttf2tfm.h" +#include "newobj.h" +#include "pklib.h" +#include "ttfenc.h" +#include "ttflib.h" +#include "errormsg.h" +#include "filesrch.h" +#include "parse.h" +#include "subfont.h" + + +char ident[] = "ttf2pk version 1.3"; +char progname[] = "ttf2pk"; /* for error/warning messages */ + + +Boolean have_sfd = False; +Boolean have_pid = False; +Boolean have_eid = False; + + +/* + * Checks for an equal sign surrounded by whitespace. + */ + +static char * +strip_equal(char *s, char *os, char *p) +{ + while (isspace(*p)) + p++; + if (*p != '=') + boops(os, p - s, "Missing `='."); + p++; + while (isspace(*p)) + p++; + return p; +} + + +#define USAGE "\ + Convert a TrueType font to TeX's PK format.\n\ +\n\ +-q suppress informational output\n\ +-n only use `.pk' as extension\n\ +-t test for (returns 0 on success)\n\ +--help print this message and exit\n\ +--version print version number and exit\n\ +" + +static void +usage(void) +{ + fputs("Usage: ttf2pk [-q] [-n] \n", stdout); + fputs(" ttf2pk -t [-q] \n", stdout); + fputs(USAGE, stdout); + exit(0); +} + + +#define VERSION "\ +Copyright (C) 1997-1999 Frederic Loyer and Werner Lemberg.\n\ +There is NO warranty. You may redistribute this software\n\ +under the terms of the GNU General Public License\n\ +and the gsftopk copyright.\n\ +\n\ +For more information about these matters, see the files\n\ +named COPYING and pklib.c.\n\ +\n\ +Primary authors of ttf2pk: F. Loyer and W. Lemberg.\n\ +\n\ +ttf2pk is partially based on gsftopk from P. Vojta\n\ +and the FreeType project from\n\ +David Turner, Robert Wilhelm, and Werner Lemberg\n\ +" + +static void +version(void) +{ + fputs(ident, stdout); + fprintf(stdout, " (%s)\n", TeX_search_version()); + fputs(VERSION, stdout); + exit(0); +} + + +static int +compare(Font *fnt, char *s, char *key) +{ + char c; + char *p; + char *temp, *temp1; + int value; + int sfd_begin, postfix_begin; + + + /* + * We isolate the fontname. + */ + + while (isspace(*s)) + s++; + + p = s; + while (*p && !isspace(*p)) + p++; + + c = *p; + *p = '\0'; + temp = newstring(s); + *p = c; + + /* + * We search for a subfont definition file name. + */ + + handle_sfd(temp, &sfd_begin, &postfix_begin); + + if (sfd_begin == -1) + value = strcmp(temp, key); + else + { + size_t len, len1, len2; + + + /* + * The sfd file will be only searched if prefix and postfix match. + */ + + len = strlen(key); + len1 = strlen(temp); + len2 = strlen(temp + postfix_begin); + + if (len1 + len2 >= len) + value = -1; + else if (!strncmp(temp, key, len1) && + !strcmp(temp + postfix_begin, key + (len - len2))) + { + c = key[len - len2]; + key[len - len2] = '\0'; + temp1 = newstring(key + len1); + key[len - len2] = c; + + if (fnt->sfdname) + free(fnt->sfdname); + fnt->sfdname = newstring(temp + sfd_begin); + + /* + * If the sfd file can't be opened the search is continued. + */ + + value = !init_sfd(fnt, False); + + if (!value) + { + value = -1; + + while (get_sfd(fnt)) + { + if (!strcmp(fnt->subfont_name, temp1)) + { + value = 0; /* success */ + have_sfd = True; + break; + } + } + + close_sfd(); + } + + free(temp1); + } + else + value = -1; + } + + free(temp); + + return value; +} + + +int +main(int argc, char** argv) +{ + size_t l; + unsigned int i; + long index, code; + FILE *config_file; + char *configline, *oldconfigline, *p, *q; + Font font; + encoding *enc; + long inenc_array[256]; + char *fontname; + size_t fontname_len; + char *pk_filename, *tfm_filename, *enc_filename, *cfg_filename; + char *real_ttfname, *real_cfg_filename; + int dpi = 0, ptsize; + Boolean hinting = True; + Boolean quiet = False; + Boolean no_dpi = False; + Boolean testing = False; + + + TeX_search_init(argv[0], "ttf2pk", "TTF2PK"); + + if (argc == 1) + oops("Need at least two arguments.\n" + "Try `ttf2pk --help' for more information."); + + if (argc == 2) + { + if (strcmp(argv[1], "--help") == 0) + usage(); + else if (strcmp(argv[1], "--version") == 0) + version(); + } + + while (argv[1][0] == '-') + { + if (argv[1][1] == 'q') + quiet = True; + else if (argv[1][1] == 'n') + no_dpi = True; + else if (argv[1][1] == 't') + testing = True; + else + oops("Unknown option `%s'.\n" + "Try `ttf2pk --help' for more information.", argv[1]); + + argv++; + argc--; + } + + if (testing) + { + if (argc != 2) + oops("Need exactly one parameter for `-t' option.\n" + "Try `ttf2pk --help' for more information."); + } + else if (argc != 3) + oops("Need at most two arguments.\n" + "Try `ttf2pk --help' for more information."); + + if (!quiet) + printf("This is %s\n", ident); + + if (!testing) + if ((dpi = atoi(argv[2])) <= 50) + oops("dpi value must be larger than 50."); + + fontname = argv[1]; + fontname_len = strlen(fontname); + enc_filename = NULL; + + ptsize = 10; + + init_font_structure(&font); + + cfg_filename = newstring("ttfonts.map"); + real_cfg_filename = TeX_search_config_file(&cfg_filename); + if (!real_cfg_filename) + oops("Cannot find file ttfonts.map."); + + config_file = fopen(real_cfg_filename, "rt"); + if (config_file == NULL) + oops("Cannot open file ttfonts.map."); + + do + { + configline = get_line(config_file); + if (!configline) + oops("Error while reading ttfonts.map."); + if (!*configline) + { + /* + * This is the only error message we suppress if the -q flag + * is set, making it possible to call ttf2pk silently. + */ + if (!quiet) + fprintf(stdout, + "%s: ERROR: Cannot find font %s in ttfonts.map.\n", + progname, fontname); + exit(2); + } + } while (compare(&font, configline, fontname)); + + fclose(config_file); + + if (testing) + { + if (!quiet) + fprintf(stdout, "%s\n", configline); + exit(0); + } + + /* + * Parse the line from the config file. We split the config line buffer + * into substrings according to the given options. + */ + + l = strlen(configline); + if (configline[l - 1] == '\n') + configline[l - 1] = '\0'; /* strip newline */ + + oldconfigline = newstring(configline); + + p = configline; + while (isspace(*p)) + p++; + while (*p && !isspace(*p)) + p++; + + q = p; + + while (*p && isspace(*p)) + p++; + if (!*p) + boops(oldconfigline, q - configline, "TTF file missing."); + + font.ttfname = p; + + while (*p && !isspace(*p)) + p++; + if (*p) + *p++ = '\0'; + + for (; *p; p++) + { + if (isspace(*p)) + continue; + + if (!strncmp(p, "Slant", 5)) + { + p = strip_equal(configline, oldconfigline, p + 5); + if (sscanf(p, "%f", &(font.slant)) == 0) + boops(oldconfigline, p - configline, "Bad `Slant' parameter."); + } + else if (!strncmp(p, "Encoding", 8)) + { + if (have_sfd) + boops(oldconfigline, p - configline, + "No `Encoding' parameter allowed for subfonts."); + + p = strip_equal(configline, oldconfigline, p + 8); + if (!*p) + boops(oldconfigline, p - configline, "Bad `Encoding' parameter."); + enc_filename = p; + } + else if (!strncmp(p, "Extend", 6)) + { + p = strip_equal(configline, oldconfigline, p + 6); + if (sscanf(p, "%f", &(font.efactor)) == 0) + boops(oldconfigline, p - configline, "Bad `Extend' parameter."); + } + else if (!strncmp(p, "Fontindex", 9)) + { + p = strip_equal(configline, oldconfigline, p + 9); + if (sscanf(p, "%lu", &(font.fontindex)) < 0) + boops(oldconfigline, p - configline, "Bad `Fontindex' parameter."); + } + else if (!strncmp(p, "Pid", 3)) + { + p = strip_equal(configline, oldconfigline, p + 3); + if (sscanf(p, "%hu", &(font.pid)) < 0) + boops(oldconfigline, p - configline, "Bad `Pid' parameter."); + have_pid = True; + } + else if (!strncmp(p, "Eid", 3)) + { + p = strip_equal(configline, oldconfigline, p + 3); + if (sscanf(p, "%hu", &(font.eid)) < 0) + boops(oldconfigline, p - configline, "Bad `Eid' parameter."); + have_eid = True; + } + else if (!strncmp(p, "Hinting", 7)) + { + p = strip_equal(configline, oldconfigline, p + 7); + if (p[1] == 'N' || p[1] == 'n' || + p[0] == 'Y' || p[1] == 'y' || + p[0] == '1') + hinting = True; + else if (p[1] == 'F' || p[1] == 'f' || + p[0] == 'N' || p[1] == 'n' || + p[0] == '0') + hinting = False; + else + boops(oldconfigline, p - configline, "Bad `Hinting' parameter."); + } + else if (!strncmp(p, "PS", 2)) + { + p = strip_equal(configline, oldconfigline, p + 2); + if (p[1] != '\0' && + (p[2] == 'l' || p[2] == 'L')) + font.PSnames = Only; + else if (p[1] == 'N' || p[1] == 'n' || + p[0] == 'Y' || p[0] == 'y' || + p[0] == '1') + font.PSnames = Yes; + else if (p[1] == 'F' || p[1] == 'f' || + p[0] == 'N' || p[0] == 'n' || + p[0] == '0') + font.PSnames = No; + else + boops(oldconfigline, p - configline, "Bad `PS' parameter."); + + if (have_sfd) + boops(oldconfigline, p - configline, + "No `PS' parameter allowed for subfonts."); + } + else if (!strncmp(p, "Rotate", 6)) + { + p = strip_equal(configline, oldconfigline, p + 6); + if (p[1] == 'N' || p[1] == 'n' || + p[0] == 'Y' || p[1] == 'y' || + p[0] == '1') + font.rotate = True; + else if (p[1] == 'F' || p[1] == 'f' || + p[0] == 'N' || p[1] == 'n' || + p[0] == '0') + font.rotate = False; + else + boops(oldconfigline, p - configline, "Bad `Rotate' parameter."); + + if (!have_sfd) + boops(oldconfigline, p - configline, + "No `Rotate' parameter allowed for non-subfonts."); + } + else if (!strncmp(p, "Y-Offset", 8)) + { + p = strip_equal(configline, oldconfigline, p + 8); + if (sscanf(p, "%f", &(font.y_offset)) == 0) + boops(oldconfigline, p - configline, "Bad `Y-Offset' parameter."); + } + else if (!strncmp(p, "Replacement", 11)) + { + p = strip_equal(configline, oldconfigline, p + 11); + if (!*p) + boops(oldconfigline, p - configline, "Bad `Replacement' parameter."); + font.replacementname = p; + } + else + { + char *new_name, *old_name; + stringlist *sl; + + + old_name = p; + while (*p && !isspace(*p) && *p != '=') + p++; + + q = p; + p = strip_equal(configline, oldconfigline, p); + *q = '\0'; + + new_name = p; + while (*p && !isspace(*p)) + p++; + if (*p) + *p++ = '\0'; + + sl = newstringlist(); + sl->new_name = new_name; + sl->old_name = old_name; + sl->next = font.replacements; + font.replacements = sl; + + p--; /* to make the next while loop work */ + } + + while (*p && !isspace(*p)) + p++; + if (*p) + *p = '\0'; + } + + if (font.PSnames == Only) + if (have_pid || have_eid) + boops(oldconfigline, 0, + "No `Pid' or `Eid' parameters allowed if `PS=Only' is set."); + + font.replacementname = newstring(font.replacementname); + get_replacements(&font); + + tfm_filename = newstring(fontname); + TFMopen(&tfm_filename); + + pk_filename = mymalloc(fontname_len + 10); + if (no_dpi) + sprintf(pk_filename, "%s.pk", fontname); + else + sprintf(pk_filename, "%s.%dpk", fontname, dpi); + PKopen(pk_filename, fontname, dpi); + + font.ttfname = newstring(font.ttfname); + real_ttfname = TeX_search_ttf_file(&(font.ttfname)); + if (!real_ttfname) + oops("Cannot find `%s'.", font.ttfname); + TTFopen(real_ttfname, &font, dpi, ptsize, quiet); + + enc_filename = newstring(enc_filename); + enc = readencoding(&enc_filename, &font, True); + if (enc) + { + char *name; + + + restore_glyph(enc, &font); + + for (i = 0; i <= 0xFF; i++) + { + name = enc->vec[i]; + if (!font.PSnames) + { + code = adobename_to_code(name); + if (code < 0 && strcmp(name, ".notdef") != 0) + warning("Cannot map character `%s'.", name); + inenc_array[i] = code; + } + else + { + /* we search the glyph index */ + index = TTFsearch_PS_name(name); + if (index < 0) + warning("Cannot map character `%s'.", name); + inenc_array[i] = index | 0x10000; + } + } + } + else + { + if (font.replacements) + warning("Replacement glyphs will be ignored."); + + if (have_sfd) + TTFget_subfont(&font, inenc_array); + else + /* get the table of glyph names too */ + enc = TTFget_first_glyphs(&font, inenc_array); + } + + for (i = 0; i <= 0xFF; i++) + { + byte *bitmap; + int w, h, hoff, voff; + + + if ((code = inenc_array[i]) >= 0) + { + if (!quiet) + { + printf("Processing glyph %3ld %s index 0x%04x %s\n", + (long)i, (code >= 0x10000) ? "glyph" : "code", + (unsigned int)(code & 0xFFFF), enc ? enc->vec[i] : ""); + fflush(stdout); + } + + if (TTFprocess(&font, code, + &bitmap, &w, &h, &hoff, &voff, hinting, quiet)) + PKputglyph(i, + -hoff, -voff, w - hoff, h - voff, + w, h, bitmap); + else + warning("Cannot render glyph with %s index 0x%x.", + (code >= 0x10000) ? "glyph" : "code", + (unsigned int)(code & 0xFFFF)); + } + } + + PKclose(); + exit(0); /* for safety reasons */ + return 0; /* never reached */ +} + + +/* end */ diff --git a/contrib/ttf2pk/ttf2pk.doc b/contrib/ttf2pk/ttf2pk.doc new file mode 100644 index 0000000..3cf50e2 --- /dev/null +++ b/contrib/ttf2pk/ttf2pk.doc @@ -0,0 +1,733 @@ + +ttf2tfm -- TrueType to TFM converter +ttf2pk -- TrueType to PK converter +==================================== + +These two auxiliary programs make TrueType fonts usable with TeX. +ttf2tfm extracts the metric and kerning information of a TrueType font +and converts it into metric files usable by TeX (quite similar to +afm2tfm which is part of the dvips package). ttf2pk rasterizes the +glyph outlines of a TrueType font into a bitmap font in PK format. + +Since a TrueType font often contains more than 256 glyphs, some means +are necessary to map a subset of the TrueType glyphs into a TeX font. +To do this, two mapping tables are needed: the first maps from the +TrueType font to a raw TeX font (this mapping table is used both by +ttf2tfm and ttf2pk), and the second maps from the raw TeX font to +another (virtual) TeX font providing all kerning and ligature +information needed by TeX. + +We sometimes refer to this first map as the `input' or `raw' map, and +to the second as the `output' or `virtual' map. + +This two stage mapping has the advantage that one raw font can be +accessed with various TeX encodings (e.g. T1 and OT1) via the virtual +font mechanism, and just one PK file is necessary. + +For CJK fonts, a different mechanism is provided (see section `Subfont +definition files' below). Additionally, rotated glyphs for +pseudo-vertical writing are supported -- if possible, vertical glyph +presentation forms are used from the font's GSUB table. + + + +ttf2tfm +======= + +Usage: + + ttf2tfm FILE[.ttf|.ttc] [OPTION]... [FILE[.tfm]] + +Options (default values are given in brackets): + +-c REAL use REAL for height of small caps made with -V [0.8] +-e REAL widen (extend) characters by a factor of REAL [1.0] +-E INT select INT as the TTF encoding ID [1] +-f INT select INT as the font index in a TTC [0] +-l create 1st/2nd byte ligatures in subfonts +-n use PS names of TrueType font +-N use only PS names and no cmap +-O use octal for all character codes in the vpl file +-p ENCFILE[.enc] read ENCFILE for the TTF->raw TeX mapping +-P INT select INT as the TTF platform ID [3] +-q suppress informational output +-r OLDNAME NEWNAME replace glyph name OLDNAME with NEWNAME +-R RPLFILE[.rpl] read RPLFILE containing glyph replacement names +-s REAL oblique (slant) characters by REAL, usually <<1 [0.0] +-t ENCFILE[.enc] read ENCFILE for the encoding of the vpl file +-T ENCFILE[.enc] equivalent to -p ENCFILE -t ENCFILE +-u output only characters from encodings, nothing extra +-v FILE[.vpl] make a VPL file for conversion to VF +-V SCFILE[.vpl] like -v, but synthesize smallcaps as lowercase +-x rotate subfont glyphs by 90 degrees +-y REAL move rotated glyphs down by a factor of REAL [0.25] +--help print this message and exit +--version print version number and exit + + +The usage is very similar to afm2tfm. Please consult the dvips info +file for more details on the various parameters. Here we will +concentrate on the differences between afm2tfm and ttf2tfm. + + +cmaps +----- + +Contrary to Type 1 PostScript fonts (but similar to the new CID-keyed +PostScript fonts), most TrueType fonts have more than one native +mapping table, also called `cmap', which maps the (internal) TTF glyph +indices to the (external) TTF character codes. Common examples are a +mapping table to Unicode encoded character positions and the standard +Macintosh mapping. To specify this TrueType mapping table, use the +options `-P' and `-E'. With `-P' you specify the platform ID; defined +values are: + + platform platform ID (pid) + ---------------------------------- + Apple Unicode 0 + Macintosh 1 + ISO 2 + Microsoft 3 + +The encoding ID depends on the platform. For pid=0, we ignore the +`-E' parameter (setting it to zero) since the mapping table is always +Unicode version 2.0. For pid=1, the following table lists the defined +values: + + platform ID = 1 + script encoding ID (eid) + --------------------------------- + Roman 0 + Japanese 1 + Chinese 2 + Korean 3 + Arabic 4 + Hebrew 5 + Greek 6 + Russian 7 + Roman Symbol 8 + Devanagari 9 + Gurmukhi 10 + Gujarati 11 + Oriya 12 + Bengali 13 + Tamil 14 + Telugu 15 + Kannada 16 + Malayalam 17 + Sinhalese 18 + Burmese 19 + Khmer 20 + Thai 21 + Laotian 22 + Georgian 23 + Armenian 24 + Maldivian 25 + Tibetan 26 + Mongolian 27 + Geez 28 + Slavic 29 + Vietnamese 30 + Sindhi 31 + Uninterpreted 32 + +Here are the ISO encoding IDs: + + platform ID = 2 + encoding encoding ID + ---------------------------- + ASCII 0 + ISO 10646 1 + ISO 8859-1 2 + +And finally, the Microsoft encoding IDs: + + platform ID = 3 + encoding encoding ID + --------------------------- + Symbol 0 + Unicode 2.0 1 + Shift JIS 2 + GB 2312 (1980) 3 + Big 5 4 + KSC 5601 (Wansung) 5 + KSC 5601 (Johab) 6 + +The program will abort if you specify an invalid platform/encoding ID +pair. Please note that most fonts have at most two or three cmaps, +usually corresponding to the pid/eid pairs (1,0), (3,0), or (3,1) in +case of Latin based fonts. Valid Microsoft fonts should have a (3,1) +mapping table, but some fonts exist (mostly Asian fonts) which have a +(3,1) cmap not encoded in Unicode. The reason for this strange +behavior is the fact that some MS Windows versions will reject fonts +having a non-Unicode cmap (since all non-Unicode Microsoft encoding +IDs are for Asian specific MS Windows versions). + +The `-P' and `-E' options to ttf2tfm must be equally specified for +ttf2pk; the corresponding parameters in ttfonts.map are `Pid' and +`Eid', respectively. + +The default pid/eid pair is (3,1). + +If you use the `-N' switch, all cmaps are ignored, using only the +PostScript names in the TrueType font. The corresponding option in +ttfonts.map is `PS=Only'. + +If you use the `-n' switch, the default glyph names built into ttf2tfm +are replaced with the PS glyph names found in the font. In many cases +this is not what you want because the glyph names in the font are +often incorrect or non-standard. The corresponding option in +ttfonts.map `PS=Yes'. + + +input and output encodings +-------------------------- + +You must specify the encoding vectors from the TrueType font to the +raw TeX font and from the raw TeX font to the virtual TeX font exactly +as with afm2tfm, but you have more possibilities to address the +character codes. [With `encoding vector' a mapping table with 256 +entries in form of a PostScript vector is meant; see the file +`T1-WGL4.enc' of this package for an example.] With afm2tfm, you must +access each glyph with its Adobe glyph name, e.g. `/quotedsingle' or +`/Acircumflex'. This has been extended with ttf2tfm; now you can (and +sometimes must) access the code points and/or glyphs directly using +the following syntax for specifying the character position in decimal, +octal, or hexadecimal notation: `/.c', +`/.c0', or `/.c0x'. Examples: +`/.c72', `/.c0646', `/.c0x48'. To access a glyph index directly, use +the character `g' instead of `c' in the just introduced notation. +Example: `/.g0x32'. + +[Note: The `.cXXX' notation makes no sense if `-N' is used.] + +Another possibility is to use the `-r old-glyphname new-glyphname' +switch to rename a glyph. Example: + + ttf2tfm ... -r .g0xc7 dotlessi -r hungarumlaut dblacute ... + +Nevertheless, it is not allowed to use the `.gXXX' or `.cXXX' glyph +name construct for `new-glyphname'. + +Alternatively, you can collect such replacement pairs in a file which +should have `.rpl' as extension, using the `-R' option. The syntax is +simple: Each line contains a pair `old-glyphname new-glyphname' +separated by whitespace (without the quotation marks). The percent +sign starts a line comment; you can continue a line with a backslash +as the last character. An example for a replacement file is `VPS.rpl' +(to be used in conjunction with `ET5.enc' for Vietnamese) which is +part of this package. + +The `-r' and `-R' switches are ignored for subfonts or if no encoding +tables are specified. For ttf2pk, the corresponding option to `-R' is +`Replacement'. Single replacements are directly given as +old_glyphname=newglyphname in ttfonts.map. + +For pid/eid pairs (1,0) and (3,1), both ttf2tfm and ttf2pk recognize +built-in default Adobe glyph names; the former pair follows the names +given in Appendix E of the book `Inside Macintosh', volume 6, the +latter uses the names given in the TrueType Specification (WGL4, a +Unicode subset). Note that Adobe glyph names are not unique and do +sometimes differ: E.g., many PS fonts have the glyph `mu', whereas +this glyph is called `mu1' in the WGL4 character set to distinguish it +from the real Greek letter mu. You can find those mapping tables in +the source code file `ttfenc.c'. + +On the other hand, the switches `-n' and `-N' make ttf2tfm read in and +use the PostScript names in the TrueType font itself (stored in the +font's `post' table) instead of the default Adobe glyph names. + +If you don't select an input encoding, the first 256 glyphs of the +TrueType font with a valid entry in the selected cmap will be mapped +to the TeX raw font (without the `-q' option ttf2tfm prints this +mapping table to standard output), followed by all glyphs not yet +addressed in the selected cmap. However, some code points for the +(1,0) pid/eid pair are omitted since they do not represent glyphs +useful for TeX: 0x00 (null), 0x08 (backspace), 0x09 (horizontal +tabulation), 0x0d (carriage return), and 0x1d (group separator). The +`invalid character' with glyph index 0 will be omitted too. + +If you select the `-N' switch, the first 256 glyphs of the TrueType +font with a valid PostScript name will be used in case no input +encoding is specified. Again, some glyphs are omitted: `.notdef', +`.null', and `nonmarkingreturn'. + +If you don't select an output encoding, ttf2tfm uses the same mapping +table as afm2tfm would use (you can find it in the source code file +texenc.c); it corresponds to TeX typewriter text. Unused positions +(either caused by empty code points in the mapping table or missing +glyphs in the TrueType font) will be filled (rather arbitrarily) with +characters present in the input encoding but not specified in the +output encoding (without the `-q' option ttf2tfm prints the final +output encoding to standard output). Use the `-u' option if you want +only glyphs in the virtual font which are defined in the output +encoding file, and nothing more. + +One feature missing in afm2tfm has been added which is needed by the +LaTeX T1 encoding: ttf2tfm will construct the glyph `Germandbls' (by +simply concatenating to `S' glyphs) even for normal fonts if possible. +It appears in the glyph list (written to stdout) as the last item, +marked with an asterisk. Since this isn't a real glyph it will be +available only in the virtual font. + +For both input and output encoding, an empty code position is +represented by the glyph name `.notdef'. + +In encoding files, you can use `\' as the final character of a line to +indicate that the input is continued on the next line. The backslash +and the following newline character will be removed. + +ttf2tfm returns 0 on success and 1 on error; warning and error +messages are written to standard error. + + +other options +------------- + +You can select the font in a TrueType font collection (which usually +has the extension `.ttc') with `-f'; the default value, zero, +specifies the first font. For fonts not being a collection, this +parameter is ignored. + +The option `-l' makes ttf2tfm create ligatures in subfonts between +first and second bytes of all the original character codes. Example: +Character code 0xABCD maps to character position 123 in subfont 45. +Then a ligature in subfont 45 between position 0xAB and 0xCD pointing +to character 123 will be produced. The fonts of the Korean HLaTeX +package use this feature. + +To produce glyphs rotated by 90 degrees counter-clockwise, use `-x'. +If the font contains a GSUB table (with feature `vert') to specify +vertical glyph presentation forms, both ttf2pk and ttf2tfm will use +it. This will work only in subfont mode. The y-offset of rotated +glyphs can be specified with the `-y' option; its parameter gives the +fractional amount of shifting downwards (the unit is one EM). If not +specified, a value of 0.25 (em) is used. + + + +ttf2pk +====== + +Usage: + + ttf2pk [-q] [-n] FONT DPI + ttf2pk -t [-q] FONT + +Options: + +-q suppresses informational output +-n only use `.pk' as extension +-t test for FONT (returns 0 on success) +--help print this message and exit +--version print version number and exit + + +The FONT parameter must correspond to an entry in the file ttfonts.map +(see below for details), otherwise error code 2 is returned -- this +can be used for scripts like mktexpk to test whether the given font +name is a (registered) TrueType font. + +Another possibility is to use the `-t' switch which will print the +line of ttfonts.map corresponding to FONT and return 0 on success +(`-q' suppresses any output). + +DPI specifies the intended resolution (we always assume a design size +of 10pt). + + +ttfonts.map +----------- + +ttf2pk uses, similar to dvips, a font definition file called +ttfonts.map. The parameters specified to ttf2tfm are here preserved +-- ttf2tfm writes out to standard output, as the last line, a proper +configuration entry for ttfonts.map. + +As an example, a call to + + ttf2tfm arial -s 0.25 -P 1 -E 0 -r .g0xc7 caron \ + -p 8r.enc -t T1-WGL4.enc -v arialsx arials + +will produce the following line: + + arials arial Slant=0.25 Encoding=8r.enc Pid=1 Eid=0 .g0xc7=caron + +The output encoding given with `-t' for the virtual font `arialsx' is +immaterial to ttf2pk (nevertheless, input encoding files must have the +same format as with ttf2tfm, and all said above about encoding files +holds). + +Here a table listing the various ttf2tfm parameters and its +corresponding ttfonts.map entries: + + -s Slant + -e Extend + -p Encoding + -f Fontindex + -P Pid + -E Eid + -n PS=Yes + -N PS=Only + -R Replacement + -x Rotate=Yes + -y Y-Offset + +Single replacement glyph names given to ttf2tfm with the `-r' switch +are directly specified with old-glyphname=new-glyphname. For subfonts +or if no encoding file is given, replacement glyphs are ignored. + +One additional parameter in ttfonts.map is unique to ttf2pk: +`Hinting', which can take the values `On' or `Off'. Some fonts (e.g. +the CJK part of cyberbit.ttf) are rendered incorrectly if hinting is +activated. Default is `On' (you can also use `Yes', `No', `1', and +`0'). + +The format of ttfonts.map is simple. Each line defines a font; first +comes the TeX font name, then its TrueType font file name, followed by +the parameters in any order. Case is significant (even for parameter +names); the parameters are separated from its values by an equal sign, +with possible whitespace surrounding it. ttf2pk reads in ttfonts.map +line by line, continuing until the TeX font specified on the command +line is found, otherwise the programs exits with error code 2. Thus +you can use any character invalid in a TeX font name to start a +comment line. + +In both ttfonts.map and encoding files, use `\' as the final character +of a line to indicate that the input is continued on the next line. +The backslash and the following newline character will be removed. + +ttf2pk will abort if it can't find and read the TeX font metrics file +of the given TeX font name. + + +Subfont definition files +======================== + +CJK (Chinese/Japanese/Korean) fonts usually contain several thousand +glyphs; to use them with TeX it is necessary to split such large fonts +into subfonts. Subfont definition files (usually having the extension +`.sfd') are a simple means to do this smoothly. A subfont file name +usually consists of a prefix, a subfont infix, and a postfix (which is +empty in most cases), e.g. + + ntukai23 -> prefix: ntukai, infix: 23, postfix: (empty) + +Here the syntax of a line in an SFD file, describing one subfont: + + `\n' + + := anything except whitespace. It's best to use only + alphanumerical characters. + := space, formfeed, carriage return, horizontal and + vertical tabs -- no newline characters. + := | + | + + + := + := `_' + := `:' + + := hexadecimal (prefix `0x'), decimal, or octal + (prefix `0') + +A line can be continued on the next line with a backslash ending the +line. The ranges must not overlap; offsets have to be in the range +0-255. + +Example: + + The line + + 03 10: 0x2349 0x2345_0x2347 + + assigns to the code positions 10, 11, 12, and 13 of the subfont + having the infix `03' the character codes 0x2349, 0x2345, 0x2346, + and 0x2347, respectively. + +The SFD files in the distribution are customized for the CJK package +for LaTeX. + +You have to embed the SFD file into the TFM font name (at the place +where the infix will appear) surrounded by two `@' signs, on the +command line resp. the ttfonts.map file; both ttf2tfm and ttf2pk +switch then to subfont mode. + +Subfont mode disables the options `-n', `-N', `-p', `-r', `-R', `-t', +`-T', `-u', `-v', and `-V' for ttf2tfm; similarly, no `Encoding' and +`Replacement' parameter resp. single replacement glyph names are +allowed in ttfonts.map. + +ttf2tfm will create ALL subfont TFM files specified in the SFD files +(provided the subfont contains glyphs) in one run. + +Example: + + The call + + ttf2tfm ntukai.ttf ntukai@/usr/local/lib/ttf2tfm/Big5@ + + will use `/usr/local/lib/ttf2tfm/Big5.sfd', producing the subfont + files ntukai01.tfm, ntukai02.tfm etc. + + ttf2pk should be then called on the subfonts directly: + + ttf2pk ntukai01 600 + ttf2pk ntukai02 600 + ... + + +Some notes on file searching +============================ + +Both ttf2pk and ttf2tfm use either the kpathsea, emtexdir, or MiKTeX +library for searching files (emtexdir will work only on operating +systems which have an MS-DOSish background, i.e. MS-DOS, OS/2, +Windows; MiKTeX is specific to MS Windows). + +During compilation, you have to define HAVE_KPATHSEA, HAVE_EMTEXDIR, +or MIKTEX to activate the specific file search code. + +As a last resort, both programs can be compiled without a search +library; the searched files must be then in the current directory or +specified with a path. Default extensions will be appended also (with +the exception that only `.ttf' is appended and not `.ttc'). + + +kpathsea +-------- + +Please note that older versions of kpathsea (<3.2) have no special +means to search for TrueType fonts and related files, thus we use the +paths for PostScript related stuff. The actual version of kpathsea is +displayed on screen if you call either ttf2pk or ttf2tfm with the +`--version' command line switch. + +Here is a table of the file type and the corresponding kpathsea +variables. TTF2PKINPUTS and TTF2TFMINPUTS are program specific +environment variables introduced in kpathsea version 3.2: + + .ttf and .ttc TTFONTS + ttfonts.map TTF2PKINPUTS + .enc TTF2PKINPUTS, TTF2TFMINPUTS + .rpl TTF2PKINPUTS, TTF2TFMINPUTS + .tfm TFMFONTS + .sfd TTF2PKINPUTS, TTF2TFMINPUTS + +And here the same for pre-3.2-versions of kpathsea: + + .ttf and .ttc T1FONTS + ttfonts.map TEXCONFIG + .enc TEXPSHEADERS + .rpl TEXPSHEADERS + .tfm TFMFONTS + .sfd TEXPSHEADERS + +Finally, the same for pre-3.0-versions: + + .ttf and .ttc DVIPSHEADERS + ttfonts.map TEXCONFIG + .enc DVIPSHEADERS + .rpl DVIPSHEADERS + .tfm TFMFONTS + .sfd DVIPSHEADERS + +Please consult the info files for kpathsea for details on these +variables. The decision whether to use the old or the new scheme will +be done during compilation. + +You should set the TEXMFCNF variable to the directory where your +texmf.cnf configuration file resides. + +The default TDS location for the files in the data subdirectory is + + $TEXMF/ttf2tfm + +(or $TEXMF/ttf2pk; you should either make a symbolic link + + % ln -s $TEXMF/ttf2tfm $TEXMF/ttf2pk + +or set the variable TTF2PKINPUTS to $TEXMF/ttf2tfm for newer kpathsea +versions) + +Here is the proper command to find out to which value a kpathsea +variable is set (we use `TTFONTS' as an example). This is especially +useful if a variable isn't set in texmf.cnf or in the environment, +thus pointing to the default value which is hard-coded into the +kpathsea library. + + % kpsewhich --progname=ttf2tfm --expand-var='$TTFONTS' + +We select the program name also since it is possible to specify +variables which are searched only for a certain program -- in our +example it would be `TTFONTS.ttf2tfm'. + +A similar but not identical method is to say + + % kpsewhich --progname=ttf2tfm --show-path='truetype fonts' + +[A full list of format types can be obtained by saying `kpsewhich +--help' on the command line prompt.] This is exactly the how ttf2tfm +(and ttf2pk) search for files; the disadvantage is that all variables +are expanded which can cause very long string. + + +emtexdir +-------- + +Here the list of suffixes and its related environment variables to be +set in autoexec.bat (resp. in config.sys for OS/2): + + .ttf and .ttc TTFONTS + ttfonts.map TTFCFG + .enc TTFCFG + .rpl TTFCFG + .tfm TEXTFM + .sfd TTFCFG + +With other words, all files in the data subdirectory should be moved +to a place in your emtex tree with TTFCFG pointing to this directory. + +If one of the variables isn't set, a warning message is emitted. The +current directory will always be searched. As usual, one exclamation +mark appended to a directory path causes subdirectories one level deep +to be searched, two exclamation marks causes all subdirectories to be +searched. Example: + + TTFONTS=c:\fonts\truetype!!;d:\myfonts\truetype! + +Constructions like `c:\fonts!!\truetype' aren't possible. + + +MiKTeX +------ + +Both ttf2tfm and ttf2pk have been fully integrated into MiKTeX. +Please refer to the documentation of MiKTeX for more details on file +searching. + + + +A full example +============== + +Here an example how to handle the font `verdana.ttf' and its variants. + + +1. Construct the font name +-------------------------- + + [This is the most complicated part -- in case you are too lazy to + construct font names compliant to TeX's `fontname' scheme, just use + your own names.] + + Using the `ftdump' utility (which is part of FreeType) you can find + out the PostScript name of the specific TTF which is probably the + best choice to adapt TrueType fonts to the PostScript-oriented + `fontname' scheme. + + In our example, the PostScript name is `Verdana'. + + `fontname' uses the scheme + + S TT W [V...] [N] [E] [DD] + + as documented in `fontname.texi' resp. `fontname.dvi'. Now you have + to check the various mapping files: + + S: supplier.map: `j' for `Microsoft' + TT: typeface.map: `vn' for `Verdana' + W: weight.map: `r' for `Regular Roman', + `b' for `bold' + V, + N: variant.map: `8r' for the raw base font + `8t' for the virtual font + (i.e., LaTeX's T1 encoding) + [additionally an inserted `c' for small caps, + `o' for slanted (`oblique'), or `i' for italic + fonts] + + Here the standard combinations: + + `jvnr8r' for the default base font. + `jvnr8t' for the virtual default font. + `jvnrc8t' for the virtual font with small caps. [As you can see, + no additional raw font is needed.] + `jvnro8r' for the slanted base font. + `jvnro8t' for the virtual slanted font. + + The corresponding variants are: + + bold: verdanab.ttf -> jvnb{8r,8t} + small caps: jvnbc8t + slanted: jvnbo{8r,8t} + italic: verdanai.ttf -> jvni{8r,8t} + bold and italic: verdanaz.ttf -> jvnbi{8r,8t} + + +2. Font definition files +------------------------ + + The FD file should be called `t1jvn.fd' (as you can see, this is T1 + encoding). It is very similar to `t1ptm.fd', part of the PSNFSS + package (which can be found in almost all TeX distributions). A + `verdana.sty' file can also be modeled after `times.sty'. + + +3. Calling ttf2tfm +------------------ + + To make the example simpler, we use `T1-WGL4.enc' for both the raw + and the virtual encoding. This should be sufficient for most + TrueType fonts mapped to T1 encoding. Other packages may define + other encodings (e.g. the `t2' package available from CTAN defines + mapping files for Cyrillic encodings) -- it may also be necessary to + use the `-n' or `-N' switch together with replacement glyph names to + access all glyph names in the TrueType font. + + To create `jvnr8r' and `jvnr8t', just call + + ttf2tfm verdana -T T1-WGL4 -v jvnr8t jvnr8r + vptovf jvnr8t + + For `jvnrc8t', do + + ttf2tfm verdana -T T1-WGL4 -V jvnrc8t jvnr8r + vptovf jvnrc8t + + Note that almost always some warnings will appear about missing + glyphs. + + The last line written to stdout by ttf2tfm is a suitable entry for + ttfonts.map -- since ttf2pk doesn't care about virtual fonts, both + calls below produce the same. + + Now just repeat this procedure. For slanted fonts you should + additionally use the switch `-s 0.176' (of course you can change the + slanting amount to make it fit your needs). + + + +Problems +======== + +Most vptovf implementations allow only 100 bytes for the TFM header +(the limit is 1024 in the TFM file itself): 8 bytes for checksum and +design size, 40 bytes for the family name, 20 bytes for the encoding, +and 4 bytes for a face byte. There remain only 28 bytes for some +additional information which is used by ttf2tfm for an identification +string (which is essentially a copy of the command line), and this +limit is always exceeded. + +The optimal solution is to increase the value of `max_header_bytes' in +the file vptovf.w (and probably pltotf.w) to, say, 400 and recompile +vptovf (and pltotf). Otherwise you'll get some (harmless) error +messages like + + This HEADER index is too big for my present table size + +which can be safely ignored. + + +--- end of ttf2pk.doc --- diff --git a/contrib/ttf2pk/ttf2tfm.1 b/contrib/ttf2pk/ttf2tfm.1 new file mode 100644 index 0000000..7e6bad9 --- /dev/null +++ b/contrib/ttf2pk/ttf2tfm.1 @@ -0,0 +1,1095 @@ +.\" man page for ttf2tfm +. +.TH TTF2TFM 1 15-Aug-1999 "FreeType version 1.3" +.SH NAME +ttf2tfm \- build TeX metric files from a TrueType font +.SH SYNOPSIS +.na +.nh +.B ttf2tfm +.in +\n(.ku +.sp -1 +.IR ttffile [ .ttf | .ttc ] +[\c +.BI -c \ \%caps-height-factor\c +] +[\c +.BI -e \ \%extension-factor\c +] +[\c +.BI -E \ \%encoding-id\^\c +] +[\c +.BI -f \ \%font-index\c +] +[\c +.B -l\c +] +[\c +.B -n\c +] +[\c +.B -N\c +] +[\c +.B -O\c +] +[\c +.B -p\ \c +.IR \%inencfile [ .enc ]\c +] +[\c +.BI -P \ \%platform-id\^\c +] +[\c +.B -q\c +] +[\c +.BI -r \ \%old-glyphname\ \%new-glyphname\c +] +[\c +.B -R\ \c +.IR \%replacement-file [ .rpl ]\c +] +[\c +.BI -s \ \%slant-factor\c +] +[\c +.B -t\ \c +.IR \%outencfile [ .enc ]\c +] +[\c +.B -T\ \c +.IR \%inoutencfile [ .enc ]\c +] +[\c +.B -u\c +] +[\c +.B -v\ \c +.IR \%vplfile [ .vpl ]\c +] +[\c +.B -V\ \c +.IR \%scvplfile [ .vpl ]\c +] +[\c +.B -x\c +] +[\c +.BI -y \ \%vertical-shift-factor\c +] +[\c +.IR \%tfmfile [ .tfm ]\c +] +.br +.in +.B "ttf2tfm --version" +| +.B --help +.ad +.hy +. +. +. +.\" ==== +.\" ==== macro definitions +.\" ==== +. +.\" here we define \TeX for troff and nroff +.if t .ds TX \fRT\\h'-0.1667m'\\v'0.20v'E\\v'-0.20v'\\h'-0.125m'X\fP +.if n .ds TX TeX +. +.\" and here the same for \LaTeX +.if t \{\ +.ie '\*(.T'dvi' \ +.ds LX \fRL\h'-0.36m'\v'-0.15v'\s-3A\s0\h'-0.15m'\v'0.15v'\fP\*(TX +.el .ds LX \fRL\h'-0.36m'\v'-0.22v'\s-2A\s0\h'-0.15m'\v'0.22v'\fP\*(TX +.\} +.if n .ds LX LaTeX +. +.\" \LaTeXe +.\" note that we need \vareps for TeX instead of \eps which can only be +.\" accessed with the \N escape sequence (in the Math Italic font) +.if t \{\ +.ie '\*(.T'dvi' .ds LE \*(LX\h'0.15m'2\v'0.20v'\f(MI\N'34'\fP\v'-0.20v' +.el .ds LE \*(LX\h'0.15m'2\v'0.20v'\(*e\v'-0.20v' +.\} +.if n .ds LE LaTeX\ 2e +. +.\" a typewriter font +.if t \{\ +.de C +\fC\\$1\fP\\$2\fC\\$3\fP\\$4 +.. +.\} +.if n \{\ +.de C +\\$1\\$2\\$3\\$4 +.. +.\} +. +.\" ==== +.\" ==== end of macro definitions +.\" ==== +. +. +. +.SH DESCRIPTION +This program extracts the metric and kerning information of a TrueType +font and converts it into metric files usable by \*(TX +(quite similar to +.B afm2tfm +which is part of the +.B dvips +package; please consult its info files for more details on the various +parameters (especially encoding files). +.PP +Since a TrueType font often contains more than 256\ glyphs, some means +are necessary to map a subset of the TrueType glyphs into a \*(TX +font. +To do this, two mapping tables are needed: the first (called `input' or +`raw' encoding) maps the TrueType font to a raw \*(TX font (this mapping +table is used by both +.B ttf2tfm +and +.BR ttf2pk ), +and the second (called `output' or `virtual' encoding) maps the raw \*(TX +font to another (virtual) \*(TX +font, providing all kerning and ligature information needed by \*(TX. +.PP +This two stage mapping has the advantage that one raw font can be +accessed with various \*(TX +encodings (e.g.\ T1 and OT1) via the virtual font mechanism, and just +one +.C PK +file is necessary. +.PP +For CJKV (Chinese/Japanese/Korean/old Vietnamese) fonts, a different +mechanism is provided (see +.B "SUBFONT DEFINITION FILES" +below). +. +. +.SH PARAMETERS +Most of the command line switch names are the same as in +.B afm2tfm +for convenience. +One or more space characters between an option and its value is mandatory; +options can't be concatenated. +For historical reasons, the first parameter can +.I not +be a switch but must be the font name. +.TP +.BI -c \ caps-height-factor +The height of small caps made with the +.B -V +switch. +Default value of this real number is\ 0.8 times the height of uppercase +glyphs. +Will be ignored in subfont mode. +.TP +.BI -e \ extension-factor +The extension factor to stretch the characters horizontally. +Default value of this real number is\ 1.0; if less than\ 1.0, you get a +condensed font. +.TP +.BI -E \ encoding-id +The TrueType encoding ID. +Default value of this non-negative integer is\ 1. +Will be ignored if +.B -N +is used. +.TP +.BI -f \ font-index +The font index in a TrueType Collection. +Default is the first font (index\ 0). +Will be ignored for ordinary TrueType fonts. +[TrueType collections are usually found in some CJK fonts; e.g.\ the first +font index specifies glyphs and metrics for horizontal writing, and the +second font index does the same for vertical writing. +TrueType collections usually have the extension `\c +.C \&.ttc '.] +.TP +.B -l +Create ligatures in subfonts between first and second bytes of all the +original character codes. +Example: Character code\ 0xABCD maps to character position\ 123 in +subfont\ 45. +Then a ligature in subfont\ 45 between position 0xAB and\ 0xCD pointing +to character\ 123 will be produced. +The fonts of the Korean H\*(LX +package use this feature. +Will be ignored if not in subfont mode. +.TP +.B -n +Use PS names (of glyphs) of the TrueType font. +Will be ignored in subfont mode. +Only glyphs with a valid entry in the selected cmap are used. +.TP +.B -N +Use only PS names of the TrueType font. +No cmap is used, thus the switches +.B -E +and +.B -P +have no effect, causing a warning message. +Will be ignored in subfont mode. +.TP +.B -O +Use octal values for all character codes in the +.C VPL +file rather than names; this is useful for symbol or CJK fonts where +character names such as `A' are meaningless. +.TP +.BI -p \ inencfile +The input encoding file name for the TTF\(->raw\ \*(TX +mapping. +This parameter has to be specified in +.C \%ttfonts.map +for successive +.B ttf2pk +calls. +Will be ignored in subfont mode. +.TP +.BI -P \ platform-id +The TrueType platform ID. +Default value of this non-negative integer is\ 3. +Will be ignored if +.B -N +is used. +.TP +.B -q +Make +.B ttf2tfm +quiet. +It suppresses any informational output except warning and error +messages. +For CJK fonts, the output can get quite large if you don't specify +this switch. +.TP +.BI -r \ old-glyphname\ new-glyphname +Replaces +.I \%old-glyphname +with +.IR \%new-glyphname . +This switch is useful if you want to give an unnamed glyph (i.e., a glyph +which can be represented with `.gXXX' or `.cXXX' only) a name or if you want +to rename an already existing glyph name. +You can't use the `.gXXX' or `.cXXX' glyph name constructs for +.IR \%new-glyphname ; +multiple occurrences of +.B -r +are possible. +If in subfont mode or if no encoding file is specified, this switch is +ignored. +.TP +.BI -R \ replacement-file +Use this switch if you have many replacement pairs; they can be collected +in a file which should have `\c +.C \&.rpl ' +as extension. +The syntax used in such replacement files is simple: Each non-empty +line must contain a pair `\c +.IR "\%old-glyphname \%new-glyphname" ' +separated by whitespace (without the quotation marks). +A percent sign starts a line comment; you can continue a line on the next +line with a backslash as the last character. +If in subfont mode or if no encoding file is specified, this switch is +ignored. +.TP +.BI -s \ slant-factor +The obliqueness factor to slant the font, usually much smaller than\ 1. +Default of this real number is\ 0.0; if the value is larger than zero, +the characters slope to the right, otherwise to the left. +.TP +.BI -t \ outencfile +The output encoding file name for the virtual font(s). +Only characters in the raw \*(TX +font are used. +Will be ignored in subfont mode. +.TP +.BI -T \ inoutencfile +This is equivalent to +.RB ` -p +.I inoutencfile +.B -t +.IR inoutencfile '. +Will be ignored in subfont mode. +.TP +.B -u +Use only those characters specified in the output encoding, and no +others. +By default, +.B ttf2tfm +tries to include all characters in the virtual font, even those not +present in the encoding for the virtual font (it puts them into +otherwise-unused positions, rather arbitrarily). +Will be ignored in subfont mode. +.TP +.BI -v \ vplfile +Output a +.C VPL +file in addition to the +.C TFM +file. +If no output encoding file is specified, +.B ttf2tfm +uses a default font encoding (cmtt10). +Will be ignored in subfont mode. +.TP +.BI -V \ scvplfile +Same as +.BR -v , +but the virtual font generated is a pseudo small caps font obtained by +scaling uppercase letters by\ 0.8 (resp. the value specified with +.BR -c ) +to typeset lowercase. +This font handles accented letters and retains proper kerning. +Will be ignored in subfont mode. +.TP +.B -x +Rotate all glyphs by 90 degrees counter-clockwise. +If no +.B -y +parameter is given, the rotated glyphs are shifted down vertically +by\ 0.25em. +Will be ignored if not in subfont mode. +.TP +.BI -y \ vertical-shift-factor +Shift down rotated glyphs by the given amount (the unit is +.IR em ). +Ignored if not in subfont mode or glyphs are not rotated. +.TP +.B --version +Shows the current version of +.B ttf2tfm +and the used file search library (e.g. +.BR kpathsea ). +.TP +.B --help +Shows usage information. +.PP +If no +.C TFM +file name is given, the name of the +.C TTF +file is used, including the full path and replacing the extension with `\c +.C \&.tfm '. +. +. +.SH CMAPS +Contrary to Type\ 1 PostScript fonts (but similar to the new CID +PostScript font format), most TrueType fonts have more than one native +mapping table, also called `cmap', which maps the (internal) TTF glyph +indices to the (external) TTF character codes. +Common examples are a mapping table to Unicode encoded character +positions, and the standard Macintosh mapping. + +To specify a TrueType mapping table, use the options +.B -P +and +.BR -E . +With +.B -P +you specify the platform ID; defined values are: +.PP +.in +4m +.ta 3iC +.I "platform platform ID (pid)" +.sp +.ta 3iR +Apple Unicode 0 +.br +Macintosh 1 +.br +ISO 2 +.br +Microsoft 3 +.PP +The encoding ID depends on the platform. +For pid=0, we ignore the +.B -E +parameter (setting it to zero) since the mapping table is always +Unicode version\ 2.0. +For pid=1, the following table lists the defined values: +.PP +.in +4m +.ta 3iC +.ti -2m +platform ID = 1 +.sp +.I "script encoding ID (eid)" +.sp +.ta 3iR +Roman 0 +.br +Japanese 1 +.br +Chinese 2 +.br +Korean 3 +.br +Arabic 4 +.br +Hebrew 5 +.br +Greek 6 +.br +Russian 7 +.br +Roman Symbol 8 +.br +Devanagari 9 +.br +Gurmukhi 10 +.br +Gujarati 11 +.br +Oriya 12 +.br +Bengali 13 +.br +Tamil 14 +.br +Telugu 15 +.br +Kannada 16 +.br +Malayalam 17 +.br +Sinhalese 18 +.br +Burmese 19 +.br +Khmer 20 +.br +Thai 21 +.br +Laotian 22 +.br +Georgian 23 +.br +Armenian 24 +.br +Maldivian 25 +.br +Tibetan 26 +.br +Mongolian 27 +.br +Geez 28 +.br +Slavic 29 +.br +Vietnamese 30 +.br +Sindhi 31 +.br +Uninterpreted 32 +.PP +Here are the ISO encoding IDs: +.PP +.in +4m +.ta 3iC +.ti -2m +platform ID = 2 +.sp +.I "encoding encoding ID (eid)" +.sp +.ta 3iR +ASCII 0 +.br +ISO 10646 1 +.br +ISO 8859-1 2 +.PP +And finally, the Microsoft encoding IDs: +.PP +.in +4m +.ta 3iC +.ti -2m +platform ID = 3 +.sp +.I "encoding encoding ID (eid)" +.sp +.ta 3iR +Symbol 0 +.br +Unicode 2.0 1 +.br +Shift JIS 2 +.br +GB 2312 (1980) 3 +.br +Big 5 4 +.br +KSC 5601 (Wansung) 5 +.br +KSC 5601 (Johab) 6 +.PP +The program will abort if you specify an invalid platform/encoding ID +pair. +It will then show the possible pid/eid pairs. +Please note that most fonts have at most two or three cmaps, usually +corresponding to the pid/eid pairs (1,0), (3,0), or (3,1) in case of +Latin based fonts. +Valid Microsoft fonts should have a (3,1) mapping table, but some +fonts exist (mostly Asian fonts) which have a (3,1) cmap not encoded +in Unicode. +The reason for this strange behavior is the fact that some MS\ Windows +versions will reject fonts having a non-(3,1) cmap (since all non-Unicode +Microsoft encoding IDs are for Asian MS\ Windows versions). +.PP +The +.B -P +and +.B -E +options of +.B ttf2tfm +must be equally specified for +.BR ttf2pk ; +the corresponding parameters in +.C \%ttfonts.map +are `Pid' and `Eid', respectively. +.PP +The default pid/eid pair is (3,1). +.PP +Similarly, an +.B -f +option must be specified as `Fontindex' parameter in +.C \%ttfonts.map . +.PP +If you use the +.B -N +switch, all cmaps are ignored, using only the PostScript names in the +TrueType font. +The corresponding option in +.C \%ttfonts.map +is \%`PS=Only'. +If you use the +.B -n +switch, the default glyph names built into +.B ttf2tfm +are replaced with the PS glyph names found in the font. +In many cases this is not what you want because the glyph names in the +font are often incorrect or non-standard. +The corresponding option in +.C \%ttfonts.map +is \%`PS=Yes'. +.PP +Single replacement glyph names specified with +.B -r +must be given directly as `\c +.IR old-glyphname = new-glyphname '; +.B -R +is equivalent to the `Replacement' option. +. +. +.SH INPUT AND OUTPUT ENCODINGS +You must specify the encoding vectors from the TrueType font to the +raw \*(TX +font and from the raw \*(TX +font to the virtual \*(TX +font exactly as with +.BR afm2tfm , +but you have more possibilities to address the character codes. +[With `encoding vector' a mapping table with 256\ entries in form of a +PostScript vector is meant; see the file +.C \%T1-WGL4.enc +of this package for an example.] +With +.BR afm2tfm , +you must access each glyph with its Adobe glyph name, e.g.\ \c +\%`/quotedsingle' or \%`/Acircumflex'. +This has been extended with +.BR ttf2tfm ; +now you can (and sometimes must) access the code points and/or glyphs +directly, using the following syntax for specifying the character position +in decimal, octal, or hexadecimal notation: +`/.c\c +.IR ', +`/.c0\c +.IR ', +or `/.c0x\c +.IR '. +Examples: \%`/.c72', \%`/.c0646', \%`/.c0x48'. +To access a glyph index directly, using the character `g' instead of +`c' in the just introduced notation. +Example: \%`/.g0x32'. +[Note: The `.cXXX' notation makes no sense if +.B -N +is used.] +.PP +For pid/eid pairs (1,0) and (3,1), both +.B ttf2tfm +and +.B ttf2pk +recognize built-in default Adobe glyph names; the former follows the names +given in Appendix\ E of the book `Inside Macintosh', volume\ 6, the latter +uses the names given in the TrueType Specification (WGL4, a Unicode subset). +Note that Adobe names for a given glyph are often not unique and do +sometimes differ, e.g., many PS fonts have the glyph `mu', whereas this +glyph is called `mu1' in the WGL4 character set to distinguish it from the +real Greek letter mu. +Be also aware that OpenType (i.e. TrueType\ 2.0) fonts use an updated WGL4 +table; we use the data from the latest published TrueType specification +(1.66). +You can find those mapping tables in the source code file +.C \%ttfenc.c . +.PP +On the other hand, the switches +.B -n +and +.B -N +makes +.B ttf2tfm +read in and use the PostScript names in the TrueType font itself (stored +in the `post' table) instead of the default Adobe glyph names. +.PP +Use the +.B -r +switch to remap single glyph names and +.B -R +to specify a file containing replacement glyph name pairs. +.PP +If you don't select an input encoding, the first 256\ glyphs of the +TrueType font with a valid entry in the selected cmap will be mapped +to the \*(TX +raw font (without the +.B -q +option, +.B ttf2tfm +prints this mapping table to standard output), followed by all glyphs +not yet addressed in the selected cmap. +However, some code points for the (1,0) pid/eid pair are omitted since +they do not represent glyphs useful for \*(TX: +0x00 (null), 0x08 (backspace), 0x09 (horizontal tabulation), 0x0d +(carriage return), and 0x1d (group separator). +The `invalid character' with glyph index\ 0 will be omitted too. +.PP +If you select the +.B -N +switch, the first 256\ glyphs of the TrueType font with a valid PostScript +name will be used in case no input encoding is specified. +Again, some glyphs are omitted: `.notdef', `.null', and +`nonmarkingreturn'. +.PP +If you don't select an output encoding, +.B ttf2tfm +uses the same mapping table as +.B afm2tfm +would use (you can find it in the source code file +.C \%texenc.c ); +it corresponds to \*(TX +typewriter text. +Unused positions (either caused by empty code points in the mapping +table or missing glyphs in the TrueType font) will be filled (rather +arbitrarily) with characters present in the input encoding but not +specified in the output encoding (without the +.B -q +option +.B ttf2tfm +prints the final output encoding to standard output). +Use the +.B -u +option if you want only glyphs in the virtual font which are defined +in the output encoding file, and nothing more. +.PP +One feature missing in +.B afm2tfm +has been added which is needed by the T1 encoding: +.B ttf2tfm +will construct the glyph `Germandbls' (by simply concatenating to `S' +glyphs) even for normal fonts if possible. +It appears in the glyph list as the last item, marked with an asterisk. +Since this isn't a real glyph it will be available only in the virtual +font. +.PP +For both input and output encoding, an empty code position is +represented by the glyph name \%`/.notdef'. +.PP +In encoding files, you can use `\\' as the final character of a line to +indicate that the input is continued on the next line. +The backslash and the following newline character will be removed. +.PP +. +. +.SH SUBFONT DEFINITION FILES +CJKV (Chinese/Japanese/Korean/old Vietnamese) fonts usually contain several +thousand glyphs; to use them with \*(TX +it is necessary to split such large fonts into subfonts. +Subfont definition files (usually having the extension `\c +.C \&.sfd ') +are a simple means to do this smoothly. +.PP +A subfont file name usually consists of a prefix, a subfont infix, and +a postfix (which is empty in most cases), e.g. +.PP +.in +2m +ntukai23 \(-> prefix: ntukai, infix: 23, postfix: (empty) +.PP +Here the syntax of a line in an +.C SFD +file, describing one subfont: +.in +2m +.TP +.I +.sp +.TP +.IR \ := +anything except whitespace. +It's best to use only alphanumerical characters. +.TP +.IR \ := +space, formfeed, carriage return, horizontal and vertical tabs -- no +newline characters. +.TP +.IR \ := +.IR " " \ | +.br +.IR " " \ | +.br +.I +.TP +.IR \ := +.I +.br +.TP +.IR \ := +.IR \ `_' \ +.br +.TP +.IR \ := +.IR \ `:' +.TP +.IR \ := +hexadecimal (prefix `0x'), decimal, or octal (prefix `0') +.PP +A line can be continued on the next line with a backslash ending the line. +The ranges must not overlap; offsets have to be in the range 0-255. +.PP +Example: +.PP +.in +2m +The line +.PP +.in +4m +.C "03 10: 0x2349 0x2345_0x2347" +.PP +.in +2m +assigns to the code positions 10, 11, 12, and\ 13 of the subfont +having the infix `03' the character codes 0x2349, 0x2345, 0x2346, and +0x2347 respectively. +.PP +The +.C SFD +files in the distribution are customized for the CJK package for +\*(LX. +.PP +You have to embed the +.C SFD +file name into the +.C TFM +font name (at the place where the infix will appear) surrounded by two +`@' signs, on the command line resp.\ the +.C \%ttfonts.map +file; both +.B ttf2tfm +and +.B ttf2pk +switch then to subfont mode. +.PP +Subfont mode disables the options +.BR -n , \ -N , \ -p , +.BR -r , \ -R , \ -t , +.BR -T , \ -u , \ -v , +and +.B -V +for +.BR ttf2tfm ; +similarly, no `Encoding' or `Replacement' parameter is allowed in +.C \%ttfonts.map . +Single replacement glyph names are ignored too. +.PP +.B ttf2tfm +will create all subfont +.C TFM +files specified in the +.C SFD +files (provided the subfont contains glyphs) in one run. +.PP +Example: +.PP +.in +2m +The call +.PP +.in +4m +.C "ttf2tfm ntukai.ttf ntukai@/usr/local/lib/ttf2tfm/Big5@" +.PP +.in +2m +will use +.C /usr/local/lib/ttf2tfm/Big5.sfd , +producing +.I all +subfont files +.C ntukai01.tfm , +.C ntukai02.tfm , +etc. +. +. +.SH "RETURN VALUE" +ttf2tfm returns 0 on success and 1 on error; warning and error +messages are written to standard error. +. +. +.SH "SOME NOTES ON FILE SEARCHING" +Both +.B ttf2pk +and +.B ttf2tfm +use either the +.BR kpathsea , +.BR emtexdir , +or +.B MiKTeX +library for searching files +.RB ( emtexdir +will work only on operating systems which have an MS-DOSish background, i.e. +MS-DOS, OS/2, Windows; +.B MiKTeX +is specific to MS Windows). +.PP +As a last resort, both programs can be compiled without a search library; +the searched files must be then in the current directory or specified with a +path. +Default extensions will be appended also (with the exception that only `\c +.C \&.ttf ' +is appended and not `\c +.C \&.ttc '). +.PP +KPATHSEA +.PP +Please note that older versions of +.B kpathsea +(<3.2) have no special means to seach for TrueType fonts and related +files, thus we use the paths for PostScript related stuff. +The actual version of kpathsea is displayed on screen if you call +either +.B ttf2pk +or +.B ttf2tfm +with the +.B --version +command line switch. +.PP +Here is a table of the file type and the corresponding +.B kpathsea +variables. +.C TTF2PKINPUTS +and +.C TTF2TFMINPUTS +are program specific environment variables introduced in +.B kpathsea +version\ 3.2: +.PP +.in +4m +.ta 2i +.C \&.ttf \ and "\ .ttc TTFONTS" +.br +.C "ttfonts.map TTF2PKINPUTS" +.br +.C "\&.enc TTF2PKINPUTS, TTF2TFMINPUTS" +.br +.C "\&.rpl TTF2PKINPUTS, TTF2TFMINPUTS" +.br +.C "\&.tfm TFMFONTS" +.br +.C "\&.sfd TTF2PKINPUTS, TTF2TFMINPUTS" +.PP +And here the same for pre-3.2-versions of +.B kpathsea: +.PP +.in +4m +.ta 2i +.C \&.ttf \ and "\ .ttc T1FONTS" +.br +.C "ttfonts.map TEXCONFIG" +.br +.C "\&.enc TEXPSHEADERS" +.br +.C "\&.rpl TEXPSHEADERS" +.br +.C "\&.tfm TFMFONTS" +.br +.C "\&.sfd TEXPSHEADERS" +.PP +Finally, the same for pre-3.0-versions (as used e.g. in te\*(TX\ 0.4): +.PP +.in +4m +.ta 2i +.C \&.ttf \ and "\ .ttc DVIPSHEADERS" +.br +.C "ttfonts.map TEXCONFIG" +.br +.C "\&.enc DVIPSHEADERS" +.br +.C "\&.rpl DVIPSHEADERS" +.br +.C "\&.tfm TFMFONTS" +.br +.C "\&.sfd DVIPSHEADERS" +.PP +Please consult the info files of +.B kpathsea +for details on these variables. +The decision whether to use the old or the new scheme will be done +during compilation. +.PP +You should set the +.C TEXMFCNF +variable to the directory where your +.C texmf.cnf +configuration file resides. +.PP +Here is the proper command to find out to which value a +.B kpathsea +variable is set (we use +.C TTFONTS +as an example). +This is especially useful if a variable isn't set in +.C texmf.cnf +or in the environment, thus pointing to the default value which is +hard-coded into the +.B kpathsea +library. +.PP +.in +2m +.C "kpsewhich -progname=ttf2tfm -expand-var='$TTFONTS'" +.PP +We select the program name also since it is possible to specify +variables which are searched only for a certain program -- in our +example it would be +.C TTFONTS.ttf2tfm . +.PP +A similar but not identical method is to say +.PP +.in +2m +.C "kpsewhich -progname=ttf2tfm -show-path='truetype fonts'" +.PP +[A full list of format types can be obtained by saying `\c +.C "kpsewhich --help" ' +on the command line prompt.] +This is exactly the how +.B ttf2tfm +(and +.BR ttf2pk ) +search for files; the disadvantage is that all variables are expanded +which can cause very long strings. +.PP +EMTEXDIR +.PP +Here the list of suffixes and its related environment variables to be +set in +.C autoexec.bat +(resp. in +.C config.sys +for OS/2): +.PP +.in +4m +.ta 2i +.C \&.ttf \ and "\ .ttc TTFONTS" +.br +.C "ttfonts.map TTFCFG" +.br +.C "\&.enc TTFCFG" +.br +.C "\&.rpl TTFCFG" +.br +.C "\&.tfm TEXTFM" +.br +.C "\&.sfd TTFCFG" +.PP +If one of the variables isn't set, a warning message is emitted. +The current directory will always be searched. +As usual, one exclamation mark appended to a directory path causes +subdirectories one level deep to be searched, two exclamation marks causes +all subdirectories to be searched. +Example: +.PP +.in +2m +.C TTFONTS=c:\\\\fonts\\\\truetype!!;d:\\\\myfonts\\\\truetype! +.PP +Constructions like `\c +.C c:\\\\fonts!!\\\\truetype ' +aren't possible. +.PP +MIKTEX +.PP +Both +.B ttf2tfm +and +.B ttf2pk +have been fully integrated into +.BR MiKTeX . +Please refer to the documentation of +.B MiKTeX +for more details on file searching. +. +. +.SH PROBLEMS +Most +.B vptovf +implementations allow only 100\ bytes for the +.C TFM +header (the limit is 1024 in the +.C TFM +file itself): 8\ bytes for checksum and design size, 40\ bytes for the +family name, 20\ bytes for the encoding, and 4\ bytes for a face byte. +There remain only 28\ bytes for some additional information which is used by +.B ttf2tfm +for an identification string (which is essentially a copy of the command +line), and this limit is always exceeded. + +The optimal solution is to increase the value of +.I \%max_header_bytes +in the file +.C vptovf.web +(and probably +.C pltotf.web +too) to, say,\ 400 +and recompile +.B vptovf +(and +.BR pltotf ). +Otherwise you'll get some (harmless) error messages like +.PP +.in +2m +.C "This HEADER index is too big for my present table size" +.PP +which can be safely ignored. +. +. +.SH "SEE ALSO" +.BR ttf2pk (1), +.BR afm2tfm (1), +.BR vptovf (1), +.br +the info pages for +.B dvips +and +.B kpathsea +. +. +.SH AVAILABILITY +.B ttf2tfm +is part of the FreeType package, a high quality TrueType rendering +library. +. +. +.SH AUTHORS +Werner LEMBERG +.C +.br +Fr\('ed\('eric LOYER +.C diff --git a/contrib/ttf2pk/ttf2tfm.c b/contrib/ttf2pk/ttf2tfm.c new file mode 100644 index 0000000..5d97420 --- /dev/null +++ b/contrib/ttf2pk/ttf2tfm.c @@ -0,0 +1,885 @@ +/* + * ttf2tfm.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg . + */ + +/* + * This program converts TTF files to TeX TFM files, and optionally + * to TeX VPL files that retain all kerning and ligature information. + * Both files make the characters not normally encoded by TeX available + * by character codes greater than 0x7F. + */ + +/* + * Adapted from afm2tfm by F. Loyer . + */ + +#include +#include +#include /* for size_t */ +#include + +#include "ttf2tfm.h" +#include "newobj.h" +#include "ttfenc.h" +#include "ligkern.h" +#include "texenc.h" +#include "ttfaux.h" +#include "tfmaux.h" +#include "vplaux.h" +#include "errormsg.h" +#include "filesrch.h" +#include "parse.h" +#include "subfont.h" + + +char ident[] = "ttf2tfm version 1.3"; +char progname[] = "ttf2tfm"; /* for error/warning messages */ + +/* command line options */ + +static char makevpl; /* can be 1 or 2 */ +static Boolean pedantic; +static Boolean quiet; +static Boolean forceoctal; + + +/* + * Re-encode the TTF font. + */ + +static void +handlereencoding(Font *fnt) +{ + int i; + ttfinfo *ti; + char *p; + + + if (fnt->inencname) + { + fnt->inencoding = readencoding(&(fnt->inencname), fnt, True); + + /* reset all pointers in the mapping table */ + for (i = 0; i <= 0xFF; i++) + if (NULL != (ti = fnt->inencptrs[i])) + { + ti->incode = -1; + fnt->inencptrs[i] = NULL; + } + + /* + * Reencode TTF <--> raw TeX. Only these code points will be used + * for the output encoding. + */ + + for (i = 0; i <= 0xFF; i++) + { + p = fnt->inencoding->vec[i]; + if (p && *p) + { + if ((ti = findadobe(p, fnt->charlist))) + { + if (ti->incode >= 0) + { + warning("Character `%s' encoded twice in input encoding\n" + " (positions %x and %x; the latter is ignored).", + p, ti->incode, i); + fnt->inencoding->vec[i] = ".notdef"; + continue; + } + if (ti->charcode >= 0) + { + ti->incode = i; + fnt->inencptrs[i] = ti; + } + } + else + { + warning("Cannot find character `%s'\n" + " specified in input encoding.", p); + } + } + } + fnt->codingscheme = fnt->inencoding->name; + } + + if (!quiet) + { + if (fnt->inencname) + printf("\nUsing %s as input encoding.\n", fnt->inencname); + else + { + printf( + "\nUsing the first 256 glyphs in the following input encoding:\n\n"); + for (i = 0; i <= 0xFF; i++) + { + if ((ti = fnt->inencptrs[i])) + printf(" 0x%02x %s\n", i, ti->adobename); + } + printf("\n"); + } + } + + if (fnt->outencname) + fnt->outencoding = readencoding(&(fnt->outencname), fnt, False); + else + fnt->outencoding = readencoding(NULL, fnt, False); +} + + +static void +assignchars(Font *fnt) +{ + register char **p; + register int i, j, k; + register ttfinfo *ti; + int nextfree = 0x80; + + + /* + * First, we assign all those that match perfectly. + */ + + for (i = 0, p = fnt->outencoding->vec; i <= 0xFF; i++, p++) + if ((ti = findmappedadobe(*p, fnt->inencptrs))) + { + if (ti->outcode >= 0) + fnt->nextout[i] = ti->outcode; /* linked list */ + ti->outcode = i; + fnt->outencptrs[i] = ti; + } + else if (strcmp(*p, ".notdef") != 0) + warning("Cannot map character `%s'\n" + " specified in output encoding.", *p); + + if (pedantic) + goto end; + + /* + * Next, we assign all the others, retaining the TTF code positions, + * possibly multiplying assigned characters, unless the output encoding + * was precisely specified. + */ + + for (i = 0; i <= 0xFF; i++) + if ((ti = fnt->inencptrs[i]) && + ti->charcode >= 0 && ti->charcode <= 0xFF && + ti->outcode < 0 && fnt->outencptrs[ti->charcode] == NULL) + { + ti->outcode = ti->charcode; + fnt->outencptrs[ti->charcode] = ti; + } + + /* + * Finally, we map all remaining characters into free locations beginning + * with 0x80. + */ + + for (i = 0; i <= 0xFF; i++) + if ((ti = fnt->inencptrs[i]) && ti->outcode < 0) + { + while (fnt->outencptrs[nextfree]) + { + nextfree = (nextfree + 1) & 0xFF; + if (nextfree == 0x80) + goto finishup; /* all slots full */ + } + ti->outcode = nextfree; + fnt->outencptrs[nextfree] = ti; + } + +finishup: + + /* + * Now, if any of the characters are encoded multiple times, we want + * ti->outcode to be the first one assigned, since that is most likely + * to be the most important one. So we reverse the above lists. + */ + + for (i = 0; i <= 0xFF; i++) + if ((ti = fnt->inencptrs[i]) && ti->outcode >= 0) + { + k = -1; + while (fnt->nextout[ti->outcode] >= 0) + { + j = fnt->nextout[ti->outcode]; + fnt->nextout[ti->outcode] = k; + k = ti->outcode; + ti->outcode = j; + } + fnt->nextout[ti->outcode] = k; + } + +end: + + if (!quiet) + { + printf("\nUsing the following output encoding:\n\n"); + for (i = 0; i <= 0xFF; i++) + { + if ((ti = fnt->outencptrs[i])) + printf(" 0x%02x %s\n", i, ti->adobename); + } + printf("\n"); + } +} + + +#define VERSION "\ +Copyright (C) 1997-1999 Frederic Loyer and Werner Lemberg.\n\ +There is NO warranty. You may redistribute this software\n\ +under the terms of the GNU General Public License\n\ +and the Dvips copyright.\n\ +\n\ +For more information about these matters, see the files\n\ +named COPYING and ttf2tfm.c.\n\ +\n\ +Primary authors of ttf2tfm: F. Loyer and W. Lemberg.\n\ +\n\ +ttf2tfm is based on afm2tfm from T. Rokicki\n\ +and the FreeType project from\n\ +David Turner, Robert Wilhelm, and Werner Lemberg.\n\ +" + +static void +version(void) +{ + fputs(ident, stdout); + fprintf(stdout, " (%s)\n", TeX_search_version()); + fputs(VERSION, stdout); + exit(0); +} + + +#define USAGE "\ + Convert a TrueType font table to TeX's font metric format.\n\ +\n\ +-c REAL use REAL for height of small caps made with -V [0.8]\n\ +-e REAL widen (extend) characters by a factor of REAL [1.0]\n\ +-E INT select INT as the TTF encoding ID [1]\n\ +-f INT select INT as the font index in a TTC [0]\n\ +-l create 1st/2nd byte ligatures in subfonts\n\ +-n use PS names of TrueType font\n\ +-N use only PS names and no cmap\n\ +-O use octal for all character codes in the vpl file\n\ +-p ENCFILE[.enc] read ENCFILE for the TTF->raw TeX mapping\n\ +-P INT select INT as the TTF platform ID [3]\n\ +-q suppress informational output\n\ +-r OLDNAME NEWNAME replace glyph name OLDNAME with NEWNAME\n\ +-R RPLFILE[.rpl] read RPLFILE containing glyph replacement names\n\ +-s REAL oblique (slant) characters by REAL, usually <<1 [0.0]\n\ +-t ENCFILE[.enc] read ENCFILE for the encoding of the vpl file\n\ +-T ENCFILE[.enc] equivalent to -p ENCFILE -t ENCFILE\n\ +-u output only characters from encodings, nothing extra\n\ +-v FILE[.vpl] make a VPL file for conversion to VF\n\ +-V SCFILE[.vpl] like -v, but synthesize smallcaps as lowercase\n\ +-x rotate subfont glyphs by 90 degrees\n\ +-y REAL move rotated glyphs down by a factor of REAL [0.25]\n\ +--help print this message and exit\n\ +--version print version number and exit\n\ +" + +static void +usage(void) +{ + fputs("Usage: ttf2tfm FILE[.ttf|.ttc] [OPTION]... [FILE[.tfm]]\n", stdout); + fputs(USAGE, stdout); + exit(0); +} + + +static void +handle_options(int argc, char *argv[], Font *fnt) +{ + register int lastext; + register int i; + size_t l; + int arginc; + char *temp; + char c; + char *vpl_name = NULL; + Boolean have_capheight = 0; + Boolean have_sfd = 0; + int sfd_begin, postfix_begin; + int base_name; + stringlist* sl; + + + /* scan first whether the -q switch is set */ + for (i = 1; i < argc; i++) + if (argv[i][0] == '-' && argv[i][1] == 'q') + quiet = True; + + if (!quiet) + printf("This is %s\n", ident); + +#if defined(MSDOS) || defined(OS2) || defined(ATARIST) + /* Make VPL file identical to that created under Unix */ + fnt->titlebuf = (char *)mymalloc(strlen(progname) + strlen(argv[1]) + + 1 + 1); + sprintf(fnt->titlebuf, "%s %s", progname, argv[1]); +#else + fnt->titlebuf = (char *)mymalloc(strlen(argv[0]) + strlen(argv[1]) + + 1 + 1); + sprintf(fnt->titlebuf, "%s %s", argv[0], argv[1]); +#endif + + + /* + * TrueType font name. + */ + + fnt->ttfname = newstring(argv[1]); + + /* + * The other arguments. We delay the final processing of some switches + * until the tfm font name has been scanned -- if it contains two `@'s, + * many switches are ignored. + */ + + while (argc > 2 && *argv[2] == '-') + { + arginc = 2; + i = argv[2][1]; + + switch (i) + { + case 'v': + makevpl = 1; + if (argc <= 3) + oops("Missing parameter for -v option."); + if (vpl_name) + free(vpl_name); + vpl_name = newstring(argv[3]); + handle_extension(&vpl_name, ".vpl"); + break; + + case 'V': + makevpl = 2; + if (argc <= 3) + oops("Missing parameter for -V option."); + if (vpl_name) + free(vpl_name); + vpl_name = newstring(argv[3]); + handle_extension(&vpl_name, ".vpl"); + break; + + case 'f': + if (argc <= 3) + oops("Missing parameter for -f option."); + if (sscanf(argv[3], "%lu", &(fnt->fontindex)) == 0) + oops("Invalid font index."); + fnt->fontindexparam = argv[3]; + break; + + case 'E': + if (argc <= 3) + oops("Missing parameter for -E option."); + if (sscanf(argv[3], "%hu", &(fnt->eid)) == 0) + oops("Invalid encoding ID."); + fnt->eidparam = argv[3]; + break; + + case 'P': + if (argc <= 3) + oops("Missing parameter for -P option."); + if (sscanf(argv[3], "%hu", &(fnt->pid)) == 0) + oops("Invalid platform ID."); + fnt->pidparam = argv[3]; + break; + + case 'e': + if (argc <= 3) + oops("Missing parameter for -e option."); + if (sscanf(argv[3], "%f", &(fnt->efactor)) == 0 || fnt->efactor < 0.01) + oops("Bad extension factor."); + fnt->efactorparam = argv[3]; + break; + + case 'c': + if (argc <= 3) + oops("Missing parameter for -c option."); + have_capheight = True; + if (sscanf(argv[3], "%f", &(fnt->capheight)) == 0) + fnt->capheight = 0; + break; + + case 's': + if (argc <= 3) + oops("Missing parameter for -s option."); + if (sscanf(argv[3], "%f", &(fnt->slant)) == 0) + oops("Bad slant parameter."); + fnt->slantparam = argv[3]; + break; + + case 'p': + if (argc <= 3) + oops("Missing parameter for -p option."); + if (fnt->inencname) + free(fnt->inencname); + fnt->inencname = newstring(argv[3]); + break; + + case 'T': + if (argc <= 3) + oops("Missing parameter for -T option."); + if (fnt->inencname) + free(fnt->inencname); + if (fnt->outencname) + free(fnt->outencname); + fnt->inencname = newstring(argv[3]); + fnt->outencname = newstring(argv[3]); + break; + + case 't': + if (argc <= 3) + oops("Missing parameter for -T option."); + if (fnt->outencname) + free(fnt->outencname); + fnt->outencname = newstring(argv[3]); + break; + + case 'r': + if (argc <= 4) + oops("Not enough parameters for -r option."); + sl = newstringlist(); + sl->old_name = newstring(argv[3]); + sl->new_name = newstring(argv[4]); + sl->single_replacement = True; + sl->next = fnt->replacements; + fnt->replacements = sl; + arginc = 3; + break; + + case 'R': + if (argc <= 3) + oops("Missing parameter for -R option."); + if (fnt->replacementname) + free(fnt->replacementname); + fnt->replacementname = newstring(argv[3]); + break; + + case 'y': + if (argc <= 3) + oops("Missing parameter for -y option."); + if (sscanf(argv[3], "%f", &(fnt->y_offset)) == 0) + oops("Invalid y-offset."); + fnt->y_offsetparam = argv[3]; + break; + + case 'O': + forceoctal = True; + arginc = 1; + break; + + case 'n': + fnt->PSnames = Yes; + arginc = 1; + break; + + case 'N': + fnt->PSnames = Only; + arginc = 1; + break; + + case 'u': + pedantic = True; + arginc = 1; + break; + + case 'q': + quiet = True; + arginc = 1; + break; + + case 'l': + fnt->subfont_ligs = True; + arginc = 1; + break; + + case 'x': + fnt->rotate = True; + arginc = 1; + break; + + default: + if (argc <= 3 || argv[3][0] == '-') + { + warning("Unknown option `%s' will be ignored.\n", argv[2]); + arginc = 1; + } + else + warning("Unknown option `%s %s' will be ignored.\n", + argv[2], argv[3]); + } + + for (i = 0; i < arginc; i++) + { + l = strlen(fnt->titlebuf); + fnt->titlebuf = (char *)myrealloc((void *)fnt->titlebuf, + l + strlen(argv[2]) + 1 + 1); + sprintf(fnt->titlebuf + strlen(fnt->titlebuf), " %s", argv[2]); + argv++; + argc--; + } + } + + /* Read replacement glyph name file */ + + get_replacements(fnt); + + if (argc > 3 || (argc == 3 && *argv[2] == '-')) + oops("Need at most two non-option arguments."); + + /* + * The tfm file name. + */ + + if (argc == 2) + temp = newstring(fnt->ttfname); + else + { + temp = newstring(argv[2]); + l = strlen(fnt->titlebuf); + fnt->titlebuf = (char *)myrealloc((void *)fnt->titlebuf, + l + strlen(argv[2]) + 1 + 1); + sprintf(fnt->titlebuf + strlen(fnt->titlebuf), " %s", argv[2]); + } + + handle_sfd(temp, &sfd_begin, &postfix_begin); + + if (sfd_begin > -1) + { + have_sfd = True; + i = sfd_begin - 2; + } + else + i = strlen(temp) - 1; + + /* + * Now we search the beginning of the name without directory. + */ + + for (; i >= 0; i--) + if (temp[i] == '/' || temp[i] == ':' || temp[i] == '\\') + break; + + base_name = i + 1; + + /* + * We store the path (with the final directory separator). + */ + + if (base_name > 0) + { + c = temp[base_name]; + temp[base_name] = '\0'; + fnt->tfm_path = newstring(temp); + temp[base_name] = c; + } + + if (have_sfd) + { + /* the prefix and the sfd file name */ + + if (temp[base_name]) + fnt->outname = newstring(temp + base_name); + + fnt->sfdname = newstring(temp + sfd_begin); + } + else + postfix_begin = base_name; + + /* + * Get the extension. + */ + + lastext = -1; + for (i = postfix_begin; temp[i]; i++) + if (temp[i] == '.') + lastext = i; + + if (argc == 2 && lastext >= 0) + { + temp[lastext] = '\0'; /* remove TTF file extension */ + lastext = -1; + } + + if (lastext == -1) + fnt->tfm_ext = newstring(".tfm"); + else + { + fnt->tfm_ext = newstring(temp + lastext); + temp[lastext] = '\0'; + } + + if (have_sfd) + { + if (temp[postfix_begin]) + fnt->outname_postfix = newstring(temp + postfix_begin); + } + else + { + if (temp[base_name]) + fnt->outname = newstring(temp + base_name); + else + oops("Invalid tfm file name."); + } + + + /* + * Now we can process the remaining parameters. + */ + + if (have_sfd) + { + if (makevpl) + { + warning("Ignoring `-v' and `-V' switches for subfonts."); + makevpl = 0; + } + if (have_capheight) + warning("Ignoring `-c' switch for subfonts."); + if (fnt->inencname || fnt->outencname) + { + warning("Ignoring `-p', `-t', and `-T' switches for subfonts."); + fnt->inencname = NULL; + fnt->outencname = NULL; + } + if (fnt->y_offsetparam && !fnt->rotate) + warning("Ignoring `-y' switch for non-rotated subfonts."); + if (fnt->PSnames) + { + warning("Ignoring `-n' or '-N' switch for subfonts."); + fnt->PSnames = No; + } + + init_sfd(fnt, True); + } + else + { + if (have_capheight && fnt->capheight < 0.01) + oops("Bad small caps height."); + + if (vpl_name) + if ((fnt->vplout = fopen(vpl_name, "wt")) == NULL) + oops("Cannot open vpl output file."); + + if (fnt->subfont_ligs) + { + warning("Ignoring `-l' switch for non-subfont."); + fnt->subfont_ligs = False; + } + + if (fnt->rotate) + { + warning("Ignoring `-x' switch for non-subfont."); + fnt->rotate = False; + } + + if (fnt->y_offsetparam) + warning("Ignoring `-y' switch for non-subfont."); + } + + if (fnt->PSnames == Only) + { + if (fnt->pidparam || fnt->eidparam) + { + warning("Ignoring `-P' and `-E' options if `-N' switch is selected."); + fnt->pidparam = NULL; + fnt->eidparam = NULL; + } + } + + if (vpl_name) + free(vpl_name); + free(temp); +} + + +/* + * This routine prints out the line that needs to be added to ttfonts.map. + */ + +static void +consttfonts(Font *fnt) +{ + if (!quiet) + printf("\n"); + if (fnt->outname) + printf("%s", fnt->outname); + if (fnt->sfdname) + printf("@%s@", fnt->sfdname); + if (fnt->outname_postfix) + printf("%s", fnt->outname_postfix); + + printf(" %s", fnt->ttfname); + + if (fnt->slantparam || fnt->efactorparam || + fnt->inencname || + fnt->pidparam || fnt->eidparam || + fnt->fontindexparam || + fnt->replacements || + fnt->replacementname || + fnt->PSnames || + fnt->rotate || fnt->y_offsetparam) + { + if (fnt->slantparam) + printf(" Slant=%s", fnt->slantparam); + if (fnt->efactorparam) + printf(" Extend=%s", fnt->efactorparam); + if (fnt->inencname) + printf(" Encoding=%s", fnt->inencname); + if (fnt->pidparam) + printf(" Pid=%s", fnt->pidparam); + if (fnt->eidparam) + printf(" Eid=%s", fnt->eidparam); + if (fnt->fontindexparam) + printf(" Fontindex=%s", fnt->fontindexparam); + if (fnt->PSnames) + printf(" PS=%s", fnt->PSnames == Yes ? "Yes" : "Only"); + if (fnt->rotate) + printf(" Rotate=Yes"); + if (fnt->y_offsetparam) + printf(" Y-Offset=%s", fnt->y_offsetparam); + if (fnt->replacementname && fnt->inencoding) + printf(" Replacement=%s", fnt->replacementname); + if (fnt->replacements && fnt->inencoding) + { + stringlist *sl; + + + for (sl = fnt->replacements; sl; sl = sl->next) + if (sl->single_replacement) + printf(" %s=%s", sl->old_name, sl->new_name); + } + } + printf("\n"); +} + + +int +main(int argc, char *argv[]) +{ + Font font; + ttfinfo *ti; + + + init_font_structure(&font); + + TeX_search_init(argv[0], "ttf2tfm", "TTF2TFM"); + + if (argc == 1) + { + fputs("ttf2tfm: Need at least one file argument.\n", stderr); + fputs("Try `ttf2tfm --help' for more information.\n", stderr); + exit(1); + } + if (argc == 2) + { + if (strcmp(argv[1], "--help") == 0) + usage(); + else if (strcmp(argv[1], "--version") == 0) + version(); + } + + handle_options(argc, argv, &font); + + if (font.sfdname) + { + while (get_sfd(&font)) + { + char *temp; + int i, start, end, len; + + + get_tfm_fullname(&font); + + /* + * Extract base name of sfd file. + */ + + temp = newstring(font.sfdname); + len = strlen(temp); + + start = 0; + for (i = len - 1; i >= 0; i--) + if (temp[i] == '/' || temp[i] == ':' || temp[i] == '\\') + { + start = i + 1; + break; + } + + end = len; + for (i = len - 1; i >= 0; i--) + if (temp[i] == '.') + { + end = i; + break; + } + temp[end] = '\0'; + + font.codingscheme = (char *)mymalloc(strlen(temp + start) + 4 + 1); + sprintf(font.codingscheme, "CJK-%s", temp + start); + free(temp); + + readttf(&font, quiet, True); + if (font.replacements) + warning("Replacement glyphs will be ignored."); + + if (NULL != (ti = findadobe("space", font.charlist))) + font.fontspace = ti->width; + else if (NULL != (ti = findadobe(".c0x20", font.charlist))) + font.fontspace = ti->width; + else + font.fontspace = transform(500, 0, font.efactor, font.slant); + + if (buildtfm(&font)) + writetfm(&font); + } + + close_sfd(); + } + else + { + get_tfm_fullname(&font); + + readttf(&font, quiet, False); + replace_glyphs(&font); + + if (NULL != (ti = findadobe("space", font.charlist))) + font.fontspace = ti->width; + else if (NULL != (ti = findadobe(".c0x20", font.charlist))) + font.fontspace = ti->width; + else + font.fontspace = transform(500, 0, font.efactor, font.slant); + + handlereencoding(&font); + + buildtfm(&font); + writetfm(&font); + } + + if (makevpl) + { + assignchars(&font); + if (makevpl > 1) + upmap(&font); + writevpl(&font, makevpl, forceoctal); + fclose(font.vplout); + } + + consttfonts(&font); + + exit(0); /* for safety reasons */ + return 0; /* never reached */ +} + + +/* end */ diff --git a/contrib/ttf2pk/ttf2tfm.h b/contrib/ttf2pk/ttf2tfm.h new file mode 100644 index 0000000..b4f54e4 --- /dev/null +++ b/contrib/ttf2pk/ttf2tfm.h @@ -0,0 +1,234 @@ +/* + * ttf2tfm.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef TTF2TFM_H +#define TTF2TFM_H + +#include + + +enum Boolean_ +{ + False = 0, + True = 1 +}; +typedef enum Boolean_ Boolean; + +enum PSstate_ +{ + No = 0, + Yes = 1, + Only = 2 +}; +typedef enum PSstate_ PSstate; + + +struct _encoding +{ + char *name; + char *vec[256]; +}; +typedef struct _encoding encoding; + + +/* + * This is what we store character data in. + */ + +struct _ttfinfo; +typedef struct _ttfinfo ttfinfo; +struct _lig; +typedef struct _lig lig; +struct _kern; +typedef struct _kern kern; +struct _ttfptr; +typedef struct _ttfptr ttfptr; +struct _pcc; +typedef struct _pcc pcc; +struct _stringlist; +typedef struct _stringlist stringlist; + + + +struct _ttfinfo +{ + ttfinfo *next; + long charcode; /* the TTF character code (or glyph index */ + /* if bit 17 is set) */ + unsigned short glyphindex; /* the TTF glyph number */ + short incode; /* the code position in the raw TeX font */ + short outcode; /* the code position in the virtual font */ + char *adobename; + + short width; + short llx, lly, urx, ury; + + lig *ligs; + kern *kerns; + ttfptr *kern_equivs; + Boolean constructed; + pcc *pccs; /* we use the composite feature for */ + /* `germandbls' <--> `SS' only */ + unsigned char wptr, hptr, dptr, iptr; +}; + + +struct _lig +{ + lig *next; + char *succ, *sub; + short op, boundleft; +}; + + +struct _kern +{ + kern *next; + char *succ; + short delta; +}; + + +struct _ttfptr +{ + ttfptr *next; + ttfinfo *ch; +}; + + +struct _pcc +{ + pcc *next; + char *partname; + short xoffset, yoffset; +}; + + +struct _stringlist +{ + stringlist* next; + char *old_name; + char *new_name; + Boolean single_replacement; +}; + + +struct _Font +{ + char *ttfname; + + /* + * Full path and extension of the tfm file + */ + + char *tfm_path; + char *tfm_ext; + + /* + * The final tfm name is composed of the following three parts. + */ + + char *outname; /* only namestem without extension */ + char *subfont_name; /* NULL if not used */ + char *outname_postfix; /* NULL if not used */ + char *fullname; /* outname + subfont_name + outname_postfix */ + + FILE *vplout; + FILE *tfmout; + + /* + * The input encoding maps from the TrueType font to the raw TeX font. + */ + + char *inencname; /* name of input encoding file */ + encoding *inencoding; /* the input encoding vector */ + ttfinfo *inencptrs[256]; /* the input mapping table. Will be + filled initially with the first + 256 characters in the selected + cmap of the TrueType font */ + stringlist *replacements; /* replacements for glyph names given + with the -r option on the command + line */ + char *replacementname; /* name of replacement file */ + + /* + * The output encoding maps from the raw TeX font to the virtual font. + */ + + char *outencname; /* name of output encoding file */ + encoding *outencoding; /* the output encoding vector */ + ttfinfo *outencptrs[256]; /* the output mapping table */ + + short nextout[256]; /* for characters encoded multiple times + in output */ + + Boolean sawligkern; /* there were LIGKERN lines in the + output encoding file */ + Boolean subfont_ligs; /* ligatures 1st byte/2nd byte in + subfonts wanted */ + + ttfinfo *charlist; /* a linked list of all valid chars */ + + ttfinfo *uppercase[256]; /* needed for small caps fonts */ + ttfinfo *lowercase[256]; /* ditto */ + + short boundarychar; /* the boundary character */ + char *codingscheme; /* coding scheme for TeX */ + char *titlebuf; + + /* + * The name of the subfont definition file. + */ + + char *sfdname; + long sf_code[256]; + + /* + * We get the following three values from the TTF's postscript table. + */ + + short units_per_em; + float italicangle; + char fixedpitch; + + short xheight; /* xheight for TeX */ + short fontspace; /* font space for TeX */ + + /* + * These values can be specified on the command line. + */ + + unsigned short pid; /* the TTF platform ID */ + unsigned short eid; /* the TTF encoding ID */ + float efactor; /* to extend the glyphs horizontally */ + float slant; /* to slant the font */ + unsigned long fontindex; /* font number in TTC */ + float capheight; /* the height of small caps glyphs */ + PSstate PSnames; /* we use the PS names in the TTF */ + Boolean rotate; /* we rotate the glyphs by 90 degrees */ + float y_offset; /* y offset for rotated glyphs */ + + /* + * The command line parameter strings needed for ttf2pk. + */ + + char *pidparam; + char *eidparam; + char *efactorparam; + char *slantparam; + char *fontindexparam; + char *y_offsetparam; +}; +typedef struct _Font Font; + +#endif /* TEX2TFM_H */ + + +/* end */ diff --git a/contrib/ttf2pk/ttfaux.c b/contrib/ttf2pk/ttfaux.c new file mode 100644 index 0000000..dc96917 --- /dev/null +++ b/contrib/ttf2pk/ttfaux.c @@ -0,0 +1,714 @@ +/* + * ttfaux.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#include +#include +#include + +#include "freetype.h" +#include "extend/ftxkern.h" /* we are in the FreeType package tree */ +#include "extend/ftxpost.h" +#include "extend/ftxopen.h" + +#include "ttf2tfm.h" +#include "newobj.h" +#include "ligkern.h" +#include "ttfenc.h" +#include "tfmaux.h" +#include "errormsg.h" +#include "ttfaux.h" +#include "filesrch.h" + + +#define Macintosh_platform 1 +#define Macintosh_encoding 0 + +#define Microsoft_platform 3 +#define Microsoft_Unicode_encoding 1 + +#define SCRIPT_kana MAKE_TT_TAG('k', 'a', 'n', 'a') +#define SCRIPT_hani MAKE_TT_TAG('h', 'a', 'n', 'i') +#define SCRIPT_hang MAKE_TT_TAG('h', 'a', 'n', 'g') + +#define LANGUAGE_JAN MAKE_TT_TAG('J', 'A', 'N', ' ') +#define LANGUAGE_CHN MAKE_TT_TAG('C', 'H', 'N', ' ') +#define LANGUAGE_KOR MAKE_TT_TAG('K', 'O', 'R', ' ') + +#define FEATURE_vert MAKE_TT_TAG('v', 'e', 'r', 't') + + +extern char progname[]; + +char *real_ttfname; + +TT_Engine engine; +TT_Face face; +TT_Instance instance; +TT_Glyph glyph; +TT_Outline outline; +TT_CharMap char_map; +TT_Matrix matrix1, matrix2; + +TT_Big_Glyph_Metrics metrics; +TT_Face_Properties properties; +TT_BBox bbox; + +TT_Kerning directory; +TT_Post post; + +TTO_GSUBHeader gsub_; +TTO_GSUBHeader *gsub; + +Boolean has_gsub; + + + +static void +readttf_kern(Font *fnt) +{ + register kern *nk; + register ttfinfo *ti; + TT_Kern_0_Pair* pairs0; + TT_Error error; + unsigned int i, j; + + + if ((error = TT_Get_Kerning_Directory(face, &directory))) + oops("Cannot get kerning directory (error code = 0x%x).", error); + + if (directory.nTables == 0) + return; + + for (i = 0; i < directory.nTables; i++) + { + if ((error = TT_Load_Kerning_Table(face, i))) + oops("Cannot load kerning table (error code = 0x%x).", error); + + switch (directory.tables[i].format) + { + case 0: + pairs0 = directory.tables[i].t.kern0.pairs; + for (j = 0; j < directory.tables[i].t.kern0.nPairs; j++, pairs0++) + { + ti = findglyph(pairs0->left, fnt->charlist); + if (ti == NULL) + warning("kern char not found"); + else + { + nk = newkern(); + nk->succ = findglyph(pairs0->right, fnt->charlist)->adobename; + nk->delta = transform(pairs0->value * 1000 / fnt->units_per_em, 0, + fnt->efactor, fnt->slant); + nk->next = ti->kerns; + ti->kerns = nk; + } + } + return; /* we stop after the first format 0 kerning table */ + + default: + break; + } + } + return; +} + + +void +readttf(Font *fnt, Boolean quiet, Boolean only_range) +{ + TT_Error error; + ttfinfo *ti, *Ti; + long Num, index; + unsigned int i, j; + long k, max_k; + unsigned short num_cmap; + unsigned short cmap_plat, cmap_enc; + int index_array[257]; + + static Boolean initialized = False; + + TT_UShort in_string[2]; + TTO_GSUB_String in, out; + + TT_UShort script_index, language_index, feature_index; + TT_UShort req_feature_index = 0xFFFF; + + + /* + * We allocate a placeholder boundary and the `.notdef' character. + */ + + if (!only_range) + { + ti = newchar(fnt); + ti->charcode = -1; + ti->adobename = ".notdef"; + + ti = newchar(fnt); + ti->charcode = -1; + ti->adobename = "||"; /* boundary character name */ + } + + /* + * Initialize FreeType engine. + */ + + if (!initialized) + { + if ((error = TT_Init_FreeType(&engine))) + oops("Cannot initialize engine (error code = 0x%x).", error); + + if ((error = TT_Init_Kerning_Extension(engine))) + oops("Cannot initialize kerning (error code = 0x%x).", error); + + if (fnt->PSnames) + if ((error = TT_Init_Post_Extension(engine))) + oops("Cannot initialize PS name support (error code = 0x%x).", error); + + if (fnt->rotate) + if ((error = TT_Init_GSUB_Extension(engine))) + oops("Cannot initialize GSUB support (error code = 0x%x).", error); + + /* + * Load face. + */ + + real_ttfname = TeX_search_ttf_file(&(fnt->ttfname)); + if (!real_ttfname) + oops("Cannot find `%s'.", fnt->ttfname); + + if ((error = TT_Open_Face(engine, real_ttfname, &face))) + oops("Cannot open `%s'.", real_ttfname); + + /* + * Get face properties and allocate preload arrays. + */ + + TT_Get_Face_Properties(face, &properties); + + /* + * Now we try to open the proper font in a collection. + */ + + if (fnt->fontindex != 0) + { + if (properties.num_Faces == 1) + { + warning("This isn't a TrueType collection.\n" + "Parameter `-f' is ignored."); + fnt->fontindex = 0; + fnt->fontindexparam = NULL; + } + else + { + TT_Close_Face(face); + if ((error = TT_Open_Collection(engine, real_ttfname, + fnt->fontindex, &face))) + oops("Cannot open font %lu in TrueType Collection `%s'.", + fnt->fontindex, real_ttfname); + } + } + + /* + * Create instance. + */ + + if ((error = TT_New_Instance(face, &instance))) + oops("Cannot create instance for `%s' (error code = 0x%x).", + real_ttfname, error); + + /* + * We use a dummy glyph size of 10pt. + */ + + if ((error = TT_Set_Instance_CharSize(instance, 10 * 64))) + oops("Cannot set character size (error code = 0x%x).", error); + + matrix1.xx = (TT_Fixed)(floor(fnt->efactor * 1024) * (1L<<16)/1024); + matrix1.xy = (TT_Fixed)(floor(fnt->slant * 1024) * (1L<<16)/1024); + matrix1.yx = (TT_Fixed)0; + matrix1.yy = (TT_Fixed)(1L<<16); + + if (fnt->rotate) + { + matrix2.xx = 0; + matrix2.yx = 1L << 16; + matrix2.xy = -matrix2.yx; + matrix2.yy = matrix2.xx; + } + + if ((error = TT_Set_Instance_Transform_Flags( + instance, + fnt->rotate ? 1 : 0, + fnt->efactor != 1.0 ? 1 : 0))) + oops("Cannot set transform flags (error code = 0x%x).", error); + + /* + * Create glyph container. + */ + + if ((error = TT_New_Glyph(face, &glyph))) + oops("Cannot create glyph container (error code = 0x%x).", error); + + fnt->units_per_em = properties.header->Units_Per_EM; + fnt->fixedpitch = properties.postscript->isFixedPitch; + fnt->italicangle = properties.postscript->italicAngle / 65536.0; + + if (fnt->PSnames != Only) + { + num_cmap = properties.num_CharMaps; + for (i = 0; i < num_cmap; i++) + { + if ((error = TT_Get_CharMap_ID(face, i, &cmap_plat, &cmap_enc))) + oops("Cannot query cmap (error code = 0x%x).", error); + if (cmap_plat == fnt->pid && cmap_enc == fnt->eid) + break; + } + if (i == num_cmap) + { + fprintf(stderr, "%s: ERROR: Invalid platform and/or encoding ID.\n", + progname); + if (num_cmap == 1) + fprintf(stderr, " The only valid PID/EID pair is"); + else + fprintf(stderr, " Valid PID/EID pairs are:\n"); + for (i = 0; i < num_cmap; i++) + { + TT_Get_CharMap_ID(face, i, &cmap_plat, &cmap_enc); + fprintf(stderr, " (%i,%i)\n", cmap_plat, cmap_enc); + } + fprintf(stderr, "\n"); + exit(1); + } + + if ((error = TT_Get_CharMap(face, i, &char_map))) + oops("Cannot load cmap (error code = 0x%x).", error); + } + + if (fnt->PSnames) + { + if ((error = TT_Load_PS_Names(face, &post))) + oops("Cannot load TrueType PS names (error code = 0x%x).", error); + } + else if (cmap_plat == Microsoft_platform && + cmap_enc == Microsoft_Unicode_encoding) + set_encoding_scheme(encUnicode, fnt); + else if (cmap_plat == Macintosh_platform && + cmap_enc == Macintosh_encoding) + set_encoding_scheme(encMac, fnt); + else + set_encoding_scheme(encFontSpecific, fnt); + + if (fnt->rotate) + { + gsub = &gsub_; + + error = TT_Load_GSUB_Table(face, gsub, NULL); + if (!error) + has_gsub = True; + else if (error != TT_Err_Table_Missing) + warning("Cannot load GSUB table (error code = 0x%x).", error); + else + warning("No GSUB data available " + "for vertical glyph presentation forms."); + + /* we check for the `vert' feature in Chinese, Japanese, and Korean */ + + error = TT_GSUB_Select_Script(gsub, + SCRIPT_kana, + &script_index); + if (error) + goto check_hani; + error = TT_GSUB_Select_Feature(gsub, + FEATURE_vert, + script_index, + 0xFFFF, + &feature_index); + if (error) + { + error = TT_GSUB_Select_Language(gsub, + LANGUAGE_JAN, + script_index, + &language_index, + &req_feature_index); + if (error) + goto check_hani; + error = TT_GSUB_Select_Feature(gsub, + FEATURE_vert, + script_index, + language_index, + &feature_index); + if (error) + goto check_hani; + else + goto Done; + } + else + goto Done; + + check_hani: + error = TT_GSUB_Select_Script(gsub, + SCRIPT_hani, + &script_index); + if (error) + goto check_hang; + error = TT_GSUB_Select_Feature(gsub, + FEATURE_vert, + script_index, + 0xFFFF, + &feature_index); + if (error) + { + error = TT_GSUB_Select_Language(gsub, + LANGUAGE_CHN, + script_index, + &language_index, + &req_feature_index); + if (error) + goto check_hang; + error = TT_GSUB_Select_Feature(gsub, + FEATURE_vert, + script_index, + language_index, + &feature_index); + if (error) + goto check_hang; + else + goto Done; + } + else + goto Done; + + check_hang: + error = TT_GSUB_Select_Script(gsub, + SCRIPT_hang, + &script_index); + if (error) + goto Done; + error = TT_GSUB_Select_Feature(gsub, + FEATURE_vert, + script_index, + 0xFFFF, + &feature_index); + if (error) + { + error = TT_GSUB_Select_Language(gsub, + LANGUAGE_KOR, + script_index, + &language_index, + &req_feature_index); + if (error) + goto Done; + error = TT_GSUB_Select_Feature(gsub, + FEATURE_vert, + script_index, + language_index, + &feature_index); + } + + Done: + if (error) + { + warning("There is no data for vertical typesetting in GSUB table."); + has_gsub = False; + } + + if (req_feature_index != 0xFFFF) + TT_GSUB_Add_Feature(gsub, req_feature_index, ALL_GLYPHS); + TT_GSUB_Add_Feature(gsub, feature_index, ALL_GLYPHS); + + in.length = 1; + in.pos = 0; + in.string = in_string; + in.properties = NULL; + + out.pos = 0; + out.allocated = 0; + out.string = NULL; + out.properties = NULL; + } + + initialized = True; + } + + if (!quiet) + { + if (only_range) + printf("\n\n%s:\n", fnt->fullname); + printf("\n"); + printf("Glyph Code Glyph Name "); + printf("Width llx lly urx ury\n"); + printf("---------------------------------------"); + printf("---------------------------------\n"); + } + + /* + * We load only glyphs with a valid cmap entry. Nevertheless, for + * the default mapping, we use the first 256 glyphs addressed by + * ascending code points, followed by glyphs not in the cmap. + * + * If we compute a range, we take the character codes given in + * the fnt->sf_code array. + * + * If the -N flag is set, no cmap is used at all. Instead, the + * first 256 glyphs (with a valid PS name) are used for the default + * mapping. + */ + + if (!only_range) + for (i = 0; i < 257; i++) + index_array[i] = 0; + else + for (i = 0; i < 256; i++) + fnt->inencptrs[i] = 0; + + j = 0; + if (fnt->PSnames == Only) + max_k = properties.num_Glyphs - 1; + else + max_k = only_range ? 0xFF : 0xFFFF; + + for (k = 0; k <= max_k; k++) + { + char *an; + + + if (fnt->PSnames != Only) + { + if (only_range) + { + index = fnt->sf_code[k]; + if (index < 0) + continue; + j = k; + } + else + index = k; + + Num = TT_Char_Index(char_map, index); + + /* now we try to get a vertical glyph form */ + + if (has_gsub) + { + in_string[0] = Num; + error = TT_GSUB_Apply_String(gsub, &in, &out); + if (error && error != TTO_Err_Not_Covered) + warning("Cannot get the vertical glyph form for glyph index %d.", + Num); + else + Num = out.string[0]; + } + + if (Num < 0) + oops("Failure on cmap mapping from %s.", fnt->ttfname); + if (Num == 0) + continue; + if (!only_range) + if (Num <= 256) + index_array[Num] = 1; + } + else + { + Num = k; + index = 0; + } + + error = TT_Load_Glyph(instance, glyph, Num, 0); + if (!error) + error = TT_Get_Glyph_Big_Metrics(glyph, &metrics); + if (!error) + error = TT_Get_Glyph_Outline(glyph, &outline); + if (!error) + { + if (fnt->efactor != 1.0 || fnt->slant != 0.0 ) + TT_Transform_Outline(&outline, &matrix1); + if (fnt->rotate) + TT_Transform_Outline(&outline, &matrix2); + } + if (!error) + error = TT_Get_Outline_BBox(&outline, &bbox); /* we need the non- + grid-fitted bbox */ + if (!error) + { + if (fnt->PSnames) + (void)TT_Get_PS_Name(face, Num, &an); + else + an = code_to_adobename(index); + + /* ignore characters not usable for typesetting with TeX */ + + if (strcmp(an, ".notdef") == 0) + continue; + if (strcmp(an, ".null") == 0) + continue; + if (strcmp(an, "nonmarkingreturn") == 0) + continue; + + ti = newchar(fnt); + ti->charcode = index; + ti->glyphindex = Num; + ti->adobename = an; + ti->llx = bbox.xMin * 1000 / fnt->units_per_em; + ti->lly = bbox.yMin * 1000 / fnt->units_per_em; + ti->urx = bbox.xMax * 1000 / fnt->units_per_em; + ti->ury = bbox.yMax * 1000 / fnt->units_per_em; + + /* + * We must now shift the rotated character both horizontally + * and vertically. The vertical amount is 25% by default. + */ + + if (fnt->rotate) + { + ti->llx += (metrics.vertBearingY - bbox.xMin) * + 1000 / fnt->units_per_em; + ti->lly -= 1000 * fnt->y_offset; + ti->urx += (metrics.vertBearingY - bbox.xMin) * + 1000 / fnt->units_per_em; + ti->ury -= 1000 * fnt->y_offset; + } + + /* + * We need to avoid negative heights or depths. They break accents + * in math mode, among other things. + */ + + if (ti->lly > 0) + ti->lly = 0; + if (ti->ury < 0) + ti->ury = 0; + if (fnt->rotate) + ti->width = metrics.vertAdvance * 1000 / fnt->units_per_em; + else + ti->width = transform(metrics.horiAdvance * 1000 / fnt->units_per_em, + 0, fnt->efactor, fnt->slant); + + if (!quiet) + printf("%5ld %04lx %-25s %5d % 5d,% 5d -- % 5d,% 5d\n", + Num, index, ti->adobename, + ti->width, + ti->llx, ti->lly, ti->urx, ti->ury); + + if (j < 256) + { + fnt->inencptrs[j] = ti; + ti->incode = j; + } + j++; + } + } + + /* + * Now we load glyphs without a cmap entry, provided some slots are + * still free -- we skip this if we have to compute a range or use + * PS names. + */ + + if (!only_range && !fnt->PSnames) + { + for (i = 1; i <= properties.num_Glyphs; i++) + { + char *an; + + + if (index_array[i] == 0) + { + error = TT_Load_Glyph(instance, glyph, i, 0); + if (!error) + error = TT_Get_Glyph_Big_Metrics(glyph, &metrics); + if (!error) + error = TT_Get_Glyph_Outline(glyph, &outline); + if (!error) + error = TT_Get_Outline_BBox(&outline, &bbox); + if (!error) + { + an = code_to_adobename(i | 0x10000); + + ti = newchar(fnt); + ti->charcode = i | 0x10000; + ti->glyphindex = i; + ti->adobename = an; + ti->llx = bbox.xMin * 1000 / fnt->units_per_em; + ti->lly = bbox.yMin * 1000 / fnt->units_per_em; + ti->urx = bbox.xMax * 1000 / fnt->units_per_em; + ti->ury = bbox.yMax * 1000 / fnt->units_per_em; + + if (ti->lly > 0) + ti->lly = 0; + if (ti->ury < 0) + ti->ury = 0; + ti->width = transform(metrics.horiAdvance*1000 / fnt->units_per_em, + 0, fnt->efactor, fnt->slant); + + if (!quiet) + printf("%5d %-25s %5d % 5d,% 5d -- % 5d,% 5d\n", + i, ti->adobename, + ti->width, + ti->llx, ti->lly, ti->urx, ti->ury); + + if (j < 256) + { + fnt->inencptrs[j] = ti; + ti->incode = j; + } + else + break; + j++; + } + } + } + } + + /* Finally, we construct a `Germandbls' glyph if necessary */ + + if (!only_range) + { + if (NULL == findadobe("Germandbls", fnt->charlist) && + NULL != (Ti = findadobe("S", fnt->charlist))) + { + pcc *np, *nq; + + + ti = newchar(fnt); + ti->charcode = properties.num_Glyphs | 0x10000; + ti->glyphindex = properties.num_Glyphs; + ti->adobename = "Germandbls"; + ti->width = Ti->width << 1; + ti->llx = Ti->llx; + ti->lly = Ti->lly; + ti->urx = Ti->width + Ti->urx; + ti->ury = Ti->ury; + ti->kerns = Ti->kerns; + + np = newpcc(); + np->partname = "S"; + nq = newpcc(); + nq->partname = "S"; + nq->xoffset = Ti->width; + np->next = nq; + ti->pccs = np; + ti->constructed = True; + + if (!quiet) + printf("* %-25s %5d % 5d,% 5d -- % 5d,% 5d\n", + ti->adobename, + ti->width, + ti->llx, ti->lly, ti->urx, ti->ury); + } + } + + /* kerning between subfonts isn't available */ + if (!only_range) + readttf_kern(fnt); +} + + +/* end */ diff --git a/contrib/ttf2pk/ttfaux.h b/contrib/ttf2pk/ttfaux.h new file mode 100644 index 0000000..5737c2f --- /dev/null +++ b/contrib/ttf2pk/ttfaux.h @@ -0,0 +1,21 @@ +/* + * ttfaux.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef TTFAUX_H +#define TTFAUX_H + +#include "ttf2tfm.h" + +void readttf(Font *fnt, Boolean quiet, Boolean only_range); + +#endif /* TTFAUX_H */ + + +/* end */ diff --git a/contrib/ttf2pk/ttfenc.c b/contrib/ttf2pk/ttfenc.c new file mode 100644 index 0000000..9362926 --- /dev/null +++ b/contrib/ttf2pk/ttfenc.c @@ -0,0 +1,1281 @@ +/* + * ttfenc.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + + +#include +#include +#include + +#include "newobj.h" +#include "ttf2tfm.h" +#include "ttfenc.h" +#include "errormsg.h" + +EncodingScheme current_encoding_scheme; + +struct encoding_table +{ + long code; + char *adobename; +}; + +struct encoding_table unicode_table[] = +{ + {-1, ".notdef"}, + + {0x0020, "space"}, + {0x0021, "exclam"}, + {0x0022, "quotedbl"}, + {0x0023, "numbersign"}, + {0x0024, "dollar"}, + {0x0025, "percent"}, + {0x0026, "ampersand"}, + {0x0027, "quotesingle"}, + {0x0028, "parenleft"}, + {0x0029, "parenright"}, + {0x002a, "asterisk"}, + {0x002b, "plus"}, + {0x002c, "comma"}, + {0x002d, "hyphen"}, /* cf "minus" */ + {0x002e, "period"}, + {0x002f, "slash"}, + + {0x0030, "zero"}, + {0x0031, "one"}, + {0x0032, "two"}, + {0x0033, "three"}, + {0x0034, "four"}, + {0x0035, "five"}, + {0x0036, "six"}, + {0x0037, "seven"}, + {0x0038, "eight"}, + {0x0039, "nine"}, + {0x003a, "colon"}, + {0x003b, "semicolon"}, + {0x003c, "less"}, + {0x003d, "equal"}, + {0x003e, "greater"}, + {0x003f, "question"}, + + {0x0040, "at"}, + {0x0041, "A"}, + {0x0042, "B"}, + {0x0043, "C"}, + {0x0044, "D"}, + {0x0045, "E"}, + {0x0046, "F"}, + {0x0047, "G"}, + {0x0048, "H"}, + {0x0049, "I"}, + {0x004a, "J"}, + {0x004b, "K"}, + {0x004c, "L"}, + {0x004d, "M"}, + {0x004e, "N"}, + {0x004f, "O"}, + + {0x0050, "P"}, + {0x0051, "Q"}, + {0x0052, "R"}, + {0x0053, "S"}, + {0x0054, "T"}, + {0x0055, "U"}, + {0x0056, "V"}, + {0x0057, "W"}, + {0x0058, "X"}, + {0x0059, "Y"}, + {0x005a, "Z"}, + {0x005b, "bracketleft"}, + {0x005c, "backslash"}, + {0x005d, "bracketright"}, + {0x005e, "asciicircum"}, + {0x005f, "underscore"}, + + {0x0060, "grave"}, + {0x0061, "a"}, + {0x0062, "b"}, + {0x0063, "c"}, + {0x0064, "d"}, + {0x0065, "e"}, + {0x0066, "f"}, + {0x0067, "g"}, + {0x0068, "h"}, + {0x0069, "i"}, + {0x006a, "j"}, + {0x006b, "k"}, + {0x006c, "l"}, + {0x006d, "m"}, + {0x006e, "n"}, + {0x006f, "o"}, + + {0x0070, "p"}, + {0x0071, "q"}, + {0x0072, "r"}, + {0x0073, "s"}, + {0x0074, "t"}, + {0x0075, "u"}, + {0x0076, "v"}, + {0x0077, "w"}, + {0x0078, "x"}, + {0x0079, "y"}, + {0x007a, "z"}, + {0x007b, "braceleft"}, + {0x007c, "bar"}, + {0x007d, "braceright"}, + {0x007e, "asciitilde"}, + + {0x00a0, "nbspace"}, /* cf "space" */ + {0x00a1, "exclamdown"}, + {0x00a2, "cent"}, + {0x00a3, "sterling"}, + {0x00a4, "currency"}, + {0x00a5, "yen"}, + {0x00a6, "brokenbar"}, + {0x00a7, "section"}, + {0x00a8, "dieresis"}, + {0x00a9, "copyright"}, /* "copyrightserif" "copyrightsans" */ + {0x00aa, "ordfeminine"}, + {0x00ab, "guillemotleft"}, + {0x00ac, "logicalnot"}, + {0x00ad, "sfthyphen"}, /* cf "hyphen" */ + {0x00ae, "registered"}, /* "registeredserif" "registeredsans" */ + {0x00af, "overscore"}, + + {0x00b0, "degree"}, + {0x00b1, "plusminus"}, + {0x00b2, "twosuperior"}, + {0x00b3, "threesuperior"}, + {0x00b4, "acute"}, + {0x00b5, "mu1"}, /* "micro" */ + {0x00b6, "paragraph"}, + {0x00b7, "middot"}, /* cf "periodcentered" */ + {0x00b8, "cedilla"}, + {0x00b9, "onesuperior"}, + {0x00ba, "ordmasculine"}, + {0x00bb, "guillemotright"}, + {0x00bc, "onequarter"}, + {0x00bd, "onehalf"}, + {0x00be, "threequarters"}, + {0x00bf, "questiondown"}, + + {0x00c0, "Agrave"}, + {0x00c1, "Aacute"}, + {0x00c2, "Acircumflex"}, + {0x00c3, "Atilde"}, + {0x00c4, "Adieresis"}, + {0x00c5, "Aring"}, + {0x00c6, "AE"}, + {0x00c7, "Ccedilla"}, + {0x00c8, "Egrave"}, + {0x00c9, "Eacute"}, + {0x00ca, "Ecircumflex"}, + {0x00cb, "Edieresis"}, + {0x00cc, "Igrave"}, + {0x00cd, "Iacute"}, + {0x00ce, "Icircumflex"}, + {0x00cf, "Idieresis"}, + + {0x00d0, "Eth"}, + {0x00d1, "Ntilde"}, + {0x00d2, "Ograve"}, + {0x00d3, "Oacute"}, + {0x00d4, "Ocircumflex"}, + {0x00d5, "Otilde"}, + {0x00d6, "Odieresis"}, + {0x00d7, "multiply"}, + {0x00d8, "Oslash"}, + {0x00d9, "Ugrave"}, + {0x00da, "Uacute"}, + {0x00db, "Ucircumflex"}, + {0x00dc, "Udieresis"}, + {0x00dd, "Yacute"}, + {0x00de, "Thorn"}, + {0x00df, "germandbls"}, + + {0x00e0, "agrave"}, + {0x00e1, "aacute"}, + {0x00e2, "acircumflex"}, + {0x00e3, "atilde"}, + {0x00e4, "adieresis"}, + {0x00e5, "aring"}, + {0x00e6, "ae"}, + {0x00e7, "ccedilla"}, + {0x00e8, "egrave"}, + {0x00e9, "eacute"}, + {0x00ea, "ecircumflex"}, + {0x00eb, "edieresis"}, + {0x00ec, "igrave"}, + {0x00ed, "iacute"}, + {0x00ee, "icircumflex"}, + {0x00ef, "idieresis"}, + + {0x00f0, "eth"}, + {0x00f1, "ntilde"}, + {0x00f2, "ograve"}, + {0x00f3, "oacute"}, + {0x00f4, "ocircumflex"}, + {0x00f5, "otilde"}, + {0x00f6, "odieresis"}, + {0x00f7, "divide"}, + {0x00f8, "oslash"}, + {0x00f9, "ugrave"}, + {0x00fa, "uacute"}, + {0x00fb, "ucircumflex"}, + {0x00fc, "udieresis"}, + {0x00fd, "yacute"}, + {0x00fe, "thorn"}, + {0x00ff, "ydieresis"}, + + {0x0100, "Amacron"}, + {0x0101, "amacron"}, + {0x0102, "Abreve"}, + {0x0103, "abreve"}, + {0x0104, "Aogonek"}, + {0x0105, "aogonek"}, + {0x0106, "Cacute"}, + {0x0107, "cacute"}, + {0x0108, "Ccircumflex"}, + {0x0109, "ccircumflex"}, + {0x010a, "Cdot"}, + {0x010b, "cdot"}, + {0x010c, "Ccaron"}, + {0x010d, "ccaron"}, + {0x010e, "Dcaron"}, + {0x010f, "dcaron"}, + + {0x0110, "Dslash"}, + {0x0111, "dmacron"}, + {0x0112, "Emacron"}, + {0x0113, "emacron"}, + {0x0114, "Ebreve"}, + {0x0115, "ebreve"}, + {0x0116, "Edot"}, + {0x0117, "edot"}, + {0x0118, "Eogonek"}, + {0x0119, "eogonek"}, + {0x011a, "Ecaron"}, + {0x011b, "ecaron"}, + {0x011c, "Gcircumflex"}, + {0x011d, "gcircumflex"}, + {0x011e, "Gbreve"}, + {0x011f, "gbreve"}, + + {0x0120, "Gdot"}, + {0x0121, "gdot"}, + {0x0122, "Gcedilla"}, + {0x0123, "gcedilla"}, + {0x0124, "Hcircumflex"}, + {0x0125, "hcircumflex"}, + {0x0126, "Hbar"}, + {0x0127, "hbar"}, + {0x0128, "Itilde"}, + {0x0129, "itilde"}, + {0x012a, "Imacron"}, + {0x012b, "imacron"}, + {0x012c, "Ibreve"}, + {0x012d, "ibreve"}, + {0x012e, "Iogonek"}, + {0x012f, "iogonek"}, + + {0x0130, "Idot"}, + {0x0131, "dotlessi"}, + {0x0132, "IJ"}, + {0x0133, "ij"}, + {0x0134, "Jcircumflex"}, + {0x0135, "jcircumflex"}, + {0x0136, "Kcedilla"}, + {0x0137, "kcedilla"}, + {0x0138, "kgreenlandic"}, + {0x0139, "Lacute"}, + {0x013a, "lacute"}, + {0x013b, "Lcedilla"}, + {0x013c, "lcedilla"}, + {0x013d, "Lcaron"}, + {0x013e, "lcaron"}, + {0x013f, "Ldot"}, + + {0x0140, "ldot"}, + {0x0141, "Lslash"}, + {0x0142, "lslash"}, + {0x0143, "Nacute"}, + {0x0144, "nacute"}, + {0x0145, "Ncedilla"}, + {0x0146, "ncedilla"}, + {0x0147, "Ncaron"}, + {0x0148, "ncaron"}, + {0x0149, "napostrophe"}, + {0x014a, "Eng"}, + {0x014b, "eng"}, + {0x014c, "Omacron"}, + {0x014d, "omacron"}, + {0x014e, "Obreve"}, + {0x014f, "obreve"}, + + {0x0150, "Odblacute"}, + {0x0151, "odblacute"}, + {0x0152, "OE"}, + {0x0153, "oe"}, + {0x0154, "Racute"}, + {0x0155, "racute"}, + {0x0156, "Rcedilla"}, + {0x0157, "rcedilla"}, + {0x0158, "Rcaron"}, + {0x0159, "rcaron"}, + {0x015a, "Sacute"}, + {0x015b, "sacute"}, + {0x015c, "Scircumflex"}, + {0x015d, "scircumflex"}, + {0x015e, "Scedilla"}, + {0x015f, "scedilla"}, + + {0x0160, "Scaron"}, + {0x0161, "scaron"}, + {0x0162, "Tcedilla"}, + {0x0163, "tcedilla"}, + {0x0164, "Tcaron"}, + {0x0165, "tcaron"}, + {0x0166, "Tbar"}, + {0x0167, "tbar"}, + {0x0168, "Utilde"}, + {0x0169, "utilde"}, + {0x016a, "Umacron"}, + {0x016b, "umacron"}, + {0x016c, "Ubreve"}, + {0x016d, "ubreve"}, + {0x016e, "Uring"}, + {0x016f, "uring"}, + + {0x0170, "Udblacute"}, + {0x0171, "udblacute"}, + {0x0172, "Uogonek"}, + {0x0173, "uogonek"}, + {0x0174, "Wcircumflex"}, + {0x0175, "wcircumflex"}, + {0x0176, "Ycircumflex"}, + {0x0177, "ycircumflex"}, + {0x0178, "Ydieresis"}, + {0x0179, "Zacute"}, + {0x017a, "zacute"}, + {0x017b, "Zdot"}, + {0x017c, "zdot"}, + {0x017d, "Zcaron"}, + {0x017e, "zcaron"}, + {0x017f, "longs"}, + + {0x0192, "florin"}, + + {0x01fa, "Aringacute"}, + {0x01fb, "aringacute"}, + {0x01fc, "AEacute"}, + {0x01fd, "aeacute"}, + {0x01fe, "Oslashacute"}, + {0x01ff, "oslashacute"}, + + {0x02c6, "circumflex"}, + {0x02c7, "caron"}, + {0x02c9, "macron"}, /* cf "overscore" */ + + {0x02d8, "breve"}, + {0x02d9, "dotaccent"}, + {0x02da, "ring"}, + {0x02db, "ogonek"}, + {0x02dc, "tilde"}, + {0x02dd, "hungarumlaut"}, + + {0x037e, "semicolon"}, + + {0x0384, "tonos"}, + {0x0385, "dieresistonos"}, + {0x0386, "Alphatonos"}, + {0x0387, "anoteleia"}, + {0x0388, "Epsilontonos"}, + {0x0389, "Etatonos"}, + {0x038a, "Iotatonos"}, + {0x038c, "Omicrontonos"}, + {0x038e, "Upsilontonos"}, + {0x038f, "Omegatonos"}, + + {0x0390, "iotadieresistonos"}, + {0x0391, "Alpha"}, + {0x0392, "Beta"}, + {0x0393, "Gamma"}, + {0x0394, "Delta"}, + {0x0395, "Epsilon"}, + {0x0396, "Zeta"}, + {0x0397, "Eta"}, + {0x0398, "Theta"}, + {0x0399, "Iota"}, + {0x039a, "Kappa"}, + {0x039b, "Lambda"}, + {0x039c, "Mu"}, + {0x039d, "Nu"}, + {0x039e, "Xi"}, + {0x039f, "Omicron"}, + + {0x03a0, "Pi"}, + {0x03a1, "Rho"}, + {0x03a2, "Sigma"}, + {0x03a3, "Tau"}, + {0x03a4, "Upsilon"}, + {0x03a5, "Phi"}, + {0x03a6, "Chi"}, + {0x03a7, "Psi"}, + {0x03a8, "Omega"}, /* cf "Ohm" */ + {0x03aa, "Iotadieresis"}, + {0x03ab, "Upsilondieresis"}, + {0x03ac, "alphatonos"}, + {0x03ad, "epsilontonos"}, + {0x03ae, "etatonos"}, + {0x03af, "iotatonos"}, + + {0x03b0, "upsilondieresistonos"}, + {0x03b1, "alpha"}, + {0x03b2, "beta"}, + {0x03b3, "gamma"}, + {0x03b4, "delta"}, + {0x03b5, "epsilon"}, + {0x03b6, "zeta"}, + {0x03b7, "eta"}, + {0x03b8, "theta"}, + {0x03b9, "iota"}, + {0x03ba, "kappa"}, + {0x03bb, "lambda"}, + {0x03bc, "mu"}, + {0x03bd, "nu"}, + {0x03be, "xi"}, + {0x03bf, "omicron"}, + + {0x03c0, "pi"}, + {0x03c1, "rho"}, + {0x03c2, "sigma1"}, + {0x03c3, "sigma"}, + {0x03c4, "tau"}, + {0x03c5, "upsilon"}, + {0x03c6, "phi"}, + {0x03c7, "chi"}, + {0x03c8, "psi"}, + {0x03c9, "omega"}, + {0x03ca, "iotadieresis"}, + {0x03cb, "upsilondieresis"}, + {0x03cc, "omicrontonos"}, + {0x03cd, "upsilontonos"}, + {0x03ce, "omegatonos"}, + + {0x0401, "afii10023"}, + {0x0402, "afii10051"}, + {0x0403, "afii10052"}, + {0x0404, "afii10053"}, + {0x0405, "afii10054"}, + {0x0406, "afii10055"}, + {0x0407, "afii10056"}, + {0x0408, "afii10057"}, + {0x0409, "afii10058"}, + {0x040a, "afii10059"}, + {0x040b, "afii10060"}, + {0x040c, "afii10061"}, + {0x040e, "afii10062"}, + {0x040f, "afii10145"}, + + {0x0410, "afii10017"}, + {0x0411, "afii10018"}, + {0x0412, "afii10019"}, + {0x0413, "afii10020"}, + {0x0414, "afii10021"}, + {0x0415, "afii10022"}, + {0x0416, "afii10024"}, + {0x0417, "afii10025"}, + {0x0418, "afii10026"}, + {0x0419, "afii10027"}, + {0x041a, "afii10028"}, + {0x041b, "afii10029"}, + {0x041c, "afii10030"}, + {0x041d, "afii10031"}, + {0x041e, "afii10032"}, + {0x041f, "afii10033"}, + + {0x0420, "afii10034"}, + {0x0421, "afii10035"}, + {0x0422, "afii10036"}, + {0x0423, "afii10037"}, + {0x0424, "afii10038"}, + {0x0425, "afii10039"}, + {0x0426, "afii10040"}, + {0x0427, "afii10041"}, + {0x0428, "afii10042"}, + {0x0429, "afii10043"}, + {0x042a, "afii10044"}, + {0x042b, "afii10045"}, + {0x042c, "afii10046"}, + {0x042d, "afii10047"}, + {0x042e, "afii10048"}, + {0x042f, "afii10049"}, + + {0x0430, "afii10065"}, + {0x0431, "afii10066"}, + {0x0432, "afii10067"}, + {0x0433, "afii10068"}, + {0x0434, "afii10069"}, + {0x0435, "afii10070"}, + {0x0436, "afii10072"}, + {0x0437, "afii10073"}, + {0x0438, "afii10074"}, + {0x0439, "afii10075"}, + {0x043a, "afii10076"}, + {0x043b, "afii10077"}, + {0x043c, "afii10078"}, + {0x043d, "afii10079"}, + {0x043e, "afii10080"}, + {0x043f, "afii10081"}, + + {0x0440, "afii10082"}, + {0x0441, "afii10083"}, + {0x0442, "afii10084"}, + {0x0443, "afii10085"}, + {0x0444, "afii10086"}, + {0x0445, "afii10087"}, + {0x0446, "afii10088"}, + {0x0447, "afii10089"}, + {0x0448, "afii10090"}, + {0x0449, "afii10091"}, + {0x044a, "afii10092"}, + {0x044b, "afii10093"}, + {0x044c, "afii10094"}, + {0x044d, "afii10095"}, + {0x044e, "afii10096"}, + {0x044f, "afii10097"}, + + {0x0451, "afii10071"}, + {0x0452, "afii10099"}, + {0x0453, "afii10100"}, + {0x0454, "afii10101"}, + {0x0455, "afii10102"}, + {0x0456, "afii10103"}, + {0x0457, "afii10104"}, + {0x0458, "afii10105"}, + {0x0459, "afii10106"}, + {0x045a, "afii10107"}, + {0x045b, "afii10108"}, + {0x045c, "afii10109"}, + {0x045e, "afii10110"}, + {0x045f, "afii10193"}, + + {0x0490, "afii10050"}, + {0x0491, "afii10098"}, + + {0x1e80, "Wgrave"}, + {0x1e81, "wgrave"}, + {0x1e82, "Wacute"}, + {0x1e83, "wacute"}, + {0x1e84, "Wdieresis"}, + {0x1e85, "wdieresis"}, + + {0x1ef2, "Ygrave"}, + {0x1ef3, "ygrave"}, + + {0x2013, "endash"}, + {0x2014, "emdash"}, + {0x2015, "afii00208"}, /* horizontal bar */ + {0x2017, "underscoredbl"}, + {0x2018, "quoteleft"}, + {0x2019, "quoteright"}, + {0x201a, "quotesinglbase"}, + {0x201b, "quotereversed"}, + {0x201c, "quotedblleft"}, + {0x201d, "quotedblright"}, + {0x201e, "quotedblbase"}, + + {0x2020, "dagger"}, + {0x2021, "daggerdbl"}, + {0x2022, "bullet"}, + {0x2026, "ellipsis"}, + {0x2030, "perthousand"}, + {0x2032, "minute"}, + {0x2033, "second"}, + {0x2039, "guilsinglleft"}, + {0x203a, "guilsinglright"}, + {0x203c, "exclamdbl"}, + {0x203e, "radicalex"}, + + {0x2044, "fraction"}, /* cf U+2215 */ + + {0x207f, "nsuperior"}, + + {0x20a3, "franc"}, + {0x20a4, "afii08941"}, /* lira sign */ + {0x20a7, "peseta"}, + + {0x2105, "afii61248"}, /* care of */ + + {0x2113, "afii61289"}, /* script small l */ + {0x2116, "afii61352"}, /* numero sign */ + + {0x2122, "trademark"}, + {0x2126, "Ohm"}, + {0x212e, "estimated"}, + + {0x215b, "oneeighth"}, + {0x215c, "threeeighths"}, + {0x215d, "fiveeighths"}, + {0x215e, "seveneighths"}, + + {0x2190, "arrowleft"}, + {0x2191, "arrowup"}, + {0x2192, "arrowright"}, + {0x2193, "arrowdown"}, + {0x2194, "arrowboth"}, + {0x2195, "arrowupdn"}, + + {0x21a8, "arrowupdnbse"}, + + {0x2202, "partialdiff"}, + {0x2206, "increment"}, + {0x220f, "product"}, + + {0x2211, "summation"}, + {0x2212, "minus"}, + {0x2215, "fraction"}, /* cf U+2044 */ + {0x2219, "periodcentered"}, + {0x221a, "radical"}, + {0x221e, "infinity"}, + {0x221f, "orthogonal"}, + + {0x2229, "intersection"}, + {0x222b, "integral"}, + + {0x2248, "approxequal"}, + + {0x2260, "notequal"}, + {0x2261, "equivalence"}, + {0x2264, "lessequal"}, + {0x2265, "greaterequal"}, + + {0x2302, "house"}, + + {0x2310, "revlogicalnot"}, + + {0x2320, "integraltp"}, + {0x2321, "integralbt"}, + + {0x2500, "SF100000"}, + {0x2502, "SF110000"}, + {0x250c, "SF010000"}, + + {0x2510, "SF030000"}, + {0x2514, "SF020000"}, + {0x2518, "SF040000"}, + {0x251c, "SF080000"}, + + {0x2524, "SF090000"}, + {0x252c, "SF060000"}, + + {0x2534, "SF070000"}, + {0x253c, "SF050000"}, + + {0x2550, "SF430000"}, + {0x2551, "SF240000"}, + {0x2552, "SF510000"}, + {0x2553, "SF520000"}, + {0x2554, "SF390000"}, + {0x2555, "SF220000"}, + {0x2556, "SF210000"}, + {0x2557, "SF250000"}, + {0x2558, "SF500000"}, + {0x2559, "SF490000"}, + {0x255a, "SF380000"}, + {0x255b, "SF280000"}, + {0x255c, "SF270000"}, + {0x255d, "SF260000"}, + {0x255e, "SF360000"}, + {0x255f, "SF370000"}, + + {0x2560, "SF420000"}, + {0x2561, "SF190000"}, + {0x2562, "SF200000"}, + {0x2563, "SF230000"}, + {0x2564, "SF470000"}, + {0x2565, "SF480000"}, + {0x2566, "SF410000"}, + {0x2567, "SF450000"}, + {0x2568, "SF460000"}, + {0x2569, "SF400000"}, + {0x256a, "SF540000"}, + {0x256b, "SF530000"}, + {0x256c, "SF440000"}, + + {0x2580, "upblock"}, + {0x2584, "dnblock"}, + {0x2588, "block"}, + {0x258c, "lfblock"}, + + {0x2590, "rtblock"}, + {0x2591, "ltshade"}, + {0x2592, "shade"}, + {0x2593, "dkshade"}, + + {0x25a0, "filledbox"}, + {0x25a1, "H22073"}, + {0x25aa, "H18543"}, + {0x25ab, "H18551"}, + {0x25ac, "filledrect"}, + + {0x25b2, "triagup"}, + {0x25ba, "triagrt"}, + {0x25bc, "triagdn"}, + + {0x25c4, "triaglf"}, + {0x25ca, "lozenge"}, + {0x25cb, "circle"}, + {0x25cf, "H18533"}, + + {0x25d8, "invbullet"}, + {0x25d9, "invcircle"}, + + {0x25e6, "openbullet"}, + + {0x263a, "smileface"}, + {0x263b, "invsmileface"}, + {0x263c, "sun"}, + + {0x2640, "female"}, + {0x2642, "male"}, + + {0x2660, "spade"}, + {0x2663, "club"}, + {0x2665, "heart"}, + {0x2666, "diamond"}, + {0x266a, "musicalnote"}, + {0x266b, "musicalnotedbl"}, + + {0xf000, "applelogo"}, + {0xf001, "fi"}, + {0xf002, "fl"}, + {0xf004, "commaaccent"}, + {0xf005, "undercommaaccent"}, + {0xfb01, "fi"}, + {0xfb02, "fl"}, +}; + +struct encoding_table mac_table[] = +{ + {-1, ".notdef"}, + {0x0000, ".notdef"}, /* null */ + {0x0008, ".notdef"}, /* backspace */ + {0x0009, ".notdef"}, /* horizontal tabulation */ + {0x000d, ".notdef"}, /* carriage return */ + {0x001d, ".notdef"}, /* group separator */ + {0x0020, "space"}, + {0x0021, "exclam"}, + {0x0022, "quotedbl"}, + {0x0023, "numbersign"}, + {0x0024, "dollar"}, + {0x0025, "percent"}, + {0x0026, "ampersand"}, + {0x0027, "quotesingle"}, + {0x0028, "parenleft"}, + {0x0029, "parenright"}, + {0x002a, "asterisk"}, + {0x002b, "plus"}, + {0x002c, "comma"}, + {0x002d, "hyphen"}, + {0x002e, "period"}, + {0x002f, "slash"}, + + {0x0030, "zero"}, + {0x0031, "one"}, + {0x0032, "two"}, + {0x0033, "three"}, + {0x0034, "four"}, + {0x0035, "five"}, + {0x0036, "six"}, + {0x0037, "seven"}, + {0x0038, "eight"}, + {0x0039, "nine"}, + {0x003a, "colon"}, + {0x003b, "semicolon"}, + {0x003c, "less"}, + {0x003d, "equal"}, + {0x003e, "greater"}, + {0x003f, "question"}, + + {0x0040, "at"}, + {0x0041, "A"}, + {0x0042, "B"}, + {0x0043, "C"}, + {0x0044, "D"}, + {0x0045, "E"}, + {0x0046, "F"}, + {0x0047, "G"}, + {0x0048, "H"}, + {0x0049, "I"}, + {0x004a, "J"}, + {0x004b, "K"}, + {0x004c, "L"}, + {0x004d, "M"}, + {0x004e, "N"}, + {0x004f, "O"}, + + {0x0050, "P"}, + {0x0051, "Q"}, + {0x0052, "R"}, + {0x0053, "S"}, + {0x0054, "T"}, + {0x0055, "U"}, + {0x0056, "V"}, + {0x0057, "W"}, + {0x0058, "X"}, + {0x0059, "Y"}, + {0x005a, "Z"}, + {0x005b, "bracketleft"}, + {0x005c, "backslash"}, + {0x005d, "bracketright"}, + {0x005e, "asciicircum"}, + {0x005f, "underscore"}, + + {0x0060, "grave"}, + {0x0061, "a"}, + {0x0062, "b"}, + {0x0063, "c"}, + {0x0064, "d"}, + {0x0065, "e"}, + {0x0066, "f"}, + {0x0067, "g"}, + {0x0068, "h"}, + {0x0069, "i"}, + {0x006a, "j"}, + {0x006b, "k"}, + {0x006c, "l"}, + {0x006d, "m"}, + {0x006e, "n"}, + {0x006f, "o"}, + + {0x0070, "p"}, + {0x0071, "q"}, + {0x0072, "r"}, + {0x0073, "s"}, + {0x0074, "t"}, + {0x0075, "u"}, + {0x0076, "v"}, + {0x0077, "w"}, + {0x0078, "x"}, + {0x0079, "y"}, + {0x007a, "z"}, + {0x007b, "braceleft"}, + {0x007c, "bar"}, + {0x007d, "braceright"}, + {0x007e, "asciitilde"}, + + {0x0080, "Adieresis"}, + {0x0081, "Aring"}, + {0x0082, "Ccedilla"}, + {0x0083, "Eacute"}, + {0x0084, "Ntilde"}, + {0x0085, "Odieresis"}, + {0x0086, "Udieresis"}, + {0x0087, "aacute"}, + {0x0088, "agrave"}, + {0x0089, "acircumflex"}, + {0x008a, "adieresis"}, + {0x008b, "atilde"}, + {0x008c, "aring"}, + {0x008d, "ccedilla"}, + {0x008e, "eacute"}, + {0x008f, "egrave"}, + + {0x0090, "ecircumflex"}, + {0x0091, "edieresis"}, + {0x0092, "iacute"}, + {0x0093, "igrave"}, + {0x0094, "icircumflex"}, + {0x0095, "idieresis"}, + {0x0096, "ntilde"}, + {0x0097, "oacute"}, + {0x0098, "ograve"}, + {0x0099, "ocircumflex"}, + {0x009a, "odieresis"}, + {0x009b, "otilde"}, + {0x009c, "uacute"}, + {0x009d, "ugrave"}, + {0x009e, "ucircumflex"}, + {0x009f, "udieresis"}, + + {0x00a0, "dagger"}, + {0x00a1, "degree"}, + {0x00a2, "cent"}, + {0x00a3, "sterling"}, + {0x00a4, "section"}, + {0x00a5, "bullet"}, + {0x00a6, "paragraph"}, + {0x00a7, "germandbls"}, + {0x00a8, "registered"}, + {0x00a9, "copyright"}, + {0x00aa, "trademark"}, + {0x00ab, "acute"}, + {0x00ac, "dieresis"}, + {0x00ad, "notequal"}, + {0x00ae, "AE"}, + {0x00af, "Oslash"}, + + {0x00b0, "infinity"}, + {0x00b1, "plusminus"}, + {0x00b2, "lessequal"}, + {0x00b3, "greaterequal"}, + {0x00b4, "yen"}, + {0x00b5, "mu"}, + {0x00b6, "partialdiff"}, + {0x00b7, "summation"}, + {0x00b8, "product"}, + {0x00b9, "pi"}, + {0x00ba, "integral"}, + {0x00bb, "ordfeminine"}, + {0x00bc, "ordmasculine"}, + {0x00bd, "Omega"}, + {0x00be, "ae"}, + {0x00bf, "oslash"}, + + {0x00c0, "questiondown"}, + {0x00c1, "exclamdown"}, + {0x00c2, "logicalnot"}, + {0x00c3, "radical"}, + {0x00c4, "florin"}, + {0x00c5, "approxequal"}, + {0x00c6, "Delta"}, + {0x00c7, "guillemotleft"}, + {0x00c8, "guillemotright"}, + {0x00c9, "ellipsis"}, + {0x00ca, "nbspace"}, + {0x00cb, "Agrave"}, + {0x00cc, "Atilde"}, + {0x00cd, "Otilde"}, + {0x00ce, "OE"}, + {0x00cf, "oe"}, + + {0x00d0, "endash"}, + {0x00d1, "emdash"}, + {0x00d2, "quotedblleft"}, + {0x00d3, "quotedblright"}, + {0x00d4, "quoteleft"}, + {0x00d5, "quoteright"}, + {0x00d6, "divide"}, + {0x00d7, "lozenge"}, + {0x00d8, "ydieresis"}, + {0x00d9, "Ydieresis"}, + {0x00da, "fraction"}, + {0x00db, "currency"}, + {0x00dc, "guilsinglleft"}, + {0x00dd, "guilsinglright"}, + {0x00de, "fi"}, + {0x00df, "fl"}, + + {0x00e0, "daggerdbl"}, + {0x00e1, "periodcentered"}, + {0x00e2, "quotesinglbase"}, + {0x00e3, "quotedblbase"}, + {0x00e4, "perthousand"}, + {0x00e5, "Acircumflex"}, + {0x00e6, "Ecircumflex"}, + {0x00e7, "Aacute"}, + {0x00e8, "Edieresis"}, + {0x00e9, "Egrave"}, + {0x00ea, "Iacute"}, + {0x00eb, "Icircumflex"}, + {0x00ec, "Idieresis"}, + {0x00ed, "Igrave"}, + {0x00ee, "Oacute"}, + {0x00ef, "Ocircumflex"}, + + {0x00f0, "apple"}, + {0x00f1, "Ograve"}, + {0x00f2, "Uacute"}, + {0x00f3, "Ucircumflex"}, + {0x00f4, "Ugrave"}, + {0x00f5, "dotlessi"}, + {0x00f6, "circumflex"}, + {0x00f7, "tilde"}, + {0x00f8, "macron"}, + {0x00f9, "breve"}, + {0x00fa, "dotaccent"}, + {0x00fb, "ring"}, + {0x00fc, "cedilla"}, + {0x00fd, "hungarumlaut"}, + {0x00fe, "ogonek"}, + {0x00ff, "caron"}, +}; + + +struct encoding_table *current_table; +size_t current_table_len; + + +void +set_encoding_scheme(EncodingScheme e, Font *fnt) +{ + current_encoding_scheme = e; + + switch (e) + { + case encUnicode: + current_table = unicode_table; + current_table_len = sizeof (unicode_table) / sizeof (unicode_table[0]); + break; + + case encMac: + current_table = mac_table; + current_table_len = sizeof (mac_table) / sizeof (mac_table[0]); + break; + + case encFontSpecific: + break; + } +} + + +/* + * We return ".c0x" + * if no name is found. + * + * We return ".g0x" + * if it's a glyph index (code >= 0x10000). + */ + +char * +code_to_adobename(long code) +{ + unsigned int n, n1 = 0, n2 = current_table_len - 1; + char *p; + + + if (current_encoding_scheme == encFontSpecific) + { + p = (char *)mymalloc(9); + sprintf(p, ".%c0x%x", (code >= 0x10000) ? 'g' : 'c', + (unsigned int)(code & 0xFFFF)); + return p; + } + + while (n1 <= n2) + { + n = (n1 + n2) / 2; + if (code < current_table[n].code) + n2 = n - 1; + else if (code > current_table[n].code) + n1 = n + 1; + else + return current_table[n].adobename; + } + + p = (char *)mymalloc(9); + sprintf(p, ".%c0x%x", (code >= 0x10000) ? 'g' : 'c', + (unsigned int)(code & 0xFFFF)); + return p; +} + + +/* + * The first of two identical entries will win. + */ + +long +adobename_to_code(char *s) +{ + size_t i; + long j; + char p; + + + if (s == NULL) + return -1; + + if (current_encoding_scheme == encFontSpecific) + { + if (*(s++) != '.') + return -1; + + p = *(s++); + if (!(p == 'c' || p == 'g')) + return -1; + + j = strtol(s, &s, 0); + if (*s == '\0') + return (p == 'g') ? (j | 0x10000) : j; + else + return -1; + } + + for (i = 0; i < current_table_len; i++) + { + if (strcmp(current_table[i].adobename, s) == 0) + return current_table[i].code; + } + + if (*(s++) != '.') + return -1; + + p = *(s++); + if (!(p == 'c' || p == 'g')) + return -1; + + j = strtol(s, &s, 0); + if (*s == '\0') + return (p == 'g') ? (j | 0x10000) : j; + else + return -1; +} + + +ttfinfo * +findglyph(unsigned short g, ttfinfo *p) +{ + register ttfinfo *ti; + + + if (!p) + return NULL; + + for (ti = p; ti; ti = ti->next) + if (g == ti->glyphindex) + return ti; + + return NULL; +} + + +ttfinfo * +findadobe(char *p, ttfinfo *ap) +{ + register ttfinfo *ti; + register long l = -1; + register char c = '\0', d = '\0'; + + + if (!p) + return NULL; + + if (p[0] == '.' && + (c = p[1]) && (c == 'c' || c == 'g') && + (d = p[2]) && '0' <= d && d <= '9') + l = strtol(p + 2, NULL, 0); + + for (ti = ap; ti; ti = ti->next) + { + if (l >= 0) + { + if (c == 'c') + { + if (ti->charcode == l) + return ti; + } + else + { + if (ti->glyphindex == l) + return ti; + } + } + else if (strcmp(p, ti->adobename) == 0) + return ti; + } + + return NULL; +} + + +ttfinfo * +findmappedadobe(char *p, ttfinfo **array) +{ + register int i; + register ttfinfo *ti; + register long l = -1; + register char c = '\0', d = '\0'; + + + if (!p) + return NULL; + + if (p[0] == '.' && + (c = p[1]) && (c == 'c' || c == 'g') && + (d = p[2]) && '0' <= d && d <= '9') + l = strtol(p + 2, NULL, 0); + + for (i = 0; i <= 0xFF; i++) + if ((ti = array[i])) + { + if (l >= 0) + { + if (c == 'c') + { + if (ti->charcode == l) + return ti; + } + else + { + if (ti->glyphindex == l) + return ti; + } + } + else if (strcmp(p, ti->adobename) == 0) + return ti; + } + + return NULL; +} + + +void +replace_glyphs(Font *fnt) +{ + stringlist *sl, *sl_old; + ttfinfo *ti; + + + for (sl = fnt->replacements, sl_old = NULL; sl; sl_old = sl, sl = sl->next) + { + if ((ti = findadobe(sl->old_name, fnt->charlist))) + ti->adobename = sl->new_name; + else + { + warning("Glyph name `%s' not found.", sl->old_name); + warning("Replacement glyph name `%s' thus ignored.", sl->new_name); + if (sl_old == NULL) + fnt->replacements = sl->next; + else + sl_old->next = sl->next; + } + } +} + + +/* the opposite of replace_glyph() */ + +void +restore_glyph(encoding *enc, Font *fnt) +{ + stringlist *sl; + int i; + + + for (sl = fnt->replacements; sl; sl = sl->next) + { + for (i = 0; i <= 0xFF; i++) + { + if (strcmp(enc->vec[i], sl->new_name) == 0) + { + enc->vec[i] = sl->old_name; + goto success; + } + } + warning("Glyph name `%s' not found in encoding.", sl->new_name); + warning("Replacement for glyph name `%s' thus ignored.", sl->old_name); + +success: + ; + } +} + + +/* end */ diff --git a/contrib/ttf2pk/ttfenc.h b/contrib/ttf2pk/ttfenc.h new file mode 100644 index 0000000..95a265b --- /dev/null +++ b/contrib/ttf2pk/ttfenc.h @@ -0,0 +1,41 @@ +/* + * ttfenc.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef TTFENC_H +#define TTFENC_H + +#include "ttf2tfm.h" + + +enum _EncodingScheme +{ + encUnicode, + encMac, + encFontSpecific +}; +typedef enum _EncodingScheme EncodingScheme; + + +void set_encoding_scheme(EncodingScheme e, Font *fnt); + +char *code_to_adobename(long code); +long adobename_to_code(char *s); + +ttfinfo *findglyph(unsigned short g, ttfinfo *p); +ttfinfo *findadobe(char *p, ttfinfo *ap); +ttfinfo *findmappedadobe(char *p, ttfinfo **array); + +void replace_glyphs(Font *fnt); +void restore_glyph(encoding *enc, Font *fnt); + +#endif /* TTFENC_H */ + + +/* end */ diff --git a/contrib/ttf2pk/ttflib.c b/contrib/ttf2pk/ttflib.c new file mode 100644 index 0000000..3cadaa2 --- /dev/null +++ b/contrib/ttf2pk/ttflib.c @@ -0,0 +1,703 @@ +/* + * ttflib.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Loyer Frederic + * Werner Lemberg + */ + +#include +#include +#include +#include /* libc ANSI */ +#include + +#include "pklib.h" /* for the `byte' type */ +#include "freetype.h" +#include "ttfenc.h" +#include "ttflib.h" +#include "errormsg.h" +#include "newobj.h" +#include "ttf2tfm.h" + +#include "extend/ftxpost.h" +#include "extend/ftxopen.h" + + +#define Macintosh_platform 1 +#define Macintosh_encoding 0 + +#define Microsoft_platform 3 +#define Microsoft_Symbol_encoding 0 +#define Microsoft_Unicode_encoding 1 + +#define SCRIPT_kana MAKE_TT_TAG('k', 'a', 'n', 'a') +#define SCRIPT_hani MAKE_TT_TAG('h', 'a', 'n', 'i') +#define SCRIPT_hang MAKE_TT_TAG('h', 'a', 'n', 'g') + +#define LANGUAGE_JAN MAKE_TT_TAG('J', 'A', 'N', ' ') +#define LANGUAGE_CHN MAKE_TT_TAG('C', 'H', 'N', ' ') +#define LANGUAGE_KOR MAKE_TT_TAG('K', 'O', 'R', ' ') + +#define FEATURE_vert MAKE_TT_TAG('v', 'e', 'r', 't') + + +TT_Engine engine; +TT_Face face; +TT_Instance instance; +TT_Glyph glyph; +TT_CharMap char_map; + +TT_Outline outline; +TT_Face_Properties properties; +TT_BBox bbox; + +TT_Post post; + +TT_Raster_Map Bit, Bit2; +void *Bitp, *Bit2p; + +int dpi; +int ptsize; + +int x_offset, y_offset; +int ppem; + +TT_Big_Glyph_Metrics metrics; + +TT_Matrix matrix1, matrix2; + +TTO_GSUBHeader gsub_; +TTO_GSUBHeader *gsub; + +TT_UShort in_string[2]; +TTO_GSUB_String in, out; + +Boolean has_gsub; + + +static void +SetRasterArea(int quiet) +{ + int temp1_x, temp1_y, temp2_x, temp2_y; + + + temp1_x = bbox.xMin / 64; /* scaling F16.6 -> int */ + temp1_y = bbox.yMin / 64; + temp2_x = (bbox.xMax + 63) / 64; + temp2_y = (bbox.yMax + 63) / 64; + + x_offset = 5 - temp1_x; + y_offset = 5 - temp1_y; + + if (!quiet) + printf(" off = (%d, %d)", x_offset, y_offset); + +#if 0 + x_offset = y_offset = 0; +#endif + + if (!quiet) + printf(" bbox = (%d, %d) <-> (%d, %d)\n", + temp1_x, temp1_y, temp2_x, temp2_y); + + Bit.rows = temp2_y - temp1_y + 10; + Bit.width = temp2_x - temp1_x + 10; + + Bit.cols = (Bit.width + 7) / 8; /* convert to # of bytes */ + Bit.flow = TT_Flow_Up; + Bit.size = Bit.rows * Bit.cols; /* number of bytes in buffer */ + + /* + * We allocate one more row to have valid pointers for comparison + * purposes in pklib.c, making `gcc -fbounds-checking' happy. + */ + + if (Bitp) + free(Bitp); + Bitp = mymalloc(Bit.size + Bit.cols); + Bit.bitmap = Bitp; + + Bit2 = Bit; + + if (Bit2p) + free(Bit2p); + Bit2p = mymalloc(Bit.size + Bit.cols); + Bit2.bitmap = Bit2p; +} + + +static void +FlipBit(void) +{ + int y; + char *p1, *p2; + + p1 = (char *)Bit.bitmap; + p2 = (char *)Bit2.bitmap + Bit2.cols * (Bit2.rows - 1); + + for (y = 0; y < Bit.rows; y++) + { + memcpy(p2, p1, Bit.cols); + p1 += Bit.cols; + p2 -= Bit.cols; + } +} + + +#if 0 + +static void +Output(TT_Raster_Map Bit) +{ + int x; + int y; + int i; + + char *p, b; + + + p = Bit.bitmap; + printf("====\n"); + + for (y = 0; y < Bit.rows; y++) + { + printf("%3d:", y); + for (x = 0; x < Bit.cols; x++) + { + b = *p++; + for(i = 0x80; i; i >>= 1) + printf((b & i) ? "x" : "."); + } + printf("\n"); + } +} + +#endif /* 0 */ + + +void +TTFopen(char *filename, Font *fnt, int new_dpi, int new_ptsize, Boolean quiet) +{ + unsigned short i, num_cmap; + unsigned short cmap_plat; + unsigned short cmap_enc; + TT_Error error; + + TT_UShort script_index, language_index, feature_index; + TT_UShort req_feature_index = 0xFFFF; + + + dpi = new_dpi; + ptsize = new_ptsize; + + if ((error = TT_Init_FreeType(&engine))) + oops("Cannot initialize FreeType engine (error code = 0x%x).", error); + + if (fnt->PSnames) + if ((error = TT_Init_Post_Extension(engine))) + oops("Cannot initialize PS name support (error code = 0x%x).", error); + + if (fnt->rotate) + if ((error = TT_Init_GSUB_Extension(engine))) + oops("Cannot initialize GSUB support (error code = 0x%x).", error); + + /* + * Load face. + */ + + error = TT_Open_Face(engine, filename, &face); + if (error) + oops("Cannot open `%s'.", filename); + + /* + * Get face properties and allocate preloaded arrays. + */ + + TT_Get_Face_Properties(face, &properties); + + /* + * Now we try to open the proper font in a collection. + */ + + if (fnt->fontindex != 0) + { + if (properties.num_Faces == 1) + warning("This isn't a TrueType collection.\n" + "Parameter `Fontindex' is ignored."); + else + { + TT_Close_Face(face); + if ((error = TT_Open_Collection(engine, filename, + fnt->fontindex, &face))) + oops("Cannot open font %lu in TrueType Collection `%s'.", + fnt->fontindex, filename); + } + } + + /* + * Create instance. + */ + + if ((error = TT_New_Instance(face, &instance))) + oops("Cannot create instance for `%s' (error code = 0x%x).", + filename, error); + + if ((error = TT_Set_Instance_Resolutions(instance, dpi, dpi))) + oops("Cannot set device resolutions (error code = 0x%x)."); + + if ((error = TT_Set_Instance_CharSize(instance, ptsize * 64))) + oops("Cannot set character size (error code = 0x%x).", error); + + ppem = (dpi * ptsize + 36) / 72; + + if (!quiet) + printf("dpi = %d, ptsize = %d, ppem = %d\n\n", dpi, ptsize, ppem); + + matrix1.xx = (TT_Fixed)(floor(fnt->efactor * 1024) * (1<<16)/1024); + matrix1.xy = (TT_Fixed)(floor(fnt->slant * 1024) * (1<<16)/1024); + matrix1.yx = (TT_Fixed)0; + matrix1.yy = (TT_Fixed)(1<<16); + + if (fnt->rotate) + { + matrix2.xx = 0; + matrix2.yx = 1L << 16; + matrix2.xy = -matrix2.yx; + matrix2.yy = matrix2.xx; + } + + if ((error = TT_Set_Instance_Transform_Flags( + instance, + fnt->rotate ? 1 : 0, + fnt->efactor != 1.0 ? 1 : 0))) + oops("Cannot set transform flags (error code = 0x%x).", error); + + /* + * Create glyph container. + */ + + if ((error = TT_New_Glyph(face, &glyph))) + oops("Cannot create glyph container (error code = 0x%x)."); + + if (fnt->PSnames != Only) + { + num_cmap = properties.num_CharMaps; + for (i = 0; i < num_cmap; i++) + { + if ((error = TT_Get_CharMap_ID(face, i, &cmap_plat, &cmap_enc))) + oops("Cannot query cmap (error code = 0x%x).", error); + if (cmap_plat == fnt->pid && cmap_enc == fnt->eid) + break; + } + if (i == num_cmap) + oops("Invalid platform and/or encoding ID."); + + if ((error = TT_Get_CharMap(face, i, &char_map))) + oops("Cannot load cmap (error code = 0x%x).", error); + } + + if (fnt->PSnames) + { + if ((error = TT_Load_PS_Names(face, &post))) + oops("Cannot load TrueType PS names (error code = 0x%x).", error); + } + else if (cmap_plat == Microsoft_platform && + cmap_enc == Microsoft_Unicode_encoding) + set_encoding_scheme(encUnicode, fnt); + else if (cmap_plat == Macintosh_platform && + cmap_enc == Macintosh_encoding) + set_encoding_scheme(encMac, fnt); + else + set_encoding_scheme(encFontSpecific, fnt); + + if (fnt->rotate) + { + gsub = &gsub_; + + error = TT_Load_GSUB_Table(face, gsub, NULL); + if (!error) + has_gsub = True; + else if (error != TT_Err_Table_Missing) + warning("Cannot load GSUB table (error code = 0x%x).", error); + else + warning("No GSUB data available " + "for vertical glyph presentation forms."); + + /* we check for the `vert' feature in Chinese, Japanese, and Korean */ + + error = TT_GSUB_Select_Script(gsub, + SCRIPT_kana, + &script_index); + if (error) + goto check_hani; + error = TT_GSUB_Select_Feature(gsub, + FEATURE_vert, + script_index, + 0xFFFF, + &feature_index); + if (error) + { + error = TT_GSUB_Select_Language(gsub, + LANGUAGE_JAN, + script_index, + &language_index, + &req_feature_index); + if (error) + goto check_hani; + error = TT_GSUB_Select_Feature(gsub, + FEATURE_vert, + script_index, + language_index, + &feature_index); + if (error) + goto check_hani; + else + goto Done; + } + else + goto Done; + + check_hani: + error = TT_GSUB_Select_Script(gsub, + SCRIPT_hani, + &script_index); + if (error) + goto check_hang; + error = TT_GSUB_Select_Feature(gsub, + FEATURE_vert, + script_index, + 0xFFFF, + &feature_index); + if (error) + { + error = TT_GSUB_Select_Language(gsub, + LANGUAGE_CHN, + script_index, + &language_index, + &req_feature_index); + if (error) + goto check_hang; + error = TT_GSUB_Select_Feature(gsub, + FEATURE_vert, + script_index, + language_index, + &feature_index); + if (error) + goto check_hang; + else + goto Done; + } + else + goto Done; + + check_hang: + error = TT_GSUB_Select_Script(gsub, + SCRIPT_hang, + &script_index); + if (error) + goto Done; + error = TT_GSUB_Select_Feature(gsub, + FEATURE_vert, + script_index, + 0xFFFF, + &feature_index); + if (error) + { + error = TT_GSUB_Select_Language(gsub, + LANGUAGE_KOR, + script_index, + &language_index, + &req_feature_index); + if (error) + goto Done; + error = TT_GSUB_Select_Feature(gsub, + FEATURE_vert, + script_index, + language_index, + &feature_index); + } + + Done: + if (error) + { + warning("There is no data for vertical typesetting in GSUB table."); + has_gsub = False; + } + + if (req_feature_index != 0xFFFF) + TT_GSUB_Add_Feature(gsub, req_feature_index, ALL_GLYPHS); + TT_GSUB_Add_Feature(gsub, feature_index, ALL_GLYPHS); + + in.length = 1; + in.pos = 0; + in.string = in_string; + in.properties = NULL; + + out.pos = 0; + out.allocated = 0; + out.string = NULL; + out.properties = NULL; + } +} + + +static TT_Error +LoadTrueTypeChar(Font *fnt, + int idx, + Boolean hint, + Boolean quiet) +{ + TT_Error error; + int flags; + + + flags = TTLOAD_SCALE_GLYPH; + if (hint) + flags |= TTLOAD_HINT_GLYPH; + + error = TT_Load_Glyph(instance, glyph, idx, flags); + if (!error) + error = TT_Get_Glyph_Big_Metrics(glyph, &metrics); + if (!error) + error = TT_Get_Glyph_Outline(glyph, &outline); + if (!error) + { + if (fnt->efactor != 1.0 || fnt->slant != 0.0 ) + TT_Transform_Outline(&outline, &matrix1); + if (fnt->rotate) + TT_Transform_Outline(&outline, &matrix2); + } + if (!error) + error = TT_Get_Outline_BBox(&outline, &bbox); /* we need the non- + grid-fitted bbox */ + if (fnt->rotate) + TT_Translate_Outline(&outline, + metrics.vertBearingY - bbox.xMin, + -fnt->y_offset * ppem * 64); + if (!error) + error = TT_Get_Outline_BBox(&outline, &bbox); + if (!error) + SetRasterArea(quiet); + return error; +} + + +Boolean +TTFprocess(Font *fnt, + long Code, + byte **bitmap, + int *width, int *height, + int *hoff, int *voff, + Boolean hinting, + Boolean quiet) +{ + int Num; + TT_Error error; + + + if (!bitmap || !width || !height || !hoff || !voff) + oops("Invalid parameter in call to TTFprocess()"); + + if (Code >= 0x10000) + Num = Code & 0xFFFF; + else + { + Num = TT_Char_Index(char_map, Code); + if (has_gsub) + { + in_string[0] = Num; + error = TT_GSUB_Apply_String(gsub, &in, &out); + if (error && error != TTO_Err_Not_Covered) + warning("Cannot get the vertical glyph form for glyph index %d.", + Num); + else + Num = out.string[0]; + } + } + + if ((error = LoadTrueTypeChar(fnt, Num, hinting, quiet)) == TT_Err_Ok) + { + memset(Bit.bitmap, 0, Bit.size); + TT_Get_Glyph_Bitmap(glyph, &Bit, x_offset * 64, y_offset * 64); + + FlipBit(); + *bitmap = Bit2.bitmap; + *width = Bit2.width; + *height = Bit2.rows; + *hoff = x_offset; + *voff = y_offset; + /* *voff = Bit2.rows - y_offset; */ + /* printf("%D %d\n", *hoff, *voff); */ + /* Output(Bit2); */ + return True; + } + else + return False; +} + + +/* + * We collect first all glyphs addressed via the cmap. Then we fill the + * array up with glyphs not in the cmap. + * + * If PSnames is set to `Only', we get the first 256 glyphs which have + * names different from `.notdef', `.null', and `nonmarkingreturn'. + * + * For nicer output, we return the glyph names in an encoding array. + */ + +encoding * +TTFget_first_glyphs(Font *fnt, long *array) +{ + unsigned int i, j, Num; + unsigned int index_array[257]; /* we ignore glyph index 0 */ + char *n; + encoding *e = (encoding *)mymalloc(sizeof (encoding)); + + + if (!array) + oops("Invalid parameter in call to TTFget_first_glyphs()"); + + for (i = 0; i < 257; i++) + index_array[i] = 0; + + j = 0; + if (fnt->PSnames != Only) + { + for (i = 0; i <= 0xFFFF; i++) + { + Num = TT_Char_Index(char_map, i); + if (Num < 0) + oops("cmap mapping failure."); + if (Num == 0) + continue; + if (Num <= 256) + index_array[Num] = 1; + + if (fnt->PSnames) + (void)TT_Get_PS_Name(face, Num, &n); + else + n = code_to_adobename(i); + if (strcmp(n, ".notdef") == 0) + continue; + if (strcmp(n, ".null") == 0) + continue; + if (strcmp(n, "nonmarkingreturn") == 0) + continue; + + if (j < 256) + { + array[j] = i; + e->vec[j] = n; + } + else + return e; + j++; + } + + if (!fnt->PSnames) + { + for (i = 1; i < properties.num_Glyphs; i++) + { + if (index_array[i] == 0) + { + if (j < 256) + { + array[j] = i | 0x10000; + e->vec[j] = code_to_adobename(i | 0x10000); + } + else + return e; + j++; + } + } + } + } + else + { + for (i = 0; i < properties.num_Glyphs; i++) + { + char *n; + + + (void)TT_Get_PS_Name(face, i, &n); + + if (strcmp(n, ".notdef") == 0) + continue; + if (strcmp(n, ".null") == 0) + continue; + if (strcmp(n, "nonmarkingreturn") == 0) + continue; + + if (j < 256) + { + array[j] = i | 0x10000; + e->vec[j] = n; + } + else + return e; + j++; + } + } + + return NULL; /* never reached */ +} + + +/* + * This routine fills `array' with the subfont character codes; + * additionally, it tests for valid glyph indices. + */ + +void +TTFget_subfont(Font *fnt, long *array) +{ + int i, j, Num; + + + if (!fnt || !array) + oops("Invalid parameter in call to TTFget_subfont()"); + + for (i = 0; i <= 0xFF; i++) + { + j = fnt->sf_code[i]; + + if (j < 0) + array[i] = j; + else + { + Num = TT_Char_Index(char_map, j); + if (Num < 0) + oops("cmap mapping failure."); + else + array[i] = j; + } + } +} + + +long +TTFsearch_PS_name(char *name) +{ + unsigned int i; + char *n; + + + for (i = 0; i < properties.num_Glyphs; i++) + { + TT_Get_PS_Name(face, i, &n); + if (strcmp(name, n) == 0) + break; + } + + if (i == properties.num_Glyphs) + return -1L; + else + return (long)i; +} + + +/* end */ diff --git a/contrib/ttf2pk/ttflib.h b/contrib/ttf2pk/ttflib.h new file mode 100644 index 0000000..e218382 --- /dev/null +++ b/contrib/ttf2pk/ttflib.h @@ -0,0 +1,31 @@ +/* + * ttflib.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef TTFLIB_H +#define TTFLIB_H + +#include "pklib.h" /* for the `byte' type */ + +void TTFopen(char *filename, Font *fnt, int new_dpi, int new_ptsize, + Boolean quiet); + +Boolean TTFprocess(Font *fnt, long Code, byte **bitmap, + int *width, int *height, int *hoff, int *voff, + Boolean hinting, Boolean quiet); + +encoding *TTFget_first_glyphs(Font *fnt, long *array); +void TTFget_subfont(Font *fnt, long *array); + +long TTFsearch_PS_name(char *name); + +#endif /* TTFLIB_H */ + + +/* end */ diff --git a/contrib/ttf2pk/vplaux.c b/contrib/ttf2pk/vplaux.c new file mode 100644 index 0000000..867c32f --- /dev/null +++ b/contrib/ttf2pk/vplaux.c @@ -0,0 +1,588 @@ +/* + * vplaux.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#include +#include +#include +#include + +#include "ttf2tfm.h" +#include "newobj.h" +#include "ttfenc.h" +#include "texenc.h" +#include "tfmaux.h" +#include "vplaux.h" +#include "errormsg.h" +#include "case.h" + + +#undef PI +#define PI 3.14159265358979323846264338327 + + +#define vout(s) fprintf(out, s) + +#define voutln(str) {fprintf(out, "%s\n", str); vlevout(level);} +#define voutln2(f, s) {fprintf(out, f, s); vlevnlout(level);} +#define voutln3(f, a, b) {fprintf(out, f, a, b); vlevnlout(level);} +#define voutln4(f, a, b, c) {fprintf(out, f, a, b, c); vlevnlout(level);} + + +static char vcharbuf[6]; +static char vnamebuf[100]; + +/* the depth of parenthesis nesting in VPL file being written */ +static int level; + + +static FILE *out; + + +static void +vlevout(register int l) +{ + while (l--) + vout(" "); +} + + +static void +vlevnlout(int level) +{ + vout("\n"); + vlevout(level); +} + + +static void +vleft(int *levelp) +{ + (*levelp)++; + vout("("); +} + + +static void +vright(int *levelp) +{ + (*levelp)--; + voutln(")"); +} + + +static char * +vchar(int c, + char *buf, + Boolean forceoctal) +{ + if (forceoctal == 0 && isalnum(c)) + (void)sprintf(buf, "C %c", c); + else + (void)sprintf(buf, "O %o", (unsigned)c); + return buf; +} + + +static char * +vname(int c, + char *buf, + ttfinfo **array, + Boolean forceoctal) +{ + if (!forceoctal && isalnum(c)) + buf[0] = '\0'; + else + sprintf(buf, " (comment %s)", array[c]->adobename); + return buf; +} + + +static int +texheight(register ttfinfo *ti, + ttfinfo *ac, + int xh) +{ + register char **p; + register ttfinfo *aci, *acci; + char buffer[200]; + + + if (xh <= 50 || *(ti->adobename + 1)) + return ti->ury; /* that was the simple case */ + + for (p = accents; *p; p++) /* otherwise we look for accented letters. */ + /* We even check glyphs not in any encoding */ + if (NULL != (aci = findadobe(*p, ac))) + { + strcpy(buffer, ti->adobename); + strcat(buffer, *p); + if (NULL != (acci = findadobe(buffer, ac))) + return acci->ury - aci->ury + xh; + } + return ti->ury; +} + + +/* + * Compute uppercase mapping, when making a small caps font. + */ + +void +upmap(Font *fnt) +{ + register ttfinfo *ti, *Ti; + register char *p, *q; + register pcc *np, *nq; + int i, j; + char lwr[50]; + + + for (Ti = fnt->charlist; Ti; Ti = Ti->next) + { + p = Ti->adobename; + if (isupper(*p)) + { + q = lwr; + for (; *p; p++) + *q++ = tolower(*p); + *q = '\0'; + + if (NULL != (ti = findmappedadobe(lwr, fnt->inencptrs))) + { + for (i = ti->outcode; i >= 0; i = fnt->nextout[i]) + fnt->uppercase[i] = Ti; + for (i = Ti->outcode; i >= 0; i = fnt->nextout[i]) + fnt->lowercase[i] = ti; + } + } + } + + /* + * Note that, contrary to the normal true/false conventions, + * uppercase[i] is NULL and lowercase[i] is non-NULL when `i' is the + * ASCII code of an uppercase letter; and vice versa for lowercase + * letters. + */ + + if (NULL != (ti = findmappedadobe("germandbls", fnt->inencptrs))) + if (NULL != (Ti = findmappedadobe("S", fnt->inencptrs))) + /* we also construct SS */ + { + for (i = ti->outcode; i >= 0; i = fnt->nextout[i]) + fnt->uppercase[i] = ti; + ti->incode = -1; + ti->width = Ti->width << 1; + ti->llx = Ti->llx; + ti->lly = Ti->lly; + ti->urx = Ti->width + Ti->urx; + ti->ury = Ti->ury; + ti->kerns = Ti->kerns; + + np = newpcc(); + np->partname = "S"; + nq = newpcc(); + nq->partname = "S"; + nq->xoffset = Ti->width; + np->next = nq; + ti->pccs = np; + ti->constructed = True; + } + + for (i = 0; casetable[i].upper; i++) + { + if ((ti = findmappedadobe(casetable[i].lower, fnt->inencptrs))) + for (j = ti->outcode; j >= 0; j = fnt->nextout[j]) + fnt->uppercase[j] = findmappedadobe(casetable[i].upper, + fnt->inencptrs); + } +} + +/* + * The logic above seems to work well enough, but it leaves useless + * characters like `fi' and `fl' in the font if they were present + * initially, and it omits characters like `dotlessj' if they are + * absent initially. + */ + + +void +writevpl(Font *fnt, char makevpl, Boolean forceoctal) +{ + register int i, j, k; + register ttfinfo *ti; + register lig *nlig; + register kern *nkern; + register pcc *npcc; + ttfinfo *asucc, *asub, *api; + ttfptr *kern_eq; + int xoff, yoff, ht; + int bc, ec; + char buf[200]; + char header[256]; + Boolean unlabeled; + float Slant; + + + out = fnt->vplout; + + header[0] = '\0'; + strncat(header, "Created by `", 12); + strncat(header, fnt->titlebuf, 255 - 12 - 1); + strncat(header, "'", 1); + + voutln2("(VTITLE %s)", header); + voutln("(COMMENT Please change VTITLE if you edit this file)"); + (void)sprintf(buf, "TeX-%s%s%s%s", + fnt->fullname, + (fnt->efactor == 1.0 ? "" : "-E"), + (fnt->slant == 0.0 ? "" : "-S"), + (makevpl == 1 ? "" : "-CSC")); + + if (strlen(buf) > 19) /* too long, will retain first 9 and last 10 chars */ + { + register char *p, *q; + + + for (p = &buf[9], q = &buf[strlen(buf)-10]; p < &buf[19]; + p++, q++) + *p = *q; + buf[19] = '\0'; + } + voutln2("(FAMILY %s)", buf); + + { + char tbuf[300]; + char *base_encoding = fnt->codingscheme; + + + if (strcmp(fnt->outencoding->name, base_encoding) == 0) + sprintf(tbuf, "%s", fnt->outencoding->name); + else + sprintf(tbuf, "%s + %s", base_encoding, fnt->outencoding->name); + + if (strlen(tbuf) > 39) + { + warning("Coding scheme too long; shortening to 39 characters"); + tbuf[39] = '\0'; + } + voutln2("(CODINGSCHEME %s)", tbuf); + } + + { + long t, sc; + char *s; + int n, pos; + + + s = header; + n = strlen(s); + t = ((long)n) << 24; + sc = 16; + pos = 18; + + voutln( + "(COMMENT The following `HEADER' lines are equivalent to the string)"); + voutln2("(COMMENT \"%s\")", header); + + while (n > 0) + { + t |= ((long)(*(unsigned char *)s++)) << sc; + sc -= 8; + if (sc < 0) + { + voutln3("(HEADER D %d O %lo)", pos, t); + t = 0; + sc = 24; + pos++; + } + n--; + } + if (t) + voutln3("(HEADER D %d O %lo)", pos, t); + } + + voutln("(DESIGNSIZE R 10.0)"); + voutln("(DESIGNUNITS R 1000)"); + voutln("(COMMENT DESIGNSIZE (1 em) IS IN POINTS)"); + voutln("(COMMENT OTHER DIMENSIONS ARE MULTIPLES OF DESIGNSIZE/1000)"); + +#if 0 + /* Let vptovf compute the checksum. */ + voutln2("(CHECKSUM O %lo)", cksum ^ 0xFFFFFFFF); +#endif + + if (fnt->boundarychar >= 0) + voutln2("(BOUNDARYCHAR O %lo)", (unsigned long)fnt->boundarychar); + + vleft(&level); + voutln("FONTDIMEN"); + + Slant = fnt->slant - fnt->efactor * tan(fnt->italicangle * (PI / 180.0)); + + if (Slant) + voutln2("(SLANT R %f)", Slant); + voutln2("(SPACE D %d)", fnt->fontspace); + if (!fnt->fixedpitch) + { + voutln2("(STRETCH D %d)", transform(200, 0, fnt->efactor, fnt->slant)); + voutln2("(SHRINK D %d)", transform(100, 0, fnt->efactor, fnt->slant)); + } + voutln2("(XHEIGHT D %d)", fnt->xheight); + voutln2("(QUAD D %d)", transform(1000, 0, fnt->efactor, fnt->slant)); + voutln2("(EXTRASPACE D %d)", + fnt->fixedpitch ? fnt->fontspace : + transform(111, 0, fnt->efactor, fnt->slant)); + vright(&level); + + vleft(&level); + voutln("MAPFONT D 0"); + voutln2("(FONTNAME %s)", fnt->fullname); +#if 0 + voutln2("(FONTCHECKSUM O %lo)", (unsigned long)cksum); +#endif + vright(&level); + + if (makevpl > 1) + { + vleft(&level); + voutln("MAPFONT D 1"); + voutln2("(FONTNAME %s)", fnt->fullname); + voutln2("(FONTAT D %d)", (int)(1000.0 * fnt->capheight + 0.5)); +#if 0 + voutln2("(FONTCHECKSUM O %lo)", (unsigned long)cksum); +#endif + vright(&level); + } + + for (i = 0; i <= 0xFF && fnt->outencptrs[i] == NULL; i++) + ; + bc = i; + for (i = 0xFF; i >= 0 && fnt->outencptrs[i] == NULL; i--) + ; + ec = i; + + vleft(&level); + voutln("LIGTABLE"); + ti = findadobe("||", fnt->charlist); + unlabeled = True; + for (nlig = ti->ligs; nlig; nlig = nlig->next) + if (NULL != (asucc = findmappedadobe(nlig->succ, fnt->inencptrs))) + { + if (NULL != (asub = findmappedadobe(nlig->sub, fnt->inencptrs))) + if (asucc->outcode >= 0) + if (asub->outcode >= 0) + { + if (unlabeled) + { + voutln("(LABEL BOUNDARYCHAR)"); + unlabeled = False; + } + for (j = asucc->outcode; j >= 0; j = fnt->nextout[j]) + voutln4("(%s %s O %o)", vplligops[nlig->op], + vchar(j, vcharbuf, forceoctal), + (unsigned)asub->outcode); + } + } + if (!unlabeled) + voutln("(STOP)"); + + for (i = bc; i <= ec; i++) + if ((ti = fnt->outencptrs[i]) && ti->outcode == i) + { + unlabeled = True; + if (fnt->uppercase[i] == NULL) + /* omit ligatures from smallcap lowercase */ + for (nlig = ti->ligs; nlig; nlig = nlig->next) + if (NULL != (asucc = findmappedadobe(nlig->succ, fnt->inencptrs))) + if (NULL != (asub = findmappedadobe(nlig->sub, fnt->inencptrs))) + if (asucc->outcode >= 0) + if (asub->outcode >= 0) + { + if (unlabeled) + { + for (j = ti->outcode; j >= 0; j = fnt->nextout[j]) + voutln3("(LABEL %s)%s", + vchar(j, vcharbuf, forceoctal), + vname(j, vnamebuf, + fnt->outencptrs, forceoctal)); + unlabeled = False; + } + for (j = asucc->outcode; j >= 0; j = fnt->nextout[j]) + { + voutln4("(%s %s O %o)", vplligops[nlig->op], + vchar(j, vcharbuf, forceoctal), + (unsigned)asub->outcode); + if (nlig->boundleft) + break; + } + } + + for (nkern = (fnt->uppercase[i] ? fnt->uppercase[i]->kerns : ti->kerns); + nkern; nkern=nkern->next) + if (NULL != (asucc = findmappedadobe(nkern->succ, fnt->inencptrs))) + for (j = asucc->outcode; j >= 0; j = fnt->nextout[j]) + { + if (fnt->uppercase[j] == NULL) + { + if (unlabeled) + { + for (k = ti->outcode; k >= 0; k = fnt->nextout[k]) + voutln3("(LABEL %s)%s", + vchar(k, vcharbuf, forceoctal), + vname(k, vnamebuf, fnt->outencptrs, forceoctal)); + unlabeled = False; + } + + /* + * If other characters have the same kerns as this + * one, output the label here. This makes the TFM + * file much smaller than if we output all the + * kerns again under a different label. + */ + + for (kern_eq = ti->kern_equivs; kern_eq; + kern_eq = kern_eq->next) + { + k = kern_eq->ch->outcode; + if (k >= 0 && k <= 0xFF) + voutln3("(LABEL %s)%s", + vchar(k, vcharbuf, forceoctal), + vname(k, vnamebuf, fnt->outencptrs, forceoctal)); + } + ti->kern_equivs = NULL; /* Only output those labels once. */ + + if (fnt->uppercase[i]) + { + if (fnt->lowercase[j]) + { + for (k = fnt->lowercase[j]->outcode; k >= 0; + k = fnt->nextout[k]) + voutln4("(KRN %s R %.1f)%s", + vchar(k, vcharbuf, forceoctal), + fnt->capheight * nkern->delta, + vname(k, vnamebuf, fnt->outencptrs, forceoctal)); + } + else + voutln4("(KRN %s R %.1f)%s", + vchar(j, vcharbuf, forceoctal), + fnt->capheight * nkern->delta, + vname(j, vnamebuf, fnt->outencptrs, forceoctal)); + } + else + { + voutln4("(KRN %s R %d)%s", + vchar(j, vcharbuf, forceoctal), + nkern->delta, + vname(j, vnamebuf, fnt->outencptrs, forceoctal)); + if (fnt->lowercase[j]) + for (k = fnt->lowercase[j]->outcode; k >= 0; + k = fnt->nextout[k]) + voutln4("(KRN %s R %.1f)%s", + vchar(k, vcharbuf, forceoctal), + fnt->capheight * nkern->delta, + vname(k, vnamebuf, fnt->outencptrs, forceoctal)); + } + } + } + if (!unlabeled) + voutln("(STOP)"); + } + vright(&level); + + for (i = bc; i <= ec; i++) + if (NULL != (ti = fnt->outencptrs[i])) + { + vleft(&level); + fprintf(out, "CHARACTER %s%s\n ", + vchar(i, vcharbuf, forceoctal), + vname(i, vnamebuf, fnt->outencptrs, forceoctal)); + + if (fnt->uppercase[i]) + { + ti = fnt->uppercase[i]; + voutln2("(CHARWD R %.1f)", fnt->capheight * (ti->width)); + if (0 != (ht = texheight(ti, fnt->charlist, fnt->xheight))) + voutln2("(CHARHT R %.1f)", fnt->capheight * ht); + if (ti->lly) + voutln2("(CHARDP R %.1f)", -fnt->capheight * ti->lly); + if (ti->urx > ti->width) + voutln2("(CHARIC R %.1f)", fnt->capheight * (ti->urx - ti->width)); + } + else + { + voutln2("(CHARWD R %d)", ti->width); + if (0 != (ht = texheight(ti, fnt->charlist, fnt->xheight))) + voutln2("(CHARHT R %d)", ht); + if (ti->lly) + voutln2("(CHARDP R %d)", -ti->lly); + if (ti->urx > ti->width) + voutln2("(CHARIC R %d)", ti->urx - ti->width); + } + + if (ti->incode != i || fnt->uppercase[i] || ti->constructed) + { + vleft(&level); + voutln("MAP"); + if (fnt->uppercase[i]) + voutln("(SELECTFONT D 1)"); + + if (ti->pccs && (ti->incode < 0 || ti->constructed)) + { + xoff = 0; + yoff = 0; + + for (npcc = ti->pccs; npcc; npcc = npcc->next) + if (NULL != (api = findmappedadobe(npcc->partname, + fnt->inencptrs))) + if (api->outcode >= 0) + { + if (npcc->xoffset != xoff) + { + if (fnt->uppercase[i]) + { + voutln2("(MOVERIGHT R %.1f)", + fnt->capheight * (npcc->xoffset - xoff)); + } + else + voutln2("(MOVERIGHT R %d)", npcc->xoffset - xoff); + + xoff = npcc->xoffset; + } + + if (npcc->yoffset != yoff) + { + if (fnt->uppercase[i]) + { + voutln2("(MOVEUP R %.1f)", + fnt->capheight * (npcc->yoffset - yoff)); + } + else + voutln2("(MOVEUP R %d)", npcc->yoffset - yoff); + + yoff = npcc->yoffset; + } + + voutln2("(SETCHAR O %o)", (unsigned)api->incode); + xoff += fnt->outencptrs[api->outcode]->width; + } + } + else + voutln2("(SETCHAR O %o)", (unsigned)ti->incode); + vright(&level); + } + vright(&level); + } + + if (level) + oops("I forgot to match the parentheses."); +} + + +/* end */ diff --git a/contrib/ttf2pk/vplaux.h b/contrib/ttf2pk/vplaux.h new file mode 100644 index 0000000..f6281d8 --- /dev/null +++ b/contrib/ttf2pk/vplaux.h @@ -0,0 +1,23 @@ +/* + * vplaux.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef VPLAUX_H +#define VPLAUX_H + +#include "ttf2tfm.h" + + +void writevpl(Font *fnt, char makevpl, Boolean forceoctal); +void upmap(Font *fnt); + +#endif /* VPLAUX_H */ + + +/* end */ diff --git a/contrib/ttfbanner/.cvsignore b/contrib/ttfbanner/.cvsignore new file mode 100644 index 0000000..d0b8b54 --- /dev/null +++ b/contrib/ttfbanner/.cvsignore @@ -0,0 +1,2 @@ +ttfbanner +Makefile diff --git a/contrib/ttfbanner/Makefile.emx b/contrib/ttfbanner/Makefile.emx new file mode 100644 index 0000000..486e12d --- /dev/null +++ b/contrib/ttfbanner/Makefile.emx @@ -0,0 +1,9 @@ +# Makefile for ttfbanner + +all: ttfbanner.exe + +ttfbanner.exe: ttfbanner.o + gcc -O -o ttfbanner.exe ttfbanner.o -lttf + +ttfbanner.o: ttfbanner.c + gcc -O -c ttfbanner.c diff --git a/contrib/ttfbanner/Makefile.in b/contrib/ttfbanner/Makefile.in new file mode 100644 index 0000000..ef34d94 --- /dev/null +++ b/contrib/ttfbanner/Makefile.in @@ -0,0 +1,64 @@ +# Makefile for ttfbanner +# +# This Makefile assumes that you've already built and installed +# the FreeType library. + +VPATH = @srcdir@ +srcdir = @srcdir@ + +RM = @RM@ +RMF = @RM@ -f + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ + +CC = @CC@ +CPP = @CPP@ + +LIBTOOL = ../../libtool +MKINSTALLDIRS = $(srcdir)/../../mkinstalldirs + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +mandir = @mandir@ + +CFLAGS = @CFLAGS@ @XX_CFLAGS@ +CPPFLAGS = @CPPFLAGS@ @DEFS@ +FT_CFLAGS = $(CFLAGS) $(CPPFLAGS) +LDFLAGS = @LDFLAGS@ @LIBS@ +LIBDIR = ../../lib + +SRC = ttfbanner.c + +default all: ttfbanner + +ttfbanner: ttfbanner.o $(LIBDIR)/libttf.la + $(LIBTOOL) --mode=link $(CC) $(FT_CFLAGS) -o $@ $< \ + $(LIBDIR)/libttf.la $(LDFLAGS) + +clean: + $(RMF) *.o *BAK *CKP *~ a.out core + +realclean: clean + $(RMF) ttfbanner + $(RM) -rf .libs/ + +distclean: realclean + $(RMF) *~ *.orig core *.core + $(RMF) config.cache config.log config.status Makefile + +.c.o: + $(CC) -c $(FT_CFLAGS) $< + +install: ttfbanner + $(MKINSTALLDIRS) $(bindir) + $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) ttfbanner $(bindir)/ + +uninstall: + $(LIBTOOL) --mode=uninstall $(RM) $(bindir)/ttfbanner + +.PHONY: all clean realclean distclean install uninstall + +# end of Makefile diff --git a/contrib/ttfbanner/README b/contrib/ttfbanner/README new file mode 100644 index 0000000..62b260f --- /dev/null +++ b/contrib/ttfbanner/README @@ -0,0 +1,38 @@ +ttfbanner -- make posters using a TrueType font + +Installation +************ + +Say + + ./configure + make + make install + +It is assumed that you've built the FreeType library before. + +Usage +***** + +Just typing `ttfbanner' will provide you with some summary usage +instructions. + + +Limitations +*********** + +The program will not do any kerning. Incorrect UTF8 strings will not +always be detected. + + +Copying +******* + +This software is provided with no warranty whatsoever. You may do +whatever you wish with it as long as you don't ask me to maintain it. + + +Author +****** + +Juliusz Chroboczek diff --git a/contrib/ttfbanner/configure b/contrib/ttfbanner/configure new file mode 100644 index 0000000..c0e7f85 --- /dev/null +++ b/contrib/ttfbanner/configure @@ -0,0 +1,1372 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=../../lib/freetype.h + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + +# Do some error checking and defaulting for the host and target type. +# The inputs are: +# configure --host=HOST --target=TARGET --build=BUILD NONOPT +# +# The rules are: +# 1. You are not allowed to specify --host, --target, and nonopt at the +# same time. +# 2. Host defaults to nonopt. +# 3. If nonopt is not specified, then host defaults to the current host, +# as determined by config.guess. +# 4. Target and build default to nonopt. +# 5. If nonopt is not specified, then target and build default to host. + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +case $host---$target---$nonopt in +NONE---*---* | *---NONE---* | *---*---NONE) ;; +*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; +esac + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:573: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking target system type""... $ac_c" 1>&6 +echo "configure:594: checking target system type" >&5 + +target_alias=$target +case "$target_alias" in +NONE) + case $nonopt in + NONE) target_alias=$host_alias ;; + *) target_alias=$nonopt ;; + esac ;; +esac + +target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` +target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$target" 1>&6 + +echo $ac_n "checking build system type""... $ac_c" 1>&6 +echo "configure:612: checking build system type" >&5 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&6 + +test "$host_alias" != "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:638: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:668: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:719: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:751: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 762 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:767: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:793: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:798: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:826: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:858: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:879: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:896: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:913: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + + +OLDLIBS=$LIBS +LIBS="$LIBS -L../../lib/.libs" +CPPFLAGS="-I$srcdir/../../lib $CPPFLAGS" +echo $ac_n "checking for TT_Init_FreeType in -lttf""... $ac_c" 1>&6 +echo "configure:942: checking for TT_Init_FreeType in -lttf" >&5 +ac_lib_var=`echo ttf'_'TT_Init_FreeType | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lttf $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lttf" +else + echo "$ac_t""no" 1>&6 + + { echo "configure: error: Can't find ttf library! Compile FreeType first." 1>&2; exit 1; } +fi + +LIBS=$OLDLIBS + + +if test "x$CC" = xgcc; then + XX_CFLAGS="-Wall -ansi -pedantic" +else + case "$host" in + alpha-dec-osf*) + XX_CFLAGS="-std1 -O2 -g3" + ;; + *) + XX_CFLAGS= + ;; + esac +fi + + +# Extract the first word of "rm", so it can be a program name with args. +set dummy rm; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1003: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RM'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RM"; then + ac_cv_prog_RM="$RM" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RM="rm" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +RM="$ac_cv_prog_RM" +if test -n "$RM"; then + echo "$ac_t""$RM" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:1041: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@target@%$target%g +s%@target_alias@%$target_alias%g +s%@target_cpu@%$target_cpu%g +s%@target_vendor@%$target_vendor%g +s%@target_os@%$target_os%g +s%@build@%$build%g +s%@build_alias@%$build_alias%g +s%@build_cpu@%$build_cpu%g +s%@build_vendor@%$build_vendor%g +s%@build_os@%$build_os%g +s%@CC@%$CC%g +s%@CPP@%$CPP%g +s%@XX_CFLAGS@%$XX_CFLAGS%g +s%@RM@%$RM%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + + diff --git a/contrib/ttfbanner/configure.in b/contrib/ttfbanner/configure.in new file mode 100644 index 0000000..7859e0d --- /dev/null +++ b/contrib/ttfbanner/configure.in @@ -0,0 +1,38 @@ +dnl Process this file with autoconf to produce a configure script. + +AC_INIT(../../lib/freetype.h) + +AC_CANONICAL_SYSTEM + +AC_PROG_CC +AC_PROG_CPP + +OLDLIBS=$LIBS +LIBS="$LIBS -L../../lib/.libs" +CPPFLAGS="-I$srcdir/../../lib $CPPFLAGS" +AC_CHECK_LIB(ttf, TT_Init_FreeType, LIBS="$LIBS -lttf",[ + AC_MSG_ERROR([Can't find ttf library! Compile FreeType first.])]) +LIBS=$OLDLIBS + +dnl get Compiler flags right. + +if test "x$CC" = xgcc; then + XX_CFLAGS="-Wall -ansi -pedantic" +else + case "$host" in + alpha-dec-osf*) + XX_CFLAGS="-std1 -O2 -g3" + ;; + *) + XX_CFLAGS= + ;; + esac +fi +AC_SUBST(XX_CFLAGS) + +AC_CHECK_PROG(RM, rm, rm) +AC_PROG_INSTALL + +AC_OUTPUT(Makefile) + +dnl end of configure.in diff --git a/contrib/ttfbanner/ttfbanner.c b/contrib/ttfbanner/ttfbanner.c new file mode 100644 index 0000000..6d7bae4 --- /dev/null +++ b/contrib/ttfbanner/ttfbanner.c @@ -0,0 +1,320 @@ +/* This code was written by Juliusz Chroboczek . */ +/* It comes with no warranty whatsoever. */ +/* Feel free to use it as long as you don't ask me to maintain it. */ + +#include +#include +#include +#include +#include "freetype.h" +#include "ttfbanner.h" + +#define MAXIMIZE(x,xval) if((x)<(xval)) {x=(xval);} +#define MINIMIZE(x,xval) if((x)>(xval)) {x=(xval);} + +void +usage() +{ + fprintf(stderr, "Usage: ttfbanner [options] font.ttf string\n"); + fprintf(stderr, " where options include:\n"); + fprintf(stderr, " -e encoding: specify the encoding of the string (L1, L2 or UTF8, default L1)\n"); + fprintf(stderr, " -p pointsize: specify the point size to use (default 14)\n"); + fprintf(stderr, " -r resolution: specify x and y resolutions (default 72dpi)\n"); + fprintf(stderr, " -x resolution: specify x resolution\n"); + fprintf(stderr, " -y resolution: specify y resolution\n"); + exit(2); +} + +int +main(int argc, char **argv) +{ + int getopt(int argc, char * const argv[], const char *optstring); + extern char *optarg; + extern int optind; + int c; + + unsigned short *unicodeString=NULL; + enum {L1, L2, UTF8} encoding=L1; + double pointsize=14.0; + int xr=72, yr=72; + + TT_Raster_Map *raster; + + while((c=getopt(argc, argv, "s:e:p:r:x:y:"))!=EOF) { + switch(c) { + case 'e': + if(!strcmp(optarg,"L1")) + encoding=L1; + else if(!strcmp(optarg, "L2")) + encoding=L2; + else if(!strcmp(optarg, "UTF8")) + encoding=UTF8; + else { + fprintf(stderr, "Unknown encoding %s; defaulting to L1\n", optarg); + encoding=L1; + } + break; + case 'p': + pointsize=atof(optarg); + break; + case 'r': + xr=yr=atoi(optarg); + break; + case 'x': + xr=atoi(optarg); + break; + case 'y': + yr=atoi(optarg); + break; + default: + usage(); + } + } + + if(argc-optind!=2) + usage(); + + switch (encoding) + { + case L1: unicodeString=l1toUnicode(argv[optind+1]); + break; + case L2: unicodeString=l2toUnicode(argv[optind+1]); + break; + case UTF8: unicodeString=UTF8toUnicode(argv[optind+1]); + break; + default: Error("This cannot happen"); + } + + raster=makeBitmap(unicodeString, argv[optind], + pointsize, xr, yr); + writeBanner(raster); + + return 0; +} + +TT_Raster_Map * +makeBitmap(unsigned short *unicodeString, + char *ttf, double charsize, int xr, int yr) +{ + TT_Error error; + TT_Engine engine; + TT_Face face; + TT_Instance instance; + TT_Glyph glyph; + TT_Glyph_Metrics metrics; + TT_Raster_Map *raster; + TT_CharMap cmap; + + long xMin, xMax, yMin, yMax; + int xpos, xoffset, yoffset; + unsigned short *p; + int first; + short index; + + if((error=TT_Init_FreeType(&engine))) + FTError("Coudn't initialise FreeType engine", error); + if((error=TT_Open_Face(engine, ttf, &face))) + FTError("Coudn't open font file", error); + if((error=TT_New_Instance(face, &instance))) + FTError("Couldn't create new instance", error); + if((error=TT_Set_Instance_Resolutions(instance, xr, yr))) + FTError("Couldn't set resolutions", error); + if((error=TT_Set_Instance_CharSize(instance, (TT_F26Dot6)(charsize*64.0)))) + FTError("Coudn't set point size", error); + if((error=TT_New_Glyph(face, &glyph))) + FTError("Coudn't create glyph", error); + + if((error=find_unicode_cmap(face, &cmap))) + Error("Couldn't find suitable Cmap"); + + /* Compute size */ + xMin=yMin= 100000l; + xMax=yMax= -100000l; + for(p=unicodeString, first=1, xpos=0; (*p)!=0xFFFF; p++, first=0) { + index=TT_Char_Index(cmap, *p); + if((error=TT_Load_Glyph(instance, glyph, index, TTLOAD_DEFAULT))) + FTError("Couldn't load glyph", error); + if((error=TT_Get_Glyph_Metrics(glyph, &metrics))) + FTError("Couldn't get glyph metrics", error); + + if(first) + xMin=metrics.bbox.xMin; + xMax=xpos*64+metrics.bbox.xMax; + xpos+=(metrics.advance+32)/64; + + MAXIMIZE(yMax, metrics.bbox.yMax); + MINIMIZE(yMin, metrics.bbox.yMin); + } + + xoffset=-(xMin-63)/64; + yoffset=-(yMin-63)/64; + + if((raster=malloc(sizeof(TT_Raster_Map)))==NULL) + Error("Couldn't allocate raster structure"); + raster->rows=(yMax+63)/64+yoffset; + raster->width=(xMax+63)/64+xoffset; + raster->cols=(raster->width+7)/8; + raster->flow=TT_Flow_Down; + if((raster->bitmap=calloc(raster->cols, raster->rows))==NULL) + Error("Couldn't allocate bitmap"); + raster->size=((long)raster->rows*raster->cols); + + + for(p=unicodeString, xpos=xoffset; *p!=0xFFFF; p++) { + index=TT_Char_Index(cmap, *p); + if((error=TT_Load_Glyph(instance, glyph, index, TTLOAD_DEFAULT))) + FTError("Couldn't load glyph", error); + if((error=TT_Get_Glyph_Metrics(glyph, &metrics))) + FTError("Couldn't get glyph metrics", error); + + if((error=TT_Get_Glyph_Bitmap(glyph, raster, xpos*64, yoffset*64))) + FTError("Couldn't typeset glyph", error); + xpos+=(metrics.advance+32)/64; + } + + return raster; +} + +int +find_unicode_cmap(TT_Face face, TT_CharMap *cmap) +{ + int i,n; + unsigned short p,e; + + n=TT_Get_CharMap_Count(face); + for(i=0; irows; i++) { + int j; + for(j=0; jwidth; j++) { + if(((((unsigned char*)raster->bitmap)+i*raster->cols)[j/8]&(1<<(7-j%8))) + != 0) + putchar('*'); + else + putchar(' '); + } + putchar('\n'); + } +} + +unsigned short * +l1toUnicode(char *string) +{ + unsigned short *r; + int n,i; + + n=strlen(string); + if((r=malloc(sizeof(unsigned short)*(n+1)))==NULL) + Error("Couldn't allocate string"); + + for(i=0; i +#include +#include +#include + +#include + +#include "freetype.h" +#include "gdriver.h" + +HANDLE evgetevent,evdriverdisplaybitmap,this_wnd,main_thread,listbox,bitmap; +TEvent evevent; +char message_32[256]; +char *ev_buffer; +jmp_buf Env; +long TTMemory_Allocated = 0; // just to have a clean link with ftdump +// save last rendered image Data +int save_lines,save_cols,exit_code; +char *save_buffer; +extern int vio_Width,vio_Height,vio_ScanLineWidth; +extern TT_Raster_Map Bit; +HDC hdc,memdc; +HBITMAP hbm,hbm1; + +//________________________________________________________________________________ +void Get_Event(TEvent *event) +{ + WaitForSingleObject(evgetevent,INFINITE); // wait for completion + *event=evevent; //set by message handler before posting waited upon event + return; +} + +int Driver_Set_Graphics( int mode ) +{ RECT rect; + GetClientRect(bitmap,&rect); + vio_Width=rect.right-rect.left; + vio_Height = rect.bottom-rect.top; + vio_ScanLineWidth=vio_Width; + return 1; + + } +int Driver_Restore_Mode() +{return 1;} + +int Driver_Display_Bitmap( char* buffer, int lines, int cols ) + { + long rc; + int i; + char *top,*bottom; + HANDLE rgdi; + RECT rect; + char *w_buffer; +// bitmap=listbox; + hdc=GetDC(bitmap); + memdc=CreateCompatibleDC(hdc); + GetClientRect(bitmap,&rect); + //hbm=CreateCompatibleBitmap(hdc,lines,cols); + // need to set upside down bitmap . + if (buffer != save_buffer) //new buffer + { + if (save_buffer!=NULL) + free(save_buffer); + save_buffer=(char *)malloc(Bit.size); + memcpy(save_buffer,buffer,Bit.size); + } + w_buffer=malloc(Bit.size); // hope it succeeds + top=buffer; + bottom=w_buffer+Bit.size-cols; + for(i=0;i diff --git a/contrib/win32/hack_ftdump.c b/contrib/win32/hack_ftdump.c new file mode 100644 index 0000000..4a673a2 --- /dev/null +++ b/contrib/win32/hack_ftdump.c @@ -0,0 +1,9 @@ +/*********************************************************/ +/* Test program driver for freetype on Win32 Platform */ +/* CopyRight(left) G. Ramat 1998 (gcramat@radiostudio.it)*/ +/* */ +/*********************************************************/ + +#define exit(code) force_exit(code) +#define main(A,B) ftdump(A,B) +#include diff --git a/contrib/win32/hack_ftlint.c b/contrib/win32/hack_ftlint.c new file mode 100644 index 0000000..bee2d3f --- /dev/null +++ b/contrib/win32/hack_ftlint.c @@ -0,0 +1,9 @@ +/*********************************************************/ +/* Test program driver for freetype on Win32 Platform */ +/* CopyRight(left) G. Ramat 1998 (gcramat@radiostudio.it)*/ +/* */ +/*********************************************************/ + +#define exit(code) force_exit(code) +#define main(A,B) ftlint(A,B) +#include diff --git a/contrib/win32/hack_ftstring.c b/contrib/win32/hack_ftstring.c new file mode 100644 index 0000000..ac248aa --- /dev/null +++ b/contrib/win32/hack_ftstring.c @@ -0,0 +1,9 @@ +/*********************************************************/ +/* Test program driver for freetype on Win32 Platform */ +/* CopyRight(left) G. Ramat 1998 (gcramat@radiostudio.it)*/ +/* */ +/*********************************************************/ + +#define exit(code) force_exit(code) +#define main(A,B) ftstring(A,B) +#include diff --git a/contrib/win32/hack_fttimer.c b/contrib/win32/hack_fttimer.c new file mode 100644 index 0000000..d575d0c --- /dev/null +++ b/contrib/win32/hack_fttimer.c @@ -0,0 +1,9 @@ +/*********************************************************/ +/* Test program driver for freetype on Win32 Platform */ +/* CopyRight(left) G. Ramat 1998 (gcramat@radiostudio.it)*/ +/* */ +/*********************************************************/ + +#define exit(code) force_exit(code) +#define main(A,B) fttimer(A,B) +#include diff --git a/contrib/win32/hack_ftview.c b/contrib/win32/hack_ftview.c new file mode 100644 index 0000000..17cd957 --- /dev/null +++ b/contrib/win32/hack_ftview.c @@ -0,0 +1,9 @@ +/*********************************************************/ +/* Test program driver for freetype on Win32 Platform */ +/* CopyRight(left) G. Ramat 1998 (gcramat@radiostudio.it)*/ +/* */ +/*********************************************************/ + +#define exit(code) force_exit(code) +#define main(A,B) ftview(A,B) +#include diff --git a/contrib/win32/readme.txt b/contrib/win32/readme.txt new file mode 100644 index 0000000..fb8ca9c --- /dev/null +++ b/contrib/win32/readme.txt @@ -0,0 +1,19 @@ +The purpose of this application is to serve as a running environment for +some of the freetype project test programs: +currently available programa aree ftdump,ftlint,,ftstring,ftview; +others may be convinced to run but you may need to change the source +code to avoid duplicate problems with the linker. +This work has been based on a large amount of guesswork +and a small amount of my (little) spare time; +however it seems to be working pretty well as far as I can tell +( -g -r options are not working but I don't care 'bout them). +It can be compiled both under MS VC++ Version 4.X and Version 5. +and has been tested under Windows 95 & NT 4.0 . + +Have Fun . + Giancarlo Ramat + (gcramat@radiostudio.it) + +[Please note that all files are archived in Unix LF format (except +testw32.mdp which is a binary file). If necessary, use e.g. unzip's `-a' +flag to convert to MSDOS CR/LF convention.] diff --git a/contrib/win32/res/testw32.ico b/contrib/win32/res/testw32.ico new file mode 100644 index 0000000..7eef0bc Binary files /dev/null and b/contrib/win32/res/testw32.ico differ diff --git a/contrib/win32/res/testw32.rc2 b/contrib/win32/res/testw32.rc2 new file mode 100644 index 0000000..c81f594 --- /dev/null +++ b/contrib/win32/res/testw32.rc2 @@ -0,0 +1,13 @@ +// +// TESTW32.RC2 - resources Microsoft Visual C++ does not edit directly +// + +#ifdef APSTUDIO_INVOKED + #error this file is not editable by Microsoft Visual C++ +#endif //APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// Add manually edited resources here... + +///////////////////////////////////////////////////////////////////////////// diff --git a/contrib/win32/resource.h b/contrib/win32/resource.h new file mode 100644 index 0000000..1c284d7 --- /dev/null +++ b/contrib/win32/resource.h @@ -0,0 +1,24 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by testw32.rc +// +#define IDD_TESTW32_DIALOG 102 +#define IDR_MAINFRAME 128 +#define IDC_FONT_NAME 1000 +#define IDC_BITMAP 1001 +#define IDC_LIST_BOX 1002 +#define IDC_SELECT_ACTION 1003 +#define IDC_ACTION 1004 +#define IDC_TEST_PROGRAM 1005 +#define IDC_OPTIONS 1007 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 130 +#define _APS_NEXT_COMMAND_VALUE 32771 +#define _APS_NEXT_CONTROL_VALUE 1008 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/contrib/win32/stdafx.cpp b/contrib/win32/stdafx.cpp new file mode 100644 index 0000000..06d180b --- /dev/null +++ b/contrib/win32/stdafx.cpp @@ -0,0 +1,6 @@ +// stdafx.cpp : source file that includes just the standard includes +// testw32.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/contrib/win32/stdafx.h b/contrib/win32/stdafx.h new file mode 100644 index 0000000..80d2b6f --- /dev/null +++ b/contrib/win32/stdafx.h @@ -0,0 +1,25 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__70F52CAD_06A4_11D2_9AC4_0060978849F3__INCLUDED_) +#define AFX_STDAFX_H__70F52CAD_06A4_11D2_9AC4_0060978849F3__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__70F52CAD_06A4_11D2_9AC4_0060978849F3__INCLUDED_) diff --git a/contrib/win32/testw32.cpp b/contrib/win32/testw32.cpp new file mode 100644 index 0000000..4b1ddde --- /dev/null +++ b/contrib/win32/testw32.cpp @@ -0,0 +1,79 @@ +/*********************************************************/ +/* Test program driver for freetype on Win32 Platform */ +/* CopyRight(left) G. Ramat 1998 (gcramat@radiostudio.it)*/ +/* */ +/*********************************************************/ + +// testw32.cpp : Defines the class behaviors for the application. +// + +#include "stdafx.h" +#include "testw32.h" +#include "testw32dlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CTestw32App + +BEGIN_MESSAGE_MAP(CTestw32App, CWinApp) + //{{AFX_MSG_MAP(CTestw32App) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG + ON_COMMAND(ID_HELP, CWinApp::OnHelp) +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CTestw32App construction + +CTestw32App::CTestw32App() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CTestw32App object + +CTestw32App theApp; + +///////////////////////////////////////////////////////////////////////////// +// CTestw32App initialization + +BOOL CTestw32App::InitInstance() +{ + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + + CTestw32Dlg dlg; + m_pMainWnd = &dlg; + int nResponse = dlg.DoModal(); + if (nResponse == IDOK) + { + // TODO: Place code here to handle when the dialog is + // dismissed with OK + } + else if (nResponse == IDCANCEL) + { + // TODO: Place code here to handle when the dialog is + // dismissed with Cancel + } + + // Since the dialog has been closed, return FALSE so that we exit the + // application, rather than start the application's message pump. + return FALSE; +} + +BOOL CTestw32App::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) +{ + // TODO: Add your specialized code here and/or call the base class + + return CWinApp::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo); +} diff --git a/contrib/win32/testw32.dsp b/contrib/win32/testw32.dsp new file mode 100644 index 0000000..b1cafb6 --- /dev/null +++ b/contrib/win32/testw32.dsp @@ -0,0 +1,190 @@ +# Microsoft Developer Studio Project File - Name="testw32" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=testw32 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "testw32.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "testw32.mak" CFG="testw32 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "testw32 - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "testw32 - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "testw32 - Win32 Release" + +# PROP BASE Use_MFC 6 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 6 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +# ADD BASE RSC /l 0x410 /d "NDEBUG" /d "_AFXDLL" +# ADD RSC /l 0x410 /d "NDEBUG" /d "_AFXDLL" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386 +# ADD LINK32 /nologo /subsystem:windows /machine:I386 + +!ELSEIF "$(CFG)" == "testw32 - Win32 Debug" + +# PROP BASE Use_MFC 6 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 6 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /G5 /MDd /W3 /Gm /Zi /Od /I "../../../LIB" /I "../" /I "../../../lib/arch/win32" /I "../../" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "WIN32_GR_TEST" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 +# ADD BASE RSC /l 0x410 /d "_DEBUG" /d "_AFXDLL" +# ADD RSC /l 0x410 /d "_DEBUG" /d "_AFXDLL" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 freetype.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\lib\arch\win32\release" /libpath:"..\..\..\lib\arch\win32\debug" /FORCE:MULTIPLE /FORCE:UNRESOLVED +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "testw32 - Win32 Release" +# Name "testw32 - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\display.c +# End Source File +# Begin Source File + +SOURCE=.\driver32.c +# End Source File +# Begin Source File + +SOURCE=..\..\gmain.c +# End Source File +# Begin Source File + +SOURCE=.\hack_common.c +# End Source File +# Begin Source File + +SOURCE=.\hack_ftdump.c +# End Source File +# Begin Source File + +SOURCE=.\hack_ftlint.c +# End Source File +# Begin Source File + +SOURCE=.\hack_ftstring.c +# End Source File +# Begin Source File + +SOURCE=.\hack_fttimer.c +# End Source File +# Begin Source File + +SOURCE=.\hack_ftview.c +# End Source File +# Begin Source File + +SOURCE=.\stdafx.cpp +# ADD CPP /Yc"stdafx.h" +# End Source File +# Begin Source File + +SOURCE=.\testw32.cpp +# End Source File +# Begin Source File + +SOURCE=.\testw32.rc + +!IF "$(CFG)" == "testw32 - Win32 Release" + +!ELSEIF "$(CFG)" == "testw32 - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\testw32dlg.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\Resource.h +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# Begin Source File + +SOURCE=.\testw32.h +# End Source File +# Begin Source File + +SOURCE=.\testw32Dlg.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\res\testw32.ico +# End Source File +# Begin Source File + +SOURCE=.\res\testw32.rc2 +# End Source File +# End Group +# Begin Source File + +SOURCE=.\ReadMe.txt +# End Source File +# End Target +# End Project diff --git a/contrib/win32/testw32.dsw b/contrib/win32/testw32.dsw new file mode 100644 index 0000000..d2774c4 --- /dev/null +++ b/contrib/win32/testw32.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "testw32"=.\testw32.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/contrib/win32/testw32.h b/contrib/win32/testw32.h new file mode 100644 index 0000000..727b11f --- /dev/null +++ b/contrib/win32/testw32.h @@ -0,0 +1,50 @@ +// testw32.h : main header file for the TESTW32 application +// + +#if !defined(AFX_TESTW32_H__70F52CA9_06A4_11D2_9AC4_0060978849F3__INCLUDED_) +#define AFX_TESTW32_H__70F52CA9_06A4_11D2_9AC4_0060978849F3__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// CTestw32App: +// See testw32.cpp for the implementation of this class +// + +class CTestw32App : public CWinApp +{ +public: + CTestw32App(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CTestw32App) + public: + virtual BOOL InitInstance(); + virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo); + //}}AFX_VIRTUAL + +// Implementation + + //{{AFX_MSG(CTestw32App) + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_TESTW32_H__70F52CA9_06A4_11D2_9AC4_0060978849F3__INCLUDED_) diff --git a/contrib/win32/testw32.mak b/contrib/win32/testw32.mak new file mode 100644 index 0000000..636caa2 --- /dev/null +++ b/contrib/win32/testw32.mak @@ -0,0 +1,533 @@ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +!IF "$(CFG)" == "" +CFG=testw32 - Win32 Debug +!MESSAGE No configuration specified. Defaulting to testw32 - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "testw32 - Win32 Release" && "$(CFG)" !=\ + "testw32 - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "testw32.mak" CFG="testw32 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "testw32 - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "testw32 - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "testw32 - Win32 Debug" +MTL=mktyplib.exe +RSC=rc.exe +CPP=cl.exe + +!IF "$(CFG)" == "testw32 - Win32 Release" + +# PROP BASE Use_MFC 6 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 6 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +OUTDIR=.\Release +INTDIR=.\Release + +ALL : "$(OUTDIR)\testw32.exe" "$(OUTDIR)\testw32.pch" + +CLEAN : + -@erase ".\Release\testw32.pch" + -@erase ".\Release\testw32.exe" + -@erase ".\Release\hack_ftview.obj" + -@erase ".\Release\testw32.obj" + -@erase ".\Release\hack_fttimer.obj" + -@erase ".\Release\hack_common.obj" + -@erase ".\Release\driver32.obj" + -@erase ".\Release\stdafx.obj" + -@erase ".\Release\hack_ftlint.obj" + -@erase ".\Release\testw32dlg.obj" + -@erase ".\Release\gmain.obj" + -@erase ".\Release\hack_ftdump.obj" + -@erase ".\Release\hack_ftstring.obj" + -@erase ".\Release\display.obj" + -@erase ".\Release\testw32.res" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\lib" /I "..\..\" /I "..\..\..\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /YX"stdafx.h" /c +CPP_PROJ=/nologo /MD /W3 /GX /O2 /I "..\..\..\lib" /I "..\..\" /I "..\..\..\"\ + /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS"\ + /Fp"$(INTDIR)/testw32.pch" /YX"stdafx.h" /Fo"$(INTDIR)/" /c +CPP_OBJS=.\Release/ +CPP_SBRS= +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +# ADD BASE RSC /l 0x410 /d "NDEBUG" /d "_AFXDLL" +# ADD RSC /l 0x410 /d "NDEBUG" /d "_AFXDLL" +RSC_PROJ=/l 0x410 /fo"$(INTDIR)/testw32.res" /d "NDEBUG" /d "_AFXDLL" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/testw32.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386 +# ADD LINK32 freetype.lib /nologo /subsystem:windows /machine:I386 +LINK32_FLAGS=freetype.lib /nologo /subsystem:windows /incremental:no\ + /pdb:"$(OUTDIR)/testw32.pdb" /machine:I386 /out:"$(OUTDIR)/testw32.exe" +LINK32_OBJS= \ + "$(INTDIR)/hack_ftview.obj" \ + "$(INTDIR)/testw32.obj" \ + "$(INTDIR)/hack_fttimer.obj" \ + "$(INTDIR)/hack_common.obj" \ + "$(INTDIR)/driver32.obj" \ + "$(INTDIR)/stdafx.obj" \ + "$(INTDIR)/hack_ftlint.obj" \ + "$(INTDIR)/testw32dlg.obj" \ + "$(INTDIR)/gmain.obj" \ + "$(INTDIR)/hack_ftdump.obj" \ + "$(INTDIR)/hack_ftstring.obj" \ + "$(INTDIR)/display.obj" \ + "$(INTDIR)/testw32.res" + +"$(OUTDIR)\testw32.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "testw32 - Win32 Debug" + +# PROP BASE Use_MFC 6 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 6 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +OUTDIR=.\Debug +INTDIR=.\Debug + +ALL : "$(OUTDIR)\testw32.exe" "$(OUTDIR)\testw32.pch" + +CLEAN : + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + -@erase ".\Debug\testw32.pch" + -@erase ".\Debug\testw32.exe" + -@erase ".\Debug\stdafx.obj" + -@erase ".\Debug\display.obj" + -@erase ".\Debug\hack_ftlint.obj" + -@erase ".\Debug\hack_fttimer.obj" + -@erase ".\Debug\hack_ftdump.obj" + -@erase ".\Debug\driver32.obj" + -@erase ".\Debug\hack_ftview.obj" + -@erase ".\Debug\testw32dlg.obj" + -@erase ".\Debug\testw32.obj" + -@erase ".\Debug\gmain.obj" + -@erase ".\Debug\hack_ftstring.obj" + -@erase ".\Debug\hack_common.obj" + -@erase ".\Debug\testw32.res" + -@erase ".\Debug\testw32.ilk" + -@erase ".\Debug\testw32.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "c:\winlib\freetype.orig\test" /I "..\..\..\lib" /I "..\..\..\lib\arch\win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /YX"stdafx.h" /c +CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /I "c:\winlib\freetype.orig\test" /I\ + "..\..\..\lib" /I "..\..\..\lib\arch\win32" /D "WIN32" /D "_DEBUG" /D\ + "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Fp"$(INTDIR)/testw32.pch" /YX"stdafx.h"\ + /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /win32 +MTL_PROJ=/nologo /D "_DEBUG" /win32 +# ADD BASE RSC /l 0x410 /d "_DEBUG" /d "_AFXDLL" +# ADD RSC /l 0x410 /d "_DEBUG" /d "_AFXDLL" +RSC_PROJ=/l 0x410 /fo"$(INTDIR)/testw32.res" /d "_DEBUG" /d "_AFXDLL" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/testw32.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 +# ADD LINK32 ..\..\..\lib\arch\win32\debug\freetype.lib /nologo /subsystem:windows /debug /machine:I386 +LINK32_FLAGS=..\..\..\lib\arch\win32\debug\freetype.lib /nologo\ + /subsystem:windows /incremental:yes /pdb:"$(OUTDIR)/testw32.pdb" /debug\ + /machine:I386 /out:"$(OUTDIR)/testw32.exe" +LINK32_OBJS= \ + "$(INTDIR)/stdafx.obj" \ + "$(INTDIR)/display.obj" \ + "$(INTDIR)/hack_ftlint.obj" \ + "$(INTDIR)/hack_fttimer.obj" \ + "$(INTDIR)/hack_ftdump.obj" \ + "$(INTDIR)/driver32.obj" \ + "$(INTDIR)/hack_ftview.obj" \ + "$(INTDIR)/testw32dlg.obj" \ + "$(INTDIR)/testw32.obj" \ + "$(INTDIR)/gmain.obj" \ + "$(INTDIR)/hack_ftstring.obj" \ + "$(INTDIR)/hack_common.obj" \ + "$(INTDIR)/testw32.res" + +"$(OUTDIR)\testw32.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Target + +# Name "testw32 - Win32 Release" +# Name "testw32 - Win32 Debug" + +!IF "$(CFG)" == "testw32 - Win32 Release" + +!ELSEIF "$(CFG)" == "testw32 - Win32 Debug" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\ReadMe.txt + +!IF "$(CFG)" == "testw32 - Win32 Release" + +!ELSEIF "$(CFG)" == "testw32 - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\testw32.cpp +DEP_CPP_TESTW=\ + ".\stdafx.h"\ + ".\testw32.h"\ + ".\testw32dlg.h"\ + + +"$(INTDIR)\testw32.obj" : $(SOURCE) $(DEP_CPP_TESTW) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\testw32dlg.cpp +DEP_CPP_TESTW3=\ + ".\stdafx.h"\ + ".\testw32.h"\ + ".\testw32dlg.h"\ + ".\..\..\gdriver.h"\ + ".\..\..\gevents.h"\ + + +"$(INTDIR)\testw32dlg.obj" : $(SOURCE) $(DEP_CPP_TESTW3) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\stdafx.cpp +DEP_CPP_STDAF=\ + ".\stdafx.h"\ + + +!IF "$(CFG)" == "testw32 - Win32 Release" + +# ADD CPP /Yc"stdafx.h" + +BuildCmds= \ + $(CPP) /nologo /MD /W3 /GX /O2 /I "..\..\..\lib" /I "..\..\" /I "..\..\..\" /D\ + "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS"\ + /Fp"$(INTDIR)/testw32.pch" /Yc"stdafx.h" /Fo"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\stdafx.obj" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\testw32.pch" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "testw32 - Win32 Debug" + +# ADD CPP /Yc"stdafx.h" + +BuildCmds= \ + $(CPP) /nologo /MDd /W3 /Gm /GX /Zi /Od /I "c:\winlib\freetype.orig\test" /I\ + "..\..\..\lib" /I "..\..\..\lib\arch\win32" /D "WIN32" /D "_DEBUG" /D\ + "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Fp"$(INTDIR)/testw32.pch" /Yc"stdafx.h"\ + /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\stdafx.obj" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\testw32.pch" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)" + $(BuildCmds) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\testw32.rc +DEP_RSC_TESTW32=\ + ".\res\testw32.ico"\ + ".\res\testw32.rc2"\ + + +"$(INTDIR)\testw32.res" : $(SOURCE) $(DEP_RSC_TESTW32) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\hack_ftview.c +DEP_CPP_HACK_=\ + ".\..\..\ftview.c"\ + ".\..\..\..\lib\freetype.h"\ + ".\..\..\common.h"\ + ".\..\..\gmain.h"\ + ".\..\..\gevents.h"\ + ".\..\..\gdriver.h"\ + ".\..\..\display.h"\ + "..\..\..\lib\fterrid.h"\ + "..\..\..\lib\ftnameid.h"\ + +NODEP_CPP_HACK_=\ + ".\..\..\std.h"\ + ".\..\..\graflink.h"\ + ".\..\..\armsup.c"\ + + +"$(INTDIR)\hack_ftview.obj" : $(SOURCE) $(DEP_CPP_HACK_) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\hack_common.c +DEP_CPP_HACK_C=\ + ".\..\..\common.c"\ + ".\..\..\common.h"\ + + +"$(INTDIR)\hack_common.obj" : $(SOURCE) $(DEP_CPP_HACK_C) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\hack_ftdump.c + +!IF "$(CFG)" == "testw32 - Win32 Release" + +DEP_CPP_HACK_F=\ + ".\..\..\ftdump.c"\ + ".\..\..\..\lib\freetype.h"\ + ".\..\..\common.h"\ + ".\..\..\..\lib\ttobjs.h"\ + "..\..\..\lib\fterrid.h"\ + "..\..\..\lib\ftnameid.h"\ + ".\..\..\..\lib\ttconfig.h"\ + ".\..\..\..\lib\ttengine.h"\ + ".\..\..\..\lib\ttmutex.h"\ + ".\..\..\..\lib\ttcache.h"\ + ".\..\..\..\lib\tttables.h"\ + ".\..\..\..\lib\ttcmap.h"\ + ".\..\..\..\lib\tttypes.h"\ + +NODEP_CPP_HACK_F=\ + ".\..\..\std.h"\ + ".\..\..\graflink.h"\ + ".\..\..\armsup.c"\ + ".\..\..\ftxerr18.h"\ + ".\..\..\..\lib\ft_conf.h"\ + + +"$(INTDIR)\hack_ftdump.obj" : $(SOURCE) $(DEP_CPP_HACK_F) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "testw32 - Win32 Debug" + +DEP_CPP_HACK_F=\ + ".\..\..\ftdump.c"\ + + +"$(INTDIR)\hack_ftdump.obj" : $(SOURCE) $(DEP_CPP_HACK_F) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\hack_ftlint.c +DEP_CPP_HACK_FT=\ + ".\..\..\ftlint.c"\ + ".\..\..\..\lib\freetype.h"\ + "..\..\..\lib\fterrid.h"\ + "..\..\..\lib\ftnameid.h"\ + +NODEP_CPP_HACK_FT=\ + ".\..\..\std.h"\ + ".\..\..\graflink.h"\ + ".\..\..\armsup.c"\ + ".\..\..\ftxerr18.h"\ + + +"$(INTDIR)\hack_ftlint.obj" : $(SOURCE) $(DEP_CPP_HACK_FT) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\hack_ftstring.c +DEP_CPP_HACK_FTS=\ + ".\..\..\ftstring.c"\ + ".\..\..\..\lib\freetype.h"\ + ".\..\..\common.h"\ + ".\..\..\gmain.h"\ + ".\..\..\gevents.h"\ + ".\..\..\gdriver.h"\ + ".\..\..\display.h"\ + "..\..\..\lib\fterrid.h"\ + "..\..\..\lib\ftnameid.h"\ + +NODEP_CPP_HACK_FTS=\ + ".\..\..\std.h"\ + ".\..\..\graflink.h"\ + ".\..\..\armsup.c"\ + + +"$(INTDIR)\hack_ftstring.obj" : $(SOURCE) $(DEP_CPP_HACK_FTS) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\hack_fttimer.c +DEP_CPP_HACK_FTT=\ + ".\..\..\fttimer.c"\ + ".\..\..\..\lib\freetype.h"\ + ".\..\..\common.h"\ + ".\..\..\gmain.h"\ + ".\..\..\gdriver.h"\ + ".\..\..\gevents.h"\ + "..\..\..\lib\fterrid.h"\ + "..\..\..\lib\ftnameid.h"\ + + +"$(INTDIR)\hack_fttimer.obj" : $(SOURCE) $(DEP_CPP_HACK_FTT) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\driver32.c +DEP_CPP_DRIVE=\ + ".\..\..\gdriver.h"\ + ".\..\..\..\lib\freetype.h"\ + "..\..\..\lib\fterrid.h"\ + "..\..\..\lib\ftnameid.h"\ + + +"$(INTDIR)\driver32.obj" : $(SOURCE) $(DEP_CPP_DRIVE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=\winlib\freetype.orig\test\gmain.c +DEP_CPP_GMAIN=\ + ".\..\..\gmain.h"\ + ".\..\..\gdriver.h"\ + + +"$(INTDIR)\gmain.obj" : $(SOURCE) $(DEP_CPP_GMAIN) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=\winlib\freetype.orig\test\display.c +DEP_CPP_DISPL=\ + ".\..\..\..\lib\freetype.h"\ + ".\..\..\gmain.h"\ + ".\..\..\display.h"\ + "..\..\..\lib\fterrid.h"\ + "..\..\..\lib\ftnameid.h"\ + + +"$(INTDIR)\display.obj" : $(SOURCE) $(DEP_CPP_DISPL) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +# End Target +# End Project +################################################################################ diff --git a/contrib/win32/testw32.mdp b/contrib/win32/testw32.mdp new file mode 100644 index 0000000..51d0519 Binary files /dev/null and b/contrib/win32/testw32.mdp differ diff --git a/contrib/win32/testw32.rc b/contrib/win32/testw32.rc new file mode 100644 index 0000000..5d6cd03 --- /dev/null +++ b/contrib/win32/testw32.rc @@ -0,0 +1,202 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Italian (Italy) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ITA) +#ifdef _WIN32 +LANGUAGE LANG_ITALIAN, SUBLANG_ITALIAN +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "#define _AFX_NO_SPLITTER_RESOURCES\r\n" + "#define _AFX_NO_OLE_RESOURCES\r\n" + "#define _AFX_NO_TRACKER_RESOURCES\r\n" + "#define _AFX_NO_PROPERTY_RESOURCES\r\n" + "\r\n" + "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ITA)\r\n" + "#ifdef _WIN32\r\n" + "LANGUAGE 16, 1\r\n" + "#pragma code_page(1252)\r\n" + "#endif\r\n" + "#include ""res\\testw32.rc2"" // non-Microsoft Visual C++ edited resources\r\n" + "#include ""l.ita\\afxres.rc"" // Standard components\r\n" + "#endif\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDR_MAINFRAME ICON DISCARDABLE "res\\testw32.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_TESTW32_DIALOG DIALOGEX 0, 0, 331, 274 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_APPWINDOW +CAPTION "testw32" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "Run",IDOK,105,100,28,14 + PUSHBUTTON "Exit",IDCANCEL,105,116,28,14 + CONTROL "",IDC_BITMAP,"Static",SS_BLACKRECT,146,47,178,120 + LISTBOX IDC_LIST_BOX,7,171,317,97,LBS_NOINTEGRALHEIGHT | + WS_VSCROLL | WS_HSCROLL | WS_TABSTOP + PUSHBUTTON "<-Select Action (q to quit test pgm)",IDC_SELECT_ACTION, + 34,56,110,15 + EDITTEXT IDC_ACTION,23,56,9,12,ES_AUTOHSCROLL + COMBOBOX IDC_TEST_PROGRAM,13,12,90,64,CBS_DROPDOWN | CBS_SORT | + WS_VSCROLL | WS_TABSTOP + LTEXT "Test Program",IDC_STATIC,13,1,60,8 + EDITTEXT IDC_OPTIONS,111,12,204,12,ES_AUTOHSCROLL + LTEXT "Options/Arguments",IDC_STATIC,109,2,73,8 + LTEXT "Show Window",IDC_STATIC,146,37,70,8 +END + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "041004B0" + BEGIN + VALUE "CompanyName", "\0" + VALUE "FileDescription", "testw32 Applicazione MFC\0" + VALUE "FileVersion", "1, 0, 0, 1\0" + VALUE "InternalName", "testw32\0" + VALUE "LegalCopyright", "Copyright (C) 1998\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "testw32.EXE\0" + VALUE "ProductName", "testw32 Applicazione\0" + VALUE "ProductVersion", "1, 0, 0, 1\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x410, 1200 + END +END + +#endif // !_MAC + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_TESTW32_DIALOG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 324 + BOTTOMMARGIN, 268 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog Info +// + +IDD_TESTW32_DIALOG DLGINIT +BEGIN + IDC_TEST_PROGRAM, 0x403, 7, 0 +0x5446, 0x4956, 0x5745, "\000" + IDC_TEST_PROGRAM, 0x403, 7, 0 +0x5446, 0x5544, 0x504d, "\000" + IDC_TEST_PROGRAM, 0x403, 9, 0 +0x5446, 0x5453, 0x4952, 0x474e, "\000" + IDC_TEST_PROGRAM, 0x403, 7, 0 +0x5446, 0x494c, 0x544e, "\000" + 0 +END + +#endif // Italian (Italy) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#define _AFX_NO_SPLITTER_RESOURCES +#define _AFX_NO_OLE_RESOURCES +#define _AFX_NO_TRACKER_RESOURCES +#define _AFX_NO_PROPERTY_RESOURCES + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ITA) +#ifdef _WIN32 +LANGUAGE 16, 1 +#pragma code_page(1252) +#endif +#include "res\testw32.rc2" // non-Microsoft Visual C++ edited resources +#include "l.ita\afxres.rc" // Standard components +#endif +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/contrib/win32/testw32dlg.cpp b/contrib/win32/testw32dlg.cpp new file mode 100644 index 0000000..c3f4660 --- /dev/null +++ b/contrib/win32/testw32dlg.cpp @@ -0,0 +1,358 @@ +/*********************************************************/ +/* Test program driver for freetype on Win32 Platform */ +/* CopyRight(left) G. Ramat 1998 (gcramat@radiostudio.it)*/ +/* */ +/*********************************************************/ + +// testw32Dlg.cpp : implementation file +// + +#include "stdafx.h" +#include "testw32.h" +#include "testw32dlg.h" +#include "gdriver.h" +#include "gevents.h" +#include +#include +#include +CWnd *button_OK,*button_Cancel; +DWORD thrd_spool; // output spooler +HANDLE spool_thread; + +//Sync data: +extern "C" { + HANDLE evgetevent,evdriverdisplaybitmap,this_cwnd,main_thread,listbox,bitmap; + TEvent evevent; + char *ev_buffer; + int ev_lines,ev_columns; + char *save_buffer; + int save_lines,save_cols,exit_code; + int ftview(int,char**); + int ftdump(int,char**); + int ftlint(int,char**); + int ftstring(int,char**); + int ftstrpnm(int,char**); + int ftzoom(int,char**); + int call_test_program(int (*)(int,char**),int,char **); + +} +//pipe handling variables +int pipe_std[2]={2*0},pipe_err[2]={2*0},error; +int old_std,old_err; +//end of pipe handling variables + + +#define TEST_PROG_N 4 +//Sync data end +char ProgramName[16]; +char fontname[16]; +char fullfont[MAX_PATH]; +char *argv[255]; +int argc; +DWORD WINAPI ThreadHead(LPVOID ); +DWORD WINAPI ThreadSpool(LPVOID ); +void readpipe(int); + + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif +extern main(int,char **); +extern int X_Link; + +///////////////////////////////////////////////////////////////////////////// +// CTestw32Dlg dialog + +CTestw32Dlg::CTestw32Dlg(CWnd* pParent /*=NULL*/) + : CDialog(CTestw32Dlg::IDD, pParent) +{ + //{{AFX_DATA_INIT(CTestw32Dlg) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT + // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 + m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); +} + +void CTestw32Dlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CTestw32Dlg) + // NOTE: the ClassWizard will add DDX and DDV calls here + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CTestw32Dlg, CDialog) + //{{AFX_MSG_MAP(CTestw32Dlg) + ON_WM_PAINT() + ON_WM_QUERYDRAGICON() + ON_BN_CLICKED(IDC_SELECT_ACTION, OnSelectAction) + ON_WM_DESTROY() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CTestw32Dlg message handlers + +BOOL CTestw32Dlg::OnInitDialog() +{ int error; + FILE *retf; + CDialog::OnInitDialog(); + + // Set the icon for this dialog. The framework does this automatically + // when the application's main window is not a dialog + SetIcon(m_hIcon, TRUE); // Set big icon + SetIcon(m_hIcon, FALSE); // Set small icon + + // TODO: Add extra initialization here + //save CWnd objects for utility fns; + evgetevent=CreateEvent(NULL,FALSE,FALSE,"Get_Event"); + evdriverdisplaybitmap=CreateEvent(NULL,FALSE,FALSE,"Driver_Display_Bitmap"); + listbox=(GetDlgItem(IDC_LIST_BOX))->m_hWnd; + bitmap=(GetDlgItem(IDC_BITMAP))->m_hWnd; + button_OK=GetDlgItem(IDOK); + button_Cancel=GetDlgItem(IDCANCEL); + error=_pipe(pipe_std,1024,_O_TEXT); +// error=_pipe(pipe_err,1024,_O_TEXT); + // enable piping + if(-1==_fileno(stdout)) + {retf=freopen("throwaway_stdout.tmp","wt",stdout); + } + if(-1==_fileno(stderr)) + {retf=freopen("throwaway_stderr.tmp","wt",stderr); + } + old_std=dup(_fileno(stdout)); + old_err=dup(_fileno(stderr)); + error=dup2(pipe_std[1],_fileno(stdout)); + error=dup2(pipe_std[1],_fileno(stderr)); //error=dup2(pipe_err[1],_fileno(stderr)); + save_buffer=NULL; +// error=write(pipe_std[1],"Pipe_test:Write\n",16); +// error=fprintf(stdout,"Pipe_test:fprintf"); +// error=fflush(stdout); +// activate spooler + spool_thread=CreateThread(NULL,0,ThreadSpool,NULL,0,&thrd_spool); + + + return TRUE; // return TRUE unless you set the focus to a control +} + +// If you add a minimize button to your dialog, you will need the code below +// to draw the icon. For MFC applications using the document/view model, +// this is automatically done for you by the framework. + +void CTestw32Dlg::OnPaint() +{ + if (IsIconic()) + { + CPaintDC dc(this); // device context for painting + + SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); + + // Center icon in client rectangle + int cxIcon = GetSystemMetrics(SM_CXICON); + int cyIcon = GetSystemMetrics(SM_CYICON); + CRect rect; + GetClientRect(&rect); + int x = (rect.Width() - cxIcon + 1) / 2; + int y = (rect.Height() - cyIcon + 1) / 2; + + // Draw the icon + dc.DrawIcon(x, y, m_hIcon); + } + else + { + CDialog::OnPaint(); + } +} + +// The system calls this to obtain the cursor to display while the user drags +// the minimized window. +HCURSOR CTestw32Dlg::OnQueryDragIcon() +{ + return (HCURSOR) m_hIcon; +} + +void CTestw32Dlg::OnOK() +{ + DWORD thrd_id; + char Options[256]; + char *p,*pb,*pe; + int i; + // TODO: Add extra validation here + GetDlgItemText(IDC_TEST_PROGRAM,ProgramName,sizeof(ProgramName)-1); + GetDlgItemText(IDC_OPTIONS,Options,sizeof(Options)-1); + argv[0]=ProgramName; + p=Options; + i=1; + while (*p!=0) + { + while (*p==' ') p++; + pb=p; + while (*p>' ') p++; + pe=p; + if (pe>pb) + { + argv[i]=new char[1+pe-pb]; + strncpy(argv[i],pb,pe-pb); + argv[i][pe-pb]=0; + i++; + } + } + argv[0]=ProgramName; + argc=i; + main_thread=CreateThread(NULL,0,ThreadHead,NULL,0,&thrd_id); + +// CDialog::OnOK(); +} + +DWORD WINAPI ThreadHead(LPVOID Parm) +{ int i,rc; + +struct { + char pname[16]; + int (*program)(int,char**); +} tab[TEST_PROG_N]= +{ + {"FTVIEW",&ftview}, + {"FTDUMP",&ftdump}, + {"FTLINT",&ftlint}, + {"FTSTRING",&ftstring} +// {"FTSTRPNM",&ftstrpnm}, +// {"FTZOOM",&ftzoom} +}; +//disable Ok button + rc=button_OK->EnableWindow(FALSE); + rc=button_Cancel->EnableWindow(FALSE); + + for (i=0;(i< TEST_PROG_N) &&strcmp(tab[i].pname,ProgramName);i++); + if (i>= TEST_PROG_N) + { + MessageBox(NULL,"Please select a valid Test Program Name","FreeType Test ",MB_ICONQUESTION); + } + else + call_test_program(tab[i].program,argc,(char **)&argv); + //enable buttons again + rc=button_OK->EnableWindow(TRUE); + rc=button_Cancel->EnableWindow(TRUE); + rc=fflush(stdout); + rc=fflush(stderr); + ExitThread(1); + return 1; +} + + + +void translate_command(char nChar) +{ int rc,i; + // TODO: Add your message handler code here and/or call default + typedef struct _Translator + { + char key; + GEvent event_class; + int event_info; + } Translator; + +#define NUM_Translators 20 + + static const Translator trans[ NUM_Translators] = + { + { 'q', event_Quit, 0 }, + { (char)27, event_Quit, 0 }, + + { 'x', event_Rotate_Glyph, -1 }, + { 'c', event_Rotate_Glyph, 1 }, + { 'v', event_Rotate_Glyph, -16 }, + { 'b', event_Rotate_Glyph, 16 }, + + { '{', event_Change_Glyph, -10000 }, + { '}', event_Change_Glyph, 10000 }, + { '(', event_Change_Glyph, -1000 }, + { ')', event_Change_Glyph, 1000 }, + { '9', event_Change_Glyph, -100 }, + { '0', event_Change_Glyph, 100 }, + { 'i', event_Change_Glyph, -10 }, + { 'o', event_Change_Glyph, 10 }, + { 'k', event_Change_Glyph, -1 }, + { 'l', event_Change_Glyph, 1 }, + + { '+', event_Scale_Glyph, 10 }, + { '-', event_Scale_Glyph, -10 }, + { 'u', event_Scale_Glyph, 1 }, + { 'j', event_Scale_Glyph, -1 } + }; + for ( i = 0; i < NUM_Translators; i++ ) + { + if ( nChar == trans[i].key ) + { + evevent.what = trans[i].event_class; + evevent.info = trans[i].event_info; + break; + } + } + if (i>= NUM_Translators) + { + evevent.what=event_Keyboard; + evevent.what=nChar; + } + rc=SetEvent(evgetevent); +} + +void CTestw32Dlg::OnSelectAction() +{ + char c[2]; + GetDlgItemText(IDC_ACTION,c,2); + translate_command(c[0]); +} + + +DWORD WINAPI ThreadSpool(LPVOID Parm) +{ + while(1) + { + if (pipe_std[0]) readpipe(pipe_std[0]); // will never get out of there !!!! +// if (pipe_err[0]) readpipe(pipe_err[0]); + Sleep(1000); + } + return 1; +} + +void readpipe(int h) + { int i,j,rc; + + char buffer[1024],line[1024]; + rc=1; + while(rc) + { + rc=read(h,buffer,sizeof(buffer)); + if (rc) + { j=0; + for(i=0;i= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +///////////////////////////////////////////////////////////////////////////// +// CTestw32Dlg dialog + +class CTestw32Dlg : public CDialog +{ +// Construction +public: + CTestw32Dlg(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CTestw32Dlg) + enum { IDD = IDD_TESTW32_DIALOG }; + // NOTE: the ClassWizard will add data members here + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CTestw32Dlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + HICON m_hIcon; + + // Generated message map functions + //{{AFX_MSG(CTestw32Dlg) + virtual BOOL OnInitDialog(); + afx_msg void OnPaint(); + afx_msg HCURSOR OnQueryDragIcon(); + virtual void OnOK(); + afx_msg void OnSelectAction(); + afx_msg void OnDestroy(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_TESTW32DLG_H__70F52CAB_06A4_11D2_9AC4_0060978849F3__INCLUDED_) diff --git a/docs/FAQ b/docs/FAQ new file mode 100644 index 0000000..c567ec3 --- /dev/null +++ b/docs/FAQ @@ -0,0 +1,799 @@ + FreeType User FAQ + +-------------------------------------------------------------------- + + + Table of contents + + +1. How do I compile the test programs? + +2. What are the test programs? + +3. How do I use them? + +4. How do I only compile the FreeType library? + +5. The library compiles fine on my system, unfortunately it seems + the test programs won't. What can I do? + +6. What is FreeType, and what is it not? + +7. Can FreeType be ported to other platforms? + +8. My TrueType font only works on a Mac/in Windows. Will I be able + to use it with FreeType? + +9. What are the most common character mappings? + +10. How do I render text with FreeType? + +11. How do I render rotated/slanted text with FreeType? + +12. How do I compute a glyph bitmap's dimensions? + +13. Why is text rendering so slow? Does FreeType cache glyphs? + +14. Do you always render the same glyphs as Windows or the Mac? + +15. The program `ftlint' reports errors with one of my fonts, though + it works perfectly under Windows. What does this mean? + +16. What does the `fttimer' test program benchmarks? + +17. Is it possible to perform styling (like oblique, italic, bold, + underline, etc.) with FreeType? + +18. When does glyph hinting takes place? Is it when the glyph is + loaded, or when it is converted to a bitmap/pixmap? + +19. Which is the best, caching outlines or bitmaps? + +20. Can I open OpenType and/or TrueType GX fonts with FreeType? + +21. How can I access additional TrueType tables that FreeType + doesn't support? + +22. When will I be able to use FreeType to display TrueType fonts in + X11, Wine, or OS/2, or even other systems? + +23. What does the `free' in FreeType really means? + +24. Does FreeType support threads? Is it re-entrant? + +25. Does FreeType support `foreign languages'? + +26. I'm using fractional char sizes, but the glyphs stay at the same + integer size. Why? + +27. Hinting doesn't work at very small sizes. Why? + +-------------------------------------------------------------------- + +1. How do I compile the test programs? + + Detailed compilation steps are given in the `freetype/HOWTO.txt' + file, as well as system and compiler specific hints in the + `freetype/howto' directory. What follows is a _very_ simple + guide: + + For Unix: + + Do the following on the prompt while in the base directory of + the FreeType package: + + % ./configure + % make + % make install + + This will build and install the library (shared, if supported) + together with the test programs. Say `./configure --help' to + see the available configuring options. + + This should work with any ANSI C compiler. + + For other platforms: + + Go to the `test' directory. Look at one of the makefiles + located in the `arch/' directory, and use the + appropriate makefile from there. + + For example: + + make -f arch/msdos/makefile.gcc (DJGPP or emx) + wmake -f=arch\msdos\makefile.wat (Watcom DOS) + nmake -f arch\os2\makefile.icc (Visual Age OS/2) + make -f arch/amigaos/makefile.gcc (GCC Amiga) + + This will compile both the library and the test programs. + + +-------------------------------------------------------------------- + +2. What are the test programs? + + The test programs are simple sources that `show off' the FreeType + library. They are located in the `test' directory. They make use + of a small graphics sub-system which is able to display bitmaps + and pixmaps on a variety of platforms through the use of + system-specific `drivers'. + + The test programs are: + + ftdump: A simple TTF information dumper. Also prints the + memory used by each opened font file with FreeType. + Doesn't use the graphics sub-system. + + ftlint: A simple TrueType bytecode verifier. It simply hints + all glyphs of one or more font files at a given size + and reports errors. Doesn't use the graphics + sub-system. + + ftview: A simple font viewer. Displays all glyphs in a font + file in a window. + + ftstring: Renders a simple string to the screen. Demonstrates + how to produce text with FreeType. + + fttimer: A simple benchmark, used to profile the scan-line + conversion routines (and only them). Supports also + display. + + ftstrpnm: A version of `ftstring' which saves a bit/pixmap to a + PNM file rather than to the screen. No graphics + sub-system needed. + + ftzoom: A simple glyph viewer, useful to view, zoom and rotate + individual glyphs in a font file. + + fterror: This program demonstrates how to use the ftxerr18 + extension. Note that internationalized strings will + be available on some platforms only (e.g. Linux). + + ftmetric: A simple metric/glyph dumper. No graphics sub-system + needed. + + ftsbit: Displays data about embedded bitmaps in a TrueType + font. + + ftstrtto: Renders a string to screen, using TrueType Open + features. + + NOTE: The file `ftdebug.c' isn't part of the test suite. It is + used only by the developers team to debug the engine at a + higher level. It won't work with a standard library + compile. + + + The tiny graphics subsystem is defined in the following files: + + gmain.h/gmain.c: The subsystem's main body/interface. + + gevents.h: The definition of events defined for the + subsystem + + gdriver.h: The generic interface of all system-specific + drivers. + + System-specific drivers are in the `test/arch/' + directories, like: + + test/arch/msdos/gfs_dos.c Full-Screen DOS driver + test/arch/os2/gpm_os2.c PM (Windowed) OS/2 driver + test/arch/unix/gwin_x11.c X11 Windowed driver + + etc. + + +-------------------------------------------------------------------- + +3. How do I use them? + + Please read the file freetype/README for a full description. + + +-------------------------------------------------------------------- + +4. How do I only compile the FreeType library? + + For Unix: + + Do a `configure' run as described in section 1. Then change to + the lib subdirectory and say `make' and `make install'. + + For other platforms: + + Go to the `lib' directory. Look at one of the makefiles located + in the `arch/' directory, and use it from `lib'. + + For example: + + make -f arch/msdos/makefile.gcc (DJGPP or emx) + wmake -f=arch\msdos\makefile.wat (Watcom DOS) + nmake -f arch\os2\makefile.icc (Visual Age OS/2) + make -f arch/amigaos/makefile.gcc (GCC Amiga) + + The library is pure ANSI C and doesn't depend on any + system-specific package. You need not gcc to compile it. + + +-------------------------------------------------------------------- + +5. The library compiles fine on my system, unfortunately it seems + the test programs won't. What can I do? + + As said before, the test programs rely on a small graphics + sub-system to display the bitmaps and pixmaps produced by the + library. The following systems are currently supported: + + DOS Full-Screen + Amiga Full-Screen Note that the windowed graphics + Amiga Windowed driver are very 'basic', they do + OS/2 Full-Screen not provide menus, dialog boxes, + OS/2 Windowed etc. Rather, they provide one + X11 Windowed windowed bitmap/pixmap and translate + Win32 Windowed events to the ones defined in + `test/gevents'. + + If you want to add support to your system, you should write a new + graphics driver. To do that, read the file `test/gdriver.h' which + contains the driver generic interface, then browse the drivers + that are already provided. + + The graphics drivers are located in the `test/arch/' + directories. They're not part of the library proper. + + IMPORTANT NOTE: + + You can also directly link the library to your own application + and render glyphs directly into your own bitmaps with very few + efforts. + + +-------------------------------------------------------------------- + +6. What is FreeType, and what is it not? + + FreeType is a rather low-level font engine. It has been designed + primarily to be the basis of several font servers, for very + different systems which all have their own metrics and graphics + models. This means that it focuses on the following points: + + - Opening and loading font files in memory. + + - Giving access to most important font properties and TrueType + tables. + + - Providing a simple way to translate system-specific character + codes into glyph indexes, according to the TrueType `cmap' + specification. + + - Loading and rendering _individual_ glyphs as nicely as possible + (either in outlines, bitmaps, or pixmaps), and performing + excellent hinting. + + It isn't a high-level text rendering library, and many tasks will + have to be performed by higher level layers like: + + - glyph caching (outlines and/or maps) + - text rendering + - justification, kerning + - font mapping + - rotated/slanted text + + However, its API provides many functions that ease these + operations considerably: + + - Glyph outlines can be copied and transformed easily with the API + functions, then rendered to bitmaps or pixmaps with FreeType's + scan-line converter, which is very fast. + + - The glyph loader places the outlines in order to ease the + process of text rendering. See the documentation file named + `glyphs.htm' (resp. `glyphs.txt') or `ftstring's source for more + details. + + - The engine gives you access to several TrueType tables that can + be processed by your application to provide more powerful + rendering (e.g. kerning). + + - It is possible, and rather simple, to write separately + compilable extensions to the engine to access other TrueType + tables that are not supported by the engine in this release. + This can be handy if one wants to access data in TrueType GX or + OpenType fonts (as these formats comply to the TrueType `sfnt' + file storage format, they can be opened by the FreeType engine + as a normal TrueType file). + + +-------------------------------------------------------------------- + +7. Can FreeType be ported to other platforms? + + FreeType is written in pure ANSI C and should compile well on all + 16, 32, and 64 bits processors. Note, however, that the 16-bit + port requires a large memory model, as some tables found in + TrueType programs could exceed 64kByte (this is really true for + CJK and Unicode fonts. Nearly all others should work fine with + it). + + It doesn't support some very exotic platforms though, like a + 32-bit only processor (where the only word size is 32-bit, even + for chars and shorts). However, nothing prevents you to test it + by yourself... + + The memory management and file access routines have been gathered + in two components, namely `ttmemory' and `ttfile', which can be + specialized for a specific system. Their standard version, found + in the `lib' directory, uses simply the ANSI libc. However, + examples are given of alternative file components for OS/2 and + Unix in: + + lib/arch/os2/ttfile.c + (accessing the low-level OS/2 file API directly) + + lib/arch/unix/ttmmap.c + (using memory-mapped files for improved access) + + You would certainly need to rewrite these components if you intend + to use FreeType in an embedded system. + + +-------------------------------------------------------------------- + +8. My TrueType font only works on a Mac/in Windows. Will I be able + to use it with FreeType? + + Short Answer: YES, but be cautious! + + If you have read section 9 or 25, you know that a font file might + have different charMaps entries, used to translate character codes + to glyph indexes. The problem of most `system-specific' TrueType + fonts (sigh) is that they only contain one single mapping, like + Apple Roman, or Windows Glyph List, making it usable only on the + platform it was `designed' for. + + The test program `ftdump' can be used to display the character + encodings supported in a font file. Most fonts come with Apple + Roman and Windows Unicode. + + FreeType can use every charmap found in a font file, so it is up + to your application to choose the one that fits its task best. If + you use a font which only provides an Apple Roman charcode, you'll + probably have a hard time rendering Unicode strings without an + additional translation. + + Note that the tool `ttf_edit' can actually add missing cmaps to a + TrueType font file. More info on this can be found at: + + http://www.truetex.com + + Another possibility is to use Just van Rossum's TTX compiler + (still beta) which can convert a TrueType font into an XML + description and vice versa; it can be found at + + http://www.letterror.com/ttx/ + +-------------------------------------------------------------------- + +9. What are the most common character mappings? + + If you don't want to read the TrueType specification, here is some + information about the most used char maps. Each map is designed + by a `platform ID', followed by a platform-specific `encoding ID': + + Examples: + + 0, 0 : Apple Unicode + 1, 0 : Apple Roman + 3, 0 : Windows Symbol + 3, 1 : Windows Unicode + + Windows and Apple Unicode charmaps differ only in internal storage + layout. Both can be used transparently with FreeType. + + Many fonts come also with both Apple Roman and Windows Unicode. + + +-------------------------------------------------------------------- + +10. How do I render text with FreeType? + + This is explained with great detail in the glyphs documentation + file available in both text (glyphs.txt) and HTML (glyphs.htm, + including schematics). + + Text rendering isn't difficult. One can also look at the code for + `ftstring' or `ftstrtto' to see how it is done. + + +-------------------------------------------------------------------- + +11. How do I render rotated/slanted text with FreeType? + + It is possible to transform the outlines returned by the glyph + loader, hence producing rotated or slanted text. Please read the + `glyphs' documentation file, which explains this in great detail, + as well as some other important things. + + +-------------------------------------------------------------------- + +12. How do I compute a glyph bitmap's dimensions? + + You should grid-fit its bounding box, then compute its width and + height. This is explained in the `bitmaps.txt' documentation + file. + + +-------------------------------------------------------------------- + +13. Why is text rendering so slow? + Does FreeType cache glyphs? + + The FreeType engine doesn't cache anything, be it outlines or + bitmaps. Hence, a program that renders text by calling the glyph + loader on each letter is slow. + + Because caching cannot be performed in both an _easy_ and + _portable_ way it is left to the application. Moreover, some + graphics systems already provide some sort of caching, and it is + better to take advantage of it rather than re-implementing it. + + The `how's and `when's of caching are explained in the `glyphs' + documentation file. The `bitmaps' documentation file is also a + good source of information if you intend to render individual + glyph bitmaps. + + +-------------------------------------------------------------------- + +14. Do you always render the same glyphs as Windows or the Mac? + + Short answer: No for rare cases. + + There are a lot of technical details, too numerous and lengthy to + be put here, that prevents the FreeType library from matching 100% + the glyphs produced by the Windows or Macintosh rasterizers. + + This engine is a clean-room implementation, and most of the + reasons why its development took so much time is the largely + deficient TrueType specification published by Apple and Microsoft. + A number of key technical aspects are missing, and we found many + `undocumented' features in the TrueType bytecode, after several + months of testing and trying. We are now very satisfied with the + current quality, though still try to improve it. + + The glyph metrics (bearings and advances) also match significantly + those computed by Windows, or found in the TrueType pre-calc + tables. + + As hinting glyphs also makes use of several rounding operations, + we will be unable to provide a perfect clone unless we implement + the exact same computations _and_ rounding errors -- this is + very unlikely... + + +-------------------------------------------------------------------- + +15. The program `ftlint' reports errors with one of my fonts, though + it works perfectly under Windows. What does this mean? + + Associated to each glyph is a small `program', written in a + specific bytecode language, which is in charge of hinting the + glyph's outline to make it perfect on screen as on paper. Some of + these programs can be broken (e.g., accessing invalid areas of + memory, performing a divide by zero, etc.), and these are the + errors that are reported by `ftlint'. + + They can also mean a bug in the TrueType bytecode interpreter (or + more likely an `undocumented' feature we haven't discovered yet), + but should now be extremely rare. + + Surprisingly, even largely distributed fonts can contain broken + glyph programs. For example: + + - antqua.ttf, glyph 163 (MS Office 4.2): + + The program tries to access point number 0x127, which is too + much. + + - timesbs, arialbs, courbs (MS Office International): + + The back-slanted versions of the MS core fonts produce stack + overflows in many glyphs, and other oddities. It seems their + `maximum profile' table is invalid. + + - a ton of `free' fonts, apparently designed with mediocre tools. + + It seems the Windows TrueType engine doesn't check its arguments + often, and let all overflows run, possibly writing to critical + portions of memory. Please, don't ask us what this could do to + NT 4 :-) + + The FreeType engine performs checks on every opcode. We cannot + guarantee that it is bullet proof, of course, but it seems to work + well and catch font bugs accordingly. + + We also have artificially `enlarged' some allocated tables to make + the engine work with the back-slanted fonts without compromising + security, but it's clearly a hack we would have preferred to + avoid! + + +-------------------------------------------------------------------- + +16. What does the `fttimer' test program benchmarks? + + This test program is only dedicated to profiling FreeType's + scan-line converter, a component also called `rasterizer', which + is in charge of converting a vectorial outline into a bitmap, or a + pixmap. + + It simply loads all glyphs of a font file (by slices of 512 at + once), then converts them. Only the conversion is actually + benchmarked. + + The glyphs are rendered at size 400pt at a resolution of 96dpi + (this is about 500 pixels high!). As you'll see by running + `fttimer', the rasterizer is very fast. + + +-------------------------------------------------------------------- + +17. Is it possible to perform styling (like oblique, italic, bold, + underline, etc.) with FreeType? + + Actually, these refer to very different things: + + - Italic and Bold styles usually mean many variations from the + `Regular' font. This is why you normally need a proper font + file for each of these. For example, the MS core font Times + comes in the following TrueType files: + + TIMES.TTF Times New Roman Regular + TIMESI.TTF Times New Roman Italic + TIMESB.TTF Times New Roman Bold + TIMESBI.TTF Times New Roman Bold Italic + (sometimes named TIMESZ.TTF) + + With FreeType, you simply need the required font file to use it. + + - Oblique style refers to a transformation that is applied to a + regular font in order to make it `slanted', likes italics do. + However, an italic font very frequently contains small but + important variations that cannot be produced by this method and + make the font more appealing. + + Slanting can easily be done with a transformation under + FreeType, with the exact same process as rendering rotated text. + Please read the `glyphs' documentation file where it is + explained in details. + + Usually, Windows or the Macintosh produce oblique versions of a + regular font if the corresponding italic TrueType file isn't + available. They also stretch regular fonts horizontally if the + bold one isn't available. All of this can be done with trivial + transformations. + + - Underlining and stroking are not really part of the glyphs. + They're simply lines that are printed on the glyph after it has + been rendered. Each TrueType file provides, in its OS/2 table + (which is accessible through the face object properties in + FreeType), several values that define the position and width of + those lines, in notional font units. + + If you want to use them, you'll have to scale these values to + your current instance/point size, then draw the lines yourself. + + +-------------------------------------------------------------------- + +18. When does glyph hinting takes place? Is it when the glyph is + loaded, or when it is converted to a bitmap/pixmap? + + The glyph loader returns fitted outlines by default (it can be + asked to return a non-fitted one, or simply the original outline + in notional coordinates too). + + This is important to have a glyph's correct metrics, even if it is + not to be rendered immediately, like when caching outlines for + rotated text. + + +-------------------------------------------------------------------- + +19. Which is the best, caching outlines or bitmaps? + + It depends on your application, and what it does with text. + + Usually, if all you need is render some simple text at specific + point sizes, then simply cache the bitmaps or pixmaps. + + However, if you want to do more advanced things, like rotated + text, which require sub-pixel placement to look good, you should + then only cache the outlines, and transform/place them as needed + before sending them to the scan-line converter. + + It's always possible to produce a bitmap from an outline, and the + scan-converter is very fast. It's up to you then... + + +-------------------------------------------------------------------- + +20. Can I open OpenType and/or TrueType GX fonts with FreeType? + + TrueType GX fonts are normal TrueType fonts with enhanced tables + and capabilities. They can always be opened by a normal TrueType + engine (like Windows, the Mac, or FreeType), but their improved + features won't be available. + + On the contrary, OpenType fonts may vary. While some may contain + legal TrueType glyphs, an `otf' file may only contain glyphs + encoded in the Type 2 format. You won't be able to produce any + glyphs from such a font file without a dedicated font engine (like + the ones promised in NT 5 and Java 2D). + + FreeType is a TrueType glyph engine and doesn't support Type 2 + fonts. Supporting them would require a very different philosophy + and a different core engine (even though they could share an API). + + Note that you can write extensions to the engine to access + supplemental tables defined in these formats (see next question). + + Note that FreeType version 2 (which is in alpha stage currently) + already includes a PostScript Type 1 interpreter... + + +-------------------------------------------------------------------- + +21. How can I access additional TrueType tables that FreeType + doesn't support? + + You can write an `engine extension'. This is a separately + compilable component which can enhance the base library's + functionalities, without recompiling it. Some important + extensions are provided in the `lib/extend' directory. + + You'll need of course to know the TrueType specification + precisely, as well as some of the conventions used to access + tables and to manage memory. Read the documentation files for + more details, or contact the developers at: + + devel@freetype.org + + +-------------------------------------------------------------------- + +22. When will I be able to use FreeType to display TrueType fonts in + X11, Wine or OS/2, or even other systems? + + Actually, an OS/2 replacement for TRUETYPE.DLL based on FreeType + is part of this package (to be found in contrib/ftos2). Thanks go + to Michal Mecasek (mike@mendelu.cz) for his excellent work! + + At least three X11 TrueType font servers are available; two of + them (xfsft and xtt) are based on FreeType, whereas the third + (xfstt) uses a separately developed TrueType engine. + + More information about these servers is available at the FreeType + homepage (http://www.freetype.org). + + Don't hesitate to contact us if you plan to use or port the engine + to exotic platforms, we're always interested in helping out. + + +-------------------------------------------------------------------- + +23. What does the `free' in FreeType really means? + + The previous releases of FreeType (alphas and beta) were placed + under the LGPL. FreeType 1.0, and later releases, come with an an + alternate license, inspired from the BSD, Artistic, and IJG's + (Independent JPEG Group) ones. In short: + + - You are encouraged to use and distribute this program in all + kinds of products, including commercial ones. + + - You don't have to pay us anything for it (royalty-free). + + - You may not pretend you wrote it, or part of it that you may use + in one of your product, and you have to state clearly that you + use the FreeType code if you distribute products based on it, or + parts of it (credits clause). + + - This source code is provided AS IS, with no warranty whatsoever, + and we cannot promise support for it. + + The exact and legal terms are in the file `license.txt'. + + Enjoy ;-) + + +-------------------------------------------------------------------- + +24. Does FreeType support threads? Is it re-entrant? + + Short answer: Basically yes, but not fully tested. + + We have changed some code since FreeType 1.0 in order to support + multi-threaded environments. However, these have not been tested + yet. Apparently, the thread-safe and reentrant builds now work + well perfectly once compiled; however, no serious concurrency + testing has been performed (of course, a serious lock analysis was + done in order to modify the source). + + Right now, the mutex management functions are all gathered in the + component `ttmutex', which has to be specialized for your own + system if a thread build will be necessary. + + +-------------------------------------------------------------------- + +25. Does FreeType support `foreign languages'? + + Short Answer: YES, it does! + + From a TrueType font file point of view, there are several parts + to the file, one of them being the `glyphs', i.e., picture + representations of the symbols. + + Another part is the mapping table, also called `charMap'. + + For example, glyph #1 could be letter `A', and glyph #2 could be + letter `Z'. Glyphs can be stored in any order in a font file. + + The mapping tables contain at least one char-map entry. For + example, you could have an ASCII-map that maps character code 0x41 + to glyph #1, and code 0x5A to glyph #2, etc. FreeType provides a + `charMap' object class to access and use this information easily. + + There are several character encodings recognized and defined by + the TrueType specification, like Latin-1, Unicode, Apple Scripts, + WGL, etc., but a font file might only contain one or two of them. + + When using a more `exotic' character encoding like EBCDIC (this is + IBM mainframe stuff!), you would need to translate it to one of + the available formats (or to add a charmap table to the font). + Cf. section 8. + + +-------------------------------------------------------------------- + +26. I'm using fractional char sizes, but the glyphs stay at the same + integer size. Why? + + Because hinting only works well with integer pixel sizes. There + is a flag that can be set in a TrueType font file to force integer + pixel size scaling, even if you ask for fractional sizes with an + API function like TT_Set_Instance_CharSize(). Needless to say, + nearly all fonts have the flag set. So this is normal. + + Also, notice that when giving a charsize in fractional points, + this will be converted to integer pixels with the formula: + + pixel_size = char_size * y_resolution / 72 + + For example, using a resolution of 96 dpi, we would have: + + 9.5 pts => 12.666 pixels => 13 pixels + 10.0 pts => 13.333 pixels => 13 pixels, i.e. same size + 10.5 pts => 14 pixels => 14 pixels + 11.0 pts => 14.666 pixels => 15 pixels + 11.5 pts => 15.333 pixels => 15 pixels, i.e. same size + + If you want to control the exact size in pixels of your glyphs, + simply use a resolution of 72dpi, where char_size = pixel_size. + + +-------------------------------------------------------------------- + +27. Hinting doesn't work at very small sizes. Why? + + This is normal. There are very good technical reasons why hinting + doesn't work well at sizes under 7 ppem, usually meaning the + appearance of ugly spikes and glyph distortions. This is why the + engine disables hinting by default at such low sizes. + + +--- end of FAQ --- diff --git a/docs/TODO b/docs/TODO new file mode 100644 index 0000000..2472cce --- /dev/null +++ b/docs/TODO @@ -0,0 +1,23 @@ +FreeType TODO list + +. Handle various PostScript glyph names in ftxpost.c: + + Omega vs. Ohm + Delta vs. increment + macron vs. overscore + my vs. mu1 + periodcentered vs. middot + + with a new flag. + + +. Adaption of FreeType for non-ANSI compilers (wow, I'm heretic :-) + + +. More 16bit stuff to support _cdecl etc. Maybe something like this + may be used in place of the current EXPORT_DEF/EXPORT_FUNC: + + NEW_EXPORT_DEF( TT_Error ) + Cache_Create( PEngine_Instance engine, ... ) + +--- end of TODO --- diff --git a/docs/apiref.txt b/docs/apiref.txt new file mode 100644 index 0000000..47b0307 --- /dev/null +++ b/docs/apiref.txt @@ -0,0 +1,1867 @@ + The FreeType Engine + + Core Library Reference + + + ----------------------------------- + + + Table of Contents: + + Introduction + + I. Types + + II. Functions + + III. Error codes + + + -------------------- + + +Introduction +============ + + This reference presents the types, functions, and error codes + defined in the high-level API header file `freetype.h'. Note that + all symbols defined in this file are prefixed by `TT_', to avoid + name conflicts with other packages at link time. + + The reference for extensions of the FreeType library can be found + in the file apirefx.txt. + + + +-------------------------------------------------------------------- +-------------------------------------------------------------------- + + + +I. Types +======== + + Here is the list of all the types defined in the core FreeType + API. Their exact definition can be found in the file `freetype.h' + which should be included by every client application. + + + TT_Bool + + Can be either non-zero (true) or zero (false). + + .................................................................. + + TT_Fixed + + A signed 16.16 fixed float integer type used to specify + transform coefficients and other important data. + + .................................................................. + + TT_FWord + + A signed 16-bit type used to express a distance measured in the + font's original EM units. These are also called `FUnits' in the + TrueType specification. + + .................................................................. + + TT_UFWord + + An unsigned 16-bit type. + + .................................................................. + + TT_String + TT_Char + TT_Byte + + These types represent various 8-bit integer values (for strings, + signed, and unsigned values, respectively). + + .................................................................. + + TT_Short + TT_UShort + TT_Long + TT_ULong + + These four types are aliases for 16-bit integer (signed and + unsigned) and 32-bit integer types (signed and unsigned). + + .................................................................. + + TT_F2Dot14 + + A 2.14 fixed float integer type used for unary vectors and some + scaling coefficients. Its layout is: + + s : 1 -- sign bit + m : 1 -- mantissa bit + f : 14 -- unsigned fractional value + + where `s:m' is the 2-bit signed integer value to which the + always positive fractional part `f' should be added. + + .................................................................. + + TT_F26Dot6 + + A 26.6 fixed float integer format used to define fractional + pixel coordinates. Here, 1 unit = 1/64 pixel. + + .................................................................. + + TT_Pos + + This type is used to store point coordinates, either in + fractional pixels (26.6 fixed floats) or in EM units (simple + integers). + + The meaning of the value depends on the context. For example, + all distances relative to a scaled glyph are expressed in + fractional pixels (including bearings, advances, etc). However, + the same distances are in notional font units when the glyph was + loaded unscaled. + + .................................................................. + + TT_UnitVector + + A simple structure used to store a unit vector. The vector's + coordinates are expressed in fixed float format (2.14). + + struct + { + TT_F2Dot14 x; + TT_F2Dot14 y; + } + + .................................................................. + + TT_Vector + + A simple structure used to store a single vector. Its + coordinates are expressed in fixed float format (26.6). + + struct + { + TT_F26Dot6 x; + TT_F26Dot6 y; + } + + .................................................................. + + TT_Matrix + + A simple structure used to store a single 2x2 matrix. Its + coefficients are expressed in 16.16 fixed float format. This + matrix is used to perform linear transformations on the glyph + outline, such as slanting or rotation. + + struct + { + TT_Fixed xx, xy; + TT_Fixed yx, yy; + }; + + The computation performed is: + + x' = xx * x + xy * y + y' = yx * x + yy * y + + .................................................................. + + TT_BBox + + A simple type to hold a glyph's bounding box. Used by the + TT_Get_Outline_BBox() API. + + struct + { + TT_Pos xMin, yMin; + TT_Pos xMax, yMax; + } + + .................................................................. + + TT_Outline + + Outlines are now full-class citizens, with their own API. + + This structure is used to describe a vectorial glyph + representation to the rasterizer. It is made of several fields + described below. Note however that: + + ***** THIS STRUCTURE MAY CHANGE IN THE FUTURE. We thus + ***** encourage you to use the outlines APIs described below to + ***** process your outlines, i.e., create/copy/translate/ + ***** transform them as well as rendering bitmaps and pixmaps. + + ***** THE STRUCTURE CHANGED BETWEEN 1.0 and 1.1! + + Now that you have been warned, the fields are: + + - An array of points: + + The `n_points' field gives the number of points in the + outline, while their coordinates are found in the single + vector array `points'. The `flag' array holds for each point + a flag indicating its type. + + Currently, only the first bit (bit 0, the least significant + bit) of each byte is meaningful to the rasterizer. If set, it + indicates that the point is _on_ the curve. If not set, the + point is said to be _off_ the curve. It is then a Bezier + control point. + + For more information about point states, read the TrueType + specification or the scan-line documentation `raster.txt'. + + - An array of contours' end-point indexes: + + The `n_contours' field gives the number of contours, while the + `contours' array holds the indexes of each contour's last + point. Note that the first contour always begin at point 0. + + Hence, contours[0] holds the index of the last point of the + first contour. The second contour starting at point number + `contours[0]+1' and ending a point number `contours[1]'. + + ** IMPORTANT NOTE: ** + ********************* + + The last table entry _must_ always give the total number of + points used to draw the contours, i.e.: + + contours[n_contours - 1] == n_points + + If this value is bigger than `n_points' when calling the + scan-line converter, the component will immediately return + an error (TT_Err_Too_Many_Points). If the value is smaller, + only the points contained in the described contours will be + used in the conversion process. + + - An owner field: + + This flag should **NEVER** be changed by the user. It + indicates whether the pointer fields own the arrays they refer + to (when the flag is set), or if they simply alias them (flag + unset). + + - A high precision flag: + + If this boolean is set (i.e. not zero), the scan-line + converter uses a higher precision to compute segment and + Bezier coordinates (more precisely, it uses 1/1024 precision, + instead of the normal 1/64). This is of course slower but can + be important for glyphs rendered at small sizes. + + - A second pass flag: + + If this boolean is set, the scan-line converter performs a + second sweep on the bitmap/pixmap to detect vertical drop-out. + Only horizontal drop-outs are detected in the first pass. + This is slower, but important for glyphs rendered at small + sizes. + + - A dropout mode: + + Used to specify the method to apply for drop-out control (also + called `continuity testing' in other environments). The mode + value must be one of the values defined by the TrueType + specification. + + The recent modes 4 and 5 introduced in the newest TrueType + specification (Version 1.66) are fully supported. + + An invalid value (i.e., not 0, 1, 2, 4, or 5) is taken as no + dropout control (equivalent to mode 0). + + NOTE 1: + + The outline returned by TT_Get_Glyph_Outline() only alias the + data that is part of a glyph container (see below). However, + it is possible to create and process your own outlines with + the new API functions TT_New_Outline(), TT_Done_Outline(), + TT_Copy_Outline(), TT_Translate_Outline(), etc. + + TT_Done_Outline() will only discard an outline's array if it + owns them. + + NOTE 2: + + The outlines created by TT_New_Outline() are _not_ released by + the engine on TT_Done_FreeType(), they must be discarded + explicitly by the user who has created them! + + NOTE 3: + + The glyph loader sets the fields `high_precision', + `dropout_mode' and `second_pass' automatically. + + NOTE 4: + + This structure was called TT_Glyph_Outline in beta versions of + FreeType. + + .................................................................. + + TT_Glyph_Metrics + + A structure used to return simple glyph metrics, usable for + either horizontal or vertical layout. The values are expressed + in fractional pixels (26.6 format) if scaling was active, and in + FUnits otherwise. + + The main idea was to accomodate vertical text layouts by getting + rid of the two explicit `leftSideBearing' and `advanceWidth' + names. + + The meaning of the fields varies with the text layout: + + bearingX: Also known as the `left side bearing'. For + horizontal metrics, this value gives the horizontal + distance from the pen position to the glyph's bbox + xmin, otherwise it specifies the vertical distance. + + bearingY: Also known as the `top side bearing', this is the + vertical distance from the baseline to the glyph's + bbox ymax for horizontal metrics, the horizontal + distance otherwise. + + struct + { + TT_BBox bbox; /* the glyph's bbox */ + + TT_Pos bearingX; /* left-side bearing */ + TT_Pos bearingY; /* top-side bearing */ + + TT_Pos advance; /* advance width or height */ + }; + + ** IMPORTANT NOTE ** + + Because of the convention used by the TrueType engine, the + outlines generated at glyph-load time are all placed so that + the pen is at position (0,0). This means that you don't need + to increase the pen position by `bearingX' and/or `bearingY' + before writing a glyph. Text output can be performed with + simple lines like: + + for (glyphs in text) + { + TT_Load_Glyph( ... ); + TT_Get_Glyph_Outline( glyph, &outline ); + TT_Translate_Outline( outline, + cur_pos_x * 64, cur_pos_y * 64 ); + + TT_Get_Outline_Bitmap( outline, bitmap ); + /* blit bitmap to surface */ + + cur_pos_x += (metrics.advance + 32) / 64 + } + + See the file `test/ftstring.c' for an example. + + NOTE 2: + + This structure has changed from the beta version of FreeType. + + NOTE 3: + + FreeType implements only TT_Get_Glyph_Metrics() to return + horizontal metrics. For extracting vertical metrics you + should use TT_Get_Glyph_Big_Metrics(). + + .................................................................. + + TT_Big_Glyph_Metrics + + This structure is used to return the metrics of a glyph for both + horizontal and vertical layout. + + The `linearXXX' fields represent unhinted scaled metrics values. + They can be useful for applications which need to compute device + independent placement of glyphs. Applying these metrics to + hinted glyphs will in most cases ruin the grid fitting performed + by the bytecode interpreter. + + struct + { + TT_BBox bbox; /* the glyph's bounding box */ + + TT_Pos horiBearingX; /* horizontal left-side bearing */ + TT_Pos horiBearingY; /* horizontal top-side bearing */ + + TT_Pos vertBearingX; /* vertical left-side bearing */ + TT_Pos vertBearingY; /* vertical top-side bearing */ + + TT_Pos horiAdvance; /* horizontal advance */ + TT_Pos vertAdvance; /* vertical advance */ + + TT_Pos linearHoriBearingX; /* lin. scaled hor. lsb. */ + TT_Pos linearHoriAdvance; /* lin. scaled hor. adv. */ + + TT_Pos linearVertBearingY; /* lin. scaled vert. tsb. */ + TT_Pos linearVertAdvance; /* lin. scaled vert. adv. */ + } + + .................................................................. + + TT_Instance_Metrics + + A structure used to return instance (point size) metrics. + + struct + { + int pointSize; + /* point size in points (1 point = 1/72 inch) */ + + TT_UShort x_ppem; /* horizontal pixels per EM square */ + TT_UShort y_ppem; /* vertical pixels per EM square */ + + TT_Fixed x_scale; /* 16.16 scale for EM -> frac pixels */ + TT_Fixed y_scale; /* 16.16 scale for EM -> frac pixels */ + + TT_UShort x_resolution; /* device hor. res. in dpi */ + TT_UShort y_resolution; /* device vert. res. in dpi */ + }; + + The fields `x_scale' and `y_scale' can be used by clients to + convert from notional units (in funits) to fractional + pixels (in 26.6 fixed float format), e.g.: + + TT_FUnit em_distance; + TT_F26Dot6 frac_distance; + TT_Fixed x_scale; + + frac_distance = (em_distance * x_scale) / 0x10000; + + .................................................................. + + TT_Raster_Map + + This structure is used to describe a target bitmap (or pixmap) + to the scan-line converter. It _must_ be set up by the client + application. + + - The `rows' field contains the total number of rows in the + bitmap. + + - The `width' field gives the number of pixels per row (a bit or + a byte, depending on the map's nature). + + - The `cols' field gives the number of columns, i.e. bytes, + taken by each row in the map buffer. + + ** IMPORTANT: ** The `cols' field must be a multiple of 4 for + pixmaps! + + Typically, its value should be `(width+7)/8' for bitmaps, and + `(width+3) & -4' for pixmaps. + + - The `flow' field gives the map's vertical orientation. + + If the first bytes of the bitmap buffer pertain to its upper + row, the flow is said to be going `down', and the field should + take the value `TT_Flow_Down'. If these bytes pertain to its + lowest row, the flow is going `up', and the value is + `TT_Flow_Up'. + + As an example, the PC video modes use a `down' flow, where the + first VRAM byte corresponds to the upper and leftmost corner + of the screen. + + - The `bitmap' field is a typeless pointer to the map's buffer. + + - The `size' field contains the buffer's size in bytes. It is + usually computed as follows: + + size = rows * cols; + + NOTE 1: + + For bitmaps, the leftmost-pixel is related to the highest + (i.e. most significant) bit of its byte. There is currently + no support for the opposite convention found in some systems. + + (It can be easily added if you really need it, just ask the + development team.) + + struct + { + int rows; /* number of rows */ + int cols; /* number of columns (bytes) per row */ + int width; /* number of pixels per line */ + int flow; /* bitmap orientation */ + + void* bitmap; /* bit/pixmap buffer */ + long size; /* bit/pixmap size in bytes */ + } TT_Raster_Map; + + NOTE 2: + + TT_Get_Outline_Bitmap() resp. TT_Get_Glyph_Bitmap() are used + to render bitmaps into a TT_Raster_Map. The convention used + is 0 for the background, and 1 for the foreground. The glyph + is simply `or-ed' to the bitmap buffer. + + NOTE 3: + + TT_Get_Outline_Pixmap() and TT_Get_Glyph_Pixmap() are used to + render pixmaps into a TT_Raster_Map. Note that pixels are + drawn in spans of 4 successive bytes, only if needed. This + means that you must ALWAYS pass a clean pixmap buffer to these + functions. Otherwise, garbage could accumulate! + + .................................................................. + + TT_Header + + This structure is used to hold the font's header. Its layout + and meaning are defined in the TrueType specification, in the + `head' section. + + .................................................................. + + TT_Horizontal_Header + + This structure is used to hold the font's horizontal header. + Its layout and meaning are defined in the TrueType + specification, in the `hhead' section. + + .................................................................. + + TT_OS2 + + This structure is used to hold the font's OS/2 table. Its + layout and meaning are defined in the TrueType specification, in + the `OS/2' section. + + Note that since FreeType 1.3, we support fonts without an OS/2 + table (mainly old but popular Mac fonts). In this case, the + table's `version' field will be set to 0xFFFF by the loader, and + all other fields will be zeroed. + + .................................................................. + + TT_Postscript + + This structure is used to hold the font's PostScript table. Its + layout and meaning are defined in the TrueType specification, in + the `post' section. + + .................................................................. + + TT_Face_Properties + + This structure is used to return an opened face's properties. + These are: + + - The total number of glyphs in the font, given by the field + `num_Glyphs'. + + - The maximum number of points for the font's glyphs. This + value is used to allocate the points tables of a glyph + container's outline. It can be fairly large (like 256 points + for Roman fonts). + + - The maximum number of contours for the font's glyphs. This + value is used to allocate the contours tables of a glyph + container's outline. It can be fairly large (over 16, even in + Roman fonts). + + - The number of character mappings and name records within the + font. These values can still be retrieved through the APIs + TT_Get_CharMapCount() and TT_Get_Num_Names(), though these + have been _seriously_ deprecated. + + - The number of associated faces. This number is always 1 for a + normal TrueType font file. However, when the face object was + opened from a TrueType collection, it contains the total + number of embedded fonts. + + - Pointers to the face's header, horizontal header, OS/2, and + PostScript tables. + + struct + { + TT_UShort num_Glyphs; /* number of glyphs in face */ + TT_UShort max_Points; /* max. numb. of points in a glyph */ + TT_Short max_Contours; + /* maximum number of contours in a glyph */ + + TT_ULong num_Faces; + /* 1 for normal TrueType files resp. */ + /* the number of embedded faces for TT */ + /* collections */ + + TT_Header* header; /* TrueType header table */ + TT_Horizontal_Header* horizontal; + /* TrueType horizontal header */ + TT_Vertical_Header* vertical; + /* TrueType vertical header */ + TT_OS2* os2; /* TrueType OS/2 table */ + TT_Postscript* postscript; + /* TrueType PostScript table */ + } TT_Face_Properties; + + - Note that the `vertical' field is set to NULL if the font file + does not contain any vertical metrics. + + - Note also that since version 1.3 we support font files without + an OS/2 table. See the definition of TT_OS2 for more details. + + .................................................................. + + TT_Stream + + This handle type defines a stream used to access a font file's + data. A client application should never deal with streams + directly, but some engine extensions need it to support more + advanced features like sbit support. + + .................................................................. + + TT_Face + + This type defines a handle used to reference a face object. The + objects are never accessed directly by a client application; it + can only obtain handles to new objects, and use them to query + specific information or processes. + + See also: + + TT_Open_Face(), TT_Open_Collection(), TT_Close_Face(), + TT_Get_Face_Properties(), etc. + + .................................................................. + + TT_Instance + + This type defines a handle used to reference an instance object + (also called a `pointsize' in other type engines). An instance + is always created from a valid face object, and is destroyed + with it by the engine. + + See also: + + TT_New_Instance(), TT_Close_Instance(), + TT_Set_Instance_Pointsize(), TT_Set_Instance_Resolutions(), + etc. + + .................................................................. + + TT_Glyph + + This type defines a handle used to reference a glyph container + object. A glyph container is an object owning tables sized to + the font's maximum profile to hold any glyph of a given font + file. + + It contains an outline, some metrics, as well as some data + related to the way it should be processed by the scan-line + converter. + + Note that a glyph container doesn't contain any bitmap or + pixmap! + + See also: + + TT_New_Glyph(), TT_Close_Glyph(), TT_Get_Glyph_Metrics(), + TT_Get_Glyph_Big_Metrics(), TT_New_Outline(), + TT_Get_Glyph_Outline(), TT_Get_Glyph_Bitmap(), + TT_Get_Glyph_Pixmap() + + .................................................................. + + TT_Error + + This is the type of all error codes returned by the API. Nearly + all functions return an error code, set to 0 in case of success. + + A list of all error codes is given in section III. + + .................................................................. + + TT_Engine + + For the sake of re-entrancy it is possible to distinguish + `engines' to separate several running instances of the library. + For example, it could be used as a DLL shared by several client + applications. + + Each client program must begin by creating its own engine, + through a call to TT_Init_FreeType(). The engine must also be + passed as the first argument of the following functions: + + TT_Open_Face() + TT_Open_Collection() + TT_Set_Raster_Gray_Palette() + TT_Get_Outline_Bitmap() + TT_Get_Outline_Pixmap() + TT_Done_FreeType() + + Note that any FreeType object pertains to one single engine + (there is no sharing). Closing an engine with + TT_Done_FreeType() will delete all the objects that have been + allocated within its instance. + + + +-------------------------------------------------------------------- +-------------------------------------------------------------------- + + + +II. Functions +============= + + Here is a list of the core library's API. + + NOTE: + + A function's default result is an error code of type TT_Error; a + list of error codes is given in section III below. + + Some functions return other types, in which case the result type + is documented with its description. + + .................................................................. + + TT_FreeType_Version( int* major, int* minor ); + + Queries the major and minor version of the library. + + .................................................................. + + TT_Init_FreeType( TT_Engine* engine ); + + Creates and initializes a new engine. Returns a handle to the + engine in the `*engine' variable. + + This call must be performed before any other function of + FreeType is invoked. The engine handle must be passed to the + following functions: + + TT_Open_Face() + TT_Open_Collection() + TT_Set_Raster_Gray_Palette() + TT_Done_FreeType() + + .................................................................. + + TT_Done_FreeType( TT_Engine engine ); + + Finalizes and destroys an engine. This call destroys _all_ + objects that were previously created and used with the engine. + + .................................................................. + + TT_Open_Face( TT_Engine engine, + TT_Text* fontPathName, + TT_face* face ); + + This call opens a font file, located by `fontPathName', and + returns a handle to the newly corresponding face object in the + handle `*face'. The object is part of the `engine' instance. + + Example: + + error = TT_Open_Face( engine, "c:\ttf\wingding.ttf", &face ); + if ( error ) + fprintf( stderr, "Could not open face.\n" ); + + NOTE 1: + + The font file can be a TrueType collection; in this case, the + engine will always open the first embedded font found in the + file. + + NOTE 2: + + `TT_Text' is usually defined as `char' by a typedef + declaration. It may be a 16-bit quantity (or even wider) for + some operating systems; see ttconfig.h for details. + + .................................................................. + + TT_Open_Collection( TT_Engine engine, + TT_Text* collectionPathName, + TT_ULong fontIndex, + TT_Face* face ); + + This call opens one of the fonts found in a TrueType collection. + The font is selected through the `fontIndex' argument. The + first font has index 0. + + Note that to know a collection's number of embedded fonts, + you will have to: + + 1 - open the first collection font with TT_Open_Face(). + + 2 - query the face's properties through + TT_Get_Face_Properties(). + + The number of embedded faces is then `properties->num_Faces'. + + Example: + + TT_Face face; + TT_Face_Properties properties; + + + /* Open first embedded collection font */ + error = TT_Open_Face( engine, "c:\ttf\sample.ttc", &face ); + if ( error ) { ...error... } + + /* Get face properties */ + error = TT_Get_Face_Properties( face, &properties ); + if ( error ) { ...error... } + + printf( "There are %d fonts in this collection.\n", + properties->num_Faces ); + + TT_Close_Face( face ); + + /* Open second font in collection */ + error = TT_Open_Collection( engine, "c:\ttf\sample.ttc", 1, + &face ); + if ( error ) { ...error... } + + NOTE 1: + + If the file isn't a collection, `fontIndex' must be zero. + Otherwise, an error will be returned. + + NOTE 2: + + `TT_Text' is usually defined as `char' by a typedef + declaration. It may be a 16-bit quantity (or even wider) for + some operating systems; see ttconfig.h for details. + + .................................................................. + + TT_Set_Raster_Gray_Palette( TT_Engine engine, + TT_Byte* palette ); + + Sets the gray-level palette for an engine. The palette is used + to create pixmaps through the TT_Get_Glyph_Pixmap() function. + It is an array of five bytes, following the convention: + + palette[0] = background (white) + palette[1] = light + palette[2] = medium + palette[3] = dark + palette[4] = foreground (black) + + .................................................................. + + TT_Get_Face_Properties( TT_Face face, + TT_Face_Properties* properties ); + + Returns the `face' object's `*properties'. This structure + contains various data like the total number of glyphs and + pointers to some mandatory TrueType tables. + + See the definition of TT_Face_Properties in section I for more + details. + + Note that since version 1.3, FreeType supports fonts with no + OS/2 table, like many old Mac fonts. See the definition of + TT_OS2 for more details. + + .................................................................. + + TT_Get_Face_Metrics( TT_Face face, + TT_UShort firstGlyph, + TT_UShort lastGlyph, + TT_Short* leftBearings, + TT_UShort* widths, + TT_Short* topBearings, + TT_UShort* heights ); + + This function returns the original horizontal AND vertical + metrics for a given face `face' and a given glyph range specified + by `firstGlyph' and `lastGlyph' as found in the `hmtx' and `vmtx' + tables. These are the glyphs' left-side bearings (in + `leftBearings') and horizontal advance widths (in `widths'), as + well as top-side bearings (in `topBearings') and vertical advance + heights (in `heights'). If you aren't interested in any of the + metrics fields, simply set its value to NULL. + + All are expressed in font units, a.k.a. EM units. + + The metrics arrays must be allocated by the client program. + + IMPORTANT NOTE: + + As vertical metrics are optional in a TrueType font, this + function will return an error (TT_Err_No_Vertical_Data) if this + function is called on such a face with non-NULL `topBearings' + or `heights' arguments. + + If a font has no vertical data, the `vertical' field in its + properties structure is set to NULL. + + .................................................................. + + TT_Set_Face_Pointer( TT_Face face, + void* data ); + + For convenience purposes, each face object has a `generic' + pointer which value is unused by the engine, but that can be set + freely by client applications through this function. + + Do what you want with it; it is here to give you a chance to + link a face object to your own structures and data. + + .................................................................. + + void* TT_Get_Face_Pointer( TT_Face face ); + ^^^^ + Returns a face object's generic pointer. See + TT_Set_Face_Pointer() above. + + .................................................................. + + TT_Flush_Face( TT_Face face ); + + Closes a given face object's file handler or descriptor. This + is useful to save system resources if your application opens + dozens or even hundreds of fonts. The face object is still + valid, and its file will be re-opened automatically on the next + request which requires disk access. + + .................................................................. + + TT_Close_Face( TT_Face face ); + + Closes a given `face' object. This function will also destroy + all the face's child instances. The face's glyphs will not be + destroyed, however. + + .................................................................. + + TT_New_Instance( TT_Face face, + TT_Instance* instance ); + + Creates a new instance object related to the `face' object. A + handle to the newly created instance is returned in `instance'. + + The default instance resolution is 96dpi in both vertical and + horizontal direction; the default point size is 10pt. + + .................................................................. + + TT_Set_Instance_Resolutions( TT_Instance instance, + TT_UShort xResolution, + TT_UShort yResolution ); + + Sets the target device resolutions for a given instance. The + values are expressed in dots per inch (dpi). A value of 96dpi + is typical for an SVGA display, 72dpi for a Macintosh one, and + 300 to 6000dpi for printers. Default value (before a call to + this function) is 96dpi. + + .................................................................. + + TT_Set_Instance_CharSize( TT_Instance instance, + TT_F26Dot6 charsize ); + + Sets the point size for a given instance. The size is expressed + in fractional (26.6) `points', where 1 point = 1/72 inch. The + default value is 10pt (before a call to this function). + + For example, to use a char size of 12pt, call the function with: + + TT_Set_Instance_CharSize( instance, 12 * 64 ); + + Fractional point sizes are thus possible. + + .................................................................. + + TT_Set_Instance_CharSizes( TT_Instance instance, + TT_F26Dot6 charWidth, + TT_F26Dot6 charHeight ); + + Sets an instance's glyph width and height independently in + fractional (26.6) points. Similar to Set_Instance_CharSize() + with the exception that the horizontal and vertical glyph + dimensions can differ. + + .................................................................. + + TT_Set_Instance_PixelSizes( TT_Instance instance, + TT_UShort pixelWidth, + TT_UShort pixelHeight, + TT_F26Dot6 pointSize ); + + This function can be used to specify directly the pixel sizes + and point size of a given instance, independently of device + resolutions. This is not the recommended way to do it, but can + be used for debugging or simplicity in some special cases. + + Note that you _must_ provide a point size! + + .................................................................. + + TT_Set_Instance_Transform_Flags( TT_Instance instance, + TT_Bool rotated, + TT_Bool stretched ); + + Sets the transform flags for a given instance. These flags are + passed to the interpreter each time a glyph is loaded within the + instance. Their role is to notify the glyph hinting mechanism + that the resulting glyph will be transformed in a special way. + Setting one of these flags to true usually disables hinting, + though this behaviour varies with each font file. + + NOTE: + + The glyph loader doesn't perform the rotation or the + stretching automatically; this must be done explicitly by the + client application. Use the function TT_Transform_Outline() + for that purpose. + + .................................................................. + + TT_Get_Instance_Metrics( TT_Instance instance, + TT_Instance_Metrics* imetrics ); + + This call returns a given instance's current metrics. They are + returned in the `imetrics' structure, which contains, among + other things, the current point size, ppem, and device + resolution (horizontal and vertical). + + .................................................................. + + TT_Set_Instance_Pointer( TT_Instance instance, + void* data ); + + For convenience purposes, each instance object has a `generic' + pointer which value is unused by the engine, but that can be set + freely by client applications through this function. + + Do what you want with it, it is here to give you a chance to + link a face object to your own structures and data. + + .................................................................. + + void* TT_Get_Instance_Pointer( TT_Instance instance ) + ^^^^ + + This function returns an instance object's generic pointer set + through TT_Set_Instance_Pointer(). + + .................................................................. + + TT_Done_Instance( TT_Instance instance ); + + Closes a given instance object, destroying its associated data. + Note that this is performed automatically when a face is closed + on all its child instances. However, explicit deallocation can + help in freeing the memory used by the application earlier. + + .................................................................. + + TT_New_Glyph( TT_Face face, + TT_Glyph* glyph ); + + Creates a new glyph container for the glyphs of the font + described by the `face' handle. A pointer to the container is + returned in `glyph'. The face is said to be the glyph's parent. + + NOTE: + + A glyph is destroyed with its parent face object. However, it + is possible to delete it explicitly with TT_Done_Glyph(). + + .................................................................. + + TT_Done_Glyph( TT_Glyph glyph ); + + Discards a glyph container. This is also done automatically for + all glyphs when closing its parent face object. + + .................................................................. + + TT_Load_Glyph( TT_Instance instance, + TT_Glyph glyph, + TT_UShort glyphIndex, + TT_UShort loadFlags ); + + Loads and processes (scales and/or hints) a glyph at a given + `instance' into the `glyph' container. + + Note that `glyph' and `instance' must have the _same_ parent + face object, otherwise an error message will be returned. + + `glyph_index' is the glyph's index as found in the TrueType + font. It is _not_ a character code (see the charmap functions + below). + + `load_flags' is an integer that specifies which operations are + to be performed on the loaded glyph. The following values/bits + are used: + + TTLOAD_SCALE_GLYPH + + Indicates that the glyph must be scaled to the instance's + resolution. The pixel coordinates returned in the glyph + outline structure (see below) are then expressed in + fractional pixels represented in the 26.6 fixed point + floating format (F26Dot6). + + If scaling is disabled, the coordinates returned in the + outline structure are integer font units, also called + `FUnits' by the TrueType specification. + + TTLOAD_HINT_GLYPH + + This flag is only valid when scaling is on. It informs the + loader that the glyph must be hinted (i.e., grid-fitted for + optimal display). Note that hinting will occur only if the + instance's transformations and metrics allow it (for + example, most font programs disable hinting automatically in + case of rotation or stretching). + + When loading a hinted glyph, the metrics computed by the + loader, including the bounding box, will also be + grid-fitted. + + TTLOAD_PEDANTIC + + Starting with FreeType version 1.3, the bytecode interpreter + can ignore even more errors (like out-of-bound array + accesses). Using this flag it is possible to force TrueType + compliant interpretation of font programs. + + TTLOAD_IGNORE_GLOBAL_ADVANCE_WIDTH + + A flag to handle monospaced fonts with an incorrect global + advance width in the `hhea' table. If set, the actual + advance width value of a particular glyph will be used; if + unset, the advance widths for all glyphs are forced to be + equal to the global value. + + + NOTE: + + You can also use the constant TTLOAD_DEFAULT, which is simply + the union of TTLOAD_SCALE_GLYPH and TTLOAD_HINT_GLYPH for most + `typical' loads. + + .................................................................. + + TT_Get_Glyph_Outline( TT_Glyph glyph, + TT_Outline* outline ); + + This call returns the glyph's `outline'. This is a simple + structure which contains pointers to the data used to describe + an outline to the rasterizer. See the definition of + TT_Outline in section I. + + .................................................................. + + TT_Get_Glyph_Metrics( TT_Glyph glyph, + TT_Glyph_Metrics* metrics ); + + Extracts the glyph's metrics and copies them to the `*metrics' + structure. Its format is described in section I. + + If the glyph has been loaded without scaling, the values are + expressed in FUnits (integers relative to the original font grid + called the EM Square). + + If the glyph has been loaded _with_ scaling, which is the + default, the values are expressed in fractional pixels in 26.6 + fixed point float format (F26Dot6; 1 unit = 1/64th of a pixel). + + If the glyph has been loaded with hinting, the metrics are also + grid-fitted, including the bounding box. To get the un-fitted + bbox, call TT_Get_Outline_BBox() on the glyph's outline. + + NOTE: + + BBox fitting occurs according to the following scheme: + + #define FLOOR( x ) ( (x) & -64 ) + #define CEILING( x ) ( ( (x) + 63 ) & -64 ) + + xMin = FLOOR( xMin ); + yMin = FLOOR( yMin ); + xMax = CEILING( xMax ); + yMax = CEILING( yMax ); + + This means that the outline's width and height in pixels can be + computed simply from the fitted bbox, namely + + (xMax-xMin)/64 and (yMax-yMin)/64 + + .................................................................. + + TT_Get_Glyph_Big_Metrics( TT_Glyph glyph, + TT_Big_Glyph_Metrics* metrics ); + + Extracts the glyph's big metrics and copies them to the + `*metrics' structure. Its format is described in section I. + + If the glyph has been loaded without scaling, the values are + expressed in FUnits (integers relative to the original font grid + called the EM Square). + + If the glyph has been loaded _with_ scaling, which is the + default, the values are expressed in fractional pixels in 26.6 + fixed point float format (F26Dot6; 1 unit = 1/64th of a pixel). + + If the glyph has been loaded with hinting, the metrics are also + grid-fitted, including the bounding box. To get the un-fitted + bbox, just call TT_Get_Outline_BBox() on the glyph's outline. + + NOTE 1: + + BBox fitting occurs according to the following scheme: + + #define FLOOR( x ) ( (x) & -64 ) + #define CEILING( x ) ( ( (x) + 63 ) & -64 ) + + xMin = FLOOR( xMin ); + yMin = FLOOR( yMin ); + xMax = CEILING( xMax ); + yMax = CEILING( yMax ); + + This means that the outline's width and height in pixels can be + computed simply from the fitted bounding box, namely + + (xMax-xMin)/64 and (yMax-yMin)/64 + + NOTE 2: + + The vertBearingX value in `metrics' cannot be extracted for + outline glyphs -- it is defined for embedded bitmaps only. + Instead, it is set to (xMin-xMax)/2; this will center the + bounding box on the vertical `baseline'. + + .................................................................. + + TT_Get_Glyph_Bitmap( TT_Glyph glyph, + TT_Raster_Map* bitmap, + TT_F26Dot6 xOffset, + TT_F26Dot6 yOffset ); + + This call converts the vectorial glyph representation contained + in the object handled by `glyph' into a bitmap. + + The target bitmap is described by the `bitmap' pointer. + Clipping will be done if necessary. You can also specify an + offset to be applied before the scan-line conversion; `xOffset' + and `yOffset' must be expressed in fractional pixels (where + 1 unit = 1/64th pixel). + + NOTE 1: + + Choosing non integer pixel offsets, i.e., values of `xOffset' + and `yOffset' that are not multiples of 64, will ruin the + hinting performed by the interpreter, and result in bad + rendering at small sizes. + + NOTE 2: + + The glyph's point coordinates must be scaled before calling + this function. Never call this function with a glyph that + were loaded with no scaling! + + NOTE 3: + + FreeType always shifts the glyph horizontally so that the left + side bearing is equal to the left side of the bounding box. + + .................................................................. + + TT_Get_Glyph_Pixmap( TT_Glyph glyph, + TT_Raster_Map* pixmap, + TT_F26Dot6 xOffset, + TT_F26Dot6 yOffset ); + + This call converts the vectorial glyph representation contained + in the object handled by `glyph' into a pixmap (i.e., an + 8-bit/pixel map). The result is an anti-aliased version of the + glyph (`anti-aliasing' is also known as `font-smoothing'). + + The target pixmap is described by the `pixmap' pointer. Note + that its width _must_ be a multiple of 4. For the definition + and description of a pixmap see Section I. + + As with TT_Get_Glyph_Bitmap(), you can specify offsets to be + applied before the rendering (`xOffset' and `yOffset' must be + expressed in fractional pixel coordinates). + + NOTE 1: + + You don't need to supply a temporary bitmap for the + anti-aliaser. The rasterizer uses its own scheme to optimize + memory usage. + + NOTE 2: + + The glyph's point coordinates must be scaled before calling + this function. This means that you should never call it with + a glyph which has been loaded without scaling! + + NOTE 3: + + The pixmap passed to this function should always be EMPTY + (i.e., filled with zero bytes) before the call. If not, + garbage will accumulate! + + NOTE 4: + + FreeType always shifts the glyph horizontally so that the left + side bearing is equal to the left side of the bounding box. + + .................................................................. + + TT_New_Outline( TT_UShort numPoints, + TT_UShort numContours, + TT_Outline* outline ); + + Creates a new outline object. This function creates the arrays + necessary to hold `numPoints' points and `numContours' contours, + and set `outline's pointers to them. + + The new outline owns the arrays, and they will be destroyed with + it through TT_Done_Outline(). + + NOTE 1: + + Outlines created with this function are called `user' + outlines, in contrast with the outlines returned by + TT_Get_Glyph_Outline(), which fields refer to the data + contained within a glyph object (i.e., these outlines do not + own the arrays they refer to). + + NOTE 2: + + User outlines aren't tracked by the engine, which means they + are not destroyed by a TT_Done_FreeType(). You have to + explicitly discard them through TT_Done_Outline() to avoid + memory leaks. + + .................................................................. + + TT_Done_Outline( TT_Outline* outline ); + + Deletes an outline's data. Note that you need not destroy the + outlines returned by TT_Get_Glyph_Outline(), only those created + by TT_New_Outline(). + + .................................................................. + + TT_Copy_Outline( TT_Outline* source, + TT_Outline* target ); + + Copies the content of the `source' outline into the content of + the `target' outline. The two outlines must have been created + with the same dimensions (num_points and num_contours), + otherwise this function will return an error code. + + .................................................................. + + void TT_Transform_Outline( TT_Glyph_Outline* outline, + ^^^^ TT_Matrix* matrix ); + + Applies a simple transformation matrix on a given outline. This + will multiply each point coordinate vector by a 2x2 matrix, + which coefficients are given in the 16.16 fixed float format. + + Rotation can be performed with this function. + + NOTE: + + This function takes an outline, and not a glyph handle, as a + parameter. This `feature' lets you apply transformations on + your own copies of glyphs. + + .................................................................. + + void TT_Translate_Outline( TT_Glyph_Outline* outline, + ^^^^ TT_Pos xOffset, + TT_Pos yOffset ); + + Applies a simple translation on a given outline. + + NOTE: + + This function takes an outline, and not a glyph handle, as a + parameter. This `feature' lets you apply translation to your + own copies of glyphs. + + .................................................................. + + TT_Get_Outline_Bitmap( TT_Outline* outline, + TT_Raster_Map* bitmap ); + + Renders an outline into a bitmap. The latter must be setup by + the user before the call (i.e., it is not created by this + function, instead it must be provided by the user). + + .................................................................. + + TT_Get_Outline_Pixmap( TT_Outline* outline, + TT_Raster_Map* pixmap ); + + Renders an outline into a pixmap. The latter must be setup by + the user before the call (i.e., it is not created by this + function, instead it must be provided by the user). + + NOTE: + + The pixmap passed to this function must always be EMPTY (i.e., + filled with zero bytes) before the call. Otherwise, garbage may + accumulate! + + .................................................................. + + TT_Get_Outline_BBox( TT_Outline* outline, + TT_BBox* bbox ); + + Returns an outline's bounding box in the `bbox' structure. Note + that the returned coordinates are not grid fitted! + + NOTE: + + The current release of FreeType (1.x) does compute the bounding + box for the outline's control points, and not the `exact' box + based on Bezier arcs extrema. Hence, the bbox returned by this + function may be slightly larger than necessary if the glyph + doesn't have control points at its extrema, or if it has been + rotated. + + .................................................................. + + void TT_Transform_Vector( TT_Pos* x, + ^^^^ TT_Pos* y, + TT_Matrix* matrix ); + + Applies a 2x2 matrix to a vector. + + .................................................................. + + int TT_Get_CharMapCount( TT_Face face ); + ^^^ + + Gets the number of character mappings present in the TrueType + file described by the `face' handle. Returns -1 if the handle + is invalid. + + IMPORTANT NOTE: ******** + + This function is deprecated. Get the number of character maps + from the `num_CharMaps' field in the structure returned by + TT_Get_Face_Property() instead. + + .................................................................. + + TT_Get_CharMap_ID( TT_Face face, + TT_UShort charmapIndex, + TT_UShort* platformID, + TT_UShort* encodingID ); + + Returns the platform ID and platform-specific encoding ID for + the charmap numbered `charmapIndex' in the `face' object. The + total number of character mapping tables can be found in the + `num_CharMaps' field in the structure returned by + TT_Get_Face_Property(). + + .................................................................. + + TT_Get_CharMap( TT_Face face, + TT_UShort charmapIndex, + TT_CharMap* charMap ); + + Returns a handle for the character map number `charmapIndex' of + `face'. The handle is placed in `*charMap' and can be used + later for fast lookup with the TT_Char_Index() API function. + + Charmap objects are automatically destroyed when their face + object is destroyed. + + .................................................................. + + TT_UShort TT_Char_Index( TT_CharMap charMap, + ^^^^^^^^^ TT_UShort charCode ); + + Applies a charMap to translate `charCode' into a glyph index + that can be used to load and address a glyph in the TrueType + file. In case of error, the undefined glyph (index 0) is + returned. + + The charmap handle can be obtained with TT_Get_CharMap(). + + .................................................................. + + int TT_Get_Name_Count( TT_Face face ); + ^^^ + + Gets the number of name strings found in a face's name table. + This function will return -1 if the face handle is invalid. + + IMPORTANT NOTE: ******** + + This function is deprecated. Get the number of name strings + from the `num_Names' field in the structure returned by + TT_Get_Face_Property() instead. + + .................................................................. + + TT_Get_Name_ID( TT_Face face, + TT_UShort nameIndex, + TT_UShort* platformID, + TT_UShort* encodingID, + TT_UShort* languageID, + TT_UShort* nameID ); + + Returns the ID of a given name string, indexed by the number + `nameIndex' in a given face. The name index ranges from 0 to + `num_names' minus one; this value can be found in the structure + returned by TT_Get_Face_Property(). + + Each string has a `platformID', `encodingID', `languageID' and + `nameID', as defined by the TrueType specification. + + The platformID is typically in the range [0,3]. Some font files + have unusual name table entries; these can be detected from + their platformID which is larger than 3. + + .................................................................. + + TT_Get_Name_String( TT_Face face, + TT_UShort nameIndex, + TT_String** stringPtr, + TT_UShort* length ); + + Returns a name string's address and length. Note that an + invalid name table entry always returns NULL for `stringPtr' and + zero for `length'. + + NOTE 1: + + The string belongs to the face object and should not be + written to or freed by the client application. + + NOTE 2: + + The library does not care about endianess here! If you are + using a little-endian machine and you have to interpret the + string bytes as 16-bit-wide characters (e.g. Unicode encoded), + you must byte-swap the data because 16-bit data is stored as + big-endian in TrueType fonts, and FreeType reads in the whole + name table bytewise. + + .................................................................. + + TT_Get_Font_Data( TT_face face, + TT_Long tag, + TT_Long offset, + void* buffer, + TT_Long* length ); + + Gets font or table data. Similar to the GetFontData() API of + the Windows world. You can use the macro MAKE_TT_TAG() to + generate TrueType table tags from character descriptions, like + + MAKE_TT_TAG( 'e', 'b', 'l', 'c' ) + + Use the value 0 instead for `tag' if you want to access the + whole font file. `offset' specifies the starting offset in the + table (or the offset in the file if tag == 0), `buffer' the + address of target buffer. + + Depending on the value of length, various actions are performed. + If `length' is NULL, the whole table will be loaded. An error + will be returned if `offset' is not 0. If `*length' is zero, + TT_Get_Font_Data() exits immediately, returning only the length + of the given table (in the variable `length'), or of the font + file, depending on the value of `tag'. Finally, if `*length' is + not zero, the next `length' bytes of the table (resp. the font) + are loaded into an array pointed to by `buffer', starting at + offset `offset'. Note that the `buffer' array must be large + enough to hold `length' bytes. + + +-------------------------------------------------------------------- +-------------------------------------------------------------------- + + + +III. Error Messages +=================== + + Most functions return an error code, typed to TT_Error. A return + value of zero indicates no error. The error values are defined in + the file `freetype.h'. In the following table, the prefix + `TT_Err_' is omitted, e.g. `Ok' -> `TT_Err_Ok'. + + + Error Unprefixed Error + Code Macro Name Description + ------------------------------------------------------------------ + + 0x0000 Ok Successful function call. + Always 0! + + ----------------- high-level API error codes --------------------- + + The following error codes are returned by the high-level API to + indicate an invalid client request. + + 0x0001 Invalid_Face_Handle An invalid face object handle was + passed to an API function. + + 0x0002 Invalid_Instance_Handle An invalid instance object handle + was passed to an API function. + + 0x0003 Invalid_Glyph_Handle An invalid glyph container handle + was passed to an API function. + + 0x0004 Invalid_CharMap_Handle An invalid charmap handle was + passed to an API function. + + 0x0005 Invalid_Result_Address An output parameter (a result) + was given a NULL address in an + API call. + + 0x0006 Invalid_Glyph_Index An invalid glyph index was passed + to an API function. + + 0x0007 Invalid_Argument An invalid argument was passed to + an API function. Usually, this + means a simple out-of-bounds + error. + + 0x0008 Could_Not_Open_File The pathname passed doesn't point + to an existing or accessible + file. + + 0x0009 File_Is_Not_Collection Returned by TT_Open_Collection + while trying to open a file which + isn't a collection. + + 0x000A Table_Missing The requested TrueType table is + missing in the font file. + + 0x000B Invalid_Horiz_Metrics The font's HMTX table is invalid. + Denotes a broken font. + + 0x000C Invalid_CharMap_Format A font's charmap entry has an + invalid format. Some other + entries may be valid though. + + 0x000D Invalid_PPem Invalid PPem values specified, + i.e., you are accessing a scaled + glyph without having called + TT_Set_Instance_CharSize() or + TT_Set_Instance_PixelSizes(). + + 0x0010 Invalid_File_Format The file isn't a TrueType font or + collection. + + 0x0020 Invalid_Engine An invalid engine handle was + passed to one of the API + functions. + + 0x0021 Too_Many_Extensions The client application is trying + to initialize too many + extensions. The default max + extensions number is 8 (this + value can be changed at compile + time). + + 0x0022 Extensions_Unsupported This build of the engine doesn't + support extensions. + + 0x0023 Invalid_Extension_Id This error indicates that the + client application is trying to + use an extension that has not + been initialized yet. + + 0x0080 Max_Profile_Missing The max profile table is missing. + => broken font file + + 0x0081 Header_Table_Missing The font header table is missing. + => broken font file + + 0x0082 Horiz_Header_Missing The horizontal header is missing. + => broken font file + + 0x0083 Locations_Missing The locations table is missing. + => broken font file + + 0x0084 Name_Table_Missing The name table is missing. + => broken font file + + 0x0085 CMap_Table_Missing The character encoding tables are + missing. + => broken font file + + 0x0086 Hmtx_Table_Missing The hmtx table is missing. + => broken font file + + 0x0087 OS2_Table_Missing The OS/2 table is missing. + Mac fonts doesn't have it. + + 0x0088 Post_Table_Missing The PostScript table is missing. + => broken font file + + 0x0089 Glyf_Table_Missing The glyph table is missing. + => broken font file + + ----------------- memory component error codes ------------------- + + 0x0100 Out_Of_Memory An operation couldn't be + performed due to memory + exhaustion. + + ----------------- file component error codes --------------------- + + 0x0200 Invalid_File_Offset Trying to seek to an invalid + portion of the font file. + Denotes a broken file. + + 0x0201 Invalid_File_Read Trying to read an invalid portion + of the font file. Denotes a + broken file. + + 0x0202 Invalid_Frame_Access Trying to frame an invalid + portion of the font file. + Denotes a broken file. + + ----------------- glyph loader error codes ----------------------- + + These errors are produced by the glyph loader. They denote an + invalid glyph record within the font file. + + 0x0300 Too_Many_Points The glyph has too many points to + be valid for its font file. + + 0x0301 Too_Many_Contours The glyph has too many contours + to be valid for its font file. + + 0x0302 Invalid_Composite_Glyph A composite glyph's description + is broken. + + 0x0303 Too_Many_Ins The glyph has too many + instructions to be valid for its + font file. + + ----------------- byte-code interpreter error codes -------------- + + These error codes are produced by the TrueType byte-code + interpreter. They usually indicate a broken font file or a broken + glyph within a font. + + 0x0400 Invalid_Opcode Found an invalid opcode in a + TrueType byte-code stream. + + 0x0401 Too_Few_Arguments An opcode was invoked with too + few arguments on the stack. + + 0x0402 Stack_Overflow The interpreter's stack has been + filled up and operations can't + continue. + + 0x0403 Code_Overflow The byte-code stream runs out of + its valid bounds. + + 0x0404 Bad_Argument A function received an invalid + argument. + + 0x0405 Divide_By_Zero A division by 0 operation was + queried by the interpreter + program. + + 0x0406 Storage_Overflow The program tried to access data + outside of its storage area. + + 0x0407 Cvt_Overflow The program tried to access data + outside of its control value + table. + + 0x0408 Invalid_Reference The program tried to reference an + invalid point, zone, or contour. + + 0x0409 Invalid_Distance The program tried to use an + invalid distance. + + 0x040A Interpolate_Twilight The program tried to interpolate + twilight points. + + 0x040B Debug_Opcode The now invalid `debug' opcode + was found in the byte-code + stream. + + 0x040C ENDF_In_Exec_Stream A misplaced ENDF was encountered + in the byte-code stream. + + 0x040D Out_Of_CodeRanges The program tried to allocate too + much code ranges (this is really + an engine internal error that + should never happen). + + 0x040E Nested_DEFS Nested function definitions + encountered. + + 0x040F Invalid_CodeRange The program tried to access an + invalid code range. + + 0x0410 Invalid_Displacement The program tried to use an + invalid displacement. + + 0x0411 Execution_Too_Long In order to get rid of `poison' + fonts, the interpreter produces + this error if more than one + million opcodes have been + interpreted in a single glyph + program. This detects infinite + loops softly. + + ----------------- internal failure error codes ------------------- + + These error codes are produced if an incoherent library state has + been detected. All of these reflect a severe bug in the engine + (or a severe memory corruption due to massive overwrites by your + application into the library's data)! + + If you do encounter a font that makes one of the test programs + produce such an error, please report it! + + 0x0500 Nested_Frame_Access + 0x0501 Invalid_Cache_List + 0x0502 Could_Not_Find_Context + 0x0503 Unlisted_Object + + ----------------- scan-line converter error codes ---------------- + + These error codes are produced by the raster component. They + indicate that an outline structure was incoherently set up, or + that you are trying to render a horribly complex glyph. + + They should be _extremely_ rare, however. + + 0x0600 Raster_Pool_Overflow Render pool overflow. This should + never happen in this release. + + 0x0601 Raster_Negative_Height A negative height was produced. + + 0x0602 Raster_Invalid_Value The outline data wasn't set + properly. Check that: + points >= endContours[contours] + + 0x0603 Raster_Not_Initialized You did not call + TT_Init_FreeType()! + + +--- end of apiref.txt --- diff --git a/docs/apirefx.txt b/docs/apirefx.txt new file mode 100644 index 0000000..c2d1f44 --- /dev/null +++ b/docs/apirefx.txt @@ -0,0 +1,864 @@ + The FreeType Engine + + Extension Library Reference + + + ----------------------------------- + + + Table of Contents: + + I. Engine extensions + 1. kerning (ftxkern) + 2. PostScript names (ftxpost) + 3. TrueType Open (ftxopen) + a. The `BASE' table (baseline data) + b. The `GDEF' table (glyph definitions) + c. The `GPOS' table (glyph positions) + d. The `GSUB' table (glyph substitions) + e. The `JSTF' table (justification data) + f. auxiliary functions + 4. embedded bitmaps (ftxsbit) + + II. API extensions + 1. cmap iteration (ftxcmap) + 2. internationalized error messages (ftxerr18) + 3. access to the `gasp' table (ftxgasp) + 4. fast retrieval of glyph widths and heights (ftxwidth) + + III. Error codes + + + -------------------- + + +Please read the file `user.txt' for an introduction into FreeType's +extension mechanism and the difference between engine and API +extensions. + + +I. Engine extensions +==================== + +To use engine extensions you have to compile the library with the +macro TT_CONFIG_OPTION_EXTEND_ENGINE. By default, this macro is set +and all engine extensions are linked to the FreeType library. + + + 1. kerning (ftxkern) + -------------------- + + TT_Init_Kerning_Extension( TT_Engine engine ) + + Initializes the kerning extension for a given engine. This must + be called just after the engine creation, and before any face + object allocation. Example: + + TT_Init_FreeType( &engine ); + TT_Init_Kerning_Extension( engine ); + + .................................................................. + + TT_Get_Kerning_Directory( TT_Face face, + TT_Kerning* directory ) + + Queries the kerning directory found in a face object. If no + kerning table is found in the TrueType file, the error + TT_Err_Table_Is_Missing will be returned. + + You can access the subtables through the pointers of the + directory. However, by default, the directory is only loaded if + a face object is created. You must load the subtables that + interest you with a call to TT_Load_Kerning_Table(). + + The layout of all kerning structures is defined in the file + `lib/extend/ftxkern.h'. Formats 0 and 2 (as defined in the + Microsoft TrueType specification) are exposed by this API. + + NOTE: + + This function must be called after the kerning extension has + been initialized. + + .................................................................. + + TT_Load_Kerning_Table( TT_Face face, + TT_UShort kernIndex ) + + Loads the kerning subtable number `kern_index' into memory. The + subtable can be accessed through the pointers provided by the + kerning directory, obtained from a call to the function + TT_Get_Kerning_Directory(). + + Note that the interpretation of the kerning data is left to the + client application. Read the TrueType specification for more + information on kerning encoding. + + NOTE 1: + + This function must be called after the kerning extension were + initialized. + + NOTE 2: + + An example can be found in the file `test/ftstrtto.c'. + + +==================================================================== + + + 2. PostScript names (ftxpost) + ----------------------------- + + TT_Init_Post_Extension( TT_Engine engine ) + + Initializes the PostScript name extension to load the PostScript + glyph names given in the `post' table. This must be called just + after creation of the engine, and before any face object + allocation. See description of TT_Get_PS_Name() for an example. + + .................................................................. + + TT_Load_PS_Names( TT_Face face, + TT_Post* post ) + + Loads the PostScript glyph names into memory. This must be done + before TT_Get_PS_Name() is called. In case of error, either + TT_Err_Invalid_Post_Table or TT_Err_Invalid_Post_Table_Format is + returned. See description of TT_Get_PS_Name() for an example. + + .................................................................. + + TT_Get_PS_Name( TT_Face face, + TT_UShort index, + TT_String** PSname ) + + Get the PostScript glyph name for a given glyph index. A + pointer to the name is returned in `PSname'. Example: + + ... + TT_Post post; + char* PSname; + + ... + TT_Init_Post_Extension( engine ); + TT_Load_PS_Names( face, &post ); + + ... + TT_Get_PS_Name( face, index, &PSname ); + + + NOTE: + + You must not alter the PostScript glyph name string returned + in `PSname'. + + +==================================================================== + + + 3. TrueType Open (ftxopen) + -------------------------- + + Please note that TrueType Open specific error codes have the + prefix `TTO_Err_' instead of `TT_Err_'. + + a. The `BASE' table (baseline data) + + Not yet supported. + + b. The `GDEF' table (glyph definitions) + + TT_Init_GDEF_Extension( TT_Engine engine ) + + Initializes the GDEF extension to load the glyph definition + data given in the `GDEF' table. This must be called just + after creation of the engine, and before any face object + allocation. See the file `ftstrtto.c' for an example. + + ................................................................ + + TT_Load_GDEF_Table( TT_Face face, + TTO_GDEFHeader* gdef ) + + Loads the GDEF table into `gdef' for a given face `face'. + This must be done before any queries about glyph properties + with TT_GSUB_Get_Property(). Returns TT_Err_Table_Missing if + there is no GDEF table in the font. + + ................................................................ + + TT_GDEF_Get_Glyph_Property( TTO_GDEFHeader* gdef, + TT_UShort glyphID, + TT_UShort* property ) + + Use this function to get glyph properties in the variable + `property' for the glyph with index `glyphID' stored in the + `gdef' table. This data is essential for many fonts to + correctly apply contextual substitution (both GSUB and GPOS). + As a special case, zero is assigned to `property' if `gdef' is + NULL or the glyph has no special glyph property assigned to + it. The other return values of `property' are TTO_BASE, + TTO_LIGATURE, TTO_MARK, and TTO_COMPONENT; you can directly + apply the `LookupFlag' mask to check for certain properties: + + TTO_GDEFHeader* gdef; + TTO_Lookup* lo; + TT_UShort glyph_ID; + TT_UShort p; + + + TT_GDEF_Get_Property( gdef, glyph_ID, &p ); + + if ( p & lo->LookupFlag ) + return TTO_Err_Not_Covered; + + Usually, you don't need to take care of glyph properties by + yourself since TT_GSUB_Apply_String() will do this for you by + calling TT_GDEF_Get_Property(). + + Some fonts need GDEF-like data even if no GDEF table is + provided (for example, the Arabic script needs information + which glyphs are base glyphs and which are mark glyphs). In + such cases, you should use TT_GDEF_Build_ClassDefinition() to + build the necessary structures so that TT_GDEF_Get_Property() + returns meaningful values. + + See also TT_Load_GSUB_Table() and TT_Load_GPOS_Table(). + + ................................................................ + + TT_GDEF_Build_ClassDefinition( TTO_GDEFHeader* gdef, + TT_UShort num_glyphs, + TT_UShort glyph_count, + TT_UShort* glyph_array, + TT_UShort* class_array ) + + Fills a `gdef' structure with data to make + TT_GDEF_Get_Property() work in case no GDEF table is + available. `num_glyphs' is the number of glyphs in the font. + + `glyph_count' is the number of glyphs resp. class values (as + specified in the GDEF specification) given in the arrays + `glyph_array' and `class_array', respectively. The glyph + indices in `glyph_array' must be all different and sorted in + ascending order; the function expects that glyph index + `glyph_array[n]' has its class value in `class_array[n]'. + + Note that mark attach classes as defined in OpenType 1.2 are + not supported for constructed GDEF tables. + + See `arabic.c' for an example. + + + c. The `GPOS' table (glyph positions) + + Not yet supported. + + + d. The `GSUB' table (glyph substitions) + + For glyph substitution, a string object of type TTO_GSUB_String + is used. The field `length' holds the length of the string, + `pos' points to the actual position in the glyph string `string' + (for input strings) resp. the position where the substituted + glyphs should be placed at (for output strings). + + Within the `properties' array (which must always have the same + length as `string' if set), you can define properties for glyphs + -- `string[n]' is associated with `properties[n]'. The idea is + that some features apply to specific glyphs only. As an + example, the `fina' feature for Arabic applies only to glyphs + which appear at the end of a word (strictly speaking, this + feature is used only for glyphs which have a `final' property; + such glyphs can occur in the middle of a word also under certain + circumstances which is dependent on Arabic script rules). The + relationship between properties and features can be set up with + the function TT_GSUB_Add_Feature(). If `properties' is set to + NULL, all selected features apply to all glyphs in the given + string object. If `properties' is non-NULL, the elements of the + array are treated as bit fields. A set flag means that the + corresponding feature (as set with the TT_GSUB_Add_Feature() + function) should not be applied to the particular glyph. As a + consequence, a zero value for these 16 bits means that all + features should be applied, and a value of 0xFFFF implies that + no feature at all should be used for the glyph. + + The field `allocated' is for internal use only and must not be + modified. If its value is larger than zero, you should use + free() to deallocate the memory used by `string' (and + `properties' if set) in case you want to destroy a + TTO_GSUB_String object (memory for `string' and `properties' is + allocated automatically e.g. by TT_GSUB_Apply_String() for + output string objects). + + struct TTO_GSUB_String_ + { + TT_ULong length; + TT_ULong pos; + TT_ULong allocated; + TT_UShort* string; + TT_UShort* properties; + }; + + typedef struct TTO_GSUB_String_ TTO_GSUB_String; + + Note that the `string' field must contain glyph indices, not + character codes. + + For initializing an input string object, you should set the + `length', `string', and `properties' fields (the last one only + if necessary) to appropriate values. `pos' has to be set to the + position where the substitution lookups should start (usually + zero). The `allocated' field will be ignored. + + For initializing an output string object, all fields (except + `length' which will be ignored) must be set to zero. If you + want to reuse the object, set `pos' to the position where the + substituted glyphs should be placed at (usually zero), but don't + touch the `allocated', `string', and `properties' fields. + + ................................................................ + + TT_Init_GSUB_Extension( TT_Engine engine ) + + Initializes the GSUB extension to load the glyph substitution + data given in the `GSUB' table. This must be called just + after creation of the engine, and before any face object + allocation. See the files `ftstrtto.c' and `ftdump.c' for + detailed examples. + + ................................................................ + + TT_Load_GSUB_Table( TT_Face face, + TTO_GSUBHeader* gsub, + TTO_GDEFHeader* gdef ) + + Loads the GSUB table into `gsub' for a given face `face'. + This must be done before any queries about or selection of + scripts, languages, and features. Returns + TT_Err_Table_Missing if there is no GSUB table in the font. + + `gdef' should contain a pointer to an associated GDEF table, + either a native one loaded with TT_Load_GDEF_Table() or + emulated with TT_GDEF_Build_ClassDefinition(). If `gdef' is + set to NULL, no GDEF data will be used. + + ................................................................ + + TT_GSUB_Select_Script( TTO_GSUBHeader* gsub, + TT_ULong script_tag, + TT_UShort* script_index ) + + This function sets the script index of a given script tag + `script_tag' in the variable `script_index' for the GSUB table + `gsub'. Returns TTO_Err_Not_Covered if the script tag cannot + be found. The available script tags can be queried with the + function TT_GSUB_Query_Scripts(). + + ................................................................ + + TT_GSUB_Select_Language( TTO_GSUBHeader* gsub, + TT_ULong language_tag, + TT_UShort script_index, + TT_UShort* language_index, + TT_UShort* req_feature_index ) + + This function sets the language index of a given language tag + `language_tag' and script index `script_index' in the variable + `language_index' for the GSUB table `gsub'. Returns + TTO_Err_Not_Covered if the language tag cannot be found. The + available language tags can be queried with the function + TT_GSUB_Query_Languages(). + + Additionally, the index of the required feature for this + language system is returned in `req_feature_index'; it must be + later registered for use with TT_GSUB_Add_Feature(). + + ................................................................ + + TT_GSUB_Select_Feature( TTO_GSUBHeader* gsub, + TT_ULong feature_tag, + TT_UShort script_index, + TT_UShort language_index, + TT_UShort* feature_index ) + + This function sets the feature index of a feature tag + `feature_tag', script index `script_index', and language index + `language_index' in the variable `feature_index' for the GSUB + table `gsub'. Returns TTO_Err_Not_Covered if the feature tag + cannot be found. The available feature tags can be queried + with the function TT_GSUB_Query_Features(). Setting + language_index to 0xFFFF selects the default language system. + + ................................................................ + + TT_GSUB_Query_Scripts( TTO_GSUBHeader* gsub, + TT_ULong** script_tag_list ) + + Returns the available script tags for a given GSUB table + `gsub' in the array `script_tag_list'. The array can be later + deallocated with free(). + + ................................................................ + + TT_GSUB_Query_Languages( TTO_GSUBHeader* gsub, + TT_UShort script_index, + TT_ULong** language_tag_list ) + + Returns the available language tags for a given GSUB table + `gsub' and script index `script_index' in the array + `language_tag_list'. The array can be later deallocated with + free(). + + ................................................................ + + TT_GSUB_Query_Features( TTO_GSUBHeader* gsub, + TT_UShort script_index, + TT_UShort language_index, + TT_ULong** feature_tag_list ) + + Returns the available feature tags for a given GSUB table + `gsub', script index `script_index', and language index + `language_index' in the array `feature_tag_list'. If language + index is set to 0xFFFF, the values for the default language + system are returned. The array can be later deallocated with + free(). + + ................................................................ + + TT_GSUB_Add_Feature( TTO_GSUBHeader* gsub, + TT_UShort feature_index, + TT_UShort property ) + + To prepare a call to TT_GSUB_Apply_String() which should + process a given feature with index `feature_index' and the + property `property', you must use this function. Its task is + to mark the lookup tables used by the feature for further + processing. + + `property' defines a relationship between the input string + object and the specific feature. The client must handle this + variable as a bit field, i.e., up to 16 user properties can be + defined. If `property' is set to ALL_GLYPHS (0xFFFF, the only + predefined value), or if the input string object has no set + bits in the `properties' field, the feature applies to all + glyphs. If bit `x' is set in `property', the feature applies + only to glyphs which have bit `x' not set in glyph's + `properties' field in the input string object. See + TT_GSUB_Apply_String() for an example. + + Returns TT_Err_Invalid_Argument in case of error. + + ................................................................ + + TT_GSUB_Clear_Features( TTO_GSUBHeader* gsub ) + + Clears the list of used features and properties. No lookup + tables will be processed. + + ................................................................ + + TT_GSUB_Register_Alternate_Function( TTO_GSUBHeader* gsub, + TTO_AltFunction alt, + void* data ) + + Installs a callback function to handle alternate + substitutions. `data' is a generic pointer to a user-defined + structure which will be completely ignored by the ftxopen + extension. `alt' is a function pointer defined as + + typedef TT_UShort + (*TTO_AltFunction)(TT_ULong pos, + TT_UShort glyphID, + TT_UShort num_alternates, + TT_UShort* alternates, + void* data ); + + If TT_GSUB_Apply_String() encounters an alternate lookup while + processing the input string, it will call the function `alt' + to find out which alternate glyph it should use. `pos' gives + the position in the string, `glyphID' the glyph ID of the + glyph to be replaced with an alternate glyph, and + `num_alternates' the number of alternate glyphs in the + `alternates' array. A pointer to the user-defined `data' + structure is also available. `alt' must return an index into + `alternates'. + + If `alt' is NULL or if this function isn't called at all, + TT_GSUB_Apply_String() will always use the first alternate + glyph. + + Please note that theoretically an alternate lookup can happen + during any other lookup! For example, a lookup chain like + + single subst -> alternate subst -> ligature subst + + *is* possible (albeit rather unlikely). Thus be warned that + `pos' does not necessarily reflect the position of a glyph to + be displayed at all, nor does `glyphID' specifies a glyph + which will be in the final output string. + + ................................................................ + + TT_GSUB_Apply_String( TTO_GSUBHeader* gsub, + TTO_GSUB_String* in, + TTO_GSUB_String* out ) + + This is the very function which handles glyph substitution + according to the features set up with TT_GSUB_Add_Feature(), + using both GSUB and GDEF data (if defined). Two + TTO_GSUB_String objects `in' and `out' (as described above) + are taken for input and output; after successful excecution, + the converted glyph string can been found in `out', and + `out.length' gives the actual length of the output string + (counted from the begin of the array). + + Example: + + /* We assume that the feature `xxxx' has index 5, and */ + /* feature `yyyy' has index 8, applying only to glyphs */ + /* with the property `FINAL_GLYPHS' set (0x1000 is an */ + /* ad-hoc value just for this example). */ + + /* The order of calls to TT_GSUB_Add_Feature() is not */ + /* significant. */ + + #define FINAL_GLYPHS 0x1000 + + TT_GSUB_Clear_Features( &gsub ); + TT_GSUB_Add_Feature( &gsub, 8, FINAL_GLYPHS ); + TT_GSUB_Add_Feature( &gsub, 5, ALL_GLYPHS ); + + TT_GSUB_Apply_String( &gsub, &in, &out ); + + You must initialize both `in' and `out' structures; allocation + necessary for the `out' object will be handled automatically. + + In case you don't register a function to handle alternate + substitutions (GSUB lookup 3), always the first alternate + glyph will be used. See TT_GSUB_Register_Alternate_Function() + above for more details. + + + e. The `JSTF' table (justification data) + + Not yet supported. + + + f. auxiliary functions + + TT_GSUB_Add_String( TTO_GSUB_String* in, + TT_UShort num_in, + TTO_GSUB_String* out, + TT_UShort num_out, + TT_UShort* data ) + + This function copies `num_out' elements from `data' to `out', + advancing the array pointer `in.pos' by `num_in' elements and + `out.pos' by `num_out' elements. If the string (resp. the + properties) array in `out' is empty or too small, it allocates + resp. reallocates the string (and properties) array. + Finally, it sets `out.length' equal to `out.pos'. + + The properties for all replaced glyphs are taken from the + glyph at position `in->pos'. + + TT_GSUB_Add_String() is normally used in + TT_GSUB_Apply_String(); you will need it for the special case + to skip some glyphs (i.e., copy glyphs directly from the `in' + to the `out' object), bypassing a possible GSUB substitution. + + Here an example which copies one glyph: + + TT_GSUB_Add_String( in, 1, + out, 1, + &in->string[in->pos] ); + + +==================================================================== + + + 4. embedded bitmaps (ftxsbit) + ----------------------------- + + TT_Init_SBit_Extension( TT_Engine engine ) + + Initializes the embedded bitmap extension to load the bitmap + glyphs given in the various sbit tables: `EBLC', `bloc', `EBDT', + and `bdat' (`bloc' and `bdat' tables are only in Apple fonts; + the former is equivalent to `EBLC', the latter equivalent to + `EBDT'). This must be called just after creation of the engine, + and before any face object allocation. See description of + TT_Load_Glyph_Bitmap() for an example. + + .................................................................. + + TT_Get_Face_Bitmaps( TT_Face face, + TT_EBLC* eblc_table ) + + Loads the `EBLC' (resp. `bloc') table from a font file into the + `eblc_table' structure. Use this function for testing whether + embedded bitmaps are available or not. + + This function returns TT_Err_Table_Missing if the font contains + no embedded bitmaps. All fields in `eblc_table' will then be + set to 0. + + .................................................................. + + TT_New_SBit_Image( TT_SBit_Image** image ) + + Allocates a new embedded bitmap container, pointed to by + `image'. + + .................................................................. + + void TT_Done_SBit_Image( TT_SBit_Image* image ) + ^^^^ + + Releases the embedded bitmap container `image'. + + .................................................................. + + TT_Get_SBit_Strike( TT_Face face, + TT_Instance instance, + TT_SBit_Strike* strike ) + + Loads a suitable strike (i.e. bitmap sizetable) for the given + instance. Will return TT_Err_Invalid_PPem if there is no strike + for the current x_ppem and y_ppem values. + + .................................................................. + + TT_Load_Glyph_Bitmap( TT_Face face, + TT_Instance instance, + TT_UShort glyph_index, + TT_SBit_Image* bitmap ); + + Loads a glyph bitmap for a given glyph index `glyph_index' (in + face `face' and instance `instance') into `bitmap'. It calls + TT_Get_SBit_Strike() internally for checking the current x_ppem + and y_ppem values. + + This function returns an error if there is no embedded bitmap + for the glyph at the given instance. + + Example (omitting the error handling): + + ... + TT_SBit_Image* bitmap; + + ... + TT_Init_SBit_Extension( engine ); + TT_New_SBit_Image( &bitmap ); + ... + TT_Load_Glyph_Bitmap( face, instance, glyph_index, bitmap ); + + + +-------------------------------------------------------------------- +-------------------------------------------------------------------- + + + +II. API extensions +================== + +To use API extensions, simply compile the specific extension file +and link it to the library or your program. By default, all +extensions described below are linked to the library. + + + 1. cmap iteration (ftxcmap) + --------------------------- + + TT_Long TT_CharMap_First( TT_CharMap charMap, + ^^^^^^^ TT_UShort* glyph_index ) + + + Returns the first valid character code in a given character map + `charMap'. Also returns the corresponding glyph index (in the + parameter `*glyph_index'). In case of failure, -1 is returned, + and `*glyph_index' is undefined. + + .................................................................. + + TT_Long TT_CharMap_Next( TT_CharMap charMap, + ^^^^^^^ TT_UShort last_char, + TT_UShort* glyph_index ) + + Returns the next valid character code in a given character map + `charMap' which follows `last_char'. Also returns the + corresponding glyph index (in the parameter `*glyph_index'). In + case of failure, -1 is returned, and `glyph_index' is undefined. + + .................................................................. + + TT_Long TT_CharMap_Last( TT_CharMap charMap, + ^^^^^^^ TT_UShort* glyph_index ) + + + Returns the last valid character code in a given character map + `charMap'. Also returns the corresponding glyph index (in the + parameter `*glyph_index'). In case of failure, -1 is returned, + and `*glyph_index' is undefined. + + +==================================================================== + + + 2. internationalized error messages (ftxerr18) + ---------------------------------------------- + + This extension provides internationalized error strings from the + various error messages. It uses the `gettext' package if + available or returns English/American message strings if not. + Currently, the gettext package is only available on UNIX-like + systems like Linux; this means that for other platforms only + English error strings are returned. + + If the gettext package is found on your system, the configure + script automatically includes it by default. In case you don't + want to use it, or if you encounter some problems compiling this + file, try to disable nls support by configuring FreeType with + `./configure --disable-nls'. + + Please read the gettext info files for more information how to set + up your system for internationalized messages. A short + introduction is also given in the file `i18n.txt'. + + + TT_String* TT_ErrToString18( TT_Error i ) + ^^^^^^^^^^ + + This function returns an error string for a given error code + `i'. The type `TT_String' usually defaults to `char'; see + apiref.txt for more details. + + An example how to use this function (in connection with the + gettext interface) is given e.g. in test/ftdump.c. + + +==================================================================== + + + 3. access to the `gasp' table (ftxgasp) + --------------------------------------- + + The `gasp' table is currently loaded by the core engine, but the + standard API doesn't give access to it. + + + TT_Get_Face_Gasp_Flags( TT_Face face, + TT_UShort point_size, + TT_Bool* grid_fit, + TT_Bool* smooth_font ) + + This function returns for a given `point_size' the values of the + gasp flags `grid_fit' and `smooth_font'. The returned values + are booleans (where 0 = NO, and 1 = YES). + + Note that this function will return TT_Err_Table_Missing if the + font file doesn't contain any gasp table. + + +==================================================================== + + + 4. fast retrieval of glyph widths and heights (ftxwidth) + -------------------------------------------------------- + + This extension is used to parse the `glyf' table of a TrueType + file in order to extract the bounding box of a given range of + glyphs. + + The bounding box is then used to build font unit widths and + heights that are returned in two parallel arrays. + + This extension is needed by the FreeType/2 OS/2 Font Driver. + + + TT_Get_Face_Widths( TT_Face face, + TT_UShort first_glyph, + TT_UShort last_glyph, + TT_UShort* widths, + TT_UShort* heights ) + + Returns the widths (in array `widths') and heights (in array + `heights') of a glyph range which starts at `first_glyph' and + ends at `last_glyph'. All returned values are returned in font + units. If either `widths' or `heights' is set to a NULL + pointer, no data will be returned for that particular array. + + Note: TT_Get_Face_Widths() does *not* allocate the two arrays! + + + +-------------------------------------------------------------------- +-------------------------------------------------------------------- + + + +III. Error Messages +=================== + + Most functions return an error code, typed to TT_Error. A return + value of zero indicates no error. The error values are defined in + the various extension header files (e.g. ftxkern.h). In the + following table, the prefix `TT_Err_' is omitted, e.g. `Ok' -> + `TT_Err_Ok'. + + + Error Unprefixed Error + Code Macro Name Description + ------------------------------------------------------------------ + + 0x0A00 Invalid_Kerning_Table_Format + An invalid kerning subtable + format was found in this font. + + 0x0A01 Invalid_Kerning_Table A kerning table contains illegal + glyph indices. + + 0x0B00 Invalid_Post_Table_Format + The post table format specified + in the font is invalid. + + 0x0B01 Invalid_Post_Table The post table contains illegal + entries. + + + Here the TrueType Open error codes. In the following table, the + prefix `TTO_Err_' is omitted. + + + Error Unprefixed Error + Code Macro Name Description + ------------------------------------------------------------------ + 0x1000 Invalid_SubTable_Format The TrueType Open subtable format + specified in the font is invalid. + + 0x1001 Invalid_SubTable A TrueType Open subtable contains + illegal entries. + + 0x1002 Not_Covered The requested feature, glyph, + etc. isn't covered by the actual + function. + + 0x1010 Invalid_GSUB_SubTable_Format + The GSUB subtable format + specified in the font is invalid. + + 0x1011 Invalid_GSUB_SubTable The GSUB subtable contains + illegal entries. + + 0x1020 Invalid_GPOS_SubTable_Format + The GPOS subtable format + specified in the font is invalid. + + 0x1021 Invalid_GPOS_SubTable The GPOS subtable contains + illegal entries. + + +--- end of apirefx.txt --- diff --git a/docs/bitmaps.txt b/docs/bitmaps.txt new file mode 100644 index 0000000..847befe --- /dev/null +++ b/docs/bitmaps.txt @@ -0,0 +1,771 @@ + + Bitmap and Pixmap generation with FreeType + ------------------------------------------ + + Table of Contents + + + Introduction + + I. The rasterizer component + + II. Bitmap & pixmap descriptors + + III. Rendering an outline + + IV. Anti-aliasing palette and other concerns + + Conclusion + + + +Introduction +------------ + + This document describes the steps that are needed to render a + glyph outline into a bitmap or a pixmap with the FreeType library. + It contains several important details needed to generate bitmaps + correctly in all situations, including if an outline has been + transformed or translated. + + +-------------------------------------------------------------------- + + +I. The rasterizer component +--------------------------- + + In FreeType, the component in charge of performing bitmap and + pixmap rendering is called the `rasterizer'. Generation is + performed through a traditional process called `scan-line + conversion', but exhibits certain properties: + + - The rasterizer doesn't allocate bitmaps: + + In fact, it is only able to render an outline into an existing + bitmap or pixmap, which is passed to one of its rendering + functions. This means that the target bitmap/pixmap must be set + up correctly by the caller to achieve desired results. Setting + up bitmap and pixmap descriptors is explained in section II. + + - It is able to render anti-aliased pixmaps directly: + + This is unlike other graphics packages, which render to a + `large' bitmap which is then filtered down. Putting the + anti-aliasing logic within the rasterizer improves performance + and reduces memory usage, as well as lets us use better + algorithms which couldn't work in a `two-phase' process. + + The rasterizer is located in the files `ttraster.h' and + `ttraster.c' (or `ttraster.pas' for the Pascal version -- + unfortunately, this is severely out of date). + + The format of outlines isn't important for most developers and + won't be discussed here. However, a few conventions must be + explained regarding the vector outlines: + + + 1. Units + + All point coordinates within an outline are stored in 32-bit + fractional pixel values, using the 26.6 fixed float format + (which uses 26 bits for the integer part, and 6 bits for the + fractional part). The following table gives some examples of + real versus 26.6 coordinates: + + ----------------------------------------- + real real coord 26.6 coord + coord. * 2^6 + ----------------------------------------- + 0 0*64 = 0.0 0 + 2.4 2.4*64 = 153.6 154 + 3 3*64 = 192.0 192 + -1.7 -1.7*64 = -108.8 -109 + + As you can see, conversion is relatively simple -- basically a + multiplication by 64. + + In order to differentiate coordinates expressed in real or 26.6 + systems, we'll use in the following lines brackets (`[' and `]') + for real coordinates, and simple parentheses (`(' and `)') for + fractional coordinates so that + + [1.0,2.5] equals (64,160) + + [0,0] equals (0,0) + + [-2,3] equals (-128,192) + + + 2. Orientation + + The rasterizer uses the traditional convention of an X axis + oriented from left to right, and of a Y axis oriented from + bottom to top. + + ^ Y + | + | + | + -*-----> X + | + + You've probably already used it at school when doing math :-) + + Though the orientation of bitmap lines has the opposite + direction on nearly all graphics systems, the former convention + is the _right_ one when it comes to vector graphics. The reason + is simply that for managing angles and vector cross-products + resp. orientations in complex algorithms, a single convention, + used in math as well as computing alike solves many headaches. + + And due to education, most people expect a 45 degrees angle to + be in the top right quadrant, at coordinate (1,1). + + + 3. Pixels and the grid + + In a vector outline, a point is immaterial and has no size or + width, just like in usual geometry. A `pixel' is an element of + a computer image called a `map' (like a bitmap or a pixmap). + + The FreeType rasterizer follows the convention defined by the + TrueType specification regarding pixel placement: + + - The map can be seen as a `grid' placed in the vector plane. + The grid lines are set on integer real coordinates (i.e., on + multiples of 64 in 26.6 fractional notation). + + Each pixel is one `cell' of the grid, and can be `lit' with + any color. Hence, each pixel has a width and a height of + [1.0] units, (i.e., 64 fixed float units). + + ^ Y + | + | The pixel grid with two + | points (not pixels!) + +-----+-----+-----+-----+-----+ at coordinates [0,0] + | | | | | | and [2,2]. + | | | | | | + | | | | |[2,2]| + +-----+-----+-----+-----@-----+ The pixels are the + | | |11111|22222| | grid's cells, and this + | | |11111|22222| | example show the four + | | |11111|22222| | pixels enclosed within + +-----+-----+-----+-----+-----+ the rectangle delimited + | | |33333|44444| | by these two points. + | | |33333|44444| | + | | |33333|44444| | + --+-----+-----@-----+-----+-----+----> X + | | |[0,0]| | | + | | | | | | Note that the numbering + | | | | | | of pixels isn't + +-----+-----+-----+-----+-----+ meaningful here, it's + | | | | | | only used to distinguish + | | | | | | them. + | | | | | | + +-----+-----+-----+-----+-----+ + | + | + + - The `center' of each pixel is always located on a + `half-integer' coordinate, i.e., at -1.5, -0.5, 0.5, 1.5, etc. + + - When drawing a shape, the rasterizer only `lits' a pixel when + its center is placed _within_ the shape. This is important + because an outline point may not be necessarily be on a grid + line. + + - When a pixel center falls on the shape, the pixel is lit too. + + For example, the following graphics show the `lit' pixels + corresponding to the rectangle enclosed by the points: + + [-0.2, 0] and [2.4, 2.7] + + + ^ Y As one can see, the + | newest pixels `1' + | and `2' are now lit, + | because its centers + +-----+-----+-----+-----+--[2.4,2.7] are located at + | | |11111|22222| @ | coordinates + | . | . |11.11|22.22| . | [0.5,2.5] and + | | |11111|22222| | [1.5,2.5], + +-----+-----+-----+-----+-----+ respectively. + | | |33333|44444| | + | . | . |33.33|44.44| . | Note that pixel + | | |33333|44444| | centers are + +-----+-----+-----+-----+-----+ represented with a + | | |55555|66666| | dot in the graphics. + | . | . |55.55|66.66| . | + | | |55555|66666| | + --+-----+----@+-----+-----+-----+----> X + | | [-0.2,0] | | | + | . | . | . | . | . | + | | | | | | Note also that pixel + +-----+-----+-----+-----+-----+ numbering is still + | | | | | | meaningless there. + | . | . | . | . | . | + | | | | | | + +-----+-----+-----+-----+-----+ + | + | + + + 4. Drop-out control + + Sometimes, a stroke is too thin to even contain a single pixel + center. This results in `lost continuity' in the resulting + bitmap, i.e., some unpleasant `holes' or `breaks' in the + rendered shape, which are called a `drop-out'. + + Because a glyph representation uses curves (Bezier arcs), this + case is not easily controllable during the `hinting' of glyph + outlines by the font driver, which means that the rasterizer + must be able to correct these `artefacts'. + + This processing is called `drop-out control', and can be + performed in several modes, defined by the TrueType + specification, and which details do not belong to this document. + However, the important idea is that, in _some_ cases, a pixel + may be lit even if its center isn't part of the shape. + + This case is relatively rare, but is mentioned because it has + consequences of the rendering of maps. More precisely, in the + way an outline's extent is computed (see below). + + +-------------------------------------------------------------------- + + +II. Bitmap and pixmap descriptors +--------------------------------- + + The Freetype rasterizer only supports bitmaps and 8-bit pixmaps. + In order to render an outline, a map descriptor must be sent to + its rendering functions, along with a vectorial outline. + + + 1. Bitmap properties + + This section explains how to set up a bitmap descriptor, and how + vector coordinates in the outline plane relate to pixel + positions within the bitmap buffer. + + A bitmap's `raw data' is made of a simple bit buffer where each + bit corresponds to a monochrome pixel. For the sake of + simplicity, the FreeType rasterizer uses the following + conventions to store bitmaps in a buffer: + + - The value 0 is used for `unlit' pixels, usually the + `background' when rendering text. Hence 1 is used for `lit'. + + - Lines are padded to 8 bits, i.e. bytes. A bitmap row thus + takes an integral number of bytes in its buffer. No further + alignment is required. + + (Some systems compress bitmaps by _not_ padding bit rows to + byte boundaries. It is not possible to render into such a + bitmap buffer with FreeType.) + + - In a bitmap buffer byte, the left-most pixel is represented by + the most significant bit (i.e., 0x80). + + The opposite convention is not supported by the FreeType + rasterizer, though it may possibly be implemented too if this + ever comes useful (ask the developers -- for now, nobody did). + + - Increasing offsets within a row correspond to right-most + positions in the bitmap (i.e., byte 1 contains the + 8 bits/pixels that are located on the right of the + 8 bits/pixels of byte 0). + + - A bitmap can be oriented in two ways: + + o If increasing row addresses within the buffer correspond to + lower vertical lines, the bitmap is said to go `down'. This + is, for example, the case of nearly all video RAMs. + + o If increasing row addresses within the buffer correspond to + higher vertical lines, the bitmap is said to go `up'. This + is the case, for example, for OS/2 bitmaps. + + The `direction' of a bitmap is called `flow' to avoid any + confusion. In both cases, the rasterizer ALWAYS matches the + vector coordinate (0,0) with the lower-left corner of the + *lower-left* pixel in the bitmap. + + The following graphics illustrate these ideas: + + + + Y ^ + | A `down-flow' bitmap. + +--+--+--+--+--+--+--+--+ On the left is each + | | | | | | | | | row's number and its + 0: 0 | | | | | | | | | offset in the bitmap + +--+--+--+--+--+--+--+--+ buffer (where `w' is + | | | | | | | | | the width, in bytes, + 1: w | | | | | | | | | of a single bitmap + +--+--+--+--+--+--+--+--+ row). Note that the + | | | | | | | | | origin is located at + 2: 2*w | | | | | | | | | the lower left, i.e., + +--+--+--+--+--+--+--+--+ near the leftmost bit + | | | | | | | | | of the last bitmap + 3: 3*w | | | | | | | | | row. + -@--+--+--+--+--+--+--+-----> X + |[0,0] + + + + Y ^ + | An `up-flow' bitmap. + +--+--+--+--+--+--+--+--+ On the left is each + | | | | | | | | | row's number and its + 3: 3*w | | | | | | | | | offset in the bitmap + +--+--+--+--+--+--+--+--+ buffer (where `w' is + | | | | | | | | | the width, in bytes, + 2: 2*w | | | | | | | | | of a single bitmap + +--+--+--+--+--+--+--+--+ row). Note that the + | | | | | | | | | origin is located at + 1: w | | | | | | | | | the lower left, i.e., + +--+--+--+--+--+--+--+--+ near the first bit in + | | | | | | | | | the buffer. + 0: 0 | | | | | | | | | The first buffer bit + -@--+--+--+--+--+--+--+-----> X corresponds to the + |[0,0] rectangle [0,0]-[1,1] + in the vector plane. + + + 2. Bitmap descriptors + + Now that you understand all these details, a bitmap can be + described to the rasterizer engine through a map, which + structure must be set up by client application: + + struct TT_Raster_Map_ + { + int rows; /* number of rows */ + int cols; /* number of columns (bytes) per row */ + int width; /* number of pixels per line */ + int flow; /* bitmap orientation */ + + void* bitmap; /* bit/pixmap buffer */ + long size; /* bit/pixmap size in bytes */ + }; + typedef struct TT_Raster_Map_ TT_Raster_Map; + + where the fields stand for: + + rows: + The number of rows within the bitmap buffer. + + cols: + The number of columns, i.e. bytes per row within the + buffer. It corresponds to the `w' value used in the above + graphics. + + width: + The number of pixels (i.e. bits) per row in the buffer. The + rasterizer always clips its rendering to the bit width + specified in this field, even if the `cols' fields + corresponds to a larger width. + + flow: + The bitmap flow. Use the constants TT_Flow_Up and + TT_Flow_Down exclusively for this field. + + bitmap: + A typeless pointer to the bit buffer. + + size: + The total size of the bit buffer in bytes. This is not used + directly by the rasterizer, so applications can use it. + + Note that the `cols' field should always be bigger than the + value of `width' multiplied by 8. The rasterizer clips the + generated bitmap to the `width' first bits in a row. + + Note also that it is of course allowed to create, for example, a + Windows or X11 bitmap through a normal system-specific API call, + using a TT_Raster_Map that describes it to the rasterizer. It + is thus possible to draw directly into such OS specific + structures. + + + IMPORTANT: ***************************************************** + + When rendering a bitmap, the rasterizer always OR-es the shape + on the target bitmap. It is thus possible to draw several + shapes into a single surface which successive calls to the + render functions. + + **************************************************************** + + + 3. Pixmap properties + + The rasterizer only supports 8-bit pixmaps, where one pixel is + represented by a single byte. They must conform to the + following rules: + + - A 5-entries palette is used to generate an outline's pixmap in + the buffer. They correspond to: + + palette[0] -> background + palette[1] -> `light' + palette[2] -> `medium' + palette[3] -> `dark' + palette[4] -> foreground + + where the terms `light', `medium', and `dark' correspond to + intermediate values between the first (background) and last + (foreground) entry. + + The upcoming FreeType 2.0 will feature an additional + anti-aliasing logic with a 17-entries palette. + + - Lines are padded to 32 bits, i.e. 4 bytes. A pixmap row thus + takes a multiple of 4 bytes in its buffer. + + - Increasing offsets within a row correspond to right-most + positions in the bitmap (i.e., byte/pixel 1 is to the right of + byte/pixel 0). + + - A pixmap can be oriented in two ways, following the same rules + as a bitmap regarding its flow. + + + IMPORTANT: ***************************************************** + + In order to improve performance when rendering large outlines + with anti-aliasing, the rasterizer draws pixels in runs of + 4-bytes ONLY when at least one of their `colour' isn't 0 + (background). + + This means that you should ALWAYS CLEAR the pixmap buffer before + calling the rendering function, you may otherwise experience + ugly artefacts, which are possibly left from a previous + rendering! + + In general, it is not possible to do colour compositing with the + FreeType rasterizer (compositing is if you want to superpose a + transparent coloured layer on top of an image). This is mainly + due to the fact that: + + - There are too many pixel formats to support. + + - There is not a single portable way to do it anyway. + + - It really is a graphics processing question, not one that + should be solved by a text rendering engine. + + **************************************************************** + + + 4. Pixmap descriptors + + Pixmaps use the same descriptor structure as bitmaps, with a few + differences in interpretation: + + - The `cols' field is used to indicate the number of _bytes_ in + a pixmap row. It must thus be a multiple of 4! + + - The rasterizer clips the outline to the first `width' + pixels/width within each buffer row. + + As usual, it should be possible to use a system-specific pixmap + and render directly into it, as long as you set up a descriptor + for it. + + +------------------------------------------------------------------------- + + +III. Rendering an outline +------------------------- + + Now that you understand how the rasterizer sees the target bitmaps + and pixmaps it renders to, this section will explain how the + rendering eventually happen. + + + 1. Outline coordinates and extents + + Let's first consider the case where we're rendering text + directly into a huge single bitmap. To do that, we simply + translate each glyph outline before calling the rasterizer. + Here the roadmap: + + - Vectorial coordinates [0,0] are mapped to the lower left + `corner' (in the grid) of the lower left pixel in the bitmap + (whatever its flow is). + + - When the glyph loader returns an outline, the latter is placed + so that the coordinate [0,0] corresponds to the current cursor + position. + + This means that: + + - If we use our own cursor (cx,cy) within the bitmap during text + rendering, we must translate the outline to its position + before rendering it, e.g. with + + TT_Translate_Outline( outline, cx, cy ) + + (and the cursor position must be incremented after rendering + each glyph). + + - Before translation (i.e., when it is returned by the glyph + loader), the glyph outline doesn't necessarily lie on any of + the coordinate axes, nor is it limited to the first quadrant + (i.e., x>0 and y>0 is not true in general). + + Its extent can be computed with the function + TT_Get_Outline_BBox(), which returns the minimum and maximum + values of its X and Y point coordinates (in 26.6 format, of + course). + + + 2. Computing an outline's dimensions in pixels + + In many cases, however, it is much better to render individual + glyph bitmaps, then cache them with appropriate metrics in order + to render text much more quickly at a given point size. + + To be able to render the smallest possible bitmap, the exact + outline's extent dimensions in pixel are required. Again a + roadmap: + + - Get the outline's bounding box in vector coordinates: + + Simply call the TT_Get_Outline_BBox() function which will + return the values of xMin, yMin, xMax, and yMax in vector + (i.e. fractional) coordinates. + + - Grid-fit the bounding box: + + Because of the way pixels are lit in the bitmaps relative to + the position of their `centers' within the shape (see + section I), it is necessary to align the values of xMin, xMax, + yMin, and yMax to the pixel grid in order to compute the width + and height of the resulting bitmap. This can be done with: + + xMin = FLOOR ( xMin ); with FLOOR(x) == (x & -64) + xMax = CEILING( xMax ); CEILING(x) == ((x+63) & -64) + yMin = FLOOR ( yMin ); + yMax = CEILING( yMax ); + + The extents in pixels can then be simply computed as: + + pixel_width = (xMax - xMin) / 64; + pixel_height = (yMax - yMin) / 64; + + Note that because of drop-out control, and because the + bounding box computed currently includes all Bezier control + points from the outline, the bitmap may be slightly larger + than necessary in some cases. + + Some improvements are planned for FreeType 2.0; for now, you + should consider that finding the `exact' bitmap bounding box + requires to scan all `borders' to detect null columns or rows. + However, the values are right in most cases. + + NOTE: It seems that in some *rare* cases, which relate to + weird drop-out control situations, the above dimensions + are not enough to store all bits from the outline (there + are one or more bits `cut' on the edge). + + This being hard to study (it only appears in very poorly + hinted fonts), we leave this problem to FreeType 2.0. + + - Create/setup a bitmap with the computed dimensions. DON'T + FORGET TO CLEAR ITS BUFFER TOO! + + - Translate the outline to stick within the bitmap space. This + is done easily by translating it by (-xMin,-yMin), where you + should ALWAYS USE THE GRID-FITTED VALUES computed above for + xMin and yMin: + + TT_Translate_Outline( outline, -xMin, -yMin ); + + + IMPORTANT: *************************************************** + + For technical reasons, you should never translate a HINTED + outline by a non-integer vector (i.e., a vector which + coordinates aren't multiples of 64)! This would CERTAINLY + completely RUIN the delicate HINTING of the glyph, and will + result probably in pure GARBAGE at small point sizes. + + Of course, if you're not interested in hinting, like when + displaying rotated text, you can ignore this rule and + translate to any position freely. + + ************************************************************** + + - Render the bitmap (or pixmap). + + DON'T FORGET TO STORE THE GRID-FITTED xMin and yMin WITH THE + BITMAP! This will allow you later to place it correctly + relative to your cursor position. + + + Here's some example pseudo code: + + { + ... load the glyph ... + + TT_Outline outline; + TT_BBox bbox; + TT_Raster_Map bitmap; + + + /* get the outline */ + TT_Get_Glyph_Outline( glyph, &outline ); + + /* compute its extent */ + TT_Get_Outline_BBox( &outline, &bbox ); + + /* Grid-fit it */ + bbox.xMin &= -64; + bbox.xMax = ( bbox.xMax + 63 ) & -64; + bbox.yMin &= -64; + bbox.yMax = ( bbox.yMax + 63 ) & -64; + + /* compute pixel dimensions */ + width = (bbox.xMax - bbox.xMin) / 64; + height = (bbox.yMax - bbox.yMin) / 64; + + /* set up bitmap */ + bitmap.rows = height; + bitmap.width = width; + bitmap.cols = (width + 7) / 8; + bitmap.size = bitmap.rows * bitmap.cols; + bitmap.bitmap = malloc( bitmap.size ); + if ( !bitmap.bitmap ) + return error_memory... + + /* clear the bitmap buffer! */ + memset( bitmap.bitmap, 0, bitmap.size ); + + /* translate outline */ + TT_Translate_Outline( &outline, -bbox.xMin, -bbox.yMin ); + + /* render it within the bitmap */ + TT_Get_Outline_Bitmap( engine, &outline, &bitmap ); + + /* We're done; don't forget to save bbox.xMin and */ + /* bbox.yMin to adjust the bitmap position when */ + /* rendering text with it */ + + ... + } + + + 3. The case of transformed/rotated glyphs: + + You may want to apply a transformation other than a translation + to your glyph outlines before rendering them. For example, a + simple slant to synthesize italics, or a slight rotation. + + In all cases, it is possible to render individual glyph bitmaps. + Just make sure to follow the same process AFTER you have + transformed you outline! + + DON'T FORGET THAT YOU NEED TO RE-COMPUTE THE BBOX TO GET THE + CORRECT PIXEL DIMENSIONS AFTER A TRANSFORMATION. + + +-------------------------------------------------------------------- + + +IV. Anti-aliasing palette and other concerns + + When rendering pixmaps, using the TT_Get_Outline_Pixmap() or + TT_Get_Glyph_Pixmap() functions, the rasterizer uses a 5-entries + palette of 8-bit deep `colors'. + + By default, this palette is set to ( 0, 1, 2, 3, 4 ), but one can + change it to suit your needs with TT_Set_Raster_Palette(). + + While in bitmap mode, it simply OR-es the pixel values to the + target bitmap that has been passed to TT_Get_Outline_Bitmap(). + + For pixmaps it simply writes directly the palette entries + corresponding to the `color' of the `lit' pixels it has computed. + This means that it is NOT POSSIBLE to render text in a single + pixmap with multiple calls to TT_Get_Outline_Pixmaps() within the + same target! + + The reason is that `gray' pixels of two distinct outlines are not + `added' when they overlap (the operation called 'compositing'), as + it could be expected by applications. + + The following graphic shows this effect when rendering two + overlapping anti-aliased shapes: + + + *** *** + .** .** + ** **. **. ** + .*. .*.. .*..*. + .*. + .*. = ---> ..*. + .*. ** | .*. ** + ** | ** + **. | **. + *** | *** + | + + missing black pixel after second + rendering... + + + There is no simple way to perform a composition within the + rasterizer. This would not be portable; moreover, it would be + extremely slow if it is too general. This operation is thus left + to client applications which can use their own system-specific API + for transparently blitting the glyph pixmaps into a surface to + form text. + + NOTE: + + If your system doesn't support transparent/alpha blits, you can + still have a look at the source file `freetype/test/display.c'. + It uses a large pixmap, with a special palette trick to render all + text quickly, then convert everything to `real' colors for + display. + + +-------------------------------------------------------------------- + + +Conclusion +---------- + + We've seen how the FreeType rasterizer sees bitmaps through + descriptors, as well as the mapping which exists between the + vector coordinate space and the pixel position space. + + You should now be able to render outlines into bitmaps and pixmaps + while applying transformations like translation, slanting, or + rotation. Don't forget a few rules, however: + + - Always clear the bitmap/pixmap buffer before rendering (unless + you want to render several glyphs in a single _bitmap_; it won't + work on a pixmap). + + - A pixmap `cols' field, i.e. the size in bytes of each rows, must + be a multiple of 4. + + - Never translate a hinted outline by a non-integer vector if you + want to preserve the hints (i.e., the vector's coordinates must + be multiples of 64). + + - Finally, don't expect the rasterizer to composite transparent + `grays' for you in a single target pixmap through multiple + calls. + + +--- end of bitmaps.txt --- diff --git a/docs/changes.txt b/docs/changes.txt new file mode 100644 index 0000000..95daad8 --- /dev/null +++ b/docs/changes.txt @@ -0,0 +1,851 @@ +Changes between FreeType version 1.3 and version 1.3.1 +====================================================== + + Bug fixes. + +Changes between FreeType version 1.2 and version 1.3 +==================================================== + + +Documentation +------------- + + Improved installation instructions. + + + Complete revision of almost all documentation files. + +** +** Added the file apirefx.txt to document all extensions to the +** FreeType library. Consequently, errstr.txt has been removed. +** + + Added the file optimize.txt, explaining how to improve FreeType + on a given architecture. + +** +** Documentation about possible patent restrictions added. +** + + Added howto/mac.txt (stating basically that the FreeType team + can't support the Macintosh platform because of lack of + knowledge). + + + Added howto/msdos.txt, documenting compilation for various 16bit + and 32bit compilers. + + +API functions +------------- + + TT_Load_Kerning_Table() now returns TT_Err_Invalid_Argument + instead of TT_Err_Bad_Argument (which is used for an internal + error only) for an invalid argument. The same holds for + TT_Get_Face_Widths() and TT_Get_Glyph_Big_Metrics(). + + + If the glyf table is missing, the new error code + TT_Err_Glyf_Table_Missing is returned instead of + TT_Err_Table_Missing. This affects TT_Get_Face_Widths(), + TT_Load_Glyph(), and TT_Open_Face(). + +** +** New function TT_FreeType_Version() to get the major and minor +** version dynamically. +** + + TT_Load_Glyph() has now two additional flags. TTLOAD_PEDANTIC + will force pedantic handling of the glyph instructions, and + TTLOAD_IGNORE_GLOBAL_ADVANCE_WIDTH is needed for some fonts + which have correct advance width values for the glyphs but an + incorrect global advance width value. + + + TT_Get_Glyph_Big_Metrics() now returns correct vertical bearing + values (both linear and pixel values). + + + New error code TT_Err_Glyf_Table_Missing (0x89) used to indicate + a missing `glyf' table. + + + The following macros have been shortened to stay within the + limit of 32 characters (the longer macro names are still + available if HAVE_LIMITS_ON_IDENTS is not defined). + + TT_UCR_ARABIC_PRESENTATION_FORMS_A -> + TT_UCR_ARABIC_PRESENTATIONS_A + TT_UCR_ARABIC_PRESENTATION_FORMS_B -> + TT_UCR_ARABIC_PRESENTATIONS_B + + TT_UCR_COMBINING_DIACRITICAL_MARKS -> + TT_UCR_COMBINING_DIACRITICS + TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB -> + TT_UCR_COMBINING_DIACRITICS_SYMB + + + freetype.h: + + TT_Bool is now typedef'ed as `typedef int'. + + New typedefs: TT_Int and TT_UInt. + + Declarations of TT_Matrix_Multiply() and TT_Matrix_Invert() + have been removed since these functions were never + implemented. + + +Architectures +------------- + + Added `ansi' directory to the supported architectures -- any + ANSI C compiler should compile FreeType with these files. + + + Added `debugger' directory to the architectures. Use this to + build a special version of FreeType for bytecode debugging + (tested with OS/2 and Unix). + + + Added more files to the `mac' architecture directory to make + basic support complete. + + + Support for VMS added (to compile the library only). + Contributed by Jouk Jansen . + + + Added `win16' architecture directory for older Windows versions. + A graphics driver (gw_win16.c) for the example programs is + available also. + +** +** Antoine Leca contributed support for many MS-DOS and Windows +** compilers (including library fixes to make it 16bit compliant): +** + Borland C++ for MS-DOS (tested with v. 3.1, 4.02, 5.0), + Microsoft C for MS-DOS, + Turbo C (versions 1.5 and 2.0 -- version 1.0 is too old), + Borland C++ 4.0 and 5.0 for Windows (both 16bit and 32bit + versions), + gcc under Win32 (Cygwin32 or MinGW32), + Microsoft Visual C++ 2.x, 4.x, 5.0, and 6.0 for Windows + + + Support for the gettext package with DJGPP compiler has been + added. + + + Since many older compilers on both MS-DOS and Windows platforms + have problems to build dependency files automatically, scripts + for gcc under Unix have been added to do this. Similarly, a + script to produce a DLL definition file is now included in the + distribution. + + + Moved old win32 support to contrib/win32, replacing all CR/LF + with LF, and using only lowercase file names for consistency. + Additionally, some missing files in the FreeType 1.2 + distribution have been added. Antoine Leca has written a new, + light-weight graphics driver (gw_win32.c) which fits better into + the current scheme. + + + Small additions have been made to the Amiga graphics driver. + + + The use of the ARM macro (intended for this architecture) has + been completely removed due to lack of support. + + + Checks for endianness have been removed completely since + FreeType isn't dependent on it. + + +Global compilation macros +------------------------- + + The TT_HUGE_PTR macro has been added to support fonts with more + than 16000 characters or so with 16bit MS-DOS compilers. + Consequently, the files hugefile.c and hugemem.c have been added + which provide special versions for these compilers. + + + HAVE_LIMITS_ON_IDENTS has been introduced to overcome + restrictions with old compilers which can't digest identifiers + longer than 32 characters. + +** +** Added option TT_CONFIG_OPTION_NO_INTERPRETER to desactivate the +** bytecode interpreter completely. This option is off by default. +** + + Added options TT_CONFIG_OPTION_STATIC_RASTER and + TT_CONFIG_OPTION_STATIC_INTERPRETER to build static versions of + the respective components. Off by default. (It was formerly + called TT_STATIC_RASTER.) + + Better debugging support (see ttconfig.h for details): + DEBUG_LEVEL_TRACE, DEBUG_LEVEL_ERROR, DEBUG_INTERPRETER, + DEBUG_MEMORY, DEBUG_FILE. + + Added TT_MAX_EXTENSIONS to define the maximal number of + extensions (currently set to 8 -- this macro was previously in + ttextend.c). + + +Extensions +---------- +** +** Full support for TrueType Open resp. OpenType GSUB tables has +** been implemented. It uses a GDEF table if available; otherwise, +** a method to construct an artificial GDEF table has been added +** (note that GDEF parts not related to GSUB are loaded but not +** further handled). An example how to use it can be found in the +** new test program ftstrtto. +** + + Rudimentary GPOS support -- currently, you can load the GPOS + subtables but nothing more. + +** +** Documentation for all extensions can be found in the file +** apirefx.txt. +** + + Fixed a bug in TT_Load_PS_Names() which returned a local, thus + invalid pointer. + +** +** Support for embedded bitmaps has been added (thanks to +** YAMANO'UCHI Hidetoshi who has contributed +** a lot of the code). It can handle `bloc', `bdat', `EBLC', and +** `EBDT' tables. [TrueType embedded bitmaps are also called +** `sbits' (for `scaler bitmaps').] +** + +Test programs +------------- +** +** A new test program called ftstrtto has been added to test +** TrueType Open features. Almost all available FreeType +** extensions are used in this program -- it displays a UTF 8 +** encoded string on screen, allowing to toggle kerning, embedded +** bitmaps, GSUB support, and hinting. Additionally, it has a +** special module to handle the Arabic script properly (in +** arabic.c), i.e., it treats initial, medial, final, and isolated +** glyphs correctly. +** + + The new module `blitter.c' provides the blitting function + Blit_Bitmap() for bitmaps of various depth. + + + The debugging program `fdebug' has been rewritten to provide a + better user interface. + + + ftdump has been extended to show information about embedded + bitmaps and GSUB data. It will now also show the PostScript + name of the font. + + + The new test program ftmetric can dump metrics and glyphs -- it + uses the gettext package for i18n support. + + + Another new test program is ftsbit to dump embedded bitmaps + contained in a font. + + + A small bug has been fixed in ftstring to compute the right + bounding box of the string. + + + ftview has been extended to display embedded bitmaps also + (switch `-B'). + + + The maximal point size of glyphs in ftview has been increased to + 5000pt -- this has shown some clipping bugs in the engine which + has been fixed meanwhile. As a demonstration, it also activates + tracing of the raster and gload component if DEBUG_LEVEL_TRACE + (see above) is defined. + + +Miscellaneous +------------- + + The library has been updated to use autoconf 2.13 and libtool + 1.3.3 throughout. + +** +** FreeType will now install its header files in +** /freetype/... since the number of files has grown again. +** + + Added a lot of EXPORT_FUNC/EXPORT_DEF macros to functions for + correct exporting in DLLs. + +** +** FreeType can now successfully load Mac fonts which don't have an +** `OS/2' table. +** + + Fixed a bug in handling composite glyphs where the composite + elements use attached points. + + + Better debugging support for instructions. + + + Various workarounds have been implemented to support slightly + broken fonts (or rather, fonts not following exactly the + TrueType specifications). + + +Contributed programs +-------------------- + + ttf2bdf: +** +** Swapped all the columns in the mapping files. +** + + Changed the mapping table loader to index on the second column + instead of the first. + + + Changed the includes to deal with compilation on Windows. + + + Added some new mapping tables. + + + Fixed an incorrect parameter for Traditional C compilers. + + + Added generation of the _XFREE86_GLYPH_RANGES properties. + + + Change all CRLF's, CR's, or LF's in copyright strings to + double spaces. + + + Changed it so gcc 2.8.1 likes the return type of main() again. + + + Changed Makefile.in a bit to make installation more + consistent. + + + Changed the lower limit for the vertical and horizontal + resolutions to be 10dpi instead of 50dpi. + + + ttf2pfb: + + Has now rudimentary support for mapping tables (switch `-m') + and better PostScript name support for ordinary Type 1 fonts + -- nevertheless, it is far from finished, and there are some + plans to merge it with ttf2pt1. + + configure script added. + + Option `-k' added to keep output file in case of error. + + `-v' is now really verbose. + + ttf2pk: +** +** Support for MiKTeX's file searching mechanism added (ttf2pk +** and ttf2tfm are now part of the MiKTeX). +** +** +** Support for rotated glyphs added (only for subfonts; switches +** `-x' and `-y' to activate rotation resp. controlling the y +** offset). If a GSUB table with the `vert' feature is available +** in the font, vertical glyph presentation forms are used. +** + + Added warning message to the configure script in case the + kpathsea library isn't used. + + + Fixed an omission in Bg5.sfd. + +** +** Added UBg5plus.sfd for mapping Unicode to Bg5+ encoding. +** Similar SFD files now available: UBg5.sfd, UGB.sfd, UGBK.sfd, +** UJIS.sfd, UKS.sfd. +** + + Added documentation for dvidrv.btm. + + + Will now compile with kpathsea version 3.3 or newer also. + + + Subfont ligature support added as needed in the HLaTeX package + for Korean (switch `-l'). + +** +** Since ttf2pk support has been added to teTeX version 1.0 and +** newer, no patch are necessary. +** + + Fixed a string initialization bug in buildtfm() (file + tfmaux.c). + + + Added more documentation about file searching and a full + example how to use ttf2tfm. + + + Fixed a small bug in ttf2tfm.c which printed `(null)' instead + of nothing for the ttfonts.map entry if the font name prefix + string was empty. + + + ttf2tfm will now use the first type 0 kerning table only + (instead of the first kerning table only). + + + Both ttf2pk and ttf2tfm will now apply stretching and slanting + directly to the outline. This usually yields smaller bounding + boxes. + + + ttf2tfm will now output a comment string to the VPL file to + illustrate the meaning of the `HEADER' lines. + + + ttfbanner: + + Added Makefile for emx+gcc compiler. + + + Added autoconf support. + + + Fixed a lot of compilation warnings. + + +Pascal source code +------------------ + + The Pascal source code has been seriously updated since 1.2. + Here are the most important changes. + +** +** A. Support for charmaps and the name table +** +** +** The Charmap functions were not correctly implemented before +** 1.3. They are now available in the Pascal API. +** +** +** Similarly, the `name' table was not loaded, and the +** TT_Get_Name function wasn't implemented before 1.3. It is now +** done. +** +** +** The Pascal engine is now feature-complete, except that it +** provides no extensions like the C source code. +** + + B. Improvements in the glyph loader and the interpreter + + + Several changes were made in order to be able to load more + broken fonts, as well as old Apple fonts which happened to use + some very rarely-used aspects of the specification. + + + Note that the Pascal bytecode interpreter, contrary to the C + version, is not able to silently accept broken glyphs yet, or + even use the flag TTLOAD_PEDANTIC. Implementing this in + Pascal would require some serious work (unlike to C, where + this feature was introduced easily with the use of a few + macros to minimize source changes). So TT_Load_Glyph might + return an error with the Pascal engine while the C one accept + the same request successfully. + + + C. Ports to Delphi and Free Pascal + + This release has been compiled on the following compilers: + + - Free Pascal 0.9 (Dos,Linux,Win32,OS/2) + - Virtual Pascal 1.1 and 2.0 (Win32 and OS/2) + - Turbo Pascal 6.0 and Borland Pascal 7.0 (Dos) + - Delphi 1, 2, and 3. It should work with D4 and D5 also. + (Windows) + + Note that most of the test programs will not compile on + anything except MS-DOS or OS/2. The debugger also needs the + Turbo Vision library. The library, however, should compile + fine with all tools cited above. + + + +Changes between FreeType 1.1 and 1.2 +==================================== + +Mostly bug fixes and build fixes. + + + +Changes between FreeType 1.0 and 1.1 +==================================== + +There were various changes since the 1.0 release. Here they are +summarized: + +- Added vertical layout support + + The engine now loads the vertical header and metrics if available + and makes them visible through the new `vertical' field of the + face properties (it is set to NULL if no vertical data was found + in the font file). + + The glyph loader now loads all metrics (horizontal and vertical), + but still returns the horizontal ones only with the API + TT_Get_Glyph_Metrics(). However, TT_Get_Glyph_Bit_Metrics() has + been added to extract them from a glyph container. + + +- Serialization of coordinates arrays in TT_Outline() + + As announced in the previous API reference, the structure of + TT_Outline changed slightly, as well as the naming of its fields. + The points are now stored in a single array of TT_Vector, instead + of two parallel arrays (one for the Xs, the other for the Ys). + + +- New API function TT_Get_Face_Metrics() + + Useful to access unscaled metrics like left side bearings, advance + widths, top side bearings, and advance height, for a given range + of glyphs. + + +- New extension: ftxcmap.c + + Used by some applications to enumerate and parse the charmap + tables in an easier way. + + +- New extension: ftxpost.c + + With this extension you can access the PostScript glyph names + given in the `post' table. + + +- New extension: ftxwidth.c + + This extension is used to parse the `glyf' table to extract the + bounding boxes of a given range of glyphs. This is much faster + than loading individual glyphs. + + +- The FreeType engine is now THREAD-SAFE and REENTRANT + + However, the implementation of ttmutex must be refined for your + system -- the default one is a dummy and doesn't do anything! + Beware! THIS IS STILL IN BETA. + + The thread-safe and reentrant builds now compile and seem to run + well when used with a single thread. Some efforts have been spent + to check the coherency of the lock contentions within the engine, + but we haven't tested multi-threading heavily. + + +- Large internal re-organization + + Too technical to explain shortly, but results in a much better + memory footprint and smaller code, especially when opening + multiple faces. + + +- Fixes/enhancements to the interpreter + + The infamous Monotype.com bug (a new free font released by + Microsoft Typography a few days after the FreeType 1.0 release!) + is fixed, of course, as well as few other little and unpleasant + artifacts... + + The interpreter was also seriously re-organized to allow the use + of a very large `switch' statement, instead of a jump table, which + results in smaller and faster code on some systems (depending of + the compiler too). Users of the library can experiment with the + TT_CONFIG_OPTION_INTERPRETER_SWITCH configuration macro to test + this. + + +- Single object compilation mode + + The core engine can now be compiled into a single object file. + This allows optimizing compilers to do more global optimizations, + and get rid of many of the `intermediate' internal symbols used to + link internal engine components together. + + The engine now takes only 48kByte of stripped Intel object code! + + +- DLL compilation mode + + In order to allow the compilation of the library as a DLL, the + keyword EXPORT has been added as a prefix to all high-level API + functions found in `freetype.h'. Define it to the value you need + before `#include "freetype.h"' when building the DLL (if undefined + it will default to nothing within this header file). + + (Apparently, this is only useful on Win32, maybe on OS/2.) + + +- Renamed configuration macros + + These were renamed to forms of TT_CONFIG_OPTION_XXXXX_YYYYY. + They're located in ttconfig.h and can be defined/undefined + manually by developers who want to tune the compilation of the + engine: + + TT_CONFIG_OPTION_EXTEND_ENGINE + + Allows extensions to be linked with the single object engine. + If you don't need any of them, you may save one or more + kilobytes by undefining it. + + + TT_CONFIG_OPTION_GRAY_SCALING + + Allows the compilation of the gray-scaling (font smoothing) + code in ttraster. If undefined, some APIs won't be available: + + TT_Set_Raster_Palette(), + TT_Get_Glyph_Pixmap(), + TT_Get_Outline_Pixmap() + + + TT_CONFIG_OPTION_INTERPRETER_SWITCH + + Uses a large `switch' statement in the bytecode interpreter + instead of a constant call-table. Depending on your processor + and compiler, this can lead to significant reduction of code + size and/or increase of performance. + + + TT_CONFIG_OPTION_THREAD_SAFE + + When defined, a thread-safe version of the engine is built. A + thread-safe version is a bit bigger, probably not slower, than + a non-threaded build. ATTENTION: You must redefine the file + `lib/ttmutex.c' for your own platform to get it to work + correctly. + + + Some more options may come in the future... + + +- New API functions TT_MulDiv() and TT_MulFix()" + + To help you compute `a*b/c' with 64-bit intermediate precision, or + `a*b/0x10000' with the same one... + + These are not necessarily the fastest functions but they are + clearly portable and overflow-safe. Your runtime/compiler may + provide better replacements, though... + + + +Changes between FreeType Beta and 1.0 +===================================== + +There were a number of changes since the public beta: + + +I. Bug fixes +------------ + + The following bugs have been fixed in this release: + + + - Incorrect advance width and left side bearings + + The glyph loader has been re-designed to match the values found + in the pre-calc tables... + + + - Problems when opening multiple fonts + + Fixed. A stupid bug in the i/o component. + + + - Problems with some Georgian fonts + + Fixed. Discovered some new undocumented opcodes behaviour... + + + - Buglets in the test programs which made them return invalid + error codes + + Fixed. + + + - Memory leaks when trying to open broken some font files + + Fixed. Waiting for more broken fonts to test... + + + - Non-square resolutions don't work or display correctly + + They now work very well! + + + - The scan-line converter, while in font-smoothing mode, doesn't + perform horizontal drop-out control + + This wasn't really bug, but the feature has been correctly + added. + + +The remaining `features' persist, as they're not essential yet: + + - The `rotated' and `stretched' flags do not work (glyph loading + will then return errors). However, it is still possible to + rotate or transform any outline without setting these flags. + + - We always use drop-out mode number 2, as some of the values + returned by some `cvt programs' seem invalid for now... + + +Note also that an `event hook/callback' has been introduced in this +release, but is still under alpha (not even beta; it is commented +out currently). You should not rely on this... + + +II. Code changes +---------------- + + 1. API Changes + + A few API changes were necessary in order to support important + features, or future improvements which will come in later + releases. + + + - TT_Set_Instance_Resolution() was renamed to + TT_Set_Instance_Resolutions(). + + + - TT_Set_Instance_PointSize() has disappeared. Instead, the + following APIs have been defined: + + TT_Set_Instance_CharSize() + TT_Set_Instance_CharSizes() + TT_Set_Instance_PixelSizes() + + + - The TT_Engine class has been introduced. It models one + instance of the library, and is used to allow re-entrance and + shared library code. The functions which now depend on a + TT_Engine parameter are: + + TT_Init_FreeType() + TT_Done_FreeType() + TT_Open_Face() + TT_Open_Collection() + TT_Set_Raster_Palette() + TT_Get_Outline_Bitmap() + TT_Get_Outline_Pixmap() + + Note that there is _no_ sharing of objects between distinct + engines. + + + - Each face and instance object have an inside pointer which use + is reserved to client application. Several functions are + defined to set and read it: + + TT_Set_Face_Pointer() / TT_Get_Face_Pointer() + TT_Set_Instance_Pointer() / TT_Get_Instance_Pointer() + + + - TT_Apply_Outline_Matrix() has been renamed to + TT_Transform_Outline(). + TT_Apply_Outline_Translation() has been renamed to + TT_Translate_Outline() + TT_Apply_Vector_Matrix() has been renamed to + TT_Transform_Vector() + + all for the sake of clarity. + + + 2. Structural changes + + Some structures have evolved. + + + - The instance metrics have now two new fields which are + `x_scale' and `y_scale'. Each one is a scaling factor, + expressed in the 16.16 fixed float format (TT_Fixed), used to + convert one distance expressed in font units into the same + distance in fractional (26.6) pixels. + + + - A new structure TT_BBox has been defined to describe an + outline's bounding box. + + + - The outlines are now full-class citizen. It is possible to + create new outlines, copy, clone, transform, translate and + render them through specific methods of the TT_Outline class + (previously called TT_Glyph_Outline). Read the API reference + for a complete listing. + + + - The glyph metrics have a new structure: they contain a TT_BBox + field, a TT_Outline field, as well as three metrics values, + which are `bearingX', `bearingY', and `advance'. Read the + file `glyphs.txt' for more information about their definitions + and uses. + + + 3. Small but IMPORTANT changes + + + - The `max_Faces' field of a face's properties has disappeared. + It is replaced by `num_Faces' which gives the total number of + fonts embedded in a collection (the previous field gave the + total minus one). + + + - TT_Load_Glyph() now returns correctly placed outlines, and + computes advance widths which match the pre-calc values in the + "hdmx" table in nearly all cases. + + + - TT_Get_Glyph_Metrics() returns grid-fitted metrics for hinted + glyphs (i.e., loaded with the TTLOAD_HINT_GLYPH, or + TTLOAD_DEFAULT, flags). This includes the bounding box. To + get the exact bounding box of a hinted glyph, you should + extract its outline, then call TT_Get_Outline_BBox(). + + + - Some improvements in the glyph loader, which improves + drastically the placement of glyphs (especially composite + ones) which previously caused trouble for some fonts + (e.g. goudy.ttf). + + + - Several minor improvements in the interpreter to improve + rendering and bounds checking... + + + - Up-to-date Pascal source code, with output equivalent to the C + tree... + + +--- END --- diff --git a/docs/convntns.txt b/docs/convntns.txt new file mode 100644 index 0000000..0117785 --- /dev/null +++ b/docs/convntns.txt @@ -0,0 +1,970 @@ + + Conventions and Design in the FreeType library + ---------------------------------------------- + + +Table of Contents + +Introduction + +I. Style and Formatting + + 1. Naming + 2. Declarations & Statements + 3. Blocks + 4. Macros + +II. Design conventions + + 1. Modularity and Components Layout + 2. Configuration and Debugging + +III. Usage conventions + + 1. Error handling + 2. Font File I/O + 3. Memory management (due to change soon) + 4. Support for threaded environments + 5. Object Management + + +Introduction +============ + +This text introduces the many conventions used within the FreeType +library code. Please read it before trying any modifications or +extensions of the source code. + + + +I. Style and Formatting +======================= + +The following coding rules are extremely important to keep the +library's source code homogeneously. Keep in mind the following +points: + + - `Humans read source code, not machines' (Donald Knuth) + + The library source code should be as readable as possible, even + by non-C experts. With `readable', two things are meant: First, + the source code should be pleasant to the eye, with sufficient + whitespace and newlines, to not look like a boring stack of + characters stuck to each other. Second, the source should be + _expressive_ enough about its goals. This convention contains + rules that can help the source focus on its purpose, not on a + particular implementation. + + - `Paper is the _ultimate_ debugger' (David Turner :-) + + There is nothing like sheets of paper (and a large floor) to + help you understand the design of a library you're new to, or to + debug it. The formatting style presented here is targeted at + printing. For example, it is more than highly recommended to + never produce a source line that is wider than 78 columns. More + on this below. + + +1. Naming +--------- + + a. Components + + A unit of the library is called a `component'. Each component + has at least an interface, and often a body. The library comes + in two language flavors, C and Pascal (the latter severely out + of date unfortunately). A component in C is defined by two + files, one `.h' header and one `.c' body, while a Pascal + component is contained in a single `.pas' file. + + All component source file names begin with the `tt' prefix, with + the exception of the `FreeType' component. For example, the + file component is implemented by the files `ttfile.h', + `ttfile.c', and `ttfile.pas'. Only lowercase letters should be + used, following the 8+3 naming convention to allow compilation + under DOS. + + In the C version, a single component can have multiple bodies. + For example, `ttfile.c' provides stream i/o through standard + ANSI libc calls, while `ttfile2.c' implements the same thing + using a Unix memory-mapping API. + + The FreeType component is an interface-only component. + + b. Long and expressive labels + + Never hesitate to use long labels for your types, variables, + etc.! Except maybe for things like very trivial types, the + longest is the best, as it increases the source's + _expressiveness_. Never forget that the role of a label is to + express the `function' of the entity it represents, not its + implementation! + + NOTE: Hungarian notation is NOT expressive, as it sticks the + `type' of a variable to its name. A label like `usFoo' + rarely tells the use of the variable it represents. + + And the state of a variable (global, static, dynamic) + isn't helpful anymore. + + Avoid Hungarian Notation like the *plague*! + + + When forging a name with several nouns + (e.g. `number-of-points'), use an uppercase letter for the first + letter of each word (except the first), like: + + numberOfPoints + + You are also welcomed to introduce underscores `_' in your + labels, especially when sticking large nouns together, as it + `airs' the code greatly. E.g.: + + `numberOfPoints' or `number_Of_Points' + + `IncredibleFunction' or `Incredible_Function' + + And finally, always put a capital letter after an underscore, + except in variable labels that are all lowercase: + + `number_of_points' is OK for a variable (_all_ lowercase label) + + `incredible_function' is NOT for a function! + ^ ^ + + `Microsoft_windows' is a *shame*! + ^ ^ + + `Microsoft_Windows' isn't really better, but at least its a + ^ ^ correct function label within this + convention ;-) + + c. Types + + All types that are defined for use by FreeType client + applications are defined in the FreeType component. All types + defined there have a label beginning with `TT_'. Examples: + + TT_Face, TT_F26Dot6, etc. + + However, the library uses a lot more of internal types that are + defined in the Types, Tables, and Objs components (`tttypes' & + `tttables' files). + + By convention, all internal types, except the simplest ones like + integers, have their name beginning with a capital `T', like in + 'TFoo'. Note that the first letter of `foo' is also + capitalized. The corresponding pointer type uses a capital `P' + instead, i.e. (TFoo*) is simply named 'PFoo'. Examples: + + typedef struct _TTableDir + { + TT_Fixed version; /* should be 0x10000 */ + UShort numTables; /* Tables number */ + + UShort searchRange; /* These parameters are only used */ + UShort entrySelector;/* for a dichotomy search in the */ + UShort rangeShift; /* directory. We ignore them. */ + } TTableDir; + + typedef TTableDir* PTableDir; + + Note that we _always_ define a typedef for structures. The + original struct label starts with `_T'. + + This convention is a famous one from the Pascal world. + + Try to use C or Pascal types to the very least! Rely on + internally defined equivalent types instead. For example, not + all compilers agree on the sign of `char'; the size of `int' is + platform-specific, etc. + + There are equivalents to the most common types in the `Types' + components, like `Short', `UShort', etc. Using the internal + types will guarantee that you won't need to replace every + occurence of `short' or wathever when compiling on a weird + platform or with a weird compiler, and there are many more than + you could think of... + + d. Functions + + The name of a function should always begin with a capital + letter, as lowercase first letters are reserved for variables. + The name of a function should be, again, _expressive_! Never + hesitate to put long function names in your code: It will make + the code much more readable. + + Expressiveness doesn't necessarily imply lengthiness though; for + instance, reading shorts from a file stream is performed using + the following functions defined in the `File' component: + + Get_Byte, Get_Short, Get_UShort, Get_Long, etc. + + Which is somewhat more readable than: + + cget, sget, usget, lget, etc. + + e. Variables + + Variable names should always begin with a lowercase letter. + Lowercase first letters are reserved for variables in this + convention, as it has been already explained above. You're + still welcome to use long and expressive variable names. + + Something like `numP' can express a number of pixels, porks, + pancakes, and much more... Something like `num_points' won't. + + Today, we are still using short variable labels in some parts of + the library. We're working on removing them however... + + As a side note, a field name of a structure counts as a variable + name too. There are exceptions to the first-lowercase-letter + rule, but these are only related to fields within the structure + defined by the TrueType specification (well, at least it + _should_ be that way). + + +2. Declarations & Statements +---------------------------- + + a. Columning + + Try to align declarations and assignments in columns, if it + proves logical. For example (taken from `ttraster.c'): + + struct _TProfile + { + Int flow; /* Profile orientation : Asc/Descending */ + Int height; /* profile's height in scanlines */ + Int start; /* profile's start scanline */ + ULong offset; /* offset of profile's data in render pool */ + PProfile link; /* link to next profile */ + Int index; /* index of profile's entry in trace table */ + Int count_lines; /* count of lines having to be drawn */ + Int start_line; /* lines to be rendered before this profile */ + PTraceRec trace; /* pointer to profile's current trace table */ + }; + + instead of + + struct _TProfile { + Int flow; /* Profile orientation : Asc/Descending */ + Int height; /* profile's height in scanlines */ + Int start; /* profile's start scanline */ + ULong offset; /* offset of profile's data in render pool */ + PProfile link; /* link to next profile */ + Int index; /* index of profile's entry in trace table */ + Int count_lines; /* count of lines having to be drawn */ + Int start_line; /* lines to be rendered before this profile */ + PTraceRec trace; /* pointer to profile's current trace table */ + }; + + This comes from the fact that you're more interested by the + field and its function than by its type. + + Or: + + x = i + 1; + y += j; + min = 100; + + instead of + + x=i+1; + y+=j; + min=100; + + And don't hesitate to separate blocks of declarations with + newlines to `distinguish' logical sections. + + E.g., taken from an old source file, in the declarations of the CMap + loader: + + long n, num_SH; + unsigned short u; + long off; + unsigned short l; + long num_Seg; + unsigned short* glArray; + long table_start; + int limit, i; + + TCMapDir cmap_dir; + TCMapDirEntry entry_; + PCMapTable Plcmt; + PCMap2SubHeader Plcmsub; + PCMap4 Plcm4; + PCMap4Segment segments; + + instead of + + long n, num_SH; + unsigned short u; + long off; + unsigned short l; + long num_Seg; + unsigned short *glArray; + long table_start; + int limit, i; + TCMapDir cmap_dir; + TCMapDirEntry entry_; + PCMapTable Plcmt; + PCMap2SubHeader Plcmsub; + PCMap4 Plcm4; + PCMap4Segment segments; + + b. Aliases and the `with' clause + + The Pascal language comes with a very handy `with' clause that + is often used when dealing with the fields of a same record. + The following Pascal source extract + + with table[incredibly_long_index] do + begin + x := some_x; + y := some_y; + z := wathever_the_hell; + end; + + is usually translated to: + + table[incredibly_long_index].x = some_x; + table[incredibly_long_index].y = some_y; + table[incredibly_long_index].z = wathever_the_hell; + + When a lot of fields are involved, it is usually helpful to + define an `alias' for the record, like in: + + alias = table + incredibly_long_index; + + alias->x = some_x; + alias->y = some_y; + alias->z = wathever_the_hell; + + which gives cleaner source code, and eases the compiler's + optimization work. + + Though the use of aliases is currently not fixed in the current + library source, it is useful to follow one of these rules: + + - Avoid an alias with a stupid, or cryptic name, something like: + + TFooRecord tfr; + .... + [lots of lines snipped] + .... + + tfr = weird_table + weird_index; + + ... + + tfr->num = n; + + It doesn't really help to guess what 'tfr' stands for several + lines after its declaration, even if it's an extreme + contraction of one particular type. + + Something like `cur_record' or `alias_cmap' is better. The + current source also uses a prefix of `Pl' for such aliases + (like Pointer to Local alias), but this use is _not_ + encouraged. If you want to use prefixes, use `loc_', `cur_', + or `al_' at the very least, with a descriptive name following. + + - Or simply use a local variable with a semi-expressive name: + + { + THorizontalHeader hheader; + TVerticalHeader vheader; + + + hheader = instance->fontRes->horizontalHeader; + vheader = instance->fontRes->verticalHeader; + + hheader->foo = bar; + vheader->foo = bar2; + ... + } + + which is much better than + + { + THorizontalHeader Plhhead; + TVerticalHeader Plvhead; + + Plhhead = instance->fontRes->horizontalHeader; + Plvhead = instance->fontRes->verticalHeader; + + Plhhead->foo = bar; + Plvhead->foo = bar2; + ... + } + + +3. Blocks +--------- + + Block separation is done with `{' and `}'. We do not use the K&R + convention which becomes only useful with an extensive use of + tabs. The `{' and its corresponding `}' should always be on the + same column. It makes it easier to separate a block from the rest + of the source, and it helps your _brain_ associates the accolades + easily (ask any Lisp programmer on the topic!). + + Use two spaces for the next indentation level. + + Never use tabs in your code, their widths may vary with editors + and systems. + + Example: + + if (condition_test) { + waow mamma; + I'm doing K&R format; + just like the Linux kernel; + } else { + This test failed poorly; + } + + is _OUT_! + + if ( condition_test ) + { + This code isn't stuck to the condition; + read it on paper, you'll find it more; + pleasant to the eye; + } + else + { + Of course, this is a matter of taste; + That's just the way it is in this convention; + and you should follow it to be homogenous with; + the rest of the FreeType code; + } + + is _IN_! + + +4. Macros +--------- + + Macros should be made of uppercase letters. When a macro label is + forged from several words, it is possible to only uppercasify the + first word, using an underscore to separate the nouns. This is + used in ttload.c, ttgload.c and ttfile.c with macros like + + ACCESS_Frame, GET_UShort, CUR_Stream + + The role of the macros used throughout the engine is explained + later in this document. + + + +II. Design Conventions +====================== + + +1. Modularity and Components Layout +----------------------------------- + + The FreeType engine has been designed with portability in mind. + This implies the ability to compile and run it on a great variety + of systems and weird environments, unlike many packages where the + word strictly means `runs on a bunch of Unix-like systems'. We + have thus decided to stick to the following restrictions: + + - The C version is written in ANSI C. The Pascal version compiles + and run under Turbo Pascal 5.0 and compatible compilers. + + - The library, if compiled with gcc, doesn't produce any warning + with the `-ansi -pedantic' flags. Other compilers with better + checks may produce ANSI warnings that we'd be happy to now + about. + + (NOTE: It can of course be compiled by an `average' C compiler, + and even by a C++ one.) + + - It only requires in its simplest form an ANSI libc to compile, + and no utilities other than a C pre-processor, compiler, and + linker. + + - It is written in a modular fashion. Each module is called a + `component' and is made of two files in the C version (an + interface with suffix `.h' and body with suffix `.c' ) and one + file in the Pascal one. + + - The very low-level components can be easily replaced by + system-specific ones that do not rely on the standard libc. + These components deal mainly with i/o, memory, and mutex + operations. + + - A client application must only include one interface file named + `freetype.h' resp. `freetype.pas' to use the engine. All other + components should never be used or accessed by client + applications, and their name always begin with a `tt' prefix: + + ttmemory, ttobjs, ttinterp, ttapi, etc. + + - All configuration options are gathered in two files. One + contains the processor and OS specific configuration options, + while the other treats options that may be enabled or disabled + by the developer to test specific features (like assertions, + debugging, etc). + + IMPORTANT NOTES: + + These restrictions only apply to the core engine. The package + that comes with it contains several test programs sources that + are much less portable, even if they present a modular model + inspired from the engine's layout. + + The components currently found in the `lib' directory are: + + -------- high-level interface ---------------------------------- + + freetype.h High-level API, to be used by client applications. + + ttapi.c Implementation of the api found in `freetype.h'. + + -------- configuration ----------------------------------------- + + ttconfig.h Engine configuration options. These are commented + and switched by hand by the developer. See + section 2 below for more info. + + ft-conf.h Included by ttconfig.h, this file isn't part of + the `lib' directory, but depends on the target + environment. See section 2 blow for more info. + + -------- definitions ------------------------------------------- + + tttypes.h The engine's internal types definitions. + tttables.h The TrueType tables definitions, per se the Specs. + tttags.h The TrueType table tags definitions. + tterror.[ch] The error and debugging component. + + ttdebug.[ch] Only used by the debugger, should not be linked + into a release build. + + ttcalc.[ch] Math component used to perform some computations + with an intermediate 64-bit precision. + + -------- replaceable components -------------------------------- + + ttmemory.[ch] Memory component. This version uses the ANSI libc + but can be replaced easily by your own version. + + ttfile.[ch] Stream i/o component. This version uses the ANSI + libc but can be replaced easily by your own + version. Compiled only if file memory mapping + isn't available on your system. + + ttfile2.[ch] Unix-specific file memory mapping version of the + file component. It won't compile on other + systems. Usually results in much faster file + access (about 2x on a SCSI P166 system) + + ttmutex.[ch] Generic mutex component. This version is a dummy + and should only be used for a single-thread build. + You _need_ to replace this component's body with + your own implementation to be able to build a + threaded version of the engine. + + -------- data management --------------------------------------- + + ttengine.h The engine instance record definition, root of all + engine data. + + ttlists.[ch] Generic lists manager. + ttcache.[ch] Generic cache manager. + + ttobjs.[ch] The engine's object definitions and + implementations module contains structures, + constructors, destructors and methods for the + following objects: + + face, instance, glyph, execution_context + + ttload.[c] The TrueType tables loader. + + ttgload.[ch] The glyph loader. A component in itself, due to + the task's complexity. + + ttindex.[ch] The character mapping to glyph index conversion + routines. Implements functions defined in + `freetype.h'. + + ttinterp.[ch] The TrueType instructions interpreter. Probably + the nicest source in this engine. Apparently, + many have failed to produce a comparable one due + to the very poorly written specification! It took + David Turner three months of his spare time to get + it working correctly! :-) + + ttraster.[ch] The engine's second best piece. This is the + scan-line converter. Performs gray-level + rendering (also known as font-smoothing) as well + as dropout-control. + + +2. Configuration and Debugging +------------------------------ + + As stated above, configuration depends on two files: + + The environment configuration file `ft-conf.h': + + This file contains the definitions of many configuration options + that are processor and OS-dependent. On Unix systems, this file + is generated automatically by the `configure' script that comes + with the released package. + + On other environments, it is located in one of the architecture + directories found in `arch' (e.g. `arch/os2/ft-conf.h'). + + The path to this file should be passed to the compiler when + compiling _each_ component. (typically with an -I option). + + The engine configuration file `ttconfig.h': + + This file contains many configuration options that the developer + can turn on or off to experiment with some `features' of the + engine that are not part of its `simplest' form. The options + are commented. + + Note that the makefiles are compiler-specific. + + It is possible to enable the dumping of debugging information by + compiling the components with the various debug macros. Please + consult the file `ttconfig.h' for details. + + If you want to port the engine to another environment, you will + need to + + - Write a new `ft-conf.h' file for it. Just copy one of those + available and change the flags accordingly (they're all + commented). + + - Replace the memory, file, and mutex components with yours, + presenting the same interface and behaviour. + + - Eventually add some code in ttapi.c to initialize + system-specific data with the engine. + + + +III. Usage conventions +====================== + + +1. Error Handling +----------------- + + Error handling has been refined to allow reentrant builds of the + library, available only in the C version. We thus have now two + different conventions. + + In Pascal: + + A global error variable is used to report errors when they are + detected. All functions return a boolean that indicates success + or failure of the call. If an error occurs within a given + function, the latter must set the error variable and return + `false' (which means failure). + + It is then possible to make several calls in a single `if' + statement like: + + if not Perform_Action_1( parms_of_1 ) or + not Perform_Action_2( parms_of_2 ) or + not Perform_Action_3( parms_of_3 ) then goto Fail; + + where execution will jump to the `Fail' label whenever an error + occurs in the sequence of actions invoked in the condition. + + In C: + + Global errors are forbidden in re-entrant builds. Each function + thus returns directly an error code. A return value of 0 means + that no error occured, while a non-zero other value indicates a + failure of any kind. + + This convention is more constraining than the one used in the + Pascal source. The above Pascal statement should be translated + into the following C fragment: + + rc = Perform_Action_1( parms_of_1 ); + if ( rc ) + goto Fail; + + rc = Perform_Action_2( parms_of_2 ); + if ( rc ) + goto Fail; + + rc = Perform_Action_3( parms_of_3 ); + if ( rc ) + goto Fail; + + which, while being equivalent, isn't as pleasantly readable. + + One `simple' way to match the original fragment would be to + write: + + if ( (rc = Perform_Action_1( parms_of_1 )) || + (rc = Perform_Action_2( parms_of_2 )) || + (rc = Perform_Action_3( parms_of_3 )) ) + goto Fail; + + which is better but uses assignments within expressions, which + are always delicate to manipulate in C (the risk of writing `==' + exists, and would go unnoticed by a compiler). Moreover, the + assignments are a bit redundant and don't express much things + about the actions performed (they only speak of the error + management issue). + + That is why some macros have been defined for the most + frequently used functions. They relate to low-level routines + that are called very often (mainly i/o, mutex, and memory + handling functions). Each macro produces an implicit assignment + to a variable called `error' and can be used instead as a simple + function call. Example: + + if ( PERFORM_Action_1( parms_of_1 ) || + PERFORM_Action_2( parms_of_2 ) || + PERFORM_Action_3( parms_of_3 ) ) + goto Fail; + + with + + #define PERFORM_Action_1( parms_1 ) \ + ( error = Perform_Action_1( parms_1 ) ) + #define PERFORM_Action_2( parms_1 ) \ + ( error = Perform_Action_2( parms_1 ) ) + #define PERFORM_Action_3( parms_1 ) \ + ( error = Perform_Action_3( parms_1 ) ) + + defined at the beginning of the file. + + There, the developer only needs to define a local `error' + variable and use the macros directly in the code, without caring + about the actual error handling performed. Examples of such a + usage can be found in `ttload.c' and `ttgload.c'. Moreover, the + structure of the source files remain very similar, even though + the error handling is very different. + + This convention is very close to the use of exceptions in + languages like C++, Pascal, Java, etc. where the developer + focuses on the actions to perform, and not on every little error + checking. + + +2. Font File I/O +---------------- + + a. Streams + + The engine uses `streams' to access the font files. A stream is + a structure defined in the `File' component containing + information used to access files through a system-specific i/o + library. + + The current implementation of the File component uses the ANSI + libc i/o functions. However, for the sake of embedding in light + systems and independence of a complete libc, it is possible to + re-implement the component for a specific system or OS, letting + it use system calls. + + A stream is of type `TStream' defined in the `TTObjs' interface. + The type is `(void*)' but actually points to a structure defined + within the File component. + + A stream is created, managed and closed through the interface of + the `File' component. Several implementations of the same + component can co-exist, each taking advantage of specific system + features (the file `ttfile2.c' uses memory-mapped files for + instance) as long as it respects the interface. + + b. Frames + + TrueType is tied to the big-endian format, which implies that + reading shorts or longs from the font file may need conversions + depending on the target processor. To be able to easily detect + read errors and allow simple conversion calls or macros, the + engine is able to access a font file using `frames'. + + A frame is simply a sequence of successive bytes taken from the + input file at the current position. A frame is pre-loaded into + memory by a `TT_Access_Frame()' call of the `File' component. + + It is then possible to read all sizes of data through the + `Get_xxx()' functions, like Get_Byte(), Get_Short(), + Get_UShort(), etc. + + When all important data is read, the frame can be released by a + call to `TT_Forget_Frame()'. + + The benefits of frames are various. Consider these two + approaches at extracting values: + + if ( (error = Read_Short( &var1 )) || + (error = Read_Long ( &var2 )) || + (error = Read_Long ( &var3 )) || + (error = Read_Short( &var4 )) ) + + return FAILURE; + + and + + /* Read the next 16 bytes */ + if ( (error = TT_Access_Frame( 16L )) ) + return error; /* The Frame could not be read */ + + var1 = Get_Short(); /* extract values from the frame */ + var2 = Get_Long(); + var3 = Get_Long(); + var4 = Get_Short(); + + TT_Forget_Frame(); /* release the frame */ + + In the first case, there are four error assignments with four + checks of the file read. This unnecessarily increases the size + of the generated code. Moreover, you must be sure that `var1' + and `var4' are short variables, `var2' and `var3' long ones, if + you want to avoid bugs and/or compiler warnings. + + In the second case, you perform only one check for the read, and + exit immediately on failure. Then the values are extracted from + the frame, as the result of function calls. This means that you + can use automatic type conversion; there is no problem if + e.g. `var1' and `var4' are longs, unlike previously. + + On big-endian machines, the `Get_xxx()' functions could also be + simple macros that merely peek the values directly from the + frame, which speeds up and simplifies the generated code! + + And finally, frames are ideal when you are using memory-mapped + files, as the frame is not really `pre-loaded' and never uses + any `heap' space. + + IMPORTANT: You CANNOT nest several frame accesses. There is + only one frame available at a time for a specific + instance. + + It is also the programmer's responsibility to never + extract more data than was pre-loaded in the frame! + (But you usually know how many values you want to + extract from the file before doing so). + + +3. Memory Management +-------------------- + + The library now uses a component which interface is similar to + malloc()/free(). It defines only two functions. + + * Alloc() + + To be used like malloc(), except that it returns an error code, + not an address. Its arguments are the size of the requested + block and the address of the target pointer to the `fresh' + block. An error code is returned in case of failure (and this + will also set the target pointer to NULL), 0 in case of success. + + Alloc() should always respect the following rules: + + - Requesting a block of size 0 should set the target pointer to + NULL and return no error code (i.e., return 0). + + - The returned block is always zeroed. This is an important + assumption of other parts of the library. + + If you wish to replace the memory component with your own, + please respect this behaviour, or your engine won't work + correctly. + + * Free() + + As you may have already guessed, Free() is Alloc()'s + counterpart. It takes as argument the _target pointer's + address_! You should _never_ pass the block's address directly, + i.e. the pointer, to Free(). + + Free should always respect the following rules: + + - Calling it with a NULL argument, or the address of a NULL + pointer is valid, and should return success. + + - The pointer is always set to NULL after the block's + deallocation. This is also an important assumption of many + other parts of the library. + + If you wish to replace the memory component with your own, + please respect this behaviour, or your engine won't work + correctly. + + As the pointers addresses needed as arguments are typed `void**', + the component's interface also provides in the C version some + macros to help use them more easily, these are: + + MEM_Alloc A version of Alloc that casts the argument pointer + to (void**). + + ALLOC Same as MEM_Alloc, but with an assignment to a + variable called `error'. See the section `error + handling' above for more info on this. + + FREE A version of Free() that casts the argument + pointer to (void**). There is currently no error + handling by with this macro. + + MEM_Set An alias for `memset()', which can be easily + changed to anything else if you wish to use a + different memory manager than the functions + provided by the ANSI libc. + + MEM_Copy An alias of `memcpy()' or `bcopy()' used to move + blocks of memory. You may change it to something + different if you wish to use something else that + your standard libc. + + +4. Support for threaded environments +------------------------------------ + + Support for threaded environments have been added to the C + sources, and only to these. It is now theorically possible to + build three distinct versions of the library: + + single-thread build: + + The default build. This one doesn't known about different + threads. Hence, no code is generated to perform coherent data + sharing and locking. + + thread-safe build: + + With this build, several threads can use the library at the + same time. However, some key components can only be used by + one single thread at a time, and use a mutex to synchronize + access to their functions. These are mainly the file, raster + and interpreter components. + + re-entrant build: + + A re-entrant version is able to perform certain actions in + parallel that a thread-safe one cannot. This includes + accessing file(s) in parallel, interpreting different + instruction streams in parallel, or even scan-line converting + distinct glyphs at the same time. + + Note that most of the latest changes in the engine are making the + distinction between the thread-safe and re-entrant builds thinner + than ever. + + There is a `ttmutex' component that presents a generic interface + to mutex operations. It should be re-implemented for each + platform. + + + + +--- end of convntns.txt --- diff --git a/docs/credits b/docs/credits new file mode 100644 index 0000000..9d6c6bd --- /dev/null +++ b/docs/credits @@ -0,0 +1,94 @@ + +NOTE: This list is far from being complete. Please send a mail if + you want to be included. + + +David TURNER (david.turner@freetype.org) + + Main engine design and coding. Pascal source maintainer. + + +Robert WILHELM (robert.wilhelm@freetype.org) + + Web, FTP and CVS wizard & administrator. C source maintainer. + Incredible bug and spell fixer! + + +Werner LEMBERG (werner.lemberg@freetype.org) + + Internationalization and CJK guru. ttf2pk author. + + +Antoine LECA (antoine.leca@renault.fr) + + 16bit support for various compilersamd platforms. + + +Mark LEISHER (mleisher@crl.nmsu.edu) + + Internationalization. X11 font server prototype author. ttf2bdf + author. + + +Pavel KANKOVSKY (peak@argo.troja.mff.cuni.cz) + + Old logo, internationalization, on-line demo, humor, and + remarkable bug hunter! + + +Erwin DIETERICH (erwin.dieterich.ed@bayer-ag.de) + + *Real* internationalization :-) Author of the ftxerr18 and gettext + support. + + +Michal NECASEK (mike@mendelu.cz) + + Author and maintainer of the OS/2 font driver based on FreeType. + + +Munagala V. S. RAMANATH, CurveSoft, Inc. (ram@curvesoft.com) + + Contributor of many bug fixes and code improvements. + + +Williss, Dave (dwilliss@tnt.microimages.com) + + GSUB support. Author of the Mac port. + + +Yamano-uchi, Hidetoshi + + embedded bitmap support + + + +The following people have also contributed to the development of +FreeType: + + Beebe, Nelson H. F.: Tested FreeType on many platforms. + Benett, Kendall + Choi, Junho + Chong, Chin Soon + Chroboczek, Juliusz: Author of the xfsft Truetype font server. + Cohen, Marc L. + Davis, Jack + Demaille, Akim + Ellis, Duane + Feinberg, Matthew + Furr, Anthony + Hoo, Dave: 16bit support + Jamme, Thibault + Lewis, Kevin + Long, Jeff + Marukawa, Kazushi + Nijtmans, Jan + Olson, Eric + Paterson-Jones, Roland + Pommnitz, Joerg + Quigley, Ian + Steger, Helmut + Taggart, Scott + + +--- end of credits --- diff --git a/docs/freetype.lsm b/docs/freetype.lsm new file mode 100644 index 0000000..c8c15e3 --- /dev/null +++ b/docs/freetype.lsm @@ -0,0 +1,16 @@ +Begin3 +Title: freetype +Version: 1.3 +Entered-date: 01SEP99 +Description: truetype font rasterizer +Keywords: font truetype rasterizer +Author: David Turner , + Werner Lemberg + Robert Wilhelm +Maintained-by: Robert Wilhelm +Primary-site: ftp://sunsite.unc.edu/pub/Linux/X11/fonts/ +Alternate-site: +Original-site: ftp://ftp.freetype.org/pub/freetype +Platforms: Linux, OS/2, MSDOS, Amiga OS, Unix, Mac, Windows +Copying-policy: BSD-like +End diff --git a/docs/glyphs.htm b/docs/glyphs.htm new file mode 100644 index 0000000..d6f0b54 --- /dev/null +++ b/docs/glyphs.htm @@ -0,0 +1,1257 @@ + + +An introduction to glyphs + + + + + + + + +http://www.freetype.org

+ +

+ Glyph Hell

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

+

+ +

+ +Introduction

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

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

+ +


+ + +I. An overview of font files

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

+ +

    + +
  • Face Data

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

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

    + +

  • Instance Data

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

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

    + +

  • Glyph Data

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

    + +

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

      + +

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

      + +

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

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

    + +

  • Text and Layout Data

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

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

+ +


+ + +II. Glyph Outlines

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

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

+ +

    + +
  1. Vectorial representation

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

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

    + +

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

      + +

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

      + +

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

    + +

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

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

    + +

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

      + +

      + pixel_size = point_size * + resolution / 72 +

      + +

      + pixel_coordinate = grid_coordinate * + pixel_size / EM_size +

      + +

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

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

    + +

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

    + +


    + IMPORTANT NOTE:

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


    + +

  2. Hinting and Bitmap rendering

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

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

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

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

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

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

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

+ + +


+ +III. Glyph metrics

+ +

    + +
  1. Baseline, Pens and Layouts

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

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

    + +

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

      + +

      +

      +

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

      + +


      + IMPORTANT NOTE:

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


      + +

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

      + +

      + +
      + +

    + +

  2. Typographic metrics and bounding + boxes

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

    + +

      + +
    • The ascent

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

      + +

    • The descent

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

      + +

    • The linegap

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

      + +

      + ascent - descent + linegap +

      + + if you use the typographic values. + +

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

    + +

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

      + +

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

      + +

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

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

    + + Other, simpler metrics are:

    + +

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

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

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

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

      + +

    • The internal leading

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

      + +

      + internal_leading = ascent - descent - + EM_size +

      + +

    • The external leading

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

    + +

  3. Bearings and Advances

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

    + +

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

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

      + +

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

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

      + +

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

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

      + +

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

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

      + +

    5. The glyph width

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

      + +

    6. The glyph height

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

      + +

    7. The right side bearing

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

      + +

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

    + +

    +

    + + +

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

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

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

    + +

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

      + +

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

      + +

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

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

    + +


    + IMPORTANT NOTE:

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

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


    + +

+ +

+ + +IV. Text processing

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

+ +

    + +
  1. Writing simple text strings

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

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

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

    + +

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

      + +

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

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

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

      + +

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

      + +

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

      + +

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

    + +

  2. Writing right-to-left and vertical text

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

    + +

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

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

      + +

    • For vertical text (like Chinese or Japanese)

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

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

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

      +  pen_y -= metrics.advance;
      +
      + +

    + +

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

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

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

    + +

      + +
    1. Generate the bitmaps.

      + +

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

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

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

        + +

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

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

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

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

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

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

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

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

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

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

    + +

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

      + +

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

      + +

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

      + +

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

    + +

  5. Kerning glyphs

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

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

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

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

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

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

    + +

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

      + +

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

      + +

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

        + +

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

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

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

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

    + +

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

      + +

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

      + +

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

    + +


    + IMPORTANT NOTE:

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

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


    + +

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

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

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

    + +


    + NOTE:

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


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

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

    + +

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

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

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

    + +


    + NOTE:

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

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

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


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

    + +

  8. Other interesting text processes

    + +

      + +
    • Glyph substitution

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

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

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

      + +

    • Justification

      + + ... + +

    + +
+ +To be continued... + + + diff --git a/docs/glyphs.txt b/docs/glyphs.txt new file mode 100644 index 0000000..239686a --- /dev/null +++ b/docs/glyphs.txt @@ -0,0 +1,999 @@ +http://www.freetype.org + + Glyph Hell + + An introduction to glyphs, as used and defined in the FreeType engine + + ------------------------------------------------------------------------ + +Introduction + +This article discusses in great detail the definition of glyph metrics, per +se the TrueType specification, and the way they are managed and used by the +FreeType engine. This information is crucial when it comes to rendering text +strings, either in a conventional (i.e. Roman) layout, or with vertical or +right-to-left ones. Some aspects like glyph rotation and transformation are +explained too. + +Comments and corrections are highly welcome, and can be sent to the FreeType +developers list. + + ------------------------------------------------------------------------ + +I. An overview of font files + +In TrueType, a single font file is used to contain information related to +classification, modeling and rendering of text using a given typeface. This +data is located in various independent `tables', which can be sorted in four +simple classes, as described below: + + * Face Data + + We call face data the amount of information related to a given + typeface, independently of any particular scaling, transformation, + and/or glyph index. This usually means some typeface-global metrics and + attributes, like family and styles, PANOSE number, typographic + ascenders and descenders, as well as some very TrueType specific items + like the font `programs' found in the fpgm and prep tables, the gasp + table, character mappings, etc. + + In FreeType, a face object is used to model a font file's face data. + + * Instance Data + + We call instance a given pointsize/transformation, at a given device + resolution (e.g. 8pt at 96x96dpi, or 12pt at 300x600dpi, etc). Some + tables found in the font files are used to produce instance-specific + data, like the cvt table, or the prep program. Though they are often + part of the face data, their processing results in information called + instance data. + + In FreeType, it is modeled through an instance object, which is always + created from an existing face object. + + * Glyph Data + + We call glyph data the piece of information related to specific glyphs. + This includes the following things that are described in more details + in the next sections: + + o The glyph's vectorial representation, also called its outline. + + o Various metrics, like the glyph's bounding box, its bearings and + advance values. + + o TrueType specifies a specific instruction bytecode, used to + associate each glyph with a small program, called the glyph code. + Its purpose is to grid-fit the outline to any target instance, in + order to produce excellent output at small pixel sizes. + + The FreeType engine doesn't map each glyph to a single structure, as + this would waste memory for no good reason. Rather, a glyph object is a + container, created from any active face, which can be used to load + and/or process any font glyph at any instance (or even no instance at + all). Of course, the glyph properties (outline, metrics, bitmaps, etc.) + can be extracted independently from an object once it has been loaded + or processed. + + * Text and Layout Data + + Finally, there is a last class of data that doesn't really fit in all + others, and that can be called text data. It comprises information + related to the grouping of glyphs together to form text. Simple + examples are the kerning table, which controls the spacing between + adjacent glyphs, as well as some of the extensions introduced in + TrueType Open, OpenType, and TrueType GX like glyph substitution + (ligatures, vertical representations), baseline management, + justification, etc. + + This article focuses on the basic TrueType tables, and hence, will only + talk about kerning, as FreeType doesn't support OpenType nor GX (yet). + [Support for TrueType Open is already partially available.] + + ------------------------------------------------------------------------ + +II. Glyph Outlines + +TrueType is a scalable font format; it is thus possible to render glyphs at +any scale, and under any affine transform, from a single source +representation. However, simply scaling vectorial shapes exhibits at small +sizes (where `small' refers here to anything smaller than at least +150 pixels) a collection of un-harmonious artifacts, like widths and/or +heights degradations. + +Because of this, the format also provides a complete programming language +used to design small programs associated to each glyph. Its role is to align +the point positions on the pixel grid after the scaling. This operation is +hence called grid-fitting, or even hinting. + + 1. Vectorial representation + + The source format of outlines is a collection of closed paths called + contours. Each contour delimits an outer or inner region of the glyph, + and can be made of either line segments and/or second-order beziers + (also called conic beziers or quadratics). + + It is described internally as a series of successive points, with each + point having an associated flag indicating whether it is `on' or `off' + the curve. These rules are applied to decompose the contour: + + o Two successive `on' points indicate a line segment joining them. + + o One `off' point amidst two `on' points indicates a conic bezier, + the `off' point being the control point, and the `on' ones the + start and end points. + + o Finally, two successive `off' points forces the rasterizer to + create (only during bitmap rendering) a virtual `on' point amidst + them, at their exact middle. This greatly facilitates the + definition of successive Bezier arcs. + + * # on + * off + __---__ + #-__ _-- -_ + --__ _- - + --__ # \ + --__ # + -# + Two `on' points + Two `on' points and one `off' point + between them + + * + # __ Two `on' points with two `off' + \ - - points between them. The point + \ / \ marked `0' is the middle of the + - 0 \ `off' points, and is a `virtual + -_ _- # on' point where the curve passes. + -- It does not appear in the point + list. + * + + Each glyph's original outline points are located on a grid of + indivisible units. The points are stored in the font file as + 16-bit integer grid coordinates, with the grid origin's being at (0,0); + they thus range from -16384 to 16383. + + In creating the glyph outlines, a type designer uses an imaginary + square called the EM square. Typically, the EM square encloses the + capital letter `M' and most other letters of a typical roman alphabet. + The square's size, i.e., the number of grid units on its sides, is very + important for two reasons: + + o It is the reference used to scale the outlines to a given + instance. For example, a size of 12pt at 300x300dpi corresponds to + 12*300/72 = 50 pixels. This is the size the EM square would appear + on the output device if it was rendered directly. In other words, + scaling from grid units to pixels uses the formula + + pixel_size = point_size * resolution / 72 + + pixel_coordinate = grid_coordinate * pixel_size / EM_size + + o The greater the EM size is, the larger resolution the designer can + use when digitizing outlines. For example, in the extreme example + of an EM size of 4 units, there are only 25 point positions + available within the EM square which is clearly not enough. + Typical TrueType fonts use an EM size of 2048 units (note: with + Type 1 PostScript fonts, the EM size is fixed to 1000 grid units. + However, point coordinates can be expressed in floating values). + + Note that glyphs can freely extend beyond the EM square if the font + designer wants this. The EM is used as a convenience, and is a valuable + convenience from traditional typography. + + Grid units are very often called font units or EM units. + + ----------------------------------------------------------------------- + IMPORTANT NOTE: + + Under FreeType, scaled pixel positions are all expressed in the 26.6 + fixed float format (made of a 26-bit integer mantissa, and a 6-bit + fractional part). In other words, all coordinates are multiplied by 64. + The grid lines along the integer pixel positions, are multiples of 64, + like (0,0), (64,0), (0,64), (128,128), etc., while the pixel centers + lie at middle coordinates (32 modulo 64) like (32,32), (96,32), etc. + ----------------------------------------------------------------------- + + 2. Hinting and Bitmap rendering + + As said before, simply scaling outlines to a specific instance always + creates undesirable artifacts, like stems of different widths or + heights in letters like `E' or `H'. Proper glyph rendering needs that + the scaled points are aligned along the pixel grid (hence the name + grid-fitting), and that important widths and heights are respected + throughout the whole font (for example, it is very often desirable that + the letters `I' and `T' have their central vertical line of the same + pixel width). + + Type 1 PostScript font files include with each glyph a small series of + distances called hints, which are later used by the type manager to try + grid-fitting the outlines as cleverly as possible. On one hand, it has + the consequence that upgrading your font engine can enhance the visual + aspects of all fonts of your system; on the other hand, the quality of + even the best version of Adobe's Type Manager isn't always very + pleasing at small sizes (notwithstanding font smoothing). + + TrueType takes a radically different approach: Each glyph has an + associated `program', designed in a specific geometrical language, + which is used to align explicitly each outline point to the pixel grid, + preserving important distances and metrics. A stack-based low-level + bytecode is used to store it in the font file, and is interpreted later + when rendering the scaled glyphs. + + This means that even very complex glyphs can be rendered perfectly at + very small sizes, as long as the corresponding glyph code is designed + correctly. Moreover, a glyph can loose some of its details, like + serifs, at small sizes to become more readable, because the bytecode + provides interesting features. + + However, this also have the sad implication that an ill-designed glyph + code will always render junk, whatever the font engine's version, and + that it's very difficult to produce quality glyph code. There are about + 200 TrueType opcodes, and no known `high-level language' for it. Most + type artists aren't programmers at all and the only tools able to + produce quality code from vectorial representation have been + distributed to only a few font foundries, while tools available to the + public, e.g. Fontographer, are usually expensive though generating + average to mediocre glyph code. + + All this explains why an enormous number of broken or ugly `free' fonts + have appeared on the TrueType scene, and that this format is now + mistakenly thought as `crap' by many people. Funnily, these are often + the same who stare at the `beauty' of the classic `Times New Roman' and + `Arial/Helvetica' at 8 points. + + Once a glyph's code has been executed, the scan-line converter converts + the fitted outline into a bitmap (or a pixmap with font-smoothing). + + ------------------------------------------------------------------------ + +III. Glyph metrics + + 1. Baseline, Pens and Layouts + + The baseline is an imaginary line that is used to `guide' glyphs when + rendering text. It can be horizontal (e.g. Roman, Cyrillic, Arabic, + etc.) or vertical (e.g. Chinese, Japanese, etc). Moreover, to render + text, a virtual point, located on the baseline, called the pen + position, is used to locate glyphs. + + Each layout uses a different convention for glyph placement: + + o With horizontal layout, glyphs simply `rest' on the baseline. Text + is rendered by incrementing the pen position, either to the right + or to the left. + + [Image] + + The distance between two successive pen positions is + glyph-specific and is called the advance width. Note that its + value is always positive, even for right-to-left oriented + alphabets, like Arabic. This introduces some differences in the + way text is rendered. + + ------------------------------------------------------------------ + IMPORTANT NOTE: + + The pen position is always placed on the baseline in TrueType, + unlike the convention used by some graphics systems, like Windows, + to always put the pen above the line, at the ascender's position. + ------------------------------------------------------------------ + + o With vertical layout, glyphs are centered around the baseline: + + [Image] + + 2. Typographic metrics and bounding boxes + + A various number of face metrics are defined for all glyphs in a given + font. Three of them have a rather curious status in the TrueType + specification; they only apply to horizontal layouts: + + o The ascent + + This is the distance from the baseline to the highest/upper grid + coordinate used to place an outline point. It is a positive value, + due to the grid's orientation with the y axis upwards. + + o The descent + + The distance from the baseline to the lowest grid coordinate used + to place an outline point. This is a negative value, due to the + grid's orientation. + + o The linegap + + The distance that must be placed between two lines of text. The + baseline-to-baseline distance should be computed as + + ascent - descent + linegap + + if you use the typographic values. + + The problem with these metrics is that they appear three times in a + single font file, each version having a slightly different meaning: + + 1. The font's horizontal header provides the ascent, descent and + linegap fields, which are used to express the designer's intents, + rather than the real values that may be computed from all glyphs + in the outline. These are used by the Macintosh font engine to + perform font mapping (i.e. font substitution). + + 2. The OS/2 table provides the usWinAscent and usWinDescent fields. + These values are computed for glyphs of the Windows ANSI charset + only, which means that they are wrong for any other glyph. Note + that usWinDescent is always positive (i.e. looks like `-descent'). + + 3. The OS/2 table provides the typoAscender, typoDescender and + typoLinegap values, which hopefully concern the whole font file. + These are the correct system-independent values! + + All metrics are expressed in font units. If you want to use any of the + two first versions of these metrics, the TrueType specification + contains some considerations and computing tips that might help you. + + Other, simpler metrics are: + + o The glyph's bounding box, also called bbox + + This is an imaginary box that encloses any glyph (usually as + tightly as possible). It is represented by four fields, namely + xMin, yMin, xMax, and yMax, that can be computed for any outline. + In FreeType, their values can be in font units (if measured in the + original outline) or in 26.6 pixel units (if measured on scaled + outlines). + + Note that if it wasn't for grid-fitting, you wouldn't need to know + a box's complete values, but only its dimensions to know how big + is a glyph outline/bitmapa. However, correct rendering of hinted + glyphs needs the preservation of important grid alignment on each + glyph translation/placement on the baseline, which is why FreeType + always returns the complete glyph outline. + + Note also that the font's header contains a global font bounding + box in font units which should enclose all glyphs in a font. This + can be used to pre-compute the maximum dimensions of any glyph at + a given instance. + + o The internal leading + + This concept comes directly from the world of traditional + typography. It represents the amount of space within the `leading' + which is reserved for glyph features that lay outside of the EM + square (like accentuation). It usually can be computed as + + internal_leading = ascent - descent - EM_size + + o The external leading + + This is another name for the linegap. + + 3. Bearings and Advances + + Each glyph has also distances called bearings and advances. Their + definition is constant, but their values depend on the layout, as the + same glyph can be used to render text either horizontally or + vertically. + + 1. The left side bearing: a.k.a. bearingX + + This is the horizontal distance from the current pen position to + the glyph's left bounding box edge. It is positive for horizontal + layouts, and most generally negative for vertical one. + + 2. The top side bearing: a.k.a. bearingY + + This is the vertical distance from the baseline to the top of the + glyph's bounding box. It is usually positive for horizontal + layouts, and negative for vertical ones + + 3. The advance width: a.k.a. advanceX + + This is the horizontal distance the pen position must be + incremented (for left-to-right writing) or decremented (for + right-to-left writing) by after each glyph is rendered when + processing text. It is always positive for horizontal layouts, and + null for vertical ones. + + 4. The advance height: a.k.a. advanceY + + This is the vertical distance the pen position must be decremented + by after each glyph is rendered. It is always null for horizontal + layouts, and positive for vertical layouts. + + 5. The glyph width + + The glyph's horizontal extent. More simply, it is (bbox.xMax - + bbox.xMin) for unscaled font coordinates. For scaled glyphs, its + computation requests specific care, described in the grid-fitting + chapter below. + + 6. The glyph height + + The glyph's vertical extent. More simply, it is (bbox.yMax - + bbox.yMin) for unscaled font coordinates. For scaled glyphs, its + computation requests specific care, described in the grid-fitting + chapter below. + + 7. The right side bearing + + Only used for horizontal layouts to describe the distance from the + bbox's right edge to the advance width. It is in most cases a + non-negative number. The FreeType library doesn't provide this + metric directly, as it isn't really part of the TrueType + specification. It can be computed simply as + + advance_width - left_side_bearing - (xMax-xMin) + + [Image] + + [Image] + + Finally, if you use `ABC widths' under Windows and OS/2, the following + relations apply: + + A = left side bearing + B = width + C = right side bearing + + A+B+C = advance width + + 4. The effects of grid-fitting + + All these metrics are stored in font units in the font file. They must + be scaled and grid-fitted properly to be used at a specific instance. + This implies several things: + + o First, a glyph program not only aligns the outline along the grid + pixel, it also processes the left side bearing and the advance + width. Other grid-fitted metrics are usually available in optional + TrueType tables if you need them. + + o A glyph program may decide to extend or stretch any of these two + metrics if it has a need for it. This means that you cannot assume + that the fitted metrics are simply equal to the scaled one plus or + minus a liberal distance < 1 pixel (i.e., less than 64 fractional + pixel units). For example, it is often necessary to stretch the + letter `m' horizontally at small pixel sizes to make all vertical + stems visible, while the same glyph can be perfectly `square' at + larger sizes. + + o Querying the fitted metrics of all glyphs at a given instance is + very slow, as it needs to load and process each glyph + independently. For this reason, some optional TrueType tables are + defined in the specification, containing pre-computed metrics for + specific instances (the most commonly used, like 8, 9, 10, 11, 12, + and 14 points at 96dpi, for example). These tables aren't always + present in a TrueType font. + + If you don't need the exact fitted value, it's much faster to + query the metrics in font units, then scale them to the instance's + dimensions. + + ----------------------------------------------------------------------- + IMPORTANT NOTE: + + Another very important consequence of grid-fitting is the fact that + moving a fitted outline by a non-integer pixel distance will simply + ruin the hinter's work, as alignments won't be preserved. The + translated glyph will then look `ugly' when converted to a bitmap! + + In other words, each time you want to translate a fitted glyph outline, + you must take care of only using integer pixel distances (the x and + y offsets must be multiples of 64, which equals to 1.0 in the 26.6 + fixed float format). If you don't care about grid-fitting (typically + when rendering rotated text), you can use any offset you want and use + sub-pixel glyph placement. + ----------------------------------------------------------------------- + + ------------------------------------------------------------------------ + +IV. Text processing + +This section demonstrates how to use the concepts previously defined to +render text, whatever the layout you use. + + 1. Writing simple text strings + + We will start by generating a simple string with a Roman alphabet. The + layout is thus horizontal, left to right. + + For now, we will assume all glyphs are rendered in a single target + bitmap. The case of generating individual glyph bitmaps, then placing + them on demand on a device is presented in a later chapter of this + section. + + Rendering the string needs to place each glyph on the baseline; this + process looks like the following: + + 1. Place the pen to the cursor position. The pen is always located on + the baseline. Its coordinates must be grid-fitted (i.e. multiples + of 64)! + + pen_x = cursor_x; + pen_y = cursor_y; + + 2. Load the glyph outline and its metrics. Using the flag + TTLOAD_DEFAULT will scale and hint the glyph: + + TT_Load_Glyph( instance, + glyph, + glyph_index, + TTLOAD_DEFAULT ); + + TT_Get_Glyph_Metrics( glyph, &metrics ); + TT_Get_Glyph_Outline( glyph, &outline ); + + 3. The loader always places the glyph outline relative to the + imaginary pen position (0,0). You thus simply need to translate + the outline by the vector: + + ( pen_x, pen_y ) + + To place it on its correct position, you can use the call + + TT_Translate_Outline( outline, pen_x, pen_y ); + + 4. Render the outline in the target bitmap, the glyph will be + surimposed on it with a binary `or' operation (FreeType never + creates glyph bitmaps by itself, it simply renders glyphs in the + arrays you pass to it. See the API reference for a complete + description of bitmaps and pixmaps). + + TT_Get_Outline_Bitmap( outline, &target_bitmap ); + + ------------------------------------------------------------------ + IMPORTANT NOTE: + + If you don't want to access the outline in your code, you can also + use the API function TT_Get_Glyph_Bitmap() which does the same as + the previous lines: + + TT_Get_Glyph_Outline( glyph, &outline ); + TT_Translate_Outline( outline, x_offset, y_offset ); + TT_Get_Outline_Bitmap( outline, &target_bitmap ); + TT_Translate_Outline( outline, -x_offset, -y_offset ); + + is equivalent to: + + TT_Get_Glyph_Bitmap( glyph, + x_offset, + y_offset, + &target_bitmap ); + + ------------------------------------------------------------------ + + 5. Now advance the pen to its next position. The advance is always + grid-fitted when the glyph was hinted: + + pen_x += metrics.advance; + + The advance being grid-fitted, the pen position remains aligned on + the grid. + + 6. Start over on item 2 until string completion. That's it! + + 2. Writing right-to-left and vertical text + + Generating strings for different layouts is very similar. Here are the + most important differences. + + o For right-to-left text (like Arabic) + + The main difference here is that, as the advance width and left + side bearings are oriented against the flow of text, the pen + position must be decremented by the advance width, before placing + and rendering the glyph. Other than that, the rest is strictly + similar. + + o For vertical text (like Chinese or Japanese) + + In this case, the baseline is vertical, which means that the pen + position must be shifted in the vertical direction. You need the + vertical glyph metrics to do that (using the + TT_Get_Big_Glyph_Metrics() function). + + Once you get these, the rest of the process is very similar. The + glyph outline is placed relative to an imaginary origin of (0,0), + and you should translate it to the pen position before rendering + it. + + The big difference is that you must decrement pen_y, rather than + increment pen_x (this is for the TrueType convention of y oriented + upwards). + + pen_y -= metrics.advance; + + 3. Generating individual glyph bitmaps and using them to render text + + Loading each glyph when rendering text is slow, and it's much more + efficient to render each one in a standalone bitmap to place it in a + cache. Text can then be rendered fast by applying simple blit + operations on the target device. + + To be able to render text correctly with the bitmaps, you must record + and associate with them its fitted bearings and advances. Hence the + following process: + + 1. Generate the bitmaps. + + + Load the glyph and get its metrics. + + TT_Load_Glyph( instance, + glyph, + glyph_index, + TTLOAD_DEFAULT ); + + TT_Get_Glyph_Metrics( glyph, &metrics ); + + The bbox is always fitted when calling TT_Get_Glyph_Metrics() + on a hinted glyph. You can then easily compute the glyph's + dimension in pixels as: + + width = (bbox.xMax - bbox.xMin) / 64; + height = (bbox.yMax - bbox.yMin) / 64; + + NOTE 1: + The fitted bounding box always contains all the dropouts that + may be produced by the scan-line converter. This width and + height are thus valid for all kinds of glyphs). + + NOTE 2: + If you want to compute the dimensions of a rotated outline's + bitmap, compute its bounding box with TT_Get_Outline_BBox(), + then grid-fit the bbox manually: + + #define FLOOR(x) ((x) & -64) + #define CEILING(x) (((x)+63) & -64) + + xMin = FLOOR(xMin); + yMin = FLOOR(yMin); + yMin = CEILING(xMax); + yMax = CEILING(yMax); + + then compute width and height as above. + + + Create a bitmap of the given dimension, e.g.: + + bitmap.width = width; + bitmap.cols = (width+7) & -8; + bitmap.rows = height; + bitmap.flow = TT_Flow_Up; + bitmap.size = bitmap.cols * bitmap.rows; + bitmap.buffer = malloc( bitmap.size ); + + + Render the glyph into the bitmap. + + Don't forget to shift it by (-xMin, -yMin) to fit it in the + bitmap: + + /* Note that the offsets must be grid-fitted to */ + /* preserve hinting! */ + TT_Get_Glyph_Bitmap( glyph, + &bitmap, + -bbox.xMin, + -bbox.yMin ); + + 2. Store the bitmap with the following values: + + bearingX / 64 = left side bearing in pixels + advance / 64 = advance width/height in pixels + + When your cache is set up, you can then render text using a scheme + similar to the ones describe in 1. and 2., with the exception that + now pen positions and metrics are expressed in pixel values. We + are done! + + pen_x = cursor_x; + pen_y = cursor_y; + + while ( glyph_to_render ) + { + access_cache( glyph_index, metrics, bitmap ); + + blit_bitmap_to_position + ( pen_x + bearingX, + pen_y (+ bearingY depending on orientation ) ); + + pen_x += advance; + } + + 4. Device-independent text rendering + + The previously described rendering processes all align glyphs on the + baseline according to metrics fitted for the display's distance. In + some cases, the display isn't the final output, and placing the glyphs + in a device-independent way is more important than anything. + + A typical case is a word processor which displays text as it should + appear on paper when printed. As you've probably noticed, the glyphs + aren't always spaced uniformly on the screen as you type them, + sometimes the space between an `m' and a `t' is too small, some other + it is too large, etc. + + These differences are simply due to the fact that the word processor + aligns glyphs in an device-independent way, using original metrics in + font units to do it, then scale them as it can to display text on + screen, usually at a very smaller resolution than your printer's one. + + Device-independence is a crucial part of document portability, and it + is very saddening to see that most professional word processors don't + do it correctly. For example, MS Word uses the fitted metrics of the + printer's resolution, rather than the originals in font units. + + This is great to get sure that your text prints very well on your + printer, but it also implies that someone printing the exact same + document on a device with different output resolutions (e.g. bubble-jet + vs. laser printers) may encounter trouble. + + As the differences in advances accumulate on one line, they can sum to + the width of one or more glyphs in extreme cases, which is enough to + `overflow' the automatic justification algorithm. This may add + additional lines of printed text, or even remove some. Moreover, + supplemental lines can produce unexpected page breaks and `blank' + pages. This can be extremely painful when working with large documents, + as this `feature' may require you to redesign completely your + formatting to re-print it. + + In conclusion, if you want portable document rendering, never hesitate + to use and apply device-independent terms! For example, a simple way to + produce text would be: + + 1. Get a scale to convert from your device-independent units to 26.6 + pixels. + + 2. Get another scale to convert from original font units to + device-independent units. + + 3. Perform pen placement and advances in device-independent units. + + 4. To render each glyph, compute the pen's rounded position, as well + as the rounded glyph left side bearing, both expressed in 26.6 + pixels (don't use the fitted metrics). You will then be able to + place the glyph and/or blit its bitmap. + + 5. Kerning glyphs + + An interesting effect that most people appreciate is kerning. It + consists of modifying the spacing between two successive glyphs + according to their outlines. For example, the letters `T' and a `y' can + be easily moved closer, as the top of the `y' fits nicely under the + `T's upper right bar. + + To perform kerning, the TrueType specification provides a specific + table (its tag being `kern'), with several storage formats. This + section doesn't explain how to access this information; however, you + can have a look at the standard extension called `ttkern.h' which comes + with FreeType. + + The kerning distance between two glyphs is a value expressed in font + units which indicates whether their outline can be moved together or + apart when one follows the other. The distance isn't reflexive, which + means that the kerning for the glyph pair (`T',`y') isn't the same as + the one for (`y',`T'). + + The value is positive when the glyphs must be moved apart, and negative + when they must be moved closer. You can implement kerning simply by + adding its scaled and rounded value to the advance width when moving + the pen position. Here an example for horizontal kerning: + + #define ROUND( x ) ( (x + 32) & -64 ) + + scaled_kerning = kerning * imetrics.x_scale / 0x10000; + + pen_x += metrics.advance + ROUND( scaled_kerning ); + + 6. Rotated and stretched/slanted text + + In order to produce rotated glyphs with FreeType, one must understand a + few things: + + o The engine doesn't apply specific transformations to the glyphs it + loads and processes (other than the simpler resolution-base + scaling and grid-fitting). If you want to rotate glyphs, you will + have to load their outline, then apply the geometric + transformations that please you (a number of APIs are there to + help you to do it easily). + + o Even if the glyph loader hints `straight' glyphs, it is possible + to inform the font and glyph programs that you're going to later + transform the resulting outlines. Two flags can be passed to the + bytecode interpreter: + + + The `rotated' flag indicates that you are going to rotate the + glyphs in a non-trivial direction (i.e., on neither of the + two coordinate axis). You are advised not to set it when + writing 90 degrees-rotated text for example. + + + The `stretched' flag indicates that you are going to apply a + transformation that will distort distances. While rotations + and symmetries keep distances constant, slanting and + stretching do modify them. + + These flags can be interpreted by the glyph code to toggle certain + processings which vary from one font to the other. However, most of the + TrueType fonts that were tested with FreeType, if not all of them, + simply change the dropout-mode when any of these flags is set, and/or + disable hinting when rotation is detected. We advise you to never set + these flags, even when rotating text. For what it's worth, hinted + rotated text is no uglier than un-hinted one. + + You can use the function TT_Set_Instance_Transform_Flags() to set them. + Then, rendering can be done with the following calls: + + /* set the flags */ + TT_Set_Instance_Transforms( instance, + rotated, + stretched ); + + /* load a given glyph */ + TT_Get_Glyph_Outline( instance, + glyph, + index, + TTLOAD_DEFAULT ); + + /* access its outline */ + TT_Get_Glyph_Outline( instance, &outline ); + + /* in order to transform it */ + TT_Transform_Outline( outline, &matrix ); + /* and/or */ + TT_Translate_Outline( outline, + x_offset, y_offset ); + + /* to render it */ + TT_Get_Outline_Bitmap( outline, &bitmap ); + + Here is an example, assuming that the following variables + + TT_Matrix matrix; /* 2x2 matrix */ + TT_Pos x_off, y_off; /* corrective offsets */ + + define a transformation that can be correctly applied to a glyph + outline which have been previously placed relative to the imaginary + point position (0,0) with bearings preserved. Rendering text can now be + done as follows: + + 1. Initialize the pen position; when rotating, it is extremely well + advised to use sub-pixel placement as you don't care about + hinting. + + pen_x = cursor_x; + pen_y = cursor_y; + + 2. Transform the glyph as needed, then translate it to the current + pen position: + + TT_Transform_Outline( outline, &matrix ); + TT_Translate_Outline( outline, + pen_x + x_off, + pen_y + y_off ); + + (Note that the transformation offsets have been included in the + translation.) + + 3. Render the bitmap, as it has now been placed correctly. + + 4. To change the pen position, transform the vector (0,advance) with + your matrix, and add it: + + vec_x = metrics.advance; + vec_y = 0; + TT_Transform_Vector( &vec_x, &vec_y, &matrix ); + pen_x += vec_x; + pen_y += vec_y; + + 5. Start over at 2. until completion. + + ----------------------------------------------------------------------- + IMPORTANT NOTE: + + Do not grid-fit the pen position before rendering your glyph when + rendering rotated text. If you do, your transformed baseline won't be + preserved on each glyph, and the text will look like it's `hopping' + randomly. This is particularly visible at small sizes. + + Sub-pixel precision placement is very important for clean rotated text. + ----------------------------------------------------------------------- + + 7. Font-smoothing, a.k.a. gray-levels rendering + + The FreeType engine's scan-line converter (the component also called + the rasterizer) is able to convert a vectorial glyph outline into + either a normal bitmap, or an 8-bit pixmap (a.k.a. colored bitmaps on + some systems). This last feature is called gray-level rendering or + font-smoothing, because it uses a user-supplied palette to produce + anti-aliased versions of the glyphs. + + Its principle is to render a bitmap which is twice as large than the + target pixmap, then simply filtering it using a 2x2 summation. + + ----------------------------------------------------------------------- + NOTE: + + FreeType's scan-line converter doesn't use or need an intermediate + second bitmap. Rather, filtering is performed in a single pass during + the sweep (see the file `raster.txt' for more information about it). + ----------------------------------------------------------------------- + + You'll notice that, as with Windows 95, FreeType's rasterizer only + grays those parts of the glyph which need it, i.e., diagonals and + curves, while keeping horizontal and vertical stems straight `black'. + This greatly improves the legibility of text, while avoiding the + `blurry' look anti-aliased fonts typically found with Adobe's Type + Manager or Acrobat. + + There are thus five available gray-levels, ranging from 0 to 4, where + level 0 and level 4 are the background and foreground colors, + respectively, and where levels 1, 2, 3 are intermediate. For example, + to render black text on a white background, one can use a palette like: + + palette[0] = white (background) + palette[1] = light gray + palette[2] = medium gray + palette[3] = dark gray + palette[4] = black (foreground) + + To set the engine's gray-level palette, simply use the API function + TT_Set_Raster_Palette() after initialization. It expects an array of + 5 chars which will be used to render the pixmaps. + + Note that the rasterizer doesn't create bitmaps or pixmaps. Rather, it + simply renders glyphs in the arrays you pass to it. The generated glyph + bitmaps are simply `or'-ed to the target (with 0 being the background + as a convention); in the case of pixmaps, pixels are simply written to + the buffer, in spans of four aligned bytes. + + ----------------------------------------------------------------------- + NOTE: + + The raster isn't able to superpose `transparent' glyphs on the target + pixmap. This means that you should always call the API functions + TT_Get_Glyph_Pixmap() and TT_Get_Outline_Pixmap() with an empty map, + and perform the superposition yourself. + + This can be more or less tricky, depending on the palette you are using + and your target graphics resolution. One of the components found in the + test directory, called `display.c', has large comments on the way it + implements it for the test programs. You are encouraged to read the + test program sources to understand how one can take advantage of font + smoothing. + + Pixmap surimposition is too system-specific a feature to be part of the + FreeType engine. Moreover, not everybody needs it! + ----------------------------------------------------------------------- + + Finally, the question of sur-imposing anti-aliased colored text on any + texture, since being even more tricky, is left as an exercise to the + reader ;-) If this topic really interests you, the FreeType mailing + list may host some helpful enthusiasts ready to answer your questions. + Who knows :-) + + 8. Other interesting text processes + + o Glyph substitution + + Substitution is used to replace one glyph by another when some + specific condition is met in the text string. Its most common + examples are ligatures (like replacing the `f' followed by `i' by + the single glyph `fi' if available in the font), as well as + positional selection as performed in the Arabic script (for those + not aware of this, each letter of the Arabic alphabet can be + written differently according to its position on words: starting, + ending, intermediate, or isolated). + + The base TrueType format doesn't define any table for glyph + substitution. However, GX, TrueType Open, and OpenType provide + (incompatible) extensions to perform it. Of course, it isn't + supported by the engine, but an extension could be easily written + to access the required tables. + + [Support for TrueType Open is already partially available.] + + o Justification + + ... + +To be continued... diff --git a/docs/i18n.txt b/docs/i18n.txt new file mode 100644 index 0000000..22f5da9 --- /dev/null +++ b/docs/i18n.txt @@ -0,0 +1,161 @@ + +Using national language support (NLS) in FreeType +================================================= + +21. 1. 1998 +Erwin Dieterich + + +1) Introduction +2) Using gettext (user's view) +3) Using gettext (programmer's view) +4) Using gettext (maintainer's view) +5) How can I switch off NLS? I don't need/want it. + + +Only Unix NLS using gettext() is covered here. If you are able to +help with internationalization (i18n) for different operating +systems, please e-mail me at Erwin.Dieterich.ED@Bayer-AG.de. + + + +1) Introduction + +If a program is to be used by people who are not fluent speakers of +English, the first thing they will ask for is communication in their +native language. If someone tries to implement NLS in a program +using only #ifdefs and other such programming strategies, it's +likely that this someone will get nowhere. + +Gettext() is a possible way to help. Only minimal extra programming +effort is needed; the translations are implemented separately from +the program, and it is not necessary to recompile a program if you +want to switch the messages to a different language. If you wouldd +like to know more about gettext(), I recommend reading the GNU +gettext tools manual, written by Ulrich Drepper, Jim Meyering, and +Francois Pinard. + +Currently supported languages are: + + Czech (cz) translator: Pavel Kankovsky + + Dutch (nl) translator: Gertjan de Back + French (fr) translator: David Turner + German (de) translator: Erwin Dieterich + + Spain (es) translator: Miguel A. Perez Valdenebro + + +Currently supported programs in the `test' directory are: + + ftlint + ftdump + fterror + ftmetric + ftsbit + + +2) Using gettext (user's view) + +Using gettext as an end user is very simple. If FreeType is +correctly installed on your computer, you can simply issue an +`export LANG=' in your Bourne shell or `setenv +LANG=' if you are using csh. That's all. In order to +switch back to English, just use `export LANG=' or `setenv LANG='. + + is a two character code describing your language: +de=German, fr=French etc. Every supported language has its own +.po file in the `po' directory of FreeType. If your +language is not there you should consider contributing a +translation. Just e-mail me. Here is a transcript of what `export +LANG=' does: + + test> ftlint 24 furiosot.ttf + Could not find or open furiosot.ttf. + FreeType error message: OS/2 table missing. + + test> export LANG=de + test> ftlint 24 furiosot.ttf + Datei `furiosot.ttf' konnte nicht gefunden oder geöffnet werden. + FreeType Fehlermeldung: `OS/2'-Tabelle fehlt. + + test> export LANG= + test> ftlint 24 furiosot.ttf + Could not find or open file furioso.ttf. + FreeType error message: OS/2 table missing. + +Doesn't this look good? But what if nothing happens if you set +LANG? Here are some hints: + +First: Is your language really supported? If it is, you need to be +sure that you have gettext() installed (if you are sitting at a +Linux box, chances are very good that you have). If you compiled +FreeType yourself and nothing strange happened, then your version of +FreeType has NLS compiled in, as this is the default, unless you +forgot to install the translation files in the right places (`make +install' in the po/ directory should be enough, but you need root +permissions as these files are installed somewhere in /usr/local) -- +good luck :-) + + +3) Using gettext (programmer's view) + +If you intend to use NLS in your program, you just need to make a +few simple changes. Here I only describe how NLS is enabled in the +programs that come with FreeType in test/. If you would like to add +NLS to other programs using FreeType as well, take a look at +FreeType's installation files; you can probably use these files as a +model. + +Every string that should be translated needs gettext() around it. +So + + Message( "Usage: %s fontname[.ttf|.ttc]\n\n", + execname ); + +becomes + + Message( gettext( "Usage: %s fontname[.ttf|.ttc]\n\n" ), + execname ); + + +Yes, it's that simple. Next you need to initialize gettext. Put +the following in the header section of your file: + + #include "ft_conf.h" + #ifdef HAVE_LIBINTL_H + #include + #endif + + #ifndef HAVE_LIBINTL_H + #define gettext( x ) ( x ) + #endif + +and this at the very beginning of your main program: + + #ifdef HAVE_LIBINTL_H + setlocale(LC_ALL, ""); + bindtextdomain( "freetype", LOCALEDIR ); + textdomain( "freetype" ); + #endif + + +That's all. Just have a look at fterror.c in test/. + + +4) Using gettext (maintainer's view) + +I am too lazy today :-) If something isn't clear, just ask me. + + +5) How can I switch off NLS? I don't need/want it. + +Just say `configure --disable-nls' and recompile FreeType. + + +If you have any questions or comments regarding this short +introduction to NLS & FreeType, feel free to email me at +Erwin.Dieterich.ED@Bayer-AG.de. + + +--- end of i18n.txt --- diff --git a/docs/image/baselin2.gif b/docs/image/baselin2.gif new file mode 100644 index 0000000..b9c28bd Binary files /dev/null and b/docs/image/baselin2.gif differ diff --git a/docs/image/baseline.gif b/docs/image/baseline.gif new file mode 100644 index 0000000..f966ad2 Binary files /dev/null and b/docs/image/baseline.gif differ diff --git a/docs/image/emsquare.gif b/docs/image/emsquare.gif new file mode 100644 index 0000000..21dcfb3 Binary files /dev/null and b/docs/image/emsquare.gif differ diff --git a/docs/image/freetype.gif b/docs/image/freetype.gif new file mode 100644 index 0000000..8be6d21 Binary files /dev/null and b/docs/image/freetype.gif differ diff --git a/docs/image/freetype.png b/docs/image/freetype.png new file mode 100644 index 0000000..d520046 Binary files /dev/null and b/docs/image/freetype.png differ diff --git a/docs/image/grid1.gif b/docs/image/grid1.gif new file mode 100644 index 0000000..db15e23 Binary files /dev/null and b/docs/image/grid1.gif differ diff --git a/docs/image/grid2.gif b/docs/image/grid2.gif new file mode 100644 index 0000000..d0d9529 Binary files /dev/null and b/docs/image/grid2.gif differ diff --git a/docs/image/grid3.gif b/docs/image/grid3.gif new file mode 100644 index 0000000..5b8035d Binary files /dev/null and b/docs/image/grid3.gif differ diff --git a/docs/image/metrics.gif b/docs/image/metrics.gif new file mode 100644 index 0000000..b8813b4 Binary files /dev/null and b/docs/image/metrics.gif differ diff --git a/docs/image/metrics2.gif b/docs/image/metrics2.gif new file mode 100644 index 0000000..1366ef2 Binary files /dev/null and b/docs/image/metrics2.gif differ diff --git a/docs/image/small2.gif b/docs/image/small2.gif new file mode 100644 index 0000000..25f6afe Binary files /dev/null and b/docs/image/small2.gif differ diff --git a/docs/image/tfp-back.png b/docs/image/tfp-back.png new file mode 100644 index 0000000..53be671 Binary files /dev/null and b/docs/image/tfp-back.png differ diff --git a/docs/optimize.txt b/docs/optimize.txt new file mode 100644 index 0000000..8c10397 --- /dev/null +++ b/docs/optimize.txt @@ -0,0 +1,158 @@ + + FreeType Optimization HOWTO + + + +Introduction +============ + + This file describes several ways to improve the performance of the + FreeType engine on specific builds. Each `trick' has some + drawbacks, be it on code size or portability. + + The performance improvement cannot be quantified here simply + because id depends significantly on platforms _and_ compilers. + + + +I. Tweaking the configuration file +================================== + + The FreeType configuration file is named `ft_conf.h' and contains + the definition of various macros that are used to configure the + engine at build time. + + Apart from the Unix configuration file, which is generated when + calling the `configure' script from the template called + + freetype/ft_conf.h.in , + + all configuration files are located in + + freetype/lib/arch//ft_conf.h , + + where stands for your platform. This release also + provides an `ansi' build, i.e., the directory `lib/arch/ansi' used + to compile with any ANSI-compliant compiler. + + The configuration macros that relate to performance are described + next. + + + 1. TT_CONFIG_OPTION_INTERPRETER_SWITCH + -------------------------------------- + + If set, this macro builds a bytecode interpreter which uses a + huge `switch' statement to parse the bytecode stream during + glyph hinting. + + If unset, the interpreter uses a big jump table to call each + bytecode's routine. + + This macro is *set* by default. However, it may be worthwile on + some platforms to unset it. + + Note that this macro is ignored if + TT_CONFIG_OPTION_NO_INTERPRETER is set. + + + 2. TT_CONFIG_OPTION_STATIC_INTERPRETER + -------------------------------------- + + If set, this macro builds a bytecode interpreter which uses a + static variable to store its state. On some processors, this + will produce code which is bigger but slightly faster. + + Note that you should NOT DEFINE this macro when building a + thread-safe version of the engine. + + This macro is *unset* by default. + + + 3. TT_CONFIG_OPTION_STATIC_RASTER + --------------------------------- + + If set, this macro builds a scan-line converter which uses a + static variable to store its state. On some processors, though + depending on the compiler used, this will produce code which is + bigger but moderately faster. + + Note that you should NOT DEFINE this macro when building a + thread-safe version of the engine. + + This macro is *unset* by default. We do not recommend using it + except for extreme cases where a performance `edge' is needed. + + + +II. Replacing some components with optimized versions +===================================================== + + You can also, in order to improve performance, replace one or more + components from the original source files. Here are our + suggestions. + + + 1. Use memory-mapped files whenever available + --------------------------------------------- + + Loading a glyph from a TrueType file needs many random seeks, + which take a lot of time when using disk-based files. + + Whenever possible, use memory-mappings to improve load + performance dramatically. For an example, see the source file + + freetype/lib/arch/unix/ttmmap.c + + which uses Unix memory-mapped files. + + + 2. Replace the computation routines in `ttcalc.c' + --------------------------------------------------- + + This file contains many computation routines that can easily be + replaced by inline-assembly, tailored for a specific processor + and/or compiler. + + After heavy testing, we have found that these functions, + especially TT_MulDiv(), are the ones that are most extensively + used and called when loading glyphs from a font file. + + We do not provide inline-assembly with this release, as we want + to emphasize the portability of our library. However, when + working on a specific project where the hardware is known to be + fixed (like on an embedded system), great performance gains + could be achieved by replacing these routines. + + (By the way, the square root function is not optimal, but it is + very seldom called. However, its accuracy is _critical_. + Replacing it with a fast but inaccurate algorithm will ruin the + rendering of glyphs at small sizes.) + + + +III. Measuring performance improvements +======================================= + + Once you have chosen some improvements and rebuilt the library, + some quick ways to measure the `new' speed are: + + - Run the test program `ftlint' on a directory containing many + TrueType fonts, and measure the time it takes. On Unix, you can + use the shell command `time' to do it like in + + % time test/ftlint 10 /ttfonts/*.ttf + + This will measure the performance improvement of the TrueType + interpreter. + + - Run the test program `fttimer' on a font containing many complex + glyphs (the latest available versions of Times or Arial should + do it), probaby using anti-aliasing, as in: + + % time test/fttimer -g /ttfonts/arial.ttf + + Compare the results of several of these runs for each build. + + +--- end of OPTIMIZE --- diff --git a/docs/porting.txt b/docs/porting.txt new file mode 100644 index 0000000..a73aaa2 --- /dev/null +++ b/docs/porting.txt @@ -0,0 +1,1078 @@ + + + The FreeType Porting Guide + + or + + Everything you need to know to make FreeType + run on the weirdest system + + +-------------------------------------------------------------------- + + Table of Contents + + + Introduction + + I. General design and system modules + + II. Memory component API + + 1. The alloction function: TT_Alloc() + 2. The release function: TT_Free() + 3. The ALLOC() and ALLOC_ARRAY() macros + 4. The MEM_xxxx() macros + + III. File component API + + 1. Streams and their functions + 2. Frames and file access + 3. Differences in thread support levels + + IV. Mutex component API + + V. Summary & Advanced concepts + + 1. Porting summary + 2. Exotic filesystems + + VI. Troubleshooting + + Conclusion + + +-------------------------------------------------------------------- + +Introduction +============ + +The FreeType engine is portable in many ways: + +- First, it can be compiled by any ANSI C compliant compiler, which + guarantees the widest possible uses. + +- Its default build uses a tiny fraction of the ANSI libc, mainly + for memory management and I/O access, which should be available on + most systems (i.e., malloc(), free(), fopen(), fread(), etc). + +- Its design is modular, and allows an implementer to remove all + dependencies on a particular runtime environment, to adapt the + engine to its specific needs. For example, it is possible to use + memory-mapped files on systems which support them. + +This document explains the engine's design, presenting the `system' +modules that need to be changed by porters of the library, as well +as how to do it. + +Note that this documentation is _very_ detailed, and you may +DIRECTLY JUMP to SECTION V (Summary and advanced concepts) which +gives you a QUICK STEP-BY-STEP GUIDE TO PORTING each component, +without the need to understand all the guts of the TrueType engine. + +Several issues are discussed, including the use of exotic font +storage conventions. + + +-------------------------------------------------------------------- + + +I. General design, and system modules +===================================== + + The engine's design is intentionally highly modular. It is made + of several `components', each with its own specific goals. Three + of these play an important role with regards to portability. They + are: + + - the memory component: + + Found in the files `ttmemory.h' and `ttmemory.c'. It defines + several macros and a few functions used by _all_ other modules + to allocate, release, copy, and move memory blocks. + + - the file component: + + Found in the files `ttfile.h' and `ttfile.c'. It defines + several types and abstractions (streams, frames), that are used + by _all_ other modules to access font files. + + - the mutex component: + + This component compiles to a null object if the engine is built + in single-thread mode. Otherwise, for thread-safe and reentrant + builds, the macros and functions it defines are used by the rest + of the engine to protect shared variables. + + NOTE: + + Because the ANSI libc doesn't provide synchronisation + primitives (synchronisation isn't portable accross platforms), + the default implementation, found in `ttmutex.c', is made of + dummy functions which always return a successful error + condition. + + You _need_ to re-define this component for your system if you + decide to make a thread-safe or reentrant build, even if you + use the ANSI libc. + + + When specializing a component, i.e., rewriting it for your + platform, you should respect a few conventions which are explained + in the following sections. Note also that the system-specific + implementations are usually placed in the + `freetype/lib/arch/' directory. For example: + + freetype/lib/arch/unix/ttmmap.c + + A Unix-only implementation of ttfile which uses the + memory-mapped file API (this greatly improves the engine's + performance, due to the random access pattern typicals of + glyph data retrieval). + + freetype/lib/arch/os2/os2file.c + + This is an implementation of ttfile specific to OS/2, which + directly calls the system functions DosOpen(), DosRead(), etc. + + The FreeType/2 DLL (a free TrueType font driver for OS/2) also + uses its own memory component which calls a special allocation + routine required in its runtime environment, and also provides + additional statistics that can be displayed by an auxiliary + tool while the driver is running in the system. + +We ask you to respect this directory convention. This really needs +a minor Makefile change, and still having the ability to compile the +`default' ttfile and ttmemory will help you debug your specific +ports by easy comparisons. + + +-------------------------------------------------------------------- + + +II. Memory component API +======================== + + This section presents the macros and functions defined in + ttmemory.h, and how they should be implemented, if you decide to + rewrite the source file ttmemory.c from scratch. An easier + solution would be to replace the calls to malloc() and free() with + your own functions, though. + + +1. Allocation routine : TT_Alloc() +---------------------------------- + + This function is used to allocate blocks of memory, just like + malloc(), but defines a very different interface. Its prototype + is: + + TT_Error TT_Alloc( long size, void** p ); + + [The FreeType source files use abstract data types like `Long' for + all internal functions and `TT_Long' for externally visible + structures. See tttypes.h and freetype.h, respectively.] + + We can see that: + + - The function returns an error code, and _not_ a pointer. The + reason for this is that your own implementation may perfectly + fail for more than one good reason. For example, it could + detect a corrupted heap, a memory exhaustion or an unusually + large block, and have a different error code for each of these + cases. + + If a memory allocation error occurs in a FreeType function, it + is always taken into account (of course, for safety reasons), + but its code is directly sent to the caller. This means that + your own applications and font servers will be able to interpret + these errors and let you handle them appropriately. + + - Its second argument is the _address_ of a typeless pointer. + This means the need to typecast it before calling this function. + + The macro MEM_Alloc() is defined in ttmemory.h to do it for you, + as well as the `memory extraction' performed by the `&' + operator, so that you can write: + + char* buffer; + + + MEM_Alloc( size, buffer ); + + instead of + + TT_Alloc( size, (void**)&buffer ); + + Note that the engine _never_ uses this macro directly, but + ALLOC() instead (see below) in order to _always_ test the error + code. + + ***************** + *** IMPORTANT *** + ***************** + + - A newly allocated block should _always_ be filled with zeroes! + This is a _very_ strong convention used within all the engine. + It helps greatly to reduce code size, in general. If your + implementation of TT_Alloc() doesn't respect it, you're pretty + certain to build an unrunnable (at best) or (worse) instable + engine! Beware. + + +2. Release routine: TT_Free() +----------------------------- + + This routine is naturally used to release any block created + through TT_Alloc(). Its prototype is: + + TT_Error TT_Free( void** P ); + + We can see that: + + - It also returns an error code. Note, however, that the error is + ignored in most, if not all, parts of the engine. This is + because freeing memory usually happens when all necessary work + has been finished, or when something already wrong happened. + + - It takes the address of a typeless-pointer, and _not_ the + pointer's value itself. This is used to set the pointer's value + to NULL just after the block was released, which avoids dangling + references in objects. Of course, there is a macro defined to + simplify source writing. One can use FREE() like: + + char* buffer; + + + MEM_Alloc( size, buffer ); + + .... work .... + + FREE( buffer ); + + /* now `buffer' is set to NULL; the following line will */ + /* seg-fault */ + + a = buffer[0]; + + + ***************** + *** IMPORTANT *** + ***************** + + - The function TT_Free() (and thus the macro FREE()) will accept a + NULL pointer successfully! This means more precisely that the + address of a pointer may have the value NULL; in this case it + will return with a successful error code (TT_Err_Ok == 0). + + This convention is also _very_ strong in the engine, and + simplifies both code size and style. One of its primary origin + is the engine's object management which requires the ability to + release an object, be it normal or `partial', with the same + code. + + +3. The ALLOC() and ALLOC_ARRAY() macros +--------------------------------------- + + Two macros are also defined to make the FreeType source code + easier to read and understand. Their role is to perform an + allocation, while saving the error condition in an _implicit_ + local variable called `error', and returning a boolean which is + set to true in case of error. Their definition is + + #define ALLOC( pointer, size ) \ + ( ( error = MEM_Alloc( pointer, size ) ) != TT_Err_Ok ) + + and + + #define ALLOC_ARRAY( pointer, count, type ) \ + ( ( error = MEM_Alloc( pointer, \ + (count) * sizeof ( type ) ) ) \ + != TT_Err_Ok ) + + They are always used in `if' statements, and can be chained + together. Here is some example code: + + char* buffer1 = 0; /* temporary buffer 1 */ + char* buffer2 = 0; /* temporary buffer 2 */ + TT_Error error; + + + ... + + if ( ALLOC_ARRAY( buffer1, n, TT_F26Dot6 ) || + ALLOC_ARRAY( buffer2, n, short ) ) + goto Fail; + + ... work ... + + Fail: + FREE( buffer2 ); + FREE( buffer1 ); + return error; + + + Notes: + + - If an error occurs during the first allocation, execution will + jump immediately to the `Fail' label. + + - The failure code, which releases the buffers, doesn't need to + differentiate whether the first allocation succeeded or not + (simply because FREE() accepts null pointers with no + problems). + + The equivalent code, without macros, would be: + + char* buffer1; + char* buffer2; + TT_Error error; + + + error = TT_Alloc( n * sizeof ( TT_F26Dot6 ), + (void**)&buffer1 ); + if ( error ) goto Fail_Buffer1; + + error = TT_Alloc( n * sizeof ( short ), + (void**)&buffer2 ); + if ( error ) goto Fail_Buffer2; + + .... work .... + + Fail_Buffer2: + TT_Free( (void**)&buffer2 ); + + Fail_Buffer1: + TT_Free( (void**)&buffer1 ); + + + Which is a lot less clear about its intents, and uses more special + cases. + + +4. The MEM_xxxx() macros +------------------------ + + Finally, three macros are defined to perform some common memory + block operations. Their names are rather explicative: + + - MEM_Copy() + + Used by the engine to copy one block of data in memory to + another one. + + - MEM_Set() + + Used to set all bytes of a block of memory to a given value. + + - MEM_Move() + + Well, guess what ;-) + + + These operations could have been embedded in functions like + TT_Mem_Copy(), TT_Mem_Set(), and TT_Mem_Move(), but a lot of + compilers are able to inline directly calls to such `intrinsic' + functions as memcpy() and memmove(). Hence, macros make sense + here. + + +-------------------------------------------------------------------- + + +III. File Component API +======================= + + This section describes the file component's API, and the things + that are needed to port it to a specific system. Note that only a + fraction of the source code in `ttfile.c' needs to be rewritten + during a port. + + +1. Streams and their functions +------------------------------ + + A stream in FreeType (version 1.x) encapsulates both the + location/naming of a file, and its access. This is due to the + fact that they were originally designed to embed a simple ANSI + `FILE*' file pointer. + + This means several things: + + - A stream is created and opened via the TT_Open_Stream() + function. It takes, in the default build, a font pathname of + type `char*' that it uses when calling fopen(). + + - It can be released/closed via the function TT_Close_Stream(). + + - It embeds a `current file position', just like an ordinary file + descriptor. It is thus seekable, through the function + TT_Seek_File(). + + - Raw data can be extracted from a stream through TT_Read_File() + and TT_Read_At_File(). + + However, it has certain properties that differ from a libc `FILE*' + data type: + + - Because each face object has its own stream, and because most + operating systems limit the number of opened system resources in + each process, it is more than helpful to be able to `flush' a + stream. + + A stream is said to be flushed if the system resource it + contains (like a file descriptor) has been closed. However, + this resource is re-opened automatically when needed. + + The function TT_Flush_Stream() is used to flush a stream. If a + stream has been flushed, it is also said to be `asleep'. + + - The engine calls TT_Use_Stream() before each new stream access. + With it, the file component is able to awake (or `activate') + streams that are flushed, if needed. + + - Consequently, the engine calls TT_Done_Stream() when it has + performed all I/O access. These two APIs (TT_Use_Stream() and + TT_Done_Stream()) let the file component track and manage the + engine's access patterns, and allows it to cache opened streams + more cleverly. + + For example, one could implement an LRU list used to track the + `oldest' streams, and only activate the 10 `freshest' ones, thus + limiting the total number of system stream resources used by the + library, independently of the total number of opened faces in + the engine. + + +2. Frames and file access +------------------------- + + In order to resolve endianess and alignment issues, the engine + uses the concept of `frames' to extract data from a TrueType + table. + + - A frame is simply a sequence of successive bytes, taken from a + stream from its current position. A frame can only exist within + a stream. + + - The function TT_Access_Frame() (ideally) reads its data and + places it into an intermediate buffer, which is later used for + parsing. This function also checks that the whole frame fits + into the original file. For example, it will return an error if + detecting `over-reads' in the file (which can happen if the font + file is broken). + + Note that the intermediate buffer disappears in the case of + memory-mapped files. + + - Each frame has an internal cursor, which is set to its buffer's + base by the previous function. Note, however, that it differs + from the stream's current position, which has been advanced once + TT_Acess_Frame() is completed. + + - Data is extracted from the frame through calls to functions of + the form: + + TT_Get_(); + + where can be any of: Byte (unsigned char), Char + (signed char), Short, UShort, Long, or ULong. + + Each function returns the integer below the current frame + cursor, and advances the latter in the buffer. + + - Finally, when the frame access ends, the engine calls the + TT_Forget_Frame() function, which will release the intermediate + buffer and set the cursor to NULL. + + Here is a typical frame read sequence: + + /* first - read the next 12-bytes frame in memory */ + error = TT_Access_Frame( 12 ); + if ( error ) + return error; + + /* now, extract all data */ + object->field1 = TT_Get_Short(); + object->field2 = TT_Get_Long(); + object->field3 = TT_Get_Char(); + object->filed4 = TT_Get_Long(); + object->field5 = TT_Get_Byte(); + + /* done - now release the frame */ + TT_Forget_Frame(); + + /* now perform some checks */ + if ( object->field1 == -1 ) + return Error_1; + + if ( object->field2 > object->field4 ) + return Error_2; + + + ***************** + *** IMPORTANT *** + ***************** + + A few things need to be noticed by porters when they implement + frame loading (i.e. the TT_Access_Frame() function): + + - The functions that need to be ported are TT_Access_Frame() and + TT_Forget_Frame(). The TT_Get_XXXX() functions should be left + as is. + + - A frame has a state, and must _always_ be released through + TT_Forget_Frame() in case of an error. This means that the + engine will _never_ use code like the following: + + error = TT_Access_Frame( 12 ); + if ( error ) + goto Fail; + + object->field1 = TT_Get_Short(); + + /* now check error and return immediately -- */ + /* WITHOUT RELEASING FRAME! ERROR! */ + if ( object->field1 == -1 ) + goto Fail; + + object->field2 = TT_Get_Long(); + object->field3 = TT_Get_Char(); + object->field4 = TT_Get_Long(); + + /* check for error, return immediately -- */ + /* WITHOUT RELEASING FRAME! ERROR! */ + if ( object->field2 > object->field4 ) + goto Fail; + + /* now release frame */ + TT_Forget_Frame(); + + This means more simply that EACH successful call to + TT_Access_Frame() will ALWAYS be followed by a call to + TT_Forget_Frame()! + + - As a consequence of the first rule, and also in order to keep + things simple, NESTING FRAME ACCESSES aren't allowed. For + example, the following code will produce an error: + + /* First frame access */ + error = TT_Access_Frame( 8 ); + if ( error ) + goto Fail; + + /* read a file offset */ + offset = TT_Get_Long(); + + /* seek and load another frame */ + error = TT_File_Seek( stream, offset ); + if ( error ) + goto Fail; + + error = TT_Access_Frame( 4 ); + /* The function TT_Access_Frame detects nested calls */ + /* and ALWAYS returns TT_Err_Nested_Frame_Access! */ + if ( error ) + goto Fail; + + data1 = TT_Get_Long(); + + /* release second frame */ + TT_Forget_Frame(); + + /* read next integer from the first frame */ + data2 = TT_Get_Long(); + + /* release first frame */ + TT_Forget_Frame(); + + This simplifies the work that needs to be done wen porting the + TT_Access_Frame() and TT_Forget_Frame() functions. + + +3. Differences in thread support levels +--------------------------------------- + + The FreeType library can be built to three distinct thread-support + levels. This section will present each other, and show how this + translates within the ttfile.c source code. + + a. Levels + + The three levels are + + - single thread + + No synchronization primitive is used to protect the data in + the file component. Hence, there is only one `current' stream + at any one time. Note, however, that in some cases, more than + one stream may be `active' (or `awakened'); e.g., when using + memory-mapped files, each opened face needs a valid mapping + before it can be used/parsed by the engine. + + - thread-safe + + The thread safe mode synchronizes concurrent accesses to the + renderer's component through mutexes. For the file component, + this means a single mutex which is `locked' by a call to + TT_Use_Stream(), and `released' by TT_Done_Stream(). + + As a consequence, there is only one possible `current' stream + when the engine reads files, like in the single thread case. + + - re-entrant + + In this mode, concurrent accesses are possible on many + components, including ttfile. This means that each + TT_Use_Stream() must _really_ create its own system/ANSI + stream for a single file, and that the file component _cannot_ + have any state (only stream objects have!), like a `current + stream' and `current frame'. + + This mode must use mutexes to protect all shared variables and + lists from concurrent changes/reads. The only component which + is still serialized in this mode is the scan-line converter + (a.k.a. ttraster). + + b. Implementation differences + + Because the TrueType engine serves more as a `font format + driver' than a general and high-level text-rendering library, it + has been decided to keep its code as simple and compact as + possible. + + This implies some implementation differences between the three + thread modes, which are briefly explained below: + + - Single-thread and thread-safe mode can have a state, which + means for ttfile.c, a `current stream' and `current frame'. + + - In the reentrant mode, the `state' must be stored in a + thread-local place, which means the stack (or more simply + local function variables). + + What follows is that some ttfile functions won't take the same + number of arguments depending on the thread-support mode. Let + uss take the example of frame access and parsing: + + In single-thread and thread-safe mode, the current frame is + automatically set by the TT_Access_Frame() function, which only + takes a `size' argument to determine the run of bytes to extract + from the _current_stream_ within ttfile's state. + + Moreover, the TT_Get_XXXX() functions extract data from the + current frame, and need no arguments. A simple frame access + then looks like this: + + /* read the next 12-bytes frame from the _current_stream_ */ + error = TT_Access_Frame( 12 ); + if ( error ) + return error; + + /* now, extract all data from the _current_frame_ */ + object->field1 = TT_Get_Short(); + object->field2 = TT_Get_Long(); + object->field3 = TT_Get_Char(); + object->filed4 = TT_Get_Long(); + object->field5 = TT_Get_Byte(); + + /* done - now release the current frame */ + TT_Forget_Frame(); + + In reentrant mode, things are a bit different. The current + stream and current frame must be passed as parameters, and the + code looks like this (notice the new function parameters!): + + + TT_Frame frame; /* define a local variable to handle */ + /* the current frame */ + + .... /* we suppose we already have a stream variable */ + .... /* named `stream' (how surprising ;-) */ + + /* read the next 12-bytes frame from a given stream */ + error = TT_Access_Frame( stream, 12, &frame ); + if ( error ) + return error; + + /* now, extract all data from the given frame */ + object->field1 = TT_Get_Short( frame ); + object->field2 = TT_Get_Long ( frame ); + object->field3 = TT_Get_Char ( frame ); + object->filed4 = TT_Get_Long ( frame ); + object->field5 = TT_Get_Byte ( frame ); + + /* done - now release the current frame */ + TT_Forget_Frame( frame ); + + + The differences between these two schemes are striking. Though + an `easy' solution would have been to only write the engine in + reentrant-mode, it would have resulted in larger and slightly + slower code, as well as the source a bit more obscure about its + intents and thus harder to maintain. Also, the reentrant + version is only needed in rare cases and environments, and it + wasn't thought as a good idea to complexify _source_ code in + order to comply with rare uses. + + The problem is solved within the engine by the use of a set of + carefully selected macros, which help generate both versions + from a _single_ source file. + + Moreover, as the macros imitate the non-reentrant syntax (i.e., + the use of the `stream' and `frame' parameters is implicit to + the macros), the source is kept clear and easy to understand, + even if compiled in re-entrant mode. + + The code looks then like the following in the engine: + + /* read the next 12-bytes frame from the current stream */ + /* assignment of the error code in the local `error' */ + /* variable is also implicit to the ACCESS_Frame macro, */ + /* and its result is always a boolean (no ANSI warnings) */ + + if ( ACCESS_Frame( 12 ) ) + goto Fail; + + /* Now, extract all data from the current frame. */ + /* The macros GET_xxxxx use an implicit local `frame' */ + /* variable in reentrant mode. */ + + object->field1 = GET_Short(); + object->field2 = GET_Long(); + object->field3 = GET_Char(); + object->filed4 = GET_Long(); + object->field5 = GET_Byte(); + + /* done - now release the current frame */ + + FORGET_Frame(); + + Another advantage of the above code is its `expressiveness' in + the sense that it really describes what is happening during the + frame load, hiding the boring but necessary details required by + error checking and reentrancy. And if the error checks are + within the macros, we are sure we won't forget them because they + are `too boring to code' (one of the reason why `exceptions' + caught so quickly in C++ and Java). + + c. Consequences on ttfile + + Of course, the macros only hide real differences in + implementation which must be reflected in ttfile.h and ttfile.c. + In order to ease this task, some other macros are used, which + use is reserved for these two files. There are: + + STREAM_ARG + STREAM_ARGS + FRAME_ARG + FRAME_ARGS in ttfile.h + + CUR_Stream + STREAM_VAR + STREAM_VARS + FRAME_VAR + FRAME_VARS in ttfile.c + + All of these macros (with the exception of CUR_Stream) default + to nothing (i.e. a void macro) in single-thread and re-entrant + mode, which only differ from the use of a mutex lock and release + in the functions TT_Use_Stream() and TT_Done_Stream(). + CUR_Stream defaults to the file component's current stream, + found in its internal state (as you can guess, it designates the + `current stream'). + + On the opposite, the macros are used to define additional + function parameters (if a function is called) and arguments (if + calling in a function). For example, the following (fictional) + code: + + /* return the size of a given stream */ + long Stream_Size( STREAM_ARG ) + { + return CUR_Stream.size; + } + + expands to: + + long Stream_Size() + { + return file_component.current_stream.size; + } + + in non-reentrant mode, and to: + + long Stream_Size( TT_Stream stream ) + { + return (*stream).size; + } + + otherwise. + + Thus, we can see the following reentrant expansions: + + STREAM_ARG --> TT_Stream stream + STREAM_ARGS --> TT_Stream stream, (note the comma) + + FRAME_ARG --> TT_Frame frame + FRAME_ARGS --> TT_Frame frame, (note the comma) + + STREAM_VAR --> stream + STREAM_VARS --> stream, + + FRAME_VAR --> frame + FRAME_VARS --> frame, + + They follow these simple rules: + + - An XXXX_ARG is used to define a single optional parameter in + a function _prototype_. The parameter is said to be single + if it is not followed by anything, e.g. + + long Stream_Size( STREAM_ARG ) + + - An XXXX_ARGS is the same, followed by a comma, in order to + place other (non-optional) parameters behind, e.g. + + TT_Error Stream_Seek( STREAM_ARGS long pos ) + + - An XXXX_VAR is used, _only_ within ttfile.c, to _call_ a + function having an XXXX_ARG or XXXX_ARGS in its prototype + resp. declaration. + + long Stream_Left( STREAM_ARG ) + { + return ( Stream_Size( STREAM_VAR ) - + Stream_Pos( STREAM_VAR ) ); + } + + - An XXXX_VARS is the same, but can be followed by non-optional + parameters. + + The macros allow you to write some code independently of the + thread level within ttfile.c. + + ***************** + *** IMPORTANT *** + ***************** + + In general, porters should not be concerned about the use of + these macros. One easy way to port is to take the ANSI code in + ttfile.c and modify only the parts that really access the system + (like fopen(), fread(), fseek(), etc). + + These details are explained here to make you understand how the + code works, in case you are interested in more elaborate ports. + + +-------------------------------------------------------------------- + + +IV. Mutex Component API +======================= + + As said before, the default library source code uses the ANSI libc + only, and the source code in ttmutex.c only contains dummy + functions which return a successful error condition in all cases. + + You thus NEED to specialize it in order to successfully use a + thread-safe or reentrant build. Here is explained what is really + important: + + +1. The TMutex type +------------------ + + The engine uses the `TMutex' type defined in ttmutex.h to handle + mutexes. It is only a typedef of a `void*' and should be kept + that way for the fastest porting. + + Your job will most probably be to store a system mutex/semaphore + handle or pointer in it. + + +2. The mutex macros and functions +--------------------------------- + + The interface file ttmutex.h defines several macros that are used + within the engine to protect all shared variables (like lists) + from concurrent accesses. All macros default to `void' (nothing) + in single thread mode, and to calls to the TT_Mutex_XXXX() + functions in multi-threaded modes. + + These functions are: + + o TT_Mutex_Create() + + Takes a TMutex address as an argument. It should place a NULL + pointer in this output variable in case of failure. + + o TT_Mutex_Lock() + + It also takes the address of a TMutex as an argument. Used to + lock the mutex/semaphore, of course. + + o TT_Mutex_Release() + + Guess what ;-) Same interface. + + o TT_Mutex_Delete() + + Destroys a mutex/semaphore. + + +3. Redefining the TMutex type +----------------------------- + + You can also get rid of the TT_Mutex_xxxx() functions if you want + to use your system's synchronization API. This can be done in two + simple steps: + + a. Redefine the TMutex type to suit your system's handle types. + + b. Redefine the MUTEX_xxxx() macros in order to call directly your + API in the case of multi-threaded builds. + + Both methods (specializing the TT_Mutex_xxx() functions or + redefining the macros) are possible. + + +-------------------------------------------------------------------------- + + +V. Summary and Advanced Concepts +================================ + +1. Quick step-by-step guide to porting the system components +------------------------------------------------------------ + + a. Port the memory component + + o Look at the `ttmemory.h' file and change the macros + MEM_Copy(), MEM_Move(), and MEM_Set() to reflect your system's + API providing the equivalent functionality. The reason that + macros instead of functions are used there is that many + compilers are able to inline directly these functions within + your code. + + o Look at the `ttmemory.c' file. Replace the single malloc() + call with your own allocation routine, and the single free() + with your own release routine. If your allocator uses more + sophisticated functions, you will probably have to rewrite + more parts of this file. See section I above. + + b. Port the mutex component + + o Look at the file `ttmutex.c' and specialize each routine to + have it use your system's synchronization API. + + o For a more advanced port, you can also directly redefine the + definition of the TMutex type in ttmutex.h, as well as the + macro definitions (like MUTEX_Create(), MUTEX_Lock(), etc.) to + use directly your system's API. The TT_Mutex_xxxx() won't be + necessary then. + + c. Port the file component + + o For a quick port, look at the following functions and replace + the ANSI libc calls (like fopen(), fclose(), fread(), etc.): + + Stream_Activate(), Stream_Deactivate(), TT_Open_Stream(), + TT_Done_Stream(), TT_Seek_File(), TT_Skip_File(), + TT_Read_File(), TT_File_Pos() + + o If you plan to use memory-mapped files, you can have a look at + the Unix file component found in + `freetype/lib/arch/unix/ttmmap.c'. It should give you an + indication of what to do. + + +2. Exotic file systems and font resources +----------------------------------------- + + a. Other file naming conventions + + The high-level library uses the `TT_Text*' type to define the + type of characters used for a font file's pathname. By default, + it equals to the `char*' type, which allow you to open a face + object with the following call: + + error = TT_Open_Face( engine, "c:\fonts\times.ttf", &face ); + + The implementation of TT_Open_Face() passes directly the + pathname pointer to the internal TT_Open_Stream() function, + located in the file component, which really opens the file. + + Some filesystems use different naming conventions, like UTF-16 + code, where each character is coded in 16 bits. In order to + help them to use FreeType, all you need to do is the following: + + - Define the macro TT_HAVE_TT_TEXT. + + - Define the type `TT_Text' to the character type you need, like + 'wchar_t' for Unicode. + + Note that this should apply when compiling the FreeType library, + as well as WHEN INCLUDING THE FILE `freetype.h' IN YOUR + APPLICATIONS. + + If the configuration macro TT_HAVE_TT_TEXT is not defined, the + file `freetype.h' defines TT_Text as `char*'. You can read its + source code to see it more explicitly (look at the very first + lines of the code). + + You can also use TT_Text as a pointer to more specific files, + like a simple memory address when the font is located in ROM, + etc. + + Just synchronize the definition of TT_Text with the + implementation in ttfile.c! + + b. Font Resources + + FreeType 2.0 will feature many architectural changes that will + help make porting easier, especially with regards of the file + component. + + To do this, it will separate the concepts of a `font resource', + i.e. a file seen as a storage, from a `font stream', i.e. a + file seen as a stream of data. Only the resource related code + will be visible to porters, and it will be much easier to port + (for example, nearly all thread-support levels issues will be + treated internally in the rest of the engine, and will be + invisible to the resource component). + + We're sorry for the current design and state, but TT_Stream + started as a simple encapsulation of an ANSI FILE* variable, + before font-specific access patterns made them become what they + now are. + + FreeType 2.0 will be a good reason to re-design I/O access more + clearly, and fortunately with more power and flexibility (like + using easily files of different type, ROM-based, memory-mapped, + disk-based, in a single engine). + + However, all of this doesn't mean than the current design + doesn't work. It does, so don't hesitate to use it :-) + + +-------------------------------------------------------------------- + + +VI. Troubleshooting +=================== + + To be written. + + +-------------------------------------------------------------------- + + +Conclusion +========== + + To be written. + + +--- end of porting.txt --- diff --git a/docs/raster.txt b/docs/raster.txt new file mode 100644 index 0000000..34d05eb --- /dev/null +++ b/docs/raster.txt @@ -0,0 +1,577 @@ +This file is an attempt at explaining the internals of the FreeType +rasterizer. This component is quite general purpose and could +easily be integrated into other programs (but still under the +current license). + +-------------------------------------------------------------------- + + The HOWs and WHYs of the FreeType rasterizer + + by David Turner + + + I. Introduction + + II. Rendering Technology + +III. Implementation Details + + IV. Gray-Level Support + + + +I. Introduction +=============== + + A rasterizer is a library in charge of converting a vectorial + representation of a shape into a bitmap. The FreeType rasterizer + has been developed to render the glyphs found in TrueType files, + made up of segments and second-order Beziers. This document is an + explanation of its design and implementation. + + Though these explanations start from the basics, a knowledge of + common rasterization techniques is assumed. + + +-------------------------------------------------------------------- + + +II. Rendering Technology +======================== + +1. Requirements +--------------- + + We will assume that all scaling/rotating/hinting/whatever has been + already done. The glyph is thus described, as in the TrueType + specification, by a list of points. Each point has an x and y + coordinate, as well as a flag that indicates whether the point is + _on_ or _off_ the curve. + + More precisely: + + - All point coordinates are in the 26.6 fixed float format as + defined by the specification. The orientation used is: + + ^ y + | reference orientation + | + *----> x + 0 + + This means that the `distance' between two neighbouring pixels + is 64 `units' (1 unit = 1/64th of a pixel). + + Note that, for the rasterizer, pixel centers are located at + integer coordinates, i.e., (0.0, 0.0) is the coordinate of the + origin's center (unlike what happens within the TrueType + bytecode interpreter where this point's center lies at (0.5, + 0.5)). + + A pixel line in the target bitmap is called a `scanline'. + + - A glyph is usually made of several contours, also called + outlines. A contour is simply a closed curve that delimits an + outer or inner region of the glyph. It is described by a series + of successive points of the points table. + + Each point of the glyph has an associated flag that indicates + whether it is `on' or `off' the curve. Two successive `on' + points indicate a line segment joining the two points. + + One `off' point amidst two `on' points indicates a second degree + Bezier parametric arc, defined by these three points (the `off' + point being the control point, and the `on' ones the start and + end points). + + Finally, two successive `off' points forces the rasterizer to + create, during rendering, an `on' point amidst them, at their + exact middle. This greatly facilitates the definition of + successive Bezier arcs. + + * # on curve + * off curve + __---__ + #-__ _-- -_ + --__ _- - + --__ # \ + --__ # + -# + Two `on' points + Two `on' points and one `off' point + between them + + * + # __ Two `on' points with two `off' + \ - - points between them. The point + \ / \ marked `0' is the middle of the + - 0 \ `off' points, and is a `virtual + -_ _- # on' point where the curve passes. + -- It does not appear in the point + * list. + + + The FreeType rasterizer, as intended to render TrueType glyphs, + does not support third order Beziers, usually found in Type 1 + fonts. Type 1 support may lead to further development of the + engine (it is already part of FreeType 2.0). + + The parametric form of a second-order Bezier is: + + P(t) = (1-t)^2*P1 + 2*t*(1-t)*P2 + t^2*P3 + + with t a real number in the range [0..1] + + P1 and P3 are the endpoints, P2 the control point. + + Note that the rasterizer does not use this formula. It exhibits, + however, one very useful property of Bezier arcs: Each point of + the curve is a weighted average of the control points. + + As all weights are positive and always sum up to 1, whatever the + value of t, each arc point lies within the triangle defined by the + arc's three control points. + + +2. Profiles and Spans +--------------------- + + The following is a basic explanation of the _kind_ of computations + made by the rasterizer to build a bitmap from a vector + representation. Note that the actual implementation is slightly + different, due to performance tuning and other factors. + + However, the following ideas remain in the same category, and are + more convenient to understand. + + a. Sweeping the shape + + The best way to fill a shape is to decompose it into a number of + simple horizontal segments, then turn them on in the target + bitmap. These segments are called `spans'. + + __---__ + _-- -_ + _- - + - \ + / \ + / \ + | \ + + __---__ Example: filling a shape + _----------_ with spans. + _-------------- + ----------------\ + /-----------------\ This is typically done from the top + / \ to the bottom of the shape, in a + | | \ movement called a `sweep". + V + + __---__ + _----------_ + _-------------- + ----------------\ + /-----------------\ + /-------------------\ + |---------------------\ + + + In order to draw a span, the rasterizer must compute its + coordinates, which are simply the shape's contours' + x-coordinates taken on the y-scanlines. + + + /---/ |---| Note that there are usually + /---/ |---| several spans per scanline. + | /---/ |---| + | /---/_______|---| When rendering this shape to the + V /----------------| current scanline y, we must + /-----------------| compute the x values of the + a /----| |---| points a, b, c, and d. + - - - * * - - - - * * - - y - + / / b c| |d + + + /---/ |---| + /---/ |---| And then turn on the spans a-b + /---/ |---| and c-d. + /---/_______|---| + /----------------| + /-----------------| + a /----| |---| + - - - ####### - - - - ##### - - y - + / / b c| |d + + b. Decomposing outlines into profiles + + For each scanline during the sweep, we need the following + information: + + o The number of spans on the current scanline, given by the + number of shape points intersecting the scanline (these are + the points a, b, c, and d in the above example). + + o The x coordinates of these points. + + These are computed before the sweep, in a phase called + `decomposition' which converts the glyph into *profiles*. + + Put it simply, a `profile' is a contour's portion that can only + be either ascending or descending, i.e., it is monotonic in the + vertical direction (we will also say y-monotonic). There is no + such thing as a horizontal profile, as we shall see. + + Here are a few examples: + + + this square + 1 2 + ---->---- is made of two + | | | | + | | profiles | | + ^ v ^ + v + | | | | + | | | | + ----<---- + + up down + + + this triangle + + P2 1 2 + + |\ is made of two | \ + ^ | \ \ | \ + | | \ \ profiles | \ | + | | \ v ^ | \ | + | \ | | + \ v + | \ | | \ + P1 ---___ \ ---___ \ + ---_\ ---_ \ + <--__ P3 up down + + + + A more general contour can be made of more than two profiles: + + __ ^ + / | / ___ / | + / | / | / | / | + | | / / => | v / / + | | | | | | ^ | + ^ | |___| | | ^ + | + | + v + | | | v | | + | | | up | + |___________| | down | + + <-- up down + + + Successive profiles are always joined by horizontal segments + that are not part of the profiles themselves. + + Note that for the rasterizer, a profile is simply an *array* + that associates one horizontal *pixel* coordinate to each bitmap + *scanline* crossed by the contour's section containing the + profile. Note also that profiles are *oriented* up or down + along the glyph's original flow orientation. + + In other graphics libraries, profiles are also called `edges' or + `edgelists'. + + c. The Render Pool + + FreeType has been designed to be able to run well on _very_ + light systems, including embedded systems with very few memory. + + A render pool will be allocated once; the rasterizer uses this + pool for all its needs by managing this memory directly in it. + The algorithms that are used for profile computation make it + possible to use the pool as a simple growing heap. This means + that this memory management is actually easy, and faster than + any kind of malloc()/free() combination. + + Moreover, we'll see later that the rasterizer is able, when + dealing with profiles too large and numerous to lie all at once + in the render pool, to immediately decompose recursively the + rendering process into independent sub-tasks, each taking less + memory to be performed (see `sub-banding' below). + + The render pool doesn't need to be large. A 4kByte pool is + enough for nearly all renditions, though nearly 100% slower than + a more confortable 16 or 32kByte pool (that was tested with + complex glyphs at sizes over 500 pixels). + + d. Computing Profiles Extents + + Remember that a profile is an array, associating a _scanline_ to + the x pixel coordinate of its intersection with a contour. + + Though it's not exactly how the FreeType rasterizer works, it is + convenient to think that we need a profile's height before + allocating it in the pool and computing its coordinates. + + The profile's height is the number of scanlines crossed by the + y-monotonic section of a contour. We thus need to compute these + sections from the vectorial description. In order to do that, + we are obliged to compute all (local and global) y-extrema of + the glyph (minima and maxima). + + + P2 For instance, this triangle has only + two y-extrema, which are simply + |\ + | \ P2.y as an y-maximum + | \ P3.y as an y-minimum + | \ + | \ P1.y is not an y-extremum (though it is + | \ a x-minimum, which we don't need). + P1 ---___ \ + ---_\ + P3 + + Note that the extrema are expressed in pixel units, not in + scanlines. The triangle's height is certainly (P3.y-P2.y+1) + pixel units, but its profiles' heights are computed in + scanlines. The exact conversion is simply: + + - min scanline = FLOOR ( min y ) + - max scanline = CEILING( max y ) + + A problem arises with Bezier Arcs. While a segment is always + necessarily y-monotonic (i.e., flat, ascending, or descending), + which makes extrema computations easy, the ascent of an arc can + vary between its control points. + + P2 + * + # on curve + * off curve + __-x--_ + _-- -_ + P1 _- - A non y-monotonic Bezier arc. + # \ + - The arc goes from P1 to P3. + \ + \ P3 + # + + We first need to be able to easily detect non-monotonic arcs, + according to their control points. I will state here, without + proof, that the monotony condition can be expressed as: + + P1.y <= P2.y <= P3.y for an ever-ascending arc + + P1.y >= P2.y >= P3.y for an ever-descending arc + + with the special case of + + P1.y = P2.y = P3.y where the arc is said to be `flat'. + + As you can see, these conditions can be very easily tested. + They are, however, extremely important, as any arc that does not + satisfy them necessarily contains an extremum. + + Note also that a monotonic arc can contain an extremum too, + which is then one of its `on' points: + + P1 P2 + #---__ * P1P2P3 is ever-descending, but P1 + -_ is an y-extremum. + - + ---_ \ + -> \ + \ P3 + # + + Let's go back to our previous example: + + P2 + * + # on curve + * off curve + __-x--_ + _-- -_ + P1 _- - A non-y-monotonic Bezier arc. + # \ + - Here we have + \ P2.y >= P1.y && + \ P3 P2.y >= P3.y (!) + # + + We need to compute the y-maximum of this arc to be able to + compute a profile's height (the point marked by an `x'). The + arc's equation indicates that a direct computation is possible, + but we'll rely on a different technique, which use will become + apparent a bit later. + + Bezier arcs have the special property of being very easily + decomposed into two other sub-arcs, which are themselves Beziers + arcs. Moreover, it is easy to prove that there is at most one + y-extremum on each Bezier arc (for second degree ones). + + For instance, the following arc P1P2P3 can be decomposed into + two sub-arcs Q1Q2Q3 and R1R2R3 that look like: + + P2 + * + # on curve + * off curve + + + Original Bezier Arc P1P2P3. + __---__ + _-- --_ + _- -_ + - - + / \ + / \ + # # + P1 P3 + + + + + P2 + * + + + + Q3 Decomposed into two subarcs + Q2 R2 Q1Q2Q3 and R1R2R3 + * __-#-__ * + _-- --_ + _- R1 -_ Q1 = P1 R3 = P3 + - - Q2 = (P1+P2)/2 R2 = (P2+P3)/2 + / \ + / \ Q3 = R1 = (Q2+R2)/2 + # # + Q1 R3 Note that Q2, R2, and Q3=R1 + are on a single line which is + tangent to the curve. + + We have then decomposed a non-y-monotonic bezier into two + smaller sub-arcs. Note that in the above drawing, both sub-arcs + are monotonic, and that the extremum is then Q3=R1. However, in + a more general case, only one sub-arc is guaranteed to be + monotonic. Getting back to our former example: + + Q2 + * + + __-x--_ R1 + _-- #_ + Q1 _- Q3 - R2 + # \ * + - + \ + \ R3 + # + + Here, we see that, though Q1Q2Q3 is still non-monotonic, R1R2R3 + is ever descending: we thus know that it doesn't contain the + extremum. We can then re-subdivide Q1Q2Q3 into two sub-arcs and + go on recursively, stopping when we encounter two monotonic + subarcs, or when the subarcs become simply too small. + + We will finally find the y-extremum. Note that the iterative + process of finding an extremum is called `flattening'. + + e. Computing Profiles coordinates + + Once we have the height of each profile, we are able to allocate + it in the render pool. We now have to compute its coordinate + for each scanline. + + In the case of segments, the computation is straightforward, and + uses good old Euclide (also known as Bresenham ;-). However, + for Bezier arcs, things get a little more complicated. + + We assume that all Beziers that are part of a profile are the + result of `flattening' the curve, which means that they are all + y-monotonic (ascending or descending, and never flat). We now + have to compute the arcs' intersections with the profile's + scanlines. One way is to use a similar scheme to `flattening', + called `stepping'. + + Consider this arc, going from P1 to + --------------------- P3. Suppose that we need to + compute its intersections with the + drawn scanlines. Again, this is + --------------------- feasible directly, if we dare + to compute one square root per + * P2 _---# P3 scanline (how great!). + ------------- _-- -- + _- + _/ Rather, it is still possible to use + ---------/----------- the decomposition property in the + / same recursive way, i.e. subdivide + | the arc into subarcs until these + ------|-------------- get too small to cross more than + | one scanline! + | + -----|--------------- This is very easily done using a + | rasterizer-managed stack of + | subarcs. + # P1 + + f. Sweeping and Sorting the spans + + Once all our profiles have been computed, we begin the sweep to + build (and fill) the spans. + + As the TrueType specification uses the winding fill rule, we + place on each scanline the profiles present in two separate + lists. + + One list, called the `left' one, only contains ascending + profiles, while the other `right' list contains the descending + profiles. + + As each glyph is made of closed curves, a simple geometric + property is that the two lists necessarily contain the same + number of elements. + + Creating spans is there straightforward: + + 1. We sort each list in increasing x order. + + 2. We pair each value of the left list, with its corresponding + value in the right one. + + + / / | | For example, we have here + / / | | four profiles. Two of + >/ / | | | them are ascending (1 & + 1// / ^ | | | 2 3), while the two others + // // 3| | | v are descending (2 & 4). + / //4 | | | On the given scanline, + a / /< | | the left list is (1,3), + - - - *-----* - - - - *---* - - y - and the right one is + / / b c| |d (4,2) (sorted). + + There are then two spans, joining + 1 to 4 (i.e. a-b) and 3 to 2 + (i.e. c-d)! + + Sorting doesn't necessarily take much time, as in 99 cases out + of 100, the lists' order is kept from one scanline to the next. + We can thus implement it with two simple singly-linked lists, + sorted by a classic bubble-sort, which takes a minimum amount of + time when the lists are already sorted. + + A previous version of the rasterizer used more elaborate + structures, like arrays to perform `faster' sorting. It turned + out that this old scheme is not faster than the one described + above. + + Once the spans have been `created', we can simply draw them in + the target bitmap. + + g. Drop-out control + + To be continued. + + +--- end of raster.txt --- diff --git a/docs/readme.txt b/docs/readme.txt new file mode 100644 index 0000000..2a37bcc --- /dev/null +++ b/docs/readme.txt @@ -0,0 +1,106 @@ +Welcome to the documentation directory of FreeType. + +Here are short overview where you can find which information. + + + apiref.txt FreeType high-level API reference. All the types, + functions, and error codes of FreeType. + + .................................................................. + + apirefx.txt The API reference of FreeType extensions which come + with the library itself. + + .................................................................. + + bitmaps.txt How to render a glyph outline into a bitmap. + + .................................................................. + + changes.txt Guess what :-) + + .................................................................. + + convntns.txt The FreeType developer's conventions guide. Lists + the design and coding conventions used in the + engine's source code. This file is incomplete but + contains information that should be read by any + person willing to hack the FreeType code. + + .................................................................. + + credits A list of persons who have contributed to FreeType. + + .................................................................. + + glyphs.htm An introduction to glyphs in general, its usage in + glyphs.txt TrueType, and how FreeType handles them. The file + `glyphs.txt' is a simple text dump (done with + Netscape) of glyphs.htm. + + .................................................................. + + i18n.txt A short introduction to the GNU gettext package. + + .................................................................. + + porting.txt The FreeType porting guide. All you need to + configure and adapt very easily FreeType's source + code to tailor it to your own platform. + + Learn how to provide your own memory, i/o, and mutex + components, optimally fitted to your system. See + how you can build a singly-threaded, thread-safe, or + re-entrant version of the engine from the same + source code! + + .................................................................. + + raster.txt The scan-line converter's internals explained. The + document is still incomplete but presents many key + concepts. + + .................................................................. + + threads.txt How to use threads with FreeType. + + .................................................................. + + user.txt FreeType's user guide. A guide to FreeType's + concepts, a step by step example, and a note about + future works and projects. + + .................................................................. + + FAQ The new up-to-date FreeType FAQ. Look here first if + you have problems with the library. + + .................................................................. + + TODO Things which probably will come, which would be nice + to have, problems still here, etc. + + + +These documents will probably come later. + + develop.txt The FreeType developer's guide. All you need to know + in order to be able to understand and even hack the + engine's core source code. + + extend.txt The FreeType extension writer's how-to. All you need + to be able to provide new extensions to the engine. + + undoc.txt Undocumented TrueType! + + Yes, ladies and gentlemen, the TrueType + specification is fuzzy and misleading enough to + disband some serious commercial developers, but that + wasn't enough for us. Even though it took some time + (aaargh...), we finally discovered through hard work + the real meanings of the specs, fixed some errors + and even found surprising undocumented behaviour or + features! + + +--- end of readme.txt --- diff --git a/docs/threads.txt b/docs/threads.txt new file mode 100644 index 0000000..6e157fa --- /dev/null +++ b/docs/threads.txt @@ -0,0 +1,117 @@ +Threads with FreeType +===================== + + +The FreeType engine can now be compiled in thread-safe mode. +Because we want to keep the engine small and fast, the thread +protection is simple. This file gives an overview of what you can +do, and what you should strictly never do. + + +How to enable thread-safe support? + +A. You must have a valid replacement for the file `lib/ttmutex.c' + which calls your system's API to create, lock, and release + mutexes or semaphores. The current implementation is a dummy and + doesn't do anything. + +B. You must re-define the configuration macro + TT_CONFIG_OPTION_THREAD_SAFE located in `ttconfig.h'. Then + recompile. + + +IMPORTANT NOTE: + + If two threads create and use their own TT_Engine structure, they + can freely call the library concurrently on each of them (as well + as all their related objects), even in the non-threaded build. + The following remarks only apply to concurrent requests performed + on a single TT_Engine shared by multiple threads. + + +-------------------------------------------------------------------- + +- What you can do: + + With the exceptions listed below (in `What you can't do'), you can + call all API functions concurrently with two different threads. + This includes: + + Creating two or more faces from the same engine (i.e. concurrent + calls to TT_Open_Face()/TT_Open_Collection()). + + Creating two or more instances from the same face object + (i.e. concurrent calls to TT_New_Instance()). + + Creating two or more glyph containers from the same face object + (i.e. concurrent calls to TT_New_Glyph()). + + The same holds for destruction of objects. + + Load two or more glyphs concurrently for the same face or + instance (i.e. concurrent TT_Load_Glyph() calls). + + Render two or more glyphs at the same time, in the same engine + (i.e. calling TT_Get_Glyph_Bitmap()/TT_Get_Glyph_Pixmap() or + TT_Get_Outline_Bitmap()/TT_GetOutline_Pixmap() concurrently). + + NOTE: The scan-line converter can only render one glyph at a + time, for a given TT_Engine. Concurrent calls are + synchronized through a mutex, though. + + If you really, _really_, need to generate bitmaps or + pixmaps concurrently, create an additional engine and use + it with TT_Get_Outline_Bitmap()/TT_Get_Outline_Pixmap() + (you don't need to create any object in it, the outline + can come from any source too). + + This is, however, not recommended (it works perfectly, but + this could change in the future for various technical + reasons). + + +--------------------------------------------------------------------------- + +- What you cannot do: + + - You shouldn't try to delete an object while still using it with + another thread. The engine doesn't protect you from stupidity! + For example, these concurrent calls: + + TT_Close_Face( face ); + TT_Get_Glyph_Bitmap( glyph, &bitmap ); + + will act unexpectedly if the glyph is a child of the face (i.e., + was created with TT_New_Glyph( face, &glyph )) + ^^^^ + same face + + Here are some other examples: + + TT_Get_Glyph_Outline( glyph1, ... ); + TT_Load_Glyph( instance, glyph1, ... ); + + or + + TT_Get_Outline_BBox( outline, &bbox ); + TT_Transform_Outline( outline ); + + etc. + + You get the idea: Only the face and instances are protected -- + glyph containers and outlines should be thread-specific. + + + - You shouldn't initialize extensions in an engine concurrently + (which is what every mere mortal will do anyway :-). + + + +That's about it. Now enjoy the lib ;-) + + +PS: See the `MT-Note' and `MT-Safe' remarks in ttapi.c for more + detailed information on each specific function. + + +--- end of threads.txt --- diff --git a/docs/user.txt b/docs/user.txt new file mode 100644 index 0000000..d24d693 --- /dev/null +++ b/docs/user.txt @@ -0,0 +1,916 @@ + + The FreeType Engine + + Core Library User Guide + + or + + How to use the engine in your applications and font servers + + --------------------------------------------------- + + Introduction + + + I. Basic Concepts + + 1. Concepts + 2. Handles + 3. Conventions of use + 4. Object classes + + II. Extensions + + 1. What is an extension? + 2. Where to find them + 3. Writing your own extension + + Conclusion + +-------------------------------------------------------------------- + +Introduction +============ + + This file has been written to present the FreeType core library to + would-be writers of applications and font servers. It first + describes the concepts on which the engine is based, then how to + use it to obtain glyph metrics, outlines and bitmaps. + + The last part discusses the ability to add and use extensions to + the core library to get access to supplemental TrueType tables + which are not currently provided by the core engine. If you would + like to write your own extensions, read also the FreeType + developer's guide. + + +I. Basic Concepts +================= + + + 1. Concepts + ----------- + + FreeType defines several kinds of structures called `objects', + that are used to manage the various abstractions required to + access and display fonts. + + In care of good encapsulation, these objects are not directly + accessible from a client application. Rather, the user receives + a `handle' for each object he or she queries and wants to use. + This handle is a stand-alone reference; it cannot be used like a + pointer to access directly the object's data. + + 2. Properties + ------------- + + It is however possible to obtain and set object properties + through several functions of the API. For example, you can + query a face object's properties with only a handle for it, + using the function TT_Get_Face_Properties(). + + Note that the data will be returned in a user-allocated + structure, but will also contain pointers addressing directly + some data found within the object. + + A client application should never modify the data through these + pointers! In order to set new properties' values, the user must + always call a specific API function to do so, as a certain + number of other related data might not appear in the returned + structure and imply various non-visible coherency and coercion + rules. + + 3. Conventions of use + --------------------- + + o All API functions have their label prefixed by `TT_', as well + as all external (i.e. client-side) types. + + o To allow the use of FreeType's core engine in threaded + environments, nearly all API functions return an error code, + which is always set to 0 in case of success. + + The error codes' type is `TT_Error', and a listing of them is + given in the API references (see `apiref.txt' and + `apirefx.txt'). + + Some functions do not return an error code. Their result is + usually a value that becomes negative in case of error (this + is used for functions where only one kind of error can be + reported, like an invalid glyph index). + + An important note is that the engine should not leak memory + when returning an error, e.g., querying the creation of an + object will allocate several internal tables that will be + freed if a disk error occurs during a load. + + o A handle is acquired through API functions labeled along the + names: + + TT_Open_xxxx(), TT_New_xxxx() + + where `xxxx' is the object's class (Face, Instance, etc). + + Examples: + + TT_Open_Face(), TT_Open_Collection(), + TT_New_Instance(), TT_New_Glyph() + + o A handle is closed through an API labeled + + TT_Close_xxxx() or TT_Done_xxxx() + + where `xxxx' is the object's class (Face, Instance, etc). + + Examples: + + TT_Close_Face(), TT_Done_Instance(), TT_Done_Glyph() + + o Properties are obtained through an API labeled + + TT_Get_xxxx_yyyy() + + where `xxxx' is the object's class, and `yyyy' its property. + + Examples: + + TT_Get_Face_Properties(), TT_Get_Instance_Metrics() + TT_Get_Glyph_Outline(), TT_Get_Glyph_Bitmap() + + o Properties are set through an API labeled + + TT_Set_xxxx_yyyy() + + where `xxxx' is the object's class, and `yyyy' its property. + + Examples: + + TT_Set_Instance_Resolutions(), + TT_Set_Instance_CharSize() + + 4. Object Classes + ----------------- + + The following object classes are defined in this release of the + engine: + + o The Engine objects + + The FreeType library can be built to be completely re-entrant, + even though its default build doesn't support threads (more on + this in the `threads.txt'). + + As a consequence, it is possible to open several instances of + the library, called `engines'. Each engine has its own set of + current objects (faces, instances, etc.), and there is no + sharing between them. + + The idea is that the library could be compiled as a shared + library or DLL, and then be able to provide several distinct + engines to independent client applications. In this case, + each client program must create its own engine with + TT_Init_FreeType() to hold its data. + + Closing an engine will destroy _all_ objects that were + allocated since its opening, releasing all resources, etc., + with the exception of user-allocated outline objects. + + o The Face objects + + A face contains the data that is specific to a single TrueType + font file. It presents information common to all glyphs and + all point sizes like font-specific metrics and properties. + + You can open a face object by simply giving a pathname to the + TrueType file. You can later close (i.e. discard) the face + object. + + You can also open a single face embedded in a TrueType + collection. + + See also: + + TT_Open_Face(), TT_Open_Collection(), TT_Close_Face(), + TT_Get_face_Properties() + + o The Instance objects + + An instance is also called a `pointsize' or a `fontsize' in + some windowing systems. An instance holds the information + used to render glyphs on a specific device at a given point + size; it is always related to an opened face object. + + For instance, if you want to generate glyphs for text from the + same typeface at `sizes' of 10 and 12 points, all you need is + one face object, from which you will create two distinct + instances. + + A device is defined by its horizontal and vertical resolution, + usually specified in dots per inch (dpi). A point size is a + scaling number, given as _absolute_ values in points, where 1 + point = 1/72 inch. + + The `pixel' size, also known as the `ppem' value (for Points + Per EM square) is computed from both the device resolution and + the point size. It determines the size of the resulting glyph + bitmaps on your screen or sheet of paper. + + The default device resolution for any new instance is 96dpi in + both directions, which corresponds to VGA screens. The + default point size is 10pt. The high-level API allows you to + change this whenever you want for any given instance object. + + Note that closing a face object will automatically destroy all + its child instances (even though you can release them yourself + to free memory). + + See also: + + TT_New_Instance(), TT_Done_Instance(), + TT_Get_Instance_Metrics(), TT_Set_Instance_Resolutions(), + TT_Set_Instance_Pointsize() + + o The Glyph objects + + A Glyph object is a _container_ for the data that describes + any glyph of a given font. This means that it typically + holds: + + - Glyph metrics information, like bounding box or advance + width. + + - Outline arrays sized large enough to hold any glyph from the + face. This size is extracted from the face's internal + `maxProfile' table to optimize memory costs. + + - Other important parameters related to the `fine' rendering + of the glyphs. This includes things like the + dropout-control mode used at low sizes. + + - And it doesn't contain a bitmap or a pixmap! + + A glyph object is used to load, hint, and rasterize a single + glyph, as taken from the font file. + + See also: + + TT_New_Glyph(), TT_Done_Glyph(), TT_Get_Glyph_Metrics(), + TT_Get_Glyph_Outline(), TT_Get_Glyph_Bitmap(), + TT_Get_Glyph_Pixmap() + + o The Character Map (CharMap) handle + + Glyphs can be indexed in a TrueType file in any order, + independently of any standard character encoding, like ASCII + or Unicode. For this reason, each file comes with one or more + character mapping tables, used to translate from one specific + encoding's character codes to font glyph indices. + + There are many encoding formats, and each one can be + distinguished by two values: + + - its platform ID + - its platform-specific encoding ID + + Their values are defined in the TrueType specification and + won't be commented there. The FAQ lists the most commonly + used (platform,encoding) pairs. + + It is possible to enumerate the charmaps provided by a + TrueType font and to use any of these to perform translations. + + The charmaps are loaded into memory only on demand to save the + space taken by the maps that are not needed on your system. + They are part of the face object, however. + + This means that even though a charmap can be accessed through + a handle (obtained through the TT_Get_CharMap() function), it + isn't a stand-alone object. For example, you never need to + de-allocate it; this is automatically done by the engine when + its face object expires. + + See also: + + TT_Get_CharMap_Count(), TT_Get_CharMap_ID(), + TT_Get_CharMap(), TT_Char_Index(). + + o The Outline Objects + + An outline is a vector representation of a glyph. It is made + of several control points joined by line segments and Bezier + arcs, themselves gathered in closed paths called `contours'. + The outline have also several flags, or attributes, which are + used by the scan-line converter to select the best rendering + algorithms to convert the glyph's bitmap. + + Unlike other objects in FreeType, outlines aren't managed + through handles, but directly with the structure `TT_Outline', + defined for client applications. Each glyph container + contains an outline sized large enough to hold any glyph from + its parent face. Client applications can access it with + TT_Get_Glyph_Outline(). However, one can also create its own + outlines if needed with TT_New_Outline() and + TT_Clone_Outline(). + + Note that user-created outlines are NOT tracked by the + library. Hence, the client must release them himself with one + or more calls to TT_Done_Outline(). + + A various number of methods/operations are defined for the + outline class to simplify its management. + + + IMPORTANT NOTE: ********************************************** + + The definition of TT_Outline may change in the future. + Developers are thus advised to always use the outline + methods provided by the API rather than reading or setting + data themselves. + + ************************************************************** + + See also: + + TT_New_Outline(), TT_Clone_Outline(), TT_Copy_Outline(), + TT_Done_Outline(), TT_Get_Outline_BBox(), + TT_Get_Outline_Bitmap(), TT_Get_Outline_Pixmap(), + TT_Translate_Outline(), TT_Transform_Outline() + + o Bitmaps and Pixmaps + + One very important aspect of FreeType is that it is unable to + create bitmaps on its own. Rather, it is up to the client + application to do it, and pass a reference, in the form of a + TT_Raster_Map, to the scan-line converter (the component in + charge of generating bitmaps from outlines). + + Hence the importance of the TT_Raster_Map structure, which + layout is: + + struct + { + int rows; /* number of rows */ + int cols; /* number of columns (bytes) per row */ + int width; /* number of pixels per line */ + int flow; /* bitmap orientation */ + + void* bitmap; /* bit/pixmap buffer */ + long size; /* bit/pixmap size in bytes */ + } TT_Raster_Map; + + - The `rows' field contains the total number of rows in the + bitmap. + + - The `width' field gives the number of pixels per row (a bit + or a byte, depending on the map's nature). + + - The `cols' field gives the number of columns, i.e. bytes, + taken by each row in the map buffer. + + IMPORTANT: The `cols' field must be a multiple of 4 for + pixmaps! + + Typically, its value should be `(width+7)/8' for bitmaps, + and `(width+3) & -4' for pixmaps. + + - The `flow' field gives the map's vertical orientation. + + For example, if the first bytes of the bitmap buffer pertain + to its upper row, the flow is said to be going `down', and + the field should take the value `TT_Flow_Down'. If these + bytes pertain to its lowest row, the flow is going `up', and + the value is `TT_Flow_Up'. + + As an example, the PC video modes use a `down' flow, where + the first VRAM byte corresponds to the upper and leftmost + corner of the screen. + + - The `bitmap' field is a typeless pointer to the map's + buffer. + + - The `size' field contains the buffer's size in bytes. It is + usually computed as follows: + + size = rows * cols; + + NOTE: For bitmaps, the leftmost-pixel is related to the + highest (i.e. most significant) bit of its byte. + There is currently no support for the opposite + convention found in some systems. + + (It can be easily added if you really need it, just + ask the development team.) + + +II. Step-by-step Example +======================== + + Here is an example to show, step by step, how a client application + can open a font file, set one or several instances, load any + glyph, then render it to a bitmap. + + 1. Initialize the engine + ------------------------ + + This is the first thing to do. You need to initialize an engine + through a call to TT_Init_FreeType(). This function will set up + a various number of structures needed by the library. + + This allocates about 68kByte, of which 64kByte are dedicated to + the scan-line converter's `render pool', a workspace used for + bitmap generation. Note that even though this space is bounded, + the raster is able to render a glyph to any size or bitmap, even + horribly huge ones. + + NOTE: You can reduce the size of this pool by modifying the + constant RASTER_RENDER_POOL in the file `ttraster.c'. A + smaller pool will result in slower rendering at large + sizes. Take care of never assigning a value smaller than + 4kByte however, as bugs may start to lurk in! + + Example: + + TT_Engine engine; + + + error = TT_Init_FreeType( &engine ); + if ( error ) + { + printf( "could not create engine instance\n"); + ... + } + + 2. Initialize the extensions you need + ------------------------------------- + + FreeType provides several extensions which are optional, + separately compilable components to add some rare features to + the engine and its API. + + You need to explicitly initialize the extensions you want to + use. Each extension must provide an initialization function, + following the naming convention: + + TT_Init_xxx_Extension( engine ); + + where `xxx' is the extension's `kind'. + + Example: + + error = TT_Init_Kerning_Extension( engine ); + if ( error ) + ... + + 3. Open the font file + --------------------- + + There are two ways to open a font face, depending on its file + format: + + - If it is a TrueType file (ttf), you can simply use the API + named TT_Open_Face(), which takes the file's pathname as + argument, as well as the address of the returned face handle. + + Check the returned error code to see if the file could be + opened and accessed successfully. + + TT_Face face; /* face handle */ + + + error = TT_Open_Face( engine, "/fonts/arial.ttf", &face ); + if ( error ) + { + printf( "could not open the file\n" ); + ... + } + + - If the font is embedded in a TrueType collection (ttc), you + can use the API named TT_Open_Collection(), which takes also + the font's index within the collection's directory. + + TT_Face face; /* face handle */ + + + /* Load the collection's second face (index=1) */ + error = TT_Open_Collection( engine, "/fonts/mingli.ttc", + 1, &face ); + if ( error ) + { + printf( "could not open the file\n" ); + ... + } + + - Finally, when you do not know the number of faces embedded in + a TrueType collection, the following technique can be used: + + o Call TT_Open_Face() with the collection file's pathname. + This API recognizes collections automatically and always + return a handle for its first embedded font. + + o Get the face's properties through TT_Get_Face_Properties(). + These contain, among other things, the total number of fonts + embedded in the collection, in its field `num_Faces'. + + TT_Face face; /* face handle */ + TT_Face_Properties props; /* face properties */ + + + /* open the first collection font */ + error = TT_Open_Face( engine, "/fonts/mingli.ttc", + &face ); + if ( error ) + { + printf( "could not open the file\n" ); + ... + } + + /* Get the face properties */ + TT_Get_Face_Properties( face, &props ); + + /* Now print the number of faces */ + printf( "there are %d faces in this collection file\n", + props->num_Faces ); + + 4. Create an instance from the face object + ------------------------------------------ + + You must create an instance (also known as a `pointsize') which + contains information relative to the target output device's + resolutions and a given point size. + + o The instance object is created through TT_New_Instance(): + + TT_Instance instance; + + + error = TT_New_Instance( face, &instance ); + if ( error ) + { + printf( "could not create instance\n" ); + ... + } + + TECHNICAL NOTE: Creating a new instance executes its font + program. This can fail if the font is broken. + Never assume that the error code returned here + is always 0. + + o You must set the instance's properties to suit your needs. + These are simply its device resolutions, set through + TT_Set_Instance_Resolutions(), and its point size, set through + TT_Set_Instance_CharSize(): + + /* Set the target horizontal and vertical resolution to */ + /* 300dpi in each direction (typically for a printer). */ + /* A fresh instance's default resolutions are 96dpi in */ + /* both directions. */ + error = TT_Set_Instance_Resolutions( instance, 300, 300 ); + if ( error ) + { + printf( "could not set resolution\n" ); + ... + } + + /* Now set the point size to 12pt. Default is 10pt. */ + /* Don't forget that the size is expressed in 26.6 fixed */ + /* float format, so multiply by 64. */ + error = TT_Set_Instance_CharSize( instance, 12 * 64 ); + if ( error ) + { + printf( "could not set point size\n" ); + ... + } + + TECHNICAL NOTE: These calls may execute the font's `prep' + program, which can fail if the font is broken. + Never assume that the error code returned is + are always 0. + + o You can also set the instance's transformation flags to tell + the glyph loading function that you are going to perform a + transformation (like rotation or slanting) on the glyph. Note + that the glyph loader doesn't perform the transformation. It + only informs the glyphs' hinting instruction streams about + these flags which may use it to disable or enable various + features (grid-fitting, drop-out control, etc). + + Use e.g. + + TT_Set_Instance_Transforms( FALSE, TRUE ); + + to indicate that you're going to stretch, but not rotate, this + instance's glyphs. Default is, of course, both FALSE. + + 5. Create a glyph container + --------------------------- + + You need a glyph object to serve as a container for the glyphs + you want to load from the face. This is done simply by + + TT_Glyph glyph; /* glyph object handle */ + + + error = TT_New_Glyph( face, &glyph ); + if ( error ) + { + printf( "could not create glyph\n" ); + ... + } + + 6. Find your platform's character mappings + ------------------------------------------ + + Each font file can come with one or more character mapping + tables, used to convert character codes to glyph indices. You + must know the values of the `platformID' and `encodingID' as + defined in the TrueType specification for your platform. For + example, Windows Unicode encoding is (platform:3,encoding:1), + while Apple Unicode is (platform:0,encoding:0). Both formats + differ in internal storage layout and can be used transparently + with the same inputs with FreeType. + + The function TT_Get_CharMap_Count() returns the number of + character mappings present in a face. You can then enumerate + these with the function TT_Get_CharMap_ID(). Once you've found + a mapping usable for your platform, use TT_Get_CharMap() to + return a TT_CharMap handle that will be used later to get glyph + indices. + + 7. Load the glyph + ----------------- + + The glyph loader is easily queried through TT_Load_Glyph(). + This API function takes several arguments: + + o An instance handle to specify at which point size and + resolution the loaded glyph should be scaled and grid-fitted. + + o A glyph container, used to hold the glyph's data in memory. + Note that the instance and the glyph must relate to the _same_ + font file. An error would be produced immediately otherwise. + + o A glyph index, used to reference the glyph within the font + file. This index is not a platform specific character code, + and a character's glyph index may vary from one font to + another. To compute glyph indices from character codes, use + the TT_CharMap handle created in section 6 with + TT_Char_Index(). + + We strongly recommend using the Unicode charmap whenever + possible. + + o A load mode, indicating what kind of operations you need. + There are only two defined for the moment: + + TTLOAD_SCALE_GLYPH: + + If set, this flag indicates that the loaded glyph will be + scaled (according to the instance specified as an + argument) to fractional pixel coordinates (26.6). If not, + the coordinates will remain integer FUnits. Please refer + to the TrueType specification and the FreeType header + files for more details on the 26.6 format and other data + types. + + TTLOAD_HINT_GLYPH: + + This flag is only in effect if the TTLOAD_SCALE_GLYPH flag + is set. It indicates that the glyph must also be `hinted' + resp. `grid-fitted' for better display results. Note that + this also means that the glyph metrics will be + grid-fitted, including the bounding box. + + You can simply `or' the flags. As most applications will + require both flags to be set, the constant TTLOAD_DEFAULT is + defined as: + + #define TTLOAD_DEFAULT (TTLOAD_SCALE_GLYPH | \ + TTLOAD_HINT_GLYPH ) + + Example: + + error = TT_Load_Glyph( instance, glyph, 36, + TTLOAD_DEFAULT ); + if ( error ) + { + printf("could not load the glyph\n"); + ... + } + + 8. Query glyph properties + ------------------------- + + You're then able to query various glyph properties: + + o The glyph metrics can be obtained through + TT_Get_Glyph_Metrics(). The data returned in the metrics + structure is: + + - the glyph's left side bearing (bearingX) + - the glyph's top side bearing (bearingY) + - the glyph's advance width (advance) + - the glyph's bounding box (bbox) + + These values are expressed in 26.6 pixel units when the glyph + was loaded with scaling, or in FUnits if not. To obtain + vertical metrics you should use the function + TT_Get_Glyph_Big_Metrics(). + + o The glyph outline can be queried through + TT_Get_Glyph_Outline(). This can be useful to process the + point coordinates (e.g. applying stretching or rotation) with + functions like TT_Apply_Outline_Matrix() or + TT_Apply_Outline_Translation(). Note that these functions do + not recompute a glyph's metrics after the transformation! + + The outline's structure is described in the reference + `apiref.txt'. + + A bitmap or pixmap for the glyph can be queried with the API + functions TT_Get_Glyph_Bitmap() and TT_Get_Glyph_Pixmap(). + These functions take a glyph handle as an argument, as well as + a bitmap/pixmap description block and two offsets. + + The target map is described through a TT_Raster_Map object, + which structure is defined in the reference (see + `apiref.txt'). The offsets are given in the same units as the + points coordinates and glyph metrics: 26.6 pixel units for a + scaled glyph, and FUnits for an unscaled one. + + IMPORTANT TECHNICAL NOTE: If the glyph has been scaled and + hinted, the offsets _must_ be + multiples of 64 (i.e. integer pixel + offsets). Otherwise, you would ruin + the grid fitting (which usually + results in ugly glyphs). + + Example: + + TT_Glyph_Metrics metrics; + TT_Outline outline; + TT_Raster_Map bitmap; + + + TT_Get_Glyph_Metrics( glyph, &metrics ); + TT_Get_Glyph_Outline( glyph, &outline ); + + /* set up the bitmap */ + ... + TT_Get_Glyph_Bitmap( glyph, &bitmap, 0, 0 ); + + 9. When you are done + -------------------- + + o You can close any font face object with TT_Close_Face(). This + call will automatically discard its child instances, glyphs + and charmaps. + + o You can also close the engine with a single call to + TT_Done_FreeType(). This will release _all_ objects that were + previously allocated (with the exception of user-created + outlines), and close all font files, as well as extensions + that were inited for it. + + +III. Extensions +=============== + + 1. What is an extension? + ------------------------ + + FreeType allows you to access a various number of TrueType + tables, as well as to render individual glyphs. However: + + 1. It doesn't perform some high-level operations, like + generating a string text from many individual glyphs. + + 2. It doesn't perform kerning (which can be needed by operations + mentioned in item 1). + + 3. It doesn't give access to all the defined TrueType tables, + especially the optional ones. + + While item 1 is a feature that will never go into FreeType's + core engine, which goal is to provide easy access to font data + and rendering _individual_ glyphs, point 2 and 3 can be added to + the engine's features through extensions. + + An extension is simply a small piece of code that extends the + engine's abilities and APIs. It is possible to extend the + engine without touching the core's source code, this is + described in chapter 3 below. + + 2. The two kinds of extensions + ------------------------------ + + There are basically two kinds of extensions, which require + different implementations. + + a. API extensions + + An API extension is a set of functions that extend the + FreeType core API to give access to tables that are already + loaded by the engine, but not provided for now. An example of + such data can be: + + - the horizontal metrics table (hmtx) + - the `gasp' table + + This kind of extension is made of: + + o an API extension header file, following the usage convention + introduced here (all labels prefixed with `TT_'), and which + will be included by the clients which want to use the + extension. By convention, such header names begin with + `ftx' (for FreeType eXtension). + + Examples: ftxgasp.h, ftxhmtx.h + + o One or more functions used to give access to the tables that + are already loaded and managed by the engine. They usually + only copy pointers to the target structure given by the + client application since these structures are not accessible + through the 'normal' API. An API extension doesn't need to + be initialized before being used. + + b. Engine extensions + + It can sometimes be useful to load and manage several tables + that are not considered by the core engine. These extensions + need to provide additional functions to fit into FreeType's + internal object management model, and are more sophisticated + than API extensions. + + An example is given in this distribution to provide kerning + support (or more technically spoken, access to the kerning + tables found within the TrueType files). It is made of: + + o An API extension providing new interfaces to the client + applications that need it. See the file `ftxkern.h' + resp. `apirefx.txt'. + + o A specific implementation, providing services to create, + load, and manage kerning tables as additional parts of a + face object. In the case of kerning, the directory of + tables is loaded when the face is opened, and tables + themselves are fetched from the file on demand. This + implies several `hooks' in the core engine. See the files + `ttkern.h' and `ttkern.c'. These are called `engine + extensions'. + + o A specific extension initialization function, namely + TT_Init_Kerning_Extension(), that must be called after an + engine's creation, and before any face object allocation. + This function will `register' the extension within the + engine and make its API workable. + + 3. Writing your own extensions + ------------------------------ + + As it was suggested earlier, writing an engine extension is a + delicate process, as the additional code must follow a certain + number of design rules, presented in the FreeType developer's + guide. Unfortunately, there is currently no extension writer's + guide. + + By writing your own extensions, it will be possible to support + more advanced TrueType formats like TrueType GX or OpenType in a + near future, without having to torture the engine core source at + each iteration. + + If you encounter some difficulties when trying to create your + own extension, please read the core source file carefully, and + in the event that you may need changes that are not fitted to + the current extension mechanism, do not hesitate to contact the + authors at `devel@freetype.org'. + + +Conclusion +========== + + The engine source code has become rather stable since now, and + its quality compares very favorably to Windows and the Macintosh + rasterizers. Its internals will continue to change, though very + slowly, even if the API isn't expected to grow much in a near + future. + + FreeType is really a glyph-oriented TrueType driver. Its + purpose is to open and manage font files in order to load single + glyphs and render them as cleanly as possible. A number of + features, important to developers, like text string rendering, + font mapping and underlining/stroking, to name a few, aren't + provided there even though they'd be highly appreciated. + + We hope you have success and fun using this engine. Much time + has been taken to make it one of the best in its genre. + Remember that it is not intended to be a complete font server or + text rendering library, but a pretty solid base for these kinds + of applications, as well as others. + + We thank you for your time and consideration. + + David Turner, Robert Wilhelm, Werner Lemberg, + and all the FreeType enthusiasts... + + +--- End of user.txt --- diff --git a/freetype.spec b/freetype.spec new file mode 100644 index 0000000..e367b11 --- /dev/null +++ b/freetype.spec @@ -0,0 +1,162 @@ +Summary: FreeType library +Name: freetype +Version: 1.3.1 +Release: 1 +Source: ftp://ftp.freetype.org/pub/freetype/freetype-%{version}.tar.gz +URL: http://www.freetype.org/ +Copyright: BSD-Like +Group: Libraries +BuildRoot: /var/tmp/freetype + +%description +The FreeType engine is a free and portable TrueType font rendering +engine. It has been developed to provide TrueType support to a +great variety of platforms and environments. + +Note that FreeType is a *library*. It is not a font server for your +favorite platform, even though it was designed to be used in many of +them. Note also that it is *not* a complete text-rendering library. +Its purpose is simply to open and manage font files, as well as +load, hint and render individual glyphs efficiently. You can also +see it as a `TrueType driver' for a higher-level library, though +rendering text with it is extremely easy, as demo-ed by the test +programs. + +This package contains the files needed to run programs that use the +FreeType engine. + +%package devel +Summary: FreeType development headers and libraries +Group: Development/Libraries +Requires: %{name} = %{version} + +%description devel +The FreeType engine is a free and portable TrueType font rendering +engine. It has been developed to provide TrueType support to a +great variety of platforms and environments. + +Note that FreeType is a *library*. It is not a font server for your +favorite platform, even though it was designed to be used in many of +them. Note also that it is *not* a complete text-rendering library. +Its purpose is simply to open and manage font files, as well as +load, hint and render individual glyphs efficiently. You can also +see it as a `TrueType driver' for a higher-level library, though +rendering text with it is extremely easy, as demo-ed by the test +programs. + +This package contains all supplementary files you need to develop +your own programs using the FreeType engine. + +%package demo +Summary: FreeType test and demo programs +Group: Applications/Graphics +Requires: %{name} = %{version} + +%description demo +The FreeType engine is a free and portable TrueType font rendering engine. +It has been developed to provide TT support to a great variety of platforms +and environments. + +Note that FreeType is a *library*. It is not a font server for your favorite +platform, even though it was designed to be used in many of them. Note also +that it is *not* a complete text-rendering library. Its purpose is simply to +open and manage font files, as well as load, hint and render individual +glyphs efficiently. You can also see it as a "TrueType driver" for a +higher-level library, though rendering text with it is extremely easy, as +demo-ed by the test programs. + +This package contains several programs bundled with the FreeType engine for +testing and demonstration purposes. + +%changelog +* Thu Sep 9 1998 Pavel Kankovsky +- Simplified (and fixed) file list. + +* Wed Jun 16 1999 Werner Lemberg +- Updated to version 1.3. + +* Sun Oct 25 1998 Pavel Kankovsky +- libttf.so version number updated again. +- Default localedir based on prefix. +- File list adjustments (howto/). + +* Sun Oct 16 1998 Pavel Kankovsky +- Source filename fixed. +- HOWTO removed. +- libttf.so version number updated. + +* Tue Sep 29 1998 Robert Wilhelm +- Updated to version 1.2. + +* Tue Jul 14 1998 Alexander Zimmermann +- Added missing files. +- Added %defattr tags. + +* Thu Jun 18 1998 Robert Wilhelm +- Added lots of attr(-,root,root). + +* Wed May 27 1998 Pavel Kankovsky +- Changed group attr of freetype and freetype-devel package. +- Fixed misc glitches. + +* Sun May 24 1998 Pavel Kankovsky +- Split the package into three parts (runtime library, development + tools, and demo programs). +- Added missing files (headers, NLS). +- Added ldconfing upon (de)installation. + +* Thu Mar 12 1998 Bruno Lopes F. Cabral +- NLS for Portuguese language is missing, sorry (may be in a near future) + (please note the workaround using --with-locale-dir and gnulocaledir. + NLS Makefile needs a bit more rework but again I'll not patch it here). + +%prep +%setup + +find . -name CVS -type d | xargs rm -rf + +%build +./configure --prefix=/usr --enable-static +make all + +%install +make install prefix=$RPM_BUILD_ROOT/usr + +%clean +rm -rf $RPM_BUILD_ROOT + +%post +/sbin/ldconfig + +%postun +/sbin/ldconfig + +%files +%defattr(644, root, root, 755) +%doc announce license.txt +/usr/lib/libttf.so.* +/usr/share/locale/ + +%files devel +%defattr(644, root, root, 755) +%doc INSTALL README PATENTS announce license.txt readme.1st +%doc docs/ howto/ +/usr/lib/libttf.so +/usr/lib/libttf.la +/usr/lib/libttf.a +/usr/include/freetype/ + +%files demo +%defattr(755, root, root, 755) +%doc announce license.txt +/usr/bin/ftdump +/usr/bin/fterror +/usr/bin/ftlint +/usr/bin/ftmetric +/usr/bin/ftsbit +/usr/bin/ftstring +/usr/bin/ftstrpnm +/usr/bin/ftstrtto +/usr/bin/fttimer +/usr/bin/ftview +/usr/bin/ftzoom diff --git a/ft_conf.h.in b/ft_conf.h.in new file mode 100644 index 0000000..c19b442 --- /dev/null +++ b/ft_conf.h.in @@ -0,0 +1,211 @@ +/* ft_conf.h.in. */ + +/* This file is part of the FreeType project. */ + + +/* we need the following because there are some typedefs in this file */ + +#ifndef FT_CONF_H +#define FT_CONF_H + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define if the X Window System is missing or not being used. */ +#undef X_DISPLAY_MISSING + +/* The number of bytes in a int. */ +#undef SIZEOF_INT + +/* The number of bytes in a long. */ +#undef SIZEOF_LONG + +/* Define if you have the getpagesize function. */ +#undef HAVE_GETPAGESIZE + +/* Define if you have the memcpy function. */ +#undef HAVE_MEMCPY + +/* Define if you have the memmove function. */ +#undef HAVE_MEMMOVE + +/* Define if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define if you have the header file. */ +#undef HAVE_LOCALE_H + +/* Define if you have the header file. */ +#undef HAVE_LIBINTL_H + +/* Define if you have the libintl library. */ +#undef HAVE_LIBINTL + +/**********************************************************************/ +/* */ +/* The following configuration macros can be tweaked manually by */ +/* a developer to turn on or off certain features or options in the */ +/* TrueType engine. This may be useful to tune it for specific */ +/* purposes.. */ +/* */ +/**********************************************************************/ + +/*************************************************************************/ +/* Define this if the underlying operating system uses a different */ +/* character width than 8bit for file names. You must then also supply */ +/* a typedef declaration for defining 'TT_Text'. Default is off. */ + +#undef HAVE_TT_TEXT + + +/*************************************************************************/ +/* Define this if you want to generate code to support engine extensions */ +/* Default is on, but if you're satisfied by the basic services provided */ +/* by the engine and need no extensions, undefine this configuration */ +/* macro to save a few more bytes. */ + +#define TT_CONFIG_OPTION_EXTEND_ENGINE + + +/*************************************************************************/ +/* Define this if you want to generate code to support gray-scaling, */ +/* a.k.a. font-smoothing or anti-aliasing. Default is on, but you can */ +/* disable it if you don't need it. */ + +#define TT_CONFIG_OPTION_GRAY_SCALING + + +/*************************************************************************/ +/* Define this if you want to completely disable the use of the bytecode */ +/* interpreter. Doing so will produce a much smaller library, but the */ +/* quality of the rendered glyphs will enormously suffer from this. */ +/* */ +/* This switch was introduced due to the Apple patents issue which */ +/* emerged recently on the FreeType lists. We still do not have Apple's */ +/* opinion on the subject and will change this as soon as we have. */ + +#undef TT_CONFIG_OPTION_NO_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to use a big 'switch' statement within the */ +/* bytecode interpreter. Because some non-optimizing compilers are not */ +/* able to produce jump tables from such statements, undefining this */ +/* configuration macro will generate the appropriate C jump table in */ +/* ttinterp.c. If you use an optimizing compiler, you should leave it */ +/* defined for better performance and code compactness.. */ + +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the scan-line */ +/* converter (the component which in charge of converting outlines into */ +/* bitmaps). This will produce a bigger object file for "ttraster.c", */ +/* which _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_RASTER + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the TrueType */ +/* bytecode interpreter. This will produce much bigger code, which */ +/* _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_INTERPRETER + + +/*************************************************************************/ +/* Define TT_CONFIG_THREAD_SAFE if you want to build a thread-safe */ +/* version of the library. */ + +#undef TT_CONFIG_OPTION_THREAD_SAFE + + +/**********************************************************************/ +/* */ +/* The following macros are used to define the debug level, as well */ +/* as individual tracing levels for each component. There are */ +/* currently three modes of operation : */ +/* */ +/* - trace mode (define DEBUG_LEVEL_TRACE) */ +/* */ +/* The engine prints all error messages, as well as tracing */ +/* ones, filtered by each component's level */ +/* */ +/* - debug mode (define DEBUG_LEVEL_ERROR) */ +/* */ +/* Disable tracing, but keeps error output and assertion */ +/* checks. */ +/* */ +/* - release mode (don't define anything) */ +/* */ +/* Don't include error-checking or tracing code in the */ +/* engine's code. Ideal for releases. */ +/* */ +/* NOTE : */ +/* */ +/* Each component's tracing level is defined in its own source. */ +/* */ +/**********************************************************************/ + +/* Define if you want to use the tracing debug mode */ +#undef DEBUG_LEVEL_TRACE + +/* Define if you want to use the error debug mode - ignored if */ +/* DEBUG_LEVEL_TRACE is defined */ +#undef DEBUG_LEVEL_ERROR + + +/**************************************************************************/ +/* Definition of various integer sizes. These types are used by ttcalc */ +/* and ttinterp (for the 64-bit integers) only.. */ + +#if SIZEOF_INT == 4 + + typedef signed int TT_Int32; + typedef unsigned int TT_Word32; + +#elif SIZEOF_LONG == 4 + + typedef signed long TT_Int32; + typedef unsigned long TT_Word32; + +#else +#error "no 32bit type found" +#endif + +#if SIZEOF_LONG == 8 + +/* LONG64 must be defined when a 64-bit type is available */ +/* INT64 must then be defined to this type.. */ +#define LONG64 +#define INT64 long + +#else + +/* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */ +/* by defining the TT_USE_LONG_LONG macro in 'ft_conf.h'. Note that this */ +/* will produce many -ansi warnings during library compilation. */ +#ifdef TT_USE_LONG_LONG + +#define LONG64 +#define INT64 long long + +#endif /* TT_USE_LONG_LONG */ +#endif + +#endif /* FT_CONF_H */ diff --git a/howto/mac.txt b/howto/mac.txt new file mode 100644 index 0000000..6ed97d9 --- /dev/null +++ b/howto/mac.txt @@ -0,0 +1,19 @@ + The FreeType Mac Compilation HowTo + + + Please note that the FreeType team does *not* support the + Macintosh platform due to lack of knowledge. + + However, we provide the basic files to compile the library in + the lib/arch/mac directory (OK, `folders'). Also the project + files for PowerPC with CodeWarrior have been contributed (in + contrib/mac). + + A noteworthy point is that the precompiled standard MacOS + headers should be turned off to compile the library, to avoid + errors caused by conflicting definitions of `Fixed' and `Byte'. + + +Good luck! + +--- end of mac.txt --- diff --git a/howto/msdos.txt b/howto/msdos.txt new file mode 100644 index 0000000..6ab0c40 --- /dev/null +++ b/howto/msdos.txt @@ -0,0 +1,250 @@ + The FreeType MS-DOS Compilation HowTo + +Contents + +Introduction +I. Building the library + 1. Quick Compilation + 2. Manual compilation + 3. Notes +II. Building other parts of the package + 1. Test programs + 2. Other contribs +III. Special issues of 16-bit MS-DOS + + + +Introduction +============ + +This file describes the compilation of the FreeType package on a +MS-DOS system. It comes with Makefiles for the following compilers: + + - gcc/emx and gcc/djgpp with GNU make (32 bit) + + - wcc386 with wmake (Watcom -- tried with 10.6) + + - gcc/emx with dmake (32 bit) + + - cl with nmake (16-bit Microsoft C -- tried with 7 and VC++ 1.5x) + + - bcc/tcc with make (16-bit Borland C++ and Turbo C) + +NOTE: + + You are advised to jump to section II.1 if you want to run the + FreeType test/demo programs as quick as possible. + + + +I. Building the library +======================= + + +1. Quick Compilation +-------------------- + + The easiest way to compile the library on MS-DOS is to go to the + directory `freetype/lib'. Then type, depending on your compiler: + + gcc/emx, + gcc/djgpp: make -f arch/msdos/Makefile.gcc + gcc/dmake: dmake -r -f arch/msdos/Makefile.dm + + wcc386: wmake -f=arch\msdos\Makefile.wat + + cl: nmake /f arch\msdos\Makefile.MS (for version 7) + cl: nmake /f arch\msdos\Makefile.VC (for Visual C++ 1.x) + + tcc: make -farch/msdos/Makefile.TC + bcc: make -farch/msdos/Makefile.BC + + This should build the `libttf.a' or `libttf.lib' library files. + + You can also use the following targets: + + clean - Cleans all intermediate object files created during + compilation. Keeps all library and executables in + place. + + distclean - Cleans everything, leaving the directories as they + were before the compilation. + + debug - Makes a development version of the library. Only + useful for FreeType developers and hackers. + + Note that you can also select to use the `debugging' flags for + your compiler (instead of the `optimizing' ones), by defining + the `DEBUG' symbol, like in + + nmake /f arch\msdos\Makefile.MS DEBUG=1 + make -farch/msdos/Makefile.BC /DDEBUG + etc. + + Doing so will automatically select the debug target instead of + the normal mode. + + For 16-bit compilers, you can also try defining the `BIGFONTS' + symbol, to enable the use of the `huge pointers' needed to + handle some big fonts. More on this at the end of this file. + + +2. Manual compilation +--------------------- + + Here are explained the steps that are required to compile the + FreeType _library_ (and only this one) by hand. + + Unlike previous versions, FreeType 1.1 and above can be compiled + in two modes, called `debug mode' and `single object mode'. + + Debug mode is simply the normal way of compiling C programs, i.e., + each `*.c' file is compiled into an individual `*.obj' object + file, and all of them are linked together into an archive (i.e., + `*.lib' library). + + Single object mode is slightly different: All C files are included + in a single source during compilation, resulting in a single final + object file for the core library. This has the advantage of + letting optimizing compilers do more global work, as well as + getting rid of all external which are used solely for the purpose + of components interfacing. + + In both modes, you need to include the following paths to your + makefile/command line: + + the location of all `tt*.[hc]' files + the location of system-specific files + + For example, if you are compiling from the `freetype/lib' + directory, you can type for debug mode something like + + gcc -c -I. -Iarch/msdos tt*.c + + to compile all required files into object ones. Then assemble + them in a library with `ar', `lib', or `tlib'. + + In single object mode, you only need to compile the file named + `freetype.c' which is located in `freetype/lib/arch/msdos'. From + the same directory as before, one would type + + gcc -c -I. -Iarch/msdos arch/msdos/freetype.c + + You can also compile the extensions located in + `freetype/lib/extend' separately from the base engine. You will + need to include the same paths as before, though; be sure to add + the path to the `extend' directory, like in + + gcc -c -I. -Iarch/msdos -Iextend extend/*.c + + +3. Notes +-------- + + `char' is always `signed char' in the sources! + + `ttconfig.h' relies heavily on a file called `ft_conf.h' that + contains information related to the target platform, located in + the `freetype/lib/arch/msdos/' directory. Depending on your + compiler, you may need to slightly edit it. + + We use gcc as our reference compiler for warnings. This means + that we use the `-ansi -pedantic -Wall' flags and try to get rid + of warnings in this situation. If you're compiling with another + compiler, you may encounter warnings, not errors. Note that the + Borland compilers seem to produce lots of irrelevant warnings + (like `potential loss of precision'). + + + +II. Building other parts of the package +======================================= + + +1. Test programs +---------------- + + These are located in `freetype/test'. Most of them use a tiny + graphics sub-system which is simply used to display bitmaps and + pixmaps on a variety of platforms. The MS-DOS version is a very + basic one that only works in full-screen using standard VGA mode. + + To compile them, you must be in the `freetype/test' directory and + invoke the makefile in arch/msdos. For example: + + nmake /f arch\msdos\Makefile.VC + + + NOTE 1: + + This will automatically invoke the library makefile for you! + + NOTE 2: + + For now, the graphical test programs only run on the following + platforms: Unix, OS/2, Dos, Amiga, and Windows. + + The library, being pure ANSI-C, can be used on any system to + generate bitmaps and pixmaps. + + +2. Other contribs +----------------- + + You may find some other contributions to the FreeType project in + the `freetype/contrib' directory. Each of these programs should + have its own Makefiles and documentations. Also check their + licenses, as the programs are not necessarily distributed under + the FreeType one. + + Most of these contributions are targeted to Unix. You are invited + to port them to MS-DOS, and then contribute your improvements. + + + +III. Special issues of 16-bit MS-DOS +==================================== + + As usual, 16-bit MS-DOS have some limitations. + + First, and mainly, only the large model is usable. The small and + medium models are not usable, because the library uses more than + 64kByte of data; and the compact model is unusable as well, since + the code of the library itself is slightly less than 64kByte, thus + leaving very small place for the real work. The net effect of + that limitation is that performances are not very impressive, to + say the least (32-bit DOS extenders perform usually three-time + faster). + + Even with the large model, the rasterizer is still limited in + size, particularly with pixmaps (that is, with anti-aliasing gray + levels). + + Another annoying limitation exists with some East Asian fonts that + have 16,383 glyphs or more, since an internal table then + overflows. We tried to overcome this using the so-called `huge + pointers', but then good support for these in the run-time library + is needed. To enable this support, try defining the `BIGFONTS' + symbol with the makefile, like using + + nmake /f arch\msdos\makefile.MS BIGFONTS=1 + make -farch/msdos/makefile.BC /DBIGFONTS + etc. + + The Makefiles for both Microsoft and Borland compilers depend on a + special file, `arch/msdos/depend.dos', which is built by a Unix + script named `makedep'. You may consider editing it if you + heavily modify the source files; or better yet, re-run the script, + using any clone of the Bourne shell and gcc, the GNU compiler, + with + + arch/msdos/makedep + + in both the `lib' and the `test' directories. + + + +Good luck! + + +--- end of msdos.txt --- diff --git a/howto/os2.txt b/howto/os2.txt new file mode 100644 index 0000000..2ce5bab --- /dev/null +++ b/howto/os2.txt @@ -0,0 +1,200 @@ + The FreeType OS/2 Compilation HowTo + +Contents + +Introduction +I. Building the library + 1. Quick Compilation + 2. Manual compilation + 3. Notes +II. Building other parts of the package + 1. Test programs + 2. Other contribs +III. Troubleshooting + + + +Introduction +============ + +This file describes the compilation of the FreeType package on an +OS/2 system. It comes with makefiles for the following compilers: + + - gcc/emx with GNU make + + - icc with nmake (Visual Age C++) + + - wcc386 with wmake (Watcom -- tried with 10.6) + + - gcc/emx with dmake + + +NOTE: + + You're advised to jump to section II.1 if you want to run the + FreeType test/demo programs as quick as possible. + + + +I. Building the library +======================= + + +1. Quick Compilation +-------------------- + + The easiest way to compile the library on OS/2 is to go to the + directory `freetype/lib'. Then type, depending on your compiler, + + gcc/emx: make -f arch/os2/makefile.emx + gcc/dmake: dmake -f arch/os2/makefile.dm + + icc: nmake -f arch\os2\makefile.icc + wcc386: wmake -f=arch\os2\makefile.wat + + This should build the `libttf.a' or `libttf.lib' library files. + + You can also use the following targets: + + debug - Makes a development version of the library. Only + useful for FreeType developers and hackers. + + clean - Cleans all intermediate object files created during + compilation. Keeps all library and executables in + place. + + distclean - Cleans everything, leaving the directories as they + were before the compilation. + + +2. Manual compilation +--------------------- + + Here are explained the steps that are required to compile the + FreeType _library_ (and only this one) by hand. + + Unlike previous versions, FreeType 1.1 and above can be compiled + in two modes, called `debug mode' and `single object mode'. + + Debug mode is simply the normal way of compiling C programs, i.e., + each `*.c' file is compiled into an individual `*.obj' object + file, and all of them are linked together into an archive (i.e., + `*.lib' library). + + Single object mode is slightly different: all C files are included + in a single source during compilation, resulting in a single final + object file for the core library. This has the advantage of + letting optimizing compilers do more global work, as well as + getting rid of all external symbols which are used solely for the + purpose of components interfacing. + + In both modes, you need to include the following paths to your + makefile/command line: + + the location of all `tt*.[hc]' files + the location of system-specific files + + For example, if you are compiling from the `freetype/lib' + directory, you can type for debug mode something like + + gcc -c -I. -Iarch/os2 tt*.c arch/os2/os2file.c + + to compile all required files into object ones. Then assemble + them in a library with `ar' or `implib'. + + In single object mode, you only need to compile the file named + `freetype.c' which is located in `freetype/lib/arch/os2'. From + the same directory as before, one would type: + + gcc -c -I. -Iarch/os2 arch/os2/freetype.c + + You can also compile the extensions located in + `freetype/lib/extend' separately from the base engine. You will + need to include the same paths as before, though; be sure to add + the path to the `extend' directory, like in + + gcc -c -I. -Iarch/os2 -Iextend extend/*.c + + + +II. Building other parts of the package +======================================= + + +1. Test programs +---------------- + + The test programs are located in `freetype/test'. Most of them + use a tiny graphics sub-system which is simply used to display + bitmaps and pixmaps in a windows on a variety of platforms. The + OS/2 version comes in two flavors: PM and full-screen. + + To compile them, you must be in the `freetype/test' directory, and + invoke the makefile in arch/os2. For example: + + nmake -f arch\os2\makefile.os2 + + + NOTE 1: + + This will automatically invoke the library makefile for you! + + NOTE 2: + + The test programs come in two flavors, distinguished by the `fs' + suffix appended to their name. For example: + + ftview (PM version) + ftviewfs (Full Screen version) + + The full-screen version is there mainly for debugging purposes. + + NOTE 3: + + For now, the graphical test programs only run on the following + platforms: Unix, OS/2, Dos, Amiga, and Windows. + + The library, being pure ANSI-C, can be used on any system to + generate bitmaps and pixmaps. + + +2. Other contributions +---------------------- + + You may find some other contributions to the FreeType project in + the `freetype/contrib' directory. Each of these programs should + have its own Makefiles and documentations. Also check their + licenses, as the programs not necessarily distributed under the + FreeType one. You are invited to port the non-OS/2 applications + to OS/2. + + For OS/2, you will find the source code for the FreeType/2 font + driver in `freetype/contrib/os2'. Read its documentation + carefully before trying to compile it, as it certainly won't be + easy. + + + +III. Troubleshooting +==================== + + There is only one important point on OS/2: + + `The test program crashes with anti-aliasing on!' + + It has been discovered that some versions of Visual Age C++ + contain a bug which miscompiles the anti-aliasing source in + ttraster.c, hence resulting in a page fault when trying to render + a pixmap in the engine. Apparently, not all levels/versions of + the compiler contain the bug. You'll notice the problem + immediately (page fault :-). + + Please apply the most recent fixpack to your Visual Age C++ copy + in order to get rid of it (newer fixpacks seem to solve the + issue). + + +Good luck! + + +--- end of os2.txt --- diff --git a/howto/unix.txt b/howto/unix.txt new file mode 100644 index 0000000..1824580 --- /dev/null +++ b/howto/unix.txt @@ -0,0 +1,255 @@ + The FreeType Unix Compilation HOWTO + +Contents + +Introduction +I. Building the library + 1. Quick Compilation + 2. Manual compilation + 3. Notes +II. Building other parts of the package + 1. Test programs + 2. Other contribs +III. Successful Build Reports + + + +Introduction +============ + +This file describes the compilation of the FreeType package on a +Unix system. Using the `configure' script it should be rather easy +to build the library. However, detailed instructions on how to +compile the library manually are given later in this document. + + + +I. Building the library +======================= + + +1. Quick Compilation +-------------------- + + The easiest way to compile the library on a Unix system is by + using the `configure' script that comes with it. Simply go to the + root directory of the FreeType package, then type + + ./configure + + to run a script that will probe your system and detect various + configuration issues, which are explained later in this document. + + From there, you can simply type + + make + + to invoke compilation of the whole package. You can also use the + following commands: + + make debug - Make a development version of the library. + Only useful for FreeType developers and + hackers. The default build should come with + `-g' (i.e., debug info in the object file) + already. + + make clean - Clean all intermediate object files created + during compilation. Keeps all library and + executables in place. + + make distclean - Clean everything, leaving the directories as + they were before the compilation. You'll need + to run `./configure' again to be able to + re-build it. + + make install - Install the library files libttf.a, libttf.la + or libttf.so to your system library path + (`/usr/local/lib' by default). The path can be + set manually with ./configure. + + make uninstall - Undo a `make install'. + + +2. Trouble-shooting and simple customization +-------------------------------------------- + + The make build seems to fail on some Solaris systems. This is + mainly due to the fact that the test programs (not the font + library itself) try to use certain libraries and/or utilities if + they find them on your system. In some cases, the Sun versions + are incompatible to the GNU ones. If you encounter such problems, + please report them to us so we can try to fix it. + + The configure script and makefiles that it generates can/make use + of the following things: + + - gettext - In order to compile the internationalized error + message string extension, which isn't part of the + core library. You can disable this and get a + clean compile with + + ./configure --disable-nls + + + - libtool - Used to generate shared libraries. You can + disable it by typing + + ./configure --disable-shared + + which will generate and link the FreeType engine + as a static library. + + By default, static compilation is disabled if the + configure script detects that your compiler + and/or operating system supports shared + libraries. You can ask for static libraries with + + ./configure --enable-static + + For more configuration options, type `./configure --help' to see a + summary of what is possible. The option to change the library + installation path for `make install' is, as usual, + `--prefix='. Example: + + ./configure --prefix=${HOME}/local/lib --disable-shared + + to install a static library (libttf.a) in `~/local/lib' (after a + `make install') + + +3. Manual compilation +--------------------- + + Here are explained the steps that are required to compile the + FreeType _library_ (and only this one) by hand. + + a. Generate a configuration file named `ft_conf.h' + + This file contains a certain number of configuration macro + declarations which must fit your system. The configure script + generates it automatically for you, but you can also take the + template file `freetype/ft_conf.h.in' and change it by hand, + then save it as `freetype/ft_conf.h'. + + b. Choose your compilation mode + + Unlike previous versions, FreeType 1.1 and above can be compiled + in two modes, called `debug mode' and `single object mode'. + + Debug mode is simply the normal way of compiling C programs, + i.e., each *.c file is compiled into an individual *.o object + file, and all of them are linked together into an archive (i.e., + a *.a library). + + Single object mode is slightly different: All C files are + included in a single source file during compilation, resulting + in a single final object file for the core library. This has + the advantage of letting optimizing compilers do more global + work, as well as getting rid of all external symbols which are + used solely for the purpose of components interfacing. + + In both modes, you need to include the following paths to your + makefile/command line: + + . the location of the `ft_conf.h' file + . the location of all `tt*.[hc]' files + . the location of system-specific files, i.e., `ttmmap.c' on + Unix. + + For example, if you are compiling from the `freetype/lib' + directory, you can type for debug mode something like + + gcc -c -I.. -I. -Iarch/unix tt*.c arch/unix/ttmmap.c + + to compile all required files. Then assemble them in a library + with `ar' (and run `runlib' if necessary). + + In single object mode, you only need to compile the file named + `freetype.c' which is located in `freetype/lib/arch/unix'. From + the same directory as before, one would type: + + gcc -c -I.. -I. -Iarch/unix arch/unix/freetype.c + + You can also compile the extensions located in + `freetype/lib/extend' separately from the base engine. You'll + need to include the same paths as before, though. + + + +II. Building other parts of the package +======================================= + + +1. Test programs +---------------- + + All test programs are located in `freetype/test'. Most of them + use a tiny graphics sub-system which simply display bitmaps and + pixmaps in a windows on a variety of platforms. Of course, the + Unix version uses X11. + + The default `make' builds all tests programs automatically. Just + go the `freetype/test' and launch the programs when you are there. + Documentation on the test programs can be found in the file + `freetype/README'. + + NOTE: + + For now, the graphical test programs only run on the following + platforms: Unix, OS/2, Dos, Amiga, and Windows. + + The library, being pure ANSI-C, can be used on any system to + generate bitmaps and pixmaps. + + +2. Other contributions +---------------------- + + You may find some other contributions to the FreeType project in + the `freetype/contrib' directory. Each of these programs should + have their own makefiles and documentations. Also check their + licenses, as they are not necessarily distributed under the + FreeType one. + + + +III. Successful Build Reports +============================= + +Nelson H. F. Beebe and others report the +following successfully builds (with gcc 2.8.1) of freetype-1.1 on + + DEC Alpha 2100-5/250: OSF/1 3.2 + HP 9000/735: HP-UX 10.01 + Intel Pentium (200MHz MMX): Linux 2.0.30 + SGI Challenge L: IRIX 5.3 + Sun SPARC 20/512: Solaris 2.6 + Sun SPARC Ultra-2: SunOS 5.5.1 + IBM RS/6000: AIX 4.1 + +Chances are good the the current release will build on the same +machines and platforms. + +There are build problems reported on SunOs 4.x which have the form + + ld: /usr/tmp/cca07291.o: assert pure-text failed: + reference to [offset] at f754 in /usr/tmp/cca07291.o + +This may be a compiler bug in gcc 2.8.1. + +You can work around by just building a static library with + + ./configure --disable-shared --enable-static --disable-nls + +Maybe `make debug' will help here too (untested). + +Other successful builds: + + Sun SPARC Solaris 2.5 with Sun C compiler+linker + +For updated build reports, please consult our web site: + + http://www.freetype.org + + +--- end of unix.txt --- diff --git a/howto/windows.txt b/howto/windows.txt new file mode 100644 index 0000000..196ef83 --- /dev/null +++ b/howto/windows.txt @@ -0,0 +1,344 @@ + The FreeType Windows Compilation HowTo + +Contents + +Introduction +I. Building the library + 1. Quick Compilation + 2. Manual compilation + 3. Notes +II. Building other parts of the package + 1. Test programs + 2. Other contributions +III. Special issues of 16-bit Windows + + + +Introduction +============ + +This file describes the compilation of the FreeType package on a +Windows system. It comes with Makefiles for the following +compilers: + + - gcc/CygWin32 and gcc/MinGW32 with GNU make (32 bit) + + - cl with nmake (16-bit and 32-bit Microsoft C and Visual C++) + + - bcc with make (16-bit and 32-bit Borland C++ and also Borland + C++ builder) + +Throughout this file, we use `winXX' if it applies indifferently to +both 16-bit and 32-bit versions. You should replace it with win16 +resp. win32, as applicable. + +NOTE: + + You are advised to jump to section II.1 if you want to run the + FreeType test/demo programs as quick as possible. + + + +I. Building the library +======================= + + +1. Quick Compilation +-------------------- + + The easiest way to compile the library on Windows is to go to the + directory `freetype/lib'. Then type, depending on your compiler: + + gcc: make -f arch/win32/Makefile.gcc + + cl: nmake /f arch\win16\Makefile.MS (for C/C++ 7) + cl: nmake /f arch\win16\Makefile.VC (for VC++ 16bit) + cl: nmake /f arch\win32\Makefile.CL (for VC++ 32bit) + + bcc: make -farch/win16/Makefile.BC + bcc32: make -farch/win32/Makefile.BC + + This should build the `libttf.a' or `libttf.lib' library files. + Of course, this assumes that your compiler is regularly installed. + + You can also use the following targets: + + clean - Cleans all intermediate object files created during + compilation. Keeps all library and executables in + place. + + distclean - Cleans everything, leaving the directories as they + were before the compilation. + + debug - Makes a development version of the library. Only + useful for FreeType developers and hackers. + + Note that you can also select to use the `debugging' flags for + your compiler (instead of the `optimizing' ones), by defining + the `DEBUG' symbol, like in + + nmake /f arch\win32\Makefile.CL DEBUG=1 + make -farch/winXX/Makefile.BC /DDEBUG + etc. + + Doing so will automatically select the debug target instead of + the normal mode. + + For 16-bit compilers, you can also try to define the `BIGFONTS' + symbol, enabling the use of the `huge pointers' needed to handle + some big fonts. More on this at the end of this file. + + Another way to compile the library is to use the IDE provided with + the following compilers: Borland C++ 5.0, Visual C++ 4.0, and + Visual C++ 5.0. The project/workspace files can be found in the + `freetype/lib/arch/win32' directory: + + freetype.ide for Borland C++ 4.0 and 5.0 (and perhaps 4.5) + + freetype.dsp project and workspace files for + freetype.dsw Visual C++ 5.0 + + freetype.mdp project and makefile files for + freetype.mak Visual C++ 4.0 + + They generate a static library, which contain the core engine as a + single object file, as well as all standard extensions. + + Notes: + + - You may need to update the include paths in the Borland C++ + workspace settings. The current one looks in the directory + "c:\Program Files\Borland\BC 5.0\Include" for include files. + + - Take care that some compilers may overwrite these files when + generating the library (e.g. Borland C++ creates its own + `freetype.mdp' file, which isn't a Visual C++ project during + compilation). + + This is only important if you try to compile the lib with + several compilers. + + We gladly accept project files for other compilers. + + +2. Manual compilation +--------------------- + + Here are explained the steps that are required to compile the + FreeType _library_ (and only this one) by hand. + + Unlike previous versions, FreeType 1.1 and above can be compiled + in two modes, called `debug mode' and `single object mode'. + + Debug mode is simply the normal way of compiling C programs, i.e., + each `*.c' file is compiled into an individual `*.obj' object + file, and all of them are linked together into an archive (i.e., + `*.lib' library). + + Single object mode is slightly different: All C files are included + in a single source during compilation, resulting in a single final + object file for the core library. This has the advantage of + letting optimizing compilers do more global work, as well as + getting rid of all external which are used solely for the purpose + of components interfacing. + + In both modes, you need to include the following paths to your + makefile/command line: + + the location of all `tt*.[hc]' files + the location of system-specific files + + For example, if you are compiling from the `freetype/lib' + directory, you can type for debug mode something like + + gcc -c -I. -Iarch/win32 tt*.c + + to compile all required files into object ones. Then assemble + them in a library with `ar', `lib', or `tlib'. + + In single object mode, you only need to compile the file named + `freetype.c' which is located in `freetype/lib/arch/winXX'. From + the same directory as before, one would type + + gcc -c -I. -Iarch/win32 arch/win32/freetype.c + + You can also compile the extensions located in + `freetype/lib/extend' separately from the base engine. You will + need to include the same paths as before, though; be sure to add + the path to the `extend' directory, like in + + gcc -c -I. -Iarch/win32 -Iextend extend/*.c + + +3. Building a DLL +----------------- + + The easiest way to build the library as a DLL is also to use the + Makefiles we provide! Go to the directory `freetype/lib', then + type, depending on your compiler: + + gcc: (not yet supported) + + cl: nmake /f arch\win16\Makefile.VC DLL=1 dll (16bit) + cl: nmake /f arch\win32\Makefile.CL DLL=1 dll (32bit) + + bcc: make -farch/win16/Makefile.BC -DDLL dll + bcc32: make -farch/win32/Makefile.BC -DDLL dll + + This should build `ft13_XX.dll' (`13' for version 1.3, `XX' is + either 16 or 32), and the `libttf.lib' library file. + + You can also use the following target: + + install - Install the DLL `ft13_XX.dll' to your system directory + (`C:\WINDOWS' by default). You can override the + directory by specifying the name of the directory: + + make -farch/winXX/Makefile.BC /DINSTALL_DIR=C:\TESTDLL install + nmake /f arch\win32\Makefile.CL INSTALL_DIR=D:\WINNT install + + Note that you can also select to use the `debugging' flags for + your compiler (instead of the `optimizing' ones), by defining + the `DEBUG' symbol, like in + + nmake /f arch\win16\Makefile.VC DEBUG=1 DLL=1 dll + make -farch/winXX/Makefile.BC /DDEBUG /DDLL dll + etc. + + Another way to build to DLL with Visual C++ is to use a special + Makefile that does exactly that, without relying on any settings. + + With VC++ 6.0, just type while in the `freetype/lib/arch/win32' + directory: + + nmake /f makefile.vc + + on the command line. + + For other versions, modify the $(TOOLS32) variable to point to the + directory where the build tools are. No need to set any + environment variables. + + +4. Notes +-------- + + `char' is always `signed char' in the sources! + + `ttconfig.h' relies heavily on a file called `ft_conf.h' that + contains information related to the target platform, located in + the `freetype/lib/arch/winXX/' directory. Depending on your + compiler, you may need to slightly edit it. + + We use gcc as our reference compiler for warnings. This means + that we use the `-ansi -pedantic -Wall' flags and try to get rid + of warnings in this situation. If you are compiling with another + compiler, you may encounter warnings, not errors. Note that the + Borland compilers seem to produce lots of irrelevant warnings + (like `potential loss of precision'). + + + +II. Building other parts of the package +======================================= + + +1. Test programs +---------------- + + All test programs are located in `freetype/test'. Most of them + use a tiny graphics sub-system which is simply used to display + bitmaps and pixmaps on a variety of platforms. The Windows + version is a very basic one that only displays a small graphic + windows in addition to the console where the flow of messages + still goes. + + To compile them, you must be in the `freetype/test' directory and + invoke the makefile in arch/winXX. For example: + + nmake -f arch\os2\Makefile.VC + + NOTE 1: + + This will automatically invoke the library makefile for you! + + NOTE 2: + + For now, the graphical test programs only run on the following + platforms: Unix, OS/2, Dos, Amiga, and Windows. + + The library, being pure ANSI-C, can be used on any system to + generate bitmaps and pixmaps. + + +2. Other contributions +---------------------- + + You may find some other contributions to the FreeType project in + the `freetype/contrib' directory. Each of these programs should + have its own Makefiles and documentations. Also check their + licenses, as the programs are not necessarily distributed under + the FreeType one. + + Most of these contributions are targeted to Unix. You are invited + to port them to Windows, and then contribute your improvements. + + + +III. Special issues of 16-bit Windows +===================================== + + As usual, 16-bit Windows have some limitations. + + First, and mainly, only the large model is usable. The small and + medium models are not usable, because the library uses more than + 64kByte of data; and the compact model is unusable as well, since + the code of the library itself is slightly less than 64kByte, thus + leaving very small place for the real work. The net effect of + that limitation is that performances are not very impressive, to + say the least (32-bit DOS extenders perform usually three-time + faster). + + Even with the large model, the rasterizer is still limited in + size, particularly with pixmaps (that is, with anti-aliasing gray + levels). + + The test programs rely on a tiny graphical driver that mimics the + ones available on other platforms. It has some peculiarities. + First, as the test programs need a `console', the programs should + linked with some emulation of that concept. We used successfully + Borland EasyWin and Microsoft QuickWin for this purpose. Then, + the graphics window that displays the bitmaps incur the usual + 64kByte limit: The size of the window is quite tiny, particularly + when displaying `gray-level' bitmaps (the size is then 320x200, + but contrary to full-screen MS-DOS the pixels are not magnified). + Ultimately, no efforts have been done to accomodate the colors of + the screen: As a result, displaying gray bitmaps in 256-color mode + uses only 4 levels of gray (instead of 5 rendered by the library). + + Another annoying limitation exists with some East Asian fonts that + have 16,383 glyphs or more, since an internal table then + overflows. We tried to overcome this using so-called `huge + pointers', but then good support for these in the run-time library + is needed. To enable huge pointers, try defining the `BIGFONTS' + symbol with the makefile, like + + nmake /f arch\win16\makefile.VC BIGFONTS=1 + make -farch/win16/makefile.BC /DBIGFONTS + etc. + + The makefiles for both Microsoft and Borland compilers depend on a + special file, arch/winXX/depend.win, which is built by a Unix + script named `makedep'. You may consider editing it if you + heavily modify the source files; or better yet, re-run the script, + using any clone of the Bourne shell and gcc, the GNU compiler, + with + + arch/winXX/makedep + + in both the `lib' and the `test' directories. + + +Good luck! + +--- end of windows.txt --- diff --git a/install-sh b/install-sh new file mode 100644 index 0000000..ebc6691 --- /dev/null +++ b/install-sh @@ -0,0 +1,250 @@ +#! /bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/lib/.cvsignore b/lib/.cvsignore new file mode 100644 index 0000000..e61a727 --- /dev/null +++ b/lib/.cvsignore @@ -0,0 +1,3 @@ +.libs +*.lo +libttf.la diff --git a/lib/arch/amigaos/Makefile.gcc b/lib/arch/amigaos/Makefile.gcc new file mode 100644 index 0000000..ef02372 --- /dev/null +++ b/lib/arch/amigaos/Makefile.gcc @@ -0,0 +1,69 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for amiga using ADE Enviroment. +# +# You will need GNU make. +# +# Use this file while in the lib directory with the following statement: +# +# make -f arch/amigaos/Makefile.gcc + +ARCH = arch/amigaos +FT_MAKEFILE = $(ARCH)/Makefile.gcc + +AR = ar +RM = rm + +CC = gcc + +CFLAGS = -Wall -pedantic -ansi -O2 -g -noixemul -I$(ARCH) -I. -Iextend + +SRC_X = extend/ftxgasp.c extend/ftxkern.c extend/ftxpost.c \ + extend/ftxcmap.c extend/ftxwidth.c extend/ftxsbit.c \ + extend/ftxgsub.c extend/ftxgpos.c extend/ftxgdef.c \ + extend/ftxopen.c +OBJS_X = $(SRC_X:.c=.o) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c \ + ttextend.c ttfile.c ttgload.c ttinterp.c ttload.c \ + ttmemory.c ttmutex.c ttobjs.c ttraster.c +OBJS_M = $(SRC_M:.c=.o) $(OBJS_X) + +SRC_S = $(ARCH)/freetype.c +OBJ_S = $(SRC_S:.c=.o) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +.PHONY: all debug clean distclean + + +all: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_S libttf.a + +debug: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_M libttf.a + + +$(OBJ_S): $(SRC_S) $(SRC_M) + + +libttf.a: $($(LIB_FILES)) + $(AR) src $@ $^ + +clean: + $(RM) $($(LIB_FILES)) + +distclean: clean + $(RM) dep.end libttf.a + +depend: $(SRC_S) $(SRC_M) $(SRC_X) + $(CC) -E -M $^ > dep.end + +ifeq (dep.end,$(wildcard dep.end)) + include dep.end +endif + +# end of Makefile.gcc diff --git a/lib/arch/amigaos/freetype.c b/lib/arch/amigaos/freetype.c new file mode 100644 index 0000000..723c8f4 --- /dev/null +++ b/lib/arch/amigaos/freetype.c @@ -0,0 +1,25 @@ +/* This file is part of the FreeType project */ + +/* Single object library component for AmigaOS */ +#define TT_MAKE_OPTION_SINGLE_OBJECT + +#include "ttapi.c" +#include "ttcache.c" +#include "ttcalc.c" +#include "ttcmap.c" +#include "ttdebug.c" +#include "ttfile.c" +#include "ttgload.c" +#include "ttinterp.c" +#include "ttload.c" +#include "ttmemory.c" +#include "ttmutex.c" +#include "ttobjs.c" +#include "ttraster.c" + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE +#include "ttextend.c" +#endif + + +/* END */ diff --git a/lib/arch/amigaos/ft_conf.h b/lib/arch/amigaos/ft_conf.h new file mode 100644 index 0000000..6aa4b3f --- /dev/null +++ b/lib/arch/amigaos/ft_conf.h @@ -0,0 +1,220 @@ +/* This file is part of the FreeType project */ + +/* ft_conf.h for AmigaOS using ADE enviroment */ + + +/* we need the following because there are some typedefs in this file */ + +#ifndef FT_CONF_H +#define FT_CONF_H + +/* Define to empty if the keyword does not work. */ + +/* #undef const */ + +/* Define if you have a working `mmap' system call. */ + +/* #undef HAVE_MMAP */ + +/* Define if you have the header file. */ + +#define HAVE_STDLIB_H + +/* Define if the X Window System is missing or not being used. */ + +#define X_DISPLAY_MISSING + +/* The number of bytes in a int. */ + +#define SIZEOF_INT 4 + +/* The number of bytes in a long. */ + +#define SIZEOF_LONG 4 + +/* Define if you have the getpagesize function. */ + +#define HAVE_GETPAGESIZE + +/* Define if you have the memcpy function. */ + +#define HAVE_MEMCPY + +/* Define if you have the memmove function. */ + +#define HAVE_MEMMOVE + +/* Define if you have the valloc function. */ + +#define HAVE_VALLOC + +/* Define if you have the header file. */ + +#define HAVE_FCNTL_H + +/* Define if you have the header file. */ + +#define HAVE_UNISTD_H + +/**********************************************************************/ +/* */ +/* The following configuration macros can be tweaked manually by */ +/* a developer to turn on or off certain features or options in the */ +/* TrueType engine. This may be useful to tune it for specific */ +/* purposes.. */ +/* */ +/**********************************************************************/ + + +/*************************************************************************/ +/* Define this if the underlying operating system uses a different */ +/* character width than 8bit for file names. You must then also supply */ +/* a typedef declaration for defining 'TT_Text'. Default is off. */ + +/* #define HAVE_TT_TEXT */ + + +/*************************************************************************/ +/* Define this if you want to generate code to support engine extensions */ +/* Default is on, but if you're satisfied by the basic services provided */ +/* by the engine and need no extensions, undefine this configuration */ +/* macro to save a few more bytes. */ + +#define TT_CONFIG_OPTION_EXTEND_ENGINE + + +/*************************************************************************/ +/* Define this if you want to generate code to support gray-scaling, */ +/* a.k.a. font-smoothing or anti-aliasing. Default is on, but you can */ +/* disable it if you don't need it. */ + +#define TT_CONFIG_OPTION_GRAY_SCALING + + +/*************************************************************************/ +/* Define this if you want to completely disable the use of the bytecode */ +/* interpreter. Doing so will produce a much smaller library, but the */ +/* quality of the rendered glyphs will enormously suffer from this. */ +/* */ +/* This switch was introduced due to the Apple patents issue which */ +/* emerged recently on the FreeType lists. We still do not have Apple's */ +/* opinion on the subject and will change this as soon as we have. */ + +#undef TT_CONFIG_OPTION_NO_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to use a big 'switch' statement within the */ +/* bytecode interpreter. Because some non-optimizing compilers are not */ +/* able to produce jump tables from such statements, undefining this */ +/* configuration macro will generate the appropriate C jump table in */ +/* ttinterp.c. If you use an optimizing compiler, you should leave it */ +/* defined for better performance and code compactness.. */ + +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the TrueType */ +/* bytecode interpreter. This will produce much bigger code, which */ +/* _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the scan-line */ +/* converter (the component which in charge of converting outlines into */ +/* bitmaps). This will produce a bigger object file for "ttraster.c", */ +/* which _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_RASTER + + +/*************************************************************************/ +/* Define TT_CONFIG_THREAD_SAFE if you want to build a thread-safe */ +/* version of the library. */ + +#undef TT_CONFIG_OPTION_THREAD_SAFE + + +/**********************************************************************/ +/* */ +/* The following macros are used to define the debug level, as well */ +/* as individual tracing levels for each component. There are */ +/* currently three modes of operation : */ +/* */ +/* - trace mode (define DEBUG_LEVEL_TRACE) */ +/* */ +/* The engine prints all error messages, as well as tracing */ +/* ones, filtered by each component's level */ +/* */ +/* - debug mode (define DEBUG_LEVEL_ERROR) */ +/* */ +/* Disable tracing, but keeps error output and assertion */ +/* checks. */ +/* */ +/* - release mode (don't define anything) */ +/* */ +/* Don't include error-checking or tracing code in the */ +/* engine's code. Ideal for releases. */ +/* */ +/* NOTE : */ +/* */ +/* Each component's tracing level is defined in its own source. */ +/* */ +/**********************************************************************/ + +/* Define if you want to use the tracing debug mode */ +#undef DEBUG_LEVEL_TRACE + +/* Define if you want to use the error debug mode - ignored if */ +/* DEBUG_LEVEL_TRACE is defined */ +#undef DEBUG_LEVEL_ERROR + +/**************************************************************************/ +/* Definition of various integer sizes. These types are used by ttcalc */ +/* and ttinterp (for the 64-bit integers) only.. */ + +#if SIZEOF_INT == 4 + + typedef signed int TT_Int32; + typedef unsigned int TT_Word32; + +#elif SIZEOF_LONG == 4 + + typedef signed long TT_Int32; + typedef unsigned long TT_Word32; + +#else +#error "no 32bit type found" +#endif + +#if SIZEOF_LONG == 8 + +/* LONG64 must be defined when a 64-bit type is available */ +/* INT64 must then be defined to this type.. */ +#define LONG64 +#define INT64 long + +#else + +/* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */ +/* by defining the TT_USE_LONG_LONG macro in 'ft_conf.h'. Note that this */ +/* will produce many -ansi warnings during library compilation. */ +#ifdef TT_USE_LONG_LONG + +#define LONG64 +#define INT64 long long + +#endif /* TT_USE_LONG_LONG */ +#endif + +#endif /* FT_CONF_H */ + + +/* END */ diff --git a/lib/arch/ansi/freetype.c b/lib/arch/ansi/freetype.c new file mode 100644 index 0000000..820687a --- /dev/null +++ b/lib/arch/ansi/freetype.c @@ -0,0 +1,32 @@ +/* This file is part of the FreeType project */ + +/* Single file library component for the ANSI target */ +#define TT_MAKE_OPTION_SINGLE_OBJECT + +/* first include common core components */ + +#include "ttapi.c" +#include "ttcache.c" +#include "ttcalc.c" +#include "ttcmap.c" +#include "ttdebug.c" +#include "ttgload.c" +#include "ttinterp.c" +#include "ttload.c" +#include "ttobjs.c" +#include "ttraster.c" + +/* then system-specific (or ANSI) components */ + +#include "ttfile.c" +#include "ttmemory.c" +#include "ttmutex.c" + +/* the extensions are compiled separately, but we need to */ +/* include the file ttextend.c if we want to support them */ + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE +#include "ttextend.c" +#endif + +/* END */ diff --git a/lib/arch/ansi/ft_conf.h b/lib/arch/ansi/ft_conf.h new file mode 100644 index 0000000..352e646 --- /dev/null +++ b/lib/arch/ansi/ft_conf.h @@ -0,0 +1,227 @@ +/* This file is part of the FreeType project */ + +/* ft_conf.h for the ANSI Build */ + + +/* we need the following because there are some typedefs in this file */ + +#ifndef FT_CONF_H +#define FT_CONF_H + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H + +/* Define if you have the getpagesize function. */ +#undef HAVE_GETPAGESIZE + +/* Define if you have the memcpy function. */ +#define HAVE_MEMCPY + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE + +/* Define if you have the valloc function. */ +#undef HAVE_VALLOC + +/* Define if you have the header file. Unix-specific */ +#undef HAVE_FCNTL_H + +/* command.com can't pipe stderr into a file; any message would be */ +/* written into the graphics screen. */ +#define HAVE_PRINT_FUNCTION 1 + +#define Print( format, ap ) vfprintf( stdout, (format), (ap) ) + + +/* The number of bytes in a int. We use the ANSI header file limits.h */ +/* for determining it since there is no easy way to guess. */ +/* */ +#include +#if UINT_MAX == 0xFFFF +#define SIZEOF_INT 2 +#elif UINT_MAX == 0xFFFFFFFF +#define SIZEOF_INT 4 +#else +#error "Unsupported number of bytes in `int' type!" +#endif + +/* We now try to guess the size of longs in the same way */ +/* */ +#if ULONG_MAX == 0xFFFFFFFF +#define SIZEOF_LONG 4 +#elif ULONG_MAX == 0xFFFFFFFFFFFFFFFF +#define SIZEOF_LONG 8 +#else +#error "Unsupported number of bytes in `long' type!" +#endif + + +/**********************************************************************/ +/* */ +/* The following configuration macros can be tweaked manually by */ +/* a developer to turn on or off certain features or options in the */ +/* TrueType engine. This may be useful to tune it for specific */ +/* purposes.. */ +/* */ +/**********************************************************************/ + + +/*************************************************************************/ +/* Define this if the underlying operating system uses a different */ +/* character width than 8bit for file names. You must then also supply */ +/* a typedef declaration for defining 'TT_Text'. Default is off. */ + +/* #define HAVE_TT_TEXT */ + + +/*************************************************************************/ +/* Define this if you want to generate code to support engine extensions */ +/* Default is on, but if you're satisfied by the basic services provided */ +/* by the engine and need no extensions, undefine this configuration */ +/* macro to save a few more bytes. */ + +#define TT_CONFIG_OPTION_EXTEND_ENGINE + + +/*************************************************************************/ +/* Define this if you want to generate code to support gray-scaling, */ +/* a.k.a. font-smoothing or anti-aliasing. Default is on, but you can */ +/* disable it if you don't need it. */ + +#define TT_CONFIG_OPTION_GRAY_SCALING + + +/*************************************************************************/ +/* Define this if you want to completely disable the use of the bytecode */ +/* interpreter. Doing so will produce a much smaller library, but the */ +/* quality of the rendered glyphs will enormously suffer from this. */ +/* */ +/* This switch was introduced due to the Apple patents issue which */ +/* emerged recently on the FreeType lists. We still do not have Apple's */ +/* opinion on the subject and will change this as soon as we have. */ + +#undef TT_CONFIG_OPTION_NO_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to use a big 'switch' statement within the */ +/* bytecode interpreter. Because some non-optimizing compilers are not */ +/* able to produce jump tables from such statements, undefining this */ +/* configuration macro will generate the appropriate C jump table in */ +/* ttinterp.c. If you use an optimizing compiler, you should leave it */ +/* defined for better performance and code compactness.. */ + +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the TrueType */ +/* bytecode interpreter. This will produce much bigger code, which */ +/* _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the scan-line */ +/* converter (the component which in charge of converting outlines into */ +/* bitmaps). This will produce a bigger object file for "ttraster.c", */ +/* which _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#define TT_CONFIG_OPTION_STATIC_RASTER + + +/*************************************************************************/ +/* Define TT_CONFIG_THREAD_SAFE if you want to build a thread-safe */ +/* version of the library. */ + +#undef TT_CONFIG_OPTION_THREAD_SAFE + + +/**********************************************************************/ +/* */ +/* The following macros are used to define the debug level, as well */ +/* as individual tracing levels for each component. There are */ +/* currently three modes of operation : */ +/* */ +/* - trace mode (define DEBUG_LEVEL_TRACE) */ +/* */ +/* The engine prints all error messages, as well as tracing */ +/* ones, filtered by each component's level */ +/* */ +/* - debug mode (define DEBUG_LEVEL_ERROR) */ +/* */ +/* Disable tracing, but keeps error output and assertion */ +/* checks. */ +/* */ +/* - release mode (don't define anything) */ +/* */ +/* Don't include error-checking or tracing code in the */ +/* engine's code. Ideal for releases. */ +/* */ +/* NOTE : */ +/* */ +/* Each component's tracing level is defined in its own source. */ +/* */ +/**********************************************************************/ + +/* Define if you want to use the tracing debug mode */ +#undef DEBUG_LEVEL_TRACE + +/* Define if you want to use the error debug mode - ignored if */ +/* DEBUG_LEVEL_TRACE is defined */ +#undef DEBUG_LEVEL_ERROR + + +/**************************************************************************/ +/* Definition of various integer sizes. These types are used by ttcalc */ +/* and ttinterp (for the 64-bit integers) only.. */ + +#if SIZEOF_INT == 4 + + typedef signed int TT_Int32; + typedef unsigned int TT_Word32; + +#elif SIZEOF_LONG == 4 + + typedef signed long TT_Int32; + typedef unsigned long TT_Word32; + +#else +#error "no 32bit type found" +#endif + +#if SIZEOF_LONG == 8 + +/* LONG64 must be defined when a 64-bit type is available */ +/* INT64 must then be defined to this type.. */ +#define LONG64 +#define INT64 long + +#else + +/* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */ +/* by defining the TT_USE_LONG_LONG macro in 'ft_conf.h'. Note that this */ +/* will produce many -ansi warnings during library compilation. */ +#ifdef TT_USE_LONG_LONG + +#define LONG64 +#define INT64 long long + +#endif /* TT_USE_LONG_LONG */ +#endif + +#endif /* FT_CONF_H */ + + +/* END */ diff --git a/lib/arch/debugger/Makefile b/lib/arch/debugger/Makefile new file mode 100644 index 0000000..6da004b --- /dev/null +++ b/lib/arch/debugger/Makefile @@ -0,0 +1,96 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for emx-gcc under OS/2 or under +# Unix with extra debugging capabilities. +# +# You will need GNU make. +# +# Use this file while in the lib directory with the following statement: +# +# make -f arch/debugger/Makefile + +ARCH = arch/debugger +FT_MAKEFILE = $(ARCH)/Makefile + +CC = gcc + +#CFLAGS = -W -Wall -O0 -g -ansi -pedantic -I$(ARCH) -I. -Iextend + +CFLAGS = -Wall -O0 -g -ansi -I$(ARCH) -I. -Iextend + +#CFLAGS = -Wall -ansi -pedantic -O2 -s -I$(ARCH) -I. -Iextend + +# Detect OS/2 to add the flag -DOS2 when compiling ttinterp.c +# +ifdef OS2_SHELL +OS := OS2 +RM := del +else +OS := UNIX # Unix build otherwise +RM := rm -f +endif + +TTFILE = ./ttfile.c +TTMEMORY = ./ttmemory.c +TTMUTEX = ./ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +SRC_X = extend/ftxgasp.c extend/ftxkern.c extend/ftxpost.c \ + extend/ftxcmap.c extend/ftxwidth.c extend/ftxsbit.c \ + extend/ftxgsub.c extend/ftxgpos.c extend/ftxopen.c \ + extend/ftxgdef.c +OBJS_X = $(SRC_X:.c=.o) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c \ + ttgload.c ttinterp.c ttload.c ttobjs.c \ + ttraster.c ttextend.c $(PORT) +OBJS_M = $(SRC_M:.c=.o) $(OBJS_X) + +SRC_S = $(ARCH)/freetype.c +OBJ_S = $(SRC_S:.c=.o) +OBJS_S = $(OBJ_S) $(OBJS_X) + +# We place the library file in the ARCH directory, so that it doesn't +# interfere with the normal build. +# +LIBTTF_A = $(ARCH)/libttf.a + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< -D$(OS) + +.PHONY: all debug clean distclean depend + + +all: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_S $(LIBTTF_A) + +debug: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_M $(LIBTTF_A) + +$(OBJ_S): $(SRC_S) $(SRC_M) + +$(LIBTTF_A): $($(LIB_FILES)) + -$(RM) $@ + ar src $@ $^ + +clean: +ifdef OS2_SHELL + -$(RM) $(subst /,\,$(LIBTTF_A)) + -$(RM) $(subst /,\,$(OBJS_S)) +else + -$(RM) $(LIBTTF_A) + -$(RM) $(OBJS_S) +endif + +distclean: clean + -$(RM) dep.end + +depend: $(SRC_S) $(SRC_M) $(SRC_X) + $(CC) $(CFLAGS) -E -M $^ > dep.end + +ifeq (dep.end,$(wildcard dep.end)) + include dep.end +endif + +# end of Makefile diff --git a/lib/arch/debugger/freetype.c b/lib/arch/debugger/freetype.c new file mode 100644 index 0000000..b431cdf --- /dev/null +++ b/lib/arch/debugger/freetype.c @@ -0,0 +1,32 @@ +/* This file is part of the FreeType project */ + +/* Single file library component for the debugging target */ +#define TT_MAKE_OPTION_SINGLE_OBJECT + +/* first include common core components */ + +#include "ttapi.c" +#include "ttcache.c" +#include "ttcalc.c" +#include "ttcmap.c" +#include "ttdebug.c" +#include "ttgload.c" +#include "ttinterp.c" +#include "ttload.c" +#include "ttobjs.c" +#include "ttraster.c" + +/* then system-specific (or ANSI) components */ + +#include "ttfile.c" +#include "ttmemory.c" +#include "ttmutex.c" + +/* the extensions are compiled separately, but we need to */ +/* include the file ttextend.c if we want to support them */ + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE +#include "ttextend.c" +#endif + +/* END */ diff --git a/lib/arch/debugger/ft_conf.h b/lib/arch/debugger/ft_conf.h new file mode 100644 index 0000000..061b378 --- /dev/null +++ b/lib/arch/debugger/ft_conf.h @@ -0,0 +1,236 @@ +/* This file is part of the FreeType project */ + +/* ft_conf.h for a debugging build */ + + +/* we need the following because there are some typedefs in this file */ + +#ifndef FT_CONF_H +#define FT_CONF_H + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H + +/* Define if you have the getpagesize function. */ +#undef HAVE_GETPAGESIZE + +/* Define if you have the memcpy function. */ +#define HAVE_MEMCPY + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE + +/* Define if you have the valloc function. */ +#undef HAVE_VALLOC + +/* Define if you have the header file. Unix-specific */ +#undef HAVE_FCNTL_H + +/* command.com can't pipe stderr into a file; any message would be */ +/* written into the graphics screen. */ +#define HAVE_PRINT_FUNCTION 1 + +#define Print( format, ap ) vfprintf( stdout, (format), (ap) ) + + +/* The number of bytes in a int. We use the ANSI header file limits.h */ +/* for determining it since there is no easy way to guess. */ +/* */ +#include +#if UINT_MAX == 0xFFFF +#define SIZEOF_INT 2 +#elif UINT_MAX == 0xFFFFFFFF +#define SIZEOF_INT 4 +#else +#error "Unsupported number of bytes in `int' type!" +#endif + +/* We now try to guess the size of longs in the same way */ +/* */ +#if ULONG_MAX == 0xFFFFFFFF +#define SIZEOF_LONG 4 +#elif ULONG_MAX == 0xFFFFFFFFFFFFFFFF +#define SIZEOF_LONG 8 +#else +#error "Unsupported number of bytes in `long' type!" +#endif + + +/**********************************************************************/ +/* */ +/* The following configuration macros can be tweaked manually by */ +/* a developer to turn on or off certain features or options in the */ +/* TrueType engine. This may be useful to tune it for specific */ +/* purposes.. */ +/* */ +/**********************************************************************/ + + +/*************************************************************************/ +/* Define this if the underlying operating system uses a different */ +/* character width than 8bit for file names. You must then also supply */ +/* a typedef declaration for defining 'TT_Text'. Default is off. */ + +/* #define HAVE_TT_TEXT */ + + +/*************************************************************************/ +/* Define this if you want to generate code to support engine extensions */ +/* Default is on, but if you're satisfied by the basic services provided */ +/* by the engine and need no extensions, undefine this configuration */ +/* macro to save a few more bytes. */ + +#define TT_CONFIG_OPTION_EXTEND_ENGINE + + +/*************************************************************************/ +/* Define this if you want to generate code to support gray-scaling, */ +/* a.k.a. font-smoothing or anti-aliasing. Default is on, but you can */ +/* disable it if you don't need it. */ + +#define TT_CONFIG_OPTION_GRAY_SCALING + + +/*************************************************************************/ +/* Define this if you want to completely disable the use of the bytecode */ +/* interpreter. Doing so will produce a much smaller library, but the */ +/* quality of the rendered glyphs will enormously suffer from this. */ +/* */ +/* This switch was introduced due to the Apple patents issue which */ +/* emerged recently on the FreeType lists. We still do not have Apple's */ +/* opinion on the subject and will change this as soon as we have. */ + +#undef TT_CONFIG_OPTION_NO_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to use a big 'switch' statement within the */ +/* bytecode interpreter. Because some non-optimizing compilers are not */ +/* able to produce jump tables from such statements, undefining this */ +/* configuration macro will generate the appropriate C jump table in */ +/* ttinterp.c. If you use an optimizing compiler, you should leave it */ +/* defined for better performance and code compactness.. */ +/* */ +/* For debugging, we use a jump table; this allows some interesting */ +/* things during development. */ + +#undef TT_CONFIG_OPTION_INTERPRETER_SWITCH + + +/*************************************************************************/ +/* Define this if you want to build a `static' version of the TrueType */ +/* bytecode interpreter. This will produce much bigger code, which */ +/* _may_ be faster on some architectures. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine. */ +/* */ +/* We use a static interpreter in the debugger; this helps in setting */ +/* data breakpoints to fixed memory addresses. */ + +#define TT_CONFIG_OPTION_STATIC_INTERPRETER + +/* an extra for the debugger */ +#define DEBUG_INTERPRETER + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the scan-line */ +/* converter (the component which in charge of converting outlines into */ +/* bitmaps). This will produce a bigger object file for "ttraster.c", */ +/* which _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ + +#define TT_CONFIG_OPTION_STATIC_RASTER + + +/*************************************************************************/ +/* Define TT_CONFIG_THREAD_SAFE if you want to build a thread-safe */ +/* version of the library. */ + +#undef TT_CONFIG_OPTION_THREAD_SAFE + + +/**********************************************************************/ +/* */ +/* The following macros are used to define the debug level, as well */ +/* as individual tracing levels for each component. There are */ +/* currently three modes of operation : */ +/* */ +/* - trace mode (define DEBUG_LEVEL_TRACE) */ +/* */ +/* The engine prints all error messages, as well as tracing */ +/* ones, filtered by each component's level */ +/* */ +/* - debug mode (define DEBUG_LEVEL_ERROR) */ +/* */ +/* Disable tracing, but keeps error output and assertion */ +/* checks. */ +/* */ +/* - release mode (don't define anything) */ +/* */ +/* Don't include error-checking or tracing code in the */ +/* engine's code. Ideal for releases. */ +/* */ +/* NOTE : */ +/* */ +/* Each component's tracing level is defined in its own source. */ +/* */ +/**********************************************************************/ + +/* Define if you want to use the tracing debug mode. */ +/* Set to DEBUG_LEVEL_TRACE for the debugger. */ +#define DEBUG_LEVEL_TRACE + +/* Define if you want to use the error debug mode - ignored if */ +/* DEBUG_LEVEL_TRACE is defined */ +#undef DEBUG_LEVEL_ERROR + + +/**************************************************************************/ +/* Definition of various integer sizes. These types are used by ttcalc */ +/* and ttinterp (for the 64-bit integers) only.. */ + +#if SIZEOF_INT == 4 + + typedef signed int TT_Int32; + typedef unsigned int TT_Word32; + +#elif SIZEOF_LONG == 4 + + typedef signed long TT_Int32; + typedef unsigned long TT_Word32; + +#else +#error "no 32bit type found" +#endif + +#if SIZEOF_LONG == 8 + +/* LONG64 must be defined when a 64-bit type is available */ +/* INT64 must then be defined to this type.. */ +#define LONG64 +#define INT64 long + +#else + +/* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */ +/* by defining the TT_USE_LONG_LONG macro in 'ft_conf.h'. Note that this */ +/* will produce many -ansi warnings during library compilation. */ +#ifdef TT_USE_LONG_LONG + +#define LONG64 +#define INT64 long long + +#endif /* TT_USE_LONG_LONG */ +#endif + +#endif /* FT_CONF_H */ + + +/* END */ diff --git a/lib/arch/mac/README b/lib/arch/mac/README new file mode 100644 index 0000000..8033486 --- /dev/null +++ b/lib/arch/mac/README @@ -0,0 +1,47 @@ + +This is the readme of the freetype.hqx archive in the contrib/mac +subdirectory. Please note that the FreeType team does *not* support the +Macintosh platform due to lack of knowledge. All questions regarding the +code should be sent to both David Williss and the freetype-devel list. + + +---------------------------------------------------------------------------- + + +These are CodeWarrior projects for building the FreeType library on a Macintosh +I've only provided PPC projects here, but building for 68K shouldn't be hard. +There are two directories here (OK, "folders"). One contains a project for +building freetype.ppc.lib and the other is for freetype.ppc.dll. (I havn't +actually tested the DLL yet.) + +The Macintosh stores TrueType fonts in a "Fonts" folder under the "System" +folder. There is a standard MacOS API for finding this folder, so I use it. +However, the fonts aren't normal flat files. They have all the data in +resources in the resource fork. Each font is an 'sfnt' resource, and each +file can have more than one 'sfnt' resource. + +To get at them, I made a copy of ttmmap.c from the Unix implementation and +modified it to load/release the resource and lock/unlock the handle as needed. +This only required a change to the open and close functions. After that, it +works just as if it was using Unix memory mapping. + +One thing however. Because of the bizarre scheme for storing the fonts, I +made up a way of specifying the font filename. + + fonts:/fontfile/fontname + +Where fonts:/ is a literal string that means "the fonts folder", fontfile is +the name of the actual file and fontname is the name of the 'sfnt' resource. +Currently, this is the only thing it understands. It might be nice if some +day (2.0 maybe?) ttfile.c and ttmmap.c wern't mutialy exclusive and it could +decide which method to use based on the filename or something. + +Another thing that I had to change to make this work. It seems that Macintosh +TrueType fonts have no OS/2 table, so ttload.c needs to be modified to make +that nonfatal, at least on a Macintosh. + +--- + +David Williss +MicroImages, Inc. +dwilliss@microimages.com diff --git a/lib/arch/mac/freetype.c b/lib/arch/mac/freetype.c new file mode 100644 index 0000000..5db4438 --- /dev/null +++ b/lib/arch/mac/freetype.c @@ -0,0 +1,48 @@ +/* This file is *not* part of the FreeType project, because the team */ +/* lacks the necessary expertise to support it. */ + +/* freetype.c for MacOS */ +/* single object library component for MacOS */ + +/* Written by Dave Willis on 1998-07-30. */ +/* Modified by Antoine Leca for the 1.3 release, but untested. */ + +#define TT_MAKE_OPTION_SINGLE_OBJECT + +/* Note, you should define the EXPORT_DEF and EXPORT_FUNC macros here */ +/* if you want to build a DLL. If undefined, the macros are defined */ +/* as "export" and "" (i.e. nothing), which is the normal behaviour. */ +/* The macros are placed before each high-level API function */ +/* declaration. You can then use them to take any compiler-specific */ +/* pragma for DLL-exported symbols. See 'ttconfig.h' for details. */ + + +/* first include common core components */ + +#define MAC_MAIN_OBJECT +#include "ttapi.c" +#include "ttcache.c" +#include "ttcalc.c" +#include "ttcmap.c" +#include "ttdebug.c" +#include "ttgload.c" +#include "ttinterp.c" +#include "ttload.c" +#include "ttobjs.c" +#include "ttobjs.c" +#include "ttraster.c" + +/* then system-specific (or ANSI) components */ + +#include "ttmmap.c" /* Was "ttfile.c" */ +#include "ttmemory.c" +#include "ttmutex.c" + +/* finally, add some extensions */ + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE +#include "ttextend.c" +#endif + + +/* END */ diff --git a/lib/arch/mac/ft_conf.h b/lib/arch/mac/ft_conf.h new file mode 100644 index 0000000..4043ae5 --- /dev/null +++ b/lib/arch/mac/ft_conf.h @@ -0,0 +1,211 @@ +/* This file is *not* part of the FreeType project, because the team */ +/* lacks the necessary expertise to support it. */ + +/* ft_conf.h for MacOS */ + +/* Written by Dave Willis on 1998-07-30. */ +/* Modified by Antoine Leca for the 1.3 release, but untested. */ + + +/* we need the following because there are some typedefs in this file */ + +#ifndef FT_CONF_H +#define FT_CONF_H + +/* Define to empty if the 'const' keyword does not work. */ +/* #undef const */ + +/* Define if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H + +/* Define if you have the getpagesize function. */ +#undef HAVE_GETPAGESIZE + +/* Define if you have the memcpy function. */ +#define HAVE_MEMCPY + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE + +/* Define if you have the valloc function. */ +#undef HAVE_VALLOC + +/* Define if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + +/* The number of bytes in a int. */ +#define SIZEOF_INT 4 + +/* The number of bytes in a long. */ +#define SIZEOF_LONG 4 + +/**********************************************************************/ +/* */ +/* The following configuration macros can be tweaked manually by */ +/* a developer to turn on or off certain features or options in the */ +/* TrueType engine. This may be useful to tune it for specific */ +/* purposes.. */ +/* */ +/**********************************************************************/ + + +/*************************************************************************/ +/* Define this if the underlying operating system uses a different */ +/* character width than 8bit for file names. You must then also supply */ +/* a typedef declaration for defining 'TT_Text'. Default is off. */ + +/* #define HAVE_TT_TEXT */ + + +/*************************************************************************/ +/* Define this if you want to generate code to support engine extensions */ +/* Default is on, but if you're satisfied by the basic services provided */ +/* by the engine and need no extensions, undefine this configuration */ +/* macro to save a few more bytes. */ + +#define TT_CONFIG_OPTION_EXTEND_ENGINE + + +/*************************************************************************/ +/* Define this if you want to generate code to support gray-scaling, */ +/* a.k.a. font-smoothing or anti-aliasing. Default is on, but you can */ +/* disable it if you don't need it. */ + +#define TT_CONFIG_OPTION_GRAY_SCALING + + +/*************************************************************************/ +/* Define this if you want to completely disable the use of the bytecode */ +/* interpreter. Doing so will produce a much smaller library, but the */ +/* quality of the rendered glyphs will enormously suffer from this. */ +/* */ +/* This switch was introduced due to the Apple patents issue which */ +/* emerged recently on the FreeType lists. We still do not have Apple's */ +/* opinion on the subject and will change this as soon as we have. */ + +#undef TT_CONFIG_OPTION_NO_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to use a big 'switch' statement within the */ +/* bytecode interpreter. Because some non-optimizing compilers are not */ +/* able to produce jump tables from such statements, undefining this */ +/* configuration macro will generate the appropriate C jump table in */ +/* ttinterp.c. If you use an optimizing compiler, you should leave it */ +/* defined for better performance and code compactness.. */ + +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the TrueType */ +/* bytecode interpreter. This will produce much bigger code, which */ +/* _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the scan-line */ +/* converter (the component which in charge of converting outlines into */ +/* bitmaps). This will produce a bigger object file for "ttraster.c", */ +/* which _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_RASTER + + + +/*************************************************************************/ +/* Define TT_CONFIG_THREAD_SAFE if you want to build a thread-safe */ +/* version of the library. */ + +#undef TT_CONFIG_OPTION_THREAD_SAFE + + +/**********************************************************************/ +/* */ +/* The following macros are used to define the debug level, as well */ +/* as individual tracing levels for each component. There are */ +/* currently three modes of operation : */ +/* */ +/* - trace mode (define DEBUG_LEVEL_TRACE) */ +/* */ +/* The engine prints all error messages, as well as tracing */ +/* ones, filtered by each component's level */ +/* */ +/* - debug mode (define DEBUG_LEVEL_ERROR) */ +/* */ +/* Disable tracing, but keeps error output and assertion */ +/* checks. */ +/* */ +/* - release mode (don't define anything) */ +/* */ +/* Don't include error-checking or tracing code in the */ +/* engine's code. Ideal for releases. */ +/* */ +/* NOTE : */ +/* */ +/* Each component's tracing level is defined in its own source. */ +/* */ +/**********************************************************************/ + +/* Define if you want to use the tracing debug mode */ +#undef DEBUG_LEVEL_TRACE + +/* Define if you want to use the error debug mode - ignored if */ +/* DEBUG_LEVEL_TRACE is defined */ +#undef DEBUG_LEVEL_ERROR + + +/**************************************************************************/ +/* Definition of various integer sizes. These types are used by ttcalc */ +/* and ttinterp (for the 64-bit integers) only.. */ + +#if SIZEOF_INT == 4 + + typedef signed int TT_Int32; + typedef unsigned int TT_Word32; + +#elif SIZEOF_LONG == 4 + + typedef signed long TT_Int32; + typedef unsigned long TT_Word32; + +#else +#error "no 32bit type found" +#endif + +#if SIZEOF_LONG == 8 + +/* LONG64 must be defined when a 64-bit type is available */ +/* INT64 must then be defined to this type.. */ +#define LONG64 +#define INT64 long + +#else + +/* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */ +/* by defining the TT_USE_LONG_LONG macro in 'ft_conf.h'. Note that this */ +/* will produce many -ansi warnings during library compilation. */ +#ifdef TT_USE_LONG_LONG + +#define LONG64 +#define INT64 long long + +#endif /* TT_USE_LONG_LONG */ +#endif + +#endif /* FT_CONF_H */ + + +/* END */ diff --git a/lib/arch/mac/ttmmap.c b/lib/arch/mac/ttmmap.c new file mode 100644 index 0000000..3a7a917 --- /dev/null +++ b/lib/arch/mac/ttmmap.c @@ -0,0 +1,1069 @@ +/******************************************************************* + * + * ttmmap.c 2.0 + * + * Memory-Mapped file component ( replaces ttfile.c ). + * + * Copyright 1996-1998 by + * David Turner, Robert Wilhelm, and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * Changes between 2.0 and 1.3 : + * + * - adopted new design/separation introduced in ttfile.c 2.0 + * + ******************************************************************/ + +#include "ttconfig.h" + +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + + +#ifdef HAVE_FCNTL_H +#include +#endif + +#include +#include + + +#include "freetype.h" +#include "tttypes.h" +#include "ttdebug.h" +#include "ttengine.h" +#include "ttmutex.h" +#include "ttmemory.h" +#include "ttfile.h" /* our prototypes */ + + /* This definition is mandatory for each file component! */ + EXPORT_FUNC + const TFileFrame TT_Null_FileFrame = { NULL, 0, 0 }; + + /* It has proven useful to do some bounds checks during */ + /* development phase. Define DEBUG_FILE when compiling */ + /* this component to enable them. */ + +#ifdef DEBUG_FILE +#define CHECK_FRAME( frame, n ) \ + do { \ + if ( frame.cursor+n > frame.address + frame.size ) \ + Panic( "Frame boundary error!\n" ); \ + } while ( 0 ) +#else +#define CHECK_FRAME( frame, n ) \ + do { \ + } while( 0 ) +#endif + + struct _TFileMap + { + String* base; /* base address of mapped file */ + Int refcount; /* reference count for handle region */ + Long size; /* stream size in file */ + Long offset; /* offset in file */ + Handle handle; /* Macintosh style handle to lock/unlock */ + short resid; /* Id of resource file to close when done */ + }; + + typedef struct _TFileMap TFileMap; + +#define MAP_Address( map ) (Byte*)( (map)->base + (map)->offset ) + + /* The stream record structure */ + typedef struct _TStream_Rec + { + TFileMap* map; /* mapped file description */ + Long pos ; /* cursor in mapped file */ + } TStream_Rec; + + typedef TStream_Rec* PStream_Rec; + +#define STREAM2REC( x ) ( (TStream_Rec*)HANDLE_Val( x ) ) + + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + /**** ****/ + /**** N O N R E E N T R A N T I M P L E M E N T A T I O N ****/ + /**** ****/ + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + + /* The TFile_Component structure holds all the data that was */ + /* previously declared static or global in this component. */ + /* */ + /* It is accessible through the 'engine.file_component' */ + /* variable in re-entrant builds, or directly through the */ + /* static 'files' variable in other builds. */ + + struct _TFile_Component + { + TMutex lock; /* used by the thread-safe build only */ + PStream_Rec stream; /* current stream */ + TFileFrame frame; /* current frame */ + }; + + typedef struct _TFile_Component TFile_Component; + +/* The macro CUR_Stream denotes the current input stream */ +/* Note that for the re-entrant version, the 'stream' name has been */ +/* chosen according to the macro STREAM_ARGS. */ + +/* The macro CUR_Frame denotes the current file frame */ +/* Note that for the re-entrant version, the 'frame' name has been */ +/* chosen according to the macro FRAME_ARGS. */ + +/* The macro STREAM_VAR is used when calling public functions */ +/* that need an 'optional' stream argument. */ + +#define CUR_Stream files.stream /* thread-safe macros */ +#define CUR_Frame files.frame + +#define STREAM_VARS /* void */ +#define STREAM_VAR /* void */ + + /* the 'files' variable is only defined in non-reentrant builds */ + + static TFile_Component files; + + + +/******************************************************************* + * + * Function : TTFile_Init + * + * Description : Initializes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Init( PEngine_Instance engine ) + { + MUTEX_Create( files.lock ); + files.stream = NULL; + ZERO_Frame( files.frame ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTFile_Done + * + * Description : Finalizes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Done( PEngine_Instance engine ) + { + MUTEX_Destroy( files.lock ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Use_Stream + * + * Description : Copies or duplicates a given stream. + * + * Input : org_stream original stream + * stream target stream (copy or duplicate) + * + * Output : Error code + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Use_Stream( TT_Stream org_stream, + TT_Stream* stream ) + { + MUTEX_Lock( files.lock ); + *stream = org_stream; + files.stream = STREAM2REC( org_stream ); /* set current stream */ + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Done_Stream + * + * Description : Releases a given stream. + * + * Input : stream + * + * Output : Error code + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Done_Stream( TT_Stream* stream ) + { + HANDLE_Set( *stream, NULL ); + MUTEX_Release( files.lock ); + + return TT_Err_Ok; + } + +#else /* TT_CONFIG_OPTION_THREAD_SAFE */ + + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + /******** ********/ + /******** R E E N T R A N T I M P L E M E N T A T I O N ********/ + /******** ********/ + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + +#define CUR_Stream STREAM2REC( stream ) /* re-entrant macros */ +#define CUR_Frame (*frame) + +#define STREAM_VARS stream, +#define STREAM_VAR stream + + +/******************************************************************* + * + * Function : TTFile_Init + * + * Description : Initializes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Init( PEngine_Instance engine ) + { + engine.file_component = NULL; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTFile_Done + * + * Description : Finalizes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Done( PEngine_Instance engine ) + { + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Use_Stream + * + * Description : Copies or duplicates a given stream. + * + * Input : org_stream original stream + * stream target stream (copy or duplicate) + * + * Output : Error code. The output stream is set to NULL in + * case of Failure. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Use_Stream( TT_Stream input_stream, + TT_Stream* copy ) + { + TT_Error error; + PStream_Rec stream_rec; + PStream_Rec copy_rec; + + + stream_rec = STREAM2REC( input_stream ); + + if ( ALLOC( copy_rec, sizeof ( TStream_Rec ) ) ) + goto Fail; + + HANDLE_Set( *copy, copy_rec ); + + copy_rec->map->refcount++; + copy_rec->pos = 0; + + return TT_Err_Ok; + + Fail: + HANDLE_Set( *copy, NULL ); + return error; + } + + +/******************************************************************* + * + * Function : TT_Done_Stream + * + * Description : Releases a given stream. + * + * Input : stream + * + * Output : error code + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Done_Stream( TT_Stream* stream ) + { + return TT_Close_Stream( stream ); + } + +#endif /* TT_CONFIG_OPTION_THREAD_SAFE */ + + + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + /*********** ***********/ + /*********** C O M M O N I M P L E M E N T A T I O N ***********/ + /*********** ***********/ + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + +/******************************************************************* + * + * Function : AllocateMap + * + * Description : Allocates a new map from the table. + * + * Output : Pointer to new stream rec. NULL in case of failure. + * + ******************************************************************/ + + static + TFileMap* Allocate_Map( void ) + { + TFileMap* result; + + + if ( MEM_Alloc( result, sizeof ( TFileMap ) ) ) + return NULL; + + result->refcount = 1; + return result; + } + + +/******************************************************************* + * + * Function : ReleaseMap + * + * Description : Releases a used map to the table if reference i + * counter reaches zero. + * + * Input : map + * + * Output : None. + * + * Note : Called by TT_Close_File() + * + ******************************************************************/ + + static + void Release_Map ( TFileMap* map ) + { + map->refcount--; + if ( map->refcount <= 0 ) + { + /* MacOS System calls */ + HUnlock(map->handle); + ReleaseResource(map->handle); + CloseResFile(map->resid); + + FREE( map ); + } + } + + +/* Whadda ya mean "strdup undefined"? Fine, I'll define my own! */ +static char *mystrdup(const char *str) { + char *ret; + + if ( TT_Alloc(strlen(str) + 1, (void**)&ret) != 0 ) return(NULL); + strcpy(ret, str); + return(ret); + } + +/******************************************************************* + * + * Function : TT_Open_Stream + * + * Description : Opens the font file and saves the total file size. + * + * Input : error address of stream's error variable + * (re-entrant build only). + * filepathname pathname of the file to open + * stream address of target TT_Stream structure + * + * Output : SUCCESS on success, FAILURE on error. + * The target stream is set to -1 in case of failure. + * + ******************************************************************/ +/* +** This is not a totally generic implementation. It currently assumes the filename +** starts with "fonts:" and uses slashes instead of colons like Mac code normally +** would. Given a filename of the form "fonts:/filename/resname", Load the resource +** and lock the handle +** +** The "fonts:" at the beginning is just a convention I came up with to +** indicate the Fonts folder inside the current System folder (find via FindFolder()) +*/ + + LOCAL_FUNC + TT_Error TT_Open_Stream( const String* filepathname, + TT_Stream* stream ) + { + TT_Error error; + Int file; + PStream_Rec stream_rec; + TFileMap* map; + + int size, err = 0; + short vRefNum, res = -1; + Str255 FontName; + char *cp, *p, *fname, *sep; + Str63 myName; + long dirID; + + + if ( ALLOC( *stream, sizeof ( TStream_Rec ) ) ) + return error; + + map = Allocate_Map(); + if ( !map ) + { + error = TT_Err_Out_Of_Memory; + goto Memory_Fail; + } + + stream_rec = STREAM2REC( *stream ); + + /* Find the dirID of the Fonts folder in the current System folder */ + if (FindFolder(kOnSystemDisk, kFontsFolderType, kDontCreateFolder, &vRefNum, &dirID)) + goto File_Fail; + + /* Break the name apart */ + fname = mystrdup(filepathname); /* Make a copy so we can muck with it */ + sep = ":/"; /* Things that can seperate file path componants */ + + strtok(fname, sep); /* Skip over "fonts:" */ + + if ((p = strtok(NULL, sep)) == NULL) /* Get filename */ + goto File_Fail; + strcpy(myName + 1, p); /* Make this a Pascal string (Yuck!) */ + myName[0] = strlen(p); + + if ((p = strtok(NULL, sep)) == NULL) /* Get res name */ + goto File_Fail; + strcpy(FontName+1, p); /* Make this a Pascal string (Yuck!) */ + FontName[0] = strlen(p); + + FREE( fname ); + + if ((cp = strchr(FontName, '.')) != NULL) /* Strip off ".ttf" , if any */ + *cp = 0; + + /* Read the font into a buffer */ + if ((map->resid = HOpenResFile(vRefNum, dirID, myName, fsRdPerm)) == -1) + goto File_Fail; + + if ((map->handle = Get1NamedResource('sfnt', FontName)) == NULL) + goto Map_Fail; + + HLock(map->handle); + map->base = *map->handle; + map->offset = 0; + map->size = GetResourceSizeOnDisk(map->handle); + + if ( map->base == NULL ) + goto Lock_Fail; + + stream_rec->map = map; + stream_rec->pos = 0; + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + CUR_Stream = stream_rec; +#endif + + return TT_Err_Ok; + + Lock_Fail: + ReleaseResource(map->handle); + + Map_Fail: + CloseResFile(map->resid); + + File_Fail: + error = TT_Err_Could_Not_Open_File; + FREE( map ); + + Memory_Fail: + FREE( *stream ); + FREE( fname ); + return error; + } + + +/******************************************************************* + * + * Function : TT_Close_Stream + * + * Description : Closes a stream. + * + * Input : stream + * + * Output : SUCCESS (always) + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TT_Close_Stream( TT_Stream* stream ) + { + PStream_Rec rec = STREAM2REC( *stream ); + + + Release_Map( rec->map ); + FREE( rec ); + + HANDLE_Set( *stream, NULL ); + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Flush_Stream + * + * Description : Flushes a stream, i.e., closes its file handle. + * + * Input : stream address of target TT_Stream structure + * + * Output : Error code + * + * NOTE : Never flush the current opened stream. This means that + * you should _never_ call this function between a + * TT_Use_Stream() and a TT_Done_Stream()! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Flush_Stream( TT_Stream* stream ) + { + /* XXX - DUMMY IMPLEMENTATION */ + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Stream_Size + * + * Description : Returns the length of a given stream, even if it + * is flushed. + * + * Input : stream the stream + * + * Output : Length of stream in bytes. + * + ******************************************************************/ + + EXPORT_FUNC + Long TT_Stream_Size( TT_Stream stream ) + { + PStream_Rec rec = STREAM2REC( stream ); + + + if ( rec ) + return rec->map->size; + else + return 0; /* invalid stream - return 0 */ + } + + +/******************************************************************* + * + * Function : TT_Seek_File + * + * Description : Seeks the file cursor to a different position. + * + * Input : position new position in file + * + * Output : SUCCESS on success. FAILURE if out of range. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Seek_File( STREAM_ARGS Long position ) + { + if ( position > CUR_Stream->map->size ) + return TT_Err_Invalid_File_Offset; + + CUR_Stream->pos = position; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Skip_File + * + * Description : Skips forward the file cursor. + * + * Input : distance number of bytes to skip + * + * Output : see TT_Seek_File + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Skip_File( STREAM_ARGS Long distance ) + { + return TT_Seek_File( STREAM_VARS CUR_Stream->pos + distance ); + } + + +/******************************************************************* + * + * Function : TT_Read_File + * + * Description : Reads a chunk of the file and copies it to memory. + * + * Input : buffer target buffer + * count length in bytes to read + * + * Output : SUCCESS on success. FAILURE if out of range. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Read_File( STREAM_ARGS void* buffer, Long count ) + { + if ( CUR_Stream->pos + count > CUR_Stream->map->size ) + return TT_Err_Invalid_File_Read; + + MEM_Copy( buffer, + MAP_Address( CUR_Stream->map ) + CUR_Stream->pos, count ); + CUR_Stream->pos += count; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Read_At_File + * + * Description : Reads file at a specified position. + * + * Input : position position to seek to before read + * buffer target buffer + * count number of bytes to read + * + * Output : SUCCESS on success. FAILURE if error. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Read_At_File( STREAM_ARGS Long position, + void* buffer, + Long count ) + { + TT_Error error; + + + if ( (error = TT_Seek_File( STREAM_VARS position )) || + (error = TT_Read_File( STREAM_VARS buffer, count )) ) + return error; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_File_Pos + * + * Description : Returns current file seek pointer. + * + * Input : none + * + * Output : current file position + * + ******************************************************************/ + + EXPORT_FUNC + Long TT_File_Pos( STREAM_ARG ) + { + return CUR_Stream->pos; + } + + +/******************************************************************* + * + * Function : TT_Access_Frame + * + * Description : Notifies the component that we're going to read + * 'size' bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx() + * functions easily. + * + * Input : size number of bytes to access. + * + * Output : Error code + * + * Notes: The function fails if the byte range is not within the + * the file, or if there is not enough memory to cache + * the bytes properly (which usually means that aSize is + * too big in both cases). + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Access_Frame( STREAM_ARGS FRAME_ARGS Long size ) + { + if ( CUR_Frame.address != NULL ) + return TT_Err_Nested_Frame_Access; + + if ( CUR_Stream->pos + size > CUR_Stream->map->size ) + return TT_Err_Invalid_Frame_Access; + + CUR_Frame.size = size; + CUR_Frame.address = MAP_Address( CUR_Stream->map ) + CUR_Stream->pos; + CUR_Frame.cursor = CUR_Frame.address; + + CUR_Stream->pos += size; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Check_And_Access_Frame + * + * Description : Notifies the component that we're going to read + * 'size' bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx() + * functions easily. + * + * Input : size number of bytes to access. + * + * Output : Error code + * + * Notes: The function truncates 'size' if the byte range is not + * within the file. + * + * It will fail if there is not enough memory to cache + * the bytes properly (which usually means that aSize is + * too big). + * + * It will fail if you make two consecutive calls + * to TT_Access_Frame(), without a TT_Forget_Frame() between + * them. + * + * The only difference with TT_Access_Frame() is that we + * check that the frame is within the current file. We + * otherwise truncate it. The 'overflow' is set to zero. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Check_And_Access_Frame( STREAM_ARGS FRAME_ARGS Long size ) + { + TT_Error error; + Long readBytes; + + + if ( CUR_Frame.address != NULL ) + return TT_Err_Nested_Frame_Access; + + readBytes = CUR_Stream->map->size - CUR_Stream->pos; + if ( size > readBytes ) + { + /* There is overflow, we allocate a new block then */ + if ( ALLOC( CUR_Frame.address, size ) ) + return error; + + CUR_Frame.size = size; + + /* copy the valid part */ + MEM_Copy( CUR_Frame.address, + MAP_Address( CUR_Stream->map ) + CUR_Stream->pos, + readBytes ); + } + else + { + CUR_Frame.size = size; + CUR_Frame.address = MAP_Address( CUR_Stream->map ) + CUR_Stream->pos; + } + + CUR_Frame.cursor = CUR_Frame.address; + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Forget_Frame + * + * Description : Releases a cached frame after reading. + * + * Input : None + * + * Output : SUCCESS on success. FAILURE on error. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Forget_Frame( FRAME_ARG ) + { + if ( CUR_Frame.address == NULL ) + return TT_Err_Nested_Frame_Access; + + /* If we were using a duplicate in case of overflow, free it now */ + if ( CUR_Frame.address < (Byte*)CUR_Stream->map->base || + CUR_Frame.address >= (Byte*)CUR_Stream->map->base + + CUR_Stream->map->size ) + FREE( CUR_Frame.address ); + + ZERO_Frame( files.frame ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : GET_Byte + * + * Description : Extracts a byte from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted Byte + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call.) + * + ******************************************************************/ + +#if 0 + + EXPORT_FUNC + Byte TT_Get_Byte( FRAME_ARG ) + { + CHECK_FRAME( CUR_Frame, 1 ); + + return (Byte)(*CUR_Frame.cursor++); + } + +#endif + + +/******************************************************************* + * + * Function : GET_Char + * + * Description : Extracts a signed byte from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted char + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call.) + * + ******************************************************************/ + + EXPORT_FUNC + Char TT_Get_Char( FRAME_ARG ) + { + CHECK_FRAME( CUR_Frame, 1 ); + + return (Char)(*CUR_Frame.cursor++); + } + + +/******************************************************************* + * + * Function : GET_Short + * + * Description : Extracts a short from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted short + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call.) + * + ******************************************************************/ + + EXPORT_FUNC + Short TT_Get_Short( FRAME_ARG ) + { + Short getshort; + + + CHECK_FRAME( CUR_Frame, 2 ); + + getshort = ((Short)CUR_Frame.cursor[0] << 8) | + (Short)CUR_Frame.cursor[1]; + + CUR_Frame.cursor += 2; + + return getshort; + } + + +/******************************************************************* + * + * Function : GET_UShort + * + * Description : Extracts an unsigned short from the frame. + * + * Input : None or current frame + * + * Output : Extracted ushort + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call.) + * + ******************************************************************/ + +#if 0 + + EXPORT_FUNC + UShort TT_Get_UShort( FRAME_ARG ) + { + UShort getshort; + + + CHECK_FRAME( CUR_Frame, 2 ); + + getshort = ((UShort)CUR_Frame.cursor[0] << 8) | + (UShort)CUR_Frame.cursor[1]; + + CUR_Frame.cursor += 2; + + return getshort; + } + +#endif + + +/******************************************************************* + * + * Function : GET_Long + * + * Description : Extracts a long from the frame. + * + * Input : None or current frame + * + * Output : Extracted long + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call.) + * + ******************************************************************/ + + EXPORT_FUNC + Long TT_Get_Long( FRAME_ARG ) + { + Long getlong; + + + CHECK_FRAME( CUR_Frame, 4 ); + + getlong = ((Long)CUR_Frame.cursor[0] << 24) | + ((Long)CUR_Frame.cursor[1] << 16) | + ((Long)CUR_Frame.cursor[2] << 8 ) | + (Long)CUR_Frame.cursor[3]; + + CUR_Frame.cursor += 4; + + return getlong; + } + + +/******************************************************************* + * + * Function : GET_ULong + * + * Description : Extracts an unsigned long from the frame. + * + * Input : None + * + * Output : Extracted ulong + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call.) + * + ******************************************************************/ + +#if 0 + + EXPORT_FUNC + ULong TT_Get_ULong( FRAME_ARG ) + { + ULong getlong; + + + CHECK_FRAME( CUR_Frame, 4 ); + + getlong = ( ((ULong)CUR_Frame.cursor[0] << 24) | + ((ULong)CUR_Frame.cursor[1] << 16) | + ((ULong)CUR_Frame.cursor[2] << 8 ) | + (ULong)CUR_Frame.cursor[3] ); + + CUR_Frame.cursor += 4; + + return getlong; + } + +#endif + + +/* END */ diff --git a/lib/arch/msdos/Makefile.BC b/lib/arch/msdos/Makefile.BC new file mode 100644 index 0000000..ba5d50b --- /dev/null +++ b/lib/arch/msdos/Makefile.BC @@ -0,0 +1,132 @@ +# This file is part of the FreeType project. +# +# It builds the library for Borland C++ for MS-DOS, large model. +# Due to size constraints, it does not try to pack all modules into one +# (`single-object mode'). +# +# You will need Borland MAKE. +# Tested with Borland C++ v.3.1, 4.02, 5.0. +# +# Use this file while in the lib directory with the following statement: +# +# make -farch/msdos/Makefile.BC +# +# +# A debug version can be obtained with +# +# make -DDEBUG -farch/msdos/Makefile.BC +# +# A special version enabled to handle big fonts (with more than 16,384 +# glyphs) can be obtained with +# +# make -DBIGFONTS -farch/msdos/Makefile.BC + +ARCH = arch\msdos +FT_MAKEFILE = $(ARCH)\Makefile.BC + +CC = bcc +LIB = tlib /c /e + +# Credits go to Dave Hoo for pointing out that modern +# Borland compilers (from BC++ 3.1 on) can increase the limit on +# the length of identifiers. +!if ! $d(DEBUG) +CFLAGS = -ml -A -O2 -3 -i40 -w-nak -w-par -w-use -w-aus -w-stu -w-stv -w-cln -w-sig -I$(ARCH);.;extend +!else +CFLAGS = -v -N -ml -A -i40 -w-nak -w-par -w-use -w-aus -w-stu -w-stv -w-cln -w-sig -I$(ARCH);.;extend +!endif + + +!if $d(BIGFONTS) +CFLAGS = $(CFLAGS) -DTT_HUGE_PTR=__huge + +TTFILE = $(ARCH)\.\hugefile.c +TTMEMORY = $(ARCH)\.\hugemem.c +!else +TTFILE = .\ttfile.c +TTMEMORY = .\ttmemory.c +!endif +TTMUTEX = .\ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +# Do not insert spaces before the \ at end of line, +# otherwise the substitution for TLIB command line will fail. +SRC_X = extend\ftxgasp.c extend\ftxkern.c extend\ftxpost.c\ + extend\ftxcmap.c extend\ftxwidth.c extend\ftxerr18.c\ + extend\ftxsbit.c extend\ftxgsub.c extend\ftxgpos.c\ + extend\ftxopen.c extend\ftxgdef.c +OBJS_X = $(SRC_X:.c=.obj) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c\ + ttgload.c ttinterp.c ttload.c ttobjs.c\ + ttraster.c ttextend.c ttdebug.c $(PORT) +OBJS_M = $(SRC_M:.c=.obj) $(OBJS_X) + +SRC_S = $(ARCH)\.\freetype.c +OBJ_S = $(SRC_S:.c=.obj) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +# Since Borland's make does not handle $($(LIB_FILES)), and using +# -DLIB_FILES="$(OBJS_S)" will excess the capacity of COMMAND.COM, we cheat +# by constructing TLIB's response file directly in the `all' target. +# +# Another solution, useful during debugging of part of the library, +# would be to include each .obj in the library as soon as it is compiled. +# It is commented out below. See Makefile.TC for an application. +.c.obj: + $(CC) -c -o$* @&&| + $(CFLAGS) $< +| +# $(LIB) libttf +-$*.obj + + +!if !$d(DEBUG) +# Skipped if DEBUG build +# (but it changes nothing, since we always build in multiple parts). +all: $(OBJS_M) + -del libttf.lib + $(LIB) libttf.lib @&&| ++ $(OBJS_M: = + ) +| + +!endif + + +debug: $(OBJS_M) + -del libttf.lib + $(LIB) libttf.lib @&&| ++ $(OBJS_M: = + ) +| + +$(OBJ_S): $(SRC_S) $(SRC_M) + +# Not used here because it excesses the capacity of COMMAND.COM... +libttf.lib: $(LIB_FILES) + -del libttf.lib + $(LIB) libttf.lib @&&| ++ $(**: = + ) +| + +!if $d(BIGFONTS) +$(TTMEMORY:.c=.obj): $(TTMEMORY) + $(CC) -c -o$* @&&| + $(CFLAGS) -A- $*.c +| +!endif + + +clean: + -del *.obj + -del extend\*.obj + -del $(ARCH)\*.obj + -del libttf.bak + -del response + +distclean: clean + -del libttf.lib + +!include "$(ARCH)\depend.dos" + +# end of Makefile diff --git a/lib/arch/msdos/Makefile.MS b/lib/arch/msdos/Makefile.MS new file mode 100644 index 0000000..3c793fa --- /dev/null +++ b/lib/arch/msdos/Makefile.MS @@ -0,0 +1,117 @@ +# This file is part of the FreeType project. +# +# It builds the library for Microsoft C for MS-DOS, large model. +# It also works for Visual C++ 1.x 16-bits compiler, but you should +# instead use the Makefile customized for it, Makefile.VC. +# Due to size constraints, it does not try to pack all modules into one. +# +# You will need NMAKE. +# +# Use this file while in the lib directory with the following statement: +# +# nmake /f arch\msdos\Makefile.MS +# +# +# A debug version can be obtained with +# +# nmake DEBUG=1 /f arch\msdos\Makefile.MS +# +# A special version enabled to handle big fonts (with more than 16,384 +# glyphs) can be obtained with +# +# nmake BIGFONTS=1 /f arch\msdos\Makefile.MS + +ARCH = arch\msdos +FT_MAKEFILE = $(ARCH)\Makefile.MS + +CC = cl /nologo +LIB = lib /noignorecase /nologo + +!ifndef DEBUG +CFLAGS = /Ox /AL /W2 /G2 /I$(ARCH) /I. /Iextend +!else +CFLAGS = /Zi /AL /W2 /G2 /I$(ARCH) /I. /Iextend +!endif + + +!ifndef BIGFONTS +CFLAGS = $(CFLAGS) /Za + +TTFILE = .\ttfile.c +TTMEMORY = .\ttmemory.c +!else +CFLAGS = $(CFLAGS) /DTT_HUGE_PTR=__huge /Ze + +TTFILE = $(ARCH)\hugefile.c +TTMEMORY = $(ARCH)\hugemem.c +!endif + +TTMUTEX = .\ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +# Do not insert spaces between the file names or at end of line, otherwise +# the substitution for LIB command line will fail. Thank you. +# +SRC_X = extend\ftxgasp.c extend\ftxkern.c extend\ftxpost.c\ +extend\ftxcmap.c extend\ftxwidth.c extend\ftxerr18.c extend\ftxsbit.c\ +extend\ftxopen.c extend\ftxgsub.c extend\ftxgpos.c extend\ftxgdef.c +OBJS_X = $(SRC_X:.c=.obj) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c\ +ttgload.c ttinterp.c ttload.c ttobjs.c ttraster.c ttextend.c $(PORT) +OBJS_M = $(SRC_M:.c=.obj) $(OBJS_X) + +SRC_S = $(ARCH)\freetype.c +OBJ_S = $(SRC_S:.c=.obj) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +# Since Microsoft's NMAKE does not handle $($(LIB_FILES)), and using +# LIB_FILES="$(OBJS_S)" will excess the capacity of COMMAND.COM, we cheat +# by constructing LIB's response file directly in the `all' target. +# +# Another solution, useful during debugging of part of the library, +# would be to include each .obj in the library as soon as it is compiled. +# It is commented out below. See Makefile.TC for an application. +.c.obj: + @$(CC) /c /Fo$@ @<< + $(CFLAGS) $*.c +<< +# $(LIB) libttf +-$*.obj + + +!ifndef DEBUG +# Skipped if DEBUG build +# (but it changes nothing, since we always build in multiple parts). +all: $(OBJS_M) + -del libttf.lib + $(LIB) libttf.lib @<&| + +CC = gcc + +CFLAGS = -Wall -O2 -g -ansi -pedantic -I$(ARCH) -I. -Iextend +# CFLAGS = -Wall -ansi -O2 -s -I$(ARCH) -I. -Iextend + +SRC_X = extend/ftxgasp.c extend/ftxkern.c extend/ftxpost.c \ + extend/ftxcmap.c extend/ftxwidth.c extend/ftxsbit.c \ + extend/ftxgsub.c extend/ftxgpos.c extend/ftxopen.c \ + extend/ftxgdef.c extend/ftxerr18.c +OBJS_X = $(SRC_X:.c=.o) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c \ + ttfile.c ttgload.c ttinterp.c ttload.c \ + ttmemory.c ttmutex.c ttobjs.c ttraster.c ttextend.c +OBJS_M = $(SRC_M:.c=.o) $(OBJS_X) + +SRC_S = $(ARCH)/freetype.c +OBJ_S = $(SRC_S:.c=.o) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +.PHONY: all debug clean distclean depend + + +all: + $(FT_MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_S libttf.a + +debug: + $(FT_MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_M libttf.a + + +$(OBJ_S): $(SRC_S) $(SRC_M) + $(CC) $(CFLAGS) -c -o $@ $(SRC_S) + +libttf.a: $($(LIB_FILES)) + +-del $@ + ar src $@ @$(mktmp $(<:t"\n")\n) + +clean: +-[ + del *.o + del extend\*.o + del $(ARCH)\*.o +] + +distclean: clean +-[ + del dep.end + del libttf.a +] + +# depend: $(SRC_S) $(SRC_M) $(SRC_X) +# $(CC) -E -M @$(mktmp $(<:t"\n")\n) > dep.end + +# ifeq (dep.end,$(wildcard dep.end)) +# include dep.end +# endif + +# end of Makefile.dm diff --git a/lib/arch/msdos/Makefile.gcc b/lib/arch/msdos/Makefile.gcc new file mode 100644 index 0000000..3325538 --- /dev/null +++ b/lib/arch/msdos/Makefile.gcc @@ -0,0 +1,92 @@ +# This file is part of the FreeType project. +# +# It builds the library for emx-gcc or djgpp under MSDOS. +# +# You will need GNU make. +# +# Use this file while in the lib directory with the following statement: +# +# make -f arch/msdos/Makefile.gcc +# +# If you have the GNU gettext package installed with DJGPP, you can also try +# +# make -f arch/msdos/Makefile.gcc HAVE_GETTEXT + +ARCH = arch/msdos +FT_MAKEFILE = $(ARCH)/Makefile.gcc + +CC = gcc + +ifndef GETTEXT +GETTEXT=NO_GETTEXT +endif + +ifdef DEBUG +CFLAGS = -Wall -O2 -g -ansi -pedantic -I$(ARCH) -I. -Iextend -D$(GETTEXT) +else +CFLAGS = -Wall -ansi -pedantic -O2 -s -I$(ARCH) -I. -Iextend -D$(GETTEXT) +endif + + +TTFILE = ./ttfile.c +TTMEMORY = ./ttmemory.c +TTMUTEX = ./ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +SRC_X = extend/ftxgasp.c extend/ftxkern.c extend/ftxpost.c \ + extend/ftxcmap.c extend/ftxwidth.c extend/ftxsbit.c \ + extend/ftxgsub.c extend/ftxgpos.c extend/ftxgdef.c \ + extend/ftxopen.c extend/ftxerr18.c +OBJS_X = $(SRC_X:.c=.o) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c \ + ttgload.c ttinterp.c ttload.c ttobjs.c \ + ttraster.c ttextend.c $(PORT) +OBJS_M = $(SRC_M:.c=.o) $(OBJS_X) + +SRC_S = $(ARCH)/freetype.c +OBJ_S = $(SRC_S:.c=.o) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +.PHONY: all debug clean distclean depend + + +all: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_S libttf.a + +debug: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_M DEBUG=1 libttf.a + +HAVE_GETTEXT: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_S GETTEXT=HAVE_GETTEXT \ + libttf.a + +$(OBJ_S): $(SRC_S) $(SRC_M) + +libttf.a: $($(LIB_FILES)) + -del $@ + ar src $@ $^ + +clean: + -del *.o + -del extend\*.o + -del $(ARCH)\*.o + -del response + +distclean: clean + -del dep.end + -del libttf.a + +depend: $(SRS_S) $(SRC_M) $(SRC_X) + $(CC) -E -M $^ > dep.end + +ifeq (dep.end,$(wildcard dep.end)) + include dep.end +endif + +# end of Makefile.gcc diff --git a/lib/arch/msdos/Makefile.wat b/lib/arch/msdos/Makefile.wat new file mode 100644 index 0000000..e2df1e3 --- /dev/null +++ b/lib/arch/msdos/Makefile.wat @@ -0,0 +1,88 @@ +# This file is part of the FreeType project +# +# This builds the Watcom library with Watcom's wcc386 under DOS +# +# You'll need Watcom's wmake +# +# +# Invoke by "wmake -f arch\msdos\Makefile.wat" while in the "lib" directory +# +# This will build "freetype\lib\libttf.lib" +# + +ARCH = arch\msdos +FT_MAKEFILE = $(ARCH)\Makefile.wat +FT_MAKE = wmake -h + + +.EXTENSIONS: +.EXTENSIONS: .lib .obj .c .h +.obj:.;.\extend;.\$(ARCH) +.c:.;.\extend;.\$(ARCH) +.h:.;.\extend;.\$(ARCH) + +CC = wcc386 + +CCFLAGS = /otexanl+ /s /w4 /zq /d3 -I$(ARCH) -I. -Iextend + + +# FIXME: should use something like OBJ = $(SRC:.c=.obj) + +SRC_X = ftxgasp.c ftxkern.c ftxpost.c & + ftxcmap.c ftxwidth.c ftxsbit.c ftxerr18.c & + ftxgsub.c ftxgpos.c ftxopen.c ftxgdef.c +OBJS_X = ftxgasp.obj ftxkern.obj ftxpost.obj & + ftxcmap.obj ftxwidth.obj ftxsbit.obj ftxerr18.obj & + ftxgsub.obj ftxgpos.obj ftxopen.obj ftxgdef.obj + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c & + ttfile.c ttgload.c ttinterp.c & + ttload.c ttmemory.c ttmutex.c ttobjs.c ttraster.c & + ttextend.c +OBJS_M = ttapi.obj ttcache.obj ttcalc.obj ttcmap.obj ttdebug.obj & + ttfile.obj ttgload.obj ttinterp.obj & + ttload.obj ttmemory.obj ttmutex.obj ttobjs.obj ttraster.obj & + ttextend.obj $(OBJS_X) + +SRC_S = freetype.c +OBJ_S = freetype.obj +OBJS_S = $(OBJ_S) $(OBJ_X) + + +.c.obj: + $(CC) $(CCFLAGS) $[* /fo=$[*.obj + +libname = libttf +libfile = $(libname).lib +cmdfile = $(libname).lst + + +all: .symbolic + $(FT_MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_S $(libfile) + +debug: .symbolic + $(FT_MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_M $(libfile) + + +$(libfile): $($(LIB_FILES)) + wlib -q -n $(libfile) @$(cmdfile) + +# is this correct? Know nothing about wmake and the Watcom compiler... +$(OBJ_S): $(SRC_S) $(SRC_M) + $(CC) $(CCFLAGS) $(SRC_S) /fo=$(OBJ_S) + +$(cmdfile): $($(LIB_FILES)) + @for %i in ($($(LIB_FILES))) do @%append $(cmdfile) +-%i + +clean: .symbolic + @-erase $(OBJ_S) + @-erase $(OBJS_M) + @-erase $(cmdfile) + +distclean: .symbolic clean + @-erase $(libfile) + +new: .symbolic + @-wtouch *.c + +# end of Makefile.wat diff --git a/lib/arch/msdos/depend.dos b/lib/arch/msdos/depend.dos new file mode 100644 index 0000000..0175c97 --- /dev/null +++ b/lib/arch/msdos/depend.dos @@ -0,0 +1,107 @@ +# This dependency file to be used with various MS-DOS compilers +# has been generated automatically with the script `makedep' on +# 03-Sep-1999. + +ttapi.obj: ttapi.c ttconfig.h arch\msdos\ft_conf.h freetype.h fterrid.h \ + ftnameid.h ttengine.h tttypes.h ttmutex.h ttcalc.h ttmemory.h \ + ttcache.h ttfile.h ttdebug.h ttobjs.h tttables.h ttcmap.h ttload.h \ + ttgload.h ttraster.h ttextend.h +ttcache.obj: ttcache.c ttengine.h tttypes.h ttconfig.h \ + arch\msdos\ft_conf.h freetype.h fterrid.h ftnameid.h ttmutex.h \ + ttmemory.h ttcache.h ttobjs.h tttables.h ttcmap.h ttdebug.h +ttcalc.obj: ttcalc.c ttcalc.h ttconfig.h arch\msdos\ft_conf.h freetype.h \ + fterrid.h ftnameid.h ttdebug.h tttypes.h tttables.h +ttcmap.obj: ttcmap.c ttobjs.h ttconfig.h arch\msdos\ft_conf.h ttengine.h \ + tttypes.h freetype.h fterrid.h ftnameid.h ttmutex.h ttcache.h \ + tttables.h ttcmap.h ttdebug.h ttfile.h ttmemory.h ttload.h +ttdebug.obj: ttdebug.c ttdebug.h ttconfig.h arch\msdos\ft_conf.h \ + tttypes.h freetype.h fterrid.h ftnameid.h tttables.h ttobjs.h \ + ttengine.h ttmutex.h ttcache.h ttcmap.h +ttextend.obj: ttextend.c ttextend.h ttconfig.h arch\msdos\ft_conf.h \ + tttypes.h freetype.h fterrid.h ftnameid.h ttobjs.h ttengine.h \ + ttmutex.h ttcache.h tttables.h ttcmap.h ttmemory.h +ttfile.obj: ttfile.c ttconfig.h arch\msdos\ft_conf.h freetype.h \ + fterrid.h ftnameid.h tttypes.h ttdebug.h ttengine.h ttmutex.h \ + ttmemory.h ttfile.h +ttgload.obj: ttgload.c tttypes.h ttconfig.h arch\msdos\ft_conf.h \ + freetype.h fterrid.h ftnameid.h ttdebug.h ttcalc.h ttfile.h \ + ttengine.h ttmutex.h tttables.h ttobjs.h ttcache.h ttcmap.h ttgload.h \ + ttmemory.h tttags.h ttload.h +ttinterp.obj: ttinterp.c freetype.h fterrid.h ftnameid.h tttypes.h \ + ttconfig.h arch\msdos\ft_conf.h ttdebug.h ttcalc.h ttmemory.h \ + ttinterp.h ttobjs.h ttengine.h ttmutex.h ttcache.h tttables.h \ + ttcmap.h +ttload.obj: ttload.c tttypes.h ttconfig.h arch\msdos\ft_conf.h \ + freetype.h fterrid.h ftnameid.h ttdebug.h ttcalc.h ttfile.h \ + ttengine.h ttmutex.h tttables.h ttobjs.h ttcache.h ttcmap.h \ + ttmemory.h tttags.h ttload.h +ttmemory.obj: ttmemory.c ttdebug.h ttconfig.h arch\msdos\ft_conf.h \ + tttypes.h freetype.h fterrid.h ftnameid.h ttmemory.h ttengine.h \ + ttmutex.h +ttmutex.obj: ttmutex.c ttmutex.h ttconfig.h arch\msdos\ft_conf.h +ttobjs.obj: ttobjs.c ttobjs.h ttconfig.h arch\msdos\ft_conf.h ttengine.h \ + tttypes.h freetype.h fterrid.h ftnameid.h ttmutex.h ttcache.h \ + tttables.h ttcmap.h ttfile.h ttdebug.h ttcalc.h ttmemory.h ttload.h \ + ttinterp.h ttextend.h +ttraster.obj: ttraster.c ttraster.h ttconfig.h arch\msdos\ft_conf.h \ + freetype.h fterrid.h ftnameid.h ttengine.h tttypes.h ttmutex.h \ + ttdebug.h ttcalc.h ttmemory.h +extend\ftxcmap.obj: extend\ftxcmap.c extend\ftxcmap.h freetype.h fterrid.h \ + ftnameid.h tttypes.h ttconfig.h arch\msdos\ft_conf.h ttobjs.h \ + ttengine.h ttmutex.h ttcache.h tttables.h ttcmap.h +extend\ftxerr18.obj: extend\ftxerr18.c ttconfig.h arch\msdos\ft_conf.h \ + extend\ftxerr18.h freetype.h fterrid.h ftnameid.h extend\ftxkern.h \ + extend\ftxpost.h extend\ftxopen.h extend\ftxgdef.h extend\ftxgsub.h \ + extend\ftxgpos.h +extend\ftxgasp.obj: extend\ftxgasp.c extend\ftxgasp.h freetype.h fterrid.h \ + ftnameid.h tttypes.h ttconfig.h arch\msdos\ft_conf.h ttobjs.h \ + ttengine.h ttmutex.h ttcache.h tttables.h ttcmap.h +extend\ftxgdef.obj: extend\ftxgdef.c tttypes.h ttconfig.h arch\msdos\ft_conf.h \ + freetype.h fterrid.h ftnameid.h tttags.h ttload.h ttobjs.h ttengine.h \ + ttmutex.h ttcache.h tttables.h ttcmap.h ttextend.h ttmemory.h \ + ttfile.h ttdebug.h extend\ftxopen.h extend\ftxgdef.h extend\ftxgsub.h \ + extend\ftxgpos.h extend\ftxopenf.h +extend\ftxgpos.obj: extend\ftxgpos.c tttypes.h ttconfig.h arch\msdos\ft_conf.h \ + freetype.h fterrid.h ftnameid.h tttags.h ttload.h ttobjs.h ttengine.h \ + ttmutex.h ttcache.h tttables.h ttcmap.h ttextend.h ttmemory.h \ + ttfile.h ttdebug.h extend\ftxopen.h extend\ftxgdef.h extend\ftxgsub.h \ + extend\ftxgpos.h extend\ftxopenf.h +extend\ftxgsub.obj: extend\ftxgsub.c tttypes.h ttconfig.h arch\msdos\ft_conf.h \ + freetype.h fterrid.h ftnameid.h tttags.h ttload.h ttobjs.h ttengine.h \ + ttmutex.h ttcache.h tttables.h ttcmap.h ttextend.h ttmemory.h \ + ttfile.h ttdebug.h extend\ftxopen.h extend\ftxgdef.h extend\ftxgsub.h \ + extend\ftxgpos.h extend\ftxopenf.h +extend\ftxkern.obj: extend\ftxkern.c extend\ftxkern.h freetype.h fterrid.h \ + ftnameid.h ttextend.h ttconfig.h arch\msdos\ft_conf.h tttypes.h \ + ttobjs.h ttengine.h ttmutex.h ttcache.h tttables.h ttcmap.h ttdebug.h \ + ttmemory.h ttfile.h ttload.h tttags.h +extend\ftxopen.obj: extend\ftxopen.c tttypes.h ttconfig.h arch\msdos\ft_conf.h \ + freetype.h fterrid.h ftnameid.h ttload.h ttobjs.h ttengine.h \ + ttmutex.h ttcache.h tttables.h ttcmap.h ttextend.h ttmemory.h \ + ttfile.h ttdebug.h extend\ftxopen.h extend\ftxgdef.h extend\ftxgsub.h \ + extend\ftxgpos.h extend\ftxopenf.h +extend\ftxpost.obj: extend\ftxpost.c extend\ftxpost.h freetype.h fterrid.h \ + ftnameid.h tttypes.h ttconfig.h arch\msdos\ft_conf.h ttobjs.h \ + ttengine.h ttmutex.h ttcache.h tttables.h ttcmap.h ttload.h ttfile.h \ + ttdebug.h tttags.h ttmemory.h ttextend.h +extend\ftxsbit.obj: extend\ftxsbit.c extend\ftxsbit.h freetype.h fterrid.h \ + ftnameid.h ttobjs.h ttconfig.h arch\msdos\ft_conf.h ttengine.h \ + tttypes.h ttmutex.h ttcache.h tttables.h ttcmap.h ttfile.h ttdebug.h \ + ttload.h ttmemory.h tttags.h ttextend.h +extend\ftxwidth.obj: extend\ftxwidth.c extend\ftxwidth.h freetype.h fterrid.h \ + ftnameid.h ttdebug.h ttconfig.h arch\msdos\ft_conf.h tttypes.h \ + ttobjs.h ttengine.h ttmutex.h ttcache.h tttables.h ttcmap.h ttfile.h \ + tttags.h ttload.h +arch\msdos\freetype.obj: arch\msdos\freetype.c ttapi.c ttconfig.h \ + arch\msdos\ft_conf.h freetype.h fterrid.h ftnameid.h ttengine.h \ + tttypes.h ttmutex.h ttcalc.h ttmemory.h ttcache.h ttfile.h ttdebug.h \ + ttobjs.h tttables.h ttcmap.h ttload.h ttgload.h ttraster.h ttextend.h \ + ttcache.c ttcalc.c ttcmap.c ttdebug.c ttgload.c tttags.h ttinterp.c \ + ttinterp.h ttload.c ttobjs.c ttraster.c arch\msdos\hugefile.c \ + ttfile.c arch\msdos\hugemem.c ttmutex.c ttextend.c +arch\msdos\hugefile.obj: arch\msdos\hugefile.c ttconfig.h arch\msdos\ft_conf.h \ + tttypes.h freetype.h fterrid.h ftnameid.h ttfile.c ttdebug.h \ + ttengine.h ttmutex.h ttmemory.h ttfile.h +arch\msdos\hugemem.obj: arch\msdos\hugemem.c ttdebug.h ttconfig.h \ + arch\msdos\ft_conf.h tttypes.h freetype.h fterrid.h ftnameid.h \ + ttmemory.h ttengine.h ttmutex.h diff --git a/lib/arch/msdos/freetype.c b/lib/arch/msdos/freetype.c new file mode 100644 index 0000000..943d5f2 --- /dev/null +++ b/lib/arch/msdos/freetype.c @@ -0,0 +1,39 @@ +/* This file is part of the FreeType project */ + +/* Single object library component for MSDOS. */ +/* Note that low-optimizing 16-bit compilers (such as Borland ones) can't */ +/* successfully compile this file, because it exceeds 64K of code size. */ +#define TT_MAKE_OPTION_SINGLE_OBJECT + +/* first include common core components */ + +#include "ttapi.c" +#include "ttcache.c" +#include "ttcalc.c" +#include "ttcmap.c" +#include "ttdebug.c" +#include "ttgload.c" +#include "ttinterp.c" +#include "ttload.c" +#include "ttobjs.c" +#include "ttraster.c" + +/* then system-specific (or ANSI) components */ + +#ifdef TT_HUGE_PTR +#include "arch/msdos/hugefile.c" +#include "arch/msdos/hugemem.c" +#else +#include "ttfile.c" +#include "ttmemory.c" +#endif +#include "ttmutex.c" + +/* finally, add some extensions */ + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE +#include "ttextend.c" +#endif + + +/* END */ diff --git a/lib/arch/msdos/ft_conf.h b/lib/arch/msdos/ft_conf.h new file mode 100644 index 0000000..0199a5c --- /dev/null +++ b/lib/arch/msdos/ft_conf.h @@ -0,0 +1,253 @@ +/* This file is part of the FreeType project */ + +/* ft_conf.h for MSDOS */ + + +/* we need the following because there are some typedefs in this file */ + +#ifndef FT_CONF_H +#define FT_CONF_H + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H + +/* Define if you have the getpagesize function. */ +#undef HAVE_GETPAGESIZE + +/* Define if you have the memcpy function. */ +#define HAVE_MEMCPY + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE + +/* Define if you have the valloc function. */ +#undef HAVE_VALLOC + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H + +/* Define if you have the header file. */ +#if defined( __EMX__ ) || defined( __DJGPP__ ) || defined( __GO32__ ) +/* some compilers are known to have ; */ +/* add yours if needed, and report to us the update. */ +#define HAVE_UNISTD_H +#else +/* most MS-DOS compilers lack */ +#undef HAVE_UNISTD_H +#endif + +/* Define if you need for console I/O functions. */ +#ifdef __EMX__ +#define HAVE_CONIO_H +#endif + +/* Define if you have the header file. */ +#undef HAVE_LOCALE_H + +/* Define if you have the header file. */ +#undef HAVE_LIBINTL_H + +/* Define if you have the libintl library. */ +#undef HAVE_LIBINTL + +/* DJGPP v.2 may feature the GNU gettext package, with some subtleties. */ +/* The macro HAVE_GETTEXT has to be set in the makefile. */ +#ifdef HAVE_GETTEXT +#define HAVE_LOCALE_H +#define HAVE_LIBINTL_H +#define HAVE_LIBINTL +#define LOCALEDIR "/usr/djgpp/share/locale" +/* Due to a name conflict, gettext is renamed gettext__ in DJGPP */ +#define gettext( str ) gettext__( str ) +#endif + +/* command.com can't pipe stderr into a file; any message would be */ +/* written into the graphics screen. */ +#define HAVE_PRINT_FUNCTION 1 + +#define Print( format, ap ) vfprintf( stdout, (format), (ap) ) + +/* The number of bytes in a int. We use the ANSI header file limits.h */ +/* for determining it since there is no easy way to guess. */ +#include +#if UINT_MAX == 0xFFFF +#define SIZEOF_INT 2 +#elif UINT_MAX == 0xFFFFFFFF +#define SIZEOF_INT 4 +#else +#error "Unsupported number of bytes in `int' type!" +#endif + +/* The number of bytes in a long. */ +#define SIZEOF_LONG 4 + +/**********************************************************************/ +/* */ +/* The following configuration macros can be tweaked manually by */ +/* a developer to turn on or off certain features or options in the */ +/* TrueType engine. This may be useful to tune it for specific */ +/* purposes.. */ +/* */ +/**********************************************************************/ + + +/*************************************************************************/ +/* Define this if the underlying operating system uses a different */ +/* character width than 8bit for file names. You must then also supply */ +/* a typedef declaration for defining 'TT_Text'. Default is off. */ + +/* #define HAVE_TT_TEXT */ + + +/*************************************************************************/ +/* Define this if you want to generate code to support engine extensions */ +/* Default is on, but if you're satisfied by the basic services provided */ +/* by the engine and need no extensions, undefine this configuration */ +/* macro to save a few more bytes. */ + +#define TT_CONFIG_OPTION_EXTEND_ENGINE + + +/*************************************************************************/ +/* Define this if you want to generate code to support gray-scaling, */ +/* a.k.a. font-smoothing or anti-aliasing. Default is on, but you can */ +/* disable it if you don't need it. */ + +#define TT_CONFIG_OPTION_GRAY_SCALING + + +/*************************************************************************/ +/* Define this if you want to completely disable the use of the bytecode */ +/* interpreter. Doing so will produce a much smaller library, but the */ +/* quality of the rendered glyphs will enormously suffer from this. */ +/* */ +/* This switch was introduced due to the Apple patents issue which */ +/* emerged recently on the FreeType lists. We still do not have Apple's */ +/* opinion on the subject and will change this as soon as we have. */ + +#undef TT_CONFIG_OPTION_NO_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to use a big 'switch' statement within the */ +/* bytecode interpreter. Because some non-optimizing compilers are not */ +/* able to produce jump tables from such statements, undefining this */ +/* configuration macro will generate the appropriate C jump table in */ +/* ttinterp.c. If you use an optimizing compiler, you should leave it */ +/* defined for better performance and code compactness.. */ + +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the TrueType */ +/* bytecode interpreter. This will produce much bigger code, which */ +/* _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the scan-line */ +/* converter (the component which in charge of converting outlines into */ +/* bitmaps). This will produce a bigger object file for "ttraster.c", */ +/* which _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_RASTER + + + +/*************************************************************************/ +/* Define TT_CONFIG_THREAD_SAFE if you want to build a thread-safe */ +/* version of the library. */ + +#undef TT_CONFIG_OPTION_THREAD_SAFE + + +/**********************************************************************/ +/* */ +/* The following macros are used to define the debug level, as well */ +/* as individual tracing levels for each component. There are */ +/* currently three modes of operation : */ +/* */ +/* - trace mode (define DEBUG_LEVEL_TRACE) */ +/* */ +/* The engine prints all error messages, as well as tracing */ +/* ones, filtered by each component's level */ +/* */ +/* - debug mode (define DEBUG_LEVEL_ERROR) */ +/* */ +/* Disable tracing, but keeps error output and assertion */ +/* checks. */ +/* */ +/* - release mode (don't define anything) */ +/* */ +/* Don't include error-checking or tracing code in the */ +/* engine's code. Ideal for releases. */ +/* */ +/* NOTE : */ +/* */ +/* Each component's tracing level is defined in its own source. */ +/* */ +/**********************************************************************/ + +/* Define if you want to use the tracing debug mode */ +#undef DEBUG_LEVEL_TRACE + +/* Define if you want to use the error debug mode - ignored if */ +/* DEBUG_LEVEL_TRACE is defined */ +#undef DEBUG_LEVEL_ERROR + + +/**************************************************************************/ +/* Definition of various integer sizes. These types are used by ttcalc */ +/* and ttinterp (for the 64-bit integers) only.. */ + +#if SIZEOF_INT == 4 + + typedef signed int TT_Int32; + typedef unsigned int TT_Word32; + +#elif SIZEOF_LONG == 4 + + typedef signed long TT_Int32; + typedef unsigned long TT_Word32; + +#else +#error "no 32bit type found" +#endif + +#if SIZEOF_LONG == 8 + +/* LONG64 must be defined when a 64-bit type is available */ +/* INT64 must then be defined to this type.. */ +#define LONG64 +#define INT64 long + +#else + +/* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */ +/* by defining the TT_USE_LONG_LONG macro in 'ft_conf.h'. Note that this */ +/* will produce many -ansi warnings during library compilation. */ +#ifdef TT_USE_LONG_LONG + +#define LONG64 +#define INT64 long long + +#endif /* TT_USE_LONG_LONG */ +#endif + +#endif /* FT_CONF_H */ + + +/* END */ diff --git a/lib/arch/msdos/hugefile.c b/lib/arch/msdos/hugefile.c new file mode 100644 index 0000000..901e0d6 --- /dev/null +++ b/lib/arch/msdos/hugefile.c @@ -0,0 +1,84 @@ +/******************************************************************* + * + * hugefile.c + * + * File I/O Component (body) for dealing with "huge" objects under + * MS-DOS. Relies on the "default" version, with a small hook. + * + * Written by Antoine Leca based on ideas from Dave Hoo. + * Copyright 1999 by Dave Hoo, Antoine Leca, + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTE + * + * This file #includes the normal version, to avoid discrepancies + * between versions. It uses only ANSI-mandated "tricks", so + * any ANSI-compliant compiler should be able to compile this file. + * + ******************************************************************/ + +#include "ttconfig.h" +#include "tttypes.h" + +/* Here we include , to have the proper definition of fread */ +#include + +/* Then, we divert the use of fread to our version */ +#undef fread +#define fread(ptr, size, n, stream) huge_fread(ptr, size, n, stream) + + LOCAL_FUNC + Long huge_fread ( void *ptr, size_t size, Long n, FILE *stream ); + +/* Now, we include the "normal" version of ttfile.c */ +/* The ANSI/ISO standard mandates that the include of */ +/* there have no bad effects. */ +#include "ttfile.c" + +/* Then, we define our implementation of fread that makes use of */ +/* "huge"-allocated memory. */ + +/******************************************************************* + * + * Function : huge_fread + * + * Description : replacement version of fread that handles + * "huge"-allocated memory. + * + * Input : See the reference for the runtime library function fread + * + * Output : See the reference for the runtime library function fread + * + * Notes : + * + ******************************************************************/ + + LOCAL_DEF + Long huge_fread ( void *ptr, size_t size, Long n, FILE *stream ) + { + char TT_HUGE_PTR * p = (char TT_HUGE_PTR *) ptr; + ULong left = (ULong)n * size; + size_t toRead; + + while ( left ) + { + toRead = (left > 0x8000) ? 0x8000 : left; + if ( (fread)( p, 1, toRead, stream ) != toRead) + return -1; + else + { + left -= (ULong) toRead; + p += toRead; + } + } + return n * size; + } + + +/* END */ diff --git a/lib/arch/msdos/hugemem.c b/lib/arch/msdos/hugemem.c new file mode 100644 index 0000000..aa44c69 --- /dev/null +++ b/lib/arch/msdos/hugemem.c @@ -0,0 +1,496 @@ +/******************************************************************* + * + * hugemem.c + * + * Memory management component (body) + * for dealing with "huge" objects with 16-bit MS-DOS. + * + * Written by Dave Hoo and Antoine Leca. + * Copyright 1999 by Dave Hoo, Antoine Leca, + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include + +#include "ttdebug.h" +#include "ttmemory.h" +#include "ttengine.h" + +#ifndef TT_HUGE_PTR +#error "This component needs TT_HUGE_PTR to be #defined." +#endif + +/* ---- Microsoft C compilers support ------------------------------------ */ + +#if defined( M_I86 ) || defined( _M_I86 ) + +#include +#define huge_alloc( size ) _halloc ( size, 1 ) +#define huge_free( block ) _hfree ( block ) + +#endif /* Microsoft compilers */ + +/* ---- Borland C compiler support --------------------------------------- */ + +#ifdef __TURBOC__ + +#include +#define huge_alloc( size ) farmalloc ( size ) +#define huge_free( block ) farfree ( block ) + +#endif + +#if !defined( huge_alloc ) || !defined( huge_free ) +#error "Your compiler is not (yet) supported. Check the source file!" +#endif + +#ifdef TT_CONFIG_OPTION_THREAD_SAFE +#error "This component needs static allocation and is not re-entrant." +#endif + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_memory + + +#ifdef DEBUG_MEMORY + +#include + +#define MAX_TRACKED_BLOCKS 1024 + + struct TMemRec_ + { + void* base; + Long size; + }; + + typedef struct TMemRec_ TMemRec; + + static TMemRec pointers[MAX_TRACKED_BLOCKS + 1]; + + static Int num_alloc; + static Int num_free; + static Int num_realloc; /* counts only `real' reallocations + (i.e., an existing buffer will be resized + to a value larger than zero */ + + static Int fail_alloc; + static Int fail_realloc; + static Int fail_free; + +#else + + /* We need a tracing stack of the calls to big chunks of memory, */ + /* in order to call the matching version of free(). */ + +#define MAX_TRACKED_BIGCHUNKS 16 + + struct TMemRec_ + { + void* base; + Long size; + }; + + typedef struct TMemRec_ TMemRec; + + static TMemRec pointers[MAX_TRACKED_BIGCHUNKS + 1]; + +#endif /* DEBUG_MEMORY */ + + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + Long TTMemory_Allocated; + Long TTMemory_MaxAllocated; +#endif + + +/******************************************************************* + * + * Function : TT_Alloc + * + * Description : Allocates memory from the heap buffer. + * + * Input : Size size of the memory to be allocated + * P pointer to a buffer pointer + * + * Output : Error code. + * + * NOTE : The newly allocated block should _always_ be zeroed + * on return. Many parts of the engine rely on this to + * work properly. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Alloc( ULong Size, void** P ) + { + Int i; + + + if ( !P ) + return TT_Err_Invalid_Argument; + /* Also see below for another case of "invalid argument". */ + + if ( Size > 0 ) + { + if ( Size > ( UINT_MAX & ~0xFu ) ) + *P = (void*)huge_alloc( Size ); + else + *P = (void*)malloc( Size ); + if ( !*P ) + return TT_Err_Out_Of_Memory; + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + TTMemory_Allocated += Size; + TTMemory_MaxAllocated += Size; +#endif + +#ifdef DEBUG_MEMORY + + num_alloc++; + + i = 0; + while ( i < MAX_TRACKED_BLOCKS && pointers[i].base != NULL ) + i++; + + if ( i >= MAX_TRACKED_BLOCKS ) + fail_alloc++; + else + { + pointers[i].base = *P; + pointers[i].size = Size; + } + +#else + + if ( Size > ( UINT_MAX & ~0xFu ) ) + { + i = 0; + while ( i < MAX_TRACKED_BIGCHUNKS && pointers[i].base != NULL ) + i++; + + if ( i >= MAX_TRACKED_BIGCHUNKS ) + /* We fail badly here. Increase MAX_TRACKED_BIGCHUNKS if needed. */ + return TT_Err_Invalid_Argument; + else + { + pointers[i].base = *P; + pointers[i].size = Size; + } + } + +#endif /* DEBUG_MEMORY */ + + if ( Size > ( UINT_MAX & ~0xFu ) ) + { + char TT_HUGE_PTR * p = (char TT_HUGE_PTR *) *P; + ULong left = (ULong)Size; + size_t toClear; + + while ( left ) + { + toClear = (left > 0xFF00) ? 0xFF00 : left; + MEM_Set( p, 0, toClear ); + left -= (ULong) toClear; + p += toClear; + } + } + else + MEM_Set( *P, 0, Size ); + } + else + *P = NULL; + + return TT_Err_Ok; + } + + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE + + +/******************************************************************* + * + * Function : TT_Realloc + * + * Description : Reallocates memory from the heap buffer. + * + * Input : Size new size of the memory to be allocated; + * if zero, TT_Free() will be called + * P pointer to a buffer pointer; if *P == NULL, + * TT_Alloc() will be called + * + * Output : Error code. + * + * NOTES : It's not necessary to zero the memory in case the + * reallocated buffer is larger than before -- the + * application has to take care of this. + * + * If the memory request fails, TT_Free() will be + * called on *P, and TT_Err_Out_Of_Memory returned. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Realloc( ULong Size, void** P ) + { + void* Q; + +#ifdef DEBUG_MEMORY + Int i; +#endif + + + if ( !P ) + return TT_Err_Invalid_Argument; + + if ( !*P ) + return TT_Alloc( Size, P ); + + if ( Size == 0 ) + return TT_Free( P ); + + if ( Size > ( UINT_MAX & ~0xFu ) ) + Q = NULL; /* Do not even try to deal with big chunks of memory. */ + else + Q = (void*)realloc( *P, Size ); + if ( !Q ) + { + TT_Free( *P ); + return TT_Err_Out_Of_Memory; + } + +#ifdef DEBUG_MEMORY + + num_realloc++; + + i = 0; + while ( i < MAX_TRACKED_BLOCKS && pointers[i].base != *P ) + i++; + + if ( i >= MAX_TRACKED_BLOCKS ) + fail_realloc++; + else + { +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + TTMemory_Allocated += Size - pointers[i].size; + if ( Size > pointers[i].size ) + TTMemory_MaxAllocated += Size - pointers[i].size; +#endif + + pointers[i].base = Q; + pointers[i].size = Size; + } +#endif /* DEBUG_MEMORY */ + + *P = Q; + + return TT_Err_Ok; + } + + +#endif /* TT_CONFIG_OPTION_EXTEND_ENGINE */ + + +/******************************************************************* + * + * Function : TT_Free + * + * Description : Releases a previously allocated block of memory. + * + * Input : P pointer to memory block + * + * Output : Always SUCCESS. + * + * Note : The pointer must _always_ be set to NULL by this function. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Free( void** P ) + { + Int i; + Long Size = 0; + + + if ( !P || !*P ) + return TT_Err_Ok; + +#ifdef DEBUG_MEMORY + + num_free++; + + i = 0; + while ( i < MAX_TRACKED_BLOCKS && pointers[i].base != *P ) + i++; + + if ( i >= MAX_TRACKED_BLOCKS ) + fail_free++; + else + { +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + TTMemory_Allocated -= pointers[i].size; +#endif + + Size = pointers[i].size; + pointers[i].base = NULL; + pointers[i].size = 0; + } + +#else + + i = 0; + while ( i < MAX_TRACKED_BIGCHUNKS && pointers[i].base != *P ) + i++; + + /* If we did not found the pointer, then this is a "small" chunk. */ + + if ( i < MAX_TRACKED_BIGCHUNKS ) + { + Size = pointers[i].size; + pointers[i].base = NULL; + pointers[i].base = NULL; + } + +#endif /* DEBUG_MEMORY */ + + if ( Size > ( UINT_MAX & ~0xFu ) ) + huge_free( *P ); + else + free( *P ); + + *P = NULL; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTMemory_Init + * + * Description : Initializes the memory. + * + * Output : Always SUCCESS. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTMemory_Init( void ) + { +#ifdef DEBUG_MEMORY + Int i; + + + for ( i = 0; i < MAX_TRACKED_BLOCKS; i++ ) + { + pointers[i].base = NULL; + pointers[i].size = 0; + } + + num_alloc = 0; + num_realloc = 0; + num_free = 0; + + fail_alloc = 0; + fail_realloc = 0; + fail_free = 0; +#else + Int i; + + for ( i = 0; i < MAX_TRACKED_BIGCHUNKS; i++ ) + { + pointers[i].base = NULL; + pointers[i].size = 0; + } +#endif + + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + TTMemory_Allocated = 0; + TTMemory_MaxAllocated = 0; +#endif + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTMemory_Done + * + * Description : Finalizes memory usage. + * + * Output : Always SUCCESS. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTMemory_Done( void ) + { +#ifdef DEBUG_MEMORY + Int i, num_leaked, tot_leaked; + + + num_leaked = 0; + tot_leaked = 0; + + for ( i = 0; i < MAX_TRACKED_BLOCKS; i++ ) + { + if ( pointers[i].base ) + { + num_leaked ++; + tot_leaked += pointers[i].size; + } + } + + fprintf( stderr, + "%d memory allocations, of which %d failed\n", + num_alloc, + fail_alloc ); + + fprintf( stderr, + "%d memory reallocations, of which %d failed\n", + num_realloc, + fail_realloc ); + + fprintf( stderr, + "%d memory frees, of which %d failed\n", + num_free, + fail_free ); + + if ( num_leaked > 0 ) + { + fprintf( stderr, + "There are %d leaked memory blocks, totalizing %d bytes\n", + num_leaked, tot_leaked ); + + for ( i = 0; i < MAX_TRACKED_BLOCKS; i++ ) + { + if ( pointers[i].base ) + { + fprintf( stderr, + "index: %4d (base: $%08lx, size: %08ld)\n", + i, + (long)pointers[i].base, + pointers[i].size ); + } + } + } + else + fprintf( stderr, "No memory leaks !\n" ); + +#endif /* DEBUG_MEMORY */ + + return TT_Err_Ok; + } + + +/* END */ diff --git a/lib/arch/msdos/makedep b/lib/arch/msdos/makedep new file mode 100644 index 0000000..d566ed8 --- /dev/null +++ b/lib/arch/msdos/makedep @@ -0,0 +1,26 @@ +# makedep +# +# This shell script creates a dependency file necessary for older compilers +# on the MS-DOS platform. + +echo "\ +# This dependency file to be used with various MS-DOS compilers +# has been generated automatically with the script \`makedep' on +# `date +%d-%b-%Y`. +" > depend.dos + +(cd ../.. + gcc -MM -Iarch/msdos -I. *.c | \ + sed -e "s/\.o:/.obj:/" -e "s:/:\\\\:g") >> depend.dos + +(cd ../.. + gcc -MM -Iarch/msdos -I. -Iextend extend/*.c | \ + sed -e "s/^\(.*\)\.o:/extend\\\\\1.obj:/" -e "s:/:\\\\:g") >> depend.dos + +(cd ../.. + gcc -MM -Iarch/msdos -I. -Iextend \ + -DTT_HUGE_PTR -Dhuge_alloc -Dhuge_free arch/msdos/*.c | \ + sed -e "s/^\(.*\)\.o:/arch\\\\msdos\\\\\1.obj:/" \ + -e "s:/:\\\\:g") >> depend.dos + +# eof diff --git a/lib/arch/os2/Makefile.dm b/lib/arch/os2/Makefile.dm new file mode 100644 index 0000000..a5c18f7 --- /dev/null +++ b/lib/arch/os2/Makefile.dm @@ -0,0 +1,84 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for emx-gcc under OS/2 +# +# You will need dmake. +# +# Use this file while in the lib directory with the following statement: +# +# dmake -r -f arch/os2/Makefile.dm + +ARCH = arch/os2 +FT_MAKEFILE = $(ARCH)/Makefile.dm +FT_MAKE = dmake -r + +.IMPORT: COMSPEC +SHELL := $(COMSPEC) +SHELLFLAGS := /c +GROUPSHELL := $(SHELL) +GROUPFLAGS := $(SHELLFLAGS) +GROUPSUFFIX := .cmd +SHELLMETAS := *"?<>&| + +CC = gcc + +CFLAGS = -Wall -O2 -g -ansi -pedantic -I$(ARCH) -I. -Iextend +# CFLAGS = -Wall -ansi -O2 -s -I$(ARCH) -I. -Iextend + +TTFILE = $(ARCH)/os2file.c +TTMEMORY = ./ttmemory.c +TTMUTEX = ./ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +SRC_X = extend/ftxgasp.c extend/ftxkern.c extend/ftxpost.c \ + extend/ftxcmap.c extend/ftxwidth.c extend/ftxsbit.c \ + extend/ftxgsub.c extend/ftxgpos.c extend/ftxopen.c \ + extend/ftxgdef.c +OBJS_X = $(SRC_X:.c=.o) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c \ + ttgload.c ttinterp.c ttload.c ttobjs.c \ + ttraster.c ttextend.c $(PORT) +OBJS_M = $(SRC_M:.c=.o) $(OBJS_X) + +SRC_S = $(ARCH)/freetype.c +OBJ_S = $(SRC_S:.c=.o) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +.PHONY: all debug clean distclean depend + + +all: + $(FT_MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_S libttf.a + +debug: + $(FT_MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_M libttf.a + + +$(OBJ_S): $(SRC_S) $(SRC_M) + $(CC) $(CFLAGS) -c -o $@ $(SRC_S) + + +libttf.a: $($(LIB_FILES)) + +-del $@ + ar src $@ @$(mktmp $(<:t"\n")\n) + +clean: + -+del $(subst,/,\ $($(LIB_FILES))) + +distclean: clean + -+del dep.end libttf.a + +# depend: $(SRC_S) $(SRC_M) $(SRC_X) +# $(CC) -E -M @$(mktmp $(<:t"\n")\n) > dep.end + +# ifeq (dep.end,$(wildcard dep.end)) +# include dep.end +# endif + +# end of Makefile.dm diff --git a/lib/arch/os2/Makefile.emx b/lib/arch/os2/Makefile.emx new file mode 100644 index 0000000..4ba9128 --- /dev/null +++ b/lib/arch/os2/Makefile.emx @@ -0,0 +1,91 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for emx-gcc under OS/2. +# +# You will need GNU make. +# +# Use this file while in the lib directory with the following statement: +# +# make -f arch/os2/Makefile.emx + +ARCH = arch/os2 +FT_MAKEFILE = $(ARCH)/Makefile.emx + +CC = gcc + +#CFLAGS = -W -Wall -O0 -g -ansi -pedantic -I$(ARCH) -I. -Iextend + +CFLAGS = -Wall -O3 -fno-inline -fomit-frame-pointer \ + -g -ansi -pedantic -I$(ARCH) -I. -Iextend + +#CFLAGS = -Wall -ansi -pedantic -O2 -s -I$(ARCH) -I. -Iextend + +TTFILE = $(ARCH)/os2file.c +TTMEMORY = ./ttmemory.c +TTMUTEX = ./ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +SRC_X = extend/ftxgasp.c extend/ftxkern.c extend/ftxpost.c \ + extend/ftxcmap.c extend/ftxwidth.c extend/ftxsbit.c \ + extend/ftxgsub.c extend/ftxgpos.c extend/ftxopen.c \ + extend/ftxgdef.c +OBJS_X = $(SRC_X:.c=.o) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c \ + ttgload.c ttinterp.c ttload.c ttobjs.c \ + ttraster.c ttextend.c $(PORT) +OBJS_M = $(SRC_M:.c=.o) $(OBJS_X) + +SRC_S = $(ARCH)/freetype.c +OBJ_S = $(SRC_S:.c=.o) +OBJS_S = $(OBJ_S) $(OBJS_X) + +SRCD_S = $(ARCH)/freetypd.c +OBJD_S = $(SRCD_S:.c=.o) +OBJDS_S = $(OBJD_S) $(OBJS_X) + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +.PHONY: all debug clean distclean depend + + +all: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_S libttf.a + +debug: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_M libttf.a + +debugger: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJDS_S libttfd.a + +$(OBJ_S): $(SRC_S) $(SRC_M) +$(OBJD_S): $(SRCD_S) $(SRC_M) + +libttf.a: $($(LIB_FILES)) + -del $@ + ar src $@ $^ + +libttfd.a: $(OBJDS) + +libttfd.a: $(OBJDS) + -del $@ + ar src $@ $^ + +clean: + -del $(subst /,\,$(OBJS_S)) + -del $(subst /,\,$(OBJS_M)) + +distclean: clean + -del dep.end + -del libttf.a + +depend: $(SRC_S) $(SRC_M) $(SRC_X) + $(CC) -E -M $^ > dep.end + +ifeq (dep.end,$(wildcard dep.end)) + include dep.end +endif + +# end of Makefile.emx diff --git a/lib/arch/os2/Makefile.icc b/lib/arch/os2/Makefile.icc new file mode 100644 index 0000000..e633c8d --- /dev/null +++ b/lib/arch/os2/Makefile.icc @@ -0,0 +1,73 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for IBM VisualAge C++ under OS/2. +# +# You will need nmake. +# +# Use this file while in the lib directory with the following statement: +# +# nmake -f arch\os2\Makefile.icc +# + +ARCH = arch\os2 +FT_MAKEFILE = $(ARCH)\Makefile.icc +FT_MAKE = $(MAKE) -nologo + +CC = icc +CFLAGS = -O+ -Ti- -Tm- -Sa -W3 -Wpro- -Wcnd- -Q+ -Iarch\os2 -I. -Iextend + +# NOTE: Optimizations are discarded, as it seems that Visual Age +# is buggy when producing ttraster.obj. The resulting code +# crashes under some circumstances (performing vertical dropout +# control when rendering smoothed outlines)! + +TTFILE = $(ARCH)\os2file.c +TTMEMORY = .\ttmemory.c +TTMUTEX = .\ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +SRC_X = extend\ftxgasp.c extend\ftxkern.c extend\ftxpost.c \ + extend\ftxcmap.c extend\ftxwidth.c extend\ftxsbit.c \ + extend\ftxgsub.c extend\ftxgpos.c extend\ftxopen.c \ + extend\ftxgdef.c +OBJS_X = $(SRC_X:.c=.obj) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c \ + ttgload.c ttinterp.c ttload.c ttobjs.c ttraster.c \ + ttextend.c $(PORT) +OBJS_M = $(SRC_M:.c=.obj) $(OBJS_X) + +SRC_S = $(ARCH)\freetype.c +OBJ_S = $(SRC_S:.c=.obj) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +all: + $(FT_MAKE) -f $(FT_MAKEFILE) LIB_FILES="$(OBJS_S)" libttf.lib + +debug: + $(FT_MAKE) -f $(FT_MAKEFILE) LIB_FILES="$(OBJS_M)" libttf.lib + + +$(OBJ_S): $(SRC_S) $(SRC_M) + $(CC) -C $(CFLAGS) /Fo$@ $*.c + +$(OBJS_X): + $(CC) -C $(CFLAGS) /Fo$@ $*.c + +$(ARCH)\os2file.obj: + $(CC) -C $(CFLAGS) /Fo$@ $*.c + +libttf.lib: $(LIB_FILES) + !ilib /nologo /noignorecase /nobackup $@ +$?,, + +clean: + -del *.obj + -del extend\*.obj + -del arch\os2\*.obj + +distclean: clean + -del libttf.lib + +# end of Makefile.icc diff --git a/lib/arch/os2/Makefile.wat b/lib/arch/os2/Makefile.wat new file mode 100644 index 0000000..4fe8adf --- /dev/null +++ b/lib/arch/os2/Makefile.wat @@ -0,0 +1,88 @@ +# This file is part of the FreeType project. +# +# This builds the Watcom library with Watcom's wcc386 under OS/2. +# +# You'll need Watcom's wmake. +# +# +# Invoke by "wmake -f arch\os2\Makefile.wat" when in the "lib" directory +# +# This will build "freetype\lib\libttf.lib" + +ARCH = arch\os2 +FT_MAKEFILE = $(ARCH)\Makefile.wat +FT_MAKE = wmake -h + + +.EXTENSIONS: +.EXTENSIONS: .lib .obj .c .h +.obj:.;.\extend;.\$(ARCH) +.c:.;.\extend;.\$(ARCH) +.h:.;.\extend;.\$(ARCH) + +CC = wcc386 + +CCFLAGS = /otexanl+ /s /w5 /zq -Iarch\os2 -I. -Iextend + +TTFILE = .\ttfile.c +TTMEMORY = .\ttmemory.c +TTMUTEX = .\ttmutex.c + +TTFILE_OBJ = ttfile.obj +TTMEMORY_OBJ = ttmemory.obj +TTMUTEX_OBJ = ttmutex.obj + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) +PORT_OBJS = $(TTFILE_OBJ) $(TTMEMORY_OBJ) $(TTMUTEX_OBJ) + +SRC_X = extend\ftxgasp.c extend\ftxkern.c extend\ftxpost.c & + extend\ftxcmap.c extend\ftxwidth.c extend\ftxsbit.c & + extend\ftxgsub.c extend\ftxgpos.c extend\ftxopen.c & + extend\ftxgdef.c + +OBJS_X = extend\ftxgasp.obj extend\ftxkern.obj extend\ftxpost.obj & + extend\ftxcmap.obj extend\ftxwidth.obj extend\ftxsbit.obj & + extend\ftxgsub.obj extend\ftxgpos.obj extend\ftxopen.obj & + extend\ftxgdef.obj + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c & + ttgload.c ttinterp.c ttload.c ttobjs.c & + ttraster.c ttextend.c $(PORT) + +OBJS_M = ttapi.obj ttcache.obj ttcalc.obj ttcmap.obj & + ttgload.obj ttinterp.obj ttload.obj ttobjs.obj & + ttraster.obj ttextend.obj $(PORT_OBJS) $(OBJS_X) + +SRC_S = freetype.c +OBJ_S = freetype.obj +OBJS_S = $(OBJ_S) $(OBJS_X) + + +.c.obj: + $(CC) $(CCFLAGS) $[* /fo=$[*.obj + +all: .symbolic + $(FT_MAKE) -f $(FT_MAKEFILE) libttf.lib + +debug: .symbolic + $(FT_MAKE) -f $(FT_MAKEFILE) LIB_FILES="$(OBJS_M)" libttf.lib + + +libttf.lib: $(OBJS_M) + wlib -q -n libttf.lib $(OBJS_M) + +# is this correct? Know nothing about wmake and the Watcom compiler... +$(OBJ_S): $(SRC_S) $(SRC_M) + $(CC) $(CCFLAGS) $(SRC_S) /fo=$(OBJ_S) + +clean: .symbolic + @-erase $(OBJS_M) + @-erase *.err + +distclean: .symbolic clean + @-erase libttf.lib + +new: .symbolic + @-wtouch *.c + +# end of Makefile.wat diff --git a/lib/arch/os2/freetype.c b/lib/arch/os2/freetype.c new file mode 100644 index 0000000..7a115cf --- /dev/null +++ b/lib/arch/os2/freetype.c @@ -0,0 +1,32 @@ +/* This file is part of the FreeType project */ + +/* Single file library component for OS/2 */ +#define TT_MAKE_OPTION_SINGLE_OBJECT + +/* first include common core components */ + +#include "ttapi.c" +#include "ttcache.c" +#include "ttcalc.c" +#include "ttcmap.c" +#include "ttdebug.c" +#include "ttgload.c" +#include "ttinterp.c" +#include "ttload.c" +#include "ttobjs.c" +#include "ttraster.c" + +/* then system-specific (or ANSI) components */ + +#include "os2file.c" +#include "ttmemory.c" +#include "ttmutex.c" + +/* the extensions are compiled separately, but we need to */ +/* include the file ttextend.c if we want to support them */ + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE +#include "ttextend.c" +#endif + +/* END */ diff --git a/lib/arch/os2/ft_conf.h b/lib/arch/os2/ft_conf.h new file mode 100644 index 0000000..c7026c7 --- /dev/null +++ b/lib/arch/os2/ft_conf.h @@ -0,0 +1,239 @@ +/******************************************************************* + * + * ft_conf.h (OS/2 version) + * + * High-level interface specification. + * + * Copyright 1996-1998 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * This file is used to contain the definition of several + * configuration-specific macros. + * + ******************************************************************/ + +/* we need the following because there are some typedefs in this file */ + +#ifndef FT_CONF_H +#define FT_CONF_H + + +/**********************************************************************/ +/* */ +/* We begin by a series of macros that are automatically set by the */ +/* 'configure' script on Unix. They must be set manually on OS/2, */ +/* so here they are : */ +/* */ +/**********************************************************************/ + +#define OS2 + +/* Define to empty if the keyword "const" does not work. */ +/* #undef const */ + +/* The number of bytes in a int. */ +#define SIZEOF_INT 4 + +/* The number of bytes in a long. */ +#define SIZEOF_LONG 4 + +/* Define if you have the memcpy function. */ +#define HAVE_MEMCPY + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H + +/* Define if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define if you need for console I/O functions. */ +#if defined(__EMX__) || defined(__IBMC__) +#define HAVE_CONIO_H +#endif + +/* Define if you have the valloc function. */ +#undef HAVE_VALLOC + +/* Define if you have the getpagesize function. */ +#undef HAVE_GETPAGESIZE + +/* Define if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/**********************************************************************/ +/* */ +/* The following configuration macros can be tweaked manually by */ +/* a developer to turn on or off certain features or options in the */ +/* TrueType engine. This may be useful to tune it for specific */ +/* purposes.. */ +/* */ +/**********************************************************************/ + + +/*************************************************************************/ +/* Define this if the underlying operating system uses a different */ +/* character width than 8bit for file names. You must then also supply */ +/* a typedef declaration for defining 'TT_Text'. Default is off. */ + +/* #define HAVE_TT_TEXT */ + + +/*************************************************************************/ +/* Define this if you want to generate code to support engine extensions */ +/* Default is on, but if you're satisfied by the basic services provided */ +/* by the engine and need no extensions, undefine this configuration */ +/* macro to save a few more bytes. */ + +#define TT_CONFIG_OPTION_EXTEND_ENGINE + + +/*************************************************************************/ +/* Define this if you want to generate code to support gray-scaling, */ +/* a.k.a. font-smoothing or anti-aliasing. Default is on, but you can */ +/* disable it if you don't need it. */ + +#define TT_CONFIG_OPTION_GRAY_SCALING + + +/*************************************************************************/ +/* Define this if you want to completely disable the use of the bytecode */ +/* interpreter. Doing so will produce a much smaller library, but the */ +/* quality of the rendered glyphs will enormously suffer from this. */ +/* */ +/* This switch was introduced due to the Apple patents issue which */ +/* emerged recently on the FreeType lists. We still do not have Apple's */ +/* opinion on the subject and will change this as soon as we have. */ + +#undef TT_CONFIG_OPTION_NO_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to use a big 'switch' statement within the */ +/* bytecode interpreter. Because some non-optimizing compilers are not */ +/* able to produce jump tables from such statements, undefining this */ +/* configuration macro will generate the appropriate C jump table in */ +/* ttinterp.c. If you use an optimizing compiler, you should leave it */ +/* defined for better performance and code compactness.. */ + +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the TrueType */ +/* bytecode interpreter. This will produce much bigger code, which */ +/* _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the scan-line */ +/* converter (the component which in charge of converting outlines into */ +/* bitmaps). This will produce a bigger object file for "ttraster.c", */ +/* which _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_RASTER + + + +/*************************************************************************/ +/* Define TT_CONFIG_THREAD_SAFE if you want to build a thread-safe */ +/* version of the library. */ + +#undef TT_CONFIG_OPTION_THREAD_SAFE + + +/**********************************************************************/ +/* */ +/* The following macros are used to define the debug level, as well */ +/* as individual tracing levels for each component. There are */ +/* currently three modes of operation : */ +/* */ +/* - trace mode (define DEBUG_LEVEL_TRACE) */ +/* */ +/* The engine prints all error messages, as well as tracing */ +/* ones, filtered by each component's level */ +/* */ +/* - debug mode (define DEBUG_LEVEL_ERROR) */ +/* */ +/* Disable tracing, but keeps error output and assertion */ +/* checks. */ +/* */ +/* - release mode (don't define anything) */ +/* */ +/* Don't include error-checking or tracing code in the */ +/* engine's code. Ideal for releases. */ +/* */ +/* NOTE : */ +/* */ +/* Each component's tracing level is defined in its own source. */ +/* */ +/**********************************************************************/ + +/* Define if you want to use the tracing debug mode */ +#undef DEBUG_LEVEL_TRACE + +/* Define if you want to use the error debug mode - ignored if */ +/* DEBUG_LEVEL_TRACE is defined */ +#undef DEBUG_LEVEL_ERROR + + +/**************************************************************************/ +/* Definition of various integer sizes. These types are used by ttcalc */ +/* and ttinterp (for the 64-bit integers) only.. */ + +#if SIZEOF_INT == 4 + + typedef signed int TT_Int32; + typedef unsigned int TT_Word32; + +#elif SIZEOF_LONG == 4 + + typedef signed long TT_Int32; + typedef unsigned long TT_Word32; + +#else +#error "no 32bit type found" +#endif + +#if SIZEOF_LONG == 8 + +/* LONG64 must be defined when a 64-bit type is available */ +/* INT64 must then be defined to this type.. */ +#define LONG64 +#define INT64 long + +#else + +/* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */ +/* by defining the TT_USE_LONG_LONG macro in 'ft_conf.h'. Note that this */ +/* will produce many -ansi warnings during library compilation. */ +#ifdef TT_USE_LONG_LONG + +#define LONG64 +#define INT64 long long + +#endif /* TT_USE_LONG_LONG */ +#endif + +#endif /* FT_CONF_H */ + + +/* END */ diff --git a/lib/arch/os2/os2file.c b/lib/arch/os2/os2file.c new file mode 100644 index 0000000..e6003fd --- /dev/null +++ b/lib/arch/os2/os2file.c @@ -0,0 +1,1237 @@ +/******************************************************************* + * + * os2file.c (OS2 version) 2.1 + * + * File I/O Component (body). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTES: + * + * This implementation relies on the OS/2 file API. It was provided + * by the PM FreeType DLL author, Michal Necasek. + * + ******************************************************************/ + +#include "ttconfig.h" + +#include /* !Mike! */ + +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "freetype.h" +#include "tttypes.h" +#include "ttdebug.h" +#include "ttengine.h" +#include "ttmutex.h" +#include "ttmemory.h" +#include "ttfile.h" /* our prototypes */ + + +/* For now, we don't define additional error messages in the core library */ +/* to report open-on demand errors. Define these errors as standard ones. */ + +#define TT_Err_Could_Not_ReOpen_File TT_Err_Could_Not_Open_File +#define TT_Err_Could_Not_ReSeek_File TT_Err_Could_Not_Open_File + + + /* This definition is mandatory for each file component! */ + EXPORT_FUNC + const TFileFrame TT_Null_FileFrame = { NULL, 0, 0 }; + + +/* It has proven useful to do some bounds checks during development phase. */ +/* They should probably be undefined for speed reasons in a later release. */ + +#if 0 +#define CHECK_FRAME( frame, n ) \ + do { \ + if ( frame.cursor + n > frame.address + frame.size ) \ + Panic( "Frame boundary error!\n" ); \ + } while ( 0 ) +#else +#define CHECK_FRAME( frame, n ) \ + do { \ + } while ( 0 ) +#endif + + + /* Because a stream can be flushed, i.e., its file handle can be */ + /* closed to save system resources, we must keep the stream's file */ + /* pathname to be able to re-open it on demand when it is flushed. */ + + struct _TStream_Rec + { + Bool opened; /* is the stream handle opened ? */ + String* name; /* the file's pathname */ + Long position; /* current pos. within the file */ + + HFILE file; /* file handle !Mike! */ + Long base; /* stream base in file */ + Long size; /* stream size in file */ + }; + + typedef struct _TStream_Rec TStream_Rec; + typedef TStream_Rec* PStream_Rec; + + + /* We support embedded TrueType files by allowing them to be */ + /* inside any file, at any location, hence the 'base' argument. */ + /* Note, however, that the current implementation does not allow you */ + /* to specify a 'base' index when opening a file. */ + /* (will come later) */ + /* I still don't know if this will turn out useful... - DavidT */ + +#define STREAM2REC( x ) ( (TStream_Rec*)HANDLE_Val( x ) ) + + static TT_Error Stream_Activate ( PStream_Rec stream ); + static TT_Error Stream_Deactivate( PStream_Rec stream ); + + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + /**** ****/ + /**** N O N R E E N T R A N T I M P L E M E N T A T I O N ****/ + /**** ****/ + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + + /* In non-reentrant builds, we allocate a single block where we'll */ + /* place all the frames smaller than FRAME_CACHE_SIZE, rather than */ + /* allocating a new block on each access. Bigger frames will be */ + /* malloced normally in the heap. */ + /* */ + /* See TT_Access_Frame() and TT_Forget_Frame() for details. */ + +#define FRAME_CACHE_SIZE 2048 + + /* The TFile_Component structure holds all the data that was */ + /* previously declared static or global in this component. */ + /* */ + /* It is accessible through the 'engine.file_component' */ + /* variable in re-entrant builds, or directly through the */ + /* static 'files' variable in other builds. */ + + struct _TFile_Component + { + TMutex lock; /* used by the thread-safe build only */ + Byte* frame_cache; /* frame cache */ + PStream_Rec stream; /* current stream */ + TFileFrame frame; /* current frame */ + }; + + typedef struct _TFile_Component TFile_Component; + + static TFile_Component files; + +#define CUR_Stream files.stream +#define CUR_Frame files.frame + +#define STREAM_VARS /* void */ +#define STREAM_VAR /* void */ + +/* The macro CUR_Stream denotes the current input stream. */ +/* Note that for the re-entrant version, the 'stream' name has been */ +/* chosen according to the macro STREAM_ARGS. */ + +/* The macro CUR_Frame denotes the current file frame. */ +/* Note that for the re-entrant version, the 'frame' name has been */ +/* chosen according to the macro FRAME_ARGS. */ + +/* The macro STREAM_VAR is used when calling public functions */ +/* that need an 'optional' stream argument. */ + + +/******************************************************************* + * + * Function : TTFile_Init + * + * Description : Initializes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Init( PEngine_Instance engine ) + { + TT_Error error; + + MUTEX_Create( files.lock ); + files.stream = NULL; + ZERO_Frame( files.frame ); + + if ( ALLOC( files.frame_cache, FRAME_CACHE_SIZE ) ) + return error; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTFile_Done + * + * Description : Finalizes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Done( PEngine_Instance engine ) + { + FREE( files.frame_cache ); + MUTEX_Destroy( files.lock ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Use_Stream + * + * Description : Copies or duplicates a given stream. + * + * Input : org_stream original stream + * stream target stream (copy or duplicate) + * + * Output : Error code. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Use_Stream( TT_Stream org_stream, + TT_Stream* stream ) + { + MUTEX_Lock( files.lock ); /* lock file mutex */ + + *stream = org_stream; /* copy the stream */ + files.stream = STREAM2REC( org_stream ); /* set current stream */ + + Stream_Activate( files.stream ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Done_Stream + * + * Description : Releases a given stream. + * + * Input : stream target stream + * + * Output : Error code. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Done_Stream( TT_Stream* stream ) + { + HANDLE_Set( *stream, NULL ); + MUTEX_Release( files.lock ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Access_Frame + * + * Description : Notifies the component that we're going to read + * 'size' bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx() + * functions easily. + * + * Input : size number of bytes to access. + * + * Output : SUCCESS on success. FAILURE on error. + * + * Notes: The function fails if the byte range is not within the + * the file, or if there is not enough memory to cache + * the bytes properly (which usually means that `size' is + * too big in both cases). + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Access_Frame( STREAM_ARGS FRAME_ARGS Long size ) + { + TT_Error error; + + + if ( CUR_Frame.address != NULL ) + return TT_Err_Nested_Frame_Access; + + if ( size <= FRAME_CACHE_SIZE ) + { + /* use the cache */ + CUR_Frame.address = files.frame_cache; + CUR_Frame.size = FRAME_CACHE_SIZE; + } + else + { + if ( ALLOC( CUR_Frame.address, size ) ) + return error; + CUR_Frame.size = size; + } + + error = TT_Read_File( STREAM_VARS (void*)CUR_Frame.address, size ); + if ( error ) + { + if ( size > FRAME_CACHE_SIZE ) + FREE( CUR_Frame.address ); + CUR_Frame.address = NULL; + CUR_Frame.size = 0; + } + + CUR_Frame.cursor = CUR_Frame.address; + return error; + } + + +/******************************************************************* + * + * Function : TT_Check_And_Access_Frame + * + * Description : Notifies the component that we're going to read + * `size' bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx() + * functions easily. + * + * Input : size number of bytes to access. + * + * Output : SUCCESS on success. FAILURE on error. + * + * Notes: The function truncates `size' if the byte range is not + * within the file. + * + * It will fail if there is not enough memory to cache + * the bytes properly (which usually means that `size' is + * too big). + * + * It will fail if you make two consecutive calls + * to TT_Access_Frame(), without a TT_Forget_Frame() between + * them. + * + * The only difference with TT_Access_Frame() is that we + * check that the frame is within the current file. We + * otherwise truncate it. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Check_And_Access_Frame( STREAM_ARGS FRAME_ARGS Long size ) + { + TT_Error error; + Long readBytes, requested; + + + if ( CUR_Frame.address != NULL ) + return TT_Err_Nested_Frame_Access; + + if ( size <= FRAME_CACHE_SIZE ) + { + /* use the cache */ + CUR_Frame.address = files.frame_cache; + CUR_Frame.size = FRAME_CACHE_SIZE; + } + else + { + if ( ALLOC( CUR_Frame.address, size ) ) + return error; + CUR_Frame.size = size; + } + + requested = size; + readBytes = CUR_Stream->size - TT_File_Pos( STREAM_VAR ); + if ( size > readBytes ) + size = readBytes; + + error = TT_Read_File( STREAM_VARS (void*)CUR_Frame.address, size ); + if ( error ) + { + if ( requested > FRAME_CACHE_SIZE ) + FREE( CUR_Frame.address ); + CUR_Frame.address = NULL; + CUR_Frame.size = 0; + } + + CUR_Frame.cursor = CUR_Frame.address; + return error; + } + + +/******************************************************************* + * + * Function : TT_Forget_Frame + * + * Description : Releases a cached frame after reading. + * + * Input : None + * + * Output : SUCCESS on success. FAILURE on error. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Forget_Frame( FRAME_ARG ) + { + if ( CUR_Frame.address == NULL ) + return TT_Err_Nested_Frame_Access; + + if ( CUR_Frame.size > FRAME_CACHE_SIZE ) + FREE( CUR_Frame.address ); + + ZERO_Frame( CUR_Frame ); + + return TT_Err_Ok; + } + + +#else /* TT_CONFIG_OPTION_THREAD_SAFE */ + + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + /******** ********/ + /******** R E E N T R A N T I M P L E M E N T A T I O N ********/ + /******** ********/ + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + +/* a simple macro to access the file component's data */ +#define files ( *((TFile_Component*)engine.file_component) ) + +#define CUR_Stream STREAM2REC( stream ) /* re-entrant macros */ +#define CUR_Frame (*frame) + +#define STREAM_VARS stream, +#define STREAM_VAR stream + + +/******************************************************************* + * + * Function : TTFile_Init + * + * Description : Initializes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Init( PEngine_Instance engine ) + { + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTFile_Done + * + * Description : Finalizes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Done( PEngine_Instance engine ) + { + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Use_Stream + * + * Description : Duplicates a stream for a new usage. + * + * Input : input_stream source stream to duplicate + * copy address of target duplicate stream + * + * Output : error code. + * The target stream is set to NULL in case of failure. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Use_Stream( TT_Stream input_stream, + TT_Stream* copy ) + { + PStream_Rec rec = STREAM2REC( input_stream ); + + return TT_Open_Stream( rec->name, copy ); + } + + +/******************************************************************* + * + * Function : TT_Done_Stream + * + * Description : Releases a given stream. + * + * Input : stream target stream + * + * Output : + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Done_Stream( TT_Stream* stream ) + { + return TT_Close_Stream( stream ); + } + + +/******************************************************************* + * + * Function : TT_Access_Frame + * + * Description : Notifies the component that we're going to read + * 'size' bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx() + * functions easily. + * + * Input : size number of bytes to access. + * + * Output : SUCCESS on success. FAILURE on error. + * + * Notes: The function fails if the byte range is not within the + * the file, or if there is not enough memory to cache + * the bytes properly (which usually means that `size' is + * too big in both cases). + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Access_Frame( STREAM_ARGS FRAME_ARGS int size ) + { + TT_Error error; + + + if ( CUR_Frame.address != NULL ) + return TT_Err_Nested_Frame_Access; + + if ( ALLOC( CUR_Frame.address, size ) ) + return error; + CUR_Frame.size = size; + + error = TT_Read_File( STREAM_VARS (void*)CUR_Frame.address, size ); + if ( error ) + { + FREE( CUR_Frame.address ); + CUR_Frame.size = 0; + } + + CUR_Frame.cursor = CUR_Frame.address; + return error; + } + + +/******************************************************************* + * + * Function : TT_Check_And_Access_Frame + * + * Description : Notifies the component that we're going to read + * `size' bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx() + * functions easily. + * + * Input : size number of bytes to access. + * + * Output : SUCCESS on success. FAILURE on error. + * + * Notes: The function truncates `size' if the byte range is not + * within the file. + * + * It will fail if there is not enough memory to cache + * the bytes properly (which usually means that `size' is + * too big). + * + * It will fail if you make two consecutive calls + * to TT_Access_Frame(), without a TT_Forget_Frame() between + * them. + * + * The only difference with TT_Access_Frame() is that we + * check that the frame is within the current file. We + * otherwise truncate it. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Check_And_Access_Frame( STREAM_ARGS FRAME_ARGS int size ) + { + TT_Error error; + Long readBytes; + + + if ( CUR_Frame.address != NULL ) + return TT_Err_Nested_Frame_Access; + + if ( ALLOC( CUR_Frame.address, size ) ) + return error; + CUR_Frame.size = size; + + readBytes = CUR_Stream->size - TT_File_Pos( STREAM_VAR ); + if ( size > readBytes ) + size = readBytes; + + error = TT_Read_File( STREAM_VARS (void*)CUR_Frame.address, size ); + if ( error ) + { + FREE( CUR_Frame.address ); + CUR_Frame.size = 0; + } + + CUR_Frame.cursor = CUR_Frame.address; + return error; + } + + +/******************************************************************* + * + * Function : TT_Forget_Frame + * + * Description : Releases a cached frame after reading. + * + * Input : None + * + * Output : SUCCESS on success. FAILURE on error. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Forget_Frame( FRAME_ARG ) + { + if ( CUR_Frame.address == NULL ) + return TT_Err_Nested_Frame_Access; + + FREE( CUR_Frame.address ); + ZERO_Frame( CUR_Frame ); + + return TT_Err_Ok; + } + +#endif /* TT_CONFIG_OPTION_THREAD_SAFE */ + + + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + /*********** ***********/ + /*********** C O M M O N I M P L E M E N T A T I O N ***********/ + /*********** ***********/ + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + +/******************************************************************* + * + * Function : Stream_Activate + * + * Description : activates a stream, this will either: + * - open a new file handle if the stream is closed + * - move the stream to the head of the linked list + * + * Input : stream the stream to activate + * + * Output : error condition. + * + * Note : this function is also called with fresh new streams + * created by TT_Open_Stream(). They have their 'size' + * field set to -1. + * + ******************************************************************/ + + static TT_Error Stream_Activate( PStream_Rec stream ) + { + ULONG ulAction; /* !Mike! */ + + if ( !stream->opened ) + { +#if 0 + if ( !(stream->file = fopen( stream->name, "rb" )) ) /* !Mike! */ +#endif + +/* XXX : Strange. GCC/EMX wants an (Byte*) for the file name? */ +#ifdef __EMX__ + + if ( DosOpen( (Byte*)stream->name, &(stream->file), + &ulAction, 0, + 0, OPEN_ACTION_OPEN_IF_EXISTS, + OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, NULL ) ) + return TT_Err_Could_Not_ReOpen_File; + +#else + + if ( DosOpen( stream->name, &(stream->file), + &ulAction, 0, + 0, OPEN_ACTION_OPEN_IF_EXISTS, + OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, NULL ) ) + return TT_Err_Could_Not_ReOpen_File; + +#endif /* __EMX__ */ + + stream->opened = TRUE; + + /* A newly created stream has a size field of -1 */ + if ( stream->size < 0 ) + { +#if 0 + fseek( stream->file, 0, SEEK_END ); /* !Mike! */ + stream->size = ftell( stream->file ); +#endif + + DosSetFilePtr( stream->file, 0, FILE_END, (ULONG *)&(stream->size) ); +#if 0 + fseek( stream->file, 0, SEEK_SET ); +#endif + + DosSetFilePtr( stream->file, 0, FILE_BEGIN, &ulAction ); + } + + /* Reset cursor in file */ + if ( stream->position ) + { +#if 0 /* !Mike! */ + if ( fseek( stream->file, stream->position, SEEK_SET ) != 0 ) +#endif + + if ( DosSetFilePtr( stream->file, stream->position, + FILE_BEGIN, &ulAction ) ) + { + /* error during seek */ +#if 0 + fclose( stream->file ); /* !Mike! */ +#endif + + DosClose( stream->file ); + stream->opened = FALSE; + return TT_Err_Could_Not_ReSeek_File; + } + } + } + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Stream_DeActivate + * + * Description : deactivates a stream, this will: + * - close its file handle if it was opened + * - remove it from the opened list if necessary + * + * Input : stream the stream to deactivate + * + * Output : Error condition + * + * Note : the function is called whenever a stream is deleted + * (_not_ when a stream handle's is closed due to an + * activation). However, the stream record isn't + * destroyed by it... + * + ******************************************************************/ + + static TT_Error Stream_Deactivate( PStream_Rec stream ) + { + if ( stream->opened ) + { + /* Save its current position within the file */ +#if 0 + stream->position = ftell( stream->file ); /* !Mike! */ +#endif + + DosSetFilePtr( stream->file, 0, FILE_CURRENT, + (ULONG *)&(stream->position) ); +#if 0 + fclose( stream->file ); /* !Mike! */ +#endif + + DosClose( stream->file ); + stream->file = 0; + stream->opened = FALSE; + } + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Stream_Size + * + * Description : Returns the length of a given stream, even if it + * is flushed. + * + * Input : stream the stream + * + * Output : length of stream in bytes. + * + ******************************************************************/ + + EXPORT_FUNC + Long TT_Stream_Size( TT_Stream stream ) + { + PStream_Rec rec = STREAM2REC( stream ); + + + if ( rec ) + return rec->size; + else + return 0; /* invalid stream - return 0 */ + } + + +/******************************************************************* + * + * Function : TT_Open_Stream + * + * Description : Opens the font file and saves the total file size. + * + * Input : error address of stream's error variable + * (re-entrant build only) + * filepathname pathname of the file to open + * stream address of target TT_Stream structure + * + * Output : SUCCESS on sucess, FAILURE on error. + * The target stream is set to -1 in case of failure. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TT_Open_Stream( const String* filepathname, + TT_Stream* stream ) + { + int len; + TT_Error error; + PStream_Rec stream_rec; + + + if ( ALLOC( *stream, sizeof ( TStream_Rec ) ) ) + return error; + + stream_rec = STREAM2REC( *stream ); + + stream_rec->file = NULLHANDLE; /* !Mike! */ + stream_rec->size = -1; + stream_rec->base = 0; + stream_rec->opened = FALSE; + stream_rec->position = 0; + + len = strlen( filepathname ) + 1; + if ( ALLOC( stream_rec->name, len ) ) + goto Fail; + + strncpy( (String*)stream_rec->name, filepathname, len ); + + error = Stream_Activate( stream_rec ); + if ( error ) + goto Fail_Activate; + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + CUR_Stream = stream_rec; +#endif + + return TT_Err_Ok; + + Fail_Activate: + FREE( stream_rec->name ); + Fail: + FREE( stream_rec ); + return error; + } + + +/******************************************************************* + * + * Function : TT_Close_Stream + * + * Description : Closes a stream. + * + * Input : stream address of target TT_Stream structure + * + * Output : SUCCESS (always). + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TT_Close_Stream( TT_Stream* stream ) + { + PStream_Rec rec = STREAM2REC( *stream ); + + + Stream_Deactivate( rec ); + FREE( rec->name ); + FREE( rec ); + + HANDLE_Set( *stream, NULL ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Flush_Stream + * + * Description : Flushes a stream, i.e., closes its file handle. + * + * Input : stream address of target TT_Stream structure + * + * Output : Error code + * + * NOTE : Never flush the current opened stream. This means that + * you should _never_ call this function between a + * TT_Use_Stream() and a TT_Done_Stream()! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Flush_Stream( TT_Stream* stream ) + { + PStream_Rec rec = STREAM2REC( *stream ); + + + if ( rec ) + { + Stream_Deactivate( rec ); + return TT_Err_Ok; + } + else + return TT_Err_Invalid_Argument; + } + + +/******************************************************************* + * + * Function : TT_Seek_File + * + * Description : Seeks the file cursor to a different position. + * + * Input : position new position in file + * + * Output : SUCCESS on success. FAILURE if out of range. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Seek_File( STREAM_ARGS long position ) + { + ULONG ibActual; /* !Mike! */ + + + position += CUR_Stream->base; + +#if 0 + if ( fseek( CUR_Stream->file, position, SEEK_SET ) ) /* !Mike! */ +#endif + + if ( DosSetFilePtr( CUR_Stream->file, position, FILE_BEGIN , &ibActual ) ) + return TT_Err_Invalid_File_Offset; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Skip_File + * + * Description : Skips forward the file cursor. + * + * Input : distance number of bytes to skip + * + * Output : see TT_Seek_File() + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Skip_File( STREAM_ARGS long distance ) + { + ULONG ibActual; /* !Mike! */ + + +#if 0 + return TT_Seek_File( STREAM_VARS ftell( CUR_Stream->file ) - + CUR_Stream->base + distance ); /* !Mike! */ +#endif + + DosSetFilePtr( CUR_Stream->file, 0, FILE_CURRENT, &ibActual ); + return TT_Seek_File( STREAM_VARS ibActual - CUR_Stream->base + distance ); + } + + +/******************************************************************* + * + * Function : TT_Read_File + * + * Description : Reads a chunk of the file and copies it to memory. + * + * Input : buffer target buffer + * count length in bytes to read + * + * Output : SUCCESS on success. FAILURE if out of range. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Read_File( STREAM_ARGS void* buffer, long count ) + { + ULONG cbActual; /* !Mike! */ + +#if 0 /* !Mike! */ + if ( fread( buffer, 1, count, CUR_Stream->file ) != (unsigned long)count ) +#endif + + DosRead( CUR_Stream->file, buffer, count, &cbActual ); + if ( cbActual != (unsigned long)count ) + return TT_Err_Invalid_File_Read; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Read_At_File + * + * Description : Reads file at a specified position. + * + * Input : position position to seek to before read + * buffer target buffer + * count number of bytes to read + * + * Output : SUCCESS on success. FAILURE if error. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Read_At_File( STREAM_ARGS long position, + void* buffer, + long count ) + { + TT_Error error; + + + if ( ( error = TT_Seek_File( STREAM_VARS position ) ) || + ( error = TT_Read_File( STREAM_VARS buffer, count ) ) ) + return error; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_File_Pos + * + * Description : Returns current file seek pointer. + * + * Input : none + * + * Output : current file position + * + ******************************************************************/ + + EXPORT_FUNC + Long TT_File_Pos( STREAM_ARG ) + { + ULONG ibActual; /* !Mike! */ + + +#if 0 + return ftell( CUR_Stream->file ) - CUR_Stream->base; /* !Mike! */ +#endif + + DosSetFilePtr( CUR_Stream->file, 0, FILE_CURRENT, &ibActual ); + return ibActual - CUR_Stream->base; + } + + +/******************************************************************* + * + * Function : GET_Byte + * + * Description : Extracts a byte from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted Byte. + * + ******************************************************************/ +#if 0 + EXPORT_FUNC + Byte TT_Get_Byte( FRAME_ARG ) + { + CHECK_FRAME( CUR_Frame, 1 ); + + return (Byte)(*CUR_Frame.cursor++); + } +#endif + +/******************************************************************* + * + * Function : GET_Char + * + * Description : Extracts a signed byte from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted char. + * + ******************************************************************/ + + EXPORT_FUNC + Char TT_Get_Char( FRAME_ARG ) + { + CHECK_FRAME( CUR_Frame, 1 ); + + return (Char)(*CUR_Frame.cursor++); + } + + +/******************************************************************* + * + * Function : GET_Short + * + * Description : Extracts a short from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted short. + * + ******************************************************************/ + + EXPORT_FUNC + short TT_Get_Short( FRAME_ARG ) + { + short getshort; + + + CHECK_FRAME( CUR_Frame, 2 ); + + getshort = ((short)CUR_Frame.cursor[0] << 8) | + (short)CUR_Frame.cursor[1]; + + CUR_Frame.cursor += 2; + + return getshort; + } + + +/******************************************************************* + * + * Function : GET_UShort + * + * Description : Extracts an unsigned short from the frame. + * + * Input : None or current frame + * + * Output : Extracted ushort. + * + ******************************************************************/ +#if 0 + EXPORT_FUNC + unsigned short TT_Get_UShort( FRAME_ARG ) + { + unsigned short getshort; + + + CHECK_FRAME( CUR_Frame, 2 ); + + getshort = ((unsigned short)CUR_Frame.cursor[0] << 8) | + (unsigned short)CUR_Frame.cursor[1]; + + CUR_Frame.cursor += 2; + + return getshort; + } +#endif + +/******************************************************************* + * + * Function : GET_Long + * + * Description : Extracts a long from the frame. + * + * Input : None or current frame + * + * Output : Extracted long. + * + ******************************************************************/ + + EXPORT_FUNC + long TT_Get_Long( FRAME_ARG ) + { + long getlong; + + + CHECK_FRAME( CUR_Frame, 4 ); + + getlong = ((long)CUR_Frame.cursor[0] << 24) | + ((long)CUR_Frame.cursor[1] << 16) | + ((long)CUR_Frame.cursor[2] << 8 ) | + (long)CUR_Frame.cursor[3]; + + CUR_Frame.cursor += 4; + + return getlong; + } + + +/******************************************************************* + * + * Function : GET_ULong + * + * Description : Extracts an unsigned long from the frame. + * + * Input : None + * + * Output : Extracted ulong. + * + ******************************************************************/ +#if 0 + EXPORT_FUNC + unsigned long TT_Get_ULong( FRAME_ARG ) + { + unsigned long getlong; + + + CHECK_FRAME( CUR_Frame, 4 ); + + getlong = ( ((unsigned long)CUR_Frame.cursor[0] << 24) | + ((unsigned long)CUR_Frame.cursor[1] << 16) | + ((unsigned long)CUR_Frame.cursor[2] << 8 ) | + (unsigned long)CUR_Frame.cursor[3] ); + + CUR_Frame.cursor += 4; + + return getlong; + } +#endif + + +/* END */ diff --git a/lib/arch/unix/.cvsignore b/lib/arch/unix/.cvsignore new file mode 100644 index 0000000..f3c7a7c --- /dev/null +++ b/lib/arch/unix/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/lib/arch/unix/Makefile.in b/lib/arch/unix/Makefile.in new file mode 100644 index 0000000..321cc7f --- /dev/null +++ b/lib/arch/unix/Makefile.in @@ -0,0 +1,244 @@ +# This file is part of the FreeType project. +# +# lib/arch/unix/Makefile.in + +ARCH = arch/unix +FT_MAKEFILE = $(ARCH)/Makefile + +RM = @RM@ +RMF = @RM@ -f +RMDIR = @RMDIR@ +LN_S = @LN_S@ + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ + +VPATH = @srcdir@/../.. +srcdir = @srcdir@/../.. + +top_builddir=.. + +CC = @CC@ +CPP = @CPP@ + +LIBTOOL = $(top_builddir)/libtool +MKINSTALLDIRS = $(srcdir)/../mkinstalldirs + +version_info = @version_info@ + +include $(top_builddir)/MakeSub + +############### PORTABILITY COMPONENTS ######################## + +# location of memory component +MEMSRC = ttmemory.c + +# location of file component +FILESRC = @TT_FILE_COMPONENT@ + +# location of mutex component +MUTEXSRC = ttmutex.c + +# location of default extensions +FTEXTDIR = $(srcdir)/extend + + +# default extensions sources +EXTSRC = $(FTEXTDIR)/ftxkern.c \ + $(FTEXTDIR)/ftxgasp.c \ + $(FTEXTDIR)/ftxpost.c \ + $(FTEXTDIR)/ftxcmap.c \ + $(FTEXTDIR)/ftxsbit.c \ + $(FTEXTDIR)/ftxwidth.c \ + $(FTEXTDIR)/ftxerr18.c \ + $(FTEXTDIR)/ftxgsub.c \ + $(FTEXTDIR)/ftxgpos.c \ + $(FTEXTDIR)/ftxgdef.c \ + $(FTEXTDIR)/ftxopen.c + +EXTOBJ = ftxkern.lo \ + ftxgasp.lo \ + ftxpost.lo \ + ftxcmap.lo \ + ftxsbit.lo \ + ftxwidth.lo \ + ftxerr18.lo \ + ftxgsub.lo \ + ftxgpos.lo \ + ftxgdef.lo \ + ftxopen.lo + +# all engine sources +SRC_M = $(srcdir)/ttapi.c \ + $(srcdir)/ttcache.c \ + $(srcdir)/ttcalc.c \ + $(srcdir)/ttcmap.c \ + $(srcdir)/ttdebug.c \ + $(srcdir)/ttextend.c \ + $(srcdir)/ttgload.c \ + $(srcdir)/ttinterp.c \ + $(srcdir)/ttload.c \ + $(srcdir)/ttobjs.c \ + $(srcdir)/ttraster.c \ + $(srcdir)/$(FILESRC) \ + $(srcdir)/$(MEMSRC) \ + $(srcdir)/$(MUTEXSRC) +SRC_S = $(srcdir)/$(ARCH)/freetype.c + +# all header files +HEADERS = $(srcdir)/freetype.h \ + $(srcdir)/fterrid.h \ + $(srcdir)/ftnameid.h \ + $(FTEXTDIR)/ftxkern.h \ + $(FTEXTDIR)/ftxgasp.h \ + $(FTEXTDIR)/ftxcmap.h \ + $(FTEXTDIR)/ftxsbit.h \ + $(FTEXTDIR)/ftxpost.h \ + $(FTEXTDIR)/ftxwidth.h \ + $(FTEXTDIR)/ftxerr18.h \ + $(FTEXTDIR)/ftxgsub.h \ + $(FTEXTDIR)/ftxgpos.h \ + $(FTEXTDIR)/ftxgdef.h \ + $(FTEXTDIR)/ftxopen.h + +# all engine objects +OBJ_M = ttapi.lo \ + ttcache.lo \ + ttcalc.lo \ + ttcmap.lo \ + ttdebug.lo \ + ttextend.lo \ + ttgload.lo \ + ttinterp.lo \ + ttload.lo \ + ttobjs.lo \ + ttraster.lo \ + file.lo \ + memory.lo \ + mutex.lo \ + $(EXTOBJ) +OBJ_S = freetype.lo $(EXTOBJ) + + +# include paths +INCLUDES = -I. -I$(top_builddir) -I$(srcdir) -I$(FTEXTDIR) + +# C flags +CFLAGS = @CFLAGS@ @XX_CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +FT_CFLAGS = $(CFLAGS) $(INCLUDES) + +# linker flags +FT_LIBS = @LIBS@ + +# i18n stuff +LOCALEDIR = @LOCALEDIR@ + + +all: do_link + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES="$(OBJ_S)" libttf.la + +debug: do_link + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES="$(OBJ_M)" libttf.la + + +do_link: + -$(RMF) memory.c file.c mutex.c + $(LN_S) $(srcdir)/$(MEMSRC) memory.c + $(LN_S) $(srcdir)/$(FILESRC) file.c + $(LN_S) $(srcdir)/$(MUTEXSRC) mutex.c + + +.SUFFIXES: .lo +.c.lo: + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) $< + +ftxkern.lo: $(FTEXTDIR)/ftxkern.c + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) $(FTEXTDIR)/ftxkern.c + +ftxgasp.lo: $(FTEXTDIR)/ftxgasp.c + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) $(FTEXTDIR)/ftxgasp.c + +ftxpost.lo: $(FTEXTDIR)/ftxpost.c + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) $(FTEXTDIR)/ftxpost.c + +ftxcmap.lo: $(FTEXTDIR)/ftxcmap.c + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) $(FTEXTDIR)/ftxcmap.c + +ftxsbit.lo: $(FTEXTDIR)/ftxsbit.c + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) $(FTEXTDIR)/ftxsbit.c + +ftxwidth.lo: $(FTEXTDIR)/ftxwidth.c + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) $(FTEXTDIR)/ftxwidth.c + +ftxerr18.lo: $(FTEXTDIR)/ftxerr18.c + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) \ + -DLOCALEDIR='"$(LOCALEDIR)"' \ + $(FTEXTDIR)/ftxerr18.c + +ftxgsub.lo: $(FTEXTDIR)/ftxgsub.c + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) $(FTEXTDIR)/ftxgsub.c + +ftxgpos.lo: $(FTEXTDIR)/ftxgpos.c + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) $(FTEXTDIR)/ftxgpos.c + +ftxgdef.lo: $(FTEXTDIR)/ftxgdef.c + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) $(FTEXTDIR)/ftxgdef.c + +ftxopen.lo: $(FTEXTDIR)/ftxopen.c + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) $(FTEXTDIR)/ftxopen.c + +freetype.lo: $(SRC_S) $(SRC_M) + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) \ + -DLOCALEDIR='"$(LOCALEDIR)"' \ + -DTT_MAKE_OPTION_SINGLE_OBJECT \ + $(SRC_S) + +libttf.la: $(LIB_FILES) + $(LIBTOOL) --mode=link $(CC) -o libttf.la $(LIB_FILES) \ + -rpath $(libdir) \ + -version-info $(version_info) $(FT_LIBS) + +install: libttf.la + $(MKINSTALLDIRS) $(libdir) $(includedir)/freetype + $(LIBTOOL) --mode=install $(INSTALL) libttf.la $(libdir) + -for P in $(HEADERS) ; do \ + $(INSTALL_DATA) $$P $(includedir)/freetype ; \ + done + +uninstall: + -$(LIBTOOL) --mode=uninstall $(RM) $(libdir)/libttf.la + -$(RMF) $(includedir)/freetype/* + -$(RMDIR) $(includedir)/freetype + +clean: + -$(RMF) $(OBJ_S) $(OBJ_M) *.o + +distclean: clean + -$(RMF) file.c memory.c mutex.c + -$(RMF) libttf.la + -$(RMF) *.orig *~ core *.core + -$(RMF) $(ARCH)/Makefile + -$(RMF) .libs/* + -$(RMDIR) .libs + +depend: do_link + (echo '/^#.* PUT NO STUFF BELOW/,$$d' ; echo w ; echo q) | \ + ed - $(ARCH)/Makefile + echo '# Dependencies generated by make depend: PUT NO STUFF BELOW' \ + >> $(ARCH)/Makefile + for file in $(SRC_S) $(SRC_M) $(EXTSRC) ; do \ + $(CPP) $(CPPFLAGS) $(INCLUDES) $$file | \ + sed -n -e 's|^# [1-9][0-9]* "\([^/].*\.h\)".*|\1|p' \ + -e 's|^# [1-9][0-9]* "\($(srcdir)/.*\.h\)".*|\1|p' | \ + sed -e 's|/\./|.|g' -e "s/^/`basename $$file .c`.lo: /" ; \ + done | \ + sort -u | \ + awk '{ if (LINE == 1) \ + { line = last = $$1 } \ + else if ($$1 != last) \ + { print line ; line = last = $$1 } \ + line = line " " $$2 } \ + END { print line }' >> $(ARCH)/Makefile + +# Dependencies generated by make depend: PUT NO STUFF BELOW diff --git a/lib/arch/unix/freetype.c b/lib/arch/unix/freetype.c new file mode 100644 index 0000000..9a4860d --- /dev/null +++ b/lib/arch/unix/freetype.c @@ -0,0 +1,27 @@ +/* This file is part of the FreeType project */ + +/* Single object library component for Unix */ + +#include "ttapi.c" +#include "ttcache.c" +#include "ttcalc.c" +#include "ttcmap.c" +#include "ttdebug.c" +#include "ttgload.c" +#include "ttinterp.c" +#include "ttload.c" +#include "ttobjs.c" +#include "ttraster.c" + +/* The Makefile creates proper links to following three files */ + +#include "file.c" +#include "memory.c" +#include "mutex.c" + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE +#include "ttextend.c" +#endif + + +/* END */ diff --git a/lib/arch/unix/ttmmap.c b/lib/arch/unix/ttmmap.c new file mode 100644 index 0000000..aac7c10 --- /dev/null +++ b/lib/arch/unix/ttmmap.c @@ -0,0 +1,1027 @@ +/******************************************************************* + * + * ttmmap.c 2.0 + * + * Memory-Mapped file component ( replaces ttfile.c ). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * Changes between 2.0 and 1.3 : + * + * - adopted new design/separation introduced in ttfile.c 2.0 + * + ******************************************************************/ + +#include "ttconfig.h" + +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#ifndef MAP_FILE +#define MAP_FILE 0x00 +#endif + +/* + * The prototype for munmap() is not provided on SunOS. This needs to + * have a check added later to see if the GNU C library is being used. + * If so, then this prototype is not needed. + */ +#if defined(__sun__) && !defined(SVR4) && !defined(__SVR4) + extern int munmap( caddr_t addr, int len ); +#endif + +#include +#ifdef HAVE_FCNTL_H +#include +#endif + + +#include "freetype.h" +#include "tttypes.h" +#include "ttdebug.h" +#include "ttengine.h" +#include "ttmutex.h" +#include "ttmemory.h" +#include "ttfile.h" /* our prototypes */ + + /* This definition is mandatory for each file component! */ + EXPORT_FUNC + const TFileFrame TT_Null_FileFrame = { NULL, 0, 0 }; + + /* It has proven useful to do some bounds checks during */ + /* development phase. Define DEBUG_FILE when compiling */ + /* this component to enable them. */ + +#ifdef DEBUG_FILE +#define CHECK_FRAME( frame, n ) \ + do { \ + if ( frame.cursor + n > frame.address + frame.size ) \ + Panic( "Frame boundary error!\n" ); \ + } while ( 0 ) +#else +#define CHECK_FRAME( frame, n ) \ + do { \ + } while( 0 ) +#endif + + struct _TFileMap + { + String* base; /* base address of mapped file */ + Int refcount; /* reference count for mmaped region */ + Long size; /* stream size in file */ + Long offset; /* offset in file */ + }; + + typedef struct _TFileMap TFileMap; + +#define MAP_Address( map ) (Byte*)( (map)->base + (map)->offset ) + + /* The stream record structure */ + typedef struct _TStream_Rec + { + TFileMap* map; /* mapped file description */ + Long pos ; /* cursor in mapped file */ + } TStream_Rec; + + typedef TStream_Rec* PStream_Rec; + +#define STREAM2REC( x ) ( (TStream_Rec*)HANDLE_Val( x ) ) + + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + /**** ****/ + /**** N O N R E E N T R A N T I M P L E M E N T A T I O N ****/ + /**** ****/ + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + + /* The TFile_Component structure holds all the data that was */ + /* previously declared static or global in this component. */ + /* */ + /* It is accessible through the 'engine.file_component' */ + /* variable in re-entrant builds, or directly through the */ + /* static 'files' variable in other builds. */ + + struct _TFile_Component + { + TMutex lock; /* used by the thread-safe build only */ + PStream_Rec stream; /* current stream */ + TFileFrame frame; /* current frame */ + }; + + typedef struct _TFile_Component TFile_Component; + +/* The macro CUR_Stream denotes the current input stream */ +/* Note that for the re-entrant version, the 'stream' name has been */ +/* chosen according to the macro STREAM_ARGS. */ + +/* The macro CUR_Frame denotes the current file frame */ +/* Note that for the re-entrant version, the 'frame' name has been */ +/* chosen according to the macro FRAME_ARGS. */ + +/* The macro STREAM_VAR is used when calling public functions */ +/* that need an 'optional' stream argument. */ + +#define CUR_Stream files.stream /* thread-safe macros */ +#define CUR_Frame files.frame + +#define STREAM_VARS /* void */ +#define STREAM_VAR /* void */ + + /* the 'files' variable is only defined in non-reentrant builds */ + + static TFile_Component files; + + + +/******************************************************************* + * + * Function : TTFile_Init + * + * Description : Initializes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Init( PEngine_Instance engine ) + { + MUTEX_Create( files.lock ); + files.stream = NULL; + ZERO_Frame( files.frame ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTFile_Done + * + * Description : Finalizes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Done( PEngine_Instance engine ) + { + MUTEX_Destroy( files.lock ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Use_Stream + * + * Description : Copies or duplicates a given stream. + * + * Input : org_stream original stream + * stream target stream (copy or duplicate) + * + * Output : Error code + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Use_Stream( TT_Stream org_stream, + TT_Stream* stream ) + { + MUTEX_Lock( files.lock ); + *stream = org_stream; + files.stream = STREAM2REC( org_stream ); /* set current stream */ + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Done_Stream + * + * Description : Releases a given stream. + * + * Input : stream + * + * Output : Error code + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Done_Stream( TT_Stream* stream ) + { + HANDLE_Set( *stream, NULL ); + MUTEX_Release( files.lock ); + + return TT_Err_Ok; + } + +#else /* TT_CONFIG_OPTION_THREAD_SAFE */ + + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + /******** ********/ + /******** R E E N T R A N T I M P L E M E N T A T I O N ********/ + /******** ********/ + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + +#define CUR_Stream STREAM2REC( stream ) /* re-entrant macros */ +#define CUR_Frame (*frame) + +#define STREAM_VARS stream, +#define STREAM_VAR stream + + +/******************************************************************* + * + * Function : TTFile_Init + * + * Description : Initializes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Init( PEngine_Instance engine ) + { + engine.file_component = NULL; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTFile_Done + * + * Description : Finalizes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Done( PEngine_Instance engine ) + { + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Use_Stream + * + * Description : Copies or duplicates a given stream. + * + * Input : org_stream original stream + * stream target stream (copy or duplicate) + * + * Output : Error code. The output stream is set to NULL in + * case of Failure. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Use_Stream( TT_Stream input_stream, + TT_Stream* copy ) + { + TT_Error error; + PStream_Rec stream_rec; + PStream_Rec copy_rec; + + + stream_rec = STREAM2REC( input_stream ); + + if ( ALLOC( copy_rec, sizeof ( TStream_Rec ) ) ) + goto Fail; + + HANDLE_Set( *copy, copy_rec ); + + copy_rec->map->refcount++; + copy_rec->pos = 0; + + return TT_Err_Ok; + + Fail: + HANDLE_Set( *copy, NULL ); + return error; + } + + +/******************************************************************* + * + * Function : TT_Done_Stream + * + * Description : Releases a given stream. + * + * Input : stream + * + * Output : error code + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Done_Stream( TT_Stream* stream ) + { + return TT_Close_Stream( stream ); + } + +#endif /* TT_CONFIG_OPTION_THREAD_SAFE */ + + + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + /*********** ***********/ + /*********** C O M M O N I M P L E M E N T A T I O N ***********/ + /*********** ***********/ + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + +/******************************************************************* + * + * Function : AllocateMap + * + * Description : Allocates a new map from the table. + * + * Output : Pointer to new stream rec. NULL in case of failure. + * + ******************************************************************/ + + static + TFileMap* Allocate_Map( void ) + { + TFileMap* result; + + + if ( MEM_Alloc( result, sizeof ( TFileMap ) ) ) + return NULL; + + result->refcount = 1; + return result; + } + + +/******************************************************************* + * + * Function : ReleaseMap + * + * Description : Releases a used map to the table if reference i + * counter reaches zero. + * + * Input : map + * + * Output : None. + * + * Note : Called by TT_Close_File() + * + ******************************************************************/ + + static + void Release_Map ( TFileMap* map ) + { + map->refcount--; + if ( map->refcount <= 0 ) + { + munmap ( (void*)map->base, map->size ); + FREE( map ); + } + } + + +/******************************************************************* + * + * Function : TT_Open_Stream + * + * Description : Opens the font file and saves the total file size. + * + * Input : error address of stream's error variable + * (re-entrant build only). + * filepathname pathname of the file to open + * stream address of target TT_Stream structure + * + * Output : SUCCESS on success, FAILURE on error. + * The target stream is set to -1 in case of failure. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TT_Open_Stream( const String* filepathname, + TT_Stream* stream ) + { + TT_Error error; + Int file; + PStream_Rec stream_rec; + TFileMap* map; + struct stat stat_buf; + + + if ( ALLOC( *stream, sizeof ( TStream_Rec ) ) ) + return error; + + map = Allocate_Map(); + if ( !map ) + { + error = TT_Err_Out_Of_Memory; + goto Memory_Fail; + } + + stream_rec = STREAM2REC( *stream ); + + file = open( (String*)filepathname, O_RDONLY ); + if ( file < 0 ) + goto File_Fail; + + if ( fstat( file, &stat_buf ) < 0 ) + goto Map_Fail; + + map->offset = 0; + map->size = stat_buf.st_size + map->offset; + map->base = mmap( NULL, + map->size, + PROT_READ, + MAP_FILE | MAP_PRIVATE, + file, + 0 ); + + if ( (long)map->base == -1 ) + goto Map_Fail; + + close( file ); + + stream_rec->map = map; + stream_rec->pos = 0; + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + CUR_Stream = stream_rec; +#endif + + return TT_Err_Ok; + + Map_Fail: + close( file ); + + File_Fail: + error = TT_Err_Could_Not_Open_File; + FREE( map ); + + Memory_Fail: + FREE( *stream ); + return error; + } + + +/******************************************************************* + * + * Function : TT_Close_Stream + * + * Description : Closes a stream. + * + * Input : stream + * + * Output : SUCCESS (always) + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TT_Close_Stream( TT_Stream* stream ) + { + PStream_Rec rec = STREAM2REC( *stream ); + + + Release_Map( rec->map ); + FREE( rec ); + + HANDLE_Set( *stream, NULL ); + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Flush_Stream + * + * Description : Flushes a stream, i.e., closes its file handle. + * + * Input : stream address of target TT_Stream structure + * + * Output : Error code + * + * NOTE : Never flush the current opened stream. This means that + * you should _never_ call this function between a + * TT_Use_Stream() and a TT_Done_Stream()! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Flush_Stream( TT_Stream* stream ) + { + /* XXX - DUMMY IMPLEMENTATION */ + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Stream_Size + * + * Description : Returns the length of a given stream, even if it + * is flushed. + * + * Input : stream the stream + * + * Output : Length of stream in bytes. + * + ******************************************************************/ + + EXPORT_FUNC + Long TT_Stream_Size( TT_Stream stream ) + { + PStream_Rec rec = STREAM2REC( stream ); + + + if ( rec ) + return rec->map->size; + else + return 0; /* invalid stream - return 0 */ + } + + +/******************************************************************* + * + * Function : TT_Seek_File + * + * Description : Seeks the file cursor to a different position. + * + * Input : position new position in file + * + * Output : SUCCESS on success. FAILURE if out of range. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Seek_File( STREAM_ARGS Long position ) + { + if ( position > CUR_Stream->map->size ) + return TT_Err_Invalid_File_Offset; + + CUR_Stream->pos = position; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Skip_File + * + * Description : Skips forward the file cursor. + * + * Input : distance number of bytes to skip + * + * Output : see TT_Seek_File + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Skip_File( STREAM_ARGS Long distance ) + { + return TT_Seek_File( STREAM_VARS CUR_Stream->pos + distance ); + } + + +/******************************************************************* + * + * Function : TT_Read_File + * + * Description : Reads a chunk of the file and copies it to memory. + * + * Input : buffer target buffer + * count length in bytes to read + * + * Output : SUCCESS on success. FAILURE if out of range. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Read_File( STREAM_ARGS void* buffer, Long count ) + { + if ( CUR_Stream->pos + count > CUR_Stream->map->size ) + return TT_Err_Invalid_File_Read; + + MEM_Copy( buffer, + MAP_Address( CUR_Stream->map ) + CUR_Stream->pos, count ); + CUR_Stream->pos += count; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Read_At_File + * + * Description : Reads file at a specified position. + * + * Input : position position to seek to before read + * buffer target buffer + * count number of bytes to read + * + * Output : SUCCESS on success. FAILURE if error. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Read_At_File( STREAM_ARGS Long position, + void* buffer, + Long count ) + { + TT_Error error; + + + if ( (error = TT_Seek_File( STREAM_VARS position )) || + (error = TT_Read_File( STREAM_VARS buffer, count )) ) + return error; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_File_Pos + * + * Description : Returns current file seek pointer. + * + * Input : none + * + * Output : current file position + * + ******************************************************************/ + + EXPORT_FUNC + Long TT_File_Pos( STREAM_ARG ) + { + return CUR_Stream->pos; + } + + +/******************************************************************* + * + * Function : TT_Access_Frame + * + * Description : Notifies the component that we're going to read + * 'size' bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx() + * functions easily. + * + * Input : size number of bytes to access. + * + * Output : Error code + * + * Notes: The function fails if the byte range is not within the + * the file, or if there is not enough memory to cache + * the bytes properly (which usually means that aSize is + * too big in both cases). + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Access_Frame( STREAM_ARGS FRAME_ARGS Long size ) + { + if ( CUR_Frame.address != NULL ) + return TT_Err_Nested_Frame_Access; + + if ( CUR_Stream->pos + size > CUR_Stream->map->size ) + return TT_Err_Invalid_Frame_Access; + + CUR_Frame.size = size; + CUR_Frame.address = MAP_Address( CUR_Stream->map ) + CUR_Stream->pos; + CUR_Frame.cursor = CUR_Frame.address; + + CUR_Stream->pos += size; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Check_And_Access_Frame + * + * Description : Notifies the component that we're going to read + * 'size' bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx() + * functions easily. + * + * Input : size number of bytes to access. + * + * Output : Error code + * + * Notes: The function truncates 'size' if the byte range is not + * within the file. + * + * It will fail if there is not enough memory to cache + * the bytes properly (which usually means that aSize is + * too big). + * + * It will fail if you make two consecutive calls + * to TT_Access_Frame(), without a TT_Forget_Frame() between + * them. + * + * The only difference with TT_Access_Frame() is that we + * check that the frame is within the current file. We + * otherwise truncate it. The 'overflow' is set to zero. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Check_And_Access_Frame( STREAM_ARGS FRAME_ARGS Long size ) + { + TT_Error error; + Long readBytes; + + + if ( CUR_Frame.address != NULL ) + return TT_Err_Nested_Frame_Access; + + readBytes = CUR_Stream->map->size - CUR_Stream->pos; + if ( size > readBytes ) + { + /* There is overflow, we allocate a new block then */ + if ( ALLOC( CUR_Frame.address, size ) ) + return error; + + CUR_Frame.size = size; + + /* copy the valid part */ + MEM_Copy( CUR_Frame.address, + MAP_Address( CUR_Stream->map ) + CUR_Stream->pos, + readBytes ); + } + else + { + CUR_Frame.size = size; + CUR_Frame.address = MAP_Address( CUR_Stream->map ) + CUR_Stream->pos; + } + + CUR_Frame.cursor = CUR_Frame.address; + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Forget_Frame + * + * Description : Releases a cached frame after reading. + * + * Input : None + * + * Output : SUCCESS on success. FAILURE on error. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Forget_Frame( FRAME_ARG ) + { + if ( CUR_Frame.address == NULL ) + return TT_Err_Nested_Frame_Access; + + /* If we were using a duplicate in case of overflow, free it now */ + if ( CUR_Frame.address < (Byte*)CUR_Stream->map->base || + CUR_Frame.address >= (Byte*)CUR_Stream->map->base + + CUR_Stream->map->size ) + FREE( CUR_Frame.address ); + + ZERO_Frame( files.frame ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : GET_Byte + * + * Description : Extracts a byte from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted Byte + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call.) + * + ******************************************************************/ + +#if 0 + + EXPORT_FUNC + Byte TT_Get_Byte( FRAME_ARG ) + { + CHECK_FRAME( CUR_Frame, 1 ); + + return (Byte)(*CUR_Frame.cursor++); + } + +#endif + + +/******************************************************************* + * + * Function : GET_Char + * + * Description : Extracts a signed byte from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted char + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call.) + * + ******************************************************************/ + + EXPORT_FUNC + Char TT_Get_Char( FRAME_ARG ) + { + CHECK_FRAME( CUR_Frame, 1 ); + + return (Char)(*CUR_Frame.cursor++); + } + + +/******************************************************************* + * + * Function : GET_Short + * + * Description : Extracts a short from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted short + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call.) + * + ******************************************************************/ + + EXPORT_FUNC + Short TT_Get_Short( FRAME_ARG ) + { + Short getshort; + + + CHECK_FRAME( CUR_Frame, 2 ); + + getshort = ((Short)CUR_Frame.cursor[0] << 8) | + (Short)CUR_Frame.cursor[1]; + + CUR_Frame.cursor += 2; + + return getshort; + } + + +/******************************************************************* + * + * Function : GET_UShort + * + * Description : Extracts an unsigned short from the frame. + * + * Input : None or current frame + * + * Output : Extracted ushort + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call.) + * + ******************************************************************/ + +#if 0 + + EXPORT_FUNC + UShort TT_Get_UShort( FRAME_ARG ) + { + UShort getshort; + + + CHECK_FRAME( CUR_Frame, 2 ); + + getshort = ((UShort)CUR_Frame.cursor[0] << 8) | + (UShort)CUR_Frame.cursor[1]; + + CUR_Frame.cursor += 2; + + return getshort; + } + +#endif + + +/******************************************************************* + * + * Function : GET_Long + * + * Description : Extracts a long from the frame. + * + * Input : None or current frame + * + * Output : Extracted long + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call.) + * + ******************************************************************/ + + EXPORT_FUNC + Long TT_Get_Long( FRAME_ARG ) + { + Long getlong; + + + CHECK_FRAME( CUR_Frame, 4 ); + + getlong = ((Long)CUR_Frame.cursor[0] << 24) | + ((Long)CUR_Frame.cursor[1] << 16) | + ((Long)CUR_Frame.cursor[2] << 8 ) | + (Long)CUR_Frame.cursor[3]; + + CUR_Frame.cursor += 4; + + return getlong; + } + + +/******************************************************************* + * + * Function : GET_ULong + * + * Description : Extracts an unsigned long from the frame. + * + * Input : None + * + * Output : Extracted ulong + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call.) + * + ******************************************************************/ + +#if 0 + + EXPORT_FUNC + ULong TT_Get_ULong( FRAME_ARG ) + { + ULong getlong; + + + CHECK_FRAME( CUR_Frame, 4 ); + + getlong = ( ((ULong)CUR_Frame.cursor[0] << 24) | + ((ULong)CUR_Frame.cursor[1] << 16) | + ((ULong)CUR_Frame.cursor[2] << 8 ) | + (ULong)CUR_Frame.cursor[3] ); + + CUR_Frame.cursor += 4; + + return getlong; + } + +#endif + + +/* END */ diff --git a/lib/arch/vms/README b/lib/arch/vms/README new file mode 100644 index 0000000..4107698 --- /dev/null +++ b/lib/arch/vms/README @@ -0,0 +1,20 @@ +This directory contains two files for compiling the FreeType library under +VMS: + + ft_conf.h the configuration file for the FreeType library + descrip.mms a makefile to be used with either MMS or MMK + +The files are such designed that after unpacking of freetype-1.2 one can +give the command + + MMS/DESCR=[.LIB.ARCH.VMS] + +to build the libraries. (Of course, for MMK use `MMK' on the command line +instead of `MMS'.) The makefile contains a `clean' target, but no `install' +target since I'm note sure where to install the library and the include +files. + +I did NOT do the test programs but I tested it with my own programs. + + + Jouk Jansen diff --git a/lib/arch/vms/descrip.mms b/lib/arch/vms/descrip.mms new file mode 100644 index 0000000..9115316 --- /dev/null +++ b/lib/arch/vms/descrip.mms @@ -0,0 +1,155 @@ +# This file is part of the FreeType project. +# +# DESCRIP.MMS: Make file for VMS using MMS or MMK +# Created by Jouk Jansen (joukj@hrem.stm.tudelft.nl) + +ARCH = arch.unix + +CC = cc + +############### PORTABILITY COMPONENTS ######################## + +# location of memory component +MEMSRC = ttmemory.c + +# location of file component +FILESRC = ttfile.c + +# location of mutex component +MUTEXSRC = ttmutex.c + +# location of default extensions +FTEXTDIR = [.lib.extend] + +# default extensions sources +EXTSRC = $(FTEXTDIR)ftxkern.c \ + $(FTEXTDIR)ftxgasp.c \ + $(FTEXTDIR)ftxpost.c \ + $(FTEXTDIR)ftxcmap.c \ + $(FTEXTDIR)ftxsbit.c \ + $(FTEXTDIR)ftxwidth.c \ + $(FTEXTDIR)ftxerr18.c \ + $(FTEXTDIR)ftxgsub.c \ + $(FTEXTDIR)ftxgpos.c \ + $(FTEXTDIR)ftxopen.c \ + $(FTEXTDIR)ftxgdef.c + +EXTOBJ = [.lib]ftxkern.obj, \ + [.lib]ftxgasp.obj, \ + [.lib]ftxpost.obj, \ + [.lib]ftxcmap.obj, \ + [.lib]ftxsbit.obj, \ + [.lib]ftxwidth.obj, \ + [.lib]ftxerr18.obj, \ + [.lib]ftxgsub.obj, \ + [.lib]ftxgpos.obj, \ + [.lib]ftxopen.obj, \ + [.lib]ftxgdef.obj + +# all engine sources +SRC_M = [.lib]ttapi.c \ + [.lib]ttcache.c \ + [.lib]ttcalc.c \ + [.lib]ttcmap.c \ + [.lib]ttdebug.c \ + [.lib]ttextend.c \ + [.lib]ttgload.c \ + [.lib]ttinterp.c \ + [.lib]ttload.c \ + [.lib]ttobjs.c \ + [.lib]ttraster.c \ + [.lib]$(FILESRC) \ + [.lib]$(MEMSRC) \ + [.lib]$(MUTEXSRC) +SRC_S = [.lib.$(ARCH)]freetype.c + +# all header files with path +HEADERS = [.lib]freetype.h \ + [.lib]fterrid.h \ + [.lib]ftnameid.h \ + $(FTEXTDIR)ftxkern.h \ + $(FTEXTDIR)ftxgasp.h \ + $(FTEXTDIR)ftxcmap.h \ + $(FTEXTDIR)ftxsbit.h \ + $(FTEXTDIR)ftxpost.h \ + $(FTEXTDIR)ftxwidth.h \ + $(FTEXTDIR)ftxerr18.h \ + $(FTEXTDIR)ftxgsub.h \ + $(FTEXTDIR)ftxgpos.h \ + $(FTEXTDIR)ftxgdef.h \ + $(FTEXTDIR)ftxopen.h + +# all engine objects +OBJ_M = [.lib]ttapi.obj, \ + [.lib]ttcache.obj, \ + [.lib]ttcalc.obj, \ + [.lib]ttcmap.obj, \ + [.lib]ttdebug.obj, \ + [.lib]ttextend.obj, \ + [.lib]ttgload.obj, \ + [.lib]ttinterp.obj, \ + [.lib]ttload.obj, \ + [.lib]ttobjs.obj, \ + [.lib]ttraster.obj, \ + [.lib]file.obj, \ + [.lib]memory.obj, \ + [.lib]mutex.obj, \ + $(EXTOBJ) +OBJ_S = [.lib]freetype.obj + + +# include paths +INCLUDES = /include=([.lib],[],$(FTEXTDIR)) + +# C flags +CFLAGS = $(INCLUDES)/obj=[.lib] + +all : do_link [.lib]libttf.olb + library/compress [.lib]libttf.olb + +do_link : + if f$search( "[.lib]memory.c" ) .nes. "" then set file/remove [.lib]memory.c; + if f$search( "[.lib]file.c" ) .nes. "" then set file/remove [.lib]file.c; + if f$search( "[.lib]mutex.c" ) .nes. "" then set file/remove [.lib]mutex.c; + if f$search( "[.lib]ft_conf.h" ) .nes. "" then set file/remove [.lib]ft_conf.h; + set file/enter=[.lib]memory.c [.lib]$(MEMSRC) + set file/enter=[.lib]file.c [.lib]$(FILESRC) + set file/enter=[.lib]mutex.c [.lib]$(MUTEXSRC) + set file/enter=[.lib]ft_conf.h [.lib.arch.vms]ft_conf.h + +[.lib]ftxkern.obj : $(FTEXTDIR)ftxkern.c + +[.lib]ftxgasp.obj : $(FTEXTDIR)ftxgasp.c + +[.lib]ftxpost.obj : $(FTEXTDIR)ftxpost.c + +[.lib]ftxcmap.obj : $(FTEXTDIR)ftxcmap.c + +[.lib]ftxsbit.obj : $(FTEXTDIR)ftxsbit.c + +[.lib]ftxwidth.obj : $(FTEXTDIR)ftxwidth.c + +[.lib]ftxerr18.obj : $(FTEXTDIR)ftxerr18.c + +[.lib]ftxgsub.obj : $(FTEXTDIR)ftxgsub.c + +[.lib]ftxgpos.obj : $(FTEXTDIR)ftxgpos.c + +[.lib]ftxgdef.obj : $(FTEXTDIR)ftxgdef.c + +[.lib]ftxopen.obj : $(FTEXTDIR)ftxopen.c + +[.lib]freetype.obj : $(SRC_S) $(SRC_M) + + +[.lib]libttf.olb : $(OBJ_M) + library/create [.lib]libttf.olb $(OBJ_M) + + +clean : + delete [.lib]*.obj;* + delete [.lib]*.olb;* + if f$search( "[.lib]memory.c" ) .nes. "" then set file/remove [.lib]memory.c; + if f$search( "[.lib]file.c" ) .nes. "" then set file/remove [.lib]file.c; + if f$search( "[.lib]mutex.c" ) .nes. "" then set file/remove [.lib]mutex.c; + if f$search( "[.lib]ft_conf.h" ) .nes. "" then set file/remove [.lib]ft_conf.h; diff --git a/lib/arch/vms/ft_conf.h b/lib/arch/vms/ft_conf.h new file mode 100644 index 0000000..b1315e6 --- /dev/null +++ b/lib/arch/vms/ft_conf.h @@ -0,0 +1,215 @@ +/* This file is part of the FreeType project */ + +/* ft_conf.h for VMS using MMS or MMK */ + + +/* we need the following because there are some typedefs in this file */ + +#ifndef FT_CONF_H +#define FT_CONF_H + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define if you have a working `mmap' system call. */ +/* #undef HAVE_MMAP */ + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define if the X Window System is missing or not being used. */ +/* #undef X_DISPLAY_MISSING */ + +/* The number of bytes in a int. */ +#define SIZEOF_INT 4 + +/* The number of bytes in a long. */ +#define SIZEOF_LONG 4 + +/* Define if you have the getpagesize function. */ +#define HAVE_GETPAGESIZE 1 + +/* Define if you have the memcpy function. */ +#define HAVE_MEMCPY 1 + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE 1 + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the header file. */ +#define HAVE_LOCALE_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_LIBINTL_H */ + +/* Define if you have the libintl library. */ +/* #undef HAVE_LIBINTL */ + +/**********************************************************************/ +/* */ +/* The following configuration macros can be tweaked manually by */ +/* a developer to turn on or off certain features or options in the */ +/* TrueType engine. This may be useful to tune it for specific */ +/* purposes.. */ +/* */ +/**********************************************************************/ + +/*************************************************************************/ +/* Define this if the underlying operating system uses a different */ +/* character width than 8bit for file names. You must then also supply */ +/* a typedef declaration for defining 'TT_Text'. Default is off. */ + +/* #undef HAVE_TT_TEXT */ + + +/*************************************************************************/ +/* Define this if you want to generate code to support engine extensions */ +/* Default is on, but if you're satisfied by the basic services provided */ +/* by the engine and need no extensions, undefine this configuration */ +/* macro to save a few more bytes. */ + +#define TT_CONFIG_OPTION_EXTEND_ENGINE + + +/*************************************************************************/ +/* Define this if you want to generate code to support gray-scaling, */ +/* a.k.a. font-smoothing or anti-aliasing. Default is on, but you can */ +/* disable it if you don't need it. */ + +#define TT_CONFIG_OPTION_GRAY_SCALING + + +/*************************************************************************/ +/* Define this if you want to completely disable the use of the bytecode */ +/* interpreter. Doing so will produce a much smaller library, but the */ +/* quality of the rendered glyphs will enormously suffer from this. */ +/* */ +/* This switch was introduced due to the Apple patents issue which */ +/* emerged recently on the FreeType lists. We still do not have Apple's */ +/* opinion on the subject and will change this as soon as we have. */ + +#undef TT_CONFIG_OPTION_NO_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to use a big 'switch' statement within the */ +/* bytecode interpreter. Because some non-optimizing compilers are not */ +/* able to produce jump tables from such statements, undefining this */ +/* configuration macro will generate the appropriate C jump table in */ +/* ttinterp.c. If you use an optimizing compiler, you should leave it */ +/* defined for better performance and code compactness.. */ + +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the TrueType */ +/* bytecode interpreter. This will produce much bigger code, which */ +/* _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the scan-line */ +/* converter (the component which in charge of converting outlines into */ +/* bitmaps). This will produce a bigger object file for "ttraster.c", */ +/* which _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_RASTER + + + +/*************************************************************************/ +/* Define TT_CONFIG_THREAD_SAFE if you want to build a thread-safe */ +/* version of the library. */ + +/* #undef TT_CONFIG_OPTION_THREAD_SAFE */ + + +/**********************************************************************/ +/* */ +/* The following macros are used to define the debug level, as well */ +/* as individual tracing levels for each component. There are */ +/* currently three modes of operation : */ +/* */ +/* - trace mode (define DEBUG_LEVEL_TRACE) */ +/* */ +/* The engine prints all error messages, as well as tracing */ +/* ones, filtered by each component's level */ +/* */ +/* - debug mode (define DEBUG_LEVEL_ERROR) */ +/* */ +/* Disable tracing, but keeps error output and assertion */ +/* checks. */ +/* */ +/* - release mode (don't define anything) */ +/* */ +/* Don't include error-checking or tracing code in the */ +/* engine's code. Ideal for releases. */ +/* */ +/* NOTE : */ +/* */ +/* Each component's tracing level is defined in its own source. */ +/* */ +/**********************************************************************/ + +/* Define if you want to use the tracing debug mode */ +/* #undef DEBUG_LEVEL_TRACE */ + +/* Define if you want to use the error debug mode - ignored if */ +/* DEBUG_LEVEL_TRACE is defined */ +/* #undef DEBUG_LEVEL_ERROR */ + + +/**************************************************************************/ +/* Definition of various integer sizes. These types are used by ttcalc */ +/* and ttinterp (for the 64-bit integers) only.. */ + +#if SIZEOF_INT == 4 + + typedef signed int TT_Int32; + typedef unsigned int TT_Word32; + +#elif SIZEOF_LONG == 4 + + typedef signed long TT_Int32; + typedef unsigned long TT_Word32; + +#else +#error "no 32bit type found" +#endif + +#if SIZEOF_LONG == 8 + +/* LONG64 must be defined when a 64-bit type is available */ +/* INT64 must then be defined to this type.. */ +#define LONG64 +#define INT64 long + +#else + +/* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */ +/* by defining the TT_USE_LONG_LONG macro in 'ft_conf.h'. Note that this */ +/* will produce many -ansi warnings during library compilation. */ +#ifdef TT_USE_LONG_LONG + +#define LONG64 +#define INT64 long long + +#endif /* TT_USE_LONG_LONG */ +#endif + +#endif /* FT_CONF_H */ + + +/* END */ diff --git a/lib/arch/win16/Makefile.BC b/lib/arch/win16/Makefile.BC new file mode 100644 index 0000000..246c127 --- /dev/null +++ b/lib/arch/win16/Makefile.BC @@ -0,0 +1,180 @@ +# This file is part of the FreeType project. +# +# It builds the library for Borland C++ for 16-bit Windows, large model. +# Due to size constraints, it does not try to pack all modules into one. +# +# You will need Borland MAKE. +# Tested with Borland C++ v.4.0 and 5.0. +# +# Use this file while in the lib directory with the following statement: +# +# make -farch/win16/Makefile.BC +# +# +# A DLL version of the library can be built with +# +# make -DDLL -farch/win16/Makefile.BC dll +# +# Debug versions can be obtained with +# +# make -DDEBUG -farch\win16\Makefile.BC +# +# Special versions enabled to handle big fonts (with more than 16,384 +# glyphs) can be obtained with +# +# make -DBIGFONTS -farch/win16/Makefile.BC + +ARCH = arch\win16 +FT_MAKEFILE = $(ARCH)\Makefile.BC +FT_DLL = ft13_16.dll + +CC = bcc +LIB = tlib /c /e +IMPLIB = implib -c -o + +SPURIOUS_WARNINGS = -w-nak -w-par -w-use -w-aus -w-stu -w-stv -w-cln -w-sig + +# Credits go to Dave Hoo for pointing out that modern +# Borland compilers (from BC++ 3.1 on) can increase the limit on +# the length of identifiers. +!if ! $d(DEBUG) +CFLAGS = -O2 -3 -ml -A -i40 -I$(ARCH);.;extend $(SPURIOUS_WARNINGS) +DLLFLAGS = -ml -WD -lC +!else +CFLAGS = -v -N -ml -A -i40 -I$(ARCH);.;extend $(SPURIOUS_WARNINGS) +DLLFLAGS = -v -ml -WD -lC +!endif + +CFLAGS = $(CFLAGS) -W + +FT_DEF = $(FT_DLL:.dll=.def) +!if $d(DLL) +CFLAGS = $(CFLAGS) -WD +!endif + + +!if $d(BIGFONTS) +CFLAGS = $(CFLAGS) -DTT_HUGE_PTR=__huge + +TTFILE = $(ARCH)\hugefile.c +TTMEMORY = $(ARCH)\hugemem.c +!else +TTFILE = .\ttfile.c +TTMEMORY = .\ttmemory.c +!endif +TTMUTEX = .\ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +# Do not insert spaces before the \ at end of line, +# otherwise the substitution for TLIB command line will fail. +SRC_X = extend\ftxgasp.c extend\ftxkern.c extend\ftxpost.c\ + extend\ftxcmap.c extend\ftxwidth.c extend\ftxerr18.c\ + extend\ftxsbit.c extend\ftxgsub.c extend\ftxgpos.c\ + extend\ftxopen.c extend\ftxgdef.c +OBJS_X = $(SRC_X:.c=.obj) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c\ + ttgload.c ttinterp.c ttload.c ttobjs.c\ + ttraster.c ttextend.c ttdebug.c $(PORT) +OBJS_M = $(SRC_M:.c=.obj) $(OBJS_X) + +SRC_S = $(ARCH)\freetype.c +OBJ_S = $(SRC_S:.c=.obj) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +# Since Borland make does not handle $($(LIB_FILES)), and using +# -DLIB_FILES="$(OBJS_S)" will excess the capacity of COMMAND.COM, we cheat +# by constructing TLIB's response file directly in the `all' target. +# +# Another solution, useful during debugging of part of the library, +# would be to include each .obj in the library as soon as it is compiled. +# See ../msdos/Makefile.TC for an application. +.c.obj: + @$(CC) -c -o$* @&&| + $(CFLAGS) $< +| + + +!if ! $d(DEBUG) +# Skipped if DEBUG build +# (but it changes nothing, since we always build in multiple parts). +all: $(OBJS_M) + -del libttf.lib + $(LIB) libttf.lib @&&| ++ $(OBJS_M: = + ) +| +!endif + +debug: $(OBJS_M) + -del libttf.lib + $(LIB) libttf.lib @&&| ++ $(OBJS_M: = + ) +| + +$(FT_DEF): $(ARCH)\ttf.def + -copy $(ARCH)\ttf.def $(FT_DEF) + +dll $(FT_DLL): $(OBJS_M) $(FT_DEF) +!if $d(DLL) + $(CC) -e$(FT_DLL) @&&| + $(DLLFLAGS) $(OBJS_M) +| + $(IMPLIB) libttf $(FT_DEF) +!else +# Re-invoke with flag set. Unfortunately, this discards the other flags. + make -DDLL -f$(ARCH)/Makefile.BC dll +!endif + +install: $(FT_DLL) +!if $d(INSTALL_DIR) + copy $(FT_DLL) $(INSTALL_DIR) +!else + copy $(FT_DLL) C:\WINDOWS +!endif + + +$(OBJ_S): $(SRC_S) $(SRC_M) + +# Not used here because it excesses the capacity of COMMAND.COM... +libttf.lib: $(LIB_FILES) + -del libttf.lib + echo -+$(**: =-+)> response + $(LIB) libttf.lib @&&| ++ $(**: = + ) +| + +!if $d(BIGFONTS) +$(TTMEMORY:.c=.obj): $(TTMEMORY) + $(CC) -c -o$* @&&| + $(CFLAGS) -A- $*.c +| + +$(TTFILE:.c=.obj): $(TTFILE) + $(CC) -c -o$* @&&| + $(CFLAGS) -A- $*.c +| +!endif + + +clean: + -del *.obj + -del extend\*.obj + -del $(ARCH)\*.obj + -del libttf.bak + -del response + -del *.def + +distclean: clean + -del libttf.lib + -del *.dll + -del $(FT_DEF) + -del C:\WINDOWS\$(FT_DLL) +!if $d(INSTALL_DIR) + -del $(INSTALL_DIR)\$(FT_DLL) +!endif + +!include "$(ARCH)\depend.win" + +# end of Makefile diff --git a/lib/arch/win16/Makefile.MS b/lib/arch/win16/Makefile.MS new file mode 100644 index 0000000..9ff0b67 --- /dev/null +++ b/lib/arch/win16/Makefile.MS @@ -0,0 +1,106 @@ +# This file is part of the FreeType project. +# +# It builds the library for Microsoft C for Windows, large model. +# It also works for Visual C++ 1.x 16-bit compilers, but you should +# instead use the Makefile customized for it, Makefile.VC. +# Due to size constraints, it does not try to pack all modules into one. +# +# You will need NMAKE. +# +# Use this file while in the lib directory with the following statement: +# +# nmake /f arch\win16\Makefile.MS +# +# +# A debug version can be obtained with +# +# nmake DEBUG=1 /f arch\win16\Makefile.MS + +ARCH = arch\win16 +FT_MAKEFILE = $(ARCH)\Makefile.MS + +CC = cl /nologo +LIB = lib /noignorecase /nologo + +!ifndef DEBUG +CFLAGS = /Ox /AL /Za /W2 /G2 -I$(ARCH) -I. -Iextend +!else +CFLAGS = /Zi /AL /Za /W2 /G2 -I$(ARCH) -I. -Iextend +!endif + +# Use /Gw instead with Microsoft C version 6 +CFLAGS = $(CFLAGS) /GA + + +TTFILE = .\ttfile.c +TTMEMORY = .\ttmemory.c +TTMUTEX = .\ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +# Do not insert spaces between the file names or at end of line, otherwise +# the substitution for LIB command line will fail. Thank you. +# +SRC_X = extend\ftxgasp.c extend\ftxkern.c extend\ftxpost.c\ +extend\ftxcmap.c extend\ftxwidth.c extend\ftxerr18.c extend\ftxsbit.c\ +extend\ftxopen.c extend\ftxgsub.c extend\ftxgpos.c extend\ftxgdef.c +OBJS_X = $(SRC_X:.c=.obj) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c\ +ttgload.c ttinterp.c ttload.c ttobjs.c ttraster.c ttextend.c $(PORT) +OBJS_M = $(SRC_M:.c=.obj) $(OBJS_X) + +SRC_S = $(ARCH)\freetype.c +OBJ_S = $(SRC_S:.c=.obj) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +# Since Microsoft's NMAKE does not handle $($(LIB_FILES)), and using +# LIB_FILES="$(OBJS_S)" will excess the capacity of COMMAND.COM, we cheat +# by constructing LIB's response file directly in the `all' target. +# +# Another solution, useful during debugging of part of the library, +# would be to include each .obj in the library as soon as it is compiled. +# See ..\msdos\Makefile.TC for an application. +.c.obj: + $(CC) /c /Fo$@ @<< + $(CFLAGS) $*.c +<< + + +!ifndef DEBUG +# Skipped if DEBUG build +# (but it changes nothing, since we always build in multiple parts). +all: $(OBJS_M) + -del libttf.lib + $(LIB) libttf.lib @< header file. */ +#define HAVE_STDLIB_H + +/* Define if you have the getpagesize function. */ +#undef HAVE_GETPAGESIZE + +/* Define if you have the memcpy function. */ +#define HAVE_MEMCPY + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE + +/* Define if you have the valloc function. */ +#undef HAVE_VALLOC + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define if you need for console I/O functions. */ +#undef HAVE_CONIO_H + +/* Define if you have the header file. */ +#undef HAVE_LOCALE_H + +/* Define if you have the header file. */ +#undef HAVE_LIBINTL_H + +/* Define if you have the libintl library. */ +#undef HAVE_LIBINTL + +/* command.com can't pipe stderr into a file; any message would be */ +/* written into the graphics screen. */ +#define HAVE_PRINT_FUNCTION 1 + +#define Print( format, ap ) vfprintf( stdout, (format), (ap) ) + +/* The number of bytes in a int. */ +#define SIZEOF_INT 2 + +/* The number of bytes in a long. */ +#define SIZEOF_LONG 4 + +/**********************************************************************/ +/* */ +/* The following configuration macros can be tweaked manually by */ +/* a developer to turn on or off certain features or options in the */ +/* TrueType engine. This may be useful to tune it for specific */ +/* purposes.. */ +/* */ +/**********************************************************************/ + + +/*************************************************************************/ +/* Define this if the underlying operating system uses a different */ +/* character width than 8bit for file names. You must then also supply */ +/* a typedef declaration for defining 'TT_Text'. Default is off. */ + +/* #define HAVE_TT_TEXT */ + + +/*************************************************************************/ +/* Define this if you want to generate code to support engine extensions */ +/* Default is on, but if you're satisfied by the basic services provided */ +/* by the engine and need no extensions, undefine this configuration */ +/* macro to save a few more bytes. */ + +#define TT_CONFIG_OPTION_EXTEND_ENGINE + + +/*************************************************************************/ +/* Define this if you want to generate code to support gray-scaling, */ +/* a.k.a. font-smoothing or anti-aliasing. Default is on, but you can */ +/* disable it if you don't need it. */ + +#define TT_CONFIG_OPTION_GRAY_SCALING + + +/*************************************************************************/ +/* Define this if you want to completely disable the use of the bytecode */ +/* interpreter. Doing so will produce a much smaller library, but the */ +/* quality of the rendered glyphs will enormously suffer from this. */ +/* */ +/* This switch was introduced due to the Apple patents issue which */ +/* emerged recently on the FreeType lists. We still do not have Apple's */ +/* opinion on the subject and will change this as soon as we have. */ + +#undef TT_CONFIG_OPTION_NO_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to use a big 'switch' statement within the */ +/* bytecode interpreter. Because some non-optimizing compilers are not */ +/* able to produce jump tables from such statements, undefining this */ +/* configuration macro will generate the appropriate C jump table in */ +/* ttinterp.c. If you use an optimizing compiler, you should leave it */ +/* defined for better performance and code compactness.. */ + +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the TrueType */ +/* bytecode interpreter. This will produce much bigger code, which */ +/* _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the scan-line */ +/* converter (the component which in charge of converting outlines into */ +/* bitmaps). This will produce a bigger object file for "ttraster.c", */ +/* which _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_RASTER + + + +/*************************************************************************/ +/* Define TT_CONFIG_THREAD_SAFE if you want to build a thread-safe */ +/* version of the library. */ + +#undef TT_CONFIG_OPTION_THREAD_SAFE + + +/**********************************************************************/ +/* */ +/* The following macros are used to define the debug level, as well */ +/* as individual tracing levels for each component. There are */ +/* currently three modes of operation : */ +/* */ +/* - trace mode (define DEBUG_LEVEL_TRACE) */ +/* */ +/* The engine prints all error messages, as well as tracing */ +/* ones, filtered by each component's level */ +/* */ +/* - debug mode (define DEBUG_LEVEL_ERROR) */ +/* */ +/* Disable tracing, but keeps error output and assertion */ +/* checks. */ +/* */ +/* - release mode (don't define anything) */ +/* */ +/* Don't include error-checking or tracing code in the */ +/* engine's code. Ideal for releases. */ +/* */ +/* NOTE : */ +/* */ +/* Each component's tracing level is defined in its own source. */ +/* */ +/**********************************************************************/ + +/* Define if you want to use the tracing debug mode */ +#undef DEBUG_LEVEL_TRACE + +/* Define if you want to use the error debug mode - ignored if */ +/* DEBUG_LEVEL_TRACE is defined */ +#undef DEBUG_LEVEL_ERROR + + +/**************************************************************************/ +/* Definition of various integer sizes. These types are used by ttcalc */ +/* and ttinterp (for the 64-bit integers) only.. */ + +#if SIZEOF_INT == 4 + + typedef signed int TT_Int32; + typedef unsigned int TT_Word32; + +#elif SIZEOF_LONG == 4 + + typedef signed long TT_Int32; + typedef unsigned long TT_Word32; + +#else +#error "no 32bit type found" +#endif + +/* LONG64 must be defined when a 64-bit type is available */ +/* INT64 must then be defined to this type.. */ +#undef LONG64 +#undef INT64 + +#endif /* FT_CONF_H */ + +/* End of ft_conf.h */ diff --git a/lib/arch/win16/hugefile.c b/lib/arch/win16/hugefile.c new file mode 100644 index 0000000..17b5f59 --- /dev/null +++ b/lib/arch/win16/hugefile.c @@ -0,0 +1,51 @@ +/******************************************************************* + * + * hugefile.c + * + * File I/O Component (body) for dealing with "huge" objects + * under 16-bit Windows. Relies on the "default" version, with + * a small hook. Requires Windows 3.1+. + * + * Written by Antoine Leca based on ideas from Dave Hoo. + * Copyright 1999 by Dave Hoo, Antoine Leca, + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTE + * + * This file #includes the normal version, to avoid discrepancies + * between versions. It uses only ANSI-mandated "tricks", so + * any ANSI-compliant compiler should be able to compile this file. + * + ******************************************************************/ + +#include "ttconfig.h" +#include "tttypes.h" + +#include + + /* Here we include , to have the proper definition of fread */ +#include + + /* Some compilers define fileno(), some define _fileno()... */ +#ifndef _fileno +#define _fileno(stream) fileno(stream) +#endif + + /* Then, we divert the use of fread to the Windows version */ +#undef fread +#define fread(ptr, size, n, stream) \ + _hread( _fileno(stream), (char TT_HUGE_PTR *) ptr, (ULong)n * size ) + + + /* Now, we include the "normal" version of `ttfile.c' */ + /* The ANSI/ISO standard mandates that the include of */ + /* there have no bad effects. */ +#include "ttfile.c" + +/* END */ diff --git a/lib/arch/win16/hugemem.c b/lib/arch/win16/hugemem.c new file mode 100644 index 0000000..c1abe5f --- /dev/null +++ b/lib/arch/win16/hugemem.c @@ -0,0 +1,539 @@ +/******************************************************************* + * + * hugemem.c + * + * Memory management component (body) + * for dealing with "huge" objects with 16-bit Windows. + * + * Written by Antoine Leca based on ideas from Dave Hoo. + * Copyright 1999 by Dave Hoo, Antoine Leca, + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include +#include + +#include "ttdebug.h" +#include "ttmemory.h" +#include "ttengine.h" + +#ifndef TT_HUGE_PTR +#error "This component needs TT_HUGE_PTR to be #defined." +#endif + +#ifdef TT_CONFIG_OPTION_THREAD_SAFE +#error "This component needs static allocation and is not re-entrant." +#endif + + /* If the memory reclaimed is abobve this limit, alloc directly from */ + /* global heap. Else, alloc using malloc (using suballocation). */ +#ifndef MEMORY_MIN_GLOBAL +#define MEMORY_MIN_GLOBAL 4096 +#endif + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_memory + + +#ifdef DEBUG_MEMORY + +#include + +#define MAX_TRACKED_BLOCKS 1024 + + struct TMemRec_ + { + void* base; + Long size; + }; + + typedef struct TMemRec_ TMemRec; + + static TMemRec pointers[MAX_TRACKED_BLOCKS + 1]; + + static Int num_alloc; + static Int num_free; + static Int num_realloc; /* counts only `real' reallocations + (i.e., an existing buffer will be resized + to a value larger than zero */ + + static Int fail_alloc; + static Int fail_realloc; + static Int fail_free; + +#else + + /* We need a tracing stack of the calls to big chunks of memory, */ + /* in order to call the matching version of free(). */ + +#define MAX_TRACKED_BIGCHUNKS 64 + + struct TMemRec_ + { + void* base; + }; + + typedef struct TMemRec_ TMemRec; + + static TMemRec pointers[MAX_TRACKED_BIGCHUNKS + 1]; + +#endif /* DEBUG_MEMORY */ + + +#ifndef TT_CONFIG_REENTRANT + Long TTMemory_Allocated; + Long TTMemory_MaxAllocated; +#endif + + +/******************************************************************* + * + * Function : TT_Alloc + * + * Description : Allocates memory from the heap buffer. + * + * Input : Size size of the memory to be allocated + * P pointer to a buffer pointer + * + * Output : Error code. + * + * NOTE : The newly allocated block should _always_ be zeroed + * on return. Many parts of the engine rely on this to + * work properly. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Alloc( ULong Size, void** P ) + { + Int i; + + + if ( !P ) + return TT_Err_Invalid_Argument; + /* Also see below for another case of "invalid argument". */ + + if ( Size > 0 ) + { + if ( Size >= MEMORY_MIN_GLOBAL ) + { + HANDLE hMem; + + hMem = GlobalAlloc( GMEM_ZEROINIT, Size ); + if ( !hMem ) + return TT_Err_Out_Of_Memory; + + *P = (void*)GlobalLock( hMem ); + } + else + *P = (void*)malloc( Size ); + + if ( !*P ) + return TT_Err_Out_Of_Memory; + +#ifndef TT_CONFIG_REENTRANT + TTMemory_MaxAllocated += Size; + TTMemory_Allocated += Size; +#endif + +#ifdef DEBUG_MEMORY + + num_alloc++; + + i = 0; + while ( i < MAX_TRACKED_BLOCKS && pointers[i].base != NULL ) + i++; + + if ( i >= MAX_TRACKED_BLOCKS ) + fail_alloc++; + else + { + pointers[i].base = *P; + pointers[i].size = Size; + } + +#else + + if ( Size >= MEMORY_MIN_GLOBAL ) + { + i = 0; + while ( i < MAX_TRACKED_BIGCHUNKS && pointers[i].base != NULL ) + i++; + + if ( i >= MAX_TRACKED_BIGCHUNKS ) + /* We fail badly here. Increase MAX_TRACKED_BIGCHUNKS if needed. */ + return TT_Err_Invalid_Argument; + else + pointers[i].base = *P; + } + +#endif /* DEBUG_MEMORY */ + + /* The nice thing about GlobalAlloc is that it zeroes the memory. */ + + if ( Size < MEMORY_MIN_GLOBAL ) + MEM_Set( *P, 0, Size ); + + } + else + *P = NULL; + + return TT_Err_Ok; + } + + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE + + +/******************************************************************* + * + * Function : TT_Realloc + * + * Description : Reallocates memory from the heap buffer. + * + * Input : Size new size of the memory to be allocated; + * if zero, TT_Free() will be called + * P pointer to a buffer pointer; if *P == NULL, + * TT_Alloc() will be called + * + * Output : Error code. + * + * NOTES : It's not necessary to zero the memory in case the + * reallocated buffer is larger than before -- the + * application has to take care of this. + * + * If the memory request fails, TT_Free() will be + * called on *P, and TT_Err_Out_Of_Memory returned. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Realloc( ULong Size, void** P ) + { + ULong oldSize; + void* Q; + Int i; + + + if ( !P ) + return TT_Err_Invalid_Argument; + + if ( !*P ) + return TT_Alloc( Size, P ); + + if ( Size == 0 ) + return TT_Free( P ); + +#ifdef DEBUG_MEMORY + + num_realloc++; + + i = 0; + while ( i < MAX_TRACKED_BLOCKS && pointers[i].base != *P ) + i++; + + if ( i >= MAX_TRACKED_BLOCKS ) + fail_realloc++; + else + oldSize = pointers[i].size; + +#else + + i = 0; + while ( i < MAX_TRACKED_BIGCHUNKS && pointers[i].base != *P ) + i++; + + /* If we did not found the pointer, then this is a "small" chunk. */ + + if ( i < MAX_TRACKED_BIGCHUNKS ) + { + /* Signal we found a big one. Real size does not matter. */ + oldSize = MEMORY_MIN_GLOBAL; + } + +#endif /* DEBUG_MEMORY */ + + if ( oldSize >= MEMORY_MIN_GLOBAL ) + { + /* Deal with a big chunk. */ + HANDLE hMem, hNewMem; + + hMem = GlobalHandle ( (ULong)*P >> 16 ) & 0xFFFF; + if ( !hMem ) /* Bad call... */ + return TT_Err_Invalid_Argument; + + GlobalUnlock( hMem ); + hNewMem = GlobalReAlloc( hMem, Size, 0 ); + if ( hNewMem ) + *P = (void*)GlobalLock( hNewMem ); + } + if ( Size >= MEMORY_MIN_GLOBAL ) + { + /* A small chunk crosses the limit... */ + + if( TT_Alloc( Size, &Q ) != TT_Err_Ok ) + Q = NULL; /* Failed to create the new block. */ + else + MEM_Copy( Q, *P, oldSize ); + + /* We need to register the new entry. */ +#ifndef DEBUG_MEMORY + + i = 0; + while ( i < MAX_TRACKED_BIGCHUNKS && pointers[i].base != NULL ) + i++; + + if ( i >= MAX_TRACKED_BIGCHUNKS ) + /* We fail badly here. Increase MAX_TRACKED_BIGCHUNKS if needed. */ + return TT_Err_Invalid_Argument; +#endif /* DEBUG_MEMORY */ + } + else + Q = (void*)realloc( *P, Size ); + + if ( !Q ) + { + TT_Free( *P ); + return TT_Err_Out_Of_Memory; + } + +#ifdef DEBUG_MEMORY + + if ( i < MAX_TRACKED_BLOCKS ) + { +#ifndef TT_CONFIG_REENTRANT + TTMemory_Allocated += Size - pointers[i].size; + if ( Size > pointers[i].size ) + TTMemory_MaxAllocated += Size - pointers[i].size; +#endif + + pointers[i].base = Q; + pointers[i].size = Size; + } +#else + if ( i < MAX_TRACKED_BIGCHUNKS ) + { + pointers[i].base = Q; + } +#endif /* DEBUG_MEMORY */ + + *P = Q; + + return TT_Err_Ok; + } + + +#endif /* TT_CONFIG_OPTION_EXTEND_ENGINE */ + + +/******************************************************************* + * + * Function : TT_Free + * + * Description : Releases a previously allocated block of memory. + * + * Input : P pointer to memory block + * + * Output : Always SUCCESS. + * + * Note : The pointer must _always_ be set to NULL by this function. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Free( void** P ) + { + Int i; + Long Size = 0; + + + if ( !P || !*P ) + return TT_Err_Ok; + +#ifdef DEBUG_MEMORY + + num_free++; + + i = 0; + while ( i < MAX_TRACKED_BLOCKS && pointers[i].base != *P ) + i++; + + if ( i >= MAX_TRACKED_BLOCKS ) + fail_free++; + else + { +#ifndef TT_CONFIG_REENTRANT + TTMemory_Allocated -= pointers[i].size; +#endif + + Size = pointers[i].size; + pointers[i].base = NULL; + pointers[i].size = 0; + } + +#else + + i = 0; + while ( i < MAX_TRACKED_BIGCHUNKS && pointers[i].base != *P ) + i++; + + /* If we did not found the pointer, then this is a "small" chunk. */ + + if ( i < MAX_TRACKED_BIGCHUNKS ) + { + pointers[i].base = NULL; + /* Signal we found a big one. Real size does not matter. */ + Size = MEMORY_MIN_GLOBAL; + } + +#endif /* DEBUG_MEMORY */ + + if ( Size >= MEMORY_MIN_GLOBAL ) + { + HANDLE hMem; + + hMem = GlobalHandle ( (ULong)*P >> 16 ) & 0xFFFF; + if ( !hMem ) /* Bad call... */ + return TT_Err_Invalid_Argument; + + GlobalUnlock( hMem ); + GlobalFree ( hMem ); + } + else + free( *P ); + + *P = NULL; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTMemory_Init + * + * Description : Initializes the memory. + * + * Output : Always SUCCESS. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTMemory_Init( void ) + { +#ifdef DEBUG_MEMORY + Int i; + + + for ( i = 0; i < MAX_TRACKED_BLOCKS; i++ ) + { + pointers[i].base = NULL; + pointers[i].size = 0; + } + + num_alloc = 0; + num_realloc = 0; + num_free = 0; + + fail_alloc = 0; + fail_realloc = 0; + fail_free = 0; +#else + Int i; + + for ( i = 0; i < MAX_TRACKED_BIGCHUNKS; i++ ) + { + pointers[i].base = NULL; + } +#endif + + +#ifndef TT_CONFIG_REENTRANT + TTMemory_Allocated = 0; + TTMemory_MaxAllocated = 0; +#endif + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTMemory_Done + * + * Description : Finalizes memory usage. + * + * Output : Always SUCCESS. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTMemory_Done( void ) + { +#ifdef DEBUG_MEMORY + Int i, num_leaked, tot_leaked; + + + num_leaked = 0; + tot_leaked = 0; + + for ( i = 0; i < MAX_TRACKED_BLOCKS; i++ ) + { + if ( pointers[i].base ) + { + num_leaked ++; + tot_leaked += pointers[i].size; + } + } + + fprintf( stderr, + "%d memory allocations, of which %d failed\n", + num_alloc, + fail_alloc ); + + fprintf( stderr, + "%d memory reallocations, of which %d failed\n", + num_realloc, + fail_realloc ); + + fprintf( stderr, + "%d memory frees, of which %d failed\n", + num_free, + fail_free ); + + if ( num_leaked > 0 ) + { + fprintf( stderr, + "There are %d leaked memory blocks, totalizing %d bytes\n", + num_leaked, tot_leaked ); + + for ( i = 0; i < MAX_TRACKED_BLOCKS; i++ ) + { + if ( pointers[i].base ) + { + fprintf( stderr, + "index: %4d (base: $%08lx, size: %08ld)\n", + i, + (long)pointers[i].base, + pointers[i].size ); + } + } + } + else + fprintf( stderr, "No memory leaks !\n" ); + +#endif /* DEBUG_MEMORY */ + + return TT_Err_Ok; + } + + +/* END */ diff --git a/lib/arch/win16/makedef b/lib/arch/win16/makedef new file mode 100644 index 0000000..e248807 --- /dev/null +++ b/lib/arch/win16/makedef @@ -0,0 +1,24 @@ +# makedef +# +# This shell script creates a .DEF file necessary for building as DLL +# on the Windows 16-bit platform. + +echo "\ +; This definition file to be used to built the library as DLL +; has been generated automatically with the script \`makedef' on +; `date +%d-%b-%Y`. + +LIBRARY ft13_16 +DESCRIPTION 'FreeType 1.3 16-bit DLL © 1996-1999 Turner, Wilhelm, Lemberg' +EXETYPE WINDOWS +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE SINGLE +EXPORTS +" > ttf.def + +(cd ../.. + sed -n -e "/^ *EXPORT_DEF/!d ; n ; s/(.*$//" \ + -e "s/;$//" -e "s/ const / /" -e "s/ *[a-zA-Z][a-zA-Z_\*]* //" \ + -e "s/ *//g" -e "s/^\(.*\)/ _\1/" -e "p" *.h extend/*.h) >> ttf.def + +# eof diff --git a/lib/arch/win16/makedep b/lib/arch/win16/makedep new file mode 100644 index 0000000..594952b --- /dev/null +++ b/lib/arch/win16/makedep @@ -0,0 +1,32 @@ +# makedep +# +# This shell script creates a dependency file necessary for older compilers +# on the Windows 16-bit platform. + +echo "\ +# This dependency file to be used with various Windows compilers +# has been generated automatically with the script \`makedep' on +# `date +%d-%b-%Y`. +" > depend.win + +(cd ../.. + gcc -MM -Iarch/win16 -I. \ + *.c | \ + sed -e "s/\.o:/.obj:/" -e "s:/:\\\\:g") >> depend.win + +(cd ../.. + gcc -MM -Iarch/win16 -I. -Iextend \ + extend/*.c | \ + sed -e "s/^\(.*\)\.o:/extend\\\\\1.obj:/" -e "s:/:\\\\:g") >> depend.win + +echo "!ifndef __MAKE__" >> depend.win + +(cd ../.. + gcc -MM -Iarch/win16 -I. -Iextend -DTT_HUGE_PTR \ + arch/win16/*.c | \ + sed -e "s/^\(.*\)\.o:/arch\\\\win16\\\\\1.obj:/" \ + -e "s:/:\\\\:g") >> depend.win + +echo "!endif" >> depend.win + +# eof diff --git a/lib/arch/win16/ttf.def b/lib/arch/win16/ttf.def new file mode 100644 index 0000000..01276eb --- /dev/null +++ b/lib/arch/win16/ttf.def @@ -0,0 +1,127 @@ +; This definition file to be used to built the library as DLL +; has been generated automatically with the script `makedef' on +; 02-Sep-1999. + +LIBRARY ft13_16 +DESCRIPTION 'FreeType 1.3 16-bit DLL © 1996-1999 Turner, Wilhelm, Lemberg' +EXETYPE WINDOWS +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE SINGLE +EXPORTS + + _TT_FreeType_Version + _TT_Init_FreeType + _TT_Done_FreeType + _TT_Set_Raster_Gray_Palette + _TT_Open_Face + _TT_Open_Collection + _TT_Get_Face_Properties + _TT_Set_Face_Pointer + _TT_Get_Face_Pointer + _TT_Flush_Face + _TT_Get_Face_Metrics + _TT_Close_Face + _TT_Get_Font_Data + _TT_New_Instance + _TT_Set_Instance_Resolutions + _TT_Set_Instance_CharSize + _TT_Set_Instance_CharSizes + _TT_Set_Instance_PixelSizes + _TT_Set_Instance_Transform_Flags + _TT_Get_Instance_Metrics + _TT_Set_Instance_Pointer + _TT_Get_Instance_Pointer + _TT_Done_Instance + _TT_New_Glyph + _TT_Done_Glyph + _TT_Load_Glyph + _TT_Get_Glyph_Outline + _TT_Get_Glyph_Metrics + _TT_Get_Glyph_Big_Metrics + _TT_Get_Glyph_Bitmap + _TT_Get_Glyph_Pixmap + _TT_New_Outline + _TT_Done_Outline + _TT_Copy_Outline + _TT_Get_Outline_Bitmap + _TT_Get_Outline_Pixmap + _TT_Get_Outline_BBox + _TT_Transform_Outline + _TT_Translate_Outline + _TT_Transform_Vector + _TT_MulDiv + _TT_MulFix + _TT_Get_CharMap_Count + _TT_Get_CharMap_ID + _TT_Get_CharMap + _TT_Char_Index + _TT_Get_Name_Count + _TT_Get_Name_ID + _TT_Get_Name_String + _TT_Register_Extension + _TT_Extension_Get + _TT_Use_Stream + _TT_Done_Stream + _TT_Flush_Stream + _TT_Read_File + _TT_Seek_File + _TT_Skip_File + _TT_Read_At_File + _TT_File_Pos + _TT_Stream_Size + _TT_Null_FileFrame + _TT_Access_Frame + _TT_Check_And_Access_Frame + _TT_Forget_Frame + _TT_Get_Char + _TT_Get_Short + _TT_Get_Long + _TT_LookUp_Table + _TT_Alloc + _TT_Realloc + _TT_Free + _TT_CharMap_First + _TT_CharMap_Next + _TT_CharMap_Last + _TT_ErrToString18 + _TT_Get_Face_Gasp_Flags + _TT_Init_GDEF_Extension + _TT_Load_GDEF_Table + _TT_GDEF_Get_Glyph_Property + _TT_GDEF_Build_ClassDefinition + _TT_Init_GPOS_Extension + _TT_Load_GPOS_Table + _TT_GPOS_Select_Script + _TT_GPOS_Select_Language + _TT_GPOS_Select_Feature + _TT_GPOS_Query_Scripts + _TT_GPOS_Query_Languages + _TT_GPOS_Query_Features + _TT_GPOS_Add_Feature + _TT_GPOS_Clear_Features + _TT_Init_GSUB_Extension + _TT_Load_GSUB_Table + _TT_GSUB_Select_Script + _TT_GSUB_Select_Language + _TT_GSUB_Select_Feature + _TT_GSUB_Query_Scripts + _TT_GSUB_Query_Languages + _TT_GSUB_Query_Features + _TT_GSUB_Add_Feature + _TT_GSUB_Clear_Features + _TT_GSUB_Register_Alternate_Function + _TT_GSUB_Apply_String + _TT_GSUB_Add_String + _TT_Init_Kerning_Extension + _TT_Get_Kerning_Directory + _TT_Load_Kerning_Table + _TT_Init_Post_Extension + _TT_Load_PS_Names + _TT_Get_PS_Name + _TT_Init_SBit_Extension + _TT_Get_Face_Bitmaps + _TT_New_SBit_Image + _TT_Done_SBit_Image + _TT_Get_SBit_Strike + _TT_Load_Glyph_Bitmap + _TT_Get_Face_Widths diff --git a/lib/arch/win32/Makefile.BC b/lib/arch/win32/Makefile.BC new file mode 100644 index 0000000..f83104f --- /dev/null +++ b/lib/arch/win32/Makefile.BC @@ -0,0 +1,161 @@ +# This file is part of the FreeType project. +# +# It builds the library for Borland C++ for Win32. +# +# You will need Borland MAKE. +# Tested with Borland C++ v.5.0 and Borland C++ builder 4.0. +# Does not work with Borland C++ 4.0, since it needs __declspec. +# +# Use this file while in the lib directory with the following statement: +# +# make -farch/win32/Makefile.BC +# +# +# A DLL version of the library can be built with +# +# make -DDLL -farch/win32/Makefile.BC dll +# +# A debug version can be obtained with +# +# make -DDEBUG -farch/win32/Makefile.BC + +ARCH = arch\win32 +FT_MAKEFILE = $(ARCH)\Makefile.BC +FT_DLL = ft13_32.dll + +CC = bcc32 +LIB = tlib /c /e +IMPLIB = implib -c + +SPURIOUS_WARNINGS = -w-nak -w-par -w-use -w-aus -w-stu -w-stv -w-cln -w-sig + +!if ! $d(DEBUG) +CFLAGS = -O2 -A -i40 -I$(ARCH);.;extend $(SPURIOUS_WARNINGS) +DLLFLAGS = -WD +!else +CFLAGS = -v -A -i40 -I$(ARCH);.;extend $(SPURIOUS_WARNINGS) +DLLFLAGS = -v -WD +!endif + +FT_DEF = $(FT_DLL:.dll=.def) +!if $d(DLL) +CFLAGS = $(CFLAGS) \ + -DEXPORT_DEF=__declspec(dllexport) -DEXPORT_FUNC=__declspec(dllexport) +!endif + + +TTFILE = .\ttfile.c +TTMEMORY = .\ttmemory.c +TTMUTEX = .\ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +# Do not insert spaces before the \ at end of line, +# otherwise the substitution for TLIB command line will fail. +SRC_X = extend\ftxgasp.c extend\ftxkern.c extend\ftxpost.c\ + extend\ftxcmap.c extend\ftxwidth.c extend\ftxerr18.c\ + extend\ftxsbit.c extend\ftxgsub.c extend\ftxgpos.c\ + extend\ftxopen.c extend\ftxgdef.c +OBJS_X = $(SRC_X:.c=.obj) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c\ + ttgload.c ttinterp.c ttload.c ttobjs.c\ + ttraster.c ttextend.c ttdebug.c $(PORT) +OBJS_M = $(SRC_M:.c=.obj) $(OBJS_X) + +SRC_S = $(ARCH)\freetype.c +OBJ_S = $(SRC_S:.c=.obj) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +# Since Borland make does not handle $($(LIB_FILES)), and using +# -DLIB_FILES="$(OBJS_S)" will excess the capacity of COMMAND.COM, we cheat +# by constructing TLIB's response file directly in the `all' target. +# +# Another solution, useful during debugging of part of the library, +# would be to include each .obj in the library as soon as it is compiled. +# See ../msdos/Makefile.TC for an application. +.c.obj: + $(CC) -c -o$* @&&| + $(CFLAGS) $< +| + + +!if ! $d(DEBUG) +# Skipped if DEBUG build +all: $(OBJS_S) + -del libttf.lib + $(LIB) libttf.lib @&&| ++ $(OBJS_S: = + ) +| + +dll $(FT_DLL): $(OBJS_S) $(FT_DEF) +!if $d(DLL) + $(CC) @&&| + $(DLLFLAGS) -e$(FT_DLL) $(OBJS_S) +| + $(IMPLIB) libttf $(FT_DLL) +!else + $(MAKE) -DDLL -f$(FT_MAKEFILE) dll # Re-invoke with flag set. +!endif +!endif + +debug: $(OBJS_M) + -del libttf.lib + $(LIB) libttf.lib @&&| ++ $(OBJS_M: = + ) +| + +!ifdef DEBUG +dll $(FT_DLL): $(OBJS_M) $(FT_DEF) +!if $d(DLL) + $(CC) @&&| + $(DLLFLAGS) -e$(FT_DLL) $(OBJS_M) +| + $(IMPLIB) libttf $(FT_DLL) +!else + $(MAKE) -DDEBUG -DDLL -f$(FT_MAKEFILE) dll +!endif +!endif + +install: $(FT_DLL) +!ifdef INSTALL_DIR + copy $(FT_DLL) $(INSTALL_DIR) +!else + copy $(FT_DLL) C:\WINDOWS +!endif + +$(OBJ_S): $(SRC_S) $(SRC_M) + +# Not used here because it excesses the capacity of COMMAND.COM... +libttf.lib: $(LIB_FILES) + -del libttf.lib + echo -+$(**: =-+)> response + $(LIB) libttf.lib @&&| ++ $(**: = + ) +| + +$(FT_DEF): $(ARCH)\ttf.def + -copy $(ARCH)\ttf.def $(FT_DEF) + +clean: + -del *.obj + -del extend\*.obj + -del $(ARCH)\*.obj + -del libttf.bak + -del response + -del *.def + -del *.tds + +distclean: clean + -del libttf.lib + -del *.dll + -del $(FT_DEF) + -del C:\WINDOWS\$(FT_DLL) +!if $d(INSTALL_DIR) + -del $(INSTALL_DIR)\$(FT_DLL) +!endif + +!include "$(ARCH)\depend.win" + +# end of Makefile diff --git a/lib/arch/win32/Makefile.CL b/lib/arch/win32/Makefile.CL new file mode 100644 index 0000000..a4145c3 --- /dev/null +++ b/lib/arch/win32/Makefile.CL @@ -0,0 +1,165 @@ +# This file is part of the FreeType project. +# +# It builds the library for Microsoft Visual C++ for 32-bit Windows. +# +# You will need NMAKE. +# +# Use this file while in the lib directory with the following statement: +# +# nmake /f arch\win32\Makefile.CL +# +# +# A DLL version of the library can be built with +# +# nmake DLL=1 /f arch\win32\Makefile.CL dll +# +# Debug versions can be obtained with +# +# nmake DEBUG=1 /f arch\win32\Makefile.CL + +ARCH = arch\win32 +FT_MAKEFILE = $(ARCH)\Makefile.CL +FT_DLL = ft13_32.dll + +CC = cl /nologo +LIB = lib /nologo +LINK = link /nologo + +CFLAGS = /Za /W2 -I$(ARCH) -I. -Iextend + +!ifndef DEBUG +CFLAGS = $(CFLAGS) /Ox +DLLFLAGS = /RELEASE +!else +CFLAGS = $(CFLAGS) /Zi /Ge +DLLFLAGS = /DEBUG +!endif + +!ifdef DLL +CFLAGS = $(CFLAGS) /GD \ + /DEXPORT_DEF=__declspec(dllexport) /DEXPORT_FUNC=__declspec(dllexport) +!else +CFLAGS = $(CFLAGS) /GA +!endif + + +TTFILE = .\ttfile.c +TTMEMORY = .\ttmemory.c +TTMUTEX = .\ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +# Do not insert spaces between the file names or at end of line, otherwise +# the substitution for LIB command line will fail. Thank you. +# +SRC_X = extend\ftxgasp.c extend\ftxkern.c extend\ftxpost.c\ +extend\ftxcmap.c extend\ftxwidth.c extend\ftxerr18.c extend\ftxsbit.c\ +extend\ftxopen.c extend\ftxgsub.c extend\ftxgpos.c extend\ftxgdef.c +OBJS_X = $(SRC_X:.c=.obj) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c\ +ttgload.c ttinterp.c ttload.c ttobjs.c ttraster.c ttextend.c $(PORT) +OBJS_M = $(SRC_M:.c=.obj) $(OBJS_X) + +SRC_S = $(ARCH)\freetype.c +OBJ_S = $(SRC_S:.c=.obj) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +# Since Microsoft's NMAKE does not handle $($(LIB_FILES)), and using +# LIB_FILES="$(OBJS_S)" will excess the capacity of COMMAND.COM, we cheat +# by constructing LIB's response file directly in the `all' target. +# +# Another solution, useful during debugging of part of the library, +# would be to include each .obj in the library as soon as it is compiled. +# See ..\msdos\Makefile.TC for an application. +.c.obj: + @$(CC) /c /Fo$@ @<< + $(CFLAGS) $*.c +<< + + +!ifndef DEBUG +# Skipped if DEBUG build +all: $(OBJS_S) + -del libttf.lib + $(LIB) /OUT:libttf.lib @< dep.end + +ifeq (dep.end,$(wildcard dep.end)) + include dep.end +endif + +# end of Makefile.Min diff --git a/lib/arch/win32/Makefile.VC b/lib/arch/win32/Makefile.VC new file mode 100644 index 0000000..7974aa7 --- /dev/null +++ b/lib/arch/win32/Makefile.VC @@ -0,0 +1,195 @@ +# Visual C++ 2.x, 4.x, 5.0 and 6.0 makefile for freetype +# adapted from suns example makefile (related to the TCL script language) + +# Does not depend on the presence of any environment variables in +# order to compile freetype; all needed information is derived from +# location of the compiler directories. + +# +# Project directories +# +# ROOT = top of source tree +# +# TMPDIR = location where .obj files should be stored during build +# +# TOOLS32 = location of VC++ 32-bit development tools. Note that the +# VC++ 2.0 header files are broken, so you need to use the +# ones that come with the developer network CD's, or later +# versions of VC++. +# + +ROOT = ..\.. +TMPDIR = . +#TOOLS32 = c:\msdev # VC++ 2.x,4.x +#TOOLS32 = c:\Program Files\devstudio\vc # VC++ 5.x +TOOLS32 = c:\Program Files\Microsoft Visual Studio\Vc98 # VC++ 6.x +INSTALLDIR = c:\WINNT\SYSTEM32 + +# Set this to the appropriate value of /MACHINE: for your platform +MACHINE = IX86 + +# Comment the following line to compile with symbols +NODEBUG=1 + + +###################################################################### +# Do not modify below this line +###################################################################### + +TTF = ttf +TTFLIB = $(TTF).lib +TTFDLL = $(TTF).dll + +TTFOBJS = \ + $(TMPDIR)\ttapi.obj \ + $(TMPDIR)\ttcache.obj \ + $(TMPDIR)\ttcalc.obj \ + $(TMPDIR)\ttcmap.obj \ + $(TMPDIR)\ttdebug.obj \ + $(TMPDIR)\ttfile.obj \ + $(TMPDIR)\ttgload.obj \ + $(TMPDIR)\ttinterp.obj \ + $(TMPDIR)\ttload.obj \ + $(TMPDIR)\ttmemory.obj \ + $(TMPDIR)\ttmutex.obj \ + $(TMPDIR)\ttobjs.obj \ + $(TMPDIR)\ttraster.obj \ + $(TMPDIR)\ttextend.obj \ + $(TMPDIR)\ftxcmap.obj \ + $(TMPDIR)\ftxgasp.obj \ + $(TMPDIR)\ftxkern.obj \ + $(TMPDIR)\ftxpost.obj \ + $(TMPDIR)\ftxwidth.obj \ + $(TMPDIR)\ftxerr18.obj + + +PATH=$(TOOLS32)\bin;$(PATH) + +cc32 = "$(TOOLS32)\bin\cl.exe" +link32 = "$(TOOLS32)\bin\link.exe" +include32 = "-I$(TOOLS32)\include" -I$(ROOT)\arch\win32 +CP = copy +RM = del + +TTF_INCLUDES = -I$(ROOT) +TTF_DEFINES = -nologo -D__WIN32__ -D__WIN32DLL__ + +TTF_CFLAGS = $(cdebug) $(cflags) $(cvarsdll) $(include32) \ + $(TTF_INCLUDES) $(TTF_DEFINES) +CON_CFLAGS = $(cdebug) $(cflags) $(cvars) $(include32) -DCONSOLE +DOS_CFLAGS = $(cdebug) $(cflags) $(include16) -AL + +###################################################################### +# Link flags +###################################################################### + +!IFDEF NODEBUG +ldebug = /RELEASE +!ELSE +ldebug = -debug:full -debugtype:cv +!ENDIF + +# declarations common to all linker options +lcommon = /NODEFAULTLIB /RELEASE /NOLOGO + +# declarations for use on Intel i386, i486, and Pentium systems +!IF "$(MACHINE)" == "IX86" +DLLENTRY = @12 +lflags = $(lcommon) /MACHINE:$(MACHINE) +!ELSE +lflags = $(lcommon) /MACHINE:$(MACHINE) +!ENDIF + +conlflags = $(lflags) -subsystem:console -entry:mainCRTStartup +guilflags = $(lflags) -subsystem:windows -entry:WinMainCRTStartup +dlllflags = $(lflags) -entry:_DllMainCRTStartup$(DLLENTRY) -dll + +!IF "$(MACHINE)" == "PPC" +libc = libc.lib +libcdll = crtdll.lib +!ELSE +libc = libc.lib oldnames.lib +libcdll = msvcrt.lib oldnames.lib +!ENDIF + +baselibs = kernel32.lib $(optlibs) advapi32.lib +winlibs = $(baselibs) user32.lib gdi32.lib comdlg32.lib winspool.lib + +guilibs = $(libc) $(winlibs) +conlibs = $(libc) $(baselibs) +guilibsdll = $(libcdll) $(winlibs) +conlibsdll = $(libcdll) $(baselibs) + +###################################################################### +# Compile flags +###################################################################### + +!IFDEF NODEBUG +cdebug = -O2 -Gs -GD +!ELSE +cdebug = -Z7 -Od -WX +!ENDIF + +# declarations common to all compiler options +ccommon = -c -W3 -nologo -YX -Dtry=__try -Dexcept=__except + +# NEED BYTEORDER INFORMATION HERE !! +!IF "$(MACHINE)" == "IX86" +cflags = $(ccommon) -D_X86_=1 +!ELSE +!IF "$(MACHINE)" == "MIPS" +cflags = $(ccommon) -D_MIPS_=1 +!ELSE +!IF "$(MACHINE)" == "PPC" +cflags = $(ccommon) -D_PPC_=1 +!ELSE +!IF "$(MACHINE)" == "ALPHA" +cflags = $(ccommon) -D_ALPHA_=1 +!ENDIF +!ENDIF +!ENDIF +!ENDIF + +cvars = -DWIN32 -D_WIN32 +cvarsmt = $(cvars) -D_MT +cvarsdll = $(cvarsmt) -D_DLL + +###################################################################### +# Project specific targets +###################################################################### + +release: $(TTFDLL) +all: $(TTFDLL) + +install: $(TTFDLL) + -@md $(INSTALLDIR) + -@$(CP) $(TTFDLL) $(INSTALLDIR) + + + +$(TTFDLL): $(TTFOBJS) ttf.def + $(link32) $(ldebug) $(dlllflags) \ + $(guilibsdll) -out:$(TTFDLL) -def:ttf.def $(TTFOBJS) + +#ttf.def: $(TTFOBJS) +# ..\..\tcl8.0.4\win\release\dumpexts -o $@ ttf.dll $(TTFOBJS) + + +# +# Implicit rules +# + +{$(ROOT)\extend}.c{$(TMPDIR)}.obj: + $(cc32) $(TTF_CFLAGS) -Fo$(TMPDIR)\ $< + +{$(ROOT)}.c{$(TMPDIR)}.obj: + $(cc32) $(TTF_CFLAGS) -Fo$(TMPDIR)\ $< + + +clean: + -@del *.exp + -@del *.lib + -@del *.dll + -@del $(TMPDIR)\*.obj + -@del *.pch + -@del *.pdb diff --git a/lib/arch/win32/Makefile.gcc b/lib/arch/win32/Makefile.gcc new file mode 100644 index 0000000..68c9f4e --- /dev/null +++ b/lib/arch/win32/Makefile.gcc @@ -0,0 +1,96 @@ +# This file is part of the FreeType project. +# +# It builds the library for gcc under Win32. +# This Makefile will fail with MinGW32 ports of gcc and make under +# bare-bones Windows 9X, because of the limitations of command.com. +# Use Makefile.min instead. +# +# You will need GNU make. +# +# Use this file while in the lib directory with the following statement: +# +# make -f arch/win32/Makefile.gcc +# +# +# If you have the GNU gettext package installed, you can also try +# +# make -f arch/win32/Makefile.gcc HAVE_GETTEXT + +ARCH = arch/win32 +FT_MAKEFILE = $(ARCH)/Makefile.gcc + +CC = gcc + +ifndef GETTEXT +GETTEXT=NO_GETTEXT +endif + +ifdef DEBUG +CFLAGS = -Wall -O2 -g -ansi -pedantic -I$(ARCH) -I. -Iextend -D$(GETTEXT) +else +CFLAGS = -Wall -ansi -pedantic -O2 -s -I$(ARCH) -I. -Iextend -D$(GETTEXT) +endif + + +TTFILE = ./ttfile.c +TTMEMORY = ./ttmemory.c +TTMUTEX = ./ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +SRC_X = extend/ftxgasp.c extend/ftxkern.c extend/ftxpost.c \ + extend/ftxcmap.c extend/ftxwidth.c extend/ftxsbit.c \ + extend/ftxgsub.c extend/ftxgpos.c extend/ftxgdef.c \ + extend/ftxopen.c extend/ftxerr18.c +OBJS_X = $(SRC_X:.c=.o) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c \ + ttgload.c ttinterp.c ttload.c ttobjs.c \ + ttraster.c ttextend.c $(PORT) +OBJS_M = $(SRC_M:.c=.o) $(OBJS_X) + +SRC_S = $(ARCH)/freetype.c +OBJ_S = $(SRC_S:.c=.o) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +.PHONY: all debug clean distclean depend + + +all: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_S libttf.a + +debug: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_M DEBUG=1 libttf.a + +HAVE_GETTEXT: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_S GETTEXT=HAVE_GETTEXT \ + libttf.a + +$(OBJ_S): $(SRC_S) $(SRC_M) + +libttf.a: $($(LIB_FILES)) + -del $@ + ar src $@ $^ + +clean: + -del *.o + -del extend\*.o + -del $(subst /,\,$(ARCH)/*.o) + -del response + +distclean: clean + -del dep.end + -del libttf.a + +depend: $(SRS_S) $(SRC_M) $(SRC_X) + $(CC) -E -M $^ > dep.end + +ifeq (dep.end,$(wildcard dep.end)) + include dep.end +endif + +# end of Makefile.gcc diff --git a/lib/arch/win32/depend.win b/lib/arch/win32/depend.win new file mode 100644 index 0000000..7fd99bc --- /dev/null +++ b/lib/arch/win32/depend.win @@ -0,0 +1,103 @@ +# This dependency file to be used with various Win32 compilers +# has been generated automatically with the script `makedep' on +# 03-Sep-1999. + +ttapi.obj: ttapi.c ttconfig.h arch\win32\ft_conf.h freetype.h fterrid.h \ + ftnameid.h ttengine.h tttypes.h ttmutex.h ttcalc.h ttmemory.h \ + ttcache.h ttfile.h ttdebug.h ttobjs.h tttables.h ttcmap.h ttload.h \ + ttgload.h ttraster.h ttextend.h +ttcache.obj: ttcache.c ttengine.h tttypes.h ttconfig.h \ + arch\win32\ft_conf.h freetype.h fterrid.h ftnameid.h ttmutex.h \ + ttmemory.h ttcache.h ttobjs.h tttables.h ttcmap.h ttdebug.h +ttcalc.obj: ttcalc.c ttcalc.h ttconfig.h arch\win32\ft_conf.h freetype.h \ + fterrid.h ftnameid.h ttdebug.h tttypes.h tttables.h +ttcmap.obj: ttcmap.c ttobjs.h ttconfig.h arch\win32\ft_conf.h ttengine.h \ + tttypes.h freetype.h fterrid.h ftnameid.h ttmutex.h ttcache.h \ + tttables.h ttcmap.h ttdebug.h ttfile.h ttmemory.h ttload.h +ttdebug.obj: ttdebug.c ttdebug.h ttconfig.h arch\win32\ft_conf.h \ + tttypes.h freetype.h fterrid.h ftnameid.h tttables.h ttobjs.h \ + ttengine.h ttmutex.h ttcache.h ttcmap.h +ttextend.obj: ttextend.c ttextend.h ttconfig.h arch\win32\ft_conf.h \ + tttypes.h freetype.h fterrid.h ftnameid.h ttobjs.h ttengine.h \ + ttmutex.h ttcache.h tttables.h ttcmap.h ttmemory.h +ttfile.obj: ttfile.c ttconfig.h arch\win32\ft_conf.h freetype.h \ + fterrid.h ftnameid.h tttypes.h ttdebug.h ttengine.h ttmutex.h \ + ttmemory.h ttfile.h +ttgload.obj: ttgload.c tttypes.h ttconfig.h arch\win32\ft_conf.h \ + freetype.h fterrid.h ftnameid.h ttdebug.h ttcalc.h ttfile.h \ + ttengine.h ttmutex.h tttables.h ttobjs.h ttcache.h ttcmap.h ttgload.h \ + ttmemory.h tttags.h ttload.h +ttinterp.obj: ttinterp.c freetype.h fterrid.h ftnameid.h tttypes.h \ + ttconfig.h arch\win32\ft_conf.h ttdebug.h ttcalc.h ttmemory.h \ + ttinterp.h ttobjs.h ttengine.h ttmutex.h ttcache.h tttables.h \ + ttcmap.h +ttload.obj: ttload.c tttypes.h ttconfig.h arch\win32\ft_conf.h \ + freetype.h fterrid.h ftnameid.h ttdebug.h ttcalc.h ttfile.h \ + ttengine.h ttmutex.h tttables.h ttobjs.h ttcache.h ttcmap.h \ + ttmemory.h tttags.h ttload.h +ttmemory.obj: ttmemory.c ttdebug.h ttconfig.h arch\win32\ft_conf.h \ + tttypes.h freetype.h fterrid.h ftnameid.h ttmemory.h ttengine.h \ + ttmutex.h +ttmutex.obj: ttmutex.c ttmutex.h ttconfig.h arch\win32\ft_conf.h +ttobjs.obj: ttobjs.c ttobjs.h ttconfig.h arch\win32\ft_conf.h ttengine.h \ + tttypes.h freetype.h fterrid.h ftnameid.h ttmutex.h ttcache.h \ + tttables.h ttcmap.h ttfile.h ttdebug.h ttcalc.h ttmemory.h ttload.h \ + ttinterp.h ttextend.h +ttraster.obj: ttraster.c ttraster.h ttconfig.h arch\win32\ft_conf.h \ + freetype.h fterrid.h ftnameid.h ttengine.h tttypes.h ttmutex.h \ + ttdebug.h ttcalc.h ttmemory.h +extend\ftxcmap.obj: extend\ftxcmap.c extend\ftxcmap.h freetype.h fterrid.h \ + ftnameid.h tttypes.h ttconfig.h arch\win32\ft_conf.h ttobjs.h \ + ttengine.h ttmutex.h ttcache.h tttables.h ttcmap.h +extend\ftxerr18.obj: extend\ftxerr18.c ttconfig.h arch\win32\ft_conf.h \ + extend\ftxerr18.h freetype.h fterrid.h ftnameid.h extend\ftxkern.h \ + extend\ftxpost.h extend\ftxopen.h extend\ftxgdef.h extend\ftxgsub.h \ + extend\ftxgpos.h +extend\ftxgasp.obj: extend\ftxgasp.c extend\ftxgasp.h freetype.h fterrid.h \ + ftnameid.h tttypes.h ttconfig.h arch\win32\ft_conf.h ttobjs.h \ + ttengine.h ttmutex.h ttcache.h tttables.h ttcmap.h +extend\ftxgdef.obj: extend\ftxgdef.c tttypes.h ttconfig.h arch\win32\ft_conf.h \ + freetype.h fterrid.h ftnameid.h tttags.h ttload.h ttobjs.h ttengine.h \ + ttmutex.h ttcache.h tttables.h ttcmap.h ttextend.h ttmemory.h \ + ttfile.h ttdebug.h extend\ftxopen.h extend\ftxgdef.h extend\ftxgsub.h \ + extend\ftxgpos.h extend\ftxopenf.h +extend\ftxgpos.obj: extend\ftxgpos.c tttypes.h ttconfig.h arch\win32\ft_conf.h \ + freetype.h fterrid.h ftnameid.h tttags.h ttload.h ttobjs.h ttengine.h \ + ttmutex.h ttcache.h tttables.h ttcmap.h ttextend.h ttmemory.h \ + ttfile.h ttdebug.h extend\ftxopen.h extend\ftxgdef.h extend\ftxgsub.h \ + extend\ftxgpos.h extend\ftxopenf.h +extend\ftxgsub.obj: extend\ftxgsub.c tttypes.h ttconfig.h arch\win32\ft_conf.h \ + freetype.h fterrid.h ftnameid.h tttags.h ttload.h ttobjs.h ttengine.h \ + ttmutex.h ttcache.h tttables.h ttcmap.h ttextend.h ttmemory.h \ + ttfile.h ttdebug.h extend\ftxopen.h extend\ftxgdef.h extend\ftxgsub.h \ + extend\ftxgpos.h extend\ftxopenf.h +extend\ftxkern.obj: extend\ftxkern.c extend\ftxkern.h freetype.h fterrid.h \ + ftnameid.h ttextend.h ttconfig.h arch\win32\ft_conf.h tttypes.h \ + ttobjs.h ttengine.h ttmutex.h ttcache.h tttables.h ttcmap.h ttdebug.h \ + ttmemory.h ttfile.h ttload.h tttags.h +extend\ftxopen.obj: extend\ftxopen.c tttypes.h ttconfig.h arch\win32\ft_conf.h \ + freetype.h fterrid.h ftnameid.h ttload.h ttobjs.h ttengine.h \ + ttmutex.h ttcache.h tttables.h ttcmap.h ttextend.h ttmemory.h \ + ttfile.h ttdebug.h extend\ftxopen.h extend\ftxgdef.h extend\ftxgsub.h \ + extend\ftxgpos.h extend\ftxopenf.h +extend\ftxpost.obj: extend\ftxpost.c extend\ftxpost.h freetype.h fterrid.h \ + ftnameid.h tttypes.h ttconfig.h arch\win32\ft_conf.h ttobjs.h \ + ttengine.h ttmutex.h ttcache.h tttables.h ttcmap.h ttload.h ttfile.h \ + ttdebug.h tttags.h ttmemory.h ttextend.h +extend\ftxsbit.obj: extend\ftxsbit.c extend\ftxsbit.h freetype.h fterrid.h \ + ftnameid.h ttobjs.h ttconfig.h arch\win32\ft_conf.h ttengine.h \ + tttypes.h ttmutex.h ttcache.h tttables.h ttcmap.h ttfile.h ttdebug.h \ + ttload.h ttmemory.h tttags.h ttextend.h +extend\ftxwidth.obj: extend\ftxwidth.c extend\ftxwidth.h freetype.h fterrid.h \ + ftnameid.h ttdebug.h ttconfig.h arch\win32\ft_conf.h tttypes.h \ + ttobjs.h ttengine.h ttmutex.h ttcache.h tttables.h ttcmap.h ttfile.h \ + tttags.h ttload.h +!ifndef __MAKE__ +arch\win32\freetype.obj: arch\win32\freetype.c ttapi.c ttconfig.h \ + arch\win32\ft_conf.h freetype.h fterrid.h ftnameid.h ttengine.h \ + tttypes.h ttmutex.h ttcalc.h ttmemory.h ttcache.h ttfile.h ttdebug.h \ + ttobjs.h tttables.h ttcmap.h ttload.h ttgload.h ttraster.h ttextend.h \ + ttcache.c ttcalc.c ttcmap.c ttdebug.c ttgload.c tttags.h ttinterp.c \ + ttinterp.h ttload.c ttobjs.c ttraster.c ttfile.c ttmemory.c ttmutex.c \ + ttextend.c +!endif diff --git a/lib/arch/win32/freetype.c b/lib/arch/win32/freetype.c new file mode 100644 index 0000000..8c391a7 --- /dev/null +++ b/lib/arch/win32/freetype.c @@ -0,0 +1,42 @@ +/* This file is part of the FreeType project */ + +/* single object library component for Win32 */ +#define TT_MAKE_OPTION_SINGLE_OBJECT + +/* Note, you should define the EXPORT_DEF and EXPORT_FUNC macros */ +/* here if you want to build a Win32 DLL. If undefined, the */ +/* macros default to "extern"/"" (nothing), which is suitable */ +/* for static libraries. See `ttconfig.h' for details. */ + +/* The macro EXPORT_DEF is placed before each high-level API */ +/* function declaration, and EXPORT_FUNC before each definition */ +/* (body). You can then use it to take any compiler-specific */ +/* pragma for DLL-exported symbols */ + +/* first include common core components */ + +#include "ttapi.c" +#include "ttcache.c" +#include "ttcalc.c" +#include "ttcmap.c" +#include "ttdebug.c" +#include "ttgload.c" +#include "ttinterp.c" +#include "ttload.c" +#include "ttobjs.c" +#include "ttraster.c" + +/* then system-specific (or ANSI) components */ + +#include "ttfile.c" +#include "ttmemory.c" +#include "ttmutex.c" + +/* finally, add some extensions */ + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE +#include "ttextend.c" +#endif + + +/* END */ diff --git a/lib/arch/win32/freetype.dsp b/lib/arch/win32/freetype.dsp new file mode 100644 index 0000000..b04390b --- /dev/null +++ b/lib/arch/win32/freetype.dsp @@ -0,0 +1,104 @@ +# Microsoft Developer Studio Project File - Name="freetype" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=freetype - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "freetype.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "freetype.mak" CFG="freetype - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "freetype - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "freetype - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe + +!IF "$(CFG)" == "freetype - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O1 /I "." /I "..\.." /I "..\..\extend" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# SUBTRACT CPP /YX +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "freetype - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /Zi /O1 /I "." /I "..\.." /I "..\..\extend" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# SUBTRACT CPP /YX +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "freetype - Win32 Release" +# Name "freetype - Win32 Debug" +# Begin Source File + +SOURCE=.\freetype.c +# End Source File +# Begin Source File + +SOURCE=..\..\Extend\Ftxcmap.c +# End Source File +# Begin Source File + +SOURCE=..\..\Extend\ftxerr18.c +# End Source File +# Begin Source File + +SOURCE=..\..\Extend\Ftxgasp.c +# End Source File +# Begin Source File + +SOURCE=..\..\Extend\Ftxkern.c +# End Source File +# Begin Source File + +SOURCE=..\..\Extend\ftxpost.c +# End Source File +# End Target +# End Project diff --git a/lib/arch/win32/freetype.dsw b/lib/arch/win32/freetype.dsw new file mode 100644 index 0000000..e21f7cd --- /dev/null +++ b/lib/arch/win32/freetype.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "freetype"=.\freetype.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/lib/arch/win32/freetype.ide b/lib/arch/win32/freetype.ide new file mode 100644 index 0000000..f5c4043 Binary files /dev/null and b/lib/arch/win32/freetype.ide differ diff --git a/lib/arch/win32/freetype.mak b/lib/arch/win32/freetype.mak new file mode 100644 index 0000000..2cb684e --- /dev/null +++ b/lib/arch/win32/freetype.mak @@ -0,0 +1,353 @@ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +!IF "$(CFG)" == "" +CFG=freetype - Win32 Debug +!MESSAGE No configuration specified. Defaulting to freetype - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "freetype - Win32 Release" && "$(CFG)" !=\ + "freetype - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "freetype.mak" CFG="freetype - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "freetype - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "freetype - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "freetype - Win32 Debug" +CPP=cl.exe + +!IF "$(CFG)" == "freetype - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +OUTDIR=.\Release +INTDIR=.\Release + +ALL : "$(OUTDIR)\freetype.lib" + +CLEAN : + -@erase ".\Release\freetype.lib" + -@erase ".\Release\Ftxkern.obj" + -@erase ".\Release\ftxpost.obj" + -@erase ".\Release\ftxerr18.obj" + -@erase ".\Release\Ftxcmap.obj" + -@erase ".\Release\Freetype.obj" + -@erase ".\Release\Ftxgasp.obj" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /W3 /GX /O2 /I "." /I "..\.." /I "..\..\extend" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +CPP_PROJ=/nologo /ML /W3 /GX /O2 /I "." /I "..\.." /I "..\..\extend" /D "WIN32"\ + /D "NDEBUG" /D "_WINDOWS" /Fp"$(INTDIR)/freetype.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\Release/ +CPP_SBRS= +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/freetype.bsc" +BSC32_SBRS= +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo +LIB32_FLAGS=/nologo /out:"$(OUTDIR)/freetype.lib" +LIB32_OBJS= \ + "$(INTDIR)/Ftxkern.obj" \ + "$(INTDIR)/ftxpost.obj" \ + "$(INTDIR)/ftxerr18.obj" \ + "$(INTDIR)/Ftxcmap.obj" \ + "$(INTDIR)/Freetype.obj" \ + "$(INTDIR)/Ftxgasp.obj" + +"$(OUTDIR)\freetype.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS) + $(LIB32) @<< + $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) +<< + +!ELSEIF "$(CFG)" == "freetype - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +OUTDIR=.\Debug +INTDIR=.\Debug + +ALL : "$(OUTDIR)\freetype.lib" + +CLEAN : + -@erase ".\Debug\freetype.lib" + -@erase ".\Debug\Freetype.obj" + -@erase ".\Debug\Ftxkern.obj" + -@erase ".\Debug\ftxpost.obj" + -@erase ".\Debug\Ftxcmap.obj" + -@erase ".\Debug\Ftxgasp.obj" + -@erase ".\Debug\ftxerr18.obj" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /W3 /GX /Z7 /Od /I "." /I "..\.." /I "..\..\extend" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c +CPP_PROJ=/nologo /MLd /W3 /GX /Z7 /Od /I "." /I "..\.." /I "..\..\extend" /D\ + "WIN32" /D "_DEBUG" /D "_WINDOWS" /Fp"$(INTDIR)/freetype.pch" /YX\ + /Fo"$(INTDIR)/" /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/freetype.bsc" +BSC32_SBRS= +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo +LIB32_FLAGS=/nologo /out:"$(OUTDIR)/freetype.lib" +LIB32_OBJS= \ + "$(INTDIR)/Freetype.obj" \ + "$(INTDIR)/Ftxkern.obj" \ + "$(INTDIR)/ftxpost.obj" \ + "$(INTDIR)/Ftxcmap.obj" \ + "$(INTDIR)/Ftxgasp.obj" \ + "$(INTDIR)/ftxerr18.obj" + +"$(OUTDIR)\freetype.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS) + $(LIB32) @<< + $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Target + +# Name "freetype - Win32 Release" +# Name "freetype - Win32 Debug" + +!IF "$(CFG)" == "freetype - Win32 Release" + +!ELSEIF "$(CFG)" == "freetype - Win32 Debug" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=\Freetype\Lib\Extend\ftxpost.c +DEP_CPP_FTXPO=\ + ".\..\..\Extend\ftxpost.h"\ + ".\..\..\tttypes.h"\ + ".\..\..\ttobjs.h"\ + ".\..\..\tttables.h"\ + ".\..\..\ttload.h"\ + ".\..\..\ttfile.h"\ + ".\..\..\tttags.h"\ + ".\..\..\ttmemory.h"\ + ".\..\..\ttextend.h"\ + ".\..\..\freetype.h"\ + "..\..\ttconfig.h"\ + ".\ft_conf.h"\ + "..\..\ttengine.h"\ + "..\..\ttmutex.h"\ + "..\..\ttcache.h"\ + "..\..\ttcmap.h"\ + ".\..\..\ttdebug.h"\ + + +"$(INTDIR)\ftxpost.obj" : $(SOURCE) $(DEP_CPP_FTXPO) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=\Freetype\Lib\Extend\ftxerr18.c +DEP_CPP_FTXER=\ + ".\..\..\Extend\ftxerr18.h"\ + ".\..\..\Extend\ftxkern.h"\ + ".\..\..\Extend\ftxpost.h"\ + ".\..\..\freetype.h"\ + "..\..\ttconfig.h"\ + ".\ft_conf.h"\ + + +"$(INTDIR)\ftxerr18.obj" : $(SOURCE) $(DEP_CPP_FTXER) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=\Freetype\Lib\Extend\Ftxgasp.c +DEP_CPP_FTXGA=\ + ".\..\..\Extend\ftxgasp.h"\ + ".\..\..\tttypes.h"\ + ".\..\..\ttobjs.h"\ + ".\..\..\tttables.h"\ + ".\..\..\freetype.h"\ + "..\..\ttconfig.h"\ + ".\ft_conf.h"\ + "..\..\ttengine.h"\ + "..\..\ttmutex.h"\ + "..\..\ttcache.h"\ + "..\..\ttcmap.h"\ + + +"$(INTDIR)\Ftxgasp.obj" : $(SOURCE) $(DEP_CPP_FTXGA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=\Freetype\Lib\Extend\Ftxkern.c +DEP_CPP_FTXKE=\ + ".\..\..\Extend\ftxkern.h"\ + ".\..\..\ttextend.h"\ + ".\..\..\tttypes.h"\ + ".\..\..\ttdebug.h"\ + ".\..\..\ttmemory.h"\ + ".\..\..\ttfile.h"\ + ".\..\..\ttobjs.h"\ + ".\..\..\ttload.h"\ + ".\..\..\tttags.h"\ + ".\..\..\freetype.h"\ + "..\..\ttconfig.h"\ + ".\ft_conf.h"\ + "..\..\ttengine.h"\ + "..\..\ttmutex.h"\ + "..\..\ttcache.h"\ + ".\..\..\tttables.h"\ + "..\..\ttcmap.h"\ + + +"$(INTDIR)\Ftxkern.obj" : $(SOURCE) $(DEP_CPP_FTXKE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=\Freetype\Lib\Extend\Ftxcmap.c +DEP_CPP_FTXCM=\ + ".\..\..\Extend\ftxcmap.h"\ + ".\..\..\tttypes.h"\ + ".\..\..\ttobjs.h"\ + ".\..\..\tttables.h"\ + ".\..\..\freetype.h"\ + "..\..\ttconfig.h"\ + ".\ft_conf.h"\ + "..\..\ttengine.h"\ + "..\..\ttmutex.h"\ + "..\..\ttcache.h"\ + "..\..\ttcmap.h"\ + + +"$(INTDIR)\Ftxcmap.obj" : $(SOURCE) $(DEP_CPP_FTXCM) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Freetype.c +DEP_CPP_FREET=\ + ".\..\..\ttapi.c"\ + ".\..\..\ttcache.c"\ + ".\..\..\ttcalc.c"\ + ".\..\..\ttcmap.c"\ + ".\..\..\ttgload.c"\ + ".\..\..\ttinterp.c"\ + ".\..\..\ttload.c"\ + ".\..\..\ttobjs.c"\ + ".\..\..\ttraster.c"\ + ".\..\..\ttfile.c"\ + ".\..\..\ttmemory.c"\ + ".\..\..\ttmutex.c"\ + ".\..\..\ttextend.c"\ + ".\..\..\freetype.h"\ + "..\..\ttengine.h"\ + "..\..\ttcalc.h"\ + ".\..\..\ttmemory.h"\ + "..\..\ttcache.h"\ + ".\..\..\ttfile.h"\ + ".\..\..\ttobjs.h"\ + ".\..\..\ttload.h"\ + "..\..\ttgload.h"\ + "..\..\ttraster.h"\ + ".\..\..\ttextend.h"\ + "..\..\ttconfig.h"\ + ".\ft_conf.h"\ + "..\..\ttmutex.h"\ + ".\..\..\tttypes.h"\ + ".\..\..\ttdebug.h"\ + ".\..\..\tttables.h"\ + "..\..\ttcmap.h"\ + ".\..\..\tttags.h"\ + "..\..\ttinterp.h"\ + {$(INCLUDE)}"\unistd.h"\ + + +"$(INTDIR)\Freetype.obj" : $(SOURCE) $(DEP_CPP_FREET) "$(INTDIR)" + + +# End Source File +# End Target +# End Project +################################################################################ diff --git a/lib/arch/win32/freetype.mdp b/lib/arch/win32/freetype.mdp new file mode 100644 index 0000000..9082b5a Binary files /dev/null and b/lib/arch/win32/freetype.mdp differ diff --git a/lib/arch/win32/ft_conf.h b/lib/arch/win32/ft_conf.h new file mode 100644 index 0000000..63819dd --- /dev/null +++ b/lib/arch/win32/ft_conf.h @@ -0,0 +1,210 @@ +/* This file is part of the FreeType project */ + +/* ft_conf.h for Win32 */ + + +/* we need the following because there are some typedefs in this file */ + +#ifndef FT_CONF_H +#define FT_CONF_H + +#ifndef WIN32 +#define WIN32 +#endif + +/* Define to empty if the 'const' keyword does not work. */ +/* #undef const */ + +/* Define if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H + +/* Define if you have the getpagesize function. */ +#undef HAVE_GETPAGESIZE + +/* Define if you have the memcpy function. */ +#define HAVE_MEMCPY + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE + +/* Define if you have the valloc function. */ +#undef HAVE_VALLOC + +/* Define if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + +/* The number of bytes in a int. */ +#define SIZEOF_INT 4 + +/* The number of bytes in a long. */ +#define SIZEOF_LONG 4 + +/**********************************************************************/ +/* */ +/* The following configuration macros can be tweaked manually by */ +/* a developer to turn on or off certain features or options in the */ +/* TrueType engine. This may be useful to tune it for specific */ +/* purposes.. */ +/* */ +/**********************************************************************/ + + +/*************************************************************************/ +/* Define this if the underlying operating system uses a different */ +/* character width than 8bit for file names. You must then also supply */ +/* a typedef declaration for defining 'TT_Text'. Default is off. */ + +/* #define HAVE_TT_TEXT */ + + +/*************************************************************************/ +/* Define this if you want to generate code to support engine extensions */ +/* Default is on, but if you're satisfied by the basic services provided */ +/* by the engine and need no extensions, undefine this configuration */ +/* macro to save a few more bytes. */ + +#define TT_CONFIG_OPTION_EXTEND_ENGINE + + +/*************************************************************************/ +/* Define this if you want to generate code to support gray-scaling, */ +/* a.k.a. font-smoothing or anti-aliasing. Default is on, but you can */ +/* disable it if you don't need it. */ + +#define TT_CONFIG_OPTION_GRAY_SCALING + + +/*************************************************************************/ +/* Define this if you want to completely disable the use of the bytecode */ +/* interpreter. Doing so will produce a much smaller library, but the */ +/* quality of the rendered glyphs will enormously suffer from this. */ +/* */ +/* This switch was introduced due to the Apple patents issue which */ +/* emerged recently on the FreeType lists. We still do not have Apple's */ +/* opinion on the subject and will change this as soon as we have. */ + +#undef TT_CONFIG_OPTION_NO_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to use a big 'switch' statement within the */ +/* bytecode interpreter. Because some non-optimizing compilers are not */ +/* able to produce jump tables from such statements, undefining this */ +/* configuration macro will generate the appropriate C jump table in */ +/* ttinterp.c. If you use an optimizing compiler, you should leave it */ +/* defined for better performance and code compactness.. */ + +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the TrueType */ +/* bytecode interpreter. This will produce much bigger code, which */ +/* _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the scan-line */ +/* converter (the component which in charge of converting outlines into */ +/* bitmaps). This will produce a bigger object file for "ttraster.c", */ +/* which _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_RASTER + + +/*************************************************************************/ +/* Define TT_CONFIG_THREAD_SAFE if you want to build a thread-safe */ +/* version of the library. */ + +#undef TT_CONFIG_OPTION_THREAD_SAFE + + +/**********************************************************************/ +/* */ +/* The following macros are used to define the debug level, as well */ +/* as individual tracing levels for each component. There are */ +/* currently three modes of operation : */ +/* */ +/* - trace mode (define DEBUG_LEVEL_TRACE) */ +/* */ +/* The engine prints all error messages, as well as tracing */ +/* ones, filtered by each component's level */ +/* */ +/* - debug mode (define DEBUG_LEVEL_ERROR) */ +/* */ +/* Disable tracing, but keeps error output and assertion */ +/* checks. */ +/* */ +/* - release mode (don't define anything) */ +/* */ +/* Don't include error-checking or tracing code in the */ +/* engine's code. Ideal for releases. */ +/* */ +/* NOTE : */ +/* */ +/* Each component's tracing level is defined in its own source. */ +/* */ +/**********************************************************************/ + +/* Define if you want to use the tracing debug mode */ +#undef DEBUG_LEVEL_TRACE + +/* Define if you want to use the error debug mode - ignored if */ +/* DEBUG_LEVEL_TRACE is defined */ +#undef DEBUG_LEVEL_ERROR + + +/**************************************************************************/ +/* Definition of various integer sizes. These types are used by ttcalc */ +/* and ttinterp (for the 64-bit integers) only.. */ + +#if SIZEOF_INT == 4 + + typedef signed int TT_Int32; + typedef unsigned int TT_Word32; + +#elif SIZEOF_LONG == 4 + + typedef signed long TT_Int32; + typedef unsigned long TT_Word32; + +#else +#error "no 32bit type found" +#endif + +#if SIZEOF_LONG == 8 + +/* LONG64 must be defined when a 64-bit type is available */ +/* INT64 must then be defined to this type.. */ +#define LONG64 +#define INT64 long + +#else + +/* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */ +/* by defining the TT_USE_LONG_LONG macro in 'ft_conf.h'. Note that this */ +/* will produce many -ansi warnings during library compilation. */ +#ifdef TT_USE_LONG_LONG + +#define LONG64 +#define INT64 long long + +#endif /* TT_USE_LONG_LONG */ +#endif + +#endif /* FT_CONF_H */ + + +/* END */ diff --git a/lib/arch/win32/makedef b/lib/arch/win32/makedef new file mode 100644 index 0000000..4f91819 --- /dev/null +++ b/lib/arch/win32/makedef @@ -0,0 +1,24 @@ +# makedef +# +# This shell script creates a .DEF file necessary for building as DLL +# on the Windows 32-bit platform. + +echo "\ +; This definition file to be used to built the library as DLL +; has been generated automatically with the script \`makedef' on +; `date +%d-%b-%Y`. + +LIBRARY ft13_32 +DESCRIPTION 'FreeType 1.3 32-bit DLL © 1996-1999 Turner, Wilhelm, Lemberg' +EXETYPE WINDOWS +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE MULTIPLE +EXPORTS +" > ttf.def + +(cd ../.. + sed -n -e "/^ *EXPORT_DEF/!d ; n ; s/(.*$//" \ + -e "s/;$//" -e "s/ const / /" -e "s/ *[a-zA-Z][a-zA-Z_\*]* //" \ + -e "s/ *//g" -e "s/^/ /" -e "p" *.h extend/*.h) >> ttf.def + +# eof diff --git a/lib/arch/win32/makedep b/lib/arch/win32/makedep new file mode 100644 index 0000000..34ade91 --- /dev/null +++ b/lib/arch/win32/makedep @@ -0,0 +1,29 @@ +# makedep +# +# This shell script creates a dependency file necessary for some compilers +# on the Win32 platform. + +echo "\ +# This dependency file to be used with various Win32 compilers +# has been generated automatically with the script \`makedep' on +# `date +%d-%b-%Y`. +" > depend.win + +(cd ../.. + gcc -MM -Iarch/win32 -I. *.c | \ + sed -e "s/\.o:/.obj:/" -e "s:/:\\\\:g") >> depend.win + +(cd ../.. + gcc -MM -Iarch/win32 -I. -Iextend extend/*.c | \ + sed -e "s/^\(.*\)\.o:/extend\\\\\1.obj:/" -e "s:/:\\\\:g") >> depend.win + +echo "!ifndef __MAKE__" >> depend.win + +(cd ../.. + gcc -MM -Iarch/win32 -I. -Iextend arch/win32/*.c | \ + sed -e "s/^\(.*\)\.o:/arch\\\\win32\\\\\1.obj:/" \ + -e "s:/:\\\\:g") >> depend.win + +echo "!endif" >> depend.win + +# eof diff --git a/lib/arch/win32/ttf.def b/lib/arch/win32/ttf.def new file mode 100644 index 0000000..f833c07 --- /dev/null +++ b/lib/arch/win32/ttf.def @@ -0,0 +1,127 @@ +; This definition file to be used to built the library as DLL +; has been generated automatically with the script `makedef' on +; 03-Sep-1999. + +LIBRARY ft13_32 +DESCRIPTION 'FreeType 1.3 32-bit DLL © 1996-1999 Turner, Wilhelm, Lemberg' +EXETYPE WINDOWS +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE MULTIPLE +EXPORTS + + TT_FreeType_Version + TT_Init_FreeType + TT_Done_FreeType + TT_Set_Raster_Gray_Palette + TT_Open_Face + TT_Open_Collection + TT_Get_Face_Properties + TT_Set_Face_Pointer + TT_Get_Face_Pointer + TT_Flush_Face + TT_Get_Face_Metrics + TT_Close_Face + TT_Get_Font_Data + TT_New_Instance + TT_Set_Instance_Resolutions + TT_Set_Instance_CharSize + TT_Set_Instance_CharSizes + TT_Set_Instance_PixelSizes + TT_Set_Instance_Transform_Flags + TT_Get_Instance_Metrics + TT_Set_Instance_Pointer + TT_Get_Instance_Pointer + TT_Done_Instance + TT_New_Glyph + TT_Done_Glyph + TT_Load_Glyph + TT_Get_Glyph_Outline + TT_Get_Glyph_Metrics + TT_Get_Glyph_Big_Metrics + TT_Get_Glyph_Bitmap + TT_Get_Glyph_Pixmap + TT_New_Outline + TT_Done_Outline + TT_Copy_Outline + TT_Get_Outline_Bitmap + TT_Get_Outline_Pixmap + TT_Get_Outline_BBox + TT_Transform_Outline + TT_Translate_Outline + TT_Transform_Vector + TT_MulDiv + TT_MulFix + TT_Get_CharMap_Count + TT_Get_CharMap_ID + TT_Get_CharMap + TT_Char_Index + TT_Get_Name_Count + TT_Get_Name_ID + TT_Get_Name_String + TT_Register_Extension + TT_Extension_Get + TT_Use_Stream + TT_Done_Stream + TT_Flush_Stream + TT_Read_File + TT_Seek_File + TT_Skip_File + TT_Read_At_File + TT_File_Pos + TT_Stream_Size + TT_Null_FileFrame + TT_Access_Frame + TT_Check_And_Access_Frame + TT_Forget_Frame + TT_Get_Char + TT_Get_Short + TT_Get_Long + TT_LookUp_Table + TT_Alloc + TT_Realloc + TT_Free + TT_CharMap_First + TT_CharMap_Next + TT_CharMap_Last + TT_ErrToString18 + TT_Get_Face_Gasp_Flags + TT_Init_GDEF_Extension + TT_Load_GDEF_Table + TT_GDEF_Get_Glyph_Property + TT_GDEF_Build_ClassDefinition + TT_Init_GPOS_Extension + TT_Load_GPOS_Table + TT_GPOS_Select_Script + TT_GPOS_Select_Language + TT_GPOS_Select_Feature + TT_GPOS_Query_Scripts + TT_GPOS_Query_Languages + TT_GPOS_Query_Features + TT_GPOS_Add_Feature + TT_GPOS_Clear_Features + TT_Init_GSUB_Extension + TT_Load_GSUB_Table + TT_GSUB_Select_Script + TT_GSUB_Select_Language + TT_GSUB_Select_Feature + TT_GSUB_Query_Scripts + TT_GSUB_Query_Languages + TT_GSUB_Query_Features + TT_GSUB_Add_Feature + TT_GSUB_Clear_Features + TT_GSUB_Register_Alternate_Function + TT_GSUB_Apply_String + TT_GSUB_Add_String + TT_Init_Kerning_Extension + TT_Get_Kerning_Directory + TT_Load_Kerning_Table + TT_Init_Post_Extension + TT_Load_PS_Names + TT_Get_PS_Name + TT_Init_SBit_Extension + TT_Get_Face_Bitmaps + TT_New_SBit_Image + TT_Done_SBit_Image + TT_Get_SBit_Strike + TT_Load_Glyph_Bitmap + TT_Get_Face_Widths diff --git a/lib/extend/ftxcmap.c b/lib/extend/ftxcmap.c new file mode 100644 index 0000000..d44136e --- /dev/null +++ b/lib/extend/ftxcmap.c @@ -0,0 +1,347 @@ +/******************************************************************* + * + * ftxcmap.h 1.0 + * + * API extension for iterating over Cmaps + * + * Copyright 1996-1999 by Juliusz Chroboczek, + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + ******************************************************************/ + +#include "ftxcmap.h" + +#include "tttypes.h" +#include "ttobjs.h" +#include "tttables.h" + +static Long charmap_first4 ( PCMap4, UShort* ); +static Long charmap_next4 ( PCMap4, UShort, UShort* ); +static Long charmap_last4 ( PCMap4, UShort* ); +static UShort charmap_find_id4( PCMap4, UShort, TCMap4Segment*, UShort ); + + +/******************************************************************* + * + * Function : TT_CharMap_First + * + * Description : Returns the first valid character code in a + * given character map. Also returns the corresponding + * glyph index. + * + * Input : charMap handle to the target character map + * id address where the glyph index will be + * be returned in case of success + * + * Output : First valid character code. -1 in case of failure. + * + * Notes : + * + ******************************************************************/ + +EXPORT_FUNC +TT_Long TT_CharMap_First( TT_CharMap charMap, + TT_UShort* id ) +{ + PCMapTable cmap; + UShort i, c; + + + if ( !( cmap = HANDLE_CharMap( charMap ) ) ) + return -1; + + switch ( cmap->format ) + { + case 0: + if ( id ) + *id = cmap->c.cmap0.glyphIdArray[0]; + return 0; + + case 4: + return charmap_first4( &cmap->c.cmap4, id ); + + case 6: + if ( cmap->c.cmap6.entryCount < 1 ) + return -1; + + if ( id ) + *id = cmap->c.cmap6.glyphIdArray[0]; + return cmap->c.cmap6.firstCode; + + default: + /* Now loop from 0 to 65535. We can't use a simple "for' on */ + /* 16-bits systems, hence the "strange" loop here.. */ + i = 0; + do + { + c = TT_Char_Index( charMap, i ); + if ( c > 0 ) + { + if ( id ) + *id = c; + return i; + } + i++; + } while ( i != 0 ); /* because i is UShort! */ + + return -1; + } +} + + +static Long charmap_first4( PCMap4 cmap4, + UShort* id ) +{ + UShort firstCode; + + + if ( cmap4->segCountX2 / 2 < 1 ) + return -1; + + firstCode = cmap4->segments[0].startCount; + + if ( id ) + *id = charmap_find_id4( cmap4, firstCode, &(cmap4->segments[0]), 0 ); + + return firstCode; +} + + +/******************************************************************* + * + * Function : TT_CharMap_Next + * + * Description : Returns the next valid character code in a given + * charMap. + * + * Input : charMap handle to the target char. map + * index starting character code + * id address where the glyph index of the next + * character will be returned + * + * Output : Next valid character code after 'index'. -1 in case + * of failure. + * + * Notes : + * + ******************************************************************/ + +EXPORT_FUNC +TT_Long TT_CharMap_Next( TT_CharMap charMap, + TT_UShort index, + TT_UShort* id ) +{ + PCMapTable cmap; + UShort i, c; + + + cmap = HANDLE_CharMap( charMap ); + if ( !cmap ) + return -1; + + switch ( cmap->format ) + { + case 0: + if ( index < 255 ) + { + if ( id ) + *id = cmap->c.cmap0.glyphIdArray[index + 1]; + return index + 1; + } + else + return -1; + + case 4: + return charmap_next4( &cmap->c.cmap4, index, id ); + + case 6: + { + UShort firstCode = cmap->c.cmap6.firstCode; + + + if ( index + 1 < firstCode + cmap->c.cmap6.entryCount ) + { + if ( id ) + *id = cmap->c.cmap6.glyphIdArray[index + 1 - firstCode]; + return index + 1; + } + else + return -1; + } + + default: + /* Now loop from 0 to 65535. We can't use a simple "for" on */ + /* 16-bits systems, hence the "strange" loop here.. */ + i = 0; + do + { + c = TT_Char_Index( charMap, i ); + if ( c > 0 ) + { + if ( id ) + *id = c; + return i; + } + i++; + } while ( i != 0 ); /* because i is UShort! */ + + return -1; + } +} + + +static Long charmap_next4( PCMap4 cmap4, + UShort charCode, + UShort* id) +{ + UShort segCount, nextCode; + UShort i; + TCMap4Segment seg4; + + + if ( charCode == 0xFFFF ) + return -1; /* get it out of the way now */ + + segCount = cmap4->segCountX2 / 2; + + for ( i = 0; i < segCount; i++ ) + if ( charCode < cmap4->segments[i].endCount ) + break; + + /* Safety check - even though the last endCount should be 0xFFFF */ + if ( i >= segCount ) + return -1; + + seg4 = cmap4->segments[i]; + + if ( charCode < seg4.startCount ) + nextCode = seg4.startCount; + else + nextCode = charCode + 1; + + if ( id ) + *id = charmap_find_id4( cmap4, nextCode, &seg4, i ); + + return nextCode; +} + + +static UShort +charmap_find_id4( PCMap4 cmap4, + UShort charCode, + TCMap4Segment* seg4, + UShort i ) +{ + UShort index1; + + + if ( seg4->idRangeOffset == 0 ) + return (charCode + seg4->idDelta) & 0xFFFF; + else + { + index1 = seg4->idRangeOffset / 2 + charCode-seg4->startCount - + ( cmap4->segCountX2 / 2 - i ); + + if ( index1 >= cmap4->numGlyphId || cmap4->glyphIdArray[index1] == 0 ) + return 0; + else + return (cmap4->glyphIdArray[index1] + seg4->idDelta) & 0xFFFF; + } +} + + +/******************************************************************* + * + * Function : TT_CharMap_Last + * + * Description : Returns the last valid character code in a + * given character map. Also returns the corresponding + * glyph index. + * + * Input : charMap handle to the target character map + * id address where the glyph index will be + * be returned in case of success + * + * Output : Last valid character code. -1 in case of failure. + * + * Notes : + * + ******************************************************************/ + +EXPORT_FUNC +TT_Long TT_CharMap_Last( TT_CharMap charMap, + TT_UShort* id ) +{ + PCMapTable cmap; + UShort i, c; + + + if ( !( cmap = HANDLE_CharMap( charMap ) ) ) + return -1; + + switch ( cmap->format ) + { + case 0: + if ( id ) + *id = cmap->c.cmap0.glyphIdArray[255]; + return 255; + + case 4: + return charmap_last4( &cmap->c.cmap4, id ); + + case 6: + if ( cmap->c.cmap6.entryCount < 1 ) + return -1; + + if ( id ) + *id = cmap->c.cmap6.glyphIdArray[cmap->c.cmap6.entryCount - 1]; + return cmap->c.cmap6.firstCode + cmap->c.cmap6.entryCount - 1; + + default: + i = 65535; + do + { + c = TT_Char_Index( charMap, i ); + if ( c > 0 ) + { + if ( id ) + *id = c; + return i; + } + i--; + } while ( i != 0 ); + + return -1; + } +} + + +static Long charmap_last4( PCMap4 cmap4, + UShort* id ) +{ + UShort lastCode; + + + if ( cmap4->segCountX2 / 2 < 1 ) + return -1; + + lastCode = cmap4->segments[cmap4->segCountX2 / 2 - 1].endCount; + + if ( id ) + *id = charmap_find_id4( cmap4, + lastCode, + &(cmap4->segments[cmap4->segCountX2 / 2 - 1]), + 0 ); + + return lastCode; +} + + +/* END */ diff --git a/lib/extend/ftxcmap.h b/lib/extend/ftxcmap.h new file mode 100644 index 0000000..38ed8e1 --- /dev/null +++ b/lib/extend/ftxcmap.h @@ -0,0 +1,60 @@ +/******************************************************************* + * + * ftxcmap.h 1.0 + * + * API extension for iterating over Cmaps + * + * Copyright 1996-1999 by Juliusz Chroboczek, + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + ******************************************************************/ + +#ifndef FTXCMAP_H +#define FTXCMAP_H + +#include "freetype.h" + +#ifdef __cplusplus +extern "C" { +#endif + + /* Find the first entry of a Cmap. Its glyph index is returned */ + /* in the "id" field, while the function returns the first valid */ + /* character code in the Cmap. It returns -1 in case of failure. */ + + EXPORT_DEF + TT_Long TT_CharMap_First( TT_CharMap charMap, + TT_UShort* id ); + + + /* Find the next entry of Cmap. Same return conventions. */ + + EXPORT_DEF + TT_Long TT_CharMap_Next( TT_CharMap charMap, + TT_UShort startId, + TT_UShort* id ); + + /* Find the last entry of a Cmap. Its glyph index is returned */ + /* in the "id" field, while the function returns the last valid */ + /* character code in the Cmap. It returns -1 in case of failure. */ + + EXPORT_DEF + TT_Long TT_CharMap_Last( TT_CharMap charMap, + TT_UShort* id ); + + +#ifdef __cplusplus +} +#endif + +#endif /* FTXCMAP_H */ + + +/* END */ diff --git a/lib/extend/ftxerr18.c b/lib/extend/ftxerr18.c new file mode 100644 index 0000000..ac8934a --- /dev/null +++ b/lib/extend/ftxerr18.c @@ -0,0 +1,241 @@ +/****************************************************************************/ +/* */ +/* Erwin Dieterich, 15. 10. 1997 */ +/* - 15. 08. 1999 */ +/* */ +/* TT_ErrToString: translate error codes to character strings */ +/* */ +/* This extension provides internationalized error strings from the */ +/* various error messages. It uses the "gettext" package if available */ +/* or returns English/American message strings if not. */ +/* */ +/* If you do not want to use it, or if you encounter some problems */ +/* compiling this file, try to disable nls support when invoking */ +/* ./configure (on Unix). */ +/* */ +/* */ +/****************************************************************************/ + +#include "ttconfig.h" + +#include "ftxerr18.h" +#include "ftxkern.h" +#include "ftxpost.h" +#include "ftxopen.h" + +#ifdef HAVE_LOCALE_H +#include +#endif + +#ifdef HAVE_LIBINTL_H +#include +#undef _ +#define _( String ) dgettext( "freetype", String ) +#else +#define _( String ) ( String ) +#endif + + +EXPORT_FUNC +TT_String* TT_ErrToString18( TT_Error error ) +{ + + switch ( error ) + { + /* ----- high-level API error codes ----- */ + case TT_Err_Ok: + return _( "Successful function call, no error." ); + + case TT_Err_Invalid_Face_Handle: + return _( "Invalid face handle." ); + case TT_Err_Invalid_Instance_Handle: + return _( "Invalid instance handle." ); + case TT_Err_Invalid_Glyph_Handle: + return _( "Invalid glyph handle." ); + case TT_Err_Invalid_CharMap_Handle: + return _( "Invalid charmap handle." ); + case TT_Err_Invalid_Result_Address: + return _( "Invalid result address." ); + case TT_Err_Invalid_Glyph_Index: + return _( "Invalid glyph index." ); + case TT_Err_Invalid_Argument: + return _( "Invalid argument." ); + case TT_Err_Could_Not_Open_File: + return _( "Could not open file." ); + case TT_Err_File_Is_Not_Collection: + return _( "File is not a TrueType collection." ); + + case TT_Err_Table_Missing: + return _( "Mandatory table missing." ); + case TT_Err_Invalid_Horiz_Metrics: + return _( "Invalid horizontal metrics (hmtx table broken)." ); + case TT_Err_Invalid_CharMap_Format: + return _( "Invalid charmap format." ); + case TT_Err_Invalid_PPem: + return _( "Invalid ppem value." ); + case TT_Err_Invalid_Vert_Metrics: + return _( "Invalid vertical metrics (vmtx table broken)." ); + + case TT_Err_Invalid_File_Format: + return _( "Invalid file format." ); + + case TT_Err_Invalid_Engine: + return _( "Invalid engine." ); + case TT_Err_Too_Many_Extensions: + return _( "Too many extensions." ); + case TT_Err_Extensions_Unsupported: + return _( "Extensions unsupported." ); + case TT_Err_Invalid_Extension_Id: + return _( "Invalid extension id." ); + + case TT_Err_No_Vertical_Data: + return _( "No vertical data in font." ); + + case TT_Err_Max_Profile_Missing: + return _( "Maximum Profile (maxp) table missing." ); + case TT_Err_Header_Table_Missing: + return _( "Font Header (head) table missing." ); + case TT_Err_Horiz_Header_Missing: + return _( "Horizontal Header (hhea) table missing." ); + case TT_Err_Locations_Missing: + return _( "Index to Location (loca) table missing." ); + case TT_Err_Name_Table_Missing: + return _( "Naming (name) table missing." ); + case TT_Err_CMap_Table_Missing: + return _( "Character to Glyph Index Mapping (cmap) tables missing." ); + case TT_Err_Hmtx_Table_Missing: + return _( "Horizontal Metrics (hmtx) table missing." ); + case TT_Err_OS2_Table_Missing: + return _( "OS/2 table missing." ); + case TT_Err_Post_Table_Missing: + return _( "PostScript (post) table missing." ); + case TT_Err_Glyf_Table_Missing: + return _( "Glyph (glyf) table missing." ); + + + /* ----- memory component error codes ----- */ + case TT_Err_Out_Of_Memory: + return _( "Out of memory." ); + + + /* ----- file component error codes ----- */ + case TT_Err_Invalid_File_Offset: + return _( "Invalid file offset." ); + case TT_Err_Invalid_File_Read: + return _( "Invalid file read." ); + case TT_Err_Invalid_Frame_Access: + return _( "Invalid frame access." ); + + + /* ----- glyph loader error codes ----- */ + case TT_Err_Too_Many_Points: + return _( "Too many points." ); + case TT_Err_Too_Many_Contours: + return _( "Too many contours." ); + case TT_Err_Invalid_Composite: + return _( "Invalid composite glyph." ); + case TT_Err_Too_Many_Ins: + return _( "Too many instructions." ); + + + /* ----- byte-code interpreter error codes ----- */ + case TT_Err_Invalid_Opcode: + return _( "Invalid opcode." ); + case TT_Err_Too_Few_Arguments: + return _( "Too few arguments." ); + case TT_Err_Stack_Overflow: + return _( "Stack overflow." ); + case TT_Err_Code_Overflow: + return _( "Code overflow." ); + case TT_Err_Bad_Argument: + return _( "Bad argument." ); + case TT_Err_Divide_By_Zero: + return _( "Divide by zero." ); + case TT_Err_Storage_Overflow: + return _( "Storage overflow." ); + case TT_Err_Cvt_Overflow: + return _( "Control Value (cvt) table overflow." ); + case TT_Err_Invalid_Reference: + return _( "Invalid reference." ); + case TT_Err_Invalid_Distance: + return _( "Invalid distance." ); + case TT_Err_Interpolate_Twilight: + return _( "Interpolate twilight points." ); + case TT_Err_Debug_OpCode: + return _( "`DEBUG' opcode found." ); + case TT_Err_ENDF_In_Exec_Stream: + return _( "`ENDF' in byte-code stream." ); + case TT_Err_Out_Of_CodeRanges: + return _( "Out of code ranges." ); + case TT_Err_Nested_DEFS: + return _( "Nested function definitions." ); + case TT_Err_Invalid_CodeRange: + return _( "Invalid code range." ); + case TT_Err_Invalid_Displacement: + return _( "Invalid displacement." ); + case TT_Err_Execution_Too_Long: + return _( "Endless loop encountered while executing instructions." ); + + + /* ----- internal failure error codes ----- */ + case TT_Err_Nested_Frame_Access: + return _( "Nested frame access." ); + case TT_Err_Invalid_Cache_List: + return _( "Invalid cache list." ); + case TT_Err_Could_Not_Find_Context: + return _( "Could not find context." ); + case TT_Err_Unlisted_Object: + return _( "Unlisted object." ); + + + /* ----- scan-line converter error codes ----- */ + case TT_Err_Raster_Pool_Overflow: + return _( "Raster pool overflow." ); + case TT_Err_Raster_Negative_Height: + return _( "Raster: negative height encountered." ); + case TT_Err_Raster_Invalid_Value: + return _( "Raster: invalid value." ); + case TT_Err_Raster_Not_Initialized: + return _( "Raster not initialized." ); + + + /* ----- engine extensions error codes ----- */ + case TT_Err_Invalid_Kerning_Table_Format: + return _( "Invalid kerning (kern) table format." ); + case TT_Err_Invalid_Kerning_Table: + return _( "Invalid kerning (kern) table." ); + case TT_Err_Invalid_Post_Table_Format: + return _( "Invalid PostScript (post) table format." ); + case TT_Err_Invalid_Post_Table: + return _( "Invalid PostScript (post) table." ); + + + /* ----- TrueType Open extension error codes ----- */ + + case TTO_Err_Invalid_SubTable_Format: + return _( "Invalid TrueType Open subtable format." ); + case TTO_Err_Invalid_SubTable: + return _( "Invalid TrueType Open subtable." ); + case TTO_Err_Not_Covered: + return _( "Glyph(s) not covered by lookup." ); + case TTO_Err_Too_Many_Nested_Contexts: + return _( "Too many nested context substitutions." ); + case TTO_Err_Invalid_GSUB_SubTable_Format: + return _( "Invalid glyph substitution (GSUB) table format." ); + case TTO_Err_Invalid_GSUB_SubTable: + return _( "Invalid glyph substitution (GSUB) table." ); + case TTO_Err_Invalid_GPOS_SubTable_Format: + return _( "Invalid glyph positioning (GPOS) table format." ); + case TTO_Err_Invalid_GPOS_SubTable: + return _( "Invalid glyph positioning (GPOS) table." ); + + + default: + ; + } + + return _( "Invalid Error Number." ); +} + + +/* END */ diff --git a/lib/extend/ftxerr18.h b/lib/extend/ftxerr18.h new file mode 100644 index 0000000..3ad060b --- /dev/null +++ b/lib/extend/ftxerr18.h @@ -0,0 +1,38 @@ +/****************************************************************************/ +/* */ +/* Erwin Dieterich, 15. 10. 1997 */ +/* - 15. 08. 1999 */ +/* */ +/* TT_ErrToString: translate error codes to character strings */ +/* */ +/* This extension provides internationalized error strings from the */ +/* various error messages. It uses the "gettext" package where available */ +/* or returns english/american message strings if not. */ +/* */ +/* If you do not want to use it, or if you encounter some problems */ +/* compiling this file, try to disable nls support by configuring */ +/* FreeType with ./configure --disable-nls */ +/* */ +/* */ +/****************************************************************************/ + +#ifndef FTXERR18_H +#define FTXERR18_H + +#include "freetype.h" + +#ifdef __cplusplus + extern "C" { +#endif + + EXPORT_DEF + TT_String* TT_ErrToString18( TT_Error i ); + +#ifdef __cplusplus + } +#endif + +#endif /* FTXERR18_H */ + + +/* END */ diff --git a/lib/extend/ftxgasp.c b/lib/extend/ftxgasp.c new file mode 100644 index 0000000..b2bc083 --- /dev/null +++ b/lib/extend/ftxgasp.c @@ -0,0 +1,69 @@ +/******************************************************************* + * + * ftxgasp.c 1.0 + * + * Gasp table support API extension body + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * The gasp table is currently loaded by the core engine, but the + * standard API doesn't give access to it. This file is used to + * demonstrate the use of a simple API extension. + * + ******************************************************************/ + +#include "ftxgasp.h" + +#include "tttypes.h" +#include "ttobjs.h" +#include "tttables.h" + + + EXPORT_FUNC + TT_Error TT_Get_Face_Gasp_Flags( TT_Face face, + TT_UShort point_size, + TT_Bool* grid_fit, + TT_Bool* smooth_font ) + { + PFace faze = HANDLE_Face( face ); + UShort i, flag; + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + if ( faze->gasp.numRanges == 0 || !faze->gasp.gaspRanges ) + return TT_Err_Table_Missing; + + for ( i = 0; i < faze->gasp.numRanges; i++ ) + { + if ( point_size <= faze->gasp.gaspRanges[i].maxPPEM ) + { + flag = faze->gasp.gaspRanges[i].gaspFlag; + + *grid_fit = ( (flag & GASP_GRIDFIT) != 0 ); + *smooth_font = ( (flag & GASP_DOGRAY ) != 0 ); + + return TT_Err_Ok; + } + } + + /* for very large fonts we enable font smoothing and discard */ + /* grid fitting */ + + *grid_fit = 0; + *smooth_font = 1; + + return TT_Err_Ok; + } + + +/* END */ diff --git a/lib/extend/ftxgasp.h b/lib/extend/ftxgasp.h new file mode 100644 index 0000000..a0dde72 --- /dev/null +++ b/lib/extend/ftxgasp.h @@ -0,0 +1,53 @@ +/******************************************************************* + * + * ftxgasp.h 1.0 + * + * Gasp table support API extension + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * The gasp table is currently loaded by the core engine, but the + * standard API doesn't give access to it. This file is used to + * demonstrate the use of a simple API extension. + * + ******************************************************************/ + +#ifndef FTXGASP_H +#define FTXGASP_H + +#include "freetype.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + /* This function returns for a given 'point_size' the values of the */ + /* gasp flags 'grid_fit' and 'smooth_font'. The returned values */ + /* are booleans (where 0 = NO, and 1 = YES). */ + + /* Note that this function will return TT_Err_Table_Missing if */ + /* the font file doesn't contain any gasp table. */ + + EXPORT_DEF + TT_Error TT_Get_Face_Gasp_Flags( TT_Face face, + TT_UShort point_size, + TT_Bool* grid_fit, + TT_Bool* smooth_font ); + +#ifdef __cplusplus +} +#endif + +#endif /* FTXGASP_H */ + + +/* END */ diff --git a/lib/extend/ftxgdef.c b/lib/extend/ftxgdef.c new file mode 100644 index 0000000..9f94e96 --- /dev/null +++ b/lib/extend/ftxgdef.c @@ -0,0 +1,1099 @@ +/******************************************************************* + * + * ftxgdef.c + * + * TrueType Open GDEF table support. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include "tttypes.h" +#include "tttags.h" +#include "ttload.h" +#include "ttextend.h" +#include "ttmemory.h" +#include "ttfile.h" + +#include "ftxopen.h" +#include "ftxopenf.h" + + +#define GDEF_ID Build_Extension_ID( 'G', 'D', 'E', 'F' ) + + + static TT_Error Load_AttachList( TTO_AttachList* al, + PFace input ); + static TT_Error Load_LigCaretList( TTO_LigCaretList* lcl, + PFace input ); + + static void Free_AttachList( TTO_AttachList* al ); + static void Free_LigCaretList( TTO_LigCaretList* lcl ); + + static void Free_NewGlyphClasses( TTO_GDEFHeader* gdef ); + + + + /********************** + * Extension Functions + **********************/ + + + static TT_Error GDEF_Create( void* ext, + PFace face ) + { + DEFINE_LOAD_LOCALS( face->stream ); + + TTO_GDEFHeader* gdef = (TTO_GDEFHeader*)ext; + Long table; + + + /* by convention */ + + if ( !gdef ) + return TT_Err_Ok; + + /* a null offset indicates that there is no GDEF table */ + + gdef->offset = 0; + + /* we store the start offset and the size of the subtable */ + + table = TT_LookUp_Table( face, TTAG_GDEF ); + if ( table < 0 ) + return TT_Err_Ok; /* The table is optional */ + + if ( FILE_Seek( face->dirTables[table].Offset ) || + ACCESS_Frame( 4L ) ) + return error; + + gdef->offset = FILE_Pos() - 4L; /* undo ACCESS_Frame() */ + gdef->Version = GET_ULong(); + + FORGET_Frame(); + + gdef->loaded = FALSE; + + return TT_Err_Ok; + } + + + static TT_Error GDEF_Destroy( void* ext, + PFace face ) + { + TTO_GDEFHeader* gdef = (TTO_GDEFHeader*)ext; + + + /* by convention */ + + if ( !gdef ) + return TT_Err_Ok; + + if ( gdef->loaded ) + { + Free_LigCaretList( &gdef->LigCaretList ); + Free_AttachList( &gdef->AttachList ); + Free_ClassDefinition( &gdef->GlyphClassDef ); + Free_ClassDefinition( &gdef->MarkAttachClassDef ); + + Free_NewGlyphClasses( gdef ); + } + + return TT_Err_Ok; + } + + + EXPORT_FUNC + TT_Error TT_Init_GDEF_Extension( TT_Engine engine ) + { + PEngine_Instance _engine = HANDLE_Engine( engine ); + + + if ( !_engine ) + return TT_Err_Invalid_Engine; + + return TT_Register_Extension( _engine, + GDEF_ID, + sizeof ( TTO_GDEFHeader ), + GDEF_Create, + GDEF_Destroy ); + } + + + EXPORT_FUNC + TT_Error TT_Load_GDEF_Table( TT_Face face, + TTO_GDEFHeader* retptr ) + { + ULong cur_offset, new_offset, base_offset; + + TT_Error error; + TT_Stream stream; + TTO_GDEFHeader* gdef; + + PFace faze = HANDLE_Face( face ); + + + if ( !retptr ) + return TT_Err_Invalid_Argument; + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + error = TT_Extension_Get( faze, GDEF_ID, (void**)&gdef ); + if ( error ) + return error; + + if ( gdef->offset == 0 ) + return TT_Err_Table_Missing; /* no GDEF table; nothing to do */ + + /* now access stream */ + + if ( USE_Stream( faze->stream, stream ) ) + return error; + + base_offset = gdef->offset; + + /* skip version */ + + if ( FILE_Seek( base_offset + 4L ) || + ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort(); + + FORGET_Frame(); + + /* all GDEF subtables are optional */ + + if ( new_offset ) + { + new_offset += base_offset; + + /* only classes 1-4 are allowed here */ + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ClassDefinition( &gdef->GlyphClassDef, 5, + faze ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + } + else + gdef->GlyphClassDef.loaded = FALSE; + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort(); + + FORGET_Frame(); + + if ( new_offset ) + { + new_offset += base_offset; + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_AttachList( &gdef->AttachList, + faze ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + else + gdef->AttachList.loaded = FALSE; + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort(); + + FORGET_Frame(); + + if ( new_offset ) + { + new_offset += base_offset; + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_LigCaretList( &gdef->LigCaretList, + faze ) ) != TT_Err_Ok ) + goto Fail2; + (void)FILE_Seek( cur_offset ); + } + else + gdef->LigCaretList.loaded = FALSE; + + /* OpenType 1.2 has introduced the `MarkAttachClassDef' field. We + first have to scan the LookupFlag values to find out whether we + must load it or not. Here we only store the current file offset. */ + + gdef->MarkAttachClassDef_offset = FILE_Pos(); + gdef->MarkAttachClassDef.loaded = FALSE; + + gdef->LastGlyph = 0; + gdef->NewGlyphClasses = NULL; + gdef->loaded = TRUE; + + *retptr = *gdef; + DONE_Stream( stream ); + + return TT_Err_Ok; + + Fail2: + Free_AttachList( &gdef->AttachList ); + + Fail1: + Free_ClassDefinition( &gdef->GlyphClassDef ); + + /* release stream */ + + DONE_Stream( stream ); + + return error; + } + + + + /******************************* + * AttachList related functions + *******************************/ + + + /* AttachPoint */ + + static TT_Error Load_AttachPoint( TTO_AttachPoint* ap, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + UShort* pi; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = ap->PointCount = GET_UShort(); + + FORGET_Frame(); + + ap->PointIndex = NULL; + + if ( count ) + { + if ( ALLOC_ARRAY( ap->PointIndex, count, UShort ) ) + return error; + + pi = ap->PointIndex; + + if ( ACCESS_Frame( count * 2L ) ) + { + FREE( pi ); + return error; + } + + for ( n = 0; n < count; n++ ) + pi[n] = GET_UShort(); + + FORGET_Frame(); + } + + return TT_Err_Ok; + } + + + static void Free_AttachPoint( TTO_AttachPoint* ap ) + { + FREE( ap->PointIndex ); + } + + + /* AttachList */ + + static TT_Error Load_AttachList( TTO_AttachList* al, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_AttachPoint* ap; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &al->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = al->GlyphCount = GET_UShort(); + + FORGET_Frame(); + + al->AttachPoint = NULL; + + if ( ALLOC_ARRAY( al->AttachPoint, count, TTO_AttachPoint ) ) + goto Fail2; + + ap = al->AttachPoint; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_AttachPoint( &ap[n], input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + + al->loaded = TRUE; + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_AttachPoint( &ap[n] ); + + FREE( ap ); + + Fail2: + Free_Coverage( &al->Coverage ); + return error; + } + + + static void Free_AttachList( TTO_AttachList* al ) + { + UShort n, count; + + TTO_AttachPoint* ap; + + + if ( !al->loaded ) + return; + + if ( al->AttachPoint ) + { + count = al->GlyphCount; + ap = al->AttachPoint; + + for ( n = 0; n < count; n++ ) + Free_AttachPoint( &ap[n] ); + + FREE( ap ); + } + + Free_Coverage( &al->Coverage ); + } + + + + /********************************* + * LigCaretList related functions + *********************************/ + + + /* CaretValueFormat1 */ + /* CaretValueFormat2 */ + /* CaretValueFormat3 */ + /* CaretValueFormat4 */ + + static TT_Error Load_CaretValue( TTO_CaretValue* cv, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + ULong cur_offset, new_offset, base_offset; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + cv->CaretValueFormat = GET_UShort(); + + FORGET_Frame(); + + switch ( cv->CaretValueFormat ) + { + case 1: + if ( ACCESS_Frame( 2L ) ) + return error; + + cv->cvf.cvf1.Coordinate = GET_Short(); + + FORGET_Frame(); + + break; + + case 2: + if ( ACCESS_Frame( 2L ) ) + return error; + + cv->cvf.cvf2.CaretValuePoint = GET_UShort(); + + FORGET_Frame(); + + break; + + case 3: + if ( ACCESS_Frame( 4L ) ) + return error; + + cv->cvf.cvf3.Coordinate = GET_Short(); + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Device( &cv->cvf.cvf3.Device, + input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + break; + + case 4: + if ( ACCESS_Frame( 2L ) ) + return error; + + cv->cvf.cvf4.IdCaretValue = GET_UShort(); + + FORGET_Frame(); + break; + + default: + return TTO_Err_Invalid_GDEF_SubTable_Format; + } + + return TT_Err_Ok; + } + + + static void Free_CaretValue( TTO_CaretValue* cv ) + { + if ( cv->CaretValueFormat == 3 ) + Free_Device( &cv->cvf.cvf3.Device ); + } + + + /* LigGlyph */ + + static TT_Error Load_LigGlyph( TTO_LigGlyph* lg, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_CaretValue* cv; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = lg->CaretCount = GET_UShort(); + + FORGET_Frame(); + + lg->CaretValue = NULL; + + if ( ALLOC_ARRAY( lg->CaretValue, count, TTO_CaretValue ) ) + return error; + + cv = lg->CaretValue; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_CaretValue( &cv[n], input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_CaretValue( &cv[n] ); + + FREE( cv ); + return error; + } + + + static void Free_LigGlyph( TTO_LigGlyph* lg ) + { + UShort n, count; + + TTO_CaretValue* cv; + + + if ( lg->CaretValue ) + { + count = lg->CaretCount; + cv = lg->CaretValue; + + for ( n = 0; n < count; n++ ) + Free_CaretValue( &cv[n] ); + + FREE( cv ); + } + } + + + /* LigCaretList */ + + static TT_Error Load_LigCaretList( TTO_LigCaretList* lcl, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_LigGlyph* lg; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &lcl->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = lcl->LigGlyphCount = GET_UShort(); + + FORGET_Frame(); + + lcl->LigGlyph = NULL; + + if ( ALLOC_ARRAY( lcl->LigGlyph, count, TTO_LigGlyph ) ) + goto Fail2; + + lg = lcl->LigGlyph; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_LigGlyph( &lg[n], input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + + lcl->loaded = TRUE; + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_LigGlyph( &lg[n] ); + + FREE( lg ); + + Fail2: + Free_Coverage( &lcl->Coverage ); + return error; + } + + + static void Free_LigCaretList( TTO_LigCaretList* lcl ) + { + UShort n, count; + + TTO_LigGlyph* lg; + + + if ( !lcl->loaded ) + return; + + if ( lcl->LigGlyph ) + { + count = lcl->LigGlyphCount; + lg = lcl->LigGlyph; + + for ( n = 0; n < count; n++ ) + Free_LigGlyph( &lg[n] ); + + FREE( lg ); + } + + Free_Coverage( &lcl->Coverage ); + } + + + + /*********** + * GDEF API + ***********/ + + + static UShort Get_New_Class( TTO_GDEFHeader* gdef, + UShort glyphID, + UShort index ) + { + UShort glyph_index, array_index; + UShort byte, bits; + + TTO_ClassRangeRecord* gcrr; + UShort** ngc; + + + if ( glyphID >= gdef->LastGlyph ) + return 0; + + gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord; + ngc = gdef->NewGlyphClasses; + + if ( glyphID < gcrr[index].Start ) + { + array_index = 0; + if ( index == 0 ) + glyph_index = glyphID; + else + glyph_index = glyphID - gcrr[index - 1].End - 1; + } + else + { + array_index = index + 1; + glyph_index = glyphID - gcrr[index].End - 1; + } + + byte = ngc[array_index][glyph_index / 4 + 1]; + bits = byte >> ( 16 - ( glyph_index % 4 + 1 ) * 4 ); + + return bits & 0x000F; + } + + + EXPORT_FUNC + TT_Error TT_GDEF_Get_Glyph_Property( TTO_GDEFHeader* gdef, + TT_UShort glyphID, + TT_UShort* property ) + { + UShort class, index; + + TT_Error error; + + + if ( !gdef || !property ) + return TT_Err_Invalid_Argument; + + /* first, we check for mark attach classes */ + + if ( gdef->MarkAttachClassDef.loaded ) + { + error = Get_Class( &gdef->MarkAttachClassDef, glyphID, &class, &index ); + if ( error && error != TTO_Err_Not_Covered ) + return error; + if ( !error ) + { + *property = class << 8; + return TT_Err_Ok; + } + } + + error = Get_Class( &gdef->GlyphClassDef, glyphID, &class, &index ); + if ( error && error != TTO_Err_Not_Covered ) + return error; + + /* if we have a constructed class table, check whether additional + values have been assigned */ + + if ( error == TTO_Err_Not_Covered && gdef->NewGlyphClasses ) + class = Get_New_Class( gdef, glyphID, index ); + + switch ( class ) + { + case UNCLASSIFIED_GLYPH: + *property = 0; + break; + + case SIMPLE_GLYPH: + *property = TTO_BASE_GLYPH; + break; + + case LIGATURE_GLYPH: + *property = TTO_LIGATURE; + break; + + case MARK_GLYPH: + *property = TTO_MARK; + break; + + case COMPONENT_GLYPH: + *property = TTO_COMPONENT; + break; + } + + return TT_Err_Ok; + } + + + static TT_Error Make_ClassRange( TTO_ClassDefinition* cd, + UShort start, + UShort end, + UShort class ) + { + TT_Error error; + UShort index; + + TTO_ClassDefFormat2* cdf2; + TTO_ClassRangeRecord* crr; + + + cdf2 = &cd->cd.cd2; + + cdf2->ClassRangeCount++; + + if ( REALLOC_ARRAY( cdf2->ClassRangeRecord, cdf2->ClassRangeCount, + TTO_ClassRangeRecord ) ) + return error; + + crr = cdf2->ClassRangeRecord; + index = cdf2->ClassRangeCount - 1; + + crr[index].Start = start; + crr[index].End = end; + crr[index].Class = class; + + cd->Defined[class] = TRUE; + + return TT_Err_Ok; + } + + + EXPORT_FUNC + TT_Error TT_GDEF_Build_ClassDefinition( TTO_GDEFHeader* gdef, + TT_UShort num_glyphs, + TT_UShort glyph_count, + TT_UShort* glyph_array, + TT_UShort* class_array ) + { + UShort start, curr_glyph, curr_class; + UShort n, count; + TT_Error error; + + TTO_ClassDefinition* gcd; + TTO_ClassRangeRecord* gcrr; + UShort** ngc; + + + if ( !gdef || !glyph_array || !class_array ) + return TT_Err_Invalid_Argument; + + gcd = &gdef->GlyphClassDef; + + /* We build a format 2 table */ + + gcd->ClassFormat = 2; + + /* A GlyphClassDef table contains at most 5 different class values */ + + if ( ALLOC_ARRAY( gcd->Defined, 5, Bool ) ) + return error; + + gcd->cd.cd2.ClassRangeCount = 0; + gcd->cd.cd2.ClassRangeRecord = NULL; + + start = glyph_array[0]; + curr_class = class_array[0]; + curr_glyph = start; + + if ( curr_class >= 5 ) + { + error = TT_Err_Invalid_Argument; + goto Fail4; + } + + glyph_count--; + + for ( n = 0; n <= glyph_count; n++ ) + { + if ( curr_glyph == glyph_array[n] && curr_class == class_array[n] ) + { + if ( n == glyph_count ) + { + if ( ( error = Make_ClassRange( gcd, start, + curr_glyph, + curr_class ) ) != TT_Err_Ok ) + goto Fail3; + } + else + { + if ( curr_glyph == 0xFFFF ) + { + error = TT_Err_Invalid_Argument; + goto Fail3; + } + else + curr_glyph++; + } + } + else + { + if ( ( error = Make_ClassRange( gcd, start, + curr_glyph - 1, + curr_class ) ) != TT_Err_Ok ) + goto Fail3; + + if ( curr_glyph > glyph_array[n] ) + { + error = TT_Err_Invalid_Argument; + goto Fail3; + } + + start = glyph_array[n]; + curr_class = class_array[n]; + curr_glyph = start; + + if ( curr_class >= 5 ) + { + error = TT_Err_Invalid_Argument; + goto Fail3; + } + + if ( n == glyph_count ) + { + if ( ( error = Make_ClassRange( gcd, start, + curr_glyph, + curr_class ) ) != TT_Err_Ok ) + goto Fail3; + } + else + { + if ( curr_glyph == 0xFFFF ) + { + error = TT_Err_Invalid_Argument; + goto Fail3; + } + else + curr_glyph++; + } + } + } + + /* now prepare the arrays for class values assigned during the lookup + process */ + + if ( ALLOC_ARRAY( gdef->NewGlyphClasses, + gcd->cd.cd2.ClassRangeCount + 1, UShort* ) ) + goto Fail2; + + count = gcd->cd.cd2.ClassRangeCount; + gcrr = gcd->cd.cd2.ClassRangeRecord; + ngc = gdef->NewGlyphClasses; + + /* We allocate arrays for all glyphs not covered by the class range + records. Each element holds four class values. */ + + if ( gcrr[0].Start ) + { + if ( ALLOC_ARRAY( ngc[0], gcrr[0].Start / 4 + 1, UShort ) ) + goto Fail1; + } + + for ( n = 1; n < count; n++ ) + { + if ( gcrr[n].Start - gcrr[n - 1].End > 1 ) + if ( ALLOC_ARRAY( ngc[n], + ( gcrr[n].Start - gcrr[n - 1].End - 1 ) / 4 + 1, + UShort ) ) + goto Fail1; + } + + if ( gcrr[count - 1].End != num_glyphs - 1 ) + { + if ( ALLOC_ARRAY( ngc[count], + ( num_glyphs - gcrr[count - 1].End - 1 ) / 4 + 1, + UShort ) ) + goto Fail1; + } + + gdef->LastGlyph = num_glyphs - 1; + + gdef->MarkAttachClassDef_offset = 0L; + gdef->MarkAttachClassDef.loaded = FALSE; + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + FREE( ngc[n] ); + + Fail2: + FREE( gdef->NewGlyphClasses ); + + Fail3: + FREE( gcd->cd.cd2.ClassRangeRecord ); + + Fail4: + FREE( gcd->Defined ); + return error; + } + + + static void Free_NewGlyphClasses( TTO_GDEFHeader* gdef ) + { + UShort** ngc; + UShort n, count; + + + if ( gdef->NewGlyphClasses ) + { + count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount + 1; + ngc = gdef->NewGlyphClasses; + + for ( n = 0; n < count; n++ ) + FREE( ngc[n] ); + + FREE( ngc ); + } + } + + + TT_Error Add_Glyph_Property( TTO_GDEFHeader* gdef, + UShort glyphID, + UShort property ) + { + TT_Error error; + UShort class, new_class, index; + UShort byte, bits, mask; + UShort array_index, glyph_index; + + TTO_ClassRangeRecord* gcrr; + UShort** ngc; + + + error = Get_Class( &gdef->GlyphClassDef, glyphID, &class, &index ); + if ( error && error != TTO_Err_Not_Covered ) + return error; + + /* we don't accept glyphs covered in `GlyphClassDef' */ + + if ( !error ) + return TTO_Err_Not_Covered; + + switch ( property ) + { + case 0: + new_class = UNCLASSIFIED_GLYPH; + break; + + case TTO_BASE_GLYPH: + new_class = SIMPLE_GLYPH; + break; + + case TTO_LIGATURE: + new_class = LIGATURE_GLYPH; + break; + + case TTO_MARK: + new_class = MARK_GLYPH; + break; + + case TTO_COMPONENT: + new_class = COMPONENT_GLYPH; + break; + + default: + return TT_Err_Invalid_Argument; + } + + gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord; + ngc = gdef->NewGlyphClasses; + + if ( glyphID < gcrr[index].Start ) + { + array_index = 0; + if ( index == 0 ) + glyph_index = glyphID; + else + glyph_index = glyphID - gcrr[index - 1].End - 1; + } + else + { + array_index = index + 1; + glyph_index = glyphID - gcrr[index].End - 1; + } + + byte = ngc[array_index][glyph_index / 4 + 1]; + bits = byte >> ( 16 - ( glyph_index % 4 + 1 ) * 4 ); + class = bits & 0x000F; + + /* we don't overwrite existing entries */ + + if ( !class ) + { + bits = new_class << ( 16 - ( glyph_index % 4 + 1 ) * 4 ); + mask = ~( 0x000F << ( 16 - ( glyph_index % 4 + 1 ) * 4 ) ); + + ngc[array_index][glyph_index / 4 + 1] &= mask; + ngc[array_index][glyph_index / 4 + 1] |= bits; + } + + return TT_Err_Ok; + } + + +/* END */ diff --git a/lib/extend/ftxgdef.h b/lib/extend/ftxgdef.h new file mode 100644 index 0000000..3387232 --- /dev/null +++ b/lib/extend/ftxgdef.h @@ -0,0 +1,216 @@ +/******************************************************************* + * + * ftxgdef.h + * + * TrueType Open GDEF table support + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef FTXOPEN_H +#error "Don't include this file! Use ftxopen.h instead." +#endif + +#ifndef FTXGDEF_H +#define FTXGDEF_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define TTO_Err_Invalid_GDEF_SubTable_Format 0x1030 +#define TTO_Err_Invalid_GDEF_SubTable 0x1031 + + +/* GDEF glyph classes */ + +#define UNCLASSIFIED_GLYPH 0 +#define SIMPLE_GLYPH 1 +#define LIGATURE_GLYPH 2 +#define MARK_GLYPH 3 +#define COMPONENT_GLYPH 4 + +/* GDEF glyph properties, corresponding to class values 1-4. Note that + TTO_COMPONENT has no corresponding flag in the LookupFlag field. */ + +#define TTO_BASE_GLYPH 0x0002 +#define TTO_LIGATURE 0x0004 +#define TTO_MARK 0x0008 +#define TTO_COMPONENT 0x0010 + + + /* Attachment related structures */ + + struct TTO_AttachPoint_ + { + TT_UShort PointCount; /* size of the PointIndex array */ + TT_UShort* PointIndex; /* array of contour points */ + }; + + typedef struct TTO_AttachPoint_ TTO_AttachPoint; + + + struct TTO_AttachList_ + { + TT_Bool loaded; + + TTO_Coverage Coverage; /* Coverage table */ + TT_UShort GlyphCount; /* number of glyphs with + attachments */ + TTO_AttachPoint* AttachPoint; /* array of AttachPoint tables */ + }; + + typedef struct TTO_AttachList_ TTO_AttachList; + + + /* Ligature Caret related structures */ + + struct TTO_CaretValueFormat1_ + { + TT_Short Coordinate; /* x or y value (in design units) */ + }; + + typedef struct TTO_CaretValueFormat1_ TTO_CaretValueFormat1; + + + struct TTO_CaretValueFormat2_ + { + TT_UShort CaretValuePoint; /* contour point index on glyph */ + }; + + typedef struct TTO_CaretValueFormat2_ TTO_CaretValueFormat2; + + + struct TTO_CaretValueFormat3_ + { + TT_Short Coordinate; /* x or y value (in design units) */ + TTO_Device Device; /* Device table for x or y value */ + }; + + typedef struct TTO_CaretValueFormat3_ TTO_CaretValueFormat3; + + + struct TTO_CaretValueFormat4_ + { + TT_UShort IdCaretValue; /* metric ID */ + }; + + typedef struct TTO_CaretValueFormat4_ TTO_CaretValueFormat4; + + + struct TTO_CaretValue_ + { + TT_UShort CaretValueFormat; /* 1, 2, 3, or 4 */ + + union + { + TTO_CaretValueFormat1 cvf1; + TTO_CaretValueFormat2 cvf2; + TTO_CaretValueFormat3 cvf3; + TTO_CaretValueFormat4 cvf4; + } cvf; + }; + + typedef struct TTO_CaretValue_ TTO_CaretValue; + + + struct TTO_LigGlyph_ + { + TT_Bool loaded; + + TT_UShort CaretCount; /* number of caret values */ + TTO_CaretValue* CaretValue; /* array of caret values */ + }; + + typedef struct TTO_LigGlyph_ TTO_LigGlyph; + + + struct TTO_LigCaretList_ + { + TT_Bool loaded; + + TTO_Coverage Coverage; /* Coverage table */ + TT_UShort LigGlyphCount; /* number of ligature glyphs */ + TTO_LigGlyph* LigGlyph; /* array of LigGlyph tables */ + }; + + typedef struct TTO_LigCaretList_ TTO_LigCaretList; + + + /* The `NewGlyphClasses' field is not defined in the TTO specification. + We use it for fonts with a constructed `GlyphClassDef' structure + (i.e., which don't have a GDEF table) to collect glyph classes + assigned during the lookup process. The number of arrays in this + pointer array is GlyphClassDef->cd.cd2.ClassRangeCount+1; the nth + array then contains the glyph class values of the glyphs not covered + by the ClassRangeRecords structures with index n-1 and n. We store + glyph class values for four glyphs in a single array element. + + `LastGlyph' is identical to the number of glyphs minus one in the + font; we need it only if `NewGlyphClasses' is not NULL (to have an + upper bound for the last array). + + Note that we first store the file offset to the `MarkAttachClassDef' + field (which has been introduced in OpenType 1.2) -- since the + `Version' field value hasn't been increased to indicate that we have + one more field for some obscure reason, we must parse the GSUB table + to find out whether class values refer to this table. Only then we + can finally load the MarkAttachClassDef structure if necessary. */ + + struct TTO_GDEFHeader_ + { + TT_Bool loaded; + TT_ULong offset; + + TT_Fixed Version; + + TTO_ClassDefinition GlyphClassDef; + TTO_AttachList AttachList; + TTO_LigCaretList LigCaretList; + TT_ULong MarkAttachClassDef_offset; + TTO_ClassDefinition MarkAttachClassDef; /* new in OT 1.2 */ + + TT_UShort LastGlyph; + TT_UShort** NewGlyphClasses; + }; + + typedef struct TTO_GDEFHeader_ TTO_GDEFHeader; + + + /* finally, the GDEF API */ + + EXPORT_DEF + TT_Error TT_Init_GDEF_Extension( TT_Engine engine ); + + EXPORT_DEF + TT_Error TT_Load_GDEF_Table( TT_Face face, + TTO_GDEFHeader* gdef ); + + EXPORT_DEF + TT_Error TT_GDEF_Get_Glyph_Property( TTO_GDEFHeader* gdef, + TT_UShort glyphID, + TT_UShort* property ); + EXPORT_DEF + TT_Error TT_GDEF_Build_ClassDefinition( TTO_GDEFHeader* gdef, + TT_UShort num_glyphs, + TT_UShort glyph_count, + TT_UShort* glyph_array, + TT_UShort* class_array ); + + +#ifdef __cplusplus +} +#endif + +#endif /* FTXGDEF_H */ + + +/* END */ diff --git a/lib/extend/ftxgpos.c b/lib/extend/ftxgpos.c new file mode 100644 index 0000000..76a52b7 --- /dev/null +++ b/lib/extend/ftxgpos.c @@ -0,0 +1,4045 @@ +/******************************************************************* + * + * ftxgpos.c + * + * TrueType Open GPOS table support. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +/* XXX There is *a lot* of duplicated code (cf. formats 7 and 8), but + I don't care currently. I believe that it would be possible to + save about 50% of TTO code by carefully designing the structures, + sharing as much as possible with extensive use of macros. This + is something for a volunteer :-) */ + +#include "tttypes.h" +#include "tttags.h" +#include "ttload.h" +#include "ttextend.h" +#include "ttmemory.h" +#include "ttfile.h" + +#include "ftxopen.h" +#include "ftxopenf.h" + + +#define GPOS_ID Build_Extension_ID( 'G', 'P', 'O', 'S' ) + + + + /********************** + * Extension Functions + **********************/ + + + static TT_Error GPOS_Create( void* ext, + PFace face ) + { + DEFINE_LOAD_LOCALS( face->stream ); + + TTO_GPOSHeader* gpos = (TTO_GPOSHeader*)ext; + Long table; + + + /* by convention */ + + if ( !gpos ) + return TT_Err_Ok; + + /* a null offset indicates that there is no GPOS table */ + + gpos->offset = 0; + + /* we store the start offset and the size of the subtable */ + + table = TT_LookUp_Table( face, TTAG_GPOS ); + if ( table < 0 ) + return TT_Err_Ok; /* The table is optional */ + + if ( FILE_Seek( face->dirTables[table].Offset ) || + ACCESS_Frame( 4L ) ) + return error; + + gpos->offset = FILE_Pos() - 4L; /* undo ACCESS_Frame() */ + gpos->Version = GET_ULong(); + + FORGET_Frame(); + + gpos->loaded = FALSE; + + return TT_Err_Ok; + } + + + static TT_Error GPOS_Destroy( void* ext, + PFace face ) + { + TTO_GPOSHeader* gpos = (TTO_GPOSHeader*)ext; + + + /* by convention */ + + if ( !gpos ) + return TT_Err_Ok; + + if ( gpos->loaded ) + { + Free_LookupList( &gpos->LookupList, GPOS ); + Free_FeatureList( &gpos->FeatureList ); + Free_ScriptList( &gpos->ScriptList ); + } + + return TT_Err_Ok; + } + + + EXPORT_FUNC + TT_Error TT_Init_GPOS_Extension( TT_Engine engine ) + { + PEngine_Instance _engine = HANDLE_Engine( engine ); + + + if ( !_engine ) + return TT_Err_Invalid_Engine; + + return TT_Register_Extension( _engine, + GPOS_ID, + sizeof ( TTO_GPOSHeader ), + GPOS_Create, + GPOS_Destroy ); + } + + + EXPORT_FUNC + TT_Error TT_Load_GPOS_Table( TT_Face face, + TTO_GPOSHeader* retptr, + TTO_GDEFHeader* gdef ) + { + ULong cur_offset, new_offset, base_offset; + + TT_UShort i, num_lookups; + TT_Error error; + TT_Stream stream; + TTO_GPOSHeader* gpos; + TTO_Lookup* lo; + + PFace faze = HANDLE_Face( face ); + + + if ( !retptr ) + return TT_Err_Invalid_Argument; + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + error = TT_Extension_Get( faze, GPOS_ID, (void**)&gpos ); + if ( error ) + return error; + + if ( gpos->offset == 0 ) + return TT_Err_Table_Missing; /* no GPOS table; nothing to do */ + + /* now access stream */ + + if ( USE_Stream( faze->stream, stream ) ) + return error; + + base_offset = gpos->offset; + + /* skip version */ + + if ( FILE_Seek( base_offset + 4L ) || + ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ScriptList( &gpos->ScriptList, + faze ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_FeatureList( &gpos->FeatureList, + faze ) ) != TT_Err_Ok ) + goto Fail3; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_LookupList( &gpos->LookupList, + faze, GPOS ) ) != TT_Err_Ok ) + goto Fail2; + + gpos->gdef = gdef; /* can be NULL */ + + /* We now check the LookupFlags for values larger than 0xFF to find + out whether we need to load the `MarkAttachClassDef' field of the + GDEF table -- this hack is necessary for OpenType 1.2 tables since + the version field of the GDEF table hasn't been incremented. + + For constructed GDEF tables, we only load it if + `MarkAttachClassDef_offset' is not zero (nevertheless, a build of + a constructed mark attach table is not supported currently). */ + + if ( gdef && + gdef->MarkAttachClassDef_offset && !gdef->MarkAttachClassDef.loaded ) + { + lo = gpos->LookupList.Lookup; + num_lookups = gpos->LookupList.LookupCount; + + for ( i = 0; i < num_lookups; i++ ) + { + if ( lo[i].LookupFlag & IGNORE_SPECIAL_MARKS ) + { + if ( FILE_Seek( gdef->MarkAttachClassDef_offset ) || + ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort(); + + FORGET_Frame(); + + if ( !new_offset ) + return TTO_Err_Invalid_GDEF_SubTable; + + new_offset += base_offset; + + if ( FILE_Seek( new_offset ) || + ( error = Load_ClassDefinition( &gdef->MarkAttachClassDef, + 256, faze ) ) != TT_Err_Ok ) + goto Fail1; + + break; + } + } + } + + gpos->loaded = TRUE; + *retptr = *gpos; + DONE_Stream( stream ); + + return TT_Err_Ok; + + Fail1: + Free_LookupList( &gpos->LookupList, GPOS ); + + Fail2: + Free_FeatureList( &gpos->FeatureList ); + + Fail3: + Free_ScriptList( &gpos->ScriptList ); + + /* release stream */ + + DONE_Stream( stream ); + + return error; + } + + + + /***************************** + * SubTable related functions + *****************************/ + + /* shared tables */ + + /* ValueRecord */ + + static TT_Error Load_ValueRecord( TTO_ValueRecord* vr, + TT_UShort format, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + ULong cur_offset, new_offset, base_offset; + + + base_offset = FILE_Pos(); + + if ( format & HAVE_X_PLACEMENT ) + { + if ( ACCESS_Frame( 2L ) ) + return error; + + vr->XPlacement = GET_Short(); + + FORGET_Frame(); + } + else + vr->XPlacement = 0; + + if ( format & HAVE_Y_PLACEMENT ) + { + if ( ACCESS_Frame( 2L ) ) + return error; + + vr->YPlacement = GET_Short(); + + FORGET_Frame(); + } + else + vr->YPlacement = 0; + + if ( format & HAVE_X_ADVANCE ) + { + if ( ACCESS_Frame( 2L ) ) + return error; + + vr->XAdvance = GET_Short(); + + FORGET_Frame(); + } + else + vr->XAdvance = 0; + + if ( format & HAVE_Y_ADVANCE ) + { + if ( ACCESS_Frame( 2L ) ) + return error; + + vr->YAdvance = GET_Short(); + + FORGET_Frame(); + } + else + vr->YAdvance = 0; + + if ( format & HAVE_X_PLACEMENT_DEVICE ) + { + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Device( &vr->XPlacementDevice, + input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + } + else + { + vr->XPlacementDevice.StartSize = 0; + vr->XPlacementDevice.EndSize = 0; + vr->XPlacementDevice.DeltaValue = NULL; + } + + if ( format & HAVE_Y_PLACEMENT_DEVICE ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Device( &vr->YPlacementDevice, + input ) ) != TT_Err_Ok ) + goto Fail3; + (void)FILE_Seek( cur_offset ); + } + else + { + vr->YPlacementDevice.StartSize = 0; + vr->YPlacementDevice.EndSize = 0; + vr->YPlacementDevice.DeltaValue = NULL; + } + + if ( format & HAVE_X_ADVANCE_DEVICE ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Device( &vr->XAdvanceDevice, + input ) ) != TT_Err_Ok ) + goto Fail2; + (void)FILE_Seek( cur_offset ); + } + else + { + vr->XAdvanceDevice.StartSize = 0; + vr->XAdvanceDevice.EndSize = 0; + vr->XAdvanceDevice.DeltaValue = NULL; + } + + if ( format & HAVE_Y_ADVANCE_DEVICE ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Device( &vr->YAdvanceDevice, + input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + else + { + vr->YAdvanceDevice.StartSize = 0; + vr->YAdvanceDevice.EndSize = 0; + vr->YAdvanceDevice.DeltaValue = NULL; + } + + if ( format & HAVE_X_ID_PLACEMENT ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + vr->XIdPlacement = GET_UShort(); + + FORGET_Frame(); + } + else + vr->XIdPlacement = 0; + + if ( format & HAVE_Y_ID_PLACEMENT ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + vr->YIdPlacement = GET_UShort(); + + FORGET_Frame(); + } + else + vr->YIdPlacement = 0; + + if ( format & HAVE_X_ID_ADVANCE ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + vr->XIdAdvance = GET_UShort(); + + FORGET_Frame(); + } + else + vr->XIdAdvance = 0; + + if ( format & HAVE_Y_ID_ADVANCE ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + vr->YIdAdvance = GET_UShort(); + + FORGET_Frame(); + } + else + vr->YIdAdvance = 0; + + return TT_Err_Ok; + + Fail1: + Free_Device( &vr->YAdvanceDevice ); + + Fail2: + Free_Device( &vr->XAdvanceDevice ); + + Fail3: + Free_Device( &vr->YPlacementDevice ); + return error; + } + + + static void Free_ValueRecord( TTO_ValueRecord* vr, + UShort format ) + { + if ( format & HAVE_Y_ADVANCE_DEVICE ) + Free_Device( &vr->YAdvanceDevice ); + if ( format & HAVE_X_ADVANCE_DEVICE ) + Free_Device( &vr->XAdvanceDevice ); + if ( format & HAVE_Y_PLACEMENT_DEVICE ) + Free_Device( &vr->YPlacementDevice ); + if ( format & HAVE_X_PLACEMENT_DEVICE ) + Free_Device( &vr->XPlacementDevice ); + } + + + /* AnchorFormat1 */ + /* AnchorFormat2 */ + /* AnchorFormat3 */ + /* AnchorFormat4 */ + + static TT_Error Load_Anchor( TTO_Anchor* an, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + ULong cur_offset, new_offset, base_offset; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + an->PosFormat = GET_UShort(); + + FORGET_Frame(); + + switch ( an->PosFormat ) + { + case 1: + if ( ACCESS_Frame( 4L ) ) + return error; + + an->af.af1.XCoordinate = GET_Short(); + an->af.af1.YCoordinate = GET_Short(); + + FORGET_Frame(); + break; + + case 2: + if ( ACCESS_Frame( 6L ) ) + return error; + + an->af.af2.XCoordinate = GET_Short(); + an->af.af2.YCoordinate = GET_Short(); + an->af.af2.AnchorPoint = GET_UShort(); + + FORGET_Frame(); + break; + + case 3: + if ( ACCESS_Frame( 6L ) ) + return error; + + an->af.af3.XCoordinate = GET_Short(); + an->af.af3.YCoordinate = GET_Short(); + + new_offset = GET_UShort(); + + FORGET_Frame(); + + if ( new_offset ) + { + new_offset += base_offset; + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Device( &an->af.af3.XDeviceTable, + input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + } + else + { + an->af.af3.XDeviceTable.StartSize = 0; + an->af.af3.XDeviceTable.EndSize = 0; + an->af.af3.XDeviceTable.DeltaValue = 0; + } + + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort(); + + FORGET_Frame(); + + if ( new_offset ) + { + new_offset += base_offset; + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Device( &an->af.af3.YDeviceTable, + input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + else + { + an->af.af3.YDeviceTable.StartSize = 0; + an->af.af3.YDeviceTable.EndSize = 0; + an->af.af3.YDeviceTable.DeltaValue = 0; + } + break; + + case 4: + if ( ACCESS_Frame( 4L ) ) + return error; + + an->af.af4.XIdAnchor = GET_UShort(); + an->af.af4.YIdAnchor = GET_UShort(); + + FORGET_Frame(); + break; + + default: + return TTO_Err_Invalid_GPOS_SubTable_Format; + } + + return TT_Err_Ok; + + Fail: + Free_Device( &an->af.af3.XDeviceTable ); + return error; + } + + + static void Free_Anchor( TTO_Anchor* an ) + { + if ( an->PosFormat == 3 ) + { + Free_Device( &an->af.af3.YDeviceTable ); + Free_Device( &an->af.af3.XDeviceTable ); + } + } + + + /* MarkArray */ + + static TT_Error Load_MarkArray ( TTO_MarkArray* ma, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_MarkRecord* mr; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = ma->MarkCount = GET_UShort(); + + FORGET_Frame(); + + ma->MarkRecord = NULL; + + if ( ALLOC_ARRAY( ma->MarkRecord, count, TTO_MarkRecord ) ) + return error; + + mr = ma->MarkRecord; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 4L ) ) + goto Fail; + + mr[n].Class = GET_UShort(); + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Anchor( &mr[n].MarkAnchor, input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_Anchor( &mr[n].MarkAnchor ); + + FREE( mr ); + return error; + } + + + static void Free_MarkArray( TTO_MarkArray* ma ) + { + UShort n, count; + + TTO_MarkRecord* mr; + + + if ( ma->MarkRecord ) + { + count = ma->MarkCount; + mr = ma->MarkRecord; + + for ( n = 0; n < count; n++ ) + Free_Anchor( &mr[n].MarkAnchor ); + + FREE( mr ); + } + } + + + /* LookupType 1 */ + + /* SinglePosFormat1 */ + /* SinglePosFormat2 */ + + TT_Error Load_SinglePos( TTO_SinglePos* sp, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count, format; + ULong cur_offset, new_offset, base_offset; + + TTO_ValueRecord* v; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 6L ) ) + return error; + + sp->PosFormat = GET_UShort(); + new_offset = GET_UShort() + base_offset; + + format = sp->ValueFormat = GET_UShort(); + + FORGET_Frame(); + + if ( !format ) + return TTO_Err_Invalid_GPOS_SubTable; + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &sp->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + switch ( sp->PosFormat ) + { + case 1: + error = Load_ValueRecord( &sp->spf.spf1.Value, format, input ); + if ( error ) + goto Fail2; + break; + + case 2: + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = sp->spf.spf2.ValueCount = GET_UShort(); + + FORGET_Frame(); + + sp->spf.spf2.Value = NULL; + + if ( ALLOC_ARRAY( sp->spf.spf2.Value, count, TTO_ValueRecord ) ) + goto Fail2; + + v = sp->spf.spf2.Value; + + for ( n = 0; n < count; n++ ) + { + error = Load_ValueRecord( &v[n], format, input ); + if ( error ) + goto Fail1; + } + break; + + default: + return TTO_Err_Invalid_GPOS_SubTable_Format; + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_ValueRecord( &v[n], format ); + + FREE( v ); + + Fail2: + Free_Coverage( &sp->Coverage ); + return error; + } + + + void Free_SinglePos( TTO_SinglePos* sp ) + { + UShort n, count, format; + + TTO_ValueRecord* v; + + + format = sp->ValueFormat; + + switch ( sp->PosFormat ) + { + case 1: + Free_ValueRecord( &sp->spf.spf1.Value, format ); + break; + + case 2: + if ( sp->spf.spf2.Value ) + { + count = sp->spf.spf2.ValueCount; + v = sp->spf.spf2.Value; + + for ( n = 0; n < count; n++ ) + Free_ValueRecord( &v[n], format ); + + FREE( v ); + } + break; + } + + Free_Coverage( &sp->Coverage ); + } + + + /* LookupType 2 */ + + /* PairSet */ + + static TT_Error Load_PairSet ( TTO_PairSet* ps, + UShort format1, + UShort format2, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + + TTO_PairValueRecord* pvr; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = ps->PairValueCount = GET_UShort(); + + FORGET_Frame(); + + ps->PairValueRecord = NULL; + + if ( ALLOC_ARRAY( ps->PairValueRecord, count, TTO_PairValueRecord ) ) + return error; + + pvr = ps->PairValueRecord; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + pvr[n].SecondGlyph = GET_UShort(); + + FORGET_Frame(); + + if ( format1 ) + { + error = Load_ValueRecord( &pvr[n].Value1, format1, input ); + if ( error ) + goto Fail; + } + if ( format2 ) + { + error = Load_ValueRecord( &pvr[n].Value2, format2, input ); + if ( error ) + goto Fail; + } + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + { + if ( format1 ) + Free_ValueRecord( &pvr[n].Value1, format1 ); + if ( format2 ) + Free_ValueRecord( &pvr[n].Value2, format2 ); + } + + FREE( pvr ); + return error; + } + + + static void Free_PairSet( TTO_PairSet* ps, + UShort format1, + UShort format2 ) + { + UShort n, count; + + TTO_PairValueRecord* pvr; + + + if ( ps->PairValueRecord ) + { + count = ps->PairValueCount; + pvr = ps->PairValueRecord; + + for ( n = 0; n < count; n++ ) + { + if ( format1 ) + Free_ValueRecord( &pvr[n].Value1, format1 ); + if ( format2 ) + Free_ValueRecord( &pvr[n].Value2, format2 ); + } + + FREE( pvr ); + } + } + + + /* PairPosFormat1 */ + + static TT_Error Load_PairPosFormat1( TTO_PairPosFormat1* ppf1, + UShort format1, + UShort format2, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_PairSet* ps; + + + base_offset = FILE_Pos() - 8L; + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = ppf1->PairSetCount = GET_UShort(); + + FORGET_Frame(); + + ppf1->PairSet = NULL; + + if ( ALLOC_ARRAY( ppf1->PairSet, count, TTO_PairSet ) ) + goto Fail; + + ps = ppf1->PairSet; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_PairSet( &ps[n], format1, + format2, input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_PairSet( &ps[n], format1, format2 ); + + FREE( ps ); + return error; + } + + + static void Free_PairPosFormat1( TTO_PairPosFormat1* ppf1, + UShort format1, + UShort format2 ) + { + UShort n, count; + + TTO_PairSet* ps; + + + if ( ppf1->PairSet ) + { + count = ppf1->PairSetCount; + ps = ppf1->PairSet; + + for ( n = 0; n < count; n++ ) + Free_PairSet( &ps[n], format1, format2 ); + + FREE( ps ); + } + } + + + /* PairPosFormat2 */ + + static TT_Error Load_PairPosFormat2( TTO_PairPosFormat2* ppf2, + UShort format1, + UShort format2, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort m, n, count1, count2; + ULong cur_offset, new_offset1, new_offset2, base_offset; + + TTO_Class1Record* c1r; + TTO_Class2Record* c2r; + + + base_offset = FILE_Pos() - 8L; + + if ( ACCESS_Frame( 8L ) ) + return error; + + new_offset1 = GET_UShort() + base_offset; + new_offset2 = GET_UShort() + base_offset; + + /* `Class1Count' and `Class2Count' are the upper limits for class + values, thus we read it now to make additional safety checks. */ + + count1 = ppf2->Class1Count = GET_UShort(); + count2 = ppf2->Class2Count = GET_UShort(); + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset1 ) || + ( error = Load_ClassDefinition( &ppf2->ClassDef1, count1, + input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset2 ) || + ( error = Load_ClassDefinition( &ppf2->ClassDef2, count2, + input ) ) != TT_Err_Ok ) + goto Fail2; + (void)FILE_Seek( cur_offset ); + + ppf2->Class1Record = NULL; + + if ( ALLOC_ARRAY( ppf2->Class1Record, count1, TTO_Class1Record ) ) + goto Fail1; + + c1r = ppf2->Class1Record; + + for ( m = 0; m < count1; m++ ) + { + c1r[m].Class2Record = NULL; + + if ( ALLOC_ARRAY( c1r[m].Class2Record, count2, TTO_Class2Record ) ) + goto Fail1; + + c2r = c1r[m].Class2Record; + + for ( n = 0; n < count2; n++ ) + { + if ( format1 ) + { + Load_ValueRecord( &c2r[n].Value1, format1, input ); + if ( error ) + goto Fail1; + } + if ( format2 ) + { + Load_ValueRecord( &c2r[n].Value2, format2, input ); + if ( error ) + goto Fail1; + } + } + } + + return TT_Err_Ok; + + Fail1: + for ( m = 0; m < count1; m++ ) + { + c2r = c1r[m].Class2Record; + + for ( n = 0; n < count2; n++ ) + { + if ( format1 ) + Free_ValueRecord( &c2r[n].Value1, format1 ); + if ( format2 ) + Free_ValueRecord( &c2r[n].Value2, format2 ); + } + + FREE( c2r ); + } + + FREE( c1r ); + + Free_ClassDefinition( &ppf2->ClassDef2 ); + + Fail2: + Free_ClassDefinition( &ppf2->ClassDef1 ); + return error; + } + + + static void Free_PairPosFormat2( TTO_PairPosFormat2* ppf2, + UShort format1, + UShort format2 ) + { + UShort m, n, count1, count2; + + TTO_Class1Record* c1r; + TTO_Class2Record* c2r; + + + if ( ppf2->Class1Record ) + { + c1r = ppf2->Class1Record; + count1 = ppf2->Class1Count; + count2 = ppf2->Class2Count; + + for ( m = 0; m < count1; m++ ) + { + c2r = c1r[m].Class2Record; + + for ( n = 0; n < count2; n++ ) + { + if ( format1 ) + Free_ValueRecord( &c2r[n].Value1, format1 ); + if ( format2 ) + Free_ValueRecord( &c2r[n].Value2, format2 ); + } + + FREE( c2r ); + } + + FREE( c1r ); + + Free_ClassDefinition( &ppf2->ClassDef2 ); + Free_ClassDefinition( &ppf2->ClassDef1 ); + } + } + + + TT_Error Load_PairPos( TTO_PairPos* pp, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort format1, format2; + ULong cur_offset, new_offset, base_offset; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 8L ) ) + return error; + + pp->PosFormat = GET_UShort(); + new_offset = GET_UShort() + base_offset; + + format1 = pp->ValueFormat1 = GET_UShort(); + format2 = pp->ValueFormat2 = GET_UShort(); + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &pp->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + switch ( pp->PosFormat ) + { + case 1: + error = Load_PairPosFormat1( &pp->ppf.ppf1, format1, format2, input ); + if ( error ) + goto Fail; + break; + + case 2: + error = Load_PairPosFormat2( &pp->ppf.ppf2, format1, format2, input ); + if ( error ) + goto Fail; + break; + + default: + return TTO_Err_Invalid_GPOS_SubTable_Format; + } + + return TT_Err_Ok; + + Fail: + Free_Coverage( &pp->Coverage ); + return error; + } + + + void Free_PairPos( TTO_PairPos* pp ) + { + UShort format1, format2; + + + format1 = pp->ValueFormat1; + format2 = pp->ValueFormat2; + + switch ( pp->PosFormat ) + { + case 1: + Free_PairPosFormat1( &pp->ppf.ppf1, format1, format2 ); + break; + + case 2: + Free_PairPosFormat2( &pp->ppf.ppf2, format1, format2 ); + break; + } + + Free_Coverage( &pp->Coverage ); + } + + + /* LookupType 3 */ + + /* CursivePosFormat1 */ + + TT_Error Load_CursivePos( TTO_CursivePos* cp, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_EntryExitRecord* eer; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 4L ) ) + return error; + + cp->PosFormat = GET_UShort(); + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &cp->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = cp->EntryExitCount = GET_UShort(); + + FORGET_Frame(); + + cp->EntryExitRecord = NULL; + + if ( ALLOC_ARRAY( cp->EntryExitRecord, count, TTO_EntryExitRecord ) ) + goto Fail2; + + eer = cp->EntryExitRecord; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort(); + + FORGET_Frame(); + + if ( new_offset ) + { + new_offset += base_offset; + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Anchor( &eer[n].EntryAnchor, + input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + else + eer[n].EntryAnchor.PosFormat = 0; + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort(); + + FORGET_Frame(); + + if ( new_offset ) + { + new_offset += base_offset; + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Anchor( &eer[n].ExitAnchor, + input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + else + eer[n].ExitAnchor.PosFormat = 0; + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + { + Free_Anchor( &eer[n].EntryAnchor ); + Free_Anchor( &eer[n].ExitAnchor ); + } + + FREE( eer ); + + Fail2: + Free_Coverage( &cp->Coverage ); + return error; + } + + + void Free_CursivePos( TTO_CursivePos* cp ) + { + UShort n, count; + + TTO_EntryExitRecord* eer; + + + if ( cp->EntryExitRecord ) + { + count = cp->EntryExitCount; + eer = cp->EntryExitRecord; + + for ( n = 0; n < count; n++ ) + { + Free_Anchor( &eer[n].EntryAnchor ); + Free_Anchor( &eer[n].ExitAnchor ); + } + + FREE( eer ); + } + + Free_Coverage( &cp->Coverage ); + } + + + /* LookupType 4 */ + + /* BaseArray */ + + static TT_Error Load_BaseArray( TTO_BaseArray* ba, + UShort num_classes, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort m, n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_BaseRecord* br; + TTO_Anchor* ban; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = ba->BaseCount = GET_UShort(); + + FORGET_Frame(); + + ba->BaseRecord = NULL; + + if ( ALLOC_ARRAY( ba->BaseRecord, count, TTO_BaseRecord ) ) + return error; + + br = ba->BaseRecord; + + for ( m = 0; m < count; m++ ) + { + br[m].BaseAnchor = NULL; + + if ( ALLOC_ARRAY( br[m].BaseAnchor, num_classes, TTO_Anchor ) ) + goto Fail; + + ban = br[m].BaseAnchor; + + for ( n = 0; n < num_classes; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Anchor( &ban[n], input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + } + + return TT_Err_Ok; + + Fail: + for ( m = 0; m < count; m++ ) + { + ban = br[m].BaseAnchor; + + for ( n = 0; n < num_classes; n++ ) + Free_Anchor( &ban[n] ); + + FREE( ban ); + } + + FREE( br ); + return error; + } + + + static void Free_BaseArray( TTO_BaseArray* ba, + UShort num_classes ) + { + UShort m, n, count; + + TTO_BaseRecord* br; + TTO_Anchor* ban; + + + if ( ba->BaseRecord ) + { + count = ba->BaseCount; + br = ba->BaseRecord; + + for ( m = 0; m < count; m++ ) + { + ban = br[m].BaseAnchor; + + for ( n = 0; n < num_classes; n++ ) + Free_Anchor( &ban[n] ); + + FREE( ban ); + } + + FREE( br ); + } + } + + + /* MarkBasePosFormat1 */ + + TT_Error Load_MarkBasePos( TTO_MarkBasePos* mbp, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + ULong cur_offset, new_offset, base_offset; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 4L ) ) + return error; + + mbp->PosFormat = GET_UShort(); + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &mbp->MarkCoverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &mbp->BaseCoverage, input ) ) != TT_Err_Ok ) + goto Fail3; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 4L ) ) + goto Fail2; + + mbp->ClassCount = GET_UShort(); + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_MarkArray( &mbp->MarkArray, input ) ) != TT_Err_Ok ) + goto Fail2; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_BaseArray( &mbp->BaseArray, mbp->ClassCount, + input ) ) != TT_Err_Ok ) + goto Fail1; + + return TT_Err_Ok; + + Fail1: + Free_MarkArray( &mbp->MarkArray ); + + Fail2: + Free_Coverage( &mbp->BaseCoverage ); + + Fail3: + Free_Coverage( &mbp->MarkCoverage ); + return error; + } + + + void Free_MarkBasePos( TTO_MarkBasePos* mbp ) + { + Free_BaseArray( &mbp->BaseArray, mbp->ClassCount ); + Free_MarkArray( &mbp->MarkArray ); + Free_Coverage( &mbp->BaseCoverage ); + Free_Coverage( &mbp->MarkCoverage ); + } + + + /* LookupType 5 */ + + /* LigatureAttach */ + + static TT_Error Load_LigatureAttach( TTO_LigatureAttach* lat, + UShort num_classes, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort m, n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_ComponentRecord* cr; + TTO_Anchor* lan; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = lat->ComponentCount = GET_UShort(); + + FORGET_Frame(); + + lat->ComponentRecord = NULL; + + if ( ALLOC_ARRAY( lat->ComponentRecord, count, TTO_ComponentRecord ) ) + return error; + + cr = lat->ComponentRecord; + + for ( m = 0; m < count; m++ ) + { + cr[m].LigatureAnchor = NULL; + + if ( ALLOC_ARRAY( cr[m].LigatureAnchor, num_classes, TTO_Anchor ) ) + goto Fail; + + lan = cr[m].LigatureAnchor; + + for ( n = 0; n < num_classes; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort(); + + FORGET_Frame(); + + if ( new_offset ) + { + new_offset += base_offset; + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Anchor( &lan[n], input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + else + lan[n].PosFormat = 0; + } + } + + return TT_Err_Ok; + + Fail: + for ( m = 0; m < count; m++ ) + { + lan = cr[m].LigatureAnchor; + + for ( n = 0; n < num_classes; n++ ) + Free_Anchor( &lan[n] ); + + FREE( lan ); + } + + FREE( cr ); + return error; + } + + + static void Free_LigatureAttach( TTO_LigatureAttach* lat, + UShort num_classes ) + { + UShort m, n, count; + + TTO_ComponentRecord* cr; + TTO_Anchor* lan; + + + if ( lat->ComponentRecord ) + { + count = lat->ComponentCount; + cr = lat->ComponentRecord; + + for ( m = 0; m < count; m++ ) + { + lan = cr[m].LigatureAnchor; + + for ( n = 0; n < num_classes; n++ ) + Free_Anchor( &lan[n] ); + + FREE( lan ); + } + + FREE( cr ); + } + } + + + /* LigatureArray */ + + static TT_Error Load_LigatureArray( TTO_LigatureArray* la, + UShort num_classes, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_LigatureAttach* lat; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = la->LigatureCount = GET_UShort(); + + FORGET_Frame(); + + la->LigatureAttach = NULL; + + if ( ALLOC_ARRAY( la->LigatureAttach, count, TTO_LigatureAttach ) ) + return error; + + lat = la->LigatureAttach; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_LigatureAttach( &lat[n], num_classes, + input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_LigatureAttach( &lat[n], num_classes ); + + FREE( lat ); + return error; + } + + + static void Free_LigatureArray( TTO_LigatureArray* la, + UShort num_classes ) + { + UShort n, count; + + TTO_LigatureAttach* lat; + + + if ( la->LigatureAttach ) + { + count = la->LigatureCount; + lat = la->LigatureAttach; + + for ( n = 0; n < count; n++ ) + Free_LigatureAttach( &lat[n], num_classes ); + + FREE( lat ); + } + } + + + /* MarkLigPosFormat1 */ + + TT_Error Load_MarkLigPos( TTO_MarkLigPos* mlp, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + ULong cur_offset, new_offset, base_offset; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 4L ) ) + return error; + + mlp->PosFormat = GET_UShort(); + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &mlp->MarkCoverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &mlp->LigatureCoverage, + input ) ) != TT_Err_Ok ) + goto Fail3; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 4L ) ) + goto Fail2; + + mlp->ClassCount = GET_UShort(); + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_MarkArray( &mlp->MarkArray, input ) ) != TT_Err_Ok ) + goto Fail2; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_LigatureArray( &mlp->LigatureArray, mlp->ClassCount, + input ) ) != TT_Err_Ok ) + goto Fail1; + + return TT_Err_Ok; + + Fail1: + Free_MarkArray( &mlp->MarkArray ); + + Fail2: + Free_Coverage( &mlp->LigatureCoverage ); + + Fail3: + Free_Coverage( &mlp->MarkCoverage ); + return error; + } + + + void Free_MarkLigPos( TTO_MarkLigPos* mlp ) + { + Free_LigatureArray( &mlp->LigatureArray, mlp->ClassCount ); + Free_MarkArray( &mlp->MarkArray ); + Free_Coverage( &mlp->LigatureCoverage ); + Free_Coverage( &mlp->MarkCoverage ); + } + + + /* LookupType 6 */ + + /* Mark2Array */ + + static TT_Error Load_Mark2Array( TTO_Mark2Array* m2a, + UShort num_classes, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort m, n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_Mark2Record* m2r; + TTO_Anchor* m2an; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = m2a->Mark2Count = GET_UShort(); + + FORGET_Frame(); + + m2a->Mark2Record = NULL; + + if ( ALLOC_ARRAY( m2a->Mark2Record, count, TTO_Mark2Record ) ) + return error; + + m2r = m2a->Mark2Record; + + for ( m = 0; m < count; m++ ) + { + m2r[m].Mark2Anchor = NULL; + + if ( ALLOC_ARRAY( m2r[m].Mark2Anchor, num_classes, TTO_Anchor ) ) + goto Fail; + + m2an = m2r[m].Mark2Anchor; + + for ( n = 0; n < num_classes; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Anchor( &m2an[n], input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + } + + return TT_Err_Ok; + + Fail: + for ( m = 0; m < count; m++ ) + { + m2an = m2r[m].Mark2Anchor; + + for ( n = 0; n < num_classes; n++ ) + Free_Anchor( &m2an[n] ); + + FREE( m2an ); + } + + FREE( m2r ); + return error; + } + + + static void Free_Mark2Array( TTO_Mark2Array* m2a, + UShort num_classes ) + { + UShort m, n, count; + + TTO_Mark2Record* m2r; + TTO_Anchor* m2an; + + + if ( m2a->Mark2Record ) + { + count = m2a->Mark2Count; + m2r = m2a->Mark2Record; + + for ( m = 0; m < count; m++ ) + { + m2an = m2r[m].Mark2Anchor; + + for ( n = 0; n < num_classes; n++ ) + Free_Anchor( &m2an[n] ); + + FREE( m2an ); + } + + FREE( m2r ); + } + } + + + /* MarkMarkPosFormat1 */ + + TT_Error Load_MarkMarkPos( TTO_MarkMarkPos* mmp, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + ULong cur_offset, new_offset, base_offset; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 4L ) ) + return error; + + mmp->PosFormat = GET_UShort(); + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &mmp->Mark1Coverage, + input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &mmp->Mark2Coverage, + input ) ) != TT_Err_Ok ) + goto Fail3; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 4L ) ) + goto Fail2; + + mmp->ClassCount = GET_UShort(); + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_MarkArray( &mmp->Mark1Array, input ) ) != TT_Err_Ok ) + goto Fail2; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Mark2Array( &mmp->Mark2Array, mmp->ClassCount, + input ) ) != TT_Err_Ok ) + goto Fail1; + + return TT_Err_Ok; + + Fail1: + Free_MarkArray( &mmp->Mark1Array ); + + Fail2: + Free_Coverage( &mmp->Mark2Coverage ); + + Fail3: + Free_Coverage( &mmp->Mark1Coverage ); + return error; + } + + + void Free_MarkMarkPos( TTO_MarkMarkPos* mmp ) + { + Free_Mark2Array( &mmp->Mark2Array, mmp->ClassCount ); + Free_MarkArray( &mmp->Mark1Array ); + Free_Coverage( &mmp->Mark2Coverage ); + Free_Coverage( &mmp->Mark1Coverage ); + } + + + /* LookupType 7 */ + + /* PosRule */ + + static TT_Error Load_PosRule( TTO_PosRule* pr, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + UShort* i; + + TTO_PosLookupRecord* plr; + + + if ( ACCESS_Frame( 4L ) ) + return error; + + pr->GlyphCount = GET_UShort(); + pr->PosCount = GET_UShort(); + + FORGET_Frame(); + + pr->Input = NULL; + + count = pr->GlyphCount - 1; /* only GlyphCount - 1 elements */ + + if ( ALLOC_ARRAY( pr->Input, count, UShort ) ) + return error; + + i = pr->Input; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail2; + + for ( n = 0; n < count; n++ ) + i[n] = GET_UShort(); + + FORGET_Frame(); + + pr->PosLookupRecord = NULL; + + count = pr->PosCount; + + if ( ALLOC_ARRAY( pr->PosLookupRecord, count, TTO_PosLookupRecord ) ) + goto Fail2; + + plr = pr->PosLookupRecord; + + if ( ACCESS_Frame( count * 4L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + { + plr[n].SequenceIndex = GET_UShort(); + plr[n].LookupListIndex = GET_UShort(); + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail1: + FREE( plr ); + + Fail2: + FREE( i ); + return error; + } + + + static void Free_PosRule( TTO_PosRule* pr ) + { + FREE( pr->PosLookupRecord ); + FREE( pr->Input ); + } + + + /* PosRuleSet */ + + static TT_Error Load_PosRuleSet( TTO_PosRuleSet* prs, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_PosRule* pr; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = prs->PosRuleCount = GET_UShort(); + + FORGET_Frame(); + + prs->PosRule = NULL; + + if ( ALLOC_ARRAY( prs->PosRule, count, TTO_PosRule ) ) + return error; + + pr = prs->PosRule; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_PosRule( &pr[n], input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_PosRule( &pr[n] ); + + FREE( pr ); + return error; + } + + + static void Free_PosRuleSet( TTO_PosRuleSet* prs ) + { + UShort n, count; + + TTO_PosRule* pr; + + + if ( prs->PosRule ) + { + count = prs->PosRuleCount; + pr = prs->PosRule; + + for ( n = 0; n < count; n++ ) + Free_PosRule( &pr[n] ); + + FREE( pr ); + } + } + + + /* ContextPosFormat1 */ + + static TT_Error Load_ContextPos1( TTO_ContextPosFormat1* cpf1, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_PosRuleSet* prs; + + + base_offset = FILE_Pos() - 2L; + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &cpf1->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = cpf1->PosRuleSetCount = GET_UShort(); + + FORGET_Frame(); + + cpf1->PosRuleSet = NULL; + + if ( ALLOC_ARRAY( cpf1->PosRuleSet, count, TTO_PosRuleSet ) ) + goto Fail2; + + prs = cpf1->PosRuleSet; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_PosRuleSet( &prs[n], input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_PosRuleSet( &prs[n] ); + + FREE( prs ); + + Fail2: + Free_Coverage( &cpf1->Coverage ); + return error; + } + + + static void Free_Context1( TTO_ContextPosFormat1* cpf1 ) + { + UShort n, count; + + TTO_PosRuleSet* prs; + + + if ( cpf1->PosRuleSet ) + { + count = cpf1->PosRuleSetCount; + prs = cpf1->PosRuleSet; + + for ( n = 0; n < count; n++ ) + Free_PosRuleSet( &prs[n] ); + + FREE( prs ); + } + + Free_Coverage( &cpf1->Coverage ); + } + + + /* PosClassRule */ + + static TT_Error Load_PosClassRule( TTO_ContextPosFormat2* cpf2, + TTO_PosClassRule* pcr, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + + UShort* c; + TTO_PosLookupRecord* plr; + Bool* d; + + + if ( ACCESS_Frame( 4L ) ) + return error; + + pcr->GlyphCount = GET_UShort(); + pcr->PosCount = GET_UShort(); + + FORGET_Frame(); + + if ( pcr->GlyphCount > cpf2->MaxContextLength ) + cpf2->MaxContextLength = pcr->GlyphCount; + + pcr->Class = NULL; + + count = pcr->GlyphCount - 1; /* only GlyphCount - 1 elements */ + + if ( ALLOC_ARRAY( pcr->Class, count, UShort ) ) + return error; + + c = pcr->Class; + d = cpf2->ClassDef.Defined; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail2; + + for ( n = 0; n < count; n++ ) + { + c[n] = GET_UShort(); + + /* We check whether the specific class is used at all. If not, + class 0 is used instead. */ + + if ( !d[c[n]] ) + c[n] = 0; + } + + FORGET_Frame(); + + pcr->PosLookupRecord = NULL; + + count = pcr->PosCount; + + if ( ALLOC_ARRAY( pcr->PosLookupRecord, count, TTO_PosLookupRecord ) ) + goto Fail2; + + plr = pcr->PosLookupRecord; + + if ( ACCESS_Frame( count * 4L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + { + plr[n].SequenceIndex = GET_UShort(); + plr[n].LookupListIndex = GET_UShort(); + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail1: + FREE( plr ); + + Fail2: + FREE( c ); + return error; + } + + + static void Free_PosClassRule( TTO_PosClassRule* pcr ) + { + FREE( pcr->PosLookupRecord ); + FREE( pcr->Class ); + } + + + /* PosClassSet */ + + static TT_Error Load_PosClassSet( TTO_ContextPosFormat2* cpf2, + TTO_PosClassSet* pcs, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_PosClassRule* pcr; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = pcs->PosClassRuleCount = GET_UShort(); + + FORGET_Frame(); + + pcs->PosClassRule = NULL; + + if ( ALLOC_ARRAY( pcs->PosClassRule, count, TTO_PosClassRule ) ) + return error; + + pcr = pcs->PosClassRule; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_PosClassRule( cpf2, &pcr[n], + input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_PosClassRule( &pcr[n] ); + + FREE( pcr ); + return error; + } + + + static void Free_PosClassSet( TTO_PosClassSet* pcs ) + { + UShort n, count; + + TTO_PosClassRule* pcr; + + + if ( pcs->PosClassRule ) + { + count = pcs->PosClassRuleCount; + pcr = pcs->PosClassRule; + + for ( n = 0; n < count; n++ ) + Free_PosClassRule( &pcr[n] ); + + FREE( pcr ); + } + } + + + /* ContextPosFormat2 */ + + static TT_Error Load_ContextPos2( TTO_ContextPosFormat2* cpf2, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_PosClassSet* pcs; + + + base_offset = FILE_Pos() - 2; + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &cpf2->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 4L ) ) + goto Fail3; + + new_offset = GET_UShort() + base_offset; + + /* `PosClassSetCount' is the upper limit for class values, thus we + read it now to make an additional safety check. */ + + count = cpf2->PosClassSetCount = GET_UShort(); + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ClassDefinition( &cpf2->ClassDef, count, + input ) ) != TT_Err_Ok ) + goto Fail3; + (void)FILE_Seek( cur_offset ); + + cpf2->PosClassSet = NULL; + cpf2->MaxContextLength = 0; + + if ( ALLOC_ARRAY( cpf2->PosClassSet, count, TTO_PosClassSet ) ) + goto Fail2; + + pcs = cpf2->PosClassSet; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + if ( new_offset != base_offset ) /* not a NULL offset */ + { + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_PosClassSet( cpf2, &pcs[n], + input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + else + { + /* we create a PosClassSet table with no entries */ + + cpf2->PosClassSet[n].PosClassRuleCount = 0; + cpf2->PosClassSet[n].PosClassRule = NULL; + } + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_PosClassSet( &pcs[n] ); + + FREE( pcs ); + + Fail2: + Free_ClassDefinition( &cpf2->ClassDef ); + + Fail3: + Free_Coverage( &cpf2->Coverage ); + return error; + } + + + static void Free_Context2( TTO_ContextPosFormat2* cpf2 ) + { + UShort n, count; + + TTO_PosClassSet* pcs; + + + if ( cpf2->PosClassSet ) + { + count = cpf2->PosClassSetCount; + pcs = cpf2->PosClassSet; + + for ( n = 0; n < count; n++ ) + Free_PosClassSet( &pcs[n] ); + + FREE( pcs ); + } + + Free_ClassDefinition( &cpf2->ClassDef ); + Free_Coverage( &cpf2->Coverage ); + } + + + /* ContextPosFormat3 */ + + static TT_Error Load_ContextPos3( TTO_ContextPosFormat3* cpf3, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_Coverage* c; + TTO_PosLookupRecord* plr; + + + base_offset = FILE_Pos() - 2L; + + if ( ACCESS_Frame( 4L ) ) + return error; + + cpf3->GlyphCount = GET_UShort(); + cpf3->PosCount = GET_UShort(); + + FORGET_Frame(); + + cpf3->Coverage = NULL; + + count = cpf3->GlyphCount; + + if ( ALLOC_ARRAY( cpf3->Coverage, count, TTO_Coverage ) ) + return error; + + c = cpf3->Coverage; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &c[n], input ) ) != TT_Err_Ok ) + goto Fail2; + (void)FILE_Seek( cur_offset ); + } + + cpf3->PosLookupRecord = NULL; + + count = cpf3->PosCount; + + if ( ALLOC_ARRAY( cpf3->PosLookupRecord, count, TTO_PosLookupRecord ) ) + goto Fail2; + + plr = cpf3->PosLookupRecord; + + if ( ACCESS_Frame( count * 4L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + { + plr[n].SequenceIndex = GET_UShort(); + plr[n].LookupListIndex = GET_UShort(); + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail1: + FREE( plr ); + + Fail2: + for ( n = 0; n < count; n++ ) + Free_Coverage( &c[n] ); + + FREE( c ); + return error; + } + + + static void Free_Context3( TTO_ContextPosFormat3* cpf3 ) + { + UShort n, count; + + TTO_Coverage* c; + + + FREE( cpf3->PosLookupRecord ); + + if ( cpf3->Coverage ) + { + count = cpf3->GlyphCount; + c = cpf3->Coverage; + + for ( n = 0; n < count; n++ ) + Free_Coverage( &c[n] ); + + FREE( c ); + } + } + + + /* ContextPos */ + + TT_Error Load_ContextPos( TTO_ContextPos* cp, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + + if ( ACCESS_Frame( 2L ) ) + return error; + + cp->PosFormat = GET_UShort(); + + FORGET_Frame(); + + switch ( cp->PosFormat ) + { + case 1: + return Load_ContextPos1( &cp->cpf.cpf1, input ); + + case 2: + return Load_ContextPos2( &cp->cpf.cpf2, input ); + + case 3: + return Load_ContextPos3( &cp->cpf.cpf3, input ); + + default: + return TTO_Err_Invalid_GPOS_SubTable_Format; + } + + return TT_Err_Ok; /* never reached */ + } + + + void Free_ContextPos( TTO_ContextPos* cp ) + { + switch ( cp->PosFormat ) + { + case 1: + Free_Context1( &cp->cpf.cpf1 ); + break; + + case 2: + Free_Context2( &cp->cpf.cpf2 ); + break; + + case 3: + Free_Context3( &cp->cpf.cpf3 ); + break; + } + } + + + /* LookupType 8 */ + + /* ChainPosRule */ + + static TT_Error Load_ChainPosRule( TTO_ChainPosRule* cpr, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + UShort* b; + UShort* i; + UShort* l; + + TTO_PosLookupRecord* plr; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + cpr->BacktrackGlyphCount = GET_UShort(); + + FORGET_Frame(); + + cpr->Backtrack = NULL; + + count = cpr->BacktrackGlyphCount; + + if ( ALLOC_ARRAY( cpr->Backtrack, count, UShort ) ) + return error; + + b = cpr->Backtrack; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail4; + + for ( n = 0; n < count; n++ ) + b[n] = GET_UShort(); + + FORGET_Frame(); + + if ( ACCESS_Frame( 2L ) ) + goto Fail4; + + cpr->InputGlyphCount = GET_UShort(); + + FORGET_Frame(); + + cpr->Input = NULL; + + count = cpr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */ + + if ( ALLOC_ARRAY( cpr->Input, count, UShort ) ) + goto Fail4; + + i = cpr->Input; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail3; + + for ( n = 0; n < count; n++ ) + i[n] = GET_UShort(); + + FORGET_Frame(); + + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + cpr->LookaheadGlyphCount = GET_UShort(); + + FORGET_Frame(); + + cpr->Lookahead = NULL; + + count = cpr->LookaheadGlyphCount; + + if ( ALLOC_ARRAY( cpr->Lookahead, count, UShort ) ) + goto Fail3; + + l = cpr->Lookahead; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail2; + + for ( n = 0; n < count; n++ ) + l[n] = GET_UShort(); + + FORGET_Frame(); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + cpr->PosCount = GET_UShort(); + + FORGET_Frame(); + + cpr->PosLookupRecord = NULL; + + count = cpr->PosCount; + + if ( ALLOC_ARRAY( cpr->PosLookupRecord, count, TTO_PosLookupRecord ) ) + goto Fail2; + + plr = cpr->PosLookupRecord; + + if ( ACCESS_Frame( count * 4L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + { + plr[n].SequenceIndex = GET_UShort(); + plr[n].LookupListIndex = GET_UShort(); + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail1: + FREE( plr ); + + Fail2: + FREE( l ); + + Fail3: + FREE( i ); + + Fail4: + FREE( b ); + return error; + } + + + static void Free_ChainPosRule( TTO_ChainPosRule* cpr ) + { + FREE( cpr->PosLookupRecord ); + FREE( cpr->Lookahead ); + FREE( cpr->Input ); + FREE( cpr->Backtrack ); + } + + + /* ChainPosRuleSet */ + + static TT_Error Load_ChainPosRuleSet( TTO_ChainPosRuleSet* cprs, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_ChainPosRule* cpr; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = cprs->ChainPosRuleCount = GET_UShort(); + + FORGET_Frame(); + + cprs->ChainPosRule = NULL; + + if ( ALLOC_ARRAY( cprs->ChainPosRule, count, TTO_ChainPosRule ) ) + return error; + + cpr = cprs->ChainPosRule; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ChainPosRule( &cpr[n], input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_ChainPosRule( &cpr[n] ); + + FREE( cpr ); + return error; + } + + + static void Free_ChainPosRuleSet( TTO_ChainPosRuleSet* cprs ) + { + UShort n, count; + + TTO_ChainPosRule* cpr; + + + if ( cprs->ChainPosRule ) + { + count = cprs->ChainPosRuleCount; + cpr = cprs->ChainPosRule; + + for ( n = 0; n < count; n++ ) + Free_ChainPosRule( &cpr[n] ); + + FREE( cpr ); + } + } + + + /* ChainContextPosFormat1 */ + + static TT_Error Load_ChainContextPos1( TTO_ChainContextPosFormat1* ccpf1, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_ChainPosRuleSet* cprs; + + + base_offset = FILE_Pos() - 2L; + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &ccpf1->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = ccpf1->ChainPosRuleSetCount = GET_UShort(); + + FORGET_Frame(); + + ccpf1->ChainPosRuleSet = NULL; + + if ( ALLOC_ARRAY( ccpf1->ChainPosRuleSet, count, TTO_ChainPosRuleSet ) ) + goto Fail2; + + cprs = ccpf1->ChainPosRuleSet; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ChainPosRuleSet( &cprs[n], input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_ChainPosRuleSet( &cprs[n] ); + + FREE( cprs ); + + Fail2: + Free_Coverage( &ccpf1->Coverage ); + return error; + } + + + static void Free_ChainContext1( TTO_ChainContextPosFormat1* ccpf1 ) + { + UShort n, count; + + TTO_ChainPosRuleSet* cprs; + + + if ( ccpf1->ChainPosRuleSet ) + { + count = ccpf1->ChainPosRuleSetCount; + cprs = ccpf1->ChainPosRuleSet; + + for ( n = 0; n < count; n++ ) + Free_ChainPosRuleSet( &cprs[n] ); + + FREE( cprs ); + } + + Free_Coverage( &ccpf1->Coverage ); + } + + + /* ChainPosClassRule */ + + static TT_Error Load_ChainPosClassRule( + TTO_ChainContextPosFormat2* ccpf2, + TTO_ChainPosClassRule* cpcr, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + + UShort* b; + UShort* i; + UShort* l; + TTO_PosLookupRecord* plr; + Bool* d; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + cpcr->BacktrackGlyphCount = GET_UShort(); + + FORGET_Frame(); + + if ( cpcr->BacktrackGlyphCount > ccpf2->MaxBacktrackLength ) + ccpf2->MaxBacktrackLength = cpcr->BacktrackGlyphCount; + + cpcr->Backtrack = NULL; + + count = cpcr->BacktrackGlyphCount; + + if ( ALLOC_ARRAY( cpcr->Backtrack, count, UShort ) ) + return error; + + b = cpcr->Backtrack; + d = ccpf2->BacktrackClassDef.Defined; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail4; + + for ( n = 0; n < count; n++ ) + { + b[n] = GET_UShort(); + + /* We check whether the specific class is used at all. If not, + class 0 is used instead. */ + + if ( !d[b[n]] ) + b[n] = 0; + } + + FORGET_Frame(); + + if ( ACCESS_Frame( 2L ) ) + goto Fail4; + + cpcr->InputGlyphCount = GET_UShort(); + + if ( cpcr->InputGlyphCount > ccpf2->MaxInputLength ) + ccpf2->MaxInputLength = cpcr->InputGlyphCount; + + FORGET_Frame(); + + cpcr->Input = NULL; + + count = cpcr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */ + + if ( ALLOC_ARRAY( cpcr->Input, count, UShort ) ) + goto Fail4; + + i = cpcr->Input; + d = ccpf2->InputClassDef.Defined; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail3; + + for ( n = 0; n < count; n++ ) + { + i[n] = GET_UShort(); + + if ( !d[i[n]] ) + i[n] = 0; + } + + FORGET_Frame(); + + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + cpcr->LookaheadGlyphCount = GET_UShort(); + + FORGET_Frame(); + + if ( cpcr->LookaheadGlyphCount > ccpf2->MaxLookaheadLength ) + ccpf2->MaxLookaheadLength = cpcr->LookaheadGlyphCount; + + cpcr->Lookahead = NULL; + + count = cpcr->LookaheadGlyphCount; + + if ( ALLOC_ARRAY( cpcr->Lookahead, count, UShort ) ) + goto Fail3; + + l = cpcr->Lookahead; + d = ccpf2->LookaheadClassDef.Defined; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail2; + + for ( n = 0; n < count; n++ ) + { + l[n] = GET_UShort(); + + if ( !d[l[n]] ) + l[n] = 0; + } + + FORGET_Frame(); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + cpcr->PosCount = GET_UShort(); + + FORGET_Frame(); + + cpcr->PosLookupRecord = NULL; + + count = cpcr->PosCount; + + if ( ALLOC_ARRAY( cpcr->PosLookupRecord, count, TTO_PosLookupRecord ) ) + goto Fail2; + + plr = cpcr->PosLookupRecord; + + if ( ACCESS_Frame( count * 4L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + { + plr[n].SequenceIndex = GET_UShort(); + plr[n].LookupListIndex = GET_UShort(); + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail1: + FREE( plr ); + + Fail2: + FREE( l ); + + Fail3: + FREE( i ); + + Fail4: + FREE( b ); + return error; + } + + + static void Free_ChainPosClassRule( TTO_ChainPosClassRule* cpcr ) + { + FREE( cpcr->PosLookupRecord ); + FREE( cpcr->Lookahead ); + FREE( cpcr->Input ); + FREE( cpcr->Backtrack ); + } + + + /* PosClassSet */ + + static TT_Error Load_ChainPosClassSet( + TTO_ChainContextPosFormat2* ccpf2, + TTO_ChainPosClassSet* cpcs, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_ChainPosClassRule* cpcr; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = cpcs->ChainPosClassRuleCount = GET_UShort(); + + FORGET_Frame(); + + cpcs->ChainPosClassRule = NULL; + + if ( ALLOC_ARRAY( cpcs->ChainPosClassRule, count, + TTO_ChainPosClassRule ) ) + return error; + + cpcr = cpcs->ChainPosClassRule; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ChainPosClassRule( ccpf2, &cpcr[n], + input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_ChainPosClassRule( &cpcr[n] ); + + FREE( cpcr ); + return error; + } + + + static void Free_ChainPosClassSet( TTO_ChainPosClassSet* cpcs ) + { + UShort n, count; + + TTO_ChainPosClassRule* cpcr; + + + if ( cpcs->ChainPosClassRule ) + { + count = cpcs->ChainPosClassRuleCount; + cpcr = cpcs->ChainPosClassRule; + + for ( n = 0; n < count; n++ ) + Free_ChainPosClassRule( &cpcr[n] ); + + FREE( cpcr ); + } + } + + + /* ChainContextPosFormat2 */ + + static TT_Error Load_ChainContextPos2( TTO_ChainContextPosFormat2* ccpf2, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + ULong backtrack_offset, input_offset, lookahead_offset; + + TTO_ChainPosClassSet* cpcs; + + + base_offset = FILE_Pos() - 2; + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &ccpf2->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 8L ) ) + goto Fail5; + + backtrack_offset = GET_UShort() + base_offset; + input_offset = GET_UShort() + base_offset; + lookahead_offset = GET_UShort() + base_offset; + + /* `ChainPosClassSetCount' is the upper limit for input class values, + thus we read it now to make an additional safety check. */ + + count = ccpf2->ChainPosClassSetCount = GET_UShort(); + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( backtrack_offset ) || + ( error = Load_ClassDefinition( &ccpf2->BacktrackClassDef, count, + input ) ) != TT_Err_Ok ) + goto Fail5; + if ( FILE_Seek( input_offset ) || + ( error = Load_ClassDefinition( &ccpf2->InputClassDef, count, + input ) ) != TT_Err_Ok ) + goto Fail4; + if ( FILE_Seek( lookahead_offset ) || + ( error = Load_ClassDefinition( &ccpf2->LookaheadClassDef, count, + input ) ) != TT_Err_Ok ) + goto Fail3; + (void)FILE_Seek( cur_offset ); + + ccpf2->ChainPosClassSet = NULL; + ccpf2->MaxBacktrackLength = 0; + ccpf2->MaxInputLength = 0; + ccpf2->MaxLookaheadLength = 0; + + if ( ALLOC_ARRAY( ccpf2->ChainPosClassSet, count, TTO_ChainPosClassSet ) ) + goto Fail2; + + cpcs = ccpf2->ChainPosClassSet; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + if ( new_offset != base_offset ) /* not a NULL offset */ + { + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ChainPosClassSet( ccpf2, &cpcs[n], + input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + else + { + /* we create a ChainPosClassSet table with no entries */ + + ccpf2->ChainPosClassSet[n].ChainPosClassRuleCount = 0; + ccpf2->ChainPosClassSet[n].ChainPosClassRule = NULL; + } + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_ChainPosClassSet( &cpcs[n] ); + + FREE( cpcs ); + + Fail2: + Free_ClassDefinition( &ccpf2->LookaheadClassDef ); + + Fail3: + Free_ClassDefinition( &ccpf2->InputClassDef ); + + Fail4: + Free_ClassDefinition( &ccpf2->BacktrackClassDef ); + + Fail5: + Free_Coverage( &ccpf2->Coverage ); + return error; + } + + + static void Free_ChainContext2( TTO_ChainContextPosFormat2* ccpf2 ) + { + UShort n, count; + + TTO_ChainPosClassSet* cpcs; + + + if ( ccpf2->ChainPosClassSet ) + { + count = ccpf2->ChainPosClassSetCount; + cpcs = ccpf2->ChainPosClassSet; + + for ( n = 0; n < count; n++ ) + Free_ChainPosClassSet( &cpcs[n] ); + + FREE( cpcs ); + } + + Free_ClassDefinition( &ccpf2->LookaheadClassDef ); + Free_ClassDefinition( &ccpf2->InputClassDef ); + Free_ClassDefinition( &ccpf2->BacktrackClassDef ); + + Free_Coverage( &ccpf2->Coverage ); + } + + + /* ChainContextPosFormat3 */ + + static TT_Error Load_ChainContextPos3( TTO_ChainContextPosFormat3* ccpf3, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + UShort backtrack_count, input_count, lookahead_count; + ULong cur_offset, new_offset, base_offset; + + TTO_Coverage* b; + TTO_Coverage* i; + TTO_Coverage* l; + TTO_PosLookupRecord* plr; + + + base_offset = FILE_Pos() - 2L; + + if ( ACCESS_Frame( 2L ) ) + return error; + + ccpf3->BacktrackGlyphCount = GET_UShort(); + + FORGET_Frame(); + + ccpf3->BacktrackCoverage = NULL; + + backtrack_count = ccpf3->BacktrackGlyphCount; + + if ( ALLOC_ARRAY( ccpf3->BacktrackCoverage, backtrack_count, + TTO_Coverage ) ) + return error; + + b = ccpf3->BacktrackCoverage; + + for ( n = 0; n < backtrack_count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail4; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &b[n], input ) ) != TT_Err_Ok ) + goto Fail4; + (void)FILE_Seek( cur_offset ); + } + + if ( ACCESS_Frame( 2L ) ) + goto Fail4; + + ccpf3->InputGlyphCount = GET_UShort(); + + FORGET_Frame(); + + ccpf3->InputCoverage = NULL; + + input_count = ccpf3->InputGlyphCount; + + if ( ALLOC_ARRAY( ccpf3->InputCoverage, input_count, TTO_Coverage ) ) + goto Fail4; + + i = ccpf3->InputCoverage; + + for ( n = 0; n < input_count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &i[n], input ) ) != TT_Err_Ok ) + goto Fail3; + (void)FILE_Seek( cur_offset ); + } + + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + ccpf3->LookaheadGlyphCount = GET_UShort(); + + FORGET_Frame(); + + ccpf3->LookaheadCoverage = NULL; + + lookahead_count = ccpf3->LookaheadGlyphCount; + + if ( ALLOC_ARRAY( ccpf3->LookaheadCoverage, lookahead_count, + TTO_Coverage ) ) + goto Fail3; + + l = ccpf3->LookaheadCoverage; + + for ( n = 0; n < lookahead_count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &l[n], input ) ) != TT_Err_Ok ) + goto Fail2; + (void)FILE_Seek( cur_offset ); + } + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + ccpf3->PosCount = GET_UShort(); + + FORGET_Frame(); + + ccpf3->PosLookupRecord = NULL; + + count = ccpf3->PosCount; + + if ( ALLOC_ARRAY( ccpf3->PosLookupRecord, count, TTO_PosLookupRecord ) ) + goto Fail2; + + plr = ccpf3->PosLookupRecord; + + if ( ACCESS_Frame( count * 4L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + { + plr[n].SequenceIndex = GET_UShort(); + plr[n].LookupListIndex = GET_UShort(); + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail1: + FREE( plr ); + + Fail2: + for ( n = 0; n < lookahead_count; n++ ) + Free_Coverage( &l[n] ); + + FREE( l ); + + Fail3: + for ( n = 0; n < input_count; n++ ) + Free_Coverage( &i[n] ); + + FREE( i ); + + Fail4: + for ( n = 0; n < backtrack_count; n++ ) + Free_Coverage( &b[n] ); + + FREE( b ); + return error; + } + + + static void Free_ChainContext3( TTO_ChainContextPosFormat3* ccpf3 ) + { + UShort n, count; + + TTO_Coverage* c; + + + FREE( ccpf3->PosLookupRecord ); + + if ( ccpf3->LookaheadCoverage ) + { + count = ccpf3->LookaheadGlyphCount; + c = ccpf3->LookaheadCoverage; + + for ( n = 0; n < count; n++ ) + Free_Coverage( &c[n] ); + + FREE( c ); + } + + if ( ccpf3->InputCoverage ) + { + count = ccpf3->InputGlyphCount; + c = ccpf3->InputCoverage; + + for ( n = 0; n < count; n++ ) + Free_Coverage( &c[n] ); + + FREE( c ); + } + + if ( ccpf3->BacktrackCoverage ) + { + count = ccpf3->BacktrackGlyphCount; + c = ccpf3->BacktrackCoverage; + + for ( n = 0; n < count; n++ ) + Free_Coverage( &c[n] ); + + FREE( c ); + } + } + + + /* ChainContextPos */ + + TT_Error Load_ChainContextPos( TTO_ChainContextPos* ccp, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + + if ( ACCESS_Frame( 2L ) ) + return error; + + ccp->PosFormat = GET_UShort(); + + FORGET_Frame(); + + switch ( ccp->PosFormat ) + { + case 1: + return Load_ChainContextPos1( &ccp->ccpf.ccpf1, input ); + + case 2: + return Load_ChainContextPos2( &ccp->ccpf.ccpf2, input ); + + case 3: + return Load_ChainContextPos3( &ccp->ccpf.ccpf3, input ); + + default: + return TTO_Err_Invalid_GPOS_SubTable_Format; + } + + return TT_Err_Ok; /* never reached */ + } + + + void Free_ChainContextPos( TTO_ChainContextPos* ccp ) + { + switch ( ccp->PosFormat ) + { + case 1: + Free_ChainContext1( &ccp->ccpf.ccpf1 ); + break; + + case 2: + Free_ChainContext2( &ccp->ccpf.ccpf2 ); + break; + + case 3: + Free_ChainContext3( &ccp->ccpf.ccpf3 ); + break; + } + } + + + + /*********** + * GPOS API + ***********/ + + + EXPORT_FUNC + TT_Error TT_GPOS_Select_Script( TTO_GPOSHeader* gpos, + TT_ULong script_tag, + TT_UShort* script_index ) + { + UShort n; + + TTO_ScriptList* sl; + TTO_ScriptRecord* sr; + + + if ( !gpos || !script_index ) + return TT_Err_Invalid_Argument; + + sl = &gpos->ScriptList; + sr = sl->ScriptRecord; + + for ( n = 0; n < sl->ScriptCount; n++ ) + if ( script_tag == sr[n].ScriptTag ) + { + *script_index = n; + + return TT_Err_Ok; + } + + return TTO_Err_Not_Covered; + } + + + EXPORT_FUNC + TT_Error TT_GPOS_Select_Language( TTO_GPOSHeader* gpos, + TT_ULong language_tag, + TT_UShort script_index, + TT_UShort* language_index, + TT_UShort* req_feature_index ) + { + UShort n; + + TTO_ScriptList* sl; + TTO_ScriptRecord* sr; + TTO_Script* s; + TTO_LangSysRecord* lsr; + + + if ( !gpos || !language_index || !req_feature_index ) + return TT_Err_Invalid_Argument; + + sl = &gpos->ScriptList; + sr = sl->ScriptRecord; + + if ( script_index >= sl->ScriptCount ) + return TT_Err_Invalid_Argument; + + s = &sr[script_index].Script; + lsr = s->LangSysRecord; + + for ( n = 0; n < s->LangSysCount; n++ ) + if ( language_tag == lsr[n].LangSysTag ) + { + *language_index = n; + *req_feature_index = lsr[n].LangSys.ReqFeatureIndex; + + return TT_Err_Ok; + } + + return TTO_Err_Not_Covered; + } + + + /* selecting 0xFFFF for language_index asks for the values of the + default language (DefaultLangSys) */ + + EXPORT_FUNC + TT_Error TT_GPOS_Select_Feature( TTO_GPOSHeader* gpos, + TT_ULong feature_tag, + TT_UShort script_index, + TT_UShort language_index, + TT_UShort* feature_index ) + { + UShort n; + + TTO_ScriptList* sl; + TTO_ScriptRecord* sr; + TTO_Script* s; + TTO_LangSysRecord* lsr; + TTO_LangSys* ls; + UShort* fi; + + TTO_FeatureList* fl; + TTO_FeatureRecord* fr; + + + if ( !gpos || !feature_index ) + return TT_Err_Invalid_Argument; + + sl = &gpos->ScriptList; + sr = sl->ScriptRecord; + + fl = &gpos->FeatureList; + fr = fl->FeatureRecord; + + if ( script_index >= sl->ScriptCount ) + return TT_Err_Invalid_Argument; + + s = &sr[script_index].Script; + lsr = s->LangSysRecord; + + if ( language_index == 0xFFFF ) + ls = &s->DefaultLangSys; + else + { + if ( language_index >= s->LangSysCount ) + return TT_Err_Invalid_Argument; + + ls = &lsr[language_index].LangSys; + } + + fi = ls->FeatureIndex; + + for ( n = 0; n < ls->FeatureCount; n++ ) + { + if ( fi[n] >= fl->FeatureCount ) + return TTO_Err_Invalid_GPOS_SubTable_Format; + + if ( feature_tag == fr[fi[n]].FeatureTag ) + { + *feature_index = fi[n]; + + return TT_Err_Ok; + } + } + + return TTO_Err_Not_Covered; + } + + + /* The next three functions return a null-terminated list */ + + EXPORT_FUNC + TT_Error TT_GPOS_Query_Scripts( TTO_GPOSHeader* gpos, + TT_ULong** script_tag_list ) + { + UShort n; + TT_Error error; + ULong* stl; + + TTO_ScriptList* sl; + TTO_ScriptRecord* sr; + + + if ( !gpos || !script_tag_list ) + return TT_Err_Invalid_Argument; + + sl = &gpos->ScriptList; + sr = sl->ScriptRecord; + + if ( ALLOC_ARRAY( stl, sl->ScriptCount + 1, ULong ) ) + return error; + + for ( n = 0; n < sl->ScriptCount; n++ ) + stl[n] = sr[n].ScriptTag; + stl[n] = 0; + + *script_tag_list = stl; + + return TT_Err_Ok; + } + + + EXPORT_FUNC + TT_Error TT_GPOS_Query_Languages( TTO_GPOSHeader* gpos, + TT_UShort script_index, + TT_ULong** language_tag_list ) + { + UShort n; + TT_Error error; + ULong* ltl; + + TTO_ScriptList* sl; + TTO_ScriptRecord* sr; + TTO_Script* s; + TTO_LangSysRecord* lsr; + + + if ( !gpos || !language_tag_list ) + return TT_Err_Invalid_Argument; + + sl = &gpos->ScriptList; + sr = sl->ScriptRecord; + + if ( script_index >= sl->ScriptCount ) + return TT_Err_Invalid_Argument; + + s = &sr[script_index].Script; + lsr = s->LangSysRecord; + + if ( ALLOC_ARRAY( ltl, s->LangSysCount + 1, ULong ) ) + return error; + + for ( n = 0; n < s->LangSysCount; n++ ) + ltl[n] = lsr[n].LangSysTag; + ltl[n] = 0; + + *language_tag_list = ltl; + + return TT_Err_Ok; + } + + + /* selecting 0xFFFF for language_index asks for the values of the + default language (DefaultLangSys) */ + + EXPORT_FUNC + TT_Error TT_GPOS_Query_Features( TTO_GPOSHeader* gpos, + TT_UShort script_index, + TT_UShort language_index, + TT_ULong** feature_tag_list ) + { + UShort n; + TT_Error error; + ULong* ftl; + + TTO_ScriptList* sl; + TTO_ScriptRecord* sr; + TTO_Script* s; + TTO_LangSysRecord* lsr; + TTO_LangSys* ls; + UShort* fi; + + TTO_FeatureList* fl; + TTO_FeatureRecord* fr; + + + if ( !gpos || !feature_tag_list ) + return TT_Err_Invalid_Argument; + + sl = &gpos->ScriptList; + sr = sl->ScriptRecord; + + fl = &gpos->FeatureList; + fr = fl->FeatureRecord; + + if ( script_index >= sl->ScriptCount ) + return TT_Err_Invalid_Argument; + + s = &sr[script_index].Script; + lsr = s->LangSysRecord; + + if ( language_index == 0xFFFF ) + ls = &s->DefaultLangSys; + else + { + if ( language_index >= s->LangSysCount ) + return TT_Err_Invalid_Argument; + + ls = &lsr[language_index].LangSys; + } + + fi = ls->FeatureIndex; + + if ( ALLOC_ARRAY( ftl, ls->FeatureCount + 1, ULong ) ) + return error; + + for ( n = 0; n < ls->FeatureCount; n++ ) + { + if ( fi[n] >= fl->FeatureCount ) + { + FREE( ftl ); + return TTO_Err_Invalid_GPOS_SubTable_Format; + } + ftl[n] = fr[fi[n]].FeatureTag; + } + ftl[n] = 0; + + *feature_tag_list = ftl; + + return TT_Err_Ok; + } + + + EXPORT_FUNC + TT_Error TT_GPOS_Add_Feature( TTO_GPOSHeader* gpos, + TT_UShort feature_index, + TT_UShort property ) + { + UShort i; + + TTO_Feature feature; + UShort* properties; + UShort* index; + + + if ( !gpos || + feature_index >= gpos->FeatureList.FeatureCount ) + return TT_Err_Invalid_Argument; + + properties = gpos->LookupList.Properties; + + feature = gpos->FeatureList.FeatureRecord[feature_index].Feature; + index = feature.LookupListIndex; + + for ( i = 0; i < feature.LookupListCount; i++ ) + properties[index[i]] |= property; + + return TT_Err_Ok; + } + + + EXPORT_FUNC + TT_Error TT_GPOS_Clear_Features( TTO_GPOSHeader* gpos ) + { + UShort i; + + UShort* properties; + + + if ( !gpos ) + return TT_Err_Invalid_Argument; + + properties = gpos->LookupList.Properties; + + for ( i = 0; i < gpos->LookupList.LookupCount; i++ ) + properties[i] = 0; + + return TT_Err_Ok; + } + + +/* END */ diff --git a/lib/extend/ftxgpos.h b/lib/extend/ftxgpos.h new file mode 100644 index 0000000..d289c88 --- /dev/null +++ b/lib/extend/ftxgpos.h @@ -0,0 +1,767 @@ +/******************************************************************* + * + * ftxgpos.h + * + * TrueType Open GPOS table support + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef FTXOPEN_H +#error "Don't include this file! Use ftxopen.h instead." +#endif + +#ifndef FTXGPOS_H +#define FTXGPOS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define TTO_Err_Invalid_GPOS_SubTable_Format 0x1020 +#define TTO_Err_Invalid_GPOS_SubTable 0x1021 + + +/* Lookup types for glyph positioning */ + +#define GPOS_LOOKUP_SINGLE 1 +#define GPOS_LOOKUP_PAIR 2 +#define GPOS_LOOKUP_CURSIVE 3 +#define GPOS_LOOKUP_MARKBASE 4 +#define GPOS_LOOKUP_MARKLIG 5 +#define GPOS_LOOKUP_MARKMARK 6 +#define GPOS_LOOKUP_CONTEXT 7 +#define GPOS_LOOKUP_CHAIN 8 + + + struct TTO_GPOSHeader_ + { + TT_Bool loaded; + TT_ULong offset; + + TT_Fixed Version; + + TTO_ScriptList ScriptList; + TTO_FeatureList FeatureList; + TTO_LookupList LookupList; + + TTO_GDEFHeader* gdef; + }; + + typedef struct TTO_GPOSHeader_ TTO_GPOSHeader; + + + /* shared tables */ + + struct TTO_ValueRecord_ + { + TT_Short XPlacement; /* horizontal adjustment for + placement */ + TT_Short YPlacement; /* vertical adjustment for + placement */ + TT_Short XAdvance; /* horizontal adjustment for + advance */ + TT_Short YAdvance; /* vertical adjustment for + advance */ + TTO_Device XPlacementDevice; /* device table for horizontal + placement */ + TTO_Device YPlacementDevice; /* device table for vertical + placement */ + TTO_Device XAdvanceDevice; /* device table for horizontal + advance */ + TTO_Device YAdvanceDevice; /* device table for vertical + advance */ + TT_UShort XIdPlacement; /* horizontal placement metric ID */ + TT_UShort YIdPlacement; /* vertical placement metric ID */ + TT_UShort XIdAdvance; /* horizontal advance metric ID */ + TT_UShort YIdAdvance; /* vertical advance metric ID */ + }; + + typedef struct TTO_ValueRecord_ TTO_ValueRecord; + + +/* Mask values to scan the value format of the ValueRecord structure. + We always expand compressed ValueRecords of the font. */ + +#define HAVE_X_PLACEMENT 0x0001 +#define HAVE_Y_PLACEMENT 0x0002 +#define HAVE_X_ADVANCE 0x0004 +#define HAVE_Y_ADVANCE 0x0008 +#define HAVE_X_PLACEMENT_DEVICE 0x0010 +#define HAVE_Y_PLACEMENT_DEVICE 0x0020 +#define HAVE_X_ADVANCE_DEVICE 0x0040 +#define HAVE_Y_ADVANCE_DEVICE 0x0080 +#define HAVE_X_ID_PLACEMENT 0x0100 +#define HAVE_Y_ID_PLACEMENT 0x0200 +#define HAVE_X_ID_ADVANCE 0x0400 +#define HAVE_Y_ID_ADVANCE 0x0800 + + + struct TTO_AnchorFormat1_ + { + TT_Short XCoordinate; /* horizontal value */ + TT_Short YCoordinate; /* vertical value */ + }; + + typedef struct TTO_AnchorFormat1_ TTO_AnchorFormat1; + + + struct TTO_AnchorFormat2_ + { + TT_Short XCoordinate; /* horizontal value */ + TT_Short YCoordinate; /* vertical value */ + TT_UShort AnchorPoint; /* index to glyph contour point */ + }; + + typedef struct TTO_AnchorFormat2_ TTO_AnchorFormat2; + + + struct TTO_AnchorFormat3_ + { + TT_Short XCoordinate; /* horizontal value */ + TT_Short YCoordinate; /* vertical value */ + TTO_Device XDeviceTable; /* device table for X coordinate */ + TTO_Device YDeviceTable; /* device table for Y coordinate */ + }; + + typedef struct TTO_AnchorFormat3_ TTO_AnchorFormat3; + + + struct TTO_AnchorFormat4_ + { + TT_UShort XIdAnchor; /* horizontal metric ID */ + TT_UShort YIdAnchor; /* vertical metric ID */ + }; + + typedef struct TTO_AnchorFormat4_ TTO_AnchorFormat4; + + + struct TTO_Anchor_ + { + TT_UShort PosFormat; /* 1, 2, 3, or 4 -- 0 indicates + that there is no Anchor table */ + + union + { + TTO_AnchorFormat1 af1; + TTO_AnchorFormat2 af2; + TTO_AnchorFormat3 af3; + TTO_AnchorFormat4 af4; + } af; + }; + + typedef struct TTO_Anchor_ TTO_Anchor; + + + struct TTO_MarkRecord_ + { + TT_UShort Class; /* mark class */ + TTO_Anchor MarkAnchor; /* anchor table */ + }; + + typedef struct TTO_MarkRecord_ TTO_MarkRecord; + + + struct TTO_MarkArray_ + { + TT_UShort MarkCount; /* number of MarkRecord tables */ + TTO_MarkRecord* MarkRecord; /* array of MarkRecord tables */ + }; + + typedef struct TTO_MarkArray_ TTO_MarkArray; + + + /* LookupType 1 */ + + struct TTO_SinglePosFormat1_ + { + TTO_ValueRecord Value; /* ValueRecord for all covered + glyphs */ + }; + + typedef struct TTO_SinglePosFormat1_ TTO_SinglePosFormat1; + + + struct TTO_SinglePosFormat2_ + { + TT_UShort ValueCount; /* number of ValueRecord tables */ + TTO_ValueRecord* Value; /* array of ValueRecord tables */ + }; + + typedef struct TTO_SinglePosFormat2_ TTO_SinglePosFormat2; + + + struct TTO_SinglePos_ + { + TT_UShort PosFormat; /* 1 or 2 */ + TTO_Coverage Coverage; /* Coverage table */ + + TT_UShort ValueFormat; /* format of ValueRecord table */ + + union + { + TTO_SinglePosFormat1 spf1; + TTO_SinglePosFormat2 spf2; + } spf; + }; + + typedef struct TTO_SinglePos_ TTO_SinglePos; + + + /* LookupType 2 */ + + struct TTO_PairValueRecord_ + { + TT_UShort SecondGlyph; /* glyph ID for second glyph */ + TTO_ValueRecord Value1; /* pos. data for first glyph */ + TTO_ValueRecord Value2; /* pos. data for second glyph */ + }; + + typedef struct TTO_PairValueRecord_ TTO_PairValueRecord; + + + struct TTO_PairSet_ + { + TT_UShort PairValueCount; + /* number of PairValueRecord tables */ + TTO_PairValueRecord* PairValueRecord; + /* array of PairValueRecord tables */ + }; + + typedef struct TTO_PairSet_ TTO_PairSet; + + + struct TTO_PairPosFormat1_ + { + TT_UShort PairSetCount; /* number of PairSet tables */ + TTO_PairSet* PairSet; /* array of PairSet tables */ + }; + + typedef struct TTO_PairPosFormat1_ TTO_PairPosFormat1; + + + struct TTO_Class2Record_ + { + TTO_ValueRecord Value1; /* pos. data for first glyph */ + TTO_ValueRecord Value2; /* pos. data for second glyph */ + }; + + typedef struct TTO_Class2Record_ TTO_Class2Record; + + + struct TTO_Class1Record_ + { + TTO_Class2Record* Class2Record; /* array of Class2Record tables */ + }; + + typedef struct TTO_Class1Record_ TTO_Class1Record; + + + struct TTO_PairPosFormat2_ + { + TTO_ClassDefinition ClassDef1; /* class def. for first glyph */ + TTO_ClassDefinition ClassDef2; /* class def. for second glyph */ + TT_UShort Class1Count; /* number of classes in ClassDef1 + table */ + TT_UShort Class2Count; /* number of classes in ClassDef2 + table */ + TTO_Class1Record* Class1Record; /* array of Class1Record tables */ + }; + + typedef struct TTO_PairPosFormat2_ TTO_PairPosFormat2; + + + struct TTO_PairPos_ + { + TT_UShort PosFormat; /* 1 or 2 */ + TTO_Coverage Coverage; /* Coverage table */ + TT_UShort ValueFormat1; /* format of ValueRecord table + for first glyph */ + TT_UShort ValueFormat2; /* format of ValueRecord table + for second glyph */ + + union + { + TTO_PairPosFormat1 ppf1; + TTO_PairPosFormat2 ppf2; + } ppf; + }; + + typedef struct TTO_PairPos_ TTO_PairPos; + + + /* LookupType 3 */ + + struct TTO_EntryExitRecord_ + { + TTO_Anchor EntryAnchor; /* entry Anchor table */ + TTO_Anchor ExitAnchor; /* exit Anchor table */ + }; + + + typedef struct TTO_EntryExitRecord_ TTO_EntryExitRecord; + + struct TTO_CursivePos_ + { + TT_UShort PosFormat; /* always 1 */ + TTO_Coverage Coverage; /* Coverage table */ + TT_UShort EntryExitCount; + /* number of EntryExitRecord tables */ + TTO_EntryExitRecord* EntryExitRecord; + /* array of EntryExitRecord tables */ + }; + + typedef struct TTO_CursivePos_ TTO_CursivePos; + + + /* LookupType 4 */ + + struct TTO_BaseRecord_ + { + TTO_Anchor* BaseAnchor; /* array of base glyph anchor + tables */ + }; + + typedef struct TTO_BaseRecord_ TTO_BaseRecord; + + + struct TTO_BaseArray_ + { + TT_UShort BaseCount; /* number of BaseRecord tables */ + TTO_BaseRecord* BaseRecord; /* array of BaseRecord tables */ + }; + + typedef struct TTO_BaseArray_ TTO_BaseArray; + + + struct TTO_MarkBasePos_ + { + TT_UShort PosFormat; /* always 1 */ + TTO_Coverage MarkCoverage; /* mark glyph coverage table */ + TTO_Coverage BaseCoverage; /* base glyph coverage table */ + TT_UShort ClassCount; /* number of mark classes */ + TTO_MarkArray MarkArray; /* mark array table */ + TTO_BaseArray BaseArray; /* base array table */ + }; + + typedef struct TTO_MarkBasePos_ TTO_MarkBasePos; + + + /* LookupType 5 */ + + struct TTO_ComponentRecord_ + { + TTO_Anchor* LigatureAnchor; /* array of ligature glyph anchor + tables */ + }; + + typedef struct TTO_ComponentRecord_ TTO_ComponentRecord; + + + struct TTO_LigatureAttach_ + { + TT_UShort ComponentCount; + /* number of ComponentRecord tables */ + TTO_ComponentRecord* ComponentRecord; + /* array of ComponentRecord tables */ + }; + + typedef struct TTO_LigatureAttach_ TTO_LigatureAttach; + + + struct TTO_LigatureArray_ + { + TT_UShort LigatureCount; /* number of LigatureAttach tables */ + TTO_LigatureAttach* LigatureAttach; + /* array of LigatureAttach tables */ + }; + + typedef struct TTO_LigatureArray_ TTO_LigatureArray; + + + struct TTO_MarkLigPos_ + { + TT_UShort PosFormat; /* always 1 */ + TTO_Coverage MarkCoverage; /* mark glyph coverage table */ + TTO_Coverage LigatureCoverage; + /* ligature glyph coverage table */ + TT_UShort ClassCount; /* number of mark classes */ + TTO_MarkArray MarkArray; /* mark array table */ + TTO_LigatureArray LigatureArray; /* ligature array table */ + }; + + typedef struct TTO_MarkLigPos_ TTO_MarkLigPos; + + + /* LookupType 6 */ + + struct TTO_Mark2Record_ + { + TTO_Anchor* Mark2Anchor; /* array of mark glyph anchor + tables */ + }; + + typedef struct TTO_Mark2Record_ TTO_Mark2Record; + + + struct TTO_Mark2Array_ + { + TT_UShort Mark2Count; /* number of Mark2Record tables */ + TTO_Mark2Record* Mark2Record; /* array of Mark2Record tables */ + }; + + typedef struct TTO_Mark2Array_ TTO_Mark2Array; + + + struct TTO_MarkMarkPos_ + { + TT_UShort PosFormat; /* always 1 */ + TTO_Coverage Mark1Coverage; /* first mark glyph coverage table */ + TTO_Coverage Mark2Coverage; /* second mark glyph coverave table */ + TT_UShort ClassCount; /* number of combining mark classes */ + TTO_MarkArray Mark1Array; /* MarkArray table for first mark */ + TTO_Mark2Array Mark2Array; /* MarkArray table for second mark */ + }; + + typedef struct TTO_MarkMarkPos_ TTO_MarkMarkPos; + + + /* needed by both lookup type 7 and 8 */ + + struct TTO_PosLookupRecord_ + { + TT_UShort SequenceIndex; /* index into current + glyph sequence */ + TT_UShort LookupListIndex; /* Lookup to apply to that pos. */ + }; + + typedef struct TTO_PosLookupRecord_ TTO_PosLookupRecord; + + + /* LookupType 7 */ + + struct TTO_PosRule_ + { + TT_UShort GlyphCount; /* total number of input glyphs */ + TT_UShort PosCount; /* number of PosLookupRecord tables */ + TT_UShort* Input; /* array of input glyph IDs */ + TTO_PosLookupRecord* PosLookupRecord; + /* array of PosLookupRecord tables */ + }; + + typedef struct TTO_PosRule_ TTO_PosRule; + + + struct TTO_PosRuleSet_ + { + TT_UShort PosRuleCount; /* number of PosRule tables */ + TTO_PosRule* PosRule; /* array of PosRule tables */ + }; + + typedef struct TTO_PosRuleSet_ TTO_PosRuleSet; + + + struct TTO_ContextPosFormat1_ + { + TTO_Coverage Coverage; /* Coverage table */ + TT_UShort PosRuleSetCount; /* number of PosRuleSet tables */ + TTO_PosRuleSet* PosRuleSet; /* array of PosRuleSet tables */ + }; + + typedef struct TTO_ContextPosFormat1_ TTO_ContextPosFormat1; + + + struct TTO_PosClassRule_ + { + TT_UShort GlyphCount; /* total number of context classes */ + TT_UShort PosCount; /* number of PosLookupRecord tables */ + TT_UShort* Class; /* array of classes */ + TTO_PosLookupRecord* PosLookupRecord; + /* array of PosLookupRecord tables */ + }; + + typedef struct TTO_PosClassRule_ TTO_PosClassRule; + + + struct TTO_PosClassSet_ + { + TT_UShort PosClassRuleCount; + /* number of PosClassRule tables */ + TTO_PosClassRule* PosClassRule; /* array of PosClassRule tables */ + }; + + typedef struct TTO_PosClassSet_ TTO_PosClassSet; + + + /* The `MaxContextLength' field is not defined in the TTO specification + but simplifies the implementation of this format. It holds the + maximal context length used in the context rules. */ + + struct TTO_ContextPosFormat2_ + { + TT_UShort MaxContextLength; + /* maximal context length */ + TTO_Coverage Coverage; /* Coverage table */ + TTO_ClassDefinition ClassDef; /* ClassDef table */ + TT_UShort PosClassSetCount; + /* number of PosClassSet tables */ + TTO_PosClassSet* PosClassSet; /* array of PosClassSet tables */ + }; + + typedef struct TTO_ContextPosFormat2_ TTO_ContextPosFormat2; + + + struct TTO_ContextPosFormat3_ + { + TT_UShort GlyphCount; /* number of input glyphs */ + TT_UShort PosCount; /* number of PosLookupRecord tables */ + TTO_Coverage* Coverage; /* array of Coverage tables */ + TTO_PosLookupRecord* PosLookupRecord; + /* array of PosLookupRecord tables */ + }; + + typedef struct TTO_ContextPosFormat3_ TTO_ContextPosFormat3; + + + struct TTO_ContextPos_ + { + TT_UShort PosFormat; /* 1, 2, or 3 */ + + union + { + TTO_ContextPosFormat1 cpf1; + TTO_ContextPosFormat2 cpf2; + TTO_ContextPosFormat3 cpf3; + } cpf; + }; + + typedef struct TTO_ContextPos_ TTO_ContextPos; + + + /* LookupType 8 */ + + struct TTO_ChainPosRule_ + { + TT_UShort BacktrackGlyphCount; + /* total number of backtrack glyphs */ + TT_UShort* Backtrack; /* array of backtrack glyph IDs */ + TT_UShort InputGlyphCount; + /* total number of input glyphs */ + TT_UShort* Input; /* array of input glyph IDs */ + TT_UShort LookaheadGlyphCount; + /* total number of lookahead glyphs */ + TT_UShort* Lookahead; /* array of lookahead glyph IDs */ + TT_UShort PosCount; /* number of PosLookupRecords */ + TTO_PosLookupRecord* PosLookupRecord; + /* array of PosLookupRecords */ + }; + + typedef struct TTO_ChainPosRule_ TTO_ChainPosRule; + + + struct TTO_ChainPosRuleSet_ + { + TT_UShort ChainPosRuleCount; + /* number of ChainPosRule tables */ + TTO_ChainPosRule* ChainPosRule; /* array of ChainPosRule tables */ + }; + + typedef struct TTO_ChainPosRuleSet_ TTO_ChainPosRuleSet; + + + struct TTO_ChainContextPosFormat1_ + { + TTO_Coverage Coverage; /* Coverage table */ + TT_UShort ChainPosRuleSetCount; + /* number of ChainPosRuleSet tables */ + TTO_ChainPosRuleSet* ChainPosRuleSet; + /* array of ChainPosRuleSet tables */ + }; + + typedef struct TTO_ChainContextPosFormat1_ TTO_ChainContextPosFormat1; + + + struct TTO_ChainPosClassRule_ + { + TT_UShort BacktrackGlyphCount; + /* total number of backtrack + classes */ + TT_UShort* Backtrack; /* array of backtrack classes */ + TT_UShort InputGlyphCount; + /* total number of context classes */ + TT_UShort* Input; /* array of context classes */ + TT_UShort LookaheadGlyphCount; + /* total number of lookahead + classes */ + TT_UShort* Lookahead; /* array of lookahead classes */ + TT_UShort PosCount; /* number of PosLookupRecords */ + TTO_PosLookupRecord* PosLookupRecord; + /* array of substitution lookups */ + }; + + typedef struct TTO_ChainPosClassRule_ TTO_ChainPosClassRule; + + + struct TTO_ChainPosClassSet_ + { + TT_UShort ChainPosClassRuleCount; + /* number of ChainPosClassRule + tables */ + TTO_ChainPosClassRule* ChainPosClassRule; + /* array of ChainPosClassRule + tables */ + }; + + typedef struct TTO_ChainPosClassSet_ TTO_ChainPosClassSet; + + + /* The `MaxXXXLength' fields are not defined in the TTO specification + but simplifies the implementation of this format. It holds the + maximal context length used in the specific context rules. */ + + struct TTO_ChainContextPosFormat2_ + { + TTO_Coverage Coverage; /* Coverage table */ + + TT_UShort MaxBacktrackLength; + /* maximal backtrack length */ + TTO_ClassDefinition BacktrackClassDef; + /* BacktrackClassDef table */ + TT_UShort MaxInputLength; + /* maximal input length */ + TTO_ClassDefinition InputClassDef; + /* InputClassDef table */ + TT_UShort MaxLookaheadLength; + /* maximal lookahead length */ + TTO_ClassDefinition LookaheadClassDef; + /* LookaheadClassDef table */ + + TT_UShort ChainPosClassSetCount; + /* number of ChainPosClassSet + tables */ + TTO_ChainPosClassSet* ChainPosClassSet; + /* array of ChainPosClassSet + tables */ + }; + + typedef struct TTO_ChainContextPosFormat2_ TTO_ChainContextPosFormat2; + + + struct TTO_ChainContextPosFormat3_ + { + TT_UShort BacktrackGlyphCount; + /* number of backtrack glyphs */ + TTO_Coverage* BacktrackCoverage; + /* array of backtrack Coverage + tables */ + TT_UShort InputGlyphCount; + /* number of input glyphs */ + TTO_Coverage* InputCoverage; + /* array of input coverage + tables */ + TT_UShort LookaheadGlyphCount; + /* number of lookahead glyphs */ + TTO_Coverage* LookaheadCoverage; + /* array of lookahead coverage + tables */ + TT_UShort PosCount; /* number of PosLookupRecords */ + TTO_PosLookupRecord* PosLookupRecord; + /* array of substitution lookups */ + }; + + typedef struct TTO_ChainContextPosFormat3_ TTO_ChainContextPosFormat3; + + + struct TTO_ChainContextPos_ + { + TT_UShort PosFormat; /* 1, 2, or 3 */ + + union + { + TTO_ChainContextPosFormat1 ccpf1; + TTO_ChainContextPosFormat2 ccpf2; + TTO_ChainContextPosFormat3 ccpf3; + } ccpf; + }; + + typedef struct TTO_ChainContextPos_ TTO_ChainContextPos; + + + union TTO_GPOS_SubTable_ + { + TTO_SinglePos single; + TTO_PairPos pair; + TTO_CursivePos cursive; + TTO_MarkBasePos markbase; + TTO_MarkLigPos marklig; + TTO_MarkMarkPos markmark; + TTO_ContextPos context; + TTO_ChainContextPos chain; + }; + + typedef union TTO_GPOS_SubTable_ TTO_GPOS_SubTable; + + + /* finally, the GPOS API */ + + EXPORT_DEF + TT_Error TT_Init_GPOS_Extension( TT_Engine engine ); + + EXPORT_DEF + TT_Error TT_Load_GPOS_Table( TT_Face face, + TTO_GPOSHeader* gpos, + TTO_GDEFHeader* gdef ); + + EXPORT_DEF + TT_Error TT_GPOS_Select_Script( TTO_GPOSHeader* gpos, + TT_ULong script_tag, + TT_UShort* script_index ); + EXPORT_DEF + TT_Error TT_GPOS_Select_Language( TTO_GPOSHeader* gpos, + TT_ULong language_tag, + TT_UShort script_index, + TT_UShort* language_index, + TT_UShort* req_feature_index ); + EXPORT_DEF + TT_Error TT_GPOS_Select_Feature( TTO_GPOSHeader* gpos, + TT_ULong feature_tag, + TT_UShort script_index, + TT_UShort language_index, + TT_UShort* feature_index ); + + EXPORT_DEF + TT_Error TT_GPOS_Query_Scripts( TTO_GPOSHeader* gpos, + TT_ULong** script_tag_list ); + EXPORT_DEF + TT_Error TT_GPOS_Query_Languages( TTO_GPOSHeader* gpos, + TT_UShort script_index, + TT_ULong** language_tag_list ); + EXPORT_DEF + TT_Error TT_GPOS_Query_Features( TTO_GPOSHeader* gpos, + TT_UShort script_index, + TT_UShort language_index, + TT_ULong** feature_tag_list ); + + EXPORT_DEF + TT_Error TT_GPOS_Add_Feature( TTO_GPOSHeader* gpos, + TT_UShort feature_index, + TT_UShort property ); + EXPORT_DEF + TT_Error TT_GPOS_Clear_Features( TTO_GPOSHeader* gpos ); + +#ifdef __cplusplus +} +#endif + +#endif /* FTXGPOS_H */ + + +/* END */ diff --git a/lib/extend/ftxgsub.c b/lib/extend/ftxgsub.c new file mode 100644 index 0000000..81930c8 --- /dev/null +++ b/lib/extend/ftxgsub.c @@ -0,0 +1,4307 @@ +/******************************************************************* + * + * ftxgsub.c + * + * TrueType Open GSUB table support. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +/* XXX There is *a lot* of duplicated code (cf. formats 5 and 6), but + I don't care currently. I believe that it would be possible to + save about 50% of TTO code by carefully designing the structures, + sharing as much as possible with extensive use of macros. This + is something for a volunteer :-) */ + +#include "tttypes.h" +#include "tttags.h" +#include "ttload.h" +#include "ttextend.h" +#include "ttmemory.h" +#include "ttfile.h" + +#include "ftxopen.h" +#include "ftxopenf.h" + + +#define GSUB_ID Build_Extension_ID( 'G', 'S', 'U', 'B' ) + + +#define ADD_String( in, num_in, out, num_out, data ) \ + ( ( error = TT_GSUB_Add_String( (in), (num_in), \ + (out), (num_out), \ + (data) ) ) != TT_Err_Ok ) + +#define CHECK_Property( gdef, index, flags, property ) \ + ( ( error = Check_Property( (gdef), (index), (flags), \ + (property) ) ) != TT_Err_Ok ) + + + static TT_Error Do_Glyph_Lookup( TTO_GSUBHeader* gsub, + UShort lookup_index, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort context_length, + int nesting_level ); + + + + /********************** + * Auxiliary functions + **********************/ + + + /* The following function copies `num_out' elements from `data' to + `out', advancing the array pointer in the `in' structure by `num_in' + elements and in `out' by `num_out' elements. If the string (resp. + the properties) array in `out' is empty or too small, it allocates + resp. reallocates the string (and properties) array. Finally, it + sets the `length' field of `out' equal to `pos' of the `out' + structure. + + The properties (if defined) for all replaced glyphs are taken from + the glyph at position `in->pos'. */ + + EXPORT_FUNC + TT_Error TT_GSUB_Add_String( TTO_GSUB_String* in, + UShort num_in, + TTO_GSUB_String* out, + UShort num_out, + UShort* data ) + { + TT_Error error; + UShort i; + UShort p_in; + UShort* p_out; + + + /* sanity check */ + + if ( !in || !out || + in->length == 0 || in->pos >= in->length || + in->length < in->pos + num_in ) + return TT_Err_Invalid_Argument; + + if ( out->pos + num_out >= out->allocated ) + { + ULong size = out->pos + num_out + 256L; + + + /* The following works because all fields in `out' must be + initialized to zero (including the `string' field) for the + first use. */ + + if ( REALLOC( out->string, size * sizeof ( UShort ) ) ) + return error; + if ( in->properties ) + if ( REALLOC( out->properties, size * sizeof ( UShort ) ) ) + return error; + out->allocated = size; + } + + if ( num_out ) + { + MEM_Copy( &out->string[out->pos], data, num_out * sizeof ( UShort ) ); + if ( in->properties ) + { + p_in = in->properties[in->pos]; + p_out = out->properties; + + for ( i = out->pos; i < out->pos + num_out; i++ ) + p_out[i] = p_in; + } + } + + in->pos += num_in; + out->pos += num_out; + + out->length = out->pos; + + return TT_Err_Ok; + } + + + static TT_Error Check_Property( TTO_GDEFHeader* gdef, + UShort index, + UShort flags, + UShort* property ) + { + TT_Error error; + + + if ( gdef ) + { + error = TT_GDEF_Get_Glyph_Property( gdef, index, property ); + if ( error ) + return error; + + /* This is OpenType 1.2 */ + + if ( flags & IGNORE_SPECIAL_MARKS ) + if ( (flags & 0xFF00) != *property ) + return TTO_Err_Not_Covered; + + if ( flags & *property ) + return TTO_Err_Not_Covered; + } + + return TT_Err_Ok; + } + + + + /********************** + * Extension Functions + **********************/ + + + static TT_Error GSUB_Create( void* ext, + PFace face ) + { + DEFINE_LOAD_LOCALS( face->stream ); + + TTO_GSUBHeader* gsub = (TTO_GSUBHeader*)ext; + Long table; + + + /* by convention */ + + if ( !gsub ) + return TT_Err_Ok; + + /* a null offset indicates that there is no GSUB table */ + + gsub->offset = 0; + + /* we store the start offset and the size of the subtable */ + + table = TT_LookUp_Table( face, TTAG_GSUB ); + if ( table < 0 ) + return TT_Err_Ok; /* The table is optional */ + + if ( FILE_Seek( face->dirTables[table].Offset ) || + ACCESS_Frame( 4L ) ) + return error; + + gsub->offset = FILE_Pos() - 4L; /* undo ACCESS_Frame() */ + gsub->Version = GET_ULong(); + + FORGET_Frame(); + + gsub->loaded = FALSE; + + return TT_Err_Ok; + } + + + static TT_Error GSUB_Destroy( void* ext, + PFace face ) + { + TTO_GSUBHeader* gsub = (TTO_GSUBHeader*)ext; + + + /* by convention */ + + if ( !gsub ) + return TT_Err_Ok; + + if ( gsub->loaded ) + { + Free_LookupList( &gsub->LookupList, GSUB ); + Free_FeatureList( &gsub->FeatureList ); + Free_ScriptList( &gsub->ScriptList ); + } + + return TT_Err_Ok; + } + + + EXPORT_FUNC + TT_Error TT_Init_GSUB_Extension( TT_Engine engine ) + { + PEngine_Instance _engine = HANDLE_Engine( engine ); + + + if ( !_engine ) + return TT_Err_Invalid_Engine; + + return TT_Register_Extension( _engine, + GSUB_ID, + sizeof ( TTO_GSUBHeader ), + GSUB_Create, + GSUB_Destroy ); + } + + + EXPORT_FUNC + TT_Error TT_Load_GSUB_Table( TT_Face face, + TTO_GSUBHeader* retptr, + TTO_GDEFHeader* gdef ) + { + ULong cur_offset, new_offset, base_offset; + + TT_UShort i, num_lookups; + TT_Error error; + TT_Stream stream; + TTO_GSUBHeader* gsub; + TTO_Lookup* lo; + + PFace faze = HANDLE_Face( face ); + + + if ( !retptr ) + return TT_Err_Invalid_Argument; + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + error = TT_Extension_Get( faze, GSUB_ID, (void**)&gsub ); + if ( error ) + return error; + + if ( gsub->offset == 0 ) + return TT_Err_Table_Missing; /* no GSUB table; nothing to do */ + + /* now access stream */ + + if ( USE_Stream( faze->stream, stream ) ) + return error; + + base_offset = gsub->offset; + + /* skip version */ + + if ( FILE_Seek( base_offset + 4L ) || + ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ScriptList( &gsub->ScriptList, + faze ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_FeatureList( &gsub->FeatureList, + faze ) ) != TT_Err_Ok ) + goto Fail3; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_LookupList( &gsub->LookupList, + faze, GSUB ) ) != TT_Err_Ok ) + goto Fail2; + + gsub->gdef = gdef; /* can be NULL */ + + /* We now check the LookupFlags for values larger than 0xFF to find + out whether we need to load the `MarkAttachClassDef' field of the + GDEF table -- this hack is necessary for OpenType 1.2 tables since + the version field of the GDEF table hasn't been incremented. + + For constructed GDEF tables, we only load it if + `MarkAttachClassDef_offset' is not zero (nevertheless, a build of + a constructed mark attach table is not supported currently). */ + + if ( gdef && + gdef->MarkAttachClassDef_offset && !gdef->MarkAttachClassDef.loaded ) + { + lo = gsub->LookupList.Lookup; + num_lookups = gsub->LookupList.LookupCount; + + for ( i = 0; i < num_lookups; i++ ) + { + if ( lo[i].LookupFlag & IGNORE_SPECIAL_MARKS ) + { + if ( FILE_Seek( gdef->MarkAttachClassDef_offset ) || + ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort(); + + FORGET_Frame(); + + if ( !new_offset ) + return TTO_Err_Invalid_GDEF_SubTable; + + new_offset += base_offset; + + if ( FILE_Seek( new_offset ) || + ( error = Load_ClassDefinition( &gdef->MarkAttachClassDef, + 256, faze ) ) != TT_Err_Ok ) + goto Fail1; + + break; + } + } + } + + gsub->loaded = TRUE; + *retptr = *gsub; + DONE_Stream( stream ); + + return TT_Err_Ok; + + Fail1: + Free_LookupList( &gsub->LookupList, GSUB ); + + Fail2: + Free_FeatureList( &gsub->FeatureList ); + + Fail3: + Free_ScriptList( &gsub->ScriptList ); + + /* release stream */ + + DONE_Stream( stream ); + + return error; + } + + + + /***************************** + * SubTable related functions + *****************************/ + + + /* LookupType 1 */ + + /* SingleSubstFormat1 */ + /* SingleSubstFormat2 */ + + TT_Error Load_SingleSubst( TTO_SingleSubst* ss, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + UShort* s; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 4L ) ) + return error; + + ss->SubstFormat = GET_UShort(); + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &ss->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + switch ( ss->SubstFormat ) + { + case 1: + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + ss->ssf.ssf1.DeltaGlyphID = GET_UShort(); + + FORGET_Frame(); + + break; + + case 2: + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = ss->ssf.ssf2.GlyphCount = GET_UShort(); + + FORGET_Frame(); + + ss->ssf.ssf2.Substitute = NULL; + + if ( ALLOC_ARRAY( ss->ssf.ssf2.Substitute, count, UShort ) ) + goto Fail2; + + s = ss->ssf.ssf2.Substitute; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + s[n] = GET_UShort(); + + FORGET_Frame(); + + break; + + default: + return TTO_Err_Invalid_GSUB_SubTable_Format; + } + + return TT_Err_Ok; + + Fail1: + FREE( s ); + + Fail2: + Free_Coverage( &ss->Coverage ); + return error; + } + + + void Free_SingleSubst( TTO_SingleSubst* ss ) + { + switch ( ss->SubstFormat ) + { + case 1: + break; + + case 2: + FREE( ss->ssf.ssf2.Substitute ); + break; + } + + Free_Coverage( &ss->Coverage ); + } + + + static TT_Error Lookup_SingleSubst( TTO_SingleSubst* ss, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort flags, + UShort context_length, + TTO_GDEFHeader* gdef ) + { + UShort index, value[1], property; + TT_Error error; + + + if ( context_length != 0xFFFF && context_length < 1 ) + return TTO_Err_Not_Covered; + + if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) ) + return error; + + error = Coverage_Index( &ss->Coverage, in->string[in->pos], &index ); + if ( error ) + return error; + + switch ( ss->SubstFormat ) + { + case 1: + value[0] = ( in->string[in->pos] + ss->ssf.ssf1.DeltaGlyphID ) & 0xFFFF; + if ( ADD_String( in, 1, out, 1, value ) ) + return error; + break; + + case 2: + if ( index >= ss->ssf.ssf2.GlyphCount ) + return TTO_Err_Invalid_GSUB_SubTable; + value[0] = ss->ssf.ssf2.Substitute[index]; + if ( ADD_String( in, 1, out, 1, value ) ) + return error; + break; + + default: + return TTO_Err_Invalid_GSUB_SubTable; + } + + if ( gdef && gdef->NewGlyphClasses ) + { + /* we inherit the old glyph class to the substituted glyph */ + + error = Add_Glyph_Property( gdef, value[0], property ); + if ( error && error != TTO_Err_Not_Covered ) + return error; + } + + return TT_Err_Ok; + } + + + /* LookupType 2 */ + + /* Sequence */ + + static TT_Error Load_Sequence( TTO_Sequence* s, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + UShort* sub; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = s->GlyphCount = GET_UShort(); + + FORGET_Frame(); + + s->Substitute = NULL; + + if ( count ) + { + if ( ALLOC_ARRAY( s->Substitute, count, UShort ) ) + return error; + + sub = s->Substitute; + + if ( ACCESS_Frame( count * 2L ) ) + { + FREE( sub ); + return error; + } + + for ( n = 0; n < count; n++ ) + sub[n] = GET_UShort(); + + FORGET_Frame(); + } + + return TT_Err_Ok; + } + + + static void Free_Sequence( TTO_Sequence* s ) + { + FREE( s->Substitute ); + } + + + /* MultipleSubstFormat1 */ + + TT_Error Load_MultipleSubst( TTO_MultipleSubst* ms, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_Sequence* s; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 4L ) ) + return error; + + ms->SubstFormat = GET_UShort(); /* should be 1 */ + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &ms->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = ms->SequenceCount = GET_UShort(); + + FORGET_Frame(); + + ms->Sequence = NULL; + + if ( ALLOC_ARRAY( ms->Sequence, count, TTO_Sequence ) ) + goto Fail2; + + s = ms->Sequence; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Sequence( &s[n], input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_Sequence( &s[n] ); + + FREE( s ); + + Fail2: + Free_Coverage( &ms->Coverage ); + return error; + } + + + void Free_MultipleSubst( TTO_MultipleSubst* ms ) + { + UShort n, count; + + TTO_Sequence* s; + + + if ( ms->Sequence ) + { + count = ms->SequenceCount; + s = ms->Sequence; + + for ( n = 0; n < count; n++ ) + Free_Sequence( &s[n] ); + + FREE( s ); + } + + Free_Coverage( &ms->Coverage ); + } + + + static TT_Error Lookup_MultipleSubst( TTO_MultipleSubst* ms, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort flags, + UShort context_length, + TTO_GDEFHeader* gdef ) + { + TT_Error error; + UShort index, property, n, count; + UShort* s; + + + if ( context_length != 0xFFFF && context_length < 1 ) + return TTO_Err_Not_Covered; + + if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) ) + return error; + + error = Coverage_Index( &ms->Coverage, in->string[in->pos], &index ); + if ( error ) + return error; + + if ( index >= ms->SequenceCount ) + return TTO_Err_Invalid_GSUB_SubTable; + + count = ms->Sequence[index].GlyphCount; + s = ms->Sequence[index].Substitute; + + if ( ADD_String( in, 1, out, count, s ) ) + return error; + + if ( gdef && gdef->NewGlyphClasses ) + { + /* this is a guess only ... */ + + if ( property == TTO_LIGATURE ) + property = TTO_BASE_GLYPH; + + for ( n = 0; n < count; n++ ) + { + error = Add_Glyph_Property( gdef, s[n], property ); + if ( error && error != TTO_Err_Not_Covered ) + return error; + } + } + + return TT_Err_Ok; + } + + + /* LookupType 3 */ + + /* AlternateSet */ + + static TT_Error Load_AlternateSet( TTO_AlternateSet* as, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + UShort* a; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = as->GlyphCount = GET_UShort(); + + FORGET_Frame(); + + as->Alternate = NULL; + + if ( ALLOC_ARRAY( as->Alternate, count, UShort ) ) + return error; + + a = as->Alternate; + + if ( ACCESS_Frame( count * 2L ) ) + { + FREE( a ); + return error; + } + + for ( n = 0; n < count; n++ ) + a[n] = GET_UShort(); + + FORGET_Frame(); + + return TT_Err_Ok; + } + + + static void Free_AlternateSet( TTO_AlternateSet* as ) + { + FREE( as->Alternate ); + } + + + /* AlternateSubstFormat1 */ + + TT_Error Load_AlternateSubst( TTO_AlternateSubst* as, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_AlternateSet* aset; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 4L ) ) + return error; + + as->SubstFormat = GET_UShort(); /* should be 1 */ + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &as->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = as->AlternateSetCount = GET_UShort(); + + FORGET_Frame(); + + as->AlternateSet = NULL; + + if ( ALLOC_ARRAY( as->AlternateSet, count, TTO_AlternateSet ) ) + goto Fail2; + + aset = as->AlternateSet; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_AlternateSet( &aset[n], input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_AlternateSet( &aset[n] ); + + FREE( aset ); + + Fail2: + Free_Coverage( &as->Coverage ); + return error; + } + + + void Free_AlternateSubst( TTO_AlternateSubst* as ) + { + UShort n, count; + + TTO_AlternateSet* aset; + + + if ( as->AlternateSet ) + { + count = as->AlternateSetCount; + aset = as->AlternateSet; + + for ( n = 0; n < count; n++ ) + Free_AlternateSet( &aset[n] ); + + FREE( aset ); + } + + Free_Coverage( &as->Coverage ); + } + + + static TT_Error Lookup_AlternateSubst( TTO_GSUBHeader* gsub, + TTO_AlternateSubst* as, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort flags, + UShort context_length, + TTO_GDEFHeader* gdef ) + { + TT_Error error; + UShort index, alt_index, property; + + TTO_AlternateSet aset; + + + if ( context_length != 0xFFFF && context_length < 1 ) + return TTO_Err_Not_Covered; + + if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) ) + return error; + + error = Coverage_Index( &as->Coverage, in->string[in->pos], &index ); + if ( error ) + return error; + + aset = as->AlternateSet[index]; + + /* we use a user-defined callback function to get the alternate index */ + + if ( gsub->alt ) + alt_index = (gsub->alt)( out->pos, in->string[in->pos], + aset.GlyphCount, aset.Alternate, + gsub->data ); + else + alt_index = 0; + + if ( ADD_String( in, 1, out, 1, &aset.Alternate[alt_index] ) ) + return error; + + if ( gdef && gdef->NewGlyphClasses ) + { + /* we inherit the old glyph class to the substituted glyph */ + + error = Add_Glyph_Property( gdef, aset.Alternate[alt_index], + property ); + if ( error && error != TTO_Err_Not_Covered ) + return error; + } + + return TT_Err_Ok; + } + + + /* LookupType 4 */ + + /* Ligature */ + + static TT_Error Load_Ligature( TTO_Ligature* l, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + UShort* c; + + + if ( ACCESS_Frame( 4L ) ) + return error; + + l->LigGlyph = GET_UShort(); + l->ComponentCount = GET_UShort(); + + FORGET_Frame(); + + l->Component = NULL; + + count = l->ComponentCount - 1; /* only ComponentCount - 1 elements */ + + if ( ALLOC_ARRAY( l->Component, count, UShort ) ) + return error; + + c = l->Component; + + if ( ACCESS_Frame( count * 2L ) ) + { + FREE( c ); + return error; + } + + for ( n = 0; n < count; n++ ) + c[n] = GET_UShort(); + + FORGET_Frame(); + + return TT_Err_Ok; + } + + + static void Free_Ligature( TTO_Ligature* l ) + { + FREE( l->Component ); + } + + + /* LigatureSet */ + + static TT_Error Load_LigatureSet( TTO_LigatureSet* ls, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_Ligature* l; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = ls->LigatureCount = GET_UShort(); + + FORGET_Frame(); + + ls->Ligature = NULL; + + if ( ALLOC_ARRAY( ls->Ligature, count, TTO_Ligature ) ) + return error; + + l = ls->Ligature; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Ligature( &l[n], input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_Ligature( &l[n] ); + + FREE( l ); + return error; + } + + + static void Free_LigatureSet( TTO_LigatureSet* ls ) + { + UShort n, count; + + TTO_Ligature* l; + + + if ( ls->Ligature ) + { + count = ls->LigatureCount; + l = ls->Ligature; + + for ( n = 0; n < count; n++ ) + Free_Ligature( &l[n] ); + + FREE( l ); + } + } + + + /* LigatureSubstFormat1 */ + + TT_Error Load_LigatureSubst( TTO_LigatureSubst* ls, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_LigatureSet* lset; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 4L ) ) + return error; + + ls->SubstFormat = GET_UShort(); /* should be 1 */ + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &ls->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = ls->LigatureSetCount = GET_UShort(); + + FORGET_Frame(); + + ls->LigatureSet = NULL; + + if ( ALLOC_ARRAY( ls->LigatureSet, count, TTO_LigatureSet ) ) + goto Fail2; + + lset = ls->LigatureSet; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_LigatureSet( &lset[n], input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_LigatureSet( &lset[n] ); + + FREE( lset ); + + Fail2: + Free_Coverage( &ls->Coverage ); + return error; + } + + + void Free_LigatureSubst( TTO_LigatureSubst* ls ) + { + UShort n, count; + + TTO_LigatureSet* lset; + + + if ( ls->LigatureSet ) + { + count = ls->LigatureSetCount; + lset = ls->LigatureSet; + + for ( n = 0; n < count; n++ ) + Free_LigatureSet( &lset[n] ); + + FREE( lset ); + } + + Free_Coverage( &ls->Coverage ); + } + + + static TT_Error Lookup_LigatureSubst( TTO_LigatureSubst* ls, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort flags, + UShort context_length, + TTO_GDEFHeader* gdef ) + { + UShort index, property; + TT_Error error; + UShort numlig, i, j; + UShort* s_in; + UShort* c; + + TTO_Ligature* lig; + + + if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) ) + return error; + + error = Coverage_Index( &ls->Coverage, in->string[in->pos], &index ); + if ( error ) + return error; + + if ( index >= ls->LigatureSetCount ) + return TTO_Err_Invalid_GSUB_SubTable; + + lig = ls->LigatureSet[index].Ligature; + + for ( numlig = ls->LigatureSet[index].LigatureCount; + numlig; + numlig--, lig++ ) + { + if ( in->pos + lig->ComponentCount > in->length ) + continue; /* Not enough glyphs in input */ + + s_in = &in->string[in->pos]; + c = lig->Component; + + if ( context_length != 0xFFFF && context_length < lig->ComponentCount ) + break; + + for ( i = 1, j = 1; i < lig->ComponentCount; i++, j++ ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + return error; + + if ( in->pos + j < in->length ) + j++; + else + break; + } + + if ( s_in[j] != c[i - 1] ) + break; + } + + if ( i == lig->ComponentCount ) + { + if ( ADD_String( in, lig->ComponentCount, out, 1, &lig->LigGlyph ) ) + return error; + + if ( gdef && gdef->NewGlyphClasses ) + { + /* this is just a guess ... */ + + error = Add_Glyph_Property( gdef, lig->LigGlyph, TTO_LIGATURE ); + if ( error && error != TTO_Err_Not_Covered ) + return error; + } + + return TT_Err_Ok; + } + } + + return TTO_Err_Not_Covered; + } + + + /* Do the actual substitution for a context substitution (either format + 5 or 6). This is only called after we've determined that the input + matches the subrule. */ + + static TT_Error Do_ContextSubst( TTO_GSUBHeader* gsub, + UShort GlyphCount, + UShort SubstCount, + TTO_SubstLookupRecord* subst, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + int nesting_level ) + { + TT_Error error; + UShort i, old_pos; + + + i = 0; + + while ( i < GlyphCount ) + { + if ( SubstCount && i == subst->SequenceIndex ) + { + old_pos = in->pos; + + /* Do a substitution */ + + error = Do_Glyph_Lookup( gsub, subst->LookupListIndex, in, out, + GlyphCount, nesting_level ); + + subst++; + SubstCount--; + i += in->pos - old_pos; + + if ( error == TTO_Err_Not_Covered ) + { + /* XXX "can't happen" -- but don't count on it */ + + if ( ADD_String( in, 1, out, 1, &in->string[in->pos] ) ) + return error; + i++; + } + else if ( error ) + return error; + } + else + { + /* No substitution for this index */ + + if ( ADD_String( in, 1, out, 1, &in->string[in->pos] ) ) + return error; + i++; + } + } + + return TT_Err_Ok; + } + + + /* LookupType 5 */ + + /* SubRule */ + + static TT_Error Load_SubRule( TTO_SubRule* sr, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + UShort* i; + + TTO_SubstLookupRecord* slr; + + + if ( ACCESS_Frame( 4L ) ) + return error; + + sr->GlyphCount = GET_UShort(); + sr->SubstCount = GET_UShort(); + + FORGET_Frame(); + + sr->Input = NULL; + + count = sr->GlyphCount - 1; /* only GlyphCount - 1 elements */ + + if ( ALLOC_ARRAY( sr->Input, count, UShort ) ) + return error; + + i = sr->Input; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail2; + + for ( n = 0; n < count; n++ ) + i[n] = GET_UShort(); + + FORGET_Frame(); + + sr->SubstLookupRecord = NULL; + + count = sr->SubstCount; + + if ( ALLOC_ARRAY( sr->SubstLookupRecord, count, TTO_SubstLookupRecord ) ) + goto Fail2; + + slr = sr->SubstLookupRecord; + + if ( ACCESS_Frame( count * 4L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + { + slr[n].SequenceIndex = GET_UShort(); + slr[n].LookupListIndex = GET_UShort(); + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail1: + FREE( slr ); + + Fail2: + FREE( i ); + return error; + } + + + static void Free_SubRule( TTO_SubRule* sr ) + { + FREE( sr->SubstLookupRecord ); + FREE( sr->Input ); + } + + + /* SubRuleSet */ + + static TT_Error Load_SubRuleSet( TTO_SubRuleSet* srs, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_SubRule* sr; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = srs->SubRuleCount = GET_UShort(); + + FORGET_Frame(); + + srs->SubRule = NULL; + + if ( ALLOC_ARRAY( srs->SubRule, count, TTO_SubRule ) ) + return error; + + sr = srs->SubRule; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_SubRule( &sr[n], input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_SubRule( &sr[n] ); + + FREE( sr ); + return error; + } + + + static void Free_SubRuleSet( TTO_SubRuleSet* srs ) + { + UShort n, count; + + TTO_SubRule* sr; + + + if ( srs->SubRule ) + { + count = srs->SubRuleCount; + sr = srs->SubRule; + + for ( n = 0; n < count; n++ ) + Free_SubRule( &sr[n] ); + + FREE( sr ); + } + } + + + /* ContextSubstFormat1 */ + + static TT_Error Load_ContextSubst1( TTO_ContextSubstFormat1* csf1, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_SubRuleSet* srs; + + + base_offset = FILE_Pos() - 2L; + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &csf1->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = csf1->SubRuleSetCount = GET_UShort(); + + FORGET_Frame(); + + csf1->SubRuleSet = NULL; + + if ( ALLOC_ARRAY( csf1->SubRuleSet, count, TTO_SubRuleSet ) ) + goto Fail2; + + srs = csf1->SubRuleSet; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_SubRuleSet( &srs[n], input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_SubRuleSet( &srs[n] ); + + FREE( srs ); + + Fail2: + Free_Coverage( &csf1->Coverage ); + return error; + } + + + static void Free_Context1( TTO_ContextSubstFormat1* csf1 ) + { + UShort n, count; + + TTO_SubRuleSet* srs; + + + if ( csf1->SubRuleSet ) + { + count = csf1->SubRuleSetCount; + srs = csf1->SubRuleSet; + + for ( n = 0; n < count; n++ ) + Free_SubRuleSet( &srs[n] ); + + FREE( srs ); + } + + Free_Coverage( &csf1->Coverage ); + } + + + /* SubClassRule */ + + static TT_Error Load_SubClassRule( TTO_ContextSubstFormat2* csf2, + TTO_SubClassRule* scr, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + + UShort* c; + TTO_SubstLookupRecord* slr; + Bool* d; + + + if ( ACCESS_Frame( 4L ) ) + return error; + + scr->GlyphCount = GET_UShort(); + scr->SubstCount = GET_UShort(); + + if ( scr->GlyphCount > csf2->MaxContextLength ) + csf2->MaxContextLength = scr->GlyphCount; + + FORGET_Frame(); + + scr->Class = NULL; + + count = scr->GlyphCount - 1; /* only GlyphCount - 1 elements */ + + if ( ALLOC_ARRAY( scr->Class, count, UShort ) ) + return error; + + c = scr->Class; + d = csf2->ClassDef.Defined; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail2; + + for ( n = 0; n < count; n++ ) + { + c[n] = GET_UShort(); + + /* We check whether the specific class is used at all. If not, + class 0 is used instead. */ + + if ( !d[c[n]] ) + c[n] = 0; + } + + FORGET_Frame(); + + scr->SubstLookupRecord = NULL; + + count = scr->SubstCount; + + if ( ALLOC_ARRAY( scr->SubstLookupRecord, count, TTO_SubstLookupRecord ) ) + goto Fail2; + + slr = scr->SubstLookupRecord; + + if ( ACCESS_Frame( count * 4L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + { + slr[n].SequenceIndex = GET_UShort(); + slr[n].LookupListIndex = GET_UShort(); + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail1: + FREE( slr ); + + Fail2: + FREE( c ); + return error; + } + + + static void Free_SubClassRule( TTO_SubClassRule* scr ) + { + FREE( scr->SubstLookupRecord ); + FREE( scr->Class ); + } + + + /* SubClassSet */ + + static TT_Error Load_SubClassSet( TTO_ContextSubstFormat2* csf2, + TTO_SubClassSet* scs, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_SubClassRule* scr; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = scs->SubClassRuleCount = GET_UShort(); + + FORGET_Frame(); + + scs->SubClassRule = NULL; + + if ( ALLOC_ARRAY( scs->SubClassRule, count, TTO_SubClassRule ) ) + return error; + + scr = scs->SubClassRule; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_SubClassRule( csf2, &scr[n], + input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_SubClassRule( &scr[n] ); + + FREE( scr ); + return error; + } + + + static void Free_SubClassSet( TTO_SubClassSet* scs ) + { + UShort n, count; + + TTO_SubClassRule* scr; + + + if ( scs->SubClassRule ) + { + count = scs->SubClassRuleCount; + scr = scs->SubClassRule; + + for ( n = 0; n < count; n++ ) + Free_SubClassRule( &scr[n] ); + + FREE( scr ); + } + } + + + /* ContextSubstFormat2 */ + + static TT_Error Load_ContextSubst2( TTO_ContextSubstFormat2* csf2, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_SubClassSet* scs; + + + base_offset = FILE_Pos() - 2; + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &csf2->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 4L ) ) + goto Fail3; + + new_offset = GET_UShort() + base_offset; + + /* `SubClassSetCount' is the upper limit for class values, thus we + read it now to make an additional safety check. */ + + count = csf2->SubClassSetCount = GET_UShort(); + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ClassDefinition( &csf2->ClassDef, count, + input ) ) != TT_Err_Ok ) + goto Fail3; + (void)FILE_Seek( cur_offset ); + + csf2->SubClassSet = NULL; + csf2->MaxContextLength = 0; + + if ( ALLOC_ARRAY( csf2->SubClassSet, count, TTO_SubClassSet ) ) + goto Fail2; + + scs = csf2->SubClassSet; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + if ( new_offset != base_offset ) /* not a NULL offset */ + { + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_SubClassSet( csf2, &scs[n], + input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + else + { + /* we create a SubClassSet table with no entries */ + + csf2->SubClassSet[n].SubClassRuleCount = 0; + csf2->SubClassSet[n].SubClassRule = NULL; + } + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_SubClassSet( &scs[n] ); + + FREE( scs ); + + Fail2: + Free_ClassDefinition( &csf2->ClassDef ); + + Fail3: + Free_Coverage( &csf2->Coverage ); + return error; + } + + + static void Free_Context2( TTO_ContextSubstFormat2* csf2 ) + { + UShort n, count; + + TTO_SubClassSet* scs; + + + if ( csf2->SubClassSet ) + { + count = csf2->SubClassSetCount; + scs = csf2->SubClassSet; + + for ( n = 0; n < count; n++ ) + Free_SubClassSet( &scs[n] ); + + FREE( scs ); + } + + Free_ClassDefinition( &csf2->ClassDef ); + Free_Coverage( &csf2->Coverage ); + } + + + /* ContextSubstFormat3 */ + + static TT_Error Load_ContextSubst3( TTO_ContextSubstFormat3* csf3, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_Coverage* c; + TTO_SubstLookupRecord* slr; + + + base_offset = FILE_Pos() - 2L; + + if ( ACCESS_Frame( 4L ) ) + return error; + + csf3->GlyphCount = GET_UShort(); + csf3->SubstCount = GET_UShort(); + + FORGET_Frame(); + + csf3->Coverage = NULL; + + count = csf3->GlyphCount; + + if ( ALLOC_ARRAY( csf3->Coverage, count, TTO_Coverage ) ) + return error; + + c = csf3->Coverage; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &c[n], input ) ) != TT_Err_Ok ) + goto Fail2; + (void)FILE_Seek( cur_offset ); + } + + csf3->SubstLookupRecord = NULL; + + count = csf3->SubstCount; + + if ( ALLOC_ARRAY( csf3->SubstLookupRecord, count, + TTO_SubstLookupRecord ) ) + goto Fail2; + + slr = csf3->SubstLookupRecord; + + if ( ACCESS_Frame( count * 4L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + { + slr[n].SequenceIndex = GET_UShort(); + slr[n].LookupListIndex = GET_UShort(); + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail1: + FREE( slr ); + + Fail2: + for ( n = 0; n < count; n++ ) + Free_Coverage( &c[n] ); + + FREE( c ); + return error; + } + + + static void Free_Context3( TTO_ContextSubstFormat3* csf3 ) + { + UShort n, count; + + TTO_Coverage* c; + + + FREE( csf3->SubstLookupRecord ); + + if ( csf3->Coverage ) + { + count = csf3->GlyphCount; + c = csf3->Coverage; + + for ( n = 0; n < count; n++ ) + Free_Coverage( &c[n] ); + + FREE( c ); + } + } + + + /* ContextSubst */ + + TT_Error Load_ContextSubst( TTO_ContextSubst* cs, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + + if ( ACCESS_Frame( 2L ) ) + return error; + + cs->SubstFormat = GET_UShort(); + + FORGET_Frame(); + + switch ( cs->SubstFormat ) + { + case 1: + return Load_ContextSubst1( &cs->csf.csf1, input ); + + case 2: + return Load_ContextSubst2( &cs->csf.csf2, input ); + + case 3: + return Load_ContextSubst3( &cs->csf.csf3, input ); + + default: + return TTO_Err_Invalid_GSUB_SubTable_Format; + } + + return TT_Err_Ok; /* never reached */ + } + + + void Free_ContextSubst( TTO_ContextSubst* cs ) + { + switch ( cs->SubstFormat ) + { + case 1: + Free_Context1( &cs->csf.csf1 ); + break; + + case 2: + Free_Context2( &cs->csf.csf2 ); + break; + + case 3: + Free_Context3( &cs->csf.csf3 ); + break; + } + } + + + static TT_Error Lookup_ContextSubst1( + TTO_GSUBHeader* gsub, + TTO_ContextSubstFormat1* csf1, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort flags, + UShort context_length, + int nesting_level ) + { + UShort index, property; + UShort i, j, k, numsr; + TT_Error error; + UShort* s_in; + + TTO_SubRule* sr; + TTO_GDEFHeader* gdef; + + + gdef = gsub->gdef; + + if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) ) + return error; + + error = Coverage_Index( &csf1->Coverage, in->string[in->pos], &index ); + if ( error ) + return error; + + sr = csf1->SubRuleSet[index].SubRule; + numsr = csf1->SubRuleSet[index].SubRuleCount; + + for ( k = 0; k < numsr; k++ ) + { + if ( context_length != 0xFFFF && context_length < sr[k].GlyphCount ) + continue; + + if ( in->pos + sr[k].GlyphCount > in->length ) + continue; /* context is too long */ + + s_in = &in->string[in->pos]; + + for ( i = 1, j = 1; i < sr[k].GlyphCount; i++, j++ ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + return error; + + if ( in->pos + j < in->length ) + j++; + else + break; + } + + if ( s_in[j] != sr[k].Input[i - 1] ) + break; + } + + if ( i == sr[k].GlyphCount ) + return Do_ContextSubst( gsub, sr[k].GlyphCount, + sr[k].SubstCount, sr[k].SubstLookupRecord, + in, out, + nesting_level ); + } + + return TTO_Err_Not_Covered; + } + + + static TT_Error Lookup_ContextSubst2( + TTO_GSUBHeader* gsub, + TTO_ContextSubstFormat2* csf2, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort flags, + UShort context_length, + int nesting_level ) + { + UShort index, property; + TT_Error error; + UShort i, j, k, known_classes; + + UShort* classes; + UShort* s_in; + UShort* cl; + + TTO_SubClassSet* scs; + TTO_SubClassRule* sr; + TTO_GDEFHeader* gdef; + + + gdef = gsub->gdef; + + if ( ALLOC_ARRAY( classes, csf2->MaxContextLength, UShort ) ) + return error; + + if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) ) + return error; + + /* Note: The coverage table in format 2 doesn't give an index into + anything. It just lets us know whether or not we need to + do any lookup at all. */ + + error = Coverage_Index( &csf2->Coverage, in->string[in->pos], &index ); + if ( error ) + goto End; + + error = Get_Class( &csf2->ClassDef, in->string[in->pos], + &classes[0], NULL ); + if ( error ) + goto End; + known_classes = 0; + + scs = &csf2->SubClassSet[classes[0]]; + if ( !scs ) + { + error = TTO_Err_Invalid_GSUB_SubTable; + goto End; + } + + for ( k = 0; k < scs->SubClassRuleCount; k++ ) + { + sr = &scs->SubClassRule[k]; + + if ( context_length != 0xFFFF && context_length < sr->GlyphCount ) + continue; + + if ( in->pos + sr->GlyphCount > in->length ) + continue; /* context is too long */ + + s_in = &in->string[in->pos]; + cl = sr->Class; + + /* Start at 1 because [0] is implied */ + + for ( i = 1, j = 1; i < sr->GlyphCount; i++, j++ ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + return error; + + if ( in->pos + j < in->length ) + j++; + else + break; + } + + if ( i > known_classes ) + { + /* Keeps us from having to do this for each rule */ + + error = Get_Class( &csf2->ClassDef, s_in[j], &classes[i], NULL ); + if ( error && error != TTO_Err_Not_Covered ) + return error; + known_classes = i; + } + + if ( cl[i - 1] != classes[i] ) + break; + } + + if ( i == sr->GlyphCount ) + { + error = Do_ContextSubst( gsub, sr->GlyphCount, + sr->SubstCount, sr->SubstLookupRecord, + in, out, + nesting_level ); + goto End; + } + } + + error = TTO_Err_Not_Covered; + + End: + FREE( classes ); + return error; + } + + + static TT_Error Lookup_ContextSubst3( + TTO_GSUBHeader* gsub, + TTO_ContextSubstFormat3* csf3, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort flags, + UShort context_length, + int nesting_level ) + { + TT_Error error; + UShort index, i, j, property; + UShort* s_in; + + TTO_Coverage* c; + TTO_GDEFHeader* gdef; + + + gdef = gsub->gdef; + + if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) ) + return error; + + if ( context_length != 0xFFFF && context_length < csf3->GlyphCount ) + return TTO_Err_Not_Covered; + + if ( in->pos + csf3->GlyphCount > in->length ) + return TTO_Err_Not_Covered; /* context is too long */ + + s_in = &in->string[in->pos]; + c = csf3->Coverage; + + for ( i = 1, j = 1; i < csf3->GlyphCount; i++, j++ ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + return error; + + if ( in->pos + j < in->length ) + j++; + else + return TTO_Err_Not_Covered; + } + + error = Coverage_Index( &c[i], s_in[j], &index ); + if ( error ) + return error; + } + + return Do_ContextSubst( gsub, csf3->GlyphCount, + csf3->SubstCount, csf3->SubstLookupRecord, + in, out, + nesting_level ); + } + + + static TT_Error Lookup_ContextSubst( TTO_GSUBHeader* gsub, + TTO_ContextSubst* cs, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort flags, + UShort context_length, + int nesting_level ) + { + switch ( cs->SubstFormat ) + { + case 1: + return Lookup_ContextSubst1( gsub, &cs->csf.csf1, in, out, + flags, context_length, nesting_level ); + + case 2: + return Lookup_ContextSubst2( gsub, &cs->csf.csf2, in, out, + flags, context_length, nesting_level ); + + case 3: + return Lookup_ContextSubst3( gsub, &cs->csf.csf3, in, out, + flags, context_length, nesting_level ); + + default: + return TTO_Err_Invalid_GSUB_SubTable_Format; + } + + return TT_Err_Ok; /* never reached */ + } + + + /* LookupType 6 */ + + /* ChainSubRule */ + + static TT_Error Load_ChainSubRule( TTO_ChainSubRule* csr, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + UShort* b; + UShort* i; + UShort* l; + + TTO_SubstLookupRecord* slr; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + csr->BacktrackGlyphCount = GET_UShort(); + + FORGET_Frame(); + + csr->Backtrack = NULL; + + count = csr->BacktrackGlyphCount; + + if ( ALLOC_ARRAY( csr->Backtrack, count, UShort ) ) + return error; + + b = csr->Backtrack; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail4; + + for ( n = 0; n < count; n++ ) + b[n] = GET_UShort(); + + FORGET_Frame(); + + if ( ACCESS_Frame( 2L ) ) + goto Fail4; + + csr->InputGlyphCount = GET_UShort(); + + FORGET_Frame(); + + csr->Input = NULL; + + count = csr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */ + + if ( ALLOC_ARRAY( csr->Input, count, UShort ) ) + goto Fail4; + + i = csr->Input; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail3; + + for ( n = 0; n < count; n++ ) + i[n] = GET_UShort(); + + FORGET_Frame(); + + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + csr->LookaheadGlyphCount = GET_UShort(); + + FORGET_Frame(); + + csr->Lookahead = NULL; + + count = csr->LookaheadGlyphCount; + + if ( ALLOC_ARRAY( csr->Lookahead, count, UShort ) ) + goto Fail3; + + l = csr->Lookahead; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail2; + + for ( n = 0; n < count; n++ ) + l[n] = GET_UShort(); + + FORGET_Frame(); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + csr->SubstCount = GET_UShort(); + + FORGET_Frame(); + + csr->SubstLookupRecord = NULL; + + count = csr->SubstCount; + + if ( ALLOC_ARRAY( csr->SubstLookupRecord, count, TTO_SubstLookupRecord ) ) + goto Fail2; + + slr = csr->SubstLookupRecord; + + if ( ACCESS_Frame( count * 4L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + { + slr[n].SequenceIndex = GET_UShort(); + slr[n].LookupListIndex = GET_UShort(); + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail1: + FREE( slr ); + + Fail2: + FREE( l ); + + Fail3: + FREE( i ); + + Fail4: + FREE( b ); + return error; + } + + + static void Free_ChainSubRule( TTO_ChainSubRule* csr ) + { + FREE( csr->SubstLookupRecord ); + FREE( csr->Lookahead ); + FREE( csr->Input ); + FREE( csr->Backtrack ); + } + + + /* ChainSubRuleSet */ + + static TT_Error Load_ChainSubRuleSet( TTO_ChainSubRuleSet* csrs, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_ChainSubRule* csr; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = csrs->ChainSubRuleCount = GET_UShort(); + + FORGET_Frame(); + + csrs->ChainSubRule = NULL; + + if ( ALLOC_ARRAY( csrs->ChainSubRule, count, TTO_ChainSubRule ) ) + return error; + + csr = csrs->ChainSubRule; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ChainSubRule( &csr[n], input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_ChainSubRule( &csr[n] ); + + FREE( csr ); + return error; + } + + + static void Free_ChainSubRuleSet( TTO_ChainSubRuleSet* csrs ) + { + UShort n, count; + + TTO_ChainSubRule* csr; + + + if ( csrs->ChainSubRule ) + { + count = csrs->ChainSubRuleCount; + csr = csrs->ChainSubRule; + + for ( n = 0; n < count; n++ ) + Free_ChainSubRule( &csr[n] ); + + FREE( csr ); + } + } + + + /* ChainContextSubstFormat1 */ + + static TT_Error Load_ChainContextSubst1( + TTO_ChainContextSubstFormat1* ccsf1, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_ChainSubRuleSet* csrs; + + + base_offset = FILE_Pos() - 2L; + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &ccsf1->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = ccsf1->ChainSubRuleSetCount = GET_UShort(); + + FORGET_Frame(); + + ccsf1->ChainSubRuleSet = NULL; + + if ( ALLOC_ARRAY( ccsf1->ChainSubRuleSet, count, TTO_ChainSubRuleSet ) ) + goto Fail2; + + csrs = ccsf1->ChainSubRuleSet; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ChainSubRuleSet( &csrs[n], input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_ChainSubRuleSet( &csrs[n] ); + + FREE( csrs ); + + Fail2: + Free_Coverage( &ccsf1->Coverage ); + return error; + } + + + static void Free_ChainContext1( TTO_ChainContextSubstFormat1* ccsf1 ) + { + UShort n, count; + + TTO_ChainSubRuleSet* csrs; + + + if ( ccsf1->ChainSubRuleSet ) + { + count = ccsf1->ChainSubRuleSetCount; + csrs = ccsf1->ChainSubRuleSet; + + for ( n = 0; n < count; n++ ) + Free_ChainSubRuleSet( &csrs[n] ); + + FREE( csrs ); + } + + Free_Coverage( &ccsf1->Coverage ); + } + + + /* ChainSubClassRule */ + + static TT_Error Load_ChainSubClassRule( + TTO_ChainContextSubstFormat2* ccsf2, + TTO_ChainSubClassRule* cscr, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + + UShort* b; + UShort* i; + UShort* l; + TTO_SubstLookupRecord* slr; + Bool* d; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + cscr->BacktrackGlyphCount = GET_UShort(); + + FORGET_Frame(); + + if ( cscr->BacktrackGlyphCount > ccsf2->MaxBacktrackLength ) + ccsf2->MaxBacktrackLength = cscr->BacktrackGlyphCount; + + cscr->Backtrack = NULL; + + count = cscr->BacktrackGlyphCount; + + if ( ALLOC_ARRAY( cscr->Backtrack, count, UShort ) ) + return error; + + b = cscr->Backtrack; + d = ccsf2->BacktrackClassDef.Defined; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail4; + + for ( n = 0; n < count; n++ ) + { + b[n] = GET_UShort(); + + /* We check whether the specific class is used at all. If not, + class 0 is used instead. */ + + if ( !d[b[n]] ) + b[n] = 0; + } + + FORGET_Frame(); + + if ( ACCESS_Frame( 2L ) ) + goto Fail4; + + cscr->InputGlyphCount = GET_UShort(); + + FORGET_Frame(); + + if ( cscr->InputGlyphCount > ccsf2->MaxInputLength ) + ccsf2->MaxInputLength = cscr->InputGlyphCount; + + cscr->Input = NULL; + + count = cscr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */ + + if ( ALLOC_ARRAY( cscr->Input, count, UShort ) ) + goto Fail4; + + i = cscr->Input; + d = ccsf2->InputClassDef.Defined; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail3; + + for ( n = 0; n < count; n++ ) + { + i[n] = GET_UShort(); + + if ( !d[i[n]] ) + i[n] = 0; + } + + FORGET_Frame(); + + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + cscr->LookaheadGlyphCount = GET_UShort(); + + FORGET_Frame(); + + if ( cscr->LookaheadGlyphCount > ccsf2->MaxLookaheadLength ) + ccsf2->MaxLookaheadLength = cscr->LookaheadGlyphCount; + + cscr->Lookahead = NULL; + + count = cscr->LookaheadGlyphCount; + + if ( ALLOC_ARRAY( cscr->Lookahead, count, UShort ) ) + goto Fail3; + + l = cscr->Lookahead; + d = ccsf2->LookaheadClassDef.Defined; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail2; + + for ( n = 0; n < count; n++ ) + { + l[n] = GET_UShort(); + + if ( !d[l[n]] ) + l[n] = 0; + } + + FORGET_Frame(); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + cscr->SubstCount = GET_UShort(); + + FORGET_Frame(); + + cscr->SubstLookupRecord = NULL; + + count = cscr->SubstCount; + + if ( ALLOC_ARRAY( cscr->SubstLookupRecord, count, + TTO_SubstLookupRecord ) ) + goto Fail2; + + slr = cscr->SubstLookupRecord; + + if ( ACCESS_Frame( count * 4L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + { + slr[n].SequenceIndex = GET_UShort(); + slr[n].LookupListIndex = GET_UShort(); + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail1: + FREE( slr ); + + Fail2: + FREE( l ); + + Fail3: + FREE( i ); + + Fail4: + FREE( b ); + return error; + } + + + static void Free_ChainSubClassRule( TTO_ChainSubClassRule* cscr ) + { + FREE( cscr->SubstLookupRecord ); + FREE( cscr->Lookahead ); + FREE( cscr->Input ); + FREE( cscr->Backtrack ); + } + + + /* SubClassSet */ + + static TT_Error Load_ChainSubClassSet( + TTO_ChainContextSubstFormat2* ccsf2, + TTO_ChainSubClassSet* cscs, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_ChainSubClassRule* cscr; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = cscs->ChainSubClassRuleCount = GET_UShort(); + + FORGET_Frame(); + + cscs->ChainSubClassRule = NULL; + + if ( ALLOC_ARRAY( cscs->ChainSubClassRule, count, + TTO_ChainSubClassRule ) ) + return error; + + cscr = cscs->ChainSubClassRule; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ChainSubClassRule( ccsf2, &cscr[n], + input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_ChainSubClassRule( &cscr[n] ); + + FREE( cscr ); + return error; + } + + + static void Free_ChainSubClassSet( TTO_ChainSubClassSet* cscs ) + { + UShort n, count; + + TTO_ChainSubClassRule* cscr; + + + if ( cscs->ChainSubClassRule ) + { + count = cscs->ChainSubClassRuleCount; + cscr = cscs->ChainSubClassRule; + + for ( n = 0; n < count; n++ ) + Free_ChainSubClassRule( &cscr[n] ); + + FREE( cscr ); + } + } + + + /* ChainContextSubstFormat2 */ + + static TT_Error Load_ChainContextSubst2( + TTO_ChainContextSubstFormat2* ccsf2, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + ULong backtrack_offset, input_offset, lookahead_offset; + + TTO_ChainSubClassSet* cscs; + + + base_offset = FILE_Pos() - 2; + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &ccsf2->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 8L ) ) + goto Fail5; + + backtrack_offset = GET_UShort() + base_offset; + input_offset = GET_UShort() + base_offset; + lookahead_offset = GET_UShort() + base_offset; + + /* `ChainSubClassSetCount' is the upper limit for input class values, + thus we read it now to make an additional safety check. */ + + count = ccsf2->ChainSubClassSetCount = GET_UShort(); + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( backtrack_offset ) || + ( error = Load_ClassDefinition( &ccsf2->BacktrackClassDef, count, + input ) ) != TT_Err_Ok ) + goto Fail5; + if ( FILE_Seek( input_offset ) || + ( error = Load_ClassDefinition( &ccsf2->InputClassDef, count, + input ) ) != TT_Err_Ok ) + goto Fail4; + if ( FILE_Seek( lookahead_offset ) || + ( error = Load_ClassDefinition( &ccsf2->LookaheadClassDef, count, + input ) ) != TT_Err_Ok ) + goto Fail3; + (void)FILE_Seek( cur_offset ); + + ccsf2->ChainSubClassSet = NULL; + ccsf2->MaxBacktrackLength = 0; + ccsf2->MaxInputLength = 0; + ccsf2->MaxLookaheadLength = 0; + + if ( ALLOC_ARRAY( ccsf2->ChainSubClassSet, count, TTO_ChainSubClassSet ) ) + goto Fail2; + + cscs = ccsf2->ChainSubClassSet; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + if ( new_offset != base_offset ) /* not a NULL offset */ + { + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ChainSubClassSet( ccsf2, &cscs[n], + input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + else + { + /* we create a ChainSubClassSet table with no entries */ + + ccsf2->ChainSubClassSet[n].ChainSubClassRuleCount = 0; + ccsf2->ChainSubClassSet[n].ChainSubClassRule = NULL; + } + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_ChainSubClassSet( &cscs[n] ); + + FREE( cscs ); + + Fail2: + Free_ClassDefinition( &ccsf2->LookaheadClassDef ); + + Fail3: + Free_ClassDefinition( &ccsf2->InputClassDef ); + + Fail4: + Free_ClassDefinition( &ccsf2->BacktrackClassDef ); + + Fail5: + Free_Coverage( &ccsf2->Coverage ); + return error; + } + + + static void Free_ChainContext2( TTO_ChainContextSubstFormat2* ccsf2 ) + { + UShort n, count; + + TTO_ChainSubClassSet* cscs; + + + if ( ccsf2->ChainSubClassSet ) + { + count = ccsf2->ChainSubClassSetCount; + cscs = ccsf2->ChainSubClassSet; + + for ( n = 0; n < count; n++ ) + Free_ChainSubClassSet( &cscs[n] ); + + FREE( cscs ); + } + + Free_ClassDefinition( &ccsf2->LookaheadClassDef ); + Free_ClassDefinition( &ccsf2->InputClassDef ); + Free_ClassDefinition( &ccsf2->BacktrackClassDef ); + + Free_Coverage( &ccsf2->Coverage ); + } + + + /* ChainContextSubstFormat3 */ + + static TT_Error Load_ChainContextSubst3( + TTO_ChainContextSubstFormat3* ccsf3, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + UShort backtrack_count, input_count, lookahead_count; + ULong cur_offset, new_offset, base_offset; + + TTO_Coverage* b; + TTO_Coverage* i; + TTO_Coverage* l; + TTO_SubstLookupRecord* slr; + + + base_offset = FILE_Pos() - 2L; + + if ( ACCESS_Frame( 2L ) ) + return error; + + ccsf3->BacktrackGlyphCount = GET_UShort(); + + FORGET_Frame(); + + ccsf3->BacktrackCoverage = NULL; + + backtrack_count = ccsf3->BacktrackGlyphCount; + + if ( ALLOC_ARRAY( ccsf3->BacktrackCoverage, backtrack_count, + TTO_Coverage ) ) + return error; + + b = ccsf3->BacktrackCoverage; + + for ( n = 0; n < backtrack_count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail4; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &b[n], input ) ) != TT_Err_Ok ) + goto Fail4; + (void)FILE_Seek( cur_offset ); + } + + if ( ACCESS_Frame( 2L ) ) + goto Fail4; + + ccsf3->InputGlyphCount = GET_UShort(); + + FORGET_Frame(); + + ccsf3->InputCoverage = NULL; + + input_count = ccsf3->InputGlyphCount; + + if ( ALLOC_ARRAY( ccsf3->InputCoverage, input_count, TTO_Coverage ) ) + goto Fail4; + + i = ccsf3->InputCoverage; + + for ( n = 0; n < input_count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &i[n], input ) ) != TT_Err_Ok ) + goto Fail3; + (void)FILE_Seek( cur_offset ); + } + + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + ccsf3->LookaheadGlyphCount = GET_UShort(); + + FORGET_Frame(); + + ccsf3->LookaheadCoverage = NULL; + + lookahead_count = ccsf3->LookaheadGlyphCount; + + if ( ALLOC_ARRAY( ccsf3->LookaheadCoverage, lookahead_count, + TTO_Coverage ) ) + goto Fail3; + + l = ccsf3->LookaheadCoverage; + + for ( n = 0; n < lookahead_count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &l[n], input ) ) != TT_Err_Ok ) + goto Fail2; + (void)FILE_Seek( cur_offset ); + } + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + ccsf3->SubstCount = GET_UShort(); + + FORGET_Frame(); + + ccsf3->SubstLookupRecord = NULL; + + count = ccsf3->SubstCount; + + if ( ALLOC_ARRAY( ccsf3->SubstLookupRecord, count, + TTO_SubstLookupRecord ) ) + goto Fail2; + + slr = ccsf3->SubstLookupRecord; + + if ( ACCESS_Frame( count * 4L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + { + slr[n].SequenceIndex = GET_UShort(); + slr[n].LookupListIndex = GET_UShort(); + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail1: + FREE( slr ); + + Fail2: + for ( n = 0; n < lookahead_count; n++ ) + Free_Coverage( &l[n] ); + + FREE( l ); + + Fail3: + for ( n = 0; n < input_count; n++ ) + Free_Coverage( &i[n] ); + + FREE( i ); + + Fail4: + for ( n = 0; n < backtrack_count; n++ ) + Free_Coverage( &b[n] ); + + FREE( b ); + return error; + } + + + static void Free_ChainContext3( TTO_ChainContextSubstFormat3* ccsf3 ) + { + UShort n, count; + + TTO_Coverage* c; + + + FREE( ccsf3->SubstLookupRecord ); + + if ( ccsf3->LookaheadCoverage ) + { + count = ccsf3->LookaheadGlyphCount; + c = ccsf3->LookaheadCoverage; + + for ( n = 0; n < count; n++ ) + Free_Coverage( &c[n] ); + + FREE( c ); + } + + if ( ccsf3->InputCoverage ) + { + count = ccsf3->InputGlyphCount; + c = ccsf3->InputCoverage; + + for ( n = 0; n < count; n++ ) + Free_Coverage( &c[n] ); + + FREE( c ); + } + + if ( ccsf3->BacktrackCoverage ) + { + count = ccsf3->BacktrackGlyphCount; + c = ccsf3->BacktrackCoverage; + + for ( n = 0; n < count; n++ ) + Free_Coverage( &c[n] ); + + FREE( c ); + } + } + + + /* ChainContextSubst */ + + TT_Error Load_ChainContextSubst( TTO_ChainContextSubst* ccs, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + + if ( ACCESS_Frame( 2L ) ) + return error; + + ccs->SubstFormat = GET_UShort(); + + FORGET_Frame(); + + switch ( ccs->SubstFormat ) + { + case 1: + return Load_ChainContextSubst1( &ccs->ccsf.ccsf1, input ); + + case 2: + return Load_ChainContextSubst2( &ccs->ccsf.ccsf2, input ); + + case 3: + return Load_ChainContextSubst3( &ccs->ccsf.ccsf3, input ); + + default: + return TTO_Err_Invalid_GSUB_SubTable_Format; + } + + return TT_Err_Ok; /* never reached */ + } + + + void Free_ChainContextSubst( TTO_ChainContextSubst* ccs ) + { + switch ( ccs->SubstFormat ) + { + case 1: + Free_ChainContext1( &ccs->ccsf.ccsf1 ); + break; + + case 2: + Free_ChainContext2( &ccs->ccsf.ccsf2 ); + break; + + case 3: + Free_ChainContext3( &ccs->ccsf.ccsf3 ); + break; + } + } + + + static TT_Error Lookup_ChainContextSubst1( + TTO_GSUBHeader* gsub, + TTO_ChainContextSubstFormat1* ccsf1, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort flags, + UShort context_length, + int nesting_level ) + { + UShort index, property; + UShort i, j, k, num_csr, curr_pos; + UShort bgc, igc, lgc; + TT_Error error; + UShort* s_in; + + TTO_ChainSubRule* csr; + TTO_ChainSubRule curr_csr; + TTO_GDEFHeader* gdef; + + + gdef = gsub->gdef; + + if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) ) + return error; + + error = Coverage_Index( &ccsf1->Coverage, in->string[in->pos], &index ); + if ( error ) + return error; + + csr = ccsf1->ChainSubRuleSet[index].ChainSubRule; + num_csr = ccsf1->ChainSubRuleSet[index].ChainSubRuleCount; + + for ( k = 0; k < num_csr; k++ ) + { + curr_csr = csr[k]; + bgc = curr_csr.BacktrackGlyphCount; + igc = curr_csr.InputGlyphCount; + lgc = curr_csr.LookaheadGlyphCount; + + if ( context_length != 0xFFFF && context_length < igc ) + continue; + + /* check whether context is too long; it is a first guess only */ + + if ( bgc > in->pos || in->pos + igc + lgc > in->length ) + continue; + + if ( bgc ) + { + /* Since we don't know in advance the number of glyphs to inspect, + we search backwards for matches in the backtrack glyph array */ + + curr_pos = 0; + s_in = &in->string[curr_pos]; + + for ( i = bgc, j = in->pos - 1; i > 0; i--, j-- ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + return error; + + if ( j > curr_pos ) + j--; + else + break; + } + + if ( s_in[j] != curr_csr.Backtrack[i - 1] ) + break; + } + + if ( i != 0 ) + continue; + } + + curr_pos = in->pos; + s_in = &in->string[curr_pos]; + + /* Start at 1 because [0] is implied */ + + for ( i = 1, j = 1; i < igc; i++, j++ ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + return error; + + if ( curr_pos + j < in->length ) + j++; + else + break; + } + + if ( s_in[j] != curr_csr.Input[i - 1] ) + break; + } + + if ( i != igc ) + continue; + + /* we are starting to check for lookahead glyphs right after the + last context glyph */ + + curr_pos = j; + s_in = &in->string[curr_pos]; + + for ( i = 0, j = 0; i < lgc; i++, j++ ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + return error; + + if ( curr_pos + j < in->length ) + j++; + else + break; + } + + if ( s_in[j] != curr_csr.Lookahead[i] ) + break; + } + + if ( i == lgc ) + return Do_ContextSubst( gsub, igc, + curr_csr.SubstCount, + curr_csr.SubstLookupRecord, + in, out, + nesting_level ); + } + + return TTO_Err_Not_Covered; + } + + + static TT_Error Lookup_ChainContextSubst2( + TTO_GSUBHeader* gsub, + TTO_ChainContextSubstFormat2* ccsf2, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort flags, + UShort context_length, + int nesting_level ) + { + UShort index, property; + TT_Error error; + UShort i, j, k, curr_pos; + UShort bgc, igc, lgc; + UShort known_backtrack_classes, + known_input_classes, + known_lookahead_classes; + + UShort* backtrack_classes; + UShort* input_classes; + UShort* lookahead_classes; + + UShort* s_in; + + UShort* bc; + UShort* ic; + UShort* lc; + + TTO_ChainSubClassSet* cscs; + TTO_ChainSubClassRule ccsr; + TTO_GDEFHeader* gdef; + + + gdef = gsub->gdef; + + if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) ) + return error; + + /* Note: The coverage table in format 2 doesn't give an index into + anything. It just lets us know whether or not we need to + do any lookup at all. */ + + error = Coverage_Index( &ccsf2->Coverage, in->string[in->pos], &index ); + if ( error ) + return error; + + if ( ALLOC_ARRAY( backtrack_classes, ccsf2->MaxBacktrackLength, UShort ) ) + return error; + known_backtrack_classes = 0; + + if ( ALLOC_ARRAY( input_classes, ccsf2->MaxInputLength, UShort ) ) + goto End3; + known_input_classes = 1; + + if ( ALLOC_ARRAY( lookahead_classes, ccsf2->MaxLookaheadLength, UShort ) ) + goto End2; + known_lookahead_classes = 0; + + error = Get_Class( &ccsf2->InputClassDef, in->string[in->pos], + &input_classes[0], NULL ); + if ( error ) + goto End1; + + cscs = &ccsf2->ChainSubClassSet[input_classes[0]]; + if ( !cscs ) + { + error = TTO_Err_Invalid_GSUB_SubTable; + goto End1; + } + + for ( k = 0; k < cscs->ChainSubClassRuleCount; k++ ) + { + ccsr = cscs->ChainSubClassRule[k]; + bgc = ccsr.BacktrackGlyphCount; + igc = ccsr.InputGlyphCount; + lgc = ccsr.LookaheadGlyphCount; + + if ( context_length != 0xFFFF && context_length < igc ) + continue; + + /* check whether context is too long; it is a first guess only */ + + if ( bgc > in->pos || in->pos + igc + lgc > in->length ) + continue; + + if ( bgc ) + { + /* Since we don't know in advance the number of glyphs to inspect, + we search backwards for matches in the backtrack glyph array. + Note that `known_backtrack_classes' starts at index 0. */ + + curr_pos = 0; + s_in = &in->string[curr_pos]; + bc = ccsr.Backtrack; + + for ( i = 0, j = in->pos - 1; i < bgc; i++, j-- ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + return error; + + if ( j > curr_pos ) + j--; + else + break; + } + + if ( i >= known_backtrack_classes ) + { + /* Keeps us from having to do this for each rule */ + + error = Get_Class( &ccsf2->BacktrackClassDef, s_in[j], + &backtrack_classes[i], NULL ); + if ( error && error != TTO_Err_Not_Covered ) + goto End1; + known_backtrack_classes = i; + } + + if ( bc[bgc - 1 - i] != backtrack_classes[i] ) + break; + } + + if ( i != bgc ) + continue; + } + + curr_pos = in->pos; + s_in = &in->string[curr_pos]; + ic = ccsr.Input; + + /* Start at 1 because [0] is implied */ + + for ( i = 1, j = 1; i < igc; i++, j++ ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + goto End1; + + if ( curr_pos + j < in->length ) + j++; + else + break; + } + + if ( i >= known_input_classes ) + { + error = Get_Class( &ccsf2->InputClassDef, s_in[j], + &input_classes[i], NULL ); + if ( error && error != TTO_Err_Not_Covered ) + goto End1; + known_input_classes = i; + } + + if ( ic[i - 1] != input_classes[i] ) + break; + } + + if ( i != igc ) + continue; + + /* we are starting to check for lookahead glyphs right after the + last context glyph */ + + curr_pos = j; + s_in = &in->string[curr_pos]; + lc = ccsr.Lookahead; + + for ( i = 0, j = 0; i < lgc; i++, j++ ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + return error; + + if ( curr_pos + j < in->length ) + j++; + else + break; + } + + if ( i >= known_lookahead_classes ) + { + error = Get_Class( &ccsf2->LookaheadClassDef, s_in[j], + &lookahead_classes[i], NULL ); + if ( error && error != TTO_Err_Not_Covered ) + goto End1; + known_lookahead_classes = i; + } + + if ( lc[i] != lookahead_classes[i] ) + break; + } + + if ( i == lgc ) + { + error = Do_ContextSubst( gsub, igc, + ccsr.SubstCount, + ccsr.SubstLookupRecord, + in, out, + nesting_level ); + goto End1; + } + } + + error = TTO_Err_Not_Covered; + + End1: + FREE( lookahead_classes ); + + End2: + FREE( input_classes ); + + End3: + FREE( backtrack_classes ); + return error; + } + + + static TT_Error Lookup_ChainContextSubst3( + TTO_GSUBHeader* gsub, + TTO_ChainContextSubstFormat3* ccsf3, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort flags, + UShort context_length, + int nesting_level ) + { + UShort index, i, j, curr_pos, property; + UShort bgc, igc, lgc; + TT_Error error; + UShort* s_in; + + TTO_Coverage* bc; + TTO_Coverage* ic; + TTO_Coverage* lc; + TTO_GDEFHeader* gdef; + + + gdef = gsub->gdef; + + if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) ) + return error; + + bgc = ccsf3->BacktrackGlyphCount; + igc = ccsf3->InputGlyphCount; + lgc = ccsf3->LookaheadGlyphCount; + + if ( context_length != 0xFFFF && context_length < igc ) + return TTO_Err_Not_Covered; + + /* check whether context is too long; it is a first guess only */ + + if ( bgc > in->pos || in->pos + igc + lgc > in->length ) + return TTO_Err_Not_Covered; + + if ( bgc ) + { + /* Since we don't know in advance the number of glyphs to inspect, + we search backwards for matches in the backtrack glyph array */ + + curr_pos = 0; + s_in = &in->string[curr_pos]; + bc = ccsf3->BacktrackCoverage; + + for ( i = bgc, j = in->pos - 1; i > 0; i--, j-- ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + return error; + + if ( j > curr_pos ) + j--; + else + return TTO_Err_Not_Covered; + } + + error = Coverage_Index( &bc[i - 1], s_in[j], &index ); + if ( error ) + return error; + } + } + + curr_pos = in->pos; + s_in = &in->string[curr_pos]; + ic = ccsf3->InputCoverage; + + /* Start at 1 because [0] is implied */ + + for ( i = 1, j = 1; i < igc; i++, j++ ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + return error; + + if ( curr_pos + j < in->length ) + j++; + else + return TTO_Err_Not_Covered; + } + + error = Coverage_Index( &ic[i], s_in[j], &index ); + if ( error ) + return error; + } + + /* we are starting for lookahead glyphs right after the last context + glyph */ + + curr_pos = j; + s_in = &in->string[curr_pos]; + lc = ccsf3->LookaheadCoverage; + + for ( i = 0, j = 0; i < lgc; i++, j++ ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + return error; + + if ( curr_pos + j < in->length ) + j++; + else + return TTO_Err_Not_Covered; + } + + error = Coverage_Index( &lc[i], s_in[j], &index ); + if ( error ) + return error; + } + + return Do_ContextSubst( gsub, igc, + ccsf3->SubstCount, + ccsf3->SubstLookupRecord, + in, out, + nesting_level ); + } + + + static TT_Error Lookup_ChainContextSubst( + TTO_GSUBHeader* gsub, + TTO_ChainContextSubst* ccs, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort flags, + UShort context_length, + int nesting_level ) + { + switch ( ccs->SubstFormat ) + { + case 1: + return Lookup_ChainContextSubst1( gsub, &ccs->ccsf.ccsf1, in, out, + flags, context_length, + nesting_level ); + + case 2: + return Lookup_ChainContextSubst2( gsub, &ccs->ccsf.ccsf2, in, out, + flags, context_length, + nesting_level ); + + case 3: + return Lookup_ChainContextSubst3( gsub, &ccs->ccsf.ccsf3, in, out, + flags, context_length, + nesting_level ); + + default: + return TTO_Err_Invalid_GSUB_SubTable_Format; + } + + return TT_Err_Ok; /* never reached */ + } + + + + /*********** + * GSUB API + ***********/ + + + EXPORT_FUNC + TT_Error TT_GSUB_Select_Script( TTO_GSUBHeader* gsub, + TT_ULong script_tag, + TT_UShort* script_index ) + { + UShort n; + + TTO_ScriptList* sl; + TTO_ScriptRecord* sr; + + + if ( !gsub || !script_index ) + return TT_Err_Invalid_Argument; + + sl = &gsub->ScriptList; + sr = sl->ScriptRecord; + + for ( n = 0; n < sl->ScriptCount; n++ ) + if ( script_tag == sr[n].ScriptTag ) + { + *script_index = n; + + return TT_Err_Ok; + } + + return TTO_Err_Not_Covered; + } + + + EXPORT_FUNC + TT_Error TT_GSUB_Select_Language( TTO_GSUBHeader* gsub, + TT_ULong language_tag, + TT_UShort script_index, + TT_UShort* language_index, + TT_UShort* req_feature_index ) + { + UShort n; + + TTO_ScriptList* sl; + TTO_ScriptRecord* sr; + TTO_Script* s; + TTO_LangSysRecord* lsr; + + + if ( !gsub || !language_index || !req_feature_index ) + return TT_Err_Invalid_Argument; + + sl = &gsub->ScriptList; + sr = sl->ScriptRecord; + + if ( script_index >= sl->ScriptCount ) + return TT_Err_Invalid_Argument; + + s = &sr[script_index].Script; + lsr = s->LangSysRecord; + + for ( n = 0; n < s->LangSysCount; n++ ) + if ( language_tag == lsr[n].LangSysTag ) + { + *language_index = n; + *req_feature_index = lsr[n].LangSys.ReqFeatureIndex; + + return TT_Err_Ok; + } + + return TTO_Err_Not_Covered; + } + + + /* selecting 0xFFFF for language_index asks for the values of the + default language (DefaultLangSys) */ + + EXPORT_FUNC + TT_Error TT_GSUB_Select_Feature( TTO_GSUBHeader* gsub, + TT_ULong feature_tag, + TT_UShort script_index, + TT_UShort language_index, + TT_UShort* feature_index ) + { + UShort n; + + TTO_ScriptList* sl; + TTO_ScriptRecord* sr; + TTO_Script* s; + TTO_LangSysRecord* lsr; + TTO_LangSys* ls; + UShort* fi; + + TTO_FeatureList* fl; + TTO_FeatureRecord* fr; + + + if ( !gsub || !feature_index ) + return TT_Err_Invalid_Argument; + + sl = &gsub->ScriptList; + sr = sl->ScriptRecord; + + fl = &gsub->FeatureList; + fr = fl->FeatureRecord; + + if ( script_index >= sl->ScriptCount ) + return TT_Err_Invalid_Argument; + + s = &sr[script_index].Script; + lsr = s->LangSysRecord; + + if ( language_index == 0xFFFF ) + ls = &s->DefaultLangSys; + else + { + if ( language_index >= s->LangSysCount ) + return TT_Err_Invalid_Argument; + + ls = &lsr[language_index].LangSys; + } + + fi = ls->FeatureIndex; + + for ( n = 0; n < ls->FeatureCount; n++ ) + { + if ( fi[n] >= fl->FeatureCount ) + return TTO_Err_Invalid_GSUB_SubTable_Format; + + if ( feature_tag == fr[fi[n]].FeatureTag ) + { + *feature_index = fi[n]; + + return TT_Err_Ok; + } + } + + return TTO_Err_Not_Covered; + } + + + /* The next three functions return a null-terminated list */ + + EXPORT_FUNC + TT_Error TT_GSUB_Query_Scripts( TTO_GSUBHeader* gsub, + TT_ULong** script_tag_list ) + { + UShort n; + TT_Error error; + ULong* stl; + + TTO_ScriptList* sl; + TTO_ScriptRecord* sr; + + + if ( !gsub || !script_tag_list ) + return TT_Err_Invalid_Argument; + + sl = &gsub->ScriptList; + sr = sl->ScriptRecord; + + if ( ALLOC_ARRAY( stl, sl->ScriptCount + 1, ULong ) ) + return error; + + for ( n = 0; n < sl->ScriptCount; n++ ) + stl[n] = sr[n].ScriptTag; + stl[n] = 0; + + *script_tag_list = stl; + + return TT_Err_Ok; + } + + + EXPORT_FUNC + TT_Error TT_GSUB_Query_Languages( TTO_GSUBHeader* gsub, + TT_UShort script_index, + TT_ULong** language_tag_list ) + { + UShort n; + TT_Error error; + ULong* ltl; + + TTO_ScriptList* sl; + TTO_ScriptRecord* sr; + TTO_Script* s; + TTO_LangSysRecord* lsr; + + + if ( !gsub || !language_tag_list ) + return TT_Err_Invalid_Argument; + + sl = &gsub->ScriptList; + sr = sl->ScriptRecord; + + if ( script_index >= sl->ScriptCount ) + return TT_Err_Invalid_Argument; + + s = &sr[script_index].Script; + lsr = s->LangSysRecord; + + if ( ALLOC_ARRAY( ltl, s->LangSysCount + 1, ULong ) ) + return error; + + for ( n = 0; n < s->LangSysCount; n++ ) + ltl[n] = lsr[n].LangSysTag; + ltl[n] = 0; + + *language_tag_list = ltl; + + return TT_Err_Ok; + } + + + /* selecting 0xFFFF for language_index asks for the values of the + default language (DefaultLangSys) */ + + EXPORT_FUNC + TT_Error TT_GSUB_Query_Features( TTO_GSUBHeader* gsub, + TT_UShort script_index, + TT_UShort language_index, + TT_ULong** feature_tag_list ) + { + UShort n; + TT_Error error; + ULong* ftl; + + TTO_ScriptList* sl; + TTO_ScriptRecord* sr; + TTO_Script* s; + TTO_LangSysRecord* lsr; + TTO_LangSys* ls; + UShort* fi; + + TTO_FeatureList* fl; + TTO_FeatureRecord* fr; + + + if ( !gsub || !feature_tag_list ) + return TT_Err_Invalid_Argument; + + sl = &gsub->ScriptList; + sr = sl->ScriptRecord; + + fl = &gsub->FeatureList; + fr = fl->FeatureRecord; + + if ( script_index >= sl->ScriptCount ) + return TT_Err_Invalid_Argument; + + s = &sr[script_index].Script; + lsr = s->LangSysRecord; + + if ( language_index == 0xFFFF ) + ls = &s->DefaultLangSys; + else + { + if ( language_index >= s->LangSysCount ) + return TT_Err_Invalid_Argument; + + ls = &lsr[language_index].LangSys; + } + + fi = ls->FeatureIndex; + + if ( ALLOC_ARRAY( ftl, ls->FeatureCount + 1, ULong ) ) + return error; + + for ( n = 0; n < ls->FeatureCount; n++ ) + { + if ( fi[n] >= fl->FeatureCount ) + { + FREE( ftl ); + return TTO_Err_Invalid_GSUB_SubTable_Format; + } + ftl[n] = fr[fi[n]].FeatureTag; + } + ftl[n] = 0; + + *feature_tag_list = ftl; + + return TT_Err_Ok; + } + + + /* Do an individual subtable lookup. Returns TT_Err_Ok if substitution + has been done, or TTO_Err_Not_Covered if not. */ + + static TT_Error Do_Glyph_Lookup( TTO_GSUBHeader* gsub, + UShort lookup_index, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort context_length, + int nesting_level ) + { + TT_Error error = TT_Err_Ok; + UShort i, flags; + TTO_Lookup* lo; + + + nesting_level++; + + if ( nesting_level > TTO_MAX_NESTING_LEVEL ) + return TTO_Err_Too_Many_Nested_Contexts; + + lo = &gsub->LookupList.Lookup[lookup_index]; + flags = lo->LookupFlag; + + for ( i = 0; i < lo->SubTableCount; i++ ) + { + switch ( lo->LookupType ) + { + case GSUB_LOOKUP_SINGLE: + error = Lookup_SingleSubst( &lo->SubTable[i].st.gsub.single, + in, out, + flags, context_length, gsub->gdef ); + break; + + case GSUB_LOOKUP_MULTIPLE: + error = Lookup_MultipleSubst( &lo->SubTable[i].st.gsub.multiple, + in, out, + flags, context_length, gsub->gdef ); + break; + + case GSUB_LOOKUP_ALTERNATE: + error = Lookup_AlternateSubst( gsub, + &lo->SubTable[i].st.gsub.alternate, + in, out, + flags, context_length, gsub->gdef ); + break; + + case GSUB_LOOKUP_LIGATURE: + error = Lookup_LigatureSubst( &lo->SubTable[i].st.gsub.ligature, + in, out, + flags, context_length, gsub->gdef ); + break; + + case GSUB_LOOKUP_CONTEXT: + error = Lookup_ContextSubst( gsub, &lo->SubTable[i].st.gsub.context, + in, out, + flags, context_length, nesting_level ); + break; + + case GSUB_LOOKUP_CHAIN: + error = Lookup_ChainContextSubst( gsub, + &lo->SubTable[i].st.gsub.chain, + in, out, + flags, context_length, + nesting_level ); + break; + } + + /* Check whether we have a successful substitution or an error other + than TTO_Err_Not_Covered */ + + if ( error != TTO_Err_Not_Covered ) + return error; + } + + return TTO_Err_Not_Covered; + } + + + /* apply one lookup to the input string object */ + + static TT_Error Do_String_Lookup( TTO_GSUBHeader* gsub, + UShort lookup_index, + TTO_GSUB_String* in, + TTO_GSUB_String* out ) + { + TT_Error error = TTO_Err_Not_Covered; + + UShort* properties = gsub->LookupList.Properties; + UShort* p_in = in->properties; + UShort* s_in = in->string; + + int nesting_level = 0; + + + while ( in->pos < in->length ) + { + if ( ~p_in[in->pos] & properties[lookup_index] ) + { + /* 0xFFFF indicates that we don't have a context length yet */ + error = Do_Glyph_Lookup( gsub, lookup_index, in, out, + 0xFFFF, nesting_level ); + if ( error && error != TTO_Err_Not_Covered ) + return error; + } + else + error = TTO_Err_Not_Covered; + + if ( error == TTO_Err_Not_Covered ) + if ( ADD_String( in, 1, out, 1, &s_in[in->pos] ) ) + return error; + } + + return error; + } + + + EXPORT_FUNC + TT_Error TT_GSUB_Add_Feature( TTO_GSUBHeader* gsub, + TT_UShort feature_index, + TT_UShort property ) + { + UShort i; + + TTO_Feature feature; + UShort* properties; + UShort* index; + + + if ( !gsub || + feature_index >= gsub->FeatureList.FeatureCount ) + return TT_Err_Invalid_Argument; + + properties = gsub->LookupList.Properties; + + feature = gsub->FeatureList.FeatureRecord[feature_index].Feature; + index = feature.LookupListIndex; + + for ( i = 0; i < feature.LookupListCount; i++ ) + properties[index[i]] |= property; + + return TT_Err_Ok; + } + + + EXPORT_FUNC + TT_Error TT_GSUB_Clear_Features( TTO_GSUBHeader* gsub ) + { + UShort i; + + UShort* properties; + + + if ( !gsub ) + return TT_Err_Invalid_Argument; + + properties = gsub->LookupList.Properties; + + for ( i = 0; i < gsub->LookupList.LookupCount; i++ ) + properties[i] = 0; + + return TT_Err_Ok; + } + + + EXPORT_FUNC + TT_Error TT_GSUB_Register_Alternate_Function( TTO_GSUBHeader* gsub, + TTO_AltFunction alt, + void* data ) + { + if ( !gsub ) + return TT_Err_Invalid_Argument; + + gsub->alt = alt; + gsub->data = data; + + return TT_Err_Ok; + } + + + EXPORT_FUNC + TT_Error TT_GSUB_Apply_String( TTO_GSUBHeader* gsub, + TTO_GSUB_String* in, + TTO_GSUB_String* out ) + { + TT_Error error = TTO_Err_Not_Covered; + UShort j; + + TTO_GSUB_String tmp1; + TTO_GSUB_String* ptmp1; + TTO_GSUB_String tmp2; + TTO_GSUB_String* ptmp2; + TTO_GSUB_String* t; + + UShort* properties; + + + if ( !gsub || + !in || !out || in->length == 0 || in->pos >= in->length ) + return TT_Err_Invalid_Argument; + + properties = gsub->LookupList.Properties; + + tmp1.length = in->length; + tmp1.allocated = in->length; + tmp1.pos = in->pos; + + if ( ALLOC_ARRAY( tmp1.string, tmp1.length, UShort ) ) + return error; + MEM_Copy( tmp1.string, in->string, in->length * sizeof ( UShort ) ); + + /* make sure that we always have a `properties' array in the string + object */ + + if ( ALLOC_ARRAY( tmp1.properties, tmp1.length, UShort ) ) + return error; + if ( in->properties ) + MEM_Copy( tmp1.properties, in->properties, + in->length * sizeof( UShort ) ); + + tmp2.allocated = 0; + tmp2.pos = 0; + tmp2.string = NULL; + tmp2.properties = NULL; + + ptmp1 = &tmp1; + ptmp2 = &tmp2; + + for ( j = 0; j < gsub->LookupList.LookupCount; j++ ) + if ( properties[j] ) + { + error = Do_String_Lookup( gsub, j, ptmp1, ptmp2 ); + if ( error && error != TTO_Err_Not_Covered ) + return error; + + /* flipping `in' and `out', preparing for the next loop */ + + ptmp1->pos = in->pos; + ptmp2->length = ptmp2->pos; + ptmp2->pos = in->pos; + + t = ptmp2; + ptmp2 = ptmp1; + ptmp1 = t; + } + + out->length = ptmp1->length; + out->pos = 0; + out->allocated = ptmp1->allocated; + out->string = ptmp1->string; + + if ( in->properties ) + out->properties = ptmp1->properties; + else + { + free( ptmp1->properties ); + out->properties = NULL; + } + + free( ptmp2->string ); + free( ptmp2->properties ); + + return error; + } + + +/* END */ diff --git a/lib/extend/ftxgsub.h b/lib/extend/ftxgsub.h new file mode 100644 index 0000000..b444c92 --- /dev/null +++ b/lib/extend/ftxgsub.h @@ -0,0 +1,581 @@ +/******************************************************************* + * + * ftxgsub.h + * + * TrueType Open GSUB table support + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef FTXOPEN_H +#error "Don't include this file! Use ftxopen.h instead." +#endif + +#ifndef FTXGSUB_H +#define FTXGSUB_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define TTO_Err_Invalid_GSUB_SubTable_Format 0x1010 +#define TTO_Err_Invalid_GSUB_SubTable 0x1011 + + +/* Lookup types for glyph substitution */ + +#define GSUB_LOOKUP_SINGLE 1 +#define GSUB_LOOKUP_MULTIPLE 2 +#define GSUB_LOOKUP_ALTERNATE 3 +#define GSUB_LOOKUP_LIGATURE 4 +#define GSUB_LOOKUP_CONTEXT 5 +#define GSUB_LOOKUP_CHAIN 6 + + +/* Use this if a feature applies to all glyphs */ + +#define ALL_GLYPHS 0xFFFF + + + /* A pointer to a function which selects the alternate glyph. `pos' is + the position of the glyph with index `glyphID', `num_alternates' + gives the number of alternates in the `alternates' array. `data' + points to the user-defined structure specified during a call to + TT_GSUB_Register_Alternate_Function(). The function must return an + index into the `alternates' array. */ + + typedef TT_UShort (*TTO_AltFunction)(TT_ULong pos, + TT_UShort glyphID, + TT_UShort num_alternates, + TT_UShort* alternates, + void* data ); + + + struct TTO_GSUBHeader_ + { + TT_Bool loaded; + TT_ULong offset; + + TT_Fixed Version; + + TTO_ScriptList ScriptList; + TTO_FeatureList FeatureList; + TTO_LookupList LookupList; + + TTO_GDEFHeader* gdef; + + /* the next two fields are used for an alternate substitution callback + function to select the proper alternate glyph. */ + + TTO_AltFunction alt; + void* data; + }; + + typedef struct TTO_GSUBHeader_ TTO_GSUBHeader; + + + /* LookupType 1 */ + + struct TTO_SingleSubstFormat1_ + { + TT_Short DeltaGlyphID; /* constant added to get + substitution glyph index */ + }; + + typedef struct TTO_SingleSubstFormat1_ TTO_SingleSubstFormat1; + + + struct TTO_SingleSubstFormat2_ + { + TT_UShort GlyphCount; /* number of glyph IDs in + Substitute array */ + TT_UShort* Substitute; /* array of substitute glyph IDs */ + }; + + typedef struct TTO_SingleSubstFormat2_ TTO_SingleSubstFormat2; + + + struct TTO_SingleSubst_ + { + TT_UShort SubstFormat; /* 1 or 2 */ + TTO_Coverage Coverage; /* Coverage table */ + + union + { + TTO_SingleSubstFormat1 ssf1; + TTO_SingleSubstFormat2 ssf2; + } ssf; + }; + + typedef struct TTO_SingleSubst_ TTO_SingleSubst; + + + /* LookupType 2 */ + + struct TTO_Sequence_ + { + TT_UShort GlyphCount; /* number of glyph IDs in the + Substitute array */ + TT_UShort* Substitute; /* string of glyph IDs to + substitute */ + }; + + typedef struct TTO_Sequence_ TTO_Sequence; + + + struct TTO_MultipleSubst_ + { + TT_UShort SubstFormat; /* always 1 */ + TTO_Coverage Coverage; /* Coverage table */ + TT_UShort SequenceCount; /* number of Sequence tables */ + TTO_Sequence* Sequence; /* array of Sequence tables */ + }; + + typedef struct TTO_MultipleSubst_ TTO_MultipleSubst; + + + /* LookupType 3 */ + + struct TTO_AlternateSet_ + { + TT_UShort GlyphCount; /* number of glyph IDs in the + Alternate array */ + TT_UShort* Alternate; /* array of alternate glyph IDs */ + }; + + typedef struct TTO_AlternateSet_ TTO_AlternateSet; + + + struct TTO_AlternateSubst_ + { + TT_UShort SubstFormat; /* always 1 */ + TTO_Coverage Coverage; /* Coverage table */ + TT_UShort AlternateSetCount; + /* number of AlternateSet tables */ + TTO_AlternateSet* AlternateSet; /* array of AlternateSet tables */ + }; + + typedef struct TTO_AlternateSubst_ TTO_AlternateSubst; + + + /* LookupType 4 */ + + struct TTO_Ligature_ + { + TT_UShort LigGlyph; /* glyphID of ligature + to substitute */ + TT_UShort ComponentCount; /* number of components in ligature */ + TT_UShort* Component; /* array of component glyph IDs */ + }; + + typedef struct TTO_Ligature_ TTO_Ligature; + + + struct TTO_LigatureSet_ + { + TT_UShort LigatureCount; /* number of Ligature tables */ + TTO_Ligature* Ligature; /* array of Ligature tables */ + }; + + typedef struct TTO_LigatureSet_ TTO_LigatureSet; + + + struct TTO_LigatureSubst_ + { + TT_UShort SubstFormat; /* always 1 */ + TTO_Coverage Coverage; /* Coverage table */ + TT_UShort LigatureSetCount; /* number of LigatureSet tables */ + TTO_LigatureSet* LigatureSet; /* array of LigatureSet tables */ + }; + + typedef struct TTO_LigatureSubst_ TTO_LigatureSubst; + + + /* needed by both lookup type 5 and 6 */ + + struct TTO_SubstLookupRecord_ + { + TT_UShort SequenceIndex; /* index into current + glyph sequence */ + TT_UShort LookupListIndex; /* Lookup to apply to that pos. */ + }; + + typedef struct TTO_SubstLookupRecord_ TTO_SubstLookupRecord; + + + /* LookupType 5 */ + + struct TTO_SubRule_ + { + TT_UShort GlyphCount; /* total number of input glyphs */ + TT_UShort SubstCount; /* number of SubstLookupRecord + tables */ + TT_UShort* Input; /* array of input glyph IDs */ + TTO_SubstLookupRecord* SubstLookupRecord; + /* array of SubstLookupRecord + tables */ + }; + + typedef struct TTO_SubRule_ TTO_SubRule; + + + struct TTO_SubRuleSet_ + { + TT_UShort SubRuleCount; /* number of SubRule tables */ + TTO_SubRule* SubRule; /* array of SubRule tables */ + }; + + typedef struct TTO_SubRuleSet_ TTO_SubRuleSet; + + + struct TTO_ContextSubstFormat1_ + { + TTO_Coverage Coverage; /* Coverage table */ + TT_UShort SubRuleSetCount; /* number of SubRuleSet tables */ + TTO_SubRuleSet* SubRuleSet; /* array of SubRuleSet tables */ + }; + + typedef struct TTO_ContextSubstFormat1_ TTO_ContextSubstFormat1; + + + struct TTO_SubClassRule_ + { + TT_UShort GlyphCount; /* total number of context classes */ + TT_UShort SubstCount; /* number of SubstLookupRecord + tables */ + TT_UShort* Class; /* array of classes */ + TTO_SubstLookupRecord* SubstLookupRecord; + /* array of SubstLookupRecord + tables */ + }; + + typedef struct TTO_SubClassRule_ TTO_SubClassRule; + + + struct TTO_SubClassSet_ + { + TT_UShort SubClassRuleCount; + /* number of SubClassRule tables */ + TTO_SubClassRule* SubClassRule; /* array of SubClassRule tables */ + }; + + typedef struct TTO_SubClassSet_ TTO_SubClassSet; + + + /* The `MaxContextLength' field is not defined in the TTO specification + but simplifies the implementation of this format. It holds the + maximal context length used in the context rules. */ + + struct TTO_ContextSubstFormat2_ + { + TT_UShort MaxContextLength; + /* maximal context length */ + TTO_Coverage Coverage; /* Coverage table */ + TTO_ClassDefinition ClassDef; /* ClassDef table */ + TT_UShort SubClassSetCount; + /* number of SubClassSet tables */ + TTO_SubClassSet* SubClassSet; /* array of SubClassSet tables */ + }; + + typedef struct TTO_ContextSubstFormat2_ TTO_ContextSubstFormat2; + + + struct TTO_ContextSubstFormat3_ + { + TT_UShort GlyphCount; /* number of input glyphs */ + TT_UShort SubstCount; /* number of SubstLookupRecords */ + TTO_Coverage* Coverage; /* array of Coverage tables */ + TTO_SubstLookupRecord* SubstLookupRecord; + /* array of substitution lookups */ + }; + + typedef struct TTO_ContextSubstFormat3_ TTO_ContextSubstFormat3; + + + struct TTO_ContextSubst_ + { + TT_UShort SubstFormat; /* 1, 2, or 3 */ + + union + { + TTO_ContextSubstFormat1 csf1; + TTO_ContextSubstFormat2 csf2; + TTO_ContextSubstFormat3 csf3; + } csf; + }; + + typedef struct TTO_ContextSubst_ TTO_ContextSubst; + + + /* LookupType 6 */ + + struct TTO_ChainSubRule_ + { + TT_UShort BacktrackGlyphCount; + /* total number of backtrack glyphs */ + TT_UShort* Backtrack; /* array of backtrack glyph IDs */ + TT_UShort InputGlyphCount; + /* total number of input glyphs */ + TT_UShort* Input; /* array of input glyph IDs */ + TT_UShort LookaheadGlyphCount; + /* total number of lookahead glyphs */ + TT_UShort* Lookahead; /* array of lookahead glyph IDs */ + TT_UShort SubstCount; /* number of SubstLookupRecords */ + TTO_SubstLookupRecord* SubstLookupRecord; + /* array of SubstLookupRecords */ + }; + + typedef struct TTO_ChainSubRule_ TTO_ChainSubRule; + + + struct TTO_ChainSubRuleSet_ + { + TT_UShort ChainSubRuleCount; + /* number of ChainSubRule tables */ + TTO_ChainSubRule* ChainSubRule; /* array of ChainSubRule tables */ + }; + + typedef struct TTO_ChainSubRuleSet_ TTO_ChainSubRuleSet; + + + struct TTO_ChainContextSubstFormat1_ + { + TTO_Coverage Coverage; /* Coverage table */ + TT_UShort ChainSubRuleSetCount; + /* number of ChainSubRuleSet tables */ + TTO_ChainSubRuleSet* ChainSubRuleSet; + /* array of ChainSubRuleSet tables */ + }; + + typedef struct TTO_ChainContextSubstFormat1_ TTO_ChainContextSubstFormat1; + + + struct TTO_ChainSubClassRule_ + { + TT_UShort BacktrackGlyphCount; + /* total number of backtrack + classes */ + TT_UShort* Backtrack; /* array of backtrack classes */ + TT_UShort InputGlyphCount; + /* total number of context classes */ + TT_UShort* Input; /* array of context classes */ + TT_UShort LookaheadGlyphCount; + /* total number of lookahead + classes */ + TT_UShort* Lookahead; /* array of lookahead classes */ + TT_UShort SubstCount; /* number of SubstLookupRecords */ + TTO_SubstLookupRecord* SubstLookupRecord; + /* array of substitution lookups */ + }; + + typedef struct TTO_ChainSubClassRule_ TTO_ChainSubClassRule; + + + struct TTO_ChainSubClassSet_ + { + TT_UShort ChainSubClassRuleCount; + /* number of ChainSubClassRule + tables */ + TTO_ChainSubClassRule* ChainSubClassRule; + /* array of ChainSubClassRule + tables */ + }; + + typedef struct TTO_ChainSubClassSet_ TTO_ChainSubClassSet; + + + /* The `MaxXXXLength' fields are not defined in the TTO specification + but simplifies the implementation of this format. It holds the + maximal context length used in the specific context rules. */ + + struct TTO_ChainContextSubstFormat2_ + { + TTO_Coverage Coverage; /* Coverage table */ + + TT_UShort MaxBacktrackLength; + /* maximal backtrack length */ + TTO_ClassDefinition BacktrackClassDef; + /* BacktrackClassDef table */ + TT_UShort MaxInputLength; + /* maximal input length */ + TTO_ClassDefinition InputClassDef; + /* InputClassDef table */ + TT_UShort MaxLookaheadLength; + /* maximal lookahead length */ + TTO_ClassDefinition LookaheadClassDef; + /* LookaheadClassDef table */ + + TT_UShort ChainSubClassSetCount; + /* number of ChainSubClassSet + tables */ + TTO_ChainSubClassSet* ChainSubClassSet; + /* array of ChainSubClassSet + tables */ + }; + + typedef struct TTO_ChainContextSubstFormat2_ TTO_ChainContextSubstFormat2; + + + struct TTO_ChainContextSubstFormat3_ + { + TT_UShort BacktrackGlyphCount; + /* number of backtrack glyphs */ + TTO_Coverage* BacktrackCoverage; + /* array of backtrack Coverage + tables */ + TT_UShort InputGlyphCount; + /* number of input glyphs */ + TTO_Coverage* InputCoverage; + /* array of input coverage + tables */ + TT_UShort LookaheadGlyphCount; + /* number of lookahead glyphs */ + TTO_Coverage* LookaheadCoverage; + /* array of lookahead coverage + tables */ + TT_UShort SubstCount; /* number of SubstLookupRecords */ + TTO_SubstLookupRecord* SubstLookupRecord; + /* array of substitution lookups */ + }; + + typedef struct TTO_ChainContextSubstFormat3_ TTO_ChainContextSubstFormat3; + + + struct TTO_ChainContextSubst_ + { + TT_UShort SubstFormat; /* 1, 2, or 3 */ + + union + { + TTO_ChainContextSubstFormat1 ccsf1; + TTO_ChainContextSubstFormat2 ccsf2; + TTO_ChainContextSubstFormat3 ccsf3; + } ccsf; + }; + + typedef struct TTO_ChainContextSubst_ TTO_ChainContextSubst; + + + union TTO_GSUB_SubTable_ + { + TTO_SingleSubst single; + TTO_MultipleSubst multiple; + TTO_AlternateSubst alternate; + TTO_LigatureSubst ligature; + TTO_ContextSubst context; + TTO_ChainContextSubst chain; + }; + + typedef union TTO_GSUB_SubTable_ TTO_GSUB_SubTable; + + + /* A simple string object. It can both `send' and `receive' data. + In case of sending, `length' and `pos' will be used. In case of + receiving, `pos' points to the first free slot, and `allocated' + specifies the amount of allocated memory (and the `length' field + will be ignored). The routine TT_Add_String() will increase the + amount of memory if necessary. After end of receive, `length' + should be set to the value of `pos', and `pos' will be set to zero. + + `properties' (which is treated as a bit field) gives the glyph's + properties: If a certain bit is set for a glyph, the feature which + has the same bit set in its property value is applied. + + NEVER modify any elements of the structure! You should rather copy + its contents if necessary. + + TT_Add_String() will also handle allocation; you should use + free() in case you want to destroy the arrays in the object. */ + + struct TTO_GSUB_String_ + { + TT_ULong length; + TT_ULong pos; + TT_ULong allocated; + TT_UShort* string; + TT_UShort* properties; + }; + + typedef struct TTO_GSUB_String_ TTO_GSUB_String; + + + /* finally, the GSUB API */ + + EXPORT_DEF + TT_Error TT_Init_GSUB_Extension( TT_Engine engine ); + + EXPORT_DEF + TT_Error TT_Load_GSUB_Table( TT_Face face, + TTO_GSUBHeader* gsub, + TTO_GDEFHeader* gdef ); + + EXPORT_DEF + TT_Error TT_GSUB_Select_Script( TTO_GSUBHeader* gsub, + TT_ULong script_tag, + TT_UShort* script_index ); + EXPORT_DEF + TT_Error TT_GSUB_Select_Language( TTO_GSUBHeader* gsub, + TT_ULong language_tag, + TT_UShort script_index, + TT_UShort* language_index, + TT_UShort* req_feature_index ); + EXPORT_DEF + TT_Error TT_GSUB_Select_Feature( TTO_GSUBHeader* gsub, + TT_ULong feature_tag, + TT_UShort script_index, + TT_UShort language_index, + TT_UShort* feature_index ); + + EXPORT_DEF + TT_Error TT_GSUB_Query_Scripts( TTO_GSUBHeader* gsub, + TT_ULong** script_tag_list ); + EXPORT_DEF + TT_Error TT_GSUB_Query_Languages( TTO_GSUBHeader* gsub, + TT_UShort script_index, + TT_ULong** language_tag_list ); + EXPORT_DEF + TT_Error TT_GSUB_Query_Features( TTO_GSUBHeader* gsub, + TT_UShort script_index, + TT_UShort language_index, + TT_ULong** feature_tag_list ); + + EXPORT_DEF + TT_Error TT_GSUB_Add_Feature( TTO_GSUBHeader* gsub, + TT_UShort feature_index, + TT_UShort property ); + EXPORT_DEF + TT_Error TT_GSUB_Clear_Features( TTO_GSUBHeader* gsub ); + + EXPORT_DEF + TT_Error TT_GSUB_Register_Alternate_Function( TTO_GSUBHeader* gsub, + TTO_AltFunction alt, + void* data ); + + EXPORT_DEF + TT_Error TT_GSUB_Apply_String( TTO_GSUBHeader* gsub, + TTO_GSUB_String* in, + TTO_GSUB_String* out ); + + EXPORT_DEF + TT_Error TT_GSUB_Add_String( TTO_GSUB_String* in, + TT_UShort num_in, + TTO_GSUB_String* out, + TT_UShort num_out, + TT_UShort* data ); + +#ifdef __cplusplus +} +#endif + +#endif /* FTXGSUB_H */ + + +/* END */ diff --git a/lib/extend/ftxkern.c b/lib/extend/ftxkern.c new file mode 100644 index 0000000..e2704ae --- /dev/null +++ b/lib/extend/ftxkern.c @@ -0,0 +1,564 @@ +/******************************************************************* + * + * ftxkern.c 1.0 + * + * Kerning support extension. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * The kerning support is currently part of the engine extensions. + * + ******************************************************************/ + +#include "ftxkern.h" + +#include "ttextend.h" +#include "tttypes.h" +#include "ttdebug.h" +#include "ttmemory.h" +#include "ttfile.h" +#include "ttobjs.h" +#include "ttload.h" /* For the macros */ +#include "tttags.h" + +/* Required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_any + +#define KERNING_ID Build_Extension_ID( 'k', 'e', 'r', 'n' ) + + +/******************************************************************* + * + * Function : SubTable_Load_0 + * + * Description : Loads a format 0 kerning subtable data. + * + * Input : kern0 pointer to the kerning subtable + * + * Output : error code + * + * Notes : - Assumes that the stream is already `used' + * + * - the file cursor must be set by the caller + * + * - in case of error, the function _must_ destroy + * the data it allocates! + * + ******************************************************************/ + + static TT_Error Subtable_Load_0( TT_Kern_0* kern0, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort num_pairs, n; + + + if ( ACCESS_Frame( 8L ) ) + return error; + + num_pairs = GET_UShort(); + kern0->nPairs = 0; + kern0->searchRange = GET_UShort(); + kern0->entrySelector = GET_UShort(); + kern0->rangeShift = GET_UShort(); + + /* we only set kern0->nPairs if the subtable has been loaded */ + + FORGET_Frame(); + + if ( ALLOC_ARRAY( kern0->pairs, num_pairs, TT_Kern_0_Pair ) ) + return error; + + if ( ACCESS_Frame( num_pairs * 6L ) ) + goto Fail; + + for ( n = 0; n < num_pairs; n++ ) + { + kern0->pairs[n].left = GET_UShort(); + kern0->pairs[n].right = GET_UShort(); + kern0->pairs[n].value = GET_UShort(); + + if ( kern0->pairs[n].left >= input->numGlyphs || + kern0->pairs[n].right >= input->numGlyphs ) + { + FORGET_Frame(); + error = TT_Err_Invalid_Kerning_Table; + goto Fail; + } + } + + FORGET_Frame(); + + /* we're ok, set the pairs count */ + kern0->nPairs = num_pairs; + + return TT_Err_Ok; + + Fail: + FREE( kern0->pairs ); + return error; + } + + +/******************************************************************* + * + * Function : SubTable_Load_2 + * + * Description : Loads a format 2 kerning subtable data. + * + * Input : kern2 pointer to the kerning subtable + * length subtable length. This is required as + * the subheader doesn't give any indication + * of the size of the `array' table. + * + * Output : error code + * + * Notes : - Assumes that the stream is already `used' + * + * - the file cursor must be set by the caller + * + * - in case of error, the function _must_ destroy + * the data it allocates! + * + ******************************************************************/ + + static TT_Error Subtable_Load_2( TT_Kern_2* kern2, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + Long table_base; + + UShort left_offset, right_offset, array_offset; + ULong array_size; + UShort left_max, right_max, n; + + + /* record the table offset */ + table_base = FILE_Pos(); + + if ( ACCESS_Frame( 8L ) ) + return error; + + kern2->rowWidth = GET_UShort(); + left_offset = GET_UShort(); + right_offset = GET_UShort(); + array_offset = GET_UShort(); + + FORGET_Frame(); + + /* first load left and right glyph classes */ + + if ( FILE_Seek( table_base + left_offset ) || + ACCESS_Frame( 4L ) ) + return error; + + kern2->leftClass.firstGlyph = GET_UShort(); + kern2->leftClass.nGlyphs = GET_UShort(); + + FORGET_Frame(); + + if ( ALLOC_ARRAY( kern2->leftClass.classes, + kern2->leftClass.nGlyphs, + UShort ) ) + return error; + + /* load left offsets */ + + if ( ACCESS_Frame( kern2->leftClass.nGlyphs * 2L ) ) + goto Fail_Left; + + for ( n = 0; n < kern2->leftClass.nGlyphs; n++ ) + kern2->leftClass.classes[n] = GET_UShort(); + + FORGET_Frame(); + + /* right class */ + + if ( FILE_Seek( table_base + right_offset ) || + ACCESS_Frame( 4L ) ) + goto Fail_Left; + + kern2->rightClass.firstGlyph = GET_UShort(); + kern2->rightClass.nGlyphs = GET_UShort(); + + FORGET_Frame(); + + if ( ALLOC_ARRAY( kern2->rightClass.classes, + kern2->rightClass.nGlyphs, + UShort ) ) + goto Fail_Left; + + /* load right offsets */ + + if ( ACCESS_Frame( kern2->rightClass.nGlyphs * 2L ) ) + goto Fail_Right; + + for ( n = 0; n < kern2->rightClass.nGlyphs; n++ ) + kern2->rightClass.classes[n] = GET_UShort(); + + FORGET_Frame(); + + /* Now load the kerning array. We don't have its size, we */ + /* must compute it from what we know. */ + + /* We thus compute the maximum left and right offsets and */ + /* add them to get the array size. */ + + left_max = right_max = 0; + + for ( n = 0; n < kern2->leftClass.nGlyphs; n++ ) + left_max = MAX( left_max, kern2->leftClass.classes[n] ); + + for ( n = 0; n < kern2->rightClass.nGlyphs; n++ ) + right_max = MAX( right_max, kern2->leftClass.classes[n] ); + + array_size = left_max + right_max + 2; + + if ( ALLOC( kern2->array, array_size ) ) + goto Fail_Right; + + if ( ACCESS_Frame( array_size ) ) + goto Fail_Array; + + for ( n = 0; n < array_size/2; n++ ) + kern2->array[n] = GET_Short(); + + FORGET_Frame(); + + /* we're good now */ + + return TT_Err_Ok; + + Fail_Array: + FREE( kern2->array ); + + Fail_Right: + FREE( kern2->rightClass.classes ); + kern2->rightClass.nGlyphs = 0; + + Fail_Left: + FREE( kern2->leftClass.classes ); + kern2->leftClass.nGlyphs = 0; + + return error; + } + + +/******************************************************************* + * + * Function : Kerning_Create + * + * Description : Creates the kerning directory if a face is + * loaded. The tables however are loaded on + * demand to save space. + * + * Input : face pointer to the parent face object + * kern pointer to the extension's kerning field + * + * Output : error code + * + * Notes : as in all constructors, the memory allocated isn't + * released in case of failure. Rather, the task is left + * to the destructor (which is called if an error + * occurs during the loading of a face). + * + ******************************************************************/ + + static TT_Error Kerning_Create( void* ext, + PFace face ) + { + DEFINE_LOAD_LOCALS( face->stream ); + + TT_Kerning* kern = (TT_Kerning*)ext; + UShort num_tables; + Long table; + + TT_Kern_Subtable* sub; + + + /* by convention */ + if ( !kern ) + return TT_Err_Ok; + + /* Now load the kerning directory. We're called from the face */ + /* constructor. We thus need not use the stream. */ + + kern->version = 0; + kern->nTables = 0; + kern->tables = NULL; + + table = TT_LookUp_Table( face, TTAG_kern ); + if ( table < 0 ) + return TT_Err_Ok; /* The table is optional */ + + if ( FILE_Seek( face->dirTables[table].Offset ) || + ACCESS_Frame( 4L ) ) + return error; + + kern->version = GET_UShort(); + num_tables = GET_UShort(); + + FORGET_Frame(); + + /* we don't set kern->nTables until we have allocated the array */ + + if ( ALLOC_ARRAY( kern->tables, num_tables, TT_Kern_Subtable ) ) + return error; + + kern->nTables = num_tables; + + /* now load the directory entries, but do _not_ load the tables ! */ + + sub = kern->tables; + + for ( table = 0; table < num_tables; table++ ) + { + if ( ACCESS_Frame( 6L ) ) + return error; + + sub->loaded = FALSE; /* redundant, but good to see */ + sub->version = GET_UShort(); + sub->length = GET_UShort() - 6; /* substract header length */ + sub->format = GET_Byte(); + sub->coverage = GET_Byte(); + + FORGET_Frame(); + + sub->offset = FILE_Pos(); + + /* now skip to the next table */ + + if ( FILE_Skip( sub->length ) ) + return error; + + sub++; + } + + /* that's fine, leave now */ + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Kerning_Destroy + * + * Description : Destroys all kerning information. + * + * Input : kern pointer to the extension's kerning field + * + * Output : error code + * + * Notes : This function is a destructor; it must be able + * to destroy partially built tables. + * + ******************************************************************/ + + static TT_Error Kerning_Destroy( void* ext, + PFace face ) + { + TT_Kerning* kern = (TT_Kerning*)ext; + TT_Kern_Subtable* sub; + UShort n; + + + /* by convention */ + if ( !kern ) + return TT_Err_Ok; + + if ( kern->nTables == 0 ) + return TT_Err_Ok; /* no tables to release */ + + /* scan the table directory and release loaded entries */ + + sub = kern->tables; + for ( n = 0; n < kern->nTables; n++ ) + { + if ( sub->loaded ) + { + switch ( sub->format ) + { + case 0: + FREE( sub->t.kern0.pairs ); + sub->t.kern0.nPairs = 0; + sub->t.kern0.searchRange = 0; + sub->t.kern0.entrySelector = 0; + sub->t.kern0.rangeShift = 0; + break; + + case 2: + FREE( sub->t.kern2.leftClass.classes ); + sub->t.kern2.leftClass.firstGlyph = 0; + sub->t.kern2.leftClass.nGlyphs = 0; + + FREE( sub->t.kern2.rightClass.classes ); + sub->t.kern2.rightClass.firstGlyph = 0; + sub->t.kern2.rightClass.nGlyphs = 0; + + FREE( sub->t.kern2.array ); + sub->t.kern2.rowWidth = 0; + break; + + default: + ; /* invalid subtable format - do nothing */ + } + + sub->loaded = FALSE; + sub->version = 0; + sub->offset = 0; + sub->length = 0; + sub->coverage = 0; + sub->format = 0; + } + sub++; + } + + FREE( kern->tables ); + kern->nTables = 0; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Get_Kerning_Directory + * + * Description : Returns a given face's kerning directory. + * + * Input : face handle to the face object + * directory pointer to client's target directory + * + * Output : error code + * + * Notes : The kerning table directory is loaded with the face + * through the extension constructor. However, the kerning + * tables themselves are only loaded on demand, as they + * may represent a lot of data, unneeded by most uses of + * the engine. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Kerning_Directory( TT_Face face, + TT_Kerning* directory ) + { + PFace faze = HANDLE_Face( face ); + TT_Error error; + TT_Kerning* kerning; + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + /* copy directory header */ + error = TT_Extension_Get( faze, KERNING_ID, (void**)&kerning ); + if ( !error ) + *directory = *kerning; + + return error; + } + + +/******************************************************************* + * + * Function : TT_Load_Kerning_Table + * + * Description : Loads a kerning table intro memory. + * + * Input : face face handle + * kern_index index in the face's kerning directory + * + * Output : error code + * + * Notes : + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Load_Kerning_Table( TT_Face face, + TT_UShort kern_index ) + { + TT_Error error; + TT_Stream stream; + + TT_Kerning* kern; + TT_Kern_Subtable* sub; + + + PFace faze = HANDLE_Face( face ); + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + error = TT_Extension_Get( faze, KERNING_ID, (void**)&kern ); + if ( error ) + return error; + + if ( kern->nTables == 0 ) + return TT_Err_Table_Missing; + + if ( kern_index >= kern->nTables ) + return TT_Err_Invalid_Argument; + + sub = kern->tables + kern_index; + + if ( sub->format != 0 && sub->format != 2 ) + return TT_Err_Invalid_Kerning_Table_Format; + + /* now access stream */ + if ( USE_Stream( faze->stream, stream ) ) + return error; + + if ( FILE_Seek( sub->offset ) ) + goto Fail; + + if ( sub->format == 0 ) + error = Subtable_Load_0( &sub->t.kern0, faze ); + else if ( sub->format == 2 ) + error = Subtable_Load_2( &sub->t.kern2, faze ); + + if ( !error ) + sub->loaded = TRUE; + + Fail: + /* release stream */ + DONE_Stream( stream ); + + return error; + } + + + EXPORT_FUNC + TT_Error TT_Init_Kerning_Extension( TT_Engine engine ) + { + PEngine_Instance _engine = HANDLE_Engine( engine ); + + TT_Error error; + + + if ( !_engine ) + return TT_Err_Invalid_Engine; + + error = TT_Register_Extension( _engine, + KERNING_ID, + sizeof ( TT_Kerning ), + Kerning_Create, + Kerning_Destroy ); + return error; + } + + +/* END */ diff --git a/lib/extend/ftxkern.h b/lib/extend/ftxkern.h new file mode 100644 index 0000000..06e221e --- /dev/null +++ b/lib/extend/ftxkern.h @@ -0,0 +1,181 @@ +/******************************************************************* + * + * ftxkern.h 1.0 + * + * High-Level API Kerning extension + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * The kerning support is currently part of the engine extensions. + * + * This file should _not_ depend on engine internal types. + * + ******************************************************************/ + +#ifndef FTXKERN_H +#define FTXKERN_H + +#include "freetype.h" + +#ifdef __cplusplus +extern "C" { +#endif + + /* The kerning support in FreeType is minimal. This means that */ + /* we do not try to interpret the kerning data in any way to */ + /* `cook' it for a user application. This API lets you access */ + /* directly the kerning tables found in the TrueType file; it's */ + /* up to the client application to apply its own processing on */ + /* these. */ + + /* The reason for this is that we generally do not encourage */ + /* feature-bloat of the core engine. Moreover, not all */ + /* libraries or font servers really need kerning data, or all */ + /* formats of this data. */ + + /************** kerning error codes *****************************/ + + /* we choose the class 0x0A for our errors, this should not */ + /* match with any error code class used in any other extension */ + +#define TT_Err_Invalid_Kerning_Table_Format 0x0A00 +#define TT_Err_Invalid_Kerning_Table 0x0A01 + + + /********** structures definitions ******************************/ + + /* Remember that all types and function are accessible by client */ + /* applications in this section, and thus should have the `TT_' */ + /* prefix. */ + + /* format 0 kerning pair */ + + struct TT_Kern_0_Pair_ + { + TT_UShort left; /* index of left glyph in pair */ + TT_UShort right; /* index of right glyph in pair */ + TT_FWord value; /* kerning value */ + }; + + typedef struct TT_Kern_0_Pair_ TT_Kern_0_Pair; + + + /* format 0 kerning subtable */ + + struct TT_Kern_0_ + { + TT_UShort nPairs; /* number of kerning pairs */ + + TT_UShort searchRange; /* these values are defined by the TT spec */ + TT_UShort entrySelector; /* for table searchs. */ + TT_UShort rangeShift; + + TT_Kern_0_Pair* pairs; /* a table of nPairs `pairs' */ + }; + + typedef struct TT_Kern_0_ TT_Kern_0; + + + /* format 2 kerning glyph class */ + + struct TT_Kern_2_Class_ + { + TT_UShort firstGlyph; /* first glyph in range */ + TT_UShort nGlyphs; /* number of glyphs in range */ + TT_UShort* classes; /* a table giving for each ranged glyph */ + /* its class offset in the subtable pairs */ + /* two-dimensional array */ + }; + + typedef struct TT_Kern_2_Class_ TT_Kern_2_Class; + + + /* format 2 kerning subtable */ + + struct TT_Kern_2_ + { + TT_UShort rowWidth; /* length of one row in bytes */ + TT_Kern_2_Class leftClass; /* left class table */ + TT_Kern_2_Class rightClass; /* right class table */ + TT_FWord* array; /* 2-dimensional kerning values array */ + }; + + typedef struct TT_Kern_2_ TT_Kern_2; + + + /* kerning subtable */ + + struct TT_Kern_Subtable_ + { + TT_Bool loaded; /* boolean; indicates whether the table is */ + /* loaded */ + TT_UShort version; /* table version number */ + TT_Long offset; /* file offset of table */ + TT_UShort length; /* length of table, _excluding_ header */ + TT_Byte coverage; /* lower 8 bit of the coverage table entry */ + TT_Byte format; /* the subtable format, as found in the */ + /* higher 8 bits of the coverage table entry */ + union + { + TT_Kern_0 kern0; + TT_Kern_2 kern2; + } t; + }; + + typedef struct TT_Kern_Subtable_ TT_Kern_Subtable; + + + struct TT_Kerning_ + { + TT_UShort version; /* kern table version number. starts at 0 */ + TT_UShort nTables; /* number of tables */ + + TT_Kern_Subtable* tables; /* the kerning sub-tables */ + }; + + typedef struct TT_Kerning_ TT_Kerning; + + + + /***************** high-level API extension **************************/ + + /* Initialize Kerning extension, must be called after */ + /* TT_Init_FreeType(). There is no need for a finalizer */ + EXPORT_DEF + TT_Error TT_Init_Kerning_Extension( TT_Engine engine ); + + /* Note on the implemented mechanism: */ + + /* The kerning table directory is loaded with the face through the */ + /* extension constructor. However, the tables will only be loaded */ + /* on demand, as they may represent a lot of data, unnecessary to */ + /* most applications. */ + + /* Queries a pointer to the kerning directory for the face object */ + EXPORT_DEF + TT_Error TT_Get_Kerning_Directory( TT_Face face, + TT_Kerning* directory ); + + /* Load the kerning table number `kern_index' in the kerning */ + /* directory. The table will stay in memory until the `face' */ + /* face is destroyed. */ + EXPORT_DEF + TT_Error TT_Load_Kerning_Table( TT_Face face, + TT_UShort kern_index ); + +#ifdef __cplusplus +} +#endif + +#endif /* FTXKERN_H */ + + +/* END */ diff --git a/lib/extend/ftxopen.c b/lib/extend/ftxopen.c new file mode 100644 index 0000000..efe0c0f --- /dev/null +++ b/lib/extend/ftxopen.c @@ -0,0 +1,1439 @@ +/******************************************************************* + * + * ftxopen.c + * + * TrueType Open common table support. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include "tttypes.h" +#include "ttload.h" +#include "ttextend.h" +#include "ttmemory.h" +#include "ttfile.h" + +#include "ftxopen.h" +#include "ftxopenf.h" + + + /*************************** + * Script related functions + ***************************/ + + + /* LangSys */ + + static TT_Error Load_LangSys( TTO_LangSys* ls, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + + UShort* fi; + + + if ( ACCESS_Frame( 6L ) ) + return error; + + ls->LookupOrderOffset = GET_UShort(); /* should be 0 */ + ls->ReqFeatureIndex = GET_UShort(); + count = ls->FeatureCount = GET_UShort(); + + FORGET_Frame(); + + ls->FeatureIndex = NULL; + + if ( ALLOC_ARRAY( ls->FeatureIndex, count, UShort ) ) + return error; + + if ( ACCESS_Frame( count * 2L ) ) + { + FREE( ls->FeatureIndex ); + return error; + } + + fi = ls->FeatureIndex; + + for ( n = 0; n < count; n++ ) + fi[n] = GET_UShort(); + + FORGET_Frame(); + + return TT_Err_Ok; + } + + + static void Free_LangSys( TTO_LangSys* ls ) + { + FREE( ls->FeatureIndex ); + } + + + /* Script */ + + static TT_Error Load_Script( TTO_Script* s, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_LangSysRecord* lsr; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + if ( new_offset != base_offset ) /* not a NULL offset */ + { + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_LangSys( &s->DefaultLangSys, + input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + } + else + { + /* we create a DefaultLangSys table with no entries */ + + s->DefaultLangSys.LookupOrderOffset = 0; + s->DefaultLangSys.ReqFeatureIndex = 0xFFFF; + s->DefaultLangSys.FeatureCount = 0; + s->DefaultLangSys.FeatureIndex = NULL; + } + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = s->LangSysCount = GET_UShort(); + + /* safety check; otherwise the official handling of TrueType Open + fonts won't work */ + + if ( s->LangSysCount == 0 && s->DefaultLangSys.FeatureCount == 0 ) + { + error = TTO_Err_Invalid_SubTable; + goto Fail2; + } + + FORGET_Frame(); + + s->LangSysRecord = NULL; + + if ( ALLOC_ARRAY( s->LangSysRecord, count, TTO_LangSysRecord ) ) + goto Fail2; + + lsr = s->LangSysRecord; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 6L ) ) + goto Fail1; + + lsr[n].LangSysTag = GET_ULong(); + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_LangSys( &lsr[n].LangSys, input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_LangSys( &lsr[n].LangSys ); + + FREE( s->LangSysRecord ); + + Fail2: + Free_LangSys( &s->DefaultLangSys ); + return error; + } + + + static void Free_Script( TTO_Script* s ) + { + UShort n, count; + + TTO_LangSysRecord* lsr; + + + Free_LangSys( &s->DefaultLangSys ); + + if ( s->LangSysRecord ) + { + count = s->LangSysCount; + lsr = s->LangSysRecord; + + for ( n = 0; n < count; n++ ) + Free_LangSys( &lsr[n].LangSys ); + + FREE( lsr ); + } + } + + + /* ScriptList */ + + TT_Error Load_ScriptList( TTO_ScriptList* sl, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_ScriptRecord* sr; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = sl->ScriptCount = GET_UShort(); + + FORGET_Frame(); + + sl->ScriptRecord = NULL; + + if ( ALLOC_ARRAY( sl->ScriptRecord, count, TTO_ScriptRecord ) ) + return error; + + sr = sl->ScriptRecord; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 6L ) ) + goto Fail; + + sr[n].ScriptTag = GET_ULong(); + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Script( &sr[n].Script, input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_Script( &sr[n].Script ); + + FREE( sl->ScriptRecord ); + return error; + } + + + void Free_ScriptList( TTO_ScriptList* sl ) + { + UShort n, count; + + TTO_ScriptRecord* sr; + + + if ( sl->ScriptRecord ) + { + count = sl->ScriptCount; + sr = sl->ScriptRecord; + + for ( n = 0; n < count; n++ ) + Free_Script( &sr[n].Script ); + + FREE( sr ); + } + } + + + + /********************************* + * Feature List related functions + *********************************/ + + + /* Feature */ + + static TT_Error Load_Feature( TTO_Feature* f, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + + UShort* lli; + + + if ( ACCESS_Frame( 4L ) ) + return error; + + f->FeatureParams = GET_UShort(); /* should be 0 */ + count = f->LookupListCount = GET_UShort(); + + FORGET_Frame(); + + f->LookupListIndex = NULL; + + if ( ALLOC_ARRAY( f->LookupListIndex, count, UShort ) ) + return error; + + lli = f->LookupListIndex; + + if ( ACCESS_Frame( count * 2L ) ) + { + FREE( f->LookupListIndex ); + return error; + } + + for ( n = 0; n < count; n++ ) + lli[n] = GET_UShort(); + + FORGET_Frame(); + + return TT_Err_Ok; + } + + + static void Free_Feature( TTO_Feature* f ) + { + FREE( f->LookupListIndex ); + } + + + /* FeatureList */ + + TT_Error Load_FeatureList( TTO_FeatureList* fl, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_FeatureRecord* fr; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = fl->FeatureCount = GET_UShort(); + + FORGET_Frame(); + + fl->FeatureRecord = NULL; + + if ( ALLOC_ARRAY( fl->FeatureRecord, count, TTO_FeatureRecord ) ) + return error; + + fr = fl->FeatureRecord; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 6L ) ) + goto Fail; + + fr[n].FeatureTag = GET_ULong(); + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Feature( &fr[n].Feature, input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_Feature( &fr[n].Feature ); + + FREE( fl->FeatureRecord ); + return error; + } + + + void Free_FeatureList( TTO_FeatureList* fl ) + { + UShort n, count; + + TTO_FeatureRecord* fr; + + + if ( fl->FeatureRecord ) + { + count = fl->FeatureCount; + fr = fl->FeatureRecord; + + for ( n = 0; n < count; n++ ) + Free_Feature( &fr[n].Feature ); + + FREE( fr ); + } + } + + + + /******************************** + * Lookup List related functions + ********************************/ + + /* the subroutines of the following two functions are defined in + ftxgsub.c and ftxgpos.c respectively */ + + + /* SubTable */ + + static TT_Error Load_SubTable( TTO_SubTable* st, + PFace input, + TTO_Type table_type, + UShort lookup_type ) + { + if ( table_type == GSUB ) + switch ( lookup_type ) + { + case GSUB_LOOKUP_SINGLE: + return Load_SingleSubst( &st->st.gsub.single, input ); + + case GSUB_LOOKUP_MULTIPLE: + return Load_MultipleSubst( &st->st.gsub.multiple, input ); + + case GSUB_LOOKUP_ALTERNATE: + return Load_AlternateSubst( &st->st.gsub.alternate, input ); + + case GSUB_LOOKUP_LIGATURE: + return Load_LigatureSubst( &st->st.gsub.ligature, input ); + + case GSUB_LOOKUP_CONTEXT: + return Load_ContextSubst( &st->st.gsub.context, input ); + + case GSUB_LOOKUP_CHAIN: + return Load_ChainContextSubst( &st->st.gsub.chain, input ); + + default: + return TTO_Err_Invalid_GSUB_SubTable_Format; + } + else + switch ( lookup_type ) + { + case GPOS_LOOKUP_SINGLE: + return Load_SinglePos( &st->st.gpos.single, input ); + + case GPOS_LOOKUP_PAIR: + return Load_PairPos( &st->st.gpos.pair, input ); + + case GPOS_LOOKUP_CURSIVE: + return Load_CursivePos( &st->st.gpos.cursive, input ); + + case GPOS_LOOKUP_MARKBASE: + return Load_MarkBasePos( &st->st.gpos.markbase, input ); + + case GPOS_LOOKUP_MARKLIG: + return Load_MarkLigPos( &st->st.gpos.marklig, input ); + + case GPOS_LOOKUP_MARKMARK: + return Load_MarkMarkPos( &st->st.gpos.markmark, input ); + + case GPOS_LOOKUP_CONTEXT: + return Load_ContextPos( &st->st.gpos.context, input ); + + case GPOS_LOOKUP_CHAIN: + return Load_ChainContextPos ( &st->st.gpos.chain, input ); + + default: + return TTO_Err_Invalid_GPOS_SubTable_Format; + } + + return TT_Err_Ok; /* never reached */ + } + + + static void Free_SubTable( TTO_SubTable* st, + TTO_Type table_type, + UShort lookup_type ) + { + if ( table_type == GSUB ) + switch ( lookup_type ) + { + case GSUB_LOOKUP_SINGLE: + Free_SingleSubst( &st->st.gsub.single ); + break; + + case GSUB_LOOKUP_MULTIPLE: + Free_MultipleSubst( &st->st.gsub.multiple ); + break; + + case GSUB_LOOKUP_ALTERNATE: + Free_AlternateSubst( &st->st.gsub.alternate ); + break; + + case GSUB_LOOKUP_LIGATURE: + Free_LigatureSubst( &st->st.gsub.ligature ); + break; + + case GSUB_LOOKUP_CONTEXT: + Free_ContextSubst( &st->st.gsub.context ); + break; + + case GSUB_LOOKUP_CHAIN: + Free_ChainContextSubst( &st->st.gsub.chain ); + break; + } + else + switch ( lookup_type ) + { + case GPOS_LOOKUP_SINGLE: + Free_SinglePos( &st->st.gpos.single ); + break; + + case GPOS_LOOKUP_PAIR: + Free_PairPos( &st->st.gpos.pair ); + break; + + case GPOS_LOOKUP_CURSIVE: + Free_CursivePos( &st->st.gpos.cursive ); + break; + + case GPOS_LOOKUP_MARKBASE: + Free_MarkBasePos( &st->st.gpos.markbase ); + break; + + case GPOS_LOOKUP_MARKLIG: + Free_MarkLigPos( &st->st.gpos.marklig ); + break; + + case GPOS_LOOKUP_MARKMARK: + Free_MarkMarkPos( &st->st.gpos.markmark ); + break; + + case GPOS_LOOKUP_CONTEXT: + Free_ContextPos( &st->st.gpos.context ); + break; + + case GPOS_LOOKUP_CHAIN: + Free_ChainContextPos ( &st->st.gpos.chain ); + break; + } + } + + + /* Lookup */ + + static TT_Error Load_Lookup( TTO_Lookup* l, + PFace input, + TTO_Type type ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_SubTable* st; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 6L ) ) + return error; + + l->LookupType = GET_UShort(); + l->LookupFlag = GET_UShort(); + count = l->SubTableCount = GET_UShort(); + + FORGET_Frame(); + + l->SubTable = NULL; + + if ( ALLOC_ARRAY( l->SubTable, count, TTO_SubTable ) ) + return error; + + st = l->SubTable; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_SubTable( &st[n], input, + type, l->LookupType ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_SubTable( &st[n], type, l->LookupType ); + + FREE( l->SubTable ); + return error; + } + + + static void Free_Lookup( TTO_Lookup* l, + TTO_Type type ) + { + UShort n, count; + + TTO_SubTable* st; + + + if ( l->SubTable ) + { + count = l->SubTableCount; + st = l->SubTable; + + for ( n = 0; n < count; n++ ) + Free_SubTable( &st[n], type, l->LookupType ); + + FREE( st ); + } + } + + + /* LookupList */ + + TT_Error Load_LookupList( TTO_LookupList* ll, + PFace input, + TTO_Type type ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_Lookup* l; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = ll->LookupCount = GET_UShort(); + + FORGET_Frame(); + + ll->Lookup = NULL; + + if ( ALLOC_ARRAY( ll->Lookup, count, TTO_Lookup ) ) + return error; + if ( ALLOC_ARRAY( ll->Properties, count, UShort ) ) + goto Fail2; + + l = ll->Lookup; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Lookup( &l[n], input, type ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail1: + FREE( ll->Properties ); + + for ( n = 0; n < count; n++ ) + Free_Lookup( &l[n], type ); + + Fail2: + FREE( ll->Lookup ); + return error; + } + + + void Free_LookupList( TTO_LookupList* ll, + TTO_Type type ) + { + UShort n, count; + + TTO_Lookup* l; + + + FREE( ll->Properties ); + + if ( ll->Lookup ) + { + count = ll->LookupCount; + l = ll->Lookup; + + for ( n = 0; n < count; n++ ) + Free_Lookup( &l[n], type ); + + FREE( l ); + } + } + + + + /***************************** + * Coverage related functions + *****************************/ + + + /* CoverageFormat1 */ + + static TT_Error Load_Coverage1( TTO_CoverageFormat1* cf1, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + + UShort* ga; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = cf1->GlyphCount = GET_UShort(); + + FORGET_Frame(); + + cf1->GlyphArray = NULL; + + if ( ALLOC_ARRAY( cf1->GlyphArray, count, UShort ) ) + return error; + + ga = cf1->GlyphArray; + + if ( ACCESS_Frame( count * 2L ) ) + { + FREE( cf1->GlyphArray ); + return error; + } + + for ( n = 0; n < count; n++ ) + ga[n] = GET_UShort(); + + FORGET_Frame(); + + return TT_Err_Ok; + } + + + static void Free_Coverage1( TTO_CoverageFormat1* cf1 ) + { + FREE( cf1->GlyphArray ); + } + + + /* CoverageFormat2 */ + + static TT_Error Load_Coverage2( TTO_CoverageFormat2* cf2, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + + TTO_RangeRecord* rr; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = cf2->RangeCount = GET_UShort(); + + FORGET_Frame(); + + cf2->RangeRecord = NULL; + + if ( ALLOC_ARRAY( cf2->RangeRecord, count, TTO_RangeRecord ) ) + return error; + + rr = cf2->RangeRecord; + + if ( ACCESS_Frame( count * 6L ) ) + goto Fail; + + for ( n = 0; n < count; n++ ) + { + rr[n].Start = GET_UShort(); + rr[n].End = GET_UShort(); + rr[n].StartCoverageIndex = GET_UShort(); + + /* sanity check; we are limited to 16bit integers */ + if ( rr[n].Start > rr[n].End || + ( rr[n].End - rr[n].Start + (long)rr[n].StartCoverageIndex ) >= + 0x10000L ) + { + error = TTO_Err_Invalid_SubTable; + goto Fail; + } + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail: + FREE( cf2->RangeRecord ); + return error; + } + + + static void Free_Coverage2( TTO_CoverageFormat2* cf2 ) + { + FREE( cf2->RangeRecord ); + } + + + TT_Error Load_Coverage( TTO_Coverage* c, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + + if ( ACCESS_Frame( 2L ) ) + return error; + + c->CoverageFormat = GET_UShort(); + + FORGET_Frame(); + + switch ( c->CoverageFormat ) + { + case 1: + return Load_Coverage1( &c->cf.cf1, input ); + + case 2: + return Load_Coverage2( &c->cf.cf2, input ); + + default: + return TTO_Err_Invalid_SubTable_Format; + } + + return TT_Err_Ok; /* never reached */ + } + + + void Free_Coverage( TTO_Coverage* c ) + { + switch ( c->CoverageFormat ) + { + case 1: + Free_Coverage1( &c->cf.cf1 ); + break; + + case 2: + Free_Coverage2( &c->cf.cf2 ); + break; + } + } + + + static TT_Error Coverage_Index1( TTO_CoverageFormat1* cf1, + UShort glyphID, + UShort* index ) + { + UShort min, max, new_min, new_max, middle; + + UShort* array = cf1->GlyphArray; + + + /* binary search */ + + new_min = 0; + new_max = cf1->GlyphCount - 1; + + do + { + min = new_min; + max = new_max; + + /* we use (min + max) / 2 = max - (max - min) / 2 to avoid + overflow and rounding errors */ + + middle = max - ( ( max - min ) >> 1 ); + + if ( glyphID == array[middle] ) + { + *index = middle; + return TT_Err_Ok; + } + else if ( glyphID < array[middle] ) + { + if ( middle == min ) + break; + new_max = middle - 1; + } + else + { + if ( middle == max ) + break; + new_min = middle + 1; + } + } while ( min < max ); + + return TTO_Err_Not_Covered; + } + + + static TT_Error Coverage_Index2( TTO_CoverageFormat2* cf2, + UShort glyphID, + UShort* index ) + { + UShort min, max, new_min, new_max, middle; + + TTO_RangeRecord* rr = cf2->RangeRecord; + + + /* binary search */ + + new_min = 0; + new_max = cf2->RangeCount - 1; + + do + { + min = new_min; + max = new_max; + + /* we use (min + max) / 2 = max - (max - min) / 2 to avoid + overflow and rounding errors */ + + middle = max - ( ( max - min ) >> 1 ); + + if ( glyphID >= rr[middle].Start && glyphID <= rr[middle].End ) + { + *index = rr[middle].StartCoverageIndex + glyphID - rr[middle].Start; + return TT_Err_Ok; + } + else if ( glyphID < rr[middle].Start ) + { + if ( middle == min ) + break; + new_max = middle - 1; + } + else + { + if ( middle == max ) + break; + new_min = middle + 1; + } + } while ( min < max ); + + return TTO_Err_Not_Covered; + } + + + TT_Error Coverage_Index( TTO_Coverage* c, + UShort glyphID, + UShort* index ) + { + switch ( c->CoverageFormat ) + { + case 1: + return Coverage_Index1( &c->cf.cf1, glyphID, index ); + + case 2: + return Coverage_Index2( &c->cf.cf2, glyphID, index ); + + default: + return TTO_Err_Invalid_SubTable_Format; + } + + return TT_Err_Ok; /* never reached */ + } + + + + /************************************* + * Class Definition related functions + *************************************/ + + + /* ClassDefFormat1 */ + + static TT_Error Load_ClassDef1( TTO_ClassDefinition* cd, + UShort limit, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + + UShort* cva; + Bool* d; + + TTO_ClassDefFormat1* cdf1; + + + cdf1 = &cd->cd.cd1; + + if ( ACCESS_Frame( 4L ) ) + return error; + + cdf1->StartGlyph = GET_UShort(); + count = cdf1->GlyphCount = GET_UShort(); + + FORGET_Frame(); + + /* sanity check; we are limited to 16bit integers */ + + if ( cdf1->StartGlyph + (long)count >= 0x10000L ) + return TTO_Err_Invalid_SubTable; + + cdf1->ClassValueArray = NULL; + + if ( ALLOC_ARRAY( cdf1->ClassValueArray, count, UShort ) ) + return error; + + d = cd->Defined; + cva = cdf1->ClassValueArray; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail; + + for ( n = 0; n < count; n++ ) + { + cva[n] = GET_UShort(); + if ( cva[n] >= limit ) + { + error = TTO_Err_Invalid_SubTable; + goto Fail; + } + d[cva[n]] = TRUE; + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail: + FREE( cva ); + + return error; + } + + + static void Free_ClassDef1( TTO_ClassDefFormat1* cdf1 ) + { + FREE( cdf1->ClassValueArray ); + } + + + /* ClassDefFormat2 */ + + static TT_Error Load_ClassDef2 ( TTO_ClassDefinition* cd, + UShort limit, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + + TTO_ClassRangeRecord* crr; + Bool* d; + + TTO_ClassDefFormat2* cdf2; + + + cdf2 = &cd->cd.cd2; + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = cdf2->ClassRangeCount = GET_UShort(); + + FORGET_Frame(); + + cdf2->ClassRangeRecord = NULL; + + if ( ALLOC_ARRAY( cdf2->ClassRangeRecord, count, TTO_ClassRangeRecord ) ) + return error; + + d = cd->Defined; + crr = cdf2->ClassRangeRecord; + + if ( ACCESS_Frame( count * 6L ) ) + goto Fail; + + for ( n = 0; n < count; n++ ) + { + crr[n].Start = GET_UShort(); + crr[n].End = GET_UShort(); + crr[n].Class = GET_UShort(); + + /* sanity check */ + + if ( crr[n].Start > crr[n].End || + crr[n].Class >= limit ) + { + error = TTO_Err_Invalid_SubTable; + goto Fail; + } + d[crr[n].Class] = TRUE; + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail: + FREE( crr ); + + return error; + } + + + static void Free_ClassDef2( TTO_ClassDefFormat2* cdf2 ) + { + FREE( cdf2->ClassRangeRecord ); + } + + + /* ClassDefinition */ + + TT_Error Load_ClassDefinition( TTO_ClassDefinition* cd, + UShort limit, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + + if ( ALLOC_ARRAY( cd->Defined, limit, Bool ) ) + return error; + + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + cd->ClassFormat = GET_UShort(); + + FORGET_Frame(); + + switch ( cd->ClassFormat ) + { + case 1: + error = Load_ClassDef1( cd, limit, input ); + break; + + case 2: + error = Load_ClassDef2( cd, limit, input ); + break; + + default: + error = TTO_Err_Invalid_SubTable_Format; + break; + } + + if ( error ) + goto Fail; + + cd->loaded = TRUE; + + return TT_Err_Ok; + + Fail: + FREE( cd->Defined ); + return error; + } + + + void Free_ClassDefinition( TTO_ClassDefinition* cd ) + { + if ( !cd->loaded ) + return; + + FREE( cd->Defined ); + + switch ( cd->ClassFormat ) + { + case 1: + Free_ClassDef1( &cd->cd.cd1 ); + break; + + case 2: + Free_ClassDef2( &cd->cd.cd2 ); + break; + } + } + + + static TT_Error Get_Class1( TTO_ClassDefFormat1* cdf1, + UShort glyphID, + UShort* class, + UShort* index ) + { + UShort* cva = cdf1->ClassValueArray; + + + *index = 0; + + if ( glyphID >= cdf1->StartGlyph && + glyphID <= cdf1->StartGlyph + cdf1->GlyphCount ) + { + *class = cva[glyphID - cdf1->StartGlyph]; + return TT_Err_Ok; + } + else + { + *class = 0; + return TTO_Err_Not_Covered; + } + } + + + /* we need the index value of the last searched class range record + in case of failure for constructed GDEF tables */ + + static TT_Error Get_Class2( TTO_ClassDefFormat2* cdf2, + UShort glyphID, + UShort* class, + UShort* index ) + { + TT_Error error = TT_Err_Ok; + UShort min, max, new_min, new_max, middle; + + TTO_ClassRangeRecord* crr = cdf2->ClassRangeRecord; + + + /* binary search */ + + new_min = 0; + new_max = cdf2->ClassRangeCount - 1; + + do + { + min = new_min; + max = new_max; + + /* we use (min + max) / 2 = max - (max - min) / 2 to avoid + overflow and rounding errors */ + + middle = max - ( ( max - min ) >> 1 ); + + if ( glyphID >= crr[middle].Start && glyphID <= crr[middle].End ) + { + *class = crr[middle].Class; + error = TT_Err_Ok; + break; + } + else if ( glyphID < crr[middle].Start ) + { + if ( middle == min ) + { + *class = 0; + error = TTO_Err_Not_Covered; + break; + } + new_max = middle - 1; + } + else + { + if ( middle == max ) + { + *class = 0; + error = TTO_Err_Not_Covered; + break; + } + new_min = middle + 1; + } + } while ( min < max ); + + if ( index ) + *index = middle; + + return error; + } + + + TT_Error Get_Class( TTO_ClassDefinition* cd, + UShort glyphID, + UShort* class, + UShort* index ) + { + switch ( cd->ClassFormat ) + { + case 1: + return Get_Class1( &cd->cd.cd1, glyphID, class, index ); + + case 2: + return Get_Class2( &cd->cd.cd2, glyphID, class, index ); + + default: + return TTO_Err_Invalid_SubTable_Format; + } + + return TT_Err_Ok; /* never reached */ + } + + + + /*************************** + * Device related functions + ***************************/ + + + TT_Error Load_Device( TTO_Device* d, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + + UShort* dv; + + + if ( ACCESS_Frame( 6L ) ) + return error; + + d->StartSize = GET_UShort(); + d->EndSize = GET_UShort(); + d->DeltaFormat = GET_UShort(); + + FORGET_Frame(); + + if ( d->StartSize > d->EndSize || + d->DeltaFormat == 0 || d->DeltaFormat > 3 ) + return TTO_Err_Invalid_SubTable; + + d->DeltaValue = NULL; + + count = ( ( d->EndSize - d->StartSize + 1 ) >> + ( 4 - d->DeltaFormat ) ) + 1; + + if ( ALLOC_ARRAY( d->DeltaValue, count, UShort ) ) + return error; + + if ( ACCESS_Frame( count * 2L ) ) + { + FREE( d->DeltaValue ); + return error; + } + + dv = d->DeltaValue; + + for ( n = 0; n < count; n++ ) + dv[n] = GET_UShort(); + + FORGET_Frame(); + + return TT_Err_Ok; + } + + + void Free_Device( TTO_Device* d ) + { + FREE( d->DeltaValue ); + } + + + /* Since we have the delta values stored in compressed form, we must + uncompress it now. To simplify the interface, the function always + returns a meaningful value in `value'; the error is just for + information. + | + format = 1: 0011223344556677|8899101112131415|... + | + byte 1 byte 2 + + 00: (byte >> 14) & mask + 11: (byte >> 12) & mask + ... + + mask = 0x0003 + | + format = 2: 0000111122223333|4444555566667777|... + | + byte 1 byte 2 + + 0000: (byte >> 12) & mask + 1111: (byte >> 8) & mask + ... + + mask = 0x000F + | + format = 3: 0000000011111111|2222222233333333|... + | + byte 1 byte 2 + + 00000000: (byte >> 8) & mask + 11111111: (byte >> 0) & mask + .... + + mask = 0x00FF */ + + TT_Error Get_Device( TTO_Device* d, + UShort size, + Short* value ) + { + UShort byte, bits, mask, f, s; + + + f = d->DeltaFormat; + + if ( size >= d->StartSize && size <= d->EndSize ) + { + s = size - d->StartSize; + byte = d->DeltaValue[s >> ( 4 - f )]; + bits = byte >> ( 16 - ( s % ( 1 << ( 4 - f ) ) + 1 ) * ( 1 << f ) ); + mask = 0xFFFF >> ( 16 - ( 1 << f ) ); + + *value = (Short)( bits & mask ); + + /* conversion to a signed value */ + + if ( *value >= ( ( mask + 1 ) >> 1 ) ) + *value -= mask + 1; + + return TT_Err_Ok; + } + else + { + *value = 0; + return TTO_Err_Not_Covered; + } + } + + +/* END */ diff --git a/lib/extend/ftxopen.h b/lib/extend/ftxopen.h new file mode 100644 index 0000000..861fcdd --- /dev/null +++ b/lib/extend/ftxopen.h @@ -0,0 +1,304 @@ +/******************************************************************* + * + * ftxopen.h + * + * TrueType Open support. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * This file should be included by the application. Nevertheless, + * the table specific APIs (and structures) are located in files like + * ftxgsub.h or ftxgpos.h; these header files are read by ftxopen.h . + * + ******************************************************************/ + +#ifndef FTXOPEN_H +#define FTXOPEN_H + +#include "freetype.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define TTO_MAX_NESTING_LEVEL 100 + +#define TTO_Err_Invalid_SubTable_Format 0x1000 +#define TTO_Err_Invalid_SubTable 0x1001 +#define TTO_Err_Not_Covered 0x1002 +#define TTO_Err_Too_Many_Nested_Contexts 0x1003 + + + /* Script list related structures */ + + struct TTO_LangSys_ + { + TT_UShort LookupOrderOffset; /* always 0 for TT Open 1.0 */ + TT_UShort ReqFeatureIndex; /* required FeatureIndex */ + TT_UShort FeatureCount; /* number of Feature indices */ + TT_UShort* FeatureIndex; /* array of Feature indices */ + }; + + typedef struct TTO_LangSys_ TTO_LangSys; + + + struct TTO_LangSysRecord_ + { + TT_ULong LangSysTag; /* LangSysTag identifier */ + TTO_LangSys LangSys; /* LangSys table */ + }; + + typedef struct TTO_LangSysRecord_ TTO_LangSysRecord; + + + struct TTO_Script_ + { + TTO_LangSys DefaultLangSys; /* DefaultLangSys table */ + TT_UShort LangSysCount; /* number of LangSysRecords */ + TTO_LangSysRecord* LangSysRecord; /* array of LangSysRecords */ + }; + + typedef struct TTO_Script_ TTO_Script; + + + struct TTO_ScriptRecord_ + { + TT_ULong ScriptTag; /* ScriptTag identifier */ + TTO_Script Script; /* Script table */ + }; + + typedef struct TTO_ScriptRecord_ TTO_ScriptRecord; + + + struct TTO_ScriptList_ + { + TT_UShort ScriptCount; /* number of ScriptRecords */ + TTO_ScriptRecord* ScriptRecord; /* array of ScriptRecords */ + }; + + typedef struct TTO_ScriptList_ TTO_ScriptList; + + + /* Feature list related structures */ + + struct TTO_Feature_ + { + TT_UShort FeatureParams; /* always 0 for TT Open 1.0 */ + TT_UShort LookupListCount; /* number of LookupList indices */ + TT_UShort* LookupListIndex; /* array of LookupList indices */ + }; + + typedef struct TTO_Feature_ TTO_Feature; + + + struct TTO_FeatureRecord_ + { + TT_ULong FeatureTag; /* FeatureTag identifier */ + TTO_Feature Feature; /* Feature table */ + }; + + typedef struct TTO_FeatureRecord_ TTO_FeatureRecord; + + + struct TTO_FeatureList_ + { + TT_UShort FeatureCount; /* number of FeatureRecords */ + TTO_FeatureRecord* FeatureRecord; /* array of FeatureRecords */ + }; + + typedef struct TTO_FeatureList_ TTO_FeatureList; + + + /* Lookup list related structures */ + + struct TTO_SubTable_; /* defined below after inclusion + of ftxgsub.h and ftxgpos.h */ + typedef struct TTO_SubTable_ TTO_SubTable; + + + struct TTO_Lookup_ + { + TT_UShort LookupType; /* Lookup type */ + TT_UShort LookupFlag; /* Lookup qualifiers */ + TT_UShort SubTableCount; /* number of SubTables */ + TTO_SubTable* SubTable; /* array of SubTables */ + }; + + typedef struct TTO_Lookup_ TTO_Lookup; + + + /* The `Properties' field is not defined in the TTO specification but + is needed for processing lookups. If properties[n] is > 0, the + function TT_GSUB_Apply() will process Lookup[n] for glyphs which + have the specific bit not set in the `properties' field of the + input string object. */ + + struct TTO_LookupList_ + { + TT_UShort LookupCount; /* number of Lookups */ + TTO_Lookup* Lookup; /* array of Lookup records */ + TT_UShort* Properties; /* array of flags */ + }; + + typedef struct TTO_LookupList_ TTO_LookupList; + + +/* Possible LookupFlag bit masks. `IGNORE_SPECIAL_MARKS' comes from the + OpenType 1.2 specification. */ + +#define IGNORE_BASE_GLYPHS 0x0002 +#define IGNORE_LIGATURES 0x0004 +#define IGNORE_MARKS 0x0008 +#define IGNORE_SPECIAL_MARKS 0xFF00 + + + struct TTO_CoverageFormat1_ + { + TT_UShort GlyphCount; /* number of glyphs in GlyphArray */ + TT_UShort* GlyphArray; /* array of glyph IDs */ + }; + + typedef struct TTO_CoverageFormat1_ TTO_CoverageFormat1; + + + struct TTO_RangeRecord_ + { + TT_UShort Start; /* first glyph ID in the range */ + TT_UShort End; /* last glyph ID in the range */ + TT_UShort StartCoverageIndex; /* coverage index of first + glyph ID in the range */ + }; + + typedef struct TTO_RangeRecord_ TTO_RangeRecord; + + + struct TTO_CoverageFormat2_ + { + TT_UShort RangeCount; /* number of RangeRecords */ + TTO_RangeRecord* RangeRecord; /* array of RangeRecords */ + }; + + typedef struct TTO_CoverageFormat2_ TTO_CoverageFormat2; + + + struct TTO_Coverage_ + { + TT_UShort CoverageFormat; /* 1 or 2 */ + + union + { + TTO_CoverageFormat1 cf1; + TTO_CoverageFormat2 cf2; + } cf; + }; + + typedef struct TTO_Coverage_ TTO_Coverage; + + + struct TTO_ClassDefFormat1_ + { + TT_UShort StartGlyph; /* first glyph ID of the + ClassValueArray */ + TT_UShort GlyphCount; /* size of the ClassValueArray */ + TT_UShort* ClassValueArray; /* array of class values */ + }; + + typedef struct TTO_ClassDefFormat1_ TTO_ClassDefFormat1; + + + struct TTO_ClassRangeRecord_ + { + TT_UShort Start; /* first glyph ID in the range */ + TT_UShort End; /* last glyph ID in the range */ + TT_UShort Class; /* applied to all glyphs in range */ + }; + + typedef struct TTO_ClassRangeRecord_ TTO_ClassRangeRecord; + + + struct TTO_ClassDefFormat2_ + { + TT_UShort ClassRangeCount; + /* number of ClassRangeRecords */ + TTO_ClassRangeRecord* ClassRangeRecord; + /* array of ClassRangeRecords */ + }; + + typedef struct TTO_ClassDefFormat2_ TTO_ClassDefFormat2; + + + /* The `Defined' field is not defined in the TTO specification but + apparently needed for processing fonts like trado.ttf: This font + refers to a class which contains not a single element. We map such + classes to class 0. */ + + struct TTO_ClassDefinition_ + { + TT_Bool loaded; + + TT_Bool* Defined; /* array of Booleans. + If Defined[n] is FALSE, + class n contains no glyphs. */ + TT_UShort ClassFormat; /* 1 or 2 */ + + union + { + TTO_ClassDefFormat1 cd1; + TTO_ClassDefFormat2 cd2; + } cd; + }; + + typedef struct TTO_ClassDefinition_ TTO_ClassDefinition; + + + struct TTO_Device_ + { + TT_UShort StartSize; /* smallest size to correct */ + TT_UShort EndSize; /* largest size to correct */ + TT_UShort DeltaFormat; /* DeltaValue array data format: + 1, 2, or 3 */ + TT_UShort* DeltaValue; /* array of compressed data */ + }; + + typedef struct TTO_Device_ TTO_Device; + + +#include "ftxgdef.h" +#include "ftxgsub.h" +#include "ftxgpos.h" + + + struct TTO_SubTable_ + { + union + { + TTO_GSUB_SubTable gsub; + TTO_GPOS_SubTable gpos; + } st; + }; + + + enum TTO_Type_ + { + GSUB, + GPOS + }; + + typedef enum TTO_Type_ TTO_Type; + + +#ifdef __cplusplus +} +#endif + +#endif /* FTXOPEN_H */ + + +/* END */ diff --git a/lib/extend/ftxopenf.h b/lib/extend/ftxopenf.h new file mode 100644 index 0000000..ea349af --- /dev/null +++ b/lib/extend/ftxopenf.h @@ -0,0 +1,135 @@ +/******************************************************************* + * + * ftxopenf.h + * + * internal TrueType Open functions + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef FTXOPENF_H +#define FTXOPENF_H + +#include "ftxopen.h" + +#ifdef __cplusplus +extern "C" { +#endif + + /* functions from ftxopen.c */ + + TT_Error Load_ScriptList( TTO_ScriptList* sl, + PFace input ); + TT_Error Load_FeatureList( TTO_FeatureList* fl, + PFace input ); + TT_Error Load_LookupList( TTO_LookupList* ll, + PFace input, + TTO_Type type ); + + TT_Error Load_Coverage( TTO_Coverage* c, + PFace input ); + TT_Error Load_ClassDefinition( TTO_ClassDefinition* cd, + UShort limit, + PFace input ); + TT_Error Load_Device( TTO_Device* d, + PFace input ); + + void Free_ScriptList( TTO_ScriptList* sl ); + void Free_FeatureList( TTO_FeatureList* fl ); + void Free_LookupList( TTO_LookupList* ll, + TTO_Type type ); + + void Free_Coverage( TTO_Coverage* c ); + void Free_ClassDefinition( TTO_ClassDefinition* cd ); + void Free_Device( TTO_Device* d ); + + + /* functions from ftxgsub.c */ + + TT_Error Load_SingleSubst( TTO_SingleSubst* ss, + PFace input ); + TT_Error Load_MultipleSubst( TTO_MultipleSubst* ms, + PFace input ); + TT_Error Load_AlternateSubst( TTO_AlternateSubst* as, + PFace input ); + TT_Error Load_LigatureSubst( TTO_LigatureSubst* ls, + PFace input ); + TT_Error Load_ContextSubst( TTO_ContextSubst* cs, + PFace input ); + TT_Error Load_ChainContextSubst( TTO_ChainContextSubst* ccs, + PFace input ); + + void Free_SingleSubst( TTO_SingleSubst* ss ); + void Free_MultipleSubst( TTO_MultipleSubst* ms ); + void Free_AlternateSubst( TTO_AlternateSubst* as ); + void Free_LigatureSubst( TTO_LigatureSubst* ls ); + void Free_ContextSubst( TTO_ContextSubst* cs ); + void Free_ChainContextSubst( TTO_ChainContextSubst* ccs ); + + + /* functions from ftxgpos.c */ + + TT_Error Load_SinglePos( TTO_SinglePos* sp, + PFace input ); + TT_Error Load_PairPos( TTO_PairPos* pp, + PFace input ); + TT_Error Load_CursivePos( TTO_CursivePos* cp, + PFace input ); + TT_Error Load_MarkBasePos( TTO_MarkBasePos* mbp, + PFace input ); + TT_Error Load_MarkLigPos( TTO_MarkLigPos* mlp, + PFace input ); + TT_Error Load_MarkMarkPos( TTO_MarkMarkPos* mmp, + PFace input ); + TT_Error Load_ContextPos( TTO_ContextPos* cp, + PFace input ); + TT_Error Load_ChainContextPos( TTO_ChainContextPos* ccp, + PFace input ); + + void Free_SinglePos( TTO_SinglePos* sp ); + void Free_PairPos( TTO_PairPos* pp ); + void Free_CursivePos( TTO_CursivePos* cp ); + void Free_MarkBasePos( TTO_MarkBasePos* mbp ); + void Free_MarkLigPos( TTO_MarkLigPos* mlp ); + void Free_MarkMarkPos( TTO_MarkMarkPos* mmp ); + void Free_ContextPos( TTO_ContextPos* cp ); + void Free_ChainContextPos( TTO_ChainContextPos* ccp ); + + + /* query functions */ + + TT_Error Coverage_Index( TTO_Coverage* c, + UShort glyphID, + UShort* index ); + TT_Error Get_Class( TTO_ClassDefinition* cd, + UShort glyphID, + UShort* class, + UShort* index ); + TT_Error Get_Device( TTO_Device* d, + UShort size, + Short* value ); + + + /* functions from ftxgdef.c */ + + TT_Error Add_Glyph_Property( TTO_GDEFHeader* gdef, + UShort glyphID, + UShort property ); + + +#ifdef __cplusplus +} +#endif + +#endif /* FTXOPENF_H */ + + +/* END */ diff --git a/lib/extend/ftxpost.c b/lib/extend/ftxpost.c new file mode 100644 index 0000000..27a92d2 --- /dev/null +++ b/lib/extend/ftxpost.c @@ -0,0 +1,522 @@ +/******************************************************************* + * + * ftxpost.c + * + * post table support API extension body + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * The post table is not completely loaded by the core engine. This + * file loads the missing PS glyph names and implements an API to + * access them. + * + ******************************************************************/ + +#include "ftxpost.h" + +#include "tttypes.h" +#include "ttobjs.h" +#include "tttables.h" +#include "ttload.h" /* for the macros */ +#include "ttfile.h" +#include "tttags.h" +#include "ttmemory.h" +#include "ttextend.h" + + +#define POST_ID Build_Extension_ID( 'p', 'o', 's', 't' ) + + + /* the 258 default Mac PS glyph names */ + + String* TT_Post_Default_Names[258] = + { + /* 0 */ + ".notdef", ".null", "CR", "space", "exclam", + "quotedbl", "numbersign", "dollar", "percent", "ampersand", + /* 10 */ + "quotesingle", "parenleft", "parenright", "asterisk", "plus", + "comma", "hyphen", "period", "slash", "zero", + /* 20 */ + "one", "two", "three", "four", "five", + "six", "seven", "eight", "nine", "colon", + /* 30 */ + "semicolon", "less", "equal", "greater", "question", + "at", "A", "B", "C", "D", + /* 40 */ + "E", "F", "G", "H", "I", + "J", "K", "L", "M", "N", + /* 50 */ + "O", "P", "Q", "R", "S", + "T", "U", "V", "W", "X", + /* 60 */ + "Y", "Z", "bracketleft", "backslash", "bracketright", + "asciicircum", "underscore", "grave", "a", "b", + /* 70 */ + "c", "d", "e", "f", "g", + "h", "i", "j", "k", "l", + /* 80 */ + "m", "n", "o", "p", "q", + "r", "s", "t", "u", "v", + /* 90 */ + "w", "x", "y", "z", "braceleft", + "bar", "braceright", "asciitilde", "Adieresis", "Aring", + /* 100 */ + "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis", + "aacute", "agrave", "acircumflex", "adieresis", "atilde", + /* 110 */ + "aring", "ccedilla", "eacute", "egrave", "ecircumflex", + "edieresis", "iacute", "igrave", "icircumflex", "idieresis", + /* 120 */ + "ntilde", "oacute", "ograve", "ocircumflex", "odieresis", + "otilde", "uacute", "ugrave", "ucircumflex", "udieresis", + /* 130 */ + "dagger", "degree", "cent", "sterling", "section", + "bullet", "paragraph", "germandbls", "registered", "copyright", + /* 140 */ + "trademark", "acute", "dieresis", "notequal", "AE", + "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", + /* 150 */ + "yen", "mu", "partialdiff", "summation", "product", + "pi", "integral", "ordfeminine", "ordmasculine", "Omega", + /* 160 */ + "ae", "oslash", "questiondown", "exclamdown", "logicalnot", + "radical", "florin", "approxequal", "Delta", "guillemotleft", + /* 170 */ + "guillemotright", "ellipsis", "nbspace", "Agrave", "Atilde", + "Otilde", "OE", "oe", "endash", "emdash", + /* 180 */ + "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", + "lozenge", "ydieresis", "Ydieresis", "fraction", "currency", + /* 190 */ + "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl", + "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex", + /* 200 */ + "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute", + "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex", + /* 210 */ + "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", + "dotlessi", "circumflex", "tilde", "macron", "breve", + /* 220 */ + "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek", + "caron", "Lslash", "lslash", "Scaron", "scaron", + /* 230 */ + "Zcaron", "zcaron", "brokenbar", "Eth", "eth", + "Yacute", "yacute", "Thorn", "thorn", "minus", + /* 240 */ + "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf", + "onequarter", "threequarters", "franc", "Gbreve", "gbreve", + /* 250 */ + "Idot", "Scedilla", "scedilla", "Cacute", "cacute", + "Ccaron", "ccaron", "dmacron", + }; + + + + static TT_Error Load_Format_20( TT_Post_20* post20, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort nameindex, n, num; + Byte len; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + num = GET_UShort(); + + FORGET_Frame(); + + /* UNDOCUMENTED! The number of glyphs in this table can be smaller */ + /* than the value in the maxp table (cf. cyberbit.ttf). */ + + /* There already exist fonts which have more than 32768 glyph names */ + /* in this table, so the test for this threshold has been dropped. */ + if ( num > input->numGlyphs ) + return TT_Err_Invalid_Post_Table; + + post20->numGlyphs = num; + + if ( ALLOC_ARRAY( post20->glyphNameIndex, num, TT_UShort ) ) + return error; + + if ( ACCESS_Frame( num * 2L ) ) + goto Fail; + + for ( n = 0; n < num; n++ ) + { + post20->glyphNameIndex[n] = GET_UShort(); + + if ( post20->glyphNameIndex[n] > 258 + num ) + { + FORGET_Frame(); + error = TT_Err_Invalid_Post_Table; + goto Fail; + } + } + + FORGET_Frame(); + + if ( ALLOC_ARRAY( post20->glyphNames, num, Char* ) ) + goto Fail; + + /* We must initialize the glyphNames array for proper */ + /* deallocation. */ + for ( n = 0; n < num; n++ ) + post20->glyphNames[n] = NULL; + + /* Now we can read the glyph names which are stored in */ + /* Pascal string format. */ + for ( n = 0; n < num; n++ ) + { + nameindex = post20->glyphNameIndex[n]; + + if ( nameindex < 258 ) + ; /* default Mac glyph, do nothing */ + else + { + if ( ACCESS_Frame( 1L ) ) + goto Fail1; + + len = GET_Byte(); + + FORGET_Frame(); + + if ( ALLOC_ARRAY( post20->glyphNames[nameindex - 258], + len + 1, Char ) || + FILE_Read( post20->glyphNames[nameindex - 258], len ) ) + goto Fail1; + + /* we make a C string */ + post20->glyphNames[nameindex - 258][len] = '\0'; + } + } + + return TT_Err_Ok; + + + Fail1: + for ( n = 0; n < num; n++ ) + if ( post20->glyphNames[n] ) + FREE( post20->glyphNames[n] ); + + FREE( post20->glyphNames ); + + Fail: + FREE( post20->glyphNameIndex ); + return error; + } + + + static TT_Error Load_Format_25( TT_Post_25* post25, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, num; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + /* UNDOCUMENTED! This value appears only in the Apple TT specs. */ + num = GET_UShort(); + + FORGET_Frame(); + + if ( num > input->numGlyphs || num > 258 ) + return TT_Err_Invalid_Post_Table; + + post25->numGlyphs = num; + + if ( ALLOC_ARRAY( post25->offset, num, Char ) ) + return error; + + if ( ACCESS_Frame( num ) ) + goto Fail; + + for ( n = 0; n < num; n++ ) + { + post25->offset[n] = GET_Char(); + + /* We add 128 to the tests to avoid problems with negative */ + /* values for comparison. */ + if ( n + ( post25->offset[n] + 128 ) > num + 128 || + n + ( post25->offset[n] + 128 ) < 128 ) + { + FORGET_Frame(); + error = TT_Err_Invalid_Post_Table; + goto Fail; + } + } + + FORGET_Frame(); + + return TT_Err_Ok; + + + Fail: + FREE( post25->offset ); + return error; + } + + + static TT_Error Post_Create( void* ext, + PFace face ) + { + TT_Post* post = (TT_Post*)ext; + Long table; + + + /* by convention */ + if ( !post ) + return TT_Err_Ok; + + /* we store the start offset and the size of the subtable */ + table = TT_LookUp_Table( face, TTAG_post ); + post->offset = face->dirTables[table].Offset + 32L; + post->length = face->dirTables[table].Length - 32L; + post->loaded = FALSE; + + return TT_Err_Ok; + } + + + static TT_Error Post_Destroy( void* ext, + PFace face ) + { + TT_Post* post = (TT_Post*)ext; + UShort n; + + + /* by convention */ + if ( !post ) + return TT_Err_Ok; + + if ( post->loaded ) + { + switch ( face->postscript.FormatType ) + { + case 0x00010000: /* nothing to do */ + break; + + case 0x00020000: + for ( n = 0; n < post->p.post20.numGlyphs; n++ ) + if ( post->p.post20.glyphNames[n] ) + FREE( post->p.post20.glyphNames[n] ); + FREE( post->p.post20.glyphNames ); + FREE( post->p.post20.glyphNameIndex ); + break; + + case 0x00028000: + FREE( post->p.post25.offset ); + break; + + case 0x00030000: /* nothing to do */ + break; + +#if 0 + case 0x00040000: + break; +#endif + + default: + ; /* invalid format, do nothing */ + } + } + + return TT_Err_Ok; + } + + + EXPORT_FUNC + TT_Error TT_Init_Post_Extension( TT_Engine engine ) + { + PEngine_Instance _engine = HANDLE_Engine( engine ); + + TT_Error error; + + + if ( !_engine ) + return TT_Err_Invalid_Engine; + + error = TT_Register_Extension( _engine, + POST_ID, + sizeof ( TT_Post ), + Post_Create, + Post_Destroy ); + return error; + } + + +/******************************************************************* + * + * Function : TT_Load_PS_Names + * + * Description : Loads the PostScript Glyph Name subtable (if any). + * + * Output : error code + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Load_PS_Names( TT_Face face, + TT_Post* ppost ) + { + PFace faze = HANDLE_Face( face ); + TT_Error error; + TT_Stream stream; + TT_Post* post; + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + error = TT_Extension_Get( faze, POST_ID, (void**)&post ); + if ( error ) + return error; + + if ( USE_Stream( faze->stream, stream ) ) + return error; + + + switch ( faze->postscript.FormatType ) + { + case 0x00010000: + error = TT_Err_Ok; /* nothing to do */ + break; + + case 0x00020000: + if ( FILE_Seek( post->offset ) ) + goto Fail; + + error = Load_Format_20( &post->p.post20, faze ); + break; + + case 0x00028000: /* 2.5 in 16.16 format */ + if ( FILE_Seek( post->offset ) ) + goto Fail; + + error = Load_Format_25( &post->p.post25, faze ); + break; + + case 0x00030000: + error = TT_Err_Ok; /* nothing to do */ + break; + +#if 0 + case 0x00040000: + break; +#endif + + default: + error = TT_Err_Invalid_Post_Table_Format; + break; + } + + if ( !error ) + { + post->loaded = TRUE; + *ppost = *post; + } + + + Fail: + DONE_Stream( stream ); + + return error; + } + + +/******************************************************************* + * + * Function : TT_Get_PS_Name + * + * Description : Gets the PostScript Glyph Name of a glyph. + * + * Input : index glyph index + * PSname address of a string pointer. + * Will be NULL in case of error; otherwise it + * contains a pointer to the glyph name. + * + * You must not modify the returned string! + * + * Output : error code + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_PS_Name( TT_Face face, + TT_UShort index, + TT_String** PSname ) + { + PFace faze = HANDLE_Face( face ); + TT_Error error; + TT_Post* post; + UShort nameindex; + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + if ( index >= faze->numGlyphs ) + return TT_Err_Invalid_Glyph_Index; + + error = TT_Extension_Get( faze, POST_ID, (void**)&post ); + if ( error ) + return error; + + + *PSname = TT_Post_Default_Names[0]; /* default value */ + + switch ( faze->postscript.FormatType ) + { + case 0x00010000: + if ( index < 258 ) /* paranoid checking */ + *PSname = TT_Post_Default_Names[index]; + break; + + case 0x00020000: + if ( index < post->p.post20.numGlyphs ) + nameindex = post->p.post20.glyphNameIndex[index]; + else + break; + + if ( nameindex < 258 ) + *PSname = TT_Post_Default_Names[nameindex]; + else + *PSname = (String*)post->p.post20.glyphNames[nameindex - 258]; + break; + + case 0x00028000: + if ( index < post->p.post25.numGlyphs ) /* paranoid checking */ + *PSname = TT_Post_Default_Names[index + post->p.post25.offset[index]]; + break; + + case 0x00030000: + break; /* nothing to do */ + +#if 0 + case 0x00040000: + break; +#endif + + default: + ; /* should never happen */ + } + + return TT_Err_Ok; + } + + +/* END */ diff --git a/lib/extend/ftxpost.h b/lib/extend/ftxpost.h new file mode 100644 index 0000000..534b608 --- /dev/null +++ b/lib/extend/ftxpost.h @@ -0,0 +1,107 @@ +/******************************************************************* + * + * ftxpost.h + * + * post table support API extension + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * The post table is not completely loaded by the core engine. This + * file loads the missing PS glyph names and implements an API to + * access them. + * + ******************************************************************/ + +#ifndef FTXPOST_H +#define FTXPOST_H + +#include "freetype.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define TT_Err_Invalid_Post_Table_Format 0x0B00 +#define TT_Err_Invalid_Post_Table 0x0B01 + + /* the 258 standard Mac glyph names, used for format 1.0 and 2.5 */ + + extern TT_String* TT_Post_Default_Names[]; + + + /* format 2.0 table */ + + struct TT_Post_20_ + { + TT_UShort numGlyphs; + TT_UShort* glyphNameIndex; + TT_Char** glyphNames; + }; + + typedef struct TT_Post_20_ TT_Post_20; + + struct TT_Post_25_ + { + TT_UShort numGlyphs; + TT_Char* offset; + }; + + typedef struct TT_Post_25_ TT_Post_25; + +#if 0 + /* format 4.0 table -- not implemented yet */ + + struct TT_Post_40_ + { + }; + + typedef struct TT_Post_40_ TT_Post_40; +#endif + + + struct TT_Post_ + { + TT_Long offset; + TT_Long length; + TT_Bool loaded; + + union + { + TT_Post_20 post20; + TT_Post_25 post25; +#if 0 + TT_Post_40 post40; +#endif + } p; + }; + + typedef struct TT_Post_ TT_Post; + + + EXPORT_DEF + TT_Error TT_Init_Post_Extension( TT_Engine engine ); + + EXPORT_DEF + TT_Error TT_Load_PS_Names( TT_Face face, + TT_Post* post ); + EXPORT_DEF + TT_Error TT_Get_PS_Name( TT_Face face, + TT_UShort index, + TT_String** PSname ); + +#ifdef __cplusplus +} +#endif + +#endif /* FTXPOST_H */ + + +/* END */ diff --git a/lib/extend/ftxsbit.c b/lib/extend/ftxsbit.c new file mode 100644 index 0000000..02162bd --- /dev/null +++ b/lib/extend/ftxsbit.c @@ -0,0 +1,1391 @@ +/******************************************************************* + * + * ftxsbit.c + * + * Embedded bitmap API extension + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * This extension is used to load the embedded bitmaps present + * in certain TrueType files. + * + ******************************************************************/ + +#include "ftxsbit.h" +#include "ttobjs.h" +#include "ttfile.h" +#include "ttload.h" +#include "ttmemory.h" +#include "tttags.h" +#include "ttextend.h" +#include "ttdebug.h" + + +#define SBIT_ID Build_Extension_ID( 's', 'b', 'i', 't' ) + + +/* Required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_bitmap + +/* In all functions, the stream is taken from the 'face' object */ +#define DEFINE_LOCALS DEFINE_LOAD_LOCALS( face->stream ) +#define DEFINE_LOCALS_WO_FRAME DEFINE_LOAD_LOCALS_WO_FRAME( face->stream ) + + +/*************************** + * + * miscellaneous functions + * + ***************************/ + +/******************************************************************* + * + * Function: Load_BitmapData + * + * Bit-aligned bitmap data -> Byte-aligned bitmap data when pad is 0 + * + ******************************************************************/ + + static + TT_Error Load_BitmapData( TT_SBit_Image* image, + Int image_size, + Byte x_offset, + Byte y_offset, + UShort source_width, + UShort source_height, + Bool byte_padded ) + { + DEFINE_LOCALS; + + Int count; /* number of bits left in rows */ + Int loaded; /* number of bits loaded in the accumulator */ + UShort buff; /* accumulator */ + + PByte line; /* target write cursor */ + PByte limit; + + + if ( ( y_offset + source_height > image->map.rows ) || + ( x_offset + source_width > image->map.width ) ) + return TT_Err_Invalid_Argument; + + if ( ACCESS_Frame( image_size ) ) + return error; + + buff = 0; + loaded = 0; + line = (PByte)image->map.bitmap + + y_offset * image->map.cols; + limit = (PByte)image->map.bitmap + + ( y_offset + source_height ) * image->map.cols; + + for ( ; line < limit; line += image->map.cols ) + { + PByte ptr; + + + ptr = line + x_offset / 8; + count = source_width; + + /* We may assume that `loaded' is less than 8 */ + buff >>= x_offset % 8; + loaded += x_offset % 8; + + /* first of all, read all consecutive bytes */ + while ( count >= 8 ) + { + if ( loaded < 8 ) + { + buff |= ((UShort)GET_Byte()) << (8 - loaded); + loaded += 8; + } + + *ptr++ |= (Byte)(buff >> 8); + buff <<= 8; + loaded -= 8; + count -= 8; + } + + /* now write remaining bits (i.e. end of line with count < 8) */ + if ( count > 0 ) + { + if ( loaded < count ) + { + buff |= ((UShort)GET_Byte()) << (8 - loaded); + loaded += 8; + } + + *ptr |= ((Byte)(buff >> 8)) & ~(0xFF >> count); + buff <<= count; + loaded -= count; + } + + if ( byte_padded ) + { + buff = 0; + loaded = 0; + } + } + + FORGET_Frame(); + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function: Crop_Bitmap + * + ******************************************************************/ + + static + void Crop_Bitmap( TT_SBit_Image* image ) + { + /*******************************************************/ + /* In the following situation, some bounding boxes of */ + /* embedded bitmaps are too large. We need to crop it */ + /* to a reasonable size. */ + /* */ + /* --------- */ + /* | | ----- */ + /* | *** | |***| */ + /* | * | -----> | * | */ + /* | * | | * | */ + /* | * | | * | */ + /* | * | | * | */ + /* | *** | |***| */ + /* --------- ----- */ + /* */ + /*******************************************************/ + + Int rows, count; + Long line_len; + PByte line; + + + /********************************************************************/ + /* */ + /* first of all, check the top-most lines of the bitmap and remove */ + /* them if they're empty. */ + /* */ + { + line = (PByte)image->map.bitmap; + rows = image->map.rows; + line_len = image->map.cols; + + for ( count = 0; count < rows; count++ ) + { + PByte cur = line; + PByte limit = line + line_len; + + + for ( ; cur < limit; cur++ ) + if ( cur[0] ) + goto Found_Top; + + /* the current line was empty -- skip to next one */ + line = limit; + } + + Found_Top: + /* check that we have at least one filled line */ + if ( count >= rows ) + goto Empty_Bitmap; + + /* now, crop the empty upper lines */ + if ( count > 0 ) + { + line = (PByte)image->map.bitmap; + + MEM_Move( line, line + count*line_len, (rows-count) * line_len ); + + image->metrics.bbox.yMax -= count; + image->metrics.vertBearingY -= count; + image->metrics.horiBearingY -= count; + image->map.rows -= count; + rows -= count; + } + } + + /*******************************************************************/ + /* */ + /* second, crop the lower lines */ + /* */ + { + line = (PByte)image->map.bitmap + (rows-1) * line_len; + + for ( count = 0; count < rows; count++ ) + { + PByte cur = line; + PByte limit = line + line_len; + + + for ( ; cur < limit; cur++ ) + if ( cur[0] ) + goto Found_Bottom; + + /* the current line was empty -- skip to previous one */ + line -= line_len; + } + + Found_Bottom: + if ( count > 0 ) + { + image->metrics.bbox.yMin += count; + image->map.rows -= count; + rows -= count; + } + } + + /*******************************************************************/ + /* */ + /* third, get rid of the space on the left side of the glyph */ + /* */ + do + { + PByte limit; + + + line = (PByte)image->map.bitmap; + limit = line + rows * line_len; + + for ( ; line < limit; line += line_len ) + if ( line[0] & 0x80 ) + goto Found_Left; + + /* shift the whole glyph one pixel to the left */ + line = (PByte)image->map.bitmap; + limit = line + rows * line_len; + + for ( ; line < limit; line += line_len ) + { + Int n, width = image->map.width; + Byte old; + PByte cur = line; + + + old = cur[0] << 1; + + for ( n = 8; n < width; n += 8 ) + { + Byte val; + + + val = cur[1]; + cur[0] = old | (val >> 7); + old = val << 1; + cur++; + } + cur[0] = old; + } + + image->map.width--; + image->metrics.horiBearingX++; + image->metrics.vertBearingX++; + image->metrics.bbox.xMin++; + + } while ( image->map.width > 0 ); + + Found_Left: + + /*********************************************************************/ + /* */ + /* finally, crop the bitmap width to get rid of the space on the */ + /* right side of the glyph. */ + /* */ + do + { + Int right = image->map.width-1; + PByte limit; + Byte mask; + + + line = (PByte)image->map.bitmap + (right >> 3); + limit = line + rows*line_len; + mask = 0x80 >> (right & 7); + + for ( ; line < limit; line += line_len ) + if ( line[0] & mask ) + goto Found_Right; + + /* crop the whole glyph on the right */ + image->map.width--; + image->metrics.bbox.xMax--; + + } while ( image->map.width > 0 ); + + Found_Right: + /* all right, the bitmap was cropped */ + return; + + Empty_Bitmap: + image->map.width = 0; + image->map.rows = 0; + image->map.cols = 0; + image->map.size = 0; + } + +/************* + * + * Main body + * + *************/ + + + static + TT_Error Load_Range_Codes( TT_SBit_Range* range, + PFace face, + Bool load_offsets ) + { + DEFINE_LOCALS; + + ULong count, n, size; + + + (void)face; + + /* read glyph count */ + if ( ACCESS_Frame( 4L ) ) + goto Exit; + count = GET_ULong(); + FORGET_Frame(); + + range->num_glyphs = count; + + /* Allocate glyph offsets table if needed */ + if ( load_offsets ) + { + if ( ALLOC_ARRAY( range->glyph_offsets, count, ULong ) ) + goto Exit; + + size = count * 4L; + } + else + size = count * 2L; + + /* Allocate glyph codes table and access frame */ + if ( ALLOC_ARRAY ( range->glyph_codes, count, UShort ) || + ACCESS_Frame( size ) ) + goto Exit; + + for ( n = 0; n < count; n++ ) + { + range->glyph_codes[n] = GET_UShort(); + + if ( load_offsets ) + range->glyph_offsets[n] = (ULong)range->image_offset + GET_UShort(); + } + + FORGET_Frame(); + + Exit: + return error; + } + + + static + TT_Error Load_SBit_Range( TT_SBit_Strike* strike, + TT_SBit_Range* range, + PFace face ) + { + DEFINE_LOCALS; + + UShort format; + + + (void)face; + (void)strike; + + format = range->index_format; + PTRACE6(( "Index Format: %d\n", format )); + + switch( format ) + { + case 1: /* variable metrics with 4-byte offsets */ + case 3: /* variable metrics with 2-byte offsets */ + { + UShort num_glyphs, size_elem; + Bool large = (format == 1); + ULong* cur; + + num_glyphs = range->last_glyph - range->first_glyph + 1; + PTRACE5(( " num glyphs: %hu\n", num_glyphs )); + + range->num_glyphs = num_glyphs; + + num_glyphs++; /* BEWARE */ + + size_elem = large ? 4 : 2; + + if ( ALLOC_ARRAY( range->glyph_offsets, num_glyphs, ULong ) || + ACCESS_Frame( num_glyphs * size_elem ) ) + return error; + + cur = range->glyph_offsets; + + while ( num_glyphs > 0 ) + { + cur[0] = (TT_ULong)( range->image_offset + + (large ? GET_ULong() : GET_UShort()) ); + PTRACE7(( " offset: %d\n", cur[0] )); + cur++; + num_glyphs--; + } + + FORGET_Frame(); + } + break; + + case 2: /* all glyphs have identical metrics */ + case 4: + case 5: + { + error = 0; + + if ( format != 4 ) /* read constant metrics, formats 2 and 5 */ + { + TT_SBit_Metrics* metrics; + + + if ( ACCESS_Frame( 12L ) ) + return error; + + range->image_size = GET_ULong(); + metrics = &range->metrics; + + metrics->height = GET_Byte(); + metrics->width = GET_Byte(); + + metrics->horiBearingX = GET_Char(); + metrics->horiBearingY = GET_Char(); + metrics->horiAdvance = GET_Byte(); + + metrics->vertBearingX = GET_Char(); + metrics->vertBearingY = GET_Char(); + metrics->vertAdvance = GET_Byte(); + + FORGET_Frame(); + } + + if ( format != 2 ) /* load range codes, formats 4 and 5 */ + error = Load_Range_Codes( range, face, (format == 4) ); + } + break; + + default: + error = TT_Err_Invalid_File_Format; + } + + PTRACE3(( "Embedded Bitmap Location Tables loaded.\n" )); + + return error; + } + + +/******************************************************************* + * + * Function : Load_TrueType_Eblc + * + * Description : Loads the Eblc table directory into face table. + * + * Input : face face record to look for + * + * Output : Error code. + * + ******************************************************************/ + + static + TT_Error Load_TrueType_Eblc( PFace face, + TT_EBLC* eblc ) + { + DEFINE_LOCALS; + + ULong eblc_offset; + UShort i; + Long table; + + TT_SBit_Strike* strike; + + + PTRACE2(( "Load_EBLC_Table( %08lx )\n", (long)face )); + + eblc->version = 0; + + /* Try to find the `EBLC' or `bloc' table in the font files. */ + /* Both tags describe the same table; `EBLC' is for OpenType */ + /* fonts while `bloc' is for TrueType GX fonts. Many fonts */ + /* contain both tags pointing to the same table. */ + + table = TT_LookUp_Table( face, TTAG_EBLC ); + if ( table < 0 ) + table = TT_LookUp_Table( face, TTAG_bloc ); + + if ( table < 0 ) + /* This table is optional */ + return TT_Err_Ok; + + eblc_offset = face->dirTables[table].Offset; + + if ( FILE_Seek( eblc_offset ) || + ACCESS_Frame( 8L ) ) + return error; + + eblc->version = GET_ULong(); + eblc->num_strikes = GET_ULong(); + + FORGET_Frame(); + + PTRACE2(( "-- Tables count: %12u\n", eblc->num_strikes )); + PTRACE2(( "-- Format version: %08lx\n", eblc->version )); + + if ( eblc->version != 0x00020000 ) + { + PERROR(( "Invalid file format!\n" )); + return TT_Err_Invalid_File_Format; + } + + if ( ALLOC_ARRAY( eblc->strikes, eblc->num_strikes, TT_SBit_Strike ) || + ACCESS_Frame( 48L * eblc->num_strikes ) ) + return error; + + strike = eblc->strikes; + + for ( i = 0; i < eblc->num_strikes; i++, strike++ ) + { /* loop through the tables and get all entries */ + ULong indexTablesSize; + TT_SBit_Line_Metrics* metrics; + Int count; + + + strike->ranges_offset = GET_ULong(); + indexTablesSize = GET_ULong(); /* dont' save */ + + strike->num_ranges = GET_ULong(); + strike->color_ref = GET_ULong(); + + /* load horizontal and vertical metrics */ + metrics = &strike->hori; + for ( count = 2; count > 0; count-- ) + { + metrics->ascender = GET_Char(); + metrics->descender = GET_Char(); + metrics->max_width = GET_Byte(); + + metrics->caret_slope_numerator = GET_Char(); + metrics->caret_slope_denominator = GET_Char(); + metrics->caret_offset = GET_Char(); + + metrics->min_origin_SB = GET_Char(); + metrics->min_advance_SB = GET_Char(); + metrics->max_before_BL = GET_Char(); + metrics->min_after_BL = GET_Char(); + metrics->pads[0] = GET_Char(); + metrics->pads[1] = GET_Char(); + + metrics = &strike->vert; + } + + strike->start_glyph = GET_UShort(); + strike->end_glyph = GET_UShort(); + strike->x_ppem = GET_Byte(); + strike->y_ppem = GET_Byte(); + strike->bit_depth = GET_Byte(); + strike->flags = GET_Char(); + + PTRACE4(( " start - end - ppemX - ppemY\n" )); + PTRACE4(( " %04d - %04d - %3u - %3u\n", + strike->start_glyph, + strike->end_glyph, + strike->x_ppem, + strike->y_ppem )); + } + + FORGET_Frame(); + + /* Load EBLC index ranges */ + strike = eblc->strikes; + + for ( i = 0; i < eblc->num_strikes; i++, strike++ ) + { + TT_SBit_Range* range; + UShort count = strike->num_ranges; + + + /* loop through the tables and get all entries */ + if ( ALLOC_ARRAY( strike->sbit_ranges, + strike->num_ranges, + TT_SBit_Range ) || + FILE_Seek( eblc_offset + strike->ranges_offset ) || + ACCESS_Frame( strike->num_ranges * 8L ) ) + return error; + + for ( range = strike->sbit_ranges; count > 0; count--, range++ ) + { + range->first_glyph = GET_UShort(); + range->last_glyph = GET_UShort(); + range->table_offset = eblc_offset + strike->ranges_offset + + GET_ULong(); + } + FORGET_Frame(); + + /* Now, read each index table */ + range = strike->sbit_ranges; + for ( count = strike->num_ranges; count > 0; count--, range++ ) + { + /* Read the header */ + if ( FILE_Seek( range->table_offset ) || + ACCESS_Frame( 8L ) ) + return error;; + + range->index_format = GET_UShort(); + range->image_format = GET_UShort(); + range->image_offset = GET_ULong(); + + FORGET_Frame(); + + error = Load_SBit_Range( strike, range, face ); + if (error) return error; + } + } + + return TT_Err_Ok; + } + + + static + void Free_TrueType_Eblc( TT_EBLC* eblc ) + { + if ( eblc ) + { + ULong i; + TT_SBit_Strike* strike = eblc->strikes; + + + strike = eblc->strikes; + + for ( i = eblc->num_strikes; i > 0; i--, strike++ ) + { + /* for each strike, release all glyph ranges */ + TT_SBit_Range* range = strike->sbit_ranges; + Int n; + + + for ( n = strike->num_ranges; n > 0; n--, range++ ) + { + /* release a range */ + FREE( range->glyph_offsets ); + FREE( range->glyph_codes ); + } + FREE( strike->sbit_ranges ); + strike->num_ranges = 0; + } + FREE( eblc->strikes ); + eblc->num_strikes = 0; + eblc->version = 0; + } + } + + + static + TT_Error Load_SBit_Metrics( TT_Big_Glyph_Metrics* metrics, + TT_SBit_Range* range, + ULong ebdt_offset ) + { + TT_Error error; + Byte height, width; + + + /* copy bitmap metrics for formats 2 and 5 */ + if ( ( ( range->index_format == 2 ) || ( range->index_format == 5 ) ) && + ( range->image_format == 5 ) ) + /* metrics are taken from current image bitmap */ + /* i.e. from `image.metrics' */ + { + TT_SBit_Metrics* rmetrics = &range->metrics; + + + metrics->bbox.xMin = rmetrics->horiBearingX; + metrics->bbox.xMax = metrics->bbox.xMin + rmetrics->width; + + metrics->bbox.yMax = rmetrics->horiBearingY; + metrics->bbox.yMin = metrics->bbox.yMax - rmetrics->height; + + metrics->horiBearingX = rmetrics->horiBearingX; + metrics->horiBearingY = metrics->bbox.yMax; + metrics->horiAdvance = rmetrics->horiAdvance; + + metrics->vertBearingX = rmetrics->vertBearingX; + metrics->vertBearingY = rmetrics->vertBearingY; + metrics->vertAdvance = rmetrics->vertAdvance; + + return TT_Err_Ok; + } + + switch ( range->image_format ) + { + case 1: + case 2: + case 6: + case 7: + case 8: + case 9: + { + Long length = 5L; + + + if ( range->image_format == 8 ) + length++; + + /* read the small metrics */ + if ( ACCESS_Frame( length ) ) + return error; + + height = GET_Byte(); + width = GET_Byte(); + + metrics->horiBearingX = GET_Char(); + metrics->horiBearingY = GET_Char(); + metrics->horiAdvance = GET_Byte(); + + FORGET_Frame(); + + metrics->bbox.xMin = metrics->horiBearingX; + metrics->bbox.yMax = metrics->horiBearingY; + metrics->bbox.xMax = metrics->bbox.xMin + width; + metrics->bbox.yMin = metrics->bbox.yMax - height; + + /* read the rest of the big metrics for the formats */ + /* that support it. */ + if ( ( range->image_format >= 6 ) && ( range->image_format != 8 ) ) + { + if ( ACCESS_Frame( 3L ) ) + return error; + + metrics->vertBearingX = (Int)GET_Char(); + metrics->vertBearingY = (Int)GET_Char(); + metrics->vertAdvance = (Int)GET_Char(); + + FORGET_Frame(); + } + else + { + /* XXX: How can we fill these when the information isn't */ + /* available? */ + metrics->vertBearingX = 0; + metrics->vertBearingY = 0; + metrics->vertAdvance = 0; + } + } + break; + + case 5: /* metrics are taken from current image bitmap */ + /* i.e. from 'image.metrics' */ + break; + + default: + PERROR(( "Unsupported embedded bitmap format!\n" )); + return TT_Err_Invalid_File_Format; + } + + return TT_Err_Ok; + } + + + static + TT_Error Load_SBit_Image( TT_SBit_Strike strike, + UShort glyph_index, + Byte x_offset, + Byte y_offset, + ULong ebdt_offset, + TT_SBit_Image* image, + UShort component_depth ) + { + TT_Error error; + Byte height, width; + + ULong bitmap_offset; + + TT_SBit_Range* range = 0; + + TT_Big_Glyph_Metrics metrics; + + /********************************************************************/ + /* */ + /* Scan the strike's range for the position/metrics of the source */ + /* glyph. */ + { + UShort count = strike.num_ranges; + TT_SBit_Range* cur = strike.sbit_ranges; + + for ( ; count > 0; count--, cur++ ) + { + /* look for the glyph in the current range */ + switch ( cur->index_format ) + { + case 1: + case 2: + case 3: + if ( glyph_index >= cur->first_glyph && + glyph_index <= cur->last_glyph ) + { + UShort delta = glyph_index - cur->first_glyph; + + + range = cur; + bitmap_offset = cur->index_format == 2 + ? cur->image_offset + cur->image_size * delta + : cur->glyph_offsets[delta]; + goto Found; + } + break; + + case 4: + case 5: + { + UShort n; + + + for ( n = 0; n < cur->num_glyphs; n++ ) + if ( cur->glyph_codes[n] == glyph_index ) + { + range = cur; + bitmap_offset = cur->index_format == 4 + ? cur->glyph_offsets[n] + : cur->image_offset + cur->image_size * n; + goto Found; + } + } + break; + + default: + return TT_Err_Invalid_Glyph_Index; + } + } + /* Not found */ + return TT_Err_Invalid_Glyph_Index; + } + + Found: + if ( FILE_Seek( ebdt_offset + bitmap_offset ) ) + return error; + + /* First of all, load the metrics if needed */ + error = Load_SBit_Metrics( &metrics, range, ebdt_offset ); + if ( error ) + return error; + + width = metrics.bbox.xMax - metrics.bbox.xMin; + height = metrics.bbox.yMax - metrics.bbox.yMin; + + if ( !component_depth ) + { + image->metrics = metrics; + + image->map.width = width; + image->map.rows = height; + + image->map.cols = (width + 7) >> 3; + image->map.size = height * image->map.cols; + + if ( REALLOC( image->map.bitmap, image->map.size ) ) + return error; + + MEM_Set( image->map.bitmap, 0, image->map.size ); + } + + /* Now, load the data as needed */ + switch ( range->image_format ) + { + case 1: + case 6: /* byte-aligned data */ + error = Load_BitmapData( image, + height * (( width + 7 ) >> 3), + x_offset, y_offset, + width, height, + 1 ); + if ( error ) + return error; + break; + + case 2: + case 5: + case 7: + error = Load_BitmapData( image, + (width * height + 7) >> 3, + x_offset, y_offset, + width, height, 0 ); + if ( error ) + return error; + break; + + case 8: + case 9: + { + /* Now, load composite sbit glyphs */ + /* This code is not sophisticated */ + + TT_SBit_Component* component_array; + UShort num_components; + + Int i = 0; + + + if ( ACCESS_Frame( 2L ) ) + return error; + num_components = GET_UShort(); + FORGET_Frame(); + + MEM_Alloc( component_array, + sizeof ( TT_SBit_Component ) * num_components ); + + if ( ACCESS_Frame( 4L * num_components ) ) + return error; + + for ( i = 0; i < num_components; i++ ) + { + component_array[i].glyph_code = GET_UShort(); + component_array[i].x_offset = GET_Char(); + component_array[i].y_offset = GET_Char(); + } + + FORGET_Frame(); + + component_depth++; + + for ( i = 0; i < num_components; i++ ) + { + error = Load_SBit_Image( strike, component_array[i].glyph_code, + component_array[i].x_offset, + component_array[i].y_offset, + ebdt_offset, + image, + component_depth ); + if ( error ) + return error; + } + FREE( component_array ); + break; + + default: + return TT_Err_Invalid_File_Format; + } + } + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function: Load_TrueType_Ebdt + * + ******************************************************************/ + + static + TT_Error Load_TrueType_Ebdt( PFace face, + TT_SBit_Strike strike, + ULong glyph_index, + TT_SBit_Image* image ) + { + DEFINE_LOCALS; + + ULong ebdt_offset; + ULong version; + Long i; + + + /* Try to find the `EBDT' or `bdat' table in the font files. */ + /* Both tags describe the same table, `EBDT' is for OpenType */ + /* fonts, while `bdat' is for TrueType GX fonts. Many fonts */ + /* contain both tags pointing to the same table */ + + i = TT_LookUp_Table( face, TTAG_EBDT ); + if ( i < 0 ) + i = TT_LookUp_Table( face, TTAG_bdat ); + + if ( i < 0 ) + return TT_Err_Table_Missing; + + ebdt_offset = face->dirTables[i].Offset; + + if ( FILE_Seek( ebdt_offset ) || + ACCESS_Frame( 4L ) ) /* read into frame */ + return error; + + version = GET_ULong(); + FORGET_Frame(); + + PTRACE2(( "-- Format version : %08lx\n", version )); + if ( version != 0x00020000 ) + { + PERROR(( "Invalid file format!\n" )); + return TT_Err_Invalid_File_Format; + } + + /* This doesn't compile, I simply commented it out ?? - David */ + /* PTRACE4(( "-- Format: %d\n", range->image_format )); */ + + error = Load_SBit_Image( strike, + glyph_index, + 0, 0, + ebdt_offset, + image, + 0 ); + if ( error ) + return error; + + return TT_Err_Ok; + } + + + static TT_Error EBLC_Create( void* ext, + PFace face ) + { + TT_EBLC* eblc = (TT_EBLC*)ext; + + + /* by convention */ + if ( !eblc ) + return TT_Err_Ok; + + return Load_TrueType_Eblc( face, eblc ); + } + + + static TT_Error EBLC_Destroy( void* ext, + PFace face ) + { + TT_EBLC* eblc = (TT_EBLC*)ext; + + + (void)face; + + if ( eblc ) + Free_TrueType_Eblc( eblc ); + + return TT_Err_Ok; + } + + + /*************************************************************/ + /* */ + /* */ + /* TT_Init_SBit_Extension */ + /* */ + /* */ + /* Initialize the embedded bitmaps extension for the */ + /* FreeType engine. */ + /* */ + /* */ + /* engine :: handle to current FreeType library instance */ + /* */ + /* */ + /* Error code. 0 means success. */ + /* */ + EXPORT_FUNC + TT_Error TT_Init_SBit_Extension( TT_Engine engine ) + { + PEngine_Instance _engine = HANDLE_Engine( engine ); + + TT_Error error; + + + if ( !_engine ) + return TT_Err_Invalid_Engine; + + error = TT_Register_Extension( _engine, + SBIT_ID, + sizeof ( TT_EBLC ), + EBLC_Create, + EBLC_Destroy ); + + return error; + } + + + /*************************************************************/ + /* */ + /* */ + /* TT_Get_Face_Bitmaps */ + /* */ + /* */ + /* Loads the `EBLC' table from a font file, if any. */ + /* */ + /* */ + /* face :: handle to the source TrueType font/face */ + /* */ + /* */ + /* eblc_table :: a descriptor for the EBLC table */ + /* */ + /* */ + /* Error code. 0 means success. */ + /* */ + /* */ + /* This function returns TT_Err_Table_Missing if the */ + /* font contains no embedded bitmaps. All fields in */ + /* `eblc_table' will then be set to 0. */ + /* */ + EXPORT_FUNC + TT_Error TT_Get_Face_Bitmaps( TT_Face face, + TT_EBLC* eblc_table ) + { + PFace faze = HANDLE_Face( face ); + TT_EBLC* eblc; + TT_Error error; + + + error = TT_Extension_Get( faze, SBIT_ID, (void**)&eblc ); + if ( !error ) + { + if ( eblc->version ) + { + *eblc_table = *eblc; + return TT_Err_Ok; + } + error = TT_Err_Table_Missing; + } + + eblc_table->version = 0; + eblc_table->num_strikes = 0; + eblc_table->strikes = 0; + + return error; + } + + +/******************************************************************* + * + * TT_Get_SBit_Strike + * + * + * Loads suitable strike (bitmap sizetable) for given instance. + * This strike includes sbitLineMetrics. + * + * + * face :: the source face + * instance :: the current size instance + * + * + * strike :: the bitmap strike descriptor + * + * + * TrueType error code. 0 means success. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_SBit_Strike( TT_Face face, + TT_Instance instance, + TT_SBit_Strike* strike ) + { + TT_Error error; + PFace faze = HANDLE_Face( face ); + PInstance ins = HANDLE_Instance( instance ); + + TT_EBLC* eblc; + TT_Int x_ppem, y_ppem; + + + if ( !strike || !ins || ins->owner != faze ) + return TT_Err_Invalid_Argument; + + error = TT_Extension_Get( faze, SBIT_ID, (void**)&eblc ); + if ( error ) + goto Exit; + + /********************************************************************/ + /* */ + /* Look for an sbit strike that matches the current x and y ppms */ + /* */ + { + UShort count = eblc->num_strikes; + TT_SBit_Strike* cur = eblc->strikes; + + + x_ppem = ins->metrics.x_ppem; + y_ppem = ins->metrics.y_ppem; + + MEM_Set( strike, 0, sizeof ( TT_SBit_Strike ) ); + + for ( ; count > 0; count--, cur++ ) + if ( cur->x_ppem == x_ppem && + cur->y_ppem == y_ppem ) + { + *strike = *cur; + break; + } + + /* return immediately if we didn't find an appropriate strike */ + if ( !strike->num_ranges ) + error = TT_Err_Invalid_PPem; + } + + Exit: + return error; + } + + + /*************************************************************/ + /* */ + /* */ + /* TT_Load_Glyph_Bitmap */ + /* */ + /* */ + /* Loads a given glyph embedded bitmap. */ + /* */ + /* */ + /* face :: handle to the source TrueType font/face */ + /* instance :: current size/transform instance */ + /* glyph_index :: index of source glyph */ + /* bitmap :: target embedded bitmap descriptor */ + /* */ + /* */ + /* Error code. 0 means success. */ + /* */ + /* */ + /* This function returns an error if there is no */ + /* embedded bitmap for the glyph at the given */ + /* instance. */ + /* */ + EXPORT_FUNC + TT_Error TT_Load_Glyph_Bitmap( TT_Face face, + TT_Instance instance, + TT_UShort glyph_index, + TT_SBit_Image* image ) + { + TT_Stream stream; + TT_Error error; + + PFace faze = HANDLE_Face( face ); + PInstance ins = HANDLE_Instance( instance ); + + TT_SBit_Strike strike; + + + if ( ins->owner != faze ) + { + error = TT_Err_Invalid_Argument; + goto Fail; + } + + /********************************************************************/ + /* */ + /* Look for an sbit strike that matches the current x and y ppms */ + /* */ + error = TT_Get_SBit_Strike( face, instance, &strike ); + if ( error ) + goto Fail; + + /* return immediately if the glyph index isn't in the strike extent */ + if ( glyph_index < strike.start_glyph || + glyph_index > strike.end_glyph ) + { + error = TT_Err_Invalid_Glyph_Index; + goto Fail; + } + + { + image->bit_depth = 1; + + if ( !USE_Stream( faze->stream, stream ) ) + { + error = Load_TrueType_Ebdt( faze, strike, glyph_index, image ); + + DONE_Stream( stream ); + + /* exit successfully if we can */ + if ( !error ) + { + image->map.flow = TT_Flow_Down; + + Crop_Bitmap( image ); + + /* correct sbit metrics */ + { + TT_Big_Glyph_Metrics* metrics = &image->metrics; + + + metrics->bbox.xMin *= 64; + metrics->bbox.xMax *= 64; + + metrics->bbox.yMax *= 64; + metrics->bbox.yMin *= 64; + + metrics->horiBearingX *= 64; + metrics->horiBearingY *= 64; + metrics->horiAdvance *= 64; + + metrics->vertBearingX *= 64; + metrics->vertBearingY *= 64; + metrics->vertAdvance *= 64; + } + + goto Exit; + } + } + } + + Fail: + image->map.width = 0; + image->map.rows = 0; + image->map.cols = 0; + image->map.size = 0; + image->map.bitmap = 0; + image->map.flow = 0; + image->bit_depth = 0; + + Exit: + return error; + } + + + /*************************************************************/ + /* */ + /* */ + /* TT_New_SBit_Image */ + /* */ + /* */ + /* Allocates a new embedded bitmap container. */ + /* */ + /* */ + /* image :: sbit image */ + /* */ + /* */ + /* Error code. 0 means success. */ + /* */ + EXPORT_FUNC + TT_Error TT_New_SBit_Image( TT_SBit_Image** image ) + { + return MEM_Alloc( *image, sizeof ( **image ) ); + } + + + /*************************************************************/ + /* */ + /* */ + /* TT_Done_SBit_Image */ + /* */ + /* */ + /* Releases an embedded bitmap container. */ + /* */ + /* */ + /* image :: sbit image */ + /* */ + EXPORT_FUNC + void TT_Done_SBit_Image( TT_SBit_Image* image ) + { + FREE( image->map.bitmap ); + FREE( image ); + } + + +/* END */ diff --git a/lib/extend/ftxsbit.h b/lib/extend/ftxsbit.h new file mode 100644 index 0000000..05e7b1f --- /dev/null +++ b/lib/extend/ftxsbit.h @@ -0,0 +1,490 @@ +/******************************************************************* + * + * ftxsbit.h + * + * embedded bitmap support API extension + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * This extension is used to load the embedded bitmaps present + * in certain TrueType files. + * + ******************************************************************/ + +#ifndef FTXSBIT_H +#define FTXSBIT_H + +#include "freetype.h" + +#ifdef __cplusplus +extern "C" { +#endif + + /*************************************************************/ + /* */ + /* TT_SBit_Metrics */ + /* */ + /* */ + /* A structure used to hold the big metrics of a given */ + /* glyph bitmap in a TrueType or OpenType font. These */ + /* are usually found in the `EBDT' table. */ + /* */ + /* */ + /* height :: glyph height in pixels */ + /* width :: glyph width in pixels */ + /* */ + /* horiBearingX :: horizontal left bearing */ + /* horiBearingY :: horizontal top bearing */ + /* horiAdvance :: horizontal advance */ + /* */ + /* vertBearingX :: vertical left bearing */ + /* vertBearingY :: vertical top bearing */ + /* vertAdvance :: vertical advance */ + /* */ + typedef struct TT_SBit_Metrics_ + { + TT_Byte height; + TT_Byte width; + + TT_Char horiBearingX; + TT_Char horiBearingY; + TT_Byte horiAdvance; + + TT_Char vertBearingX; + TT_Char vertBearingY; + TT_Byte vertAdvance; + + } TT_SBit_Metrics; + + + /*************************************************************/ + /* */ + /* TT_SBit_Small_Metrics */ + /* */ + /* */ + /* A structure used to hold the small metrics of a given */ + /* glyph bitmap in a TrueType or OpenType font. These */ + /* are usually found in the `EBDT' table. */ + /* */ + /* */ + /* height :: glyph height in pixels */ + /* width :: glyph width in pixels */ + /* */ + /* bearingX :: left-side bearing */ + /* bearingY :: top-side bearing */ + /* advance :: advance width or height */ + /* */ + typedef struct TT_SBit_Small_Metrics_ + { + TT_Byte height; + TT_Byte width; + + TT_Char bearingX; + TT_Char bearingY; + TT_Byte advance; + + } TT_SBit_Small_Metrics; + + + /*************************************************************/ + /* */ + /* TT_SBit_Line_Metrics */ + /* */ + /* */ + /* A structure used to describe the text line metrics of */ + /* a given bitmap strike, for either horizontal or */ + /* vertical layout. */ + /* */ + /* */ + /* ascender :: ascender in pixels */ + /* descender :: descender in pixels */ + /* max_width :: maximum glyph width in pixels */ + /* */ + /* caret_slope_enumerator :: Rise of the caret slope, */ + /* typically set to 1 for non-italic fonts. */ + /* caret_slope_denominator :: Rise of the caret slope, */ + /* typically set to 0 for non-italic fonts. */ + /* caret_offset :: Offset in pixels */ + /* to move the caret for proper positioning. */ + /* */ + /* min_origin_SB :: Minimum of horiBearingX */ + /* (resp. vertBearingY) */ + /* min_advance_SB :: Minimum of */ + /* (hori. advance - ( horiBearingX + width )) */ + /* (resp. vert. advance - ( vertBearingY + height )) */ + /* max_before_BL :: Maximum of horiBearingY */ + /* (resp. Maximum of vertBearingY) */ + /* min_after_BL :: Minimum of ( horiBearingY - height ) */ + /* (resp. vertBearingX - width ) */ + /* */ + typedef struct TT_SBit_Line_Metrics_ + { + TT_Char ascender; + TT_Char descender; + TT_Byte max_width; + TT_Char caret_slope_numerator; + TT_Char caret_slope_denominator; + TT_Char caret_offset; + TT_Char min_origin_SB; + TT_Char min_advance_SB; + TT_Char max_before_BL; + TT_Char min_after_BL; + TT_Char pads[2]; + + } TT_SBit_Line_Metrics; + + + /*************************************************************/ + /* */ + /* TT_SBit_Range */ + /* */ + /* */ + /* A TrueType/OpenType subIndexTable as defined in the */ + /* `EBLC' or `bloc' tables. */ + /* */ + /* */ + /* */ + /* first_glyph :: first glyph index in range */ + /* last_glyph :: last glyph index in range */ + /* */ + /* index_format :: format of index table. valid */ + /* values are 1 to 5. */ + /* */ + /* image_format :: format of `EBDT' image data */ + /* image_offset :: offset to image data in `EBDT' */ + /* */ + /* image_size :: for index formats 2 and 5. This is */ + /* the size in bytes of each glyph bitmap */ + /* glyph bitmap */ + /* */ + /* big_metrics :: for index formats 2 and 5. This is */ + /* the big metrics for each glyph bitmap */ + /* */ + /* num_glyphs :: for index formats 4 and 5. This is */ + /* the number of glyphs in the code */ + /* array. */ + /* */ + /* glyph_offsets :: for index formats 1 and 3. */ + /* glyph_codes :: for index formats 4 and 5. */ + /* */ + /* table_offset :: offset of index table in `EBLC' table */ + /* -- only used during strike loading. */ + /* */ + typedef struct TT_SBit_Range + { + TT_UShort first_glyph; + TT_UShort last_glyph; + + TT_UShort index_format; + TT_UShort image_format; + TT_ULong image_offset; + + TT_ULong image_size; + TT_SBit_Metrics metrics; + TT_ULong num_glyphs; + + TT_ULong* glyph_offsets; + TT_UShort* glyph_codes; + + TT_ULong table_offset; + + } TT_SBit_Range; + + + /*************************************************************/ + /* */ + /* TT_SBit_Strike */ + /* */ + /* */ + /* A structure used describe a given bitmap strike in the */ + /* `EBLC' or `bloc' tables. */ + /* */ + /* */ + /* */ + /* num_index_ranges :: number of index ranges */ + /* index_ranges :: array of glyph index ranges */ + /* */ + /* color_ref :: unused. color reference? */ + /* hori :: line metrics for horizontal layouts. */ + /* vert :: line metrics for vertical layouts. */ + /* */ + /* start_glyph :: lowest glyph index for this strike. */ + /* end_glyph :: higher glyph index for this strike. */ + /* */ + /* x_ppem :: horizontal pixels per EM */ + /* y_ppem :: vertical pixels per EM */ + /* bit_depth :: bit depth. valid values are 1, 2, 4 & 8 */ + /* flags :: vertical or horizontal? */ + /* */ + typedef struct TT_SBit_Strike_ + { + TT_Int num_ranges; + TT_SBit_Range* sbit_ranges; + TT_ULong ranges_offset; + + TT_ULong color_ref; + + TT_SBit_Line_Metrics hori; + TT_SBit_Line_Metrics vert; + + TT_UShort start_glyph; + TT_UShort end_glyph; + + TT_Byte x_ppem; + TT_Byte y_ppem; + TT_Byte bit_depth; + TT_Char flags; + + } TT_SBit_Strike; + + + /*************************************************************/ + /* */ + /* TT_SBit_Component */ + /* */ + /* */ + /* A simple structure to describe a compound sbit element */ + /* */ + /* */ + /* glyph_code :: element's glyph index */ + /* x_offset :: element's left bearing */ + /* y_offset :: element's top bearing */ + /* */ + typedef struct TT_SBit_Component_ + { + TT_UShort glyph_code; + TT_Char x_offset; + TT_Char y_offset; + + } TT_SBit_Component; + + + /*************************************************************/ + /* */ + /* TT_SBit_Scale */ + /* */ + /* */ + /* A structure used describe a given bitmap scaling */ + /* table, as defined for the `EBSC' table. */ + /* */ + /* */ + /* hori :: horizontal line metrics */ + /* vert :: vertical line metrics */ + /* */ + /* x_ppem :: horizontal pixels per EM */ + /* y_ppem :: vertical pixels per EM */ + /* */ + /* x_ppem_substitute :: substitution x_ppem */ + /* y_ppem_substitute :: substitution y_ppem */ + /* */ + typedef struct TT_SBit_Scale_ + { + TT_SBit_Line_Metrics hori; + TT_SBit_Line_Metrics vert; + + TT_Byte x_ppem; + TT_Byte y_ppem; + + TT_Byte x_ppem_substitute; + TT_Byte y_ppem_substitute; + + } TT_SBit_Scale; + + + /*************************************************************/ + /* */ + /* TT_SBit_Image */ + /* */ + /* */ + /* A structure used to describe a given embedded bitmap */ + /* image. */ + /* */ + /* */ + /* map :: bitmap descriptor */ + /* bit_depth :: pixel bit depth */ + /* metrics :: glyph metrics for the bitmap */ + /* */ + typedef struct TT_SBit_Image_ + { + TT_Raster_Map map; + int bit_depth; + TT_Big_Glyph_Metrics metrics; + + } TT_SBit_Image; + + + /*************************************************************/ + /* */ + /* TT_EBLC */ + /* */ + /* */ + /* A structure used to describe the `EBLC' table from */ + /* a TrueType font. */ + /* */ + /* */ + /* version :: version number of the EBLC table */ + /* */ + /* num_strikes :: the number of strikes, i.e. bitmap */ + /* sizes, present in this font */ + /* */ + /* strikes :: array of strikes */ + /* */ + typedef struct TT_EBLC_ + { + TT_ULong version; + TT_ULong num_strikes; + TT_SBit_Strike* strikes; + + } TT_EBLC; + + + + + /*************************************************************/ + /* */ + /* */ + /* TT_Init_SBit_Extension */ + /* */ + /* */ + /* Initializes the embedded bitmap extension for the */ + /* FreeType engine. */ + /* */ + /* */ + /* engine :: handle to current FreeType library instance */ + /* */ + /* */ + /* Error code. 0 means success. */ + /* */ + EXPORT_DEF + TT_Error TT_Init_SBit_Extension( TT_Engine engine ); + + + /*************************************************************/ + /* */ + /* */ + /* TT_Get_Face_Bitmaps */ + /* */ + /* */ + /* Loads the `EBLC' table from a font file, if any. */ + /* */ + /* */ + /* face :: handle to the source TrueType font/face */ + /* */ + /* */ + /* eblc_table :: a descriptor for the EBLC table */ + /* */ + /* */ + /* Error code. 0 means success. */ + /* */ + /* */ + /* This function returns TT_Err_Table_Missing if the */ + /* font contains no embedded bitmaps. All fields in */ + /* `eblc_table' will then be set to 0. */ + /* */ + EXPORT_DEF + TT_Error TT_Get_Face_Bitmaps( TT_Face face, + TT_EBLC* eblc_table ); + + + /*************************************************************/ + /* */ + /* */ + /* TT_New_SBit_Image */ + /* */ + /* */ + /* Allocates a new embedded bitmap container. */ + /* */ + /* */ + /* image :: sbit image */ + /* */ + /* */ + /* Error code. 0 means success. */ + /* */ + EXPORT_DEF + TT_Error TT_New_SBit_Image( TT_SBit_Image** image ); + + + /*************************************************************/ + /* */ + /* */ + /* TT_Done_SBit_Image */ + /* */ + /* */ + /* Releases an embedded bitmap container. */ + /* */ + /* */ + /* image :: sbit image */ + /* */ + EXPORT_DEF + void TT_Done_SBit_Image( TT_SBit_Image* image ); + + + /*************************************************************/ + /* */ + /* TT_Get_SBit_Strike */ + /* */ + /* */ + /* Loads a suitable strike (bitmap sizetable) for the */ + /* given instance. This strike includes */ + /* sbitLineMetrics. */ + /* */ + /* */ + /* face :: the source face */ + /* instance :: the current size instance */ + /* */ + /* */ + /* strike :: the bitmap strike descriptor */ + /* */ + /* */ + /* Error code. 0 means success. */ + /* */ + EXPORT_DEF + TT_Error TT_Get_SBit_Strike( TT_Face face, + TT_Instance instance, + TT_SBit_Strike* strike ); + + + /*************************************************************/ + /* */ + /* */ + /* TT_Load_Glyph_Bitmap */ + /* */ + /* */ + /* Loads a given glyph embedded bitmap. */ + /* */ + /* */ + /* face :: handle to the source TrueType font/face */ + /* instance :: current size/transform instance */ + /* glyph_index :: index of source glyph */ + /* bitmap :: target embedded bitmap descriptor */ + /* */ + /* */ + /* Error code. 0 means success. */ + /* */ + /* */ + /* This function returns an error if there is no */ + /* embedded bitmap for the glyph at the given */ + /* instance. */ + /* */ + EXPORT_DEF + TT_Error TT_Load_Glyph_Bitmap( TT_Face face, + TT_Instance instance, + TT_UShort glyph_index, + TT_SBit_Image* bitmap ); + +#ifdef __cplusplus +} +#endif + +#endif /* FTXSBIT_H */ + + +/* END */ diff --git a/lib/extend/ftxwidth.c b/lib/extend/ftxwidth.c new file mode 100644 index 0000000..5415f5a --- /dev/null +++ b/lib/extend/ftxwidth.c @@ -0,0 +1,185 @@ +/******************************************************************* + * + * ftxwidth.c 1.0 + * + * Glyph Widths (and Heights) fast retrieval extension + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * This extension is used to parse the "glyf" table of a TrueType + * file in order to extract the bbox of a given range of glyphs. + * + * The bbox is then used to build font unit widths and height + * that are returned in two parallel arrays. + * + * This extension is needed by the FreeType/2 OS/2 Font Driver. + * + ******************************************************************/ + + +#include "ftxwidth.h" +#include "ttdebug.h" +#include "ttobjs.h" +#include "ttfile.h" +#include "tttags.h" +#include "ttload.h" + +/* Required by the tracing mode */ + +#undef TT_COMPONENT +#define TT_COMPONENT trace_any + + + /******************************************************************/ + /* */ + /* Function: TT_Get_Face_Widths */ + /* */ + /* Description: Returns the widths and/or heights of a given */ + /* range of glyphs for a face. */ + /* */ + /* Input: */ + /* face :: face handle */ + /* */ + /* first_glyph :: first glyph in range */ + /* */ + /* last_glyph :: last glyph in range */ + /* */ + /* widths :: address of table receiving the widths */ + /* expressed in font units (ushorts). Set */ + /* this parameter to NULL if you're not */ + /* interested by these values. */ + /* */ + /* heights :: address of table receiving the heights */ + /* expressed in font units (ushorts). Set */ + /* this parameter to NULL if you're not */ + /* interested by these values. */ + /* */ + /* Returns: */ + /* Error code */ + /* */ + /* */ + /******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Face_Widths( TT_Face face, + TT_UShort first_glyph, + TT_UShort last_glyph, + TT_UShort* widths, + TT_UShort* heights ) + { + DEFINE_ALL_LOCALS; + + PFace faze = HANDLE_Face(face); + UShort n; + Long table; + + ULong glyf_offset; /* offset of glyph table in file */ + UShort zero_width = 0; /* width of glyph 0 */ + UShort zero_height = 0; /* height of glyph 0 */ + + Bool zero_loaded = 0; + +#ifndef TT_HUGE_PTR + PStorage locations; +#else + Storage TT_HUGE_PTR * locations; +#endif + TT_BBox bbox; + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + if ( last_glyph >= faze->numGlyphs || + first_glyph > last_glyph ) + return TT_Err_Invalid_Argument; + + /* find "glyf" table */ + table = TT_LookUp_Table( faze, TTAG_glyf ); + if ( table < 0 ) + { + PERROR(( "ERROR: there is no glyph table in this font file!\n" )); + return TT_Err_Glyf_Table_Missing; + } + glyf_offset = faze->dirTables[table].Offset; + + /* now access stream */ + if ( USE_Stream( faze->stream, stream ) ) + return error; + + locations = faze->glyphLocations + first_glyph; + + /* loop to load each glyph in the range */ + for ( n = first_glyph; n <= last_glyph; n++ ) + { + if ( n + 1 < faze->numGlyphs && + locations[0] == locations[1] ) + { + /* Note : Glyph 0 is always used to indicate a missing glyph */ + /* in a range. We must thus return its width and height */ + /* where appropriate when we find an undefined glyph. */ + if ( zero_loaded == 0 ) + { + if ( FILE_Seek( glyf_offset + faze->glyphLocations[0] ) || + ACCESS_Frame( 10L ) ) + goto Fail; + + (void)GET_Short(); /* skip number of contours */ + + bbox.xMin = GET_Short(); + bbox.yMin = GET_Short(); + bbox.xMax = GET_Short(); + bbox.yMax = GET_Short(); + + FORGET_Frame(); + + zero_width = (UShort)(bbox.xMax - bbox.xMin); + zero_height = (UShort)(bbox.yMax - bbox.yMin); + zero_loaded = 1; + } + + if ( widths ) + *widths++ = zero_width; + + if ( heights ) + *heights++ = zero_height; + } + else + { + /* normal glyph, read header */ + if ( FILE_Seek( glyf_offset + locations[0] ) || + ACCESS_Frame( 10L ) ) + goto Fail; + + (void)GET_Short(); /* skip number of contours */ + + bbox.xMin = GET_Short(); + bbox.yMin = GET_Short(); + bbox.xMax = GET_Short(); + bbox.yMax = GET_Short(); + + FORGET_Frame(); + + if ( widths ) + *widths++ = (UShort)(bbox.xMax - bbox.xMin); + + if ( heights ) + *heights++ = (UShort)(bbox.yMax - bbox.yMin); + } + } + + Fail: + DONE_Stream( stream ); + return error; + } + + +/* END */ diff --git a/lib/extend/ftxwidth.h b/lib/extend/ftxwidth.h new file mode 100644 index 0000000..5ac7251 --- /dev/null +++ b/lib/extend/ftxwidth.h @@ -0,0 +1,80 @@ +/******************************************************************* + * + * ftxwidth.h + * + * Glyph Widths (and Heights) fast retrieval extension. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * This extension is used to parse the `glyf' table of a TrueType + * file in order to extract the bounding box of a given range of glyphs. + * + * The bounding box is then used to build font unit widths and heights + * that are returned in two parallel arrays. + * + * This extension is needed by the FreeType/2 OS/2 Font Driver. + * + ******************************************************************/ + +#ifndef FTXWIDTH_H +#define FTXWIDTH_H + +#include "freetype.h" + +#ifdef __cplusplus +extern "C" { +#endif + + /******************************************************************/ + /* */ + /* Function: TT_Get_Face_Widths */ + /* */ + /* Description: Returns the widths and/or heights of a given */ + /* range of glyphs for a face. */ + /* */ + /* Input: */ + /* face :: face handle */ + /* */ + /* first_glyph :: first glyph in range */ + /* */ + /* last_glyph :: last glyph in range */ + /* */ + /* widths :: address of table receiving the widths */ + /* expressed in font units (ushorts). Set */ + /* this parameter to NULL if you're not */ + /* interested by these values. */ + /* */ + /* heights :: address of table receiving the heights */ + /* expressed in font units (ushorts). Set */ + /* this parameter to NULL if you're not */ + /* interested by these values */ + /* */ + /* Returns: */ + /* Error code */ + /* */ + /* */ + /******************************************************************/ + + EXPORT_DEF + TT_Error TT_Get_Face_Widths( TT_Face face, + TT_UShort first_glyph, + TT_UShort last_glyph, + TT_UShort* widths, + TT_UShort* heights ); + +#ifdef __cplusplus +} +#endif + +#endif /* FTXWIDTH_H */ + + +/* END */ diff --git a/lib/extend/readme.1st b/lib/extend/readme.1st new file mode 100644 index 0000000..cce94cd --- /dev/null +++ b/lib/extend/readme.1st @@ -0,0 +1,61 @@ +This directory contains several extensions to the core engine. + +An extension is a separately compilable unit which can be linked by +a client application to add new functionalities to the engine. + +There are two kinds of extensions: an `API extension' provides +clients with new APIs to access internal engine structures or data, +while an `engine extension' implements new TrueType data or table +management. + +This directory contains the following: + + ftxcmap: An API extension to iterate over cmaps. + + ftxgasp: A simple API extension which returns the TrueType `gasp' + table to client applications, when found in a font file. + Though this table is always loaded by the engine, there + is no function in the core API to access it. The reason + is simple: to demonstrate a simple API extension with + `ftxgasp'! + + ftxkern: This engine extension is used to access kerning data, + when available in a font file. Note that it implements + on-the-fly loading and retrieving of kerning tables. + However, it doesn't interpret or process the data, and + client applications should use it according to the + TrueType specification. + + ftxpost: An engine extension to load the PostScript glyph names + of the `post' table. See the `ftzoom' program for an + example how to use it. + + ftxwidth: A simple extension used to load the widths and heights + of a given range of glyphs in a face. Results are + expressed in unscaled font units. This is required by + the latest version of the FreeType/2 DLL to speed up + font loading in the GRE (the OS/2 GRaphics Engine). It + can be used by other applications though... + + ftxerr18: This extension simply converts a TrueType engine error + code into a corresponding string describing the error. + It is useful if you intend to write a package for end + users and want to give them not `Error code 135' but + `OS/2 table missing'. See docs/errstr.txt for a + description how to use it (really simple!). ftxerr18 + supports localization of error strings (that is: error + strings are automatically translated into supported + languages) using gettext(). See docs/i18n.txt about + using gettext. + + ftxsbit: Embedded bitmap support. This is an engine extension. + See e.g. the `ftstrtto' program for its usage. + + ftxopen, + ftxgsub, + ftxgpos, + ftxgdef: This is experimental stuff for TrueType Open support! + Please ignore it or help debugging :-) + + +--- END --- diff --git a/lib/freetype.h b/lib/freetype.h new file mode 100644 index 0000000..0b0237c --- /dev/null +++ b/lib/freetype.h @@ -0,0 +1,1147 @@ +/******************************************************************* + * + * freetype.h + * + * High-level interface specification. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * Note: + * + * This is the only file that should be included by client + * application sources. All other types and functions defined + * in the `tt*.h' files are library internals and should not be + * included. + * + ******************************************************************/ + +#ifndef FREETYPE_H +#define FREETYPE_H + + +#define TT_FREETYPE_MAJOR 1 +#define TT_FREETYPE_MINOR 3 + + +#include "fterrid.h" +#include "ftnameid.h" + +/* To make freetype.h independent from configuration files we check */ +/* whether EXPORT_DEF has been defined already. */ + +#ifndef EXPORT_DEF +#define EXPORT_DEF extern +#endif + +/* The same for TT_Text. If you define the HAVE_TT_TEXT macro, you */ +/* have to provide a typedef declaration for TT_Text before */ +/* including this file. */ + +#ifndef HAVE_TT_TEXT +#define HAVE_TT_TEXT + typedef char TT_Text; /* The data type to represent */ + /* file name string elements. */ +#endif + +#ifdef __cplusplus + extern "C" { +#endif + + + /*******************************************************************/ + /* */ + /* FreeType types definitions. */ + /* */ + /* All these begin with a 'TT_' prefix. */ + /* */ + /*******************************************************************/ + + typedef int TT_Bool; + + typedef signed long TT_Fixed; /* signed fixed 16.16 float */ + + typedef signed short TT_FWord; /* distance in FUnits */ + typedef unsigned short TT_UFWord; /* unsigned distance */ + + typedef char TT_String; + typedef signed char TT_Char; + typedef unsigned char TT_Byte; + typedef signed short TT_Short; + typedef unsigned short TT_UShort; + typedef int TT_Int; + typedef unsigned int TT_UInt; + typedef signed long TT_Long; + typedef unsigned long TT_ULong; + + typedef signed short TT_F2Dot14; /* Signed fixed float 2.14 used for */ + /* unit vectors, with layout */ + /* */ + /* s : 1 -- sign bit */ + /* m : 1 -- integer bit */ + /* f : 14 -- unsigned fractional */ + /* */ + /* `s:m' is the 2-bit signed int */ + /* value to which the positive */ + /* fractional part should be added. */ + + typedef signed long TT_F26Dot6; /* 26.6 fixed float, used for */ + /* glyph points pixel coordinates. */ + + typedef signed long TT_Pos; /* Point position, expressed either */ + /* in fractional pixels or notional */ + /* units, depending on context. */ + /* For example, glyph coordinates */ + /* returned by TT_Load_Glyph() are */ + /* expressed in font units if */ + /* scaling wasn't requested, and */ + /* in 26.6 fractional pixels if it */ + /* was. */ + + + struct TT_UnitVector_ /* guess what... */ + { + TT_F2Dot14 x; + TT_F2Dot14 y; + }; + + typedef struct TT_UnitVector_ TT_UnitVector; + + + struct TT_Vector_ /* simple vector type */ + { + TT_F26Dot6 x; + TT_F26Dot6 y; + }; + + typedef struct TT_Vector_ TT_Vector; + + + /* A simple 2x2 matrix used for transformations. */ + /* You should use 16.16 fixed floats. */ + /* */ + /* x' = xx*x + xy*y */ + /* y' = yx*x + yy*y */ + /* */ + + struct TT_Matrix_ + { + TT_Fixed xx, xy; + TT_Fixed yx, yy; + }; + + typedef struct TT_Matrix_ TT_Matrix; + + + /* A structure used to describe the source glyph to the renderer. */ + + struct TT_Outline_ + { + TT_Short n_contours; /* number of contours in glyph */ + TT_UShort n_points; /* number of points in the glyph */ + + TT_Vector* points; /* the outline's points */ + TT_Byte* flags; /* the points flags */ + TT_UShort* contours; /* the contour end points */ + + /* The following flag indicates that the outline owns the arrays it */ + /* refers to. Typically, this is true of outlines created from the */ + /* TT_New_Outline() API, while it isn't for those returned by */ + /* TT_Get_Glyph_Outline(). */ + + TT_Bool owner; /* The outline owns the coordinates, */ + /* flags and contours array it uses. */ + + /* The following flags are set automatically by */ + /* TT_Get_Glyph_Outline(). Their meaning is the following: */ + /* */ + /* high_precision If true, the scan-line converter will use a */ + /* higher precision to render bitmaps (i.e., a */ + /* 1/1024 pixel precision). This is important for */ + /* small ppem sizes. */ + /* */ + /* second_pass If true, the scan-line converter performs a */ + /* second sweep phase dedicated to find vertical */ + /* drop-outs. If false, only horizontal drop-outs */ + /* will be checked during the first vertical */ + /* sweep (yes, this is a bit confusing but it is */ + /* really the way it should work). This is */ + /* important for small ppems too. */ + /* */ + /* dropout_mode Specifies the TrueType drop-out mode to use for */ + /* continuity checking. Valid values are 0 (no */ + /* check), 1, 2, 4, and 5. */ + /* */ + /* Most of the engine's users will safely ignore these fields... */ + + TT_Bool high_precision; /* high precision rendering */ + TT_Bool second_pass; /* two sweeps rendering */ + TT_Char dropout_mode; /* dropout mode */ + }; + + typedef struct TT_Outline_ TT_Outline; + + + /* A structure used to describe a simple bounding box. */ + + struct TT_BBox_ + { + TT_Pos xMin; + TT_Pos yMin; + TT_Pos xMax; + TT_Pos yMax; + }; + + typedef struct TT_BBox_ TT_BBox; + + + /* A structure used to return glyph metrics. */ + /* */ + /* The `bearingX' isn't called `left-side bearing' anymore because */ + /* it has different meanings depending on the glyph's orientation. */ + /* */ + /* The same is true for `bearingY', which is the top-side bearing */ + /* defined by the TT_Spec, i.e., the distance from the baseline to */ + /* the top of the glyph's bbox. According to our current convention, */ + /* this is always the same as `bbox.yMax' but we make it appear for */ + /* consistency in its proper field. */ + /* */ + /* The `advance' field is the advance width for horizontal layout, */ + /* and advance height for vertical layouts. */ + + struct TT_Glyph_Metrics_ + { + TT_BBox bbox; /* glyph bounding box */ + + TT_Pos bearingX; /* left-side bearing */ + TT_Pos bearingY; /* top-side bearing, per se the TT spec */ + + TT_Pos advance; /* advance width (or height) */ + }; + + typedef struct TT_Glyph_Metrics_ TT_Glyph_Metrics; + + + /* A structure used to return horizontal _and_ vertical glyph */ + /* metrics. */ + /* */ + /* A glyph can be used either in a horizontal or vertical layout. */ + /* Its glyph metrics vary with orientation. The TT_Big_Glyph_Metrics */ + /* structure is used to return _all_ metrics in one call. */ + + struct TT_Big_Glyph_Metrics_ + { + TT_BBox bbox; /* glyph bounding box */ + + TT_Pos horiBearingX; /* left side bearing in horizontal layouts */ + TT_Pos horiBearingY; /* top side bearing in horizontal layouts */ + + TT_Pos vertBearingX; /* left side bearing in vertical layouts */ + TT_Pos vertBearingY; /* top side bearing in vertical layouts */ + + TT_Pos horiAdvance; /* advance width for horizontal layout */ + TT_Pos vertAdvance; /* advance height for vertical layout */ + + /* The following fields represent unhinted scaled metrics values. */ + /* They can be useful for applications needing to do some device */ + /* independent placement of glyphs. */ + /* */ + /* Applying these metrics to hinted glyphs will most surely ruin */ + /* the grid fitting performed by the bytecode interpreter. These */ + /* values are better used to compute accumulated positioning */ + /* distances. */ + + TT_Pos linearHoriBearingX; /* linearly scaled horizontal lsb */ + TT_Pos linearHoriAdvance; /* linearly scaled horizontal advance */ + + TT_Pos linearVertBearingY; /* linearly scaled vertical tsb */ + TT_Pos linearVertAdvance; /* linearly scaled vertical advance */ + }; + + typedef struct TT_Big_Glyph_Metrics_ TT_Big_Glyph_Metrics; + + + /* A structure used to return instance metrics. */ + + struct TT_Instance_Metrics_ + { + TT_F26Dot6 pointSize; /* char. size in points (1pt = 1/72 inch) */ + + TT_UShort x_ppem; /* horizontal pixels per EM square */ + TT_UShort y_ppem; /* vertical pixels per EM square */ + + TT_Fixed x_scale; /* 16.16 to convert from EM units to 26.6 pix */ + TT_Fixed y_scale; /* 16.16 to convert from EM units to 26.6 pix */ + + TT_UShort x_resolution; /* device horizontal resolution in dpi */ + TT_UShort y_resolution; /* device vertical resolution in dpi */ + }; + + typedef struct TT_Instance_Metrics_ TT_Instance_Metrics; + + + /* Flow constants: */ + /* */ + /* The flow of a bitmap refers to the way lines are oriented */ + /* within the bitmap data, i.e., the orientation of the Y */ + /* coordinate axis. */ + /* */ + /* For example, if the first bytes of the bitmap pertain to */ + /* its top-most line, then the flow is `down'. If these bytes */ + /* pertain to its lowest line, the the flow is `up'. */ + +#define TT_Flow_Down -1 /* bitmap is oriented from top to bottom */ +#define TT_Flow_Up 1 /* bitmap is oriented from bottom to top */ +#define TT_Flow_Error 0 /* an error occurred during rendering */ + + + /* A structure used to describe the target bitmap or pixmap to the */ + /* renderer. Note that there is nothing in this structure that */ + /* gives the nature of the buffer. */ + /* */ + /* IMPORTANT NOTE: */ + /* */ + /* In the case of a pixmap, the `width' and `cols' fields must */ + /* have the _same_ values, and _must_ be padded to 32-bits, i.e., */ + /* be a multiple of 4. Clipping problems will arise otherwise, */ + /* if not even page faults! */ + /* */ + /* The typical settings are: */ + /* */ + /* - for a WxH bitmap: */ + /* */ + /* rows = H */ + /* cols = (W+7) / 8 */ + /* width = W */ + /* flow = your_choice */ + /* */ + /* - for a WxH pixmap: */ + /* */ + /* rows = H */ + /* cols = (W+3) & ~3 */ + /* width = cols */ + /* flow = your_choice */ + + struct TT_Raster_Map_ + { + int rows; /* number of rows */ + int cols; /* number of columns (bytes) per row */ + int width; /* number of pixels per line */ + int flow; /* bitmap orientation */ + + void* bitmap; /* bit/pixmap buffer */ + long size; /* bit/pixmap size in bytes */ + }; + + typedef struct TT_Raster_Map_ TT_Raster_Map; + + + /* ------ The font header TrueType table structure ------ */ + + struct TT_Header_ + { + TT_Fixed Table_Version; + TT_Fixed Font_Revision; + + TT_Long CheckSum_Adjust; + TT_Long Magic_Number; + + TT_UShort Flags; + TT_UShort Units_Per_EM; + + TT_Long Created [2]; + TT_Long Modified[2]; + + TT_FWord xMin; + TT_FWord yMin; + TT_FWord xMax; + TT_FWord yMax; + + TT_UShort Mac_Style; + TT_UShort Lowest_Rec_PPEM; + + TT_Short Font_Direction; + TT_Short Index_To_Loc_Format; + TT_Short Glyph_Data_Format; + }; + + typedef struct TT_Header_ TT_Header; + + + /* ------ The horizontal header TrueType table structure ------ */ + + /*******************************************************/ + /* This structure is the one defined by the TrueType */ + /* specification, plus two fields used to link the */ + /* font-units metrics to the header. */ + + struct TT_Horizontal_Header_ + { + TT_Fixed Version; + TT_FWord Ascender; + TT_FWord Descender; + TT_FWord Line_Gap; + + TT_UFWord advance_Width_Max; /* advance width maximum */ + + TT_FWord min_Left_Side_Bearing; /* minimum left-sb */ + TT_FWord min_Right_Side_Bearing; /* minimum right-sb */ + TT_FWord xMax_Extent; /* xmax extents */ + TT_FWord caret_Slope_Rise; + TT_FWord caret_Slope_Run; + + TT_Short Reserved0, + Reserved1, + Reserved2, + Reserved3, + Reserved4; + + TT_Short metric_Data_Format; + TT_UShort number_Of_HMetrics; + + /* The following fields are not defined by the TrueType specification */ + /* but they're used to connect the metrics header to the relevant */ + /* `HMTX' or `VMTX' table. */ + + void* long_metrics; + void* short_metrics; + }; + + typedef struct TT_Horizontal_Header_ TT_Horizontal_Header; + + + /*******************************************************/ + /* This structure is the one defined by the TrueType */ + /* specification. Note that it has exactly the same */ + /* layout as the horizontal header (both are loaded */ + /* by the same function). */ + + struct TT_Vertical_Header_ + { + TT_Fixed Version; + TT_FWord Ascender; + TT_FWord Descender; + TT_FWord Line_Gap; + + TT_UFWord advance_Height_Max; /* advance height maximum */ + + TT_FWord min_Top_Side_Bearing; /* minimum left-sb or top-sb */ + TT_FWord min_Bottom_Side_Bearing; /* minimum right-sb or bottom-sb */ + TT_FWord yMax_Extent; /* xmax or ymax extents */ + TT_FWord caret_Slope_Rise; + TT_FWord caret_Slope_Run; + TT_FWord caret_Offset; + + TT_Short Reserved1, + Reserved2, + Reserved3, + Reserved4; + + TT_Short metric_Data_Format; + TT_UShort number_Of_VMetrics; + + /* The following fields are not defined by the TrueType specification */ + /* but they're used to connect the metrics header to the relevant */ + /* `HMTX' or `VMTX' table. */ + + void* long_metrics; + void* short_metrics; + }; + + typedef struct TT_Vertical_Header_ TT_Vertical_Header; + + + /* ------ The OS/2 table ------ */ + + /************************************************************************/ + /* Note that since FreeType 1.3, we support Mac fonts which do not have */ + /* an OS/2 table. In this case the `version' field will be set to */ + /* 0xFFFF by the table loader; all other fields should be 0. */ + + struct TT_OS2_ + { + TT_UShort version; /* 0x0001 */ + TT_FWord xAvgCharWidth; + TT_UShort usWeightClass; + TT_UShort usWidthClass; + TT_Short fsType; + TT_FWord ySubscriptXSize; + TT_FWord ySubscriptYSize; + TT_FWord ySubscriptXOffset; + TT_FWord ySubscriptYOffset; + TT_FWord ySuperscriptXSize; + TT_FWord ySuperscriptYSize; + TT_FWord ySuperscriptXOffset; + TT_FWord ySuperscriptYOffset; + TT_FWord yStrikeoutSize; + TT_FWord yStrikeoutPosition; + TT_Short sFamilyClass; + + TT_Byte panose[10]; + + TT_ULong ulUnicodeRange1; /* Bits 0-31 */ + TT_ULong ulUnicodeRange2; /* Bits 32-63 */ + TT_ULong ulUnicodeRange3; /* Bits 64-95 */ + TT_ULong ulUnicodeRange4; /* Bits 96-127 */ + + TT_Char achVendID[4]; + + TT_UShort fsSelection; + TT_UShort usFirstCharIndex; + TT_UShort usLastCharIndex; + TT_Short sTypoAscender; + TT_Short sTypoDescender; + TT_Short sTypoLineGap; + TT_UShort usWinAscent; + TT_UShort usWinDescent; + + /* only version 1 tables: */ + + TT_ULong ulCodePageRange1; /* Bits 0-31 */ + TT_ULong ulCodePageRange2; /* Bits 32-63 */ + }; + + typedef struct TT_OS2_ TT_OS2; + + + /* ------ The PostScript table ------ */ + + struct TT_Postscript_ + { + TT_Fixed FormatType; + TT_Fixed italicAngle; + TT_FWord underlinePosition; + TT_FWord underlineThickness; + TT_ULong isFixedPitch; + TT_ULong minMemType42; + TT_ULong maxMemType42; + TT_ULong minMemType1; + TT_ULong maxMemType1; + + /* Glyph names follow in the file, but we don't */ + /* load them by default. See the ftxpost.c extension. */ + }; + + typedef struct TT_Postscript_ TT_Postscript; + + + /* ------ The horizontal device metrics table (`hdmx') ------ */ + + struct TT_Hdmx_Record_ + { + TT_Byte ppem; + TT_Byte max_width; + TT_Byte* widths; + }; + + typedef struct TT_Hdmx_Record_ TT_Hdmx_Record; + + + struct TT_Hdmx_ + { + TT_UShort version; + TT_Short num_records; + TT_Hdmx_Record* records; + }; + + typedef struct TT_Hdmx_ TT_Hdmx; + + + /* A structure used to describe face properties. */ + + struct TT_Face_Properties_ + { + TT_UShort num_Glyphs; /* number of glyphs in face */ + TT_UShort max_Points; /* maximum number of points in a glyph */ + TT_UShort max_Contours; /* maximum number of contours in a glyph */ + + TT_UShort num_CharMaps; /* number of charmaps in the face */ + TT_UShort num_Names; /* number of name records in the face */ + + TT_ULong num_Faces; /* 1 for normal TrueType files, and the */ + /* number of embedded faces for TrueType */ + /* collections */ + + TT_Header* header; /* TrueType header table */ + TT_Horizontal_Header* horizontal; /* TrueType horizontal header */ + TT_OS2* os2; /* TrueType OS/2 table */ + TT_Postscript* postscript; /* TrueType Postscript table */ + TT_Hdmx* hdmx; /* TrueType hor. dev. metr. table */ + TT_Vertical_Header* vertical; /* TT Vertical header, if present */ + }; + + typedef struct TT_Face_Properties_ TT_Face_Properties; + + + /* Here are the definitions of the handle types used for FreeType's */ + /* most common objects accessed by the client application. We use */ + /* a simple trick: */ + /* */ + /* Each handle type is a structure that only contains one */ + /* pointer. The advantage of structures is that they are */ + /* mutually exclusive types. We could have defined the */ + /* following types: */ + /* */ + /* typedef void* TT_Stream; */ + /* typedef void* TT_Face; */ + /* typedef void* TT_Instance; */ + /* typedef void* TT_Glyph; */ + /* typedef void* TT_CharMap; */ + /* */ + /* but these would have allowed lines like: */ + /* */ + /* stream = instance; */ + /* */ + /* in the client code this would be a severe bug, unnoticed */ + /* by the compiler! */ + /* */ + /* Thus, we enforce type checking with a simple language */ + /* trick... */ + /* */ + /* NOTE: Some macros are defined in tttypes.h to perform */ + /* automatic type conversions for library hackers... */ + + struct TT_Engine_ { void* z; }; + struct TT_Stream_ { void* z; }; + struct TT_Face_ { void* z; }; + struct TT_Instance_ { void* z; }; + struct TT_Glyph_ { void* z; }; + struct TT_CharMap_ { void* z; }; + + typedef struct TT_Engine_ TT_Engine; /* engine instance */ + typedef struct TT_Stream_ TT_Stream; /* stream handle type */ + typedef struct TT_Face_ TT_Face; /* face handle type */ + typedef struct TT_Instance_ TT_Instance; /* instance handle type */ + typedef struct TT_Glyph_ TT_Glyph; /* glyph handle type */ + typedef struct TT_CharMap_ TT_CharMap; /* character map handle type */ + + + /* Almost all functions return an error code of this type. */ + + typedef long TT_Error; + + + /*******************************************************************/ + /* */ + /* FreeType API */ + /* */ + /* All these begin with a `TT_' prefix. */ + /* */ + /* Most of them are implemented in the `ttapi.c' source file. */ + /* */ + /*******************************************************************/ + + /* Get version information. */ + + EXPORT_DEF + TT_Error TT_FreeType_Version( int *major, + int *minor ); + + + /* Initialize the engine. */ + + EXPORT_DEF + TT_Error TT_Init_FreeType( TT_Engine* engine ); + + + /* Finalize the engine, and release all allocated objects. */ + + EXPORT_DEF + TT_Error TT_Done_FreeType( TT_Engine engine ); + + + /* Set the gray level palette. This is an array of 5 bytes used */ + /* to produce the font smoothed pixmaps. By convention: */ + /* */ + /* palette[0] = background (white) */ + /* palette[1] = light */ + /* palette[2] = medium */ + /* palette[3] = dark */ + /* palette[4] = foreground (black) */ + /* */ + + EXPORT_DEF + TT_Error TT_Set_Raster_Gray_Palette( TT_Engine engine, + TT_Byte* palette ); + + + /* ----------------------- face management ----------------------- */ + + /* Open a new TrueType font file, and returns a handle for */ + /* it in variable '*face'. */ + /* */ + /* Note: The file can be either a TrueType file (*.ttf) or */ + /* a TrueType collection (*.ttc, in this case, only */ + /* the first face is opened). The number of faces in */ + /* the same collection can be obtained in the face's */ + /* properties, using TT_Get_Face_Properties() and the */ + /* `max_Faces' field. */ + + EXPORT_DEF + TT_Error TT_Open_Face( TT_Engine engine, + const TT_Text* fontPathName, + TT_Face* face ); + + + /* Open a TrueType font file located inside a collection. */ + /* The font is assigned by its index in `fontIndex'. */ + + EXPORT_DEF + TT_Error TT_Open_Collection( TT_Engine engine, + const TT_Text* collectionPathName, + TT_ULong fontIndex, + TT_Face* face ); + + + /* Return face properties in the `properties' structure. */ + /* */ + /* Note that since version 1.3, we support font files with no */ + /* OS/2 table (mainly old Mac fonts). In this case, the OS/2 */ + /* `version' field will be set to 0xFFFF, and all other fields */ + /* will be zeroed. */ + + EXPORT_DEF + TT_Error TT_Get_Face_Properties( TT_Face face, + TT_Face_Properties* properties ); + + + /* Set a face object's generic pointer */ + + EXPORT_DEF + TT_Error TT_Set_Face_Pointer( TT_Face face, + void* data ); + + + /* Get a face object's generic pointer */ + + EXPORT_DEF + void* TT_Get_Face_Pointer( TT_Face face ); + + + /* Close a face's file handle to save system resources. The file */ + /* will be re-opened automatically on the next disk access. */ + + EXPORT_DEF + TT_Error TT_Flush_Face( TT_Face face ); + + /* Get a face's glyph metrics expressed in font units. Returns any */ + /* number of arrays. Set the fields to NULL if you are not interested */ + /* by a given array. */ + + EXPORT_DEF + TT_Error TT_Get_Face_Metrics( TT_Face face, + TT_UShort firstGlyph, + TT_UShort lastGlyph, + TT_Short* leftBearings, + TT_UShort* widths, + TT_Short* topBearings, + TT_UShort* heights ); + + + /* Close a given font object, destroying all associated */ + /* instances. */ + + EXPORT_DEF + TT_Error TT_Close_Face( TT_Face face ); + + + /* Get font or table data. */ + + EXPORT_DEF + TT_Error TT_Get_Font_Data( TT_Face face, + TT_ULong tag, + TT_Long offset, + void* buffer, + TT_Long* length ); + + +/* A simple macro to build table tags from ASCII chars */ + +#define MAKE_TT_TAG( _x1, _x2, _x3, _x4 ) \ + (((TT_ULong)_x1 << 24) | \ + ((TT_ULong)_x2 << 16) | \ + ((TT_ULong)_x3 << 8) | \ + (TT_ULong)_x4) + + + + /* ----------------------- instance management -------------------- */ + + /* Open a new font instance and returns an instance handle */ + /* for it in `*instance'. */ + + EXPORT_DEF + TT_Error TT_New_Instance( TT_Face face, + TT_Instance* instance ); + + + /* Set device resolution for a given instance. The values are */ + /* given in dpi (Dots Per Inch). Default is 96 in both directions. */ + + EXPORT_DEF + TT_Error TT_Set_Instance_Resolutions( TT_Instance instance, + TT_UShort xResolution, + TT_UShort yResolution ); + + + /* Set the pointsize for a given instance. Default is 10pt. */ + + EXPORT_DEF + TT_Error TT_Set_Instance_CharSize( TT_Instance instance, + TT_F26Dot6 charSize ); + + EXPORT_DEF + TT_Error TT_Set_Instance_CharSizes( TT_Instance instance, + TT_F26Dot6 charWidth, + TT_F26Dot6 charHeight ); + +#define TT_Set_Instance_PointSize( ins, ptsize ) \ + TT_Set_Instance_CharSize( ins, ptsize*64L ) + + EXPORT_DEF + TT_Error TT_Set_Instance_PixelSizes( TT_Instance instance, + TT_UShort pixelWidth, + TT_UShort pixelHeight, + TT_F26Dot6 pointSize ); + + + /* This function has been deprecated! Do not use it, as it */ + /* doesn't work reliably. You can perfectly control hinting */ + /* yourself when loading glyphs, then apply transforms as usual. */ + + EXPORT_DEF + TT_Error TT_Set_Instance_Transform_Flags( TT_Instance instance, + TT_Bool rotated, + TT_Bool stretched ); + + + /* Return instance metrics in `metrics'. */ + + EXPORT_DEF + TT_Error TT_Get_Instance_Metrics( TT_Instance instance, + TT_Instance_Metrics* metrics ); + + + /* Set an instance's generic pointer. */ + + EXPORT_DEF + TT_Error TT_Set_Instance_Pointer( TT_Instance instance, + void* data ); + + + /* Get an instance's generic pointer. */ + + EXPORT_DEF + void* TT_Get_Instance_Pointer( TT_Instance instance ); + + + /* Close a given instance object, destroying all associated data. */ + + EXPORT_DEF + TT_Error TT_Done_Instance( TT_Instance instance ); + + + + /* ----------------------- glyph management ----------------------- */ + + /* Create a new glyph object related to the given `face'. */ + + EXPORT_DEF + TT_Error TT_New_Glyph( TT_Face face, + TT_Glyph* glyph ); + + + /* Discard (and destroy) a given glyph object. */ + + EXPORT_DEF + TT_Error TT_Done_Glyph( TT_Glyph glyph ); + + +#define TTLOAD_SCALE_GLYPH 1 +#define TTLOAD_HINT_GLYPH 2 +#define TTLOAD_PEDANTIC 128 +#define TTLOAD_IGNORE_GLOBAL_ADVANCE_WIDTH 256 + +#define TTLOAD_DEFAULT (TTLOAD_SCALE_GLYPH | TTLOAD_HINT_GLYPH) + + + /* Load and process (scale/transform and hint) a glyph from the */ + /* given `instance'. The glyph and instance handles must be */ + /* related to the same face object. The glyph index can be */ + /* computed with a call to TT_Char_Index(). */ + /* */ + /* The 'load_flags' argument is a combination of the macros */ + /* TTLOAD_SCALE_GLYPH and TTLOAD_HINT_GLYPH. Hinting will be */ + /* applied only if the scaling is selected. */ + /* */ + /* If scaling is off (i.e., load_flags = 0), the returned */ + /* outlines are in EM square coordinates (also called FUnits), */ + /* extracted directly from the font with no hinting. Other */ + /* glyph metrics are also in FUnits. */ + /* */ + /* If scaling is on, the returned outlines are in fractional */ + /* pixel units (i.e. TT_F26Dot6 = 26.6 fixed floats). */ + /* */ + /* NOTE: The glyph index must be in the range 0..num_glyphs-1, */ + /* where `num_glyphs' is the total number of glyphs in */ + /* the font file (given in the face properties). */ + + EXPORT_DEF + TT_Error TT_Load_Glyph( TT_Instance instance, + TT_Glyph glyph, + TT_UShort glyphIndex, + TT_UShort loadFlags ); + + + /* Return glyph outline pointers in `outline'. Note that the returned */ + /* pointers are owned by the glyph object, and will be destroyed with */ + /* it. The client application should _not_ change the pointers. */ + + EXPORT_DEF + TT_Error TT_Get_Glyph_Outline( TT_Glyph glyph, + TT_Outline* outline ); + + + /* Copy the glyph metrics into `metrics'. */ + + EXPORT_DEF + TT_Error TT_Get_Glyph_Metrics( TT_Glyph glyph, + TT_Glyph_Metrics* metrics ); + + + /* Copy the glyph's big metrics into `metrics'. */ + /* Necessary to obtain vertical metrics. */ + + EXPORT_DEF + TT_Error TT_Get_Glyph_Big_Metrics( TT_Glyph glyph, + TT_Big_Glyph_Metrics* metrics ); + + + /* Render the glyph into a bitmap, with given position offsets. */ + /* */ + /* Note: Only use integer pixel offsets to preserve the fine */ + /* hinting of the glyph and the `correct' anti-aliasing */ + /* (where vertical and horizontal stems aren't grayed). This */ + /* means that `xOffset' and `yOffset' must be multiples */ + /* of 64! */ + + EXPORT_DEF + TT_Error TT_Get_Glyph_Bitmap( TT_Glyph glyph, + TT_Raster_Map* map, + TT_F26Dot6 xOffset, + TT_F26Dot6 yOffset ); + + + /* Render the glyph into a pixmap, with given position offsets. */ + /* */ + /* Note: Only use integer pixel offsets to preserve the fine */ + /* hinting of the glyph and the `correct' anti-aliasing */ + /* (where vertical and horizontal stems aren't grayed). This */ + /* means that `xOffset' and `yOffset' must be multiples */ + /* of 64! */ + + EXPORT_DEF + TT_Error TT_Get_Glyph_Pixmap( TT_Glyph glyph, + TT_Raster_Map* map, + TT_F26Dot6 xOffset, + TT_F26Dot6 yOffset ); + + + + /* ----------------------- outline support ------------------------ */ + + /* Allocate a new outline. Reserve space for `numPoints' and */ + /* `numContours'. */ + + EXPORT_DEF + TT_Error TT_New_Outline( TT_UShort numPoints, + TT_Short numContours, + TT_Outline* outline ); + + + /* Release an outline. */ + + EXPORT_DEF + TT_Error TT_Done_Outline( TT_Outline* outline ); + + + /* Copy an outline into another one. */ + + EXPORT_DEF + TT_Error TT_Copy_Outline( TT_Outline* source, + TT_Outline* target ); + + + /* Render an outline into a bitmap. */ + + EXPORT_DEF + TT_Error TT_Get_Outline_Bitmap( TT_Engine engine, + TT_Outline* outline, + TT_Raster_Map* map ); + + + /* Render an outline into a pixmap. */ + + EXPORT_DEF + TT_Error TT_Get_Outline_Pixmap( TT_Engine engine, + TT_Outline* outline, + TT_Raster_Map* map ); + + + /* Return an outline's bounding box -- this function is slow as it */ + /* performs a complete scan-line process, without drawing, to get */ + /* the most accurate values. */ + + EXPORT_DEF + TT_Error TT_Get_Outline_BBox( TT_Outline* outline, + TT_BBox* bbox ); + + + /* Apply a transformation to a glyph outline. */ + + EXPORT_DEF + void TT_Transform_Outline( TT_Outline* outline, + TT_Matrix* matrix ); + + + /* Apply a translation to a glyph outline. */ + + EXPORT_DEF + void TT_Translate_Outline( TT_Outline* outline, + TT_F26Dot6 xOffset, + TT_F26Dot6 yOffset ); + + + /* Apply a transformation to a vector. */ + + EXPORT_DEF + void TT_Transform_Vector( TT_F26Dot6* x, + TT_F26Dot6* y, + TT_Matrix* matrix ); + + + /* Compute A*B/C with 64 bits intermediate precision. */ + + EXPORT_DEF + TT_Long TT_MulDiv( TT_Long A, + TT_Long B, + TT_Long C ); + + + /* Compute A*B/0x10000 with 64 bits intermediate precision. */ + /* Useful to multiply by a 16.16 fixed float value. */ + + EXPORT_DEF + TT_Long TT_MulFix( TT_Long A, + TT_Long B ); + + + /* ----------------- character mapping support --------------- */ + + /* Return the number of character mappings found in this file. */ + /* Returns -1 in case of failure (invalid face handle). */ + /* */ + /* DON'T USE THIS FUNCTION! IT HAS BEEN DEPRECATED! */ + /* */ + /* It is retained for backwards compatibility only and will */ + /* fail on 16bit systems. */ + /* */ + /* You can now get the charmap count in the `num_CharMaps' */ + /* field of a face's properties. */ + /* */ + + EXPORT_DEF + int TT_Get_CharMap_Count( TT_Face face ); + + + /* Return the ID of charmap number `charmapIndex' of a given face */ + /* used to enumerate the charmaps present in a TrueType file. */ + + EXPORT_DEF + TT_Error TT_Get_CharMap_ID( TT_Face face, + TT_UShort charmapIndex, + TT_UShort* platformID, + TT_UShort* encodingID ); + + + /* Look up the character maps found in `face' and return a handle */ + /* for the one matching `platformID' and `platformEncodingID' */ + /* (see the TrueType specs relating to the `cmap' table for */ + /* information on these ID numbers). Returns an error code. */ + /* In case of failure, the handle is set to NULL and is invalid. */ + + EXPORT_DEF + TT_Error TT_Get_CharMap( TT_Face face, + TT_UShort charmapIndex, + TT_CharMap* charMap ); + + + /* Translate a character code through a given character map */ + /* and return the corresponding glyph index to be used in */ + /* a TT_Load_Glyph() call. This function returns 0 in case */ + /* of failure. */ + + EXPORT_DEF + TT_UShort TT_Char_Index( TT_CharMap charMap, + TT_UShort charCode ); + + + + /* --------------------- names table support ------------------- */ + + /* Return the number of name strings found in the name table. */ + /* Returns -1 in case of failure (invalid face handle). */ + /* */ + /* DON'T USE THIS FUNCTION! IT HAS BEEN DEPRECATED! */ + /* */ + /* It is retained for backwards compatibility only and will */ + /* fail on 16bit systems. */ + /* */ + /* You can now get the number of name strings in a face with */ + /* the `num_Names' field of its properties. */ + + EXPORT_DEF + int TT_Get_Name_Count( TT_Face face ); + + + /* Return the ID of the name number `nameIndex' of a given face */ + /* used to enumerate the charmaps present in a TrueType file. */ + + EXPORT_DEF + TT_Error TT_Get_Name_ID( TT_Face face, + TT_UShort nameIndex, + TT_UShort* platformID, + TT_UShort* encodingID, + TT_UShort* languageID, + TT_UShort* nameID ); + + + /* Return the address and length of the name number `nameIndex' */ + /* of a given face in the variables `stringPtr' resp. `length'. */ + /* The string is part of the face object and shouldn't be */ + /* written to or released. */ + /* */ + /* Note that for an invalid platform ID a null pointer will be */ + /* returned. */ + + EXPORT_DEF + TT_Error TT_Get_Name_String( TT_Face face, + TT_UShort nameIndex, + TT_String** stringPtr, + TT_UShort* length ); + + +#ifdef __cplusplus + } +#endif + +#endif /* FREETYPE_H */ + + +/* END */ diff --git a/lib/fterrid.h b/lib/fterrid.h new file mode 100644 index 0000000..0444e6f --- /dev/null +++ b/lib/fterrid.h @@ -0,0 +1,161 @@ +/******************************************************************* + * + * fterrid.h + * + * TrueType Error ID definitions + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef FREETYPE_H +#error "Don't include this file! Use freetype.h instead." +#endif + +#ifndef FTERRID_H +#define FTERRID_H + + /************************ error codes declaration **************/ + + /* The error codes are grouped in 'classes' used to indicate the */ + /* 'level' at which the error happened. */ + /* The class is given by an error code's high byte. */ + + + /* ------------- Success is always 0 -------- */ + +#define TT_Err_Ok 0 + + + /* -------- High-level API error codes ------ */ + +#define TT_Err_Invalid_Face_Handle 0x001 +#define TT_Err_Invalid_Instance_Handle 0x002 +#define TT_Err_Invalid_Glyph_Handle 0x003 +#define TT_Err_Invalid_CharMap_Handle 0x004 +#define TT_Err_Invalid_Result_Address 0x005 +#define TT_Err_Invalid_Glyph_Index 0x006 +#define TT_Err_Invalid_Argument 0x007 +#define TT_Err_Could_Not_Open_File 0x008 +#define TT_Err_File_Is_Not_Collection 0x009 + +#define TT_Err_Table_Missing 0x00A +#define TT_Err_Invalid_Horiz_Metrics 0x00B +#define TT_Err_Invalid_CharMap_Format 0x00C +#define TT_Err_Invalid_PPem 0x00D +#define TT_Err_Invalid_Vert_Metrics 0x00E + +#define TT_Err_Invalid_File_Format 0x010 + +#define TT_Err_Invalid_Engine 0x020 +#define TT_Err_Too_Many_Extensions 0x021 +#define TT_Err_Extensions_Unsupported 0x022 +#define TT_Err_Invalid_Extension_Id 0x023 + +#define TT_Err_No_Vertical_Data 0x030 + +#define TT_Err_Max_Profile_Missing 0x080 +#define TT_Err_Header_Table_Missing 0x081 +#define TT_Err_Horiz_Header_Missing 0x082 +#define TT_Err_Locations_Missing 0x083 +#define TT_Err_Name_Table_Missing 0x084 +#define TT_Err_CMap_Table_Missing 0x085 +#define TT_Err_Hmtx_Table_Missing 0x086 +#define TT_Err_OS2_Table_Missing 0x087 +#define TT_Err_Post_Table_Missing 0x088 +#define TT_Err_Glyf_Table_Missing 0x089 + + + /* -------- Memory component error codes ---- */ + + /* this error indicates that an operation cannot */ + /* be performed due to memory exhaustion. */ + +#define TT_Err_Out_Of_Memory 0x100 + + + /* -------- File component error codes ------ */ + + /* these error codes indicate that the file could */ + /* not be accessed properly. Usually, this means */ + /* a broken font file! */ + +#define TT_Err_Invalid_File_Offset 0x200 +#define TT_Err_Invalid_File_Read 0x201 +#define TT_Err_Invalid_Frame_Access 0x202 + + + /* -------- Glyph loader error codes -------- */ + + /* Produced only by the glyph loader, these error */ + /* codes indicate a broken glyph in a font file. */ + +#define TT_Err_Too_Many_Points 0x300 +#define TT_Err_Too_Many_Contours 0x301 +#define TT_Err_Invalid_Composite 0x302 +#define TT_Err_Too_Many_Ins 0x303 + + + /* --- bytecode interpreter error codes ----- */ + + /* These error codes are produced by the TrueType */ + /* bytecode interpreter. They usually indicate a */ + /* broken font file, a broken glyph within a font */ + /* file, or a bug in the interpreter! */ + +#define TT_Err_Invalid_Opcode 0x400 +#define TT_Err_Too_Few_Arguments 0x401 +#define TT_Err_Stack_Overflow 0x402 +#define TT_Err_Code_Overflow 0x403 +#define TT_Err_Bad_Argument 0x404 +#define TT_Err_Divide_By_Zero 0x405 +#define TT_Err_Storage_Overflow 0x406 +#define TT_Err_Cvt_Overflow 0x407 +#define TT_Err_Invalid_Reference 0x408 +#define TT_Err_Invalid_Distance 0x409 +#define TT_Err_Interpolate_Twilight 0x40A +#define TT_Err_Debug_OpCode 0x40B +#define TT_Err_ENDF_In_Exec_Stream 0x40C +#define TT_Err_Out_Of_CodeRanges 0x40D +#define TT_Err_Nested_DEFS 0x40E +#define TT_Err_Invalid_CodeRange 0x40F +#define TT_Err_Invalid_Displacement 0x410 +#define TT_Err_Execution_Too_Long 0x411 + + + /* ------ internal failure error codes ----- */ + + /* These error codes are produced when an incoherent */ + /* library state has been detected. These reflect a */ + /* severe bug in the engine! (Or a major overwrite */ + /* of your application into the library's data.) */ + +#define TT_Err_Nested_Frame_Access 0x500 +#define TT_Err_Invalid_Cache_List 0x501 +#define TT_Err_Could_Not_Find_Context 0x502 +#define TT_Err_Unlisted_Object 0x503 + + + /* ---- scan-line converter error codes ----- */ + + /* These error codes are produced by the raster component. */ + /* They indicate that an outline structure was incoherently */ + /* setup, or that you're trying to render an horribly */ + /* complex glyph! */ + +#define TT_Err_Raster_Pool_Overflow 0x600 +#define TT_Err_Raster_Negative_Height 0x601 +#define TT_Err_Raster_Invalid_Value 0x602 +#define TT_Err_Raster_Not_Initialized 0x603 + +#endif /* FTERRID_H */ + + +/* END */ diff --git a/lib/ftnameid.h b/lib/ftnameid.h new file mode 100644 index 0000000..5d51234 --- /dev/null +++ b/lib/ftnameid.h @@ -0,0 +1,628 @@ +/******************************************************************* + * + * ftnameid.h + * + * TrueType Name ID definitions + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef FREETYPE_H +#error "Don't include this file! Use freetype.h instead." +#endif + +#ifndef FTNAMEID_H +#define FTNAMEID_H + +/* + * possible values for the 'Platform' identifier code in the name + * records of the TTF "name" table + */ + +#define TT_PLATFORM_APPLE_UNICODE 0 +#define TT_PLATFORM_MACINTOSH 1 +#define TT_PLATFORM_ISO 2 +#define TT_PLATFORM_MICROSOFT 3 + + +/* + * possible values of the platform specific encoding identifier field in + * the name records of the TTF "name" table when the 'Platform' identifier + * code is TT_PLATFORM_APPLE_UNICODE + */ + +#define TT_APPLE_ID_DEFAULT 0 +#define TT_APPLE_ID_UNICODE_1_1 1 +#define TT_APPLE_ID_ISO_10646 2 +#define TT_APPLE_ID_UNICODE_2_0 3 + + +/* + * possible values of the platform specific encoding identifier field in + * the name records of the TTF "name" table when the 'Platform' identifier + * code is TT_PLATFORM_MACINTOSH + */ + +#define TT_MAC_ID_ROMAN 0 +#define TT_MAC_ID_JAPANESE 1 +#define TT_MAC_ID_TRADITIONAL_CHINESE 2 +#define TT_MAC_ID_KOREAN 3 +#define TT_MAC_ID_ARABIC 4 +#define TT_MAC_ID_HEBREW 5 +#define TT_MAC_ID_GREEK 6 +#define TT_MAC_ID_RUSSIAN 7 +#define TT_MAC_ID_RSYMBOL 8 +#define TT_MAC_ID_DEVANAGARI 9 +#define TT_MAC_ID_GURMUKHI 10 +#define TT_MAC_ID_GUJARATI 11 +#define TT_MAC_ID_ORIYA 12 +#define TT_MAC_ID_BENGALI 13 +#define TT_MAC_ID_TAMIL 14 +#define TT_MAC_ID_TELUGU 15 +#define TT_MAC_ID_KANNADA 16 +#define TT_MAC_ID_MALAYALAM 17 +#define TT_MAC_ID_SINHALESE 18 +#define TT_MAC_ID_BURMESE 19 +#define TT_MAC_ID_KHMER 20 +#define TT_MAC_ID_THAI 21 +#define TT_MAC_ID_LAOTIAN 22 +#define TT_MAC_ID_GEORGIAN 23 +#define TT_MAC_ID_ARMENIAN 24 +#define TT_MAC_ID_MALDIVIAN 25 +#define TT_MAC_ID_SIMPLIFIED_CHINESE 25 +#define TT_MAC_ID_TIBETAN 26 +#define TT_MAC_ID_MONGOLIAN 27 +#define TT_MAC_ID_GEEZ 28 +#define TT_MAC_ID_SLAVIC 29 +#define TT_MAC_ID_VIETNAMESE 30 +#define TT_MAC_ID_SINDHI 31 +#define TT_MAC_ID_UNINTERP 32 + + +/* + * possible values of the platform specific encoding identifier field in + * the name records of the TTF "name" table when the 'Platform' identifier + * code is TT_PLATFORM_ISO + */ + +#define TT_ISO_ID_7BIT_ASCII 0 +#define TT_ISO_ID_10646 1 +#define TT_ISO_ID_8859_1 2 + + +/* + * possible values of the platform specific encoding identifier field in + * the name records of the TTF "name" table when the 'Platform' identifier + * code is TT_PLATFORM_MICROSOFT + */ + +#define TT_MS_ID_SYMBOL_CS 0 +#define TT_MS_ID_UNICODE_CS 1 +#define TT_MS_ID_SJIS 2 +#define TT_MS_ID_GB2312 3 +#define TT_MS_ID_BIG_5 4 +#define TT_MS_ID_WANSUNG 5 +#define TT_MS_ID_JOHAB 6 + + + +/* + * possible values of the language identifier field in the name records of + * the TTF "name" table when the 'Platform' identifier code is + * TT_PLATFORM_MACINTOSH + * + * the canonical source for the Apple assigned Language ID's is at + * http://fonts.apple.com/TTRefMan/RM06/Chap6name.html + */ + +#define TT_MAC_LANGID_ENGLISH 0 +#define TT_MAC_LANGID_FRENCH 1 +#define TT_MAC_LANGID_GERMAN 2 +#define TT_MAC_LANGID_ITALIAN 3 +#define TT_MAC_LANGID_DUTCH 4 +#define TT_MAC_LANGID_SWEDISH 5 +#define TT_MAC_LANGID_SPANISH 6 +#define TT_MAC_LANGID_DANISH 7 +#define TT_MAC_LANGID_PORTUGUESE 8 +#define TT_MAC_LANGID_NORWEGIAN 9 +#define TT_MAC_LANGID_HEBREW 10 +#define TT_MAC_LANGID_JAPANESE 11 +#define TT_MAC_LANGID_ARABIC 12 +#define TT_MAC_LANGID_FINNISH 13 +#define TT_MAC_LANGID_GREEK 14 +#define TT_MAC_LANGID_ICELANDIC 15 +#define TT_MAC_LANGID_MALTESE 16 +#define TT_MAC_LANGID_TURKISH 17 +#define TT_MAC_LANGID_CROATIAN 18 +#define TT_MAC_LANGID_CHINESE_TRADITIONAL 19 +#define TT_MAC_LANGID_URDU 20 +#define TT_MAC_LANGID_HINDI 21 +#define TT_MAC_LANGID_THAI 22 +#define TT_MAC_LANGID_KOREAN 23 +#define TT_MAC_LANGID_LITHUANIAN 24 +#define TT_MAC_LANGID_POLISH 25 +#define TT_MAC_LANGID_HUNGARIAN 26 +#define TT_MAC_LANGID_ESTONIAN 27 +#define TT_MAC_LANGID_LETTISH 28 +#define TT_MAC_LANGID_SAAMISK 29 +#define TT_MAC_LANGID_FAEROESE 30 +#define TT_MAC_LANGID_FARSI 31 +#define TT_MAC_LANGID_RUSSIAN 32 +#define TT_MAC_LANGID_CHINESE_SIMPLIFIED 33 +#define TT_MAC_LANGID_FLEMISH 34 +#define TT_MAC_LANGID_IRISH 35 +#define TT_MAC_LANGID_ALBANIAN 36 +#define TT_MAC_LANGID_ROMANIAN 37 +#define TT_MAC_LANGID_CZECH 38 +#define TT_MAC_LANGID_SLOVAK 39 +#define TT_MAC_LANGID_SLOVENIAN 40 +#define TT_MAC_LANGID_YIDDISH 41 +#define TT_MAC_LANGID_SERBIAN 42 +#define TT_MAC_LANGID_MACEDONIAN 43 +#define TT_MAC_LANGID_BULGARIAN 44 +#define TT_MAC_LANGID_UKRAINIAN 45 +#define TT_MAC_LANGID_BYELORUSSIAN 46 +#define TT_MAC_LANGID_UZBEK 47 +#define TT_MAC_LANGID_KAZAKH 48 +#define TT_MAC_LANGID_AZERBAIJANI 49 +#define TT_MAC_LANGID_AZERBAIJANI_ARABIC_SCRIPT 50 +#define TT_MAC_LANGID_ARMENIAN 51 +#define TT_MAC_LANGID_GEORGIAN 52 +#define TT_MAC_LANGID_MOLDAVIAN 53 +#define TT_MAC_LANGID_KIRGHIZ 54 +#define TT_MAC_LANGID_TAJIKI 55 +#define TT_MAC_LANGID_TURKMEN 56 +#define TT_MAC_LANGID_MONGOLIAN 57 +#define TT_MAC_LANGID_MONGOLIAN_CYRILLIC_SCRIPT 58 +#define TT_MAC_LANGID_PASHTO 59 +#define TT_MAC_LANGID_KURDISH 60 +#define TT_MAC_LANGID_KASHMIRI 61 +#define TT_MAC_LANGID_SINDHI 62 +#define TT_MAC_LANGID_TIBETAN 63 +#define TT_MAC_LANGID_NEPALI 64 +#define TT_MAC_LANGID_SANSKRIT 65 +#define TT_MAC_LANGID_MARATHI 66 +#define TT_MAC_LANGID_BENGALI 67 +#define TT_MAC_LANGID_ASSAMESE 68 +#define TT_MAC_LANGID_GUJARATI 69 +#define TT_MAC_LANGID_PUNJABI 70 +#define TT_MAC_LANGID_ORIYA 71 +#define TT_MAC_LANGID_MALAYALAM 72 +#define TT_MAC_LANGID_KANNADA 73 +#define TT_MAC_LANGID_TAMIL 74 +#define TT_MAC_LANGID_TELUGU 75 +#define TT_MAC_LANGID_SINHALESE 76 +#define TT_MAC_LANGID_BURMESE 77 +#define TT_MAC_LANGID_KHMER 78 +#define TT_MAC_LANGID_LAO 79 +#define TT_MAC_LANGID_VIETNAMESE 80 +#define TT_MAC_LANGID_INDONESIAN 81 +#define TT_MAC_LANGID_TAGALOG 82 +#define TT_MAC_LANGID_MALAY_ROMAN_SCRIPT 83 +#define TT_MAC_LANGID_MALAY_ARABIC_SCRIPT 84 +#define TT_MAC_LANGID_AMHARIC 85 +#define TT_MAC_LANGID_TIGRINYA 86 +#define TT_MAC_LANGID_GALLA 87 +#define TT_MAC_LANGID_SOMALI 88 +#define TT_MAC_LANGID_SWAHILI 89 +#define TT_MAC_LANGID_RUANDA 90 +#define TT_MAC_LANGID_RUNDI 91 +#define TT_MAC_LANGID_CHEWA 92 +#define TT_MAC_LANGID_MALAGASY 93 +#define TT_MAC_LANGID_ESPERANTO 94 +#define TT_MAC_LANGID_WELSH 128 +#define TT_MAC_LANGID_BASQUE 129 +#define TT_MAC_LANGID_CATALAN 130 +#define TT_MAC_LANGID_LATIN 131 +#define TT_MAC_LANGID_QUECHUA 132 +#define TT_MAC_LANGID_GUARANI 133 +#define TT_MAC_LANGID_AYMARA 134 +#define TT_MAC_LANGID_TATAR 135 +#define TT_MAC_LANGID_UIGHUR 136 +#define TT_MAC_LANGID_DZONGKHA 137 +#define TT_MAC_LANGID_JAVANESE 138 +#define TT_MAC_LANGID_SUNDANESE 139 +#define TT_MAC_LANGID_SCOTTISH_GAELIC 140 +#define TT_MAC_LANGID_IRISH_GAELIC 141 +#define TT_MAC_LANGID_BRETON 142 +#define TT_MAC_LANGID_INUKTITUT 143 + + +/* + * possible values of the language identifier field in the name records of + * the TTF "name" table when the 'Platform' identifier code is + * TT_PLATFORM_MICROSOFT + * + * the canonical source for the MS assigned LCID's is at + * http://www.microsoft.com/typography/OTSPEC/lcid-cp.txt + */ + +#define TT_MS_LANGID_ARABIC_SAUDI_ARABIA 0x0401 +#define TT_MS_LANGID_ARABIC_IRAQ 0x0801 +#define TT_MS_LANGID_ARABIC_EGYPT 0x0c01 +#define TT_MS_LANGID_ARABIC_LIBYA 0x1001 +#define TT_MS_LANGID_ARABIC_ALGERIA 0x1401 +#define TT_MS_LANGID_ARABIC_MOROCCO 0x1801 +#define TT_MS_LANGID_ARABIC_TUNISIA 0x1c01 +#define TT_MS_LANGID_ARABIC_OMAN 0x2001 +#define TT_MS_LANGID_ARABIC_YEMEN 0x2401 +#define TT_MS_LANGID_ARABIC_SYRIA 0x2801 +#define TT_MS_LANGID_ARABIC_JORDAN 0x2c01 +#define TT_MS_LANGID_ARABIC_LEBANON 0x3001 +#define TT_MS_LANGID_ARABIC_KUWAIT 0x3401 +#define TT_MS_LANGID_ARABIC_UAE 0x3801 +#define TT_MS_LANGID_ARABIC_BAHRAIN 0x3c01 +#define TT_MS_LANGID_ARABIC_QATAR 0x4001 +#define TT_MS_LANGID_BULGARIAN_BULGARIA 0x0402 +#define TT_MS_LANGID_CATALAN_SPAIN 0x0403 +#define TT_MS_LANGID_CHINESE_TAIWAN 0x0404 +#define TT_MS_LANGID_CHINESE_PRC 0x0804 +#define TT_MS_LANGID_CHINESE_HONG_KONG 0x0c04 +#define TT_MS_LANGID_CHINESE_SINGAPORE 0x1004 +#define TT_MS_LANGID_CHINESE_MACAU 0x1404 +#define TT_MS_LANGID_CZECH_CZECH_REPUBLIC 0x0405 +#define TT_MS_LANGID_DANISH_DENMARK 0x0406 +#define TT_MS_LANGID_GERMAN_GERMANY 0x0407 +#define TT_MS_LANGID_GERMAN_SWITZERLAND 0x0807 +#define TT_MS_LANGID_GERMAN_AUSTRIA 0x0c07 +#define TT_MS_LANGID_GERMAN_LUXEMBOURG 0x1007 +#define TT_MS_LANGID_GERMAN_LIECHTENSTEI 0x1407 +#define TT_MS_LANGID_GREEK_GREECE 0x0408 +#define TT_MS_LANGID_ENGLISH_UNITED_STATES 0x0409 +#define TT_MS_LANGID_ENGLISH_UNITED_KINGDOM 0x0809 +#define TT_MS_LANGID_ENGLISH_AUSTRALIA 0x0c09 +#define TT_MS_LANGID_ENGLISH_CANADA 0x1009 +#define TT_MS_LANGID_ENGLISH_NEW_ZEALAND 0x1409 +#define TT_MS_LANGID_ENGLISH_IRELAND 0x1809 +#define TT_MS_LANGID_ENGLISH_SOUTH_AFRICA 0x1c09 +#define TT_MS_LANGID_ENGLISH_JAMAICA 0x2009 +#define TT_MS_LANGID_ENGLISH_CARIBBEAN 0x2409 +#define TT_MS_LANGID_ENGLISH_BELIZE 0x2809 +#define TT_MS_LANGID_ENGLISH_TRINIDAD 0x2c09 +#define TT_MS_LANGID_ENGLISH_ZIMBABWE 0x3009 +#define TT_MS_LANGID_ENGLISH_PHILIPPINES 0x3409 +#define TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT 0x040a +#define TT_MS_LANGID_SPANISH_MEXICO 0x080a +#define TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT 0x0c0a +#define TT_MS_LANGID_SPANISH_GUATEMALA 0x100a +#define TT_MS_LANGID_SPANISH_COSTA_RICA 0x140a +#define TT_MS_LANGID_SPANISH_PANAMA 0x180a +#define TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC 0x1c0a +#define TT_MS_LANGID_SPANISH_VENEZUELA 0x200a +#define TT_MS_LANGID_SPANISH_COLOMBIA 0x240a +#define TT_MS_LANGID_SPANISH_PERU 0x280a +#define TT_MS_LANGID_SPANISH_ARGENTINA 0x2c0a +#define TT_MS_LANGID_SPANISH_ECUADOR 0x300a +#define TT_MS_LANGID_SPANISH_CHILE 0x340a +#define TT_MS_LANGID_SPANISH_URUGUAY 0x380a +#define TT_MS_LANGID_SPANISH_PARAGUAY 0x3c0a +#define TT_MS_LANGID_SPANISH_BOLIVIA 0x400a +#define TT_MS_LANGID_SPANISH_EL_SALVADOR 0x440a +#define TT_MS_LANGID_SPANISH_HONDURAS 0x480a +#define TT_MS_LANGID_SPANISH_NICARAGUA 0x4c0a +#define TT_MS_LANGID_SPANISH_PUERTO_RICO 0x500a +#define TT_MS_LANGID_FINNISH_FINLAND 0x040b +#define TT_MS_LANGID_FRENCH_FRANCE 0x040c +#define TT_MS_LANGID_FRENCH_BELGIUM 0x080c +#define TT_MS_LANGID_FRENCH_CANADA 0x0c0c +#define TT_MS_LANGID_FRENCH_SWITZERLAND 0x100c +#define TT_MS_LANGID_FRENCH_LUXEMBOURG 0x140c +#define TT_MS_LANGID_FRENCH_MONACO 0x180c +#define TT_MS_LANGID_HEBREW_ISRAEL 0x040d +#define TT_MS_LANGID_HUNGARIAN_HUNGARY 0x040e +#define TT_MS_LANGID_ICELANDIC_ICELAND 0x040f +#define TT_MS_LANGID_ITALIAN_ITALY 0x0410 +#define TT_MS_LANGID_ITALIAN_SWITZERLAND 0x0810 +#define TT_MS_LANGID_JAPANESE_JAPAN 0x0411 +#define TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA 0x0412 +#define TT_MS_LANGID_KOREAN_JOHAB_KOREA 0x0812 +#define TT_MS_LANGID_DUTCH_NETHERLANDS 0x0413 +#define TT_MS_LANGID_DUTCH_BELGIUM 0x0813 +#define TT_MS_LANGID_NORWEGIAN_NORWAY_BOKMAL 0x0414 +#define TT_MS_LANGID_NORWEGIAN_NORWAY_NYNORSK 0x0814 +#define TT_MS_LANGID_POLISH_POLAND 0x0415 +#define TT_MS_LANGID_PORTUGUESE_BRAZIL 0x0416 +#define TT_MS_LANGID_PORTUGUESE_PORTUGAL 0x0816 +#define TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND 0x0417 +#define TT_MS_LANGID_ROMANIAN_ROMANIA 0x0418 +#define TT_MS_LANGID_MOLDAVIAN_MOLDAVIA 0x0818 +#define TT_MS_LANGID_RUSSIAN_RUSSIA 0x0419 +#define TT_MS_LANGID_RUSSIAN_MOLDAVIA 0x0819 +#define TT_MS_LANGID_CROATIAN_CROATIA 0x041a +#define TT_MS_LANGID_SERBIAN_SERBIA_LATIN 0x081a +#define TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC 0x0c1a +#define TT_MS_LANGID_SLOVAK_SLOVAKIA 0x041b +#define TT_MS_LANGID_ALBANIAN_ALBANIA 0x041c +#define TT_MS_LANGID_SWEDISH_SWEDEN 0x041d +#define TT_MS_LANGID_SWEDISH_FINLAND 0x081d +#define TT_MS_LANGID_THAI_THAILAND 0x041e +#define TT_MS_LANGID_TURKISH_TURKEY 0x041f +#define TT_MS_LANGID_URDU_PAKISTAN 0x0420 +#define TT_MS_LANGID_INDONESIAN_INDONESIA 0x0421 +#define TT_MS_LANGID_UKRAINIAN_UKRAINE 0x0422 +#define TT_MS_LANGID_BELARUSIAN_BELARUS 0x0423 +#define TT_MS_LANGID_SLOVENE_SLOVENIA 0x0424 +#define TT_MS_LANGID_ESTONIAN_ESTONIA 0x0425 +#define TT_MS_LANGID_LATVIAN_LATVIA 0x0426 +#define TT_MS_LANGID_LITHUANIAN_LITHUANIA 0x0427 +#define TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA 0x0827 +#define TT_MS_LANGID_MAORI_NEW_ZEALAND 0x0428 +#define TT_MS_LANGID_FARSI_IRAN 0x0429 +#define TT_MS_LANGID_VIETNAMESE_VIET_NAM 0x042a +#define TT_MS_LANGID_ARMENIAN_ARMENIA 0x042b +#define TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN 0x042c +#define TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC 0x082c +#define TT_MS_LANGID_BASQUE_SPAIN 0x042d +#define TT_MS_LANGID_SORBIAN_GERMANY 0x042e +#define TT_MS_LANGID_MACEDONIAN_MACEDONIA 0x042f +#define TT_MS_LANGID_SUTU_SOUTH_AFRICA 0x0430 +#define TT_MS_LANGID_TSONGA_SOUTH_AFRICA 0x0431 +#define TT_MS_LANGID_TSWANA_SOUTH_AFRICA 0x0432 +#define TT_MS_LANGID_VENDA_SOUTH_AFRICA 0x0433 +#define TT_MS_LANGID_XHOSA_SOUTH_AFRICA 0x0434 +#define TT_MS_LANGID_ZULU_SOUTH_AFRICA 0x0435 +#define TT_MS_LANGID_AFRIKAANS_SOUTH_AFRICA 0x0436 +#define TT_MS_LANGID_GEORGIAN_GEORGIA 0x0437 +#define TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS 0x0438 +#define TT_MS_LANGID_HINDI_INDIA 0x0439 +#define TT_MS_LANGID_MALTESE_MALTA 0x043a +#define TT_MS_LANGID_SAAMI_LAPONIA 0x043b +#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043c +#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083c +#define TT_MS_LANGID_MALAY_MALAYSIA 0x043e +#define TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM 0x083e +#define TT_MS_LANGID_KAZAK_KAZAKSTAN 0x043f +#define TT_MS_LANGID_SWAHILI_KENYA 0x0441 +#define TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN 0x0443 +#define TT_MS_LANGID_UZBEK_UZBEKISTAN_CYRILLIC 0x0843 +#define TT_MS_LANGID_TATAR_TATARSTAN 0x0444 +#define TT_MS_LANGID_BENGALI_INDIA 0x0445 +#define TT_MS_LANGID_PUNJABI_INDIA 0x0446 +#define TT_MS_LANGID_GUJARATI_INDIA 0x0447 +#define TT_MS_LANGID_ORIYA_INDIA 0x0448 +#define TT_MS_LANGID_TAMIL_INDIA 0x0449 +#define TT_MS_LANGID_TELUGU_INDIA 0x044a +#define TT_MS_LANGID_KANNADA_INDIA 0x044b +#define TT_MS_LANGID_MALAYALAM_INDIA 0x044c +#define TT_MS_LANGID_ASSAMESE_INDIA 0x044d +#define TT_MS_LANGID_MARATHI_INDIA 0x044e +#define TT_MS_LANGID_SANSKRIT_INDIA 0x044f +#define TT_MS_LANGID_KONKANI_INDIA 0x0457 + + +/* + * possible values of the 'Name' identifier field in the name records of + * the TTF "name" table. These values are platform independent. + */ + +#define TT_NAME_ID_COPYRIGHT 0 +#define TT_NAME_ID_FONT_FAMILY 1 +#define TT_NAME_ID_FONT_SUBFAMILY 2 +#define TT_NAME_ID_UNIQUE_ID 3 +#define TT_NAME_ID_FULL_NAME 4 +#define TT_NAME_ID_VERSION_STRING 5 +#define TT_NAME_ID_PS_NAME 6 +#define TT_NAME_ID_TRADEMARK 7 +/* the following values are from the OpenType spec */ +#define TT_NAME_ID_MANUFACTURER 8 +#define TT_NAME_ID_DESIGNER 9 +#define TT_NAME_ID_DESCRIPTION 10 +#define TT_NAME_ID_VENDOR_URL 11 +#define TT_NAME_ID_DESIGNER_URL 12 +#define TT_NAME_ID_LICENSE 13 +#define TT_NAME_ID_LICENSE_URL 14 +/* number 15 is reserved */ +#define TT_NAME_ID_PREFERRED_FAMILY 16 +#define TT_NAME_ID_PREFERRED_SUBFAMILY 17 +#define TT_NAME_ID_MAC_FULL_NAME 18 + + +/* + * Bit Mask values for the Unicode Ranges from the TTF "OS2 " table. + */ + +/* General Scripts Area */ + +/* Bit 0 C0 Controls and Basic Latin */ +#define TT_UCR_BASIC_LATIN (1L << 0) /* U+0000-U+007F */ +/* Bit 1 C1 Controls and Latin-1 Supplement */ +#define TT_UCR_LATIN1_SUPPLEMENT (1L << 1) /* U+0080-U+00FF */ +/* Bit 2 Latin Extended-A */ +#define TT_UCR_LATIN_EXTENDED_A (1L << 2) /* U+0100-U+017F */ +/* Bit 3 Latin Extended-B */ +#define TT_UCR_LATIN_EXTENDED_B (1L << 3) /* U+0180-U+024F */ +/* Bit 4 IPA Extensions */ +#define TT_UCR_IPA_EXTENSIONS (1L << 4) /* U+0250-U+02AF */ +/* Bit 5 Spacing Modifier Letters */ +#define TT_UCR_SPACING_MODIFIER (1L << 5) /* U+02B0-U+02FF */ +/* Bit 6 Combining Diacritical Marks */ +#define TT_UCR_COMBINING_DIACRITICS (1L << 6) /* U+0300-U+036F */ +/* Bit 7 Greek */ +#define TT_UCR_GREEK (1L << 7) /* U+0370-U+03FF */ +/* Bit 8 is reserved (was: Greek Symbols and Coptic) */ +/* Bit 9 Cyrillic */ +#define TT_UCR_CYRILLIC (1L << 9) /* U+0400-U+04FF */ +/* Bit 10 Armenian */ +#define TT_UCR_ARMENIAN (1L << 10) /* U+0530-U+058F */ +/* Bit 11 Hebrew */ +#define TT_UCR_HEBREW (1L << 11) /* U+0590-U+05FF */ +/* Bit 12 is reserved (was: Hebrew Extended) */ +/* Bit 13 Arabic */ +#define TT_UCR_ARABIC (1L << 13) /* U+0600-U+06FF */ +/* Bit 14 is reserved (was: Arabic Extended) */ +/* Bit 15 Devanagari */ +#define TT_UCR_DEVANAGARI (1L << 15) /* U+0900-U+097F */ +/* Bit 16 Bengali */ +#define TT_UCR_BENGALI (1L << 16) /* U+0980-U+09FF */ +/* Bit 17 Gurmukhi */ +#define TT_UCR_GURMUKHI (1L << 17) /* U+0A00-U+0A7F */ +/* Bit 18 Gujarati */ +#define TT_UCR_GUJARATI (1L << 18) /* U+0A80-U+0AFF */ +/* Bit 19 Oriya */ +#define TT_UCR_ORIYA (1L << 19) /* U+0B00-U+0B7F */ +/* Bit 20 Tamil */ +#define TT_UCR_TAMIL (1L << 20) /* U+0B80-U+0BFF */ +/* Bit 21 Telugu */ +#define TT_UCR_TELUGU (1L << 21) /* U+0C00-U+0C7F */ +/* Bit 22 Kannada */ +#define TT_UCR_KANNADA (1L << 22) /* U+0C80-U+0CFF */ +/* Bit 23 Malayalam */ +#define TT_UCR_MALAYALAM (1L << 23) /* U+0D00-U+0D7F */ +/* Bit 24 Thai */ +#define TT_UCR_THAI (1L << 24) /* U+0E00-U+0E7F */ +/* Bit 25 Lao */ +#define TT_UCR_LAO (1L << 25) /* U+0E80-U+0EFF */ +/* Bit 26 Georgian */ +#define TT_UCR_GEORGIAN (1L << 26) /* U+10A0-U+10FF */ +/* Bit 27 is reserved (was Georgian Extended) */ +/* Bit 28 Hangul Jamo */ +#define TT_UCR_HANGUL_JAMO (1L << 28) /* U+1100-U+11FF */ +/* Bit 29 Latin Extended Additional */ +#define TT_UCR_LATIN_EXTENDED_ADDITIONAL (1L << 29) /* U+1E00-U+1EFF */ +/* Bit 30 Greek Extended */ +#define TT_UCR_GREEK_EXTENDED (1L << 30) /* U+1F00-U+1FFF */ + +/* Symbols Area */ + +/* Bit 31 General Punctuation */ +#define TT_UCR_GENERAL_PUNCTUATION (1L << 31) /* U+2000-U+206F */ +/* Bit 32 Superscripts And Subscripts */ +#define TT_UCR_SUPERSCRIPTS_SUBSCRIPTS (1L << 0) /* U+2070-U+209F */ +/* Bit 33 Currency Symbols */ +#define TT_UCR_CURRENCY_SYMBOLS (1L << 1) /* U+20A0-U+20CF */ +/* Bit 34 Combining Diacritical Marks For Symbols */ +#define TT_UCR_COMBINING_DIACRITICS_SYMB (1L << 2) /* U+20D0-U+20FF */ +/* Bit 35 Letterlike Symbols */ +#define TT_UCR_LETTERLIKE_SYMBOLS (1L << 3) /* U+2100-U+214F */ +/* Bit 36 Number Forms */ +#define TT_UCR_NUMBER_FORMS (1L << 4) /* U+2150-U+218F */ +/* Bit 37 Arrows */ +#define TT_UCR_ARROWS (1L << 5) /* U+2190-U+21FF */ +/* Bit 38 Mathematical Operators */ +#define TT_UCR_MATHEMATICAL_OPERATORS (1L << 6) /* U+2200-U+22FF */ +/* Bit 39 Miscellaneous Technical */ +#define TT_UCR_MISCELLANEOUS_TECHNICAL (1L << 7) /* U+2300-U+23FF */ +/* Bit 40 Control Pictures */ +#define TT_UCR_CONTROL_PICTURES (1L << 8) /* U+2400-U+243F */ +/* Bit 41 Optical Character Recognition */ +#define TT_UCR_OCR (1L << 9) /* U+2440-U+245F */ +/* Bit 42 Enclosed Alphanumerics */ +#define TT_UCR_ENCLOSED_ALPHANUMERICS (1L << 10) /* U+2460-U+24FF */ +/* Bit 43 Box Drawing */ +#define TT_UCR_BOX_DRAWING (1L << 11) /* U+2500-U+257F */ +/* Bit 44 Block Elements */ +#define TT_UCR_BLOCK_ELEMENTS (1L << 12) /* U+2580-U+259F */ +/* Bit 45 Geometric Shapes */ +#define TT_UCR_GEOMETRIC_SHAPES (1L << 13) /* U+25A0-U+25FF */ +/* Bit 46 Miscellaneous Symbols */ +#define TT_UCR_MISCELLANEOUS_SYMBOLS (1L << 14) /* U+2600-U+26FF */ +/* Bit 47 Dingbats */ +#define TT_UCR_DINGBATS (1L << 15) /* U+2700-U+27BF */ + +/* CJK Phonetics and Symbols Area */ + +/* Bit 48 CJK Symbols And Punctuation */ +#define TT_UCR_CJK_SYMBOLS (1L << 16) /* U+3000-U+303F */ +/* Bit 49 Hiragana */ +#define TT_UCR_HIRAGANA (1L << 17) /* U+3040-U+309F */ +/* Bit 50 Katakana */ +#define TT_UCR_KATAKANA (1L << 18) /* U+30A0-U+30FF */ +/* Bit 51 Bopomofo */ +#define TT_UCR_BOPOMOFO (1L << 19) /* U+3100-U+312F */ +/* Bit 52 Hangul Compatibility Jamo */ +#define TT_UCR_HANGUL_COMPATIBILITY_JAMO (1L << 20) /* U+3130-U+318F */ +/* Bit 53 CJK Miscellaneous */ +#define TT_UCR_CJK_MISC (1L << 21) /* U+3190-U+319F */ +/* Bit 54 Enclosed CJK Letters And Months */ +#define TT_UCR_ENCLOSED_CJK_LETTERS_MONTHS (1L << 22) /* U+3200-U+32FF */ +/* Bit 55 CJK Compatibility */ +#define TT_UCR_CJK_COMPATIBILITY (1L << 23) /* U+3300-U+33FF */ + +/* Hangul Syllables Area */ + +/* Bit 56 Hangul */ +#define TT_UCR_HANGUL (1L << 24) /* U+AC00-U+D7A3 */ + +/* Surrogates Area */ + +/* Bit 57 Surrogates */ +#define TT_UCR_SURROGATES (1L << 25) /* U+D800-U+DFFF */ +/* Bit 58 is reserved for Unicode SubRanges */ + +/* CJK Ideographs Area */ + +/* Bit 59 CJK Unified Ideographs */ +#define TT_UCR_CJK_UNIFIED_IDEOGRAPHS (1L << 27) /* U+4E00-U+9FFF */ + +/* Private Use Area */ + +/* Bit 60 Private Use */ +#define TT_UCR_PRIVATE_USE (1L << 28) /* U+E000-U+F8FF */ + +/* Compatibility Area and Specials */ + +/* Bit 61 CJK Compatibility Ideographs */ +#define TT_UCR_CJK_COMPATIBILITY_IDEOGRAPHS (1L << 29) /* U+F900-U+FAFF */ +/* Bit 62 Alphabetic Presentation Forms */ +#define TT_UCR_ALPHABETIC_PRESENTATION_FORMS (1L << 30) /* U+FB00-U+FB4F */ +/* Bit 63 Arabic Presentation Forms-A */ +#define TT_UCR_ARABIC_PRESENTATIONS_A (1L << 31) /* U+FB50-U+FSFF */ +/* Bit 64 Combining Half Marks */ +#define TT_UCR_COMBINING_HALF_MARKS (1L << 0) /* U+FE20-U+FE2F */ +/* Bit 65 CJK Compatibility Forms */ +#define TT_UCR_CJK_COMPATIBILITY_FORMS (1L << 1) /* U+FE30-U+FE4F */ +/* Bit 66 Small Form Variants */ +#define TT_UCR_SMALL_FORM_VARIANTS (1L << 2) /* U+FE50-U+FE6F */ +/* Bit 67 Arabic Presentation Forms-B */ +#define TT_UCR_ARABIC_PRESENTATIONS_B (1L << 3) /* U+FE70-U+FEFF */ +/* Bit 68 Halfwidth And Fullwidth Forms */ +#define TT_UCR_HALFWIDTH_FULLWIDTH_FORMS (1L << 4) /* U+FF00-U+FFEF */ +/* Bit 69 Specials */ +#define TT_UCR_SPECIALS (1L << 5) /* U+FEFF, + U+FFF0-U+FFFF */ +/* Bit 70 Tibetan */ +#define TT_UCR_TIBETAN (1L << 6) /* U+0F00-U+0FBF */ + + +/* Some compilers have a very limited length of identifiers. */ +#if defined( __TURBOC__ ) && __TURBOC__ < 0x0410 || defined( __PACIFIC__ ) +#define HAVE_LIMIT_ON_IDENTS +#endif + +#ifndef HAVE_LIMIT_ON_IDENTS + +/* + * Here some alias #defines in order to be clearer. + * + * These are not always #defined to stay within the 31 character limit + * which some compilers have. + * + * Credits go to Dave Hoo for pointing out that modern + * Borland compilers (read: from BC++ 3.1 on) can increase this limit. + * If you get a warning with such a compiler, use the -i40 switch. + */ + +#define TT_UCR_ARABIC_PRESENTATION_FORMS_A \ + TT_UCR_ARABIC_PRESENTATIONS_A +#define TT_UCR_ARABIC_PRESENTATION_FORMS_B \ + TT_UCR_ARABIC_PRESENTATIONS_B + +#define TT_UCR_COMBINING_DIACRITICAL_MARKS \ + TT_UCR_COMBINING_DIACRITICS +#define TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB \ + TT_UCR_COMBINING_DIACRITICS_SYMB + +#endif /* ndef HAVE_LIMIT_ON_IDENTS */ + +#endif /* FTNAMEID_H */ + + +/* END */ diff --git a/lib/header.h b/lib/header.h new file mode 100644 index 0000000..ebd5574 --- /dev/null +++ b/lib/header.h @@ -0,0 +1,49 @@ +/******************************************************************* + * + * Function : + * + * Description : + * + * Input : + * + * Output : + * + * Notes : + * + ******************************************************************/ + +/******************************************************************* + * + * Function : + * + * Description : + * + * Input : None + * + * Output : Error code. + * + ******************************************************************/ + +/******************************************************************* + * + * Function : + * + * Description : + * + ******************************************************************/ + +/******************************************************************* + * + * Component Name (e.g. TTRaster.C) + eventually a version number. + * + * Component Short Description (e.g. Rasterizer). + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ diff --git a/lib/ttapi.c b/lib/ttapi.c new file mode 100644 index 0000000..3ee90b4 --- /dev/null +++ b/lib/ttapi.c @@ -0,0 +1,2219 @@ +/******************************************************************* + * + * ttapi.c + * + * High-level interface implementation + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * Notes: + * + * This file is used to implement most of the functions that are + * defined in the file "freetype.h". However, two functions are + * implemented elsewhere : + * + * TT_MulDiv and TT_MulFix are in ttcalc.h/ttcalc.c + * + ******************************************************************/ + +#include "ttconfig.h" + +#include "freetype.h" +#include "ttengine.h" +#include "ttcalc.h" +#include "ttmemory.h" +#include "ttcache.h" +#include "ttfile.h" +#include "ttobjs.h" +#include "ttload.h" +#include "ttgload.h" +#include "ttraster.h" +#include "ttextend.h" + + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_api + + +#ifdef TT_STATIC_RASTER +#define RAS_OPS /* void */ +#define RAS_OP /* void */ +#else +#define RAS_OPS ((TRaster_Instance*)_engine->raster_component), +#define RAS_OP ((TRaster_Instance*)_engine->raster_component) +#endif /* TT_STATIC_RASTER */ + + +#define RENDER_Glyph( glyph, target ) \ + Render_Glyph( RAS_OPS glyph, target ) + +#define RENDER_Gray_Glyph( glyph, target, palette ) \ + Render_Gray_Glyph( RAS_OPS glyph, target, palette ) + + + +/******************************************************************* + * + * Function : TT_FreeType_Version + * + * Description : Returns the major and minor version of the library. + * + * Input : major, minor addresses + * + * Output : Error code. + * + * MT-Note : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_FreeType_Version( int *major, int *minor ) + { + if ( !major || !minor ) + return TT_Err_Invalid_Argument; + + *major = TT_FREETYPE_MAJOR; + *minor = TT_FREETYPE_MINOR; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Init_FreeType + * + * Description : The library's engine initializer. This function + * must be called prior to any call. + * + * Input : engine pointer to a FreeType engine instance + * + * Output : Error code. + * + * MT-Note : This function should be called each time you want + * to create a TT_Engine. It is not necessarily thread + * safe depending on the implementations of ttmemory, + * ttfile and ttmutex, so take care. Their default + * implementations are safe, however. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Init_FreeType( TT_Engine* engine ) + { + PEngine_Instance _engine; + + TT_Error error; + int n; + + + /* first of all, initialize memory sub-system */ + error = TTMemory_Init(); + if ( error ) + return error; + + /* Allocate engine instance */ + if ( ALLOC( _engine, sizeof ( TEngine_Instance ) ) ) + return error; + +#undef TT_FAIL +#define TT_FAIL( x ) ( error = x (_engine) ) != TT_Err_Ok + + /* Initalize components */ + if ( TT_FAIL( TTFile_Init ) || + TT_FAIL( TTCache_Init ) || +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE + TT_FAIL( TTExtend_Init ) || +#endif + TT_FAIL( TTObjs_Init ) || + TT_FAIL( TTRaster_Init ) ) + goto Fail; + +#undef TT_FAIL + + /* set the gray palette defaults: 0 to 4 */ + for ( n = 0; n < 5; n++ ) + _engine->raster_palette[n] = (Byte)n; /* Conversion ok, some warn */ + + /* create the engine lock */ + MUTEX_Create( _engine->lock ); + + HANDLE_Set( *engine, _engine ); + return TT_Err_Ok; + + Fail: + TT_Done_FreeType( *engine ); + HANDLE_Set( *engine, NULL ); + return error; + } + + +/******************************************************************* + * + * Function : TT_Done_FreeType + * + * Description : The library's engine finalizer. This function + * will discard all active face and glyph objects + * from the heap. + * + * Input : engine FreeType engine instance + * + * Output : Error code. + * + * MT-Note : Destroys an engine. Not necessarily thread-safe + * depending on the implementations of ttmemory, + * ttfile and ttmutex. The default implementations + * are safe, however. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Done_FreeType( TT_Engine engine ) + { + PEngine_Instance _engine = HANDLE_Engine( engine ); + + + if ( !_engine ) + return TT_Err_Ok; + + MUTEX_Destroy( _engine->lock ); + + TTRaster_Done( _engine ); + TTObjs_Done ( _engine ); +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE + TTExtend_Done( _engine ); +#endif + TTCache_Done ( _engine ); + TTFile_Done ( _engine ); + FREE( _engine ); + + TTMemory_Done(); + + return TT_Err_Ok; + } + + +#ifdef TT_CONFIG_OPTION_GRAY_SCALING + +/******************************************************************* + * + * Function : TT_Set_Raster_Gray_Palette + * + * Description : Sets the gray-levels palette used for font + * smoothing. + * + * Input : engine FreeType engine instance + * palette address of palette (a 5 byte array) + * + * Output : Invalid argument if 'palette' is NULL. + * + * MT-Note: NO! Unprotected modification of an engine's palette. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Set_Raster_Gray_Palette( TT_Engine engine, + Byte* palette ) + { + int i; + + + if ( !palette ) + return TT_Err_Invalid_Argument; + + for ( i = 0; i < 5; i++ ) + HANDLE_Engine( engine )->raster_palette[i] = (Byte)palette[i]; + + return TT_Err_Ok; + } + +#endif /* TT_CONFIG_OPTION_GRAY_SCALING */ + + +/******************************************************************* + * + * Function : TT_Open_Face + * + * Description : Creates a new face object from a given font file. + * + * Input : engine FreeType engine instance + * fontPathName the font file's pathname + * face adress of returned face handle + * + * Output : Error code. + * + * Note : The face handle is set to NULL in case of failure. + * + * MT-Note : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Open_Face( TT_Engine engine, + const TT_Text* fontPathName, + TT_Face* face ) + { + PEngine_Instance _engine = HANDLE_Engine( engine ); + + TFont_Input input; + TT_Error error; + TT_Stream stream; + PFace _face; + + + if ( !_engine ) + return TT_Err_Invalid_Engine; + + /* open the file */ + error = TT_Open_Stream( fontPathName, &stream ); + if ( error ) + return error; + + input.stream = stream; + input.fontIndex = 0; + input.engine = _engine; + + /* Create and load the new face object - this is thread-safe */ + error = CACHE_New( _engine->objs_face_cache, + _face, + &input ); + + /* Set the handle */ + HANDLE_Set( *face, _face ); + + if ( error ) + goto Fail; + + return TT_Err_Ok; + + Fail: + TT_Close_Stream( &stream ); + return error; + } + + +/******************************************************************* + * + * Function : TT_Open_Collection + * + * Description : Creates a new face object from a given font file. + * + * Input : engine FreeType engine instance + * collectionPathName the font file's pathname + * fontIndex index of font in TrueType collection + * face adress of returned face handle + * + * Output : Error code. + * + * Note : The face handle is set to NULL in case of failure. + * + * MT-Note : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Open_Collection( TT_Engine engine, + const TT_Text* collectionPathName, + TT_ULong fontIndex, + TT_Face* face ) + { + PEngine_Instance _engine = HANDLE_Engine( engine ); + + TFont_Input input; + TT_Error error; + TT_Stream stream; + PFace _face; + + + if ( !_engine ) + return TT_Err_Invalid_Engine; + + /* open the file */ + error = TT_Open_Stream( collectionPathName, &stream ); + if ( error ) + return error; + + input.stream = stream; + input.fontIndex = fontIndex; + input.engine = _engine; + + /* Create and load the new face object - this is thread-safe */ + error = CACHE_New( _engine->objs_face_cache, + _face, + &input ); + + /* Set the handle */ + HANDLE_Set( *face, _face ); + + if ( error ) + goto Fail; + + return TT_Err_Ok; + + Fail: + TT_Close_Stream( &stream ); + + return error; + } + + +/******************************************************************* + * + * Function : TT_Get_Face_Properties + * + * Description : Returns face properties. + * + * Input : face the face handle + * properties address of target properties record + * + * Output : Error code. + * + * Note : Currently, max_Faces is always set to 0. + * + * MT-Note : YES! Reads only permanent data. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Face_Properties( TT_Face face, + TT_Face_Properties* properties ) + { + PFace _face = HANDLE_Face( face ); + + + if ( !_face ) + return TT_Err_Invalid_Face_Handle; + + properties->num_Glyphs = _face->numGlyphs; + properties->max_Points = _face->maxPoints; + properties->max_Contours = _face->maxContours; + properties->num_CharMaps = _face->numCMaps; + properties->num_Names = _face->nameTable.numNameRecords; + + if ( _face->ttcHeader.DirCount == 0 ) + properties->num_Faces = 1; + else + properties->num_Faces = _face->ttcHeader.DirCount; + + properties->header = &_face->fontHeader; + properties->horizontal = &_face->horizontalHeader; + + if ( _face->verticalInfo ) + properties->vertical = &_face->verticalHeader; + else + properties->vertical = NULL; + + properties->os2 = &_face->os2; + properties->postscript = &_face->postscript; + properties->hdmx = &_face->hdmx; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Set_Face_Pointer + * + * Description : Each face object has one pointer, which use is + * reserved to client applications. The TrueType + * engine never accesses or uses this field. + * + * This function is used to set the pointer. + * + * Input : face the given face handle + * data the generic pointer value + * + * Output : Error code. + * + * MT-Note : NO! But this function is reserved to "enlightened" + * developers, so it shouldn't be a problem. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Set_Face_Pointer( TT_Face face, + void* data ) + { + PFace faze = HANDLE_Face( face ); + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + else + faze->generic = data; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Get_Face_Pointer + * + * Description : Each face object has one pointer, which use is + * reserved to client applications. The TrueType + * engine never access or use this field. + * + * This function is used to read the pointer. + * + * Input : face the given face handle + * data the generic pointer value + * + * Output : Error code. + * + * MT-Note : NO! But this function is reserved to "enlightened" + * developers, so it shouldn't be a problem. + * + ******************************************************************/ + + EXPORT_FUNC + void* TT_Get_Face_Pointer( TT_Face face ) + { + PFace faze = HANDLE_Face( face ); + + + if ( !faze ) + return NULL; + else + return faze->generic; + } + + +/******************************************************************* + * + * Function : TT_Get_Face_Metrics + * + * Description : This function returns the original horizontal AND + * vertical metrics as found in the "hmtx" and "vmtx" + * tables. These are the glyphs' left-side-bearings + * and advance widths (horizontal), as well as top + * side bearings and advance heights (vertical). + * + * All are expressed in FONT UNITS, a.k.a. EM + * units. + * + * Input : face The given face handle. + * first Index of first glyph in table. + * last Index of last glyph in table. + * + * leftBearings A pointer to an array of TT_Shorts where the + * left side bearings for the glyphs 'first' + * to 'last' will be returned. If these metrics + * don't interest you, simply set it to NULL. + * + * widths A pointer to an array of TT_UShorts + * where the advance widths for the glyphs + * 'first' to 'last' will be returned. If these + * metrics don't interest you, simply set it + * to NULL. + * + * topBearings A pointer to an array of TT_Shorts where the + * top side bearings for the glyphs 'first' + * to 'last' will be returned. If these metrics + * don't interest you, simply set it to NULL. + * + * heights A pointer to an array of TT_UShorts + * where the advance heights for the glyphs + * 'first' to 'last' will be returned. If these + * metrics don't interest you, simply set it + * to NULL. + * + * Output : Error code. + * + * IMPORTANT NOTE : + * + * As vertical metrics are optional in a TrueType font, this + * function will return an error ( TT_Err_No_Vertical_Data ) + * whenever this function is called on such a face with non-NULL + * 'topBearings' or 'heights' arguments. + * + * When a font has no vertical data, the 'vertical' field in its + * properties structure is set to NULL. + * + * MT-Note : YES! Reads only permanent data. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Face_Metrics( TT_Face face, + TT_UShort firstGlyph, + TT_UShort lastGlyph, + TT_Short* leftBearings, + TT_UShort* widths, + TT_Short* topBearings, + TT_UShort* heights ) + { + PFace _face = HANDLE_Face( face ); + UShort num; + + + if ( !_face ) + return TT_Err_Invalid_Face_Handle; + + /* Check the glyph range */ + if ( lastGlyph >= _face->numGlyphs || firstGlyph > lastGlyph ) + return TT_Err_Invalid_Argument; + + num = lastGlyph - firstGlyph; /* number of elements-1 in each array */ + + /* store the left side bearings and advance widths first */ + { + UShort n; + Short left_bearing; + UShort advance_width; + + + for ( n = 0; n <= num; n++ ) + { + TT_Get_Metrics( &_face->horizontalHeader, + firstGlyph + n, &left_bearing, &advance_width ); + + if ( leftBearings ) leftBearings[n] = left_bearing; + if ( widths ) widths[n] = advance_width; + } + } + + /* check for vertical data if topBearings or heights is non-NULL */ + if ( !topBearings && !heights ) + return TT_Err_Ok; + + if ( !_face->verticalInfo ) + return TT_Err_No_Vertical_Data; + + /* store the top side bearings */ + { + UShort n; + Short top_bearing; + UShort advance_height; + + for ( n = 0; n <= num; n++ ) + { + TT_Get_Metrics( (TT_Horizontal_Header*)&_face->verticalHeader, + firstGlyph + n, &top_bearing, &advance_height ); + + if ( topBearings ) topBearings[n] = top_bearing; + if ( heights ) heights[n] = advance_height; + } + } + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Flush_Face + * + * Description : This function is used to close an active face's + * file handle or descriptor. This is useful to save + * system resources, if your application uses tons + * of fonts. + * + * Input : face the given face handle + * + * Output : Error code. + * + * MT-Note : YES! (If ttfile is.) + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Flush_Face( TT_Face face ) + { + PFace faze = HANDLE_Face( face ); + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + else + return TT_Flush_Stream( &faze->stream ); + } + + +/******************************************************************* + * + * Function : TT_Close_Face + * + * Description : Closes an opened face object. This function + * will destroy all objects associated to the + * face, except the glyphs. + * + * Input : face the given face handle + * + * Output : Error code. + * + * NOTE : The handle is set to NULL on exit. + * + * MT-Note : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Close_Face( TT_Face face ) + { + PFace _face = HANDLE_Face( face ); + + + if ( !_face ) + return TT_Err_Invalid_Face_Handle; + + TT_Close_Stream( &_face->stream ); + + /* delete the face object -- this is thread-safe */ + return CACHE_Done( _face->engine->objs_face_cache, _face ); + } + + +/******************************************************************* + * + * Function : TT_New_Instance + * + * Description : Creates a new instance from a given face. + * + * Input : face parent face handle + * instance address of instance handle + * + * Output : Error code. + * + * Note : The handle is set to NULL in case of failure. + * + * MT-Note : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_New_Instance( TT_Face face, + TT_Instance* instance ) + { + TT_Error error; + PFace _face = HANDLE_Face( face ); + PInstance _ins; + + + if ( !_face ) + return TT_Err_Invalid_Face_Handle; + + /* get a new instance from the face's cache -- this is thread-safe */ + error = CACHE_New( &_face->instances, _ins, _face ); + + HANDLE_Set( *instance, _ins ); + + if ( !error ) + { + error = Instance_Init( _ins ); + if ( error ) + { + HANDLE_Set( *instance, NULL ); + CACHE_Done( &_face->instances, _ins ); + } + } + + return error; + } + + +/******************************************************************* + * + * Function : TT_Set_Instance_Resolutions + * + * Description : Resets an instance to a new device resolution. + * + * Input : instance the instance handle + * xResolution new horizontal device resolution in dpi + * yResolution new vertical device resolution in dpi + * + * Output : Error code. + * + * Note : There is no check for overflow; with other words, + * the product of glyph dimensions times the device + * resolutions must have reasonable values. + * + * MT-Note : You should set the charsize or pixel size immediately + * after this call in multi-threaded programs. This will + * force the instance data to be resetted. Otherwise, you + * may encounter corruption when loading two glyphs from + * the same instance concurrently! + * + * Happily, 99.99% will do just that :-) + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Set_Instance_Resolutions( TT_Instance instance, + TT_UShort xResolution, + TT_UShort yResolution ) + { + PInstance ins = HANDLE_Instance( instance ); + + + if ( !ins ) + return TT_Err_Invalid_Instance_Handle; + + ins->metrics.x_resolution = xResolution; + ins->metrics.y_resolution = yResolution; + ins->valid = FALSE; + + /* In the case of a thread-safe implementation, we immediately */ + /* call Instance_Reset in order to change the instance's variable */ + + /* In the case of a non-threaded build, we simply set the 'valid' */ + /* flag to FALSE, which will force the instance's resetting at */ + /* the next glyph loading */ + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Set_Instance_CharSizes + * + * Description : Resets an instance to new point size. + * + * Input : instance the instance handle + * charWidth the new width in 26.6 char points + * charHeight the new height in 26.6 char points + * + * Output : Error code. + * + * Note : There is no check for overflow; with other words, + * the product of glyph dimensions times the device + * resolution must have reasonable values. + * + * MT-Note : NO! This should be called only when setting/resetting + * instances, so there is no need to protect. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Set_Instance_CharSizes( TT_Instance instance, + TT_F26Dot6 charWidth, + TT_F26Dot6 charHeight ) + { + PInstance ins = HANDLE_Instance( instance ); + + + if ( !ins ) + return TT_Err_Invalid_Instance_Handle; + + if ( charWidth < 1 * 64 ) + charWidth = 1 * 64; + + if ( charHeight < 1 * 64 ) + charHeight = 1 * 64; + + ins->metrics.x_scale1 = ( charWidth * ins->metrics.x_resolution ) / 72; + ins->metrics.x_scale2 = ins->owner->fontHeader.Units_Per_EM; + + ins->metrics.y_scale1 = ( charHeight * ins->metrics.y_resolution ) / 72; + ins->metrics.y_scale2 = ins->owner->fontHeader.Units_Per_EM; + + if ( ins->owner->fontHeader.Flags & 8 ) + { + ins->metrics.x_scale1 = (ins->metrics.x_scale1+32) & -64; + ins->metrics.y_scale1 = (ins->metrics.y_scale1+32) & -64; + } + + ins->metrics.x_ppem = ins->metrics.x_scale1 / 64; + ins->metrics.y_ppem = ins->metrics.y_scale1 / 64; + + if ( charWidth > charHeight ) + ins->metrics.pointSize = charWidth; + else + ins->metrics.pointSize = charHeight; + + ins->valid = FALSE; + + return Instance_Reset( ins ); + } + + +/******************************************************************* + * + * Function : TT_Set_Instance_CharSize + * + * Description : Resets an instance to new point size. + * + * Input : instance the instance handle + * charSize the new character size in 26.6 char points + * + * Output : Error code. + * + * Note : There is no check for overflow; with other words, + * the product of glyph dimensions times the device + * resolution must have reasonable values. + * + * MT-Note : NO! This should be called only when setting/resetting + * instances, so there is no need to protect. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Set_Instance_CharSize( TT_Instance instance, + TT_F26Dot6 charSize ) + { + return TT_Set_Instance_CharSizes( instance, charSize, charSize ); + } + + +/******************************************************************* + * + * Function : TT_Set_Instance_PixelSizes + * + * Description : Resets an instance to new pixel sizes + * + * Input : instance the instance handle + * pixelWidth the new width in pixels + * pixelHeight the new height in pixels + * + * Output : Error code. + * + * Note : There is no check for overflow; with other words, + * the product of glyph dimensions times the device + * resolution must have reasonable values. + * + * MT-Note : NO! This should be called only when setting/resetting + * instances, so there is no need to protect. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Set_Instance_PixelSizes( TT_Instance instance, + TT_UShort pixelWidth, + TT_UShort pixelHeight, + TT_F26Dot6 pointSize ) + { + PInstance ins = HANDLE_Instance( instance ); + + if ( !ins ) + return TT_Err_Invalid_Instance_Handle; + + if ( pixelWidth < 1 ) pixelWidth = 1; + if ( pixelHeight < 1 ) pixelHeight = 1; + + ins->metrics.x_ppem = pixelWidth; + ins->metrics.y_ppem = pixelHeight; + ins->metrics.pointSize = pointSize; + + ins->metrics.x_scale1 = ins->metrics.x_ppem * 64L; + ins->metrics.x_scale2 = ins->owner->fontHeader.Units_Per_EM; + ins->metrics.y_scale1 = ins->metrics.y_ppem * 64L; + ins->metrics.y_scale2 = ins->owner->fontHeader.Units_Per_EM; + + ins->valid = FALSE; + + return Instance_Reset( ins ); + } + + +/******************************************************************* + * + * Function : TT_Set_Instance_Transform_Flags + * + * Description : Informs the interpreter about the transformations + * that will be applied to the rendered glyphs. + * + * Input : instance the instance handle + * rotated set to TRUE if the glyph are rotated + * stretched set to TRUE if the glyph are stretched + * + * Output : Error code. + * + * Note : This function is deprecated! It's much better to + * control hinting manually when calling TT_Load_Glyph + * than relying on the font programs... + * + * Never use it, unless calling for trouble ;-) + * + * MT-Note : NO! This should be called only when setting/resetting + * instances, so there is no need to protect. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Set_Instance_Transform_Flags( TT_Instance instance, + TT_Bool rotated, + TT_Bool stretched ) + { + PInstance ins = HANDLE_Instance( instance ); + + + if ( !ins ) + return TT_Err_Invalid_Instance_Handle; + + ins->metrics.rotated = rotated; + ins->metrics.stretched = stretched; + ins->valid = FALSE; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Get_Instance_Metrics + * + * Description : Returns instance metrics. + * + * Input : instance the instance handle + * metrics address of target instance metrics record + * + * Output : Error code. + * + * MT-Note : YES! Reads only semi-permanent data. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Instance_Metrics( TT_Instance instance, + TT_Instance_Metrics* metrics ) + { + PInstance ins = HANDLE_Instance( instance ); + + + if ( !ins ) + return TT_Err_Invalid_Instance_Handle; + + if ( !ins->valid ) + Instance_Reset( ins ); + + metrics->pointSize = ins->metrics.pointSize; + + metrics->x_scale = TT_MulDiv( 0x10000, + ins->metrics.x_scale1, + ins->metrics.x_scale2 ); + + metrics->y_scale = TT_MulDiv( 0x10000, + ins->metrics.y_scale1, + ins->metrics.y_scale2 ); + + metrics->x_resolution = ins->metrics.x_resolution; + metrics->y_resolution = ins->metrics.y_resolution; + metrics->x_ppem = ins->metrics.x_ppem; + metrics->y_ppem = ins->metrics.y_ppem; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Set_Instance_Pointer + * + * Description : Each instance has one pointer, which use is + * reserved to client applications. The TrueType + * engine never accesses or uses this field. + * + * This function is used to set the pointer. + * + * Input : face the given face handle + * data the generic pointer value + * + * Output : Error code. + * + * MT-Note : NO! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Set_Instance_Pointer( TT_Instance instance, + void* data ) + { + PInstance ins = HANDLE_Instance( instance ); + + + if ( !ins ) + return TT_Err_Invalid_Instance_Handle; + else + ins->generic = data; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Get_Instance_Pointer + * + * Description : Each instance has one pointer, which use is + * reserved to client applications. The TrueType + * engine never accesses or uses this field. + * + * This function is used to read the pointer. + * + * Input : face the given face handle + * data the generic pointer value + * + * Output : Error code. + * + * MT-Safe : NO! + * + ******************************************************************/ + + EXPORT_FUNC + void* TT_Get_Instance_Pointer( TT_Instance instance ) + { + PInstance ins = HANDLE_Instance( instance ); + + + if ( !ins ) + return NULL; + else + return ins->generic; + } + + +/******************************************************************* + * + * Function : TT_Done_Instance + * + * Description : Closes a given instance. + * + * Input : instance address of instance handle + * + * Output : Error code. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Done_Instance( TT_Instance instance ) + { + PInstance ins = HANDLE_Instance( instance ); + + + if ( !ins ) + return TT_Err_Invalid_Instance_Handle; + + /* delete the instance -- this is thread-safe */ + return CACHE_Done( &ins->owner->instances, ins ); + } + + +/******************************************************************* + * + * Function : TT_New_Glyph + * + * Description : Creates a new glyph object related to a given + * face. + * + * Input : face the face handle + * glyph address of target glyph handle + * + * Output : Error code. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_New_Glyph( TT_Face face, + TT_Glyph* glyph ) + { + TT_Error error; + PFace _face = HANDLE_Face( face ); + PGlyph _glyph; + + + if ( !_face ) + return TT_Err_Invalid_Face_Handle; + + /* get a new glyph from the face's cache -- this is thread-safe */ + error = CACHE_New( &_face->glyphs, _glyph, _face ); + + HANDLE_Set( *glyph, _glyph ); + + return error; + } + + +/******************************************************************* + * + * Function : TT_Done_Glyph + * + * Description : Destroys a given glyph object. + * + * Input : glyph the glyph handle + * + * Output : Error code. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Done_Glyph( TT_Glyph glyph ) + { + PGlyph _glyph = HANDLE_Glyph( glyph ); + + + if ( !_glyph ) + return TT_Err_Invalid_Glyph_Handle; + + /* delete the engine -- this is thread-safe */ + return CACHE_Done( &_glyph->face->glyphs, _glyph ); + } + + +/******************************************************************* + * + * Function : TT_Load_Glyph + * + * Description : Loads a glyph. + * + * Input : instance the instance handle + * glyph the glyph handle + * glyphIndex the glyph index + * loadFlags flags controlling how to load the glyph + * (none, scaled, hinted, both) + * + * Output : Error code. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Load_Glyph( TT_Instance instance, + TT_Glyph glyph, + TT_UShort glyphIndex, + TT_UShort loadFlags ) + { + PInstance _ins; + PGlyph _glyph; + TT_Error error; + + + _ins = HANDLE_Instance( instance ); + + if ( !_ins ) + loadFlags &= ~(TTLOAD_SCALE_GLYPH | TTLOAD_HINT_GLYPH); + + if ( (loadFlags & TTLOAD_SCALE_GLYPH) == 0 ) + _ins = 0; + + _glyph = HANDLE_Glyph( glyph ); + if ( !_glyph ) + return TT_Err_Invalid_Glyph_Handle; + + if ( _ins ) + { + if ( _ins->owner != _glyph->face ) + return TT_Err_Invalid_Face_Handle; + + if ( !_ins->valid ) + { + /* This code can only be called in non thread-safe builds */ + error = Instance_Reset( _ins ); + if ( error ) + return error; + } + } + + return Load_TrueType_Glyph( _ins, _glyph, glyphIndex, loadFlags ); + } + + +/******************************************************************* + * + * Function : TT_Get_Glyph_Outline + * + * Description : Returns the glyph's outline data. + * + * Input : glyph the glyph handle + * outline address where the glyph outline will be returned + * + * Output : Error code. + * + * MT-Safe : YES! Reads only semi-permanent data. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Glyph_Outline( TT_Glyph glyph, + TT_Outline* outline ) + { + PGlyph _glyph = HANDLE_Glyph( glyph ); + + + if ( !_glyph ) + return TT_Err_Invalid_Glyph_Handle; + + *outline = _glyph->outline; + outline->owner = FALSE; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Get_Glyph_Metrics + * + * Description : Extracts the glyph's horizontal metrics information. + * + * Input : glyph glyph object handle + * metrics address where metrics will be returned + * + * Output : Error code. + * + * MT-Safe : NO! Glyph containers can't be shared. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Glyph_Metrics( TT_Glyph glyph, + TT_Glyph_Metrics* metrics ) + { + PGlyph _glyph = HANDLE_Glyph( glyph ); + + + if ( !_glyph ) + return TT_Err_Invalid_Glyph_Handle; + + metrics->bbox = _glyph->metrics.bbox; + metrics->bearingX = _glyph->metrics.horiBearingX; + metrics->bearingY = _glyph->metrics.horiBearingY; + metrics->advance = _glyph->metrics.horiAdvance; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Get_Glyph_Big_Metrics + * + * Description : Extracts the glyph's big metrics information. + * + * Input : glyph glyph object handle + * metrics address where big metrics will be returned + * + * Output : Error code. + * + * MT-Safe : NO! Glyph containers can't be shared. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Glyph_Big_Metrics( TT_Glyph glyph, + TT_Big_Glyph_Metrics* metrics ) + { + PGlyph _glyph = HANDLE_Glyph( glyph ); + + + if ( !_glyph ) + return TT_Err_Invalid_Glyph_Handle; + + *metrics = _glyph->metrics; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Get_Glyph_Bitmap + * + * Description : Produces a bitmap from a glyph outline. + * + * Input : glyph the glyph container's handle + * map target pixmap description block + * xOffset x offset in fractional pixels (26.6 format) + * yOffset y offset in fractional pixels (26.6 format) + * + * Output : Error code. + * + * Note : Only use integer pixel offsets if you want to preserve + * the fine hints applied to the outline. This means that + * xOffset and yOffset must be multiples of 64! + * + * MT-Safe : NO! Glyph containers can't be shared. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Glyph_Bitmap( TT_Glyph glyph, + TT_Raster_Map* map, + TT_F26Dot6 xOffset, + TT_F26Dot6 yOffset ) + { + PEngine_Instance _engine; + TT_Engine engine; + TT_Error error; + PGlyph _glyph = HANDLE_Glyph( glyph ); + + TT_Outline outline; + + + if ( !_glyph ) + return TT_Err_Invalid_Glyph_Handle; + + _engine = _glyph->face->engine; + HANDLE_Set( engine, _engine ); + + outline = _glyph->outline; + /* XXX : For now, use only dropout mode 2 */ + /* outline.dropout_mode = _glyph->scan_type; */ + outline.dropout_mode = 2; + + TT_Translate_Outline( &outline, xOffset, yOffset ); + error = TT_Get_Outline_Bitmap( engine, &outline, map ); + TT_Translate_Outline( &outline, -xOffset, -yOffset ); + + return error; + } + + +#ifdef TT_CONFIG_OPTION_GRAY_SCALING + +/******************************************************************* + * + * Function : TT_Get_Glyph_Pixmap + * + * Description : Produces a grayscaled pixmap from a glyph + * outline. + * + * Input : glyph the glyph container's handle + * map target pixmap description block + * xOffset x offset in fractional pixels (26.6 format) + * yOffset y offset in fractional pixels (26.6 format) + * + * Output : Error code. + * + * Note : Only use integer pixel offsets to preserve the fine + * hinting of the glyph and the 'correct' anti-aliasing + * (where vertical and horizontal stems aren't grayed). + * This means that xOffset and yOffset must be multiples + * of 64! + * + * You can experiment with offsets of +32 to get 'blurred' + * versions of the glyphs (a nice effect at large sizes that + * some graphic designers may appreciate :) + * + * MT-Safe : NO! Glyph containers can't be shared. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Glyph_Pixmap( TT_Glyph glyph, + TT_Raster_Map* map, + TT_F26Dot6 xOffset, + TT_F26Dot6 yOffset ) + { + PEngine_Instance _engine; + TT_Engine engine; + TT_Error error; + PGlyph _glyph = HANDLE_Glyph( glyph ); + + TT_Outline outline; + + + if ( !_glyph ) + return TT_Err_Invalid_Glyph_Handle; + + _engine = _glyph->face->engine; + HANDLE_Set(engine,_engine); + + outline = _glyph->outline; + /* XXX : For now, use only dropout mode 2 */ + /* outline.dropout_mode = _glyph->scan_type; */ + outline.dropout_mode = 2; + + TT_Translate_Outline( &outline, xOffset, yOffset ); + error = TT_Get_Outline_Pixmap( engine, &outline, map ); + TT_Translate_Outline( &outline, -xOffset, -yOffset ); + + return error; + } + +#endif /* TT_CONFIG_OPTION_GRAY_SCALING */ + + + static const TT_Outline null_outline + = { 0, 0, NULL, NULL, NULL, 0, 0, 0, 0 }; + + +/******************************************************************* + * + * Function : TT_New_Outline + * + * Description : Creates a new TrueType outline, reserving + * array space for a given number of points and + * contours. + * + * Input : numPoints number of points + * numContours number of contours + * outline address of target outline structure + * + * Output : Error code + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_New_Outline( TT_UShort numPoints, + TT_Short numContours, + TT_Outline* outline ) + { + TT_Error error; + + + if ( !outline ) + return TT_Err_Invalid_Argument; + + *outline = null_outline; + + if ( ALLOC( outline->points, numPoints*2*sizeof ( TT_F26Dot6 ) ) || + ALLOC( outline->flags, numPoints *sizeof ( Byte ) ) || + ALLOC( outline->contours, numContours*sizeof ( UShort ) ) ) + goto Fail; + + outline->n_points = numPoints; + outline->n_contours = numContours; + outline->owner = TRUE; + return TT_Err_Ok; + + Fail: + outline->owner = TRUE; + TT_Done_Outline( outline ); + return error; + } + + +/******************************************************************* + * + * Function : TT_Done_Outline + * + * Description : Deletes an outline created through TT_New_Outline(). + * Calling this function for outlines returned + * by TT_Get_Glyph_Outline() yields an error. + * + * Input : outline address of outline + * + * Output : Error code. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Done_Outline( TT_Outline* outline ) + { + if ( outline ) + { + if ( outline->owner ) + { + FREE( outline->points ); + FREE( outline->flags ); + FREE( outline->contours ); + } + *outline = null_outline; + return TT_Err_Ok; + } + else + return TT_Err_Invalid_Argument; + } + + +/******************************************************************* + * + * Function : TT_Get_Outline_Bitmap + * + * Description : Render a TrueType outline into a bitmap. + * Note that the bitmap must be created by the caller. + * + * Input : outline the outline to render + * map the target bitmap + * + * Output : Error code. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Outline_Bitmap( TT_Engine engine, + TT_Outline* outline, + TT_Raster_Map* map ) + { + PEngine_Instance _engine = HANDLE_Engine( engine ); + TT_Error error; + + + if ( !_engine ) + return TT_Err_Invalid_Engine; + + if ( !outline || !map ) + return TT_Err_Invalid_Argument; + + MUTEX_Lock( _engine->raster_lock ); + error = RENDER_Glyph( outline, map ); + MUTEX_Release( _engine->raster_lock ); + + return error; + } + + +#ifdef TT_CONFIG_OPTION_GRAY_SCALING + +/******************************************************************* + * + * Function : TT_Get_Outline_Pixmap + * + * Description : Render a TrueType outline into a pixmap. + * Note that the pixmap must be created by the caller. + * + * Input : outline the outline to render + * map the target bitmap + * + * Output : Error code + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Outline_Pixmap( TT_Engine engine, + TT_Outline* outline, + TT_Raster_Map* map ) + { + PEngine_Instance _engine = HANDLE_Engine( engine ); + TT_Error error; + + + if ( !_engine ) + return TT_Err_Invalid_Engine; + + if ( !outline || !map ) + return TT_Err_Invalid_Argument; + + MUTEX_Lock( _engine->raster_lock ); + error = RENDER_Gray_Glyph( outline, map, _engine->raster_palette ); + MUTEX_Release( _engine->raster_lock ); + return error; + } + +#endif /* TT_CONFIG_OPTION_GRAY_SCALING */ + + +/******************************************************************* + * + * Function : TT_Copy_Outline + * + * Description : Copy an outline into another. The source and + * target outlines must have the same points and + * contours numbers. + * + * Input : source address of source outline + * target address of target outline + * + * Output : Error code + * + * Note : This function doesn't touch the target outline's 'owner' + * field. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Copy_Outline( TT_Outline* source, + TT_Outline* target ) + { + if ( !source || !target || + source->n_points != target->n_points || + source->n_contours != target->n_contours ) + return TT_Err_Invalid_Argument; + + MEM_Copy( target->points, source->points, + source->n_points * 2 * sizeof ( TT_F26Dot6 ) ); + + MEM_Copy( target->flags, source->flags, + source->n_points * sizeof ( Byte ) ); + + MEM_Copy( target->contours, source->contours, + source->n_contours * sizeof ( Short ) ); + + target->high_precision = source->high_precision; + target->second_pass = target->second_pass; + target->dropout_mode = source->dropout_mode; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Transform_Outline + * + * Description : Applies a simple transformation to an outline. + * + * Input : outline the glyph's outline. Can be extracted + * from a glyph container through + * TT_Get_Glyph_Outline(). + * + * matrix simple matrix with 16.16 fixed floats + * + * Output : Error code (always TT_Err_Ok). + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + void TT_Transform_Outline( TT_Outline* outline, + TT_Matrix* matrix ) + { + UShort n; + TT_F26Dot6 x, y; + TT_Vector* vec; + + + vec = outline->points; + for ( n = 0; n < outline->n_points; n++ ) + { + x = TT_MulFix( vec->x, matrix->xx ) + + TT_MulFix( vec->y, matrix->xy ); + + y = TT_MulFix( vec->x, matrix->yx ) + + TT_MulFix( vec->y, matrix->yy ); + + vec->x = x; + vec->y = y; + vec++; + } + } + + +/******************************************************************* + * + * Function : TT_Transform_Vector + * + * Description : Apply a simple transform to a vector + * + * Input : x, y the vector. + * + * matrix simple matrix with 16.16 fixed floats + * + * Output : None. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + void TT_Transform_Vector( TT_F26Dot6* x, + TT_F26Dot6* y, + TT_Matrix* matrix ) + { + TT_F26Dot6 xz, yz; + + + xz = TT_MulFix( *x, matrix->xx ) + + TT_MulFix( *y, matrix->xy ); + + yz = TT_MulFix( *x, matrix->yx ) + + TT_MulFix( *y, matrix->yy ); + + *x = xz; + *y = yz; + } + + +/******************************************************************* + * + * Function : TT_Translate_Outline + * + * Description : Applies a simple translation. + * + * Input : outline no comment :) + * xOffset + * yOffset + * + * Output : Error code. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + void TT_Translate_Outline( TT_Outline* outline, + TT_F26Dot6 xOffset, + TT_F26Dot6 yOffset ) + { + UShort n; + TT_Vector* vec = outline->points; + + + for ( n = 0; n < outline->n_points; n++ ) + { + vec->x += xOffset; + vec->y += yOffset; + vec++; + } + } + + +/******************************************************************* + * + * Function : TT_Get_Outline_BBox + * + * Description : Returns an outline's bounding box. + * + * Input : outline no comment :) + * bbox address where the bounding box is returned + * + * Output : Error code. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Outline_BBox( TT_Outline* outline, + TT_BBox* bbox ) + { + TT_F26Dot6 x, y; + UShort k; + + + if ( outline && bbox ) + { + if ( outline->n_points == 0 ) + { + bbox->xMin = 0; + bbox->yMin = 0; + bbox->xMax = 0; + bbox->yMax = 0; + } + else + { + TT_Vector* vec = outline->points; + + bbox->xMin = bbox->xMax = vec->x; + bbox->yMin = bbox->yMax = vec->y; + vec++; + + for ( k = 1; k < outline->n_points; k++ ) + { + x = vec->x; + if ( x < bbox->xMin ) bbox->xMin = x; + if ( x > bbox->xMax ) bbox->xMax = x; + y = vec->y; + if ( y < bbox->yMin ) bbox->yMin = y; + if ( y > bbox->yMax ) bbox->yMax = y; + vec++; + } + } + return TT_Err_Ok; + } + else + return TT_Err_Invalid_Argument; + } + + + + /* ----------------- character mappings support ------------- */ + +/******************************************************************* + * + * Function : TT_Get_CharMap_Count + * + * Description : Returns the number of charmaps in a given face. + * + * Input : face face object handle + * + * Output : Number of tables. -1 in case of error (bad handle). + * + * Note : DON'T USE THIS FUNCTION! IT HAS BEEN DEPRECATED! + * + * It is retained for backwards compatibility only and will + * fail on 16bit systems. + * + * MT-Safe : YES ! + * + ******************************************************************/ + + EXPORT_FUNC + int TT_Get_CharMap_Count( TT_Face face ) + { + PFace faze = HANDLE_Face( face ); + + return ( faze ? faze->numCMaps : -1 ); + } + + +/******************************************************************* + * + * Function : TT_Get_CharMap_ID + * + * Description : Returns the ID of a given charmap. + * + * Input : face face object handle + * charmapIndex index of charmap in directory + * platformID address of returned platform ID + * encodingID address of returned encoding ID + * + * Output : error code + * + * MT-Safe : YES ! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_CharMap_ID( TT_Face face, + TT_UShort charmapIndex, + TT_UShort* platformID, + TT_UShort* encodingID ) + { + PCMapTable cmap; + PFace faze = HANDLE_Face( face ); + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + if ( charmapIndex >= faze->numCMaps ) + return TT_Err_Invalid_Argument; + + cmap = faze->cMaps + charmapIndex; + + *platformID = cmap->platformID; + *encodingID = cmap->platformEncodingID; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Get_CharMap + * + * Description : Looks up a charmap. + * + * Input : face face object handle + * charmapIndex index of charmap in directory + * charMap address of returned charmap handle + * + * Output : Error code. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_CharMap( TT_Face face, + TT_UShort charmapIndex, + TT_CharMap* charMap ) + { + TT_Error error; + TT_Stream stream; + PCMapTable cmap; + PFace faze = HANDLE_Face( face ); + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + if ( charmapIndex >= faze->numCMaps ) + return TT_Err_Invalid_Argument; + + cmap = faze->cMaps + charmapIndex; + + /* Load table if needed */ + error = TT_Err_Ok; + + /* MT-NOTE: We're modifying the face object, so protect it. */ + MUTEX_Lock( faze->lock ); + + if ( !cmap->loaded ) + { + (void)USE_Stream( faze->stream, stream ); + if ( !error ) + { + error = CharMap_Load( cmap, stream ); + DONE_Stream( stream ); + } + + if ( error ) + cmap = NULL; + else + cmap->loaded = TRUE; + } + MUTEX_Release( faze->lock ); + + HANDLE_Set( *charMap, cmap ); + + return error; + } + + +/******************************************************************* + * + * Function : TT_Char_Index + * + * Description : Returns the glyph index corresponding to + * a given character code defined for the 'charmap'. + * + * Input : charMap charmap handle + * charcode character code + * + * Output : glyph index. + * + * Notes : Character code 0 is the unknown glyph, which should never + * be displayed. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_UShort TT_Char_Index( TT_CharMap charMap, + TT_UShort charCode ) + { + PCMapTable cmap = HANDLE_CharMap( charMap ); + + + if ( !cmap ) + return 0; /* we return 0 in case of invalid char map */ + + return CharMap_Index( cmap, charCode ); + } + + +/******************************************************************* + * + * Function : TT_Get_Name_Count + * + * Description : Returns the number of strings found in the + * name table. + * + * Input : face face handle + * + * Output : number of strings. + * + * Notes : Returns -1 on error (invalid handle). + * + * DON'T USE THIS FUNCTION! IT HAS BEEN DEPRECATED! + * + * It is retained for backwards compatibility only and will + * fail on 16bit systems. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + int TT_Get_Name_Count( TT_Face face ) + { + PFace faze = HANDLE_Face( face ); + + + if ( !faze ) + return -1; + + return faze->nameTable.numNameRecords; + } + + +/******************************************************************* + * + * Function : TT_Get_Name_ID + * + * Description : Returns the IDs of the string number 'nameIndex' + * in the name table of a given face. + * + * Input : face face handle + * nameIndex index of string. First is 0 + * platformID addresses of returned IDs + * encodingID + * languageID + * nameID + * + * Output : Error code. + * + * Notes : Some files have a corrupt or unusual name table, with some + * entries having a platformID > 3. These can usually + * be ignored by a client application. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Name_ID( TT_Face face, + TT_UShort nameIndex, + TT_UShort* platformID, + TT_UShort* encodingID, + TT_UShort* languageID, + TT_UShort* nameID ) + { + TNameRec* namerec; + PFace faze = HANDLE_Face( face ); + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + if ( nameIndex >= faze->nameTable.numNameRecords ) + return TT_Err_Invalid_Argument; + + namerec = faze->nameTable.names + nameIndex; + + *platformID = namerec->platformID; + *encodingID = namerec->encodingID; + *languageID = namerec->languageID; + *nameID = namerec->nameID; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Get_Name_String + * + * Description : Returns the address and length of a given + * string found in the name table. + * + * Input : face face handle + * nameIndex string index + * stringPtr address of returned pointer to string + * length address of returned string length + * + * Output : Error code. + * + * Notes : If the string's platformID is invalid, + * stringPtr is NULL, and length is 0. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Name_String( TT_Face face, + TT_UShort nameIndex, + TT_String** stringPtr, + TT_UShort* length ) + { + TNameRec* namerec; + PFace faze = HANDLE_Face( face ); + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + if ( nameIndex >= faze->nameTable.numNameRecords ) + return TT_Err_Invalid_Argument; + + namerec = faze->nameTable.names + nameIndex; + + *stringPtr = (String*)namerec->string; + *length = namerec->stringLength; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Get_Font_Data + * + * Description : Loads any font table into client memory. + * + * Input : face Face object to look for. + * + * tag Tag of table to load. Use the value 0 if you + * want to access the whole font file, else set + * this parameter to a valid TrueType table tag + * that you can forge with the MAKE_TT_TAG + * macro. + * + * offset Starting offset in the table (or the file + * if tag == 0). + * + * buffer Address of target buffer + * + * length Address of decision variable: + * + * if length == NULL: + * Load the whole table. Returns an + * error if 'offset' != 0. + * + * if *length == 0 : + * Exit immediately, returning the + * length of the given table, or of + * the font file, depending on the + * value of 'tag'. + * + * if *length != 0 : + * Load the next 'length' bytes of + * table or font, starting at offset + * 'offset' (in table or font too). + * + * Output : Error code. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Font_Data( TT_Face face, + TT_ULong tag, + TT_Long offset, + void* buffer, + TT_Long* length ) + { + PFace faze = HANDLE_Face( face ); + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + return Load_TrueType_Any( faze, tag, offset, buffer, length ); + } + + + /************************ callback definition ******************/ + + /* Register a new callback to the TrueType engine -- this should */ + /* only be used by higher-level libraries, not typical clients */ + /* */ + /* This is not part of the current FreeType release, thus */ + /* undefined... */ + +#if 0 + EXPORT_FUNC + TT_Error TT_Register_Callback( TT_Engine engine, + int callback_id, + void* callback_ptr ) + { + PEngine_Instance eng = HANDLE_Engine( engine ); + + + if ( !eng ) + return TT_Err_Invalid_Argument; + + /* currently, we only support one callback */ + if (callback_id != TT_Callback_Glyph_Outline_Load) + return TT_Err_Invalid_Argument; + + eng->glCallback = (TT_Glyph_Loader_Callback)callback_ptr; + return TT_Err_Ok; + } +#endif /* 0 */ + + +/* END */ diff --git a/lib/ttcache.c b/lib/ttcache.c new file mode 100644 index 0000000..5162419 --- /dev/null +++ b/lib/ttcache.c @@ -0,0 +1,463 @@ +/******************************************************************* + * + * ttcache.c 1.1 + * + * Generic object cache + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * Changes between 1.1 and 1.0: + * + * - introduced the refresher and finalizer in the cache class + * definition/implementation. + * + ******************************************************************/ + +#include "ttengine.h" +#include "ttmemory.h" +#include "ttcache.h" +#include "ttobjs.h" +#include "ttdebug.h" + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_cache + +#define ZERO_List( list ) list = NULL + +/* The macro FREE_Elements aliases the current engine instance's */ +/* free list_elements recycle list. */ +#define FREE_Elements ( engine->list_free_elements ) + +/* Redefinition of LOCK and UNLOCK macros for New_Element and Done_Element */ +/* Note: The macros are redefined below for the cache functions */ + +#undef LOCK +#define LOCK() MUTEX_Lock ( engine->lock ) + +#undef UNLOCK +#define UNLOCK() MUTEX_Release( engine->lock ) + +/******************************************************************* + * + * Function : Element_New + * + * Description : Gets a new (either fresh or recycled) list + * element. The element is unlisted. + * + * Input : None + * + * Output : List element address. NULL if out of memory. + * + ******************************************************************/ + + static + PList_Element Element_New( PEngine_Instance engine ) + { + PList_Element element; + + + LOCK(); + if ( FREE_Elements ) + { + element = (PList_Element)FREE_Elements; + FREE_Elements = element->next; + } + else + { + if ( !MEM_Alloc( element, sizeof ( TList_Element ) ) ) + { + element->next = NULL; + element->data = NULL; + } + } + + /* Note: in case of failure, Alloc sets the pointer to NULL */ + UNLOCK(); + + return element; + } + + +/******************************************************************* + * + * Function : Element_Done + * + * Description : Recycles an unlinked list element. + * + * Input : The list element to recycle. It _must_ be unlisted. + * + * Output : none. + * + * Note : This function doesn't check the element. + * + ******************************************************************/ + + static + void Element_Done( PEngine_Instance engine, + PList_Element element ) + { + LOCK(); + /* Simply add the list element to the recycle list */ + element->next = (PList_Element)FREE_Elements; + FREE_Elements = element; + UNLOCK(); + } + + +/* Redefinition of LOCK and UNLOCK macros for the cache functions */ +/* Note: The macros are defined above for the list element functions */ + +#undef LOCK +#define LOCK() MUTEX_Lock( *cache->lock ) + +#undef UNLOCK +#define UNLOCK() MUTEX_Release( *cache->lock ) + + +/******************************************************************* + * + * Function : Cache_Create + * + * Description : Creates a new cache that will be used to list + * and recycle several objects of the same class. + * + * Input : clazz a pointer to the cache's class. This is + * a simple structure that describes the + * the cache's object types and recycling + * limits. + * + * cache address of cache to create + * + * lock address of the mutex to use for this + * cache. The mutex will be used to protect + * the cache's lists. Use NULL for unprotected + * cache. + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Cache_Create( PEngine_Instance engine, + PCache_Class clazz, + TCache* cache, + TMutex* lock ) + { + cache->engine = engine; + cache->clazz = clazz; + cache->lock = lock; + cache->idle_count = 0; + + ZERO_List( cache->active ); + ZERO_List( cache->idle ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Cache_Destroy + * + * Description : Destroys a cache and all its idle and active + * objects. This will call each object's destructor + * before freeing it. + * + * Input : cache address of cache to destroy + * + * Output : error code. + * + * Note: This function is not MT-Safe, as we assume that a client + * isn't stupid enough to use an object while destroying it. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Cache_Destroy( TCache* cache ) + { + PDestructor destroy; + PList_Element current; + PList_Element next; + + + /* now destroy all active and idle listed objects */ + + /* get the destructor function */ + destroy = cache->clazz->done; + + /* destroy all elements in active list */ + current = cache->active; + while ( current ) + { + next = current->next; + destroy( current->data ); + FREE( current->data ); + + Element_Done( cache->engine, current ); + current = next; + } + ZERO_List(cache->active); + + /* destroy all elements in idle list */ + current = cache->idle; + while ( current ) + { + next = current->next; + destroy( current->data ); + FREE( current->data ); + + Element_Done( cache->engine, current ); + current = next; + } + ZERO_List(cache->idle); + + cache->clazz = NULL; + cache->idle_count = 0; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Cache_New + * + * Description : Extracts a new object from a cache. This will + * try to recycle an idle object, if any is found. + * Otherwise, a new object will be allocated and + * built (by calling its constructor). + * + * Input : cache address of cache to use + * new_object address of target pointer to the 'new' + * object + * parent_object this pointer is passed to a new object + * constructor (unused if object is + * recycled) + * + * Output : Error code. + * + * Notes: This function is thread-safe, each cache list is protected + * through the cache's mutex, if there is one... + * + * *new_object will be set to NULL in case of failure. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Cache_New( TCache* cache, + void** new_object, + void* parent_object ) + { + TT_Error error; + PList_Element current; + PConstructor build; + PRefresher reset; + void* object; + + + LOCK(); + current = cache->idle; + if ( current ) + { + cache->idle = current->next; + cache->idle_count--; + } + UNLOCK(); + + if ( current ) + { + object = current->data; + reset = cache->clazz->reset; + if ( reset ) + { + error = reset( object, parent_object ); + if ( error ) + { + LOCK(); + current->next = cache->idle; + cache->idle = current; + cache->idle_count++; + UNLOCK(); + goto Exit; + } + } + } + else + { + /* if no object was found in the cache, create a new one */ + build = cache->clazz->init; + + if ( MEM_Alloc( object, cache->clazz->object_size ) ) + goto Memory_Fail; + + current = Element_New( cache->engine ); + if ( !current ) + goto Memory_Fail; + + current->data = object; + + error = build( object, parent_object ); + if ( error ) + { + Element_Done( cache->engine, current ); + goto Fail; + } + } + + LOCK(); + current->next = cache->active; + cache->active = current; + UNLOCK(); + + *new_object = current->data; + return TT_Err_Ok; + + Exit: + *new_object = NULL; + return error; + + Memory_Fail: + error = TT_Err_Out_Of_Memory; + + Fail: + FREE( object ); + goto Exit; + } + + +/******************************************************************* + * + * Function : Cache_Done + * + * Description : Releases an object to the cache. This will either + * recycle or destroy the object, based on the cache's + * class and state. + * + * Input : cache the cache to use + * data the object to recycle/discard + * + * Output : error code. + * + * Notes : The object's destructor is called only when + * the objectwill be effectively destroyed by this + * function. This will not happen during recycling. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Cache_Done( TCache* cache, void* data ) + { + TT_Error error; + PList_Element element; + PList_Element prev; + PFinalizer finalize; + Long limit; + Bool destroy; + + + /* Look for object in active list */ + LOCK(); + + element = cache->active; + prev = NULL; + while ( element ) + { + if ( element->data == data ) + { + if ( prev ) + prev->next = element->next; + else + cache->active = element->next; + goto Suite; + } + prev = element; + element = element->next; + } + + UNLOCK(); + return TT_Err_Unlisted_Object; + + Suite: + + limit = cache->clazz->idle_limit; + destroy = (cache->idle_count >= limit); + UNLOCK(); + + if ( destroy ) + { + /* destroy the object when the cache is full */ + cache->clazz->done( element->data ); + FREE( element->data ); + Element_Done( cache->engine, element ); + } + else + { + /* Finalize the object before adding it to the */ + /* idle list. Return the error if any is found. */ + + finalize = cache->clazz->finalize; + if ( finalize ) + { + error = finalize( element->data ); + if ( error ) + goto Exit; + + /* Note: a failure at finalize time is a severe bug in */ + /* the engine, which is why we allow ourselves to */ + /* lose the object in this case. A finalizer should */ + /* have its own error codes to spot this kind of */ + /* problems easily. */ + } + + LOCK(); + element->next = cache->idle; + cache->idle = element; + cache->idle_count++; + UNLOCK(); + } + + error = TT_Err_Ok; + + Exit: + return error; + } + + + LOCAL_FUNC + TT_Error TTCache_Init( PEngine_Instance engine ) + { + /* Create list elements mutex */ + FREE_Elements = NULL; + return TT_Err_Ok; + } + + + LOCAL_FUNC + TT_Error TTCache_Done( PEngine_Instance engine ) + { + /* We don't protect this function, as this is the end of the engine's */ + /* execution.. */ + PList_Element element, next; + + + /* frees the recycled list elements */ + element = FREE_Elements; + while ( element ) + { + next = element->next; + FREE( element ); + element = next; + } + return TT_Err_Ok; + } + + +/* END */ diff --git a/lib/ttcache.h b/lib/ttcache.h new file mode 100644 index 0000000..e6f17c3 --- /dev/null +++ b/lib/ttcache.h @@ -0,0 +1,216 @@ +/******************************************************************* + * + * ttcache.h 1.1 + * + * Generic object cache + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * This component defines and implements object caches. + * + * An object class is a structure layout that encapsulate one + * given type of data used by the FreeType engine. Each object + * class is completely described by: + * + * - a 'root' or 'leading' structure containing the first + * important fields of the class. The root structure is + * always of fixed size. + * + * It is implemented as a simple C structure, and may + * contain several pointers to sub-tables that can be + * sized and allocated dynamically. + * + * Examples: TFace, TInstance, TGlyph & TExecution_Context + * (defined in 'ttobjs.h') + * + * - we make a difference between 'child' pointers and 'peer' + * pointers. A 'child' pointer points to a sub-table that is + * owned by the object, while a 'peer' pointer points to any + * other kind of data the object isn't responsible for. + * + * An object class is thus usually a 'tree' of 'child' tables. + * + * - each object class needs a constructor and a destructor. + * + * A constructor is a function which receives the address of + * freshly allocated and zeroed object root structure and + * 'builds' all the valid child data that must be associated + * to the object before it becomes 'valid'. + * + * A destructor does the inverse job: given the address of + * a valid object, it must discard all its child data and + * zero its main fields (essentially the pointers and array + * sizes found in the root fields). + * + * + * Important notes: + * + * When the constructor fails to allocate an object, it must + * return immediately with an error code, and not try to release + * what it has previously allocated before the error. The cache + * manager detects the error and calls the destructor on the + * partial object, before returning the error to the caller (along + * with a NULL pointer for the "new" object). + * + * The destructor must thus be able to deal with "partial objects", + * i.e., objects where only part of the child tables are allocated, + * and only release these ones. As the TT_Free() function accepts + * a NULL parameter (and returns successfuly in this case), no check + * is really necessary when using the macro 'FREE()'. + * + * Currently, there is no check in the cache manager to see if a + * destructor fails (double error state!). + * + * This scheme is more compact and more maintanable than the one + * where de-allocation code is duplicated in the constructor + * _and_ the destructor. + * + * + * + * Changes between 1.1 and 1.0: + * + * - introduced the refreshed and finalizer class definition/implementation + * - inserted an engine instance pointer in the cache structure + * + ******************************************************************/ + +#ifndef TTCACHE_H +#define TTCACHE_H + +#include "tttypes.h" +#include "ttconfig.h" +#include "ttmutex.h" + +#ifdef __cplusplus + extern "C" { +#endif + + typedef TT_Error TConstructor( void* object, + void* parent ); + + typedef TT_Error TDestructor ( void* object ); + + typedef TConstructor TRefresher; + typedef TDestructor TFinalizer; + + typedef TConstructor* PConstructor; + typedef TDestructor* PDestructor; + typedef TRefresher* PRefresher; + typedef TFinalizer* PFinalizer; + + + /* A Cache class record holds the data necessary to define */ + /* a cache kind. */ + struct TCache_Class_ + { + ULong object_size; + Long idle_limit; + PConstructor init; + PDestructor done; + PRefresher reset; + PFinalizer finalize; + }; + + typedef struct TCache_Class_ TCache_Class; + typedef TCache_Class* PCache_Class; + + + + /* Simple list node record. A list element is said to be 'unlinked' */ + /* when it doesn't belong to any list. */ + struct TList_Element_; + + typedef struct TList_Element_ TList_Element; + typedef TList_Element* PList_Element; + + struct TList_Element_ + { + PList_Element next; + void* data; + }; + + + /* Simple singly-linked list record - LIFO style, no tail field */ + typedef PList_Element TSingle_List; + + struct TCache_ + { + PEngine_Instance engine; + PCache_Class clazz; /* 'class' is a reserved word in C++ */ + TMutex* lock; + TSingle_List active; + TSingle_List idle; + Long idle_count; + }; + + typedef struct TCache_ TCache; + typedef TCache* PCache; + + /* Returns a new list element, either fresh or recycled. */ + /* Note: the returned element is unlinked. */ + + /* An object cache holds two lists tracking the active and */ + /* idle objects that are currently created and used by the */ + /* engine. It can also be 'protected' by a mutex. */ + + /* Initializes a new cache, of class 'clazz', pointed by 'cache', */ + /* protected by the 'lock' mutex. Set 'lock' to NULL if the cache */ + /* doesn't need protection */ + + LOCAL_DEF + TT_Error Cache_Create( PEngine_Instance engine, + PCache_Class clazz, + TCache* cache, + TMutex* lock ); + + /* Destroys a cache and all its listed objects */ + + LOCAL_DEF + TT_Error Cache_Destroy( TCache* cache ); + + + /* Extracts a new object from the cache */ + + LOCAL_DEF + TT_Error Cache_New( TCache* cache, + void** new_object, + void* parent_object ); + + + /* Returns an object to the cache, or discards it depending */ + /* on the cache class' 'idle_limit' field */ + + LOCAL_DEF + TT_Error Cache_Done( TCache* cache, void* data ); + +#define CACHE_New( _cache, _newobj, _parent ) \ + Cache_New( (TCache*)_cache, (void**)&_newobj, (void*)_parent ) + +#define CACHE_Done( _cache, _obj ) \ + Cache_Done( (TCache*)_cache, (void*)_obj ) + + + + LOCAL_DEF + TT_Error TTCache_Init( PEngine_Instance engine ); + + LOCAL_DEF + TT_Error TTCache_Done( PEngine_Instance engine ); + + +#ifdef __cplusplus + } +#endif + +#endif /* TTCACHE_H */ + + +/* END */ diff --git a/lib/ttcalc.c b/lib/ttcalc.c new file mode 100644 index 0000000..0733624 --- /dev/null +++ b/lib/ttcalc.c @@ -0,0 +1,403 @@ +/******************************************************************* + * + * ttcalc.c + * + * Arithmetic Computations (body). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include "ttcalc.h" +#include "ttdebug.h" +#include "tttables.h" + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_calc + + +/* Support for 1-complement arithmetic has been totally dropped in this */ +/* release. You can still write your own code if you need it... */ + + static const Long Roots[63] = + { + 1, 1, 2, 3, 4, 5, 8, 11, + 16, 22, 32, 45, 64, 90, 128, 181, + 256, 362, 512, 724, 1024, 1448, 2048, 2896, + 4096, 5892, 8192, 11585, 16384, 23170, 32768, 46340, + + 65536, 92681, 131072, 185363, 262144, 370727, + 524288, 741455, 1048576, 1482910, 2097152, 2965820, + 4194304, 5931641, 8388608, 11863283, 16777216, 23726566, + + 33554432, 47453132, 67108864, 94906265, + 134217728, 189812531, 268435456, 379625062, + 536870912, 759250125, 1073741824, 1518500250, + 2147483647 + }; + + +#ifdef LONG64 + + EXPORT_FUNC + TT_Long TT_MulDiv( TT_Long a, TT_Long b, TT_Long c ) + { + Long s; + + + s = a; a = ABS( a ); + s ^= b; b = ABS( b ); + s ^= c; c = ABS( c ); + + a = ((TT_Int64)a * b + c/2) / c; + return ( s < 0 ) ? -a : a; + } + + + EXPORT_FUNC + TT_Long TT_MulFix( TT_Long a, TT_Long b ) + { + Long s; + + + s = a; a = ABS( a ); + s ^= b; b = ABS( b ); + + a = ((TT_Int64)a * b + 0x8000) / 0x10000; + return ( s < 0 ) ? -a : a; + } + + + LOCAL_FUNC + Int Order64( TT_Int64 z ) + { + Int j = 0; + + + while ( z ) + { + z = (unsigned INT64)z >> 1; + j++; + } + return j - 1; + } + + + LOCAL_FUNC + TT_Int32 Sqrt64( TT_Int64 l ) + { + TT_Int64 r, s; + + + if ( l <= 0 ) return 0; + if ( l == 1 ) return 1; + + r = Roots[Order64( l )]; + + do + { + s = r; + r = ( r + l/r ) >> 1; + } + while ( r > s || r*r > l ); + + return r; + } + +#else /* LONG64 */ + + + /* The TT_MulDiv function has been optimized thanks to ideas from */ + /* Graham Asher. The trick is to optimize computation when everything */ + /* fits within 32-bits (a rather common case). */ + /* */ + /* we compute 'a*b+c/2', then divide it by 'c'. (positive values) */ + /* */ + /* 46340 is FLOOR(SQRT(2^31-1)). */ + /* */ + /* if ( a <= 46340 && b <= 46340 ) then ( a*b <= 0x7FFEA810 ) */ + /* */ + /* 0x7FFFFFFF - 0x7FFEA810 = 0x157F0 */ + /* */ + /* if ( c < 0x157F0*2 ) then ( a*b+c/2 <= 0x7FFFFFFF ) */ + /* */ + /* and 2*0x157F0 = 176096 */ + /* */ + + EXPORT_FUNC + TT_Long TT_MulDiv( TT_Long a, TT_Long b, TT_Long c ) + { + long s; + + + if ( a == 0 || b == c ) + return a; + + s = a; a = ABS( a ); + s ^= b; b = ABS( b ); + s ^= c; c = ABS( c ); + + if ( a <= 46340 && b <= 46340 && c <= 176095 ) + { + a = ( a*b + c/2 )/c; + } + else + { + TT_Int64 temp, temp2; + + MulTo64( a, b, &temp ); + temp2.hi = (TT_Int32)(c >> 31); + temp2.lo = (TT_Word32)(c / 2); + Add64( &temp, &temp2, &temp ); + a = Div64by32( &temp, c ); + } + + return ( s < 0 ) ? -a : a; + } + + /* The optimization for TT_MulFix is different. We could simply be */ + /* happy by applying the same principles than with TT_MulDiv, because */ + /* */ + /* c = 0x10000 < 176096 */ + /* */ + /* however, in most cases, we have a 'b' with a value around 0x10000 */ + /* which is greater than 46340. */ + /* */ + /* According to Graham's testing, most cases have 'a' < 100, so a good */ + /* idea is to use bounds like 1024 and 2097151 (= floor(2^31-1)/1024 ) */ + /* for 'a' and 'b' respectively.. */ + /* */ + + EXPORT_FUNC + TT_Long TT_MulFix( TT_Long a, TT_Long b ) + { + long s; + + if ( a == 0 || b == 0x10000 ) + return a; + + s = a; a = ABS( a ); + s ^= b; b = ABS( b ); + + if ( a <= 1024 && b <= 2097151 ) + { + a = ( a*b + 0x8000 ) >> 16; + } + else + { + TT_Int64 temp, temp2; + + MulTo64( a, b, &temp ); + temp2.hi = 0; + temp2.lo = 0x8000; + Add64( &temp, &temp2, &temp ); + a = Div64by32( &temp, 0x10000 ); + } + + return ( s < 0 ) ? -a : a; + } + + + LOCAL_FUNC + void Neg64( TT_Int64* x ) + { + /* Remember that -(0x80000000) == 0x80000000 with 2-complement! */ + /* We take care of that here. */ + + x->hi ^= 0xFFFFFFFFUL; + x->lo ^= 0xFFFFFFFFUL; + x->lo++; + + if ( !x->lo ) + { + x->hi++; + if ( x->hi == 0x80000000UL ) /* Check -MaxInt32 - 1 */ + { + x->lo--; + x->hi--; /* We return 0x7FFFFFFF! */ + } + } + } + + + LOCAL_FUNC + void Add64( TT_Int64* x, TT_Int64* y, TT_Int64* z ) + { + register TT_Word32 lo, hi; + + + lo = x->lo + y->lo; + hi = x->hi + y->hi + ( lo < x->lo ); + + z->lo = lo; + z->hi = hi; + } + + + LOCAL_FUNC + void Sub64( TT_Int64* x, TT_Int64* y, TT_Int64* z ) + { + register TT_Word32 lo, hi; + + + lo = x->lo - y->lo; + hi = x->hi - y->hi - ( (TT_Int32)lo < 0 ); + + z->lo = lo; + z->hi = hi; + } + + + LOCAL_FUNC + void MulTo64( TT_Int32 x, TT_Int32 y, TT_Int64* z ) + { + TT_Int32 s; + TT_Word32 lo1, hi1, lo2, hi2, lo, hi, i1, i2; + + + s = x; x = ABS( x ); + s ^= y; y = ABS( y ); + + lo1 = x & 0x0000FFFF; hi1 = x >> 16; + lo2 = y & 0x0000FFFF; hi2 = y >> 16; + + lo = lo1*lo2; + i1 = lo1*hi2; + i2 = lo2*hi1; + hi = hi1*hi2; + + /* Check carry overflow of i1 + i2 */ + + if ( i2 ) + { + if ( i1 >= (TT_Word32)-(TT_Int32)i2 ) hi += 1L << 16; + i1 += i2; + } + + i2 = i1 >> 16; + i1 = i1 << 16; + + /* Check carry overflow of i1 + lo */ + if ( i1 ) + { + if ( lo >= (TT_Word32)-(TT_Int32)i1 ) hi++; + lo += i1; + } + + hi += i2; + + z->lo = lo; + z->hi = hi; + + if ( s < 0 ) Neg64( z ); + } + + + LOCAL_FUNC + TT_Int32 Div64by32( TT_Int64* x, TT_Int32 y ) + { + TT_Int32 s; + TT_Word32 q, r, i, lo; + + + s = x->hi; if ( s < 0 ) Neg64( x ); + s ^= y; y = ABS( y ); + + /* Shortcut */ + if ( x->hi == 0 ) + { + q = x->lo / y; + return ( s < 0 ) ? -(TT_Int32)q : (TT_Int32)q; + } + + r = x->hi; + lo = x->lo; + + if ( r >= (TT_Word32)y ) /* we know y is to be treated as unsigned here */ + return ( s < 0 ) ? 0x80000001UL : 0x7FFFFFFFUL; + /* Return Max/Min Int32 if divide overflow */ + /* This includes division by zero! */ + q = 0; + for ( i = 0; i < 32; i++ ) + { + r <<= 1; + q <<= 1; + r |= lo >> 31; + + if ( r >= (TT_Word32)y ) + { + r -= y; + q |= 1; + } + lo <<= 1; + } + + return ( s < 0 ) ? -(TT_Int32)q : (TT_Int32)q; + } + + + LOCAL_FUNC + Int Order64( TT_Int64* z ) + { + TT_Word32 i; + Int j; + + + if ( z->hi ) + { + i = z->hi; + j = 32; + } + else + { + i = z->lo; + j = 0; + } + + while ( i > 0 ) + { + i >>= 1; + j++; + } + return j-1; + } + + + LOCAL_FUNC + TT_Int32 Sqrt64( TT_Int64* l ) + { + TT_Int64 l2; + TT_Int32 r, s; + + + if ( (TT_Int32)l->hi < 0 || + (l->hi == 0 && l->lo == 0) ) return 0; + + s = Order64( l ); + if ( s == 0 ) return 1; + + r = Roots[s]; + do + { + s = r; + r = ( r + Div64by32(l,r) ) >> 1; + MulTo64( r, r, &l2 ); + Sub64 ( l, &l2, &l2 ); + } + while ( r > s || (TT_Int32)l2.hi < 0 ); + + return r; + } + +#endif /* LONG64 */ + + +/* END */ diff --git a/lib/ttcalc.h b/lib/ttcalc.h new file mode 100644 index 0000000..9b4c306 --- /dev/null +++ b/lib/ttcalc.h @@ -0,0 +1,97 @@ +/******************************************************************* + * + * ttcalc.h + * + * Arithmetic Computations (specification). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef TTCALC_H +#define TTCALC_H + +#include "ttconfig.h" +#include "freetype.h" + + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef LONG64 + + typedef INT64 TT_Int64; + +#define ADD_64( x, y, z ) z = x + y +#define SUB_64( x, y, z ) z = x - y +#define MUL_64( x, y, z ) z = (TT_Int64)(x) * (y) + +#define DIV_64( x, y ) ( (x) / (y) ) + +#define SQRT_64( x ) Sqrt64( x ) +#define SQRT_32( x ) Sqrt32( x ) + + LOCAL_DEF TT_Int32 Sqrt64( TT_Int64 l ); + +#else /* LONG64 */ + + struct TT_Int64_ + { + TT_Word32 lo; + TT_Word32 hi; + }; + + typedef struct TT_Int64_ TT_Int64; + +#define ADD_64( x, y, z ) Add64( &x, &y, &z ) +#define SUB_64( x, y, z ) Sub64( &x, &y, &z ) +#define MUL_64( x, y, z ) MulTo64( x, y, &z ) + +#define DIV_64( x, y ) Div64by32( &x, y ) + +#define SQRT_64( x ) Sqrt64( &x ) +#define SQRT_32( x ) Sqrt32( x ) + + LOCAL_DEF void Add64( TT_Int64* x, TT_Int64* y, TT_Int64* z ); + LOCAL_DEF void Sub64( TT_Int64* x, TT_Int64* y, TT_Int64* z ); + + LOCAL_DEF void MulTo64( TT_Int32 x, TT_Int32 y, TT_Int64* z ); + + LOCAL_DEF TT_Int32 Div64by32( TT_Int64* x, TT_Int32 y ); + + LOCAL_DEF int Order64( TT_Int64* z ); + + LOCAL_DEF TT_Int32 Sqrt64( TT_Int64* l ); + +#endif /* LONG64 */ + + /* The two following functions are now part of the API! */ + + /* TT_Long TT_MulDiv( TT_Long a, TT_Long b, TT_Long c ); */ + /* TT_Long TT_MulFix( TT_Long a, TT_Long b ); */ + + +#define INT_TO_F26DOT6( x ) ( (Long)(x) << 6 ) +#define INT_TO_F2DOT14( x ) ( (Long)(x) << 14 ) +#define INT_TO_FIXED( x ) ( (Long)(x) << 16 ) +#define F2DOT14_TO_FIXED( x ) ( (Long)(x) << 2 ) +#define FLOAT_TO_FIXED( x ) ( (Long)(x * 65536.0) ) + +#define ROUND_F26DOT6( x ) ( x >= 0 ? ( ((x) + 32) & -64) \ + : ( -((32 - (x)) & -64) ) ) + +#ifdef __cplusplus + } +#endif + +#endif /* TTCALC_H */ + +/* END */ diff --git a/lib/ttcmap.c b/lib/ttcmap.c new file mode 100644 index 0000000..6b8596f --- /dev/null +++ b/lib/ttcmap.c @@ -0,0 +1,503 @@ +/******************************************************************* + * + * ttcmap.c 1.0 + * + * TrueType Character Mappings + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include "ttobjs.h" +#include "ttdebug.h" +#include "ttfile.h" +#include "ttmemory.h" +#include "ttload.h" +#include "ttcmap.h" + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_cmap + + +/******************************************************************* + * + * Function : CharMap_Load + * + * Description : Loads a given charmap into memory. + * + * Input : cmap pointer to cmap table + * + * Output : Error code. + * + * Notes : - Assumes the the stream is already used (opened). + * + * - In case of error, releases all partially allocated + * tables. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error CharMap_Load( PCMapTable cmap, + TT_Stream input ) + { + DEFINE_LOAD_LOCALS( input ); + + UShort num_SH, num_Seg, i; + + UShort u, l; + + PCMap0 cmap0; + PCMap2 cmap2; + PCMap4 cmap4; + PCMap6 cmap6; + + PCMap2SubHeader cmap2sub; + PCMap4Segment segments; + + + if ( cmap->loaded ) + return TT_Err_Ok; + + if ( FILE_Seek( cmap->offset ) ) + return error; + + switch ( cmap->format ) + { + case 0: + cmap0 = &cmap->c.cmap0; + + if ( ALLOC( cmap0->glyphIdArray, 256L ) || + FILE_Read( (void*)cmap0->glyphIdArray, 256L ) ) + goto Fail; + + break; + + case 2: + num_SH = 0; + cmap2 = &cmap->c.cmap2; + + /* allocate subheader keys */ + + if ( ALLOC_ARRAY( cmap2->subHeaderKeys, 256, UShort ) || + ACCESS_Frame( 512L ) ) + goto Fail; + + for ( i = 0; i < 256; i++ ) + { + u = GET_UShort() / 8; + cmap2->subHeaderKeys[i] = u; + + if ( num_SH < u ) + num_SH = u; + } + + FORGET_Frame(); + + /* load subheaders */ + + cmap2->numGlyphId = l = + ( ( cmap->length - 2L * (256 + 3) - num_SH * 8L ) & 0xffff) / 2; + + if ( ALLOC_ARRAY( cmap2->subHeaders, + num_SH + 1, + TCMap2SubHeader ) || + ACCESS_Frame( ( num_SH + 1 ) * 8L ) ) + goto Fail; + + cmap2sub = cmap2->subHeaders; + + for ( i = 0; i <= num_SH; i++ ) + { + cmap2sub->firstCode = GET_UShort(); + cmap2sub->entryCount = GET_UShort(); + cmap2sub->idDelta = GET_Short(); + /* we apply the location offset immediately */ + cmap2sub->idRangeOffset = GET_UShort() - ( num_SH - i ) * 8 - 2; + + cmap2sub++; + } + + FORGET_Frame(); + + /* load glyph ids */ + + if ( ALLOC_ARRAY( cmap2->glyphIdArray, l, UShort ) || + ACCESS_Frame( l * 2L ) ) + goto Fail; + + for ( i = 0; i < l; i++ ) + cmap2->glyphIdArray[i] = GET_UShort(); + + FORGET_Frame(); + break; + + case 4: + cmap4 = &cmap->c.cmap4; + + /* load header */ + + if ( ACCESS_Frame( 8L ) ) + goto Fail; + + cmap4->segCountX2 = GET_UShort(); + cmap4->searchRange = GET_UShort(); + cmap4->entrySelector = GET_UShort(); + cmap4->rangeShift = GET_UShort(); + + num_Seg = cmap4->segCountX2 / 2; + + FORGET_Frame(); + + /* load segments */ + + if ( ALLOC_ARRAY( cmap4->segments, + num_Seg, + TCMap4Segment ) || + ACCESS_Frame( (num_Seg * 4 + 1) * 2L ) ) + goto Fail; + + segments = cmap4->segments; + + for ( i = 0; i < num_Seg; i++ ) + segments[i].endCount = GET_UShort(); + + (void)GET_UShort(); + + for ( i = 0; i < num_Seg; i++ ) + segments[i].startCount = GET_UShort(); + + for ( i = 0; i < num_Seg; i++ ) + segments[i].idDelta = GET_Short(); + + for ( i = 0; i < num_Seg; i++ ) + segments[i].idRangeOffset = GET_UShort(); + + FORGET_Frame(); + + cmap4->numGlyphId = l = + ( ( cmap->length - ( 16L + 8L * num_Seg ) ) & 0xffff ) / 2; + + /* load ids */ + + if ( ALLOC_ARRAY( cmap4->glyphIdArray, l , UShort ) || + ACCESS_Frame( l * 2L ) ) + goto Fail; + + for ( i = 0; i < l; i++ ) + cmap4->glyphIdArray[i] = GET_UShort(); + + FORGET_Frame(); + break; + + case 6: + cmap6 = &cmap->c.cmap6; + + if ( ACCESS_Frame( 4L ) ) + goto Fail; + + cmap6->firstCode = GET_UShort(); + cmap6->entryCount = GET_UShort(); + + FORGET_Frame(); + + l = cmap6->entryCount; + + if ( ALLOC_ARRAY( cmap6->glyphIdArray, + cmap6->entryCount, + Short ) || + ACCESS_Frame( l * 2L ) ) + goto Fail; + + for ( i = 0; i < l; i++ ) + cmap6->glyphIdArray[i] = GET_UShort(); + + FORGET_Frame(); + break; + + default: /* corrupt character mapping table */ + return TT_Err_Invalid_CharMap_Format; + + } + return TT_Err_Ok; + + Fail: + CharMap_Free( cmap ); + return error; + } + + +/******************************************************************* + * + * Function : CharMap_Free + * + * Description : Releases a given charmap table. + * + * Input : cmap pointer to cmap table + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error CharMap_Free( PCMapTable cmap ) + { + if ( !cmap ) + return TT_Err_Ok; + + switch ( cmap->format ) + { + case 0: + FREE( cmap->c.cmap0.glyphIdArray ); + break; + + case 2: + FREE( cmap->c.cmap2.subHeaderKeys ); + FREE( cmap->c.cmap2.subHeaders ); + FREE( cmap->c.cmap2.glyphIdArray ); + break; + + case 4: + FREE( cmap->c.cmap4.segments ); + FREE( cmap->c.cmap4.glyphIdArray ); + cmap->c.cmap4.segCountX2 = 0; + break; + + case 6: + FREE( cmap->c.cmap6.glyphIdArray ); + cmap->c.cmap6.entryCount = 0; + break; + + default: + /* invalid table format, do nothing */ + ; + } + + cmap->loaded = FALSE; + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : CharMap_Index + * + * Description : Performs charcode->glyph index translation. + * + * Input : cmap pointer to cmap table + * + * Output : Glyph index, 0 in case of failure. + * + ******************************************************************/ + + static UShort code_to_index0( UShort charCode, PCMap0 cmap0 ); + static UShort code_to_index2( UShort charCode, PCMap2 cmap2 ); + static UShort code_to_index4( UShort charCode, PCMap4 cmap4 ); + static UShort code_to_index6( UShort charCode, PCMap6 cmap6 ); + + + LOCAL_FUNC + UShort CharMap_Index( PCMapTable cmap, + UShort charcode ) + { + switch ( cmap->format ) + { + case 0: + return code_to_index0( charcode, &cmap->c.cmap0 ); + case 2: + return code_to_index2( charcode, &cmap->c.cmap2 ); + case 4: + return code_to_index4( charcode, &cmap->c.cmap4 ); + case 6: + return code_to_index6( charcode, &cmap->c.cmap6 ); + default: + return 0; + } + } + + +/******************************************************************* + * + * Function : code_to_index0 + * + * Description : Converts the character code into a glyph index. + * Uses format 0. + * charCode will be masked to get a value in the range + * 0x00-0xFF. + * + * Input : charCode the wanted character code + * cmap0 a pointer to a cmap table in format 0 + * + * Output : Glyph index into the glyphs array. + * 0 if the glyph does not exist. + * + ******************************************************************/ + + static UShort code_to_index0( UShort charCode, + PCMap0 cmap0 ) + { + if ( charCode <= 0xFF ) + return cmap0->glyphIdArray[charCode]; + else + return 0; + } + + +/******************************************************************* + * + * Function : code_to_index2 + * + * Description : Converts the character code into a glyph index. + * Uses format 2. + * + * Input : charCode the wanted character code + * cmap2 a pointer to a cmap table in format 2 + * + * Output : Glyph index into the glyphs array. + * 0 if the glyph does not exist. + * + ******************************************************************/ + + static UShort code_to_index2( UShort charCode, + PCMap2 cmap2 ) + { + UShort index1, idx, offset; + TCMap2SubHeader sh2; + + + index1 = cmap2->subHeaderKeys[charCode <= 0xFF ? + charCode : (charCode >> 8)]; + + if ( index1 == 0 ) + { + if ( charCode <= 0xFF ) + return cmap2->glyphIdArray[charCode]; /* 8bit character code */ + else + return 0; + } + else /* 16bit character code */ + { + if ( charCode <= 0xFF ) + return 0; + + sh2 = cmap2->subHeaders[index1]; + + if ( (charCode & 0xFF) < sh2.firstCode ) + return 0; + + if ( (charCode & 0xFF) >= (sh2.firstCode + sh2.entryCount) ) + return 0; + + offset = sh2.idRangeOffset / 2 + (charCode & 0xFF) - sh2.firstCode; + if ( offset < cmap2->numGlyphId ) + idx = cmap2->glyphIdArray[offset]; + else + return 0; + + if ( idx ) + return (idx + sh2.idDelta) & 0xFFFF; + else + return 0; + } + } + + +/******************************************************************* + * + * Function : code_to_index4 + * + * Description : Converts the character code into a glyph index. + * Uses format 4. + * + * Input : charCode the wanted character code + * cmap4 a pointer to a cmap table in format 4 + * + * Output : Glyph index into the glyphs array. + * 0 if the glyph does not exist. + * + ******************************************************************/ + + static UShort code_to_index4( UShort charCode, + PCMap4 cmap4 ) + { + UShort index1, segCount; + UShort i; + TCMap4Segment seg4; + + + segCount = cmap4->segCountX2 / 2; + + for ( i = 0; i < segCount; i++ ) + if ( charCode <= cmap4->segments[i].endCount ) + break; + + /* Safety check - even though the last endCount should be 0xFFFF */ + if ( i >= segCount ) + return 0; + + seg4 = cmap4->segments[i]; + + if ( charCode < seg4.startCount ) + return 0; + + if ( seg4.idRangeOffset == 0 ) + return ( charCode + seg4.idDelta ) & 0xFFFF; + else + { + index1 = seg4.idRangeOffset / 2 + (charCode - seg4.startCount) - + (segCount - i); + + if ( index1 < cmap4->numGlyphId ) + { + if ( cmap4->glyphIdArray[index1] == 0 ) + return 0; + else + return ( cmap4->glyphIdArray[index1] + seg4.idDelta ) & 0xFFFF; + } + else + return 0; + } + } + + +/******************************************************************* + * + * Function : code_to_index6 + * + * Description : Converts the character code into a glyph index. + * Uses format 6. + * + * Input : charCode the wanted character code + * cmap6 a pointer to a cmap table in format 6 + * + * Output : Glyph index into the glyphs array. + * 0 if the glyph does not exist (`missing character glyph'). + * + ******************************************************************/ + + static UShort code_to_index6( UShort charCode, + PCMap6 cmap6 ) + { + UShort firstCode; + + + firstCode = cmap6->firstCode; + + if ( charCode < firstCode ) + return 0; + + if ( charCode >= (firstCode + cmap6->entryCount) ) + return 0; + + return cmap6->glyphIdArray[charCode - firstCode]; + } + + +/* END */ diff --git a/lib/ttcmap.h b/lib/ttcmap.h new file mode 100644 index 0000000..8a1f834 --- /dev/null +++ b/lib/ttcmap.h @@ -0,0 +1,169 @@ +/******************************************************************* + * + * ttcmap.h 1.0 + * + * TrueType Character Mappings + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + ******************************************************************/ + +#ifndef TTCMAP_H +#define TTCMAP_H + +#include "ttconfig.h" +#include "tttypes.h" + + +#ifdef __cplusplus + extern "C" { +#endif + + /* format 0 */ + + struct TCMap0_ + { + PByte glyphIdArray; + }; + + typedef struct TCMap0_ TCMap0; + typedef TCMap0* PCMap0; + + + /* format 2 */ + + struct TCMap2SubHeader_ + { + UShort firstCode; /* first valid low byte */ + UShort entryCount; /* number of valid low bytes */ + Short idDelta; /* delta value to glyphIndex */ + UShort idRangeOffset; /* offset from here to 1st code */ + }; + + typedef struct TCMap2SubHeader_ TCMap2SubHeader; + typedef TCMap2SubHeader* PCMap2SubHeader; + + struct TCMap2_ + { + PUShort subHeaderKeys; + /* high byte mapping table */ + /* value = subHeader index * 8 */ + + PCMap2SubHeader subHeaders; + PUShort glyphIdArray; + UShort numGlyphId; /* control value */ + }; + + typedef struct TCMap2_ TCMap2; + typedef TCMap2* PCMap2; + + + /* format 4 */ + + struct TCMap4Segment_ + { + UShort endCount; + UShort startCount; + Short idDelta; /* in the specs defined as UShort but the + example there gives negative values... */ + UShort idRangeOffset; + }; + + typedef struct TCMap4Segment_ TCMap4Segment; + typedef TCMap4Segment* PCMap4Segment; + + struct TCMap4_ + { + UShort segCountX2; /* number of segments * 2 */ + UShort searchRange; /* these parameters can be used */ + UShort entrySelector; /* for a binary search */ + UShort rangeShift; + + PCMap4Segment segments; + PUShort glyphIdArray; + UShort numGlyphId; /* control value */ + }; + + typedef struct TCMap4_ TCMap4; + typedef TCMap4* PCMap4; + + + /* format 6 */ + + struct TCMap6_ + { + UShort firstCode; /* first character code of subrange */ + UShort entryCount; /* number of character codes in subrange */ + + PUShort glyphIdArray; + }; + + typedef struct TCMap6_ TCMap6; + typedef TCMap6* PCMap6; + + + /* charmap table */ + + struct TCMapTable_ + { + UShort platformID; + UShort platformEncodingID; + UShort format; + UShort length; + UShort version; + + Bool loaded; + ULong offset; + + union + { + TCMap0 cmap0; + TCMap2 cmap2; + TCMap4 cmap4; + TCMap6 cmap6; + } c; + }; + + typedef struct TCMapTable_ TCMapTable; + typedef TCMapTable* PCMapTable; + + + + /* Load character mappings directory when face is loaded. */ + /* The mappings themselves are only loaded on demand. */ + + LOCAL_DEF + TT_Error CharMap_Load( PCMapTable table, + TT_Stream input ); + + + /* Destroy one character mapping table */ + + LOCAL_DEF + TT_Error CharMap_Free( PCMapTable table ); + + + /* Use character mapping table to perform mapping */ + + LOCAL_DEF + UShort CharMap_Index( PCMapTable cmap, + UShort charCode ); + + /* NOTE: The PFace type isn't defined at this point */ + +#ifdef __cplusplus + } +#endif + +#endif /* TTCMAP_H */ + + +/* END */ diff --git a/lib/ttconfig.h b/lib/ttconfig.h new file mode 100644 index 0000000..c56e1ac --- /dev/null +++ b/lib/ttconfig.h @@ -0,0 +1,279 @@ +/******************************************************************* + * + * ttconfig.h 1.0 + * + * Configuration settings header file (spec only). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * Notes: + * + * All the configuration #define statements have been gathered in + * this file to allow easy check and modification. + * + ******************************************************************/ + +#ifndef TTCONFIG_H +#define TTCONFIG_H + + + +/* ------------ auto configuration ------------------------------------- */ + + +/*************************************************************************/ +/* Here we include the file ft_conf.h for system dependent stuff. */ +/* The specific makefile is responsible for providing the right path to */ +/* this file. */ + +#include "ft_conf.h" + + +/**************************************************************************/ +/* Define TT_CONFIG_THREAD_SAFE if you want to build a thread-safe */ +/* version of the library. */ + +/* #define TT_CONFIG_OPTION_THREAD_SAFE */ + + + +/* ------------ general debugging -------------------------------------- */ + + +/************************************************************************* + * + * There are now three debugging modes: + * + * - trace mode: + * + * Error and trace messages are sent to the log file + * (which can be the standard error output). Define + * DEBUG_LEVEL_TRACE to enable this mode. + * + * - error mode: + * + * Only error messages are generated. Define + * DEBUG_LEVEL_ERROR to enable this mode. + * + * - release mode: + * + * Error messages are neither sent nor generated. The code is + * free from any debugging parts. + * + * + * Note that you should link the engine with the 'ttdebug' component. + * in case either DEBUG_LEVEL_TRACE or DEBUG_LEVEL_ERROR is defined. + * + * Please consult ttdebug.h for more details. */ + +/* #define DEBUG_LEVEL_TRACE */ +/* #define DEBUG_LEVEL_ERROR */ + + + +/* ------------ special debugging -------------------------------------- */ + + +/*************************************************************************/ +/* Define this if you want to generate a special debug version of the */ +/* rasterizer. This will progressively draw the glyphs while the */ +/* computations are done directly on the graphics screen... (with */ +/* inverted glyphs). */ +/* */ +/* Use it at your own risk! It is not maintained currently. */ +/* */ +/* IMPORTANT: This is reserved to developers willing to debug the */ +/* rasterizer, which seems working very well in its */ +/* current state... */ + +/* #define DEBUG_RASTER */ + + +/*************************************************************************/ +/* Define this to have a simple debugger version of RunIns(). */ +/* */ +/* Use it at your own risk! It is not maintained currently. */ + +/* #define DEBUG_INTERPRETER */ + + +/*************************************************************************/ +/* Define this to have some housekeeping of allocation and deallocation. */ +/* */ +/* Please note that probably not all OS-specific versions of ttmemory.c */ +/* provide this functionality. */ + +/* #define DEBUG_MEMORY */ + + +/*************************************************************************/ +/* Define this to have bounds checking for file buffer frames. */ +/* */ +/* Please note that probably not all OS-specific versions of ttfile.c */ +/* provide this functionality. */ + +/* #define DEBUG_FILE */ + + + +/* ------------ arithmetic and processor support ----------------------- */ + + +/*************************************************************************/ +/* Define TT_USE_LONG_LONG if you want to enable the use of the */ +/* 'long long' 64-bit type provided by gcc and other compilers. Note */ +/* that : */ +/* */ +/* 1. The type isn't ANSI, and thus will produce many warnings */ +/* during library compilation. */ +/* */ +/* 2. Though the generated object files are slightly smaller, the */ +/* resulting executables are bigger of about 4Kb! gcc must be */ +/* linking some extra code in there! */ +/* */ +/* 3. There is really no speed gain in doing so (but it may help */ +/* debug the ttcalc component). */ +/* */ +/* IMPORTANT NOTE: You don't need to define it on 64-bits machines! */ +/* */ +/* NOTE 2 : This flag used to be _GNUC_LONG64_ */ + +/* #define TT_USE_LONG_LONG */ + + +/*************************************************************************/ +/* define ALIGNMENT to your processor/environment preferred alignment */ +/* size. A value of 8 should work on all current processors, even */ +/* 64-bits ones. */ + +#define ALIGNMENT 8 + + + +/* --------------- miscellaneous ----------------------------------- */ + + +/*********************************************************************/ +/* The number of extensions available. Don't change this value */ +/* except if you add new extensions to the engine. */ + +#define TT_MAX_EXTENSIONS 8 + + + +/* --------------- automatic setup -- don't touch ------------------ */ + + +/*********************************************************************/ +/* If HAVE_TT_TEXT is defined we don't provide a default typedef for */ +/* defining TT_Text. */ + +#ifndef HAVE_TT_TEXT +#define HAVE_TT_TEXT + typedef char TT_Text; +#endif + + +/*********************************************************************/ +/* We define NULL in case it's not defined yet. The default */ +/* location is stdlib.h. */ + +#ifdef HAVE_STDLIB_H +#include +#endif + + +/*********************************************************************/ +/* Some systems can't use vfprintf for error messages on stderr; if */ +/* HAVE_PRINT_FUNCTION is defined, the Print macro must be supplied */ +/* externally (having the same parameters). */ +/* */ +/* This is only used by the "ttdebug" component, which should be */ +/* linked to the engine only in debug mode. */ + +#if defined( DEBUG_LEVEL_TRACE ) || defined( DEBUG_LEVEL_ERROR ) +#ifndef HAVE_PRINT_FUNCTION +#define Print( format, ap ) vfprintf( stderr, (format), (ap) ) +#endif +#endif + + +/********************************************************************/ +/* */ +/* I have added the ability to compile the library into a single */ +/* object file. This gets rids of all the external symbols defined */ +/* in each component interface, and de-pollutes the name-space. */ +/* */ +/* I use two macros, namely LOCAL_FUNC and LOCAL_DEF, which only */ +/* apply to functions that are internal to the engine, and */ +/* should never be seen or linked by a client application. */ +/* */ +/* LOCAL_DEF used in header (.h) files, to define a function */ +/* that will be seen by other components. This */ +/* translates to "extern" in normal mode, and to */ +/* "static" in single-object mode. */ +/* */ +/* LOCAL_FUNC used in implementation (.c) files, just before */ +/* the function body. This translates to nothing */ +/* in normal mode, and to "static" in single-object */ +/* mode. */ +/* */ +/* Getting rid of un-necessary symbols makes the "ttcommon" */ +/* renaming macros hack unnecessary. Moreover, the stripped */ +/* single object file (freetype.o) is 52 Kb, instead of the */ +/* previous 57 Kb (size of all combined .o files), and gives */ +/* a better idea of the engine's real code size. */ +/* */ +/* It is called a "MAKE_OPTION" because the macro must be */ +/* defined in the Makefile, rather than this one. It allows */ +/* any developer to quickly switch from one mode to the other */ +/* without messing with "ttconfig.h" each time. */ +/* */ +#ifndef TT_MAKE_OPTION_SINGLE_OBJECT +#define LOCAL_FUNC /* void */ +#define LOCAL_DEF extern +#else +#define LOCAL_FUNC static +#define LOCAL_DEF static +#endif + + +/*************************************************************************/ +/* Define EXPORT_DEF and EXPORT_FUNC as needed to build e.g. a DLL. All */ +/* variables and functions visible from outside have these prefixes. */ + +#ifndef EXPORT_DEF +#define EXPORT_DEF extern +#endif + +#ifndef EXPORT_FUNC +#define EXPORT_FUNC /* void */ +#endif + + + +/* -------------- internal (developer) configuration toggles ------------ */ + + +#undef TT_STATIC_INTERPRETER +/* Do not undefine this configuration macro. It is now a default that */ +/* must be kept in all release builds. */ + + +#undef TT_STATIC_RASTER +/* Define this if you want to generate a static raster. This makes */ +/* a non re-entrant version of the scan-line converter, which is */ +/* about 10% faster and 50% bigger than an indirect one! */ + + +#endif /* TTCONFIG_H */ + + +/* END */ diff --git a/lib/ttdebug.c b/lib/ttdebug.c new file mode 100644 index 0000000..4afe2dc --- /dev/null +++ b/lib/ttdebug.c @@ -0,0 +1,404 @@ +/* Simple debugging component. Temporary */ + +#include "ttdebug.h" +#include "tttables.h" +#include "ttobjs.h" + + +#ifdef DEBUG_LEVEL_TRACE + char tt_trace_levels[trace_max]; +#endif + +#if defined( DEBUG_LEVEL_ERROR ) || defined( DEBUG_LEVEL_TRACE ) + +#include +#include +#include + + + static String tempStr[128]; + + static const String* OpStr[256] = + { + "SVTCA y", /* Set vectors to coordinate axis y */ + "SVTCA x", /* Set vectors to coordinate axis x */ + "SPvTCA y", /* Set Proj. vec. to coord. axis y */ + "SPvTCA x", /* Set Proj. vec. to coord. axis x */ + "SFvTCA y", /* Set Free. vec. to coord. axis y */ + "SFvTCA x", /* Set Free. vec. to coord. axis x */ + "SPvTL //", /* Set Proj. vec. parallel to segment */ + "SPvTL +", /* Set Proj. vec. normal to segment */ + "SFvTL //", /* Set Free. vec. parallel to segment */ + "SFvTL +", /* Set Free. vec. normal to segment */ + "SPvFS", /* Set Proj. vec. from stack */ + "SFvFS", /* Set Free. vec. from stack */ + "GPV", /* Get projection vector */ + "GFV", /* Get freedom vector */ + "SFvTPv", /* Set free. vec. to proj. vec. */ + "ISECT", /* compute intersection */ + + "SRP0", /* Set reference point 0 */ + "SRP1", /* Set reference point 1 */ + "SRP2", /* Set reference point 2 */ + "SZP0", /* Set Zone Pointer 0 */ + "SZP1", /* Set Zone Pointer 1 */ + "SZP2", /* Set Zone Pointer 2 */ + "SZPS", /* Set all zone pointers */ + "SLOOP", /* Set loop counter */ + "RTG", /* Round to Grid */ + "RTHG", /* Round to Half-Grid */ + "SMD", /* Set Minimum Distance */ + "ELSE", /* Else */ + "JMPR", /* Jump Relative */ + "SCvTCi", /* Set CVT */ + "SSwCi", /* */ + "SSW", /* */ + + "DUP", + "POP", + "CLEAR", + "SWAP", + "DEPTH", + "CINDEX", + "MINDEX", + "AlignPTS", + "INS_$28", + "UTP", + "LOOPCALL", + "CALL", + "FDEF", + "ENDF", + "MDAP[-]", + "MDAP[r]", + + "IUP[y]", + "IUP[x]", + "SHP[0]", + "SHP[1]", + "SHC[0]", + "SHC[1]", + "SHZ[0]", + "SHZ[1]", + "SHPIX", + "IP", + "MSIRP[0]", + "MSIRP[1]", + "AlignRP", + "RTDG", + "MIAP[-]", + "MIAP[r]", + + "NPushB", + "NPushW", + "WS", + "RS", + "WCvtP", + "RCvt", + "GC[0]", + "GC[1]", + "SCFS", + "MD[0]", + "MD[1]", + "MPPEM", + "MPS", + "FlipON", + "FlipOFF", + "DEBUG", + + "LT", + "LTEQ", + "GT", + "GTEQ", + "EQ", + "NEQ", + "ODD", + "EVEN", + "IF", + "EIF", + "AND", + "OR", + "NOT", + "DeltaP1", + "SDB", + "SDS", + + "ADD", + "SUB", + "DIV", + "MUL", + "ABS", + "NEG", + "FLOOR", + "CEILING", + "ROUND[G]", + "ROUND[B]", + "ROUND[W]", + "ROUND[?]", + "NROUND[G]", + "NROUND[B]", + "NROUND[W]", + "NROUND[?]", + + "WCvtF", + "DeltaP2", + "DeltaP3", + "DeltaC1", + "DeltaC2", + "DeltaC3", + "SROUND", + "S45Round", + "JROT", + "JROF", + "ROFF", + "INS_$7B", + "RUTG", + "RDTG", + "SANGW", + "AA", + + "FlipPT", + "FlipRgON", + "FlipRgOFF", + "INS_$83", + "INS_$84", + "ScanCTRL", + "SDPVTL[0]", + "SDPVTL[1]", + "GetINFO", + "IDEF", + "ROLL", + "MAX", + "MIN", + "ScanTYPE", + "IntCTRL", + "INS_$8F", + + "INS_$90", + "INS_$91", + "INS_$92", + "INS_$93", + "INS_$94", + "INS_$95", + "INS_$96", + "INS_$97", + "INS_$98", + "INS_$99", + "INS_$9A", + "INS_$9B", + "INS_$9C", + "INS_$9D", + "INS_$9E", + "INS_$9F", + + "INS_$A0", + "INS_$A1", + "INS_$A2", + "INS_$A3", + "INS_$A4", + "INS_$A5", + "INS_$A6", + "INS_$A7", + "INS_$A8", + "INS_$A9", + "INS_$AA", + "INS_$AB", + "INS_$AC", + "INS_$AD", + "INS_$AE", + "INS_$AF", + + "PushB[0]", + "PushB[1]", + "PushB[2]", + "PushB[3]", + "PushB[4]", + "PushB[5]", + "PushB[6]", + "PushB[7]", + "PushW[0]", + "PushW[1]", + "PushW[2]", + "PushW[3]", + "PushW[4]", + "PushW[5]", + "PushW[6]", + "PushW[7]", + + "MDRP[G]", + "MDRP[B]", + "MDRP[W]", + "MDRP[?]", + "MDRP[rG]", + "MDRP[rB]", + "MDRP[rW]", + "MDRP[r?]", + "MDRP[mG]", + "MDRP[mB]", + "MDRP[mW]", + "MDRP[m?]", + "MDRP[mrG]", + "MDRP[mrB]", + "MDRP[mrW]", + "MDRP[mr?]", + "MDRP[pG]", + "MDRP[pB]", + + "MDRP[pW]", + "MDRP[p?]", + "MDRP[prG]", + "MDRP[prB]", + "MDRP[prW]", + "MDRP[pr?]", + "MDRP[pmG]", + "MDRP[pmB]", + "MDRP[pmW]", + "MDRP[pm?]", + "MDRP[pmrG]", + "MDRP[pmrB]", + "MDRP[pmrW]", + "MDRP[pmr?]", + + "MIRP[G]", + "MIRP[B]", + "MIRP[W]", + "MIRP[?]", + "MIRP[rG]", + "MIRP[rB]", + "MIRP[rW]", + "MIRP[r?]", + "MIRP[mG]", + "MIRP[mB]", + "MIRP[mW]", + "MIRP[m?]", + "MIRP[mrG]", + "MIRP[mrB]", + "MIRP[mrW]", + "MIRP[mr?]", + "MIRP[pG]", + "MIRP[pB]", + + "MIRP[pW]", + "MIRP[p?]", + "MIRP[prG]", + "MIRP[prB]", + "MIRP[prW]", + "MIRP[pr?]", + "MIRP[pmG]", + "MIRP[pmB]", + "MIRP[pmW]", + "MIRP[pm?]", + "MIRP[pmrG]", + "MIRP[pmrB]", + "MIRP[pmrW]", + "MIRP[pmr?]" + }; + + + const String* Cur_U_Line( void* _exec ) + { + String s[32]; + + Int op, i, n; + + PExecution_Context exec; + + + exec = _exec; + + op = exec->code[exec->IP]; + + sprintf( tempStr, "%s", OpStr[op] ); + + if ( op == 0x40 ) + { + n = exec->code[exec->IP + 1]; + sprintf( s, "(%d)", n ); + strncat( tempStr, s, 8 ); + + if ( n > 20 ) n = 20; /* limit output */ + + for ( i = 0; i < n; i++ ) + { + sprintf( s, " $%02hx", exec->code[exec->IP + i + 2] ); + strncat( tempStr, s, 8 ); + } + } + else if ( op == 0x41 ) + { + n = exec->code[exec->IP + 1]; + sprintf( s, "(%d)", n ); + strncat( tempStr, s, 8 ); + + if ( n > 20 ) n = 20; /* limit output */ + + for ( i = 0; i < n; i++ ) + { + sprintf( s, " $%02hx%02hx", exec->code[exec->IP + i*2 + 2], + exec->code[exec->IP + i*2 + 3] ); + strncat( tempStr, s, 8 ); + } + } + else if ( (op & 0xF8) == 0xB0 ) + { + n = op - 0xB0; + + for ( i = 0; i <= n; i++ ) + { + sprintf( s, " $%02hx", exec->code[exec->IP + i + 1] ); + strncat( tempStr, s, 8 ); + } + } + else if ( (op & 0xF8) == 0xB8 ) + { + n = op-0xB8; + + for ( i = 0; i <= n; i++ ) + { + sprintf( s, " $%02hx%02hx", exec->code[exec->IP + i*2 + 1], + exec->code[exec->IP + i*2 + 2] ); + strncat( tempStr, s, 8 ); + } + } + + return (String*)tempStr; + } + + + /* the Print() function is defined in ttconfig.h; */ + /* it defaults to vprintf on systems which have it */ + + void TT_Message( const String* fmt, ... ) + { + va_list ap; + + va_start( ap, fmt ); + Print( fmt, ap ); + va_end( ap ); + } + + + void TT_Panic( const String* fmt, ... ) + { + va_list ap; + + va_start( ap, fmt ); + Print( fmt, ap ); + va_end( ap ); + + exit( EXIT_FAILURE ); + } + +#endif /* defined( DEBUG_LEVEL_ERROR ) || defined( DEBUG_LEVEL_TRACE ) */ + +#if defined( DEBUG_LEVEL_TRACE ) + + /* use this function to set the values of tt_trace_levels */ + + void set_tt_trace_levels( int index, char value ) + { + tt_trace_levels[index] = value; + } + +#endif + +/* END */ diff --git a/lib/ttdebug.h b/lib/ttdebug.h new file mode 100644 index 0000000..8e889dc --- /dev/null +++ b/lib/ttdebug.h @@ -0,0 +1,170 @@ +/******************************************************************* + * + * ttdebug.h + * + * Debugging and Logging component (specification) + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * This component contains various macros and functions used to + * ease the debugging of the FreeType engine. Its main purpose + * is in assertion checking, tracing, and error detection. + * + * There are now three debugging modes: + * + * - trace mode: + * + * Error and trace messages are sent to the log file + * (which can be the standard error output). Define + * DEBUG_LEVEL_TRACE to enable this mode. + * + * - error mode: + * + * Only error messages are generated. Define + * DEBUG_LEVEL_ERROR to enable this mode. + * + * - release mode: + * + * Error messages are neither sent nor generated. The code is + * free from any debugging parts. + * + ******************************************************************/ + +#ifndef TTDEBUG_H +#define TTDEBUG_H + +#include "ttconfig.h" +#include "tttypes.h" + + +#ifdef __cplusplus + extern "C" { +#endif + + +#if defined( DEBUG_LEVEL_TRACE ) + + typedef enum Trace_Component_ + { + trace_any = 0, + trace_api, + trace_interp, + trace_load, + trace_gload, + trace_memory, + trace_file, + trace_mutex, + trace_cache, + trace_calc, + trace_cmap, + trace_extend, + trace_objs, + trace_raster, + + trace_bitmap, + trace_max + + } Trace_Component; + + + /* Here we define an array to hold the trace levels per component. */ + /* Since it is globally defined, all array members are set to 0. */ + /* You should set the values in this array either in your program */ + /* or with your debugger. */ + /* */ + /* Currently, up to eight levels (PTRACE0-PTRACE7, see below) are */ + /* used in some parts of the engine. */ + /* */ + /* For example, to have all tracing messages in the raster */ + /* component, say */ + /* */ + /* #define DEBUG_LEVEL_TRACE */ + /* #include "ttdebug.h" */ + /* */ + /* ... */ + /* set_tt_trace_levels( trace_raster, 7 ) */ + /* */ + /* in your code before initializing the FreeType engine. */ + /* */ + /* Maybe it is better to define DEBUG_LEVEL_TRACE in ttconfig.h... */ + + extern char tt_trace_levels[trace_max]; + + /* IMPORTANT: */ + /* */ + /* Each component must define the macro TT_COMPONENT */ + /* to a valid Trace_Component value before using any */ + /* PTRACEx macro. */ + /* */ + +#define PTRACE( level, varformat ) \ + if ( tt_trace_levels[TT_COMPONENT] >= level ) TT_Message##varformat + +#elif defined( DEBUG_LEVEL_ERROR ) + +#define PTRACE( level, varformat ) /* nothing */ + +#else /* RELEASE MODE */ + +#define TT_Assert( condition, action ) /* nothing */ + +#define PTRACE( level, varformat ) /* nothing */ +#define PERROR( varformat ) /* nothing */ +#define PANIC( varformat ) /* nothing */ + +#endif + + +/************************************************************************/ +/* */ +/* Define macros and fuctions that are common to the debug and trace */ +/* modes. */ +/* */ + +#if defined( DEBUG_LEVEL_TRACE ) || defined( DEBUG_LEVEL_ERROR ) + + +#define TT_Assert( condition, action ) if ( !(condition) ) ( action ) + + void TT_Message( const String* fmt, ... ); + void TT_Panic ( const String* fmt, ... ); + /* print a message and exit */ + + const String* Cur_U_Line( void* exec ); + +#define PERROR( varformat ) TT_Message##varformat +#define PANIC( varformat ) TT_Panic##varformat + +#endif + +#if defined( DEBUG_LEVEL_TRACE ) + + void set_tt_trace_levels( int index, char value ); + +#endif + + +#define PTRACE0( varformat ) PTRACE( 0, varformat ) +#define PTRACE1( varformat ) PTRACE( 1, varformat ) +#define PTRACE2( varformat ) PTRACE( 2, varformat ) +#define PTRACE3( varformat ) PTRACE( 3, varformat ) +#define PTRACE4( varformat ) PTRACE( 4, varformat ) +#define PTRACE5( varformat ) PTRACE( 5, varformat ) +#define PTRACE6( varformat ) PTRACE( 6, varformat ) +#define PTRACE7( varformat ) PTRACE( 7, varformat ) + + +#ifdef __cplusplus + } +#endif + + +#endif /* TTDEBUG_H */ diff --git a/lib/ttengine.h b/lib/ttengine.h new file mode 100644 index 0000000..e946d06 --- /dev/null +++ b/lib/ttengine.h @@ -0,0 +1,115 @@ +/******************************************************************* + * + * ttengine.h 1.1 + * + * Engine instance structure definition. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * New in 1.1 : + * + * - added the 'raster_lock' mutex field to synchronize + * scan-line conversion in thread-safe and re-entrant builds. + * + ******************************************************************/ + +#ifndef TTENGINE_H +#define TTENGINE_H + +#include "tttypes.h" +#include "ttconfig.h" +#include "freetype.h" +#include "ttmutex.h" + +#ifdef __cplusplus + extern "C" { +#endif + + /********************************************************************/ + /* */ + /* The freetype engine instance structure. */ + /* */ + /* This structure holds all the data that is necessary to run */ + /* one instance of the freetype engine. It is needed to get a */ + /* completely re-entrant version of the library. */ + /* */ + /* The goal is to move _all_ component-specific variables, either */ + /* static or global in the structure; the component initializers */ + /* and finalizers will all be called with the address of a valid */ + /* TEngine_Instance. */ + /* */ + /********************************************************************/ + + struct TEngine_Instance_ + { + TMutex lock; /* engine lock */ + + void* list_free_elements; + + void* objs_face_class; /* the face cache class */ + void* objs_instance_class; /* the instance cache class */ + void* objs_execution_class; /* the context cache class */ + void* objs_glyph_class; /* the glyph cache class */ + + void* objs_face_cache; /* these caches are used to track */ + void* objs_exec_cache; /* the current face and execution */ + /* context objects */ + + void* file_component; /* ttfile implementation dependent */ + + TMutex raster_lock; /* mutex for this engine's render pool */ + void* raster_component; /* ttraster implementation depedent */ + Byte raster_palette[5]; /* gray-levels palette for anti-aliasing */ + + void* extension_component; /* extensions dependent */ + +#if 0 + TT_Glyph_Loader_Callback glCallback; /* glyph loader callback, if any */ +#endif + }; + + /* NOTE : The raster's lock is only acquired by the Render_Glyph and */ + /* Render_Gray_Glyph functions, which always release it on exit */ + /* They do not lock the engine mutex. This means you shouldn't */ + /* be concerned about deadlocks between the two mutexes, as these */ + /* should never appear.. */ + + typedef struct TEngine_Instance_ TEngine_Instance; + typedef TEngine_Instance* PEngine_Instance; + + +#ifdef TT_CONFIG_OPTION_THREAD_SAFE /* for re-entrant builds */ + +#define ENGINE_ARG TEngine_Instance* _engine +#define ENGINE_ARGS TEngine_Instance* _engine, + +#define ENGINE_VAR _engine +#define ENGINE_VARS _engine, + +#define ENGINE _engine + +#else /* for thread-safe builds */ + +#define ENGINE_ARG /* void */ +#define ENGINE_ARGS + +#define ENGINE_VAR +#define ENGINE_VARS + +#endif /* TT_CONFIG_OPTION_THREAD_SAFE */ + +#ifdef __cplusplus + } +#endif + +#endif /* TTENGINE_H */ + + +/* END */ diff --git a/lib/ttextend.c b/lib/ttextend.c new file mode 100644 index 0000000..cb77e7f --- /dev/null +++ b/lib/ttextend.c @@ -0,0 +1,212 @@ +/******************************************************************* + * + * ttextend.h 2.0 + * + * Extensions Interface + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * This is an updated version of the extension component, now + * located in the main library's source directory. It allows + * the dynamic registration/use of various face object extensions + * through a simple API. + * + ******************************************************************/ + +#include "ttextend.h" +#include "ttengine.h" +#include "ttmemory.h" + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_extend + + + struct TExtension_Registry_ + { + Int num_extensions; + Long cur_offset; + TExtension_Class classes[TT_MAX_EXTENSIONS]; + }; + + typedef struct TExtension_Registry_ TExtension_Registry; + typedef TExtension_Registry* PExtension_Registry; + + + + /* Initialize the extension component */ + + LOCAL_FUNC + TT_Error TTExtend_Init( PEngine_Instance engine ) + { + TT_Error error; + PExtension_Registry exts; + + + if ( ALLOC( exts, sizeof ( TExtension_Registry ) ) ) + return error; + + exts->num_extensions = 0; + exts->cur_offset = 0; + engine->extension_component = (void*)exts; + + return TT_Err_Ok; + } + + + /* Finalize the extension component */ + + LOCAL_FUNC + TT_Error TTExtend_Done( PEngine_Instance engine ) + { + FREE( engine->extension_component ); + return TT_Err_Ok; + } + + + /* Register a new extension */ + + EXPORT_FUNC + TT_Error TT_Register_Extension( PEngine_Instance engine, + Long id, + Long size, + PExt_Constructor create, + PExt_Destructor destroy ) + { + PExtension_Registry exts; + PExtension_Class clazz; + Int p; + + + exts = (PExtension_Registry)engine->extension_component; + if ( !exts ) + return TT_Err_Ok; + + p = exts->num_extensions; + + if ( p >= TT_MAX_EXTENSIONS ) + return TT_Err_Too_Many_Extensions; + + clazz = exts->classes + p; + clazz->id = id; + clazz->size = size; + clazz->build = create; + clazz->destroy = destroy; + + clazz->offset = exts->cur_offset; + + exts->num_extensions++; + exts->cur_offset += ( size + ALIGNMENT-1 ) & -ALIGNMENT; + + return TT_Err_Ok; + } + + + /* Query an extension block by extension_ID */ + + EXPORT_FUNC + TT_Error TT_Extension_Get( PFace face, + Long extension_id, + void** extension_block ) + { + PExtension_Registry registry; + PExtension_Class clazz; + Int n; + + + if ( !face->extension ) + return TT_Err_Extensions_Unsupported; + + registry = (PExtension_Registry)face->engine->extension_component; + + for ( n = 0; n < face->n_extensions; n++ ) + { + clazz = registry->classes + n; + if ( clazz->id == extension_id ) + { + *extension_block = (PByte)face->extension + clazz->offset; + return TT_Err_Ok; + } + } + + return TT_Err_Invalid_Extension_Id; + } + + + /* Destroy all extensions within a face object. Called by the */ + /* face object destructor. */ + + LOCAL_FUNC + TT_Error Extension_Destroy( PFace face ) + { + PEngine_Instance engine = face->engine; + PExtension_Registry registry; + PExtension_Class clazz; + Int n; + PByte ext; + + + registry = (PExtension_Registry)engine->extension_component; + + for ( n = 0; n < face->n_extensions; n++ ) + { + clazz = registry->classes + n; + ext = (PByte)face->extension + clazz->offset; + + /* the destructor is optional */ + if ( clazz->destroy ) + clazz->destroy( (void*)ext, face ); + } + + /* destroy the face's extension block too */ + FREE( face->extension ); + face->n_extensions = 0; + + return TT_Err_Ok; + } + + + /* Create an extension within a face object. Called by the */ + /* face object constructor. */ + + LOCAL_FUNC + TT_Error Extension_Create( PFace face ) + { + PEngine_Instance engine = face->engine; + PExtension_Registry registry; + PExtension_Class clazz; + TT_Error error; + Int n; + PByte ext; + + + registry = (PExtension_Registry)engine->extension_component; + + face->n_extensions = registry->num_extensions; + if ( ALLOC( face->extension, registry->cur_offset ) ) + return error; + + for ( n = 0; n < face->n_extensions; n++ ) + { + clazz = registry->classes + n; + ext = (PByte)face->extension + clazz->offset; + error = clazz->build( (void*)ext, face ); + if ( error ) + goto Fail; + } + return TT_Err_Ok; + + Fail: + Extension_Destroy( face ); + return error; + } + + +/* END */ diff --git a/lib/ttextend.h b/lib/ttextend.h new file mode 100644 index 0000000..d5d8622 --- /dev/null +++ b/lib/ttextend.h @@ -0,0 +1,168 @@ +/******************************************************************* + * + * ttextend.h 2.0 + * + * Extensions Interface. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * This is an updated version of the extension component, now + * located in the main library's source directory. It allows + * the dynamic registration/use of various face object extensions + * through a simple API. + * + ******************************************************************/ + +#ifndef TTEXTEND_H +#define TTEXTEND_H + +#include "ttconfig.h" +#include "tttypes.h" +#include "ttobjs.h" + + +#ifdef __cplusplus + extern "C" { +#endif + + /* The extensions don't need to be integrated at compile time into */ + /* the engine, only at link time. */ + + + /* When a new face object is created, the face constructor calls */ + /* the extension constructor with the following arguments: */ + /* */ + /* ext : typeless pointer to the face's extension block. */ + /* Its size is the one given at registration time */ + /* in the extension class's 'size' field. */ + /* */ + /* face : the parent face object. Note that the extension */ + /* constructor is called when the face object is */ + /* built. */ + + typedef TT_Error TExt_Constructor( void* ext, PFace face ); + + + /* When a face object is destroyed, the face destructor calls */ + /* the extension destructor with the following arguments. */ + /* */ + /* ext : typeless pointer to the face's extension block. */ + /* Its size is the one given at registration time */ + /* in the extension class's 'size' field. */ + /* */ + /* face : the parent face object. Note that the extension */ + /* destructor is called before the actual face object */ + /* is destroyed. */ + + typedef TT_Error TExt_Destructor ( void* ext, PFace face ); + + typedef TExt_Constructor* PExt_Constructor; + typedef TExt_Destructor* PExt_Destructor; + + + struct TExtension_Class_ + { + Long id; /* extension id */ + Long size; /* size in bytes of extension record */ + PExt_Constructor build; /* the extension's class constructor */ + PExt_Destructor destroy; /* the extension's class destructor */ + + Long offset; /* offset of ext. record in face obj */ + /* (set by the engine) */ + }; + + typedef struct TExtension_Class_ TExtension_Class; + typedef TExtension_Class* PExtension_Class; + + +#define Build_Extension_ID( a, b, c, d ) \ + ( ((ULong)(a) << 24) | \ + ((ULong)(b) << 16) | \ + ((ULong)(c) << 8 ) | \ + (ULong)(d) ) + + /* A note regarding extensions and the single-object compilation */ + /* mode : */ + /* */ + /* When the engine is compiled as a single object file, extensions */ + /* must remain linkable *after* compile time. In order to do this, */ + /* we need to export the functions that an extension may need. */ + /* Fortunately, we can limit ourselves to : */ + /* */ + /* o TT_Register_Extension (previously called Extension_Register) */ + /* which is to be called by each extension on within */ + /* it TT_Init_XXXX_Extension initializer. */ + /* */ + /* o File and frame access functions. Fortunately, these already */ + /* have their names prefixed by "TT_", so no change was needed */ + /* except replacing the LOCAL_DEF keyword with EXPORT_DEF */ + /* */ + /* o Memory access functions, i.e. TT_Alloc and TT_Free. Again, */ + /* the change is minimal */ + /* */ + /* o the table-lookup function : TT_LookUp_Table, formerly known */ + /* as Load_TrueType_Table in ttload.c. */ + /* */ + /* */ + /* Other than that, an extension should be able to #include all */ + /* relevant header files to get access to internal types, but */ + /* should not call engine internal functions.. */ + /* */ + /* If there is a need for a specific internal function call, let */ + /* me known to see if we need to export it by default.. */ + /* - DavidT */ + /* */ + + /* Register a new extension. Called by extension */ + /* service initializers. */ + EXPORT_DEF + TT_Error TT_Register_Extension( PEngine_Instance engine, + Long id, + Long size, + PExt_Constructor create, + PExt_Destructor destroy ); + + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE + /* Initialize the extension component */ + LOCAL_DEF + TT_Error TTExtend_Init( PEngine_Instance engine ); + + /* Finalize the extension component */ + LOCAL_DEF + TT_Error TTExtend_Done( PEngine_Instance engine ); + + /* Create an extension within a face object. Called by the */ + /* face object constructor. */ + LOCAL_DEF + TT_Error Extension_Create( PFace face ); + + /* Destroy all extensions within a face object. Called by the */ + /* face object destructor. */ + LOCAL_DEF + TT_Error Extension_Destroy( PFace face ); +#endif + + /* Query an extension block by extension_ID. Called by extension */ + /* service routines. */ + EXPORT_DEF + TT_Error TT_Extension_Get( PFace face, + Long extension_id, + void** extension_block ); + +#ifdef __cplusplus + } +#endif + + +#endif /* TTEXTEND_H */ + + +/* END */ diff --git a/lib/ttfile.c b/lib/ttfile.c new file mode 100644 index 0000000..07d9698 --- /dev/null +++ b/lib/ttfile.c @@ -0,0 +1,1175 @@ +/******************************************************************* + * + * ttfile.c (extended version) 2.1 + * + * File I/O Component (body). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTES: + * + * This implementation relies on the ANSI libc. You may wish to + * modify it to get rid of libc and go straight to the your + * platform's stream routines. + * + * The same source code can be used for thread-safe and re-entrant + * builds of the library. + * + * Changes between 2.0 and 2.1 : + * + * - it is now possible to close a stream's file handle explicitely + * through the new API "TT_Flush_Stream". This will simply close + * a stream's file handle (useful to save system resources when + * dealing with lots of opened fonts). Of course, the function + * "TT_Use_Stream" will automatically re-open a stream's handle if + * necessary. + * + * - added "TT_Stream_Size" to replace "TT_File_Size" which wasn't + * used anyway. This one returns the size of any stream, even + * flushed one (when the previous TT_File_Size could only return + * the size of the current working stream). This is used by the + * new "Load_TrueType_Any" function in the tables loader. + * + ******************************************************************/ + +#include "ttconfig.h" + +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "freetype.h" +#include "tttypes.h" +#include "ttdebug.h" +#include "ttengine.h" +#include "ttmutex.h" +#include "ttmemory.h" +#include "ttfile.h" /* our prototypes */ + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_file + + +/* For now, we don't define additional error messages in the core library */ +/* to report open-on demand errors. Define these error as standard ones */ + +#define TT_Err_Could_Not_ReOpen_File TT_Err_Could_Not_Open_File +#define TT_Err_Could_Not_ReSeek_File TT_Err_Could_Not_Open_File + + /* This definition is mandatory for each file component! */ + EXPORT_FUNC + const TFileFrame TT_Null_FileFrame = { NULL, 0, 0 }; + +/* It has proven useful to do some bounds checks during development phase. */ +/* They should probably be undefined for speed reasons in a later release. */ + +#if DEBUG_FILE +#define CHECK_FRAME( frame, n ) \ + do { \ + if ( frame.cursor + n > frame.address + frame.size ) \ + Panic( "Frame boundary error!\n" ); \ + } while ( 0 ) +#else +#define CHECK_FRAME( frame, n ) /* nothing */ +#endif + + /* Because a stream can be flushed, i.e. its file handle can be */ + /* closed to save system resources, we must keep the stream's file */ + /* pathname to be able to re-open it on demand when it is flushed */ + + struct TStream_Rec_; + typedef struct TStream_Rec_ TStream_Rec; + typedef TStream_Rec* PStream_Rec; + + struct TStream_Rec_ + { + Bool opened; /* is the stream handle opened ? */ + TT_Text* name; /* the file's pathname */ + Long position; /* current position within the file */ + + FILE* file; /* file handle */ + Long base; /* stream base in file */ + Long size; /* stream size in file */ + }; + + /* We support embedded TrueType files by allowing them to be */ + /* inside any file, at any location, hence the 'base' argument. */ + /* Note however that the current implementation does not allow you */ + /* to specify a 'base' index when opening a file. */ + /* (will come later) */ + /* I still don't know if this will turn out useful ?? - DavidT */ + +#define STREAM2REC( x ) ( (TStream_Rec*)HANDLE_Val( x ) ) + + static TT_Error Stream_Activate ( PStream_Rec stream ); + static TT_Error Stream_Deactivate( PStream_Rec stream ); + + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + /**** ****/ + /**** N O N R E E N T R A N T I M P L E M E N T A T I O N ****/ + /**** ****/ + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + + /* in non-rentrant builds, we allocate a single block where we'll */ + /* place all the frames smaller than FRAME_CACHE_SIZE, rather than */ + /* allocating a new block on each access. Bigger frames will be */ + /* malloced normally in the heap. */ + /* */ + /* See TT_Access_Frame() and TT_Forget_Frame() for details. */ + +#define FRAME_CACHE_SIZE 2048 + + /* The TFile_Component structure holds all the data that was */ + /* previously declared static or global in this component. */ + /* */ + /* It is accessible through the 'engine.file_component' */ + /* variable in re-entrant builds, or directly through the */ + /* static 'files' variable in other builds. */ + + struct TFile_Component_ + { + TMutex lock; /* used by the thread-safe build only */ + Byte* frame_cache; /* frame cache */ + PStream_Rec stream; /* current stream */ + TFileFrame frame; /* current frame */ + }; + + typedef struct TFile_Component_ TFile_Component; + + static TFile_Component files; + +#define CUR_Stream files.stream +#define CUR_Frame files.frame + +#define STREAM_VARS /* void */ +#define STREAM_VAR /* void */ + +/* The macro CUR_Stream denotes the current input stream. */ +/* Note that for the re-entrant version, the 'stream' name has been */ +/* chosen according to the macro STREAM_ARGS. */ + +/* The macro CUR_Frame denotes the current file frame. */ +/* Note that for the re-entrant version, the 'frame' name has been */ +/* chosen according to the macro FRAME_ARGS. */ + +/* The macro STREAM_VAR is used when calling public functions */ +/* that need an 'optional' stream argument. */ + + +/******************************************************************* + * + * Function : TTFile_Init + * + * Description : Initializes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Init( PEngine_Instance engine ) + { + TT_Error error; + + + MUTEX_Create( files.lock ); + files.stream = NULL; + ZERO_Frame( files.frame ); + + if ( ALLOC( files.frame_cache, FRAME_CACHE_SIZE ) ) + return error; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTFile_Done + * + * Description : Finalizes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Done( PEngine_Instance engine ) + { + FREE( files.frame_cache ); + MUTEX_Destroy( files.lock ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Use_Stream + * + * Description : Copies or duplicates a given stream. + * + * Input : org_stream original stream + * stream target stream (copy or duplicate) + * + * Output : Error code. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Use_Stream( TT_Stream org_stream, + TT_Stream* stream ) + { + MUTEX_Lock( files.lock ); /* lock file mutex */ + + *stream = org_stream; /* copy the stream */ + files.stream = STREAM2REC(org_stream); /* set current stream */ + + Stream_Activate( files.stream ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Done_Stream + * + * Description : Releases a given stream. + * + * Input : stream target stream + * + * Output : Error code. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Done_Stream( TT_Stream* stream ) + { + HANDLE_Set( *stream, NULL ); + MUTEX_Release( files.lock ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Access_Frame + * + * Description : Notifies the component that we're going to read + * 'size' bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx + * functions easily. + * + * Input : size number of bytes to access. + * + * Output : SUCCESS on success. FAILURE on error. + * + * Notes: The function fails if the byte range is not within the + * the file, or if there is not enough memory to cache + * the bytes properly (which usually means that `size' is + * too big in both cases). + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Access_Frame( STREAM_ARGS FRAME_ARGS Long size ) + { + TT_Error error; + + + if ( CUR_Frame.address != NULL ) + return TT_Err_Nested_Frame_Access; + + if ( size <= FRAME_CACHE_SIZE ) + { + /* use the cache */ + CUR_Frame.address = files.frame_cache; + CUR_Frame.size = FRAME_CACHE_SIZE; + } + else + { + if ( ALLOC( CUR_Frame.address, size ) ) + return error; + CUR_Frame.size = size; + } + + error = TT_Read_File( STREAM_VARS (void*)CUR_Frame.address, size ); + if (error) + { + if ( size > FRAME_CACHE_SIZE ) + FREE( CUR_Frame.address ); + CUR_Frame.address = NULL; + CUR_Frame.size = 0; + } + + CUR_Frame.cursor = CUR_Frame.address; + return error; + } + + +/******************************************************************* + * + * Function : TT_Check_And_Access_Frame + * + * Description : Notifies the component that we're going to read + * `size' bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx + * functions easily. + * + * Input : size number of bytes to access. + * + * Output : SUCCESS on success. FAILURE on error. + * + * Notes: The function truncates `size' if the byte range is not + * within the file. + * + * It will fail if there is not enough memory to cache + * the bytes properly (which usually means that `size' is + * too big). + * + * It will fail if you make two consecutive calls + * to TT_Access_Frame(), without a TT_Forget_Frame() between + * them. + * + * The only difference with TT_Access_Frame() is that we + * check that the frame is within the current file. We + * otherwise truncate it. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Check_And_Access_Frame( STREAM_ARGS FRAME_ARGS Long size ) + { + TT_Error error; + Long readBytes, requested; + + + if ( CUR_Frame.address != NULL ) + return TT_Err_Nested_Frame_Access; + + if ( size <= FRAME_CACHE_SIZE ) + { + /* use the cache */ + CUR_Frame.address = files.frame_cache; + CUR_Frame.size = FRAME_CACHE_SIZE; + } + else + { + if ( ALLOC( CUR_Frame.address, size ) ) + return error; + CUR_Frame.size = size; + } + + requested = size; + readBytes = CUR_Stream->size - TT_File_Pos( STREAM_VAR ); + if ( size > readBytes ) + size = readBytes; + + error = TT_Read_File( STREAM_VARS (void*)CUR_Frame.address, size ); + if (error) + { + if ( requested > FRAME_CACHE_SIZE ) + FREE( CUR_Frame.address ); + CUR_Frame.address = NULL; + CUR_Frame.size = 0; + } + + CUR_Frame.cursor = CUR_Frame.address; + return error; + } + + +/******************************************************************* + * + * Function : TT_Forget_Frame + * + * Description : Releases a cached frame after reading. + * + * Input : None + * + * Output : SUCCESS on success. FAILURE on error. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Forget_Frame( FRAME_ARG ) + { + if ( CUR_Frame.address == NULL ) + return TT_Err_Nested_Frame_Access; + + if ( CUR_Frame.size > FRAME_CACHE_SIZE ) + FREE( CUR_Frame.address ); + + ZERO_Frame( CUR_Frame ); + + return TT_Err_Ok; + } + + +#else /* TT_CONFIG_OPTION_THREAD_SAFE */ + + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + /******** ********/ + /******** R E E N T R A N T I M P L E M E N T A T I O N ********/ + /******** ********/ + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + +/* a simple macro to access the file component's data */ +#define files ( *((TFile_Component*)engine.file_component) ) + +#define CUR_Stream STREAM2REC( stream ) /* re-entrant macros */ +#define CUR_Frame (*frame) + +#define STREAM_VARS stream, +#define STREAM_VAR stream + + +/******************************************************************* + * + * Function : TTFile_Init + * + * Description : Initializes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Init( PEngine_Instance engine ) + { + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTFile_Done + * + * Description : Finalizes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Done( PEngine_Instance engine ) + { + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Use_Stream + * + * Description : Duplicates a stream for a new usage. + * + * Input : input_stream source stream to duplicate + * copy address of target duplicate stream + * + * Output : error code. + * The target stream is set to NULL in case of failure. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Use_Stream( TT_Stream input_stream, + TT_Stream* copy ) + { + PStream_Rec rec = STREAM2REC( input_stream ); + + return TT_Open_Stream( rec->name, copy ); + } + + +/******************************************************************* + * + * Function : TT_Done_Stream + * + * Description : Releases a given stream. + * + * Input : stream target stream + * + * Output : + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Done_Stream( TT_Stream* stream ) + { + return TT_Close_Stream( stream ); + } + + +/******************************************************************* + * + * Function : TT_Access_Frame + * + * Description : Notifies the component that we're going to read + * 'size' bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx + * functions easily. + * + * Input : size number of bytes to access. + * + * Output : SUCCESS on success. FAILURE on error. + * + * Notes: The function fails if the byte range is not within the + * the file, or if there is not enough memory to cache + * the bytes properly (which usually means that `size' is + * too big in both cases). + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Access_Frame( STREAM_ARGS FRAME_ARGS Long size ) + { + TT_Error error; + + + if ( CUR_Frame.address != NULL ) + return TT_Err_Nested_Frame_Access; + + if ( ALLOC( CUR_Frame.address, size ) ) + return error; + CUR_Frame.size = size; + + error = TT_Read_File( STREAM_VARS (void*)CUR_Frame.address, size ); + if ( error ) + { + FREE( CUR_Frame.address ); + CUR_Frame.size = 0; + } + + CUR_Frame.cursor = CUR_Frame.address; + return error; + } + + +/******************************************************************* + * + * Function : TT_Check_And_Access_Frame + * + * Description : Notifies the component that we're going to read + * `size' bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx + * functions easily. + * + * Input : size number of bytes to access. + * + * Output : SUCCESS on success. FAILURE on error. + * + * Notes: The function truncates `size' if the byte range is not + * within the file. + * + * It will fail if there is not enough memory to cache + * the bytes properly (which usually means that `size' is + * too big). + * + * It will fail if you make two consecutive calls + * to TT_Access_Frame(), without a TT_Forget_Frame() between + * them. + * + * The only difference with TT_Access_Frame() is that we + * check that the frame is within the current file. We + * otherwise truncate it. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Check_And_Access_Frame( STREAM_ARGS FRAME_ARGS Long size ) + { + TT_Error error; + Long readBytes; + + + if ( CUR_Frame.address != NULL ) + return TT_Err_Nested_Frame_Access; + + if ( ALLOC( CUR_Frame.address, size ) ) + return error; + CUR_Frame.size = size; + + readBytes = CUR_Stream->size - TT_File_Pos( STREAM_VAR ); + if ( size > readBytes ) + size = readBytes; + + error = TT_Read_File( STREAM_VARS (void*)CUR_Frame.address, size ); + if ( error ) + { + FREE( CUR_Frame.address ); + CUR_Frame.size = 0; + } + + CUR_Frame.cursor = CUR_Frame.address; + return error; + } + + +/******************************************************************* + * + * Function : TT_Forget_Frame + * + * Description : Releases a cached frame after reading. + * + * Input : None + * + * Output : SUCCESS on success. FAILURE on error. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Forget_Frame( FRAME_ARG ) + { + if ( CUR_Frame.address == NULL ) + return TT_Err_Nested_Frame_Access; + + FREE( CUR_Frame.address ); + ZERO_Frame( CUR_Frame ); + + return TT_Err_Ok; + } + +#endif /* TT_CONFIG_OPTION_THREAD_SAFE */ + + + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + /*********** ***********/ + /*********** C O M M O N I M P L E M E N T A T I O N ***********/ + /*********** ***********/ + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + +/******************************************************************* + * + * Function : Stream_Activate + * + * Description : activates a stream, this will either: + * - open a new file handle if the stream is closed + * - move the stream to the head of the linked list + * + * Input : stream the stream to activate + * + * Output : error condition. + * + * Note : This function is also called with fresh new streams + * created by TT_Open_Stream(). They have their 'size' + * field set to -1. + * + ******************************************************************/ + + static TT_Error Stream_Activate( PStream_Rec stream ) + { + if ( !stream->opened ) + { + if ( (stream->file = fopen( (TT_Text*)stream->name, "rb" )) == 0 ) + return TT_Err_Could_Not_ReOpen_File; + + stream->opened = TRUE; + + /* A newly created stream has a size field of -1 */ + if ( stream->size < 0 ) + { + fseek( stream->file, 0, SEEK_END ); + stream->size = ftell( stream->file ); + fseek( stream->file, 0, SEEK_SET ); + } + + /* Reset cursor in file */ + if ( stream->position ) + { + if ( fseek( stream->file, stream->position, SEEK_SET ) != 0 ) + { + /* error during seek */ + fclose( stream->file ); + stream->opened = FALSE; + return TT_Err_Could_Not_ReSeek_File; + } + } + } + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Stream_DeActivate + * + * Description : deactivates a stream, this will : + * - close its file handle if it was opened + * - remove it from the opened list if necessary + * + * Input : stream the stream to deactivate + * + * Output : Error condition + * + * Note : the function is called whenever a stream is deleted + * (_not_ when a stream handle's is closed due to an + * activation). However, the stream record isn't + * destroyed by it.. + * + ******************************************************************/ + + static TT_Error Stream_Deactivate( PStream_Rec stream ) + { + if ( stream->opened ) + { + /* Save its current position within the file */ + stream->position = ftell( stream->file ); + fclose( stream->file ); + stream->file = 0; + stream->opened = FALSE; + } + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Stream_Size + * + * Description : Returns the length of a given stream, even if it + * is flushed. + * + * Input : stream the stream + * + * Output : Length of stream in bytes. + * + ******************************************************************/ + + EXPORT_FUNC + Long TT_Stream_Size( TT_Stream stream ) + { + PStream_Rec rec = STREAM2REC( stream ); + + + if ( rec ) + return rec->size; + else + return 0; /* invalid stream - return 0 */ + } + + +/******************************************************************* + * + * Function : TT_Open_Stream + * + * Description : Opens the font file and saves the total file size. + * + * Input : error address of stream's error variable + * (re-entrant build only) + * filepathname pathname of the file to open + * stream address of target TT_Stream structure + * + * Output : SUCCESS on sucess, FAILURE on error. + * The target stream is set to -1 in case of failure. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TT_Open_Stream( const TT_Text* filepathname, + TT_Stream* stream ) + { + Int len; + TT_Error error; + PStream_Rec stream_rec; + + if ( ALLOC( *stream, sizeof ( TStream_Rec ) ) ) + return error; + + stream_rec = STREAM2REC( *stream ); + + stream_rec->file = NULL; + stream_rec->size = -1L; + stream_rec->base = 0; + stream_rec->opened = FALSE; + stream_rec->position = 0; + + len = strlen( filepathname ) + 1; + if ( ALLOC( stream_rec->name, len ) ) + goto Fail; + + strncpy( stream_rec->name, filepathname, len ); + + error = Stream_Activate( stream_rec ); + if ( error ) + goto Fail_Activate; + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + CUR_Stream = stream_rec; +#endif + + return TT_Err_Ok; + + Fail_Activate: + FREE( stream_rec->name ); + Fail: + FREE( stream_rec ); + return error; + } + + +/******************************************************************* + * + * Function : TT_Close_Stream + * + * Description : Closes a stream. + * + * Input : stream address of target TT_Stream structure + * + * Output : SUCCESS (always). + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TT_Close_Stream( TT_Stream* stream ) + { + PStream_Rec rec = STREAM2REC( *stream ); + + + Stream_Deactivate( rec ); + FREE( rec->name ); + FREE( rec ); + + HANDLE_Set( *stream, NULL ); + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Flush_Stream + * + * Description : Flushes a stream, i.e., closes its file handle. + * + * Input : stream address of target TT_Stream structure + * + * Output : Error code + * + * NOTE : Never flush the current opened stream. This means that + * you should _never_ call this function between a + * TT_Use_Stream() and a TT_Done_Stream()! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Flush_Stream( TT_Stream* stream ) + { + PStream_Rec rec = STREAM2REC( *stream ); + + + if ( rec ) + { + Stream_Deactivate( rec ); + return TT_Err_Ok; + } + else + return TT_Err_Invalid_Argument; + } + + +/******************************************************************* + * + * Function : TT_Seek_File + * + * Description : Seeks the file cursor to a different position. + * + * Input : position new position in file + * + * Output : SUCCESS on success. FAILURE if out of range. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Seek_File( STREAM_ARGS Long position ) + { + position += CUR_Stream->base; + + if ( fseek( CUR_Stream->file, position, SEEK_SET ) ) + return TT_Err_Invalid_File_Offset; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Skip_File + * + * Description : Skips forward the file cursor. + * + * Input : distance number of bytes to skip + * + * Output : see TT_Seek_File() + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Skip_File( STREAM_ARGS Long distance ) + { + return TT_Seek_File( STREAM_VARS ftell( CUR_Stream->file ) - + CUR_Stream->base + distance ); + } + + +/******************************************************************* + * + * Function : TT_Read_File + * + * Description : Reads a chunk of the file and copies it to memory. + * + * Input : buffer target buffer + * count length in bytes to read + * + * Output : SUCCESS on success. FAILURE if out of range. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Read_File( STREAM_ARGS void* buffer, Long count ) + { + if ( fread( buffer, 1, count, CUR_Stream->file ) != (ULong)count ) + return TT_Err_Invalid_File_Read; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Read_At_File + * + * Description : Reads file at a specified position. + * + * Input : position position to seek to before read + * buffer target buffer + * count number of bytes to read + * + * Output : SUCCESS on success. FAILURE if error. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Read_At_File( STREAM_ARGS Long position, + void* buffer, + Long count ) + { + TT_Error error; + + + if ( (error = TT_Seek_File( STREAM_VARS position )) != TT_Err_Ok || + (error = TT_Read_File( STREAM_VARS buffer, count )) != TT_Err_Ok ) + return error; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_File_Pos + * + * Description : Returns current file seek pointer. + * + * Input : none + * + * Output : Current file position. + * + ******************************************************************/ + + EXPORT_FUNC + Long TT_File_Pos( STREAM_ARG ) + { + return ftell( CUR_Stream->file ) - CUR_Stream->base; + } + + +/******************************************************************* + * + * Function : GET_Byte + * + * Description : Extracts a byte from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted Byte. + * + ******************************************************************/ +#if 0 + EXPORT_FUNC + Byte TT_Get_Byte( FRAME_ARG ) + { + CHECK_FRAME( CUR_Frame, 1 ); + + return (Byte)(*CUR_Frame.cursor++); + } +#endif + + +/******************************************************************* + * + * Function : GET_Char + * + * Description : Extracts a signed byte from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted char. + * + ******************************************************************/ + EXPORT_FUNC + Char TT_Get_Char( FRAME_ARG ) + { + CHECK_FRAME( CUR_Frame, 1 ); + + return (Char)(*CUR_Frame.cursor++); + } + + +/******************************************************************* + * + * Function : GET_Short + * + * Description : Extracts a short from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted short. + * + ******************************************************************/ + + EXPORT_FUNC + Short TT_Get_Short( FRAME_ARG ) + { + Short getshort; + + + CHECK_FRAME( CUR_Frame, 2 ); + + getshort = (Short)((CUR_Frame.cursor[0] << 8) | + CUR_Frame.cursor[1]); + + CUR_Frame.cursor += 2; + + return getshort; + } + + +/******************************************************************* + * + * Function : GET_UShort + * + * Description : Extracts an unsigned short from the frame. + * + * Input : None or current frame + * + * Output : Extracted ushort. + * + ******************************************************************/ +#if 0 + EXPORT_FUNC + UShort TT_Get_UShort( FRAME_ARG ) + { + UShort getshort; + + + CHECK_FRAME( CUR_Frame, 2 ); + + getshort = (UShort)((CUR_Frame.cursor[0] << 8) | + CUR_Frame.cursor[1]); + + CUR_Frame.cursor += 2; + + return getshort; + } +#endif + + +/******************************************************************* + * + * Function : GET_Long + * + * Description : Extracts a long from the frame. + * + * Input : None or current frame + * + * Output : Extracted long. + * + ******************************************************************/ + + EXPORT_FUNC + Long TT_Get_Long( FRAME_ARG ) + { + Long getlong; + + + CHECK_FRAME( CUR_Frame, 4 ); + + getlong = ((Long)CUR_Frame.cursor[0] << 24) | + ((Long)CUR_Frame.cursor[1] << 16) | + ((Long)CUR_Frame.cursor[2] << 8 ) | + (Long)CUR_Frame.cursor[3]; + + CUR_Frame.cursor += 4; + + return getlong; + } + + +/******************************************************************* + * + * Function : GET_ULong + * + * Description : Extracts an unsigned long from the frame. + * + * Input : None or current frame + * + * Output : Extracted ulong. + * + ******************************************************************/ +#if 0 + EXPORT_FUNC + ULong TT_Get_ULong( FRAME_ARG ) + { + ULong getlong; + + + CHECK_FRAME( CUR_Frame, 4 ); + + getlong = ( ((ULong)CUR_Frame.cursor[0] << 24) | + ((ULong)CUR_Frame.cursor[1] << 16) | + ((ULong)CUR_Frame.cursor[2] << 8 ) | + (ULong)CUR_Frame.cursor[3] ); + + CUR_Frame.cursor += 4; + + return getlong; + } +#endif + + +/* END */ diff --git a/lib/ttfile.h b/lib/ttfile.h new file mode 100644 index 0000000..eebd1c1 --- /dev/null +++ b/lib/ttfile.h @@ -0,0 +1,271 @@ +/******************************************************************* + * + * ttfile.h 1.3 + * + * File I/O Component (specification). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * Changes between 1.3 and 1.2: + * + * - all functions report error values now + * + * - the stream semantics have also changed + * + * Changes between 1.2 and 1.1: + * + * - added macros to support re-entrant builds + * + * - added the TT_Duplicate_File function to duplicate streams + * (re-entrant builds only) + * + ******************************************************************/ + +#ifndef TTFILE_H +#define TTFILE_H + +#include "ttconfig.h" +#include "freetype.h" +#include "ttengine.h" +#include "ttdebug.h" + +#ifdef __cplusplus + extern "C" { +#endif + + /* Initialize file component */ + LOCAL_DEF + TT_Error TTFile_Init( PEngine_Instance engine ); + + /* Done with file component */ + LOCAL_DEF + TT_Error TTFile_Done( PEngine_Instance engine ); + + + /**********************************************************************/ + /* */ + /* Stream functions. */ + /* */ + /**********************************************************************/ + + /* Open a file and return a stream handle for it. */ + /* Should only be used for a new face object's main stream. */ + + LOCAL_DEF + TT_Error TT_Open_Stream( const TT_Text* name, + TT_Stream* stream ); + + + /* Closes, then discards, a stream when it's no longer needed. */ + /* Should only be used for a stream opend with TT_Open_Stream(). */ + + LOCAL_DEF + TT_Error TT_Close_Stream( TT_Stream* stream ); + + + /* Informs the component that we're going to use the file */ + /* opened in 'org_stream', and report errors to the 'error' */ + /* variable. */ + + /* in non re-entrant builds, 'org_stream' is simply copied */ + /* to 'stream'. Otherwise, the latter is a duplicate handle */ + /* for the file opened with 'org_stream' */ + + EXPORT_DEF + TT_Error TT_Use_Stream( TT_Stream org_stream, + TT_Stream* stream ); + + /* Informs the component that we don't need to perform file */ + /* operations on the stream 'stream' anymore. This must be */ + /* used with streams "opened" with TT_Use_Stream() only! */ + + /* in re-entrant builds, this will really discard the stream */ + + EXPORT_DEF + TT_Error TT_Done_Stream( TT_Stream* stream ); + + /* Closes the stream's file handle to release system resources */ + /* The function TT_Use_Stream automatically re-activates a */ + /* flushed stream when it uses one */ + + EXPORT_DEF + TT_Error TT_Flush_Stream( TT_Stream* stream ); + +/* The macros STREAM_ARGS and STREAM_ARG let us build a thread-safe */ +/* or re-entrant implementation depending on a single configuration */ +/*define. */ + +#ifdef TT_CONFIG_OPTION_THREAD_SAFE + +#define STREAM_ARGS TT_Stream stream, +#define STREAM_ARG TT_Stream stream + +#else + +#define STREAM_ARGS /* void */ +#define STREAM_ARG void + +#endif /* TT_CONFIG_OPTION_THREAD_SAFE */ + + + /****************************************************************/ + /* */ + /* File Functions. */ + /* */ + /* The following functions perform file operations on the */ + /* currently 'used' stream. In thread-safe builds, only one */ + /* stream can be used at a time. Synchronisation is performed */ + /* through the Use_Stream()/Done_Stream() functions. */ + /* */ + /****************************************************************/ + + /* Read 'count' bytes from file into 'buffer' */ + + EXPORT_DEF + TT_Error TT_Read_File( STREAM_ARGS void* buffer, + Long count ); + + + /* Seek file cursor to a given position */ + + EXPORT_DEF + TT_Error TT_Seek_File( STREAM_ARGS Long position ); + + + /* Skip the next 'distance' bytes in file */ + + EXPORT_DEF + TT_Error TT_Skip_File( STREAM_ARGS Long distance ); + + + /* Read the 'count' bytes at 'position' into 'buffer' */ + + EXPORT_DEF + TT_Error TT_Read_At_File( STREAM_ARGS Long position, + void* buffer, + Long count ); + + /* Return current file position */ + + EXPORT_DEF + Long TT_File_Pos( STREAM_ARG ); + + /* Return length of a given stream, even if it is flushed */ + + EXPORT_DEF + Long TT_Stream_Size( TT_Stream stream ); + + + /********************************************************************/ + /* */ + /* Frame operations. */ + /* */ + /* For a comprehensive explanation of frames, please refer to the */ + /* documentation files. */ + /* */ + /********************************************************************/ + + /* Frame type declaration.*/ + + struct TFileFrame_ + { + Byte* address; /* frame buffer */ + Byte* cursor; /* current cursor position in frame */ + Long size; /* frame size */ + }; + + typedef struct TFileFrame_ TFileFrame; + + EXPORT_DEF + const TFileFrame TT_Null_FileFrame; + + +/* The macro ZERO_Frame is used to define and init a frame. */ +/* It is important to have a default frame of { NULL, NULL, 0 } */ +/* before a call to TT_Access_Frame(). Otherwise, the call will */ +/* fail with a TT_Err_Nested_Frame_Accesses error. */ + +#define ZERO_Frame( frame ) \ + { \ + (frame).address = NULL; \ + (frame).cursor = NULL; \ + (frame).size = 0; \ + } + + +/* The macros FRAME_ARGS and FRAME_ARG let us build a thread-safe */ +/* or re-entrant implementation depending on a single configuration */ +/* define */ + +#ifdef TT_CONFIG_OPTION_THREAD_SAFE + +#define FRAME_ARGS TFileFrame* frame, +#define FRAME_ARG TFileFrame* frame + +#else + +#define FRAME_ARGS /* void */ +#define FRAME_ARG void + +#endif /* TT_CONFIG_OPTION_THREAD_SAFE */ + + + /* Access the next 'size' bytes from current position. */ + /* Fails if all bytes cannot be read/accessed. */ + + EXPORT_DEF + TT_Error TT_Access_Frame( STREAM_ARGS FRAME_ARGS Long size ); + + + /* Access the bytes located in the next 'size' bytes of the file. */ + /* Doesn't fail if less than 'size' bytes are accessible (like */ + /* at the end of the file). */ + + EXPORT_DEF + TT_Error TT_Check_And_Access_Frame( STREAM_ARGS FRAME_ARGS Long size ); + + /* Forget frame */ + + EXPORT_DEF + TT_Error TT_Forget_Frame( FRAME_ARG ); + + + /* primitive routines for data accessing */ + + EXPORT_DEF + Char TT_Get_Char ( FRAME_ARG ); + EXPORT_DEF + Short TT_Get_Short( FRAME_ARG ); + EXPORT_DEF + Long TT_Get_Long ( FRAME_ARG ); + +#ifdef TT_CONFIG_OPTION_THREAD_SAFE + +#define TT_Get_Byte( frame ) ( (Byte )TT_Get_Char ( frame ) ) +#define TT_Get_UShort( frame ) ( (UShort)TT_Get_Short( frame ) ) +#define TT_Get_ULong( frame ) ( (ULong )TT_Get_Long ( frame ) ) + +#else + +#define TT_Get_Byte() ( (Byte )TT_Get_Char () ) +#define TT_Get_UShort() ( (UShort)TT_Get_Short() ) +#define TT_Get_ULong() ( (ULong )TT_Get_Long () ) + +#endif /* TT_CONFIG_OPTION_THREAD_SAFE */ + + +#ifdef __cplusplus + } +#endif + +#endif /* TTFILE_H */ + + +/* END */ diff --git a/lib/ttgload.c b/lib/ttgload.c new file mode 100644 index 0000000..a7ca317 --- /dev/null +++ b/lib/ttgload.c @@ -0,0 +1,1351 @@ +/******************************************************************* + * + * ttgload.c 1.0 + * + * TrueType Glyph Loader. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include "tttypes.h" +#include "ttdebug.h" +#include "ttcalc.h" +#include "ttfile.h" + +#include "tttables.h" +#include "ttobjs.h" +#include "ttgload.h" + +#include "ttmemory.h" +#include "tttags.h" +#include "ttload.h" + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_gload + + +/* composite font flags */ + +#define ARGS_ARE_WORDS 0x001 +#define ARGS_ARE_XY_VALUES 0x002 +#define ROUND_XY_TO_GRID 0x004 +#define WE_HAVE_A_SCALE 0x008 +/* reserved 0x010 */ +#define MORE_COMPONENTS 0x020 +#define WE_HAVE_AN_XY_SCALE 0x040 +#define WE_HAVE_A_2X2 0x080 +#define WE_HAVE_INSTR 0x100 +#define USE_MY_METRICS 0x200 + + +/********************************************************/ +/* Return horizontal or vertical metrics in font units */ +/* for a given glyph. The metrics are the left side */ +/* bearing (resp. top side bearing) and advance width */ +/* (resp. advance height). */ +/* */ +/* This function will much probably move to another */ +/* component in the short future, but I haven't decided */ +/* which yet... */ + + LOCAL_FUNC + void TT_Get_Metrics( TT_Horizontal_Header* header, + UShort index, + Short* bearing, + UShort* advance ) + { + PLongMetrics longs_m; + + UShort k = header->number_Of_HMetrics; + + + if ( index < k ) + { + longs_m = (PLongMetrics)header->long_metrics + index; + *bearing = longs_m->bearing; + *advance = longs_m->advance; + } + else + { + *bearing = ((PShortMetrics)header->short_metrics)[index - k]; + *advance = ((PLongMetrics)header->long_metrics)[k - 1].advance; + } + } + + +/********************************************************/ +/* Return horizontal metrics in font units for a given */ +/* glyph. If `check' is true, take care of mono-spaced */ +/* fonts by returning the advance width max. */ + + static void Get_HMetrics( PFace face, + UShort index, + Bool check, + Short* lsb, + UShort* aw ) + { + TT_Get_Metrics( &face->horizontalHeader, index, lsb, aw ); + + if ( check && face->postscript.isFixedPitch ) + *aw = face->horizontalHeader.advance_Width_Max; + } + + +/********************************************************/ +/* Return advance width table for a given pixel size */ +/* if it is found in the font's `hdmx' table (if any). */ + + static PByte Get_Advance_Widths( PFace face, + UShort ppem ) + { + UShort n; + + + for ( n = 0; n < face->hdmx.num_records; n++ ) + if ( face->hdmx.records[n].ppem == ppem ) + return face->hdmx.records[n].widths; + + return NULL; + } + + +/********************************************************/ +/* Copy current glyph into original one. */ + +#define cur_to_org( n, zone ) \ + MEM_Copy( (zone)->org, (zone)->cur, (n) * sizeof ( TT_Vector ) ) + +/********************************************************/ +/* copy original glyph into current one */ + +#define org_to_cur( n, zone ) \ + MEM_Copy( (zone)->cur, (zone)->org, (n) * sizeof ( TT_Vector ) ) + +/********************************************************/ +/* translate an array of coordinates */ + + static void translate_array( UShort n, + TT_Vector* coords, + TT_Pos delta_x, + TT_Pos delta_y ) + { + UShort k; + + + if ( delta_x ) + for ( k = 0; k < n; k++ ) + coords[k].x += delta_x; + + if ( delta_y ) + for ( k = 0; k < n; k++ ) + coords[k].y += delta_y; + } + + +/********************************************************/ +/* mount one zone on top of another */ + + static void mount_zone( PGlyph_Zone source, + PGlyph_Zone target ) + { + UShort np; + Short nc; + + np = source->n_points; + nc = source->n_contours; + + target->org = source->org + np; + target->cur = source->cur + np; + target->touch = source->touch + np; + + target->contours = source->contours + nc; + + target->n_points = 0; + target->n_contours = 0; + } + + +/******************************************************************* + * + * Function: Load_Simple_Glyph + * + ******************************************************************/ + + static TT_Error Load_Simple_Glyph( PExecution_Context exec, + TT_Stream input, + Short n_contours, + Short left_contours, + UShort left_points, + UShort load_flags, + PSubglyph_Record subg ) + { + DEFINE_LOAD_LOCALS( input ); + + PGlyph_Zone pts; + Short k; + UShort j; + UShort n_points, n_ins; + PFace face; + Byte* flag; + TT_Vector* vec; + TT_F26Dot6 x, y; + + + face = exec->face; + + /* simple check */ + if ( n_contours > left_contours ) + { + PTRACE0(( "ERROR: Glyph index %ld has %d contours > left %d\n", + subg->index, n_contours, left_contours )); + return TT_Err_Too_Many_Contours; + } + + + /* preparing the execution context */ + mount_zone( &subg->zone, &exec->pts ); + + /* reading the contours endpoints */ + if ( ACCESS_Frame( (n_contours + 1) * 2L ) ) + return error; + + PTRACE4(( " Contour endpoints:" )); + + for ( k = 0; k < n_contours; k++ ) + { + exec->pts.contours[k] = GET_UShort(); + PTRACE4(( " %d", exec->pts.contours[k] )); + } + PTRACE4(( "\n" )); + + if ( n_contours > 0 ) + n_points = exec->pts.contours[n_contours - 1] + 1; + else + n_points = 0; + + n_ins = GET_UShort(); + + FORGET_Frame(); + + if ( n_points > left_points ) + { + PTRACE0(( "ERROR: Too many points in glyph %ld\n", subg->index )); + return TT_Err_Too_Many_Points; + } + + /* loading instructions */ + + PTRACE4(( " Instructions size: %d\n", n_ins )); + + if ( n_ins > face->maxProfile.maxSizeOfInstructions ) + { + PTRACE0(( "ERROR: Too many instructions!\n" )); + return TT_Err_Too_Many_Ins; + } + + if ( FILE_Read( exec->glyphIns, n_ins ) ) + return error; + + if ( (error = Set_CodeRange( exec, + TT_CodeRange_Glyph, + exec->glyphIns, + n_ins )) != TT_Err_Ok ) + return error; + + + /* read the flags */ + + if ( CHECK_ACCESS_Frame( n_points * 5L ) ) + return error; + + j = 0; + flag = exec->pts.touch; + + while ( j < n_points ) + { + Byte c, cnt; + + flag[j] = c = GET_Byte(); + j++; + + if ( c & 8 ) + { + cnt = GET_Byte(); + while( cnt > 0 ) + { + flag[j++] = c; + cnt--; + } + } + } + + /* read the X */ + + x = 0; + vec = exec->pts.org; + + for ( j = 0; j < n_points; j++ ) + { + if ( flag[j] & 2 ) + { + if ( flag[j] & 16 ) + x += GET_Byte(); + else + x -= GET_Byte(); + } + else + { + if ( (flag[j] & 16) == 0 ) + x += GET_Short(); + } + + vec[j].x = x; + } + + + /* read the Y */ + + y = 0; + + for ( j = 0; j < n_points; j++ ) + { + if ( flag[j] & 4 ) + { + if ( flag[j] & 32 ) + y += GET_Byte(); + else + y -= GET_Byte(); + } + else + { + if ( (flag[j] & 32) == 0 ) + y += GET_Short(); + } + + vec[j].y = y; + } + + FORGET_Frame(); + + /* Now add the two shadow points at n and n + 1. */ + /* We need the left side bearing and advance width. */ + + /* pp1 = xMin - lsb */ + vec[n_points].x = subg->metrics.bbox.xMin - subg->metrics.horiBearingX; + vec[n_points].y = 0; + + /* pp2 = pp1 + aw */ + vec[n_points+1].x = vec[n_points].x + subg->metrics.horiAdvance; + vec[n_points+1].y = 0; + + /* clear the touch flags */ + + for ( j = 0; j < n_points; j++ ) + exec->pts.touch[j] &= TT_Flag_On_Curve; + + exec->pts.touch[n_points ] = 0; + exec->pts.touch[n_points + 1] = 0; + + /* Note that we return two more points that are not */ + /* part of the glyph outline. */ + + n_points += 2; + + /* now eventually scale and hint the glyph */ + + pts = &exec->pts; + pts->n_points = n_points; + pts->n_contours = n_contours; + + if ( (load_flags & TTLOAD_SCALE_GLYPH) == 0 ) + { + /* no scaling, just copy the orig arrays into the cur ones */ + org_to_cur( n_points, pts ); + } + else + { + /* first scale the glyph points */ + + for ( j = 0; j < n_points; j++ ) + { + pts->org[j].x = Scale_X( &exec->metrics, pts->org[j].x ); + pts->org[j].y = Scale_Y( &exec->metrics, pts->org[j].y ); + } + + /* if hinting, round pp1, and shift the glyph accordingly */ + if ( subg->is_hinted ) + { + x = pts->org[n_points - 2].x; + x = ((x+32) & -64) - x; + translate_array( n_points, pts->org, x, 0 ); + + org_to_cur( n_points, pts ); + + pts->cur[n_points - 1].x = (pts->cur[n_points - 1].x + 32) & -64; + + /* now consider hinting */ + if ( n_ins > 0 ) + { + exec->is_composite = FALSE; + exec->pedantic_hinting = load_flags & TTLOAD_PEDANTIC; + + error = Context_Run( exec, FALSE ); + if (error && exec->pedantic_hinting) + return error; + } + } + else + org_to_cur( n_points, pts ); + } + + /* save glyph phantom points */ + if (!subg->preserve_pps) + { + subg->pp1 = pts->cur[n_points - 2]; + subg->pp2 = pts->cur[n_points - 1]; + } + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_Composite_End + * + ******************************************************************/ + + static + TT_Error Load_Composite_End( UShort n_points, + Short n_contours, + PExecution_Context exec, + PSubglyph_Record subg, + UShort load_flags, + TT_Stream input ) + { + DEFINE_LOAD_LOCALS( input ); + + UShort k, n_ins; + PGlyph_Zone pts; + + + if ( subg->is_hinted && + subg->element_flag & WE_HAVE_INSTR ) + { + if ( ACCESS_Frame( 2L ) ) + return error; + + n_ins = GET_UShort(); /* read size of instructions */ + FORGET_Frame(); + + PTRACE4(( " Instructions size: %d\n", n_ins )); + + if ( n_ins > exec->face->maxProfile.maxSizeOfInstructions ) + { + PTRACE0(( "ERROR: Too many instructions in composite glyph %ld\n", + subg->index )); + return TT_Err_Too_Many_Ins; + } + + if ( FILE_Read( exec->glyphIns, n_ins ) ) + return error; + + error = Set_CodeRange( exec, + TT_CodeRange_Glyph, + exec->glyphIns, + n_ins ); + + if ( error ) + return error; + } + else + n_ins = 0; + + + /* prepare the execution context */ + n_points += 2; + exec->pts = subg->zone; + pts = &exec->pts; + + pts->n_points = n_points; + pts->n_contours = n_contours; + + /* add phantom points */ + pts->cur[n_points - 2] = subg->pp1; + pts->cur[n_points - 1] = subg->pp2; + + pts->touch[n_points - 1] = 0; + pts->touch[n_points - 2] = 0; + + /* if hinting, round the phantom points */ + if ( subg->is_hinted ) + { + pts->cur[n_points - 2].x = (subg->pp1.x + 32) & -64; + pts->cur[n_points - 1].x = (subg->pp2.x + 32) & -64; + } + + for ( k = 0; k < n_points; k++ ) + pts->touch[k] &= TT_Flag_On_Curve; + + cur_to_org( n_points, pts ); + + /* now consider hinting */ + if ( subg->is_hinted && n_ins > 0 ) + { + exec->is_composite = TRUE; + exec->pedantic_hinting = load_flags & TTLOAD_PEDANTIC; + + error = Context_Run( exec, FALSE ); + if (error && exec->pedantic_hinting) + return error; + } + + /* save glyph origin and advance points */ + subg->pp1 = pts->cur[n_points - 2]; + subg->pp2 = pts->cur[n_points - 1]; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Init_Glyph_Component + * + ******************************************************************/ + + static + void Init_Glyph_Component( PSubglyph_Record element, + PSubglyph_Record original, + PExecution_Context exec ) + { + element->index = -1; + element->is_scaled = FALSE; + element->is_hinted = FALSE; + + if ( original ) + mount_zone( &original->zone, &element->zone ); + else + element->zone = exec->pts; + + element->zone.n_contours = 0; + element->zone.n_points = 0; + + element->arg1 = 0; + element->arg2 = 0; + + element->element_flag = 0; + element->preserve_pps = FALSE; + + element->transform.xx = 1L << 16; + element->transform.xy = 0; + element->transform.yx = 0; + element->transform.yy = 1L << 16; + + element->transform.ox = 0; + element->transform.oy = 0; + + element->metrics.horiBearingX = 0; + element->metrics.horiAdvance = 0; + } + + + + LOCAL_FUNC + TT_Error Load_TrueType_Glyph( PInstance instance, + PGlyph glyph, + UShort glyph_index, + UShort load_flags ) + { + enum TPhases_ + { + Load_Exit, + Load_Glyph, + Load_Header, + Load_Simple, + Load_Composite, + Load_End + }; + + typedef enum TPhases_ TPhases; + + DEFINE_ALL_LOCALS; + + PFace face; + + UShort num_points; + Short num_contours; + UShort left_points; + Short left_contours; + UShort num_elem_points; + + Long table; + UShort load_top; + Long k, l; + UShort new_flags; + Long index; + UShort u, v; + + Long glyph_offset, offset; + + TT_F26Dot6 x, y, nx, ny; + + Fixed xx, xy, yx, yy; + + PExecution_Context exec; + + PSubglyph_Record subglyph, subglyph2; + + TGlyph_Zone base_pts; + + TPhases phase; + PByte widths; + +/* TT_Glyph_Loader_Callback cacheCb; */ +/* TT_Outline cached_outline; */ + + + /* first of all, check arguments */ + if ( !glyph ) + return TT_Err_Invalid_Glyph_Handle; + + face = glyph->face; + if ( !face ) + return TT_Err_Invalid_Glyph_Handle; + + if ( glyph_index >= face->numGlyphs ) + return TT_Err_Invalid_Glyph_Index; + + if ( instance && (load_flags & TTLOAD_SCALE_GLYPH) == 0 ) + { + instance = 0; + load_flags &= ~( TTLOAD_SCALE_GLYPH | TTLOAD_HINT_GLYPH ); + } + + table = TT_LookUp_Table( face, TTAG_glyf ); + if ( table < 0 ) + { + PTRACE0(( "ERROR: There is no glyph table in this font file!\n" )); + return TT_Err_Glyf_Table_Missing; + } + + glyph_offset = face->dirTables[table].Offset; + + /* query new execution context */ + + if ( instance && instance->debug ) + exec = instance->context; + else + exec = New_Context( face ); + + if ( !exec ) + return TT_Err_Could_Not_Find_Context; + + Context_Load( exec, face, instance ); + + if ( instance ) + { + if ( instance->GS.instruct_control & 2 ) + exec->GS = Default_GraphicsState; + else + exec->GS = instance->GS; + /* load default graphics state */ + + glyph->outline.high_precision = ( instance->metrics.y_ppem < 24 ); + } + + /* save its critical pointers, as they'll be modified during load */ + base_pts = exec->pts; + + /* init variables */ + left_points = face->maxPoints; + left_contours = face->maxContours; + + num_points = 0; + num_contours = 0; + + load_top = 0; + subglyph = exec->loadStack; + + Init_Glyph_Component( subglyph, NULL, exec ); + + subglyph->index = glyph_index; + subglyph->is_hinted = load_flags & TTLOAD_HINT_GLYPH; + + /* when the cvt program has disabled hinting, the argument */ + /* is ignored. */ + if ( instance && instance->GS.instruct_control & 1 ) + subglyph->is_hinted = FALSE; + + + /* now access stream */ + + if ( USE_Stream( face->stream, stream ) ) + goto Fin; + + /* Main loading loop */ + + phase = Load_Glyph; + index = 0; + + while ( phase != Load_Exit ) + { + subglyph = exec->loadStack + load_top; + + switch ( phase ) + { + /************************************************************/ + /* */ + /* Load_Glyph state */ + /* */ + /* reading a glyph's generic header to determine */ + /* whether it's simple or composite */ + /* */ + /* exit states: Load_Header and Load_End */ + + case Load_Glyph: + /* check glyph index and table */ + + index = subglyph->index; + if ( index < 0 || index >= face->numGlyphs ) + { + error = TT_Err_Invalid_Glyph_Index; + goto Fail; + } + + /* get horizontal metrics */ + + { + Short left_bearing; + UShort advance_width; + + + Get_HMetrics( face, (UShort)index, + !(load_flags & TTLOAD_IGNORE_GLOBAL_ADVANCE_WIDTH), + &left_bearing, + &advance_width ); + + subglyph->metrics.horiBearingX = left_bearing; + subglyph->metrics.horiAdvance = advance_width; + } + + phase = Load_Header; + + + /* The cache callback isn't part of the FreeType release yet */ + /* It is discarded for the moment.. */ + /* */ +#if 0 + if ( instance ) + { + /* is the glyph in an outline cache ? */ + cacheCb = instance->owner->engine->glCallback; + if ( cacheCb && 0 ) /* disabled */ + { + /* we have a callback */ + error = cacheCb( instance->generic, + index, &cached_outline, &x, &y ); + if ( !error ) + { + /* no error, then append the outline to the current subglyph */ + /* error = Append_Outline( subglyph, + &left_points, + &left_contours, + &cached_outline ); */ + phase = Load_End; + } + } + } +#endif + break; + + + /************************************************************/ + /* */ + /* Load_Header state */ + /* */ + /* reading a glyph's generic header to determine */ + /* wether it's simple or composite */ + /* */ + /* exit states: Load_Simple and Load_Composite */ + /* */ + + case Load_Header: /* load glyph */ + + if ( index + 1 < face->numLocations && + face->glyphLocations[index] == face->glyphLocations[index + 1] ) + { + /* as described by Frederic Loyer, these are spaces, and */ + /* not the unknown glyph. */ + + num_contours = 0; + num_points = 0; + + subglyph->metrics.bbox.xMin = 0; + subglyph->metrics.bbox.xMax = 0; + subglyph->metrics.bbox.yMin = 0; + subglyph->metrics.bbox.yMax = 0; + + subglyph->pp1.x = 0; + subglyph->pp2.x = subglyph->metrics.horiAdvance; + if (load_flags & TTLOAD_SCALE_GLYPH) + subglyph->pp2.x = Scale_X( &exec->metrics, subglyph->pp2.x ); + + exec->glyphSize = 0; + phase = Load_End; + break; + } + + offset = glyph_offset + face->glyphLocations[index]; + + /* read first glyph header */ + if ( FILE_Seek( offset ) || + ACCESS_Frame( 10L ) ) + goto Fail_File; + + num_contours = GET_Short(); + + subglyph->metrics.bbox.xMin = GET_Short(); + subglyph->metrics.bbox.yMin = GET_Short(); + subglyph->metrics.bbox.xMax = GET_Short(); + subglyph->metrics.bbox.yMax = GET_Short(); + + FORGET_Frame(); + + PTRACE6(( "Glyph %ld:\n", index )); + PTRACE6(( " # of contours: %d\n", num_contours )); + PTRACE6(( " xMin: %4d xMax: %4d\n", + subglyph->metrics.bbox.xMin, + subglyph->metrics.bbox.xMax )); + PTRACE6(( " yMin: %4d yMax: %4d\n", + subglyph->metrics.bbox.yMin, + subglyph->metrics.bbox.yMax )); + + if ( num_contours > left_contours ) + { + PTRACE0(( "ERROR: Too many contours for glyph %ld\n", index )); + error = TT_Err_Too_Many_Contours; + goto Fail; + } + + subglyph->pp1.x = subglyph->metrics.bbox.xMin - + subglyph->metrics.horiBearingX; + subglyph->pp1.y = 0; + subglyph->pp2.x = subglyph->pp1.x + subglyph->metrics.horiAdvance; + if (load_flags & TTLOAD_SCALE_GLYPH) + { + subglyph->pp1.x = Scale_X( &exec->metrics, subglyph->pp1.x ); + subglyph->pp2.x = Scale_X( &exec->metrics, subglyph->pp2.x ); + } + + /* is it a simple glyph ? */ + if ( num_contours > 0 ) + phase = Load_Simple; + else + phase = Load_Composite; + + break; + + + /************************************************************/ + /* */ + /* Load_Simple state */ + /* */ + /* reading a simple glyph (num_contours must be set to */ + /* the glyph's number of contours.) */ + /* */ + /* exit states : Load_End */ + /* */ + + case Load_Simple: + new_flags = load_flags; + + /* disable hinting when scaling */ + if ( !subglyph->is_hinted ) + new_flags &= ~TTLOAD_HINT_GLYPH; + + error = Load_Simple_Glyph( exec, + stream, + num_contours, + left_contours, + left_points, + new_flags, + subglyph ); + if ( error ) + goto Fail; + + /* Note: We could have put the simple loader source there */ + /* but the code is fat enough already :-) */ + + num_points = exec->pts.n_points - 2; + + phase = Load_End; + + break; + + + /************************************************************/ + /* */ + /* Load_Composite state */ + /* */ + /* reading a composite glyph header a pushing a new */ + /* load element on the stack. */ + /* */ + /* exit states: Load_Glyph */ + /* */ + + case Load_Composite: + + /* create a new element on the stack */ + load_top++; + + if ( load_top > face->maxComponents ) + { + error = TT_Err_Invalid_Composite; + goto Fail; + } + + subglyph2 = exec->loadStack + load_top; + + Init_Glyph_Component( subglyph2, subglyph, NULL ); + subglyph2->is_hinted = subglyph->is_hinted; + + /* now read composite header */ + + if ( ACCESS_Frame( 4L ) ) + goto Fail_File; + + subglyph->element_flag = new_flags = GET_UShort(); + + subglyph2->index = GET_UShort(); + + FORGET_Frame(); + + k = 1 + 1; + + if ( new_flags & ARGS_ARE_WORDS ) + k *= 2; + + if ( new_flags & WE_HAVE_A_SCALE ) + k += 2; + + else if ( new_flags & WE_HAVE_AN_XY_SCALE ) + k += 4; + + else if ( new_flags & WE_HAVE_A_2X2 ) + k += 8; + + if ( ACCESS_Frame( k ) ) + goto Fail_File; + + if ( new_flags & ARGS_ARE_WORDS ) + { + k = GET_Short(); + l = GET_Short(); + } + else + { + k = GET_Char(); + l = GET_Char(); + } + + subglyph->arg1 = k; + subglyph->arg2 = l; + + if ( new_flags & ARGS_ARE_XY_VALUES ) + { + subglyph->transform.ox = k; + subglyph->transform.oy = l; + } + + xx = 1L << 16; + xy = 0; + yx = 0; + yy = 1L << 16; + + if ( new_flags & WE_HAVE_A_SCALE ) + { + xx = (Fixed)GET_Short() << 2; + yy = xx; + subglyph2->is_scaled = TRUE; + } + else if ( new_flags & WE_HAVE_AN_XY_SCALE ) + { + xx = (Fixed)GET_Short() << 2; + yy = (Fixed)GET_Short() << 2; + subglyph2->is_scaled = TRUE; + } + else if ( new_flags & WE_HAVE_A_2X2 ) + { + xx = (Fixed)GET_Short() << 2; + xy = (Fixed)GET_Short() << 2; + yx = (Fixed)GET_Short() << 2; + yy = (Fixed)GET_Short() << 2; + subglyph2->is_scaled = TRUE; + } + + FORGET_Frame(); + + subglyph->transform.xx = xx; + subglyph->transform.xy = xy; + subglyph->transform.yx = yx; + subglyph->transform.yy = yy; + + k = TT_MulFix( xx, yy ) - TT_MulFix( xy, yx ); + + /* disable hinting in case of scaling/slanting */ + if ( ABS( k ) != (1L << 16) ) + subglyph2->is_hinted = FALSE; + + subglyph->file_offset = FILE_Pos(); + + phase = Load_Glyph; + + break; + + + /************************************************************/ + /* */ + /* Load_End state */ + /* */ + /* after loading a glyph, apply transformation and offset */ + /* where necessary, pops element and continue or */ + /* stop process. */ + /* */ + /* exit states : Load_Composite and Load_Exit */ + /* */ + + case Load_End: + if ( load_top > 0 ) + { + subglyph2 = subglyph; + + load_top--; + subglyph = exec->loadStack + load_top; + + /* check advance width and left side bearing */ + + if ( !subglyph->preserve_pps && + subglyph->element_flag & USE_MY_METRICS ) + { + subglyph->metrics.horiBearingX = subglyph2->metrics.horiBearingX; + subglyph->metrics.horiAdvance = subglyph2->metrics.horiAdvance; + + subglyph->pp1 = subglyph2->pp1; + subglyph->pp2 = subglyph2->pp2; + + subglyph->preserve_pps = TRUE; + } + + /* apply scale */ + + if ( subglyph2->is_scaled ) + { + TT_Vector* cur = subglyph2->zone.cur; + TT_Vector* org = subglyph2->zone.org; + + for ( u = 0; u < num_points; u++ ) + { + nx = TT_MulFix( cur->x, subglyph->transform.xx ) + + TT_MulFix( cur->y, subglyph->transform.yx ); + + ny = TT_MulFix( cur->x, subglyph->transform.xy ) + + TT_MulFix( cur->y, subglyph->transform.yy ); + + cur->x = nx; + cur->y = ny; + + nx = TT_MulFix( org->x, subglyph->transform.xx ) + + TT_MulFix( org->y, subglyph->transform.yx ); + + ny = TT_MulFix( org->x, subglyph->transform.xy ) + + TT_MulFix( org->y, subglyph->transform.yy ); + + org->x = nx; + org->y = ny; + + cur++; + org++; + } + } + + /* adjust counts */ + + num_elem_points = subglyph->zone.n_points; + + for ( k = 0; k < num_contours; k++ ) + subglyph2->zone.contours[k] += num_elem_points; + + subglyph->zone.n_points += num_points; + subglyph->zone.n_contours += num_contours; + + left_points -= num_points; + left_contours -= num_contours; + + if ( !(subglyph->element_flag & ARGS_ARE_XY_VALUES) ) + { + /* move second glyph according to control points */ + /* the attach points are relative to the specific component */ + + u = (UShort)subglyph->arg1; + v = (UShort)subglyph->arg2; + + if ( u >= num_elem_points || + v >= num_points ) + { + error = TT_Err_Invalid_Composite; + goto Fail; + } + + /* adjust count */ + v += num_elem_points; + + x = subglyph->zone.cur[u].x - subglyph->zone.cur[v].x; + y = subglyph->zone.cur[u].y - subglyph->zone.cur[v].y; + } + else + { + /* apply offset */ + + x = subglyph->transform.ox; + y = subglyph->transform.oy; + + if ( load_flags & TTLOAD_SCALE_GLYPH ) + { + x = Scale_X( &exec->metrics, x ); + y = Scale_Y( &exec->metrics, y ); + + if ( subglyph->element_flag & ROUND_XY_TO_GRID ) + { + x = (x+32) & -64; + y = (y+32) & -64; + } + } + } + + translate_array( num_points, subglyph2->zone.cur, x, y ); + + cur_to_org( num_points, &subglyph2->zone ); + + num_points = subglyph->zone.n_points; + num_contours = subglyph->zone.n_contours; + + /* check for last component */ + + if ( FILE_Seek( subglyph->file_offset ) ) + goto Fail_File; + + if ( subglyph->element_flag & MORE_COMPONENTS ) + phase = Load_Composite; + else + { + error = Load_Composite_End( num_points, + num_contours, + exec, + subglyph, + load_flags, + stream ); + if ( error ) + goto Fail; + + phase = Load_End; + } + } + else + phase = Load_Exit; + + break; + + + case Load_Exit: + break; + } + } + + /* finally, copy the points arrays to the glyph object */ + + exec->pts = base_pts; + + for ( u = 0; u < num_points + 2; u++ ) + { + glyph->outline.points[u] = exec->pts.cur[u]; + glyph->outline.flags [u] = exec->pts.touch[u]; + } + + for ( k = 0; k < num_contours; k++ ) + glyph->outline.contours[k] = exec->pts.contours[k]; + + glyph->outline.n_points = num_points; + glyph->outline.n_contours = num_contours; + glyph->outline.second_pass = TRUE; + + /* translate array so that (0,0) is the glyph's origin */ + translate_array( num_points + 2, + glyph->outline.points, + -subglyph->pp1.x, + 0 ); + + TT_Get_Outline_BBox( &glyph->outline, &glyph->metrics.bbox ); + + if ( subglyph->is_hinted ) + { + /* grid-fit the bounding box */ + glyph->metrics.bbox.xMin &= -64; + glyph->metrics.bbox.yMin &= -64; + glyph->metrics.bbox.xMax = (glyph->metrics.bbox.xMax+63) & -64; + glyph->metrics.bbox.yMax = (glyph->metrics.bbox.yMax+63) & -64; + } + + /* get the device-independent scaled horizontal metrics */ + /* take care of fixed-pitch fonts... */ + { + TT_Pos left_bearing; + TT_Pos advance; + + + left_bearing = subglyph->metrics.horiBearingX; + advance = subglyph->metrics.horiAdvance; + + if ( face->postscript.isFixedPitch ) + advance = face->horizontalHeader.advance_Width_Max; + + if ( load_flags & TTLOAD_SCALE_GLYPH ) + { + left_bearing = Scale_X( &exec->metrics, left_bearing ); + advance = Scale_X( &exec->metrics, advance ); + } + + glyph->metrics.linearHoriBearingX = left_bearing; + glyph->metrics.linearHoriAdvance = advance; + } + + glyph->metrics.horiBearingX = glyph->metrics.bbox.xMin; + glyph->metrics.horiBearingY = glyph->metrics.bbox.yMax; + glyph->metrics.horiAdvance = subglyph->pp2.x - subglyph->pp1.x; + + /* Now take care of vertical metrics. In the case where there is */ + /* no vertical information within the font (relatively common), make */ + /* up some metrics `by hand' ... */ + + { + Short top_bearing; /* vertical top side bearing (EM units) */ + UShort advance_height; /* vertical advance height (EM units) */ + + TT_Pos left; /* scaled vertical left side bearing */ + TT_Pos Top; /* scaled original vertical top side bearing */ + TT_Pos top; /* scaled vertical top side bearing */ + TT_Pos advance; /* scaled vertical advance height */ + + + /* Get the unscaled `tsb' and `ah' values */ + if ( face->verticalInfo && + face->verticalHeader.number_Of_VMetrics > 0 ) + { + /* Don't assume that both the vertical header and vertical */ + /* metrics are present in the same font :-) */ + + TT_Get_Metrics( (TT_Horizontal_Header*)&face->verticalHeader, + glyph_index, + &top_bearing, + &advance_height ); + } + else + { + /* Make up the distances from the horizontal header.. */ + + /* NOTE: The OS/2 values are the only `portable' ones, */ + /* which is why we use them... */ + /* */ + /* NOTE2: The sTypoDescender is negative, which is why */ + /* we compute the baseline-to-baseline distance */ + /* here with : */ + /* ascender - descender + linegap */ + /* */ + top_bearing = (Short) (face->os2.sTypoLineGap / 2); + advance_height = (UShort)(face->os2.sTypoAscender - + face->os2.sTypoDescender + + face->os2.sTypoLineGap); + } + + /* We must adjust the top_bearing value from the bounding box given + in the glyph header to te bounding box calculated with + TT_Get_Outline_BBox() */ + + /* scale the metrics */ + if ( load_flags & TTLOAD_SCALE_GLYPH ) + { + Top = Scale_Y( &exec->metrics, top_bearing ); + top = Scale_Y( &exec->metrics, + top_bearing + subglyph->metrics.bbox.yMax ) - + glyph->metrics.bbox.yMax; + advance = Scale_Y( &exec->metrics, advance_height ); + } + else + { + Top = top_bearing; + top = top_bearing + subglyph->metrics.bbox.yMax - + glyph->metrics.bbox.yMax; + advance = advance_height; + } + + glyph->metrics.linearVertBearingY = Top; + glyph->metrics.linearVertAdvance = advance; + + /* XXX : for now, we have no better algo for the lsb, but it should */ + /* work ok.. */ + /* */ + left = ( glyph->metrics.bbox.xMin - glyph->metrics.bbox.xMax ) / 2; + + /* grid-fit them if necessary */ + if ( subglyph->is_hinted ) + { + left &= -64; + top = (top + 63) & -64; + advance = (advance + 32) & -64; + } + + glyph->metrics.vertBearingX = left; + glyph->metrics.vertBearingY = top; + glyph->metrics.vertAdvance = advance; + } + + /* Adjust advance width to the value contained in the hdmx table. */ + if ( !exec->face->postscript.isFixedPitch && instance && + subglyph->is_hinted ) + { + widths = Get_Advance_Widths( exec->face, + exec->instance->metrics.x_ppem ); + if ( widths ) + glyph->metrics.horiAdvance = widths[glyph_index] << 6; + } + + glyph->outline.dropout_mode = (Char)exec->GS.scan_type; + + error = TT_Err_Ok; + + Fail_File: + Fail: + DONE_Stream( stream ); + + Fin: + + /* reset the execution context */ + exec->pts = base_pts; + + if ( !instance || !instance->debug ) + Done_Context( exec ); + + return error; + } + + +/* END */ diff --git a/lib/ttgload.h b/lib/ttgload.h new file mode 100644 index 0000000..cfdfb2c --- /dev/null +++ b/lib/ttgload.h @@ -0,0 +1,51 @@ +/******************************************************************* + * + * ttgload.h 1.0 + * + * TrueType Glyph Loader. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef TTGLOAD_H +#define TTGLOAD_H + +#include "ttconfig.h" +#include "tttypes.h" +#include "ttobjs.h" + +#ifdef __cplusplus + extern "C" { +#endif + + + LOCAL_DEF + void TT_Get_Metrics( TT_Horizontal_Header* header, + UShort index, + Short* bearing, + UShort* advance ); + + + LOCAL_DEF + TT_Error Load_TrueType_Glyph( PInstance instance, + PGlyph glyph, + UShort glyph_index, + UShort load_flags ); + +#ifdef __cplusplus + } +#endif + + +#endif /* TTGLOAD_H */ + + +/* END */ diff --git a/lib/ttinterp.c b/lib/ttinterp.c new file mode 100644 index 0000000..9158fec --- /dev/null +++ b/lib/ttinterp.c @@ -0,0 +1,6654 @@ +/******************************************************************* + * + * ttinterp.c 3.1 + * + * TrueType bytecode intepreter. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * Changes between 3.1 and 3.0: + * + * - A more relaxed version of the interpreter. It is now able to + * ignore errors like out-of-bound array access and writes in order + * to silently support broken glyphs (even if the results are not + * always pretty). + * + * Note that one can use the flag TTLOAD_PEDANTIC to force + * TrueType-compliant interpretation. + * + * - A big #if used to completely disable the interpreter, which + * is due to the Apple patents issues which emerged recently. + * + ******************************************************************/ + +#include "freetype.h" +#include "tttypes.h" +#include "ttdebug.h" +#include "ttcalc.h" +#include "ttmemory.h" +#include "ttinterp.h" + + +#ifdef TT_CONFIG_OPTION_NO_INTERPRETER + + LOCAL_FUNC + TT_Error RunIns( PExecution_Context exc ) + { + /* do nothing - always successful */ + (void)exc; + return TT_Err_Ok; + } + +#else + + +#ifdef DEBUG_INTERPRETER +#include +#include "ttdebug.h" + +/* Define the `getch()' function. On Unix systems, it is an alias */ +/* for `getchar()', and the debugger front end must ensure that the */ +/* `stdin' file descriptor is not in line-by-line input mode. */ +#ifdef OS2 +#include +#else +#define getch getchar +#endif + +#endif /* DEBUG_INTEPRETER */ + + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_interp + + +/* In order to detect infinite loops in the code, we set-up */ +/* a counter within the run loop. a singly stroke of interpretation */ +/* is now limited to a maximum number of opcodes defined below.. */ +/* */ +#define MAX_RUNNABLE_OPCODES 1000000 + + +/* There are two kinds of implementations there: */ +/* */ +/* a. static implementation: */ +/* */ +/* The current execution context is a static variable, */ +/* which fields are accessed directly by the interpreter */ +/* during execution. The context is named 'cur'. */ +/* */ +/* This version is non-reentrant, of course. */ +/* */ +/* */ +/* b. indirect implementation: */ +/* */ +/* The current execution context is passed to _each_ */ +/* function as its first argument, and each field is */ +/* thus accessed indirectly. */ +/* */ +/* This version is, however, fully re-entrant. */ +/* */ +/* */ +/* The idea is that an indirect implementation may be */ +/* slower to execute on the low-end processors that are */ +/* used in some systems (like 386s or even 486s). */ +/* */ +/* When the interpreter started, we had no idea of the */ +/* time that glyph hinting (i.e. executing instructions) */ +/* could take in the whole process of rendering a glyph, */ +/* and a 10 to 30% performance penalty on low-end systems */ +/* didn't seem much of a good idea. This question led us */ +/* to provide two distinct builds of the C version from */ +/* a single source, with the use of macros (again). */ +/* */ +/* Now that the engine is working (and working really */ +/* well!), it seems that the greatest time-consuming */ +/* factors are: file i/o, glyph loading, rasterizing and */ +/* _then_ glyph hinting! */ +/* */ +/* Tests performed with two versions of the 'fttimer' */ +/* program seem to indicate that hinting takes less than 5% */ +/* of the rendering process, which is dominated by glyph */ +/* loading and scan-line conversion by an high order of */ +/* magnitude. */ +/* */ +/* As a consequence, the indirect implementation is now the */ +/* default, as its performance costs can be considered */ +/* negligible in our context. Note, however, that we */ +/* kept the same source with macros because: */ +/* */ +/* - the code is kept very close in design to the */ +/* Pascal one used for development. */ +/* */ +/* - it's much more readable that way! */ +/* */ +/* - it's still open to later experimentation and tuning */ + + + +#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER /* indirect implementation */ + +#define CUR (*exc) /* see ttobjs.h */ + +#else /* static implementation */ + +#define CUR cur + + static TExecution_Context cur; /* static exec. context variable */ + + /* apparently, we have a _lot_ of direct indexing when accessing */ + /* the static 'cur', which makes the code bigger (due to all the */ + /* four bytes addresses). */ + +#endif /* !TT_CONFIG_OPTION_STATIC_INTERPRETER */ + + +#define INS_ARG EXEC_OPS PStorage args /* see ttobjs.h */ + +#define SKIP_Code() SkipCode( EXEC_ARG ) + +#define GET_ShortIns() GetShortIns( EXEC_ARG ) + +#define COMPUTE_Funcs() Compute_Funcs( EXEC_ARG ) + +#define NORMalize( x, y, v ) Normalize( EXEC_ARGS x, y, v ) + +#define SET_SuperRound( scale, flags ) \ + SetSuperRound( EXEC_ARGS scale, flags ) + +#define INS_Goto_CodeRange( range, ip ) \ + Ins_Goto_CodeRange( EXEC_ARGS range, ip ) + +#define CUR_Func_project( x, y ) CUR.func_project( EXEC_ARGS x, y ) +#define CUR_Func_move( z, p, d ) CUR.func_move( EXEC_ARGS z, p, d ) +#define CUR_Func_dualproj( x, y ) CUR.func_dualproj( EXEC_ARGS x, y ) +#define CUR_Func_freeProj( x, y ) CUR.func_freeProj( EXEC_ARGS x, y ) +#define CUR_Func_round( d, c ) CUR.func_round( EXEC_ARGS d, c ) + +#define CUR_Func_read_cvt( index ) \ + CUR.func_read_cvt( EXEC_ARGS index ) + +#define CUR_Func_write_cvt( index, val ) \ + CUR.func_write_cvt( EXEC_ARGS index, val ) + +#define CUR_Func_move_cvt( index, val ) \ + CUR.func_move_cvt( EXEC_ARGS index, val ) + +#define CURRENT_Ratio() Current_Ratio( EXEC_ARG ) +#define CURRENT_Ppem() Current_Ppem( EXEC_ARG ) + +#define CALC_Length() Calc_Length( EXEC_ARG ) + +#define INS_SxVTL( a, b, c, d ) Ins_SxVTL( EXEC_ARGS a, b, c, d ) + +#define COMPUTE_Point_Displacement( a, b, c, d ) \ + Compute_Point_Displacement( EXEC_ARGS a, b, c, d ) + +#define MOVE_Zp2_Point( a, b, c, t ) Move_Zp2_Point( EXEC_ARGS a, b, c, t ) + +#define CUR_Ppem() Cur_PPEM( EXEC_ARG ) + + /* Instruction dispatch function, as used by the interpreter */ + typedef void (*TInstruction_Function)( INS_ARG ); + +#define BOUNDS( x, n ) ( (x) >= (n) ) + + + +/*********************************************************************/ +/* */ +/* Before an opcode is executed, the interpreter verifies that */ +/* there are enough arguments on the stack, with the help of */ +/* the Pop_Push_Count table. */ +/* */ +/* For each opcode, the first column gives the number of arguments */ +/* that are popped from the stack; the second one gives the number */ +/* of those that are pushed in result. */ +/* */ +/* Note that for opcodes with a varying number of parameters, */ +/* either 0 or 1 arg is verified before execution, depending */ +/* on the nature of the instruction: */ +/* */ +/* - if the number of arguments is given by the bytecode */ +/* stream or the loop variable, 0 is chosen. */ +/* */ +/* - if the first argument is a count n that is followed */ +/* by arguments a1..an, then 1 is chosen. */ +/* */ +/*********************************************************************/ + +#undef PACK +#define PACK( x, y ) ((x << 4) | y) + + static const Byte Pop_Push_Count[256] = + { + /* opcodes are gathered in groups of 16 */ + /* please keep the spaces as they are */ + + /* SVTCA y */ PACK( 0, 0 ), + /* SVTCA x */ PACK( 0, 0 ), + /* SPvTCA y */ PACK( 0, 0 ), + /* SPvTCA x */ PACK( 0, 0 ), + /* SFvTCA y */ PACK( 0, 0 ), + /* SFvTCA x */ PACK( 0, 0 ), + /* SPvTL // */ PACK( 2, 0 ), + /* SPvTL + */ PACK( 2, 0 ), + /* SFvTL // */ PACK( 2, 0 ), + /* SFvTL + */ PACK( 2, 0 ), + /* SPvFS */ PACK( 2, 0 ), + /* SFvFS */ PACK( 2, 0 ), + /* GPV */ PACK( 0, 2 ), + /* GFV */ PACK( 0, 2 ), + /* SFvTPv */ PACK( 0, 0 ), + /* ISECT */ PACK( 5, 0 ), + + /* SRP0 */ PACK( 1, 0 ), + /* SRP1 */ PACK( 1, 0 ), + /* SRP2 */ PACK( 1, 0 ), + /* SZP0 */ PACK( 1, 0 ), + /* SZP1 */ PACK( 1, 0 ), + /* SZP2 */ PACK( 1, 0 ), + /* SZPS */ PACK( 1, 0 ), + /* SLOOP */ PACK( 1, 0 ), + /* RTG */ PACK( 0, 0 ), + /* RTHG */ PACK( 0, 0 ), + /* SMD */ PACK( 1, 0 ), + /* ELSE */ PACK( 0, 0 ), + /* JMPR */ PACK( 1, 0 ), + /* SCvTCi */ PACK( 1, 0 ), + /* SSwCi */ PACK( 1, 0 ), + /* SSW */ PACK( 1, 0 ), + + /* DUP */ PACK( 1, 2 ), + /* POP */ PACK( 1, 0 ), + /* CLEAR */ PACK( 0, 0 ), + /* SWAP */ PACK( 2, 2 ), + /* DEPTH */ PACK( 0, 1 ), + /* CINDEX */ PACK( 1, 1 ), + /* MINDEX */ PACK( 1, 0 ), + /* AlignPTS */ PACK( 2, 0 ), + /* INS_$28 */ PACK( 0, 0 ), + /* UTP */ PACK( 1, 0 ), + /* LOOPCALL */ PACK( 2, 0 ), + /* CALL */ PACK( 1, 0 ), + /* FDEF */ PACK( 1, 0 ), + /* ENDF */ PACK( 0, 0 ), + /* MDAP[0] */ PACK( 1, 0 ), + /* MDAP[1] */ PACK( 1, 0 ), + + /* IUP[0] */ PACK( 0, 0 ), + /* IUP[1] */ PACK( 0, 0 ), + /* SHP[0] */ PACK( 0, 0 ), + /* SHP[1] */ PACK( 0, 0 ), + /* SHC[0] */ PACK( 1, 0 ), + /* SHC[1] */ PACK( 1, 0 ), + /* SHZ[0] */ PACK( 1, 0 ), + /* SHZ[1] */ PACK( 1, 0 ), + /* SHPIX */ PACK( 1, 0 ), + /* IP */ PACK( 0, 0 ), + /* MSIRP[0] */ PACK( 2, 0 ), + /* MSIRP[1] */ PACK( 2, 0 ), + /* AlignRP */ PACK( 0, 0 ), + /* RTDG */ PACK( 0, 0 ), + /* MIAP[0] */ PACK( 2, 0 ), + /* MIAP[1] */ PACK( 2, 0 ), + + /* NPushB */ PACK( 0, 0 ), + /* NPushW */ PACK( 0, 0 ), + /* WS */ PACK( 2, 0 ), + /* RS */ PACK( 1, 1 ), + /* WCvtP */ PACK( 2, 0 ), + /* RCvt */ PACK( 1, 1 ), + /* GC[0] */ PACK( 1, 1 ), + /* GC[1] */ PACK( 1, 1 ), + /* SCFS */ PACK( 2, 0 ), + /* MD[0] */ PACK( 2, 1 ), + /* MD[1] */ PACK( 2, 1 ), + /* MPPEM */ PACK( 0, 1 ), + /* MPS */ PACK( 0, 1 ), + /* FlipON */ PACK( 0, 0 ), + /* FlipOFF */ PACK( 0, 0 ), + /* DEBUG */ PACK( 1, 0 ), + + /* LT */ PACK( 2, 1 ), + /* LTEQ */ PACK( 2, 1 ), + /* GT */ PACK( 2, 1 ), + /* GTEQ */ PACK( 2, 1 ), + /* EQ */ PACK( 2, 1 ), + /* NEQ */ PACK( 2, 1 ), + /* ODD */ PACK( 1, 1 ), + /* EVEN */ PACK( 1, 1 ), + /* IF */ PACK( 1, 0 ), + /* EIF */ PACK( 0, 0 ), + /* AND */ PACK( 2, 1 ), + /* OR */ PACK( 2, 1 ), + /* NOT */ PACK( 1, 1 ), + /* DeltaP1 */ PACK( 1, 0 ), + /* SDB */ PACK( 1, 0 ), + /* SDS */ PACK( 1, 0 ), + + /* ADD */ PACK( 2, 1 ), + /* SUB */ PACK( 2, 1 ), + /* DIV */ PACK( 2, 1 ), + /* MUL */ PACK( 2, 1 ), + /* ABS */ PACK( 1, 1 ), + /* NEG */ PACK( 1, 1 ), + /* FLOOR */ PACK( 1, 1 ), + /* CEILING */ PACK( 1, 1 ), + /* ROUND[0] */ PACK( 1, 1 ), + /* ROUND[1] */ PACK( 1, 1 ), + /* ROUND[2] */ PACK( 1, 1 ), + /* ROUND[3] */ PACK( 1, 1 ), + /* NROUND[0] */ PACK( 1, 1 ), + /* NROUND[1] */ PACK( 1, 1 ), + /* NROUND[2] */ PACK( 1, 1 ), + /* NROUND[3] */ PACK( 1, 1 ), + + /* WCvtF */ PACK( 2, 0 ), + /* DeltaP2 */ PACK( 1, 0 ), + /* DeltaP3 */ PACK( 1, 0 ), + /* DeltaCn[0] */ PACK( 1, 0 ), + /* DeltaCn[1] */ PACK( 1, 0 ), + /* DeltaCn[2] */ PACK( 1, 0 ), + /* SROUND */ PACK( 1, 0 ), + /* S45Round */ PACK( 1, 0 ), + /* JROT */ PACK( 2, 0 ), + /* JROF */ PACK( 2, 0 ), + /* ROFF */ PACK( 0, 0 ), + /* INS_$7B */ PACK( 0, 0 ), + /* RUTG */ PACK( 0, 0 ), + /* RDTG */ PACK( 0, 0 ), + /* SANGW */ PACK( 1, 0 ), + /* AA */ PACK( 1, 0 ), + + /* FlipPT */ PACK( 0, 0 ), + /* FlipRgON */ PACK( 2, 0 ), + /* FlipRgOFF */ PACK( 2, 0 ), + /* INS_$83 */ PACK( 0, 0 ), + /* INS_$84 */ PACK( 0, 0 ), + /* ScanCTRL */ PACK( 1, 0 ), + /* SDVPTL[0] */ PACK( 2, 0 ), + /* SDVPTL[1] */ PACK( 2, 0 ), + /* GetINFO */ PACK( 1, 1 ), + /* IDEF */ PACK( 1, 0 ), + /* ROLL */ PACK( 3, 3 ), + /* MAX */ PACK( 2, 1 ), + /* MIN */ PACK( 2, 1 ), + /* ScanTYPE */ PACK( 1, 0 ), + /* InstCTRL */ PACK( 2, 0 ), + /* INS_$8F */ PACK( 0, 0 ), + + /* INS_$90 */ PACK( 0, 0 ), + /* INS_$91 */ PACK( 0, 0 ), + /* INS_$92 */ PACK( 0, 0 ), + /* INS_$93 */ PACK( 0, 0 ), + /* INS_$94 */ PACK( 0, 0 ), + /* INS_$95 */ PACK( 0, 0 ), + /* INS_$96 */ PACK( 0, 0 ), + /* INS_$97 */ PACK( 0, 0 ), + /* INS_$98 */ PACK( 0, 0 ), + /* INS_$99 */ PACK( 0, 0 ), + /* INS_$9A */ PACK( 0, 0 ), + /* INS_$9B */ PACK( 0, 0 ), + /* INS_$9C */ PACK( 0, 0 ), + /* INS_$9D */ PACK( 0, 0 ), + /* INS_$9E */ PACK( 0, 0 ), + /* INS_$9F */ PACK( 0, 0 ), + + /* INS_$A0 */ PACK( 0, 0 ), + /* INS_$A1 */ PACK( 0, 0 ), + /* INS_$A2 */ PACK( 0, 0 ), + /* INS_$A3 */ PACK( 0, 0 ), + /* INS_$A4 */ PACK( 0, 0 ), + /* INS_$A5 */ PACK( 0, 0 ), + /* INS_$A6 */ PACK( 0, 0 ), + /* INS_$A7 */ PACK( 0, 0 ), + /* INS_$A8 */ PACK( 0, 0 ), + /* INS_$A9 */ PACK( 0, 0 ), + /* INS_$AA */ PACK( 0, 0 ), + /* INS_$AB */ PACK( 0, 0 ), + /* INS_$AC */ PACK( 0, 0 ), + /* INS_$AD */ PACK( 0, 0 ), + /* INS_$AE */ PACK( 0, 0 ), + /* INS_$AF */ PACK( 0, 0 ), + + /* PushB[0] */ PACK( 0, 1 ), + /* PushB[1] */ PACK( 0, 2 ), + /* PushB[2] */ PACK( 0, 3 ), + /* PushB[3] */ PACK( 0, 4 ), + /* PushB[4] */ PACK( 0, 5 ), + /* PushB[5] */ PACK( 0, 6 ), + /* PushB[6] */ PACK( 0, 7 ), + /* PushB[7] */ PACK( 0, 8 ), + /* PushW[0] */ PACK( 0, 1 ), + /* PushW[1] */ PACK( 0, 2 ), + /* PushW[2] */ PACK( 0, 3 ), + /* PushW[3] */ PACK( 0, 4 ), + /* PushW[4] */ PACK( 0, 5 ), + /* PushW[5] */ PACK( 0, 6 ), + /* PushW[6] */ PACK( 0, 7 ), + /* PushW[7] */ PACK( 0, 8 ), + + /* MDRP[00] */ PACK( 1, 0 ), + /* MDRP[01] */ PACK( 1, 0 ), + /* MDRP[02] */ PACK( 1, 0 ), + /* MDRP[03] */ PACK( 1, 0 ), + /* MDRP[04] */ PACK( 1, 0 ), + /* MDRP[05] */ PACK( 1, 0 ), + /* MDRP[06] */ PACK( 1, 0 ), + /* MDRP[07] */ PACK( 1, 0 ), + /* MDRP[08] */ PACK( 1, 0 ), + /* MDRP[09] */ PACK( 1, 0 ), + /* MDRP[10] */ PACK( 1, 0 ), + /* MDRP[11] */ PACK( 1, 0 ), + /* MDRP[12] */ PACK( 1, 0 ), + /* MDRP[13] */ PACK( 1, 0 ), + /* MDRP[14] */ PACK( 1, 0 ), + /* MDRP[15] */ PACK( 1, 0 ), + + /* MDRP[16] */ PACK( 1, 0 ), + /* MDRP[17] */ PACK( 1, 0 ), + /* MDRP[18] */ PACK( 1, 0 ), + /* MDRP[19] */ PACK( 1, 0 ), + /* MDRP[20] */ PACK( 1, 0 ), + /* MDRP[21] */ PACK( 1, 0 ), + /* MDRP[22] */ PACK( 1, 0 ), + /* MDRP[23] */ PACK( 1, 0 ), + /* MDRP[24] */ PACK( 1, 0 ), + /* MDRP[25] */ PACK( 1, 0 ), + /* MDRP[26] */ PACK( 1, 0 ), + /* MDRP[27] */ PACK( 1, 0 ), + /* MDRP[28] */ PACK( 1, 0 ), + /* MDRP[29] */ PACK( 1, 0 ), + /* MDRP[30] */ PACK( 1, 0 ), + /* MDRP[31] */ PACK( 1, 0 ), + + /* MIRP[00] */ PACK( 2, 0 ), + /* MIRP[01] */ PACK( 2, 0 ), + /* MIRP[02] */ PACK( 2, 0 ), + /* MIRP[03] */ PACK( 2, 0 ), + /* MIRP[04] */ PACK( 2, 0 ), + /* MIRP[05] */ PACK( 2, 0 ), + /* MIRP[06] */ PACK( 2, 0 ), + /* MIRP[07] */ PACK( 2, 0 ), + /* MIRP[08] */ PACK( 2, 0 ), + /* MIRP[09] */ PACK( 2, 0 ), + /* MIRP[10] */ PACK( 2, 0 ), + /* MIRP[11] */ PACK( 2, 0 ), + /* MIRP[12] */ PACK( 2, 0 ), + /* MIRP[13] */ PACK( 2, 0 ), + /* MIRP[14] */ PACK( 2, 0 ), + /* MIRP[15] */ PACK( 2, 0 ), + + /* MIRP[16] */ PACK( 2, 0 ), + /* MIRP[17] */ PACK( 2, 0 ), + /* MIRP[18] */ PACK( 2, 0 ), + /* MIRP[19] */ PACK( 2, 0 ), + /* MIRP[20] */ PACK( 2, 0 ), + /* MIRP[21] */ PACK( 2, 0 ), + /* MIRP[22] */ PACK( 2, 0 ), + /* MIRP[23] */ PACK( 2, 0 ), + /* MIRP[24] */ PACK( 2, 0 ), + /* MIRP[25] */ PACK( 2, 0 ), + /* MIRP[26] */ PACK( 2, 0 ), + /* MIRP[27] */ PACK( 2, 0 ), + /* MIRP[28] */ PACK( 2, 0 ), + /* MIRP[29] */ PACK( 2, 0 ), + /* MIRP[30] */ PACK( 2, 0 ), + /* MIRP[31] */ PACK( 2, 0 ) + }; + + static const TT_Vector Null_Vector = {0,0}; + +#undef NULL_Vector +#define NULL_Vector (TT_Vector*)&Null_Vector + +/******************************************************************* + * + * Function : Norm + * + * Description : Returns the norm (length) of a vector. + * + * Input : X, Y vector + * + * Output : Returns length in F26dot6. + * + *****************************************************************/ + + static TT_F26Dot6 Norm( TT_F26Dot6 X, TT_F26Dot6 Y ) + { + TT_Int64 T1, T2; + + + MUL_64( X, X, T1 ); + MUL_64( Y, Y, T2 ); + + ADD_64( T1, T2, T1 ); + + return (TT_F26Dot6)SQRT_64( T1 ); + } + + +/******************************************************************* + * + * Function : FUnits_To_Pixels + * + * Description : Scale a distance in FUnits to pixel coordinates. + * + * Input : Distance in FUnits + * + * Output : Distance in 26.6 format. + * + *****************************************************************/ + + static TT_F26Dot6 FUnits_To_Pixels( EXEC_OPS Short distance ) + { + return TT_MulDiv( distance, + CUR.metrics.scale1, + CUR.metrics.scale2 ); + } + + +/******************************************************************* + * + * Function : Current_Ratio + * + * Description : Return the current aspect ratio scaling factor + * depending on the projection vector's state and + * device resolutions. + * + * Input : None + * + * Output : Aspect ratio in 16.16 format, always <= 1.0 . + * + *****************************************************************/ + + static Long Current_Ratio( EXEC_OP ) + { + if ( CUR.metrics.ratio ) + return CUR.metrics.ratio; + + if ( CUR.GS.projVector.y == 0 ) + CUR.metrics.ratio = CUR.metrics.x_ratio; + + else if ( CUR.GS.projVector.x == 0 ) + CUR.metrics.ratio = CUR.metrics.y_ratio; + + else + { + Long x, y; + + + x = TT_MulDiv( CUR.GS.projVector.x, CUR.metrics.x_ratio, 0x4000 ); + y = TT_MulDiv( CUR.GS.projVector.y, CUR.metrics.y_ratio, 0x4000 ); + CUR.metrics.ratio = Norm( x, y ); + } + + return CUR.metrics.ratio; + } + + + static Long Current_Ppem( EXEC_OP ) + { + return TT_MulFix( CUR.metrics.ppem, CURRENT_Ratio() ); + } + + + static TT_F26Dot6 Read_CVT( EXEC_OPS ULong index ) + { + return CUR.cvt[index]; + } + + + static TT_F26Dot6 Read_CVT_Stretched( EXEC_OPS ULong index ) + { + return TT_MulFix( CUR.cvt[index], CURRENT_Ratio() ); + } + + + static void Write_CVT( EXEC_OPS ULong index, TT_F26Dot6 value ) + { + CUR.cvt[index] = value; + } + + static void Write_CVT_Stretched( EXEC_OPS ULong index, TT_F26Dot6 value ) + { + CUR.cvt[index] = TT_MulDiv( value, 0x10000, CURRENT_Ratio() ); + } + + + static void Move_CVT( EXEC_OPS ULong index, TT_F26Dot6 value ) + { + CUR.cvt[index] += value; + } + + static void Move_CVT_Stretched( EXEC_OPS ULong index, TT_F26Dot6 value ) + { + CUR.cvt[index] += TT_MulDiv( value, 0x10000, CURRENT_Ratio() ); + } + + +/****************************************************************** + * + * Function : Calc_Length + * + * Description : Computes the length in bytes of current opcode. + * + *****************************************************************/ + + static Bool Calc_Length( EXEC_OP ) + { + CUR.opcode = CUR.code[CUR.IP]; + + switch ( CUR.opcode ) + { + case 0x40: + if ( CUR.IP + 1 >= CUR.codeSize ) + return FAILURE; + + CUR.length = CUR.code[CUR.IP + 1] + 2; + break; + + case 0x41: + if ( CUR.IP + 1 >= CUR.codeSize ) + return FAILURE; + + CUR.length = CUR.code[CUR.IP + 1] * 2 + 2; + break; + + case 0xB0: + case 0xB1: + case 0xB2: + case 0xB3: + case 0xB4: + case 0xB5: + case 0xB6: + case 0xB7: + CUR.length = CUR.opcode - 0xB0 + 2; + break; + + case 0xB8: + case 0xB9: + case 0xBA: + case 0xBB: + case 0xBC: + case 0xBD: + case 0xBE: + case 0xBF: + CUR.length = (CUR.opcode - 0xB8) * 2 + 3; + break; + + default: + CUR.length = 1; + break; + } + + /* make sure result is in range */ + + if ( CUR.IP + CUR.length > CUR.codeSize ) + return FAILURE; + + return SUCCESS; + } + + +/******************************************************************* + * + * Function : GetShortIns + * + * Description : Returns a short integer taken from the instruction + * stream at address IP. + * + * Input : None + * + * Output : Short read at Code^[IP..IP+1] + * + * Notes : This one could become a Macro in the C version. + * + *****************************************************************/ + + static Short GetShortIns( EXEC_OP ) + { + /* Reading a byte stream so there is no endianess (DaveP) */ + CUR.IP += 2; + return (Short)((CUR.code[CUR.IP - 2] << 8) + CUR.code[CUR.IP - 1]); + } + + +/******************************************************************* + * + * Function : Ins_Goto_CodeRange + * + * Description : Goes to a certain code range in the instruction + * stream. + * + * + * Input : aRange + * aIP + * + * Output : SUCCESS or FAILURE. + * + *****************************************************************/ + + static Bool Ins_Goto_CodeRange( EXEC_OPS Int aRange, ULong aIP ) + { + TCodeRange* WITH; + + + if ( aRange < 1 || aRange > 3 ) + { + CUR.error = TT_Err_Bad_Argument; + return FAILURE; + } + + WITH = &CUR.codeRangeTable[aRange - 1]; + + if ( WITH->Base == NULL ) /* invalid coderange */ + { + CUR.error = TT_Err_Invalid_CodeRange; + return FAILURE; + } + + /* NOTE: Because the last instruction of a program may be a CALL */ + /* which will return to the first byte *after* the code */ + /* range, we test for aIP <= Size, instead of aIP < Size. */ + + if ( aIP > WITH->Size ) + { + CUR.error = TT_Err_Code_Overflow; + return FAILURE; + } + + CUR.code = WITH->Base; + CUR.codeSize = WITH->Size; + CUR.IP = aIP; + CUR.curRange = aRange; + + return SUCCESS; + } + + +/******************************************************************* + * + * Function : Direct_Move + * + * Description : Moves a point by a given distance along the + * freedom vector. The point will be touched. + * + * Input : point index of point to move + * distance distance to apply + * zone affected glyph zone + * + * Output : None + * + *****************************************************************/ + + static void Direct_Move( EXEC_OPS PGlyph_Zone zone, + UShort point, + TT_F26Dot6 distance ) + { + TT_F26Dot6 v; + + + v = CUR.GS.freeVector.x; + + if ( v != 0 ) + { + zone->cur[point].x += TT_MulDiv( distance, + v * 0x10000L, + CUR.F_dot_P ); + + zone->touch[point] |= TT_Flag_Touched_X; + } + + v = CUR.GS.freeVector.y; + + if ( v != 0 ) + { + zone->cur[point].y += TT_MulDiv( distance, + v * 0x10000L, + CUR.F_dot_P ); + + zone->touch[point] |= TT_Flag_Touched_Y; + } + } + + +/******************************************************************/ +/* */ +/* The following versions are used whenever both vectors are both */ +/* along one of the coordinate unit vectors, i.e. in 90% cases. */ +/* */ +/******************************************************************/ + +/******************************************************************* + * Direct_Move_X + * + *******************************************************************/ + + static void Direct_Move_X( EXEC_OPS PGlyph_Zone zone, + UShort point, + TT_F26Dot6 distance ) + { + zone->cur[point].x += distance; + zone->touch[point] |= TT_Flag_Touched_X; + } + + +/******************************************************************* + * Direct_Move_Y + * + *******************************************************************/ + + static void Direct_Move_Y( EXEC_OPS PGlyph_Zone zone, + UShort point, + TT_F26Dot6 distance ) + { + zone->cur[point].y += distance; + zone->touch[point] |= TT_Flag_Touched_Y; + } + + +/******************************************************************* + * + * Function : Round_None + * + * Description : Does not round, but adds engine compensation. + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : rounded distance. + * + * NOTE : The spec says very few about the relationship between + * rounding and engine compensation. However, it seems + * from the description of super round that we should + * should add the compensation before rounding. + * + ******************************************************************/ + + static TT_F26Dot6 Round_None( EXEC_OPS TT_F26Dot6 distance, + TT_F26Dot6 compensation ) + { + TT_F26Dot6 val; + + + if ( distance >= 0 ) + { + val = distance + compensation; + if ( val < 0 ) + val = 0; + } + else { + val = distance - compensation; + if ( val > 0 ) + val = 0; + } + + return val; + } + + +/******************************************************************* + * + * Function : Round_To_Grid + * + * Description : Rounds value to grid after adding engine + * compensation + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : Rounded distance. + * + *****************************************************************/ + + static TT_F26Dot6 Round_To_Grid( EXEC_OPS TT_F26Dot6 distance, + TT_F26Dot6 compensation ) + { + TT_F26Dot6 val; + + + if ( distance >= 0 ) + { + val = distance + compensation + 32; + if ( val > 0 ) + val &= ~63; + else + val = 0; + } + else + { + val = -( (compensation - distance + 32) & (-64) ); + if ( val > 0 ) + val = 0; + } + + return val; + } + + +/******************************************************************* + * + * Function : Round_To_Half_Grid + * + * Description : Rounds value to half grid after adding engine + * compensation. + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : Rounded distance. + * + *****************************************************************/ + + static TT_F26Dot6 Round_To_Half_Grid( EXEC_OPS TT_F26Dot6 distance, + TT_F26Dot6 compensation ) + { + TT_F26Dot6 val; + + + if ( distance >= 0 ) + { + val = ((distance + compensation) & (-64)) + 32; + if ( val < 0 ) + val = 0; + } + else + { + val = -( ((compensation - distance) & (-64)) + 32 ); + if ( val > 0 ) + val = 0; + } + + return val; + } + + +/******************************************************************* + * + * Function : Round_Down_To_Grid + * + * Description : Rounds value down to grid after adding engine + * compensation. + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : Rounded distance. + * + *****************************************************************/ + + static TT_F26Dot6 Round_Down_To_Grid( EXEC_OPS TT_F26Dot6 distance, + TT_F26Dot6 compensation ) + { + TT_F26Dot6 val; + + + if ( distance >= 0 ) + { + val = distance + compensation; + if ( val > 0 ) + val &= ~63; + else + val = 0; + } + else + { + val = -( (compensation - distance) & (-64) ); + if ( val > 0 ) + val = 0; + } + + return val; + } + + +/******************************************************************* + * + * Function : Round_Up_To_Grid + * + * Description : Rounds value up to grid after adding engine + * compensation. + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : Rounded distance. + * + *****************************************************************/ + + static TT_F26Dot6 Round_Up_To_Grid( EXEC_OPS TT_F26Dot6 distance, + TT_F26Dot6 compensation ) + { + TT_F26Dot6 val; + + + if ( distance >= 0 ) + { + val = distance + compensation + 63; + if ( val > 0 ) + val &= ~63; + else + val = 0; + } + else + { + val = -( (compensation - distance + 63) & (-64) ); + if ( val > 0 ) + val = 0; + } + + return val; + } + + +/******************************************************************* + * + * Function : Round_To_Double_Grid + * + * Description : Rounds value to double grid after adding engine + * compensation. + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : Rounded distance. + * + *****************************************************************/ + + static TT_F26Dot6 Round_To_Double_Grid( EXEC_OPS TT_F26Dot6 distance, + TT_F26Dot6 compensation ) + { + TT_F26Dot6 val; + + + if ( distance >= 0 ) + { + val = distance + compensation + 16; + if ( val > 0 ) + val &= ~31; + else + val = 0; + } + else + { + val = -( (compensation - distance + 16) & (-32) ); + if ( val > 0 ) + val = 0; + } + + return val; + } + + +/******************************************************************* + * + * Function : Round_Super + * + * Description : Super-rounds value to grid after adding engine + * compensation. + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : Rounded distance. + * + * NOTE : The spec says very few about the relationship between + * rounding and engine compensation. However, it seems + * from the description of super round that we should + * should add the compensation before rounding. + * + *****************************************************************/ + + static TT_F26Dot6 Round_Super( EXEC_OPS TT_F26Dot6 distance, + TT_F26Dot6 compensation ) + { + TT_F26Dot6 val; + + + if ( distance >= 0 ) + { + val = (distance - CUR.phase + CUR.threshold + compensation) & + (-CUR.period); + if ( val < 0 ) + val = 0; + val += CUR.phase; + } + else + { + val = -( (CUR.threshold - CUR.phase - distance + compensation) & + (-CUR.period) ); + if ( val > 0 ) + val = 0; + val -= CUR.phase; + } + + return val; + } + + +/******************************************************************* + * + * Function : Round_Super_45 + * + * Description : Super-rounds value to grid after adding engine + * compensation. + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : Rounded distance. + * + * NOTE : There is a separate function for Round_Super_45 as we + * may need a greater precision. + * + *****************************************************************/ + + static TT_F26Dot6 Round_Super_45( EXEC_OPS TT_F26Dot6 distance, + TT_F26Dot6 compensation ) + { + TT_F26Dot6 val; + + + if ( distance >= 0 ) + { + val = ( (distance - CUR.phase + CUR.threshold + compensation) / + CUR.period ) * CUR.period; + if ( val < 0 ) + val = 0; + val += CUR.phase; + } + else + { + val = -( ( (CUR.threshold - CUR.phase - distance + compensation) / + CUR.period ) * CUR.period ); + if ( val > 0 ) + val = 0; + val -= CUR.phase; + } + + return val; + } + + +/******************************************************************* + * Compute_Round + * + *****************************************************************/ + + static void Compute_Round( EXEC_OPS Byte round_mode ) + { + switch ( round_mode ) + { + case TT_Round_Off: + CUR.func_round = (TRound_Function)Round_None; + break; + + case TT_Round_To_Grid: + CUR.func_round = (TRound_Function)Round_To_Grid; + break; + + case TT_Round_Up_To_Grid: + CUR.func_round = (TRound_Function)Round_Up_To_Grid; + break; + + case TT_Round_Down_To_Grid: + CUR.func_round = (TRound_Function)Round_Down_To_Grid; + break; + + case TT_Round_To_Half_Grid: + CUR.func_round = (TRound_Function)Round_To_Half_Grid; + break; + + case TT_Round_To_Double_Grid: + CUR.func_round = (TRound_Function)Round_To_Double_Grid; + break; + + case TT_Round_Super: + CUR.func_round = (TRound_Function)Round_Super; + break; + + case TT_Round_Super_45: + CUR.func_round = (TRound_Function)Round_Super_45; + break; + } + } + + +/******************************************************************* + * + * Function : SetSuperRound + * + * Description : Sets Super Round parameters. + * + * Input : GridPeriod Grid period + * selector SROUND opcode + * + * Output : None. + * + *****************************************************************/ + + static void SetSuperRound( EXEC_OPS TT_F26Dot6 GridPeriod, + Long selector ) + { + switch ( (Int)(selector & 0xC0) ) + { + case 0: + CUR.period = GridPeriod / 2; + break; + + case 0x40: + CUR.period = GridPeriod; + break; + + case 0x80: + CUR.period = GridPeriod * 2; + break; + + /* This opcode is reserved, but... */ + + case 0xC0: + CUR.period = GridPeriod; + break; + } + + switch ( (Int)(selector & 0x30) ) + { + case 0: + CUR.phase = 0; + break; + + case 0x10: + CUR.phase = CUR.period / 4; + break; + + case 0x20: + CUR.phase = CUR.period / 2; + break; + + case 0x30: + CUR.phase = GridPeriod * 3 / 4; + break; + } + + if ( (selector & 0x0F) == 0 ) + CUR.threshold = CUR.period - 1; + else + CUR.threshold = ( (Int)(selector & 0x0F) - 4 ) * CUR.period / 8; + + CUR.period /= 256; + CUR.phase /= 256; + CUR.threshold /= 256; + } + + +/******************************************************************* + * + * Function : Project + * + * Description : Computes the projection of vector given by (v2-v1) + * along the current projection vector. + * + * Input : v1, v2 input vector + * + * Output : Returns distance in F26dot6 format. + * + *****************************************************************/ + + static TT_F26Dot6 Project( EXEC_OPS TT_Vector* v1, + TT_Vector* v2 ) + { + TT_Int64 T1, T2; + + + MUL_64( v1->x - v2->x, CUR.GS.projVector.x, T1 ); + MUL_64( v1->y - v2->y, CUR.GS.projVector.y, T2 ); + + ADD_64( T1, T2, T1 ); + + return (TT_F26Dot6)DIV_64( T1, 0x4000L ); + } + + +/******************************************************************* + * + * Function : Dual_Project + * + * Description : Computes the projection of the vector given by + * (v2-v1) along the current dual vector. + * + * Input : v1, v2 input vector + * + * Output : Returns distance in F26dot6 format. + * + *****************************************************************/ + + static TT_F26Dot6 Dual_Project( EXEC_OPS TT_Vector* v1, + TT_Vector* v2 ) + { + TT_Int64 T1, T2; + + + MUL_64( v1->x - v2->x, CUR.GS.dualVector.x, T1 ); + MUL_64( v1->y - v2->y, CUR.GS.dualVector.y, T2 ); + + ADD_64( T1, T2, T1 ); + + return (TT_F26Dot6)DIV_64( T1, 0x4000L ); + } + + +/******************************************************************* + * + * Function : Free_Project + * + * Description : Computes the projection of the vector given by + * (v2-v1) along the current freedom vector. + * + * Input : v1, v2 input vector + * + * Output : Returns distance in F26dot6 format. + * + *****************************************************************/ + + static TT_F26Dot6 Free_Project( EXEC_OPS TT_Vector* v1, + TT_Vector* v2 ) + { + TT_Int64 T1, T2; + + + MUL_64( v1->x - v2->x, CUR.GS.freeVector.x, T1 ); + MUL_64( v1->y - v2->y, CUR.GS.freeVector.y, T2 ); + + ADD_64( T1, T2, T1 ); + + return (TT_F26Dot6)DIV_64( T1, 0x4000L ); + } + + +/******************************************************************* + * + * Function : Project_x + * + * Input : Vx, Vy input vector + * + * Output : Returns Vx. + * + * Note : Used as a dummy function. + * + *****************************************************************/ + + static TT_F26Dot6 Project_x( EXEC_OPS TT_Vector* v1, + TT_Vector* v2 ) + { + return (v1->x - v2->x); + } + + +/******************************************************************* + * + * Function : Project_y + * + * Input : Vx, Vy input vector + * + * Output : Returns Vy. + * + * Note : Used as a dummy function. + * + *****************************************************************/ + + static TT_F26Dot6 Project_y( EXEC_OPS TT_Vector* v1, + TT_Vector* v2 ) + { + return (v1->y - v2->y); + } + + +/******************************************************************* + * + * Function : Compute_Funcs + * + * Description : Computes the projections and movement function + * pointers according to the current graphics state. + * + * Input : None + * + *****************************************************************/ + + static void Compute_Funcs( EXEC_OP ) + { + if ( CUR.GS.freeVector.x == 0x4000 ) + { + CUR.func_freeProj = (TProject_Function)Project_x; + CUR.F_dot_P = CUR.GS.projVector.x * 0x10000L; + } + else + { + if ( CUR.GS.freeVector.y == 0x4000 ) + { + CUR.func_freeProj = (TProject_Function)Project_y; + CUR.F_dot_P = CUR.GS.projVector.y * 0x10000L; + } + else + { + CUR.func_freeProj = (TProject_Function)Free_Project; + CUR.F_dot_P = (Long)CUR.GS.projVector.x * CUR.GS.freeVector.x * 4 + + (Long)CUR.GS.projVector.y * CUR.GS.freeVector.y * 4; + } + } + + CUR.cached_metrics = FALSE; + + if ( CUR.GS.projVector.x == 0x4000 ) + CUR.func_project = (TProject_Function)Project_x; + else + { + if ( CUR.GS.projVector.y == 0x4000 ) + CUR.func_project = (TProject_Function)Project_y; + else + CUR.func_project = (TProject_Function)Project; + } + + if ( CUR.GS.dualVector.x == 0x4000 ) + CUR.func_dualproj = (TProject_Function)Project_x; + else + { + if ( CUR.GS.dualVector.y == 0x4000 ) + CUR.func_dualproj = (TProject_Function)Project_y; + else + CUR.func_dualproj = (TProject_Function)Dual_Project; + } + + CUR.func_move = (TMove_Function)Direct_Move; + + if ( CUR.F_dot_P == 0x40000000L ) + { + if ( CUR.GS.freeVector.x == 0x4000 ) + CUR.func_move = (TMove_Function)Direct_Move_X; + else + { + if ( CUR.GS.freeVector.y == 0x4000 ) + CUR.func_move = (TMove_Function)Direct_Move_Y; + } + } + + /* at small sizes, F_dot_P can become too small, resulting */ + /* in overflows and 'spikes' in a number of glyphs like 'w'. */ + + if ( ABS( CUR.F_dot_P ) < 0x4000000L ) + CUR.F_dot_P = 0x40000000L; + + /* Disable cached aspect ratio */ + CUR.metrics.ratio = 0; + } + + +/******************************************************************* + * + * Function : Normalize + * + * Description : Norms a vector + * + * Input : Vx, Vy input vector + * R normed unit vector + * + * Output : Returns FAILURE if a vector parameter is zero. + * + *****************************************************************/ + + static Bool Normalize( EXEC_OPS TT_F26Dot6 Vx, + TT_F26Dot6 Vy, + TT_UnitVector* R ) + { + TT_F26Dot6 W; + Bool S1, S2; + + + if ( ABS( Vx ) < 0x10000L && ABS( Vy ) < 0x10000L ) + { + Vx *= 0x100; + Vy *= 0x100; + + W = Norm( Vx, Vy ); + + if ( W == 0 ) + { + /* XXX : UNDOCUMENTED! It seems that it's possible to try */ + /* to normalize the vector (0,0). Return immediately */ + return SUCCESS; + } + + R->x = (TT_F2Dot14)TT_MulDiv( Vx, 0x4000L, W ); + R->y = (TT_F2Dot14)TT_MulDiv( Vy, 0x4000L, W ); + + return SUCCESS; + } + + W = Norm( Vx, Vy ); + + Vx = TT_MulDiv( Vx, 0x4000L, W ); + Vy = TT_MulDiv( Vy, 0x4000L, W ); + + W = Vx * Vx + Vy * Vy; + + /* Now, we want that Sqrt( W ) = 0x4000 */ + /* Or 0x1000000 <= W < 0x1004000 */ + + if ( Vx < 0 ) + { + Vx = -Vx; + S1 = TRUE; + } + else + S1 = FALSE; + + if ( Vy < 0 ) + { + Vy = -Vy; + S2 = TRUE; + } + else + S2 = FALSE; + + while ( W < 0x1000000L ) + { + /* We need to increase W, by a minimal amount */ + if ( Vx < Vy ) + Vx++; + else + Vy++; + + W = Vx * Vx + Vy * Vy; + } + + while ( W >= 0x1004000L ) + { + /* We need to decrease W, by a minimal amount */ + if ( Vx < Vy ) + Vx--; + else + Vy--; + + W = Vx * Vx + Vy * Vy; + } + + /* Note that in various cases, we can only */ + /* compute a Sqrt(W) of 0x3FFF, eg. Vx = Vy */ + + if ( S1 ) + Vx = -Vx; + + if ( S2 ) + Vy = -Vy; + + R->x = (TT_F2Dot14)Vx; /* Type conversion */ + R->y = (TT_F2Dot14)Vy; /* Type conversion */ + + return SUCCESS; + } + + +/**************************************************************** + * + * Opcodes + * + ****************************************************************/ + + + static Bool Ins_SxVTL( EXEC_OPS UShort aIdx1, + UShort aIdx2, + Int aOpc, + TT_UnitVector* Vec ) + { + Long A, B, C; + TT_Vector* p1; + TT_Vector* p2; + + + if ( BOUNDS( aIdx1, CUR.zp2.n_points ) || + BOUNDS( aIdx2, CUR.zp1.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return FAILURE; + } + + p1 = CUR.zp1.cur + aIdx2; + p2 = CUR.zp2.cur + aIdx1; + + A = p1->x - p2->x; + B = p1->y - p2->y; + + if ( (aOpc & 1) != 0 ) + { + C = B; /* CounterClockwise rotation */ + B = A; + A = -C; + } + + NORMalize( A, B, Vec ); + return SUCCESS; + } + + +/* When not using the big switch statements, the interpreter uses a */ +/* call table defined later below in this source. Each opcode must */ +/* thus have a corresponding function, even trivial ones. */ +/* */ +/* They're all defined there. */ + +#define DO_SVTCA \ + { \ + Short A, B; \ + \ + \ + A = (Short)(CUR.opcode & 1) << 14; \ + B = A ^ (Short)0x4000; \ + \ + CUR.GS.freeVector.x = A; \ + CUR.GS.projVector.x = A; \ + CUR.GS.dualVector.x = A; \ + \ + CUR.GS.freeVector.y = B; \ + CUR.GS.projVector.y = B; \ + CUR.GS.dualVector.y = B; \ + \ + COMPUTE_Funcs(); \ + } + + +#define DO_SPVTCA \ + { \ + Short A, B; \ + \ + \ + A = (Short)(CUR.opcode & 1) << 14; \ + B = A ^ (Short)0x4000; \ + \ + CUR.GS.projVector.x = A; \ + CUR.GS.dualVector.x = A; \ + \ + CUR.GS.projVector.y = B; \ + CUR.GS.dualVector.y = B; \ + \ + COMPUTE_Funcs(); \ + } + + +#define DO_SFVTCA \ + { \ + Short A, B; \ + \ + \ + A = (Short)(CUR.opcode & 1) << 14; \ + B = A ^ (Short)0x4000; \ + \ + CUR.GS.freeVector.x = A; \ + CUR.GS.freeVector.y = B; \ + \ + COMPUTE_Funcs(); \ + } + + +#define DO_SPVTL \ + if ( INS_SxVTL( (UShort)args[1], \ + (UShort)args[0], \ + CUR.opcode, \ + &CUR.GS.projVector) == SUCCESS ) \ + { \ + CUR.GS.dualVector = CUR.GS.projVector; \ + COMPUTE_Funcs(); \ + } + + +#define DO_SFVTL \ + if ( INS_SxVTL( (UShort)args[1], \ + (UShort)args[0], \ + CUR.opcode, \ + &CUR.GS.freeVector) == SUCCESS ) \ + COMPUTE_Funcs(); + + +#define DO_SFVTPV \ + CUR.GS.freeVector = CUR.GS.projVector; \ + COMPUTE_Funcs(); + + +#define DO_SPVFS \ + { \ + Short S; \ + Long X, Y; \ + \ + \ + /* Only use low 16bits, then sign extend */ \ + S = (Short)args[1]; \ + Y = (Long)S; \ + S = (Short)args[0]; \ + X = (Long)S; \ + \ + NORMalize( X, Y, &CUR.GS.projVector ); \ + \ + CUR.GS.dualVector = CUR.GS.projVector; \ + COMPUTE_Funcs(); \ + } + + +#define DO_SFVFS \ + { \ + Short S; \ + Long X, Y; \ + \ + \ + /* Only use low 16bits, then sign extend */ \ + S = (Short)args[1]; \ + Y = (Long)S; \ + S = (Short)args[0]; \ + X = S; \ + \ + NORMalize( X, Y, &CUR.GS.freeVector ); \ + COMPUTE_Funcs(); \ + } + + +#define DO_GPV \ + args[0] = CUR.GS.projVector.x; \ + args[1] = CUR.GS.projVector.y; + + +#define DO_GFV \ + args[0] = CUR.GS.freeVector.x; \ + args[1] = CUR.GS.freeVector.y; + + +#define DO_SRP0 \ + CUR.GS.rp0 = (UShort)args[0]; + + +#define DO_SRP1 \ + CUR.GS.rp1 = (UShort)args[0]; + + +#define DO_SRP2 \ + CUR.GS.rp2 = (UShort)args[0]; + + +#define DO_RTHG \ + CUR.GS.round_state = TT_Round_To_Half_Grid; \ + CUR.func_round = (TRound_Function)Round_To_Half_Grid; + + +#define DO_RTG \ + CUR.GS.round_state = TT_Round_To_Grid; \ + CUR.func_round = (TRound_Function)Round_To_Grid; + + +#define DO_RTDG \ + CUR.GS.round_state = TT_Round_To_Double_Grid; \ + CUR.func_round = (TRound_Function)Round_To_Double_Grid; + + +#define DO_RUTG \ + CUR.GS.round_state = TT_Round_Up_To_Grid; \ + CUR.func_round = (TRound_Function)Round_Up_To_Grid; + + +#define DO_RDTG \ + CUR.GS.round_state = TT_Round_Down_To_Grid; \ + CUR.func_round = (TRound_Function)Round_Down_To_Grid; + + +#define DO_ROFF \ + CUR.GS.round_state = TT_Round_Off; \ + CUR.func_round = (TRound_Function)Round_None; + + +#define DO_SROUND \ + SET_SuperRound( 0x4000L, args[0] ); \ + CUR.GS.round_state = TT_Round_Super; \ + CUR.func_round = (TRound_Function)Round_Super; + + +#define DO_S45ROUND \ + SET_SuperRound( 0x2D41L, args[0] ); \ + CUR.GS.round_state = TT_Round_Super_45; \ + CUR.func_round = (TRound_Function)Round_Super_45; + + +#define DO_SLOOP \ + if ( args[0] < 0 ) \ + CUR.error = TT_Err_Bad_Argument; \ + else \ + CUR.GS.loop = args[0]; + + +#define DO_SMD \ + CUR.GS.minimum_distance = (TT_F26Dot6)args[0]; + + +#define DO_SCVTCI \ + CUR.GS.control_value_cutin = (TT_F26Dot6)args[0]; + + +#define DO_SSWCI \ + CUR.GS.single_width_cutin = (TT_F26Dot6)args[0]; + + + /* XXX : UNDOCUMENTED! or bug in the Windows engine? */ + /* */ + /* It seems that the value that is read here is */ + /* expressed in 16.16 format, rather than in */ + /* font units.. */ + /* */ +#define DO_SSW \ + CUR.GS.single_width_value = (TT_F26Dot6)(args[0] >> 10); + + +#define DO_FLIPON \ + CUR.GS.auto_flip = TRUE; + + +#define DO_FLIPOFF \ + CUR.GS.auto_flip = FALSE; + + +#define DO_SDB \ + CUR.GS.delta_base = (Short)args[0]; + + +#define DO_SDS \ + CUR.GS.delta_shift = (Short)args[0]; + + +#define DO_MD /* nothing */ + + +#define DO_MPPEM \ + args[0] = CURRENT_Ppem(); + + +#define DO_MPS \ + args[0] = CUR.metrics.pointSize; + + +#define DO_DUP \ + args[1] = args[0]; + + +#define DO_CLEAR \ + CUR.new_top = 0; + + +#define DO_SWAP \ + { \ + Long L; \ + \ + L = args[0]; \ + args[0] = args[1]; \ + args[1] = L; \ + } + + +#define DO_DEPTH \ + args[0] = CUR.top; + + +#define DO_CINDEX \ + { \ + Long L; \ + \ + \ + L = args[0]; \ + \ + if ( L <= 0 || L > CUR.args ) \ + CUR.error = TT_Err_Invalid_Reference; \ + else \ + args[0] = CUR.stack[CUR.args - L]; \ + } + + +#define DO_JROT \ + if ( args[1] != 0 ) \ + { \ + CUR.IP += args[0]; \ + CUR.step_ins = FALSE; \ + } + + +#define DO_JMPR \ + CUR.IP += args[0]; \ + CUR.step_ins = FALSE; + + +#define DO_JROF \ + if ( args[1] == 0 ) \ + { \ + CUR.IP += args[0]; \ + CUR.step_ins = FALSE; \ + } + + +#define DO_LT \ + args[0] = (args[0] < args[1]); + + +#define DO_LTEQ \ + args[0] = (args[0] <= args[1]); + + +#define DO_GT \ + args[0] = (args[0] > args[1]); + + +#define DO_GTEQ \ + args[0] = (args[0] >= args[1]); + + +#define DO_EQ \ + args[0] = (args[0] == args[1]); + + +#define DO_NEQ \ + args[0] = (args[0] != args[1]); + + +#define DO_ODD \ + args[0] = ( (CUR_Func_round( args[0], 0 ) & 127) == 64 ); + + +#define DO_EVEN \ + args[0] = ( (CUR_Func_round( args[0], 0 ) & 127) == 0 ); + + +#define DO_AND \ + args[0] = ( args[0] && args[1] ); + + +#define DO_OR \ + args[0] = ( args[0] || args[1] ); + + +#define DO_NOT \ + args[0] = !args[0]; + + +#define DO_ADD \ + args[0] += args[1]; + + +#define DO_SUB \ + args[0] -= args[1]; + + +#define DO_DIV \ + if ( args[1] == 0 ) \ + CUR.error = TT_Err_Divide_By_Zero; \ + else \ + args[0] = TT_MulDiv( args[0], 64L, args[1] ); + + +#define DO_MUL \ + args[0] = TT_MulDiv( args[0], args[1], 64L ); + + +#define DO_ABS \ + args[0] = ABS( args[0] ); + + +#define DO_NEG \ + args[0] = -args[0]; + + +#define DO_FLOOR \ + args[0] &= -64; + + +#define DO_CEILING \ + args[0] = (args[0] + 63) & (-64); + + +#define DO_RS \ + { \ + ULong I = (ULong)args[0]; \ + if ( BOUNDS( I, CUR.storeSize ) ) \ + { \ + if ( CUR.pedantic_hinting ) \ + { \ + ARRAY_BOUND_ERROR; \ + } \ + else \ + args[0] = 0; \ + } \ + else \ + args[0] = CUR.storage[I]; \ + } + + +#define DO_WS \ + { \ + ULong I = (ULong)args[0]; \ + if ( BOUNDS( I, CUR.storeSize ) ) \ + { \ + if ( CUR.pedantic_hinting ) \ + { \ + ARRAY_BOUND_ERROR; \ + } \ + } \ + else \ + CUR.storage[I] = args[1]; \ + } + + + +#define DO_RCVT \ + { \ + ULong I = (ULong)args[0]; \ + if ( BOUNDS( I, CUR.cvtSize ) ) \ + { \ + if ( CUR.pedantic_hinting ) \ + { \ + ARRAY_BOUND_ERROR; \ + } \ + else \ + args[0] = 0; \ + } \ + else \ + args[0] = CUR_Func_read_cvt(I); \ + } + + +#define DO_WCVTP \ + { \ + ULong I = (ULong)args[0]; \ + if ( BOUNDS( I, CUR.cvtSize ) ) \ + { \ + if ( CUR.pedantic_hinting ) \ + { \ + ARRAY_BOUND_ERROR; \ + } \ + } \ + else \ + CUR_Func_write_cvt( I, args[1] ); \ + } + + +#define DO_WCVTF \ + { \ + ULong I = (ULong)args[0]; \ + if ( BOUNDS( I, CUR.cvtSize ) ) \ + { \ + if ( CUR.pedantic_hinting ) \ + { \ + ARRAY_BOUND_ERROR; \ + } \ + } \ + else \ + CUR.cvt[I] = FUnits_To_Pixels( EXEC_ARGS (Short)args[1] ); \ + } + + +#define DO_DEBUG \ + CUR.error = TT_Err_Debug_OpCode; + + +#define DO_ROUND \ + args[0] = CUR_Func_round( args[0], \ + CUR.metrics.compensations[CUR.opcode-0x68] ); + + +#define DO_NROUND \ + args[0] = Round_None( EXEC_ARGS \ + args[0], \ + CUR.metrics.compensations[CUR.opcode - 0x6C] ); + + +#define DO_MAX \ + if ( args[1] > args[0] ) \ + args[0] = args[1]; + + +#define DO_MIN \ + if ( args[1] < args[0] ) \ + args[0] = args[1]; + + +#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH + + +#undef ARRAY_BOUND_ERROR +#define ARRAY_BOUND_ERROR \ + { \ + CUR.error = TT_Err_Invalid_Reference; \ + return; \ + } + + +/*******************************************/ +/* SVTCA[a] : Set F and P vectors to axis */ +/* CodeRange : $00-$01 */ +/* Stack : --> */ + + static void Ins_SVTCA( INS_ARG ) + { + DO_SVTCA + } + + +/*******************************************/ +/* SPVTCA[a] : Set PVector to Axis */ +/* CodeRange : $02-$03 */ +/* Stack : --> */ + + static void Ins_SPVTCA( INS_ARG ) + { + DO_SPVTCA + } + + +/*******************************************/ +/* SFVTCA[a] : Set FVector to Axis */ +/* CodeRange : $04-$05 */ +/* Stack : --> */ + + static void Ins_SFVTCA( INS_ARG ) + { + DO_SFVTCA + } + +/*******************************************/ +/* SPVTL[a] : Set PVector to Line */ +/* CodeRange : $06-$07 */ +/* Stack : uint32 uint32 --> */ + + static void Ins_SPVTL( INS_ARG ) + { + DO_SPVTL + } + + +/*******************************************/ +/* SFVTL[a] : Set FVector to Line */ +/* CodeRange : $08-$09 */ +/* Stack : uint32 uint32 --> */ + + static void Ins_SFVTL( INS_ARG ) + { + DO_SFVTL + } + + +/*******************************************/ +/* SFVTPV[] : Set FVector to PVector */ +/* CodeRange : $0E */ +/* Stack : --> */ + + static void Ins_SFVTPV( INS_ARG ) + { + DO_SFVTPV + } + + +/*******************************************/ +/* SPVFS[] : Set PVector From Stack */ +/* CodeRange : $0A */ +/* Stack : f2.14 f2.14 --> */ + + static void Ins_SPVFS( INS_ARG ) + { + DO_SPVFS + } + + +/*******************************************/ +/* SFVFS[] : Set FVector From Stack */ +/* CodeRange : $0B */ +/* Stack : f2.14 f2.14 --> */ + + static void Ins_SFVFS( INS_ARG ) + { + DO_SFVFS + } + + +/*******************************************/ +/* GPV[] : Get Projection Vector */ +/* CodeRange : $0C */ +/* Stack : ef2.14 --> ef2.14 */ + + static void Ins_GPV( INS_ARG ) + { + DO_GPV + } + + +/*******************************************/ +/* GFV[] : Get Freedom Vector */ +/* CodeRange : $0D */ +/* Stack : ef2.14 --> ef2.14 */ + + static void Ins_GFV( INS_ARG ) + { + DO_GFV + } + + +/*******************************************/ +/* SRP0[] : Set Reference Point 0 */ +/* CodeRange : $10 */ +/* Stack : uint32 --> */ + + static void Ins_SRP0( INS_ARG ) + { + DO_SRP0 + } + + +/*******************************************/ +/* SRP1[] : Set Reference Point 1 */ +/* CodeRange : $11 */ +/* Stack : uint32 --> */ + + static void Ins_SRP1( INS_ARG ) + { + DO_SRP1 + } + + +/*******************************************/ +/* SRP2[] : Set Reference Point 2 */ +/* CodeRange : $12 */ +/* Stack : uint32 --> */ + + static void Ins_SRP2( INS_ARG ) + { + DO_SRP2 + } + + +/*******************************************/ +/* RTHG[] : Round To Half Grid */ +/* CodeRange : $19 */ +/* Stack : --> */ + + static void Ins_RTHG( INS_ARG ) + { + DO_RTHG + } + + +/*******************************************/ +/* RTG[] : Round To Grid */ +/* CodeRange : $18 */ +/* Stack : --> */ + + static void Ins_RTG( INS_ARG ) + { + DO_RTG + } + + +/*******************************************/ +/* RTDG[] : Round To Double Grid */ +/* CodeRange : $3D */ +/* Stack : --> */ + + static void Ins_RTDG( INS_ARG ) + { + DO_RTDG + } + + +/*******************************************/ +/* RUTG[] : Round Up To Grid */ +/* CodeRange : $7C */ +/* Stack : --> */ + + static void Ins_RUTG( INS_ARG ) + { + DO_RUTG + } + + +/*******************************************/ +/* RDTG[] : Round Down To Grid */ +/* CodeRange : $7D */ +/* Stack : --> */ + + static void Ins_RDTG( INS_ARG ) + { + DO_RDTG + } + + +/*******************************************/ +/* ROFF[] : Round OFF */ +/* CodeRange : $7A */ +/* Stack : --> */ + + static void Ins_ROFF( INS_ARG ) + { + DO_ROFF + } + + +/*******************************************/ +/* SROUND[] : Super ROUND */ +/* CodeRange : $76 */ +/* Stack : Eint8 --> */ + + static void Ins_SROUND( INS_ARG ) + { + DO_SROUND + } + + +/*******************************************/ +/* S45ROUND[]: Super ROUND 45 degrees */ +/* CodeRange : $77 */ +/* Stack : uint32 --> */ + + static void Ins_S45ROUND( INS_ARG ) + { + DO_S45ROUND + } + + +/*******************************************/ +/* SLOOP[] : Set LOOP variable */ +/* CodeRange : $17 */ +/* Stack : int32? --> */ + + static void Ins_SLOOP( INS_ARG ) + { + DO_SLOOP + } + + +/*******************************************/ +/* SMD[] : Set Minimum Distance */ +/* CodeRange : $1A */ +/* Stack : f26.6 --> */ + + static void Ins_SMD( INS_ARG ) + { + DO_SMD + } + + +/**********************************************/ +/* SCVTCI[] : Set Control Value Table Cut In */ +/* CodeRange : $1D */ +/* Stack : f26.6 --> */ + + static void Ins_SCVTCI( INS_ARG ) + { + DO_SCVTCI + } + + +/**********************************************/ +/* SSWCI[] : Set Single Width Cut In */ +/* CodeRange : $1E */ +/* Stack : f26.6 --> */ + + static void Ins_SSWCI( INS_ARG ) + { + DO_SSWCI + } + + +/**********************************************/ +/* SSW[] : Set Single Width */ +/* CodeRange : $1F */ +/* Stack : int32? --> */ + + static void Ins_SSW( INS_ARG ) + { + DO_SSW + } + + +/**********************************************/ +/* FLIPON[] : Set Auto_flip to On */ +/* CodeRange : $4D */ +/* Stack : --> */ + + static void Ins_FLIPON( INS_ARG ) + { + DO_FLIPON + } + + +/**********************************************/ +/* FLIPOFF[] : Set Auto_flip to Off */ +/* CodeRange : $4E */ +/* Stack : --> */ + + static void Ins_FLIPOFF( INS_ARG ) + { + DO_FLIPOFF + } + + +/**********************************************/ +/* SANGW[] : Set Angle Weight */ +/* CodeRange : $7E */ +/* Stack : uint32 --> */ + + static void Ins_SANGW( INS_ARG ) + { + /* instruction not supported anymore */ + } + + +/**********************************************/ +/* SDB[] : Set Delta Base */ +/* CodeRange : $5E */ +/* Stack : uint32 --> */ + + static void Ins_SDB( INS_ARG ) + { + DO_SDB + } + + +/**********************************************/ +/* SDS[] : Set Delta Shift */ +/* CodeRange : $5F */ +/* Stack : uint32 --> */ + + static void Ins_SDS( INS_ARG ) + { + DO_SDS + } + + +/**********************************************/ +/* MPPEM[] : Measure Pixel Per EM */ +/* CodeRange : $4B */ +/* Stack : --> Euint16 */ + + static void Ins_MPPEM( INS_ARG ) + { + DO_MPPEM + } + + +/**********************************************/ +/* MPS[] : Measure PointSize */ +/* CodeRange : $4C */ +/* Stack : --> Euint16 */ + + static void Ins_MPS( INS_ARG ) + { + DO_MPS + } + +/*******************************************/ +/* DUP[] : Duplicate top stack element */ +/* CodeRange : $20 */ +/* Stack : StkElt --> StkElt StkElt */ + + static void Ins_DUP( INS_ARG ) + { + DO_DUP + } + + +/*******************************************/ +/* POP[] : POPs the stack's top elt. */ +/* CodeRange : $21 */ +/* Stack : StkElt --> */ + + static void Ins_POP( INS_ARG ) + { + /* nothing to do */ + } + + +/*******************************************/ +/* CLEAR[] : Clear the entire stack */ +/* CodeRange : $22 */ +/* Stack : StkElt... --> */ + + static void Ins_CLEAR( INS_ARG ) + { + DO_CLEAR + } + + +/*******************************************/ +/* SWAP[] : Swap the top two elements */ +/* CodeRange : $23 */ +/* Stack : 2 * StkElt --> 2 * StkElt */ + + static void Ins_SWAP( INS_ARG ) + { + DO_SWAP + } + + +/*******************************************/ +/* DEPTH[] : return the stack depth */ +/* CodeRange : $24 */ +/* Stack : --> uint32 */ + + static void Ins_DEPTH( INS_ARG ) + { + DO_DEPTH + } + + +/*******************************************/ +/* CINDEX[] : copy indexed element */ +/* CodeRange : $25 */ +/* Stack : int32 --> StkElt */ + + static void Ins_CINDEX( INS_ARG ) + { + DO_CINDEX + } + + +/*******************************************/ +/* EIF[] : End IF */ +/* CodeRange : $59 */ +/* Stack : --> */ + + static void Ins_EIF( INS_ARG ) + { + /* nothing to do */ + } + + +/*******************************************/ +/* JROT[] : Jump Relative On True */ +/* CodeRange : $78 */ +/* Stack : StkElt int32 --> */ + + static void Ins_JROT( INS_ARG ) + { + DO_JROT + } + + +/*******************************************/ +/* JMPR[] : JuMP Relative */ +/* CodeRange : $1C */ +/* Stack : int32 --> */ + + static void Ins_JMPR( INS_ARG ) + { + DO_JMPR + } + + +/*******************************************/ +/* JROF[] : Jump Relative On False */ +/* CodeRange : $79 */ +/* Stack : StkElt int32 --> */ + + static void Ins_JROF( INS_ARG ) + { + DO_JROF + } + + +/*******************************************/ +/* LT[] : Less Than */ +/* CodeRange : $50 */ +/* Stack : int32? int32? --> bool */ + + static void Ins_LT( INS_ARG ) + { + DO_LT + } + + +/*******************************************/ +/* LTEQ[] : Less Than or EQual */ +/* CodeRange : $51 */ +/* Stack : int32? int32? --> bool */ + + static void Ins_LTEQ( INS_ARG ) + { + DO_LTEQ + } + + +/*******************************************/ +/* GT[] : Greater Than */ +/* CodeRange : $52 */ +/* Stack : int32? int32? --> bool */ + + static void Ins_GT( INS_ARG ) + { + DO_GT + } + + +/*******************************************/ +/* GTEQ[] : Greater Than or EQual */ +/* CodeRange : $53 */ +/* Stack : int32? int32? --> bool */ + + static void Ins_GTEQ( INS_ARG ) + { + DO_GTEQ + } + + +/*******************************************/ +/* EQ[] : EQual */ +/* CodeRange : $54 */ +/* Stack : StkElt StkElt --> bool */ + + static void Ins_EQ( INS_ARG ) + { + DO_EQ + } + + +/*******************************************/ +/* NEQ[] : Not EQual */ +/* CodeRange : $55 */ +/* Stack : StkElt StkElt --> bool */ + + static void Ins_NEQ( INS_ARG ) + { + DO_NEQ + } + + +/*******************************************/ +/* ODD[] : Odd */ +/* CodeRange : $56 */ +/* Stack : f26.6 --> bool */ + + static void Ins_ODD( INS_ARG ) + { + DO_ODD + } + + +/*******************************************/ +/* EVEN[] : Even */ +/* CodeRange : $57 */ +/* Stack : f26.6 --> bool */ + + static void Ins_EVEN( INS_ARG ) + { + DO_EVEN + } + + +/*******************************************/ +/* AND[] : logical AND */ +/* CodeRange : $5A */ +/* Stack : uint32 uint32 --> uint32 */ + + static void Ins_AND( INS_ARG ) + { + DO_AND + } + + +/*******************************************/ +/* OR[] : logical OR */ +/* CodeRange : $5B */ +/* Stack : uint32 uint32 --> uint32 */ + + static void Ins_OR( INS_ARG ) + { + DO_OR + } + + +/*******************************************/ +/* NOT[] : logical NOT */ +/* CodeRange : $5C */ +/* Stack : StkElt --> uint32 */ + + static void Ins_NOT( INS_ARG ) + { + DO_NOT + } + + +/*******************************************/ +/* ADD[] : ADD */ +/* CodeRange : $60 */ +/* Stack : f26.6 f26.6 --> f26.6 */ + + static void Ins_ADD( INS_ARG ) + { + DO_ADD + } + + +/*******************************************/ +/* SUB[] : SUBstract */ +/* CodeRange : $61 */ +/* Stack : f26.6 f26.6 --> f26.6 */ + + static void Ins_SUB( INS_ARG ) + { + DO_SUB + } + + +/*******************************************/ +/* DIV[] : DIVide */ +/* CodeRange : $62 */ +/* Stack : f26.6 f26.6 --> f26.6 */ + + static void Ins_DIV( INS_ARG ) + { + DO_DIV + } + + +/*******************************************/ +/* MUL[] : MULtiply */ +/* CodeRange : $63 */ +/* Stack : f26.6 f26.6 --> f26.6 */ + + static void Ins_MUL( INS_ARG ) + { + DO_MUL + } + + +/*******************************************/ +/* ABS[] : ABSolute value */ +/* CodeRange : $64 */ +/* Stack : f26.6 --> f26.6 */ + + static void Ins_ABS( INS_ARG ) + { + DO_ABS + } + + +/*******************************************/ +/* NEG[] : NEGate */ +/* CodeRange : $65 */ +/* Stack : f26.6 --> f26.6 */ + + static void Ins_NEG( INS_ARG ) + { + DO_NEG + } + + +/*******************************************/ +/* FLOOR[] : FLOOR */ +/* CodeRange : $66 */ +/* Stack : f26.6 --> f26.6 */ + + static void Ins_FLOOR( INS_ARG ) + { + DO_FLOOR + } + + +/*******************************************/ +/* CEILING[] : CEILING */ +/* CodeRange : $67 */ +/* f26.6 --> f26.6 */ + + static void Ins_CEILING( INS_ARG ) + { + DO_CEILING + } + +/*******************************************/ +/* RS[] : Read Store */ +/* CodeRange : $43 */ +/* Stack : uint32 --> uint32 */ + + static void Ins_RS( INS_ARG ) + { + DO_RS + } + + +/*******************************************/ +/* WS[] : Write Store */ +/* CodeRange : $42 */ +/* Stack : uint32 uint32 --> */ + + static void Ins_WS( INS_ARG ) + { + DO_WS + } + + +/*******************************************/ +/* WCVTP[] : Write CVT in Pixel units */ +/* CodeRange : $44 */ +/* Stack : f26.6 uint32 --> */ + + static void Ins_WCVTP( INS_ARG ) + { + DO_WCVTP + } + + +/*******************************************/ +/* WCVTF[] : Write CVT in FUnits */ +/* CodeRange : $70 */ +/* Stack : uint32 uint32 --> */ + + static void Ins_WCVTF( INS_ARG ) + { + DO_WCVTF + } + + +/*******************************************/ +/* RCVT[] : Read CVT */ +/* CodeRange : $45 */ +/* Stack : uint32 --> f26.6 */ + + static void Ins_RCVT( INS_ARG ) + { + DO_RCVT + } + + +/********************************************/ +/* AA[] : Adjust Angle */ +/* CodeRange : $7F */ +/* Stack : uint32 --> */ + + static void Ins_AA( INS_ARG ) + { + /* Intentional - no longer supported */ + } + + +/********************************************/ +/* DEBUG[] : DEBUG. Unsupported */ +/* CodeRange : $4F */ +/* Stack : uint32 --> */ + +/* NOTE : The original instruction pops a value from the stack */ + + static void Ins_DEBUG( INS_ARG ) + { + DO_DEBUG + } + +/*******************************************/ +/* ROUND[ab] : ROUND value */ +/* CodeRange : $68-$6B */ +/* Stack : f26.6 --> f26.6 */ + + static void Ins_ROUND( INS_ARG ) + { + DO_ROUND + } + +/*******************************************/ +/* NROUND[ab]: No ROUNDing of value */ +/* CodeRange : $6C-$6F */ +/* Stack : f26.6 --> f26.6 */ + + static void Ins_NROUND( INS_ARG ) + { + DO_NROUND + } + + + +/*******************************************/ +/* MAX[] : MAXimum */ +/* CodeRange : $68 */ +/* Stack : int32? int32? --> int32 */ + + static void Ins_MAX( INS_ARG ) + { + DO_MAX + } + + +/*******************************************/ +/* MIN[] : MINimum */ +/* CodeRange : $69 */ +/* Stack : int32? int32? --> int32 */ + + static void Ins_MIN( INS_ARG ) + { + DO_MIN + } + + +#endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */ + + +/* The following functions are called as is within the switch statement */ + +/*******************************************/ +/* MINDEX[] : move indexed element */ +/* CodeRange : $26 */ +/* Stack : int32? --> StkElt */ + + static void Ins_MINDEX( INS_ARG ) + { + Long L, K; + + + L = args[0]; + + if ( L <= 0 || L > CUR.args ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + + K = CUR.stack[CUR.args - L]; + + MEM_Move( (&CUR.stack[CUR.args - L ]), + (&CUR.stack[CUR.args - L + 1]), + (L - 1) * sizeof ( Long ) ); + + CUR.stack[CUR.args - 1] = K; + } + + +/*******************************************/ +/* ROLL[] : roll top three elements */ +/* CodeRange : $8A */ +/* Stack : 3 * StkElt --> 3 * StkElt */ + + static void Ins_ROLL( INS_ARG ) + { + Long A, B, C; + + + A = args[2]; + B = args[1]; + C = args[0]; + + args[2] = C; + args[1] = A; + args[0] = B; + } + + + +/****************************************************************/ +/* */ +/* MANAGING THE FLOW OF CONTROL */ +/* */ +/* Instructions appear in the specs' order. */ +/* */ +/****************************************************************/ + + static Bool SkipCode( EXEC_OP ) + { + CUR.IP += CUR.length; + + if ( CUR.IP < CUR.codeSize ) + if ( CALC_Length() == SUCCESS ) + return SUCCESS; + + CUR.error = TT_Err_Code_Overflow; + return FAILURE; + } + + +/*******************************************/ +/* IF[] : IF test */ +/* CodeRange : $58 */ +/* Stack : StkElt --> */ + + static void Ins_IF( INS_ARG ) + { + Int nIfs; + Bool Out; + + + if ( args[0] != 0 ) + return; + + nIfs = 1; + Out = 0; + + do + { + if ( SKIP_Code() == FAILURE ) + return; + + switch ( CUR.opcode ) + { + case 0x58: /* IF */ + nIfs++; + break; + + case 0x1b: /* ELSE */ + Out = (nIfs == 1); + break; + + case 0x59: /* EIF */ + nIfs--; + Out = (nIfs == 0); + break; + } + } while ( Out == 0 ); + } + + +/*******************************************/ +/* ELSE[] : ELSE */ +/* CodeRange : $1B */ +/* Stack : --> */ + + static void Ins_ELSE( INS_ARG ) + { + Int nIfs; + + + nIfs = 1; + + do + { + if ( SKIP_Code() == FAILURE ) + return; + + switch ( CUR.opcode ) + { + case 0x58: /* IF */ + nIfs++; + break; + + case 0x59: /* EIF */ + nIfs--; + break; + } + } while ( nIfs != 0 ); + } + + +/****************************************************************/ +/* */ +/* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS */ +/* */ +/* Instructions appear in the specs' order. */ +/* */ +/****************************************************************/ + + static PDefRecord Locate_FDef( EXEC_OPS Int n, Bool new_def ) + { + PDefRecord def; + UShort hash; + UShort cnt; + + /* The function table is interpreted as a simple hash table */ + /* with indexes computed modulo maxFDefs and the linear search */ + /* of free cells in the case of a collision. */ + /* Except for some old Apple fonts, all functions in a TrueType */ + /* font fit into 0..maxFDefs - 1 range and the lookup is */ + /* reduced to a single step. */ + + /* Minor optimization. */ + if ( !new_def && ( n < 0 || n > CUR.maxFunc ) ) + return NULL; + + for ( cnt = 0; cnt < CUR.maxFDefs; ++cnt ) + { + hash = ( (UShort)n + cnt ) % CUR.maxFDefs; + def = &CUR.FDefs[ hash ]; + if ( !def->Active ) + return new_def ? def : NULL; + if ( def->Opc == n ) + return def; + } + + /* The table is full and the entry has not been found. */ + return NULL; + } + + +/*******************************************/ +/* FDEF[] : Function DEFinition */ +/* CodeRange : $2C */ +/* Stack : uint32 --> */ + + static void Ins_FDEF( INS_ARG ) + { + Int n; + PDefRecord def; + + + /* check that there is enough room */ + if ( CUR.numFDefs >= CUR.maxFDefs ) + { + /* We could introduce a new error message, but we're too close */ + /* from the release to change all the 'po' files again.. */ + CUR.error = TT_Err_Too_Many_Ins; + return; + } + + n = (Int)args[0]; + if ( n < 0 || (ULong)n != args[0] ) + { + /* Gotcha. Function index is uint32 according to the specs */ + /* but TDefRecord.Opc is defined as Int. We cannot store */ + /* the definition of this function. */ + CUR.error = TT_Err_Bad_Argument; + return; + } + + def = Locate_FDef( EXEC_ARGS n, TRUE ); + if ( !def ) + { + /* Oh, oh. Something is wrong. Locate_FDef should never fail here. */ + CUR.error = TT_Err_Too_Many_Ins; + return; + } + + /* Some font programs are broken enough to redefine functions! */ + if ( !def->Active ) + CUR.numFDefs++; + + def->Range = CUR.curRange; + def->Opc = n; + def->Start = CUR.IP + 1; + def->Active = TRUE; + + if ( n > CUR.maxFunc ) + CUR.maxFunc = n; + + /* Now skip the whole function definition. */ + /* We don't allow nested IDEFS & FDEFs. */ + + while ( SKIP_Code() == SUCCESS ) + { + switch ( CUR.opcode ) + { + case 0x89: /* IDEF */ + case 0x2c: /* FDEF */ + CUR.error = TT_Err_Nested_DEFS; + return; + case 0x2d: /* ENDF */ + return; + } + } + } + + +/*******************************************/ +/* ENDF[] : END Function definition */ +/* CodeRange : $2D */ +/* Stack : --> */ + + static void Ins_ENDF( INS_ARG ) + { + PCallRecord pRec; + + + if ( CUR.callTop <= 0 ) /* We encountered an ENDF without a call */ + { + CUR.error = TT_Err_ENDF_In_Exec_Stream; + return; + } + + CUR.callTop--; + + pRec = &CUR.callStack[CUR.callTop]; + + pRec->Cur_Count--; + + CUR.step_ins = FALSE; + + if ( pRec->Cur_Count > 0 ) + { + CUR.callTop++; + CUR.IP = pRec->Cur_Restart; + } + else + /* Loop through the current function */ + INS_Goto_CodeRange( pRec->Caller_Range, + pRec->Caller_IP ); + + /* Exit the current call frame. */ + + /* NOTE: When the last intruction of a program */ + /* is a CALL or LOOPCALL, the return address */ + /* is always out of the code range. This is */ + /* a valid address, and it's why we do not test */ + /* the result of Ins_Goto_CodeRange() here! */ + } + + +/*******************************************/ +/* CALL[] : CALL function */ +/* CodeRange : $2B */ +/* Stack : uint32? --> */ + + static void Ins_CALL( INS_ARG ) + { + Int n; + PDefRecord def; + PCallRecord pCrec; + + + n = (Int)args[0]; + def = Locate_FDef( EXEC_ARGS n, FALSE ); + if ( !def ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + + /* check call stack */ + if ( CUR.callTop >= CUR.callSize ) + { + CUR.error = TT_Err_Stack_Overflow; + return; + } + + pCrec = CUR.callStack + CUR.callTop; + + pCrec->Caller_Range = CUR.curRange; + pCrec->Caller_IP = CUR.IP + 1; + pCrec->Cur_Count = 1; + pCrec->Cur_Restart = def->Start; + + CUR.callTop++; + + INS_Goto_CodeRange( def->Range, + def->Start ); + + CUR.step_ins = FALSE; + } + + +/*******************************************/ +/* LOOPCALL[]: LOOP and CALL function */ +/* CodeRange : $2A */ +/* Stack : uint32? Eint16? --> */ + + static void Ins_LOOPCALL( INS_ARG ) + { + Int n; + Long count; + PDefRecord def; + PCallRecord pTCR; + + + n = (Int)args[1]; + def = Locate_FDef( EXEC_ARGS n, FALSE ); + if ( !def ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + + if ( CUR.callTop >= CUR.callSize ) + { + CUR.error = TT_Err_Stack_Overflow; + return; + } + + count = (Long)args[0]; + if ( count <= 0 ) + return; + + pTCR = &CUR.callStack[CUR.callTop]; + + pTCR->Caller_Range = CUR.curRange; + pTCR->Caller_IP = CUR.IP + 1; + pTCR->Cur_Count = count; + pTCR->Cur_Restart = def->Start; + + CUR.callTop++; + + INS_Goto_CodeRange( def->Range, + def->Start ); + + CUR.step_ins = FALSE; + } + + +/*******************************************/ +/* IDEF[] : Instruction DEFinition */ +/* CodeRange : $89 */ +/* Stack : Eint8 --> */ + + static void Ins_IDEF( INS_ARG ) + { + Byte opcode; + PDefRecord def; + PDefRecord limit; + + + opcode = (Byte)args[0]; + + /* First of all, look for the same instruction in our table */ + def = CUR.IDefs; + limit = def + CUR.numIDefs; + for ( ; def < limit; def++ ) + if ( def->Opc == opcode ) + break; + + if ( def == limit ) + { + /* check that there is enough room for a new instruction */ + if ( CUR.numIDefs >= CUR.maxIDefs ) + { + /* XXX Bad error code. See FDEF[]. */ + CUR.error = TT_Err_Too_Many_Ins; + return; + } + CUR.numIDefs++; + } + + def->Opc = opcode; + def->Start = CUR.IP + 1; + def->Range = CUR.curRange; + def->Active = TRUE; + + if ( opcode > CUR.maxIns ) + CUR.maxIns = opcode; + + /* Now skip the whole function definition */ + /* We don't allow nested IDEFs & FDEFs. */ + + while ( SKIP_Code() == SUCCESS ) + { + switch ( CUR.opcode ) + { + case 0x89: /* IDEF */ + case 0x2c: /* FDEF */ + CUR.error = TT_Err_Nested_DEFS; + return; + case 0x2d: /* ENDF */ + return; + } + } + } + + +/****************************************************************/ +/* */ +/* PUSHING DATA ONTO THE INTERPRETER STACK */ +/* */ +/* Instructions appear in the specs' order. */ +/* */ +/****************************************************************/ + +/*******************************************/ +/* NPUSHB[] : PUSH N Bytes */ +/* CodeRange : $40 */ +/* Stack : --> uint32... */ + + static void Ins_NPUSHB( INS_ARG ) + { + UShort L, K; + + + L = (UShort)CUR.code[CUR.IP + 1]; + + if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) + { + CUR.error = TT_Err_Stack_Overflow; + return; + } + + for ( K = 1; K <= L; K++ ) + args[K - 1] = CUR.code[CUR.IP + K + 1]; + + CUR.new_top += L; + } + + +/*******************************************/ +/* NPUSHW[] : PUSH N Words */ +/* CodeRange : $41 */ +/* Stack : --> int32... */ + + static void Ins_NPUSHW( INS_ARG ) + { + UShort L, K; + + + L = (UShort)CUR.code[CUR.IP + 1]; + + if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) + { + CUR.error = TT_Err_Stack_Overflow; + return; + } + + CUR.IP += 2; + + for ( K = 0; K < L; K++ ) + args[K] = GET_ShortIns(); + + CUR.step_ins = FALSE; + CUR.new_top += L; + } + + +/*******************************************/ +/* PUSHB[abc]: PUSH Bytes */ +/* CodeRange : $B0-$B7 */ +/* Stack : --> uint32... */ + + static void Ins_PUSHB( INS_ARG ) + { + UShort L, K; + + + L = (UShort)CUR.opcode - 0xB0 + 1; + + if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) + { + CUR.error = TT_Err_Stack_Overflow; + return; + } + + for ( K = 1; K <= L; K++ ) + args[K - 1] = CUR.code[CUR.IP + K]; + } + + +/*******************************************/ +/* PUSHW[abc]: PUSH Words */ +/* CodeRange : $B8-$BF */ +/* Stack : --> int32... */ + + static void Ins_PUSHW( INS_ARG ) + { + UShort L, K; + + + L = (UShort)CUR.opcode - 0xB8 + 1; + + if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) + { + CUR.error = TT_Err_Stack_Overflow; + return; + } + + CUR.IP++; + + for ( K = 0; K < L; K++ ) + args[K] = GET_ShortIns(); + + CUR.step_ins = FALSE; + } + + + +/****************************************************************/ +/* */ +/* MANAGING THE GRAPHICS STATE */ +/* */ +/* Instructions appear in the specs' order. */ +/* */ +/****************************************************************/ + +/**********************************************/ +/* GC[a] : Get Coordinate projected onto */ +/* CodeRange : $46-$47 */ +/* Stack : uint32 --> f26.6 */ + +/* BULLSHIT: Measures from the original glyph must be taken */ +/* along the dual projection vector! */ + + static void Ins_GC( INS_ARG ) + { + ULong L; + TT_F26Dot6 R; + + + L = (ULong)args[0]; + + if ( BOUNDS( L, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + else + R = 0; + } + else + { + if ( CUR.opcode & 1 ) + R = CUR_Func_dualproj( CUR.zp2.org + L, NULL_Vector ); + else + R = CUR_Func_project( CUR.zp2.cur + L, NULL_Vector ); + } + + args[0] = R; + } + + +/**********************************************/ +/* SCFS[] : Set Coordinate From Stack */ +/* CodeRange : $48 */ +/* Stack : f26.6 uint32 --> */ +/* */ +/* Formula: */ +/* */ +/* OA := OA + ( value - OA.p )/( f.p ) * f */ +/* */ + + static void Ins_SCFS( INS_ARG ) + { + Long K; + UShort L; + + + L = (UShort)args[0]; + + if ( BOUNDS( L, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + K = CUR_Func_project( CUR.zp2.cur + L, NULL_Vector ); + + CUR_Func_move( &CUR.zp2, L, args[1] - K ); + + /* not part of the specs, but here for safety */ + + if ( CUR.GS.gep2 == 0 ) + CUR.zp2.org[L] = CUR.zp2.cur[L]; + } + + +/**********************************************/ +/* MD[a] : Measure Distance */ +/* CodeRange : $49-$4A */ +/* Stack : uint32 uint32 --> f26.6 */ + +/* BULLSHIT: Measure taken in the original glyph must be along */ +/* the dual projection vector. */ + +/* Second BULLSHIT: Flag attributes are inverted! */ +/* 0 => measure distance in original outline */ +/* 1 => measure distance in grid-fitted outline */ + +/* Third one !! : zp0 - zp1, and not "zp2 - zp1" !!! */ +/* */ + + static void Ins_MD( INS_ARG ) + { + UShort K, L; + TT_F26Dot6 D; + + + K = (UShort)args[1]; + L = (UShort)args[0]; + + if( BOUNDS( L, CUR.zp0.n_points ) || + BOUNDS( K, CUR.zp1.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + else + D = 0; + } + else + { + if ( CUR.opcode & 1 ) + D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K ); + else + D = CUR_Func_dualproj( CUR.zp0.org + L, CUR.zp1.org + K ); + } + + args[0] = D; + } + + +/*******************************************/ +/* SDPVTL[a] : Set Dual PVector to Line */ +/* CodeRange : $86-$87 */ +/* Stack : uint32 uint32 --> */ + + static void Ins_SDPVTL( INS_ARG ) + { + Long A, B, C; + UShort p1, p2; /* was Int in pas type ERROR */ + + + p1 = (UShort)args[1]; + p2 = (UShort)args[0]; + + if ( BOUNDS( p2, CUR.zp1.n_points ) || + BOUNDS( p1, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + { + TT_Vector* v1 = CUR.zp1.org + p2; + TT_Vector* v2 = CUR.zp2.org + p1; + + + A = v1->x - v2->x; + B = v1->y - v2->y; + } + + if ( (CUR.opcode & 1) != 0 ) + { + C = B; /* CounterClockwise rotation */ + B = A; + A = -C; + } + + NORMalize( A, B, &CUR.GS.dualVector ); + + { + TT_Vector* v1 = CUR.zp1.cur + p2; + TT_Vector* v2 = CUR.zp2.cur + p1; + + + A = v1->x - v2->x; + B = v1->y - v2->y; + } + + if ( (CUR.opcode & 1) != 0 ) + { + C = B; /* CounterClockwise rotation */ + B = A; + A = -C; + } + + NORMalize( A, B, &CUR.GS.projVector ); + + COMPUTE_Funcs(); + } + + +/*******************************************/ +/* SZP0[] : Set Zone Pointer 0 */ +/* CodeRange : $13 */ +/* Stack : uint32 --> */ + + static void Ins_SZP0( INS_ARG ) + { + switch ( (Int)args[0] ) + { + case 0: + CUR.zp0 = CUR.twilight; + break; + + case 1: + CUR.zp0 = CUR.pts; + break; + + default: + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + CUR.GS.gep0 = (UShort)args[0]; + } + + +/*******************************************/ +/* SZP1[] : Set Zone Pointer 1 */ +/* CodeRange : $14 */ +/* Stack : uint32 --> */ + + static void Ins_SZP1( INS_ARG ) + { + switch ( (Int)args[0] ) + { + case 0: + CUR.zp1 = CUR.twilight; + break; + + case 1: + CUR.zp1 = CUR.pts; + break; + + default: + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + CUR.GS.gep1 = (UShort)args[0]; + } + + +/*******************************************/ +/* SZP2[] : Set Zone Pointer 2 */ +/* CodeRange : $15 */ +/* Stack : uint32 --> */ + + static void Ins_SZP2( INS_ARG ) + { + switch ( (Int)args[0] ) + { + case 0: + CUR.zp2 = CUR.twilight; + break; + + case 1: + CUR.zp2 = CUR.pts; + break; + + default: + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + CUR.GS.gep2 = (UShort)args[0]; + } + + +/*******************************************/ +/* SZPS[] : Set Zone Pointers */ +/* CodeRange : $16 */ +/* Stack : uint32 --> */ + + static void Ins_SZPS( INS_ARG ) + { + switch ( (Int)args[0] ) + { + case 0: + CUR.zp0 = CUR.twilight; + break; + + case 1: + CUR.zp0 = CUR.pts; + break; + + default: + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + CUR.zp1 = CUR.zp0; + CUR.zp2 = CUR.zp0; + + CUR.GS.gep0 = (UShort)args[0]; + CUR.GS.gep1 = (UShort)args[0]; + CUR.GS.gep2 = (UShort)args[0]; + } + + +/*******************************************/ +/* INSTCTRL[]: INSTruction ConTRol */ +/* CodeRange : $8e */ +/* Stack : int32 int32 --> */ + + static void Ins_INSTCTRL( INS_ARG ) + { + Long K, L; + + + K = args[1]; + L = args[0]; + + if ( K < 1 || K > 2 ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + if ( L != 0 ) + L = K; + + CUR.GS.instruct_control = + (Byte)( CUR.GS.instruct_control & ~(Byte)K ) | (Byte)L; + } + + +/*******************************************/ +/* SCANCTRL[]: SCAN ConTRol */ +/* CodeRange : $85 */ +/* Stack : uint32? --> */ + + static void Ins_SCANCTRL( INS_ARG ) + { + Int A; + + + /* Get Threshold */ + A = (Int)(args[0] & 0xFF); + + if ( A == 0xFF ) + { + CUR.GS.scan_control = TRUE; + return; + } + else if ( A == 0 ) + { + CUR.GS.scan_control = FALSE; + return; + } + + A *= 64; + + if ( (args[0] & 0x100) != 0 && CUR.metrics.pointSize <= A ) + CUR.GS.scan_control = TRUE; + + if ( (args[0] & 0x200) != 0 && CUR.metrics.rotated ) + CUR.GS.scan_control = TRUE; + + if ( (args[0] & 0x400) != 0 && CUR.metrics.stretched ) + CUR.GS.scan_control = TRUE; + + if ( (args[0] & 0x800) != 0 && CUR.metrics.pointSize > A ) + CUR.GS.scan_control = FALSE; + + if ( (args[0] & 0x1000) != 0 && CUR.metrics.rotated ) + CUR.GS.scan_control = FALSE; + + if ( (args[0] & 0x2000) != 0 && CUR.metrics.stretched ) + CUR.GS.scan_control = FALSE; +} + + +/*******************************************/ +/* SCANTYPE[]: SCAN TYPE */ +/* CodeRange : $8D */ +/* Stack : uint32? --> */ + + static void Ins_SCANTYPE( INS_ARG ) + { + /* For compatibility with future enhancements, */ + /* we must ignore new modes */ + + if ( args[0] >= 0 && args[0] <= 5 ) + { + if ( args[0] == 3 ) + args[0] = 2; + + CUR.GS.scan_type = (Int)args[0]; + } + } + + + +/****************************************************************/ +/* */ +/* MANAGING OUTLINES */ +/* */ +/* Instructions appear in the specs' order. */ +/* */ +/****************************************************************/ + +/**********************************************/ +/* FLIPPT[] : FLIP PoinT */ +/* CodeRange : $80 */ +/* Stack : uint32... --> */ + + static void Ins_FLIPPT( INS_ARG ) + { + UShort point; + + + if ( CUR.top < CUR.GS.loop ) + { + CUR.error = TT_Err_Too_Few_Arguments; + return; + } + + while ( CUR.GS.loop > 0 ) + { + CUR.args--; + + point = (UShort)CUR.stack[CUR.args]; + + if ( BOUNDS( point, CUR.pts.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + } + else + CUR.pts.touch[point] ^= TT_Flag_On_Curve; + + CUR.GS.loop--; + } + + CUR.GS.loop = 1; + CUR.new_top = CUR.args; + } + + +/**********************************************/ +/* FLIPRGON[]: FLIP RanGe ON */ +/* CodeRange : $81 */ +/* Stack : uint32 uint32 --> */ +/* (but UShorts are sufficient) */ + + static void Ins_FLIPRGON( INS_ARG ) + { + UShort I, K, L; + + + K = (UShort)args[1]; + L = (UShort)args[0]; + + if ( BOUNDS( K, CUR.pts.n_points ) || + BOUNDS( L, CUR.pts.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + for ( I = L; I <= K; I++ ) + CUR.pts.touch[I] |= TT_Flag_On_Curve; + } + + +/**********************************************/ +/* FLIPRGOFF : FLIP RanGe OFF */ +/* CodeRange : $82 */ +/* Stack : uint32 uint32 --> */ +/* (but UShorts are sufficient) */ + + static void Ins_FLIPRGOFF( INS_ARG ) + { + UShort I, K, L; + + + K = (UShort)args[1]; + L = (UShort)args[0]; + + if ( BOUNDS( K, CUR.pts.n_points ) || + BOUNDS( L, CUR.pts.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + for ( I = L; I <= K; I++ ) + CUR.pts.touch[I] &= ~TT_Flag_On_Curve; + } + + + static Bool Compute_Point_Displacement( EXEC_OPS + PCoordinates x, + PCoordinates y, + PGlyph_Zone zone, + UShort* refp ) + { + TGlyph_Zone zp; + UShort p; + TT_F26Dot6 d; + + + if ( CUR.opcode & 1 ) + { + zp = CUR.zp0; + p = CUR.GS.rp1; + } + else + { + zp = CUR.zp1; + p = CUR.GS.rp2; + } + + if ( BOUNDS( p, zp.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Displacement; + return FAILURE; + } + + *zone = zp; + *refp = p; + + d = CUR_Func_project( zp.cur + p, zp.org + p ); + + *x = TT_MulDiv(d, (Long)CUR.GS.freeVector.x * 0x10000L, CUR.F_dot_P ); + *y = TT_MulDiv(d, (Long)CUR.GS.freeVector.y * 0x10000L, CUR.F_dot_P ); + + return SUCCESS; + } + + + static void Move_Zp2_Point( EXEC_OPS + UShort point, + TT_F26Dot6 dx, + TT_F26Dot6 dy, + Bool touch ) + { + if ( CUR.GS.freeVector.x != 0 ) + { + CUR.zp2.cur[point].x += dx; + if ( touch ) + CUR.zp2.touch[point] |= TT_Flag_Touched_X; + } + + if ( CUR.GS.freeVector.y != 0 ) + { + CUR.zp2.cur[point].y += dy; + if ( touch ) + CUR.zp2.touch[point] |= TT_Flag_Touched_Y; + } + } + + +/**********************************************/ +/* SHP[a] : SHift Point by the last point */ +/* CodeRange : $32-33 */ +/* Stack : uint32... --> */ + + static void Ins_SHP( INS_ARG ) + { + TGlyph_Zone zp; + UShort refp; + + TT_F26Dot6 dx, + dy; + UShort point; + + + if ( CUR.top < CUR.GS.loop ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + + if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) + return; + + while ( CUR.GS.loop > 0 ) + { + CUR.args--; + point = (UShort)CUR.stack[CUR.args]; + + if ( BOUNDS( point, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + } + else + /* UNDOCUMENTED! SHP touches the points */ + MOVE_Zp2_Point( point, dx, dy, TRUE ); + + CUR.GS.loop--; + } + + CUR.GS.loop = 1; + CUR.new_top = CUR.args; + } + + +/**********************************************/ +/* SHC[a] : SHift Contour */ +/* CodeRange : $34-35 */ +/* Stack : uint32 --> */ + + static void Ins_SHC( INS_ARG ) + { + TGlyph_Zone zp; + UShort refp; + TT_F26Dot6 dx, + dy; + + Short contour; + UShort first_point, last_point, i; + + + contour = (UShort)args[0]; + + if ( BOUNDS( contour, CUR.pts.n_contours ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) + return; + + if ( contour == 0 ) + first_point = 0; + else + first_point = CUR.pts.contours[contour - 1] + 1; + + last_point = CUR.pts.contours[contour]; + + /* XXX: this is probably wrong... at least it prevents memory */ + /* corruption when zp2 is the twilight zone */ + if ( last_point > CUR.zp2.n_points ) + { + if ( CUR.zp2.n_points > 0 ) + last_point = CUR.zp2.n_points - 1; + else + last_point = 0; + } + + /* UNDOCUMENTED! SHC doesn't touch the points */ + for ( i = first_point; i <= last_point; i++ ) + { + if ( zp.cur != CUR.zp2.cur || refp != i ) + MOVE_Zp2_Point( i, dx, dy, FALSE ); + } + } + + +/**********************************************/ +/* SHZ[a] : SHift Zone */ +/* CodeRange : $36-37 */ +/* Stack : uint32 --> */ + + static void Ins_SHZ( INS_ARG ) + { + TGlyph_Zone zp; + UShort refp; + TT_F26Dot6 dx, + dy; + + UShort last_point, i; + + + if ( BOUNDS( args[0], 2 ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) + return; + + if ( CUR.zp2.n_points > 0 ) + last_point = CUR.zp2.n_points - 1; + else + last_point = 0; + + /* UNDOCUMENTED! SHZ doesn't touch the points */ + for ( i = 0; i <= last_point; i++ ) + { + if ( zp.cur != CUR.zp2.cur || refp != i ) + MOVE_Zp2_Point( i, dx, dy, FALSE ); + } + } + + +/**********************************************/ +/* SHPIX[] : SHift points by a PIXel amount */ +/* CodeRange : $38 */ +/* Stack : f26.6 uint32... --> */ + + static void Ins_SHPIX( INS_ARG ) + { + TT_F26Dot6 dx, dy; + UShort point; + + + if ( CUR.top < CUR.GS.loop + 1 ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + + dx = TT_MulDiv( args[0], + (Long)CUR.GS.freeVector.x, + 0x4000 ); + dy = TT_MulDiv( args[0], + (Long)CUR.GS.freeVector.y, + 0x4000 ); + + while ( CUR.GS.loop > 0 ) + { + CUR.args--; + + point = (UShort)CUR.stack[CUR.args]; + + if ( BOUNDS( point, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + } + else + MOVE_Zp2_Point( point, dx, dy, TRUE ); + + CUR.GS.loop--; + } + + CUR.GS.loop = 1; + CUR.new_top = CUR.args; + } + + +/**********************************************/ +/* MSIRP[a] : Move Stack Indirect Relative */ +/* CodeRange : $3A-$3B */ +/* Stack : f26.6 uint32 --> */ + + static void Ins_MSIRP( INS_ARG ) + { + UShort point; + TT_F26Dot6 distance; + + + point = (UShort)args[0]; + + if ( BOUNDS( point, CUR.zp1.n_points ) || + BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + /* XXX: UNDOCUMENTED! behaviour */ + if ( CUR.GS.gep0 == 0 ) /* if in twilight zone */ + { + CUR.zp1.org[point] = CUR.zp0.org[CUR.GS.rp0]; + CUR.zp1.cur[point] = CUR.zp1.org[point]; + } + + distance = CUR_Func_project( CUR.zp1.cur + point, + CUR.zp0.cur + CUR.GS.rp0 ); + + CUR_Func_move( &CUR.zp1, point, args[1] - distance ); + + CUR.GS.rp1 = CUR.GS.rp0; + CUR.GS.rp2 = point; + + if ( (CUR.opcode & 1) != 0 ) + CUR.GS.rp0 = point; + } + + +/**********************************************/ +/* MDAP[a] : Move Direct Absolute Point */ +/* CodeRange : $2E-$2F */ +/* Stack : uint32 --> */ + + static void Ins_MDAP( INS_ARG ) + { + UShort point; + TT_F26Dot6 cur_dist, + distance; + + + point = (UShort)args[0]; + + if ( BOUNDS( point, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + /* XXX: Is there some undocumented feature while in the */ + /* twilight zone? ? */ + if ( (CUR.opcode & 1) != 0 ) + { + cur_dist = CUR_Func_project( CUR.zp0.cur + point, NULL_Vector ); + distance = CUR_Func_round( cur_dist, + CUR.metrics.compensations[0] ) - cur_dist; + } + else + distance = 0; + + CUR_Func_move( &CUR.zp0, point, distance ); + + CUR.GS.rp0 = point; + CUR.GS.rp1 = point; + } + + +/**********************************************/ +/* MIAP[a] : Move Indirect Absolute Point */ +/* CodeRange : $3E-$3F */ +/* Stack : uint32 uint32 --> */ + + static void Ins_MIAP( INS_ARG ) + { + ULong cvtEntry; + UShort point; + TT_F26Dot6 distance, + org_dist; + + + cvtEntry = (ULong)args[1]; + point = (UShort)args[0]; + + if ( BOUNDS( point, CUR.zp0.n_points ) || + BOUNDS( cvtEntry, CUR.cvtSize ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + /* UNDOCUMENTED! */ + /* */ + /* The behaviour of an MIAP instruction is quite */ + /* different when used in the twilight zone. */ + /* */ + /* First, no control value cutin test is performed */ + /* as it would fail anyway. Second, the original */ + /* point, i.e. (org_x,org_y) of zp0.point, is set */ + /* to the absolute, unrounded distance found in */ + /* the CVT. */ + /* */ + /* This is used in the CVT programs of the Microsoft */ + /* fonts Arial, Times, etc., in order to re-adjust */ + /* some key font heights. It allows the use of the */ + /* IP instruction in the twilight zone, which */ + /* otherwise would be "illegal" according to the */ + /* specs :) */ + /* */ + /* We implement it with a special sequence for the */ + /* twilight zone. This is a bad hack, but it seems */ + /* to work. */ + + distance = CUR_Func_read_cvt( cvtEntry ); + + if ( CUR.GS.gep0 == 0 ) /* If in twilight zone */ + { + CUR.zp0.org[point].x = TT_MulDiv( CUR.GS.freeVector.x, + distance, 0x4000L ); + CUR.zp0.org[point].y = TT_MulDiv( CUR.GS.freeVector.y, + distance, 0x4000L ); + CUR.zp0.cur[point] = CUR.zp0.org[point]; + } + + org_dist = CUR_Func_project( CUR.zp0.cur + point, NULL_Vector ); + + if ( (CUR.opcode & 1) != 0 ) /* rounding and control cutin flag */ + { + if ( ABS( distance - org_dist ) > CUR.GS.control_value_cutin ) + distance = org_dist; + + distance = CUR_Func_round( distance, CUR.metrics.compensations[0] ); + } + + CUR_Func_move( &CUR.zp0, point, distance - org_dist ); + + CUR.GS.rp0 = point; + CUR.GS.rp1 = point; + } + + +/**********************************************/ +/* MDRP[abcde] : Move Direct Relative Point */ +/* CodeRange : $C0-$DF */ +/* Stack : uint32 --> */ + + static void Ins_MDRP( INS_ARG ) + { + UShort point; + TT_F26Dot6 org_dist, distance; + + + point = (UShort)args[0]; + + if ( BOUNDS( point, CUR.zp1.n_points ) || + BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + /* XXX: Is there some undocumented feature while in the */ + /* twilight zone? */ + + org_dist = CUR_Func_dualproj( CUR.zp1.org + point, + CUR.zp0.org + CUR.GS.rp0 ); + + /* single width cutin test */ + + if ( ABS( org_dist ) < CUR.GS.single_width_cutin ) + { + if ( org_dist >= 0 ) + org_dist = CUR.GS.single_width_value; + else + org_dist = -CUR.GS.single_width_value; + } + + /* round flag */ + + if ( (CUR.opcode & 4) != 0 ) + distance = CUR_Func_round( org_dist, + CUR.metrics.compensations[CUR.opcode & 3] ); + else + distance = Round_None( EXEC_ARGS + org_dist, + CUR.metrics.compensations[CUR.opcode & 3] ); + + /* minimum distance flag */ + + if ( (CUR.opcode & 8) != 0 ) + { + if ( org_dist >= 0 ) + { + if ( distance < CUR.GS.minimum_distance ) + distance = CUR.GS.minimum_distance; + } + else + { + if ( distance > -CUR.GS.minimum_distance ) + distance = -CUR.GS.minimum_distance; + } + } + + /* now move the point */ + + org_dist = CUR_Func_project( CUR.zp1.cur + point, + CUR.zp0.cur + CUR.GS.rp0 ); + + CUR_Func_move( &CUR.zp1, point, distance - org_dist ); + + CUR.GS.rp1 = CUR.GS.rp0; + CUR.GS.rp2 = point; + + if ( (CUR.opcode & 16) != 0 ) + CUR.GS.rp0 = point; + } + + +/**********************************************/ +/* MIRP[abcde] : Move Indirect Relative Point */ +/* CodeRange : $E0-$FF */ +/* Stack : int32? uint32 --> */ + + static void Ins_MIRP( INS_ARG ) + { + UShort point; + ULong cvtEntry; + + TT_F26Dot6 cvt_dist, + distance, + cur_dist, + org_dist; + + + point = (UShort)args[0]; + cvtEntry = (ULong)(args[1] + 1); + + /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */ + + if ( BOUNDS( point, CUR.zp1.n_points ) || + BOUNDS( cvtEntry, CUR.cvtSize + 1 ) || + BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + if ( !cvtEntry ) + cvt_dist = 0; + else + cvt_dist = CUR_Func_read_cvt( cvtEntry - 1 ); + + /* single width test */ + + if ( ABS( cvt_dist ) < CUR.GS.single_width_cutin ) + { + if ( cvt_dist >= 0 ) + cvt_dist = CUR.GS.single_width_value; + else + cvt_dist = -CUR.GS.single_width_value; + } + + /* XXX : UNDOCUMENTED! -- twilight zone */ + + if ( CUR.GS.gep1 == 0 ) + { + CUR.zp1.org[point].x = CUR.zp0.org[CUR.GS.rp0].x + + TT_MulDiv( cvt_dist, + CUR.GS.freeVector.x, + 0x4000 ); + + CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y + + TT_MulDiv( cvt_dist, + CUR.GS.freeVector.y, + 0x4000 ); + + CUR.zp1.cur[point] = CUR.zp1.org[point]; + } + + org_dist = CUR_Func_dualproj( CUR.zp1.org + point, + CUR.zp0.org + CUR.GS.rp0 ); + + cur_dist = CUR_Func_project( CUR.zp1.cur + point, + CUR.zp0.cur + CUR.GS.rp0 ); + + /* auto-flip test */ + + if ( CUR.GS.auto_flip ) + { + if ( (org_dist ^ cvt_dist) < 0 ) + cvt_dist = -cvt_dist; + } + + /* control value cutin and round */ + + if ( (CUR.opcode & 4) != 0 ) + { + /* XXX: UNDOCUMENTED! Only perform cut-in test when both points */ + /* refer to the same zone. */ + + if ( CUR.GS.gep0 == CUR.GS.gep1 ) + if ( ABS( cvt_dist - org_dist ) >= CUR.GS.control_value_cutin ) + cvt_dist = org_dist; + + distance = CUR_Func_round( cvt_dist, + CUR.metrics.compensations[CUR.opcode & 3] ); + } + else + distance = Round_None( EXEC_ARGS + cvt_dist, + CUR.metrics.compensations[CUR.opcode & 3] ); + + /* minimum distance test */ + + if ( (CUR.opcode & 8) != 0 ) + { + if ( org_dist >= 0 ) + { + if ( distance < CUR.GS.minimum_distance ) + distance = CUR.GS.minimum_distance; + } + else + { + if ( distance > -CUR.GS.minimum_distance ) + distance = -CUR.GS.minimum_distance; + } + } + + CUR_Func_move( &CUR.zp1, point, distance - cur_dist ); + + CUR.GS.rp1 = CUR.GS.rp0; + + if ( (CUR.opcode & 16) != 0 ) + CUR.GS.rp0 = point; + + /* UNDOCUMENTED! */ + + CUR.GS.rp2 = point; + } + + +/**********************************************/ +/* ALIGNRP[] : ALIGN Relative Point */ +/* CodeRange : $3C */ +/* Stack : uint32 uint32... --> */ + + static void Ins_ALIGNRP( INS_ARG ) + { + UShort point; + TT_F26Dot6 distance; + + + if ( CUR.top < CUR.GS.loop || + BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + while ( CUR.GS.loop > 0 ) + { + CUR.args--; + + point = (UShort)CUR.stack[CUR.args]; + + if ( BOUNDS( point, CUR.zp1.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + } + else + { + distance = CUR_Func_project( CUR.zp1.cur + point, + CUR.zp0.cur + CUR.GS.rp0 ); + + CUR_Func_move( &CUR.zp1, point, -distance ); + } + + CUR.GS.loop--; + } + + CUR.GS.loop = 1; + CUR.new_top = CUR.args; + } + + +/**********************************************/ +/* ISECT[] : moves point to InterSECTion */ +/* CodeRange : $0F */ +/* Stack : 5 * uint32 --> */ + + static void Ins_ISECT( INS_ARG ) + { + UShort point, + a0, a1, + b0, b1; + + TT_F26Dot6 discriminant; + + TT_F26Dot6 dx, dy, + dax, day, + dbx, dby; + + TT_F26Dot6 val; + + TT_Vector R; + + + point = (UShort)args[0]; + + a0 = (UShort)args[1]; + a1 = (UShort)args[2]; + b0 = (UShort)args[3]; + b1 = (UShort)args[4]; + + if ( BOUNDS( b0, CUR.zp0.n_points ) || + BOUNDS( b1, CUR.zp0.n_points ) || + BOUNDS( a0, CUR.zp1.n_points ) || + BOUNDS( a1, CUR.zp1.n_points ) || + BOUNDS( point, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + dbx = CUR.zp0.cur[b1].x - CUR.zp0.cur[b0].x; + dby = CUR.zp0.cur[b1].y - CUR.zp0.cur[b0].y; + + dax = CUR.zp1.cur[a1].x - CUR.zp1.cur[a0].x; + day = CUR.zp1.cur[a1].y - CUR.zp1.cur[a0].y; + + dx = CUR.zp0.cur[b0].x - CUR.zp1.cur[a0].x; + dy = CUR.zp0.cur[b0].y - CUR.zp1.cur[a0].y; + + CUR.zp2.touch[point] |= TT_Flag_Touched_Both; + + discriminant = TT_MulDiv( dax, -dby, 0x40L ) + + TT_MulDiv( day, dbx, 0x40L ); + + if ( ABS( discriminant ) >= 0x40 ) + { + val = TT_MulDiv( dx, -dby, 0x40L ) + TT_MulDiv( dy, dbx, 0x40L ); + + R.x = TT_MulDiv( val, dax, discriminant ); + R.y = TT_MulDiv( val, day, discriminant ); + + CUR.zp2.cur[point].x = CUR.zp1.cur[a0].x + R.x; + CUR.zp2.cur[point].y = CUR.zp1.cur[a0].y + R.y; + } + else + { + /* else, take the middle of the middles of A and B */ + + CUR.zp2.cur[point].x = ( CUR.zp1.cur[a0].x + + CUR.zp1.cur[a1].x + + CUR.zp0.cur[b0].x + + CUR.zp0.cur[b1].x ) / 4; + CUR.zp2.cur[point].y = ( CUR.zp1.cur[a0].y + + CUR.zp1.cur[a1].y + + CUR.zp0.cur[b0].y + + CUR.zp0.cur[b1].y ) / 4; + } + } + + +/**********************************************/ +/* ALIGNPTS[] : ALIGN PoinTS */ +/* CodeRange : $27 */ +/* Stack : uint32 uint32 --> */ + + static void Ins_ALIGNPTS( INS_ARG ) + { + UShort p1, p2; + TT_F26Dot6 distance; + + + p1 = (UShort)args[0]; + p2 = (UShort)args[1]; + + if ( BOUNDS( args[0], CUR.zp1.n_points ) || + BOUNDS( args[1], CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + distance = CUR_Func_project( CUR.zp0.cur + p2, + CUR.zp1.cur + p1 ) / 2; + + CUR_Func_move( &CUR.zp1, p1, distance ); + CUR_Func_move( &CUR.zp0, p2, -distance ); + } + + +/**********************************************/ +/* IP[] : Interpolate Point */ +/* CodeRange : $39 */ +/* Stack : uint32... --> */ + + static void Ins_IP( INS_ARG ) + { + TT_F26Dot6 org_a, org_b, org_x, + cur_a, cur_b, cur_x, + distance; + UShort point; + + + if ( CUR.top < CUR.GS.loop ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + + /* XXX: there are some glyphs in some braindead but popular */ + /* fonts out there (e.g. [aeu]grave in monotype.ttf) */ + /* calling IP[] with bad values of rp[12] */ + /* do something sane when this odd thing happens */ + + if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) || + BOUNDS( CUR.GS.rp2, CUR.zp1.n_points ) ) + { + org_a = cur_a = 0; + org_b = cur_b = 0; + } + else + { + org_a = CUR_Func_dualproj( CUR.zp0.org + CUR.GS.rp1, NULL_Vector ); + org_b = CUR_Func_dualproj( CUR.zp1.org + CUR.GS.rp2, NULL_Vector ); + + cur_a = CUR_Func_project( CUR.zp0.cur + CUR.GS.rp1, NULL_Vector ); + cur_b = CUR_Func_project( CUR.zp1.cur + CUR.GS.rp2, NULL_Vector ); + } + + while ( CUR.GS.loop > 0 ) + { + CUR.args--; + + point = (UShort)CUR.stack[CUR.args]; + if ( BOUNDS( point, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + } + else + { + org_x = CUR_Func_dualproj( CUR.zp2.org + point, NULL_Vector ); + cur_x = CUR_Func_project ( CUR.zp2.cur + point, NULL_Vector ); + + if ( ( org_a <= org_b && org_x <= org_a ) || + ( org_a > org_b && org_x >= org_a ) ) + + distance = ( cur_a - org_a ) + ( org_x - cur_x ); + + else if ( ( org_a <= org_b && org_x >= org_b ) || + ( org_a > org_b && org_x < org_b ) ) + + distance = ( cur_b - org_b ) + ( org_x - cur_x ); + + else + /* note: it seems that rounding this value isn't a good */ + /* idea (cf. width of capital 'S' in Times) */ + + distance = TT_MulDiv( cur_b - cur_a, + org_x - org_a, + org_b - org_a ) + ( cur_a - cur_x ); + + CUR_Func_move( &CUR.zp2, point, distance ); + } + + CUR.GS.loop--; + } + + CUR.GS.loop = 1; + CUR.new_top = CUR.args; + } + + +/**********************************************/ +/* UTP[a] : UnTouch Point */ +/* CodeRange : $29 */ +/* Stack : uint32 --> */ + + static void Ins_UTP( INS_ARG ) + { + UShort point; + Byte mask; + + + point = (UShort)args[0]; + + if ( BOUNDS( point, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + mask = 0xFF; + + if ( CUR.GS.freeVector.x != 0 ) + mask &= ~TT_Flag_Touched_X; + + if ( CUR.GS.freeVector.y != 0 ) + mask &= ~TT_Flag_Touched_Y; + + CUR.zp0.touch[point] &= mask; + } + + + /* Local variables for Ins_IUP: */ + struct LOC_Ins_IUP + { + TT_Vector* orgs; /* original and current coordinate */ + TT_Vector* curs; /* arrays */ + }; + + + static void Shift( UShort p1, + UShort p2, + UShort p, + struct LOC_Ins_IUP* LINK ) + { + UShort i; + TT_F26Dot6 x; + + + x = LINK->curs[p].x - LINK->orgs[p].x; + + for ( i = p1; i < p; i++ ) + LINK->curs[i].x += x; + + for ( i = p + 1; i <= p2; i++ ) + LINK->curs[i].x += x; + } + + + static void Interp( UShort p1, + UShort p2, + UShort ref1, + UShort ref2, + struct LOC_Ins_IUP* LINK ) + { + UShort i; + TT_F26Dot6 x, x1, x2, d1, d2; + + + if ( p1 > p2 ) + return; + + x1 = LINK->orgs[ref1].x; + d1 = LINK->curs[ref1].x - LINK->orgs[ref1].x; + x2 = LINK->orgs[ref2].x; + d2 = LINK->curs[ref2].x - LINK->orgs[ref2].x; + + if ( x1 == x2 ) + { + for ( i = p1; i <= p2; i++ ) + { + x = LINK->orgs[i].x; + + if ( x <= x1 ) + x += d1; + else + x += d2; + + LINK->curs[i].x = x; + } + return; + } + + if ( x1 < x2 ) + { + for ( i = p1; i <= p2; i++ ) + { + x = LINK->orgs[i].x; + + if ( x <= x1 ) + x += d1; + else + { + if ( x >= x2 ) + x += d2; + else + x = LINK->curs[ref1].x + + TT_MulDiv( x - x1, + LINK->curs[ref2].x - LINK->curs[ref1].x, + x2 - x1 ); + } + LINK->curs[i].x = x; + } + return; + } + + /* x2 < x1 */ + + for ( i = p1; i <= p2; i++ ) + { + x = LINK->orgs[i].x; + if ( x <= x2 ) + x += d2; + else + { + if ( x >= x1 ) + x += d1; + else + x = LINK->curs[ref1].x + + TT_MulDiv( x - x1, + LINK->curs[ref2].x - LINK->curs[ref1].x, + x2 - x1 ); + } + LINK->curs[i].x = x; + } + } + + +/**********************************************/ +/* IUP[a] : Interpolate Untouched Points */ +/* CodeRange : $30-$31 */ +/* Stack : --> */ + + static void Ins_IUP( INS_ARG ) + { + struct LOC_Ins_IUP V; + Byte mask; + + UShort first_point; /* first point of contour */ + UShort end_point; /* end point (last+1) of contour */ + + UShort first_touched; /* first touched point in contour */ + UShort cur_touched; /* current touched point in contour */ + + UShort point; /* current point */ + Short contour; /* current contour */ + + + if ( CUR.opcode & 1 ) + { + mask = TT_Flag_Touched_X; + V.orgs = CUR.pts.org; + V.curs = CUR.pts.cur; + } + else + { + mask = TT_Flag_Touched_Y; + V.orgs = (TT_Vector*)( ((TT_F26Dot6*)CUR.pts.org) + 1 ); + V.curs = (TT_Vector*)( ((TT_F26Dot6*)CUR.pts.cur) + 1 ); + } + + contour = 0; + point = 0; + + do + { + end_point = CUR.pts.contours[contour]; + first_point = point; + + while ( point <= end_point && (CUR.pts.touch[point] & mask) == 0 ) + point++; + + if ( point <= end_point ) + { + first_touched = point; + cur_touched = point; + + point++; + + while ( point <= end_point ) + { + if ( (CUR.pts.touch[point] & mask) != 0 ) + { + if ( point > 0 ) + Interp( cur_touched + 1, + point - 1, + cur_touched, + point, + &V ); + cur_touched = point; + } + + point++; + } + + if ( cur_touched == first_touched ) + Shift( first_point, end_point, cur_touched, &V ); + else + { + Interp( cur_touched + 1, + end_point, + cur_touched, + first_touched, + &V ); + + if ( first_touched > 0 ) + Interp( first_point, + first_touched - 1, + cur_touched, + first_touched, + &V ); + } + } + contour++; + } while ( contour < CUR.pts.n_contours ); + } + + +/**********************************************/ +/* DELTAPn[] : DELTA Exceptions P1, P2, P3 */ +/* CodeRange : $5D,$71,$72 */ +/* Stack : uint32 (2 * uint32)... --> */ + + static void Ins_DELTAP( INS_ARG ) + { + ULong nump, k; + UShort A; + ULong C; + Long B; + + + nump = (ULong)args[0]; /* some points theoretically may occur more + than once, thus UShort isn't enough */ + + for ( k = 1; k <= nump; k++ ) + { + if ( CUR.args < 2 ) + { + CUR.error = TT_Err_Too_Few_Arguments; + return; + } + + CUR.args -= 2; + + A = (UShort)CUR.stack[CUR.args + 1]; + B = CUR.stack[CUR.args]; + + /* XXX : because some popular fonts contain some invalid DeltaP */ + /* instructions, we simply ignore them when the stacked */ + /* point reference is off limit, rather than returning an */ + /* error. As a delta instruction doesn't change a glyph */ + /* in great ways, this shouldn't be a problem.. */ + + if ( !BOUNDS( A, CUR.zp0.n_points ) ) + { + C = ((ULong)B & 0xF0) >> 4; + + switch ( CUR.opcode ) + { + case 0x5d: + break; + + case 0x71: + C += 16; + break; + + case 0x72: + C += 32; + break; + } + + C += CUR.GS.delta_base; + + if ( CURRENT_Ppem() == (Long)C ) + { + B = ((ULong)B & 0xF) - 8; + if ( B >= 0 ) + B++; + B = B * 64L / (1L << CUR.GS.delta_shift); + + CUR_Func_move( &CUR.zp0, A, B ); + } + } + else + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + } + + CUR.new_top = CUR.args; + } + + +/**********************************************/ +/* DELTACn[] : DELTA Exceptions C1, C2, C3 */ +/* CodeRange : $73,$74,$75 */ +/* Stack : uint32 (2 * uint32)... --> */ + + static void Ins_DELTAC( INS_ARG ) + { + ULong nump, k; + ULong A, C; + Long B; + + + nump = (ULong)args[0]; + + for ( k = 1; k <= nump; k++ ) + { + if ( CUR.args < 2 ) + { + CUR.error = TT_Err_Too_Few_Arguments; + return; + } + + CUR.args -= 2; + + A = (ULong)CUR.stack[CUR.args + 1]; + B = CUR.stack[CUR.args]; + + if ( BOUNDS( A, CUR.cvtSize ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + } + else + { + C = ((ULong)B & 0xF0) >> 4; + + switch ( CUR.opcode ) + { + case 0x73: + break; + + case 0x74: + C += 16; + break; + + case 0x75: + C += 32; + break; + } + + C += CUR.GS.delta_base; + + if ( CURRENT_Ppem() == (Long)C ) + { + B = ((ULong)B & 0xF) - 8; + if ( B >= 0 ) + B++; + B = B * 64L / (1L << CUR.GS.delta_shift); + + CUR_Func_move_cvt( A, B ); + } + } + } + + CUR.new_top = CUR.args; + } + + + +/****************************************************************/ +/* */ +/* MISC. INSTRUCTIONS */ +/* */ +/****************************************************************/ + + +/**********************************************/ +/* GETINFO[] : GET INFOrmation */ +/* CodeRange : $88 */ +/* Stack : uint32 --> uint32 */ + +/* XXX According to Apple specs, bits 1 & 2 of the argument ought to be */ +/* consulted before rotated / stretched info is returned */ + + static void Ins_GETINFO( INS_ARG ) + { + Long K; + + + K = 0; + + /* We return then Windows 3.1 version number */ + /* for the font scaler */ + if ( (args[0] & 1) != 0 ) + K = 3; + + /* Has the glyph been rotated ? */ + if ( CUR.metrics.rotated ) + K |= 0x80; + + /* Has the glyph been stretched ? */ + if ( CUR.metrics.stretched ) + K |= 0x100; + + args[0] = K; + } + + + static void Ins_UNKNOWN( INS_ARG ) + { + /* look up the current instruction in our table */ + PDefRecord def, limit; + + def = CUR.IDefs; + limit = def + CUR.numIDefs; + for ( ; def < limit; def++ ) + { + if ( def->Opc == CUR.opcode && def->Active ) + { + PCallRecord pCrec; + + /* implement instruction as a function call */ + + /* check call stack */ + if ( CUR.callTop >= CUR.callSize ) + { + CUR.error = TT_Err_Stack_Overflow; + return; + } + + pCrec = CUR.callStack + CUR.callTop; + + pCrec->Caller_Range = CUR.curRange; + pCrec->Caller_IP = CUR.IP + 1; + pCrec->Cur_Count = 1; + pCrec->Cur_Restart = def->Start; + + CUR.callTop++; + + INS_Goto_CodeRange( def->Range, + def->Start ); + + CUR.step_ins = FALSE; + return; + } + } + + CUR.error = TT_Err_Invalid_Opcode; + } + + +#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH + static TInstruction_Function Instruct_Dispatch[256] = + { + /* Opcodes are gathered in groups of 16. */ + /* Please keep the spaces as they are. */ + + /* SVTCA y */ Ins_SVTCA, + /* SVTCA x */ Ins_SVTCA, + /* SPvTCA y */ Ins_SPVTCA, + /* SPvTCA x */ Ins_SPVTCA, + /* SFvTCA y */ Ins_SFVTCA, + /* SFvTCA x */ Ins_SFVTCA, + /* SPvTL // */ Ins_SPVTL, + /* SPvTL + */ Ins_SPVTL, + /* SFvTL // */ Ins_SFVTL, + /* SFvTL + */ Ins_SFVTL, + /* SPvFS */ Ins_SPVFS, + /* SFvFS */ Ins_SFVFS, + /* GPV */ Ins_GPV, + /* GFV */ Ins_GFV, + /* SFvTPv */ Ins_SFVTPV, + /* ISECT */ Ins_ISECT, + + /* SRP0 */ Ins_SRP0, + /* SRP1 */ Ins_SRP1, + /* SRP2 */ Ins_SRP2, + /* SZP0 */ Ins_SZP0, + /* SZP1 */ Ins_SZP1, + /* SZP2 */ Ins_SZP2, + /* SZPS */ Ins_SZPS, + /* SLOOP */ Ins_SLOOP, + /* RTG */ Ins_RTG, + /* RTHG */ Ins_RTHG, + /* SMD */ Ins_SMD, + /* ELSE */ Ins_ELSE, + /* JMPR */ Ins_JMPR, + /* SCvTCi */ Ins_SCVTCI, + /* SSwCi */ Ins_SSWCI, + /* SSW */ Ins_SSW, + + /* DUP */ Ins_DUP, + /* POP */ Ins_POP, + /* CLEAR */ Ins_CLEAR, + /* SWAP */ Ins_SWAP, + /* DEPTH */ Ins_DEPTH, + /* CINDEX */ Ins_CINDEX, + /* MINDEX */ Ins_MINDEX, + /* AlignPTS */ Ins_ALIGNPTS, + /* INS_$28 */ Ins_UNKNOWN, + /* UTP */ Ins_UTP, + /* LOOPCALL */ Ins_LOOPCALL, + /* CALL */ Ins_CALL, + /* FDEF */ Ins_FDEF, + /* ENDF */ Ins_ENDF, + /* MDAP[0] */ Ins_MDAP, + /* MDAP[1] */ Ins_MDAP, + + /* IUP[0] */ Ins_IUP, + /* IUP[1] */ Ins_IUP, + /* SHP[0] */ Ins_SHP, + /* SHP[1] */ Ins_SHP, + /* SHC[0] */ Ins_SHC, + /* SHC[1] */ Ins_SHC, + /* SHZ[0] */ Ins_SHZ, + /* SHZ[1] */ Ins_SHZ, + /* SHPIX */ Ins_SHPIX, + /* IP */ Ins_IP, + /* MSIRP[0] */ Ins_MSIRP, + /* MSIRP[1] */ Ins_MSIRP, + /* AlignRP */ Ins_ALIGNRP, + /* RTDG */ Ins_RTDG, + /* MIAP[0] */ Ins_MIAP, + /* MIAP[1] */ Ins_MIAP, + + /* NPushB */ Ins_NPUSHB, + /* NPushW */ Ins_NPUSHW, + /* WS */ Ins_WS, + /* RS */ Ins_RS, + /* WCvtP */ Ins_WCVTP, + /* RCvt */ Ins_RCVT, + /* GC[0] */ Ins_GC, + /* GC[1] */ Ins_GC, + /* SCFS */ Ins_SCFS, + /* MD[0] */ Ins_MD, + /* MD[1] */ Ins_MD, + /* MPPEM */ Ins_MPPEM, + /* MPS */ Ins_MPS, + /* FlipON */ Ins_FLIPON, + /* FlipOFF */ Ins_FLIPOFF, + /* DEBUG */ Ins_DEBUG, + + /* LT */ Ins_LT, + /* LTEQ */ Ins_LTEQ, + /* GT */ Ins_GT, + /* GTEQ */ Ins_GTEQ, + /* EQ */ Ins_EQ, + /* NEQ */ Ins_NEQ, + /* ODD */ Ins_ODD, + /* EVEN */ Ins_EVEN, + /* IF */ Ins_IF, + /* EIF */ Ins_EIF, + /* AND */ Ins_AND, + /* OR */ Ins_OR, + /* NOT */ Ins_NOT, + /* DeltaP1 */ Ins_DELTAP, + /* SDB */ Ins_SDB, + /* SDS */ Ins_SDS, + + /* ADD */ Ins_ADD, + /* SUB */ Ins_SUB, + /* DIV */ Ins_DIV, + /* MUL */ Ins_MUL, + /* ABS */ Ins_ABS, + /* NEG */ Ins_NEG, + /* FLOOR */ Ins_FLOOR, + /* CEILING */ Ins_CEILING, + /* ROUND[0] */ Ins_ROUND, + /* ROUND[1] */ Ins_ROUND, + /* ROUND[2] */ Ins_ROUND, + /* ROUND[3] */ Ins_ROUND, + /* NROUND[0] */ Ins_NROUND, + /* NROUND[1] */ Ins_NROUND, + /* NROUND[2] */ Ins_NROUND, + /* NROUND[3] */ Ins_NROUND, + + /* WCvtF */ Ins_WCVTF, + /* DeltaP2 */ Ins_DELTAP, + /* DeltaP3 */ Ins_DELTAP, + /* DeltaCn[0] */ Ins_DELTAC, + /* DeltaCn[1] */ Ins_DELTAC, + /* DeltaCn[2] */ Ins_DELTAC, + /* SROUND */ Ins_SROUND, + /* S45Round */ Ins_S45ROUND, + /* JROT */ Ins_JROT, + /* JROF */ Ins_JROF, + /* ROFF */ Ins_ROFF, + /* INS_$7B */ Ins_UNKNOWN, + /* RUTG */ Ins_RUTG, + /* RDTG */ Ins_RDTG, + /* SANGW */ Ins_SANGW, + /* AA */ Ins_AA, + + /* FlipPT */ Ins_FLIPPT, + /* FlipRgON */ Ins_FLIPRGON, + /* FlipRgOFF */ Ins_FLIPRGOFF, + /* INS_$83 */ Ins_UNKNOWN, + /* INS_$84 */ Ins_UNKNOWN, + /* ScanCTRL */ Ins_SCANCTRL, + /* SDPVTL[0] */ Ins_SDPVTL, + /* SDPVTL[1] */ Ins_SDPVTL, + /* GetINFO */ Ins_GETINFO, + /* IDEF */ Ins_IDEF, + /* ROLL */ Ins_ROLL, + /* MAX */ Ins_MAX, + /* MIN */ Ins_MIN, + /* ScanTYPE */ Ins_SCANTYPE, + /* InstCTRL */ Ins_INSTCTRL, + /* INS_$8F */ Ins_UNKNOWN, + + /* INS_$90 */ Ins_UNKNOWN, + /* INS_$91 */ Ins_UNKNOWN, + /* INS_$92 */ Ins_UNKNOWN, + /* INS_$93 */ Ins_UNKNOWN, + /* INS_$94 */ Ins_UNKNOWN, + /* INS_$95 */ Ins_UNKNOWN, + /* INS_$96 */ Ins_UNKNOWN, + /* INS_$97 */ Ins_UNKNOWN, + /* INS_$98 */ Ins_UNKNOWN, + /* INS_$99 */ Ins_UNKNOWN, + /* INS_$9A */ Ins_UNKNOWN, + /* INS_$9B */ Ins_UNKNOWN, + /* INS_$9C */ Ins_UNKNOWN, + /* INS_$9D */ Ins_UNKNOWN, + /* INS_$9E */ Ins_UNKNOWN, + /* INS_$9F */ Ins_UNKNOWN, + + /* INS_$A0 */ Ins_UNKNOWN, + /* INS_$A1 */ Ins_UNKNOWN, + /* INS_$A2 */ Ins_UNKNOWN, + /* INS_$A3 */ Ins_UNKNOWN, + /* INS_$A4 */ Ins_UNKNOWN, + /* INS_$A5 */ Ins_UNKNOWN, + /* INS_$A6 */ Ins_UNKNOWN, + /* INS_$A7 */ Ins_UNKNOWN, + /* INS_$A8 */ Ins_UNKNOWN, + /* INS_$A9 */ Ins_UNKNOWN, + /* INS_$AA */ Ins_UNKNOWN, + /* INS_$AB */ Ins_UNKNOWN, + /* INS_$AC */ Ins_UNKNOWN, + /* INS_$AD */ Ins_UNKNOWN, + /* INS_$AE */ Ins_UNKNOWN, + /* INS_$AF */ Ins_UNKNOWN, + + /* PushB[0] */ Ins_PUSHB, + /* PushB[1] */ Ins_PUSHB, + /* PushB[2] */ Ins_PUSHB, + /* PushB[3] */ Ins_PUSHB, + /* PushB[4] */ Ins_PUSHB, + /* PushB[5] */ Ins_PUSHB, + /* PushB[6] */ Ins_PUSHB, + /* PushB[7] */ Ins_PUSHB, + /* PushW[0] */ Ins_PUSHW, + /* PushW[1] */ Ins_PUSHW, + /* PushW[2] */ Ins_PUSHW, + /* PushW[3] */ Ins_PUSHW, + /* PushW[4] */ Ins_PUSHW, + /* PushW[5] */ Ins_PUSHW, + /* PushW[6] */ Ins_PUSHW, + /* PushW[7] */ Ins_PUSHW, + + /* MDRP[00] */ Ins_MDRP, + /* MDRP[01] */ Ins_MDRP, + /* MDRP[02] */ Ins_MDRP, + /* MDRP[03] */ Ins_MDRP, + /* MDRP[04] */ Ins_MDRP, + /* MDRP[05] */ Ins_MDRP, + /* MDRP[06] */ Ins_MDRP, + /* MDRP[07] */ Ins_MDRP, + /* MDRP[08] */ Ins_MDRP, + /* MDRP[09] */ Ins_MDRP, + /* MDRP[10] */ Ins_MDRP, + /* MDRP[11] */ Ins_MDRP, + /* MDRP[12] */ Ins_MDRP, + /* MDRP[13] */ Ins_MDRP, + /* MDRP[14] */ Ins_MDRP, + /* MDRP[15] */ Ins_MDRP, + + /* MDRP[16] */ Ins_MDRP, + /* MDRP[17] */ Ins_MDRP, + /* MDRP[18] */ Ins_MDRP, + /* MDRP[19] */ Ins_MDRP, + /* MDRP[20] */ Ins_MDRP, + /* MDRP[21] */ Ins_MDRP, + /* MDRP[22] */ Ins_MDRP, + /* MDRP[23] */ Ins_MDRP, + /* MDRP[24] */ Ins_MDRP, + /* MDRP[25] */ Ins_MDRP, + /* MDRP[26] */ Ins_MDRP, + /* MDRP[27] */ Ins_MDRP, + /* MDRP[28] */ Ins_MDRP, + /* MDRP[29] */ Ins_MDRP, + /* MDRP[30] */ Ins_MDRP, + /* MDRP[31] */ Ins_MDRP, + + /* MIRP[00] */ Ins_MIRP, + /* MIRP[01] */ Ins_MIRP, + /* MIRP[02] */ Ins_MIRP, + /* MIRP[03] */ Ins_MIRP, + /* MIRP[04] */ Ins_MIRP, + /* MIRP[05] */ Ins_MIRP, + /* MIRP[06] */ Ins_MIRP, + /* MIRP[07] */ Ins_MIRP, + /* MIRP[08] */ Ins_MIRP, + /* MIRP[09] */ Ins_MIRP, + /* MIRP[10] */ Ins_MIRP, + /* MIRP[11] */ Ins_MIRP, + /* MIRP[12] */ Ins_MIRP, + /* MIRP[13] */ Ins_MIRP, + /* MIRP[14] */ Ins_MIRP, + /* MIRP[15] */ Ins_MIRP, + + /* MIRP[16] */ Ins_MIRP, + /* MIRP[17] */ Ins_MIRP, + /* MIRP[18] */ Ins_MIRP, + /* MIRP[19] */ Ins_MIRP, + /* MIRP[20] */ Ins_MIRP, + /* MIRP[21] */ Ins_MIRP, + /* MIRP[22] */ Ins_MIRP, + /* MIRP[23] */ Ins_MIRP, + /* MIRP[24] */ Ins_MIRP, + /* MIRP[25] */ Ins_MIRP, + /* MIRP[26] */ Ins_MIRP, + /* MIRP[27] */ Ins_MIRP, + /* MIRP[28] */ Ins_MIRP, + /* MIRP[29] */ Ins_MIRP, + /* MIRP[30] */ Ins_MIRP, + /* MIRP[31] */ Ins_MIRP + }; +#endif + + +/****************************************************************/ +/* */ +/* RUN */ +/* */ +/* This function executes a run of opcodes. It will exit */ +/* in the following cases: */ +/* */ +/* - Errors (in which case it returns FALSE) */ +/* */ +/* - Reaching the end of the main code range (returns TRUE). */ +/* Reaching the end of a code range within a function */ +/* call is an error. */ +/* */ +/* - After executing one single opcode, if the flag */ +/* 'Instruction_Trap' is set to TRUE (returns TRUE). */ +/* */ +/* On exit whith TRUE, test IP < CodeSize to know wether it */ +/* comes from a instruction trap or a normal termination. */ +/* */ +/* */ +/* Note: The documented DEBUG opcode pops a value from */ +/* the stack. This behaviour is unsupported, here */ +/* a DEBUG opcode is always an error. */ +/* */ +/* */ +/* THIS IS THE INTERPRETER'S MAIN LOOP */ +/* */ +/* Instructions appear in the specs' order. */ +/* */ +/****************************************************************/ + + LOCAL_FUNC +#ifndef DEBUG_INTERPRETER + TT_Error RunIns( PExecution_Context exc ) +#else + TT_Error RunIns2( PExecution_Context exc ) +#endif + { + UShort A; + PDefRecord WITH; + PCallRecord WITH1; + + Long ins_counter = 0; /* executed instructions counter */ + +#ifdef TT_CONFIG_OPTION_STATIC_INTERPRETER + cur = *exc; +#endif + + /* set CVT functions */ + CUR.metrics.ratio = 0; + if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem ) + { + /* non-square pixels, use the stretched routines */ + CUR.func_read_cvt = Read_CVT_Stretched; + CUR.func_write_cvt = Write_CVT_Stretched; + CUR.func_move_cvt = Move_CVT_Stretched; + } + else + { + /* square pixels, use normal routines */ + CUR.func_read_cvt = Read_CVT; + CUR.func_write_cvt = Write_CVT; + CUR.func_move_cvt = Move_CVT; + } + + COMPUTE_Funcs(); + Compute_Round( EXEC_ARGS (Byte)exc->GS.round_state ); + + do + { + if ( CALC_Length() != SUCCESS ) + { + CUR.error = TT_Err_Code_Overflow; + goto LErrorLabel_; + } + + /* First, let's check for empty stack and overflow */ + + CUR.args = CUR.top - (Pop_Push_Count[CUR.opcode] >> 4); + + /* `args' is the top of the stack once arguments have been popped. */ + /* One can also interpret it as the index of the last argument. */ + + if ( CUR.args < 0 ) + { + CUR.error = TT_Err_Too_Few_Arguments; + goto LErrorLabel_; + } + + CUR.new_top = CUR.args + (Pop_Push_Count[CUR.opcode] & 15); + + /* `new_top' is the new top of the stack, after the instruction's */ + /* execution. `top' will be set to `new_top' after the 'switch' */ + /* statement. */ + + if ( CUR.new_top > CUR.stackSize ) + { + CUR.error = TT_Err_Stack_Overflow; + goto LErrorLabel_; + } + + CUR.step_ins = TRUE; + CUR.error = TT_Err_Ok; + +#ifdef TT_CONFIG_OPTION_INTERPRETER_SWITCH + { + PStorage args = CUR.stack + CUR.args; + Byte opcode = CUR.opcode; + + +#undef ARRAY_BOUND_ERROR +#define ARRAY_BOUND_ERROR goto Set_Invalid_Ref + + switch ( opcode ) + { + case 0x00: /* SVTCA y */ + case 0x01: /* SVTCA x */ + case 0x02: /* SPvTCA y */ + case 0x03: /* SPvTCA x */ + case 0x04: /* SFvTCA y */ + case 0x05: /* SFvTCA x */ + { + Short AA, BB; + + + AA = (Short)(opcode & 1) << 14; + BB = AA ^ (Short)0x4000; + + if ( opcode < 4 ) + { + CUR.GS.projVector.x = AA; + CUR.GS.projVector.y = BB; + + CUR.GS.dualVector.x = AA; + CUR.GS.dualVector.y = BB; + } + + if ( (opcode & 2) == 0 ) + { + CUR.GS.freeVector.x = AA; + CUR.GS.freeVector.y = BB; + } + + COMPUTE_Funcs(); + } + break; + + case 0x06: /* SPvTL // */ + case 0x07: /* SPvTL + */ + DO_SPVTL + break; + + case 0x08: /* SFvTL // */ + case 0x09: /* SFvTL + */ + DO_SFVTL + break; + + case 0x0A: /* SPvFS */ + DO_SPVFS + break; + + case 0x0B: /* SFvFS */ + DO_SFVFS + break; + + case 0x0C: /* GPV */ + DO_GPV + break; + + case 0x0D: /* GFV */ + DO_GFV + break; + + case 0x0E: /* SFvTPv */ + DO_SFVTPV + break; + + case 0x0F: /* ISECT */ + Ins_ISECT( EXEC_ARGS args ); + break; + + case 0x10: /* SRP0 */ + DO_SRP0 + break; + + case 0x11: /* SRP1 */ + DO_SRP1 + break; + + case 0x12: /* SRP2 */ + DO_SRP2 + break; + + case 0x13: /* SZP0 */ + Ins_SZP0( EXEC_ARGS args ); + break; + + case 0x14: /* SZP1 */ + Ins_SZP1( EXEC_ARGS args ); + break; + + case 0x15: /* SZP2 */ + Ins_SZP2( EXEC_ARGS args ); + break; + + case 0x16: /* SZPS */ + Ins_SZPS( EXEC_ARGS args ); + break; + + case 0x17: /* SLOOP */ + DO_SLOOP + break; + + case 0x18: /* RTG */ + DO_RTG + break; + + case 0x19: /* RTHG */ + DO_RTHG + break; + + case 0x1A: /* SMD */ + DO_SMD + break; + + case 0x1B: /* ELSE */ + Ins_ELSE( EXEC_ARGS args ); + break; + + case 0x1C: /* JMPR */ + DO_JMPR + break; + + case 0x1D: /* SCVTCI */ + DO_SCVTCI + break; + + case 0x1E: /* SSWCI */ + DO_SSWCI + break; + + case 0x1F: /* SSW */ + DO_SSW + break; + + case 0x20: /* DUP */ + DO_DUP + break; + + case 0x21: /* POP */ + /* nothing :-) !! */ + break; + + case 0x22: /* CLEAR */ + DO_CLEAR + break; + + case 0x23: /* SWAP */ + DO_SWAP + break; + + case 0x24: /* DEPTH */ + DO_DEPTH + break; + + case 0x25: /* CINDEX */ + DO_CINDEX + break; + + case 0x26: /* MINDEX */ + Ins_MINDEX( EXEC_ARGS args ); + break; + + case 0x27: /* ALIGNPTS */ + Ins_ALIGNPTS( EXEC_ARGS args ); + break; + + case 0x28: /* ???? */ + Ins_UNKNOWN( EXEC_ARGS args ); + break; + + case 0x29: /* UTP */ + Ins_UTP( EXEC_ARGS args ); + break; + + case 0x2A: /* LOOPCALL */ + Ins_LOOPCALL( EXEC_ARGS args ); + break; + + case 0x2B: /* CALL */ + Ins_CALL( EXEC_ARGS args ); + break; + + case 0x2C: /* FDEF */ + Ins_FDEF( EXEC_ARGS args ); + break; + + case 0x2D: /* ENDF */ + Ins_ENDF( EXEC_ARGS args ); + break; + + case 0x2E: /* MDAP */ + case 0x2F: /* MDAP */ + Ins_MDAP( EXEC_ARGS args ); + break; + + + case 0x30: /* IUP */ + case 0x31: /* IUP */ + Ins_IUP( EXEC_ARGS args ); + break; + + case 0x32: /* SHP */ + case 0x33: /* SHP */ + Ins_SHP( EXEC_ARGS args ); + break; + + case 0x34: /* SHC */ + case 0x35: /* SHC */ + Ins_SHC( EXEC_ARGS args ); + break; + + case 0x36: /* SHZ */ + case 0x37: /* SHZ */ + Ins_SHZ( EXEC_ARGS args ); + break; + + case 0x38: /* SHPIX */ + Ins_SHPIX( EXEC_ARGS args ); + break; + + case 0x39: /* IP */ + Ins_IP( EXEC_ARGS args ); + break; + + case 0x3A: /* MSIRP */ + case 0x3B: /* MSIRP */ + Ins_MSIRP( EXEC_ARGS args ); + break; + + case 0x3C: /* AlignRP */ + Ins_ALIGNRP( EXEC_ARGS args ); + break; + + case 0x3D: /* RTDG */ + DO_RTDG + break; + + case 0x3E: /* MIAP */ + case 0x3F: /* MIAP */ + Ins_MIAP( EXEC_ARGS args ); + break; + + case 0x40: /* NPUSHB */ + Ins_NPUSHB( EXEC_ARGS args ); + break; + + case 0x41: /* NPUSHW */ + Ins_NPUSHW( EXEC_ARGS args ); + break; + + case 0x42: /* WS */ + DO_WS + break; + + Set_Invalid_Ref: + CUR.error = TT_Err_Invalid_Reference; + break; + + case 0x43: /* RS */ + DO_RS + break; + + case 0x44: /* WCVTP */ + DO_WCVTP + break; + + case 0x45: /* RCVT */ + DO_RCVT + break; + + case 0x46: /* GC */ + case 0x47: /* GC */ + Ins_GC( EXEC_ARGS args ); + break; + + case 0x48: /* SCFS */ + Ins_SCFS( EXEC_ARGS args ); + break; + + case 0x49: /* MD */ + case 0x4A: /* MD */ + Ins_MD( EXEC_ARGS args ); + break; + + case 0x4B: /* MPPEM */ + DO_MPPEM + break; + + case 0x4C: /* MPS */ + DO_MPS + break; + + case 0x4D: /* FLIPON */ + DO_FLIPON + break; + + case 0x4E: /* FLIPOFF */ + DO_FLIPOFF + break; + + case 0x4F: /* DEBUG */ + DO_DEBUG + break; + + case 0x50: /* LT */ + DO_LT + break; + + case 0x51: /* LTEQ */ + DO_LTEQ + break; + + case 0x52: /* GT */ + DO_GT + break; + + case 0x53: /* GTEQ */ + DO_GTEQ + break; + + case 0x54: /* EQ */ + DO_EQ + break; + + case 0x55: /* NEQ */ + DO_NEQ + break; + + case 0x56: /* ODD */ + DO_ODD + break; + + case 0x57: /* EVEN */ + DO_EVEN + break; + + case 0x58: /* IF */ + Ins_IF( EXEC_ARGS args ); + break; + + case 0x59: /* EIF */ + /* do nothing */ + break; + + case 0x5A: /* AND */ + DO_AND + break; + + case 0x5B: /* OR */ + DO_OR + break; + + case 0x5C: /* NOT */ + DO_NOT + break; + + case 0x5D: /* DELTAP1 */ + Ins_DELTAP( EXEC_ARGS args ); + break; + + case 0x5E: /* SDB */ + DO_SDB + break; + + case 0x5F: /* SDS */ + DO_SDS + break; + + case 0x60: /* ADD */ + DO_ADD + break; + + case 0x61: /* SUB */ + DO_SUB + break; + + case 0x62: /* DIV */ + DO_DIV + break; + + case 0x63: /* MUL */ + DO_MUL + break; + + case 0x64: /* ABS */ + DO_ABS + break; + + case 0x65: /* NEG */ + DO_NEG + break; + + case 0x66: /* FLOOR */ + DO_FLOOR + break; + + case 0x67: /* CEILING */ + DO_CEILING + break; + + case 0x68: /* ROUND */ + case 0x69: /* ROUND */ + case 0x6A: /* ROUND */ + case 0x6B: /* ROUND */ + DO_ROUND + break; + + case 0x6C: /* NROUND */ + case 0x6D: /* NROUND */ + case 0x6E: /* NRRUND */ + case 0x6F: /* NROUND */ + DO_NROUND + break; + + case 0x70: /* WCVTF */ + DO_WCVTF + break; + + case 0x71: /* DELTAP2 */ + case 0x72: /* DELTAP3 */ + Ins_DELTAP( EXEC_ARGS args ); + break; + + case 0x73: /* DELTAC0 */ + case 0x74: /* DELTAC1 */ + case 0x75: /* DELTAC2 */ + Ins_DELTAC( EXEC_ARGS args ); + break; + + case 0x76: /* SROUND */ + DO_SROUND + break; + + case 0x77: /* S45Round */ + DO_S45ROUND + break; + + case 0x78: /* JROT */ + DO_JROT + break; + + case 0x79: /* JROF */ + DO_JROF + break; + + case 0x7A: /* ROFF */ + DO_ROFF + break; + + case 0x7B: /* ???? */ + Ins_UNKNOWN( EXEC_ARGS args ); + break; + + case 0x7C: /* RUTG */ + DO_RUTG + break; + + case 0x7D: /* RDTG */ + DO_RDTG + break; + + case 0x7E: /* SANGW */ + case 0x7F: /* AA */ + /* nothing - obsolete */ + break; + + case 0x80: /* FLIPPT */ + Ins_FLIPPT( EXEC_ARGS args ); + break; + + case 0x81: /* FLIPRGON */ + Ins_FLIPRGON( EXEC_ARGS args ); + break; + + case 0x82: /* FLIPRGOFF */ + Ins_FLIPRGOFF( EXEC_ARGS args ); + break; + + case 0x83: /* UNKNOWN */ + case 0x84: /* UNKNOWN */ + Ins_UNKNOWN( EXEC_ARGS args ); + break; + + case 0x85: /* SCANCTRL */ + Ins_SCANCTRL( EXEC_ARGS args ); + break; + + case 0x86: /* SDPVTL */ + case 0x87: /* SDPVTL */ + Ins_SDPVTL( EXEC_ARGS args ); + break; + + case 0x88: /* GETINFO */ + Ins_GETINFO( EXEC_ARGS args ); + break; + + case 0x89: /* IDEF */ + Ins_IDEF( EXEC_ARGS args ); + break; + + case 0x8A: /* ROLL */ + Ins_ROLL( EXEC_ARGS args ); + break; + + case 0x8B: /* MAX */ + DO_MAX + break; + + case 0x8C: /* MIN */ + DO_MIN + break; + + case 0x8D: /* SCANTYPE */ + Ins_SCANTYPE( EXEC_ARGS args ); + break; + + case 0x8E: /* INSTCTRL */ + Ins_INSTCTRL( EXEC_ARGS args ); + break; + + case 0x8F: + Ins_UNKNOWN( EXEC_ARGS args ); + break; + + default: + if ( opcode >= 0xE0 ) + Ins_MIRP( EXEC_ARGS args ); + else if ( opcode >= 0xC0 ) + Ins_MDRP( EXEC_ARGS args ); + else if ( opcode >= 0xB8 ) + Ins_PUSHW( EXEC_ARGS args ); + else if ( opcode >= 0xB0 ) + Ins_PUSHB( EXEC_ARGS args ); + else + Ins_UNKNOWN( EXEC_ARGS args ); + } + + } +#else + Instruct_Dispatch[CUR.opcode]( EXEC_ARGS &CUR.stack[CUR.args] ); +#endif + if ( CUR.error != TT_Err_Ok ) + { + switch ( (Int)(CUR.error) ) + { + case TT_Err_Invalid_Opcode: /* looking for redefined instructions */ + A = 0; + + while ( A < CUR.numIDefs ) + { + WITH = &CUR.IDefs[A]; + + if ( WITH->Active && CUR.opcode == WITH->Opc ) + { + if ( CUR.callTop >= CUR.callSize ) + { + CUR.error = TT_Err_Invalid_Reference; + goto LErrorLabel_; + } + + WITH1 = &CUR.callStack[CUR.callTop]; + + WITH1->Caller_Range = CUR.curRange; + WITH1->Caller_IP = CUR.IP + 1; + WITH1->Cur_Count = 1; + WITH1->Cur_Restart = WITH->Start; + + if ( INS_Goto_CodeRange( WITH->Range, WITH->Start ) == FAILURE ) + goto LErrorLabel_; + + goto LSuiteLabel_; + } + else + { + A++; + continue; + } + } + + CUR.error = TT_Err_Invalid_Opcode; + goto LErrorLabel_; +/* break; Unreachable code warning suppress. Leave in case a later + change to remind the editor to consider break; */ + + default: + goto LErrorLabel_; +/* break; */ + } + } + + CUR.top = CUR.new_top; + + if ( CUR.step_ins ) + CUR.IP += CUR.length; + + /* increment instruction counter and check if we didn't */ + /* run this program for too long ?? (e.g. infinite loops) */ + if ( ++ins_counter > MAX_RUNNABLE_OPCODES ) + { + CUR.error = TT_Err_Execution_Too_Long; + goto LErrorLabel_; + } + + LSuiteLabel_: + + if ( CUR.IP >= CUR.codeSize ) + { + if ( CUR.callTop > 0 ) + { + CUR.error = TT_Err_Code_Overflow; + goto LErrorLabel_; + } + else + goto LNo_Error_; + } + } while ( !CUR.instruction_trap ); + + LNo_Error_: + CUR.error = TT_Err_Ok; + + LErrorLabel_: + +#ifdef TT_CONFIG_OPTION_STATIC_INTERPRETER + *exc = cur; +#endif + + return CUR.error; + + + } + + +#ifdef DEBUG_INTERPRETER + + /* This function must be declared by the debugger front end */ + /* in order to specify which code range to debug. */ + + int debug_coderange = TT_CodeRange_Glyph; + + + LOCAL_FUNC + TT_Error RunIns( PExecution_Context exc ) + { + Int A, diff; + ULong next_IP; + Char ch, oldch; + char *temp; + int key; + + TT_Error error = 0; + + TGlyph_Zone save; + TGlyph_Zone pts; + +#define TT_Round_Off 5 +#define TT_Round_To_Half_Grid 0 +#define TT_Round_To_Grid 1 +#define TT_Round_To_Double_Grid 2 +#define TT_Round_Up_To_Grid 4 +#define TT_Round_Down_To_Grid 3 +#define TT_Round_Super 6 +#define TT_Round_Super_45 7 + + const String* round_str[8] = + { + "to half-grid", + "to grid", + "to double grid", + "down to grid", + "up to grid", + "off", + "super", + "super 45" + }; + + /* Check that we're running the code range that is effectively */ + /* asked by the debugger front end. */ + if ( exc->curRange != debug_coderange ) + return RunIns2( exc ); + + pts = exc->pts; + + save.n_points = pts.n_points; + save.n_contours = pts.n_contours; + + MEM_Alloc( save.org, sizeof ( TT_Vector ) * save.n_points ); + MEM_Alloc( save.cur, sizeof ( TT_Vector ) * save.n_points ); + MEM_Alloc( save.touch, sizeof ( Byte ) * save.n_points ); + + exc->instruction_trap = 1; + + oldch = '\0'; + + do + { + if ( exc->IP < exc->codeSize ) + { +#ifdef TT_CONFIG_OPTION_STATIC_INTERPRETER + cur = *exc; +#endif + CALC_Length(); + + exc->args = exc->top - (Pop_Push_Count[exc->opcode] >> 4); + + /* `args' is the top of the stack once arguments have been popped. */ + /* One can also interpret it as the index of the last argument. */ + + /* Print the current line. We use a 80-columns console with the */ + /* following formatting: */ + /* */ + /* [loc]:[addr] [opcode] [disassemby] [a][b]|[c][d] */ + /* */ + + { + char temp[80]; + int n, col, pop; + int args = CUR.args; + + + sprintf( temp, "%78c\n", ' ' ); + + /* first letter of location */ + switch ( CUR.curRange ) + { + case TT_CodeRange_Glyph: + temp[0] = 'g'; + break; + case TT_CodeRange_Cvt: + temp[0] = 'c'; + break; + default: + temp[0] = 'f'; + } + + /* current IP */ + sprintf( temp+1, "%04lx: %02x %-36.36s", + CUR.IP, + CUR.opcode, + Cur_U_Line(&CUR) ); + + strncpy( temp+46, " (", 2 ); + + args = CUR.top - 1; + pop = Pop_Push_Count[CUR.opcode] >> 4; + col = 48; + for ( n = 6; n > 0; n-- ) + { + if ( pop == 0 ) + temp[col-1] = (temp[col-1] == '(' ? ' ' : ')' ); + + if ( args < CUR.top && args >= 0 ) + sprintf( temp+col, "%04lx", CUR.stack[args] ); + else + sprintf( temp+col, " " ); + + temp[col+4] = ' '; + col += 5; + pop--; + args--; + } + temp[78] = '\n'; + temp[79] = '\0'; + PTRACE0(( temp )); + } + + /* First, check for empty stack and overflow */ + if ( CUR.args < 0 ) + { + PTRACE0(( "ERROR : Too few arguments\n" )); + exc->error = TT_Err_Too_Few_Arguments; + goto LErrorLabel_; + } + + CUR.new_top = CUR.args + (Pop_Push_Count[CUR.opcode] & 15); + + /* new_top is the new top of the stack, after the instruction's */ + /* execution. top will be set to new_top after the 'case' */ + + if ( CUR.new_top > CUR.stackSize ) + { + PTRACE0(( "ERROR : Stack overflow\n" )); + exc->error = TT_Err_Stack_Overflow; + goto LErrorLabel_; + } + } + else + PTRACE0(( "End of program reached.\n" )); + + key = 0; + do + { + /* read keyboard */ + + ch = getch(); + + switch ( ch ) + { + /* Help - show keybindings */ + case '?': + PTRACE0(( "FDebug Help\n\n" )); + PTRACE0(( "? Show this page\n" )); + PTRACE0(( "q Quit debugger\n" )); + PTRACE0(( "n Skip to next instruction\n" )); + PTRACE0(( "s Step into\n" )); + PTRACE0(( "v Show vector info\n" )); + PTRACE0(( "g Show graphics state\n" )); + PTRACE0(( "p Show points zone\n\n" )); + break; + + /* Show vectors */ + case 'v': + PTRACE0(( "freedom (%04hx,%04hx)\n", exc->GS.freeVector.x, + exc->GS.freeVector.y )); + PTRACE0(( "projection (%04hx,%04hx)\n", exc->GS.projVector.x, + exc->GS.projVector.y )); + PTRACE0(( "dual (%04hx,%04hx)\n\n", exc->GS.dualVector.x, + exc->GS.dualVector.y )); + break; + + /* Show graphics state */ + case 'g': + PTRACE0(( "rounding %s\n", round_str[exc->GS.round_state] )); + PTRACE0(( "min dist %04lx\n", exc->GS.minimum_distance )); + PTRACE0(( "cvt_cutin %04lx\n", exc->GS.control_value_cutin )); + break; + + /* Show points table */ + case 'p': + for ( A = 0; A < exc->pts.n_points; A++ ) + { + PTRACE0(( "%02hx ", A )); + PTRACE0(( "%08lx,%08lx - ", pts.org[A].x, pts.org[A].y )); + PTRACE0(( "%08lx,%08lx\n", pts.cur[A].x, pts.cur[A].y )); + } + PTRACE0(( "\n" )); + break; + + default: + key = 1; + } + } while ( !key ); + + MEM_Copy( save.org, pts.org, pts.n_points * sizeof ( TT_Vector ) ); + MEM_Copy( save.cur, pts.cur, pts.n_points * sizeof ( TT_Vector ) ); + MEM_Copy( save.touch, pts.touch, pts.n_points ); + + /* a return indicate the last command */ + if (ch == '\r') + ch = oldch; + + switch ( ch ) + { + /* Quit debugger */ + case 'q': + goto LErrorLabel_; + + /* Step over */ + case 'n': + if ( exc->IP < exc->codeSize ) + { + /* `step over' is equivalent to `step into' except if */ + /* the current opcode is a CALL or LOOPCALL */ + if ( CUR.opcode != 0x2a && CUR.opcode != 0x2b ) + goto Step_into; + + /* otherwise, loop execution until we reach the next opcode */ + next_IP = CUR.IP + CUR.length; + while ( exc->IP != next_IP ) + { + if ( ( error = RunIns2( exc ) ) ) + goto LErrorLabel_; + } + } + oldch = ch; + break; + + /* Step into */ + case 's': + if ( exc->IP < exc->codeSize ) + + Step_into: + if ( ( error = RunIns2( exc ) ) ) + goto LErrorLabel_; + oldch = ch; + break; + + default: + PTRACE0(( "unknown command. Press ? for help\n" )); + oldch = '\0'; + } + + for ( A = 0; A < pts.n_points; A++ ) + { + diff = 0; + if ( save.org[A].x != pts.org[A].x ) diff |= 1; + if ( save.org[A].y != pts.org[A].y ) diff |= 2; + if ( save.cur[A].x != pts.cur[A].x ) diff |= 4; + if ( save.cur[A].y != pts.cur[A].y ) diff |= 8; + if ( save.touch[A] != pts.touch[A] ) diff |= 16; + + if ( diff ) + { + PTRACE0(( "%02hx ", A )); + + if ( diff & 16 ) temp = "(%01hx)"; else temp = " %01hx "; + PTRACE0(( temp, save.touch[A] & 7 )); + + if ( diff & 1 ) temp = "(%08lx)"; else temp = " %08lx "; + PTRACE0(( temp, save.org[A].x )); + + if ( diff & 2 ) temp = "(%08lx)"; else temp = " %08lx "; + PTRACE0(( temp, save.org[A].y )); + + if ( diff & 4 ) temp = "(%08lx)"; else temp = " %08lx "; + PTRACE0(( temp, save.cur[A].x )); + + if ( diff & 8 ) temp = "(%08lx)"; else temp = " %08lx "; + PTRACE0(( temp, save.cur[A].y )); + + PTRACE0(( "\n" )); + + PTRACE0(( "%02hx ", A )); + + if ( diff & 16 ) temp = "[%01hx]"; else temp = " %01hx "; + PTRACE0(( temp, pts.touch[A] & 7 )); + + if ( diff & 1 ) temp = "[%08lx]"; else temp = " %08lx "; + PTRACE0(( temp, pts.org[A].x )); + + if ( diff & 2 ) temp = "[%08lx]"; else temp = " %08lx "; + PTRACE0(( temp, pts.org[A].y )); + + if ( diff & 4 ) temp = "[%08lx]"; else temp = " %08lx "; + PTRACE0(( temp, pts.cur[A].x )); + + if ( diff & 8 ) temp = "[%08lx]"; else temp = " %08lx "; + PTRACE0(( temp, pts.cur[A].y )); + + PTRACE0(( "\n\n" )); + } + } + } while ( TRUE ); + + LErrorLabel_: + + return error; + } + +#endif /* DEBUG_INTERPRETER */ + + +#endif /* TT_CONFIG_OPTION_NO_INTERPRETER */ + +/* END */ diff --git a/lib/ttinterp.h b/lib/ttinterp.h new file mode 100644 index 0000000..d991fa0 --- /dev/null +++ b/lib/ttinterp.h @@ -0,0 +1,54 @@ +/******************************************************************* + * + * ttinterp.h 2.2 + * + * TrueType bytecode intepreter. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * Changes between 2.2 and 2.1: + * + * - a small bugfix in the Push opcodes + * + * Changes between 2.1 and 2.0: + * + * - created the TTExec component to take care of all execution + * context management. The interpreter has now one single + * function. + * + * - made some changes to support re-entrancy. The re-entrant + * interpreter is smaller! + * + ******************************************************************/ + +#ifndef TTINTERP_H +#define TTINTERP_H + +#include "ttconfig.h" +#include "ttobjs.h" + + +#ifdef __cplusplus + extern "C" { +#endif + + /* Run instructions in current execution context */ + + LOCAL_DEF TT_Error RunIns( PExecution_Context exc ); + +#ifdef __cplusplus + } +#endif + +#endif /* TTINTERP_H */ + + +/* END */ diff --git a/lib/ttload.c b/lib/ttload.c new file mode 100644 index 0000000..282828f --- /dev/null +++ b/lib/ttload.c @@ -0,0 +1,1574 @@ + +/******************************************************************* + * + * ttload.c 1.0 + * + * TrueType Tables Loader. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include "tttypes.h" +#include "ttdebug.h" +#include "ttcalc.h" +#include "ttfile.h" + +#include "tttables.h" +#include "ttobjs.h" + +#include "ttmemory.h" +#include "tttags.h" +#include "ttload.h" + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_load + +/* In all functions, the stream is taken from the 'face' object */ +#define DEFINE_LOCALS DEFINE_LOAD_LOCALS( face->stream ) +#define DEFINE_LOCALS_WO_FRAME DEFINE_LOAD_LOCALS_WO_FRAME( face->stream ) + + +/******************************************************************* + * + * Function : LookUp_TrueType_Table + * + * Description : Looks for a TrueType table by name. + * + * Input : face face table to look for + * tag searched tag + * + * Output : Index of table if found, -1 otherwise. + * + ******************************************************************/ + + EXPORT_FUNC + Long TT_LookUp_Table( PFace face, + ULong tag ) + { + UShort i; + + + PTRACE4(( "TT_LookUp_Table( %08lx, %c%c%c%c )\n", + (Long)face, + (Char)(tag >> 24), + (Char)(tag >> 16), + (Char)(tag >> 8), + (Char)(tag) )); + + for ( i = 0; i < face->numTables; i++ ) + if ( face->dirTables[i].Tag == tag ) + return i; + + PTRACE4(( " Could not find table!\n" )); + return -1; + } + + +/******************************************************************* + * + * Function : Load_TrueType_Collection + * + * Description : Loads the TTC table directory into face table. + * + * Input : face face record to look for + * + * Output : Error code. + * + ******************************************************************/ + + static TT_Error Load_TrueType_Collection( PFace face ) + { + DEFINE_LOCALS; + + ULong n; + + + PTRACE3(( "Load_TrueType_Collection( %08lx )\n", (long)face )); + + if ( FILE_Seek ( 0L ) || + ACCESS_Frame( 12L ) ) + return error; + + face->ttcHeader.Tag = GET_Tag4(); + face->ttcHeader.version = GET_Long(); + face->ttcHeader.DirCount = GET_Long(); + + FORGET_Frame(); + + if ( face->ttcHeader.Tag != TTAG_ttcf ) + { + face->ttcHeader.Tag = 0; + face->ttcHeader.version = 0; + face->ttcHeader.DirCount = 0; + + face->ttcHeader.TableDirectory = NULL; + + PTRACE3(("skipped.\n")); + + return TT_Err_File_Is_Not_Collection; + } + + if ( ALLOC_ARRAY( face->ttcHeader.TableDirectory, + face->ttcHeader.DirCount, + ULong ) || + ACCESS_Frame( face->ttcHeader.DirCount * 4L ) ) + return error; + + for ( n = 0; n < face->ttcHeader.DirCount; n++ ) + face->ttcHeader.TableDirectory[n] = GET_ULong(); + + FORGET_Frame(); + + PTRACE3(( "collections directory loaded.\n" )); + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_Directory + * + * Description : Loads the table directory into face table. + * + * Input : face face record to look for + * + * faceIndex the index of the TrueType font, when + * we're opening a collection. + * + * Output : SUCCESS on success. FAILURE on error. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_Directory( PFace face, ULong faceIndex ) + { + DEFINE_LOCALS; + + UShort n, limit; + TTableDir tableDir; + + PTableDirEntry entry; + + + PTRACE2(("Load_TT_Directory( %08lx, %ld )\n", (long)face, faceIndex)); + + error = Load_TrueType_Collection( face ); + + if ( error ) + { + if ( error != TT_Err_File_Is_Not_Collection ) + return error; + + /* the file isn't a collection, exit if we're asking */ + /* for a collected font */ + if ( faceIndex != 0 ) + return error; + + /* Now skip to the beginning of the file */ + if ( FILE_Seek( 0L ) ) + return error; + } + else + { + /* The file is a collection. Check the font index */ + if ( faceIndex >= face->ttcHeader.DirCount ) + return TT_Err_Invalid_Argument; + + /* select a TrueType font in the ttc file */ + if ( FILE_Seek( face->ttcHeader.TableDirectory[faceIndex] ) ) + return error; + } + + if ( ACCESS_Frame( 12L ) ) + return error; + + tableDir.version = GET_Long(); + tableDir.numTables = GET_UShort(); + + tableDir.searchRange = GET_UShort(); + tableDir.entrySelector = GET_UShort(); + tableDir.rangeShift = GET_UShort(); + + FORGET_Frame(); + + PTRACE2(( "-- Tables count : %12u\n", tableDir.numTables )); + PTRACE2(( "-- Format version : %08lx\n", tableDir.version )); + + /* Check that we have a 'sfnt' format there */ + + if ( tableDir.version != 0x00010000 && /* MS fonts */ + tableDir.version != 0x74727565 && /* Mac fonts */ + tableDir.version != 0x00000000 ) /* some Korean fonts */ + { + PERROR(( "!! invalid file format" )); + return TT_Err_Invalid_File_Format; + } + + face->numTables = tableDir.numTables; + + if ( ALLOC_ARRAY( face->dirTables, + face->numTables, + TTableDirEntry ) ) + return error; + + if ( ACCESS_Frame( face->numTables * 16L ) ) + return error; + + limit = face->numTables; + entry = face->dirTables; + + for ( n = 0; n < limit; n++ ) + { /* loop through the tables and get all entries */ + entry->Tag = GET_Tag4(); + entry->CheckSum = GET_ULong(); + entry->Offset = GET_Long(); + entry->Length = GET_Long(); + + PTRACE2(( " %c%c%c%c - %08lx - %08lx\n", + (Char)(entry->Tag >> 24), + (Char)(entry->Tag >> 16), + (Char)(entry->Tag >> 8 ), + (Char)(entry->Tag), + entry->Offset, + entry->Length )); + entry++; + } + + FORGET_Frame(); + + PTRACE2(( "Directory loaded\n\n" )); + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_MaxProfile + * + * Description : Loads the maxp table into face table. + * + * Input : face face table to look for + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_MaxProfile( PFace face ) + { + DEFINE_LOCALS; + + Long i; + PMaxProfile maxProfile = &face->maxProfile; + + + PTRACE2(( "Load_TT_MaxProfile( %08lx )\n", (long)face )); + + if ( ( i = TT_LookUp_Table( face, TTAG_maxp ) ) < 0 ) + return TT_Err_Max_Profile_Missing; + + if ( FILE_Seek( face->dirTables[i].Offset ) ) /* seek to maxprofile */ + return error; + + if ( ACCESS_Frame( 32L ) ) /* read into frame */ + return error; + + /* read frame data into face table */ + maxProfile->version = GET_ULong(); + + maxProfile->numGlyphs = GET_UShort(); + + maxProfile->maxPoints = GET_UShort(); + maxProfile->maxContours = GET_UShort(); + maxProfile->maxCompositePoints = GET_UShort(); + maxProfile->maxCompositeContours = GET_UShort(); + + maxProfile->maxZones = GET_UShort(); + maxProfile->maxTwilightPoints = GET_UShort(); + + maxProfile->maxStorage = GET_UShort(); + maxProfile->maxFunctionDefs = GET_UShort(); + maxProfile->maxInstructionDefs = GET_UShort(); + maxProfile->maxStackElements = GET_UShort(); + maxProfile->maxSizeOfInstructions = GET_UShort(); + maxProfile->maxComponentElements = GET_UShort(); + maxProfile->maxComponentDepth = GET_UShort(); + + FORGET_Frame(); + + /* XXX : an adjustement that is necessary to load certain */ + /* broken fonts like "Keystrokes MT" :-( */ + /* */ + /* We allocate 64 function entries by default when */ + /* the maxFunctionDefs field is null. */ + + if (maxProfile->maxFunctionDefs == 0) + maxProfile->maxFunctionDefs = 64; + + face->numGlyphs = maxProfile->numGlyphs; + + face->maxPoints = MAX( maxProfile->maxCompositePoints, + maxProfile->maxPoints ); + face->maxContours = MAX( maxProfile->maxCompositeContours, + maxProfile->maxContours ); + face->maxComponents = maxProfile->maxComponentElements + + maxProfile->maxComponentDepth; + + /* XXX: Some fonts have maxComponents set to 0; we will */ + /* then use 16 of them by default. */ + if ( face->maxComponents == 0 ) + face->maxComponents = 16; + + /* We also increase maxPoints and maxContours in order to support */ + /* some broken fonts. */ + face->maxPoints += 8; + face->maxContours += 4; + + PTRACE2(( "GASP loaded.\n" )); + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_Gasp + * + * Description : Loads the TrueType Gasp table into the face + * table. + * + * Input : face face table to look for + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_Gasp( PFace face ) + { + DEFINE_LOCALS; + + Long i; + UShort j; + TGasp* gas; + GaspRange* gaspranges; + + + PTRACE2(( "Load_TT_Gasp( %08lx )\n", (long)face )); + + if ( ( i = TT_LookUp_Table( face, TTAG_gasp ) ) < 0 ) + return TT_Err_Ok; /* gasp table is not required */ + + if ( FILE_Seek( face->dirTables[i].Offset ) || + ACCESS_Frame( 4L ) ) + return error; + + gas = &face->gasp; + + gas->version = GET_UShort(); + gas->numRanges = GET_UShort(); + + FORGET_Frame(); + + PTRACE3(( "number of ranges = %d\n", gas->numRanges )); + + if ( ALLOC_ARRAY( gaspranges, gas->numRanges, GaspRange ) || + ACCESS_Frame( gas->numRanges * 4L ) ) + goto Fail; + + face->gasp.gaspRanges = gaspranges; + + for ( j = 0; j < gas->numRanges; j++ ) + { + gaspranges[j].maxPPEM = GET_UShort(); + gaspranges[j].gaspFlag = GET_UShort(); + + PTRACE3(( " [max:%d flag:%d]", + gaspranges[j].maxPPEM, + gaspranges[j].gaspFlag )); + } + PTRACE3(("\n")); + + FORGET_Frame(); + + PTRACE2(( "GASP loaded\n" )); + return TT_Err_Ok; + + Fail: + FREE( gaspranges ); + gas->numRanges = 0; + return error; + } + + +/******************************************************************* + * + * Function : Load_TrueType_Header + * + * Description : Loads the TrueType header table into the face + * table. + * + * Input : face face table to look for + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_Header( PFace face ) + { + DEFINE_LOCALS; + + Long i; + TT_Header* header; + + + PTRACE2(( "Load_TT_Header( %08lx )\n", (long)face )); + + if ( ( i = TT_LookUp_Table( face, TTAG_head ) ) < 0 ) + { + PTRACE0(( "Font Header is missing !!\n" )); + return TT_Err_Header_Table_Missing; + } + + if ( FILE_Seek( face->dirTables[i].Offset ) || + ACCESS_Frame( 54L ) ) + return error; + + header = &face->fontHeader; + + header->Table_Version = GET_ULong(); + header->Font_Revision = GET_ULong(); + + header->CheckSum_Adjust = GET_Long(); + header->Magic_Number = GET_Long(); + + header->Flags = GET_UShort(); + header->Units_Per_EM = GET_UShort(); + + header->Created [0] = GET_Long(); + header->Created [1] = GET_Long(); + header->Modified[0] = GET_Long(); + header->Modified[1] = GET_Long(); + + header->xMin = GET_Short(); + header->yMin = GET_Short(); + header->xMax = GET_Short(); + header->yMax = GET_Short(); + + header->Mac_Style = GET_UShort(); + header->Lowest_Rec_PPEM = GET_UShort(); + + header->Font_Direction = GET_Short(); + header->Index_To_Loc_Format = GET_Short(); + header->Glyph_Data_Format = GET_Short(); + + FORGET_Frame(); + + PTRACE2(( " Units per EM : %8u\n", header->Units_Per_EM )); + PTRACE2(( " IndexToLoc : %8d\n", header->Index_To_Loc_Format )); + PTRACE2(( "Font Header Loaded.\n" )); + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_Metrics + * + * Description : Loads the horizontal or vertical metrics table + * into face object. + * + * Input : face + * vertical set to true when loading the vmtx table, + * or false for hmtx + * + * Output : Error code. + * + ******************************************************************/ + + static + TT_Error Load_TrueType_Metrics( PFace face, + Bool vertical ) + { + DEFINE_LOCALS; + + Long n, num_shorts, num_shorts_checked, num_longs; + + PLongMetrics* longs; + PShortMetrics* shorts; + + PLongMetrics long_metric; + + + PTRACE2(( "Load_TT_%s_Metrics( %08lx )\n", + vertical ? "Vertical" : "Horizontal", + (long)face )); + + if ( vertical ) + { + /* The table is optional, quit silently if it wasn't found */ + /* XXX : Some fonts have a valid vertical header with a non-null */ + /* "number_of_VMetrics" fields, but no corresponding */ + /* 'vmtx' table to get the metrics from (e.g. mingliu) */ + /* */ + /* For safety, we set the field to 0 ! */ + /* */ + n = TT_LookUp_Table( face, TTAG_vmtx ); + if ( n < 0 ) + { + /* Set the number_Of_VMetrics to 0! */ + PTRACE2(( " no vertical header in file.\n" )); + face->verticalHeader.number_Of_VMetrics = 0; + return TT_Err_Ok; + } + + num_longs = face->verticalHeader.number_Of_VMetrics; + longs = (PLongMetrics*)&face->verticalHeader.long_metrics; + shorts = (PShortMetrics*)&face->verticalHeader.short_metrics; + } + else + { + if ( ( n = TT_LookUp_Table( face, TTAG_hmtx ) ) < 0 ) + { + PERROR(( "!! No Horizontal metrics in file !!\n" )); + return TT_Err_Hmtx_Table_Missing; + } + + num_longs = face->horizontalHeader.number_Of_HMetrics; + longs = (PLongMetrics*)&face->horizontalHeader.long_metrics; + shorts = (PShortMetrics*)&face->horizontalHeader.short_metrics; + } + + /* never trust derived values! */ + + num_shorts = face->maxProfile.numGlyphs - num_longs; + num_shorts_checked = ( face->dirTables[n].Length - num_longs * 4 ) / 2; + + if ( num_shorts < 0 ) /* sanity check */ + { + PERROR(( "!! more metrics than glyphs!\n" )); + if ( vertical ) + return TT_Err_Invalid_Vert_Metrics; + else + return TT_Err_Invalid_Horiz_Metrics; + } + + if ( ALLOC_ARRAY( *longs, num_longs, TLongMetrics ) || + ALLOC_ARRAY( *shorts, num_shorts, TShortMetrics ) ) + return error; + + if ( FILE_Seek( face->dirTables[n].Offset ) || + ACCESS_Frame( face->dirTables[n].Length ) ) + return error; + + long_metric = *longs; + for ( n = 0; n < num_longs; n++ ) + { + long_metric->advance = GET_UShort(); + long_metric->bearing = GET_Short(); + long_metric++; + } + + /* do we have an inconsistent number of metric values? */ + + if ( num_shorts > num_shorts_checked ) + { + for ( n = 0; n < num_shorts_checked; n++ ) + (*shorts)[n] = GET_Short(); + + /* we fill up the missing left side bearings with the */ + /* last valid value. Since this will occur for buggy CJK */ + /* fonts usually, nothing serious will happen. */ + + for ( n = num_shorts_checked; n < num_shorts; n++ ) + (*shorts)[n] = (*shorts)[num_shorts_checked - 1]; + } + else + { + for ( n = 0; n < num_shorts; n++ ) + (*shorts)[n] = GET_Short(); + } + + FORGET_Frame(); + + PTRACE2(( "loaded\n" )); + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_Metrics_Header + * + * Description : Loads either the "hhea" or "vhea" table in memory + * + * Input : face face table to look for + * vertical a boolean. When set, queries the optional + * "vhea" table. Otherwise, load the mandatory + * "hhea" horizontal header. + * + * Output : Error code. + * + * Note : This function now loads the corresponding metrics table + * (either hmtx or vmtx) and attaches it to the header. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_Metrics_Header( PFace face, + Bool vertical ) + { + DEFINE_LOCALS; + + Long i; + + TT_Horizontal_Header* header; + + + PTRACE2(( vertical ? "Vertical header" : "Horizontal header " )); + + if ( vertical ) + { + face->verticalInfo = 0; + + /* The vertical header table is optional, so return quietly if */ + /* we don't find it.. */ + if ( ( i = TT_LookUp_Table( face, TTAG_vhea ) ) < 0 ) + return TT_Err_Ok; + + face->verticalInfo = 1; + header = (TT_Horizontal_Header*)&face->verticalHeader; + } + else + { + /* The orizontal header is mandatory, return an error if we */ + /* don't find it. */ + if ( ( i = TT_LookUp_Table( face, TTAG_hhea ) ) < 0 ) + return TT_Err_Horiz_Header_Missing; + + header = &face->horizontalHeader; + } + + if ( FILE_Seek( face->dirTables[i].Offset ) || + ACCESS_Frame( 36L ) ) + return error; + + header->Version = GET_ULong(); + header->Ascender = GET_Short(); + header->Descender = GET_Short(); + header->Line_Gap = GET_Short(); + + header->advance_Width_Max = GET_UShort(); + + header->min_Left_Side_Bearing = GET_Short(); + header->min_Right_Side_Bearing = GET_Short(); + header->xMax_Extent = GET_Short(); + header->caret_Slope_Rise = GET_Short(); + header->caret_Slope_Run = GET_Short(); + + header->Reserved0 = GET_Short(); /* this is caret_Offset for + vertical headers */ + header->Reserved1 = GET_Short(); + header->Reserved2 = GET_Short(); + header->Reserved3 = GET_Short(); + header->Reserved4 = GET_Short(); + + header->metric_Data_Format = GET_Short(); + header->number_Of_HMetrics = GET_UShort(); + + FORGET_Frame(); + + header->long_metrics = NULL; + header->short_metrics = NULL; + + PTRACE2(( "loaded\n" )); + + /* Now try to load the corresponding metrics */ + + return Load_TrueType_Metrics( face, vertical ); + } + + +/******************************************************************* + * + * Function : Load_TrueType_Locations + * + * Description : Loads the location table into face table. + * + * Input : face face table to look for + * + * Output : Error code. + * + * NOTE: + * The Font Header *must* be loaded in the leading segment + * calling this function. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_Locations( PFace face ) + { + DEFINE_LOCALS; + + Long n, limit; + Short LongOffsets; + + + PTRACE2(( "Locations " )); + + LongOffsets = face->fontHeader.Index_To_Loc_Format; + + if ( ( n = TT_LookUp_Table( face, TTAG_loca ) ) < 0 ) + return TT_Err_Locations_Missing; + + if ( FILE_Seek( face->dirTables[n].Offset ) ) + return error; + + if ( LongOffsets != 0 ) + { + face->numLocations = face->dirTables[n].Length >> 2; + + PTRACE2(( "(32 bit offsets): %12lu ", + face->numLocations )); + + if ( ALLOC_ARRAY( face->glyphLocations, + face->numLocations, + Long ) ) + return error; + + if ( ACCESS_Frame( face->numLocations * 4L ) ) + return error; + + limit = face->numLocations; + + for ( n = 0; n < limit; n++ ) + face->glyphLocations[n] = GET_Long(); + + FORGET_Frame(); + } + else + { + face->numLocations = face->dirTables[n].Length >> 1; + + PTRACE2(( "(16 bit offsets): %12lu ", + face->numLocations )); + + if ( ALLOC_ARRAY( face->glyphLocations, + face->numLocations, + Long ) ) + return error; + + if ( ACCESS_Frame( face->numLocations * 2L ) ) + return error; + + limit = face->numLocations; + + for ( n = 0; n < limit; n++ ) + face->glyphLocations[n] = + (Long)((ULong)GET_UShort() * 2); + + FORGET_Frame(); + } + + PTRACE2(( "loaded\n" )); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_Names + * + * Description : Loads the name table into face table. + * + * Input : face face table to look for + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_Names( PFace face ) + { + DEFINE_LOCALS; + + UShort i, bytes; + Long n; + PByte storage; + + TName_Table* names; + TNameRec* namerec; + + + PTRACE2(( "Names " )); + + if ( ( n = TT_LookUp_Table( face, TTAG_name ) ) < 0 ) + { + /* The name table is required so indicate failure. */ + PTRACE2(( "is missing!\n" )); + + return TT_Err_Name_Table_Missing; + } + + /* Seek to the beginning of the table and check the frame access. */ + /* The names table has a 6 byte header. */ + if ( FILE_Seek( face->dirTables[n].Offset ) || + ACCESS_Frame( 6L ) ) + return error; + + names = &face->nameTable; + + /* Load the initial names data. */ + names->format = GET_UShort(); + names->numNameRecords = GET_UShort(); + names->storageOffset = GET_UShort(); + + FORGET_Frame(); + + /* Allocate the array of name records. */ + if ( ALLOC_ARRAY( names->names, + names->numNameRecords, + TNameRec ) || + ACCESS_Frame( names->numNameRecords * 12L ) ) + { + names->numNameRecords = 0; + goto Fail; + } + + /* Load the name records and determine how much storage is needed */ + /* to hold the strings themselves. */ + + for ( i = bytes = 0; i < names->numNameRecords; i++ ) + { + namerec = names->names + i; + namerec->platformID = GET_UShort(); + namerec->encodingID = GET_UShort(); + namerec->languageID = GET_UShort(); + namerec->nameID = GET_UShort(); + namerec->stringLength = GET_UShort(); + namerec->stringOffset = GET_UShort(); + +#if 0 + /* check the ids */ + if ( namerec->platformID <= 3 ) + { +#endif + /* this test takes care of 'holes' in the names tables, as */ + /* reported by Erwin */ + if ( (namerec->stringOffset + namerec->stringLength) > bytes ) + bytes = namerec->stringOffset + namerec->stringLength; +#if 0 + } +#endif + } + + FORGET_Frame(); + + /* Allocate storage for the strings if they exist. */ + + names->storage = NULL; + + if ( bytes > 0 ) + { + if ( ALLOC( storage, bytes ) || + FILE_Read_At( face->dirTables[n].Offset + names->storageOffset, + (void*)storage, + bytes ) ) + goto Fail_Storage; + + names->storage = storage; + + /* Go through and assign the string pointers to the name records. */ + + for ( i = 0; i < names->numNameRecords; i++ ) + { + namerec = names->names + i; + namerec->string = storage + names->names[i].stringOffset; + +/* It is possible (but rather unlikely) that a new platform ID will be */ +/* added by Apple, so we can't rule out IDs > 3. */ + +#if 0 + if ( namerec->platformID <= 3 ) + namerec->string = storage + names->names[i].stringOffset; + else + { + namerec->string = NULL; + namerec->stringLength = 0; + } +#endif + } + } + +#ifdef DEBUG_LEVEL_TRACE + + for ( i = 0; i < names->numNameRecords; i++ ) + { + int j; + + + PTRACE2(( "%d %d %x %d ", + names->names[i].platformID, + names->names[i].encodingID, + names->names[i].languageID, + names->names[i].nameID )); + + /* I know that M$ encoded strings are Unicode, */ + /* but this works reasonable well for debugging purposes. */ + for ( j = 0; j < names->names[i].stringLength; j++ ) + { + if (names->names[i].string) + { + Char c = *(names->names[i].string + j); + + + if ( (Byte)c < 128 ) + PTRACE2(( "%c", c )); + } + } + + PTRACE2(( "\n" )); + } + +#endif /* DEBUG_LEVEL_TRACE */ + + PTRACE2(( "loaded\n" )); + return TT_Err_Ok; + + Fail_Storage: + FREE( storage ); + + Fail: + Free_TrueType_Names( face ); + return error; + } + + +/******************************************************************* + * + * Function : Free_TrueType_Names + * + * Description : Frees a name table. + * + * Input : face face table to look for + * + * Output : TT_Err_Ok. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Free_TrueType_Names( PFace face ) + { + TName_Table* names = &face->nameTable; + + + /* free strings table */ + FREE( names->names ); + + /* free strings storage */ + FREE( names->storage ); + + names->numNameRecords = 0; + names->format = 0; + names->storageOffset = 0; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_CVT + * + * Description : Loads cvt table into resident table. + * + * Input : face face table to look for + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_CVT( PFace face ) + { + DEFINE_LOCALS; + + Long n, limit; + + + PTRACE2(( "CVT " )); + + if ( ( n = TT_LookUp_Table( face, TTAG_cvt ) ) < 0 ) + { + PTRACE2(( "is missing!\n" )); + + face->cvtSize = 0; + face->cvt = NULL; + return TT_Err_Ok; + } + + face->cvtSize = face->dirTables[n].Length / 2; + + if ( ALLOC_ARRAY( face->cvt, + face->cvtSize, + Short ) ) + return error; + + if ( FILE_Seek( face->dirTables[n].Offset ) || + ACCESS_Frame( face->cvtSize * 2L ) ) + return error; + + limit = face->cvtSize; + + for ( n = 0; n < limit; n++ ) + face->cvt[n] = GET_Short(); + + FORGET_Frame(); + + PTRACE2(( "loaded\n" )); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_CMap + * + * Description : Loads the cmap directory in memory. + * The cmaps themselves are loaded in ttcmap.c . + * + * Input : face + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_CMap( PFace face ) + { + DEFINE_LOCALS; + + Long off, table_start; + Long n, limit; + + TCMapDir cmap_dir; + TCMapDirEntry entry_; + PCMapTable cmap; + + + PTRACE2(( "CMaps " )); + + if ( ( n = TT_LookUp_Table( face, TTAG_cmap ) ) < 0 ) + return TT_Err_CMap_Table_Missing; + + table_start = face->dirTables[n].Offset; + + if ( ( FILE_Seek( table_start ) ) || + ( ACCESS_Frame( 4L ) ) ) /* 4 bytes cmap header */ + return error; + + cmap_dir.tableVersionNumber = GET_UShort(); + cmap_dir.numCMaps = GET_UShort(); + + FORGET_Frame(); + + off = FILE_Pos(); /* save offset to cmapdir[] which follows */ + + /* save space in face table for cmap tables */ + if ( ALLOC_ARRAY( face->cMaps, + cmap_dir.numCMaps, + TCMapTable ) ) + return error; + + face->numCMaps = cmap_dir.numCMaps; + + limit = face->numCMaps; + cmap = face->cMaps; + + for ( n = 0; n < limit; n++ ) + { + if ( FILE_Seek( off ) || + ACCESS_Frame( 8L ) ) + return error; + + /* extra code using entry_ for platxxx could be cleaned up later */ + cmap->loaded = FALSE; + cmap->platformID = entry_.platformID = GET_UShort(); + cmap->platformEncodingID = entry_.platformEncodingID = GET_UShort(); + + entry_.offset = GET_Long(); + + FORGET_Frame(); + + off = FILE_Pos(); + + if ( FILE_Seek( table_start + entry_.offset ) || + ACCESS_Frame( 6L ) ) + return error; + + cmap->format = GET_UShort(); + cmap->length = GET_UShort(); + cmap->version = GET_UShort(); + + FORGET_Frame(); + + cmap->offset = FILE_Pos(); + + cmap++; + } + + PTRACE2(( "loaded\n" )); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_Programs + * + * Description : Loads the font (fpgm) and cvt programs into the + * face table. + * + * Input : face + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_Programs( PFace face ) + { + DEFINE_LOCALS_WO_FRAME; + + Long n; + + + PTRACE2(( "Font program " )); + + /* The font program is optional */ + if ( ( n = TT_LookUp_Table( face, TTAG_fpgm ) ) < 0 ) + { + face->fontProgram = NULL; + face->fontPgmSize = 0; + + PTRACE2(( "is missing!\n" )); + } + else + { + face->fontPgmSize = face->dirTables[n].Length; + + if ( ALLOC( face->fontProgram, + face->fontPgmSize ) || + FILE_Read_At( face->dirTables[n].Offset, + (void*)face->fontProgram, + face->fontPgmSize ) ) + return error; + + PTRACE2(( "loaded, %12d bytes\n", face->fontPgmSize )); + } + + PTRACE2(( "Prep program " )); + + if ( ( n = TT_LookUp_Table( face, TTAG_prep ) ) < 0 ) + { + face->cvtProgram = NULL; + face->cvtPgmSize = 0; + + PTRACE2(( "is missing!\n" )); + } + else + { + face->cvtPgmSize = face->dirTables[n].Length; + + if ( ALLOC( face->cvtProgram, + face->cvtPgmSize ) || + FILE_Read_At( face->dirTables[n].Offset, + (void*)face->cvtProgram, + face->cvtPgmSize ) ) + return error; + + PTRACE2(( "loaded, %12d bytes\n", face->cvtPgmSize )); + } + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_OS2 + * + * Description : Loads the OS2 Table. + * + * Input : face + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_OS2( PFace face ) + { + DEFINE_LOCALS; + + Long i; + TT_OS2* os2; + + + PTRACE2(( "OS/2 Table " )); + + /* We now support old Mac fonts where the OS/2 table doesn't */ + /* exist. Simply put, we set the `version' field to 0xFFFF */ + /* and test this value each time we need to access the table. */ + if ( ( i = TT_LookUp_Table( face, TTAG_OS2 ) ) < 0 ) + { + PTRACE2(( "is missing\n!" )); + face->os2.version = 0xFFFF; + error = TT_Err_Ok; + return TT_Err_Ok; + } + + if ( FILE_Seek( face->dirTables[i].Offset ) || + ACCESS_Frame( 78L ) ) + return error; + + os2 = &face->os2; + + os2->version = GET_UShort(); + os2->xAvgCharWidth = GET_Short(); + os2->usWeightClass = GET_UShort(); + os2->usWidthClass = GET_UShort(); + os2->fsType = GET_Short(); + os2->ySubscriptXSize = GET_Short(); + os2->ySubscriptYSize = GET_Short(); + os2->ySubscriptXOffset = GET_Short(); + os2->ySubscriptYOffset = GET_Short(); + os2->ySuperscriptXSize = GET_Short(); + os2->ySuperscriptYSize = GET_Short(); + os2->ySuperscriptXOffset = GET_Short(); + os2->ySuperscriptYOffset = GET_Short(); + os2->yStrikeoutSize = GET_Short(); + os2->yStrikeoutPosition = GET_Short(); + os2->sFamilyClass = GET_Short(); + + for ( i = 0; i < 10; i++ ) + os2->panose[i] = GET_Byte(); + + os2->ulUnicodeRange1 = GET_ULong(); + os2->ulUnicodeRange2 = GET_ULong(); + os2->ulUnicodeRange3 = GET_ULong(); + os2->ulUnicodeRange4 = GET_ULong(); + + for ( i = 0; i < 4; i++ ) + os2->achVendID[i] = GET_Byte(); + + os2->fsSelection = GET_UShort(); + os2->usFirstCharIndex = GET_UShort(); + os2->usLastCharIndex = GET_UShort(); + os2->sTypoAscender = GET_Short(); + os2->sTypoDescender = GET_Short(); + os2->sTypoLineGap = GET_Short(); + os2->usWinAscent = GET_UShort(); + os2->usWinDescent = GET_UShort(); + + FORGET_Frame(); + + if ( os2->version >= 0x0001 ) + { + /* only version 1 tables */ + + if ( ACCESS_Frame( 8L ) ) /* read into frame */ + return error; + + os2->ulCodePageRange1 = GET_ULong(); + os2->ulCodePageRange2 = GET_ULong(); + + FORGET_Frame(); + } + else + { + os2->ulCodePageRange1 = 0; + os2->ulCodePageRange2 = 0; + } + + PTRACE2(( "loaded\n" )); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_PostScript + * + * Description : Loads the post table into face table. + * + * Input : face face table to look for + * + * Output : SUCCESS on success. FAILURE on error. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_PostScript( PFace face ) + { + DEFINE_LOCALS; + + Long i; + + TT_Postscript* post = &face->postscript; + + + PTRACE2(( "PostScript " )); + + if ( ( i = TT_LookUp_Table( face, TTAG_post ) ) < 0 ) + return TT_Err_Post_Table_Missing; + + if ( FILE_Seek( face->dirTables[i].Offset ) || + ACCESS_Frame( 32L ) ) + return error; + + /* read frame data into face table */ + + post->FormatType = GET_ULong(); + post->italicAngle = GET_ULong(); + post->underlinePosition = GET_Short(); + post->underlineThickness = GET_Short(); + post->isFixedPitch = GET_ULong(); + post->minMemType42 = GET_ULong(); + post->maxMemType42 = GET_ULong(); + post->minMemType1 = GET_ULong(); + post->maxMemType1 = GET_ULong(); + + FORGET_Frame(); + + /* we don't load the glyph names, we do that in a */ + /* library extension (ftxpost). */ + + PTRACE2(( "loaded\n" )); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_Hdmx + * + * Description : Loads the horizontal device metrics table. + * + * Input : face face object to look for + * + * Output : SUCCESS on success. FAILURE on error. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_Hdmx( PFace face ) + { + DEFINE_LOCALS; + + TT_Hdmx_Record* rec; + TT_Hdmx hdmx; + Long table; + UShort n, num_glyphs; + Long record_size; + + + hdmx.version = 0; + hdmx.num_records = 0; + hdmx.records = 0; + + face->hdmx = hdmx; + + if ( ( table = TT_LookUp_Table( face, TTAG_hdmx ) ) < 0 ) + return TT_Err_Ok; + + if ( FILE_Seek( face->dirTables[table].Offset ) || + ACCESS_Frame( 8L ) ) + return error; + + hdmx.version = GET_UShort(); + hdmx.num_records = GET_Short(); + record_size = GET_Long(); + + FORGET_Frame(); + + /* Only recognize format 0 */ + + if ( hdmx.version != 0 ) + return TT_Err_Ok; + + if ( ALLOC( hdmx.records, sizeof ( TT_Hdmx_Record ) * hdmx.num_records ) ) + return error; + + num_glyphs = face->numGlyphs; + record_size -= num_glyphs+2; + rec = hdmx.records; + + for ( n = 0; n < hdmx.num_records; n++ ) + { + /* read record */ + + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + rec->ppem = GET_Byte(); + rec->max_width = GET_Byte(); + + FORGET_Frame(); + + if ( ALLOC( rec->widths, num_glyphs ) || + FILE_Read( rec->widths, num_glyphs ) ) + goto Fail; + + /* skip padding bytes */ + if ( record_size > 0 ) + if ( FILE_Skip( record_size ) ) + goto Fail; + + rec++; + } + + face->hdmx = hdmx; + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < hdmx.num_records; n++ ) + FREE( hdmx.records[n].widths ); + + FREE( hdmx.records ); + return error; + } + + +/******************************************************************* + * + * Function : Free_TrueType_Hdmx + * + * Description : Frees the horizontal device metrics table. + * + * Input : face face object to look for + * + * Output : TT_Err_Ok. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Free_TrueType_Hdmx( PFace face ) + { + UShort n; + + + if ( !face ) + return TT_Err_Ok; + + for ( n = 0; n < face->hdmx.num_records; n++ ) + FREE( face->hdmx.records[n].widths ); + + FREE( face->hdmx.records ); + face->hdmx.num_records = 0; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_Any + * + * Description : Loads any font table into client memory. Used by + * the TT_Get_Font_Data() API function. + * + * Input : face face object to look for + * + * tag tag of table to load. Use the value 0 if you + * want to access the whole font file, else set + * this parameter to a valid TrueType table tag + * that you can forge with the MAKE_TT_TAG + * macro. + * + * offset starting offset in the table (or the file + * if tag == 0 ) + * + * buffer address of target buffer + * + * length address of decision variable : + * + * if length == NULL : + * load the whole table. returns an + * an error if 'offset' == 0 !! + * + * if *length == 0 : + * exit immediately, returning the + * length of the given table, or of + * the font file, depending on the + * value of 'tag' + * + * if *length != 0 : + * load the next 'length' bytes of + * table or font, starting at offset + * 'offset' (in table or font too). + * + * Output : Error condition + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_Any( PFace face, + ULong tag, + Long offset, + void* buffer, + Long* length ) + { + TT_Stream stream; + TT_Error error; + Long table; + ULong size; + + + if ( tag != 0 ) + { + /* look for tag in font directory */ + table = TT_LookUp_Table( face, tag ); + if ( table < 0 ) + return TT_Err_Table_Missing; + + offset += face->dirTables[table].Offset; + size = face->dirTables[table].Length; + } + else + /* tag = 0 -- the use want to access the font file directly */ + size = TT_Stream_Size( face->stream ); + + if ( length && *length == 0 ) + { + *length = size; + return TT_Err_Ok; + } + + if ( length ) + size = *length; + + if ( !USE_Stream( face->stream, stream ) ) + (void)FILE_Read_At( offset, buffer, size ); + DONE_Stream( stream ); + + return error; + } + + +/* END */ diff --git a/lib/ttload.h b/lib/ttload.h new file mode 100644 index 0000000..47acae9 --- /dev/null +++ b/lib/ttload.h @@ -0,0 +1,217 @@ +/******************************************************************* + * + * ttload.h 1.1 + * + * TrueType Tables Loader. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * Changes between 1.1 and 1.0 : + * + * - add function Load_TrueType_Any used by TT_Get_Font_Data + * + ******************************************************************/ + +#ifndef TTLOAD_H +#define TTLOAD_H + +#include "ttconfig.h" +#include "tttypes.h" +#include "ttobjs.h" + +#ifdef __cplusplus + extern "C" { +#endif + + EXPORT_DEF + Long TT_LookUp_Table( PFace face, ULong tag ); + + LOCAL_DEF TT_Error Load_TrueType_Directory ( PFace face, + ULong faceIndex ); + + LOCAL_DEF TT_Error Load_TrueType_MaxProfile ( PFace face ); + LOCAL_DEF TT_Error Load_TrueType_Gasp ( PFace face ); + LOCAL_DEF TT_Error Load_TrueType_Header ( PFace face ); + LOCAL_DEF TT_Error Load_TrueType_Locations ( PFace face ); + LOCAL_DEF TT_Error Load_TrueType_Names ( PFace face ); + LOCAL_DEF TT_Error Load_TrueType_CVT ( PFace face ); + LOCAL_DEF TT_Error Load_TrueType_CMap ( PFace face ); + LOCAL_DEF TT_Error Load_TrueType_Programs ( PFace face ); + LOCAL_DEF TT_Error Load_TrueType_OS2 ( PFace face ); + LOCAL_DEF TT_Error Load_TrueType_PostScript ( PFace face ); + LOCAL_DEF TT_Error Load_TrueType_Hdmx ( PFace face ); + + LOCAL_DEF TT_Error Load_TrueType_Metrics_Header( PFace face, + Bool vertical ); + + LOCAL_DEF TT_Error Load_TrueType_Any( PFace face, + ULong tag, + Long offset, + void* buffer, + Long* length ); + + LOCAL_DEF TT_Error Free_TrueType_Names( PFace face ); + LOCAL_DEF TT_Error Free_TrueType_Hdmx ( PFace face ); + + +/* The following macros are defined to simplify the writing of */ +/* the various table and glyph loaders. */ + +/* For examples see the code in ttload.c, ttgload.c etc. */ + +#define USE_Stream( original, duplicate ) \ + ( (error = TT_Use_Stream( original, &duplicate )) != TT_Err_Ok ) + +#define DONE_Stream( _stream ) \ + TT_Done_Stream( &_stream ) + +/* Define a file frame -- use it only when needed */ +#define DEFINE_A_FRAME TFileFrame frame = TT_Null_FileFrame + +/* Define a stream -- use it only when needed */ +#define DEFINE_A_STREAM TT_Stream stream + + +#ifdef TT_CONFIG_OPTION_THREAD_SAFE /* re-entrant implementation */ + +/* The following macros define the necessary local */ +/* variables used to access streams and frames. */ + +/* Define stream locals with frame */ +#define DEFINE_STREAM_LOCALS \ + TT_Error error; \ + DEFINE_A_STREAM; \ + DEFINE_A_FRAME + +/* Define stream locals without frame */ +#define DEFINE_STREAM_LOCALS_WO_FRAME \ + TT_Error error; \ + DEFINE_A_STREAM + +/* Define locals with a predefined stream in reentrant mode -- see ttload.c */ +#define DEFINE_LOAD_LOCALS( STREAM ) \ + TT_Error error; \ + DEFINE_A_STREAM = (STREAM); \ + DEFINE_A_FRAME + +/* Define locals without frame with a predefined stream - see ttload.c */ +#define DEFINE_LOAD_LOCALS_WO_FRAME( STREAM ) \ + TT_Error error; \ + DEFINE_A_STREAM = (STREAM) + +/* Define all locals necessary to access a font file */ +#define DEFINE_ALL_LOCALS \ + TT_Error error; \ + DEFINE_A_STREAM; \ + DEFINE_A_FRAME + + +#define ACCESS_Frame( _size_ ) \ + ( (error = TT_Access_Frame( stream, \ + &frame, \ + (Long)(_size_) )) != TT_Err_Ok ) +#define CHECK_ACCESS_Frame( _size_ ) \ + ( (error = TT_Check_And_Access_Frame( stream, \ + &frame, \ + (Long)(_size_) )) != TT_Err_Ok ) +#define FORGET_Frame() \ + ( (void)TT_Forget_Frame( &frame ) ) + +#define GET_Byte() TT_Get_Byte ( &frame ) +#define GET_Char() TT_Get_Char ( &frame ) +#define GET_UShort() TT_Get_UShort( &frame ) +#define GET_Short() TT_Get_Short ( &frame ) +#define GET_Long() TT_Get_Long ( &frame ) +#define GET_ULong() TT_Get_ULong ( &frame ) +#define GET_Tag4() TT_Get_ULong ( &frame ) + +#define FILE_Pos() TT_File_Pos ( stream ) + +#define FILE_Seek( _position_ ) \ + ( (error = TT_Seek_File( stream, \ + (Long)(_position_) )) != TT_Err_Ok ) +#define FILE_Skip( _distance_ ) \ + ( (error = TT_Skip_File( stream, \ + (Long)(_distance_) )) != TT_Err_Ok ) +#define FILE_Read( buffer, count ) \ + ( (error = TT_Read_File ( stream, \ + buffer, \ + (Long)(count) )) != TT_Err_Ok ) +#define FILE_Read_At( pos, buffer, count ) \ + ( (error = TT_Read_At_File( stream, \ + (Long)(pos), \ + buffer, \ + (Long)(count) )) != TT_Err_Ok ) + +#else /* thread-safe implementation */ + +/* Define stream locals with frame -- nothing in thread-safe mode */ +#define DEFINE_STREAM_LOCALS \ + TT_Error error + +/* Define stream locals without frame -- nothing in thread-safe mode */ +#define DEFINE_STREAM_LOCALS_WO_FRAME \ + TT_Error error + +/* Define locals with a predefined stream in reentrant mode -- see ttload.c */ +#define DEFINE_LOAD_LOCALS( STREAM ) \ + TT_Error error + + +/* Define locals without frame with a predefined stream - see ttload.c */ +#define DEFINE_LOAD_LOCALS_WO_FRAME( STREAM ) \ + TT_Error error + +/* Define all locals necessary to access a font file */ +#define DEFINE_ALL_LOCALS \ + TT_Error error; \ + DEFINE_A_STREAM + + +#define ACCESS_Frame( _size_ ) \ + ( (error = TT_Access_Frame( (Long)(_size_) )) != TT_Err_Ok ) +#define CHECK_ACCESS_Frame( _size_ ) \ + ( (error = TT_Check_And_Access_Frame( (Long)(_size_) )) != TT_Err_Ok ) +#define FORGET_Frame() \ + ( (void)TT_Forget_Frame() ) + +#define GET_Byte() TT_Get_Byte () +#define GET_Char() TT_Get_Char () +#define GET_UShort() TT_Get_UShort() +#define GET_Short() TT_Get_Short () +#define GET_Long() TT_Get_Long () +#define GET_ULong() TT_Get_ULong () +#define GET_Tag4() TT_Get_ULong () + +#define FILE_Pos() TT_File_Pos() + +#define FILE_Seek( _position_ ) \ + ( (error = TT_Seek_File( (Long)(_position_) )) != TT_Err_Ok ) +#define FILE_Skip( _distance_ ) \ + ( (error = TT_Skip_File( (Long)(_distance_) )) != TT_Err_Ok ) +#define FILE_Read( buffer, count ) \ + ( (error = TT_Read_File ( buffer, \ + (Long)(count) )) != TT_Err_Ok ) +#define FILE_Read_At( pos, buffer, count ) \ + ( (error = TT_Read_At_File( (Long)(pos), \ + buffer, \ + (Long)(count) )) != TT_Err_Ok ) + +#endif /* TT_CONFIG_OPTION_THREAD_SAFE */ + +#ifdef __cplusplus + } +#endif + +#endif /* TTLOAD_H */ + + +/* END */ diff --git a/lib/ttmemory.c b/lib/ttmemory.c new file mode 100644 index 0000000..280c05f --- /dev/null +++ b/lib/ttmemory.c @@ -0,0 +1,397 @@ +/******************************************************************* + * + * ttmemory.c 1.2 + * + * Memory management component (body). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * Changes between 1.1 and 1.2: + * + * - the font pool is gone. + * + * - introduced the FREE macro and the Free function for + * future use in destructors. + * + * - Init_FontPool() is now a macro to allow the compilation of + * 'legacy' applications (all four test programs have been updated). + * + ******************************************************************/ + +#include "ttdebug.h" +#include "ttmemory.h" +#include "ttengine.h" + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_memory + + +#ifdef DEBUG_MEMORY + +#include + +#define MAX_TRACKED_BLOCKS 1024 + + struct TMemRec_ + { + void* base; + Long size; + }; + + typedef struct TMemRec_ TMemRec; + + static TMemRec pointers[MAX_TRACKED_BLOCKS + 1]; + + static Int num_alloc; + static Int num_free; + static Int num_realloc; /* counts only `real' reallocations + (i.e., an existing buffer will be resized + to a value larger than zero */ + + static Int fail_alloc; + static Int fail_realloc; + static Int fail_free; + +#endif /* DEBUG_MEMORY */ + + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + Long TTMemory_Allocated; + Long TTMemory_MaxAllocated; +#endif + + +/******************************************************************* + * + * Function : TT_Alloc + * + * Description : Allocates memory from the heap buffer. + * + * Input : Size size of the memory to be allocated + * P pointer to a buffer pointer + * + * Output : Error code. + * + * NOTE : The newly allocated block should _always_ be zeroed + * on return. Many parts of the engine rely on this to + * work properly. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Alloc( ULong Size, void** P ) + { +#ifdef DEBUG_MEMORY + Int i; +#endif + + + if ( !P ) + return TT_Err_Invalid_Argument; + + if ( Size > (size_t)-1 ) + return TT_Err_Out_Of_Memory; + if ( Size > 0 ) + { + *P = (void*)malloc( Size ); + if ( !*P ) + return TT_Err_Out_Of_Memory; + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + TTMemory_Allocated += Size; + TTMemory_MaxAllocated += Size; +#endif + +#ifdef DEBUG_MEMORY + + num_alloc++; + + i = 0; + while ( i < MAX_TRACKED_BLOCKS && pointers[i].base != NULL ) + i++; + + if ( i >= MAX_TRACKED_BLOCKS ) + fail_alloc++; + else + { + pointers[i].base = *P; + pointers[i].size = Size; + } + +#endif /* DEBUG_MEMORY */ + + MEM_Set( *P, 0, Size ); + } + else + *P = NULL; + + return TT_Err_Ok; + } + + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE + + +/******************************************************************* + * + * Function : TT_Realloc + * + * Description : Reallocates memory from the heap buffer. + * + * Input : Size new size of the memory to be allocated; + * if zero, TT_Free() will be called + * P pointer to a buffer pointer; if *P == NULL, + * TT_Alloc() will be called + * + * Output : Error code. + * + * NOTES : It's not necessary to zero the memory in case the + * reallocated buffer is larger than before -- the + * application has to take care of this. + * + * If the memory request fails, TT_Free() will be + * called on *P, and TT_Err_Out_Of_Memory returned. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Realloc( ULong Size, void** P ) + { + void* Q; + +#ifdef DEBUG_MEMORY + Int i; +#endif + + + if ( !P ) + return TT_Err_Invalid_Argument; + + if ( !*P ) + return TT_Alloc( Size, P ); + + if ( Size == 0 ) + return TT_Free( P ); + + if ( Size > (size_t)-1 ) + { + TT_Free( *P ); + return TT_Err_Out_Of_Memory; + } + + Q = (void*)realloc( *P, Size ); + if ( !Q ) + { + TT_Free( *P ); + return TT_Err_Out_Of_Memory; + } + +#ifdef DEBUG_MEMORY + + num_realloc++; + + i = 0; + while ( i < MAX_TRACKED_BLOCKS && pointers[i].base != *P ) + i++; + + if ( i >= MAX_TRACKED_BLOCKS ) + fail_realloc++; + else + { +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + TTMemory_Allocated += Size - pointers[i].size; + if ( Size > pointers[i].size ) + TTMemory_MaxAllocated += Size - pointers[i].size; +#endif + + pointers[i].base = Q; + pointers[i].size = size; + } +#endif /* DEBUG_MEMORY */ + + *P = Q; + + return TT_Err_Ok; + } + + +#endif /* TT_CONFIG_OPTION_EXTEND_ENGINE */ + + +/******************************************************************* + * + * Function : TT_Free + * + * Description : Releases a previously allocated block of memory. + * + * Input : P pointer to memory block + * + * Output : Always SUCCESS. + * + * Note : The pointer must _always_ be set to NULL by this function. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Free( void** P ) + { +#ifdef DEBUG_MEMORY + Int i; +#endif /* DEBUG_MEMORY */ + + + if ( !P || !*P ) + return TT_Err_Ok; + +#ifdef DEBUG_MEMORY + + num_free++; + + i = 0; + while ( i < MAX_TRACKED_BLOCKS && pointers[i].base != *P ) + i++; + + if ( i >= MAX_TRACKED_BLOCKS ) + fail_free++; + else + { +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + TTMemory_Allocated -= pointers[i].size; +#endif + + pointers[i].base = NULL; + pointers[i].size = 0; + } +#endif /* DEBUG_MEMORY */ + + free( *P ); + + *P = NULL; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTMemory_Init + * + * Description : Initializes the memory. + * + * Output : Always SUCCESS. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTMemory_Init( void ) + { +#ifdef DEBUG_MEMORY + Int i; + + + for ( i = 0; i < MAX_TRACKED_BLOCKS; i++ ) + { + pointers[i].base = NULL; + pointers[i].size = 0; + } + + num_alloc = 0; + num_realloc = 0; + num_free = 0; + + fail_alloc = 0; + fail_realloc = 0; + fail_free = 0; +#endif + + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + TTMemory_Allocated = 0; + TTMemory_MaxAllocated = 0; +#endif + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTMemory_Done + * + * Description : Finalizes memory usage. + * + * Output : Always SUCCESS. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTMemory_Done( void ) + { +#ifdef DEBUG_MEMORY + Int i, num_leaked, tot_leaked; + + + num_leaked = 0; + tot_leaked = 0; + + for ( i = 0; i < MAX_TRACKED_BLOCKS; i++ ) + { + if ( pointers[i].base ) + { + num_leaked ++; + tot_leaked += pointers[i].size; + } + } + + fprintf( stderr, + "%d memory allocations, of which %d failed\n", + num_alloc, + fail_alloc ); + + fprintf( stderr, + "%d memory reallocations, of which %d failed\n", + num_realloc, + fail_realloc ); + + fprintf( stderr, + "%d memory frees, of which %d failed\n", + num_free, + fail_free ); + + if ( num_leaked > 0 ) + { + fprintf( stderr, + "There are %d leaked memory blocks, totalizing %d bytes\n", + num_leaked, tot_leaked ); + + for ( i = 0; i < MAX_TRACKED_BLOCKS; i++ ) + { + if ( pointers[i].base ) + { + fprintf( stderr, + "index: %4d (base: $%08lx, size: %08ld)\n", + i, + (long)pointers[i].base, + pointers[i].size ); + } + } + } + else + fprintf( stderr, "No memory leaks !\n" ); + +#endif /* DEBUG_MEMORY */ + + return TT_Err_Ok; + } + + +/* END */ diff --git a/lib/ttmemory.h b/lib/ttmemory.h new file mode 100644 index 0000000..8cdae23 --- /dev/null +++ b/lib/ttmemory.h @@ -0,0 +1,125 @@ +/******************************************************************* + * + * ttmemory.h 1.2 + * + * Memory management component (specification). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * Changes between 1.2 and 1.1: + * + * - the font pool is gone! All allocations are now performed + * with malloc() and free(). + * + * - introduced the FREE() macro and the Free() function for + * future use in destructors. + * + * - Init_FontPool() is now a macro to allow the compilation of + * 'legacy' applications (all four test programs have been updated). + * + ******************************************************************/ + +#ifndef TTMEMORY_H +#define TTMEMORY_H + +#include "ttconfig.h" +#include "tttypes.h" +#include + + +#ifdef __cplusplus + extern "C" { +#endif + +#define MEM_Set( dest, byte, count ) memset( dest, byte, count ) + +#ifdef HAVE_MEMCPY +#define MEM_Copy( dest, source, count ) memcpy( dest, source, count ) +#else +#define MEM_Copy( dest, source, count ) bcopy( source, dest, count ) +#endif + +#ifdef HAVE_MEMMOVE +#define MEM_Move( dest, source, count ) memmove( dest, source, count ) +#else +#define MEM_Move( dest, source, count ) bcopy( source, dest, count ) +#endif + + +#define MEM_Alloc( _pointer_, _size_ ) \ + TT_Alloc( _size_, (void**)&(_pointer_) ) + +#define MEM_Realloc( _pointer_, _size_ ) \ + TT_Realloc( _size_, (void**)&(_pointer_) ) + +#define ALLOC( _pointer_, _size_ ) \ + ( ( error = MEM_Alloc( _pointer_, _size_ ) ) != TT_Err_Ok ) + +#define ALLOC_ARRAY( _pointer_, _count_, _type_ ) \ + ( ( error = MEM_Alloc( _pointer_, \ + (_count_) * sizeof ( _type_ ) ) ) != TT_Err_Ok ) + +#define REALLOC( _pointer_, _size_ ) \ + ( ( error = MEM_Realloc( _pointer_, _size_ ) ) != TT_Err_Ok ) + +#define REALLOC_ARRAY( _pointer_, _count_, _type_ ) \ + ( (error = MEM_Realloc( _pointer_, \ + (_count_) * sizeof ( _type_ ) ) ) != TT_Err_Ok ) + +#define FREE( _pointer_ ) \ + TT_Free( (void**)&(_pointer_) ) + + + /* Allocate a block of memory of 'Size' bytes from the heap, and */ + /* sets the pointer '*P' to its address. If 'Size' is 0, or in */ + /* case of error, the pointer is always set to NULL. */ + + EXPORT_DEF + TT_Error TT_Alloc( ULong Size, void** P ); + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE + + /* Reallocates a block of memory pointed to by '*P' to 'Size' */ + /* bytes from the heap, possibly changing '*P'. If 'Size' is 0, */ + /* TT_Free() is called, if '*P' is NULL, TT_Alloc() is called. */ + /* '*P' is freed (if it's non-NULL) in case of error. */ + + EXPORT_DEF + TT_Error TT_Realloc( ULong Size, void** P ); + +#endif /* TT_CONFIG_OPTION_EXTEND_ENGINE */ + + /* Releases a block that was previously allocated through Alloc. */ + /* Note that the function returns successfully when P or *P are */ + /* already NULL. The pointer '*P' is set to NULL on exit in */ + /* case of success. */ + + EXPORT_DEF + TT_Error TT_Free( void** P ); + + + /* For "legacy" applications, that should be re-coded. */ + /* Note that this won't release the previously allocated font pool. */ + +#define Init_FontPool( x, y ) while( 0 ) { } + + + LOCAL_DEF TT_Error TTMemory_Init( void ); + LOCAL_DEF TT_Error TTMemory_Done( void ); + + +#ifdef __cplusplus + } +#endif + +#endif /* TTMEMORY_H */ + + +/* END */ diff --git a/lib/ttmutex.c b/lib/ttmutex.c new file mode 100644 index 0000000..2f4b920 --- /dev/null +++ b/lib/ttmutex.c @@ -0,0 +1,85 @@ +/******************************************************************* + * + * ttmutex.c 1.0 + * + * Mutual exclusion object, single-threaded implementation + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTE: This is a generic non-functional implementation + * that you are welcome to refine for your own system. + * + * Please name your system-specific source with a + * different name (like ttmutex-os2.c or ttmutex-linux.c) + * and change your makefile accordingly. + * + ******************************************************************/ + +#include "ttmutex.h" + + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_mutex + + +/* ANSI C prevents the compilation of empty units. We thus introduce */ +/* a dummy typedef to get rid of compiler warnings/errors. */ +/* Note that gcc's -ansi -pedantic does not report any error here. */ +/* Watcom, VC++ or Borland C++ do however. */ + + typedef void _ttmutex_to_satisfy_ANSI_C_; + + +#ifdef TT_CONFIG_OPTION_THREAD_SAFE + + LOCAL_FUNC + void TT_Mutex_Create ( TMutex* mutex ) + { + *mutex = (void*)-1; + /* Replace this line with your own mutex creation code */ + } + + + LOCAL_FUNC + void TT_Mutex_Delete ( TMutex* mutex ) + { + *mutex = (void*)0; + /* Replace this line with your own mutex destruction code */ + } + + + LOCAL_FUNC + void TT_Mutex_Lock ( TMutex* mutex ) + { + /* NOTE: It is legal to call this function with a NULL argument */ + /* in which case an immediate return is appropriate. */ + if ( !mutex ) + return; + + ; /* Insert your own mutex locking code here */ + } + + + LOCAL_FUNC + void TT_Mutex_Release( TMutex* mutex ) + { + /* NOTE: It is legal to call this function with a NULL argument */ + /* in which case an immediate return is appropriate */ + if ( !mutex ) + return; + + ; /* Insert your own mutex release code here */ + } + +#endif /* TT_CONFIG_OPTION_THREAD_SAFE */ + + +/* END */ diff --git a/lib/ttmutex.h b/lib/ttmutex.h new file mode 100644 index 0000000..097385b --- /dev/null +++ b/lib/ttmutex.h @@ -0,0 +1,59 @@ +/******************************************************************* + * + * ttmutex.h 1.0 + * + * Mutual exclusion object / dummy generic interface. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * Note: This file provides a generic interface. The implementation + * to compile depends on your system and the type of + * library you want to build (either singly-threaded, + * thread-safe or re-entrant). + * + * Please read the technical documentation for more details. + * + ******************************************************************/ + +#ifndef TTMUTEX_H +#define TTMUTEX_H + +#include "ttconfig.h" + + + typedef void* TMutex; /* typeless reference to a mutex */ + +#ifdef TT_CONFIG_OPTION_THREAD_SAFE /* thread-safe and re-entrant builds */ + +#define MUTEX_Create( mutex ) TT_Mutex_Create ( &(mutex) ) +#define MUTEX_Destroy( mutex ) TT_Mutex_Delete ( &(mutex) ) +#define MUTEX_Lock( mutex ) TT_Mutex_Lock ( &(mutex) ) +#define MUTEX_Release( mutex ) TT_Mutex_Release( &(mutex) ) + + LOCAL_DEF void TT_Mutex_Create ( TMutex* mutex ); /* Create a new mutex */ + LOCAL_DEF void TT_Mutex_Delete ( TMutex* mutex ); /* Delete a mutex */ + LOCAL_DEF void TT_Mutex_Lock ( TMutex* mutex ); /* Lock a mutex. */ + LOCAL_DEF void TT_Mutex_Release( TMutex* mutex ); /* Release a mutex */ + +#else /* for the single-thread build */ + +#define MUTEX_Create( mutex ) /* nothing */ +#define MUTEX_Destroy( mutex ) /* nothing */ +#define MUTEX_Lock( mutex ) /* nothing */ +#define MUTEX_Release( mutex ) /* nothing */ + + /* No code will be generated for mutex operations */ + +#endif /* TT_CONFIG_OPTION_THREAD_SAFE */ + +#endif /* TTMUTEX_H */ + + +/* END */ diff --git a/lib/ttobjs.c b/lib/ttobjs.c new file mode 100644 index 0000000..9ce1101 --- /dev/null +++ b/lib/ttobjs.c @@ -0,0 +1,1495 @@ +/******************************************************************* + * + * ttobjs.c 1.0 + * + * Objects manager. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include "ttobjs.h" +#include "ttfile.h" +#include "ttcalc.h" +#include "ttmemory.h" +#include "ttload.h" +#include "ttinterp.h" +#include "ttdebug.h" + + +/* Add extensions definition */ +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE +#include "ttextend.h" +#endif + +/* Required by tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_objs + +/******************************************************************* + * + * Function : New_Context + * + * Description : Creates a new execution context for a given + * face object. + * + ******************************************************************/ + + LOCAL_FUNC + PExecution_Context New_Context( PFace face ) + { + PEngine_Instance engine; + PExecution_Context exec; + + + if ( !face ) + return NULL; + + engine = face->engine; + CACHE_New( engine->objs_exec_cache, exec, face ); + return exec; + } + + +/******************************************************************* + * + * Function : Done_Context + * + * Description : Discards an execution context. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Done_Context( PExecution_Context exec ) + { + PEngine_Instance engine; + + + if ( !exec ) + return TT_Err_Ok; + + engine = exec->face->engine; + return CACHE_Done( engine->objs_exec_cache, exec ); + } + + +#if 0 + +/******************************************************************* + * + * Function : New_Instance + * + * Description : Creates a new instance for a given face object. + * + ******************************************************************/ + + LOCAL_FUNC + PInstance New_Instance( PFace face ) + { + PInstance ins; + + + if ( !face ) + return NULL; + + CACHE_New( &face->instances, ins, face ); + + return ins; + } + + +/******************************************************************* + * + * Function : Done_Instance + * + * Description : Discards an instance. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Done_Instance( PInstance instance ) + { + return CACHE_Done( &instance->owner->instances, instance ); + } + +#endif + + +/******************************************************************* + * * + * GLYPH ZONE FUNCTIONS * + * * + * * + *******************************************************************/ + +/******************************************************************* + * + * Function : New_Glyph_Zone + * + * Description : Allocates a new glyph zone + * + * Input : pts pointer to the target glyph zone record + * maxPoints capacity of glyph zone in points + * maxContours capacity of glyph zone in contours + * + * Return : Error code. + * + *****************************************************************/ + + static + TT_Error New_Glyph_Zone( PGlyph_Zone pts, + UShort maxPoints, + UShort maxContours ) + { + TT_Error error; + + + if ( ALLOC( pts->org, maxPoints * 2 * sizeof ( TT_F26Dot6 ) ) || + ALLOC( pts->cur, maxPoints * 2 * sizeof ( TT_F26Dot6 ) ) || + ALLOC( pts->touch, maxPoints * sizeof ( Byte ) ) || + ALLOC( pts->contours, maxContours * sizeof ( Short ) ) ) + return error; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Done_Glyph_Zone + * + * Description : Deallocates a glyph zone + * + * Input : pts pointer to the target glyph zone record + * + * Return : Error code. + * + *****************************************************************/ + + static + TT_Error Done_Glyph_Zone( PGlyph_Zone pts ) + { + FREE( pts->contours ); + FREE( pts->touch ); + FREE( pts->cur ); + FREE( pts->org ); + + return TT_Err_Ok; + } + + + +/******************************************************************* + * * + * CODERANGE FUNCTIONS * + * * + *******************************************************************/ + +/******************************************************************* + * + * Function : Goto_CodeRange + * + * Description : Switch to a new code range (updates Code and IP). + * + * Input : exec target execution context + * range new execution code range + * IP new IP in new code range + * + * Output : SUCCESS on success. FAILURE on error (no code range). + * + *****************************************************************/ + + LOCAL_FUNC + TT_Error Goto_CodeRange( PExecution_Context exec, + Int range, + ULong IP ) + { + PCodeRange cr; + + + if ( range < 1 || range > 3 ) + return TT_Err_Bad_Argument; + + cr = &exec->codeRangeTable[range - 1]; + + if ( cr->Base == NULL ) + return TT_Err_Invalid_CodeRange; + + /* NOTE: Because the last instruction of a program may be a CALL */ + /* which will return to the first byte *after* the code */ + /* range, we test for IP <= Size, instead of IP < Size. */ + + if ( IP > cr->Size ) + return TT_Err_Code_Overflow; + + exec->code = cr->Base; + exec->codeSize = cr->Size; + exec->IP = IP; + exec->curRange = range; + + return TT_Err_Ok; + } + + +#if 0 + +/******************************************************************* + * + * Function : Get_CodeRange + * + * Description : Returns a pointer to a given code range. Should + * be used only by the debugger. Returns NULL if + * 'range' is out of current bounds. + * + * Input : exec target execution context + * range new execution code range + * + * Output : Pointer to the code range record. NULL on failure. + * + *****************************************************************/ + + LOCAL_FUNC + PCodeRange Get_CodeRange( PExecution_Context exec, Int range ) + { + if ( range < 1 || range > 3 ) + return NULL; + else /* arrays start with 1 in Pascal, and with 0 in C */ + return &exec->codeRangeTable[range - 1]; + } + +#endif + + +/******************************************************************* + * + * Function : Set_CodeRange + * + * Description : Sets a code range. + * + * Input : exec target execution context + * range code range index + * base new code base + * length range size in bytes + * + * Output : SUCCESS on success. FAILURE on error. + * + *****************************************************************/ + + LOCAL_FUNC + TT_Error Set_CodeRange( PExecution_Context exec, + Int range, + void* base, + ULong length ) + { + if ( range < 1 || range > 3 ) + return TT_Err_Bad_Argument; + + exec->codeRangeTable[range - 1].Base = (Byte*)base; + exec->codeRangeTable[range - 1].Size = length; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Clear_CodeRange + * + * Description : Clears a code range. + * + * Input : exec target execution context + * range code range index + * + * Output : SUCCESS on success. FAILURE on error. + * + * Note : Does not set the Error variable. + * + *****************************************************************/ + + LOCAL_FUNC + TT_Error Clear_CodeRange( PExecution_Context exec, Int range ) + { + if ( range < 1 || range > 3 ) + return TT_Err_Bad_Argument; + + exec->codeRangeTable[range - 1].Base = NULL; + exec->codeRangeTable[range - 1].Size = 0; + + return TT_Err_Ok; + } + + + +/******************************************************************* + * * + * EXECUTION CONTEXT ROUTINES * + * * + *******************************************************************/ + +/******************************************************************* + * + * Function : Context_Destroy + * + *****************************************************************/ + + LOCAL_FUNC + TT_Error Context_Destroy( void* _context ) + { + PExecution_Context exec = (PExecution_Context)_context; + + if ( !exec ) + return TT_Err_Ok; + + /* free composite load stack */ + FREE( exec->loadStack ); + exec->loadSize = 0; + + /* points zone */ + Done_Glyph_Zone( &exec->pts ); + exec->maxPoints = 0; + exec->maxContours = 0; + + /* free stack */ + FREE( exec->stack ); + exec->stackSize = 0; + + /* free call stack */ + FREE( exec->callStack ); + exec->callSize = 0; + exec->callTop = 0; + + /* free glyph code range */ + FREE( exec->glyphIns ); + exec->glyphSize = 0; + + exec->instance = NULL; + exec->face = NULL; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Context_Create + * + *****************************************************************/ + + LOCAL_FUNC + TT_Error Context_Create( void* _context, void* _face ) + { + PExecution_Context exec = (PExecution_Context)_context; + + PFace face = (PFace)_face; + TT_Error error; + + + /* XXX : We don't reserve arrays anymore, this is done automatically */ + /* during a "Context_Load".. */ + + exec->callSize = 32; + if ( ALLOC_ARRAY( exec->callStack, exec->callSize, TCallRecord ) ) + goto Fail_Memory; + + /* all values in the context are set to 0 already, but this is */ + /* here as a remainder */ + exec->maxPoints = 0; + exec->maxContours = 0; + + exec->stackSize = 0; + exec->loadSize = 0; + exec->glyphSize = 0; + + exec->stack = NULL; + exec->loadStack = NULL; + exec->glyphIns = NULL; + + exec->face = face; + exec->instance = NULL; + + return TT_Err_Ok; + + Fail_Memory: + Context_Destroy( exec ); + return error; + } + + +/******************************************************************* + * + * Function : Context_Load + * + *****************************************************************/ + +/****************************************************************/ +/* */ +/* Update_Max : Reallocate a buffer if it needs to */ +/* */ +/* input: size address of buffer's current size */ +/* expressed in elements */ +/* */ +/* multiplier size in bytes of each element in the */ +/* buffer */ +/* */ +/* buff address of the buffer base pointer */ +/* */ +/* new_max new capacity (size) of the buffer */ + + static + TT_Error Update_Max( ULong* size, + ULong multiplier, + void** buff, + ULong new_max ) + { + TT_Error error; + + if ( *size < new_max ) + { + FREE( *buff ); + if ( ALLOC( *buff, new_max * multiplier ) ) + return error; + *size = new_max; + } + return TT_Err_Ok; + } + + +/****************************************************************/ +/* */ +/* Update_Zone: Reallocate a zone if it needs to */ +/* */ +/* input: zone address of the target zone */ +/* */ +/* maxPoints address of the zone's current capacity */ +/* in points */ +/* */ +/* maxContours address of the zone's current capacity */ +/* in contours */ +/* */ +/* newPoints new capacity in points */ +/* */ +/* newContours new capacity in contours */ +/* */ + + static + TT_Error Update_Zone( PGlyph_Zone zone, + UShort* maxPoints, + UShort* maxContours, + UShort newPoints, + UShort newContours ) + { + if ( *maxPoints < newPoints || *maxContours < newContours ) + { + TT_Error error; + + + Done_Glyph_Zone( zone ); + + error = New_Glyph_Zone( zone, newPoints, newContours ); + if ( error ) + return error; + + *maxPoints = newPoints; + *maxContours = newContours; + } + return TT_Err_Ok; + } + + + LOCAL_FUNC + TT_Error Context_Load( PExecution_Context exec, + PFace face, + PInstance ins ) + { + Int i; + TMaxProfile* maxp; + TT_Error error; + + exec->face = face; + maxp = &face->maxProfile; + + exec->instance = ins; + + if ( ins ) + { + exec->numFDefs = ins->numFDefs; + exec->numIDefs = ins->numIDefs; + exec->maxFDefs = ins->maxFDefs; + exec->maxIDefs = ins->maxIDefs; + exec->FDefs = ins->FDefs; + exec->IDefs = ins->IDefs; + exec->metrics = ins->metrics; + + exec->maxFunc = ins->maxFunc; + exec->maxIns = ins->maxIns; + + for ( i = 0; i < MAX_CODE_RANGES; i++ ) + exec->codeRangeTable[i] = ins->codeRangeTable[i]; + + /* set graphics state */ + exec->GS = ins->GS; + + exec->cvtSize = ins->cvtSize; + exec->cvt = ins->cvt; + + exec->storeSize = ins->storeSize; + exec->storage = ins->storage; + + exec->twilight = ins->twilight; + } + + error = Update_Max( &exec->loadSize, + sizeof ( TSubglyph_Record ), + (void**)&exec->loadStack, + face->maxComponents + 1 ); + if ( error ) + return error; + + error = Update_Max( &exec->stackSize, + sizeof ( TT_F26Dot6 ), + (void**)&exec->stack, + maxp->maxStackElements + 32 ); + /* XXX : We reserve a little more elements on the stack to deal safely */ + /* with broken fonts like arialbs, courbs, timesbs... */ + if ( error ) + return error; + + error = Update_Max( &exec->glyphSize, + sizeof ( Byte ), + (void**)&exec->glyphIns, + maxp->maxSizeOfInstructions ); + if ( error ) + return error; + + error = Update_Zone( &exec->pts, + &exec->maxPoints, + &exec->maxContours, + exec->face->maxPoints + 2, + exec->face->maxContours ); + /* XXX : We reserve two positions for the phantom points! */ + if ( error ) + return error; + + exec->pts.n_points = 0; + exec->pts.n_contours = 0; + + exec->instruction_trap = FALSE; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Context_Save + * + *****************************************************************/ + + LOCAL_FUNC + TT_Error Context_Save( PExecution_Context exec, + PInstance ins ) + { + Int i; + + /* XXXX : Will probably disappear soon with all the coderange */ + /* management, which is now rather obsolete. */ + + ins->numFDefs = exec->numFDefs; + ins->numIDefs = exec->numIDefs; + ins->maxFunc = exec->maxFunc; + ins->maxIns = exec->maxIns; + + for ( i = 0; i < MAX_CODE_RANGES; i++ ) + ins->codeRangeTable[i] = exec->codeRangeTable[i]; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Context_Run + * + *****************************************************************/ + + LOCAL_FUNC + TT_Error Context_Run( PExecution_Context exec, + Bool debug ) + { + TT_Error error; + + + if ( (error = Goto_CodeRange( exec, + TT_CodeRange_Glyph, 0 )) != TT_Err_Ok ) + return error; + + exec->zp0 = exec->pts; + exec->zp1 = exec->pts; + exec->zp2 = exec->pts; + + exec->GS.gep0 = 1; + exec->GS.gep1 = 1; + exec->GS.gep2 = 1; + + exec->GS.projVector.x = 0x4000; + exec->GS.projVector.y = 0x0000; + + exec->GS.freeVector = exec->GS.projVector; + exec->GS.dualVector = exec->GS.projVector; + + exec->GS.round_state = 1; + exec->GS.loop = 1; + + /* some glyphs leave something on the stack. so we clean it */ + /* before a new execution. */ + exec->top = 0; + exec->callTop = 0; + + if ( !debug ) + return RunIns( exec ); + else + return TT_Err_Ok; + } + + + LOCAL_FUNC + const TGraphicsState Default_GraphicsState = + { + 0, 0, 0, + { 0x4000, 0 }, + { 0x4000, 0 }, + { 0x4000, 0 }, + 1, 64, 1, + TRUE, 68, 0, 0, 9, 3, + 0, FALSE, 2, 1, 1, 1 + }; + + + +/******************************************************************* + * * + * INSTANCE FUNCTIONS * + * * + * * + *******************************************************************/ + +/******************************************************************* + * + * Function : Instance_Destroy + * + * Description : + * + * Input : _instance the instance object to destroy + * + * Output : error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Instance_Destroy( void* _instance ) + { + PInstance ins = (PInstance)_instance; + + + if ( !_instance ) + return TT_Err_Ok; + + if ( ins->debug ) + { + /* the debug context must be deleted by the debugger itself */ + ins->context = NULL; + ins->debug = FALSE; + } + + FREE( ins->cvt ); + ins->cvtSize = 0; + + /* free storage area */ + FREE( ins->storage ); + ins->storeSize = 0; + + /* twilight zone */ + Done_Glyph_Zone( &ins->twilight ); + + FREE( ins->FDefs ); + FREE( ins->IDefs ); + ins->numFDefs = 0; + ins->numIDefs = 0; + ins->maxFDefs = 0; + ins->maxIDefs = 0; + ins->maxFunc = -1; + ins->maxIns = -1; + + ins->owner = NULL; + ins->valid = FALSE; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Instance_Create + * + * Description : + * + * Input : _instance instance record to initialize + * _face parent face object + * + * Output : Error code. All partially built subtables are + * released on error. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Instance_Create( void* _instance, + void* _face ) + { + PInstance ins = (PInstance)_instance; + PFace face = (PFace)_face; + TT_Error error; + Int i; + UShort n_twilight; + + PMaxProfile maxp = &face->maxProfile; + + + ins->owner = face; + ins->valid = FALSE; + + ins->maxFDefs = maxp->maxFunctionDefs; + ins->maxIDefs = maxp->maxInstructionDefs; + ins->cvtSize = face->cvtSize; + ins->storeSize = maxp->maxStorage; + + /* Set default metrics */ + { + PIns_Metrics metrics = &ins->metrics; + + + metrics->pointSize = 10 * 64; /* default pointsize = 10pts */ + + metrics->x_resolution = 96; /* default resolution = 96dpi */ + metrics->y_resolution = 96; + + metrics->x_ppem = 0; + metrics->y_ppem = 0; + + metrics->rotated = FALSE; + metrics->stretched = FALSE; + + /* set default compensation ( all 0 ) */ + for ( i = 0; i < 4; i++ ) + metrics->compensations[i] = 0; + } + + /* allocate function defs, instruction defs, cvt and storage area */ + if ( ALLOC_ARRAY( ins->FDefs, ins->maxFDefs, TDefRecord ) || + ALLOC_ARRAY( ins->IDefs, ins->maxIDefs, TDefRecord ) || + ALLOC_ARRAY( ins->cvt, ins->cvtSize, Long ) || + ALLOC_ARRAY( ins->storage, ins->storeSize, Long ) ) + goto Fail_Memory; + + /* reserve twilight zone */ + n_twilight = maxp->maxTwilightPoints; + error = New_Glyph_Zone( &ins->twilight, n_twilight, 0 ); + if (error) + goto Fail_Memory; + + ins->twilight.n_points = n_twilight; + + return TT_Err_Ok; + + Fail_Memory: + Instance_Destroy( ins ); + return error; + } + + +/******************************************************************* + * + * Function : Instance_Init + * + * Description : Initialize a fresh new instance. + * Executes the font program if any is found. + * + * Input : _instance the instance object to destroy + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Instance_Init( PInstance ins ) + { + PExecution_Context exec; + + TT_Error error; + PFace face = ins->owner; + + + if ( ins->debug ) + exec = ins->context; + else + exec = New_Context( face ); + /* debugging instances have their own context */ + + if ( !exec ) + return TT_Err_Could_Not_Find_Context; + + ins->GS = Default_GraphicsState; + + ins->numFDefs = 0; + ins->numIDefs = 0; + ins->maxFunc = -1; + ins->maxIns = -1; + + Context_Load( exec, face, ins ); + + exec->callTop = 0; + exec->top = 0; + + exec->period = 64; + exec->phase = 0; + exec->threshold = 0; + + { + PIns_Metrics metrics = &exec->metrics; + + + metrics->x_ppem = 0; + metrics->y_ppem = 0; + metrics->pointSize = 0; + metrics->x_scale1 = 0; + metrics->x_scale2 = 1; + metrics->y_scale1 = 0; + metrics->y_scale2 = 1; + + metrics->ppem = 0; + metrics->scale1 = 0; + metrics->scale2 = 1; + metrics->ratio = 1L << 16; + } + + exec->instruction_trap = FALSE; + + exec->cvtSize = ins->cvtSize; + exec->cvt = ins->cvt; + + exec->F_dot_P = 0x10000; + + /* allow font program execution */ + Set_CodeRange( exec, + TT_CodeRange_Font, + face->fontProgram, + face->fontPgmSize ); + + /* disable CVT and glyph programs coderange */ + Clear_CodeRange( exec, TT_CodeRange_Cvt ); + Clear_CodeRange( exec, TT_CodeRange_Glyph ); + + if ( face->fontPgmSize > 0 ) + { + error = Goto_CodeRange( exec, TT_CodeRange_Font, 0 ); + if ( error ) + goto Fin; + + error = RunIns( exec ); + } + else + error = TT_Err_Ok; + + Fin: + Context_Save( exec, ins ); + + if ( !ins->debug ) + Done_Context( exec ); + /* debugging instances keep their context */ + + ins->valid = FALSE; + + return error; + } + + +/******************************************************************* + * + * Function : Instance_Reset + * + * Description : Resets an instance to a new pointsize/transform. + * Executes the cvt program if any is found. + * + * Input : _instance the instance object to destroy + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Instance_Reset( PInstance ins ) + { + PExecution_Context exec; + + TT_Error error; + ULong i; + UShort j; + PFace face; + + + if ( !ins ) + return TT_Err_Invalid_Instance_Handle; + + if ( ins->valid ) + return TT_Err_Ok; + + face = ins->owner; + + if ( ins->metrics.x_ppem < 1 || + ins->metrics.y_ppem < 1 ) + return TT_Err_Invalid_PPem; + + /* compute new transformation */ + if ( ins->metrics.x_ppem >= ins->metrics.y_ppem ) + { + ins->metrics.scale1 = ins->metrics.x_scale1; + ins->metrics.scale2 = ins->metrics.x_scale2; + ins->metrics.ppem = ins->metrics.x_ppem; + ins->metrics.x_ratio = 1L << 16; + ins->metrics.y_ratio = TT_MulDiv( ins->metrics.y_ppem, + 0x10000, + ins->metrics.x_ppem ); + } + else + { + ins->metrics.scale1 = ins->metrics.y_scale1; + ins->metrics.scale2 = ins->metrics.y_scale2; + ins->metrics.ppem = ins->metrics.y_ppem; + ins->metrics.x_ratio = TT_MulDiv( ins->metrics.x_ppem, + 0x10000, + ins->metrics.y_ppem ); + ins->metrics.y_ratio = 1L << 16; + } + + /* Scale the cvt values to the new ppem. */ + /* We use by default the y ppem to scale the CVT. */ + + for ( i = 0; i < ins->cvtSize; i++ ) + ins->cvt[i] = TT_MulDiv( face->cvt[i], + ins->metrics.scale1, + ins->metrics.scale2 ); + + /* All twilight points are originally zero */ + for ( j = 0; j < ins->twilight.n_points; j++ ) + { + ins->twilight.org[j].x = 0; + ins->twilight.org[j].y = 0; + ins->twilight.cur[j].x = 0; + ins->twilight.cur[j].y = 0; + } + + /* clear storage area */ + for ( i = 0; i < ins->storeSize; i++ ) + ins->storage[i] = 0; + + ins->GS = Default_GraphicsState; + + /* get execution context and run prep program */ + + if ( ins->debug ) + exec = ins->context; + else + exec = New_Context(face); + /* debugging instances have their own context */ + + if ( !exec ) + return TT_Err_Could_Not_Find_Context; + + Context_Load( exec, face, ins ); + + Set_CodeRange( exec, + TT_CodeRange_Cvt, + face->cvtProgram, + face->cvtPgmSize ); + + Clear_CodeRange( exec, TT_CodeRange_Glyph ); + + exec->instruction_trap = FALSE; + + exec->top = 0; + exec->callTop = 0; + + if ( face->cvtPgmSize > 0 ) + { + error = Goto_CodeRange( exec, TT_CodeRange_Cvt, 0 ); + if ( error ) + goto Fin; + + if ( !ins->debug ) + error = RunIns( exec ); + } + else + error = TT_Err_Ok; + + ins->GS = exec->GS; + /* save default graphics state */ + + Fin: + Context_Save( exec, ins ); + + if ( !ins->debug ) + Done_Context( exec ); + /* debugging instances keep their context */ + + if ( !error ) + ins->valid = TRUE; + + return error; + } + + + +/******************************************************************* + * * + * FACE FUNCTIONS * + * * + * * + *******************************************************************/ + +/******************************************************************* + * + * Function : Face_Destroy + * + * Description : The face object destructor. + * + * Input : _face typeless pointer to the face object to destroy + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Face_Destroy( void* _face ) + { + PFace face = (PFace)_face; + UShort n; + + + if ( !face ) + return TT_Err_Ok; + + /* well, we assume that no other thread is using the face */ + /* at this moment, but one is never sure enough. */ + MUTEX_Lock( face->lock ); + + /* first of all, destroys the cached sub-objects */ + Cache_Destroy( &face->instances ); + Cache_Destroy( &face->glyphs ); + + /* destroy the extensions */ +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE + Extension_Destroy( face ); +#endif + + /* freeing the collection table */ + FREE( face->ttcHeader.TableDirectory ); + face->ttcHeader.DirCount = 0; + + /* freeing table directory */ + FREE( face->dirTables ); + face->numTables = 0; + + /* freeing the locations table */ + FREE( face->glyphLocations ); + face->numLocations = 0; + + /* freeing the character mapping tables */ + for ( n = 0; n < face->numCMaps; n++ ) + CharMap_Free( face->cMaps + n ); + + FREE( face->cMaps ); + face->numCMaps = 0; + + /* freeing the CVT */ + FREE( face->cvt ); + face->cvtSize = 0; + + /* freeing the horizontal metrics */ + FREE( face->horizontalHeader.long_metrics ); + FREE( face->horizontalHeader.short_metrics ); + + /* freeing the vertical ones, if any */ + if (face->verticalInfo) + { + FREE( face->verticalHeader.long_metrics ); + FREE( face->verticalHeader.short_metrics ); + face->verticalInfo = 0; + } + + /* freeing the programs */ + FREE( face->fontProgram ); + FREE( face->cvtProgram ); + face->fontPgmSize = 0; + face->cvtPgmSize = 0; + + /* freeing the gasp table */ + FREE( face->gasp.gaspRanges ); + face->gasp.numRanges = 0; + + /* freeing the name table */ + Free_TrueType_Names( face ); + + /* freeing the hdmx table */ + Free_TrueType_Hdmx( face ); + + /* TT_Close_Stream( &face->stream ); -- this is performed by the API */ + + /* destroy the mutex */ + MUTEX_Destroy(face->lock); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Face_Create + * + * Description : The face object constructor. + * + * Input : _face face record to build + * _input input stream where to load font data + * + * Output : Error code. + * + * NOTE : The input stream is kept in the face object. The + * caller shouldn't destroy it after calling Face_Create(). + * + ******************************************************************/ + +#undef LOAD_ +#define LOAD_( table ) \ + (error = Load_TrueType_##table (face)) != TT_Err_Ok + + + LOCAL_FUNC + TT_Error Face_Create( void* _face, + void* _input ) + { + PEngine_Instance engine; + + TFont_Input* input = (TFont_Input*)_input; + PFace face = (PFace)_face; + TT_Error error; + + + face->stream = input->stream; + face->engine = input->engine; + + engine = face->engine; + + MUTEX_Create( face->lock ); + + Cache_Create( engine, + engine->objs_instance_class, + &face->instances, + &face->lock ); + + Cache_Create( engine, + engine->objs_glyph_class, + &face->glyphs, + &face->lock ); + + /* Load collection directory if present, then font directory */ + + error = Load_TrueType_Directory( face, input->fontIndex ); + if ( error ) + goto Fail; + + /* Load tables */ + + if ( LOAD_( Header ) || + LOAD_( MaxProfile ) || + LOAD_( Locations ) || + + (error = Load_TrueType_Metrics_Header( face, 0 )) != TT_Err_Ok || + /* load the 'hhea' & 'hmtx' tables at once */ + + LOAD_( CMap ) || + LOAD_( CVT ) || + LOAD_( Programs ) || + LOAD_( Gasp ) || + LOAD_( Names ) || + LOAD_( OS2 ) || + LOAD_( PostScript ) || + + (error = Load_TrueType_Metrics_Header( face, 1 )) != TT_Err_Ok || + /* try to load the 'vhea' & 'vmtx' at once if present */ + + LOAD_( Hdmx ) ) + + goto Fail; + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE + if ( ( error = Extension_Create( face ) ) != TT_Err_Ok ) + return error; +#endif + + return TT_Err_Ok; + + Fail : + Face_Destroy( face ); + return error; + } + +#undef LOAD_ + + +/******************************************************************* + * + * Function : Glyph_Destroy + * + * Description : The glyph object destructor. + * + * Input : _glyph typeless pointer to the glyph record to destroy + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Glyph_Destroy( void* _glyph ) + { + PGlyph glyph = (PGlyph)_glyph; + + + if ( !glyph ) + return TT_Err_Ok; + + glyph->outline.owner = TRUE; + return TT_Done_Outline( &glyph->outline ); + } + + +/******************************************************************* + * + * Function : Glyph_Create + * + * Description : The glyph object constructor. + * + * Input : _glyph glyph record to build. + * _face the glyph's parent face. + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Glyph_Create( void* _glyph, + void* _face ) + { + PFace face = (PFace)_face; + PGlyph glyph = (PGlyph)_glyph; + + + if ( !face ) + return TT_Err_Invalid_Face_Handle; + + if ( !glyph ) + return TT_Err_Invalid_Glyph_Handle; + + glyph->face = face; + + /* XXX: Don't forget the space for the 2 phantom points */ + return TT_New_Outline( glyph->face->maxPoints + 2, + glyph->face->maxContours, + &glyph->outline ); + } + + +/******************************************************************* + * + * Function : Scale_X + * + * Description : scale an horizontal distance from font + * units to 26.6 pixels + * + * Input : metrics pointer to metrics + * x value to scale + * + * Output : scaled value + * + ******************************************************************/ + + LOCAL_FUNC + TT_Pos Scale_X( PIns_Metrics metrics, TT_Pos x ) + { + return TT_MulDiv( x, metrics->x_scale1, metrics->x_scale2 ); + } + + +/******************************************************************* + * + * Function : Scale_Y + * + * Description : scale a vertical distance from font + * units to 26.6 pixels + * + * Input : metrics pointer to metrics + * y value to scale + * + * Output : scaled value + * + ******************************************************************/ + + LOCAL_FUNC + TT_Pos Scale_Y( PIns_Metrics metrics, TT_Pos y ) + { + return TT_MulDiv( y, metrics->y_scale1, metrics->y_scale2 ); + } + + +/******************************************************************* + * + * Function : TTObjs_Init + * + * Description : The TTObjs component initializer. Creates the + * object cache classes, as well as the face record + * cache. + * + * Input : engine engine instance + * + * Output : Error code. + * + ******************************************************************/ + + static + const TCache_Class objs_face_class = + { + sizeof ( TFace ), + -1, + Face_Create, + Face_Destroy, + NULL, + NULL + }; + + static + const TCache_Class objs_instance_class = + { + sizeof ( TInstance ), + -1, + Instance_Create, + Instance_Destroy, + NULL, + NULL + }; + + /* Note that we use a cache size of 1 for the execution context. */ + /* This is to avoid re-creating a new context each time we */ + /* change one instance's attribute (resolution and/or char sizes) */ + /* or when we load a glyph. */ + + static + const TCache_Class objs_exec_class = + { + sizeof ( TExecution_Context ), + 1, + Context_Create, + Context_Destroy, + NULL, + NULL + }; + + static + const TCache_Class objs_glyph_class = + { + sizeof ( TGlyph ), + -1, + Glyph_Create, + Glyph_Destroy, + NULL, + NULL + }; + + + LOCAL_FUNC + TT_Error TTObjs_Init( PEngine_Instance engine ) + { + PCache face_cache, exec_cache; + TT_Error error; + + + face_cache = 0; + exec_cache = 0; + + if ( ALLOC( face_cache, sizeof ( TCache ) ) || + ALLOC( exec_cache, sizeof ( TCache ) ) ) + goto Fail; + + /* create face cache */ + error = Cache_Create( engine, (PCache_Class)&objs_face_class, + face_cache, &engine->lock ); + if ( error ) + goto Fail; + + engine->objs_face_cache = face_cache; + + error = Cache_Create( engine, (PCache_Class)&objs_exec_class, + exec_cache, &engine->lock ); + if ( error ) + goto Fail; + + engine->objs_exec_cache = exec_cache; + + engine->objs_face_class = (PCache_Class)&objs_face_class; + engine->objs_instance_class = (PCache_Class)&objs_instance_class; + engine->objs_execution_class = (PCache_Class)&objs_exec_class; + engine->objs_glyph_class = (PCache_Class)&objs_glyph_class; + + goto Exit; + + Fail: + FREE( face_cache ); + FREE( exec_cache ); + + Exit: + return error; + } + + +/******************************************************************* + * + * Function : TTObjs_Done + * + * Description : The TTObjs component finalizer. + * + * Input : engine engine instance + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTObjs_Done( PEngine_Instance engine ) + { + /* destroy all active faces and contexts before releasing the */ + /* caches */ + Cache_Destroy( (TCache*)engine->objs_exec_cache ); + Cache_Destroy( (TCache*)engine->objs_face_cache ); + + /* Now frees caches and cache classes */ + FREE( engine->objs_exec_cache ); + FREE( engine->objs_face_cache ); + + return TT_Err_Ok; + } + + +/* END */ diff --git a/lib/ttobjs.h b/lib/ttobjs.h new file mode 100644 index 0000000..a5ba1ff --- /dev/null +++ b/lib/ttobjs.h @@ -0,0 +1,873 @@ +/******************************************************************* + * + * ttobjs.h 1.0 + * + * Objects definition unit. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef TTOBJS_H +#define TTOBJS_H + +#include "ttconfig.h" +#include "ttengine.h" +#include "ttmutex.h" +#include "ttcache.h" +#include "tttables.h" +#include "ttcmap.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* */ +/* This file contains the definitions and methods of the four */ +/* kinds of objects managed by the FreeType engine. These are: */ +/* */ +/* */ +/* Face objects: */ +/* */ +/* There is always one face object per opened TrueType font */ +/* file, and only one. The face object contains data that is */ +/* independent of current transform/scaling/rotation and */ +/* pointsize, or glyph index. This data is made of several */ +/* critical tables that are loaded on face object creation. */ +/* */ +/* A face object tracks all active and recycled objects of */ +/* the instance and execution context classes. Destroying a face */ +/* object will automatically destroy all associated instances. */ +/* */ +/* */ +/* Instance objects: */ +/* */ +/* An instance object always relates to a given face object, */ +/* known as its 'parent' or 'owner', and contains only the */ +/* data that is specific to one given pointsize/transform of */ +/* the face. You can only create an instance from a face object. */ +/* */ +/* An instance's current transform/pointsize can be changed */ +/* at any time using a single high-level API call, */ +/* TT_Reset_Instance(). */ +/* */ +/* Execution Context objects: */ +/* */ +/* An execution context (or context in short) relates to a face. */ +/* It contains the data and tables that are necessary to load */ +/* and hint (i.e. execute the glyph instructions of) one glyph. */ +/* A context is a transient object that is queried/created on */ +/* the fly: client applications never deal with them directly. */ +/* */ +/* */ +/* Glyph objects: */ +/* */ +/* A glyph object contains only the minimal glyph information */ +/* needed to render one glyph correctly. This means that a glyph */ +/* object really contains tables that are sized to hold the */ +/* contents of _any_ glyph of a given face. A client application */ +/* can usually create one glyph object for a given face, then use */ +/* it for all subsequent loads. */ +/* */ +/* Here is an example of a client application : */ +/* (NOTE: No error checking performed here!) */ +/* */ +/* */ +/* TT_Face face; -- face handle */ +/* TT_Instance ins1, ins2; -- two instance handles */ +/* TT_Glyph glyph; -- glyph handle */ +/* */ +/* TT_Init_FreeType(); */ +/* */ +/* -- Initialize the engine. This must be done prior to _any_ */ +/* operation. */ +/* */ +/* TT_Open_Face( "/some/face/name.ttf", &face ); */ +/* */ +/* -- create the face object. This call opens the font file */ +/* */ +/* TT_New_Instance( face, &ins1 ); */ +/* TT_New_Instance( face, &ins2 ); */ +/* */ +/* TT_Set_Instance_PointSize( ins1, 8 ); */ +/* TT_Set_Instance_PointSize( ins2, 12 ); */ +/* */ +/* -- create two distinct instances of the same face */ +/* -- ins1 is pointsize 8 at resolution 96 dpi */ +/* -- ins2 is pointsize 12 at resolution 96 dpi */ +/* */ +/* TT_New_Glyph( face, &glyph ); */ +/* */ +/* -- create a new glyph object which will receive the contents */ +/* of any glyph of 'face' */ +/* */ +/* TT_Load_Glyph( ins1, glyph, 64, DEFAULT_GLYPH_LOAD ); */ +/* */ +/* -- load glyph indexed 64 at pointsize 8 in the 'glyph' object */ +/* -- NOTE: This call will fail if the instance and the glyph */ +/* do not relate to the same face object. */ +/* */ +/* TT_Get_Outline( glyph, &outline ); */ +/* */ +/* -- extract the glyph outline from the object and copies it */ +/* to the 'outline' record */ +/* */ +/* TT_Get_Metrics( glyph, &metrics ); */ +/* */ +/* -- extract the glyph metrics and put them into the 'metrics' */ +/* record */ +/* */ +/* TT_Load_Glyph( ins2, glyph, 64, DEFAULT_GLYPH_LOAD ); */ +/* */ +/* -- load the same glyph at pointsize 12 in the 'glyph' object */ +/* */ +/* */ +/* TT_Close_Face( &face ); */ +/* */ +/* -- destroy the face object. This will destroy 'ins1' and */ +/* 'ins2'. However, the glyph object will still be available */ +/* */ +/* TT_Done_FreeType(); */ +/* */ +/* -- Finalize the engine. This will also destroy all pending */ +/* glyph objects (here 'glyph'). */ + + struct TFace_; + struct TInstance_; + struct TExecution_Context_; + struct TGlyph_; + + typedef struct TFace_ TFace; + typedef TFace* PFace; + + typedef struct TInstance_ TInstance; + typedef TInstance* PInstance; + + typedef struct TExecution_Context_ TExecution_Context; + typedef TExecution_Context* PExecution_Context; + + typedef struct TGlyph_ TGlyph; + typedef TGlyph* PGlyph; + + + /*************************************************************/ + /* */ + /* ADDITIONAL SUBTABLES */ + /* */ + /* These tables are not precisely defined by the specs */ + /* but their structures is implied by the TrueType font */ + /* file layout. */ + /* */ + /*************************************************************/ + + /* Graphics State */ + /* */ + /* The Graphics State (GS) is managed by the */ + /* instruction field, but does not come from */ + /* the font file. Thus, we can use 'int's */ + /* where needed. */ + + struct TGraphicsState_ + { + UShort rp0; + UShort rp1; + UShort rp2; + + TT_UnitVector dualVector; + TT_UnitVector projVector; + TT_UnitVector freeVector; + + Long loop; + TT_F26Dot6 minimum_distance; + Int round_state; + + Bool auto_flip; + TT_F26Dot6 control_value_cutin; + TT_F26Dot6 single_width_cutin; + TT_F26Dot6 single_width_value; + Short delta_base; + Short delta_shift; + + Byte instruct_control; + Bool scan_control; + Int scan_type; + + UShort gep0; + UShort gep1; + UShort gep2; + }; + + typedef struct TGraphicsState_ TGraphicsState; + + + LOCAL_DEF + const TGraphicsState Default_GraphicsState; + + + /*************************************************************/ + /* */ + /* EXECUTION SUBTABLES */ + /* */ + /* These sub-tables relate to instruction execution. */ + /* */ + /*************************************************************/ + +#define MAX_CODE_RANGES 3 + +/* There can only be 3 active code ranges at once: */ +/* - the Font Program */ +/* - the CVT Program */ +/* - a glyph's instructions set */ + +#define TT_CodeRange_Font 1 +#define TT_CodeRange_Cvt 2 +#define TT_CodeRange_Glyph 3 + + + struct TCodeRange_ + { + PByte Base; + ULong Size; + }; + + typedef struct TCodeRange_ TCodeRange; + typedef TCodeRange* PCodeRange; + + + /* Defintion of a code range */ + /* */ + /* Code ranges can be resident to a glyph (i.e. the Font Program) */ + /* while some others are volatile (Glyph instructions). */ + /* Tracking the state and presence of code ranges allows function */ + /* and instruction definitions within a code range to be forgotten */ + /* when the range is discarded. */ + + typedef TCodeRange TCodeRangeTable[MAX_CODE_RANGES]; + + /* defines a function/instruction definition record */ + + struct TDefRecord_ + { + Int Range; /* in which code range is it located ? */ + ULong Start; /* where does it start ? */ + Int Opc; /* function #, or instruction code */ + Bool Active; /* is it active ? */ + }; + + typedef struct TDefRecord_ TDefRecord; + typedef TDefRecord* PDefRecord; + typedef TDefRecord* PDefArray; + + /* defines a call record, used to manage function calls. */ + + struct TCallRecord_ + { + Int Caller_Range; + ULong Caller_IP; + Long Cur_Count; + ULong Cur_Restart; + }; + + typedef struct TCallRecord_ TCallRecord; + typedef TCallRecord* PCallRecord; + typedef TCallRecord* PCallStack; /* defines a simple call stack */ + + + /* This type defining a set of glyph points will be used to represent */ + /* each zone (regular and twilight) during instructions decoding. */ + struct TGlyph_Zone_ + { + UShort n_points; /* number of points in zone */ + Short n_contours; /* number of contours */ + + TT_Vector* org; /* original points coordinates */ + TT_Vector* cur; /* current points coordinates */ + + Byte* touch; /* current touch flags */ + UShort* contours; /* contour end points */ + }; + + typedef struct TGlyph_Zone_ TGlyph_Zone; + typedef TGlyph_Zone* PGlyph_Zone; + + + +#ifndef TT_STATIC_INTEPRETER /* indirect implementation */ + +#define EXEC_OPS PExecution_Context exc, +#define EXEC_OP PExecution_Context exc +#define EXEC_ARGS exc, +#define EXEC_ARG exc + +#else /* static implementation */ + +#define EXEC_OPS /* void */ +#define EXEC_OP /* void */ +#define EXEC_ARGS /* void */ +#define EXEC_ARG /* void */ + +#endif + + /* Rounding function, as used by the interpreter */ + typedef TT_F26Dot6 (*TRound_Function)( EXEC_OPS TT_F26Dot6 distance, + TT_F26Dot6 compensation ); + + /* Point displacement along the freedom vector routine, as */ + /* used by the interpreter */ + typedef void (*TMove_Function)( EXEC_OPS PGlyph_Zone zone, + UShort point, + TT_F26Dot6 distance ); + + /* Distance projection along one of the proj. vectors, as used */ + /* by the interpreter */ + typedef TT_F26Dot6 (*TProject_Function)( EXEC_OPS TT_Vector* v1, + TT_Vector* v2 ); + + /* reading a cvt value. Take care of non-square pixels when needed */ + typedef TT_F26Dot6 (*TGet_CVT_Function)( EXEC_OPS ULong index ); + + /* setting or moving a cvt value. Take care of non-square pixels */ + /* when needed */ + typedef void (*TSet_CVT_Function)( EXEC_OPS ULong index, + TT_F26Dot6 value ); + + /* subglyph transformation record */ + struct TTransform_ + { + TT_Fixed xx, xy; /* transformation */ + TT_Fixed yx, yy; /* matrix */ + TT_F26Dot6 ox, oy; /* offsets */ + }; + + typedef struct TTransform_ TTransform; + typedef TTransform* PTransform; + + /* subglyph loading record. Used to load composite components */ + struct TSubglyph_Record_ + { + Long index; /* subglyph index; initialized with -1 */ + Bool is_scaled; /* is the subglyph scaled? */ + Bool is_hinted; /* should it be hinted? */ + Bool preserve_pps; /* preserve phantom points? */ + + Long file_offset; + + TT_Big_Glyph_Metrics metrics; + + TGlyph_Zone zone; + + Long arg1; /* first argument */ + Long arg2; /* second argument */ + + UShort element_flag; /* current load element flag */ + + TTransform transform; /* transform */ + + TT_Vector pp1, pp2; /* phantom points */ + + }; + + typedef struct TSubglyph_Record_ TSubglyph_Record; + typedef TSubglyph_Record* PSubglyph_Record; + typedef TSubglyph_Record* PSubglyph_Stack; + + /* A note regarding non-squared pixels: */ + /* */ + /* (This text will probably go into some docs at some time, for */ + /* now, it is kept there to explain some definitions in the */ + /* TIns_Metrics record). */ + /* */ + /* The CVT is a one-dimensional array containing values that */ + /* control certain important characteristics in a font, like */ + /* the height of all capitals, all lowercase letter, default */ + /* spacing or stem width/height. */ + /* */ + /* These values are found in FUnits in the font file, and must be */ + /* scaled to pixel coordinates before being used by the CVT and */ + /* glyph programs. Unfortunately, when using distinct x and y */ + /* resolutions (or distinct x and y pointsizes), there are two */ + /* possible scalings. */ + /* */ + /* A first try was to implement a 'lazy' scheme where all values */ + /* were scaled when first used. However, while some values are always */ + /* used in the same direction, and some other are used in many */ + /* different circumstances and orientations. */ + /* */ + /* I have found a simpler way to do the same, and it even seems to */ + /* work in most of the cases: */ + /* */ + /* - all CVT values are scaled to the maximum ppem size */ + /* */ + /* - when performing a read or write in the CVT, a ratio factor */ + /* is used to perform adequate scaling. Example: */ + /* */ + /* x_ppem = 14 */ + /* y_ppem = 10 */ + /* */ + /* we choose ppem = x_ppem = 14 as the CVT scaling size. All cvt */ + /* entries are scaled to it. */ + /* */ + /* x_ratio = 1.0 */ + /* y_ratio = y_ppem/ppem (< 1.0) */ + /* */ + /* we compute the current ratio like: */ + /* */ + /* - if projVector is horizontal, */ + /* ratio = x_ratio = 1.0 */ + /* - if projVector is vertical, */ + /* ratop = y_ratio */ + /* - else, */ + /* ratio = sqrt((proj.x*x_ratio)^2 + (proj.y*y_ratio)^2) */ + /* */ + /* reading a cvt value returns ratio * cvt[index] */ + /* writing a cvt value in pixels cvt[index] / ratio */ + /* */ + /* the current ppem is simply ratio * ppem */ + /* */ + + /* metrics used by the instance and execution context objects */ + struct TIns_Metrics_ + { + TT_F26Dot6 pointSize; /* point size. 1 point = 1/72 inch. */ + + UShort x_resolution; /* device horizontal resolution in dpi. */ + UShort y_resolution; /* device vertical resolution in dpi. */ + + UShort x_ppem; /* horizontal pixels per EM */ + UShort y_ppem; /* vertical pixels per EM */ + + Long x_scale1; + Long x_scale2; /* used to scale FUnits to fractional pixels */ + + Long y_scale1; + Long y_scale2; /* used to scale FUnits to fractional pixels */ + + /* for non-square pixels */ + Long x_ratio; + Long y_ratio; + + UShort ppem; /* maximum ppem size */ + Long ratio; /* current ratio */ + Long scale1; + Long scale2; /* scale for ppem */ + + TT_F26Dot6 compensations[4]; /* device-specific compensations */ + + Bool rotated; /* `is the glyph rotated?'-flag */ + Bool stretched; /* `is the glyph stretched?'-flag */ + }; + + typedef struct TIns_Metrics_ TIns_Metrics; + typedef TIns_Metrics* PIns_Metrics; + + + + /***********************************************************************/ + /* */ + /* FreeType Face Type */ + /* */ + /***********************************************************************/ + + struct TFace_ + { + /* parent engine instance for the face object */ + PEngine_Instance engine; + + /* i/o stream */ + TT_Stream stream; + + /* used only by the threaded builds of the library */ + TMutex lock; + + /* TrueType collection header, if any was found */ + TTTCHeader ttcHeader; + + /* maximum profile table, as found in the TrueType file */ + TMaxProfile maxProfile; + + /* Note: */ + /* it seems that some maximum values cannot be */ + /* taken directly from this table, but rather by */ + /* combining some of its fields; e.g. the max. */ + /* number of points seems to be given by */ + /* MAX( maxPoints, maxCompositePoints ) */ + /* */ + /* For this reason, we define later our own */ + /* max values that are used to load and allocate */ + /* further tables. */ + + TT_Header fontHeader; /* the font header, as */ + /* found in the TTF file */ + TT_Horizontal_Header horizontalHeader; /* the horizontal header */ + + Bool verticalInfo; /* True when vertical table */ + TT_Vertical_Header verticalHeader; /* is present in the font */ + + TT_OS2 os2; /* 'OS/2' table */ + + TT_Postscript postscript; /* 'Post' table */ + + TT_Hdmx hdmx; /* 'Hdmx' table */ + + TName_Table nameTable; /* name table */ + + TGasp gasp; /* the 'gasp' table */ + + /* The directory of TrueType tables for this typeface */ + UShort numTables; + PTableDirEntry dirTables; + + /* The directory of character mappings table for */ + /* this typeface */ + UShort numCMaps; + PCMapTable cMaps; + + /* The glyph locations table */ + ULong numLocations; /* UShort is not enough */ +#ifndef TT_HUGE_PTR + PStorage glyphLocations; +#else + Storage TT_HUGE_PTR * glyphLocations; +#endif + + /* NOTE : The "hmtx" is now part of the horizontal header */ + + /* the font program, if any */ + ULong fontPgmSize; + PByte fontProgram; + + /* the cvt program, if any */ + ULong cvtPgmSize; + PByte cvtProgram; + + /* the original, unscaled, control value table */ + ULong cvtSize; + PShort cvt; + + /* The following values _must_ be set by the */ + /* maximum profile loader */ + + UShort numGlyphs; /* the face's total number of glyphs */ + UShort maxPoints; /* max glyph points number, simple and composite */ + UShort maxContours; /* max glyph contours numb, simple and composite */ + UShort maxComponents; /* max components in a composite glyph */ + + /* the following are object caches to track active */ + /* and recycled instances and execution contexts */ + /* objects. See 'ttcache.h' */ + + TCache instances; /* current instances for this face */ + TCache glyphs; /* current glyph containers for this face */ + + + /* A typeless pointer to the face object extensions defined */ + /* in the 'ttextend.*' files. */ + void* extension; + Int n_extensions; /* number of extensions */ + + /* Use extensions to provide additional capabilities to the */ + /* engine. Read the developer's guide in the documentation */ + /* directory to know how to do that. */ + + /* a generic pointer for client use - see TT_Set/Get_Face_Pointer */ + void* generic; + }; + + + + /***********************************************************************/ + /* */ + /* FreeType Instance Type */ + /* */ + /***********************************************************************/ + + struct TInstance_ + { + PFace owner; /* face object */ + + Bool valid; + + TIns_Metrics metrics; + + UShort numFDefs; /* number of function definitions */ + UShort maxFDefs; + PDefArray FDefs; /* table of FDefs entries */ + + UShort numIDefs; /* number of instruction definitions */ + UShort maxIDefs; + PDefArray IDefs; /* table of IDefs entries */ + + Int maxFunc; /* maximum function definition id */ + Int maxIns; /* maximum instruction definition id */ + + TCodeRangeTable codeRangeTable; + + TGraphicsState GS; + TGraphicsState default_GS; + + ULong cvtSize; /* the scaled control value table */ + PLong cvt; + + ULong storeSize; /* The storage area is now part of the */ + PLong storage; /* instance */ + + TGlyph_Zone twilight; /* The instance's twilight zone */ + + /* debugging variables */ + + /* When using the debugger, we must keep the */ + /* execution context tied to the instance */ + /* object rather than asking it on demand */ + + Bool debug; + PExecution_Context context; + + /* a generic pointer for client use - see TT_Set/Get_Instance_Pointer */ + void* generic; + }; + + + /***********************************************************************/ + /* */ + /* FreeType Execution Context Type */ + /* */ + /***********************************************************************/ + + struct TExecution_Context_ + { + PFace face; + PInstance instance; + + /* instructions state */ + + TT_Error error; /* last execution error */ + + Long top; /* top of exec. stack */ + + ULong stackSize; /* size of exec. stack */ + PStorage stack; /* current exec. stack */ + + Long args; + ULong new_top; /* new top after exec. */ + + TGlyph_Zone zp0, /* zone records */ + zp1, + zp2, + pts, + twilight; + + TIns_Metrics metrics; /* instance metrics */ + + TGraphicsState GS; /* current graphics state */ + + Int curRange; /* current code range number */ + PByte code; /* current code range */ + ULong IP; /* current instruction pointer */ + ULong codeSize; /* size of current range */ + + Byte opcode; /* current opcode */ + Int length; /* length of current opcode */ + + Bool step_ins; /* true if the interpreter must */ + /* increment IP after ins. exec */ + ULong cvtSize; + PLong cvt; + + ULong glyphSize; /* glyph instructions buffer size */ + PByte glyphIns; /* glyph instructions buffer */ + + UShort numFDefs; /* number of function defs */ + UShort maxFDefs; /* maximum number of function defs */ + PDefRecord FDefs; /* table of FDefs entries */ + + UShort numIDefs; /* number of instruction defs */ + UShort maxIDefs; /* maximum number of instruction defs */ + PDefRecord IDefs; /* table of IDefs entries */ + + Int maxFunc; + Int maxIns; + + Int callTop, /* top of call stack during execution */ + callSize; /* size of call stack */ + PCallStack callStack; /* call stack */ + + UShort maxPoints; /* capacity of this context's "pts" */ + UShort maxContours; /* record, expressed in points and */ + /* contours.. */ + + TCodeRangeTable codeRangeTable; /* table of valid coderanges */ + /* useful for the debugger */ + + ULong storeSize; /* size of current storage */ + PLong storage; /* storage area */ + + TT_F26Dot6 period; /* values used for the */ + TT_F26Dot6 phase; /* 'SuperRounding' */ + TT_F26Dot6 threshold; + + /* this seems to be unused */ +#if 0 + Int cur_ppem; /* ppem along the current proj vector */ +#endif + Long scale1; /* scaling values along the current */ + Long scale2; /* projection vector too.. */ + Bool cached_metrics; /* the ppem is computed lazily. used */ + /* to trigger computation when needed */ + + Bool instruction_trap; /* If True, the interpreter will */ + /* exit after each instruction */ + + TGraphicsState default_GS; /* graphics state resulting from */ + /* the prep program */ + Bool is_composite; /* ture if the glyph is composite */ + + Bool pedantic_hinting; /* if true, read and write array */ + /* bounds faults halt the hinting */ + + /* latest interpreter additions */ + + Long F_dot_P; /* dot product of freedom and projection */ + /* vectors */ + TRound_Function func_round; /* current rounding function */ + + TProject_Function func_project, /* current projection function */ + func_dualproj, /* current dual proj. function */ + func_freeProj; /* current freedom proj. func */ + + TMove_Function func_move; /* current point move function */ + + TGet_CVT_Function func_read_cvt; /* read a cvt entry */ + TSet_CVT_Function func_write_cvt; /* write a cvt entry (in pixels) */ + TSet_CVT_Function func_move_cvt; /* incr a cvt entry (in pixels) */ + + ULong loadSize; + PSubglyph_Stack loadStack; /* loading subglyph stack */ + + }; + + + /***********************************************************************/ + /* */ + /* FreeType Glyph Object Type */ + /* */ + /***********************************************************************/ + + struct TGlyph_ + { + PFace face; + TT_Big_Glyph_Metrics metrics; + TT_Outline outline; + }; + + + /* The following type is used to load a font from a collection. */ + /* See Face_Create in ttobjs.c */ + + struct TFont_Input_ + { + TT_Stream stream; /* input stream */ + ULong fontIndex; /* index of font in collection */ + PEngine_Instance engine; /* parent engine instance */ + + }; + + typedef struct TFont_Input_ TFont_Input; + + + /********************************************************************/ + /* */ + /* Code Range Functions */ + /* */ + /********************************************************************/ + + /* Goto a specified coderange */ + LOCAL_DEF + TT_Error Goto_CodeRange( PExecution_Context exec, + Int range, + ULong IP ); + +#if 0 + /* Return a pointer to a given coderange record. */ + /* Used only by the debugger. */ + LOCAL_DEF + PCodeRange Get_CodeRange( PExecution_Context exec, + Int range ); +#endif + + /* Set a given code range properties */ + LOCAL_DEF + TT_Error Set_CodeRange( PExecution_Context exec, + Int range, + void* base, + ULong length ); + + /* Clear a given coderange */ + LOCAL_DEF + TT_Error Clear_CodeRange( PExecution_Context exec, Int range ); + + + LOCAL_DEF + PExecution_Context New_Context( PFace face ); + + LOCAL_DEF + TT_Error Done_Context( PExecution_Context exec ); + + + LOCAL_DEF + TT_Error Context_Load( PExecution_Context exec, + PFace face, + PInstance ins ); + + LOCAL_DEF + TT_Error Context_Save( PExecution_Context exec, + PInstance ins ); + + LOCAL_DEF + TT_Error Context_Run( PExecution_Context exec, + Bool debug ); + + LOCAL_DEF + TT_Error Instance_Init( PInstance ins ); + + LOCAL_DEF + TT_Error Instance_Reset( PInstance ins ); + + + /********************************************************************/ + /* */ + /* Handy scaling functions */ + /* */ + /********************************************************************/ + + LOCAL_DEF TT_Pos Scale_X( PIns_Metrics metrics, TT_Pos x ); + LOCAL_DEF TT_Pos Scale_Y( PIns_Metrics metrics, TT_Pos y ); + + /********************************************************************/ + /* */ + /* Component Initializer/Finalizer */ + /* */ + /* Called from 'freetype.c' */ + /* The component must create and register the face, instance and */ + /* execution context cache classes before any object can be */ + /* managed. */ + /* */ + /********************************************************************/ + + LOCAL_DEF TT_Error TTObjs_Init( PEngine_Instance engine ); + LOCAL_DEF TT_Error TTObjs_Done( PEngine_Instance engine ); + +#ifdef __cplusplus + } +#endif + +#endif /* TTOBJS_H */ + + +/* END */ diff --git a/lib/ttraster.c b/lib/ttraster.c new file mode 100644 index 0000000..90f9a90 --- /dev/null +++ b/lib/ttraster.c @@ -0,0 +1,2727 @@ +/******************************************************************* + * + * ttraster.c 1.5 + * + * The FreeType glyph rasterizer (body). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTES: + * + * This version supports the following: + * + * - direct grayscaling + * - sub-banding + * - drop-out modes 4 and 5 + * - second pass for complete drop-out control (bitmap only) + * - variable precision + * + * Changes between 1.5 and 1.4: + * + * Performance tuning. + * + * Changes between 1.4 and 1.3: + * + * Mainly performance tunings: + * + * - Line_Down() and Bezier_Down() now use the functions Line_Up() + * and Bezier_Up() to do their work. + * - optimized Split_Bezier() + * - optimized linked lists used during sweeps + * + ******************************************************************/ + +#include "ttraster.h" +#include "ttdebug.h" +#include "tttypes.h" +#include "ttengine.h" +#include "ttcalc.h" /* for TT_MulDiv only */ + +#include "ttmemory.h" /* only used to allocate memory on engine init */ + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_raster + + +/* The default render pool size */ +#define RASTER_RENDER_POOL 64000 + +/* The size of the two-lines intermediate bitmap used */ +/* for anti-aliasing */ +#define RASTER_GRAY_LINES 2048 + + +#define Raster_Err_None TT_Err_Ok +#define Raster_Err_Not_Ini TT_Err_Raster_Not_Initialized +#define Raster_Err_Overflow TT_Err_Raster_Pool_Overflow +#define Raster_Err_Neg_Height TT_Err_Raster_Negative_Height +#define Raster_Err_Invalid TT_Err_Raster_Invalid_Value +#define Raster_Err_Gray_Unsupported TT_Err_Raster_Gray_Unsupported + + +/* FMulDiv means "Fast MulDiv", it is uses in case where 'b' is typically */ +/* a small value and the result of (a*b) is known to fit in 32 bits. */ +#define FMulDiv( a, b, c ) ( (a) * (b) / (c) ) + +/* On the other hand, SMulDiv is for "Slow MulDiv", and is used typically */ +/* for clipping computations. It simply uses the TT_MulDiv() function */ +/* defined in "ttcalc.h" */ +/* */ +/* So, the following definition fits the bill nicely, and we don't need */ +/* to use the one in 'ttcalc' anymore, even for 16-bit systems... */ +#define SMulDiv TT_MulDiv + + +/* Define DEBUG_RASTER if you want to generate a debug version of the */ +/* rasterizer. This will progressively draw the glyphs while all the */ +/* computation are done directly on the graphics screen (the glyphs */ +/* will be inverted). */ + +/* Note that DEBUG_RASTER should only be used for debugging with b/w */ +/* rendering, not with gray levels. */ + +/* The definition of DEBUG_RASTER should appear in the file */ +/* "ttconfig.h". */ + +#ifdef DEBUG_RASTER + extern Char* Vio; /* A pointer to VRAM or display buffer */ +#endif + + +/* The rasterizer is a very general purpose component, please leave */ +/* the following redefinitions there (you never know your target */ +/* environment). */ + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef NULL +#define NULL (void*)0 +#endif + +#define MaxBezier 32 /* The maximum number of stacked Bezier curves. */ + /* Setting this constant to more than 32 is a */ + /* pure waste of space. */ + +#define Pixel_Bits 6 /* fractional bits of *input* coordinates */ + + /* States of each line, arc and profile */ + enum TStates_ + { + Unknown, + Ascending, + Descending, + Flat + }; + + typedef enum TStates_ TStates; + + struct TProfile_; + typedef struct TProfile_ TProfile; + typedef TProfile* PProfile; + + struct TProfile_ + { + TT_F26Dot6 X; /* current coordinate during sweep */ + PProfile link; /* link to next profile - various purpose */ + PStorage offset; /* start of profile's data in render pool */ + Int flow; /* Profile orientation: Asc/Descending */ + Long height; /* profile's height in scanlines */ + Long start; /* profile's starting scanline */ + + UShort countL; /* number of lines to step before this */ + /* profile becomes drawable */ + + PProfile next; /* next profile in same contour, used */ + /* during drop-out control */ + }; + + typedef PProfile TProfileList; + typedef PProfile* PProfileList; + + + /* I use the classic trick of two dummy records for the head and tail */ + /* of a linked list; this reduces tests in insertion/deletion/sorting. */ + /* NOTE: used during sweeps only. */ + + /* Simple record used to implement a stack of bands, required */ + /* by the sub-banding mechanism */ + + struct TBand_ + { + Short y_min; /* band's minimum */ + Short y_max; /* band's maximum */ + }; + + typedef struct TBand_ TBand; + + +#define AlignProfileSize \ + (( sizeof(TProfile)+sizeof(long)-1 ) / sizeof(long)) + + + /* Left fill bitmask */ + static const Byte LMask[8] = + { 0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01 }; + + /* Right fill bitmask */ + static const Byte RMask[8] = + { 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF }; + + /* prototypes used for sweep function dispatch */ + typedef void Function_Sweep_Init( RAS_ARGS Short* min, + Short* max ); + + typedef void Function_Sweep_Span( RAS_ARGS Short y, + TT_F26Dot6 x1, + TT_F26Dot6 x2, + PProfile left, + PProfile right ); + + typedef void Function_Sweep_Step( RAS_ARG ); + + +/* NOTE: These operations are only valid on 2's complement processors */ + +#define FLOOR( x ) ( (x) & -ras.precision ) +#define CEILING( x ) ( ((x) + ras.precision - 1) & -ras.precision ) +#define TRUNC( x ) ( (signed long)(x) >> ras.precision_bits ) +#define FRAC( x ) ( (x) & (ras.precision - 1) ) +#define SCALED( x ) ( ((x) << ras.scale_shift) - ras.precision_half ) + +#ifdef DEBUG_RASTER +#define DEBUG_PSET Pset() +#else +#define DEBUG_PSET +#endif + + struct TPoint_ + { + Long x, y; + }; + + typedef struct TPoint_ TPoint; + + + /* Note that I have moved the location of some fields in the */ + /* structure to ensure that the most used variables are used */ + /* at the top. Thus, their offset can be coded with less */ + /* opcodes, and it results in a smaller executable. */ + + struct TRaster_Instance_ + { + Int precision_bits; /* precision related variables */ + Int precision; + Int precision_half; + Long precision_mask; + Int precision_shift; + Int precision_step; + Int precision_jitter; + + Int scale_shift; /* == precision_shift for bitmaps */ + /* == precision_shift+1 for pixmaps */ + + PStorage buff; /* The profiles buffer */ + PStorage sizeBuff; /* Render pool size */ + PStorage maxBuff; /* Profiles buffer size */ + PStorage top; /* Current cursor in buffer */ + + TT_Error error; + + PByte flags; /* current flags table */ + PUShort outs; /* current outlines table */ + + UShort nPoints; /* number of points in current glyph */ + Short nContours; /* number of contours in current glyph */ + Int numTurns; /* number of Y-turns in outline */ + + TPoint* arc; /* current Bezier arc pointer */ + + UShort bWidth; /* target bitmap width */ + PByte bTarget; /* target bitmap buffer */ + PByte gTarget; /* target pixmap buffer */ + + Long lastX, lastY, minY, maxY; + + UShort num_Profs; /* current number of profiles */ + + Bool fresh; /* signals a fresh new profile which */ + /* 'start' field must be completed */ + Bool joint; /* signals that the last arc ended */ + /* exactly on a scanline. Allows */ + /* removal of doublets */ + PProfile cProfile; /* current profile */ + PProfile fProfile; /* head of linked list of profiles */ + PProfile gProfile; /* contour's first profile in case */ + /* of impact */ + TStates state; /* rendering state */ + + TT_Raster_Map target; /* description of target bit/pixmap */ + + Long traceOfs; /* current offset in target bitmap */ + Long traceG; /* current offset in target pixmap */ + + Short traceIncr; /* sweep's increment in target bitmap */ + + Short gray_min_x; /* current min x during gray rendering */ + Short gray_max_x; /* current max x during gray rendering */ + + /* dispatch variables */ + + Function_Sweep_Init* Proc_Sweep_Init; + Function_Sweep_Span* Proc_Sweep_Span; + Function_Sweep_Span* Proc_Sweep_Drop; + Function_Sweep_Step* Proc_Sweep_Step; + + TT_Vector* coords; + + Byte dropOutControl; /* current drop_out control method */ + + Byte grays[5]; /* Palette of gray levels used for render */ + + Byte* gray_lines; /* Intermediate table used to render the */ + /* graylevels pixmaps. */ + /* gray_lines is a buffer holding two */ + /* monochrome scanlines */ + Short gray_width; /* width in bytes of one monochrome */ + /* intermediate scanline of gray_lines. */ + /* Each gray pixel takes 2 bits long there */ + + /* The gray_lines must hold 2 lines, thus with size */ + /* in bytes of at least 'gray_width*2' */ + + Bool second_pass; /* indicates wether a horizontal pass */ + /* should be performed to control drop-out */ + /* accurately when calling Render_Glyph. */ + /* Note that there is no horizontal pass */ + /* during gray rendering. */ + TPoint arcs[2 * MaxBezier + 1]; /* The Bezier stack */ + + TBand band_stack[16]; /* band stack used for sub-banding */ + Int band_top; /* band stack top */ + + Int count_table[256]; /* Look-up table used to quickly count */ + /* set bits in a gray 2x2 cell */ + }; + + +#ifdef TT_CONFIG_OPTION_STATIC_RASTER + + static TRaster_Instance cur_ras; +#define ras cur_ras + +#else + +#define ras (*raster) + +#endif /* TT_STATIC_RASTER */ + + +#ifdef DEBUG_RASTER + + /************************************************/ + /* */ + /* Pset: */ + /* */ + /* Used for debugging only. Plots a point */ + /* in VRAM during rendering (not afterwards). */ + /* */ + /* NOTE: This procedure relies on the value */ + /* of cProfile->start, which may not */ + /* be set when Pset is called sometimes. */ + /* This will usually result in a dot */ + /* plotted on the first screen scanline */ + /* (far away its original position). */ + /* */ + /* This "bug" reflects nothing wrong */ + /* in the current implementation, and */ + /* the bitmap is rendered correctly, */ + /* so don't panic if you see 'flying' */ + /* dots in debugging mode. */ + /* */ + /* - David */ + /* */ + /************************************************/ + + static void Pset( RAS_ARG ) + { + Long o; + Long x; + + + x = ras.top[-1]; + + switch ( ras.cProfile->flow ) + { + case TT_Flow_Up: + o = Vio_ScanLineWidth * + ( ras.top-ras.cProfile->offset + ras.cProfile->start ) + + ( x / (ras.precision*8) ); + break; + + case TT_Flow_Down: + o = Vio_ScanLineWidth * + ( ras.cProfile->start-ras.top + ras.cProfile->offset ) + + ( x / (ras.precision*8) ); + break; + } + + if ( o > 0 ) + Vio[o] |= (unsigned)0x80 >> ( (x/ras.precision) & 7 ); + } + + + static void Clear_Band( RAS_ARGS Int y1, Int y2 ) + { + MEM_Set( Vio + y1*Vio_ScanLineWidth, (y2-y1+1)*Vio_ScanLineWidth, 0 ); + } + +#endif /* DEBUG_RASTER */ + + +/************************************************************************/ +/* */ +/* Function: Set_High_Precision */ +/* */ +/* Description: Sets precision variables according to param flag. */ +/* */ +/* Input: High set to True for high precision (typically for */ +/* ppem < 18), false otherwise. */ +/* */ +/************************************************************************/ + + static void Set_High_Precision( RAS_ARGS Bool High ) + { + if ( High ) + { + ras.precision_bits = 10; + ras.precision_step = 128; + ras.precision_jitter = 24; + } + else + { + ras.precision_bits = 6; + ras.precision_step = 32; + ras.precision_jitter = 2; + } + + PTRACE7(( "Set_High_Precision(%s)\n", High ? "true" : "false" )); + + ras.precision = 1 << ras.precision_bits; + ras.precision_half = ras.precision / 2; + ras.precision_shift = ras.precision_bits - Pixel_Bits; + ras.precision_mask = -ras.precision; + } + + +/****************************************************************************/ +/* */ +/* Function: New_Profile */ +/* */ +/* Description: Creates a new Profile in the render pool. */ +/* */ +/* Input: aState state/orientation of the new Profile */ +/* */ +/* Returns: SUCCESS on success. */ +/* FAILURE in case of overflow or of incoherent Profile. */ +/* */ +/****************************************************************************/ + + static Bool New_Profile( RAS_ARGS TStates aState ) + { + if ( !ras.fProfile ) + { + ras.cProfile = (PProfile)ras.top; + ras.fProfile = ras.cProfile; + ras.top += AlignProfileSize; + } + + if ( ras.top >= ras.maxBuff ) + { + ras.error = Raster_Err_Overflow; + return FAILURE; + } + + switch ( aState ) + { + case Ascending: + ras.cProfile->flow = TT_Flow_Up; + PTRACE7(( "New ascending profile = %lx\n", (long)ras.cProfile )); + break; + + case Descending: + ras.cProfile->flow = TT_Flow_Down; + PTRACE7(( "New descending profile = %lx\n", (long)ras.cProfile )); + break; + + default: + PTRACE0(( "Invalid profile direction in Raster:New_Profile !!\n" )); + ras.error = Raster_Err_Invalid; + return FAILURE; + } + + ras.cProfile->start = 0; + ras.cProfile->height = 0; + ras.cProfile->offset = ras.top; + ras.cProfile->link = (PProfile)0; + ras.cProfile->next = (PProfile)0; + + if ( !ras.gProfile ) + ras.gProfile = ras.cProfile; + + ras.state = aState; + ras.fresh = TRUE; + ras.joint = FALSE; + + return SUCCESS; + } + + +/****************************************************************************/ +/* */ +/* Function: End_Profile */ +/* */ +/* Description: Finalizes the current Profile. */ +/* */ +/* Input: None */ +/* */ +/* Returns: SUCCESS on success. */ +/* FAILURE in case of overflow or incoherency. */ +/* */ +/****************************************************************************/ + + static Bool End_Profile( RAS_ARG ) + { + Long h; + PProfile oldProfile; + + + h = ras.top - ras.cProfile->offset; + + if ( h < 0 ) + { + PTRACE0(( "Negative height encountered in End_Profile!\n" )); + ras.error = Raster_Err_Neg_Height; + return FAILURE; + } + + if ( h > 0 ) + { + PTRACE1(( "Ending profile %lx, start = %ld, height = %ld\n", + (long)ras.cProfile, ras.cProfile->start, h )); + + oldProfile = ras.cProfile; + ras.cProfile->height = h; + ras.cProfile = (PProfile)ras.top; + + ras.top += AlignProfileSize; + + ras.cProfile->height = 0; + ras.cProfile->offset = ras.top; + oldProfile->next = ras.cProfile; + ras.num_Profs++; + } + + if ( ras.top >= ras.maxBuff ) + { + PTRACE1(( "overflow in End_Profile\n" )); + ras.error = Raster_Err_Overflow; + return FAILURE; + } + + ras.joint = FALSE; + + return SUCCESS; + } + + +/****************************************************************************/ +/* */ +/* Function: Insert_Y_Turn */ +/* */ +/* Description: Insert a salient into the sorted list placed on top */ +/* of the render pool */ +/* */ +/* Input: New y scanline position */ +/* */ +/****************************************************************************/ + + static + Bool Insert_Y_Turn( RAS_ARGS Int y ) + { + PStorage y_turns; + Int y2, n; + + n = ras.numTurns-1; + y_turns = ras.sizeBuff - ras.numTurns; + + /* look for first y value that is <= */ + while ( n >= 0 && y < y_turns[n] ) + n--; + + /* if it is <, simply insert it, ignore if == */ + if ( n >= 0 && y > y_turns[n] ) + while ( n >= 0 ) + { + y2 = y_turns[n]; + y_turns[n] = y; + y = y2; + n--; + } + + if ( n < 0 ) + { + if (ras.maxBuff <= ras.top) + { + ras.error = Raster_Err_Overflow; + return FAILURE; + } + ras.maxBuff--; + ras.numTurns++; + ras.sizeBuff[-ras.numTurns] = y; + } + + return SUCCESS; + } + + +/****************************************************************************/ +/* */ +/* Function: Finalize_Profile_Table */ +/* */ +/* Description: Adjusts all links in the Profiles list. */ +/* */ +/* Input: None */ +/* */ +/* Returns: None. */ +/* */ +/****************************************************************************/ + + static + Bool Finalize_Profile_Table( RAS_ARG ) + { + Int bottom, top; + UShort n; + PProfile p; + + + n = ras.num_Profs; + + if ( n > 1 ) + { + p = ras.fProfile; + while ( n > 0 ) + { + if ( n > 1 ) + p->link = (PProfile)( p->offset + p->height ); + else + p->link = NULL; + + switch ( p->flow ) + { + case TT_Flow_Down: + bottom = p->start - p->height+1; + top = p->start; + p->start = bottom; + p->offset += p->height-1; + break; + + case TT_Flow_Up: + default: + bottom = p->start; + top = p->start + p->height-1; + } + + if ( Insert_Y_Turn( RAS_VARS bottom ) || + Insert_Y_Turn( RAS_VARS top+1 ) ) + return FAILURE; + + p = p->link; + n--; + } + } + else + ras.fProfile = NULL; + + return SUCCESS; + } + + +/****************************************************************************/ +/* */ +/* Function: Split_Bezier */ +/* */ +/* Description: Subdivides one Bezier arc into two joint */ +/* sub-arcs in the Bezier stack. */ +/* */ +/* Input: None (subdivided bezier is taken from the top of the */ +/* stack). */ +/* */ +/* Returns: None. */ +/* */ +/* */ +/* Note: This routine is the 'beef' of this component. It is _the_ */ +/* inner loop that should be optimized to hell to get the */ +/* best performance. */ +/* */ +/****************************************************************************/ + + static void Split_Bezier( TPoint* base ) + { + Long a, b; + + + base[4].x = base[2].x; + b = base[1].x; + a = base[3].x = ( base[2].x + b ) / 2; + b = base[1].x = ( base[0].x + b ) / 2; + base[2].x = ( a + b ) / 2; + + base[4].y = base[2].y; + b = base[1].y; + a = base[3].y = ( base[2].y + b ) / 2; + b = base[1].y = ( base[0].y + b ) / 2; + base[2].y = ( a + b ) / 2; + + /* hand optimized. gcc doesn't seem too good at common expression */ + /* substitution and instruction scheduling ;-) */ + } + + +/****************************************************************************/ +/* */ +/* Function: Push_Bezier */ +/* */ +/* Description: Clears the Bezier stack and pushes a new arc on top of it. */ +/* */ +/* Input: x1,y1 x2,y2 x3,y3 new Bezier arc */ +/* */ +/* Returns: None. */ +/* */ +/****************************************************************************/ + + static void Push_Bezier( RAS_ARGS Long x1, Long y1, + Long x2, Long y2, + Long x3, Long y3 ) + { + ras.arc = ras.arcs; + ras.arc[2].x = x1; ras.arc[2].y = y1; + ras.arc[1].x = x2; ras.arc[1].y = y2; + ras.arc[0].x = x3; ras.arc[0].y = y3; + } + + +/****************************************************************************/ +/* */ +/* Function: Line_Up */ +/* */ +/* Description: Computes the x-coordinates of an ascending line segment */ +/* and stores them in the render pool. */ +/* */ +/* Input: x1,y1,x2,y2 Segment start (x1,y1) and end (x2,y2) points */ +/* */ +/* Returns: SUCCESS on success. */ +/* FAILURE on Render Pool overflow. */ +/* */ +/****************************************************************************/ + + static Bool Line_Up( RAS_ARGS Long x1, Long y1, + Long x2, Long y2, + Long miny, Long maxy ) + { + Long Dx, Dy; + Int e1, e2, f1, f2, size; /* XXX: is `Short' sufficient? */ + Long Ix, Rx, Ax; + + PStorage top; + + + Dx = x2 - x1; + Dy = y2 - y1; + + if ( Dy <= 0 || y2 < miny || y1 > maxy ) + return SUCCESS; + + if ( y1 < miny ) + { + /* Take care : miny-y1 can be a very large value, we use */ + /* a slow MulDiv function to avoid clipping bugs */ + x1 += SMulDiv( Dx, miny - y1, Dy ); + e1 = TRUNC( miny ); + f1 = 0; + } + else + { + e1 = TRUNC( y1 ); + f1 = FRAC( y1 ); + } + + if ( y2 > maxy ) + { + /* x2 += FMulDiv( Dx, maxy - y2, Dy ); UNNECESSARY */ + e2 = TRUNC( maxy ); + f2 = 0; + } + else + { + e2 = TRUNC( y2 ); + f2 = FRAC( y2 ); + } + + if ( f1 > 0 ) + { + if ( e1 == e2 ) return SUCCESS; + else + { + x1 += FMulDiv( Dx, ras.precision - f1, Dy ); + e1 += 1; + } + } + else + if ( ras.joint ) + { + ras.top--; + ras.joint = FALSE; + } + + ras.joint = ( f2 == 0 ); + + if ( ras.fresh ) + { + ras.cProfile->start = e1; + ras.fresh = FALSE; + } + + size = e2 - e1 + 1; + if ( ras.top + size >= ras.maxBuff ) + { + ras.error = Raster_Err_Overflow; + return FAILURE; + } + + if ( Dx > 0 ) + { + Ix = (ras.precision*Dx) / Dy; + Rx = (ras.precision*Dx) % Dy; + Dx = 1; + } + else + { + Ix = -( (ras.precision*-Dx) / Dy ); + Rx = (ras.precision*-Dx) % Dy; + Dx = -1; + } + + Ax = -Dy; + top = ras.top; + + while ( size > 0 ) + { + *top++ = x1; + + DEBUG_PSET; + + x1 += Ix; + Ax += Rx; + if ( Ax >= 0 ) + { + Ax -= Dy; + x1 += Dx; + } + size--; + } + + ras.top = top; + return SUCCESS; + } + + + static Bool Line_Down( RAS_ARGS Long x1, Long y1, + Long x2, Long y2, + Long miny, Long maxy ) + { + Bool result, fresh; + + + fresh = ras.fresh; + + result = Line_Up( RAS_VARS x1, -y1, x2, -y2, -maxy, -miny ); + + if ( fresh && !ras.fresh ) + ras.cProfile->start = -ras.cProfile->start; + + return result; + } + + +/****************************************************************************/ +/* */ +/* Function: Bezier_Up */ +/* */ +/* Description: Computes thes x-coordinates of an ascending bezier arc */ +/* and stores them in the render pool. */ +/* */ +/* Input: None. The arc is taken from the top of the Bezier stack. */ +/* */ +/* Returns: SUCCESS on success. */ +/* FAILURE on Render Pool overflow. */ +/* */ +/****************************************************************************/ + + static Bool Bezier_Up( RAS_ARGS Long miny, Long maxy ) + { + Long y1, y2, e, e2, e0; + Short f1; + + TPoint* arc; + TPoint* start_arc; + + PStorage top; + + + arc = ras.arc; + y1 = arc[2].y; + y2 = arc[0].y; + top = ras.top; + + if ( y2 < miny || y1 > maxy ) + goto Fin; + + e2 = FLOOR( y2 ); + + if ( e2 > maxy ) + e2 = maxy; + + e0 = miny; + + if ( y1 < miny ) + e = miny; + else + { + e = CEILING( y1 ); + f1 = FRAC( y1 ); + e0 = e; + + if ( f1 == 0 ) + { + if ( ras.joint ) + { + top--; + ras.joint = FALSE; + } + + *top++ = arc[2].x; + + DEBUG_PSET; + + e += ras.precision; + } + } + + if ( ras.fresh ) + { + ras.cProfile->start = TRUNC( e0 ); + ras.fresh = FALSE; + } + + if ( e2 < e ) + goto Fin; + + if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff ) + { + ras.top = top; + ras.error = Raster_Err_Overflow; + return FAILURE; + } + + start_arc = arc; + + while ( arc >= start_arc && e <= e2 ) + { + ras.joint = FALSE; + + y2 = arc[0].y; + + if ( y2 > e ) + { + y1 = arc[2].y; + if ( y2 - y1 >= ras.precision_step ) + { + Split_Bezier( arc ); + arc += 2; + } + else + { + *top++ = arc[2].x + FMulDiv( arc[0].x - arc[2].x, + e - y1, + y2 - y1 ); + DEBUG_PSET; + + arc -= 2; + e += ras.precision; + } + } + else + { + if ( y2 == e ) + { + ras.joint = TRUE; + *top++ = arc[0].x; + + DEBUG_PSET; + + e += ras.precision; + } + arc -= 2; + } + } + + Fin: + ras.top = top; + ras.arc -= 2; + return SUCCESS; + } + + +/****************************************************************************/ +/* */ +/* Function: Bezier_Down */ +/* */ +/* Description: Computes the x-coordinates of a descending bezier arc */ +/* and stores them in the render pool. */ +/* */ +/* Input: None. Arc is taken from the top of the Bezier stack. */ +/* */ +/* Returns: SUCCESS on success. */ +/* FAILURE on Render Pool overflow. */ +/* */ +/****************************************************************************/ + + static Bool Bezier_Down( RAS_ARGS Long miny, Long maxy ) + { + TPoint* arc = ras.arc; + Bool result, fresh; + + + arc[0].y = -arc[0].y; + arc[1].y = -arc[1].y; + arc[2].y = -arc[2].y; + + fresh = ras.fresh; + + result = Bezier_Up( RAS_VARS -maxy, -miny ); + + if ( fresh && !ras.fresh ) + ras.cProfile->start = -ras.cProfile->start; + + arc[0].y = -arc[0].y; + return result; + } + + +/****************************************************************************/ +/* */ +/* Function: Line_To */ +/* */ +/* Description: Injects a new line segment and adjusts Profiles list. */ +/* */ +/* Input: x, y : segment endpoint (start point in LastX,LastY) */ +/* */ +/* Returns: SUCCESS on success. */ +/* FAILURE on Render Pool overflow or Incorrect Profile. */ +/* */ +/****************************************************************************/ + + static Bool Line_To( RAS_ARGS Long x, Long y ) + { + /* First, detect a change of direction */ + + switch ( ras.state ) + { + case Unknown: + if ( y > ras.lastY ) + { + if ( New_Profile( RAS_VARS Ascending ) ) return FAILURE; + } + else + { + if ( y < ras.lastY ) + if ( New_Profile( RAS_VARS Descending ) ) return FAILURE; + } + break; + + case Ascending: + if ( y < ras.lastY ) + { + if ( End_Profile( RAS_VAR ) || + New_Profile( RAS_VARS Descending ) ) return FAILURE; + } + break; + + case Descending: + if ( y > ras.lastY ) + { + if ( End_Profile( RAS_VAR ) || + New_Profile( RAS_VARS Ascending ) ) return FAILURE; + } + break; + + default: + ; + } + + /* Then compute the lines */ + + switch ( ras.state ) + { + case Ascending: + if ( Line_Up ( RAS_VARS ras.lastX, ras.lastY, + x, y, ras.minY, ras.maxY ) ) + return FAILURE; + break; + + case Descending: + if ( Line_Down( RAS_VARS ras.lastX, ras.lastY, + x, y, ras.minY, ras.maxY ) ) + return FAILURE; + break; + + default: + ; + } + + ras.lastX = x; + ras.lastY = y; + + return SUCCESS; + } + + +/****************************************************************************/ +/* */ +/* Function: Bezier_To */ +/* */ +/* Description: Injects a new bezier arc and adjusts the profile list. */ +/* */ +/* Input: x, y : arc endpoint (start point in LastX, LastY) */ +/* Cx, Cy : control point */ +/* */ +/* Returns: SUCCESS on success. */ +/* FAILURE on Render Pool overflow or Incorrect Profile. */ +/* */ +/****************************************************************************/ + + static Bool Bezier_To( RAS_ARGS Long x, + Long y, + Long cx, + Long cy ) + { + Long y1, y2, y3, x3; + TStates state_bez; + + + Push_Bezier( RAS_VARS ras.lastX, ras.lastY, cx, cy, x, y ); + + do + { + y1 = ras.arc[2].y; + y2 = ras.arc[1].y; + y3 = ras.arc[0].y; + x3 = ras.arc[0].x; + + /* first, categorize the bezier arc */ + + if ( y1 == y2 ) + { + if ( y2 == y3 ) + state_bez = Flat; + else if ( y2 > y3 ) + state_bez = Descending; + else + state_bez = Ascending; + } + else if ( y1 > y2 ) + { + if ( y2 >= y3 ) + state_bez = Descending; + else + state_bez = Unknown; + } + else if ( y2 <= y3 ) + state_bez = Ascending; + else + state_bez = Unknown; + + /* split non-monotonic arcs, ignore flat ones, or */ + /* computes the up and down ones */ + + switch ( state_bez ) + { + case Flat: + ras.arc -= 2; + break; + + case Unknown: + Split_Bezier( ras.arc ); + ras.arc += 2; + break; + + default: + /* detect a change of direction */ + + if ( ras.state != state_bez ) + { + if ( ras.state != Unknown ) + if ( End_Profile( RAS_VAR ) ) return FAILURE; + + if ( New_Profile( RAS_VARS state_bez ) ) return FAILURE; + } + + /* compute */ + + switch ( ras.state ) + { + case Ascending: + if ( Bezier_Up ( RAS_VARS ras.minY, ras.maxY ) ) + return FAILURE; + break; + + case Descending: + if ( Bezier_Down( RAS_VARS ras.minY, ras.maxY ) ) + return FAILURE; + break; + + default: + ; + } + } + } while ( ras.arc >= ras.arcs ); + + ras.lastX = x3; + ras.lastY = y3; + + return SUCCESS; + } + + +/****************************************************************************/ +/* */ +/* Function: Decompose_Curve */ +/* */ +/* Description: Scans the outline arays in order to emit individual */ +/* segments and beziers by calling Line_To() and Bezier_To(). */ +/* It handles all weird cases, like when the first point */ +/* is off the curve, or when there are simply no 'on' */ +/* points in the contour! */ +/* */ +/* Input: first, last : indexes of first and last point in */ +/* contour. */ +/* */ +/* Returns: SUCCESS on success. */ +/* FAILURE on error. */ +/* */ +/****************************************************************************/ + +#undef SWAP_ +#define SWAP_(x,y) { Long swap = x; x = y; y = swap; } + + static Bool Decompose_Curve( RAS_ARGS UShort first, + UShort last, + Bool flipped ) + { + Long x, y; /* current point */ + Long cx, cy; /* current Bezier control point */ + Long mx, my; /* current middle point */ + + Long x_first, y_first; /* first point's coordinates */ + Long x_last, y_last; /* last point's coordinates */ + + UShort index; /* current point's index */ + Bool on_curve; /* current point's state */ + + x_first = SCALED( ras.coords[first].x ); + y_first = SCALED( ras.coords[first].y ); + + if ( flipped ) SWAP_( x_first,y_first ); + + x_last = SCALED( ras.coords[last].x ); + y_last = SCALED( ras.coords[last].y ); + + if ( flipped ) SWAP_( x_last,y_last ); + + ras.lastX = cx = x_first; + ras.lastY = cy = y_first; + + on_curve = (ras.flags[first] & 1); + index = first; + + /* check first point to determine origin */ + if ( !on_curve ) + { + /* first point is off the curve. Yes, this happens... */ + if ( ras.flags[last] & 1 ) + { + ras.lastX = x_last; /* start at last point if it */ + ras.lastY = y_last; /* is on the curve */ + } + else + { + /* if both first and last points are off the curve, */ + /* start at their middle and record its position */ + /* for closure */ + ras.lastX = (ras.lastX + x_last)/2; + ras.lastY = (ras.lastY + y_last)/2; + + x_last = ras.lastX; + y_last = ras.lastY; + } + } + + /* now process each contour point individually */ + while ( index < last ) + { + index++; + x = SCALED( ras.coords[index].x ); + y = SCALED( ras.coords[index].y ); + + if ( flipped ) SWAP_( x, y ); + + if ( on_curve ) + { + /* the previous point was on the curve */ + on_curve = ( ras.flags[index] & 1 ); + if ( on_curve ) + { + /* two successive on points => emit segment */ + if ( Line_To( RAS_VARS x, y ) ) return FAILURE; + } + else + { + /* else, keep current control point for next bezier */ + cx = x; + cy = y; + } + } + else + { + /* the previous point was off the curve */ + on_curve = ( ras.flags[index] & 1 ); + if ( on_curve ) + { + /* reaching an `on' point */ + if ( Bezier_To( RAS_VARS x, y, cx, cy ) ) return FAILURE; + } + else + { + /* two successive `off' points => create middle point */ + mx = ( cx + x ) / 2; + my = ( cy + y ) / 2; + + if ( Bezier_To( RAS_VARS mx, my, cx, cy ) ) return FAILURE; + + cx = x; + cy = y; + } + } + } + + /* end of contour, close curve cleanly */ + if ( ras.flags[first] & 1 ) + { + if ( on_curve ) + return Line_To( RAS_VARS x_first, y_first ); + else + return Bezier_To( RAS_VARS x_first, y_first, cx, cy ); + } + else + if ( !on_curve ) + return Bezier_To( RAS_VARS x_last, y_last, cx, cy ); + + return SUCCESS; + } + + +/****************************************************************************/ +/* */ +/* Function: Convert_Glyph */ +/* */ +/* Description: Converts a glyph into a series of segments and arcs */ +/* and makes a Profiles list with them. */ +/* */ +/* Input: _xCoord, _yCoord : coordinates tables. */ +/* */ +/* Uses the 'Flag' table too. */ +/* */ +/* Returns: SUCCESS on success. */ +/* FAILURE if any error was encountered during rendering. */ +/* */ +/****************************************************************************/ + + static Bool Convert_Glyph( RAS_ARGS int flipped ) + { + Short i; + UShort start; + + PProfile lastProfile; + + + ras.fProfile = NULL; + ras.joint = FALSE; + ras.fresh = FALSE; + + ras.maxBuff = ras.sizeBuff - AlignProfileSize; + + ras.numTurns = 0; + + ras.cProfile = (PProfile)ras.top; + ras.cProfile->offset = ras.top; + ras.num_Profs = 0; + + start = 0; + + for ( i = 0; i < ras.nContours; i++ ) + { + ras.state = Unknown; + ras.gProfile = NULL; + + if ( Decompose_Curve( RAS_VARS start, ras.outs[i], flipped ) ) + return FAILURE; + + start = ras.outs[i] + 1; + + /* We must now see if the extreme arcs join or not */ + if ( ( FRAC( ras.lastY ) == 0 && + ras.lastY >= ras.minY && + ras.lastY <= ras.maxY ) ) + if ( ras.gProfile && ras.gProfile->flow == ras.cProfile->flow ) + ras.top--; + /* Note that ras.gProfile can be nil if the contour was too small */ + /* to be drawn. */ + + lastProfile = ras.cProfile; + if ( End_Profile( RAS_VAR ) ) return FAILURE; + + /* close the 'next profile in contour' linked list */ + if ( ras.gProfile ) + lastProfile->next = ras.gProfile; + } + + if (Finalize_Profile_Table( RAS_VAR )) + return FAILURE; + + return (ras.top < ras.maxBuff ? SUCCESS : FAILURE ); + } + + +/************************************************/ +/* */ +/* Init_Linked */ +/* */ +/* Inits an empty linked list. */ +/* */ +/************************************************/ + + static void Init_Linked( TProfileList* l ) + { + *l = NULL; + } + + +/************************************************/ +/* */ +/* InsNew : */ +/* */ +/* Inserts a new Profile in a linked list. */ +/* */ +/************************************************/ + + static void InsNew( PProfileList list, + PProfile profile ) + { + PProfile *old, current; + Long x; + + + old = list; + current = *old; + x = profile->X; + + while ( current ) + { + if ( x < current->X ) + break; + old = ¤t->link; + current = *old; + } + + profile->link = current; + *old = profile; + } + + +/*************************************************/ +/* */ +/* DelOld : */ +/* */ +/* Removes an old Profile from a linked list. */ +/* */ +/*************************************************/ + + static void DelOld( PProfileList list, + PProfile profile ) + { + PProfile *old, current; + + + old = list; + current = *old; + + while ( current ) + { + if ( current == profile ) + { + *old = current->link; + return; + } + + old = ¤t->link; + current = *old; + } + + /* we should never get there, unless the Profile was not part of */ + /* the list. */ + } + + +/************************************************/ +/* */ +/* Update : */ +/* */ +/* Update all X offsets of a drawing list */ +/* */ +/************************************************/ + + static void Update( PProfile first ) + { + PProfile current = first; + + + while ( current ) + { + current->X = *current->offset; + current->offset += current->flow; + current->height--; + current = current->link; + } + } + + +/************************************************/ +/* */ +/* Sort : */ +/* */ +/* Sorts a trace list. In 95%, the list */ +/* is already sorted. We need an algorithm */ +/* which is fast in this case. Bubble sort */ +/* is enough and simple. */ +/* */ +/************************************************/ + + static void Sort( PProfileList list ) + { + PProfile *old, current, next; + + + /* First, set the new X coordinate of each profile */ + Update( *list ); + + /* Then sort them */ + old = list; + current = *old; + + if ( !current ) + return; + + next = current->link; + + while ( next ) + { + if ( current->X <= next->X ) + { + old = ¤t->link; + current = *old; + + if ( !current ) + return; + } + else + { + *old = next; + current->link = next->link; + next->link = current; + + old = list; + current = *old; + } + + next = current->link; + } + } + + +/***********************************************************************/ +/* */ +/* Vertical Sweep Procedure Set : */ +/* */ +/* These three routines are used during the vertical black/white */ +/* sweep phase by the generic Draw_Sweep() function. */ +/* */ +/***********************************************************************/ + + static void Vertical_Sweep_Init( RAS_ARGS Short* min, Short* max ) + { + switch ( ras.target.flow ) + { + case TT_Flow_Up: + ras.traceOfs = *min * ras.target.cols; + ras.traceIncr = ras.target.cols; + break; + + default: + ras.traceOfs = ( ras.target.rows - 1 - *min ) * ras.target.cols; + ras.traceIncr = -ras.target.cols; + } + + ras.gray_min_x = 0; + ras.gray_max_x = 0; + } + + + static void Vertical_Sweep_Span( RAS_ARGS Short y, + TT_F26Dot6 x1, + TT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + Long e1, e2; + Short c1, c2; + Short f1, f2; + Byte* target; + + + /* Drop-out control */ + + e1 = TRUNC( CEILING( x1 ) ); + + if ( x2-x1-ras.precision <= ras.precision_jitter ) + e2 = e1; + else + e2 = TRUNC( FLOOR( x2 ) ); + + if ( e2 >= 0 && e1 < ras.bWidth ) + { + if ( e1 < 0 ) e1 = 0; + if ( e2 >= ras.bWidth ) e2 = ras.bWidth-1; + + c1 = (Short)(e1 >> 3); + c2 = (Short)(e2 >> 3); + + f1 = e1 & 7; + f2 = e2 & 7; + + if ( ras.gray_min_x > c1 ) ras.gray_min_x = c1; + if ( ras.gray_max_x < c2 ) ras.gray_max_x = c2; + + target = ras.bTarget + ras.traceOfs + c1; + + if ( c1 != c2 ) + { + *target |= LMask[f1]; + + if ( c2 > c1 + 1 ) + MEM_Set( target + 1, 0xFF, c2 - c1 - 1 ); + + target[c2 - c1] |= RMask[f2]; + } + else + *target |= ( LMask[f1] & RMask[f2] ); + } + } + + + static void Vertical_Sweep_Drop( RAS_ARGS Short y, + TT_F26Dot6 x1, + TT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + Long e1, e2; + Short c1, f1; + + + /* Drop-out control */ + + e1 = CEILING( x1 ); + e2 = FLOOR ( x2 ); + + if ( e1 > e2 ) + { + if ( e1 == e2 + ras.precision ) + { + switch ( ras.dropOutControl ) + { + case 1: + e1 = e2; + break; + + case 4: + e1 = CEILING( (x1 + x2 + 1) / 2 ); + break; + + case 2: + case 5: + /* Drop-out Control Rule #4 */ + + /* The spec is not very clear regarding rule #4. It */ + /* presents a method that is way too costly to implement */ + /* while the general idea seems to get rid of 'stubs'. */ + /* */ + /* Here, we only get rid of stubs recognized when: */ + /* */ + /* upper stub: */ + /* */ + /* - P_Left and P_Right are in the same contour */ + /* - P_Right is the successor of P_Left in that contour */ + /* - y is the top of P_Left and P_Right */ + /* */ + /* lower stub: */ + /* */ + /* - P_Left and P_Right are in the same contour */ + /* - P_Left is the successor of P_Right in that contour */ + /* - y is the bottom of P_Left */ + /* */ + + /* FIXXXME : uncommenting this line solves the disappearing */ + /* bit problem in the '7' of verdana 10pts, but */ + /* makes a new one in the 'C' of arial 14pts */ + + /* if ( x2-x1 < ras.precision_half ) */ + { + /* upper stub test */ + + if ( left->next == right && left->height <= 0 ) return; + + /* lower stub test */ + + if ( right->next == left && left->start == y ) return; + } + + /* check that the rightmost pixel isn't set */ + + e1 = TRUNC( e1 ); + + c1 = (Short)(e1 >> 3); + f1 = e1 & 7; + + if ( e1 >= 0 && e1 < ras.bWidth && + ras.bTarget[ras.traceOfs + c1] & (0x80 >> f1) ) + return; + + if ( ras.dropOutControl == 2 ) + e1 = e2; + else + e1 = CEILING( (x1 + x2 + 1) / 2 ); + + break; + + default: + return; /* unsupported mode */ + } + } + else + return; + } + + e1 = TRUNC( e1 ); + + if ( e1 >= 0 && e1 < ras.bWidth ) + { + c1 = (Short)(e1 >> 3); + f1 = e1 & 7; + + if ( ras.gray_min_x > c1 ) ras.gray_min_x = c1; + if ( ras.gray_max_x < c1 ) ras.gray_max_x = c1; + + ras.bTarget[ras.traceOfs + c1] |= (Char)(0x80 >> f1); + } + } + + + static void Vertical_Sweep_Step( RAS_ARG ) + { + ras.traceOfs += ras.traceIncr; + } + + +/***********************************************************************/ +/* */ +/* Horizontal Sweep Procedure Set : */ +/* */ +/* These three routines are used during the horizontal black/white */ +/* sweep phase by the generic Draw_Sweep() function. */ +/* */ +/***********************************************************************/ + + static void Horizontal_Sweep_Init( RAS_ARGS Short* min, Short* max ) + { + /* nothing, really */ + } + + + static void Horizontal_Sweep_Span( RAS_ARGS Short y, + TT_F26Dot6 x1, + TT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + Long e1, e2; + PByte bits; + Byte f1; + + + if ( x2-x1 < ras.precision ) + { + e1 = CEILING( x1 ); + e2 = FLOOR ( x2 ); + + if ( e1 == e2 ) + { + bits = ras.bTarget + (y >> 3); + f1 = (Byte)(0x80 >> (y & 7)); + + e1 = TRUNC( e1 ); + + if ( e1 >= 0 && e1 < ras.target.rows ) + { + if ( ras.target.flow == TT_Flow_Down ) + bits[(ras.target.rows-1 - e1) * ras.target.cols] |= f1; + else + bits[e1 * ras.target.cols] |= f1; + } + } + } +#if 0 + e2 = TRUNC( e2 ); + + if ( e2 >= 0 && e2 < ras.target.rows ) + if ( ras.target.flow == TT_Flow_Down ) + bits[(ras.target.rows-1-e2) * ras.target.cols] |= f1; + else + bits[e2 * ras.target.cols] |= f1; +#endif + } + + + static void Horizontal_Sweep_Drop( RAS_ARGS Short y, + TT_F26Dot6 x1, + TT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + Long e1, e2; + PByte bits; + Byte f1; + + + /* During the horizontal sweep, we only take care of drop-outs */ + + e1 = CEILING( x1 ); + e2 = FLOOR ( x2 ); + + if ( e1 > e2 ) + { + if ( e1 == e2 + ras.precision ) + { + switch ( ras.dropOutControl ) + { + case 1: + e1 = e2; + break; + + case 4: + e1 = CEILING( (x1 + x2 + 1) / 2 ); + break; + + case 2: + case 5: + + /* Drop-out Control Rule #4 */ + + /* The spec is not very clear regarding rule #4. It */ + /* presents a method that is way too costly to implement */ + /* while the general idea seems to get rid of 'stubs'. */ + /* */ + + /* rightmost stub test */ + + if ( left->next == right && left->height <= 0 ) return; + + /* leftmost stub test */ + + if ( right->next == left && left->start == y ) return; + + /* check that the rightmost pixel isn't set */ + + e1 = TRUNC( e1 ); + + bits = ras.bTarget + (y >> 3); + f1 = (Byte)(0x80 >> (y & 7)); + + if ( ras.target.flow == TT_Flow_Down ) + bits += (ras.target.rows-1-e1) * ras.target.cols; + else + bits += e1 * ras.target.cols; + + if ( e1 >= 0 && + e1 < ras.target.rows && + *bits & f1 ) + return; + + if ( ras.dropOutControl == 2 ) + e1 = e2; + else + e1 = CEILING( (x1 + x2 + 1) / 2 ); + + break; + + default: + return; /* unsupported mode */ + } + } + else + return; + } + + bits = ras.bTarget + (y >> 3); + f1 = (Byte)(0x80 >> (y & 7)); + + e1 = TRUNC( e1 ); + + if ( e1 >= 0 && e1 < ras.target.rows ) + { + if (ras.target.flow==TT_Flow_Down) + bits[(ras.target.rows-1-e1) * ras.target.cols] |= f1; + else + bits[e1 * ras.target.cols] |= f1; + } + } + + + static void Horizontal_Sweep_Step( RAS_ARG ) + { + /* Nothing, really */ + } + + +#ifdef TT_CONFIG_OPTION_GRAY_SCALING + +/***********************************************************************/ +/* */ +/* Vertical Gray Sweep Procedure Set: */ +/* */ +/* These two routines are used during the vertical gray-levels */ +/* sweep phase by the generic Draw_Sweep() function. */ +/* */ +/* */ +/* NOTES: */ +/* */ +/* - The target pixmap's width *must* be a multiple of 4. */ +/* */ +/* - you have to use the function Vertical_Sweep_Span() for */ +/* the gray span call. */ +/* */ +/***********************************************************************/ + + static void Vertical_Gray_Sweep_Init( RAS_ARGS Short* min, Short* max ) + { + *min = *min & -2; + *max = ( *max + 3 ) & -2; + + ras.traceOfs = 0; + + switch ( ras.target.flow ) + { + case TT_Flow_Up: + ras.traceG = (*min / 2) * ras.target.cols; + ras.traceIncr = ras.target.cols; + break; + + default: + ras.traceG = (ras.target.rows-1 - *min/2) * ras.target.cols; + ras.traceIncr = -ras.target.cols; + } + + ras.gray_min_x = ras.target.cols; + ras.gray_max_x = -ras.target.cols; + } + + + static void Vertical_Gray_Sweep_Step( RAS_ARG ) + { + Int c1, c2; + PByte pix, bit, bit2; + Int* count = ras.count_table; + Byte* grays; + + + ras.traceOfs += ras.gray_width; + + if ( ras.traceOfs > ras.gray_width ) + { + pix = ras.gTarget + ras.traceG + ras.gray_min_x * 4; + grays = ras.grays; + + if ( ras.gray_max_x >= 0 ) + { + if ( ras.gray_max_x >= ras.target.width ) + ras.gray_max_x = ras.target.width-1; + + if ( ras.gray_min_x < 0 ) + ras.gray_min_x = 0; + + bit = ras.bTarget + ras.gray_min_x; + bit2 = bit + ras.gray_width; + + c1 = ras.gray_max_x - ras.gray_min_x; + + while ( c1 >= 0 ) + { + c2 = count[*bit] + count[*bit2]; + + if ( c2 ) + { + pix[0] = grays[(c2 & 0xF000) >> 12]; + pix[1] = grays[(c2 & 0x0F00) >> 8]; + pix[2] = grays[(c2 & 0x00F0) >> 4]; + pix[3] = grays[(c2 & 0x000F) ]; + + *bit = 0; + *bit2 = 0; + } + + bit ++; + bit2++; + pix += 4; + c1 --; + } + } + + ras.traceOfs = 0; + ras.traceG += ras.traceIncr; + + ras.gray_min_x = ras.target.cols; + ras.gray_max_x = -ras.target.cols; + } + } + + + static void Horizontal_Gray_Sweep_Span( RAS_ARGS Short y, + TT_F26Dot6 x1, + TT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + /* nothing, really */ + } + + static void Horizontal_Gray_Sweep_Drop( RAS_ARGS Short y, + TT_F26Dot6 x1, + TT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + Long e1, e2; + PByte pixel; + Byte color; + + + /* During the horizontal sweep, we only take care of drop-outs */ + e1 = CEILING( x1 ); + e2 = FLOOR ( x2 ); + + if ( e1 > e2 ) + { + if ( e1 == e2 + ras.precision ) + { + switch ( ras.dropOutControl ) + { + case 1: + e1 = e2; + break; + + case 4: + e1 = CEILING( (x1 + x2 + 1) / 2 ); + break; + + case 2: + case 5: + + /* Drop-out Control Rule #4 */ + + /* The spec is not very clear regarding rule #4. It */ + /* presents a method that is way too costly to implement */ + /* while the general idea seems to get rid of 'stubs'. */ + /* */ + + /* rightmost stub test */ + if ( left->next == right && left->height <= 0 ) return; + + /* leftmost stub test */ + if ( right->next == left && left->start == y ) return; + + if ( ras.dropOutControl == 2 ) + e1 = e2; + else + e1 = CEILING( (x1 + x2 + 1) / 2 ); + + break; + + default: + return; /* unsupported mode */ + } + } + else + return; + } + + if ( e1 >= 0 ) + { + if ( x2 - x1 >= ras.precision_half ) + color = ras.grays[2]; + else + color = ras.grays[1]; + + e1 = TRUNC( e1 ) / 2; + if ( e1 < ras.target.rows ) + { + if ( ras.target.flow == TT_Flow_Down ) + pixel = ras.gTarget + + (ras.target.rows - 1 - e1) * ras.target.cols + y / 2; + else + pixel = ras.gTarget + + e1 * ras.target.cols + y / 2; + + if (pixel[0] == ras.grays[0]) + pixel[0] = color; + } + } + } + +#endif /* TT_CONFIG_OPTION_GRAY_SCALING */ + + +/********************************************************************/ +/* */ +/* Generic Sweep Drawing routine */ +/* */ +/********************************************************************/ + + static Bool Draw_Sweep( RAS_ARG ) + { + Short y, y_change, y_height; + + PProfile P, Q, P_Left, P_Right; + + Short min_Y, max_Y, top, bottom, dropouts; + + Long x1, x2, xs, e1, e2; + + TProfileList wait; + TProfileList draw_left, draw_right; + + + /* Init empty linked lists */ + + Init_Linked( &wait ); + + Init_Linked( &draw_left ); + Init_Linked( &draw_right ); + + /* first, compute min and max Y */ + + P = ras.fProfile; + max_Y = (short)TRUNC( ras.minY ); + min_Y = (short)TRUNC( ras.maxY ); + + while ( P ) + { + Q = P->link; + + bottom = P->start; + top = P->start + P->height-1; + + if ( min_Y > bottom ) min_Y = bottom; + if ( max_Y < top ) max_Y = top; + + P->X = 0; + InsNew( &wait, P ); + + P = Q; + } + + /* Check the Y-turns */ + if ( ras.numTurns == 0 ) + { + ras.error = Raster_Err_Invalid; + return FAILURE; + } + + /* Now inits the sweep */ + + ras.Proc_Sweep_Init( RAS_VARS &min_Y, &max_Y ); + + /* Then compute the distance of each profile from min_Y */ + + P = wait; + + while ( P ) + { + P->countL = P->start - min_Y; + P = P->link; + } + + /* Let's go */ + + y = min_Y; + y_height = 0; + + if ( ras.numTurns > 0 && + ras.sizeBuff[-ras.numTurns] == min_Y ) + ras.numTurns--; + + while ( ras.numTurns > 0 ) + { + /* look in the wait list for new activations */ + + P = wait; + + while ( P ) + { + Q = P->link; + P->countL -= y_height; + if ( P->countL == 0 ) + { + DelOld( &wait, P ); + + switch ( P->flow ) + { + case TT_Flow_Up: InsNew( &draw_left, P ); break; + case TT_Flow_Down: InsNew( &draw_right, P ); break; + } + } + + P = Q; + } + + /* Sort the drawing lists */ + + Sort( &draw_left ); + Sort( &draw_right ); + + y_change = (Short)ras.sizeBuff[-ras.numTurns--]; + y_height = y_change - y; + + while ( y < y_change ) + { + + /* Let's trace */ + + dropouts = 0; + + P_Left = draw_left; + P_Right = draw_right; + + while ( P_Left ) + { + x1 = P_Left ->X; + x2 = P_Right->X; + + if ( x1 > x2 ) + { + xs = x1; + x1 = x2; + x2 = xs; + } + + if ( x2-x1 <= ras.precision ) + { + e1 = FLOOR( x1 ); + e2 = CEILING( x2 ); + + if ( ras.dropOutControl != 0 && + (e1 > e2 || e2 == e1 + ras.precision) ) + { + /* a drop out was detected */ + + P_Left ->X = x1; + P_Right->X = x2; + + /* mark profile for drop-out processing */ + P_Left->countL = 1; + dropouts++; + + goto Skip_To_Next; + } + } + + ras.Proc_Sweep_Span( RAS_VARS y, x1, x2, P_Left, P_Right ); + + Skip_To_Next: + + P_Left = P_Left->link; + P_Right = P_Right->link; + } + + /* now perform the dropouts _after_ the span drawing */ + /* drop-outs processing has been moved out of the loop */ + /* for performance tuning */ + if (dropouts > 0) + goto Scan_DropOuts; + + Next_Line: + + ras.Proc_Sweep_Step( RAS_VAR ); + + y++; + + if ( y < y_change ) + { + Sort( &draw_left ); + Sort( &draw_right ); + } + + } + + /* Now finalize the profiles that needs it */ + + { + PProfile Q, P; + P = draw_left; + while ( P ) + { + Q = P->link; + if ( P->height == 0 ) + DelOld( &draw_left, P ); + P = Q; + } + } + + { + PProfile Q, P = draw_right; + while ( P ) + { + Q = P->link; + if ( P->height == 0 ) + DelOld( &draw_right, P ); + P = Q; + } + } + } + + /* for gray-scaling, flushes the bitmap scanline cache */ + while ( y <= max_Y ) + { + ras.Proc_Sweep_Step( RAS_VAR ); + y++; + } + + return SUCCESS; + +Scan_DropOuts : + + P_Left = draw_left; + P_Right = draw_right; + + while ( P_Left ) + { + if ( P_Left->countL ) + { + P_Left->countL = 0; + /* dropouts--; -- this is useful when debugging only */ + ras.Proc_Sweep_Drop( RAS_VARS y, + P_Left->X, + P_Right->X, + P_Left, + P_Right ); + } + + P_Left = P_Left->link; + P_Right = P_Right->link; + } + + goto Next_Line; + } + + +/****************************************************************************/ +/* */ +/* Function: Render_Single_Pass */ +/* */ +/* Description: Performs one sweep with sub-banding. */ +/* */ +/* Input: _XCoord, _YCoord : x and y coordinates arrays */ +/* */ +/* Returns: SUCCESS on success */ +/* FAILURE if any error was encountered during render. */ +/* */ +/****************************************************************************/ + + static TT_Error Render_Single_Pass( RAS_ARGS Bool flipped ) + { + Short i, j, k; + + + while ( ras.band_top >= 0 ) + { + ras.maxY = (Long)ras.band_stack[ras.band_top].y_max * ras.precision; + ras.minY = (Long)ras.band_stack[ras.band_top].y_min * ras.precision; + + ras.top = ras.buff; + + ras.error = Raster_Err_None; + + if ( Convert_Glyph( RAS_VARS flipped ) ) + { + if ( ras.error != Raster_Err_Overflow ) return FAILURE; + + ras.error = Raster_Err_None; + + /* sub-banding */ + +#ifdef DEBUG_RASTER + ClearBand( RAS_VARS TRUNC( ras.minY ), TRUNC( ras.maxY ) ); +#endif + + i = ras.band_stack[ras.band_top].y_min; + j = ras.band_stack[ras.band_top].y_max; + + k = ( i + j ) / 2; + + if ( ras.band_top >= 7 || k < i ) + { + ras.band_top = 0; + ras.error = Raster_Err_Invalid; + return ras.error; + } + + ras.band_stack[ras.band_top+1].y_min = k; + ras.band_stack[ras.band_top+1].y_max = j; + + ras.band_stack[ras.band_top].y_max = k - 1; + + ras.band_top++; + } + else + { + if ( ras.fProfile ) + if ( Draw_Sweep( RAS_VAR ) ) return ras.error; + ras.band_top--; + } + } + + return TT_Err_Ok; + } + + +/****************************************************************************/ +/* */ +/* Function: Render_Glyph */ +/* */ +/* Description: Renders a glyph in a bitmap. Sub-banding if needed. */ +/* */ +/* Input: AGlyph Glyph record */ +/* */ +/* Returns: SUCCESS on success. */ +/* FAILURE if any error was encountered during rendering. */ +/* */ +/****************************************************************************/ + + LOCAL_FUNC + TT_Error Render_Glyph( RAS_ARGS TT_Outline* glyph, + TT_Raster_Map* target_map ) + { + TT_Error error; + + + if ( glyph->n_points == 0 || glyph->n_contours <= 0 ) + return TT_Err_Ok; + + if ( !ras.buff ) + { + ras.error = Raster_Err_Not_Ini; + return ras.error; + } + + if ( glyph->n_points < glyph->contours[glyph->n_contours - 1] ) + { + ras.error = TT_Err_Too_Many_Points; + return ras.error; + } + + if ( target_map ) + ras.target = *target_map; + + ras.outs = glyph->contours; + ras.flags = glyph->flags; + ras.nPoints = glyph->n_points; + ras.nContours = glyph->n_contours; + ras.coords = glyph->points; + + Set_High_Precision( RAS_VARS glyph->high_precision ); + ras.scale_shift = ras.precision_shift; + ras.dropOutControl = glyph->dropout_mode; + ras.second_pass = glyph->second_pass; + + + /* Vertical Sweep */ + ras.Proc_Sweep_Init = Vertical_Sweep_Init; + ras.Proc_Sweep_Span = Vertical_Sweep_Span; + ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; + ras.Proc_Sweep_Step = Vertical_Sweep_Step; + + ras.band_top = 0; + ras.band_stack[0].y_min = 0; + ras.band_stack[0].y_max = ras.target.rows - 1; + + ras.bWidth = ras.target.width; + ras.bTarget = (Byte*)ras.target.bitmap; + + if ( (error = Render_Single_Pass( RAS_VARS 0 )) != 0 ) + return error; + + /* Horizontal Sweep */ + + if ( ras.second_pass && ras.dropOutControl != 0 ) + { + ras.Proc_Sweep_Init = Horizontal_Sweep_Init; + ras.Proc_Sweep_Span = Horizontal_Sweep_Span; + ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop; + ras.Proc_Sweep_Step = Horizontal_Sweep_Step; + + ras.band_top = 0; + ras.band_stack[0].y_min = 0; + ras.band_stack[0].y_max = ras.target.width - 1; + + if ( (error = Render_Single_Pass( RAS_VARS 1 )) != 0 ) + return error; + } + + return TT_Err_Ok; + } + + +#ifdef TT_CONFIG_OPTION_GRAY_SCALING + +/****************************************************************************/ +/* */ +/* Function: Render_Gray_Glyph */ +/* */ +/* Description: Renders a glyph with grayscaling. Sub-banding if needed. */ +/* */ +/* Input: AGlyph Glyph record */ +/* */ +/* Returns: SUCCESS on success */ +/* FAILURE if any error was encountered during rendering. */ +/* */ +/****************************************************************************/ + + LOCAL_FUNC + TT_Error Render_Gray_Glyph( RAS_ARGS TT_Outline* glyph, + TT_Raster_Map* target_map, + Byte* palette ) + { + Int i; + TT_Error error; + + if ( !ras.buff ) + { + ras.error = Raster_Err_Not_Ini; + return ras.error; + } + + if ( glyph->n_points == 0 || glyph->n_contours <= 0 ) + return TT_Err_Ok; + + if ( glyph->n_points < glyph->contours[glyph->n_contours - 1] ) + { + ras.error = TT_Err_Too_Many_Points; + return ras.error; + } + + if ( palette ) + { + for ( i = 0; i < 5; i++ ) + ras.grays[i] = palette[i]; + } + + if ( target_map ) + ras.target = *target_map; + + ras.outs = glyph->contours; + ras.flags = glyph->flags; + ras.nPoints = glyph->n_points; + ras.nContours = glyph->n_contours; + ras.coords = glyph->points; + + Set_High_Precision( RAS_VARS glyph->high_precision ); + ras.scale_shift = ras.precision_shift+1; + ras.dropOutControl = glyph->dropout_mode; + ras.second_pass = glyph->second_pass; + + + /* Vertical Sweep */ + + ras.band_top = 0; + ras.band_stack[0].y_min = 0; + ras.band_stack[0].y_max = 2 * ras.target.rows - 1; + + ras.bWidth = ras.gray_width; + if ( ras.bWidth > ras.target.cols/4 ) + ras.bWidth = ras.target.cols/4; + + ras.bWidth = ras.bWidth * 8; + ras.bTarget = (Byte*)ras.gray_lines; + ras.gTarget = (Byte*)ras.target.bitmap; + + ras.Proc_Sweep_Init = Vertical_Gray_Sweep_Init; + ras.Proc_Sweep_Span = Vertical_Sweep_Span; + ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; + ras.Proc_Sweep_Step = Vertical_Gray_Sweep_Step; + + error = Render_Single_Pass( RAS_VARS 0 ); + if (error) + return error; + + /* Horizontal Sweep */ + + if ( ras.second_pass && ras.dropOutControl != 0 ) + { + ras.Proc_Sweep_Init = Horizontal_Sweep_Init; + ras.Proc_Sweep_Span = Horizontal_Gray_Sweep_Span; + ras.Proc_Sweep_Drop = Horizontal_Gray_Sweep_Drop; + ras.Proc_Sweep_Step = Horizontal_Sweep_Step; + + ras.band_top = 0; + ras.band_stack[0].y_min = 0; + ras.band_stack[0].y_max = ras.target.width * 2 - 1; + + error = Render_Single_Pass( RAS_VARS 1 ); + if (error) + return error; + } + + return TT_Err_Ok; + } + +#endif /* TT_CONFIG_OPTION_GRAY_SCALING */ + + +/************************************************/ +/* */ +/* InitRasterizer */ +/* */ +/* Raster Initialization. */ +/* Gets the bitmap description and render pool */ +/* addresses. */ +/* */ +/************************************************/ + +#undef ras + + LOCAL_FUNC + TT_Error TTRaster_Done( PEngine_Instance engine ) + { + TRaster_Instance* ras = (TRaster_Instance*)engine->raster_component; + + + if ( !ras ) + return TT_Err_Ok; + + FREE( ras->buff ); + FREE( ras->gray_lines ); + +#ifndef TT_CONFIG_OPTION_STATIC_RASTER + FREE( engine->raster_component ); +#endif + + return TT_Err_Ok; + } + + + LOCAL_FUNC + TT_Error TTRaster_Init( PEngine_Instance engine ) + { + TT_Error error; + + Int i, l, j, c; + + TRaster_Instance* ras; + + +#ifdef TT_CONFIG_OPTION_STATIC_RASTER + ras = engine->raster_component = &cur_ras; +#else + if ( ALLOC( engine->raster_component, sizeof ( TRaster_Instance ) ) ) + return error; + + ras = (TRaster_Instance*)engine->raster_component; +#endif + + if ( ALLOC( ras->buff, RASTER_RENDER_POOL ) || + ALLOC( ras->gray_lines, RASTER_GRAY_LINES ) ) + return error; + + ras->sizeBuff = ras->buff + ( RASTER_RENDER_POOL/sizeof(long) ); + ras->gray_width = RASTER_GRAY_LINES/2; + + /* Initialization of Count_Table */ + + for ( i = 0; i < 256; i++ ) + { + l = 0; + j = i; + + for ( c = 0; c < 4; c++ ) + { + l <<= 4; + + if ( j & 0x80 ) l++; + if ( j & 0x40 ) l++; + + j = ( j << 2 ) & 0xFF; + } + + ras->count_table[i] = l; + } + + ras->dropOutControl = 2; + ras->error = Raster_Err_None; + + return TT_Err_Ok; + } + + +/* END */ diff --git a/lib/ttraster.h b/lib/ttraster.h new file mode 100644 index 0000000..66c8fef --- /dev/null +++ b/lib/ttraster.h @@ -0,0 +1,127 @@ +/******************************************************************* + * + * ttraster.h v 1.4 + * + * The FreeType glyph rasterizer. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTES: + * + * This version supports the following: + * + * - direct grayscaling + * - sub-banding + * - drop-out modes 4 and 5 + * - second pass for complete drop-out control (bitmap only) + * - variable precision + * + * + * Changes between 1.4 and 1.3: + * + * Mainly performance tunings: + * + * - Line_Down() and Bezier_Down() now use the functions Line_Up() + * and Bezier_Up() to do their work. + * - optimized Split_Bezier() + * - optimized linked lists used during sweeps + * + * Changes between 1.2 and 1.3: + * + * - made the engine optionaly re-entrant. Saves a lot + * of code for a moderate performance hit. + * + ******************************************************************/ + +#ifndef TTRASTER_H +#define TTRASTER_H + +#include "ttconfig.h" +#include "freetype.h" /* for TT_Outline */ +#include "ttengine.h" + +#ifdef __cplusplus +extern "C" { +#endif + + /* We provide two different builds of the scan-line converter */ + /* The static build uses global variables and isn't */ + /* re-entrant. */ + /* The indirect build is re-entrant but accesses all variables */ + /* indirectly. */ + /* */ + /* As a consequence, the indirect build is about 10% slower */ + /* than the static one on a _Pentium_ (this could get worse */ + /* on older processors), but the code size is reduced by */ + /* more than 30% ! */ + /* */ + /* The indirect build is now the default, defined in */ + /* ttconfig.h. Be careful if you experiment with this. */ + + /* Note also that, though its code can be re-entrant, the */ + /* component is always used in thread-safe mode. This is */ + /* simply due to the fact that we want to use a single */ + /* render pool (of 64 Kb), and not to waste memory. */ + +#ifdef TT_STATIC_RASTER + +#define RAS_ARGS /* void */ +#define RAS_ARG /* void */ + +#define RAS_VARS /* void */ +#define RAS_VAR /* void */ + +#else + +#define RAS_ARGS TRaster_Instance* raster, +#define RAS_ARG TRaster_Instance* raster + +#define RAS_VARS raster, +#define RAS_VAR raster + +#endif + + + struct TRaster_Instance_; + typedef struct TRaster_Instance_ TRaster_Instance; + + /* Render one glyph in the target bitmap, using drop-out control */ + /* mode 'scan'. */ + LOCAL_DEF + TT_Error Render_Glyph( RAS_ARGS TT_Outline* glyph, + TT_Raster_Map* target ); + +#ifdef TT_CONFIG_OPTION_GRAY_SCALING + /* Render one gray-level glyph in the target pixmap. */ + /* Palette points to an array of 5 colors used for the rendering. */ + /* Use NULL to reuse the last palette. Default is VGA graylevels. */ + LOCAL_DEF + TT_Error Render_Gray_Glyph( RAS_ARGS TT_Outline* glyph, + TT_Raster_Map* target, + Byte* palette ); +#endif + + /* Initialize rasterizer */ + LOCAL_DEF + TT_Error TTRaster_Init( PEngine_Instance engine ); + + /* Finalize it */ + LOCAL_DEF + TT_Error TTRaster_Done( PEngine_Instance engine ); + + +#ifdef __cplusplus +} +#endif + +#endif /* TTRASTER_H */ + + +/* END */ diff --git a/lib/tttables.h b/lib/tttables.h new file mode 100644 index 0000000..e3556fc --- /dev/null +++ b/lib/tttables.h @@ -0,0 +1,215 @@ +/******************************************************************* + * + * tttables.h 1.1 + * + * TrueType Tables structures and handling (specification). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef TTTABLES_H +#define TTTABLES_H + +#include "ttconfig.h" +#include "tttypes.h" + +#ifdef __cplusplus + extern "C" { +#endif + + /***********************************************************************/ + /* */ + /* TrueType Table Types */ + /* */ + /***********************************************************************/ + + /* TrueType Collection Header */ + + struct TTTCHeader_ + { + ULong Tag; + TT_Fixed version; + ULong DirCount; + PULong TableDirectory; + }; + + typedef struct TTTCHeader_ TTTCHeader; + typedef TTTCHeader* PTTCHeader; + + + /* TrueType Table Directory type */ + + struct TTableDir_ + { + TT_Fixed version; /* should be 0x10000 */ + UShort numTables; /* number of tables */ + + UShort searchRange; /* These parameters are only used */ + UShort entrySelector; /* for a dichotomy search in the */ + UShort rangeShift; /* directory. We ignore them. */ + }; + + typedef struct TTableDir_ TTableDir; + typedef TTableDir* PTableDir; + + + /* The 'TableDir' is followed by 'numTables' TableDirEntries */ + + struct TTableDirEntry_ + { + ULong Tag; /* table type */ + ULong CheckSum; /* table checksum */ + ULong Offset; /* table file offset */ + ULong Length; /* table length */ + }; + + typedef struct TTableDirEntry_ TTableDirEntry; + typedef TTableDirEntry* PTableDirEntry; + + + /* 'cmap' tables */ + + struct TCMapDir_ + { + UShort tableVersionNumber; + UShort numCMaps; + }; + + typedef struct TCMapDir_ TCMapDir; + typedef TCMapDir* PCMapDir; + + struct TCMapDirEntry_ + { + UShort platformID; + UShort platformEncodingID; + Long offset; + }; + + typedef struct TCMapDirEntry_ TCMapDirEntry; + typedef TCMapDirEntry* PCMapDirEntries; + + + /* 'maxp' Maximum Profiles table */ + + struct TMaxProfile_ + { + TT_Fixed version; + UShort numGlyphs, + maxPoints, + maxContours, + maxCompositePoints, + maxCompositeContours, + maxZones, + maxTwilightPoints, + maxStorage, + maxFunctionDefs, + maxInstructionDefs, + maxStackElements, + maxSizeOfInstructions, + maxComponentElements, + maxComponentDepth; + }; + + typedef struct TMaxProfile_ TMaxProfile; + typedef TMaxProfile* PMaxProfile; + + + /* table "gasp" */ + +#define GASP_GRIDFIT 0x01 +#define GASP_DOGRAY 0x02 + + struct GaspRange_ + { + UShort maxPPEM; + UShort gaspFlag; + }; + + typedef struct GaspRange_ GaspRange; + + + struct TGasp_ + { + UShort version; + UShort numRanges; + GaspRange* gaspRanges; + }; + + typedef struct TGasp_ TGasp; + + + /* table "head" - now defined in freetype.h */ + /* table "hhea" - now defined in freetype.h */ + + + /* tables "HMTX" and "VMTX" */ + + struct TLongMetrics_ + { + UShort advance; + Short bearing; + }; + + typedef struct TLongMetrics_ TLongMetrics, *PLongMetrics; + + typedef Short TShortMetrics, *PShortMetrics; + + /* 'loca' location table type */ + + struct TLoca_ + { + UShort Size; + PStorage Table; + }; + + typedef struct TLoca_ TLoca; + + + /* table "name" */ + + struct TNameRec_ + { + UShort platformID; + UShort encodingID; + UShort languageID; + UShort nameID; + UShort stringLength; + UShort stringOffset; + + /* this last field is not defined in the spec */ + /* but used by the FreeType engine */ + + PByte string; + }; + + typedef struct TNameRec_ TNameRec; + + + struct TName_Table_ + { + UShort format; + UShort numNameRecords; + UShort storageOffset; + TNameRec* names; + PByte storage; + }; + + typedef struct TName_Table_ TName_Table; + + +#ifdef __cplusplus + } +#endif + +#endif /* TTTABLES_H */ + + +/* END */ diff --git a/lib/tttags.h b/lib/tttags.h new file mode 100644 index 0000000..95347d1 --- /dev/null +++ b/lib/tttags.h @@ -0,0 +1,61 @@ +/******************************************************************* + * + * tttags.h + * + * tags for TrueType tables (specification only). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef TTAGS_H +#define TTAGS_H + +#include "ttconfig.h" +#include "freetype.h" /* for MAKE_TT_TAG() */ + +#define TTAG_BASE MAKE_TT_TAG( 'B', 'A', 'S', 'E' ) +#define TTAG_bloc MAKE_TT_TAG( 'b', 'l', 'o', 'c' ) +#define TTAG_bdat MAKE_TT_TAG( 'b', 'd', 'a', 't' ) +#define TTAG_cmap MAKE_TT_TAG( 'c', 'm', 'a', 'p' ) +#define TTAG_cvt MAKE_TT_TAG( 'c', 'v', 't', ' ' ) +#define TTAG_EBDT MAKE_TT_TAG( 'E', 'B', 'D', 'T' ) +#define TTAG_EBLC MAKE_TT_TAG( 'E', 'B', 'L', 'C' ) +#define TTAG_EBSC MAKE_TT_TAG( 'E', 'B', 'S', 'C' ) +#define TTAG_fpgm MAKE_TT_TAG( 'f', 'p', 'g', 'm' ) +#define TTAG_gasp MAKE_TT_TAG( 'g', 'a', 's', 'p' ) +#define TTAG_glyf MAKE_TT_TAG( 'g', 'l', 'y', 'f' ) +#define TTAG_GDEF MAKE_TT_TAG( 'G', 'D', 'E', 'F' ) +#define TTAG_GPOS MAKE_TT_TAG( 'G', 'P', 'O', 'S' ) +#define TTAG_GSUB MAKE_TT_TAG( 'G', 'S', 'U', 'B' ) +#define TTAG_hdmx MAKE_TT_TAG( 'h', 'd', 'm', 'x' ) +#define TTAG_head MAKE_TT_TAG( 'h', 'e', 'a', 'd' ) +#define TTAG_hhea MAKE_TT_TAG( 'h', 'h', 'e', 'a' ) +#define TTAG_hmtx MAKE_TT_TAG( 'h', 'm', 't', 'x' ) +#define TTAG_JSTF MAKE_TT_TAG( 'J', 'S', 'T', 'F' ) +#define TTAG_kern MAKE_TT_TAG( 'k', 'e', 'r', 'n' ) +#define TTAG_loca MAKE_TT_TAG( 'l', 'o', 'c', 'a' ) +#define TTAG_LTSH MAKE_TT_TAG( 'L', 'T', 'S', 'H' ) +#define TTAG_maxp MAKE_TT_TAG( 'm', 'a', 'x', 'p' ) +#define TTAG_name MAKE_TT_TAG( 'n', 'a', 'm', 'e' ) +#define TTAG_OS2 MAKE_TT_TAG( 'O', 'S', '/', '2' ) +#define TTAG_PCLT MAKE_TT_TAG( 'P', 'C', 'L', 'T' ) +#define TTAG_post MAKE_TT_TAG( 'p', 'o', 's', 't' ) +#define TTAG_prep MAKE_TT_TAG( 'p', 'r', 'e', 'p' ) +#define TTAG_ttc MAKE_TT_TAG( 't', 't', 'c', ' ' ) +#define TTAG_ttcf MAKE_TT_TAG( 't', 't', 'c', 'f' ) +#define TTAG_VDMX MAKE_TT_TAG( 'V', 'D', 'M', 'X' ) +#define TTAG_vhea MAKE_TT_TAG( 'v', 'h', 'e', 'a' ) +#define TTAG_vmtx MAKE_TT_TAG( 'v', 'm', 't', 'x' ) + +#endif /* TTAGS_H */ + + +/* END */ diff --git a/lib/tttypes.h b/lib/tttypes.h new file mode 100644 index 0000000..b324013 --- /dev/null +++ b/lib/tttypes.h @@ -0,0 +1,150 @@ +/******************************************************************* + * + * tttypes.h + * + * Freetype engine's common types specification + * (this spec has no associated body). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTE: + * + * All these declarations are library internals, and *not* part + * of the high-level interface. See also 'freetype.h'. + * + ******************************************************************/ + +#ifndef TTTYPES_H +#define TTTYPES_H + +#include "ttconfig.h" +#include "freetype.h" + +#ifdef __MACTYPES__ +#error " have been included, and this prevents the proper\ + compilation of this library. Please remove the precompiled headers." +#endif + + typedef char String; + typedef signed char Char; + typedef unsigned char Byte; + + typedef unsigned short UShort; + typedef signed short Short; + + typedef unsigned long ULong; + typedef signed long Long; + + typedef TT_Int32 Fixed; + + typedef int Int; + + /* Simple access types: pointers and tables */ + + typedef Byte* PByte; + typedef UShort* PUShort; + typedef Short* PShort; + typedef ULong* PULong; + typedef Long* PLong; + + typedef Fixed* PFixed; + + typedef Int* PInt; + + typedef void* Pointer; + + typedef TT_F26Dot6* PCoordinates; + typedef unsigned char* PTouchTable; + + +#ifndef Bool + typedef int Bool; /* No boolean type in C */ +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef NULL +#define NULL (void*)0 +#endif + + typedef Long Storage; + typedef Storage* PStorage; + + +/* Rounding mode constants */ + +#define TT_Round_Off 5 +#define TT_Round_To_Half_Grid 0 +#define TT_Round_To_Grid 1 +#define TT_Round_To_Double_Grid 2 +#define TT_Round_Up_To_Grid 4 +#define TT_Round_Down_To_Grid 3 +#define TT_Round_Super 6 +#define TT_Round_Super_45 7 + + +/* Touch flag masks */ + +#define TT_Flag_On_Curve 1 +#define TT_Flag_Touched_X 2 +#define TT_Flag_Touched_Y 4 +#define TT_Flag_Touched_Both 6 + + +/* Error management constants :) */ + +#define SUCCESS 0 +#define FAILURE -1 + + +/* The min and max functions missing in C. As usual, be careful not to */ +/* write things like MIN( a++, b++ ) to avoid side effects. */ + +#ifndef MIN +#define MIN( a, b ) ( (a) < (b) ? (a) : (b) ) +#endif + +#ifndef MAX +#define MAX( a, b ) ( (a) > (b) ? (a) : (b) ) +#endif + +#ifndef ABS +#define ABS( a ) ( (a) < 0 ? -(a) : (a) ) +#endif + +/* conversion macros for the handles defined in freetype.h */ + +#define HANDLE_Val( handle ) ((handle).z) + +#define HANDLE_Engine( handle ) ((PEngine_Instance)HANDLE_Val( handle )) + +#define HANDLE_Face( handle ) ((PFace)HANDLE_Val( handle )) + +#define HANDLE_Instance( handle ) ((PInstance)HANDLE_Val( handle )) + +/* HANDLE_Stream( handle ) must be defined in ttfile.c */ + +#define HANDLE_Glyph( handle ) ((PGlyph)HANDLE_Val( handle )) + +#define HANDLE_CharMap( handle ) ((PCMapTable)HANDLE_Val( handle )) + +#define HANDLE_Set( handle, val ) ((handle).z = (void*)(val)) + + +#endif /* TTTYPES_H */ + + +/* END */ diff --git a/license.txt b/license.txt new file mode 100644 index 0000000..8dae609 --- /dev/null +++ b/license.txt @@ -0,0 +1,158 @@ + The FreeType Project LICENSE + ---------------------------- + + Copyright 1996-1999 by + David Turner, Robert Wilhelm, and Werner Lemberg + + + +Introduction +============ + + The FreeType Project is distributed in several archive packages; + some of them may contain, in addition to the FreeType font engine, + various tools and contributions which rely on, or relate to, the + FreeType Project. + + This license applies to all files found in such packages, and + which do not fall under their own explicit license. The license + affects thus the FreeType font engine, the test programs, + documentation and makefiles, at the very least. + + This license was inspired by the BSD, Artistic, and IJG + (Independent JPEG Group) licenses, which all encourage inclusion + and use of free software in commercial and freeware products + alike. As a consequence, its main points are that: + + o We don't promise that this software works. However, we are be + interested in any kind of bug reports. (`as is' distribution) + + o You can use this software for whatever you want, in parts or + full form, without having to pay us. (`royalty-free' usage) + + o You may not pretend that you wrote this software. If you use + it, or only parts of it, in a program, you must acknowledge + somewhere in your documentation that you've used the FreeType + code. (`credits') + + We specifically permit and encourage the inclusion of this + software, with or without modifications, in commercial products, + provided that all warranty or liability claims are assumed by the + product vendor. + + +Legal Terms +=========== + +0. Definitions +-------------- + + Throughout this license, the terms `package', `FreeType Project', + and `FreeType archive' refer to the set of files originally + distributed by the authors (David Turner, Robert Wilhelm, and + Werner Lemberg) as the `FreeType project', be they named as alpha, + beta or final release. + + `You' refers to the licensee, or person using the project, where + `using' is a generic term including compiling the project's source + code as well as linking it to form a `program' or `executable'. + This program is referred to as `a program using the FreeType + engine'. + + This license applies to all files distributed in the original + FreeType archive, including all source code, binaries and + documentation, unless otherwise stated in the file in its + original, unmodified form as distributed in the original archive. + If you are unsure whether or not a particular file is covered by + this license, you must contact us to verify this. + + The FreeType project is copyright (C) 1996-1999 by David Turner, + Robert Wilhelm, and Werner Lemberg. All rights reserved except as + specified below. + +1. No Warranty +-------------- + + THE FREETYPE ARCHIVE IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO + USE, OF THE FREETYPE PROJECT. + + As you have not signed this license, you are not required to + accept it. However, as the FreeType project is copyrighted + material, only this license, or another one contracted with the + authors, grants you the right to use, distribute, and modify it. + Therefore, by using, distributing, or modifying the FreeType + project, you indicate that you understand and accept all the terms + of this license. + +2. Redistribution +----------------- + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + o Redistribution of source code must retain this license file + (`licence.txt') unaltered; any additions, deletions or changes + to the original files must be clearly indicated in + accompanying documentation. The copyright notices of the + unaltered, original files must be preserved in all copies of + source files. + + o Redistribution in binary form must provide a disclaimer that + states that the software is based in part of the work of the + FreeType Team, in the distribution documentation. We also + encourage you to put an URL to the FreeType web page in your + documentation, though this isn't mandatory. + + These conditions apply to any software derived from or based on + the FreeType code, not just the unmodified files. If you use our + work, you must acknowledge us. However, no fee need be paid to + us. + +3. Advertising +-------------- + + The names of FreeType's authors and contributors may not be used + to endorse or promote products derived from this software without + specific prior written permission. + + We suggest, but do not require, that you use one or more of the + following phrases to refer to this software in your documentation + or advertising materials: `FreeType Project', `FreeType Engine', + `FreeType library', or `FreeType Distribution'. + +4. Contacts +----------- + + There are two mailing lists related to FreeType: + + o freetype@freetype.org + + Discusses general use and applications of FreeType, as well as + future and wanted additions to the library and distribution. + If you are looking for support, start in this list if you + haven't found anything to help you in the documentation. + + o devel@freetype.org + + Discusses bugs, as well as engine internals, design issues, + specific licenses, porting, etc. + + o http://www.freetype.org + + Holds the current FreeType web page, which will allow you to + download our latest development version and read online + documentation. + + You can also contact us individually at: + + David Turner + Robert Wilhelm + Werner Lemberg + + +--- end of license.txt --- diff --git a/ltconfig b/ltconfig new file mode 100644 index 0000000..71ef065 --- /dev/null +++ b/ltconfig @@ -0,0 +1,3017 @@ +#! /bin/sh + +# ltconfig - Create a system-specific libtool. +# Copyright (C) 1996-1999 Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A lot of this script is taken from autoconf-2.10. + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} +echo=echo +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec "$SHELL" "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null`} + case X$UNAME in + *-DOS) PATH_SEPARATOR=';' ;; + *) PATH_SEPARATOR=':' ;; + esac +fi + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi + +if test "X${echo_test_string+set}" != "Xset"; then + # find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if (echo_test_string="`eval $cmd`") 2>/dev/null && + echo_test_string="`eval $cmd`" && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null; then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" != 'X\t' || + test "X`($echo "$echo_test_string") 2>/dev/null`" != X"$echo_test_string"; then + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + for dir in $PATH /usr/ucb; do + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + test "X`($dir/echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + test "X`(print -r "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running ltconfig again with it. + ORIGINAL_CONFIG_SHELL="${CONFIG_SHELL-/bin/sh}" + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" --no-reexec ${1+"$@"} + else + # Try using printf. + echo='printf "%s\n"' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + test "X`($echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then + # Cool, printf works + : + elif test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' && + test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then + CONFIG_SHELL="$ORIGINAL_CONFIG_SHELL" + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL $0 --fallback-echo" + elif test "X`("$CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' && + test "X`("$CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then + echo="$CONFIG_SHELL $0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null; then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "$0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec "${ORIGINAL_CONFIG_SHELL}" "$0" ${1+"$@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e s/^X//' +sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# The name of this program. +progname=`$echo "X$0" | $Xsed -e 's%^.*/%%'` + +# Constants: +PROGRAM=ltconfig +PACKAGE=libtool +VERSION=1.3.3 +TIMESTAMP=" (1.385.2.181 1999/07/02 15:49:11)" +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.c 1>&5' +ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.c $LIBS 1>&5' +rm="rm -f" + +help="Try \`$progname --help' for more information." + +# Global variables: +default_ofile=libtool +can_build_shared=yes +enable_shared=yes +# All known linkers require a `.a' archive for static linking (except M$VC, +# which needs '.lib'). +enable_static=yes +enable_fast_install=yes +enable_dlopen=unknown +enable_win32_dll=no +ltmain= +silent= +srcdir= +ac_config_guess= +ac_config_sub= +host= +nonopt= +ofile="$default_ofile" +verify_host=yes +with_gcc=no +with_gnu_ld=no +need_locks=yes +ac_ext=c +objext=o +libext=a +exeext= +cache_file= + +old_AR="$AR" +old_CC="$CC" +old_CFLAGS="$CFLAGS" +old_CPPFLAGS="$CPPFLAGS" +old_LDFLAGS="$LDFLAGS" +old_LD="$LD" +old_LN_S="$LN_S" +old_LIBS="$LIBS" +old_NM="$NM" +old_RANLIB="$RANLIB" +old_DLLTOOL="$DLLTOOL" +old_OBJDUMP="$OBJDUMP" +old_AS="$AS" + +# Parse the command line options. +args= +prev= +for option +do + case "$option" in + -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + eval "$prev=\$option" + prev= + continue + fi + + case "$option" in + --help) cat <&2 + echo "$help" 1>&2 + exit 1 + ;; + + *) + if test -z "$ltmain"; then + ltmain="$option" + elif test -z "$host"; then +# This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1 +# if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then +# echo "$progname: warning \`$option' is not a valid host type" 1>&2 +# fi + host="$option" + else + echo "$progname: too many arguments" 1>&2 + echo "$help" 1>&2 + exit 1 + fi ;; + esac +done + +if test -z "$ltmain"; then + echo "$progname: you must specify a LTMAIN file" 1>&2 + echo "$help" 1>&2 + exit 1 +fi + +if test ! -f "$ltmain"; then + echo "$progname: \`$ltmain' does not exist" 1>&2 + echo "$help" 1>&2 + exit 1 +fi + +# Quote any args containing shell metacharacters. +ltconfig_args= +for arg +do + case "$arg" in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ltconfig_args="$ltconfig_args '$arg'" ;; + *) ltconfig_args="$ltconfig_args $arg" ;; + esac +done + +# A relevant subset of AC_INIT. + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 5 compiler messages saved in config.log +# 6 checking for... messages and results +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>>./config.log + +# NLS nuisances. +# Only set LANG and LC_ALL to C if already set. +# These must not be set unconditionally because not all systems understand +# e.g. LANG=C (notably SCO). +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LANG+set}" = set; then LANG=C; export LANG; fi + +if test -n "$cache_file" && test -r "$cache_file"; then + echo "loading cache $cache_file within ltconfig" + . $cache_file +fi + +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + +if test -z "$srcdir"; then + # Assume the source directory is the same one as the path to LTMAIN. + srcdir=`$echo "X$ltmain" | $Xsed -e 's%/[^/]*$%%'` + test "$srcdir" = "$ltmain" && srcdir=. +fi + +trap "$rm conftest*; exit 1" 1 2 15 +if test "$verify_host" = yes; then + # Check for config.guess and config.sub. + ac_aux_dir= + for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/config.guess; then + ac_aux_dir=$ac_dir + break + fi + done + if test -z "$ac_aux_dir"; then + echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2 + echo "$help" 1>&2 + exit 1 + fi + ac_config_guess=$ac_aux_dir/config.guess + ac_config_sub=$ac_aux_dir/config.sub + + # Make sure we can run config.sub. + if $SHELL $ac_config_sub sun4 >/dev/null 2>&1; then : + else + echo "$progname: cannot run $ac_config_sub" 1>&2 + echo "$help" 1>&2 + exit 1 + fi + + echo $ac_n "checking host system type""... $ac_c" 1>&6 + + host_alias=$host + case "$host_alias" in + "") + if host_alias=`$SHELL $ac_config_guess`; then : + else + echo "$progname: cannot guess host type; you must specify one" 1>&2 + echo "$help" 1>&2 + exit 1 + fi ;; + esac + host=`$SHELL $ac_config_sub $host_alias` + echo "$ac_t$host" 1>&6 + + # Make sure the host verified. + test -z "$host" && exit 1 + +elif test -z "$host"; then + echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2 + echo "$help" 1>&2 + exit 1 +else + host_alias=$host +fi + +# Transform linux* to *-*-linux-gnu*, to support old configure scripts. +case "$host_os" in +linux-gnu*) ;; +linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'` +esac + +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + +case "$host_os" in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "${COLLECT_NAMES+set}" != set; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR cru $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +# Set a sane default for `AR'. +test -z "$AR" && AR=ar + +# Set a sane default for `OBJDUMP'. +test -z "$OBJDUMP" && OBJDUMP=objdump + +# If RANLIB is not set, then run the test. +if test "${RANLIB+set}" != "set"; then + result=no + + echo $ac_n "checking for ranlib... $ac_c" 1>&6 + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + for dir in $PATH; do + test -z "$dir" && dir=. + if test -f $dir/ranlib || test -f $dir/ranlib$ac_exeext; then + RANLIB="ranlib" + result="ranlib" + break + fi + done + IFS="$save_ifs" + + echo "$ac_t$result" 1>&6 +fi + +if test -n "$RANLIB"; then + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" + old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" +fi + +# Set sane defaults for `DLLTOOL', `OBJDUMP', and `AS', used on cygwin. +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$AS" && AS=as + +# Check to see if we are using GCC. +if test "$with_gcc" != yes || test -z "$CC"; then + # If CC is not set, then try to find GCC or a usable CC. + if test -z "$CC"; then + echo $ac_n "checking for gcc... $ac_c" 1>&6 + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + for dir in $PATH; do + test -z "$dir" && dir=. + if test -f $dir/gcc || test -f $dir/gcc$ac_exeext; then + CC="gcc" + break + fi + done + IFS="$save_ifs" + + if test -n "$CC"; then + echo "$ac_t$CC" 1>&6 + else + echo "$ac_t"no 1>&6 + fi + fi + + # Not "gcc", so try "cc", rejecting "/usr/ucb/cc". + if test -z "$CC"; then + echo $ac_n "checking for cc... $ac_c" 1>&6 + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + cc_rejected=no + for dir in $PATH; do + test -z "$dir" && dir=. + if test -f $dir/cc || test -f $dir/cc$ac_exeext; then + if test "$dir/cc" = "/usr/ucb/cc"; then + cc_rejected=yes + continue + fi + CC="cc" + break + fi + done + IFS="$save_ifs" + if test $cc_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same name, so the bogon will be chosen + # first if we set CC to just the name; use the full file name. + shift + set dummy "$dir/cc" "$@" + shift + CC="$@" + fi + fi + + if test -n "$CC"; then + echo "$ac_t$CC" 1>&6 + else + echo "$ac_t"no 1>&6 + fi + + if test -z "$CC"; then + echo "$progname: error: no acceptable cc found in \$PATH" 1>&2 + exit 1 + fi + fi + + # Now see if the compiler is really GCC. + with_gcc=no + echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6 + echo "$progname:581: checking whether we are using GNU C" >&5 + + $rm conftest.c + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + with_gcc=yes + fi + $rm conftest.c + echo "$ac_t$with_gcc" 1>&6 +fi + +# Allow CC to be a program name with arguments. +set dummy $CC +compiler="$2" + +echo $ac_n "checking for object suffix... $ac_c" 1>&6 +$rm conftest* +echo 'int i = 1;' > conftest.c +echo "$progname:603: checking for object suffix" >& 5 +if { (eval echo $progname:604: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; }; then + # Append any warnings to the config.log. + cat conftest.err 1>&5 + + for ac_file in conftest.*; do + case $ac_file in + *.c) ;; + *) objext=`echo $ac_file | sed -e s/conftest.//` ;; + esac + done +else + cat conftest.err 1>&5 + echo "$progname: failed program was:" >&5 + cat conftest.c >&5 +fi +$rm conftest* +echo "$ac_t$objext" 1>&6 + +echo $ac_n "checking for executable suffix... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_exeext="no" + $rm conftest* + echo 'main () { return 0; }' > conftest.c + echo "$progname:629: checking for executable suffix" >& 5 + if { (eval echo $progname:630: \"$ac_link\") 1>&5; (eval $ac_link) 2>conftest.err; }; then + # Append any warnings to the config.log. + cat conftest.err 1>&5 + + for ac_file in conftest.*; do + case $ac_file in + *.c | *.err | *.$objext ) ;; + *) ac_cv_exeext=.`echo $ac_file | sed -e s/conftest.//` ;; + esac + done + else + cat conftest.err 1>&5 + echo "$progname: failed program was:" >&5 + cat conftest.c >&5 + fi + $rm conftest* +fi +if test "X$ac_cv_exeext" = Xno; then + exeext="" +else + exeext="$ac_cv_exeext" +fi +echo "$ac_t$ac_cv_exeext" 1>&6 + +echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6 +pic_flag= +special_shlib_compile_flags= +wl= +link_static_flag= +no_builtin_flag= + +if test "$with_gcc" = yes; then + wl='-Wl,' + link_static_flag='-static' + + case "$host_os" in + beos* | irix5* | irix6* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + aix*) + # Below there is a dirty hack to force normal static linking with -ldl + # The problem is because libdl dynamically linked with both libc and + # libC (AIX C++ library), which obviously doesn't included in libraries + # list by gcc. This cause undefined symbols with -static flags. + # This hack allows C programs to be linked with "-static -ldl", but + # we not sure about C++ programs. + link_static_flag="$link_static_flag ${wl}-lC" + ;; + cygwin* | mingw* | os2*) + # We can build DLLs from non-PIC. + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + pic_flag='-m68020 -resident32 -malways-restore-a4' + ;; + sysv4*MP*) + if test -d /usr/nec; then + pic_flag=-Kconform_pic + fi + ;; + *) + pic_flag='-fPIC' + ;; + esac +else + # PORTME Check for PIC flags for the system compiler. + case "$host_os" in + aix3* | aix4*) + # All AIX code is PIC. + link_static_flag='-bnso -bI:/lib/syscalls.exp' + ;; + + hpux9* | hpux10* | hpux11*) + # Is there a better link_static_flag that works with the bundled CC? + wl='-Wl,' + link_static_flag="${wl}-a ${wl}archive" + pic_flag='+Z' + ;; + + irix5* | irix6*) + wl='-Wl,' + link_static_flag='-non_shared' + # PIC (with -KPIC) is the default. + ;; + + cygwin* | mingw* | os2*) + # We can build DLLs from non-PIC. + ;; + + osf3* | osf4* | osf5*) + # All OSF/1 code is PIC. + wl='-Wl,' + link_static_flag='-non_shared' + ;; + + sco3.2v5*) + pic_flag='-Kpic' + link_static_flag='-dn' + special_shlib_compile_flags='-belf' + ;; + + solaris*) + pic_flag='-KPIC' + link_static_flag='-Bstatic' + wl='-Wl,' + ;; + + sunos4*) + pic_flag='-PIC' + link_static_flag='-Bstatic' + wl='-Qoption ld ' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + pic_flag='-KPIC' + link_static_flag='-Bstatic' + wl='-Wl,' + ;; + + uts4*) + pic_flag='-pic' + link_static_flag='-Bstatic' + ;; + sysv4*MP*) + if test -d /usr/nec ;then + pic_flag='-Kconform_pic' + link_static_flag='-Bstatic' + fi + ;; + *) + can_build_shared=no + ;; + esac +fi + +if test -n "$pic_flag"; then + echo "$ac_t$pic_flag" 1>&6 + + # Check to make sure the pic_flag actually works. + echo $ac_n "checking if $compiler PIC flag $pic_flag works... $ac_c" 1>&6 + $rm conftest* + echo "int some_variable = 0;" > conftest.c + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $pic_flag -DPIC" + echo "$progname:776: checking if $compiler PIC flag $pic_flag works" >&5 + if { (eval echo $progname:777: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.$objext; then + # Append any warnings to the config.log. + cat conftest.err 1>&5 + + case "$host_os" in + hpux9* | hpux10* | hpux11*) + # On HP-UX, both CC and GCC only warn that PIC is supported... then they + # create non-PIC objects. So, if there were any warnings, we assume that + # PIC is not supported. + if test -s conftest.err; then + echo "$ac_t"no 1>&6 + can_build_shared=no + pic_flag= + else + echo "$ac_t"yes 1>&6 + pic_flag=" $pic_flag" + fi + ;; + *) + echo "$ac_t"yes 1>&6 + pic_flag=" $pic_flag" + ;; + esac + else + # Append any errors to the config.log. + cat conftest.err 1>&5 + can_build_shared=no + pic_flag= + echo "$ac_t"no 1>&6 + fi + CFLAGS="$save_CFLAGS" + $rm conftest* +else + echo "$ac_t"none 1>&6 +fi + +# Check to see if options -o and -c are simultaneously supported by compiler +echo $ac_n "checking if $compiler supports -c -o file.o... $ac_c" 1>&6 +$rm -r conftest 2>/dev/null +mkdir conftest +cd conftest +$rm conftest* +echo "int some_variable = 0;" > conftest.c +mkdir out +# According to Tom Tromey, Ian Lance Taylor reported there are C compilers +# that will create temporary files in the current directory regardless of +# the output directory. Thus, making CWD read-only will cause this test +# to fail, enabling locking or at least warning the user not to do parallel +# builds. +chmod -w . +save_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -o out/conftest2.o" +echo "$progname:829: checking if $compiler supports -c -o file.o" >&5 +if { (eval echo $progname:830: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.o; then + + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s out/conftest.err; then + echo "$ac_t"no 1>&6 + compiler_c_o=no + else + echo "$ac_t"yes 1>&6 + compiler_c_o=yes + fi +else + # Append any errors to the config.log. + cat out/conftest.err 1>&5 + compiler_c_o=no + echo "$ac_t"no 1>&6 +fi +CFLAGS="$save_CFLAGS" +chmod u+w . +$rm conftest* out/* +rmdir out +cd .. +rmdir conftest +$rm -r conftest 2>/dev/null + +if test x"$compiler_c_o" = x"yes"; then + # Check to see if we can write to a .lo + echo $ac_n "checking if $compiler supports -c -o file.lo... $ac_c" 1>&6 + $rm conftest* + echo "int some_variable = 0;" > conftest.c + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -c -o conftest.lo" + echo "$progname:862: checking if $compiler supports -c -o file.lo" >&5 +if { (eval echo $progname:863: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.lo; then + + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + echo "$ac_t"no 1>&6 + compiler_o_lo=no + else + echo "$ac_t"yes 1>&6 + compiler_o_lo=yes + fi + else + # Append any errors to the config.log. + cat conftest.err 1>&5 + compiler_o_lo=no + echo "$ac_t"no 1>&6 + fi + CFLAGS="$save_CFLAGS" + $rm conftest* +else + compiler_o_lo=no +fi + +# Check to see if we can do hard links to lock some files if needed +hard_links="nottested" +if test "$compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + echo $ac_n "checking if we can lock with hard links... $ac_c" 1>&6 + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + echo "$ac_t$hard_links" 1>&6 + $rm conftest* + if test "$hard_links" = no; then + echo "*** WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2 + need_locks=warn + fi +else + need_locks=no +fi + +if test "$with_gcc" = yes; then + # Check to see if options -fno-rtti -fno-exceptions are supported by compiler + echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions ... $ac_c" 1>&6 + $rm conftest* + echo "int some_variable = 0;" > conftest.c + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.c" + echo "$progname:914: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 + if { (eval echo $progname:915: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.o; then + + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + echo "$ac_t"no 1>&6 + compiler_rtti_exceptions=no + else + echo "$ac_t"yes 1>&6 + compiler_rtti_exceptions=yes + fi + else + # Append any errors to the config.log. + cat conftest.err 1>&5 + compiler_rtti_exceptions=no + echo "$ac_t"no 1>&6 + fi + CFLAGS="$save_CFLAGS" + $rm conftest* + + if test "$compiler_rtti_exceptions" = "yes"; then + no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions' + else + no_builtin_flag=' -fno-builtin' + fi + +fi + +# Check for any special shared library compilation flags. +if test -n "$special_shlib_compile_flags"; then + echo "$progname: warning: \`$CC' requires \`$special_shlib_compile_flags' to build shared libraries" 1>&2 + if echo "$old_CC $old_CFLAGS " | egrep -e "[ ]$special_shlib_compile_flags[ ]" >/dev/null; then : + else + echo "$progname: add \`$special_shlib_compile_flags' to the CC or CFLAGS env variable and reconfigure" 1>&2 + can_build_shared=no + fi +fi + +echo $ac_n "checking if $compiler static flag $link_static_flag works... $ac_c" 1>&6 +$rm conftest* +echo 'main(){return(0);}' > conftest.c +save_LDFLAGS="$LDFLAGS" +LDFLAGS="$LDFLAGS $link_static_flag" +echo "$progname:958: checking if $compiler static flag $link_static_flag works" >&5 +if { (eval echo $progname:959: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + echo "$ac_t$link_static_flag" 1>&6 +else + echo "$ac_t"none 1>&6 + link_static_flag= +fi +LDFLAGS="$save_LDFLAGS" +$rm conftest* + +if test -z "$LN_S"; then + # Check to see if we can use ln -s, or we need hard links. + echo $ac_n "checking whether ln -s works... $ac_c" 1>&6 + $rm conftest.dat + if ln -s X conftest.dat 2>/dev/null; then + $rm conftest.dat + LN_S="ln -s" + else + LN_S=ln + fi + if test "$LN_S" = "ln -s"; then + echo "$ac_t"yes 1>&6 + else + echo "$ac_t"no 1>&6 + fi +fi + +# Make sure LD is an absolute path. +if test -z "$LD"; then + ac_prog=ld + if test "$with_gcc" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo $ac_n "checking for ld used by GCC... $ac_c" 1>&6 + echo "$progname:991: checking for ld used by GCC" >&5 + ac_prog=`($CC -print-prog-name=ld) 2>&5` + case "$ac_prog" in + # Accept absolute paths. + [\\/]* | [A-Za-z]:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we are not using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac + elif test "$with_gnu_ld" = yes; then + echo $ac_n "checking for GNU ld... $ac_c" 1>&6 + echo "$progname:1015: checking for GNU ld" >&5 + else + echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 + echo "$progname:1018: checking for non-GNU ld" >&5 + fi + + if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" + fi + + if test -n "$LD"; then + echo "$ac_t$LD" 1>&6 + else + echo "$ac_t"no 1>&6 + fi + + if test -z "$LD"; then + echo "$progname: error: no acceptable ld found in \$PATH" 1>&2 + exit 1 + fi +fi + +# Check to see if it really is or is not GNU ld. +echo $ac_n "checking if the linker ($LD) is GNU ld... $ac_c" 1>&6 +# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + with_gnu_ld=yes +else + with_gnu_ld=no +fi +echo "$ac_t$with_gnu_ld" 1>&6 + +# See if the linker supports building shared libraries. +echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6 + +allow_undefined_flag= +no_undefined_flag= +need_lib_prefix=unknown +need_version=unknown +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +archive_cmds= +archive_expsym_cmds= +old_archive_from_new_cmds= +export_dynamic_flag_spec= +whole_archive_flag_spec= +thread_safe_flag_spec= +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no +hardcode_shlibpath_var=unsupported +runpath_var= +always_export_symbols=no +export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols' +# include_expsyms should be a list of space-separated symbols to be *always* +# included in the symbol list +include_expsyms= +# exclude_expsyms can be an egrep regular expression of symbols to exclude +# it will be wrapped by ` (' and `)$', so one must not match beginning or +# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', +# as well as any symbol that contains `d'. +exclude_expsyms="_GLOBAL_OFFSET_TABLE_" +# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out +# platforms (ab)use it in PIC code, but their linkers get confused if +# the symbol is explicitly referenced. Since portable code cannot +# rely on this symbol name, it's probably fine to never include it in +# preloaded symbol tables. + +case "$host_os" in +cygwin* | mingw*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$with_gcc" != yes; then + with_gnu_ld=no + fi + ;; + +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # See if GNU ld supports shared libraries. + case "$host_os" in + aix3* | aix4*) + # On AIX, the GNU linker is very broken + ld_shlibs=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + ;; + + amigaos*) + archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can use + # them. + ld_shlibs=no + ;; + + beos*) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + allow_undefined_flag=unsupported + always_export_symbols=yes + + # Extract the symbol export list from an `--export-all' def file, + # then regenerate the def file from the symbol export list, so that + # the compiled dll only exports the symbol export list. + export_symbols_cmds='test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~ + test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~ + $DLLTOOL --export-all --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --output-def $objdir/$soname-def $objdir/$soname-ltdll.$objext $libobjs $convenience~ + sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]* ; *//" < $objdir/$soname-def > $export_symbols' + + archive_expsym_cmds='echo EXPORTS > $objdir/$soname-def~ + _lt_hint=1; + for symbol in `cat $export_symbols`; do + echo " \$symbol @ \$_lt_hint ; " >> $objdir/$soname-def; + _lt_hint=`expr 1 + \$_lt_hint`; + done~ + test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~ + test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~ + $CC -Wl,--base-file,$objdir/$soname-base -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~ + $CC -Wl,--base-file,$objdir/$soname-base $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~ + $CC $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts' + + old_archive_from_new_cmds='$DLLTOOL --as=$AS --dllname $soname --def $objdir/$soname-def --output-lib $objdir/$libname.a' + ;; + + netbsd*) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + archive_cmds='$LD -Bshareable $libobjs $deplibs $linkopts -o $lib' + # can we support soname and/or expsyms with a.out? -oliva + fi + ;; + + solaris*) + if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linkopts' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = yes; then + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + case $host_os in + cygwin* | mingw*) + # dlltool doesn't understand --whole-archive et. al. + whole_archive_flag_spec= + ;; + *) + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + ;; + esac + fi +else + # PORTME fill in a description of your system's linker (not GNU ld) + case "$host_os" in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $objdir/$soname $libobjs $deplibs $linkopts -bE:$export_symbols -T512 -H512 -bM:SRE~$AR cru $lib $objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$with_gcc" = yes && test -z "$link_static_flag"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix4*) + hardcode_libdir_flag_spec='${wl}-b ${wl}nolibpath ${wl}-b ${wl}libpath:$libdir:/usr/lib:/lib' + hardcode_libdir_separator=':' + if test "$with_gcc" = yes; then + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct=yes + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + shared_flag='-shared' + else + shared_flag='${wl}-bM:SRE' + hardcode_direct=yes + fi + allow_undefined_flag=' ${wl}-berok' + archive_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bexpall ${wl}-bnoentry${allow_undefined_flag}' + archive_expsym_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}' + case "$host_os" in aix4.[01]|aix4.[01].*) + # According to Greg Wooledge, -bexpall is only supported from AIX 4.2 on + always_export_symbols=yes ;; + esac + ;; + + amigaos*) + archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + + cygwin* | mingw*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $linkopts `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib /OUT:$oldlib$oldobjs' + fix_srcfile_path='`cygpath -w $srcfile`' + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $linkopts' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9* | hpux10* | hpux11*) + case "$host_os" in + hpux9*) archive_cmds='$rm $objdir/$soname~$LD -b +b $install_libdir -o $objdir/$soname $libobjs $deplibs $linkopts~test $objdir/$soname = $lib || mv $objdir/$soname $lib' ;; + *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linkopts' ;; + esac + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_minus_L=yes # Not in the search PATH, but as the default + # location of the library. + export_dynamic_flag_spec='${wl}-E' + ;; + + irix5* | irix6*) + if test "$with_gcc" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + else + archive_cmds='$LD -shared $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linkopts' # ELF + fi + hardcode_libdir_flag_spec='${wl}-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + openbsd*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $objdir/$libname.def~$echo DATA >> $objdir/$libname.def~$echo " SINGLE NONSHARED" >> $objdir/$libname.def~$echo EXPORTS >> $objdir/$libname.def~emxexp $libobjs >> $objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $linkopts $objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $objdir/$libname.a $objdir/$libname.def' + ;; + + osf3* | osf4* | osf5*) + if test "$with_gcc" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + sco3.2v5*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ;; + + solaris*) + no_undefined_flag=' -z text' + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case "$host_os" in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linkopts' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + # archive_cmds='$LD -G -z text -h $soname -o $lib$libobjs$deplibs' + archive_cmds='$LD -G -h $soname -o $lib$libobjs$deplibs' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + *) + ld_shlibs=no + ;; + esac +fi +echo "$ac_t$ld_shlibs" 1>&6 +test "$ld_shlibs" = no && can_build_shared=no + +if test -z "$NM"; then + echo $ac_n "checking for BSD-compatible nm... $ac_c" 1>&6 + case "$NM" in + [\\/]* | [A-Za-z]:[\\/]*) ;; # Let the user override the test with a path. + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + for ac_dir in $PATH /usr/ucb /usr/ccs/bin /bin; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + NM="$ac_dir/nm -B" + break + elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + NM="$ac_dir/nm -p" + break + else + NM=${NM="$ac_dir/nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$NM" && NM=nm + ;; + esac + echo "$ac_t$NM" 1>&6 +fi + +# Check for command to grab the raw symbol name followed by C symbol from nm. +echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6 + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Transform the above into a raw symbol and a C symbol. +symxfrm='\1 \2\3 \3' + +# Transform an extracted symbol line into a proper C declaration +global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'" + +# Define system-specific variables. +case "$host_os" in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw*) + symcode='[ABCDGISTW]' + ;; +hpux*) # Its linker distinguishes data from code symbols + global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'" + ;; +irix*) + symcode='[BCDEGRST]' + ;; +solaris*) + symcode='[BDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then + symcode='[ABCDGISTW]' +fi + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Write the raw and C identifiers. + global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode\)[ ][ ]*\($ac_symprfx\)$sympat$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + $rm conftest* + cat > conftest.c <&5 + if { (eval echo $progname:1593: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.$objext; then + # Now try to grab the symbols. + nlist=conftest.nm + if { echo "$progname:1596: eval \"$NM conftest.$objext | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.$objext | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then + + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if egrep ' nm_test_var$' "$nlist" >/dev/null; then + if egrep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.c +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$global_symbol_to_cdecl"' < "$nlist" >> conftest.c' + + cat <> conftest.c +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[] = +{ +EOF + sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$nlist" >> conftest.c + cat <<\EOF >> conftest.c + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$objext conftstm.$objext + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="conftstm.$objext" + CFLAGS="$CFLAGS$no_builtin_flag" + if { (eval echo $progname:1648: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + pipe_works=yes + else + echo "$progname: failed program was:" >&5 + cat conftest.c >&5 + fi + LIBS="$save_LIBS" + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.c >&5 + fi + $rm conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + global_symbol_pipe= + fi +done +if test "$pipe_works" = yes; then + echo "${ac_t}ok" 1>&6 +else + echo "${ac_t}failed" 1>&6 +fi + +if test -z "$global_symbol_pipe"; then + global_symbol_to_cdecl= +fi + +# Check hardcoding attributes. +echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6 +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || \ + test -n "$runpath_var"; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$hardcode_shlibpath_var" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +echo "$ac_t$hardcode_action" 1>&6 + + +reload_flag= +reload_cmds='$LD$reload_flag -o $output$reload_objs' +echo $ac_n "checking for $LD option to reload object files... $ac_c" 1>&6 +# PORTME Some linkers may need a different reload flag. +reload_flag='-r' +echo "$ac_t$reload_flag" 1>&6 +test -n "$reload_flag" && reload_flag=" $reload_flag" + +# PORTME Fill in your ld.so characteristics +library_names_spec= +libname_spec='lib$name' +soname_spec= +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +file_magic_cmd= +file_magic_test_file= +deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [regex]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given egrep regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. +echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6 +case "$host_os" in +aix3*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}.so$major' + ;; + +aix4*) + version_type=linux + # AIX has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + # We preserve .a as extension for shared libraries though AIX4.2 + # and later linker supports .so + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.a' + shlibpath_var=LIBPATH + deplibs_check_method=pass_all + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}.so' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + deplibs_check_method=pass_all + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + +bsdi4*) + version_type=linux + library_names_spec='${libname}.so$major ${libname}.so' + soname_spec='${libname}.so' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + file_magic_cmd=/usr/bin/file + file_magic_test_file=/shlib/libc.so + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw*) + version_type=windows + need_version=no + need_lib_prefix=no + if test "$with_gcc" = yes; then + library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.a' + else + library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib' + fi + dynamic_linker='Win32 ld.exe' + deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + file_magic_cmd='${OBJDUMP} -f' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd*) + objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + version_type=freebsd-$objformat + case "$version_type" in + freebsd-elf*) + deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object' + file_magic_cmd=/usr/bin/file + file_magic_test_file=`echo /usr/lib/libc.so*` + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + deplibs_check_method=unknown + library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix' + need_version=yes + ;; + esac + finish_cmds='PATH="\$PATH:/sbin" OBJFORMAT="'"$objformat"'" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + case "$host_os" in + freebsd2* | freebsd3.[01]*) + shlibpath_overrides_runpath=yes + ;; + *) # from 3.2 on + shlibpath_overrides_runpath=no + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + dynamic_linker="$host_os dld.sl" + version_type=sunos + need_lib_prefix=no + need_version=no + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl' + soname_spec='${libname}${release}.sl$major' + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +irix5* | irix6*) + version_type=irix + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}.so.$major' + library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major ${libname}${release}.so $libname.so' + case "$host_os" in + irix5*) + libsuff= shlibsuff= + # this will be overridden with pass_all, but let us keep it just in case + deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" + ;; + *) + case "$LD" in # libtool.m4 will add one of these switches to LD + *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + # this will be overridden with pass_all, but let us keep it just in case + deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1" + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + file_magic_cmd=/usr/bin/file + file_magic_test_file=`echo /lib${libsuff}/libc.so*` + deplibs_check_method='pass_all' + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux-gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + file_magic_cmd=/usr/bin/file + file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` + + if test -f /lib/ld.so.1; then + dynamic_linker='GNU ld.so' + else + # Only the GNU ld.so supports shared libraries on MkLinux. + case "$host_cpu" in + powerpc*) dynamic_linker=no ;; + *) dynamic_linker='Linux ld.so' ;; + esac + fi + ;; + +netbsd*) + version_type=sunos + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so' + soname_spec='${libname}${release}.so$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + ;; + +openbsd*) + version_type=sunos + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + need_version=no + fi + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + ;; + +os2*) + libname_spec='$name' + need_lib_prefix=no + library_names_spec='$libname.dll $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_version=no + soname_spec='${libname}${release}.so' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + shlibpath_var=LD_LIBRARY_PATH + # this will be overridden with pass_all, but let us keep it just in case + deplibs_check_method='file_magic COFF format alpha shared library' + file_magic_cmd=/usr/bin/file + file_magic_test_file=/shlib/libc.so + deplibs_check_method='pass_all' + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +sco3.2v5*) + version_type=osf + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + deplibs_check_method="file_magic ELF [0-9][0-9]-bit [LM]SB dynamic lib" + file_magic_cmd=/usr/bin/file + file_magic_test_file=/lib/libc.so + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + case "$host_vendor" in + ncr) + deplibs_check_method='pass_all' + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + file_magic_cmd=/usr/bin/file + file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + esac + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so' + soname_spec='$libname.so.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +*) + dynamic_linker=no + ;; +esac +echo "$ac_t$dynamic_linker" 1>&6 +test "$dynamic_linker" = no && can_build_shared=no + +# Report the final consequences. +echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6 + +# Only try to build win32 dlls if AC_LIBTOOL_WIN32_DLL was used in +# configure.in, otherwise build static only libraries. +case "$host_os" in +cygwin* | mingw* | os2*) + if test x$can_build_shared = xyes; then + test x$enable_win32_dll = xno && can_build_shared=no + echo "checking if package supports dlls... $can_build_shared" 1>&6 + fi +;; +esac + +if test -n "$file_magic_test_file" && test -n "$file_magic_cmd"; then + case "$deplibs_check_method" in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac +fi + +echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6 +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case "$host_os" in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4*) + test "$enable_shared" = yes && enable_static=no + ;; +esac + +echo "$ac_t$enable_shared" 1>&6 + +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes + +echo "checking whether to build static libraries... $enable_static" 1>&6 + +if test "$hardcode_action" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + +echo $ac_n "checking for objdir... $ac_c" 1>&6 +rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + objdir=_libs +fi +rmdir .libs 2>/dev/null +echo "$ac_t$objdir" 1>&6 + +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else +if eval "test \"`echo '$''{'lt_cv_dlopen'+set}'`\" != set"; then + lt_cv_dlopen=no lt_cv_dlopen_libs= +echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 +echo "$progname:2170: checking for dlopen in -ldl" >&5 +ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for dlopen""... $ac_c" 1>&6 +echo "$progname:2207: checking for dlopen" >&5 +if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_dlopen) || defined (__stub___dlopen) +choke me +#else +dlopen(); +#endif + +; return 0; } +EOF +if { (eval echo $progname:2234: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_dlopen=yes" +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_dlopen=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="dlopen" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6 +echo "$progname:2251: checking for dld_link in -ldld" >&5 +ac_lib_var=`echo dld'_'dld_link | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldld $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for shl_load""... $ac_c" 1>&6 +echo "$progname:2288: checking for shl_load" >&5 +if eval "test \"`echo '$''{'ac_cv_func_shl_load'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shl_load(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_shl_load) || defined (__stub___shl_load) +choke me +#else +shl_load(); +#endif + +; return 0; } +EOF +if { (eval echo $progname:2315: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_shl_load=yes" +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_shl_load=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'shl_load`\" = yes"; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="shl_load" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6 +echo "$progname:2333: checking for shl_load in -ldld" >&5 +ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldld $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + echo "$ac_t""no" 1>&6 +fi + + +fi + + +fi + + +fi + + +fi + +fi + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + fi + + case "$lt_cv_dlopen" in + dlopen) +for ac_hdr in dlfcn.h; do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "$progname:2395: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +int fnord = 0; +EOF +ac_try="$ac_compile conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo $progname:2405: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi +done + + if test "x$ac_cv_header_dlfcn_h" = xyes; then + CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + fi + eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + LIBS="$lt_cv_dlopen_libs $LIBS" + + echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6 +echo "$progname:2433: checking whether a program can dlopen itself" >&5 +if test "${lt_cv_dlopen_self+set}" = set; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + lt_cv_dlopen_self=cross + else + cat > conftest.c < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LTDL_GLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LTDL_GLOBAL DL_GLOBAL +# else +# define LTDL_GLOBAL 0 +# endif +#endif + +/* We may have to define LTDL_LAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LTDL_LAZY_OR_NOW +# ifdef RTLD_LAZY +# define LTDL_LAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LTDL_LAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LTDL_LAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LTDL_LAZY_OR_NOW DL_NOW +# else +# define LTDL_LAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +fnord() { int i=42;} +main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW); + if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord"); + if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } + +EOF +if { (eval echo $progname:2487: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + lt_cv_dlopen_self=yes +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + lt_cv_dlopen_self=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$lt_cv_dlopen_self" 1>&6 + + if test "$lt_cv_dlopen_self" = yes; then + LDFLAGS="$LDFLAGS $link_static_flag" + echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6 +echo "$progname:2506: checking whether a statically linked program can dlopen itself" >&5 +if test "${lt_cv_dlopen_self_static+set}" = set; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + lt_cv_dlopen_self_static=cross + else + cat > conftest.c < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LTDL_GLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LTDL_GLOBAL DL_GLOBAL +# else +# define LTDL_GLOBAL 0 +# endif +#endif + +/* We may have to define LTDL_LAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LTDL_LAZY_OR_NOW +# ifdef RTLD_LAZY +# define LTDL_LAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LTDL_LAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LTDL_LAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LTDL_LAZY_OR_NOW DL_NOW +# else +# define LTDL_LAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +fnord() { int i=42;} +main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW); + if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord"); + if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } + +EOF +if { (eval echo $progname:2560: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + lt_cv_dlopen_self_static=yes +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + lt_cv_dlopen_self_static=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$lt_cv_dlopen_self_static" 1>&6 +fi + ;; + esac + + case "$lt_cv_dlopen_self" in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case "$lt_cv_dlopen_self_static" in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + +# Copy echo and quote the copy, instead of the original, because it is +# used later. +ltecho="$echo" +if test "X$ltecho" = "X$CONFIG_SHELL $0 --fallback-echo"; then + ltecho="$CONFIG_SHELL \$0 --fallback-echo" +fi +LTSHELL="$SHELL" + +LTCONFIG_VERSION="$VERSION" + +# Only quote variables if we're using ltmain.sh. +case "$ltmain" in +*.sh) + # Now quote all the things that may contain metacharacters. + for var in ltecho old_CC old_CFLAGS old_CPPFLAGS \ + old_LD old_LDFLAGS old_LIBS \ + old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS \ + AR CC LD LN_S NM LTSHELL LTCONFIG_VERSION \ + reload_flag reload_cmds wl \ + pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \ + thread_safe_flag_spec whole_archive_flag_spec libname_spec \ + library_names_spec soname_spec \ + RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \ + old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds postuninstall_cmds \ + file_magic_cmd export_symbols_cmds deplibs_check_method allow_undefined_flag no_undefined_flag \ + finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \ + hardcode_libdir_flag_spec hardcode_libdir_separator \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do + + case "$var" in + reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + export_symbols_cmds | archive_cmds | archive_expsym_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case "$ltecho" in + *'\$0 --fallback-echo"') + ltecho=`$echo "X$ltecho" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + + trap "$rm \"$ofile\"; exit 1" 1 2 15 + echo "creating $ofile" + $rm "$ofile" + cat < "$ofile" +#! $SHELL + +# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh. +# +# Copyright (C) 1996-1999 Free Software Foundation, Inc. +# Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="sed -e s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "\${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi + +### BEGIN LIBTOOL CONFIG +EOF + cfgfile="$ofile" + ;; + +*) + # Double-quote the variables that need it (for aesthetics). + for var in old_CC old_CFLAGS old_CPPFLAGS \ + old_LD old_LDFLAGS old_LIBS \ + old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS; do + eval "$var=\\\"\$var\\\"" + done + + # Just create a config file. + cfgfile="$ofile.cfg" + trap "$rm \"$cfgfile\"; exit 1" 1 2 15 + echo "creating $cfgfile" + $rm "$cfgfile" + cat < "$cfgfile" +# `$echo "$cfgfile" | sed 's%^.*/%%'` - Libtool configuration file. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +EOF + ;; +esac + +cat <> "$cfgfile" +# Libtool was configured as follows, on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# CC=$old_CC CFLAGS=$old_CFLAGS CPPFLAGS=$old_CPPFLAGS \\ +# LD=$old_LD LDFLAGS=$old_LDFLAGS LIBS=$old_LIBS \\ +# NM=$old_NM RANLIB=$old_RANLIB LN_S=$old_LN_S \\ +# DLLTOOL=$old_DLLTOOL OBJDUMP=$old_OBJDUMP AS=$old_AS \\ +# $0$ltconfig_args +# +# Compiler and other test output produced by $progname, useful for +# debugging $progname, is in ./config.log if it exists. + +# The version of $progname that generated this script. +LTCONFIG_VERSION=$LTCONFIG_VERSION + +# Shell to use when invoking shell scripts. +SHELL=$LTSHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host + +# An echo program that does not interpret backslashes. +echo=$ltecho + +# The archiver. +AR=$AR + +# The default C compiler. +CC=$CC + +# The linker used to build libraries. +LD=$LD + +# Whether we need hard or soft links. +LN_S=$LN_S + +# A BSD-compatible nm program. +NM=$NM + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$reload_flag +reload_cmds=$reload_cmds + +# How to pass a linker flag through the compiler. +wl=$wl + +# Object file suffix (normally "o"). +objext="$objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$pic_flag + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$compiler_c_o + +# Can we write directly to a .lo ? +compiler_o_lo=$compiler_o_lo + +# Must we lock files when doing compilation ? +need_locks=$need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$link_static_flag + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$no_builtin_flag + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$whole_archive_flag_spec + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$thread_safe_flag_spec + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$RANLIB +old_archive_cmds=$old_archive_cmds +old_postinstall_cmds=$old_postinstall_cmds +old_postuninstall_cmds=$old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$old_archive_from_new_cmds + +# Commands used to build and install a shared archive. +archive_cmds=$archive_cmds +archive_expsym_cmds=$archive_expsym_cmds +postinstall_cmds=$postinstall_cmds +postuninstall_cmds=$postuninstall_cmds + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$allow_undefined_flag + +# Flag that forces no undefined symbols. +no_undefined_flag=$no_undefined_flag + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$global_symbol_to_cdecl + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$hardcode_libdir_flag_spec + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$hardcode_libdir_separator + +# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$include_expsyms + +EOF + +case "$ltmain" in +*.sh) + echo '### END LIBTOOL CONFIG' >> "$ofile" + echo >> "$ofile" + case "$host_os" in + aix3*) + cat <<\EOF >> "$ofile" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "${COLLECT_NAMES+set}" != set; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + # Append the ltmain.sh script. + sed '$q' "$ltmain" >> "$ofile" || (rm -f "$ofile"; exit 1) + + chmod +x "$ofile" + ;; + +*) + # Compile the libtool program. + echo "FIXME: would compile $ltmain" + ;; +esac + +test -n "$cache_file" || exit 0 + +# AC_CACHE_SAVE +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +exit 0 + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/ltmain.sh b/ltmain.sh new file mode 100644 index 0000000..ae10cad --- /dev/null +++ b/ltmain.sh @@ -0,0 +1,3975 @@ +# ltmain.sh - Provide generalized library-building support services. +# NOTE: Changing this file will not affect anything until you rerun ltconfig. +# +# Copyright (C) 1996-1999 Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Check that we have a working $echo. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell, and then maybe $echo will work. + exec $SHELL "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 +fi + +if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + echo "$modename: not configured to build any kind of library" 1>&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 +fi + +# Global variables. +mode=$default_mode +nonopt= +prev= +prevopt= +run= +show="$echo" +show_help= +execute_dlfiles= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" + +# Parse our command line options once, thoroughly. +while test $# -gt 0 +do + arg="$1" + shift + + case "$arg" in + -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case "$prev" in + execute_dlfiles) + eval "$prev=\"\$$prev \$arg\"" + ;; + *) + eval "$prev=\$arg" + ;; + esac + + prev= + prevopt= + continue + fi + + # Have we seen a non-optional argument yet? + case "$arg" in + --help) + show_help=yes + ;; + + --version) + echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" + exit 0 + ;; + + --config) + sed -e '1,/^### BEGIN LIBTOOL CONFIG/d' -e '/^### END LIBTOOL CONFIG/,$d' $0 + exit 0 + ;; + + --debug) + echo "$progname: enabling shell trace mode" + set -x + ;; + + --dry-run | -n) + run=: + ;; + + --features) + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + exit 0 + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + --quiet | --silent) + show=: + ;; + + -dlopen) + prevopt="-dlopen" + prev=execute_dlfiles + ;; + + -*) + $echo "$modename: unrecognized option \`$arg'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + + *) + nonopt="$arg" + break + ;; + esac +done + +if test -n "$prevopt"; then + $echo "$modename: option \`$prevopt' requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 +fi + +if test -z "$show_help"; then + + # Infer the operation mode. + if test -z "$mode"; then + case "$nonopt" in + *cc | *++ | gcc* | *-gcc*) + mode=link + for arg + do + case "$arg" in + -c) + mode=compile + break + ;; + esac + done + ;; + *db | *dbx | *strace | *truss) + mode=execute + ;; + *install*|cp|mv) + mode=install + ;; + *rm) + mode=uninstall + ;; + *) + # If we have no mode, but dlfiles were specified, then do execute mode. + test -n "$execute_dlfiles" && mode=execute + + # Just use the default operation mode. + if test -z "$mode"; then + if test -n "$nonopt"; then + $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 + else + $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 + fi + fi + ;; + esac + fi + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + $echo "$modename: unrecognized option \`-dlopen'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$modename --help --mode=$mode' for more information." + + # These modes are in order of execution frequency so that they run quickly. + case "$mode" in + # libtool compile mode + compile) + modename="$modename: compile" + # Get the compilation command and the source file. + base_compile= + lastarg= + srcfile="$nonopt" + suppress_output= + + user_target=no + for arg + do + # Accept any command-line options. + case "$arg" in + -o) + if test "$user_target" != "no"; then + $echo "$modename: you cannot specify \`-o' more than once" 1>&2 + exit 1 + fi + user_target=next + ;; + + -static) + build_old_libs=yes + continue + ;; + esac + + case "$user_target" in + next) + # The next one is the -o target name + user_target=yes + continue + ;; + yes) + # We got the output file + user_target=set + libobj="$arg" + continue + ;; + esac + + # Accept the current argument as the source file. + lastarg="$srcfile" + srcfile="$arg" + + # Aesthetically quote the previous argument. + + # Backslashify any backslashes, double quotes, and dollar signs. + # These are the only characters that are still specially + # interpreted inside of double-quoted scrings. + lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly in scan + # sets, so we specify it separately. + case "$lastarg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + lastarg="\"$lastarg\"" + ;; + esac + + # Add the previous argument to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + done + + case "$user_target" in + set) + ;; + no) + # Get the name of the library object. + libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` + ;; + *) + $echo "$modename: you must specify a target with \`-o'" 1>&2 + exit 1 + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + xform='[cCFSfmso]' + case "$libobj" in + *.ada) xform=ada ;; + *.adb) xform=adb ;; + *.ads) xform=ads ;; + *.asm) xform=asm ;; + *.c++) xform=c++ ;; + *.cc) xform=cc ;; + *.cpp) xform=cpp ;; + *.cxx) xform=cxx ;; + *.f90) xform=f90 ;; + *.for) xform=for ;; + esac + + libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` + + case "$libobj" in + *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; + *) + $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 + exit 1 + ;; + esac + + if test -z "$base_compile"; then + $echo "$modename: you must specify a compilation command" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $libobj" + else + removelist="$libobj" + fi + + $run $rm $removelist + trap "$run $rm $removelist; exit 1" 1 2 15 + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\..*$%%'`.${objext} + lockfile="$output_obj.lock" + removelist="$removelist $output_obj $lockfile" + trap "$run $rm $removelist; exit 1" 1 2 15 + else + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until ln "$0" "$lockfile" 2>/dev/null; do + $show "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + echo "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + echo $srcfile > "$lockfile" + fi + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + # All platforms use -DPIC, to notify preprocessed assembler code. + command="$base_compile $pic_flag -DPIC $srcfile" + if test "$build_old_libs" = yes; then + lo_libobj="$libobj" + dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$libobj"; then + dir="$objdir" + else + dir="$dir/$objdir" + fi + libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` + + if test -d "$dir"; then + $show "$rm $libobj" + $run $rm $libobj + else + $show "$mkdir $dir" + $run $mkdir $dir + status=$? + if test $status -ne 0 && test ! -d $dir; then + exit $status + fi + fi + fi + if test "$compiler_o_lo" = yes; then + output_obj="$libobj" + command="$command -o $output_obj" + elif test "$compiler_c_o" = yes; then + output_obj="$obj" + command="$command -o $output_obj" + fi + + $run $rm "$output_obj" + $show "$command" + if $run eval "$command"; then : + else + test -n "$output_obj" && $run $rm $removelist + exit 1 + fi + + if test "$need_locks" = warn && + test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then + echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + + # Just move the object if needed, then go on to compile the next one + if test x"$output_obj" != x"$libobj"; then + $show "$mv $output_obj $libobj" + if $run $mv $output_obj $libobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # If we have no pic_flag, then copy the object into place and finish. + if test -z "$pic_flag" && test "$build_old_libs" = yes; then + # Rename the .lo from within objdir to obj + if test -f $obj; then + $show $rm $obj + $run $rm $obj + fi + + $show "$mv $libobj $obj" + if $run $mv $libobj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + + # Now arrange that obj and lo_libobj become the same file + $show "$LN_S $obj $lo_libobj" + if $run $LN_S $obj $lo_libobj; then + exit 0 + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Allow error messages only from the first compilation. + suppress_output=' >/dev/null 2>&1' + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + command="$base_compile $srcfile" + if test "$compiler_c_o" = yes; then + command="$command -o $obj" + output_obj="$obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + command="$command$suppress_output" + $run $rm "$output_obj" + $show "$command" + if $run eval "$command"; then : + else + $run $rm $removelist + exit 1 + fi + + if test "$need_locks" = warn && + test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then + echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + + # Just move the object if needed + if test x"$output_obj" != x"$obj"; then + $show "$mv $output_obj $obj" + if $run $mv $output_obj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Create an invalid libtool object if no PIC, so that we do not + # accidentally link it into a program. + if test "$build_libtool_libs" != yes; then + $show "echo timestamp > $libobj" + $run eval "echo timestamp > \$libobj" || exit $? + else + # Move the .lo from within objdir + $show "$mv $libobj $lo_libobj" + if $run $mv $libobj $lo_libobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + fi + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + $rm "$lockfile" + fi + + exit 0 + ;; + + # libtool link mode + link) + modename="$modename: link" + C_compiler="$CC" # save it, to compile generated C sources + CC="$nonopt" + case "$host" in + *-*-cygwin* | *-*-mingw* | *-*-os2*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invokation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + + # This is a source program that is used to create dlls on Windows + # Don't remove nor modify the starting and closing comments +# /* ltdll.c starts here */ +# #define WIN32_LEAN_AND_MEAN +# #include +# #undef WIN32_LEAN_AND_MEAN +# #include +# +# #ifndef __CYGWIN__ +# # ifdef __CYGWIN32__ +# # define __CYGWIN__ __CYGWIN32__ +# # endif +# #endif +# +# #ifdef __cplusplus +# extern "C" { +# #endif +# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); +# #ifdef __cplusplus +# } +# #endif +# +# #ifdef __CYGWIN__ +# #include +# DECLARE_CYGWIN_DLL( DllMain ); +# #endif +# HINSTANCE __hDllInstance_base; +# +# BOOL APIENTRY +# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) +# { +# __hDllInstance_base = hInst; +# return TRUE; +# } +# /* ltdll.c ends here */ + # This is a source program that is used to create import libraries + # on Windows for dlls which lack them. Don't remove nor modify the + # starting and closing comments +# /* impgen.c starts here */ +# /* Copyright (C) 1999 Free Software Foundation, Inc. +# +# This file is part of GNU libtool. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# */ +# +# #include /* for printf() */ +# #include /* for open(), lseek(), read() */ +# #include /* for O_RDONLY, O_BINARY */ +# #include /* for strdup() */ +# +# static unsigned int +# pe_get16 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[2]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 2); +# return b[0] + (b[1]<<8); +# } +# +# static unsigned int +# pe_get32 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[4]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 4); +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# static unsigned int +# pe_as32 (ptr) +# void *ptr; +# { +# unsigned char *b = ptr; +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# int +# main (argc, argv) +# int argc; +# char *argv[]; +# { +# int dll; +# unsigned long pe_header_offset, opthdr_ofs, num_entries, i; +# unsigned long export_rva, export_size, nsections, secptr, expptr; +# unsigned long name_rvas, nexp; +# unsigned char *expdata, *erva; +# char *filename, *dll_name; +# +# filename = argv[1]; +# +# dll = open(filename, O_RDONLY|O_BINARY); +# if (!dll) +# return 1; +# +# dll_name = filename; +# +# for (i=0; filename[i]; i++) +# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':') +# dll_name = filename + i +1; +# +# pe_header_offset = pe_get32 (dll, 0x3c); +# opthdr_ofs = pe_header_offset + 4 + 20; +# num_entries = pe_get32 (dll, opthdr_ofs + 92); +# +# if (num_entries < 1) /* no exports */ +# return 1; +# +# export_rva = pe_get32 (dll, opthdr_ofs + 96); +# export_size = pe_get32 (dll, opthdr_ofs + 100); +# nsections = pe_get16 (dll, pe_header_offset + 4 +2); +# secptr = (pe_header_offset + 4 + 20 + +# pe_get16 (dll, pe_header_offset + 4 + 16)); +# +# expptr = 0; +# for (i = 0; i < nsections; i++) +# { +# char sname[8]; +# unsigned long secptr1 = secptr + 40 * i; +# unsigned long vaddr = pe_get32 (dll, secptr1 + 12); +# unsigned long vsize = pe_get32 (dll, secptr1 + 16); +# unsigned long fptr = pe_get32 (dll, secptr1 + 20); +# lseek(dll, secptr1, SEEK_SET); +# read(dll, sname, 8); +# if (vaddr <= export_rva && vaddr+vsize > export_rva) +# { +# expptr = fptr + (export_rva - vaddr); +# if (export_rva + export_size > vaddr + vsize) +# export_size = vsize - (export_rva - vaddr); +# break; +# } +# } +# +# expdata = (unsigned char*)malloc(export_size); +# lseek (dll, expptr, SEEK_SET); +# read (dll, expdata, export_size); +# erva = expdata - export_rva; +# +# nexp = pe_as32 (expdata+24); +# name_rvas = pe_as32 (expdata+32); +# +# printf ("EXPORTS\n"); +# for (i = 0; i&2 + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + else + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + fi + build_libtool_libs=no + build_old_libs=yes + prefer_static_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test $# -gt 0; do + arg="$1" + shift + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case "$prev" in + output) + compile_command="$compile_command @OUTPUT@" + finalize_command="$finalize_command @OUTPUT@" + ;; + esac + + case "$prev" in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + compile_command="$compile_command @SYMFILE@" + finalize_command="$finalize_command @SYMFILE@" + preload=yes + fi + case "$arg" in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + ;; + esac + ;; + expsyms) + export_symbols="$arg" + if test ! -f "$arg"; then + $echo "$modename: symbol file \`$arg' does not exist" + exit 1 + fi + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case "$arg" in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit 1 + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi + + prevarg="$arg" + + case "$arg" in + -all-static) + if test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 + continue + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: not more than one -exported-symbols argument allowed" + exit 1 + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -L*) + dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` + # We need an absolute path. + case "$dir" in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + absdir="$dir" + fi + dir="$absdir" + ;; + esac + case " $deplibs " in + *" $arg "*) ;; + *) deplibs="$deplibs $arg";; + esac + case " $lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir";; + esac + case "$host" in + *-*-cygwin* | *-*-mingw* | *-*-os2*) + dllsearchdir=`cd "$dir" && pwd || echo "$dir"` + case ":$dllsearchpath:" in + ::) dllsearchpath="$dllsearchdir";; + *":$dllsearchdir:"*) ;; + *) dllsearchpath="$dllsearchpath:$dllsearchdir";; + esac + ;; + esac + ;; + + -l*) + if test "$arg" = "-lc"; then + case "$host" in + *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*) + # These systems don't actually have c library (as such) + continue + ;; + esac + elif test "$arg" = "-lm"; then + case "$host" in + *-*-cygwin* | *-*-beos*) + # These systems don't actually have math library (as such) + continue + ;; + esac + fi + deplibs="$deplibs $arg" + ;; + + -module) + module=yes + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -o) prev=output ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` + # We need an absolute path. + case "$dir" in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit 1 + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -static) + # If we have no pic_flag, then this is the same as -all-static. + if test -z "$pic_flag" && test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + # Some other compiler flag. + -* | +*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + ;; + + *.o | *.obj | *.a | *.lib) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A library object. + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + if test "$build_libtool_libs" = yes && test "$dlopen" = yes; then + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"` + prev= + fi + libobjs="$libobjs $arg" + ;; + + *.la) + # A libtool-controlled library. + + dlname= + libdir= + library_names= + old_library= + + # Check to see that this really is a libtool archive. + if (sed -e '2q' $arg | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$arg' is not a valid libtool archive" 1>&2 + exit 1 + fi + + # If the library was installed with an old release of libtool, + # it will not redefine variable installed. + installed=yes + + # Read the .la file + # If there is no directory component, then add one. + case "$arg" in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + + if test -z "$linklib"; then + $echo "$modename: cannot find name of link library for \`$arg'" 1>&2 + exit 1 + fi + + # Find the relevant object directory and library name. + name=`$echo "X$arg" | $Xsed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'` + + if test "X$installed" = Xyes; then + dir="$libdir" + else + dir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$arg"; then + dir="$objdir" + else + dir="$dir/$objdir" + fi + fi + + if test -n "$dependency_libs"; then + # Extract -R and -L from dependency_libs + temp_deplibs= + for deplib in $dependency_libs; do + case "$deplib" in + -R*) temp_xrpath=`$echo "X$deplib" | $Xsed -e 's/^-R//'` + case " $rpath $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + -L*) case "$compile_command $temp_deplibs " in + *" $deplib "*) ;; + *) temp_deplibs="$temp_deplibs $deplib";; + esac + temp_dir=`$echo "X$deplib" | $Xsed -e 's/^-L//'` + case " $lib_search_path " in + *" $temp_dir "*) ;; + *) lib_search_path="$lib_search_path $temp_dir";; + esac + ;; + *) temp_deplibs="$temp_deplibs $deplib";; + esac + done + dependency_libs="$temp_deplibs" + fi + + if test -z "$libdir"; then + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $dir/$old_library" + old_convenience="$old_convenience $dir/$old_library" + deplibs="$deplibs$dependency_libs" + compile_command="$compile_command $dir/$old_library$dependency_libs" + finalize_command="$finalize_command $dir/$old_library$dependency_libs" + continue + fi + + # This library was specified with -dlopen. + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + if test -z "$dlname" || test "$dlopen" != yes || test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking statically, + # we need to preload. + prev=dlprefiles + else + # We should not create a dependency on this library, but we + # may need any libraries it requires. + compile_command="$compile_command$dependency_libs" + finalize_command="$finalize_command$dependency_libs" + prev= + continue + fi + fi + + # The library was specified with -dlpreopen. + if test "$prev" = dlprefiles; then + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + dlprefiles="$dlprefiles $dir/$old_library" + else + dlprefiles="$dlprefiles $dir/$linklib" + fi + prev= + fi + + if test -n "$library_names" && + { test "$prefer_static_libs" = no || test -z "$old_library"; }; then + link_against_libtool_libs="$link_against_libtool_libs $arg" + if test -n "$shlibpath_var"; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *) temp_rpath="$temp_rpath $dir" ;; + esac + fi + + # We need an absolute path. + case "$dir" in + [\\/] | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + absdir="$dir" + fi + ;; + esac + + # This is the magic to use -rpath. + # Skip directories that are in the system default run-time + # search path, unless they have been requested with -R. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + + lib_linked=yes + case "$hardcode_action" in + immediate | unsupported) + if test "$hardcode_direct" = no; then + compile_command="$compile_command $dir/$linklib" + deplibs="$deplibs $dir/$linklib" + case "$host" in + *-*-cygwin* | *-*-mingw* | *-*-os2*) + dllsearchdir=`cd "$dir" && pwd || echo "$dir"` + if test -n "$dllsearchpath"; then + dllsearchpath="$dllsearchpath:$dllsearchdir" + else + dllsearchpath="$dllsearchdir" + fi + ;; + esac + elif test "$hardcode_minus_L" = no; then + case "$host" in + *-*-sunos*) + compile_shlibpath="$compile_shlibpath$dir:" + ;; + esac + case "$compile_command " in + *" -L$dir "*) ;; + *) compile_command="$compile_command -L$dir";; + esac + compile_command="$compile_command -l$name" + deplibs="$deplibs -L$dir -l$name" + elif test "$hardcode_shlibpath_var" = no; then + case ":$compile_shlibpath:" in + *":$dir:"*) ;; + *) compile_shlibpath="$compile_shlibpath$dir:";; + esac + compile_command="$compile_command -l$name" + deplibs="$deplibs -l$name" + else + lib_linked=no + fi + ;; + + relink) + if test "$hardcode_direct" = yes; then + compile_command="$compile_command $absdir/$linklib" + deplibs="$deplibs $absdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + case "$compile_command " in + *" -L$absdir "*) ;; + *) compile_command="$compile_command -L$absdir";; + esac + compile_command="$compile_command -l$name" + deplibs="$deplibs -L$absdir -l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case ":$compile_shlibpath:" in + *":$absdir:"*) ;; + *) compile_shlibpath="$compile_shlibpath$absdir:";; + esac + compile_command="$compile_command -l$name" + deplibs="$deplibs -l$name" + else + lib_linked=no + fi + ;; + + *) + lib_linked=no + ;; + esac + + if test "$lib_linked" != yes; then + $echo "$modename: configuration error: unsupported hardcode properties" + exit 1 + fi + + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + finalize_command="$finalize_command $libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + case "$finalize_command " in + *" -L$libdir "*) ;; + *) finalize_command="$finalize_command -L$libdir";; + esac + finalize_command="$finalize_command -l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case ":$finalize_shlibpath:" in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:";; + esac + finalize_command="$finalize_command -l$name" + else + # We cannot seem to hardcode it, guess we'll fake it. + case "$finalize_command " in + *" -L$dir "*) ;; + *) finalize_command="$finalize_command -L$libdir";; + esac + finalize_command="$finalize_command -l$name" + fi + else + # Transform directly to old archives if we don't build new libraries. + if test -n "$pic_flag" && test -z "$old_library"; then + $echo "$modename: cannot find static library for \`$arg'" 1>&2 + exit 1 + fi + + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_command="$compile_command $dir/$linklib" + finalize_command="$finalize_command $dir/$linklib" + else + case "$compile_command " in + *" -L$dir "*) ;; + *) compile_command="$compile_command -L$dir";; + esac + compile_command="$compile_command -l$name" + case "$finalize_command " in + *" -L$dir "*) ;; + *) finalize_command="$finalize_command -L$dir";; + esac + finalize_command="$finalize_command -l$name" + fi + fi + + # Add in any libraries that this one depends upon. + compile_command="$compile_command$dependency_libs" + finalize_command="$finalize_command$dependency_libs" + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + ;; + esac + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + done + + if test -n "$prev"; then + $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` + libobjs_save="$libobjs" + + case "$output" in + "") + $echo "$modename: you must specify an output file" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + + *.a | *.lib) + if test -n "$link_against_libtool_libs"; then + $echo "$modename: error: cannot link libtool libraries into archives" 1>&2 + exit 1 + fi + + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 + fi + + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 + fi + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + ;; + + *.la) + # Make sure we only generate libraries of the form `libNAME.la'. + case "$outputname" in + lib*) + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + eval libname=\"$libname_spec\" + ;; + *) + if test "$module" = no; then + $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + eval libname=\"$libname_spec\" + else + libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + fi + ;; + esac + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + + if test -n "$objs"; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects:$objs" 2>&1 + exit 1 + fi + + # How the heck are we supposed to write a wrapper for a shared library? + if test -n "$link_against_libtool_libs"; then + $echo "$modename: error: cannot link shared libraries into libtool libraries" 1>&2 + exit 1 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for libtool libraries" 1>&2 + fi + + set dummy $rpath + if test $# -gt 2; then + $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 + fi + install_libdir="$2" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + libext=al + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + dependency_libs="$deplibs" + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 + fi + else + + # Parse the version information argument. + IFS="${IFS= }"; save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + IFS="$save_ifs" + + if test -n "$8"; then + $echo "$modename: too many parameters to \`-version-info'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + current="$2" + revision="$3" + age="$4" + + # Check that each of the things are valid numbers. + case "$current" in + 0 | [1-9] | [1-9][0-9]*) ;; + *) + $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case "$revision" in + 0 | [1-9] | [1-9][0-9]*) ;; + *) + $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case "$age" in + 0 | [1-9] | [1-9][0-9]*) ;; + *) + $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + if test $age -gt $current; then + $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case "$version_type" in + none) ;; + + irix) + major=`expr $current - $age + 1` + versuffix="$major.$revision" + verstring="sgi$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test $loop != 0; do + iface=`expr $revision - $loop` + loop=`expr $loop - 1` + verstring="sgi$major.$iface:$verstring" + done + ;; + + linux) + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + ;; + + osf) + major=`expr $current - $age` + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test $loop != 0; do + iface=`expr $current - $loop` + loop=`expr $loop - 1` + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current"; + ;; + + windows) + # Like Linux, but with '-' rather than '.', since we only + # want one extension on Windows 95. + major=`expr $current - $age` + versuffix="-$major-$age-$revision" + ;; + + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + verstring="0.0" + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + + dependency_libs="$deplibs" + case "$host" in + *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*) + # these systems don't actually have a c library (as such)! + ;; + *) + # Add libc to deplibs on all other systems. + deplibs="$deplibs -lc" + ;; + esac + fi + + # Create the output directory, or remove our outputs if we need to. + if test -d $output_objdir; then + $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*" + $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.* + else + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + status=$? + if test $status -ne 0 && test ! -d $output_objdir; then + exit $status + fi + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + if test "$build_libtool_libs" = yes; then + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case "$deplibs_check_method" in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behaviour. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $rm conftest.c + cat > conftest.c </dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null \ + | grep " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | sed 's/.* -> //'` + case "$potliblink" in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ + | sed 10q \ + | egrep "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + echo "*** Warning: This library needs some functionality provided by $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ + -e 's/ -[LR][^ ]*//g' -e 's/[ ]//g' | + grep . >/dev/null; then + echo + if test "X$deplibs_check_method" = "Xnone"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + echo "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + # Get the real and link names of the library. + eval library_names=\"$library_names_spec\" + set dummy $library_names + realname="$2" + shift; shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + lib="$output_objdir/$realname" + for link + do + linknames="$linknames $link" + done + + # Ensure that we have .o objects for linkers which dislike .lo + # (e.g. aix) incase we are running --disable-static + for obj in $libobjs; do + oldobj=`$echo "X$obj" | $Xsed -e "$lo2o"` + if test ! -f $oldobj; then + $show "${LN_S} $obj $oldobj" + $run ${LN_S} $obj $oldobj || exit $? + fi + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + eval cmds=\"$export_symbols_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + if test -n "$export_symbols_regex"; then + $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" + $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + $show "$mv \"${export_symbols}T\" \"$export_symbols\"" + $run eval '$mv "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' + fi + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${outputname}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + for xlib in $convenience; do + # Extract the objects. + case "$xlib" in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` + done + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linkopts="$linkopts $flag" + fi + + # Do each of the archive commands. + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval cmds=\"$archive_expsym_cmds\" + else + eval cmds=\"$archive_cmds\" + fi + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + *.lo | *.o | *.obj) + if test -n "$link_against_libtool_libs"; then + $echo "$modename: error: cannot link libtool libraries into objects" 1>&2 + exit 1 + fi + + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 + fi + + case "$output" in + *.lo) + if test -n "$objs"; then + $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 + exit 1 + fi + libobj="$output" + obj=`$echo "X$output" | $Xsed -e "$lo2o"` + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $run $rm $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${obj}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + for xlib in $convenience; do + # Extract the objects. + case "$xlib" in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` + done + fi + fi + + # Create the old-style object. + reload_objs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" + + output="$obj" + eval cmds=\"$reload_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit 0 + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + $show "echo timestamp > $libobj" + $run eval "echo timestamp > $libobj" || exit $? + exit 0 + fi + + if test -n "$pic_flag"; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + eval cmds=\"$reload_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + else + # Just create a symlink. + $show $rm $libobj + $run $rm $libobj + $show "$LN_S $obj $libobj" + $run $LN_S $obj $libobj || exit $? + fi + + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit 0 + ;; + + # Anything else should be a program. + *) + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 + fi + + if test "$preload" = yes; then + if test "$dlopen" = unknown && test "$dlopen_self" = unknown && + test "$dlopen_self_static" = unknown; then + $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." + fi + fi + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$compile_rpath " in + *" $libdir "*) ;; + *) compile_rpath="$compile_rpath $libdir" ;; + esac + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + + # Create the binary in the object directory, then wrap it. + if test ! -d $output_objdir; then + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + status=$? + if test $status -ne 0 && test ! -d $output_objdir; then + exit $status + fi + fi + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + dlsyms= + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + dlsyms="${outputname}S.c" + else + $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 + fi + fi + + if test -n "$dlsyms"; then + case "$dlsyms" in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${outputname}.nm" + + $show "$rm $nlist ${nlist}S ${nlist}T" + $run $rm "$nlist" "${nlist}S" "${nlist}T" + + # Parse the name list into a source file. + $show "creating $output_objdir/$dlsyms" + + test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ +/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ +/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* Prevent the only kind of declaration conflicts we can make. */ +#define lt_preloaded_symbols some_other_symbol + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + $show "generating symbol list for \`$output'" + + test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$echo "X$objs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for arg in $progfiles; do + $show "extracting global C symbols from \`$arg'" + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + if test -n "$export_symbols_regex"; then + $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$output.exp" + $run $rm $export_symbols + $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + else + $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"' + $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T' + $run eval 'mv "$nlist"T "$nlist"' + fi + fi + + for arg in $dlprefiles; do + $show "extracting global C symbols from \`$arg'" + name=`echo "$arg" | sed -e 's%^.*/%%'` + $run eval 'echo ": $name " >> "$nlist"' + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -z "$run"; then + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $mv "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then + : + else + grep -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$dlsyms" + fi + + $echo >> "$output_objdir/$dlsyms" "\ + +#undef lt_preloaded_symbols + +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[] = +{\ +" + + sed -n -e 's/^: \([^ ]*\) $/ {\"\1\", (lt_ptr_t) 0},/p' \ + -e 's/^. \([^ ]*\) \([^ ]*\)$/ {"\2", (lt_ptr_t) \&\2},/p' \ + < "$nlist" >> "$output_objdir/$dlsyms" + + $echo >> "$output_objdir/$dlsyms" "\ + {0, (lt_ptr_t) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + fi + + pic_flag_for_symtable= + case "$host" in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";; + esac + esac + + # Now compile the dynamic symbol file. + $show "(cd $output_objdir && $C_compiler -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" + $run eval '(cd $output_objdir && $C_compiler -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? + + # Clean up the generated files. + $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" + $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" + + # Transform the symbol file into the correct name. + compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + ;; + *) + $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 + exit 1 + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi + + if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + $show "$link_command" + $run eval "$link_command" + status=$? + + # Delete the generated files. + if test -n "$dlsyms"; then + $show "$rm $output_objdir/${outputname}S.${objext}" + $run $rm "$output_objdir/${outputname}S.${objext}" + fi + + exit $status + fi + + if test -n "$shlibpath_var"; then + # We should set the shlibpath_var + rpath= + for dir in $temp_rpath; do + case "$dir" in + [\\/]* | [A-Za-z]:[\\/]*) + # Absolute path. + rpath="$rpath$dir:" + ;; + *) + # Relative path: add a thisdir entry. + rpath="$rpath\$thisdir/$dir:" + ;; + esac + done + temp_rpath="$rpath" + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 + $echo "$modename: \`$output' will be relinked during installation" 1>&2 + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname + + $show "$link_command" + $run eval "$link_command" || exit $? + + # Now create the wrapper script. + $show "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + fi + + # Quote $echo for shipping. + if test "X$echo" = "X$SHELL $0 --fallback-echo"; then + case "$0" in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";; + *) qecho="$SHELL `pwd`/$0 --fallback-echo";; + esac + qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if our run command is non-null. + if test -z "$run"; then + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) output=`echo $output|sed 's,.exe$,,'` ;; + esac + $rm $output + trap "$rm $output; exit 1" 1 2 15 + + $echo > $output "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test \"\${CDPATH+set}\" = set; then CDPATH=; export CDPATH; fi + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variable: + link_against_libtool_libs='$link_against_libtool_libs' +else + # When we are sourced in execute mode, \$file and \$echo are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + echo=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$echo works! + : + else + # Restart under the correct shell, and then maybe \$echo will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $echo >> $output "\ + + # Find the directory that this script lives in. + thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\/]* | [A-Za-z]:[\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\` + done + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + echo >> $output "\ + program=lt-'$outputname' + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || \\ + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $mkdir \"\$progdir\" + else + $rm \"\$progdir/\$file\" + fi" + + echo >> $output "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if (cd \"\$thisdir\" && eval \$relink_command); then : + else + $rm \"\$progdir/\$file\" + exit 1 + fi + fi + + $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $rm \"\$progdir/\$program\"; + $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $rm \"\$progdir/\$file\" + fi" + else + echo >> $output "\ + program='$outputname$exeext' + progdir=\"\$thisdir/$objdir\" +" + fi + + echo >> $output "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $echo >> $output "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $echo >> $output "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $echo >> $output "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + *-*-cygwin* | *-*-mingw | *-*-os2*) + # win32 systems need to use the prog path for dll + # lookup to work + $echo >> $output "\ + exec \$progdir\\\\\$program \${1+\"\$@\"} +" + ;; + *) + $echo >> $output "\ + # Export the path to the program. + PATH=\"\$progdir:\$PATH\" + export PATH + + exec \$program \${1+\"\$@\"} +" + ;; + esac + $echo >> $output "\ + \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" + exit 1 + fi + else + # The program doesn't exist. + \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 + \$echo \"This script is just a wrapper for \$program.\" 1>&2 + echo \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" + chmod +x $output + fi + exit 0 + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$objs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP` + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + # Add in members from convenience archives. + for xlib in $addlibs; do + # Extract the objects. + case "$xlib" in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP` + done + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + eval cmds=\"$old_archive_from_new_cmds\" + else + # Ensure that we have .o objects in place incase we decided + # not to build a shared library, and have fallen back to building + # static libs even though --disable-static was passed! + for oldobj in $oldobjs; do + if test ! -f $oldobj; then + obj=`$echo "X$oldobj" | $Xsed -e "$o2lo"` + $show "${LN_S} $obj $oldobj" + $run ${LN_S} $obj $oldobj || exit $? + fi + done + + eval cmds=\"$old_archive_cmds\" + fi + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$generated"; then + $show "${rm}r$generated" + $run ${rm}r$generated + fi + + # Now create the libtool archive. + case "$output" in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + $show "creating $output" + + if test -n "$xrpath"; then + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + done + dependency_libs="$temp_xrpath $dependency_libs" + fi + + # Only create the output if not a dry run. + if test -z "$run"; then + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + fi + $rm $output + $echo > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$dlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Directory that this library needs to be installed in: +libdir='$install_libdir'\ +" + done + fi + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" + $run eval "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" || exit $? + ;; + esac + exit 0 + ;; + + # libtool install mode + install) + modename="$modename: install" + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh; then + # Aesthetically quote it. + arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$arg " + arg="$1" + shift + else + install_prog= + arg="$nonopt" + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog$arg" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest="$arg" + continue + fi + + case "$arg" in + -d) isdir=yes ;; + -f) prev="-f" ;; + -g) prev="-g" ;; + -m) prev="-m" ;; + -o) prev="-o" ;; + -s) + stripme=" -s" + continue + ;; + -*) ;; + + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest="$arg" + continue + fi + ;; + esac + + # Aesthetically quote the argument. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog $arg" + done + + if test -z "$install_prog"; then + $echo "$modename: you must specify an install program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -n "$prev"; then + $echo "$modename: the \`$prev' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -z "$files"; then + if test -z "$dest"; then + $echo "$modename: no file or destination specified" 1>&2 + else + $echo "$modename: you must specify a destination" 1>&2 + fi + $echo "$help" 1>&2 + exit 1 + fi + + # Strip any trailing slash from the destination. + dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` + test "X$destdir" = "X$dest" && destdir=. + destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` + + # Not a directory, so check to see that there is only one file specified. + set dummy $files + if test $# -gt 2; then + $echo "$modename: \`$dest' is not a directory" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + fi + case "$destdir" in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case "$file" in + *.lo) ;; + *) + $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case "$file" in + *.a | *.lib) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + library_names= + old_library= + # If there is no directory component, then add one. + case "$file" in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + dir="`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/" + test "X$dir" = "X$file/" && dir= + dir="$dir$objdir" + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$realname $destdir/$realname" + $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $? + + if test $# -gt 0; then + # Delete the old symlinks, and create new ones. + for linkname + do + if test "$linkname" != "$realname"; then + $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + fi + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + eval cmds=\"$postinstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Install the pseudo-library for information purposes. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + instname="$dir/$name"i + $show "$install_prog $instname $destdir/$name" + $run eval "$install_prog $instname $destdir/$name" || exit $? + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case "$destfile" in + *.lo) + staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` + ;; + *.o | *.obj) + staticdest="$destfile" + destfile= + ;; + *) + $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + + # Install the libtool object if requested. + if test -n "$destfile"; then + $show "$install_prog $file $destfile" + $run eval "$install_prog $file $destfile" || exit $? + fi + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` + + $show "$install_prog $staticobj $staticdest" + $run eval "$install_prog \$staticobj \$staticdest" || exit $? + fi + exit 0 + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Do a test to see if this is really a libtool program. + if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + link_against_libtool_libs= + relink_command= + + # If there is no directory component, then add one. + case "$file" in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Check the variables that should have been set. + if test -z "$link_against_libtool_libs"; then + $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2 + exit 1 + fi + + finalize=yes + for lib in $link_against_libtool_libs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + # If there is no directory component, then add one. + case "$lib" in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + fi + libfile="$libdir/`$echo "X$lib" | $Xsed -e 's%^.*/%%g'`" + if test -n "$libdir" && test ! -f "$libfile"; then + $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + finalize=no + fi + done + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + if test "$finalize" = yes && test -z "$run"; then + tmpdir="/tmp" + test -n "$TMPDIR" && tmpdir="$TMPDIR" + tmpdir="$tmpdir/libtool-$$" + if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then : + else + $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 + continue + fi + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` + + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + ${rm}r "$tmpdir" + continue + fi + file="$outputname" + else + $echo "$modename: warning: cannot relink \`$file'" 1>&2 + fi + else + # Install the binary that we compiled earlier. + file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + $show "$install_prog$stripme $file $destfile" + $run eval "$install_prog\$stripme \$file \$destfile" || exit $? + test -n "$outputname" && ${rm}r "$tmpdir" + ;; + esac + done + + for file in $staticlibs; do + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + $show "$install_prog $file $oldlib" + $run eval "$install_prog \$file \$oldlib" || exit $? + + # Do each command in the postinstall commands. + eval cmds=\"$old_postinstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$future_libdirs"; then + $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 + fi + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + test -n "$run" && current_libdirs=" -n$current_libdirs" + exec $SHELL $0 --finish$current_libdirs + exit 1 + fi + + exit 0 + ;; + + # libtool finish mode + finish) + modename="$modename: finish" + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + eval cmds=\"$finish_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || admincmds="$admincmds + $cmd" + done + IFS="$save_ifs" + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $run eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + test "$show" = : && exit 0 + + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + echo " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use \`-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + echo " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + echo " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + echo + echo "See any operating system documentation about shared libraries for" + echo "more information, such as the ld(1) and ld.so(8) manual pages." + echo "----------------------------------------------------------------------" + exit 0 + ;; + + # libtool execute mode + execute) + modename="$modename: execute" + + # The first argument is the command name. + cmd="$nonopt" + if test -z "$cmd"; then + $echo "$modename: you must specify a COMMAND" 1>&2 + $echo "$help" + exit 1 + fi + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + if test ! -f "$file"; then + $echo "$modename: \`$file' is not a file" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + dir= + case "$file" in + *.la) + # Check to see that this really is a libtool archive. + if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Read the libtool library. + dlname= + library_names= + + # If there is no directory component, then add one. + case "$file" in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" + continue + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 + exit 1 + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + ;; + + *) + $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case "$file" in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + # If there is no directory component, then add one. + case "$file" in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` + args="$args \"$file\"" + done + + if test -z "$run"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + + # Restore saved enviroment variables + if test "${save_LC_ALL+set}" = set; then + LC_ALL="$save_LC_ALL"; export LC_ALL + fi + if test "${save_LANG+set}" = set; then + LANG="$save_LANG"; export LANG + fi + + # Now actually exec the command. + eval "exec \$cmd$args" + + $echo "$modename: cannot exec \$cmd$args" + exit 1 + else + # Display what would be done. + eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" + $echo "export $shlibpath_var" + $echo "$cmd$args" + exit 0 + fi + ;; + + # libtool uninstall mode + uninstall) + modename="$modename: uninstall" + rm="$nonopt" + files= + + for arg + do + case "$arg" in + -*) rm="$rm $arg" ;; + *) files="$files $arg" ;; + esac + done + + if test -z "$rm"; then + $echo "$modename: you must specify an RM program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + rmfiles="$file" + + case "$name" in + *.la) + # Possibly a libtool archive, so verify it. + if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + . $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $dir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $dir/$old_library" + + $show "$rm $rmfiles" + $run $rm $rmfiles + + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + eval cmds=\"$postuninstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + done + IFS="$save_ifs" + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + eval cmds=\"$old_postuninstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + done + IFS="$save_ifs" + fi + + # FIXME: should reinstall the best remaining shared library. + fi + ;; + + *.lo) + if test "$build_old_libs" = yes; then + oldobj=`$echo "X$name" | $Xsed -e "$lo2o"` + rmfiles="$rmfiles $dir/$oldobj" + fi + $show "$rm $rmfiles" + $run $rm $rmfiles + ;; + + *) + $show "$rm $rmfiles" + $run $rm $rmfiles + ;; + esac + done + exit 0 + ;; + + "") + $echo "$modename: you must specify a MODE" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 + ;; + esac + + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 +fi # test -z "$show_help" + +# We need to display help for each of the modes. +case "$mode" in +"") $echo \ +"Usage: $modename [OPTION]... [MODE-ARG]... + +Provide generalized library-building support services. + + --config show all configuration variables + --debug enable verbose shell tracing +-n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --finish same as \`--mode=finish' + --help display this help message and exit + --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] + --quiet same as \`--silent' + --silent don't print informational messages + --version print version information + +MODE must be one of the following: + + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for +a more detailed description of MODE." + exit 0 + ;; + +compile) + $echo \ +"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -static always build a \`.o' file suitable for static linking + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + +execute) + $echo \ +"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + +finish) + $echo \ +"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + +install) + $echo \ +"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + +link) + $echo \ +"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -static do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + +uninstall) + $echo \ +"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + +*) + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; +esac + +echo +$echo "Try \`$modename --help' for more information about other modes." + +exit 0 + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/mkinstalldirs b/mkinstalldirs new file mode 100644 index 0000000..d005d49 --- /dev/null +++ b/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id: mkinstalldirs,v 1.2 1998/09/01 16:52:17 werner Exp $ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" 1>&2 + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/net.m4 b/net.m4 new file mode 100644 index 0000000..254473b --- /dev/null +++ b/net.m4 @@ -0,0 +1,55 @@ +dnl +dnl The following was written by jhawk@mit.edu +dnl +dnl AC_LIBRARY_NET: Id: net.m4,v 1.4 1997/10/25 20:49:53 jhawk Exp +dnl +dnl This test is for network applications that need socket() and +dnl gethostbyname() -ish functions. Under Solaris, those applications need to +dnl link with "-lsocket -lnsl". Under IRIX, they should *not* link with +dnl "-lsocket" because libsocket.a breaks a number of things (for instance: +dnl gethostbyname() under IRIX 5.2, and snoop sockets under most versions of +dnl IRIX). +dnl +dnl Unfortunately, many application developers are not aware of this, and +dnl mistakenly write tests that cause -lsocket to be used under IRIX. It is +dnl also easy to write tests that cause -lnsl to be used under operating +dnl systems where neither are necessary (or useful), such as SunOS 4.1.4, which +dnl uses -lnsl for TLI. +dnl +dnl This test exists so that every application developer does not test this in +dnl a different, and subtly broken fashion. +dnl +dnl It has been argued that this test should be broken up into two seperate +dnl tests, one for the resolver libraries, and one for the libraries necessary +dnl for using Sockets API. Unfortunately, the two are carefully intertwined and +dnl allowing the autoconf user to use them independantly potentially results in +dnl unfortunate ordering dependancies -- as such, such component macros would +dnl have to carefully use indirection and be aware if the other components were +dnl executed. Since other autoconf macros do not go to this trouble, and almost +dnl no applications use sockets without the resolver, this complexity has not +dnl been implemented. +dnl +dnl The check for libresolv is in case you are attempting to link statically +dnl and happen to have a libresolv.a lying around (and no libnsl.a). +dnl +AC_DEFUN(AC_LIBRARY_NET, [ + # Most operating systems have gethostbyname() in the default searched + # libraries (i.e. libc): + AC_CHECK_FUNC(gethostbyname, , + # Some OSes (eg. Solaris) place it in libnsl: + AC_CHECK_LIB(nsl, gethostbyname, , + # Some strange OSes (SINIX) have it in libsocket: + AC_CHECK_LIB(socket, gethostbyname, , + # Unfortunately libsocket sometimes depends on libnsl. + # AC_CHECK_LIB's API is essentially broken so the following + # ugliness is necessary: + AC_CHECK_LIB(socket, gethostbyname, + LIBS="-lsocket -lnsl $LIBS", + AC_CHECK_LIB(resolv, gethostbyname), + -lnsl) + ) + ) + ) + AC_CHECK_FUNC(socket, , AC_CHECK_LIB(socket, socket, , + AC_CHECK_LIB(socket, socket, LIBS="-lsocket -lnsl $LIBS", , -lnsl))) + ]) diff --git a/pascal/lib/freetype.pas b/pascal/lib/freetype.pas new file mode 100644 index 0000000..82bc46f --- /dev/null +++ b/pascal/lib/freetype.pas @@ -0,0 +1,1931 @@ +(******************************************************************* + * + * FreeType.Pas + * + * High-level interface specification. + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * Notes : + * + * This is the only file that should be included by client + * application sources for the final release. All other types + * and functions defined in the "tt*.h" files are library + * internals, and should not be included ( except of course + * during development, as now ) + * + ******************************************************************) + +unit FreeType; + +interface + +type + +{$IFDEF OS2} + TT_Int = Longint; +{$ELSE} + TT_Int = Integer; +{$ENDIF} + + TT_Long = longint; + TT_ULong = longint; (* there are no unsigned longs in Pascal :-( *) + (* it will probably be a good idea to use cardinals *) + (* with Delphi and Virtual a bit later.. *) + TT_Short = integer; + TT_UShort = word; + + TT_Fixed = LongInt; (* Signed Fixed 16.16 Float *) + + TT_FWord = Integer; (* Distance in FUnits *) + TT_UFWord = Word; (* Unsigned Distance *) + + TT_F2Dot14 = Integer; (* signed fixed float 2.14 used for *) + (* unary vectors, with layout : *) + (* *) + (* s : 1 -- sign bit *) + (* m : 1 -- mantissa bit *) + (* f : 14 -- unsigned fractional *) + (* *) + (* 's:m' is the 2-bit signed int *) + (* value to which the *positive* *) + (* fractional part should be *) + (* added. *) + (* *) + + TT_F26Dot6 = LongInt; (* 26.6 fixed float, used for pixel coordinates *) + + TT_Pos = Longint; (* funits or 26.6, depending on context *) + + (******************************************************) + (* a simple unit vector type *) + (* *) + TT_UnitVector = record + + x : TT_F2Dot14; + y : TT_F2Dot14; + end; + + (******************************************************) + (* a simple vector type *) + (* *) + TT_Vector = record + + x : TT_Pos; + y : TT_Pos; + end; + + (******************************************************) + (* a simple 2x2 matrix type *) + (* *) + TT_Matrix = record + + xx, xy : TT_Fixed; + yx, yy : TT_Fixed; + end; + + (******************************************************) + (* a glyph's bounding box *) + (* *) + TT_BBox = record + + xMin, yMin : TT_Pos; + xMax, yMax : TT_Pos; + end; + + (******************************************************) + (* the engine's error condition type - 0 always *) + (* means success. *) + (* *) + TT_Error = TT_Int; + + TT_Points_Table = array[0..99] of TT_Vector; + TT_Points = ^TT_Points_Table; + + TT_Coordinates = array[0..99] of TT_Pos; + TT_PCoordinates = ^TT_Coordinates; + + TT_TouchTable = array[0..9] of byte; + TT_PTouchTable = ^TT_TouchTable; + + TT_ConStarts = array[0..9] of word; + TT_PConStarts = ^TT_ConStarts; + + (******************************************************) + (* glyph outline description *) + (* *) + TT_Outline = record + + n_points : integer; + n_contours : integer; + + points : TT_Points; (* array of point coordinates *) + flags : TT_PTouchTable; (* array of point flags *) + conEnds : TT_PConStarts; (* array of contours ends *) + + owner : Boolean; (* this flag is set when the outline *) + (* owns the arrays it uses. *) + + high_precision : Boolean; + second_pass : Boolean; + dropout_mode : Byte; + end; + + (******************************************************) + (* glyph metrics structure *) + (* *) + TT_Glyph_Metrics = record + + bbox : TT_BBox; + bearingX : TT_Pos; + bearingY : TT_Pos; + advance : TT_Pos; + end; + + (******************************************************) + (* big glyph metrics structure *) + (* *) + TT_Big_Glyph_Metrics = record + + bbox : TT_BBox; + horiBearingX : TT_Pos; + horiBearingY : TT_Pos; + horiAdvance : TT_Pos; + vertBearingX : TT_Pos; + vertBearingY : TT_Pos; + vertAdvance : TT_Pos; + end; + + (******************************************************) + (* instance metrics. used to return information to *) + (* clients regarding an instance's important state *) + (* *) + TT_Instance_Metrics = record + + pointsize : integer; + + x_ppem : integer; + y_ppem : integer; + + x_scale : TT_Fixed; + y_scale : TT_Fixed; + + x_resolution : integer; + y_resolution : integer; + end; + +const + TT_Flow_Down = -1; + TT_Flow_Up = +1; + +type + + (******************************************************) + (* a record used to describe a bitmap or pixmap to *) + (* the rasterizer. *) + (* *) + TT_Raster_Map = record + + Rows : TT_Int; (* rows number of the bitmap *) + Cols : TT_Int; (* columns (bytes) per row *) + Width : TT_Int; (* pixels per row *) + Flow : TT_Int; (* bit/pixmap's flow *) + Buffer : pointer; (* bit/pixmap data *) + Size : longint; (* bit/pixmap data size (bytes) *) + end; + + (******************************************************) + (* The TrueType font header table structure *) + (* *) + TT_Header = record + + table_version : TT_Fixed; + font_revision : TT_Fixed; + + checksum_adjust : TT_Long; + magic_number : TT_Long; + + flags : TT_UShort; + units_per_EM : TT_UShort; + + created : array[0..1] of TT_Long; + modified : array[0..1] of TT_Long; + + xMin, yMin : TT_FWord; + xMax, yMax : TT_FWord; + + mac_style : TT_UShort; + lowest_rec_PPEM : TT_UShort; + font_direction : TT_Short; + + index_to_loc_format : TT_Short; + glyph_data_format : TT_Short; + end; + + (******************************************************) + (* The TrueType horizontal header table structure *) + (* *) + TT_Horizontal_Header = record + + version : TT_Fixed; + ascender : TT_FWord; + descender : TT_FWord; + line_gap : TT_FWord; + + advance_Width_Max : TT_UShort; + min_left_side_bearing : TT_Short; + min_right_side_bearing : TT_Short; + xMax_extent : TT_Short; + caret_slope_rise : TT_Short; + caret_slope_run : TT_Short; + + reserved : array[0..4] of TT_SHort; + + metric_data_format : TT_Short; + number_of_HMetrics : TT_UShort; + + (* the following are not part of the header in the file *) + + short_metrics : Pointer; + long_metrics : Pointer; + end; + + (******************************************************) + (* The TrueType vertical header table structure *) + (* *) + TT_Vertical_Header = record + + version : TT_Fixed; + ascender : TT_FWord; + descender : TT_FWord; + line_gap : TT_FWord; + + advance_Height_Max : TT_UShort; + min_top_side_bearing : TT_Short; + min_bottom_side_bearing : TT_Short; + yMax_extent : TT_Short; + caret_slope_rise : TT_Short; + caret_slope_run : TT_Short; + + reserved : array[0..4] of TT_SHort; + + metric_data_format : TT_Short; + number_of_VMetrics : TT_UShort; + + (* the following are not part of the header in the file *) + + short_metrics : Pointer; + long_metrics : Pointer; + end; + + (******************************************************) + (* The TrueType OS/2 table structure *) + (* *) + TT_OS2 = record + version : TT_UShort; (* $0001 *) + xAvgCharWidth : TT_Short; + usWeightClass : TT_UShort; + usWidthClass : TT_UShort; + fsType : TT_Short; + ySubscriptXSize : TT_Short; + ySubscriptYSize : TT_Short; + ySubScriptXOffset : TT_Short; + ySubscriptYOffset : TT_Short; + ySuperscriptXSize : TT_Short; + ySuperscriptYSize : TT_Short; + ySuperscriptXOffset : TT_Short; + ySuperscriptYOffset : TT_Short; + yStrikeoutSize : TT_Short; + yStrikeoutPosition : TT_Short; + sFamilyClass : TT_Short; + panose : array[0..9] of Byte; + ulUnicodeRange1 : TT_ULong; (* bits 0-31 *) + ulUnicodeRange2 : TT_ULong; (* bits 32-63 *) + ulUnicodeRange3 : TT_ULong; (* bits 64-95 *) + ulUnicodeRange4 : TT_ULong; (* bits 96-127 *) + achVendID : array[0..3] of Byte; + fsSelection : TT_UShort; + usFirstCharIndex : TT_UShort; + usLastCharIndex : TT_UShort; + sTypoAscender : TT_Short; + sTypoDescender : TT_Short; + sTypoLineGap : TT_Short; + usWinAscent : TT_UShort; + usWinDescent : TT_UShort; + + (* only version 1 tables *) + ulCodePageRange1 : TT_ULong; + ulCodePageRange2 : TT_ULong; + end; + + (******************************************************) + (* The TrueType Postscript table structure *) + (* *) + TT_Postscript = record + + FormatType : TT_Fixed; + italicAngle : TT_Fixed; + underlinePosition : TT_Short; + underlineThickness : TT_Short; + isFixedPitch : TT_ULong; + minMemType42 : TT_ULong; + maxMemType42 : TT_ULong; + minMemType1 : TT_ULong; + maxMemType1 : TT_ULong; + end; + + (******************************************************) + (* face properties. use to report important face *) + (* data to clients *) + (* *) + TT_Face_Properties = record + + num_glyphs : integer; + max_points : integer; + max_contours : integer; + max_faces : integer; + + header : ^TT_Header; + horizontal : ^TT_Horizontal_Header; + vertical : ^TT_Vertical_Header; + os2 : ^TT_OS2; + postscript : ^TT_Postscript; + end; + + (******************************************************) + (* Objects handle types *) + (* *) + TT_Stream = record z : Pointer; end; + TT_Face = record z : Pointer; end; + TT_Instance = record z : Pointer; end; + TT_Glyph = record z : Pointer; end; + TT_CharMap = record z : Pointer; end; + + TT_Gray_Palette = array[0..4] of byte; + + (******************************************************************) + (* *) + (* ERROR CODES *) + (* *) + (******************************************************************) + +const + (* ------------------- Success is always 0 ---------------------- *) + + TT_Err_Ok = 0; + + (* -------------------------------------------------------------- *) + + TT_Err_Invalid_Face_Handle = $0001; + TT_Err_Invalid_Instance_Handle = $0002; + TT_Err_Invalid_Glyph_Handle = $0003; + TT_Err_Invalid_CharMap_Handle = $0004; + TT_Err_Invalid_Result_Address = $0005; + TT_Err_Invalid_Glyph_Index = $0006; + TT_Err_Invalid_Argument = $0007; + TT_Err_Could_Not_Open_File = $0008; + TT_Err_File_Is_Not_Collection = $0009; + + TT_Err_Table_Missing = $000A; + TT_Err_Invalid_Horiz_Metrics = $000B; + TT_Err_Invalid_Vert_Metrics = $000B; + TT_Err_Invalid_CharMap_Format = $000C; + + TT_Err_Invalid_File_Format = $0010; + TT_Err_File_Error = $0011; + + TT_Err_Invalid_Engine = $0020; + TT_Err_Too_Many_Extensions = $0021; + TT_Err_Extensions_Unsupported = $0022; + TT_Err_Invalid_Extension_Id = $0023; + + TT_Err_No_Vertical_Data = $0030; + + TT_Err_Max_Profile_Missing = $0080; + TT_Err_Header_Table_Missing = $0081; + TT_Err_Horiz_Header_Missing = $0082; + TT_Err_Locations_Missing = $0083; + TT_Err_Name_Table_Missing = $0084; + TT_Err_CMap_Table_Missing = $0085; + TT_Err_Hmtx_Table_Missing = $0086; + TT_Err_OS2_Table_Missing = $0087; + TT_Err_Post_Table_Missing = $0088; + + (* -------------------------------------------------------------- *) + + TT_Err_Out_Of_Memory = $0100; + + (* -------------------------------------------------------------- *) + + TT_Err_Invalid_File_Offset = $0200; + TT_Err_Invalid_File_Read = $0201; + TT_Err_Invalid_Frame_Access = $0202; + + (* -------------------------------------------------------------- *) + + TT_Err_Too_Many_Points = $0300; + TT_Err_Too_Many_Contours = $0301; + TT_Err_Invalid_Composite = $0302; + TT_Err_Too_Many_Ins = $0303; + + (* -------------------------------------------------------------- *) + + TT_Err_Invalid_Opcode = $0400; + TT_Err_Too_Few_Arguments = $0401; + TT_Err_Stack_Overflow = $0402; + TT_Err_Code_Overflow = $0403; + TT_Err_Bad_Argument = $0404; + TT_Err_Divide_By_Zero = $0405; + TT_Err_Storage_Overflow = $0406; + TT_Err_Cvt_Overflow = $0407; + TT_Err_Invalid_Reference = $0408; + TT_Err_Invalid_Distance = $0409; + TT_Err_Interpolate_Twilight = $040A; + TT_Err_Debug_Opcode = $040B; + TT_Err_ENDF_In_Exec_Stream = $040C; + TT_Err_Out_Of_CodeRanges = $040D; + TT_Err_Nested_DEFs = $040E; + TT_Err_Invalid_CodeRange = $040F; + TT_Err_Invalid_Displacement = $0410; + TT_Err_Execution_Too_Long = $0411; + TT_Err_Too_Many_FuncDefs = $0412; + TT_Err_Too_Many_InsDefs = $0413; + + TT_Err_Nested_Frame_Access = $0500; + TT_Err_Invalid_Cache_List = $0501; + TT_Err_Could_Not_Find_Context = $0502; + TT_Err_UNlisted_Object = $0503; + + TT_Err_Raster_Pool_Overflow = $0600; + TT_Err_Raster_Negative_Height = $0601; + TT_Err_Invalid_Value = $0602; + TT_Err_Raster_Not_Initialised = $0603; + + (* -------------------------------------------------------------- *) + + (***********************************************************************) + (* *) + (* Base Library Functions *) + (* *) + (***********************************************************************) + + (*****************************************************************) + (* Initialise the engine *) + (* *) + function TT_Init_FreeType : TT_Error; + + (*****************************************************************) + (* Finalise the engine - discards all objects *) + (* *) + procedure TT_Done_FreeType; + + (*****************************************************************) + (* Set the gray-level palette used for font-smoothing *) + (* *) + (* it is an array of 5 bytes following this convention : *) + (* *) + (* palette[0] := background (white) *) + (* palette[1] := light *) + (* palette[2] := medium *) + (* palette[3] := dark *) + (* palette[4] := foreground (black) *) + (* *) + function TT_Set_Raster_Palette( palette : TT_Gray_Palette ) : TT_Error; + + (***********************************************************************) + (* *) + (* Face Management functions *) + (* *) + (***********************************************************************) + + (*****************************************************************) + (* Open a new font file and returns a handle for it in '_face' *) + (* *) + (* The file can be a TrueType collection, in which case the *) + (* first embedded font will be loaded. *) + (* *) + function TT_Open_Face( fontname : string; + var _face : TT_Face ) : TT_Error; + + (*****************************************************************) + (* Open a font file embedded in a collection. *) + (* *) + function TT_Open_Collection( fontname : string; + faceIndex : integer; + var _face : TT_Face ) : TT_Error; + + (*****************************************************************) + (* Return face properties in 'prop' *) + (* *) + function TT_Get_Face_Properties( _face : TT_Face; + var prop : TT_Face_Properties ) : TT_Error; + + (*****************************************************************) + (* Set face's generic pointer *) + (* *) + function TT_Set_Face_Pointer( _face : TT_Face; + data : Pointer ) : TT_Error; + + (*****************************************************************) + (* Get face's generic pointer *) + (* *) + function TT_Get_Face_Pointer( _face : TT_Face ) : Pointer; + + (*****************************************************************) + (* close a given face object. This releases all child objects *) + (* like instances and glyphs *) + (* *) + function TT_Close_Face( _face : TT_Face ) : TT_Error; + + (***********************************************************************) + (* *) + (* Instance management functions *) + (* *) + (***********************************************************************) + + (*****************************************************************) + (* open a new face instance and return a handle in '_ins' *) + (* *) + function TT_New_Instance( _face : TT_Face; + var _ins : TT_Instance ) : TT_Error; + + (*****************************************************************) + (* set an instance's device resolutions, expressed in dpi *) + (* *) + function TT_Set_Instance_Resolutions( _ins : TT_Instance; + x_resolution : Integer; + y_resolution : Integer ) : TT_Error; + + (*****************************************************************) + (* set an instance's point size (assumes width==height) *) + (* *) + function TT_Set_Instance_PointSize( _ins : TT_Instance; + pointsize : Integer ) : TT_Error; + + (*****************************************************************) + (* set an instance's point size (assumes width==height) *) + (* *) + function TT_Set_Instance_CharSize( _ins : TT_Instance; + charsize : Integer ) : TT_Error; + + (*****************************************************************) + (* set an instance's point size (assumes width==height) *) + (* *) + function TT_Set_Instance_CharSizes( _ins : TT_Instance; + charsizex : Integer; + charsizey : Integer ) : TT_Error; + + (*****************************************************************) + (* set an instance's height and width, expressed in pixels *) + (* *) + function TT_Set_Instance_PixelSizes( _ins : TT_Instance; + pixelX : Integer; + pixelY : Integer; + pointsize : Integer ) : TT_Error; + + (*****************************************************************) + (* set an instance's height and width, expressed in pixels *) + (* *) + + (*****************************************************************) + (* the core truetype engine doesn't provide _direct_ support *) + (* for rotation or stretching. This means that the transforms *) + (* must be applied on the glyph outline by a higher-level *) + (* library or the client application. However, we use two flags *) + (* to notice the TrueType hinter that the glyphs will be *) + (* transformed later. *) + (* *) + (* rotated : set if the glyphs are to be rotated *) + (* distorted : set if the glyphs are to be distorted *) + (* *) + (* an application is any transform that doesn't keep distances *) + (* constants. skewing and stretching are examples of distorsion *) + (* *) + function TT_Set_Instance_Transforms( _ins : TT_Instance; + rotated : Boolean; + distorted : Boolean ) : TT_Error; + + (*****************************************************************) + (* Return instance metrics in 'm' *) + (* *) + function TT_Get_Instance_Metrics( _ins : TT_Instance; + var m : TT_Instance_Metrics ) : TT_Error; + + (*****************************************************************) + (* Set instance generic pointer *) + (* *) + function TT_Set_Instance_Pointer( _ins : TT_Instance; + data : Pointer ) : TT_Error; + + (*****************************************************************) + (* Get instance generic pointer *) + (* *) + function TT_Get_Instance_Pointer( _ins : TT_Instance ) : Pointer; + + (*****************************************************************) + (* Close an instance *) + (* *) + function TT_Done_Instance( _ins : TT_Instance ) : TT_Error; + + (***********************************************************************) + (* *) + (* Glyph management functions *) + (* *) + (***********************************************************************) + + (*****************************************************************) + (* Create a new glyph container, return a handle in '_glyph' *) + (* *) + function TT_New_Glyph( _face : TT_Face; + var _glyph : TT_Glyph ) : TT_Error; + + (*****************************************************************) + (* Releases a glyph container *) + (* *) + function TT_Done_Glyph( _glyph : TT_Glyph ) : TT_Error; + + (*****************************************************************) + (* Load a glyph inside a container *) + (* *) + function TT_Load_Glyph( _instance : TT_Instance; + _glyph : TT_Glyph; + glyph_index : Word; + load_flags : Integer ) : TT_Error; + +const + TT_Load_Scale_Glyph = 1; (* ask the loader to scale the glyph *) + (* to the current pointsize/transform *) + + TT_Load_Hint_Glyph = 2; (* when scaling is on, ask the loader *) + (* to hint the glyph too.. *) + + TT_Load_Debug = 16; + + TT_Load_Default = TT_Load_Scale_Glyph or + TT_Load_Hint_Glyph; + + + (*****************************************************************) + (* Get a glyph's outline *) + (* *) + function TT_Get_Glyph_Outline( _glyph : TT_Glyph; + var outline : TT_Outline ) : TT_Error; + + (*****************************************************************) + (* Get a glyph's metrics *) + (* *) + function TT_Get_Glyph_Metrics( _glyph : TT_Glyph; + var gmetrics : TT_Glyph_Metrics ) : TT_Error; + + (*****************************************************************) + (* Get a glyph's big metrics *) + (* *) + function TT_Get_Glyph_Big_Metrics( _glyph : TT_Glyph; + var gmetrics : TT_Big_Glyph_Metrics + ) : TT_Error; + + (*****************************************************************) + (* Render a glyph's bitmap *) + (* *) + function TT_Get_Glyph_Bitmap( _glyph : TT_Glyph; + var map : TT_Raster_Map; + x_offset : TT_F26Dot6; + y_offset : TT_F26Dot6 ) : TT_Error; + + (*****************************************************************) + (* Render a glyph's pixmap (i.e. smoothed glyph ) *) + (* *) + function TT_Get_Glyph_Pixmap( _glyph : TT_Glyph; + var map : TT_Raster_Map; + x_offset : TT_F26Dot6; + y_offset : TT_F26Dot6 ) : TT_Error; + + (***********************************************************************) + (* *) + (* Outline functions *) + (* *) + (***********************************************************************) + + (*****************************************************************) + (* Apply translation to an outline *) + (* *) + function TT_Translate_Outline( var out : TT_Outline; + x, y : TT_F26Dot6 ) : TT_Error; + + (*****************************************************************) + (* Apply a 2x2 transform to an outline *) + (* *) + function TT_Transform_Outline( var out : TT_Outline; + var mat : TT_Matrix ) : TT_Error; + + (*****************************************************************) + (* Apply a 2x2 transform to a vector *) + (* *) + function TT_Transform_Vector( var x, y : TT_F26Dot6; + var mat : TT_Matrix ) : TT_Error; + + (*****************************************************************) + (* Render an outline into a bitmap *) + (* *) + function TT_Get_Outline_Bitmap( var out : TT_Outline; + var map : TT_raster_Map ) : TT_Error; + + (*****************************************************************) + (* Render an outline into a pixmap *) + (* *) + function TT_Get_Outline_Pixmap( var out : TT_Outline; + var map : TT_raster_Map ) : TT_Error; + + + (*****************************************************************) + (* Get an outline's bounding box *) + (* *) + function TT_Get_Outline_BBox( var out : TT_Outline; + var bbox : TT_Bbox ) : TT_Error; + + (*****************************************************************) + (* Create a new glyph outline *) + (* *) + function TT_New_Outline( n_points : integer; + n_contours : integer; + var out : TT_Outline ) : TT_Error; + + (*****************************************************************) + (* Copy a glyph outline into another one *) + (* *) + function TT_Copy_Outline( var source : TT_Outline; + var target : TT_Outline ) : TT_Error; + + (*****************************************************************) + (* Clone a given outline. This will create the outline, then *) + (* copy the source in it *) + (* *) + function TT_Clone_Outline( var source : TT_Outline; + var target : TT_Outline ) : TT_Error; + + (*****************************************************************) + (* Discards a glyph outline *) + (* *) + function TT_Done_Outline( var out : TT_Outline ) : TT_Error; + + (***********************************************************************) + (* *) + (* Character Mapping support *) + (* *) + (***********************************************************************) + + (*****************************************************************) + (* Get a face's number of character maps *) + (* *) + function TT_Get_CharMap_Count( face : TT_Face ) : integer; + + (*****************************************************************) + (* Get a given char. map's ID in a face *) + (* *) + function TT_Get_CharMap_ID( face : TT_Face; + charmapIndex : integer; + var platform : integer; + var encoding : integer ) : TT_Error; + + (*****************************************************************) + (* Get a handle to a given char. map *) + (* *) + function TT_Get_CharMap( face : TT_Face; + charmapIndex : integer; + var charMap : TT_CharMap ) : TT_Error; + + (*****************************************************************) + (* Translate from char. code to glyph index *) + (* *) + function TT_Char_Index( charmap : TT_CharMap; + charCode : Longint ) : Word; + + (***********************************************************************) + (* *) + (* Names Table support *) + (* *) + (***********************************************************************) + + (*****************************************************************) + (* Return number of name table entries *) + (* *) + function TT_Get_Name_Count( face : TT_Face ) : integer; + + (*****************************************************************) + (* Return the ID of a given name table entry *) + (* *) + function TT_Get_Name_ID( face : TT_Face; + nameIndex : integer; + var platform : integer; + var encoding : integer; + var language : integer; + var nameid : integer ) : TT_Error; + + (*****************************************************************) + (* Return a given name table string *) + (* *) + function TT_Get_Name_String( face : TT_Face; + nameIndex : integer; + var str : Pointer; + var len : integer ) : TT_Error; + + (***********************************************************************) + (* *) + (* Font Storage Access *) + (* *) + (***********************************************************************) + + (*****************************************************************) + (* Access font data and copies it into user block *) + (* *) + function TT_Get_Font_Data( face : TT_Face; + tableTag : Longint; + offset : Longint; + var buffer; + var length : longint ) : TT_Error; + +implementation + +uses + TTTypes, + TTError, + TTCalc, + TTMemory, + TTTables, + TTCache, + TTFile, + TTCMap, + TTObjs, + TTLoad, + TTGLoad, + TTRaster, + TTInterp; + +var + raster_palette : TT_Gray_Palette; + + (*****************************************************************) + (* *) + (* *) + function TT_Init_FreeType : TT_Error; + begin + if TTMemory_Init or + TTCache_Init or + TTFile_Init or + TTObjs_Init or + TTRaster_Init then + begin + TT_Init_FreeType := error; + exit; + end; + + TT_Init_FreeType := TT_Err_Ok; + end; + + + (*****************************************************************) + (* *) + (* *) + procedure TT_Done_FreeType; + begin + TTRaster_Done; + TTObjs_Done; + TTFile_Done; + TTCache_Done; + TTMemory_Done; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Set_Raster_Palette( palette : TT_Gray_Palette ) : TT_Error; + begin + raster_palette := palette; + TT_Set_Raster_Palette := TT_Err_Ok; + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Open_Face( fontname : string; + var _face : TT_Face ) : TT_Error; + var + input : TFont_Input; + begin + input.fontIndex := 0; + + if TT_Open_Stream( fontname, input.stream ) then + begin + TT_Open_Face := error; + exit; + end; + + Cache_New( face_cache, Pointer(_face), @input ); + + TT_Open_Face := error; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Open_Collection( fontname : string; + faceIndex : integer; + var _face : TT_Face ) : TT_Error; + var + input : TFont_Input; + begin + input.fontIndex := faceIndex; + + if TT_Open_Stream( fontname, input.stream ) then + begin + TT_Open_Collection := error; + exit; + end; + + Cache_New( face_cache, Pointer(_face), @input ); + + TT_Open_Collection := error; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Get_Face_Properties( _face : TT_Face; + var prop : TT_Face_Properties ) : TT_Error; + var + face : PFace; + begin + face := _face.z; + if face <> nil then + begin + with prop do + begin + num_Glyphs := face^.numGlyphs; + max_Points := face^.maxPoints; + max_Contours := face^.maxContours; + max_Faces := face^.ttcHeader.dirCount; + header := @face^.fontHeader; + horizontal := @face^.horizontalHeader; + + if face^.verticalInfo then + vertical := @face^.verticalHeader + else + vertical := nil; + + os2 := @face^.os2; + postscript := @face^.postscript; + end; + TT_Get_Face_Properties := TT_Err_Ok; + end + else + TT_Get_Face_Properties := TT_Err_Invalid_Face_Handle; + end; + + + (*****************************************************************) + (* Set face's generic pointer *) + (* *) + function TT_Set_Face_Pointer( _face : TT_Face; + data : Pointer ) : TT_Error; + var + face :PFace; + begin + face := PFace(_face.z); + if face <> nil then + begin + face^.generic := data; + TT_Set_Face_Pointer := TT_Err_Ok; + end + else + TT_Set_Face_Pointer := TT_Err_Invalid_Face_Handle; + end; + + (*****************************************************************) + (* Get face's generic pointer *) + (* *) + function TT_Get_Face_Pointer( _face : TT_Face ) : Pointer; + var + face : PFace; + begin + face := PFace(_face.z); + if face <> nil then + TT_Get_Face_Pointer := face^.generic + else + TT_get_Face_Pointer := nil; + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Close_Face( _face : TT_Face ) : TT_Error; + var + face : PFace; + begin + face := _face.z; + if face <> nil then + begin + error := TT_Err_Ok; + (* Note : the stream is closed by the face destructor !! *) + Cache_Done( face_cache, _face.z ); + TT_Close_Face := error; + end + else + TT_Close_Face := TT_Err_Invalid_Face_Handle; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_New_Instance( _face : TT_Face; + var _ins : TT_Instance ) : TT_Error; + var + face : PFace; + ins : PInstance; + begin + face := _face.z; + if face <> nil then + begin + error := TT_Err_Ok; + if not Cache_New( face^.instances, _ins.z, face ) then + Instance_Init( _ins.z ); + TT_New_Instance := error; + end + else + TT_New_Instance := TT_Err_Invalid_Face_Handle; + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Set_Instance_Resolutions( _ins : TT_Instance; + x_resolution : Integer; + y_resolution : Integer ) : TT_Error; + var + ins : PInstance; + begin + ins := _ins.z; + if ins <> nil then + begin + ins^.metrics.x_resolution := x_resolution; + ins^.metrics.y_resolution := y_resolution; + ins^.valid := False; + TT_Set_Instance_Resolutions := TT_Err_Ok; + end + else + TT_Set_Instance_Resolutions := TT_Err_Invalid_Instance_Handle; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Set_Instance_CharSize( _ins : TT_Instance; + charsize : Integer ) : TT_Error; + var + ins : PInstance; + begin + TT_Set_Instance_CharSize := + TT_Set_Instance_CharSizes( _ins, charsize, charsize ); + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Set_Instance_CharSizes( _ins : TT_Instance; + charsizex : Integer; + charsizey : Integer ) : TT_Error; + var + ins : PInstance; + begin + if (charsizex < 1*64) or (charsizey < 1*64) then + begin + TT_Set_Instance_CharSizes := TT_Err_Bad_Argument; + exit; + end; + + ins := _ins.z; + if ins <> nil then + begin + with ins^.metrics do + begin + x_scale1 := ( Long(charsizex) * x_resolution ) div 72; + x_scale2 := ins^.owner^.fontHeader.units_per_EM; + + y_scale1 := ( Long(charsizey) * y_resolution ) div 72; + y_scale2 := x_scale2; + + if ins^.owner^.fontHeader.flags and 8 <> 0 then + begin + x_scale1 := (x_scale1 + 32) and -64; + y_scale1 := (y_scale1 + 32) and -64; + end; + + x_ppem := x_scale1 div 64; + y_ppem := y_scale1 div 64; + end; + + if charsizex > charsizey then + ins^.metrics.pointsize := charsizex + else + ins^.metrics.pointsize := charsizey; + + ins^.valid := False; + TT_Set_Instance_CharSizes := TT_Err_Ok; + end + else + TT_Set_Instance_CharSizes := TT_Err_Invalid_Instance_Handle; + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Set_Instance_PointSize( _ins : TT_Instance; + pointsize : integer ) : TT_Error; + begin + TT_Set_Instance_PointSize := + TT_Set_Instance_CharSize( _ins, pointsize*64 ); + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Set_Instance_PixelSizes( _ins : TT_Instance; + pixelX : Integer; + pixelY : Integer; + pointsize : Integer ) : TT_Error; + var + ins : PInstance; + begin + ins := _ins.z; + if ins <> nil then + begin + ins^.metrics.x_ppem := pixelX; + ins^.metrics.y_ppem := pixelY; + ins^.metrics.pointSize := pointsize; + + ins^.metrics.x_scale1 := ins^.metrics.x_ppem * 64; + ins^.metrics.x_scale2 := ins^.owner^.fontHeader.units_per_EM; + ins^.metrics.y_scale1 := ins^.metrics.y_ppem * 64; + ins^.metrics.y_scale2 := ins^.metrics.x_scale2; + + ins^.valid := false; + + TT_Set_Instance_PixelSizes := TT_Err_Ok; + end + else + TT_Set_Instance_PixelSizes := TT_Err_Invalid_Instance_Handle; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Set_Instance_Transforms( _ins : TT_Instance; + rotated : Boolean; + distorted : Boolean ) : TT_Error; + var + ins : PInstance; + begin + ins := _ins.z; + if ins <> nil then + begin + ins^.metrics.rotated := rotated; + ins^.metrics.stretched := distorted; + TT_Set_Instance_Transforms := TT_Err_Ok; + end + else + TT_Set_Instance_Transforms := TT_Err_Invalid_Instance_Handle; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Get_Instance_Metrics( _ins : TT_Instance; + var m : TT_Instance_Metrics ) : TT_Error; + var + ins : PInstance; + begin + ins := _ins.z; + if ins <> nil then + begin + if not ins^.valid then + if Instance_Reset( ins, False ) then + begin + TT_Get_Instance_Metrics := error; + exit; + end; + + with m do + begin + pointSize := ins^.metrics.pointSize; + + x_scale := MulDiv_Round( $10000, + ins^.metrics.x_scale1, + ins^.metrics.x_scale2 ); + + y_scale := MulDiv_Round( $10000, + ins^.metrics.y_scale1, + ins^.metrics.y_scale2 ); + + x_resolution := ins^.metrics.x_resolution; + y_resolution := ins^.metrics.y_resolution; + + x_ppem := ins^.metrics.x_ppem; + y_ppem := ins^.metrics.y_ppem; + + TT_Get_Instance_Metrics := TT_Err_Ok; + end; + end + else + TT_Get_Instance_Metrics := TT_Err_Invalid_Instance_Handle; + end; + + + (*****************************************************************) + (* Set instance generic pointer *) + (* *) + function TT_Set_Instance_Pointer( _ins : TT_Instance; + data : Pointer ) : TT_Error; + var + ins : PInstance; + begin + ins := PInstance(_ins.z); + if ins <> nil then + begin + ins^.generic := data; + TT_Set_Instance_Pointer := TT_Err_Ok; + end + else + TT_Set_Instance_Pointer := TT_Err_Invalid_Instance_Handle; + end; + + (*****************************************************************) + (* Get instance generic pointer *) + (* *) + function TT_Get_Instance_Pointer( _ins : TT_Instance ) : Pointer; + var + ins : PInstance; + begin + ins := PInstance(_ins.z); + if ins <> nil then + TT_Get_Instance_Pointer := ins^.generic + else + TT_Get_Instance_Pointer := nil; + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Done_Instance( _ins : TT_Instance ) : TT_Error; + var + ins : PInstance; + begin + ins := PInstance(_ins.z); + if ins <> nil then + begin + error := TT_Err_Ok; + Cache_Done( ins^.owner^.instances, ins ); + TT_Done_Instance := error; + end + else + TT_Done_Instance := TT_Err_Invalid_Instance_Handle; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_New_Glyph( _face : TT_Face; + var _glyph : TT_Glyph ) : TT_Error; + var + face : PFace; + begin + face := PFace(_face.z); + if face <> nil then + begin + error := TT_Err_Ok; + Cache_New( face^.glyphs, _glyph.z, _face.z ); + TT_New_Glyph := error; + end + else + TT_New_Glyph := TT_Err_Invalid_Face_Handle; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Done_Glyph( _glyph : TT_Glyph ) : TT_Error; + var + glyph : PGlyph; + begin + glyph := PGlyph(_glyph.z); + if glyph <> nil then + begin + error := TT_Err_Ok; + Cache_Done( glyph^.face^.glyphs, glyph ); + TT_Done_Glyph := error; + end + else + TT_Done_Glyph := TT_Err_Invalid_Glyph_Handle; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Load_Glyph( _instance : TT_Instance; + _glyph : TT_Glyph; + glyph_index : Word; + load_flags : Integer ) : TT_Error; + var + ins : PInstance; + glyph : PGlyph; + begin + ins := PInstance(_instance.z); + if ins = nil then + begin + TT_Load_Glyph := TT_Err_Invalid_Instance_Handle; + exit; + end; + + glyph := PGlyph(_glyph.z); + if glyph = nil then + begin + TT_Load_Glyph := TT_Err_Invalid_Glyph_Handle; + exit; + end; + + if ins^.owner <> glyph^.face then + begin + TT_Load_Glyph := TT_Err_Invalid_Face_Handle; + exit; + end; + + if not ins^.valid then + if Instance_Reset( ins, False ) then + begin + TT_Load_Glyph := error; + exit; + end; + + error := TT_Err_Ok; + Load_TrueType_Glyph( ins, glyph, glyph_index, load_flags ); + TT_Load_Glyph := error; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Get_Glyph_Outline( _glyph : TT_Glyph; + var outline : TT_Outline ) : TT_Error; + var + glyph : PGlyph; + begin + glyph := PGlyph(_glyph.z); + if glyph <> nil then + begin + outline := glyph^.outline; + outline.owner := false; + TT_Get_Glyph_Outline := TT_Err_Ok; + end + else + TT_Get_Glyph_Outline := TT_Err_Invalid_Glyph_Handle; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Get_Glyph_Metrics( _glyph : TT_Glyph; + var gmetrics : TT_Glyph_Metrics ) : TT_Error; + var + glyph : PGlyph; + begin + glyph := PGlyph(_glyph.z); + if glyph <> nil then + begin + gmetrics.bbox := glyph^.metrics.bbox; + gmetrics.bearingX := glyph^.metrics.horiBearingX; + gmetrics.bearingY := glyph^.metrics.horiBearingY; + gmetrics.advance := glyph^.metrics.horiAdvance; + TT_Get_Glyph_Metrics := TT_Err_Ok; + end + else + TT_Get_Glyph_Metrics := TT_Err_Invalid_Glyph_Handle; + end; + + (*****************************************************************) + (* Get a glyph's big metrics *) + (* *) + function TT_Get_Glyph_Big_Metrics( _glyph : TT_Glyph; + var gmetrics : TT_Big_Glyph_Metrics + ) : TT_Error; + var + glyph : PGlyph; + begin + glyph := PGlyph(_glyph.z); + if glyph <> nil then + begin + gmetrics := glyph^.metrics; + TT_Get_Glyph_Big_Metrics := TT_Err_Ok; + end + else + TT_Get_Glyph_Big_Metrics := TT_Err_Invalid_Glyph_Handle; + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Get_Glyph_Bitmap( _glyph : TT_Glyph; + var map : TT_raster_Map; + x_offset : TT_F26Dot6; + y_offset : TT_F26Dot6 ) : TT_Error; + var + glyph : PGlyph; + outline : TT_Outline; + n : Int; + begin + glyph := _glyph.z; + if glyph <> nil then + begin + outline := glyph^.outline; + (* XXX: for now, we only use dropout mode #2 *) + outline.dropout_mode := 2; + + TT_Translate_Outline( outline, x_offset, y_offset ); + TT_Get_Glyph_Bitmap := TT_Get_Outline_Bitmap( outline, map ); + TT_Translate_Outline( outline, -x_offset, -y_offset ); + end + else + TT_Get_Glyph_Bitmap := TT_Err_Invalid_Glyph_Handle; + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Get_Glyph_Pixmap( _glyph : TT_Glyph; + var map : TT_raster_Map; + x_offset : TT_F26Dot6; + y_offset : TT_F26Dot6 ) : TT_Error; + var + glyph : PGlyph; + outline : TT_Outline; + n : Int; + begin + glyph := _glyph.z; + if glyph <> nil then + begin + outline := glyph^.outline; + (* XXX: for now, we only use dropout mode #2 *) + outline.dropout_mode := 2; + + TT_translate_Outline( outline, x_offset, y_offset ); + TT_Get_Glyph_Pixmap := TT_Get_Outline_Pixmap( outline, map ); + TT_translate_Outline( outline, -x_offset, -y_offset ); + end + else + TT_Get_Glyph_Pixmap := TT_Err_Invalid_Glyph_Handle; + end; + + (*****************************************************************) + (* Create a new glyph outline *) + (* *) + function TT_New_Outline( n_points : integer; + n_contours : integer; + var out : TT_Outline ) : TT_Error; + label + Fail; + begin + out.n_points := n_points; + out.n_contours := n_contours; + out.points := nil; + out.flags := nil; + out.conEnds := nil; + out.owner := true; + + if Alloc( Pointer(out.points), 2*n_points*sizeof(TT_Pos) ) or + Alloc( Pointer(out.flags), n_points*sizeof(Byte) ) or + Alloc( Pointer(out.conEnds), n_contours*sizeof(Short) ) then + goto Fail; + + TT_New_Outline := TT_Err_Ok; + exit; + + Fail: + TT_Done_Outline( out ); + TT_New_Outline := error; + end; + + (*****************************************************************) + (* Copy a glyph outline into another one *) + (* *) + function TT_Copy_Outline( var source : TT_Outline; + var target : TT_Outline ) : TT_Error; + begin + if (source.n_points = target.n_points) and + (source.n_contours = target.n_contours) then + begin + move( source.points^, target.points^, 2*source.n_points*4 ); + move( source.flags^, target.flags^, source.n_points ); + move( source.conEnds^,target.conEnds^, source.n_contours*2 ); + end + else + TT_Copy_Outline := TT_Err_Invalid_Argument; + end; + + (*****************************************************************) + (* Clone a given outline. This will create the outline, then *) + (* copy the source in it *) + (* *) + function TT_Clone_Outline( var source : TT_Outline; + var target : TT_Outline ) : TT_Error; + begin + error := TT_New_Outline( source.n_points, source.n_contours, target ); + if error = TT_Err_Ok then + TT_Copy_Outline( source, target ); + + TT_Clone_Outline := error; + end; + + (*****************************************************************) + (* Discards a glyph outline *) + (* *) + function TT_Done_Outline( var out : TT_Outline ) : TT_Error; + begin + if out.owner then + begin + Free( Pointer(out.conEnds) ); + Free( Pointer(out.flags) ); + Free( Pointer(out.points) ); + out.n_points := 0; + out.n_contours := 0; + TT_Done_Outline := TT_Err_Ok; + end + else + TT_Done_Outline := TT_Err_Invalid_Argument; + end; + + (*****************************************************************) + (* Render an outline into a bitmap *) + (* *) + function TT_Get_Outline_Bitmap( var out : TT_Outline; + var map : TT_raster_Map ) : TT_Error; + begin + if Render_Glyph( out, map ) then + TT_Get_Outline_Bitmap := error + else + TT_Get_Outline_Bitmap := TT_Err_Ok; + end; + + (*****************************************************************) + (* Render an outline into a pixmap *) + (* *) + function TT_Get_Outline_Pixmap( var out : TT_Outline; + var map : TT_raster_Map ) : TT_Error; + begin + if Render_Gray_Glyph( out, map ) then + TT_Get_Outline_Pixmap := error + else + TT_Get_Outline_Pixmap := TT_Err_Ok; + end; + + (*****************************************************************) + (* Compute an outline's bounding box *) + (* *) + function TT_Get_Outline_BBox( var out : TT_Outline; + var bbox : TT_Bbox ) : TT_Error; + var + x, y, + xMin, yMin, + xMax, yMax : TT_Pos; + n : Int; + begin + + with bbox do + begin + xMin := $7FFFFFFF; + xMax := $80000000; + yMin := $7FFFFFFF; + yMax := $80000000; + + for n := 0 to out.n_points-1 do + begin + x := out.points^[n].x; + if x < xMin then xMin := x; + if x > xMax then xMax := x; + y := out.points^[n].y; + if y < yMin then yMin := y; + if y > yMax then yMax := y; + end; + end; + + TT_Get_Outline_BBox := TT_Err_Ok; + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Translate_Outline( var out : TT_Outline; + x, y : TT_F26Dot6 ) : TT_Error; + var + n : integer; + begin + if x <> 0 then + for n := 0 to out.n_points-1 do + inc( out.points^[n].x, x ); + + if y <> 0 then + for n := 0 to out.n_points-1 do + inc( out.points^[n].y, y ); + + TT_Translate_Outline := TT_Err_Ok; + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Transform_Outline( var out : TT_Outline; + var mat : TT_Matrix ) : TT_Error; + var + n : integer; + x, y, nx, ny : TT_F26Dot6; + begin + for n := 0 to out.n_points-1 do + begin + x := out.points^[n].x; + y := out.points^[n].y; + + nx := MulDiv_Round( mat.xx, x, $10000 ) + + MulDiv_Round( mat.xy, y, $10000 ); + + ny := MulDiv_ROund( mat.yx, x, $10000 ) + + MulDiv_Round( mat.yy, y, $10000 ); + + out.points^[n].x := nx; + out.points^[n].y := ny; + end; + + TT_Transform_Outline := TT_Err_Ok; + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Transform_Vector( var x, y : TT_F26Dot6; + var mat : TT_Matrix ) : TT_Error; + var + nx, ny : TT_F26Dot6; + begin + nx := MulDiv_Round( mat.xx, x, $10000 ) + + MulDiv_Round( mat.xy, y, $10000 ); + + ny := MulDiv_Round( mat.yx, x, $10000 ) + + MulDiv_Round( mat.yy, y, $10000 ); + + x := nx; + y := ny; + + TT_Transform_Vector := TT_Err_Ok; + end; + + (***********************************************************************) + (* *) + (* Character Mapping support *) + (* *) + (***********************************************************************) + + (*****************************************************************) + (* *) + (* *) + function TT_Get_CharMap_Count( face : TT_Face ) : integer; + var + faze : PFace; + begin + faze := PFace(face.z); + if faze = nil then + TT_Get_CharMap_Count := -1 + else + TT_Get_CharMap_Count := faze^.numCMaps; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Get_CharMap_ID( face : TT_Face; + charmapIndex : integer; + var platform : integer; + var encoding : integer ) : TT_Error; + var + faze : PFace; + cmap : PCMapTable; + begin + faze := PFace(face.z); + if faze = nil then + begin + TT_Get_CharMap_ID := TT_Err_Invalid_Face_Handle; + exit; + end; + + if (charmapIndex < 0) or (charmapIndex >= faze^.numCMaps) then + begin + TT_Get_CharMap_ID := TT_Err_Invalid_Argument; + exit; + end; + + cmap := @faze^.cMaps^[charmapIndex]; + platform := cmap^.platformID; + encoding := cmap^.platformEncodingID; + + TT_Get_CharMap_ID := TT_Err_Ok; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Get_CharMap( face : TT_Face; + charmapIndex : integer; + var charMap : TT_CharMap ) : TT_Error; + var + faze : PFace; + begin + faze := PFace(face.z); + if faze = nil then + begin + TT_Get_CharMap := TT_Err_Invalid_Face_Handle; + exit; + end; + + if (charmapIndex < 0) or (charmapIndex >= faze^.numCMaps) then + begin + TT_Get_CharMap := TT_Err_Invalid_Argument; + exit; + end; + + charmap.z := @faze^.cMaps^[charmapIndex]; + + TT_Get_CharMap := TT_Err_Ok; + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Char_Index( charmap : TT_CharMap; + charCode : Longint ) : Word; + begin + TT_Char_Index := CharMap_Index( PCMapTable(charmap.z)^, charCode ); + end; + + (***********************************************************************) + (* *) + (* Names Table support *) + (* *) + (***********************************************************************) + + (*****************************************************************) + (* *) + (* *) + function TT_Get_Name_Count( face : TT_Face ) : integer; + var + faze : PFace; + begin + TT_Get_Name_Count := 0; + + faze := PFace( face.z ); + if faze = nil then exit; + + TT_Get_Name_Count := faze^.nameTable.numNameRecords; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Get_Name_ID( face : TT_Face; + nameIndex : integer; + var platform : integer; + var encoding : integer; + var language : integer; + var nameid : integer ) : TT_Error; + var + faze : PFace; + table : PName_Table; + rec : PName_Record; + label + Fail; + begin + faze := PFace( face.z ); + if faze = nil then + begin + TT_Get_Name_Id := TT_Err_Invalid_Face_Handle; + goto Fail; + end; + + table := @faze^.nameTable; + if (nameIndex < 0) or (nameIndex > table^.numNameRecords) then + begin + TT_Get_Name_Id := TT_Err_Bad_Argument; + goto Fail; + end; + + rec := @table^.names^[nameIndex]; + + platform := rec^.platformID; + encoding := rec^.encodingID; + language := rec^.languageID; + nameid := rec^.nameID; + + TT_Get_Name_ID := TT_Err_Ok; + exit; + + Fail: + platform := -1; + encoding := -1; + language := -1; + nameid := -1; + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Get_Name_String( face : TT_Face; + nameIndex : integer; + var str : Pointer; + var len : integer ) : TT_Error; + var + faze : PFace; + table : PName_Table; + rec : PName_Record; + label + Fail; + begin + faze := PFace( face.z ); + if faze = nil then + begin + TT_Get_Name_String := TT_Err_Invalid_Face_Handle; + goto Fail; + end; + + table := @faze^.nameTable; + if (nameIndex < 0) or (nameIndex > table^.numNameRecords) then + begin + TT_Get_Name_String := TT_Err_Bad_Argument; + goto Fail; + end; + + rec := @table^.names^[nameIndex]; + + str := @table^.storage^[rec^.offset]; + len := rec^.length; + + TT_Get_Name_String := TT_Err_Ok; + exit; + + Fail: + str := nil; + len := 0; + end; + + + (*****************************************************************) + (* Access font data and copies it into user block *) + (* *) + function TT_Get_Font_Data( face : TT_Face; + tableTag : Longint; + offset : Longint; + var buffer; + var length : longint ) : TT_Error; + var + faze : PFace; + begin + faze := PFace(face.z); + if faze = nil then + begin + TT_Get_Font_Data := TT_Err_Invalid_Face_Handle; + length := 0; + end + else + begin + TT_Get_Font_Data := TT_Err_Ok; + if Load_TrueType_Any( faze, tableTag, offset, buffer, length ) then + TT_Get_Font_Data := error; + end; + end; + + +end. + diff --git a/pascal/lib/ttcache.pas b/pascal/lib/ttcache.pas new file mode 100644 index 0000000..5af1fb9 --- /dev/null +++ b/pascal/lib/ttcache.pas @@ -0,0 +1,433 @@ +(******************************************************************* + * + * ttcache.pas 1.0 + * + * Generic object cache + * + * Copyright 1996, 1997 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * This component defines and implement object caches. + * + * An object class is a structure layout that encapsulate one + * given type of data used by the FreeType engine. Each object + * class is completely described by : + * + * - a 'root' or 'leading' structure containing the first + * important fields of the class. The root structure is + * always of fixed size. + * + * It is implemented as a simple C structure, and may + * contain several pointers to sub-tables that can be + * sized and allocated dynamically. + * + * examples : TFace, TInstance, TGlyph & TExecution_Context + * ( defined in 'ttobjs.h' ) + * + * - we make a difference between 'child' pointers and 'peer' + * pointers. A 'child' pointer points to a sub-table that is + * owned by the object, while a 'peer' pointer points to any + * other kind of data the object isn't responsible for. + * + * An object class is thus usually a 'tree' of 'child' tables. + * + * - each object class needs a constructor and a destructor. + * + * A constructor is a function which receives the address of + * freshly allocated and zeroed object root structure and + * 'builds' all the valid child data that must be associated + * to the object before it becomes 'valid'. + * + * A destructor does the inverse job : given the address of + * a valid object, it must discards all its child data and + * zero its main fields (essentially the pointers and array + * sizes found in the root fields). + * + * + * + * + * + * + * + * + * + * + * + * + ******************************************************************) + +unit TTCache; + +interface + +uses TTError, TTTypes; + +type + + (* Simple list node record. A List element is said to be 'unlinked' *) + (* when it doesn't belong to any list *) + (* *) + PList_Element = ^TList_Element; + TList_Element = record + + next : PList_Element; (* Pointer to next element of list *) + data : Pointer; (* Pointer to the listed object *) + end; + + + (* Simple singly-linked list record *) + (* LIFO - style, no tail field *) + TSingle_List = PList_Element; + + + TConstructor = function( _object : Pointer; + _parent : Pointer ) : TError; + + TDestructor = function( _object : Pointer ) : TError; + + PCache_Class = ^TCache_Class; + TCache_Class = record + Object_Size : Int; + Idle_Limit : Int; + Init : TConstructor; + Done : TDestructor; + end; + (* A Cache class record holds the data necessary to define *) + (* a cache kind. *) + + PCache = ^TCache; + TCache = record + clazz : PCache_Class; (* 'class' reserved in VP & Delphi *) + active : TSingle_List; + idle : TSingle_List; + idle_count : Int; + end; + + (* An object cache holds two lists tracking the active and *) + (* idle objects that are currently created and used by the *) + (* engine. It can also be 'protected' by a mutex *) + + function Cache_Create( var clazz : TCache_Class; + var cache : TCache ) : TError; + (* Initialize a new cache named 'cache', of class 'clazz', and *) + (* protected by the 'lock' mutex. Note that the mutex is ignored *) + (* as the pascal version isn't thread-safe *) + + function Cache_Destroy( var cache : TCache ) : TError; + (* Destroys a cache and all its listed objects *) + + function Cache_New( var cache : TCache; + var new_object : Pointer; + parent_data : Pointer ) : TError; + (* Extracts a new object from the cache. *) + + function Cache_Done( var cache : TCache; obj : Pointer ) : TError; + (* returns an object to the cache, or discards it depending *) + (* on the cache class' "idle_limit" field *) + + (********************************************************) + (* *) + (* Two functions used to manage list elements *) + (* *) + (* Note that they're thread-safe in multi-threaded *) + (* builds. *) + (* *) + + function Element_New : PList_Element; + (* Returns a new list element, either fresh or recycled *) + (* Note : the returned element is unlinked *) + + procedure Element_Done( element : PList_Element ); + (* Recycles or discards an element. *) + (* Note : The element must be unlinked !! *) + + + + + function TTCache_Init : TError; + + function TTCache_Done : TError; + + +implementation + +uses TTMemory; + +const + Null_Single_List = nil; + +var + Free_Elements : PList_Element; + +(******************************************************************* + * + * Function : Element_New + * + * Description : Gets a new ( either fresh or recycled ) list + * element. The element is unlisted. + * + * Notes : returns nil if out of memory + * + *****************************************************************) + + function Element_New : PList_Element; + var + element : PList_Element; + begin + (* LOCK *) + + if Free_Elements <> nil then + begin + element := Free_Elements; + Free_Elements := element^.next; + end + else + begin + Alloc( element, sizeof(TList_Element) ); + (* by convention, an allocated block is always zeroed *) + (* the fields of element need not be set to NULL then *) + end; + + (* UNLOCK *) + + Element_New := element; + end; + +(******************************************************************* + * + * Function : Element_Done + * + * Description : recycles an unlisted list element + * + * Notes : Doesn't check that the element is unlisted + * + *****************************************************************) + + procedure Element_Done( element : PList_Element ); + begin + (* LOCK *) + + element^.next := Free_Elements; + Free_Elements := element; + + (* UNLOCK *) + end; + + +(******************************************************************* + * + * Function : Cache_Create + * + * Description : Create a new cache object + * + *****************************************************************) + function Cache_Create( var clazz : TCache_Class; + var cache : TCache ) : TError; + begin + cache.clazz := @clazz; + cache.idle_count := 0; + cache.active := Null_Single_List; + cache.idle := Null_Single_List; + + Cache_Create := Success; + end; + + +(******************************************************************* + * + * Function : Cache_Destroy + * + * Description : Destroy a given cache object + * + *****************************************************************) + function Cache_Destroy( var cache : TCache ) : TError; + var + destroy : TDestructor; + current : PList_Element; + next : PList_Element; + begin + (* now destroy all active and idle listed objects *) + + destroy := cache.clazz^.done; + + (* active list *) + current := cache.active; + while current <> nil do + begin + next := current^.next; + destroy( current^.data ); + Free( current^.data ); + Element_Done( current ); + current := next; + end; + cache.active := Null_SIngle_List; + + (* idle list *) + current := cache.idle; + while current <> nil do + begin + next := current^.next; + destroy( current^.data ); + Free( current^.data ); + Element_Done( current ); + current := next; + end; + cache.idle := Null_Single_List; + + cache.clazz := nil; + cache.idle_count := 0; + + Cache_Destroy := Success; + end; + + +(******************************************************************* + * + * Function : Cache_New + * + * Description : Extracts one 'new' object from a cache + * + * Notes : The 'parent_data' pointer is passed to the object's + * initialiser when the new object is created from + * scratch. Recycled objects do not use this pointer + * + *****************************************************************) + function Cache_New( var cache : TCache; + var new_object : Pointer; + parent_data : Pointer ) : TError; + var + error : TError; + current : PList_Element; + obj : Pointer; + label + Fail; + begin + (* LOCK *) + current := cache.idle; + if current <> nil then + begin + cache.idle := current^.next; + dec( cache.idle_count ) + end; + (* UNLOCK *) + + if current = nil then + begin + (* if no object was found in the cache, create a new one *) + if Alloc( obj, cache.clazz^.object_size ) then exit; + + current := Element_New; + if current = nil then goto Fail; + + current^.data := obj; + + error := cache.clazz^.init( obj, parent_data ); + if error then goto Fail; + end; + + (* LOCK *) + current^.next := cache.active; + cache.active := current; + (* UNLOCK *) + + new_object := current^.data; + + Cache_New := Success; + exit; + + Fail: + Free( obj ); + Cache_New := Failure; + end; + +(******************************************************************* + * + * Function : Cache_Done + * + * Description : Discards an object intro a cache + * + *****************************************************************) + + function Cache_Done( var cache : TCache; obj : Pointer ) : TError; + var + error : TError; + element : PList_Element; + parent : ^PList_Element; + label + Suite; + begin + Cache_Done := failure; + + (* find element in list *) + (* LOCK *) + parent := @cache.active; + element := parent^; + while element <> nil do + begin + if element^.data = obj then + begin + parent^ := element^.next; + (* UNLOCK *) + goto Suite; + end; + parent := @element^.next; + element := parent^; + end; + (* UNLOCK *) + + (* Element wasn't found !! *) + {$IFDEF DEBUG} + {$ENDIF} + exit; + + Suite: + if ( cache.idle_count >= cache.clazz^.idle_limit ) then + begin + (* destroy the object when the cache is full *) + cache.clazz^.done( element^.data ); + Free( element^.data ); + Element_Done( element ); + end + else + begin + (* simply add the object to the idle list *) + (* LOCK *) + element^.next := cache.idle; + cache.idle := element; + inc( cache.idle_count ); + (* UNLOCK *) + end; + + Cache_Done := Success; + end; + + + function TTCache_Init : TError; + begin + Free_Elements := nil; + TTCache_Init := Success; + end; + + + function TTCache_Done : TError; + var + current, next : PList_ELement; + begin + current := free_elements; + while current <> nil do + begin + next := current^.next; + Free( current ); + current := next; + end; + TTCache_Done := success; + end; + +end. diff --git a/pascal/lib/ttcalc.pas b/pascal/lib/ttcalc.pas new file mode 100644 index 0000000..2d08741 --- /dev/null +++ b/pascal/lib/ttcalc.pas @@ -0,0 +1,289 @@ +(******************************************************************* + * + * TTCalc.Pas 1.2 + * + * Arithmetic and Vectorial Computations (specification) + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTES : All vector operations were moved to the interpreter + * + ******************************************************************) + +unit TTCalc; + +interface + +{$I TTCONFIG.INC} + +type + (* IntN types : *) + (* *) + (* These types are used as a way to garantee the size of some *) + (* specific integers. *) + (* *) + (* Of course, they are equivalent to Short, UShort, Long, etc .. *) + (* but parts of this unit could be used by different programs. *) + (* *) + + (* Define the 16-bit type *) +{$IFDEF BORLANDPASCAL} + Int16 = Integer; + Word16 = Word; (* 16-bits unsigned *) +{$ELSE} +{$IFDEF DELPHI16} + Int16 = Integer; + Word16 = Word; (* 16-bits unsigned *) +{$ELSE} +{$IFDEF DELPHI32} + Int16 = SmallInt; + Word16 = Word; (* 16-bits unsigned *) +{$ELSE} + Int16 = SmallInt; + Word16 = SmallWord; (* 16-bits unsigned *) +{$ENDIF} +{$ENDIF} +{$ENDIF} + + Int32 = LongInt; (* 32 bits integer *) + + Word32 = LongInt; (* 32 bits 'unsigned'. Note that there's *) + (* no unsigned long in Pascal.. *) + (* As cardinals are only 31 bits !! *) + + Int64 = record (* 64 "" *) + Lo, + Hi : LongInt; + end; + +function MulDiv( A, B, C : Int32 ): Int32; + +function MulDiv_Round( A, B, C : Int32 ): Int32; + +procedure Add64( var X, Y, Z : Int64 ); +procedure Sub64( var X, Y, Z : Int64 ); + +procedure MulTo64( X, Y : Int32; var Z : Int64 ); + +function Div64by32( var X : Int64; Y : Int32 ) : Int32; + +function Order64( var Z : Int64 ) : integer; +function Order32( Z : Int32 ) : integer; + +function Sqrt32( L : Int32 ): LongInt; +function Sqrt64( L : Int64 ): LongInt; + +{$IFDEF TEST} + procedure Neg64( var x : Int64 ); + procedure DivMod64by32( var X : Int64; Y : Int32; var Q, R : Int32 ); +{$ENDIF} + +implementation + +(* add support for Virtual Pascal inline assembly *) +{$IFDEF VIRTUALPASCAL} +{$I TTCALC2.INC} +{$ENDIF} + +(* add support for Delphi 2 and 3 inline assembly *) +{$IFDEF DELPHI32} +{$I TTCALC3.INC} +{$ENDIF} + +(* add support for Borland Pascal and Turbo Pascal inline assembly *) +{$IFDEF BORLANDPASCAL} +{$I TTCALC1.INC} +{$ENDIF} + +(* Delphi 16 uses the same inline assembly than Borland Pascal *) +{$IFDEF DELPHI16} +{$I TTCALC1.INC} +{$ENDIF} + +(* add support for Free Pascal inline assembly *) +{$IFDEF FPK} +{$I TTCALC4.INC} +{$ENDIF} + + (*****************************************************************) + (* *) + (* MulDiv : computes A*B/C with an intermediate 64 bits *) + (* precision. *) + (* *) + (*****************************************************************) + + function MulDiv( a, b, c : Int32 ) : Int32; + var + s : Int32; + temp : Int64; + begin + s := a; a := abs(a); + s := s xor b; b := abs(b); + s := s xor c; c := abs(c); + + MulTo64( a, b, temp ); + c := Div64by32( temp, c ); + + if s < 0 then c := -c; + + MulDiv := c; + end; + + (*****************************************************************) + (* *) + (* MulDiv : computes A*B/C with an intermediate 64 bits *) + (* _Round precision and rounding. *) + (* *) + (*****************************************************************) + + function MulDiv_Round( a, b, c : Int32 ) : Int32; + var + s : Int32; + + temp, temp2 : Int64; + begin + s := a; a := abs(a); + s := s xor b; b := abs(b); + s := s xor c; c := abs(c); + + MulTo64( a, b, temp ); + + temp2.hi := 0; + temp2.lo := c div 2; + + Add64( temp, temp2, temp ); + + c := Div64by32( temp, c ); + + if s < 0 then c := -c; + + MulDiv_Round := c; + end; + + +(**********************************************************) +(* Negation *) + + procedure Neg64( var x : Int64 ); + begin + (* Remember that -(0x80000000) == 0x80000000 with 2-complement! *) + (* We take care of that here. *) + + x.hi := x.hi xor $FFFFFFFF; + x.lo := x.lo xor $FFFFFFFF; + inc( x.lo ); + + if x.lo = 0 then + begin + inc( x.hi ); + if x.hi = $80000000 then (* check -MaxInt32-1 *) + begin + dec( x.lo ); (* we return $7FFFFFFF *) + dec( x.hi ); + end; + end; + end; + + +(**********************************************************) +(* MSB index ( return -1 for 0 ) *) + +function Order64( var Z : Int64 ) : integer; +begin + if Z.Hi <> 0 then Order64 := 32 + Order32( Z.Hi ) + else Order64 := Order32( Z.Lo ); +end; + + +(**********************************************************) +(* MSB index ( return -1 for 0 ) *) + +function Order32( Z : Int32 ) : integer; +var b : integer; +begin + b := 0; + while Z <> 0 do begin Z := Z shr 1; inc( b ); end; + Order32 := b-1; +end; + + +const + Roots : array[0..62] of LongInt + = ( + 1, 1, 2, 3, 4, 5, 8, 11, + 16, 22, 32, 45, 64, 90, 128, 181, + 256, 362, 512, 724, 1024, 1448, 2048, 2896, + 4096, 5892, 8192, 11585, 16384, 23170, 32768, 46340, + + 65536, 92681, 131072, 185363, 262144, 370727, + 524288, 741455, 1048576, 1482910, 2097152, 2965820, + 4194304, 5931641, 8388608, 11863283, 16777216, 23726566, + + 33554432, 47453132, 67108864, 94906265, + 134217728, 189812531, 268435456, 379625062, + 536870912, 759250125, 1073741824, 1518500250, + 2147483647 + ); + + +(**************************************************) +(* Integer Square Root *) + +function Sqrt32( L : Int32 ): LongInt; +var + R, S : LongInt; +begin + if L<=0 then Sqrt32:=0 else + if L=1 then Sqrt32:=1 else + begin + R:=Roots[ Order32(L) ]; + + Repeat + S:=R; + R:=( R+ L div R ) shr 1; + until ( R <= S ) and ( R*R <= L ); + + Sqrt32:=R; + end; +end; + + +(**************************************************) +(* Integer Square Root *) + +function Sqrt64( L : Int64 ): LongInt; +var + L2 : Int64; + R, S : LongInt; +begin + if L.Hi < 0 then Sqrt64:=0 else + begin + S := Order64(L); + if S = 0 then Sqrt64:=1 else + begin + R := Roots[S]; + + Repeat + + S := R; + R := ( R+Div64by32(L,R) ) shr 1; + + if ( R > S ) then continue; + + MulTo64( R, R, L2 ); + Sub64 ( L, L2, L2 ); + + until ( L2.Hi >= 0 ); + + Sqrt64 := R; + end + end +end; + +end. diff --git a/pascal/lib/ttcalc1.inc b/pascal/lib/ttcalc1.inc new file mode 100644 index 0000000..4354f24 --- /dev/null +++ b/pascal/lib/ttcalc1.inc @@ -0,0 +1,124 @@ +(******************************************************************* + * + * TTCalc1.Inc 1.3 + * + * Arithmetic and Vectorial Computations (inline assembly) + * This version is used for 16-bit Turbo-Borland Pascal 6.0 & 7.0 + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTES : All vector operations were moved to the interpreter + * + ******************************************************************) + +(**********************************************************) +(* *) +(* The following routines are inline assembly, they are *) +(* thus processor and bitness specific. Replace them *) +(* with your own if you want to port the TrueType Engine *) + +(* We need unsigned longints to perform correctly our additions *) +(* we include inline assembly to get them, baaahhh .. *) + +{**********************************************************} +{* 64 Bit Addition *} + +procedure Add64( var X, Y, Z : Int64 ); assembler; +asm + les si,[X] + + mov ax,es:[ si ].word + mov dx,es:[si+2].word + mov bx,es:[si+4].word + mov cx,es:[si+6].word + + les si,[Y] + add ax,es:[ si ].word + adc dx,es:[si+2].word + adc bx,es:[si+4].word + adc cx,es:[si+6].word + + les si,[Z] + mov es:[ si ].word,ax + mov es:[si+2].word,dx + mov es:[si+4].word,bx + mov es:[si+6].word,cx +end; + + +{**********************************************************} +{* 64 Bit Substraction *} + +procedure Sub64( var X, Y, Z : Int64 ); assembler; +asm + les si,[X] + + mov ax,es:[ si ].word + mov dx,es:[si+2].word + mov bx,es:[si+4].word + mov cx,es:[si+6].word + + les si,[Y] + sub ax,es:[ si ].word + sbb dx,es:[si+2].word + sbb bx,es:[si+4].word + sbb cx,es:[si+6].word + + les si,[Z] + mov es:[ si ].word,ax + mov es:[si+2].word,dx + mov es:[si+4].word,bx + mov es:[si+6].word,cx +end; + + +{**********************************************************} +{* Multiply two Int32 to an Int64 *} + +procedure MulTo64( X, Y : Int32; var Z : Int64 ); assembler; +asm + les si,[Z] + db $66; mov ax,[X].word + db $66; imul [Y].word + db $66; mov es:[si],ax + db $66; mov es:[si+4],dx +end; + + +{**********************************************************} +{* Divide an Int64 by an Int32 *} + +function Div64by32( var X : Int64; Y : Int32 ) : Int32; assembler; +asm + les si,[X] + + db $66; mov ax,es:[si] + db $66; mov dx,es:[si+4] + db $66; idiv [Y].word + + db $66; mov dx, ax + db $66; sar dx, 16 +end; + + +procedure DivMod64by32( var X : Int64; Y : Int32; var Q, R : Int32 ); assembler; +asm + les si,[X] + + db $66; mov ax,es:[si] + db $66; mov dx,es:[si+4] + db $66; idiv [Y].word + + les si, [Q] + db $66; mov es:[si], ax + + les si, [R] + db $66; mov es:[si], dx +end; + diff --git a/pascal/lib/ttcalc2.inc b/pascal/lib/ttcalc2.inc new file mode 100644 index 0000000..341c0e8 --- /dev/null +++ b/pascal/lib/ttcalc2.inc @@ -0,0 +1,107 @@ +(******************************************************************* + * + * TTCalc2.Inc 1.2 + * + * Arithmetic and Vectorial Computations (inline assembly) + * This version is used for the OS/2 Virtual Pascal compiler + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTES : All vector operations were moved to the interpreter + * + ******************************************************************) + +(**********************************************************) +(* *) +(* The following routines are inline assembly, they are *) +(* thus processor and bitness specific. Replace them *) +(* with your own if you want to port the TrueType Engine *) + +(* We need unsigned longints to perform correctly our additions *) +(* we include inline assembly to get them, baaahhh .. *) + +(**********************************************************) +(* 64 Bit Addition *) + +procedure Add64( var X, Y, Z : Int64 ); assembler; +{&USES ebx, edx} +asm + mov ebx,[X].dword + mov eax,[ebx] + mov edx,[ebx+4] + + mov ebx,[Y].dword + add eax,[ebx] + adc edx,[ebx+4] + + mov ebx,[Z].dword + mov [ebx],eax + mov [ebx+4],edx +end; + + +(**********************************************************) +(* 64 Bit Substraction *) + +procedure Sub64( var X, Y, Z : Int64 ); assembler; +{&USES ebx, edx} +asm + mov ebx,[X].dword + mov eax,[ebx] + mov edx,[ebx+4] + + mov ebx,[Y].dword + sub eax,[ebx] + sbb edx,[ebx+4] + + mov ebx,[Z].dword + mov [ebx],eax + mov [ebx+4],edx +end; + + +(**********************************************************) +(* Multiply two Int32 to an Int64 *) + +procedure MulTo64( X, Y : Int32; var Z : Int64 ); assembler; +{&USES ebx, edx } +asm + mov ebx,[Z].dword + mov eax,[X] + imul dword ptr [Y] + mov [ebx],eax + mov [ebx+4],edx +end; + + +(**********************************************************) +(* Divide an Int64 by an Int32 *) + +function Div64by32( var X : Int64; Y : Int32 ) : Int32; assembler; +{&USES ebx, edx} +asm + mov ebx, [X].dword + mov eax, [ebx] + mov edx, [ebx+4] + idiv dword ptr [Y] +end; + +procedure DivMod64by32( var X : Int64; Y : Int32; var Q, R : Int32 ); + assembler; {&USES ebx, edx} +asm + mov ebx, [X].dword + mov eax, [ebx] + mov edx, [ebx+4] + idiv dword ptr [Y] + mov ebx, [Q].dword + mov [ebx], eax + mov ebx, [R].dword + mov [ebx], edx +end; + diff --git a/pascal/lib/ttcalc3.inc b/pascal/lib/ttcalc3.inc new file mode 100644 index 0000000..63a19a4 --- /dev/null +++ b/pascal/lib/ttcalc3.inc @@ -0,0 +1,99 @@ +(******************************************************************* + * + * TTCalc3.Inc 1.2 + * + * Arithmetic and Vectorial Computations (inline assembly) + * This version is used for Delphi 2 + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTES : All vector operations were moved to the interpreter + * + ******************************************************************) + +(**********************************************************) +(* *) +(* The following routines are inline assembly, they are *) +(* thus processor and bitness specific. Replace them *) +(* with your own if you want to port the TrueType Engine *) + +(* NOTE : Delphi seems to use the eax, edx then ecx registers to pass *) +(* the first three parameters *) + +(**********************************************************) +(* 64 Bit Addition *) + +procedure Add64( var X, Y, Z : Int64 ); assembler; +asm + push ebx + push esi + mov ebx, [ eax ] + mov esi, [eax+4] + add ebx, [ edx ] + adc esi, [edx+4] + mov [ ecx ], ebx + mov [ecx+4], esi + pop esi + pop ebx +end; + + +(**********************************************************) +(* 64 Bit Substraction *) + +procedure Sub64( var X, Y, Z : Int64 ); assembler; +asm + push ebx + push esi + mov ebx, [ eax ] + mov esi, [eax+4] + sub ebx, [ edx ] + sbb esi, [edx+4] + mov [ ecx ], ebx + mov [ecx+4], esi + pop esi + pop ebx +end; + + +(**********************************************************) +(* Multiply two Int32 to an Int64 *) + +procedure MulTo64( X, Y : Int32; var Z : Int64 ); assembler; +asm + imul edx + mov [ ecx ],eax + mov [ecx+4],edx +end; + +(**********************************************************) +(* Divide an Int64 by an Int32 *) + +function Div64by32( var X : Int64; Y : Int32 ) : Int32; assembler; +asm + mov ecx, edx + mov edx, [eax+4].dword + mov eax, [ eax ].dword + idiv ecx +end; + +procedure DivMod64by32( var X : Int64; Y : Int32; var Q, R : Int32 ); + assembler; +asm + push ebx + mov ebx, edx + mov edx, [eax+4].dword + mov eax, [ eax ].dword + idiv ebx + mov [ecx], eax + mov ebx, R + mov [ebx], edx + pop ebx +end; + diff --git a/pascal/lib/ttcalc4.inc b/pascal/lib/ttcalc4.inc new file mode 100644 index 0000000..7bd0822 --- /dev/null +++ b/pascal/lib/ttcalc4.inc @@ -0,0 +1,134 @@ +(******************************************************************* + * + * TTCalc4.Inc 1.2 + * + * Arithmetic and Vectorial Computations (inline assembly) + * This version is used for i386 FreePascal + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTES : All vector operations were moved to the interpreter + * + ******************************************************************) + +(**********************************************************) +(* *) +(* The following routines are inline assembly, they are *) +(* thus processor and bitness specific. Replace them *) +(* with your own if you want to port the TrueType Engine *) + +(**********************************************************) +(* 64 Bit Addition *) + +procedure Add64( var X, Y, Z : Int64 ); assembler; +asm + push %ebx + push %edx + + mov X,%ebx + mov (%ebx) ,%eax + mov 4(%ebx) ,%edx + + mov Y,%ebx + add (%ebx) ,%eax + adc 4(%ebx) ,%edx + + mov Z,%ebx + mov %eax, (%ebx) + mov %edx, 4(%ebx) + + pop %edx + pop %ebx +end; + + +(**********************************************************) +(* 64 Bit Substraction *) + +procedure Sub64( var X, Y, Z : Int64 ); assembler; +asm + push %ebx + push %edx + + mov X,%ebx + mov (%ebx) ,%eax + mov 4(%ebx) ,%edx + + mov Y,%ebx + sub (%ebx) ,%eax + sbb 4(%ebx) ,%edx + + mov Z,%ebx + mov %eax, (%ebx) + mov %edx, 4(%ebx) + + pop %edx + pop %ebx +end; + + +(**********************************************************) +(* Multiply two Int32 to an Int64 *) + +procedure MulTo64( X, Y : Int32; var Z : Int64 ); assembler; +asm + push %ebx + push %edx + + mov X,%eax + imull Y + + mov Z,%ebx + mov %eax, (%ebx) + mov %edx, 4(%ebx) + + pop %edx + pop %ebx +end; + + +(**********************************************************) +(* Divide an Int64 by an Int32 *) + +function Div64by32( var X : Int64; Y : Int32 ) : Int32; assembler; +asm + push %ebx + push %edx + + mov X,%ebx + mov (%ebx) ,%eax + mov 4(%ebx) ,%edx + idivl Y + + pop %edx + pop %ebx +end; + + +procedure DivMod64by32( var X : Int64; Y : Int32; var Q, R : Int32 ); + assembler; +asm + push %ebx + push %edx + + mov X,%ebx + mov (%ebx) ,%eax + mov 4(%ebx) ,%edx + idivl Y + + mov Q, %ebx + mov %eax, (%ebx) + + mov R, %ebx + mov %edx, (%ebx) + + pop %edx + pop %ebx +end; + diff --git a/pascal/lib/ttcmap.pas b/pascal/lib/ttcmap.pas new file mode 100644 index 0000000..8794cff --- /dev/null +++ b/pascal/lib/ttcmap.pas @@ -0,0 +1,431 @@ +(******************************************************************* + * + * ttcmap.pas 1.0 + * + * Character Mappings unit. + * + * Copyright 1996, 1997 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************) + +unit TTCMap; + +interface + +uses FreeType, TTTypes; + +type + (********************************************************************) + (* *) + (* CHARACTER MAPPINGS SUBTABLES *) + (* *) + (********************************************************************) + + (* FORMAT 0 *) + + (* Apple standard character to glyph index mapping table *) + (* the glyphIdArray for this format has 256 entries *) + + TCMap0 = record + glyphIdArray : PUShort; + end; + + (* FORMAT 2 *) + + (* the format 2 table contains a variable-length array of subHeaders *) + (* (at most 256 entries) whose size must be determined algorithmically *) + TCMap2SubHeader = record + firstCode : UShort; (* first valid low byte *) + entryCount : UShort; (* number of valid low bytes *) + idDelta : Short; (* delta value to glyphIndex *) + idRangeOffset : UShort; (* offset fr. here to 1stCode *) + end; + + TCMap2SubHeaders = array[0..100] of TCMap2SubHeader; + PCMap2SubHeaders = ^TCMap2SubHeaders; + + (* Format 2 is used for mixed 8/16bit encodings (usually CJK fonts) *) + TCMap2 = record + subHeaderKeys : PUShort; + (* high byte mapping table *) + (* value = subHeader index * 8 *) + subHeaders : PCMap2SubHeaders; + glyphIdArray : PUShort; + numGlyphId : Int; + end; + + (* FORMAT 4 *) + + (*The format 4 table contains segCount segments *) + TCMap4Segment = record + endCount : UShort; + startCount : UShort; + idDelta : UShort; + idRangeOffset : UShort; + end; + TCMap4Segments = array[0..100] of TCMap4Segment; + PCMap4Segments = ^TCMap4Segments; + + (* Microsoft standard character to glyph index mapping table *) + TCMap4 = record + segCountX2 : UShort; (* segments number * 2 *) + searchRange : UShort; (* these parameters can be used *) + entrySelector : UShort; (* for a binary search *) + rangeShift : UShort; + segments : PCMap4Segments; + glyphIdArray : PUShort; + numGlyphId : Int; + end; + + (* FORMAT 6 *) + + (* trimmed table mapping (for representing one subrange) *) + TCMap6 = record + firstCode : UShort; (* first character code of subrange *) + entryCount : UShort; (* num. of character codes in subrange *) + + glyphIdArray : PUShort; + end; + + (* CHARMAP TABLE *) + + PCMapTable = ^TCMapTable; + TCMapTable = record + platformID : UShort; + platformEncodingID : UShort; + + Format : word; + Length : word; + Version : word; + Loaded : Boolean; + Offset : Long; + + case Byte of + 0 : ( cmap0 : TCMap0 ); + 2 : ( cmap2 : TCMap2 ); + 4 : ( cmap4 : TCMap4 ); + 6 : ( cmap6 : TCMap6 ); + end; + + TCMapTables = array[0..9] of TCMapTable; + PCMapTables = ^TCMapTables; + + + function CharMap_Load( var cmap : TCMapTable ) : TError; + + procedure CharMap_Free( var cmap : TCMapTable ); + + function CharMap_Index( var cmap : TCMapTable; charCode : Long ) : UShort; + +implementation + +uses + TTError, TTMemory, TTFile; + + function CharMap_Load( var cmap : TCMapTable ) : TError; + var + num_SH, u : UShort; + i : Int; + numGlyphId : Int; + num_segs : Int; + label + Fail; + begin + CharMap_Load := Failure; + + if cmap.loaded then + begin + CharMap_Load := Success; + exit; + end; + + if TT_Seek_File( cmap.offset ) then exit; + + case cmap.format of + + 0: with cmap.cmap0 do + if Alloc( glyphIdArray, 256 ) or + TT_Read_File( glyphIdArray^, 256 ) then goto Fail; + + 2: begin + num_SH := 0; + with cmap.cmap2 do + begin + if Alloc( subHeaderKeys, 256*sizeof(UShort) ) or + TT_Access_Frame( 512 ) then goto Fail; + + for i := 0 to 255 do + begin + u := GET_UShort shr 3; + subHeaderKeys^[i] := u; + + if num_SH < u then num_SH := u; + end; + + TT_Forget_Frame; + + (* now load sub headers *) + numGlyphId := ((cmap.length - 2*(256+3) - num_SH*8) and $FFFF) + div 2; + + if Alloc( subHeaders, (num_SH+1)*sizeof(TCMap2SubHeader) ) or + TT_Access_Frame( (num_SH+1)*8 ) then goto Fail; + + for i := 0 to num_SH do with subHeaders^[i] do + begin + firstCode := GET_UShort; + entryCount := GET_UShort; + idDelta := GET_UShort; + (* we apply the location offset immediately *) + idRangeOffset := GET_UShort - (num_SH-i)*8 - 2; + end; + + TT_Forget_Frame; + + (* load glyph ids *) + if Alloc( glyphIdArray, numGlyphId*sizeof(UShort) ) or + TT_Access_Frame( numGlyphId*2 ) then goto Fail; + + for i := 0 to numGlyphId-1 do + glyphIdArray^[i] := GET_UShort; + + TT_Forget_Frame; + end; + end; + + 4: with cmap.cmap4 do + begin + if TT_Access_Frame(8) then goto Fail; + + segCountX2 := Get_UShort; + searchRange := Get_UShort; + entrySelector := Get_UShort; + rangeShift := Get_UShort; + + num_segs := segCountX2 shr 1; + + TT_Forget_Frame; + + (* load segments *) + if Alloc( segments, num_segs*sizeof(TCMap4Segment) ) or + TT_Access_Frame( (num_segs*4+1)*2 ) then goto Fail; + + for i := 0 to num_segs-1 do + segments^[i].endCount := Get_UShort; + + Get_UShort; + + for i := 0 to num_segs-1 do + segments^[i].startCount := Get_UShort; + + for i := 0 to num_segs-1 do + segments^[i].idDelta := GET_Short; + + for i := 0 to num_segs-1 do + segments^[i].idRangeOffset := GET_UShort; + + TT_Forget_Frame; + + numGlyphId := (( cmap.length - (16+8*num_segs) ) and $FFFF) + div 2; + + (* load glyph ids *) + if Alloc( glyphIdArray, numGlyphId*sizeof(UShort) ) or + TT_Access_Frame( numGlyphId*2 ) then goto Fail; + + for i := 0 to numGlyphId-1 do + glyphIdArray^[i] := Get_UShort; + + TT_Forget_Frame; + end; + + 6: with cmap.cmap6 do + begin + if TT_Access_Frame(4) then goto Fail; + + firstCode := GET_UShort; + entryCount := GET_UShort; + + TT_Forget_Frame; + + if Alloc( glyphIdArray, entryCount*sizeof(Short) ) or + TT_Access_Frame( entryCount*2 ) then goto Fail; + + for i := 0 to entryCount-1 do + glyphIdArray^[i] := GET_UShort; + + TT_Forget_Frame; + end; + + else + error := TT_Err_Invalid_Charmap_Format; + exit; + end; + + CharMap_Load := success; + exit; + + Fail: + CharMap_Free( cmap ); + end; + + + procedure CharMap_Free( var cmap : TCMapTable ); + begin + with cmap do + case format of + + 0 : begin + Free( cmap.cmap0.glyphIdArray ); + end; + + 2 : begin + Free( cmap.cmap2.glyphIdArray ); + Free( cmap.cmap2.subHeaders ); + Free( cmap.cmap2.glyphIdArray ); + end; + + 4 : begin + Free( cmap.cmap4.segments ); + Free( cmap.cmap4.glyphIdArray ); + cmap.cmap4.segCountX2 := 0; + end; + + 6 : begin + Free( cmap.cmap6.glyphIdArray ); + cmap.cmap6.entryCount := 0; + end; + end; + + cmap.loaded := False; + cmap.format := 0; + cmap.length := 0; + cmap.version := 0; + end; + + + function code_to_index0( charCode : UShort; var cmap0 : TCMap0 ) : UShort; + begin + code_to_index0 := 0; + if charCode < 256 then + code_to_index0 := cmap0.glyphIdArray^[charCode] + end; + + + + function code_to_index2( charCode : UShort; var cmap2 : TCMap2 ) : UShort; + var + index1, idx, offset : UShort; + begin + code_to_index2 := 0; + + if charCode < 256 then idx := charCode + else idx := charCode shr 8; + + index1 := cmap2.subHeaderKeys^[idx]; + + if index1 = 0 then + begin + if charCode < 256 then + code_to_index2 := cmap2.glyphIdArray^[charCode]; (* 8Bit charcode *) + end + else + begin + if charCode < 256 then + exit; + + idx := charCode and 255; + with cmap2.subHeaders^[index1] do + begin + if ( idx < firstCode ) or + ( idx >= firstCode + entryCount ) then exit; + + offset := idRangeOffset div 2 + idx - firstCode; + + if offset >= cmap2.numGlyphId then exit; + + idx := cmap2.glyphIdArray^[offset]; + if idx <> 0 then + code_to_index2 := (idx + idDelta) and $FFFF; + end + end; + end; + + + + function code_to_index4( charCode : UShort; var cmap4 : TCMap4 ) : UShort; + var + i, index1, num_segs : Int; + label + Found; + begin + code_to_index4 := 0; + num_segs := cmap4.segCountX2 div 2; + i := 0; + + while ( i < num_segs ) do with cmap4.segments^[i] do + begin + if charCode <= endCount then goto Found; + inc(i); + end; + + exit; + + Found: + with cmap4.segments^[i] do + begin + + if charCode < startCount then + exit; + + if idRangeOffset = 0 then + code_to_index4 := (charCode + idDelta) and $FFFF + else + begin + index1 := idRangeOffset div 2 + (charCode - startCount) - + -(num_segs-i); + + if ( index1 < cmap4.numGlyphId ) and + ( cmap4.glyphIdArray^[index1] <> 0 ) then + + code_to_index4 := (cmap4.glyphIdArray^[index1] + idDelta) and $FFFF; + end; + end; + end; + + + function code_to_index6( charCode : UShort; var cmap6 : TCMap6 ) : UShort; + begin + code_to_index6 := 0; + with cmap6 do + begin + + if ( charCode < firstCode ) or + ( charCode >= firstCode + entryCount ) then exit; + + code_to_index6 := glyphIdArray^[charCode-firstCode]; + end + end; + + + function CharMap_Index( var cmap : TCMapTable; + charCode : Long ) : UShort; + begin + CharMap_Index := 0; + + case cmap.format of + 0: CharMap_Index := code_to_index0( charCode, cmap.cmap0 ); + 2: CharMap_Index := code_to_index2( charCode, cmap.cmap2 ); + 4: CharMap_Index := code_to_index4( charCode, cmap.cmap4 ); + 6: CharMap_Index := code_to_index6( charCode, cmap.cmap6 ); + end; + end; + +end. diff --git a/pascal/lib/ttconfig.inc b/pascal/lib/ttconfig.inc new file mode 100644 index 0000000..3d3677a --- /dev/null +++ b/pascal/lib/ttconfig.inc @@ -0,0 +1,75 @@ +(* *) +(* TTConfig.Inc *) +(* *) +(* This file contains several definition pragmas that are used to *) +(* build several versions of the library. Each constant is commented *) + +(* Define the DEBUG constant if you want the library dumping trace *) +(* information to the standard error output. *) +{ $DEFINE DEBUG} + + +(* Define the ASSERT constant if you want to generate runtime integrity *) +(* checks within the library. Most of the checks will panic and stop the *) +(* the program when failed.. *) +{ $DEFINE ASSERT} + + +(* Define the INLINE constant if you want to use inlining when provided *) +(* by your compiler. Currently, only Virtual Pascal does *) +{$IFDEF VIRTUALPASCAL} +{$DEFINE INLINE} +{$ENDIF} + + +(* Define the USE32 constant on 32-bit systems. Virtual Pascal *) +(* always define it by default. Now set for Delphi 2 and 3 *) +{$IFDEF WIN32} +{$DEFINE USE32} +{$ENDIF} + +(* FreeType doesn't compile on old Pascal compilers that do not allow *) +(* inline assembly like Turbo Pascal 5.5 and below *) +{$IFDEF VER50} +ERROR : FreeType cannot be compiled with something older than Turbo Pascal 6.0 +{$ENDIF} +{$IFDEF VER55} +ERROR : FreeType cannot be compiled with something older than Turbo Pascal 6.0 +{$ENDIF} + +(* Define the BORLANDPASCAL constant whenever you're using a DOS-based *) +(* version of Turbo or Borland Pascal. *) +{$IFDEF VER60} +{$DEFINE BORLANDPASCAL} +{$ENDIF} +{$IFDEF VER70} +{$DEFINE BORLANDPASCAL} +{$ENDIF} + +(* Define DELPHI16 when compiled in the 16_bit version of Delphi *) +{$IFDEF VER80} +{$DEFINE DELPHI16} +{$ENDIF} + +(* Define DELPHI32 when compiled in any 32-bit version of Delphi *) +{$IFDEF VER90} (* for Delphi 2 *) +{$DEFINE DELPHI32} +{$ENDIF} +{$IFDEF VER100} (* for Delphi 3 *) +{$DEFINE DELPHI32} +{$ENDIF} +{$IFDEF VER110} (* for Borland C++ Builder 3 *) +{$DEFINE DELPHI32} +{$ENDIF} +{$IFDEF VER120} (* for Delphi 4 *) +{$DEFINE DELPHI32} +{$ENDIF} +{$IFDEF VER125} (* for Borland C++ Builder 4 *) +{$DEFINE DELPHI32} +{$ENDIF} + +(* I don't have Delphi 5, I hope this will work *) +{$IFDEF VER130} +{$DEFINE DELPHI32} +{$ENDIF} + diff --git a/pascal/lib/ttdebug.pas b/pascal/lib/ttdebug.pas new file mode 100644 index 0000000..61e42c8 --- /dev/null +++ b/pascal/lib/ttdebug.pas @@ -0,0 +1,851 @@ +(******************************************************************* + * + * TTDebug.Pas 1.2 + * + * This unit is only used by the debugger. + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************) + +unit TTDebug; + +interface + +uses TTTypes, TTTables, TTObjs, TTInterp; + +type + + ByteHexStr = string[2]; (* hex representation of a byte *) + ShortHexStr = string[4]; (* " " " short *) + LongHexStr = string[8]; (* " " " long *) + DebugStr = string[128]; (* disassembled line output *) + + { TBreakPoint } + + { A simple record to hold breakpoint information } + { it may be completed later with pass count, etc.. } + { They must be in a sorted linked list } + + PBreakPoint = ^TBreakPoint; + TBreakPoint = record + Next : PBreakPoint; + Range : Int; + Address : Int; + end; + + { TRangeRec } + + { a record to store line number information and breakpoints list } + + PRangeRec = ^TRangeRec; + TRangeRec = record + Code : PByte; + Size : Int; + index : Int; + NLines : Int; + Disassembled : PUShort; + Breaks : PBreakPoint; + end; + + +{ Generate_Range : Generate Line Number information specific to } +{ a given range } + +procedure Generate_Range( CR : PCodeRange; + index : Int; + var RR : TRangeRec ); + +{ Throw_Range : Discard Line Number Information } + +procedure Throw_Range( var RR : TRangeRec ); + +{ Toggle_Break : Toggle a breakpoint } + +procedure Toggle_Break( var Head : PBreakPoint; Range, Adr : Int ); + +{ Set_Break : Set a breakpoint on a given address } + +procedure Set_Break ( var Head : PBreakPoint; Range, Adr : Int ); + +{ Clear_Break : Clear one specific breakpoint } + +procedure Clear_Break( var Head : PBreakPoint; Bp : PBreakPoint ); + +{ Clear_All_Breaks : Clear breakpoint list } + +procedure Clear_All_Breaks( var Head : PBreakPoint ); + +{ Find_Breakpoint : find one breakpoint at a given address } + +function Find_BreakPoint( Head : PBreakPoint; Range, IP : Int ) : PBreakPoint; + +{ Cur_U_Line : returns the current disassembled line at Code(IP) } + +function Cur_U_Line( Code : PByte; IP : Int ) : DebugStr; + +{ Get_Length : returns the length of the current opcode at Code(IP) } + +function Get_Length( Code : PByte; IP : Int ) : Int; + +function Get_Dis_Line( var cr : TRangeRec; addr : Int ) : Int; + + +{ Hex_N : returns an hexadecimal string } + +function Hex8 ( B : Byte ) : ByteHexStr; +function Hex16( W : word ) : ShortHexStr; +function Hex32( L : Long ) : LongHexStr; + + +implementation + +type + PStorageLong = ^TStorageLong; + TStorageLong = record (* do-it-all union record type *) + case Byte of + 0 : ( L : LongInt ); + 1 : ( S1, S2 : Integer ); + 2 : ( W1, W2 : Word ); + 3 : ( B1, B2, + B3, B4 : Byte ); + 4 : ( P : Pointer ); + end; + +var + OpSize : int; + +const + OpStr : array[ 0..255 ] of String[10] + = ( + 'SVTCA y', (* Set vectors to coordinate axis y *) + 'SVTCA x', (* Set vectors to coordinate axis x *) + 'SPvTCA y', (* Set Proj. vec. to coord. axis y *) + 'SPvTCA x', (* Set Proj. vec. to coord. axis x *) + 'SFvTCA y', (* Set Free. vec. to coord. axis y *) + 'SFvTCA x', (* Set Free. vec. to coord. axis x *) + 'SPvTL //', (* Set Proj. vec. parallel to segment *) + 'SPvTL +', (* Set Proj. vec. normal to segment *) + 'SFvTL //', (* Set Free. vec. parallel to segment *) + 'SFvTL +', (* Set Free. vec. normal to segment *) + 'SPvFS', (* Set Proj. vec. from stack *) + 'SFvFS', (* Set Free. vec. from stack *) + 'GPV', (* Get projection vector *) + 'GFV', (* Get freedom vector *) + 'SFvTPv', (* Set free. vec. to proj. vec. *) + 'ISECT', (* compute intersection *) + + 'SRP0', (* Set reference point 0 *) + 'SRP1', (* Set reference point 1 *) + 'SRP2', (* Set reference point 2 *) + 'SZP0', (* Set Zone Pointer 0 *) + 'SZP1', (* Set Zone Pointer 1 *) + 'SZP2', (* Set Zone Pointer 2 *) + 'SZPS', (* Set all zone pointers *) + 'SLOOP', (* Set loop counter *) + 'RTG', (* Round to Grid *) + 'RTHG', (* Round to Half-Grid *) + 'SMD', (* Set Minimum Distance *) + 'ELSE', (* Else *) + 'JMPR', (* Jump Relative *) + 'SCvTCi', (* Set CVT *) + 'SSwCi', (* *) + 'SSW', (* *) + + 'DUP', + 'POP', + 'CLEAR', + 'SWAP', + 'DEPTH', + 'CINDEX', + 'MINDEX', + 'AlignPTS', + 'INS_$28', + 'UTP', + 'LOOPCALL', + 'CALL', + 'FDEF', + 'ENDF', + 'MDAP[-]', + 'MDAP[r]', + + 'IUP[y]', + 'IUP[x]', + 'SHP[0]', + 'SHP[1]', + 'SHC[0]', + 'SHC[1]', + 'SHZ[0]', + 'SHZ[1]', + 'SHPIX', + 'IP', + 'MSIRP[0]', + 'MSIRP[1]', + 'AlignRP', + 'RTDG', + 'MIAP[-]', + 'MIAP[r]', + + 'NPushB', + 'NPushW', + 'WS', + 'RS', + 'WCvtP', + 'RCvt', + 'GC[0]', + 'GC[1]', + 'SCFS', + 'MD[0]', + 'MD[1]', + 'MPPEM', + 'MPS', + 'FlipON', + 'FlipOFF', + 'DEBUG', + + 'LT', + 'LTEQ', + 'GT', + 'GTEQ', + 'EQ', + 'NEQ', + 'ODD', + 'EVEN', + 'IF', + 'EIF', + 'AND', + 'OR', + 'NOT', + 'DeltaP1', + 'SDB', + 'SDS', + + 'ADD', + 'SUB', + 'DIV', + 'MUL', + 'ABS', + 'NEG', + 'FLOOR', + 'CEILING', + 'ROUND[G]', + 'ROUND[B]', + 'ROUND[W]', + 'ROUND[?]', + 'NROUND[G]', + 'NROUND[B]', + 'NROUND[W]', + 'NROUND[?]', + + 'WCvtF', + 'DeltaP2', + 'DeltaP3', + 'DeltaC1', + 'DeltaC2', + 'DeltaC3', + 'SROUND', + 'S45Round', + 'JROT', + 'JROF', + 'ROFF', + 'INS_$7B', + 'RUTG', + 'RDTG', + 'SANGW', + 'AA', + + 'FlipPT', + 'FlipRgON', + 'FlipRgOFF', + 'INS_$83', + 'INS_$84', + 'ScanCTRL', + 'SDPVTL[0]', + 'SDPVTL[1]', + 'GetINFO', + 'IDEF', + 'ROLL', + 'MAX', + 'MIN', + 'ScanTYPE', + 'IntCTRL', + 'INS_$8F', + + 'INS_$90', + 'INS_$91', + 'INS_$92', + 'INS_$93', + 'INS_$94', + 'INS_$95', + 'INS_$96', + 'INS_$97', + 'INS_$98', + 'INS_$99', + 'INS_$9A', + 'INS_$9B', + 'INS_$9C', + 'INS_$9D', + 'INS_$9E', + 'INS_$9F', + + 'INS_$A0', + 'INS_$A1', + 'INS_$A2', + 'INS_$A3', + 'INS_$A4', + 'INS_$A5', + 'INS_$A6', + 'INS_$A7', + 'INS_$A8', + 'INS_$A9', + 'INS_$AA', + 'INS_$AB', + 'INS_$AC', + 'INS_$AD', + 'INS_$AE', + 'INS_$AF', + + 'PushB[0]', + 'PushB[1]', + 'PushB[2]', + 'PushB[3]', + 'PushB[4]', + 'PushB[5]', + 'PushB[6]', + 'PushB[7]', + 'PushW[0]', + 'PushW[1]', + 'PushW[2]', + 'PushW[3]', + 'PushW[4]', + 'PushW[5]', + 'PushW[6]', + 'PushW[7]', + + 'MDRP[G]', + 'MDRP[B]', + 'MDRP[W]', + 'MDRP[?]', + 'MDRP[rG]', + 'MDRP[rB]', + 'MDRP[rW]', + 'MDRP[r?]', + 'MDRP[mG]', + 'MDRP[mB]', + 'MDRP[mW]', + 'MDRP[m?]', + 'MDRP[mrG]', + 'MDRP[mrB]', + 'MDRP[mrW]', + 'MDRP[mr?]', + 'MDRP[pG]', + 'MDRP[pB]', + + 'MDRP[pW]', + 'MDRP[p?]', + 'MDRP[prG]', + 'MDRP[prB]', + 'MDRP[prW]', + 'MDRP[pr?]', + 'MDRP[pmG]', + 'MDRP[pmB]', + 'MDRP[pmW]', + 'MDRP[pm?]', + 'MDRP[pmrG]', + 'MDRP[pmrB]', + 'MDRP[pmrW]', + 'MDRP[pmr?]', + + 'MIRP[G]', + 'MIRP[B]', + 'MIRP[W]', + 'MIRP[?]', + 'MIRP[rG]', + 'MIRP[rB]', + 'MIRP[rW]', + 'MIRP[r?]', + 'MIRP[mG]', + 'MIRP[mB]', + 'MIRP[mW]', + 'MIRP[m?]', + 'MIRP[mrG]', + 'MIRP[mrB]', + 'MIRP[mrW]', + 'MIRP[mr?]', + 'MIRP[pG]', + 'MIRP[pB]', + + 'MIRP[pW]', + 'MIRP[p?]', + 'MIRP[prG]', + 'MIRP[prB]', + 'MIRP[prW]', + 'MIRP[pr?]', + 'MIRP[pmG]', + 'MIRP[pmB]', + 'MIRP[pmW]', + 'MIRP[pm?]', + 'MIRP[pmrG]', + 'MIRP[pmrB]', + 'MIRP[pmrW]', + 'MIRP[pmr?]' + ); + +const + HexStr : string[16] = '0123456789abcdef'; + +(******************************************************************* + * + * Function : Hex8 + * + * Description : Returns the string hexadecimal representation + * of a Byte. + * + * Input : B byte + * + * Output : two-chars string + * + *****************************************************************) + +function Hex8( B : Byte ) : ByteHexStr; +var + S : ByteHexStr; +begin + S[0] :=#2; + S[1] := HexStr[ 1+( B shr 4 ) ]; + S[2] := HexStr[ 1+( B and 15 )]; + Hex8 := S; +end; + +(******************************************************************* + * + * Function : Hex16 + * + * Description : Returns the string hexadecimal representation + * of a Short. + * + * Input : W word + * + * Output : four-chars string + * + *****************************************************************) + +function Hex16( W : word ) : ShortHexStr; +begin + Hex16 := Hex8( Hi(w) )+Hex8( Lo(w) ); +end; + +(******************************************************************* + * + * Function : Hex32 + * + * Description : Returns the string hexadecimal representation + * of a Long. + * + * Input : L Long + * + * Output : eight-chars string + * + *****************************************************************) + +function Hex32( L : Long ) : LongHexStr; +begin + Hex32 := Hex16( TStorageLong(L).W2 )+Hex16( TStorageLong(L).W1 ); +end; + +(******************************************************************* + * + * Function : Cur_U_Line + * + * Description : Returns a string of the current unassembled + * line at Code^[IP]. + * + * Input : Code base code range + * IP current instruction pointer + * + * Output : line string + * + *****************************************************************) + +function Cur_U_Line( Code : PByte; IP : Int ) : DebugStr; +var + Op : Byte; + N, I : Int; + S : DebugStr; +begin + + Op := Code^[IP]; + S := Hex16(IP)+': '+Hex8(Op)+' '+OpStr[Op]; + + case Op of + + $40 : begin + n := Code^[IP+1]; + S := S+'('+Hex8(n)+')'; + for i := 1 to n do + S := S+' $'+Hex8( Code^[Ip+i+1] ); + end; + + $41 : begin + n := Code^[IP+1]; + S := S+'('+Hex8(n)+')'; + for i := 1 to n do + S := S+' $'+Hex8( Code^[Ip+i*2+1] )+Hex8( Code^[Ip+i*2+2] ); + end; + + $B0..$B7 : begin + n := Op-$B0; + for i := 0 to N do + S := S+' $'+Hex8( Code^[Ip+i+1] ); + end; + + $B8..$BF : begin + n := Op-$B8; + for i := 0 to N do + S := S+' $'+Hex8( Code^[IP+i*2+1] )+Hex8( Code^[Ip+i*2+2] ); + end; + + end; + + Cur_U_Line := S; +end; + +(******************************************************************* + * + * Function : Get_Length + * + * Description : Returns the length in bytes of the instruction at + * current instruction pointer. + * + * Input : Code base code range + * IP current instruction pointer + * + * Output : Length in bytes + * + *****************************************************************) + +function Get_Length( Code : PByte; IP : Int ) : Int; +var + Op : Byte; + N : Int; +begin + + Op := Code^[IP]; + + case Op of + + $40 : N := 2 + Code^[IP+1]; + $41 : N := 2 + Code^[IP+1]*2; + + $B0..$B7 : N := 2 + ( Op-$B0 ); + $B8..$BF : N := 3 + ( Op-$B8 )*2 + + else + N := 1; + end; + + Get_Length := N; + +end; + +(******************************************************************* + * + * Function : Generate_Range + * + * Description : Create a list of unassembled lines for a + * given code range + * + * Input : + * + * Output : + * + *****************************************************************) + +procedure Generate_Range( CR : PCodeRange; + index : Int; + var RR : TRangeRec ); +var + Adr, Line, N : Int; + Code : PByte; +begin + + N := CR^.Size; + + RR.Code := PByte( CR^.Base ); + RR.Size := N; + + Line := 0; + + if N > 0 then + begin + Adr := 0; + GetMem( RR.Disassembled, sizeof(Short) * N ); + + while Adr < N do + begin + RR.Disassembled^[Line] := Adr; + inc( Line ); + inc( Adr, Get_Length( RR.Code, Adr )); + end; + end; + + RR.NLines := Line; + RR.Index := index; + RR.Breaks := nil; +end; + +(******************************************************************* + * + * Function : Get_Dis_Line + * + * Description : Returns the line index of address 'addr' + * in the coderange 'cr' + * + *****************************************************************) + + function Get_Dis_Line( var cr : TRangeRec; addr : Int ) : Int; + var + l, r, m : Int; + begin + if (cr.NLines = 0) or + (addr > cr.Disassembled^[cr.Nlines-1] ) then + begin + Get_Dis_Line := -1; + exit; + end; + + l := 0; + r := cr.NLines-1; + + while ( r-l > 1 ) do + begin + if cr.Disassembled^[l] = addr then + begin + Get_Dis_Line := l; + exit; + end; + + if cr.Disassembled^[r] = addr then + begin + Get_Dis_Line := r; + exit; + end; + + m := (l+r) shr 1; + if cr.Disassembled^[m] = addr then + begin + Get_Dis_Line := m; + exit; + end + else + if cr.Disassembled^[m] < addr then + l := m + else + r := m; + end; + + if cr.Disassembled^[r] = addr then + begin + Get_Dis_Line := r; + exit; + end; + + Get_Dis_Line := l; + + end; + +(******************************************************************* + * + * Function : Throw_Range + * + * Description : Destroys a list of unassembled lines for a + * given code range + * + * Input : + * + * Output : + * + *****************************************************************) + +procedure Throw_Range( var RR : TRangeRec ); +var + B, Bnext : PBreakPoint; +begin + + if RR.Size > 0 then + FreeMem( RR.Disassembled, RR.Size * sizeof(Short) ); + + RR.Disassembled := nil; + RR.Size := 0; + RR.Code := nil; + RR.NLines := 0; + + B := RR.Breaks; + RR.Breaks := nil; + + while B<>nil do + begin + Bnext := B^.Next; + Dispose( B ); + B := Bnext; + end; +end; + +(******************************************************************* + * + * Function : Set_Break + * + * Description : Sets a Breakpoint ON + * + * Input : + * + * Output : + * + *****************************************************************) + +procedure Set_Break( var Head : PBreakPoint; + Range : Int; + Adr : Int ); +var + BP, + Old, + Cur : PBreakPoint; +begin + Old := nil; + Cur := Head; + + while (Cur <> nil) and (Cur^.Address < Adr) do + begin + Old := Cur; + Cur := Cur^.Next; + end; + + { No duplicates } + if Cur <> nil then + if (Cur^.Address = Adr) and (Cur^.Range = Range) then exit; + + New( BP ); + BP^.Address := Adr; + BP^.Range := Range; + BP^.Next := Cur; + + if Old = nil then + Head := BP + else + Old^.Next := BP; +end; + +(******************************************************************* + * + * Function : Clear_Break + * + * Description : Clears a breakpoint OFF + * + * Input : + * + * Output : + * + *****************************************************************) + +procedure Clear_Break( var Head : PBreakPoint; Bp : PBreakPoint ); +var + Old, + Cur : PBreakPoint; +begin + Old := nil; + Cur := Head; + + while (Cur <> nil) and (Cur <> Bp) do + begin + Old := Cur; + Cur := Cur^.Next; + end; + + if Cur = nil then exit; + + if Old = nil then + Head := Cur^.Next + else + Old^.Next := Cur^.Next; +end; + + + +procedure Toggle_Break( var Head : PBreakPoint; Range, Adr : Int ); +var + Bp : PBreakPoint; +begin + Bp := Find_BreakPoint( Head, Range, Adr ); + if Bp <> nil then Clear_Break( Head, Bp ) + else Set_Break( Head, Range, Adr ); +end; + +(******************************************************************* + * + * Function : Clear_All_Breaks + * + * Description : Clears all breakpoints + * + * Input : + * + * Output : + * + *****************************************************************) + +procedure Clear_All_Breaks( var Head : PBreakPoint ); +var + Old, + Cur : PBreakPoint; +begin + Cur := Head; + Head := Nil; + + while Cur <> nil do + begin + Old := Cur; + Cur := Cur^.Next; + Dispose( Old ); + end; +end; + +(******************************************************************* + * + * Function : Find_BreakPoint + * + * Description : Find a breakpoint at address IP + * + * Input : Head break points sorted linked list + * IP address of expected breakpoint + * + * Output : pointer to breakpoint if found + * nil otherwise. + * + *****************************************************************) + +function Find_BreakPoint( Head : PBreakPoint; Range, IP : Int ) : PBreakPoint; +var + Cur : PBreakPoint; + Res : PBreakPoint; +begin + Cur := Head; + Res := nil; + + while Cur <> nil do + begin + if (Cur^.Address = IP ) and + (Cur^.Range = Range) then Res := Cur; + + if (Cur^.Address >= IP) then Cur := nil + else Cur := Cur^.Next; + end; + + Find_BreakPoint := Res; +end; + +end. diff --git a/pascal/lib/tterror.pas b/pascal/lib/tterror.pas new file mode 100644 index 0000000..6d58fb2 --- /dev/null +++ b/pascal/lib/tterror.pas @@ -0,0 +1,69 @@ +(******************************************************************* + * + * tterror.pas 1.0 + * + * Simple Error management unit + * + * Copyright 1996, 1997 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************) + +unit TTError; + +interface + +uses FreeType; + + procedure Check_Error( error : Integer ); + + procedure Panic1( message : String ); + procedure Trace1( message : String ); + +(* The Pascal version of the library doesn't support multiple *) +(* threads. We use a global error variable, called simply "error" *) +(* to report all defects. The various functions return an error *) +(* condition, which can be either Success (false) or Failure (true) *) + +(* Note that the use of macros in the C version to automate error *) +(* reporting makes the two source trees very similar, even if they *) +(* differ from some design points like this one *) + +var + error : integer; + +implementation + + + procedure Panic1( message : String ); + begin + writeln( message ); + halt(1); + end; + + + procedure Trace1( message : String ); + begin + writeln( message ); + end; + + + procedure Check_Error( error : Integer ); + var + num : String[4]; + begin + if error <> TT_Err_Ok then + begin + str( -error:3, num ); + Panic1( 'Error code = ' + num ); + end; + end; + +end. + diff --git a/pascal/lib/ttfile.pas b/pascal/lib/ttfile.pas new file mode 100644 index 0000000..9a4478a --- /dev/null +++ b/pascal/lib/ttfile.pas @@ -0,0 +1,979 @@ +(******************************************************************* + * + * TTFile.Pas 1.2 + * + * File I/O Component (specification) + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTES : + * + * + * Changes from 1.1 to 1.2 : + * + * - Changes the stream operations semantics. See changes.txt + * + * - stream records are now allocated on demand in the heap + * + * - introduced the 'frame cache' to avoid Allocating/Freeing + * each frame, even tiny ones.. + * + * - support for thread-safety and re-entrancy + * + * ( re-entrancy is there for information only.. ) + * + * Changes from 1.0 to 1.1 : + * + * - defined the type TT_Stream for file handles + * - renamed ( and cleaned ) the API. + * + * - caching and memory-mapped files use the same API : + * + * TT_Access_Frame to notify + * + * - only the interface was really rewritten. This component still + * only supports one opened file at a time. + * + ******************************************************************) + +Unit TTFile; + +interface + +{$I TTCONFIG.INC} + +uses FreeType, + TTTypes, + TTError; + + function TTFile_Init : TError; + procedure TTFile_Done; + + (*********************************************************************) + (* *) + (* Stream Functions *) + (* *) + (*********************************************************************) + + function TT_Open_Stream( name : String; + var stream : TT_Stream ) : TError; + (* Open a file and return a stream handle for it *) + (* should only be used for a new typeface object's main stream *) + + procedure TT_Close_Stream( var stream : TT_Stream ); + (* closes, then discards a stream, when it becomes unuseful *) + (* should only be used for a typeface object's main stream *) + + function TT_Use_Stream( org_stream : TT_Stream; + var stream : TT_Stream ) : TError; + (* notices the component that we're going to use the file *) + (* opened in 'org_stream', and report errors to the 'error' *) + (* variable. the 'stream' variable is untouched, except in *) + (* re-entrant buids. *) + + (* in re-entrant builds, the original file handle is duplicated *) + (* to a new stream which reference is passed to the 'stream' *) + (* variable.. thus, each thread can have its own file cursor to *) + (* access the same file concurrently.. *) + + procedure TT_Flush_Stream( stream : TT_Stream ); + (* closes a stream's font handle. This is useful to save *) + (* system resources. *) + + procedure TT_Done_Stream( stream : TT_Stream ); + (* notice the file component that we don't need to perform *) + (* file ops on the stream 'stream' anymore.. *) + (* *) + (* in re-entrant builds, should also discard the stream *) + + (*********************************************************************) + (* *) + (* File Functions *) + (* *) + (* the following functions perform file operations on the *) + (* currently 'used' stream. In thread-safe builds, only one *) + (* stream can be used at a time. Synchronisation is performed *) + (* through the Use_Stream/Done_Stream functions *) + (* *) + (* Note: *) + (* re-entrant versions of these functions are only available *) + (* in the C source tree. There, a macro is used to add a 'stream' *) + (* parameter to each of these routines.. *) + (* *) + (*********************************************************************) + + function TT_Read_File( var ABuff; ACount : Int ) : TError; + (* Read a chunk of bytes directly from the file *) + + function TT_Seek_File( APos : LongInt ) : TError; + (* Seek a new file position *) + + function TT_Skip_File( ADist : LongInt ) : TError; + (* Skip to a new file position *) + + function TT_Read_At_File( APos : Long; var ABuff; ACount : Int ) : TError; + (* Seek and read a chunk of bytes *) + + function TT_File_Size : Longint; + + function TT_File_Pos : Longint; + + function TT_Stream_Size( stream : TT_Stream ) : longint; + + (*********************************************************************) + (* *) + (* Frame Functions *) + (* *) + (*********************************************************************) + + function TT_Access_Frame( aSize : Int ) : TError; + (* Access the next aSize bytes *) + + function TT_Check_And_Access_Frame( aSize : Int ) : TError; + (* Access the next min(aSize,file_size-file_pos) bytes *) + + function TT_Forget_Frame : TError; + (* Forget the previously cached frame *) + + (* The four following functions should only be used after a *) + (* TT_Access_Frame and before a TT_Forget_Frame *) + + (* They do not provide error handling, intentionnaly, and are much faster *) + (* moreover, they could be converted to MACROS in the C version *) + + function GET_Byte : Byte; + function GET_Char : ShortInt; + function GET_Short : Short; + function GET_UShort : UShort; + function GET_Long : Long; + function GET_ULong : ULong; + function GET_Tag4 : ULong; + +implementation + +uses + TTMemory; + + (* THREADS: TTMutex, *) + +const + frame_cache_size = 2048; + (* we allocate a single block where we'll place all of our frames *) + (* instead of allocating an new block on each access. Note that *) + (* frames that are bigger than this constant are effectively *) + (* allocated in the heap.. *) + +type + PString = ^string; + PFile = ^FILE; + PError = ^TT_Error; + + PStream_Rec = ^TStream_Rec; + TStream_Rec = record + name : PString; (* file pathname *) + open : Boolean; (* is the stream currently opened *) + font : PFILE; (* file handle for opened stream *) + base : Longint; (* base offset for embedding *) + size : Longint; (* size of font in resource *) + posit : Longint; (* current offset for closed streams *) + end; + +var + (* THREADS: File_Mutex : TMutex *) + + font_file : PFile; + cur_stream : PStream_Rec; + + current_frame : PByte; + frame_cursor : Longint; + frame_size : LongInt; + + dummy_error : TT_Error; + + frame_cache : PByte; + + function TT_File_Size : Longint; + begin + TT_File_Size := FileSize( font_file^ ); + end; + + function TT_File_Pos : Longint; + begin + TT_File_Pos := FilePos( font_file^ ); + end; + + function TT_Stream_Size( stream : TT_Stream ) : longint; + var + rec : PStream_Rec; + begin + rec := PStream_Rec(stream); + if rec = nil then + TT_Stream_Size := 0 + else + TT_Stream_Size := rec^.size; + end; + +(******************************************************************* + * + * Function : TTFile_Init + * + * Description : Init the file component + * + * - create a file mutex for thread-safe builds + * + ******************************************************************) + + function TTFile_Init : TError; + begin + (* empty current file *) + font_file := nil; + cur_stream := nil; + + (* empty frame *) + current_frame := nil; + frame_cursor := 0; + frame_size := 0; + + (* create frame cache *) + GetMem( frame_cache, frame_cache_size ); + + TTFile_Init := Success; + end; + +(******************************************************************* + * + * Function : TTFile_Done + * + * Description : Finalize the file component + * + * - destroys the file mutex for thread-safe builds + * + ******************************************************************) + + procedure TTFile_Done; + begin + (* empty current file *) + font_file := nil; + cur_stream := nil; + + (* empty frame *) + current_frame := nil; + frame_cursor := 0; + frame_size := 0; + end; + +(******************************************************************* + * + * Function : Stream_New + * + * Description : allocates a new stream record + * + * Input : stream : the target stream variable + * + * Output : True on sucess. + * + ******************************************************************) + + function Stream_New( pathname : string; + var stream : PStream_Rec ) : TError; + var + font : PFile; + name : PString; + len : Integer; + label + Fail_Memory; + begin + name := nil; + font := nil; + stream := nil; + len := length(pathname)+1; + + (* allocate a new stream_rec in the heap *) + if Alloc( pointer(stream), sizeof(TStream_Rec) ) or + Alloc( pointer(font), sizeof(FILE) ) or + Alloc( pointer(name), len ) then + goto Fail_Memory; + + move( pathname, name^, len ); + + stream^.font := font; + stream^.name := name; + stream^.open := false; + stream^.base := 0; + stream^.size := 0; + stream^.posit := 0; + + Stream_New := Success; + exit; + + Fail_Memory: + Free( pointer(name) ); + Free( pointer(font) ); + Free( pointer(stream) ); + Stream_New := Failure; + end; + +(******************************************************************* + * + * Function : Stream_Activate + * + * Description : activates a stream, if it needs it + * + * Input : stream : the target stream variable + * + * Output : Error condition + * + ******************************************************************) + + function Stream_Activate( stream : PStream_Rec ) : TError; + var + old_filemode : Long; + begin + Stream_Activate := Failure; + if stream = nil then exit; + + with stream^ do + begin + Stream_Activate := Success; + if open then exit; + + old_filemode := System.FileMode; + System.FileMode := 0; + (* read-only mode *) + + Assign( font^, name^ ); + {$I-} + Reset( font^, 1 ); + {$I+} + + System.FileMode := old_filemode; + + if IOResult <> 0 then + begin + error := TT_Err_Could_Not_Open_File; + Stream_Activate := Failure; + exit; + end; + + open := true; + base := 0; + if size = -1 then size := FileSize(font^); + + if posit <> 0 then + Seek( font^, posit ); + end; + end; + +(******************************************************************* + * + * Function : Stream_Deactivate + * + * Description : closes an active stream + * + * Input : stream : the target stream variable + * + * Output : Error condition + * + ******************************************************************) + + function Stream_Deactivate( stream : PStream_Rec ) : TError; + begin + Stream_Deactivate := Failure; + if stream = nil then exit; + + Stream_Deactivate := Success; + if not stream^.open then exit; + + stream^.posit := FilePos( stream^.font^ ); + close( stream^.font^ ); + stream^.open := false; + end; + +(******************************************************************* + * + * Function : Stream_Done + * + * Description : frees an active stream_rec + * + * Input : stream : the target stream variable + * + * Output : True on sucess. + * + * Notes : 'stream' is set to nil on exit.. + * + ******************************************************************) + + function Stream_Done( var stream : PStream_Rec ) : TError; + begin + Stream_Deactivate( stream ); + + Free( pointer(stream^.name) ); + Free( pointer(stream^.font) ); + Free( pointer(stream) ); + + Stream_Done := Success; + end; + +(******************************************************************* + * + * Function : TT_Open_Stream + * + * Description : opens the font file in a new stream + * + * Input : stream : target stream variable + * name : file pathname + * error : the variable that will be used to + * report stream errors + * + * Output : True on sucess. + * + ******************************************************************) + + function TT_Open_Stream( name : String; + var stream : TT_Stream ) : TError; + var + rec : PStream_Rec; + font : PFile; + + old_filemode : Long; + begin + TT_Open_Stream := Failure; + + if Stream_New( name, rec ) or + Stream_Activate( rec ) then + begin + stream.z := nil; + exit; + end; + + cur_stream := rec; + font_file := rec^.font; + stream := TT_Stream(rec); + + TT_Open_Stream := Success; + end; + +(******************************************************************* + * + * Function : TT_Close_Stream + * + * Description : Closes the font file and releases memory buffer + * + * Input : None + * + * Output : True ( always ) + * + ******************************************************************) + + procedure TT_Close_Stream( var stream : TT_Stream ); + begin + if stream.z = nil then exit; + + Stream_Done( PStream_Rec(stream) ); + font_file := nil; + cur_stream := nil; + stream.z := nil; + end; + +(******************************************************************* + * + * Function : TT_Use_Stream + * + * Description : Acquire the file mutex (blocking call) + * + * Input : org_stream : original stream to use + * stream : duplicate stream (in re-entrant builds) + * set to 'org_stream' otherwise + * error : error report variable + * + * Output : True on success. False on failure + * + ******************************************************************) + + function TT_Use_Stream( org_stream : TT_Stream; + var stream : TT_Stream ) : TError; + var + rec : PStream_Rec; + begin + TT_Use_Stream := Failure; + + stream := org_stream; + if org_stream.z = nil then exit; + + rec := PStream_Rec(stream); + Stream_Activate(rec); + cur_stream := rec; + font_file := rec^.font; + + TT_Use_Stream := Success; + end; + +(******************************************************************* + * + * Function : TT_Flush_Stream + * + * Description : closes a stream + * + * Input : stream : the stream + * + * Output : True on success. False on failure + * + ******************************************************************) + + procedure TT_Flush_Stream( stream : TT_Stream ); + begin + if stream.Z <> nil then + Stream_Deactivate( PStream_Rec(stream.z) ); + end; + +(******************************************************************* + * + * Function : TT_Done_Stream + * + * Description : Release the file mutex on a stream + * + * Input : stream : the stream + * + * Output : True on success. False on failure + * + ******************************************************************) + + procedure TT_Done_Stream( stream : TT_Stream ); + begin + if stream.z <> cur_stream then exit; + cur_stream := nil; + font_file := nil; + end; + +(******************************************************************* + * + * Function : TT_Seek_File + * + * Description : Seek the file cursor to a different position + * + * Input : APos new position on file + * + * Output : True on success. False if out of range + * + * Notes : Does not set the error variable + * + ******************************************************************) + +function TT_Seek_File( APos : LongInt ) : TError; +begin + {$I-} + Seek( Font_File^, APos ); + {$I+} + if IOResult <> 0 then + begin + error := TT_Err_Invalid_File_Offset; + TT_Seek_File := Failure; + exit; + end; + + TT_Seek_File := Success; +end; + +(******************************************************************* + * + * Function : TT_Skip_File + * + * Description : Skip forward the file cursor + * + * Input : ADist number of bytes to skip + * + * Output : see Seek_Font_File + * + ******************************************************************) + +function TT_Skip_File( ADist : LongInt ) : TError; +begin + TT_Skip_File := TT_Seek_File( FilePos(Font_File^)+ADist ); +end; + +(******************************************************************* + * + * Function : TT_Read_File + * + * Description : Reads a chunk of the file and copy it to memory + * + * Input : ABuff target buffer + * ACount length in bytes to read + * + * Output : True if success. False if out of range + * + * Notes : Current version prints an error message even if the + * debug state isn't on. + * + ******************************************************************) + +function TT_Read_File( var ABuff; ACount : Int ) : TError; +begin + TT_Read_File := Failure; + {$I-} + BlockRead( Font_File^, ABuff, ACount ); + {$I+} + + if IOResult <> 0 then + begin + error := TT_Err_Invalid_File_Read; + exit; + end; + + TT_Read_File := Success; +end; + +(******************************************************************* + * + * Function : TT_Read_At_File + * + * Description : Read file at a specified position + * + * Input : APos position to seek to before read + * ABuff target buffer + * ACount number of bytes to read + * + * Output : True on success. False if error. + * + * Notes : prints an error message if seek failed. + * + ******************************************************************) + +function TT_Read_At_File( APos : Long; var ABuff; ACount : Int ) : TError; +begin + TT_Read_At_File := Failure; + + if TT_Seek_File( APos ) or + TT_Read_File( ABuff, ACount ) then exit; + + TT_Read_At_File := Success; +end; + +(******************************************************************* + * + * Function : TT_Access_Frame + * + * Description : Notifies the component that we're going to read + * aSize bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx + * functions easily. + * + * Input : aSize number of bytes to access. + * + * Output : True on success. False on failure + * + * The function fails is the byte range is not within the + * the file, or if there is not enough memory to cache + * the bytes properly ( which usually means that aSize is + * too big in both cases ). + * + * It will also fail if you make two consecutive calls + * to TT_Access_Frame, without a TT_Forget_Frame between + * them. + * + ******************************************************************) + + function TT_Access_Frame( aSize : Int ) : TError; + var + readBytes : Longint; + begin + TT_Access_Frame := Failure; + + if current_frame <> nil then + begin + error := TT_Err_Nested_Frame_Access; + exit; + end; + (* We already are accessing one frame *) + + if aSize > frame_cache_size then + GetMem( current_frame, aSize ) + else + current_frame := frame_cache; + + if TT_Read_File( current_frame^, aSize ) then + begin + if aSize > frame_cache_size then + FreeMem( current_frame, aSize ); + + current_frame := nil; + exit; + end; + + frame_size := aSize; + frame_cursor := 0; + + TT_Access_Frame := Success; + end; + +(******************************************************************* + * + * Function : TT_Check_And_Access_Frame + * + * Description : Notifies the component that we're going to read + * aSize bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx + * functions easily. + * + * Input : aSize number of bytes to access. + * + * Output : True on success. False on failure + * + * The function fails is the byte range is not within the + * the file, or if there is not enough memory to cache + * the bytes properly ( which usually means that aSize is + * too big in both cases ). + * + * It will also fail if you make two consecutive calls + * to TT_Access_Frame, without a TT_Forget_Frame between + * them. + * + * + * NOTE : The only difference with TT_Access_Frame is that we check + * that the frame is within the current file. We otherwise + * truncate it.. + * + ******************************************************************) + + function TT_Check_And_Access_Frame( aSize : Int ) : TError; + var + readBytes : Longint; + begin + TT_Check_And_Access_Frame := Failure; + + if current_frame <> nil then + begin + error := TT_Err_Nested_Frame_Access; + exit; + end; + (* We already are accessing one frame *) + + readBytes := TT_File_Size - TT_File_Pos; + if aSize > readBytes then aSize := readBytes; + + if aSize > frame_cache_size then + GetMem( current_frame, aSize ) + else + current_frame := frame_cache; + + if TT_Read_File( current_frame^, aSize ) then + begin + if aSize > frame_cache_size then + FreeMem( current_frame, aSize ); + exit; + end; + + frame_size := aSize; + frame_cursor := 0; + + TT_Check_And_Access_Frame := Success; + end; + +(******************************************************************* + * + * Function : TT_Forget_Frame + * + * Description : Releases a cached frame after reading + * + * Input : None + * + * Output : True on success. False on failure + * + ******************************************************************) + + function TT_Forget_Frame : TError; + begin + TT_Forget_Frame := Failure; + + if current_frame = nil then exit; + + if frame_size > frame_cache_size then + FreeMem( current_frame, frame_size ); + + frame_size := 0; + current_frame := nil; + frame_cursor := 0; + end; + +(******************************************************************* + * + * Function : GET_Byte + * + * Description : Extracts a byte from the current file frame + * + * Input : None + * + * Output : Extracted Byte. + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call). + * + ******************************************************************) + + function GET_Byte : Byte; + begin + GET_Byte := current_frame^[frame_cursor]; + inc( frame_cursor ); + end; + +(******************************************************************* + * + * Function : GET_Char + * + * Description : Extracts a signed byte from the current file frame + * + * Input : None + * + * Output : Extracted char. + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call). + * + ******************************************************************) + + function GET_Char : ShortInt; + begin + GET_Char := ShortInt( current_frame^[frame_cursor] ); + inc( frame_cursor ); + end; + +(******************************************************************* + * + * Function : GET_Short + * + * Description : Extracts a short from the current file frame + * + * Input : None + * + * Output : Extracted short. + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call). + * + ******************************************************************) + + function GET_Short : Short; + begin + GET_Short := (Short(current_frame^[ frame_cursor ]) shl 8) or + Short(current_frame^[frame_cursor+1]); + inc( frame_cursor, 2 ); + end; + +(******************************************************************* + * + * Function : GET_UShort + * + * Description : Extracts an unsigned short from the frame + * + * Input : None + * + * Output : Extracted ushort. + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call). + * + ******************************************************************) + + function GET_UShort : UShort; + begin + GET_UShort := (UShort(current_frame^[ frame_cursor ]) shl 8) or + UShort(current_frame^[frame_cursor+1]); + inc( frame_cursor, 2 ); + end; + +(******************************************************************* + * + * Function : GET_Long + * + * Description : Extracts a long from the frame + * + * Input : None + * + * Output : Extracted long. + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call). + * + ******************************************************************) + + function GET_Long : Long; + begin + GET_Long := (Long(current_frame^[ frame_cursor ]) shl 24) or + (Long(current_frame^[frame_cursor+1]) shl 16) or + (Long(current_frame^[frame_cursor+2]) shl 8 ) or + (Long(current_frame^[frame_cursor+3]) ); + inc( frame_cursor, 4 ); + end; + +(******************************************************************* + * + * Function : GET_ULong + * + * Description : Extracts an unsigned long from the frame + * + * Input : None + * + * Output : Extracted ulong. + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call). + * + ******************************************************************) + + function GET_ULong : ULong; + begin + GET_ULong := (ULong(current_frame^[ frame_cursor ]) shl 24) or + (ULong(current_frame^[frame_cursor+1]) shl 16) or + (ULong(current_frame^[frame_cursor+2]) shl 8 ) or + (ULong(current_frame^[frame_cursor+3]) ); + inc( frame_cursor, 4 ); + end; + +(******************************************************************* + * + * Function : GET_Tag4 + * + * Description : Extracts a Tag from the frame + * + * Input : None + * + * Output : Extracted 4 byte Tag. + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call). + * + ******************************************************************) + + function GET_Tag4 : ULong; + var + C : array[0..3] of Byte; + begin + move ( current_frame^[frame_cursor], c, 4 ); + inc( frame_cursor, 4 ); + + GET_Tag4 := ULong(C); +end; + +end. diff --git a/pascal/lib/ttgload.pas b/pascal/lib/ttgload.pas new file mode 100644 index 0000000..43c5894 --- /dev/null +++ b/pascal/lib/ttgload.pas @@ -0,0 +1,1391 @@ +(******************************************************************* + * + * ttgload.pas 1.0 + * + * TrueType glyph loader + * + * Copyright 1996, 1997 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************) + +Unit TTGLoad; + +interface + +{$I TTCONFIG.INC} + +uses + FreeType, TTError, TTTypes, TTObjs; + + function Load_TrueType_Glyph( instance : PInstance; + glyph : PGlyph; + glyph_index : Word; + load_flags : Int ) : TError; + (* loads a font glyph into a given glyph info. The instance and *) + (* glyph objects faces _must_ match. The load_flags indicates *) + (* what kind of values should be written to the glyph object *) + (* ( metrics, outline in EM coordinates, grid-fitted outline.. ) *) + (* *) + (* by default ( i.e. with load_flags = 0 ), this function only *) + (* returns the unscaled glyph metrics and points in EM units. *) + (* *) + (* Use the following flags to query scaling and hinting ops. *) + + (********************************************************) + (* return horizontal or vertical metrics in font units *) + (* for a given glyph. The metrics are the left side *) + (* bearing [resp. top side bearing] and advance width *) + (* [resp. advance height]. *) + (* *) + (* This function may move later to another component.. *) + (* *) + procedure TT_Get_Metrics( var header : TT_Horizontal_Header; + index : Int; + var bearing : TT_Pos; + var advance : TT_Pos ); + + function Get_Advance_Widths( face : PFace; + ppem : Int ) : PByte; + +implementation + +uses + TTTables, + TTCalc, + TTMemory, + TTFile, + TTInterp, + TTLoad; + +const + ARGS_ARE_WORDS = $01; + ARGS_ARE_XY_VALUES = $02; + ROUND_XY_TO_GRID = $04; + WE_HAVE_A_SCALE = $08; + (* reserved $10 *) + MORE_COMPONENTS = $20; + WE_HAVE_AN_XY_SCALE = $40; + WE_HAVE_A_2X2 = $80; + WE_HAVE_INSTR = $100; + USE_MY_METRICS = $200; + + + (********************************************************) + (* return horizontal or vertical metrics in font units *) + (* for a given glyph. The metrics are the left side *) + (* bearing [resp. top side bearing] and advance width *) + (* [resp. advance height]. *) + (* *) + (* This function may move later to another component.. *) + (* *) + procedure TT_Get_Metrics( var header : TT_Horizontal_Header; + index : Int; + var bearing : TT_Pos; + var advance : TT_Pos ); + var + k : Int; + longs : PTableLongMetrics; + begin + k := header.number_Of_HMetrics; + + if index < k then + begin + longs := PTableLongMetrics(header.long_metrics); + bearing := longs^[index].bearing; + advance := longs^[index].advance; + end + else + begin + bearing := PTableShortMetrics(header.short_metrics)^[index-k]; + advance := PTableLongMetrics(header.long_metrics)^[k-1].advance; + end; + end; + + + + (********************************************************) + (* return horizontal metrics in font units for a *) + (* given glyph. if "check" is true, take care of *) + (* mono-spaced fonts by returning the aw max. *) + (* *) + procedure Get_HMetrics( face : PFace; + index : Int; + check : Boolean; + var lsb : Int; + var aw : Int ); + var + left_bearing, advance : TT_Pos; + begin + TT_Get_Metrics( face^.horizontalHeader, index, left_bearing, advance ); + + lsb := Int(left_bearing); + aw := Int(advance); + + if check and (face^.postscript.isFixedPitch <> 0) then + aw := face^.horizontalHeader.advance_Width_Max; + end; + + + + (********************************************************) + (* return advance width table for a given pixel size *) + (* if it is found in the font's "hdmx" table (if any) *) + (* *) + function Get_Advance_Widths( face : PFace; + ppem : Int ) : PByte; + var + n : Integer; + begin + with face^.hdmx do + for n := 0 to num_records-1 do + if records^[n].ppem = ppem then + begin + Get_Advance_Widths := records^[n].widths; + exit; + end; + + Get_Advance_Widths := nil; + end; + + (********************************************************) + (* copy current glyph into original one *) + (* *) + procedure cur_to_org( n : int; + pts : PGlyph_Zone ); + var + k : int; + begin + for k := 0 to n-1 do with pts^ do + org^[k] := cur^[k]; + end; + + + (********************************************************) + (* copy original glyph into current one *) + (* *) + procedure org_to_cur( n : int; + pts : PGlyph_Zone ); + var + k : int; + begin + for k := 0 to n-1 do with pts^ do + cur^[k] := org^[k]; + end; + + (********************************************************) + (* translate an array of coordinates *) + (* *) + procedure translate_array( n : int; + coords : TT_Points; + dx, dy : TT_Pos ); + var + k : Int; + begin + if dx <> 0 then + for k := 0 to n-1 do inc( coords^[k].x, dx ); + if dy <> 0 then + for k := 0 to n-1 do inc( coords^[k].y, dy ); + end; + + (********************************************************) + (* mount one zone on top of another one *) + (* *) + procedure mount_zone( var source : TGlyph_Zone; + var target : TGlyph_Zone ); + var + np, nc : Int; + begin + np := source.n_points; + nc := source.n_contours; + + target.org := @source.org^[np]; + target.cur := @source.cur^[np]; + target.flags := @source.flags^[np]; + + target.conEnds := @source.conEnds^[nc]; + + target.n_points := 0; + target.n_contours := 0; + end; + +(******************************************************************* + * + * Function : Load_Simple_Glyph + * + * + ******************************************************************) + + + function Load_Simple_Glyph( exec : PExec_Context; + stream : TT_Stream; + n_contours : Int; + left_contours : Int; + left_points : Int; + load_flags : Int; + subg : PSubGlyph_Record ) : TError; + var + n_points, + n_ins, k : Int; + + c, cnt : Byte; + face : PFace; + coords : TT_Points; + flag : TT_PTouchTable; + x, y : TT_F26dot6; + pts : PGlyph_Zone; + + label + Fail, Fail_File, Fail_Exec; + begin + Load_Simple_Glyph := Failure; + + face := exec^.face; + + (* simple check *) + + if ( n_contours > left_contours ) then + begin + {$IFDEF DEBUG} + Writeln( 'ERROR: Glyph index ',i,' has ',Gl.numberOfContours ); + Writeln( ' contours > left ', left_contours ); + {$ENDIF} + error := TT_Err_Too_Many_Contours; + goto Fail; + end; + + (* preparing the execution context *) + mount_zone( subg^.zone, exec^.pts ); + + (* Reading the contours endpoints *) + + if TT_Access_Frame( (n_contours+1)*2 ) then + goto Fail_File; + + n_points := 0; + + for k := 0 to n_contours-1 do + begin + {$IFDEF DEBUG} Write( n_points,' '); {$ENDIF} + n_points := GET_Short; + exec^.pts.conEnds^[k] := n_points; + inc( n_points ); + end; + + if n_points > left_points then + begin + {$IFDEF DEBUG} Writeln( 'ERROR: Too many points' ); {$ENDIF} + error := TT_Err_Too_Many_Points; + goto Fail; + end; + + (* Loading instructions *) + + n_ins := GET_Short; + + TT_Forget_Frame; + +{ + if not subg^.is_hinted then + + if TT_Skip_File( n_ins ) then + goto Fail_File + else + (* skip the instructions *) + + else } + begin + + {$IFDEF DEBUG} Writeln('Instructions size : ', n_ins); {$ENDIF} + + if n_ins > face^.maxProfile.maxSizeOfInstructions then + begin + {$IFDEF DEBUG} Writeln('Too many instructions'); {$ENDIF} + error := TT_Err_Too_Many_Ins; + goto Fail; + end; + + with exec^ do + begin + if TT_Read_File( glyphIns^, n_ins ) then + goto Fail_File; + + glyphSize := n_ins; + + if Set_CodeRange( exec, + TT_CodeRange_Glyph, + glyphIns, + glyphSize ) then + goto Fail_Exec; + end + end; + + (* read the flags *) + + if TT_Check_And_Access_Frame( n_points*5 ) + then goto Fail; + + k := 0; + flag := exec^.pts.flags; + + while ( k < n_points ) do + begin + c := GET_Byte; + flag^[k] := c; + inc(k); + + if c and 8 <> 0 then + begin + cnt := GET_Byte; + + while ( cnt > 0 ) do + begin + flag^[k] := c; + inc( k ); + dec( cnt ); + end + end + end; + + (* Read the X *) + + x := 0; + coords := exec^.pts.org; + + for k := 0 to n_points-1 do + begin + if flag^[k] and 2 <> 0 then + + if flag^[k] and 16 <> 0 then inc( x, GET_Byte ) + else inc( x, -GET_Byte ) + else + if flag^[k] and 16 = 0 then inc( x, GET_Short ); + + coords^[k].x := x; + end; + + (* Read the Y *) + + y := 0; + + for k := 0 to n_points-1 do + begin + if flag^[k] and 4 <> 0 then + + if flag^[k] and 32 <> 0 then inc( y, GET_Byte ) + else inc( y, -GET_Byte ) + else + if flag^[k] and 32 = 0 then inc( y, GET_Short ); + + coords^[k].y := y; + end; + + TT_Forget_Frame; + + (* Now adds the two shadow points at n and n+1 *) + (* We need the left side bearing and advance width *) + + (* pp1 = xMin - lsb == glyph origin *) + coords^[n_points].x := subg^.bbox.XMin-subg^.leftBearing; + coords^[n_points].y := 0; + + (* pp2 = pp1 + aw == glyph next position *) + coords^[n_points+1].x := subg^.bbox.xMin- + subg^.leftBearing + subg^.advanceWidth; + coords^[n_points+1].y := 0; + + for k := 0 to n_points-1 do + exec^.pts.flags^[k] := exec^.pts.flags^[k] and TT_Flag_On_Curve; + + exec^.pts.flags^[n_points ] := 0; + exec^.pts.flags^[n_points+1] := 0; + + (* Note that we now return two more points, that are not *) + (* part of the glyph outline *) + inc( n_points, 2 ); + + (* now eventually scale and hint the glyph *) + + pts := @exec^.pts; + pts^.n_points := n_points; + + exec^.pts.n_contours := n_contours; + + if load_flags and TT_Load_Scale_Glyph = 0 then + begin + (* no scaling, just copy the org arrays into the cur ones *) + org_to_cur( n_points, pts ); + end + else + begin + + (* first scale the glyph points *) + for k := 0 to n_points-1 do with pts^ do + org^[k].x := Scale_X( exec^.metrics, org^[k].x ); + + for k := 0 to n_points-1 do with pts^ do + org^[k].y := Scale_Y( exec^.metrics, org^[k].y ); + + (* if hinting, round pp1, and shift the glyph accordingly *) + if subg^.is_hinted then + begin + x := pts^.org^[n_points-2].x; + x := ((x+32) and -64) - x; + translate_array( n_points, pts^.org, x, 0 ); + + org_to_cur( n_points, pts ); + + (* set the advance width *) + (* + x := (Scale_X( exec^.metrics, subg^.advanceWidth )+32) and -64; + with pts^ do + cur_x^[n_points-1] := cur_x^[n_points-2]+x; + *) + with pts^ do + cur^[n_points-1].x := (cur^[n_points-1].x+32) and -64; + + (* now consider hinting *) + if (exec^.glyphSize > 0) then + begin + exec^.is_composite := False; + + if Context_Run( exec, load_flags and TT_Load_Debug <> 0 ) then + goto Fail_Exec; + end; + end + else + org_to_cur( n_points, pts ); + end; + + (* save glyph origin and advance points *) + if not subg^.preserve_pps then + begin + subg^.pp1 := pts^.cur^[n_points-2]; + subg^.pp2 := pts^.cur^[n_points-1]; + end; + + Load_Simple_Glyph := Success; + + Fail: + exit; + + Fail_File: + error := TT_Err_File_Error; + exit; + + Fail_Exec: + error := exec^.error; + exit; + end; + +(******************************************************************* + * + * Function : Load_Composite_End + * + * + ******************************************************************) + + function Load_Composite_End( n_points : Int; + n_contours : Int; + exec : PExec_Context; + subg : PSubglyph_Record; + debug : Boolean ) : TError; + var + pts : PGlyph_Zone; + n_ins : Int; + k : Int; + phant1, + phant2, + x, y : TT_Pos; + widths : PByte; + + label + Fail, Fail_File, Fail_Exec; + begin + Load_Composite_End := Failure; + + if subg^.is_hinted and + (subg^.element_flag and WE_HAVE_INSTR <> 0) then + begin + if TT_Access_Frame(2) then goto Fail_File; + n_ins := Get_UShort; + TT_Forget_Frame; + + (* load the instructions *) + {$IFDEF DEBUG} Writeln('Instructions size : ', n_ins); {$ENDIF} + + if n_ins > exec^.face^.maxProfile.maxSizeOfInstructions then + begin + {$IFDEF DEBUG} Writeln('Too many instructions'); {$ENDIF} + error := TT_Err_Too_Many_Ins; + goto Fail; + end; + end + else + n_ins := 0; + + if n_ins > 0 then with exec^ do + begin + if TT_Read_File( glyphIns^, n_ins ) then + goto Fail_File; + + glyphSize := n_ins; + + if Set_CodeRange( exec, + TT_CodeRange_Glyph, + glyphIns, + glyphSize ) then goto Fail_File; + end; + + (* prepare the execution context *) + inc( n_points, 2 ); + + exec^.pts := subg^.zone; + pts := @exec^.pts; + pts^.n_points := n_points; + + (* add phantom points *) + with pts^ do + begin + cur^[n_points-2] := subg^.pp1; + cur^[n_points-1] := subg^.pp2; + flags^[n_points-2] := 0; + flags^[n_points-1] := 0; + end; + + (* if hinting, round the phantom points *) + if subg^.is_hinted then + begin + y := ((subg^.pp1.x+32) and -64); + pts^.cur^[n_points-2].y := y; + + x := ((subg^.pp2.x+32) and -64); + pts^.cur^[n_points-1].x := x; + end; + + for k := 0 to n_points-1 do + pts^.flags^[k] := pts^.flags^[k] and TT_Flag_On_Curve; + + cur_to_org( n_points, pts ); + + (* now consider hinting *) + if subg^.is_hinted and (n_ins > 0) then + begin + exec^.is_composite := true; + + if Context_Run( exec, debug ) then + goto Fail_Exec; + end; + + (* save glyph origin and advance points *) + subg^.pp1 := pts^.cur^[n_points-2]; + subg^.pp2 := pts^.cur^[n_points-1]; + + Load_Composite_End := Success; + error := TT_Err_Ok; + + Fail: + exit; + + Fail_File: + error := TT_Err_File_Error; + goto Fail; + + Fail_Exec: + error := exec^.error; + goto Fail; + + end; + + +(******************************************************************* + * + * Function : Init_Glyph_Component + * + * + ******************************************************************) + + + procedure Init_Glyph_Component( element : PSubGlyph_Record; + original : PSubGlyph_Record; + exec : PExec_Context ); + var + n: Int; + begin + with element^ do + begin + index := -1; + is_scaled := false; + is_hinted := false; + + if original <> nil then + mount_zone( original^.zone, zone ) + else + zone := exec^.pts; + + zone.n_contours := 0; + zone.n_points := 0; + + arg1 := 0; + arg2 := 0; + + element_flag := 0; + preserve_pps := false; + + transform.xx := 1 shl 16; + transform.xy := 0; + transform.yx := 0; + transform.yy := 1 shl 16; + + transform.ox := 0; + transform.oy := 0; + + leftBearing := 0; + advanceWidth := 0; + end; + end; + + + function Load_TrueType_Glyph( instance : PInstance; + glyph : PGlyph; + glyph_index : Word; + load_flags : Int ) : TError; + type + TPhases = ( Load_Exit, + Load_Glyph, + Load_Simple, + Load_Composite, + Load_End ); + (* the composite loader is a simple automata wich states *) + (* are defined by the TPhases enumeration *) + + var + face : PFace; + + num_points : Int; + num_contours : Int; + left_points : Int; + left_contours : Int; + + table, + num_ins, + index, + load_top : Int; + + new_flags, k, l : Int; + + glyph_offset, offset : Long; + + c : Byte; + + vec, nvec : TT_Vector; + + xmin, xmax, ymin, ymax : TT_F26Dot6; + + xx, xy, yx, yy : TT_Fixed; + + exec : PExec_Context; + stream : TT_Stream; + + subglyph, subglyph2 : PSubGlyph_Record; + + base_pts : TGlyph_Zone; + + phase : TPhases; + + debug : Boolean; + + leftSideBearing : TT_Pos; + advanceWidth : TT_Pos; + + top_bearing : TT_Pos; + advance_height : TT_Pos; + + error : TT_Error; + delta : Long; + widths : PByte; + horizontal : TT_Horizontal_Header; + label + Fin, + Fail, + Fail_File, + Fail_Handle, + Fail_Index; + + begin + + Load_TrueType_Glyph := Failure; + + (* check handle *) + + if (instance = nil) or (instance^.owner = nil) then + begin + error := TT_Err_Invalid_Face_Handle; + exit; + end; + + face := instance^.owner; + + table := LookUp_TrueType_Table( face, 'glyf'); + if table < 0 then + begin + {$IFDEF DEBUG} + Trace1( 'TTApi.load_glyph : couldn''t find glyf table' ); + {$ENDIF} + error := TT_Err_Table_Missing; + exit; + end; + + glyph_offset := face^.dirTables^[table].Offset; + + (* query new execution context *) + + if instance^.debug then + exec := instance^.context (* if debugging, use the pre-alloced context *) + else + exec := New_Context(instance); + + if exec = nil then + begin + error := TT_Err_Out_Of_Memory; + exit; + end; + + Context_Load( exec, instance ); + if instance^.GS.instruct_control and 2 <> 0 then + exec^.GS := Default_GraphicsState + else + exec^.GS := instance^.GS; + + glyph^.outline.high_precision := ( instance^.metrics.y_ppem < 24 ); + + glyph^.is_composite := false; + + (* save its critical pointers that will be modified *) + (* during load *) + + base_pts := exec^.pts; + + (* init variables *) + + left_points := face^.maxPoints; + left_contours := face^.maxContours; + + num_points := 0; + num_contours := 0; + + load_top := 0; + subglyph := @exec^.loadStack^[0]; + + Init_Glyph_Component( subglyph, nil, exec ); + + subglyph^.index := glyph_index; + subglyph^.is_hinted := load_flags and TT_Load_Hint_Glyph <> 0; + + if instance^.GS.instruct_control and 1 <> 0 then + subglyph^.is_hinted := False; + + (* now access stream *) + + if TT_Use_Stream( face^.stream, stream ) then + goto Fin; + + (* Main Loading Loop *) + + phase := Load_Glyph; + + while phase <> Load_Exit do + begin + + subglyph := @exec^.loadStack^[load_top]; + + case phase of + + (************************************************************) + (* *) + (* Load_Glyph state *) + (* *) + (* reading a glyph's generic header to determine *) + (* wether it's simple or composite *) + (* *) + (* exit states : Load_Simple and Load_Composite *) + (* *) + + Load_Glyph: + begin + (* check glyph index and table *) + + index := subglyph^.index; + if (index < 0) or (index >= face^.numGlyphs) then + begin + error := TT_Err_Invalid_Glyph_Index; + goto Fail; + end; + + (* load glyph metrics *) + Get_HMetrics( face, index, true, + subglyph^.leftBearing, + subglyph^.advanceWidth ); + + (* load glyph *) + if (index+1 < face^.numLocations) and + (face^.glyphLocations^[index] = face^.glyphLocations^[index+1]) then + begin + + (* as noticed by Frederic Loyer, these are spaces, not *) + (* the 'unknown' glyph *) + num_points := 0; + num_contours := 0; + + subglyph^.bbox.xMin := 0; + subglyph^.bbox.xMax := 0; + subglyph^.bbox.yMin := 0; + subglyph^.bbox.yMax := 0; + + subglyph^.pp1.x := 0; + subglyph^.pp2.x := subglyph^.advanceWidth; + if load_flags and TT_LOAD_Scale_Glyph <> 0 then + subglyph^.pp2.x := Scale_X( exec^.metrics, subglyph^.pp2.x ); + + exec^.glyphSize := 0; + phase := Load_End; + end + else + begin + offset := glyph_offset + face^.glyphLocations^[index]; + + (* read first glyph header *) + + if TT_Seek_File( offset ) or + TT_Access_Frame( 5*sizeof(Short) ) then + goto Fail_File; + + num_contours := GET_Short; + subglyph^.bbox.xMin := GET_Short; + subglyph^.bbox.yMin := GET_Short; + subglyph^.bbox.xMax := GET_Short; + subglyph^.bbox.yMax := GET_Short; + + TT_Forget_Frame; + + {$IFDEF DEBUG} + Writeln('Glyph ', i ); + + Writeln(' # of Contours : ',num_contours ); + Writeln(' xMin : ',subglyph^.xMin:4,' xMax : ',subglyph^.xMax); + Writeln(' yMin : ',subglyph^.yMin:4,' yMax : ',subglyph^.yMax); + Writeln('-'); + {$ENDIF} + + if num_contours > left_contours then + begin + {$IFDEF DEBUG} + Writeln( 'ERROR: Glyph index ', i, ' has ', num_contours ); + Writeln(' contours > left ', left_contours ); + {$ENDIF} + error := TT_Err_Too_Many_Contours; + goto Fail; + end; + + with subglyph^ do + begin + pp1.x := bbox.xMin - leftBearing; + pp1.y := 0; + pp2.x := pp1.x + advanceWidth; + pp2.y := 0; + + if load_flags and TT_Load_Scale_Glyph <> 0 then + begin + pp1.x := Scale_X( exec^.metrics, pp1.x ); + pp2.x := Scale_X( exec^.metrics, pp2.x ); + end; + end; + + (* is it a simple glyph ? *) + if num_contours >= 0 then + phase := Load_Simple + else + phase := Load_Composite; + + end + end; + + (************************************************************) + (* *) + (* Load_Simple state *) + (* *) + (* reading a simple glyph (num_contours must be set to *) + (* the glyph's number of contours..) *) + (* *) + (* exit states : Load_End *) + (* *) + + Load_Simple : + begin + new_flags := load_flags; + + if not subglyph^.is_hinted then + new_flags := new_flags and not TT_Load_Hint_Glyph; + (* disable hinting when scaling *) + + if new_flags and TT_Load_Debug <> 0 then + if load_top > 0 then + new_flags := new_flags and not TT_Load_Debug; + + if Load_Simple_Glyph( + exec, + stream, + num_contours, + left_contours, + left_points, + new_flags, + subglyph ) then + goto Fail; + + num_points := exec^.pts.n_points-2; + + phase := Load_End; + end; + + (************************************************************) + (* *) + (* Load_Composite state *) + (* *) + (* reading a composite glyph header a pushing a new *) + (* load element on the stack.. *) + (* *) + (* exit states : Load_Glyph *) + (* *) + + Load_Composite : + begin + + glyph^.is_composite := true; + + (* create a new element *) + + inc( load_top ); + + if load_top > face^.maxComponents then + begin + error := TT_Err_Invalid_Composite; + goto Fail; + end; + + subglyph2 := @exec^.loadStack^[load_top]; + + Init_Glyph_Component( subglyph2, subglyph, nil ); + + subglyph2^.index := -1; + subglyph2^.is_hinted := subglyph^.is_hinted; + + (* now read composite header *) + + if TT_Access_Frame( 4 ) then + goto Fail_File; + + new_flags := Get_UShort; + + subglyph^.element_flag := new_flags; + subglyph2^.index := Get_UShort; + + TT_Forget_Frame; + + k := 2; + + if new_flags and ARGS_ARE_WORDS <> 0 then + inc( k, 2 ); + + if new_flags and WE_HAVE_A_SCALE <> 0 then + inc( k, 2 ); + + if new_flags and WE_HAVE_AN_XY_SCALE <> 0 then + inc( k, 4 ); + + if new_flags and WE_HAVE_A_2X2 <> 0 then + inc( k, 8 ); + + if TT_Access_Frame( k ) then + goto Fail_File; + + if new_flags and ARGS_ARE_WORDS <> 0 then + begin + k := Get_Short; + l := Get_Short; + end + else + begin + k := Get_Byte; + l := Get_Byte; + end; + + subglyph^.arg1 := k; + subglyph^.arg2 := l; + + if new_flags and ARGS_ARE_XY_VALUES <> 0 then + begin + subglyph^.transform.ox := k; + subglyph^.transform.oy := l; + end; + + xx := 1 shl 16; + xy := 0; + yx := 0; + yy := 1 shl 16; + + if new_flags and WE_HAVE_A_SCALE <> 0 then + begin + xx := Long(Get_Short) shl 2; + yy := xx; + + subglyph2^.is_scaled := true; + end + else if new_flags and WE_HAVE_AN_XY_SCALE <> 0 then + begin + xx := Long(Get_Short) shl 2; + yy := Long(Get_Short) shl 2; + + subglyph2^.is_scaled := true; + end + else if new_flags and WE_HAVE_A_2X2 <> 0 then + begin + xx := Long(Get_Short) shl 2; + xy := Long(Get_Short) shl 2; + yx := Long(Get_Short) shl 2; + yy := Long(Get_Short) shl 2; + + subglyph2^.is_scaled := true; + end; + + subglyph^.transform.xx := xx; + subglyph^.transform.xy := xy; + subglyph^.transform.yx := yx; + subglyph^.transform.yy := yy; + + delta := MulDiv_Round( xx, yy, 1 shl 16 ) - + MulDiv_Round( xy, yx, 1 shl 16 ); + + if abs(delta) <> 1 shl 16 then + subglyph2^.is_hinted := false; + + TT_Forget_Frame; + + subglyph^.file_offset := TT_File_Pos; + + phase := Load_Glyph; + end; + + (************************************************************) + (* *) + (* Load_End state *) + (* *) + (* after loading a glyph, apply transform and offset *) + (* where necessary, pops element and continue or *) + (* stop process.. *) + (* *) + (* exit states : Load_Composite and Load_Exit *) + (* *) + + Load_End : + if load_top > 0 then + begin + + subglyph2 := subglyph; + + dec( load_top ); + subglyph := @exec^.loadStack^[load_top]; + + (* check advance width and left side bearing *) + + if not subglyph^.preserve_pps and + (subglyph^.element_flag and USE_MY_METRICS <> 0) then + begin + + subglyph^.leftBearing := subglyph2^.leftBearing; + subglyph^.advanceWidth := subglyph2^.advanceWidth; + + subglyph^.pp1 := subglyph2^.pp1; + subglyph^.pp2 := subglyph2^.pp2; + + subglyph^.preserve_pps := true; + end; + + (* apply scale/symmetry/rotation/wathever *) + + for k := 0 to num_points-1 do with subglyph^ do + begin + vec := subglyph2^.zone.cur^[k]; + + nvec.x := MulDiv_Round( vec.x, transform.xx, 1 shl 16 ) + + MulDiv_Round( vec.y, transform.yx, 1 shl 16 ); + + nvec.y := MulDiv_Round( vec.x, transform.xy, 1 shl 16 ) + + MulDiv_Round( vec.y, transform.yy, 1 shl 16 ); + + subglyph2^.zone.cur^[k] := nvec; + + vec := subglyph2^.zone.org^[k]; + + nvec.x := MulDiv_Round( vec.x, transform.xx, 1 shl 16 ) + + MulDiv_Round( vec.y, transform.yx, 1 shl 16 ); + + nvec.y := MulDiv_Round( vec.x, transform.xy, 1 shl 16 ) + + MulDiv_Round( vec.y, transform.yy, 1 shl 16 ); + + subglyph2^.zone.org^[k] := nvec; + end; + + (* adjust counts *) + for k := 0 to num_contours-1 do + inc( subglyph2^.zone.conEnds^[k], subglyph^.zone.n_points ); + + inc( subglyph^.zone.n_points, num_points ); + inc( subglyph^.zone.n_contours, num_contours ); + + dec( left_points, num_points ); + dec( left_contours, num_contours ); + + (* apply offset *) + + if subglyph^.element_flag and ARGS_ARE_XY_VALUES = 0 then + begin + k := subglyph^.arg1; + l := subglyph^.arg2; + + if (k < 0) or (k >= subglyph^.zone.n_points ) or + (l < 0) or (l >= num_points) then + begin + error := TT_Err_Invalid_Composite; + goto Fail; + end; + + inc( l, subglyph^.zone.n_points ); + + vec.x := subglyph^.zone.cur^[k].x - + subglyph^.zone.cur^[l].x; + + vec.y := subglyph^.zone.cur^[k].y - + subglyph^.zone.cur^[l].y; + end + else + begin + vec.x := subglyph^.transform.ox; + vec.y := subglyph^.transform.oy; + + if load_flags and TT_Load_Scale_Glyph <> 0 then + begin + vec.x := Scale_X( exec^.metrics, vec.x ); + vec.y := Scale_Y( exec^.metrics, vec.y ); + + if subglyph^.element_flag and ROUND_XY_TO_GRID <> 0 then + begin + vec.x := (vec.x+32) and -64; + vec.y := (vec.y+32) and -64; + end; + end + end; + + translate_array( num_points, subglyph2^.zone.cur, vec.x, vec.y ); + + cur_to_org( num_points, @subglyph2^.zone ); + + num_points := subglyph^.zone.n_points; + num_contours := subglyph^.zone.n_contours; + + (* check for last component *) + + if TT_Seek_File( subglyph^.file_offset ) then + goto Fail_File; + + if subglyph^.element_flag and MORE_COMPONENTS <> 0 then + phase := Load_Composite + else + begin + debug := ( load_top = 0 ) and + ( load_flags and TT_Load_Debug <> 0 ); + + if Load_Composite_End( num_points, + num_contours, + exec, + subglyph, + debug ) then goto Fail; + phase := Load_End; + end; + + end + else + phase := Load_Exit; + + end; + end; + + (* finally, copy the points arrays to the glyph object *) + + exec^.pts := base_pts; + + (* copy also the phantom points, the debugger needs them *) + inc( num_points, 2 ); + + for k := 0 to num_points-1 do with glyph^.outline do + begin + points^[k] := exec^.pts.cur^[k]; + flags ^[k] := exec^.pts.flags^[k]; + end; + + for k := 0 to num_contours-1 do with glyph^.outline do + conEnds^[k] := exec^.pts.conEnds^[k]; + + glyph^.outline.n_points := num_points; + glyph^.outline.n_contours := num_contours; + glyph^.outline.second_pass := true; + + TT_Get_Outline_BBox( glyph^.outline, glyph^.metrics.bbox ); + + glyph^.metrics.horiBearingX := glyph^.metrics.bbox.xMin - subglyph^.pp1.x; + glyph^.metrics.horiBearingY := glyph^.metrics.bbox.yMax; + glyph^.metrics.horiAdvance := subglyph^.pp2.x - subglyph^.pp1.x; + + glyph^.computed_width := glyph^.metrics.horiAdvance; + glyph^.precalc_width := -1; + + (* Now take care of vertical metrics. In the case where there is *) + (* no vertical information within the font (which is relatively *) + (* common), make up some metrics "by hand".. *) + (* *) + + begin + (* get the unscaled "tsb" and "ah" *) + (* don't assume that both the vertical header and metrics are *) + (* present in a font file... *) + if face^.verticalInfo and + ( face^.verticalHeader.number_Of_VMetrics > 0 ) then + begin + (* apparently, the following line isn't accepted by the FreePascal *) + (* compiler. It complains because the typecast occurs on a 'var' *) + (* parameter. Don't know if this is compiler bug or not, but I *) + (* changed the code with some stupid copy trick.. *) + (* *) + (* TT_Get_Metrics( TT_Horizontal_Header(face^.verticalHeader), *) + (* glyph_index, *) + (* top_bearing, *) + (* advance_height ); *) + (* *) + horizontal := TT_Horizontal_Header(face^.verticalHeader); + TT_Get_Metrics( horizontal, + glyph_index, + top_bearing, + advance_height ); + end + else + begin + (* Make up the distances from the horizontal header.. *) + (* *) + (* The typographic values are the only portable ones, which *) + (* is why we use them.. *) + (* *) + (* The sTypoDescender field is always negative, unlike the *) + (* Windows Descender.. *) + (* *) + with face^.os2 do + begin + top_bearing := sTypoLineGap div 2; + advance_height := sTypoAscender - sTypoDescender + sTypoLineGap; + end; + + end; + + (* now scale the metrics *) + if load_flags and TT_Load_Scale_Glyph <> 0 then + begin + top_bearing := Scale_Y( exec^.metrics, top_bearing ); + advance_height := Scale_Y( exec^.metrics, advance_height ); + end; + + with glyph^.metrics do + begin + vertBearingX := ( bbox.xMin - bbox.xMax ) div 2; + vertBearingY := top_bearing; + vertAdvance := advance_height; + + if load_flags and TT_Load_Hint_Glyph <> 0 then + begin + vertBearingX := vertBearingX and -64; + vertBearingY := (vertBearingY + 63) and -64; + vertAdvance := (vertAdvance+32) and -64; + end; + end; + + end; + + (* use hdmx table to adjust advance width as necessary *) + if load_flags and TT_Load_Default = TT_Load_Default then + begin + widths := Get_Advance_Widths( exec^.face, + exec^.instance^.metrics.x_ppem ); + if widths <> nil then + begin + glyph^.metrics.horiAdvance := widths^[glyph_index]*64; + glyph^.precalc_width := glyph^.metrics.horiAdvance; + end; + end; + + (* in case of hinting, shift the glyph so that (0,0) corresponds *) + (* to the glyph origin. *) + if subglyph^.is_hinted then + begin + glyph^.metrics.horiBearingX := (glyph^.metrics.bbox.xMin and -64) - + subglyph^.pp1.x; + + glyph^.metrics.horiAdvance := (glyph^.metrics.horiAdvance+32) and -64; + glyph^.computed_width := (glyph^.computed_width+32) and -64; + + translate_array( num_points, + glyph^.outline.points, + -subglyph^.pp1.x, + 0 ); + end; + + glyph^.outline.dropout_mode := exec^.GS.scan_type; + + Load_TrueType_Glyph := Success; + + Fail: + TT_Done_Stream( stream ); + + Fin: + + (* reset the execution context *) + exec^.pts := base_pts; + + if instance^.debug then + begin + exec^.pts.n_points := num_points; + exec^.pts.n_contours := num_contours; + end + else + Done_Context( exec); + + exit; + + Fail_File: + error := TT_Err_File_Error; + goto Fail; + + Fail_Handle: + error := TT_Err_Invalid_Instance_Handle; + exit; + + Fail_Index: + error := TT_Err_Invalid_Glyph_Index; + exit; + + end; + + +end. diff --git a/pascal/lib/ttinterp.pas b/pascal/lib/ttinterp.pas new file mode 100644 index 0000000..4d82e99 --- /dev/null +++ b/pascal/lib/ttinterp.pas @@ -0,0 +1,4797 @@ +(******************************************************************* + * + * TTInterp.pas 2.0 + * + * TrueType bytecode intepreter. + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * Changes between 2.0 and 1.2 : + * + * - Lots, lots, of changes : This version is not re-entrant, + * but much faster. + * + * + ******************************************************************) + +unit TTInterp; + +interface + +uses FreeType, + TTTypes, + TTObjs; + + function Run_Ins( exec : PExec_Context ) : Boolean; + (* Run the interpreter with the current code range and IP *) + +implementation +uses + TTError, + TTMemory, + TTCalc; + +type + TInstruction_Function = procedure( args : PStorage ); + +const + Null_Vector : TT_Vector = (x:0;y:0); + +var + exc : TExec_Context; (* static variable *) + +const + + (*********************************************************************) + (* *) + (* Before an opcode is executed, the interpreter verifies that *) + (* there are enough arguments on the stack, with the help of *) + (* the Pop_Push_Count table. *) + (* *) + (* Note that for opcodes with a varying numbre of parameters, *) + (* either 0 or 1 arg is verified before execution, depending *) + (* on the nature of the instruction : *) + (* *) + (* - if the number of arguments is given by the bytecode *) + (* stream or the loop variable, 0 is chosen. *) + (* *) + (* - if the first argument is a count n that is followed *) + (* by arguments a1..an, then 1 is chosen. *) + (* *) + (*********************************************************************) + + Pop_Push_Count : array[0..511] of byte + = ( + (* SVTCA y *) 0, 0, + (* SVTCA x *) 0, 0, + (* SPvTCA y *) 0, 0, + (* SPvTCA x *) 0, 0, + (* SFvTCA y *) 0, 0, + (* SFvTCA x *) 0, 0, + (* SPvTL // *) 2, 0, + (* SPvTL + *) 2, 0, + (* SFvTL // *) 2, 0, + (* SFvTL + *) 2, 0, + (* SPvFS *) 2, 0, + (* SFvFS *) 2, 0, + (* GPV *) 0, 2, + (* GFV *) 0, 2, + (* SFvTPv *) 0, 0, + (* ISECT *) 5, 0, + + (* SRP0 *) 1, 0, + (* SRP1 *) 1, 0, + (* SRP2 *) 1, 0, + (* SZP0 *) 1, 0, + (* SZP1 *) 1, 0, + (* SZP2 *) 1, 0, + (* SZPS *) 1, 0, + (* SLOOP *) 1, 0, + (* RTG *) 0, 0, + (* RTHG *) 0, 0, + (* SMD *) 1, 0, + (* ELSE *) 0, 0, + (* JMPR *) 1, 0, + (* SCvTCi *) 1, 0, + (* SSwCi *) 1, 0, + (* SSW *) 1, 0, + + (* DUP *) 1, 2, + (* POP *) 1, 0, + (* CLEAR *) 0, 0, + (* SWAP *) 2, 2, + (* DEPTH *) 0, 1, + (* CINDEX *) 1, 1, + (* MINDEX *) 1, 0, (* first arg *) + (* AlignPTS *) 2, 0, + (* INS_$28 *) 0, 0, + (* UTP *) 1, 0, + (* LOOPCALL *) 2, 0, + (* CALL *) 1, 0, + (* FDEF *) 1, 0, + (* ENDF *) 0, 0, + (* MDAP[0] *) 1, 0, + (* MDAP[1] *) 1, 0, + + (* IUP[0] *) 0, 0, + (* IUP[1] *) 0, 0, + (* SHP[0] *) 0, 0, (* no args *) + (* SHP[1] *) 0, 0, (* no args *) + (* SHC[0] *) 1, 0, + (* SHC[1] *) 1, 0, + (* SHZ[0] *) 1, 0, + (* SHZ[1] *) 1, 0, + (* SHPIX *) 1, 0, (* first arg *) + (* IP *) 0, 0, (* no args *) + (* MSIRP[0] *) 2, 0, + (* MSIRP[1] *) 2, 0, + (* AlignRP *) 0, 0, (* no args *) + (* RTDG *) 0, 0, + (* MIAP[0] *) 2, 0, + (* MIAP[1] *) 2, 0, + + (* NPushB *) 0, 0, + (* NPushW *) 0, 0, + (* WS *) 2, 0, + (* RS *) 1, 1, + (* WCvtP *) 2, 0, + (* RCvt *) 1, 1, + (* GC[0] *) 1, 1, + (* GC[1] *) 1, 1, + (* SCFS *) 2, 0, + (* MD[0] *) 2, 1, + (* MD[1] *) 2, 1, + (* MPPEM *) 0, 1, + (* MPS *) 0, 1, + (* FlipON *) 0, 0, + (* FlipOFF *) 0, 0, + (* DEBUG *) 1, 0, + + (* LT *) 2, 1, + (* LTEQ *) 2, 1, + (* GT *) 2, 1, + (* GTEQ *) 2, 1, + (* EQ *) 2, 1, + (* NEQ *) 2, 1, + (* ODD *) 1, 1, + (* EVEN *) 1, 1, + (* IF *) 1, 0, + (* EIF *) 0, 0, + (* AND *) 2, 1, + (* OR *) 2, 1, + (* NOT *) 1, 1, + (* DeltaP1 *) 1, 0, (* first arg *) + (* SDB *) 1, 0, + (* SDS *) 1, 0, + + (* ADD *) 2, 1, + (* SUB *) 2, 1, + (* DIV *) 2, 1, + (* MUL *) 2, 1, + (* ABS *) 1, 1, + (* NEG *) 1, 1, + (* FLOOR *) 1, 1, + (* CEILING *) 1, 1, + (* ROUND[0] *) 1, 1, + (* ROUND[1] *) 1, 1, + (* ROUND[2] *) 1, 1, + (* ROUND[3] *) 1, 1, + (* NROUND[0]*) 1, 1, + (* NROUND[1]*) 1, 1, + (* NROUND[2]*) 1, 1, + (* NROUND[3]*) 1, 1, + + (* WCvtF *) 2, 0, + (* DeltaP2 *) 1, 0, (* first arg *) + (* DeltaP3 *) 1, 0, (* first arg *) + (* DeltaCn[0]*) 1, 0, (* first arg *) + (* DeltaCn[1]*) 1, 0, (* first arg *) + (* DeltaCn[2]*) 1, 0, (* first arg *) + (* SROUND *) 1, 0, + (* S45Round *) 1, 0, + (* JROT *) 2, 0, + (* JROF *) 2, 0, + (* ROFF *) 0, 0, + (* INS_$7B *) 0, 0, + (* RUTG *) 0, 0, + (* RDTG *) 0, 0, + (* SANGW *) 1, 0, + (* AA *) 1, 0, + + (* FlipPT *) 0, 0, (* no args *) + (* FlipRgON *) 2, 0, + (* FlipRgOFF*) 2, 0, + (* INS_$83 *) 0, 0, + (* INS_$84 *) 0, 0, + (* ScanCTRL *) 1, 0, + (* SDVPTL[0]*) 2, 0, + (* SDVPTL[1]*) 2, 0, + (* GetINFO *) 1, 1, + (* IDEF *) 1, 0, + (* ROLL *) 3, 3, (* pops 3 args/push 3 args *) + (* MAX *) 2, 1, + (* MIN *) 2, 1, + (* ScanTYPE *) 1, 0, + (* InstCTRL *) 2, 0, + (* INS_$8F *) 0, 0, + + (* INS_$90 *) 0, 0, + (* INS_$91 *) 0, 0, + (* INS_$92 *) 0, 0, + (* INS_$93 *) 0, 0, + (* INS_$94 *) 0, 0, + (* INS_$95 *) 0, 0, + (* INS_$96 *) 0, 0, + (* INS_$97 *) 0, 0, + (* INS_$98 *) 0, 0, + (* INS_$99 *) 0, 0, + (* INS_$9A *) 0, 0, + (* INS_$9B *) 0, 0, + (* INS_$9C *) 0, 0, + (* INS_$9D *) 0, 0, + (* INS_$9E *) 0, 0, + (* INS_$9F *) 0, 0, + + (* INS_$A0 *) 0, 0, + (* INS_$A1 *) 0, 0, + (* INS_$A2 *) 0, 0, + (* INS_$A3 *) 0, 0, + (* INS_$A4 *) 0, 0, + (* INS_$A5 *) 0, 0, + (* INS_$A6 *) 0, 0, + (* INS_$A7 *) 0, 0, + (* INS_$A8 *) 0, 0, + (* INS_$A9 *) 0, 0, + (* INS_$AA *) 0, 0, + (* INS_$AB *) 0, 0, + (* INS_$AC *) 0, 0, + (* INS_$AD *) 0, 0, + (* INS_$AE *) 0, 0, + (* INS_$AF *) 0, 0, + + (* PushB[0] *) 0, 1, + (* PushB[1] *) 0, 2, + (* PushB[2] *) 0, 3, + (* PushB[3] *) 0, 4, + (* PushB[4] *) 0, 5, + (* PushB[5] *) 0, 6, + (* PushB[6] *) 0, 7, + (* PushB[7] *) 0, 8, + (* PushW[0] *) 0, 1, + (* PushW[1] *) 0, 2, + (* PushW[2] *) 0, 3, + (* PushW[3] *) 0, 4, + (* PushW[4] *) 0, 5, + (* PushW[5] *) 0, 6, + (* PushW[6] *) 0, 7, + (* PushW[7] *) 0, 8, + + (* MDRP[00] *) 1, 0, + (* MDRP[01] *) 1, 0, + (* MDRP[02] *) 1, 0, + (* MDRP[03] *) 1, 0, + (* MDRP[04] *) 1, 0, + (* MDRP[05] *) 1, 0, + (* MDRP[06] *) 1, 0, + (* MDRP[07] *) 1, 0, + (* MDRP[08] *) 1, 0, + (* MDRP[09] *) 1, 0, + (* MDRP[10] *) 1, 0, + (* MDRP[11] *) 1, 0, + (* MDRP[12] *) 1, 0, + (* MDRP[13] *) 1, 0, + (* MDRP[14] *) 1, 0, + (* MDRP[15] *) 1, 0, + (* MDRP[16] *) 1, 0, + (* MDRP[17] *) 1, 0, + + (* MDRP[18] *) 1, 0, + (* MDRP[19] *) 1, 0, + (* MDRP[20] *) 1, 0, + (* MDRP[21] *) 1, 0, + (* MDRP[22] *) 1, 0, + (* MDRP[23] *) 1, 0, + (* MDRP[24] *) 1, 0, + (* MDRP[25] *) 1, 0, + (* MDRP[26] *) 1, 0, + (* MDRP[27] *) 1, 0, + (* MDRP[28] *) 1, 0, + (* MDRP[29] *) 1, 0, + (* MDRP[30] *) 1, 0, + (* MDRP[31] *) 1, 0, + + (* MIRP[00] *) 2, 0, + (* MIRP[01] *) 2, 0, + (* MIRP[02] *) 2, 0, + (* MIRP[03] *) 2, 0, + (* MIRP[04] *) 2, 0, + (* MIRP[05] *) 2, 0, + (* MIRP[06] *) 2, 0, + (* MIRP[07] *) 2, 0, + (* MIRP[08] *) 2, 0, + (* MIRP[09] *) 2, 0, + (* MIRP[10] *) 2, 0, + (* MIRP[11] *) 2, 0, + (* MIRP[12] *) 2, 0, + (* MIRP[13] *) 2, 0, + (* MIRP[14] *) 2, 0, + (* MIRP[15] *) 2, 0, + (* MIRP[16] *) 2, 0, + (* MIRP[17] *) 2, 0, + + (* MIRP[18] *) 2, 0, + (* MIRP[19] *) 2, 0, + (* MIRP[20] *) 2, 0, + (* MIRP[21] *) 2, 0, + (* MIRP[22] *) 2, 0, + (* MIRP[23] *) 2, 0, + (* MIRP[24] *) 2, 0, + (* MIRP[25] *) 2, 0, + (* MIRP[26] *) 2, 0, + (* MIRP[27] *) 2, 0, + (* MIRP[28] *) 2, 0, + (* MIRP[29] *) 2, 0, + (* MIRP[30] *) 2, 0, + (* MIRP[31] *) 2, 0 + ); + + +(******************************************************************* + * + * Function : Norm + * + * Description : returns the norm (length) of a vector + * + * Input : X, Y vector + * + * Output : returns length in F26dot6 + * + *****************************************************************) + + function Norm( X, Y : TT_F26dot6 ): TT_F26dot6; + var + T1, T2 : Int64; + begin + MulTo64( X, X, T1 ); + MulTo64( Y, Y, T2 ); + + Add64( T1, T2, T1 ); + + if ( (T1.lo or T1.Hi) = 0 ) then Norm := 0 + else Norm := Sqrt64( T1 ); + end; + +(******************************************************************* + * + * Function : Scale_Pixels + * + * Description : Converts from FUnits to Fractional pixels + * coordinates. + * + *****************************************************************) + + function Scale_Pixels( value : long ) : TT_F26Dot6; + {$IFDEF INLINE} inline; {$ENDIF} + begin + Scale_Pixels := MulDiv_Round( value, + exc.metrics.scale1, + exc.metrics.scale2 ); + end; + + function Get_Current_Ratio : Long; + var + x, y : Long; + begin + if exc.metrics.ratio <> 0 then + Get_Current_Ratio := exc.metrics.ratio + else + begin + if exc.GS.projVector.y = 0 then + exc.metrics.ratio := exc.metrics.x_ratio + + else if exc.GS.projVector.x = 0 then + exc.metrics.ratio := exc.metrics.y_ratio + + else + begin + x := MulDiv_Round( exc.GS.projVector.x, + exc.metrics.x_ratio, + $4000 ); + + y := MulDiv_Round( exc.GS.projVector.y, + exc.metrics.y_ratio, + $4000 ); + + exc.metrics.ratio := Norm( x, y ); + end; + + Get_Current_Ratio := exc.metrics.ratio; + end + end; + + function Get_Ppem : Long; + {$IFDEF INLINE} inline; {$ENDIF} + begin + Get_Ppem := MulDiv_Round( exc.metrics.ppem, Get_Current_Ratio, $10000 ); + end; + + + function Read_CVT( index : Int ) : TT_F26Dot6; + {$IFNDEF FPK} far; {$ENDIF} + begin + Read_CVT := exc.cvt^[index]; + end; + + function Read_CVT_Stretched( index : Int ) : TT_F26Dot6; far; + begin + Read_CVT_Stretched := MulDiv_Round( exc.cvt^[index], + Get_Current_Ratio, + $10000 ); + end; + + + procedure Write_CVT( index : Int; value : TT_F26Dot6 ); far; + begin + exc.cvt^[index] := value; + end; + + procedure Write_CVT_Stretched( index : Int; value : TT_F26Dot6 ); far; + begin + exc.cvt^[index] := MulDiv_Round( value, + $10000, + Get_Current_Ratio ); + end; + + + procedure Move_CVT( index : Int; value : TT_F26Dot6 ); far; + begin + inc( exc.cvt^[index], value ); + end; + + procedure Move_CVT_Stretched( index : Int; value : TT_F26dot6 ); far; + begin + inc( exc.cvt^[index], MulDiv_Round( value, + $10000, + Get_Current_Ratio )); + end; + +(******************************************************************* + * + * Function : Calc_Length + * + * Description : Computes the length in bytes of current opcode + * + *****************************************************************) + + function Calc_Length : boolean; + begin + Calc_Length := false; + + exc.opcode := exc.Code^[exc.IP]; + + case exc.opcode of + + $40 : if exc.IP+1 >= exc.codeSize + then exit + else + exc.length := exc.code^[exc.IP+1] + 2; + + $41 : if exc.IP+1 >= exc.codeSize + then exit + else + exc.length := exc.code^[exc.IP+1]*2 + 2; + + $B0..$B7 : exc.length := exc.opcode-$B0 + 2; + $B8..$BF : exc.length := (exc.opcode-$B8)*2 + 3; + else + exc.length := 1; + end; + + Calc_Length := exc.IP+exc.length <= exc.codeSize; + end; + +(******************************************************************* + * + * Function : Get_Short + * + * Description : Return a short integer taken from the instruction + * stream at address IP. + * + * Input : None + * + * Output : Short read at Code^[IP..IP+1] + * + * Notes : This one could become a Macro in the C version + * + *****************************************************************) + + function GetShort : Short; + var + L : Array[0..1] of Byte; + resultat : Short absolute L; (* XXX : un-portable *) + begin + (* This is little-endian code *) + + L[1] := exc.code^[exc.IP]; inc(exc.IP); + L[0] := exc.code^[exc.IP]; inc(exc.IP); + GetShort := resultat; + end; + + + function Goto_CodeRange( aRange, + aIP : Int ): boolean; + begin + + Goto_CodeRange := False; + + with exc do + begin + if (aRange<1) or (aRange>3) then + begin + exc.error := TT_Err_Bad_Argument; + exit; + end; + + with CodeRangeTable[ARange] do + begin + + if Base = nil then (* invalid coderange *) + begin + error := TT_Err_Invalid_Coderange; + exit; + end; + + (* NOTE : Because the last instruction of a program may be a CALL *) + (* which will return to the first byte *after* the code *) + (* range, we test for AIP <= Size, instead of AIP < Size *) + + if AIP > Size then + begin + error := TT_Err_Code_Overflow; + Goto_CodeRange := False; + exit; + end; + + Code := PByte(Base); + CodeSize := Size; + IP := AIP; + end; + + curRange := ARange; + end; + + Goto_CodeRange := True; + end; + + +(******************************************************************* + * + * Function : Direct_Move + * + * Description : Moves a point by a given distance along the + * freedom vector. + * + * Input : Vx, Vy point coordinates to move + * touch touch flag to modify + * distance + * + * Output : None + * + *****************************************************************) + + {$F+} + procedure Direct_Move( zone : PGlyph_Zone; + point : Int; + distance : TT_F26dot6 ); + var + v : TT_F26dot6; + begin + v := exc.GS.freeVector.x; + if v <> 0 then + begin + inc( zone^.cur^[point].x, MulDiv_Round( distance, + Long(v)*$10000, + exc.F_dot_P )); + + zone^.flags^[point] := zone^.flags^[point] or TT_Flag_Touched_X; + end; + + v := exc.GS.freeVector.y; + if v <> 0 then + begin + inc( zone^.cur^[point].y, MulDiv_Round( distance, + Long(v)*$10000, + exc.F_dot_P )); + + zone^.flags^[point] := zone^.flags^[point] or TT_Flag_Touched_Y; + end; + end; + + (* The following versions are used whenever both vectors are both *) + (* along one of the coordinate unit vectors, i.e. in 90% cases *) + + procedure Direct_Move_X( zone : PGlyph_Zone; + point : Int; + distance : TT_F26dot6 ); + begin + inc( zone^.cur^[point].x, distance ); + zone^.flags^[point] := zone^.flags^[point] or TT_Flag_Touched_X; + end; + + procedure Direct_Move_Y( zone : PGlyph_Zone; + point : Int; + distance : TT_F26dot6 ); + begin + inc( zone^.cur^[point].y, distance ); + zone^.flags^[point] := zone^.flags^[point] or TT_Flag_Touched_Y; + end; + +(******************************************************************* + * + * Function : Round_None + * + * Description : Do not round, but add engine compensation + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : rounded distance + * + * NOTE : The spec says very few about the relationship between + * rounding and engine compensation. However, it seems + * from the description of super round that we should + * should add the compensation before rounding + * + *****************************************************************) + + function Round_None( distance : TT_F26dot6; + compensation : TT_F26dot6 ) : TT_F26dot6; + var + val : TT_F26dot6; + begin + if distance >= 0 then + begin + val := distance + compensation; + if val < 0 then val := 0; + end + else + begin + val := distance - compensation; + if val > 0 then val := 0; + end; + + Round_None := val; + end; + +(******************************************************************* + * + * Function : Round_To_Grid + * + * Description : round value to grid after adding engine + * compensation + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : rounded distance + * + *****************************************************************) + + function Round_To_Grid( distance : TT_F26dot6; + compensation : TT_F26dot6 ) : TT_F26dot6; + var + val : TT_F26dot6; + begin + if distance >= 0 then + begin + val := (distance + 32 + compensation) and -64; + if val < 0 then val := 0; + end + else + begin + val := - ((compensation - distance + 32) and -64); + if val > 0 then val := 0; + end; + + Round_To_Grid := val; + end; + +(******************************************************************* + * + * Function : Round_To_Half_Grid + * + * Description : round value to half grid after adding engine + * compensation + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : rounded distance + * + *****************************************************************) + + function Round_To_Half_Grid( distance : TT_F26dot6; + compensation : TT_F26dot6 ) : TT_F26dot6; + var + val : TT_F26dot6; + begin + if distance >= 0 then + begin + val := (distance + compensation) and -64 + 32; + if val < 0 then val := 0; + end + else + begin + val := - ((-distance + compensation) and -64 + 32); + if val > 0 then val := 0; + end; + + Round_To_Half_Grid := val; + end; + + +(******************************************************************* + * + * Function : Round_Down_To_Grid + * + * Description : round value down to grid after adding engine + * compensation + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : rounded distance + * + *****************************************************************) + + function Round_Down_To_Grid( distance : TT_F26dot6; + compensation : TT_F26dot6 ) : TT_F26dot6; + var + val : TT_F26dot6; + begin + if distance >= 0 then + begin + val := (distance + compensation) and -64; + if val < 0 then val := 0; + end + else + begin + val := - ((-distance + compensation) and -64); + if val > 0 then val := 0; + end; + + Round_Down_To_Grid := val; + end; + +(******************************************************************* + * + * Function : Round_Up_To_Grid + * + * Description : round value up to grid after adding engine + * compensation + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : rounded distance + * + *****************************************************************) + + function Round_Up_To_Grid( distance : TT_F26dot6; + compensation : TT_F26dot6 ) : TT_F26dot6; + var + val : TT_F26dot6; + begin + if distance >= 0 then + begin + val := (distance + 63 + compensation) and -64; + if val < 0 then val := 0; + end + else + begin + val := - ((-distance + 63 + compensation) and -64); + if val > 0 then val := 0; + end; + + Round_Up_To_Grid := val; + end; + +(******************************************************************* + * + * Function : Round_To_Double_Grid + * + * Description : round value to double grid after adding engine + * compensation + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : rounded distance + * + *****************************************************************) + + function Round_To_Double_Grid( distance : TT_F26dot6; + compensation : TT_F26dot6 ) : TT_F26dot6; + var + val : TT_F26dot6; + begin + if distance >= 0 then + begin + val := (distance + 16 + compensation) and -32; + if val < 0 then val := 0; + end + else + begin + val := - ((-distance + 16 + compensation) and -32); + if val > 0 then val := 0; + end; + + Round_To_Double_Grid := val; + end; + +(******************************************************************* + * + * Function : Round_Super + * + * Description : super round value to grid after adding engine + * compensation + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : rounded distance + * + * NOTE : The spec says very few about the relationship between + * rounding and engine compensation. However, it seems + * from the description of super round that we should + * should add the compensation before rounding + * + *****************************************************************) + + function Round_Super( distance : TT_F26dot6; + compensation : TT_F26dot6 ) : TT_F26dot6; + var + val : TT_F26dot6; + begin + with exc do + + if distance >= 0 then + begin + val := (distance - phase + threshold + compensation) and -period; + if val < 0 then val := 0; + val := val + phase; + end + else + begin + val := -((-distance - phase + threshold + compensation) and -period); + if val > 0 then val := 0; + val := val - phase; + end; + + Round_Super := val; + end; + +(******************************************************************* + * + * Function : Round_Super_45 + * + * Description : super round value to grid after adding engine + * compensation + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : rounded distance + * + * NOTE : There is a separate function for Round_Super_45 as we + * may need a greater precision. + * + *****************************************************************) + + function Round_Super_45( distance : TT_F26dot6; + compensation : TT_F26dot6 ) : TT_F26dot6; + var + val : TT_F26dot6; + begin + with exc do + + if distance >= 0 then + begin + val := ((distance - phase + threshold + compensation) div period) + * period; + if val < 0 then val := 0; + val := val + phase; + end + else + begin + val := -((-distance - phase + threshold + compensation) div period + * period ); + if val > 0 then val := 0; + val := val - phase; + end; + + Round_Super_45 := val; + end; + {$F-} + + procedure Compute_Round( round_mode : Byte ); + begin + case Round_Mode of + +{$IFDEF FPK} + TT_Round_Off : exc.func_round := @Round_None; + TT_Round_To_Grid : exc.func_round := @Round_To_Grid; + TT_Round_Up_To_Grid : exc.func_round := @Round_Up_To_Grid; + TT_Round_Down_To_Grid : exc.func_round := @Round_Down_To_Grid; + TT_Round_To_Half_Grid : exc.func_round := @Round_To_Half_Grid; + TT_Round_To_Double_Grid : exc.func_round := @Round_To_Double_Grid; + TT_Round_Super : exc.func_round := @Round_Super; + TT_Round_Super_45 : exc.func_round := @Round_Super_45; +{$ELSE} + TT_Round_Off : exc.func_round := Round_None; + TT_Round_To_Grid : exc.func_round := Round_To_Grid; + TT_Round_Up_To_Grid : exc.func_round := Round_Up_To_Grid; + TT_Round_Down_To_Grid : exc.func_round := Round_Down_To_Grid; + TT_Round_To_Half_Grid : exc.func_round := Round_To_Half_Grid; + TT_Round_To_Double_Grid : exc.func_round := Round_To_Double_Grid; + TT_Round_Super : exc.func_round := Round_Super; + TT_Round_Super_45 : exc.func_round := Round_Super_45; +{$ENDIF} + end; + end; + + +(******************************************************************* + * + * Function : SetSuperRound + * + * Description : Set Super Round parameters + * + * Input : GridPeriod Grid period + * OpCode SROUND opcode + * + * Output : None + * + * Notes : + * + *****************************************************************) + + procedure SetSuperRound( GridPeriod : TT_F26dot6; selector : Long ); + + begin + with exc do + begin + + Case selector and $C0 of + + $00 : period := GridPeriod div 2; + $40 : period := GridPeriod; + $80 : period := GridPeriod * 2; + + (* This opcode is reserved, but ... *) + + $C0 : period := GridPeriod; + end; + + Case selector and $30 of + + $00 : phase := 0; + $10 : phase := period div 4; + $20 : phase := period div 2; + $30 : phase := gridPeriod*3 div 4; + end; + + if selector and $F = 0 then + + Threshold := Period-1 + else + Threshold := (Integer( selector and $F )-4)*period div 8; + + period := period div 256; + phase := phase div 256; + threshold := threshold div 256; + + end + end; + +(******************************************************************* + * + * Function : Project + * + * Description : Computes the projection of (Vx,Vy) along the + * current projection vector + * + * Input : Vx, Vy input vector + * + * Output : return distance in F26dot6 + * + *****************************************************************) + + {$F+} + function Project( var P1, P2 : TT_Vector ) : TT_F26dot6; + var + T1, T2 : Int64; + begin + with exc.GS.projVector do + begin + MulTo64( P1.x - P2.x, x, T1 ); + MulTo64( P1.y - P2.y, y, T2 ); + end; + + Add64( T1, T2, T1 ); + + Project := Div64by32( T1, $4000 ); + end; + + + function Dual_Project( var P1, P2 : TT_Vector ) : TT_F26dot6; + var + T1, T2 : Int64; + begin + with exc.GS.dualVector do + begin + MulTo64( P1.x - P2.x, x, T1 ); + MulTo64( P1.y - P2.y, y, T2 ); + end; + + Add64( T1, T2, T1 ); + + Dual_Project := Div64by32( T1, $4000 ); + end; + + + function Free_Project( var P1, P2 : TT_Vector ) : TT_F26dot6; + var + T1, T2 : Int64; + begin + with exc.GS.freeVector do + begin + MulTo64( P1.x - P2.x, x, T1 ); + MulTo64( P1.y - P2.y, y, T2 ); + end; + + Add64( T1, T2, T1 ); + + Free_Project := Div64by32( T1, $4000 ); + end; + + + function Project_x( var P1, P2 : TT_Vector ) : TT_F26dot6; + begin + Project_x := P1.x - P2.x; + end; + + function Project_y( var P1, P2 : TT_Vector ) : TT_F26dot6; + begin + Project_y := P1.y - P2.y; + end; + {$F-} + +(******************************************************************* + * + * Function : Compute_Funcs + * + * Description : Computes the projections and movement function + * pointers according to the current graphics state + * + * Input : None + * + *****************************************************************) + + procedure Compute_Funcs; + begin + with exc, GS do + begin + + if (freeVector.x = $4000) then + begin +{$IFDEF FPK} + func_freeProj := @Project_x; +{$ELSE} + func_freeProj := Project_x; +{$ENDIF} + F_dot_P := Long(projVector.x) * $10000; + end + else + if (freeVector.y = $4000) then + begin +{$IFDEF FPK} + func_freeProj := @Project_y; +{$ELSE} + func_freeProj := Project_y; +{$ENDIF} + F_dot_P := Long(projVector.y) * $10000; + end + else + begin +{$IFDEF FPK} + func_move := @Direct_Move; + func_freeProj := @Free_Project; +{$ELSE} + func_move := Direct_Move; + func_freeProj := Free_Project; +{$ENDIF} + F_dot_P := Long(projVector.x) * freeVector.x * 4 + + Long(projVector.y) * freeVector.y * 4; + end; + +{$IFDEF FPK} + if (projVector.x = $4000) then func_Project := @Project_x + else + if (projVector.y = $4000) then func_Project := @Project_y + else + func_Project := @Project; + + if (dualVector.x = $4000) then func_dualproj := @Project_x + else + if (dualVector.y = $4000) then func_dualproj := @Project_y + else + func_dualproj := @Dual_Project; + + func_move := @Direct_Move; + + if F_dot_P = $40000000 then + + if freeVector.x = $4000 then func_move := @Direct_Move_x + else + if freeVector.y = $4000 then func_move := @Direct_Move_y; +{$ELSE} + if (projVector.x = $4000) then func_Project := Project_x + else + if (projVector.y = $4000) then func_Project := Project_y + else + func_Project := Project; + + if (dualVector.x = $4000) then func_dualproj := Project_x + else + if (dualVector.y = $4000) then func_dualproj := Project_y + else + func_dualproj := Dual_Project; + + func_move := Direct_Move; + + if F_dot_P = $40000000 then + + if freeVector.x = $4000 then func_move := Direct_Move_x + else + if freeVector.y = $4000 then func_move := Direct_Move_y; +{$ENDIF} + + (* at small sizes, F_dot_P can become too small, resulting *) + (* in overflows and 'spikes' in a number of glyfs like 'w' *) + + if abs( F_dot_P ) < $4000000 then F_dot_P := $40000000; + + (* set aspect ratio to 0 to force recomputation by Get_Current_Ratio *) + metrics.ratio := 0; + end; + end; + + +(**************************************************) +(* *) +(* Normalize : Normer un vecteur ( U, V ) *) +(* r‚sultat dans ( X, Y ) *) +(* False si vecteur paramŠtre nul *) +(* *) +(**************************************************) + +function Normalize( U, V : TT_F26dot6; var R : TT_UnitVector ): boolean; +var + Vec : TT_Vector; + W : TT_F26dot6; + S1, S2 : Boolean; + T : Int64; +begin + + if (Abs(U) < $10000) and (Abs(V) < $10000) then + begin + U := U*$100; + V := V*$100; + + W := Norm( U, V ); + if W = 0 then + begin + (* XXX : Undocumented. Apparently, it is possible to try *) + (* to normalize the vector (0,0). Return success *) + (* in this case *) + Normalize := SUCCESS; + exit; + end; + + R.x := MulDiv( U, $4000, W ); + R.y := MulDiv( V, $4000, W ); + + end + else + begin + + W := Norm( U, V ); + + if W > 0 then + begin + U := MulDiv( U, $4000, W ); + V := MulDiv( V, $4000, W ); + + W := U*U + V*V; + + (* Now, we want that Sqrt( W ) = $4000 *) + (* Or $1000000 <= W < $1004000 *) + + if U < 0 then begin U := -U; S1 := True; end else S1 := False; + if V < 0 then begin V := -V; S2 := True; end else S2 := False; + + while W < $1000000 do + begin + (* We need to increase W, by a minimal amount *) + if U < V then inc( U ) + else inc( V ); + W := U*U + V*V; + end; + + while W >= $1004000 do + begin + (* We need to decrease W, by a minimal amount *) + if U < V then dec( U ) + else dec( V ); + W := U*U + V*V; + end; + + (* Note that in various cases, we can only *) + (* compute a Sqrt(W) of $3FFF, eg. U=V *) + + if S1 then U := -U; + if S2 then V := -V; + + R.x := U; (* Type conversion *) + R.y := V; (* Type conversion *) + + end + else + begin + Normalize := False; + exc.error := TT_Err_Divide_By_Zero; + end; + end; + + Normalize := True; +end; + +{$F+} + +(****************************************************************) +(* *) +(* MANAGING THE STACK *) +(* *) +(* Instructions appear in the specs' order *) +(* *) +(****************************************************************) + +(*******************************************) +(* DUP[] : Duplicate top stack element *) +(* CodeRange : $20 *) + + procedure Ins_DUP( args : PStorage ); + begin + args^[1] := args^[0]; + end; + +(*******************************************) +(* POP[] : POPs the stack's top elt. *) +(* CodeRange : $21 *) + + procedure Ins_POP( args : PStorage ); + begin + (* nothing to do *) + end; + +(*******************************************) +(* CLEAR[] : Clear the entire stack *) +(* CodeRange : $22 *) + + procedure Ins_CLEAR( args : PStorage ); + begin + exc.new_top := 0; + end; + +(*******************************************) +(* SWAP[] : Swap the top two elements *) +(* CodeRange : $23 *) + + procedure Ins_SWAP( args : PStorage ); + var L : Long; + begin + L := args^[0]; + args^[0] := args^[1]; + args^[1] := L; + end; + +(*******************************************) +(* DEPTH[] : return the stack depth *) +(* CodeRange : $24 *) + + procedure Ins_DEPTH( args : PStorage ); + begin + args^[0] := exc.top; + end; + +(*******************************************) +(* CINDEX[] : copy indexed element *) +(* CodeRange : $25 *) + + procedure Ins_CINDEX( args : PStorage ); + var + L : Long; + begin + L := args^[0]; + if (L <= 0) or (L > exc.args) then + exc.error := TT_Err_Invalid_Reference + else + args^[0] := exc.stack^[exc.args-l]; + end; + +(*******************************************) +(* MINDEX[] : move indexed element *) +(* CodeRange : $26 *) + + procedure Ins_MINDEX( args : PStorage ); + var + L, K : Long; + begin + L := args^[0]; + if (L <= 0) or (L > exc.args) then + exc.Error := TT_Err_Invalid_Reference + else + begin + K := exc.stack^[exc.args-L]; + + move( exc.stack^[exc.args-L+1], + exc.stack^[exc.args-L], + (L-1)*sizeof(Long) ); + + exc.stack^[exc.args-1] := K; + end; + end; + +(*******************************************) +(* ROLL[] : roll top three elements *) +(* CodeRange : $8A *) + + procedure Ins_ROLL( args : PStorage ); + var + A, B, C : Long; + begin + A := args^[2]; + B := args^[1]; + C := args^[0]; + + args^[2] := C; + args^[1] := A; + args^[0] := B; + end; + +(****************************************************************) +(* *) +(* MANAGING THE FLOW OF CONTROL *) +(* *) +(* Instructions appear in the specs' order *) +(* *) +(****************************************************************) + + function SkipCode : boolean; + var + b : Boolean; + begin + b := False; + + inc( exc.IP, exc.length ); + + b := exc.IP < exc.codeSize; + + if b then b := Calc_Length; + + if not b then + exc.error := TT_Err_Code_Overflow; + + SkipCode := b; + end; + + +(*******************************************) +(* IF[] : IF test *) +(* CodeRange : $58 *) + + procedure Ins_IF( args : PStorage ); + var + nIfs : Int; + Out : Boolean; + begin + if args^[0] <> 0 then exit; + + nIfs := 1; + Out := False; + + Repeat + + if not SkipCode then exit; + + Case exc.opcode of + + (* IF *) + $58 : inc( nIfs ); + + (* ELSE *) + $1B : out:= nIfs=1; + + (* EIF *) + $59 : begin + dec( nIfs ); + out:= nIfs=0; + end; + end; + + until Out; + end; + + +(*******************************************) +(* ELSE[] : ELSE *) +(* CodeRange : $1B *) + + procedure Ins_ELSE( args : PStorage ); + var + nIfs : Int; + begin + nIfs := 1; + + Repeat + + if not SkipCode then exit; + + case exc.opcode of + + (* IF *) + $58 : inc( nIfs ); + + (* EIF *) + $59 : dec( nIfs ); + end; + + until nIfs=0; + end; + +(*******************************************) +(* EIF[] : End IF *) +(* CodeRange : $59 *) + + procedure Ins_EIF( args : PStorage ); + begin + (* nothing to do *) + end; + +(*******************************************) +(* JROT[] : Jump Relative On True *) +(* CodeRange : $78 *) + + procedure Ins_JROT( args : PStorage ); + begin + if args^[1] <> 0 then + begin + inc( exc.IP, args^[0] ); + exc.step_ins := false; + end; + end; + +(*******************************************) +(* JMPR[] : JuMP Relative *) +(* CodeRange : $1C *) + + procedure Ins_JMPR( args : PStorage ); + begin + inc( exc.IP, args^[0] ); + exc.step_ins := false; + end; + +(*******************************************) +(* JROF[] : Jump Relative On False *) +(* CodeRange : $79 *) + + procedure Ins_JROF( args : PStorage ); + begin + if args^[1] = 0 then + begin + inc( exc.IP, args^[0] ); + exc.step_ins := false; + end; + end; + +(****************************************************************) +(* *) +(* LOGICAL FUNCTIONS *) +(* *) +(* Instructions appear in the specs' order *) +(* *) +(****************************************************************) + +(*******************************************) +(* LT[] : Less Than *) +(* CodeRange : $50 *) + + procedure Ins_LT( args : PStorage ); + begin + if args^[0] < args^[1] then args^[0] := 1 + else args^[0] := 0; + end; + +(*******************************************) +(* LTEQ[] : Less Than or EQual *) +(* CodeRange : $51 *) + + procedure Ins_LTEQ( args : PStorage ); + begin + if args^[0] <= args^[1] then args^[0] := 1 + else args^[0] := 0; + end; + +(*******************************************) +(* GT[] : Greater Than *) +(* CodeRange : $52 *) + + procedure Ins_GT( args : PStorage ); + begin + if args^[0] > args^[1] then args^[0] := 1 + else args^[0] := 0; + end; + +(*******************************************) +(* GTEQ[] : Greater Than or EQual *) +(* CodeRange : $53 *) + + procedure Ins_GTEQ( args : PStorage ); + begin + if args^[0] >= args^[1] then args^[0] := 1 + else args^[0] := 0; + end; + +(*******************************************) +(* EQ[] : EQual *) +(* CodeRange : $54 *) + + procedure Ins_EQ( args : PStorage ); + begin + if args^[0] = args^[1] then args^[0] := 1 + else args^[0] := 0; + end; + +(*******************************************) +(* NEQ[] : Not EQual *) +(* CodeRange : $55 *) + + procedure Ins_NEQ( args : PStorage ); + begin + if args^[0] <> args^[1] then args^[0] := 1 + else args^[0] := 0; + end; + +(*******************************************) +(* ODD[] : Odd *) +(* CodeRange : $56 *) + + procedure Ins_ODD( args : PStorage ); + begin + if exc.func_round( args^[0], 0 ) and 127 = 64 then args^[0] := 1 + else args^[0] := 0; + end; + +(*******************************************) +(* EVEN[] : Even *) +(* CodeRange : $57 *) + + procedure Ins_EVEN( args : PStorage ); + begin + if exc.func_round( args^[0], 0 ) and 127 = 0 then args^[0] := 1 + else args^[0] := 0; + end; + +(*******************************************) +(* AND[] : logical AND *) +(* CodeRange : $5A *) + + procedure Ins_AND( args : PStorage ); + begin + if ( args^[0] <> 0 ) and + ( args^[1] <> 0 ) then args^[0] := 1 + else args^[0] := 0; + end; + +(*******************************************) +(* OR[] : logical OR *) +(* CodeRange : $5B *) + + procedure Ins_OR( args : PStorage ); + begin + if ( args^[0] <> 0 ) or + ( args^[1] <> 0 ) then args^[0] := 1 + else args^[0] := 0; + end; + +(*******************************************) +(* NOT[] : logical NOT *) +(* CodeRange : $5C *) + + procedure Ins_NOT( args : PStorage ); + begin + if args^[0] <> 0 then args^[0] := 0 + else args^[0] := 1; + end; + +(****************************************************************) +(* *) +(* ARITHMETIC AND MATH INSTRUCTIONS *) +(* *) +(* Instructions appear in the specs' order *) +(* *) +(****************************************************************) + +(*******************************************) +(* ADD[] : ADD *) +(* CodeRange : $60 *) + + procedure Ins_ADD( args : PStorage ); + begin + inc( args^[0], args^[1] ); + end; + +(*******************************************) +(* SUB[] : SUBstract *) +(* CodeRange : $61 *) + + procedure Ins_SUB( args : PStorage ); + begin + dec( args^[0], args^[1] ); + end; + +(*******************************************) +(* DIV[] : DIVide *) +(* CodeRange : $62 *) + + procedure Ins_DIV( args : PStorage ); + begin + if args^[1] = 0 then + begin + exc.error := TT_Err_Divide_By_Zero; + exit; + end; + + args^[0] := MulDiv_Round( args^[0], 64, args^[1] ); + end; + +(*******************************************) +(* MUL[] : MULtiply *) +(* CodeRange : $63 *) + + procedure Ins_MUL( args : PStorage ); + begin + args^[0] := MulDiv_Round( args^[0], args^[1], 64 ); + end; + +(*******************************************) +(* ABS[] : ABSolute value *) +(* CodeRange : $64 *) + + procedure Ins_ABS( args : PStorage ); + begin + args^[0] := abs( args^[0] ); + end; + +(*******************************************) +(* NEG[] : NEGate *) +(* CodeRange : $65 *) + + procedure Ins_NEG( args : PStorage ); + begin + args^[0] := -args^[0]; + end; + +(*******************************************) +(* FLOOR[] : FLOOR *) +(* CodeRange : $66 *) + + procedure Ins_FLOOR( args : PStorage ); + begin + args^[0] := args^[0] and -64; + end; + +(*******************************************) +(* CEILING[] : CEILING *) +(* CodeRange : $67 *) + + procedure Ins_CEILING( args : PStorage ); + begin + args^[0] := ( args^[0]+63 ) and -64; + end; + +(*******************************************) +(* MAX[] : MAXimum *) +(* CodeRange : $68 *) + + procedure Ins_MAX( args : PStorage ); + begin + if args^[1] > args^[0] then args^[0] := args^[1]; + end; + +(*******************************************) +(* MIN[] : MINimum *) +(* CodeRange : $69 *) + + procedure Ins_MIN( args : PStorage ); + begin + if args^[1] < args^[0] then args^[0] := args^[1]; + end; + +(****************************************************************) +(* *) +(* COMPENSATING FOR THE ENGINE CHARACTERISTICS *) +(* *) +(* Instructions appear in the specs' order *) +(* *) +(****************************************************************) + +(*******************************************) +(* ROUND[ab] : ROUND value *) +(* CodeRange : $68-$6B *) + + procedure Ins_ROUND( args : PStorage ); + begin + args^[0] := exc.func_round( args^[0], + exc.metrics.compensations[ exc.opcode-$68 ] ); + end; + +(*******************************************) +(* NROUND[ab]: No ROUNDing of value *) +(* CodeRange : $6C-$6F *) + + procedure Ins_NROUND( args : PStorage ); + begin + args^[0] := Round_None( args^[0], + exc.metrics.compensations[ exc.opcode-$6C ] ); + end; + +(****************************************************************) +(* *) +(* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS *) +(* *) +(* Instructions appear in the specs' order *) +(* *) +(****************************************************************) + +(*******************************************) +(* FDEF[] : Function DEFinition *) +(* CodeRange : $2C *) + + procedure Ins_FDEF( args : PStorage ); + var + func : int; + label + Suite; + begin + + (* check space *) + if exc.numFDefs >= exc.maxFDefs then begin + exc.error := TT_Err_Too_Many_FuncDefs; + exit; + end; + + func := Int(args^[0]); + with exc.FDefs^[exc.numFDefs] do + begin + Range := exc.curRange; + Opc := func; + Start := exc.IP+1; + Active := True; + end; + + if func > exc.maxFunc then + exc.maxFunc := func; + + inc(exc.numFDefs); + + (* now skip the whole function definition *) + (* we don't allow nested IDEFS & FDEFs *) + + while SkipCode do + + case exc.opcode of + + $89, (* IDEF *) + $2C : (* FDEF *) + begin + exc.error := TT_Err_Nested_Defs; + exit; + end; + + $2D : (* ENDF *) + exit; + end; + end; + +(*******************************************) +(* ENDF[] : END Function definition *) +(* CodeRange : $2D *) + + procedure Ins_ENDF( args : PStorage ); + begin + + if exc.callTop <= 0 then (* We encountered an ENDF without a call *) + begin + exc.error := TT_Err_ENDF_in_Exec_Stream; + exit; + end; + + dec( exc.CallTop ); + + with exc.Callstack^[exc.CallTop] do + begin + dec( Cur_Count ); + + exc.step_ins := false; + + if Cur_Count > 0 then + + begin + (* Loop the current function *) + inc( exc.callTop ); + exc.IP := Cur_Restart; + end + + else + (* exit the current call frame *) + (* NOTE : When the last intruction of a program *) + (* is a CALL or LOOPCALL, the return address *) + (* is always out of the code range. This is *) + (* valid address, and is why we do not test *) + (* the result of Goto_CodeRange here !! *) + + Goto_CodeRange( Caller_Range, Caller_IP ) + end; + + end; + +(*******************************************) +(* CALL[] : CALL function *) +(* CodeRange : $2B *) + + procedure Ins_CALL( args : PStorage ); + var + ii, nn : Int; + def : PDefRecord; + label + Fail; + begin + + (* First of all, check index *) + if (args^[0] < 0) or (args^[0] > exc.maxFunc) then + goto Fail; + + (* Except for some old Apple fonts, all functions in a TrueType *) + (* fonts are defined in increasing order, starting from 0. *) + (* *) + (* This mean that, normally, we have : *) + (* *) + (* exc.maxFunc+1 = exc.numFDefs *) + (* exc.FDefs[n].opc = n for n in 0..exc.maxFunc *) + (* *) + + nn := Int(args^[0]); + def := @exc.FDefs^[nn]; + + if ( exc.maxFunc+1 <> exc.numFDefs ) or ( def^.opc <> nn ) then begin + (* lookup the FDefs table *) + ii := 0; + def := @exc.FDefs^[0]; + while (ii < exc.numFDefs) and (def^.opc <> nn) do begin + inc(ii); + inc(def); + end; + + (* Fail if the function isn't listed *) + if ii >= exc.numFDefs then + goto Fail; + end; + + (* check that the function is active *) + if not def^.active then + goto Fail; + + (* check call stack *) + if exc.callTop >= exc.callSize then + begin + exc.error := TT_Err_Stack_Overflow; + exit; + end; + + with exc.callstack^[exc.callTop] do + begin + Caller_Range := exc.curRange; + Caller_IP := exc.IP+1; + Cur_Count := 1; + Cur_Restart := def^.Start; + end; + + inc( exc.CallTop ); + + with def^ do Goto_CodeRange( Range, Start ); + + exc.step_ins := false; + exit; + + Fail: + exc.error := TT_Err_Invalid_Reference; + exit; + end; + +(*******************************************) +(* LOOPCALL[]: LOOP and CALL function *) +(* CodeRange : $2A *) + + procedure Ins_LOOPCALL( args : PStorage ); + begin + + if ( args^[1] < 0 ) or ( args^[1] >= exc.numFDefs ) or + ( not exc.FDefs^[args^[1]].Active ) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + if exc.callTop >= exc.callSize then + begin + exc.error := TT_Err_Stack_Overflow; + exit; + end; + + if args^[0] > 0 then + begin + with exc.callstack^[exc.callTop] do + begin + Caller_Range := exc.curRange; + Caller_IP := exc.IP+1; + Cur_Count := args^[0]; + Cur_Restart := exc.FDefs^[args^[1]].Start; + end; + + inc( exc.CallTop ); + + with exc.FDefs^[args^[1]] do Goto_CodeRange( Range, Start ); + + exc.step_ins := false; + end; + + end; + +(*******************************************) +(* IDEF[] : Instruction DEFinition *) +(* CodeRange : $89 *) + + procedure Ins_IDEF( args : PStorage ); + var + i, A : Int; + begin + + A := 0; + + while ( A < exc.numIDefs ) do + with exc.IDefs^[A] do + begin + + if not Active then + begin + Opc := args^[0]; + Start := exc.IP+1; + Range := exc.curRange; + Active := True; + + A := exc.numIDefs; + + (* now skip the whole function definition *) + (* we don't allow nested IDEFS & FDEFs *) + + while SkipCode do + case exc.opcode of + + $89, (* IDEF *) + $2C : (* FDEF *) + begin + exc.error := TT_Err_Nested_Defs; + exit; + end; + + $2D : (* ENDF *) + exit; + end; + end + else + inc( A ); + end; + end; + +(****************************************************************) +(* *) +(* PUSHING DATA ONTO THE INTERPRETER STACK *) +(* *) +(* Instructions appear in the specs' order *) +(* *) +(****************************************************************) + +(*******************************************) +(* NPUSHB[] : PUSH N Bytes *) +(* CodeRange : $40 *) + + procedure Ins_NPUSHB( args : PStorage ); + var + L, K : Long; + begin + L := exc.code^[exc.IP+1]; + + if exc.top + L > exc.stackSize then + begin + exc.error := TT_Err_Stack_Overflow; + exit; + end; + + for K := 1 to L do + args^[k-1] := exc.code^[exc.IP+1+k]; + + inc( exc.new_top, L ); + end; + +(*******************************************) +(* NPUSHW[] : PUSH N Words *) +(* CodeRange : $41 *) + + procedure Ins_NPUSHW( args : PStorage ); + var + L, K : Long; + begin + L := exc.code^[exc.IP+1]; + + if exc.top + L > exc.stackSize then + begin + exc.error := TT_Err_Stack_Overflow; + exit; + end; + + inc( exc.IP, 2 ); + + for K := 1 to L do + args^[k-1] := GetShort; + + exc.step_ins := false; + + inc( exc.new_top, L ); + end; + +(*******************************************) +(* PUSHB[abc]: PUSH Bytes *) +(* CodeRange : $B0-$B7 *) + + procedure Ins_PUSHB( args : PStorage ); + var + L, K : Long; + begin + L := exc.opcode - $B0+1; + + if exc.top + L >= exc.stackSize then + begin + exc.error := TT_Err_Stack_Overflow; + exit; + end; + + for k := 1 to L do + args^[k-1] := exc.code^[exc.ip+k]; + + end; + +(*******************************************) +(* PUSHW[abc]: PUSH Words *) +(* CodeRange : $B8-$BF *) + + procedure Ins_PUSHW( args : PStorage ); + var + L, K : Long; + begin + L := exc.opcode - $B8+1; + + if exc.top + L >= exc.stackSize then + begin + exc.error := TT_Err_Stack_Overflow; + exit; + end; + + inc( exc.IP ); + + for k := 1 to L do + args^[k-1] := GetShort; + + exc.step_ins := false; + + end; + +(****************************************************************) +(* *) +(* MANAGING THE STORAGE AREA *) +(* *) +(* Instructions appear in the specs' order *) +(* *) +(****************************************************************) + +(*******************************************) +(* RS[] : Read Store *) +(* CodeRange : $43 *) + + procedure Ins_RS( args : PStorage ); + begin + if (args^[0] < 0) or (args^[0] >= exc.storeSize) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + args^[0] := exc.storage^[args^[0]]; + end; + +(*******************************************) +(* WS[] : Write Store *) +(* CodeRange : $42 *) + + procedure Ins_WS( args : PStorage ); + begin + if (args^[0] < 0) or (args^[0] >= exc.storeSize) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + exc.storage^[args^[0]] := args^[1]; + end; + +(*******************************************) +(* WCVTP[] : Write CVT in Pixel units *) +(* CodeRange : $44 *) + + procedure Ins_WCVTP( args : PStorage ); + begin + if (args^[0] < 0) or (args^[0] >= exc.cvtSize) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + exc.func_write_cvt( args^[0], args^[1] ); + end; + +(*******************************************) +(* WCVTF[] : Write CVT in FUnits *) +(* CodeRange : $70 *) + + procedure Ins_WCVTF( args : PStorage ); + begin + if (args^[0] < 0) or (args^[0] >= exc.cvtSize) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + exc.cvt^[args^[0]] := Scale_Pixels(args^[1]); + end; + +(*******************************************) +(* RCVT[] : Read CVT *) +(* CodeRange : $45 *) + + procedure Ins_RCVT( args : PStorage ); + begin + if (args^[0] < 0) or (args^[0] >= exc.cvtSize) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + args^[0] := exc.func_read_cvt(args^[0]); + end; + +(****************************************************************) +(* *) +(* MANAGING THE GRAPHICS STATE *) +(* *) +(* Instructions appear in the specs' order *) +(* *) +(****************************************************************) + +(*******************************************) +(* SVTCA[a] : Set F and P vectors to axis *) +(* CodeRange : $00-$01 *) + + procedure Ins_SVTCA( args : PStorage ); + var A, B : Short; + begin + case (exc.opcode and 1) of + 0 : A := $0000; + 1 : A := $4000; + end; + B := A xor $4000; + + exc.GS.freeVector.x := A; + exc.GS.projVector.x := A; + exc.GS.dualVector.x := A; + + exc.GS.freeVector.y := B; + exc.GS.projVector.y := B; + exc.GS.dualVector.y := B; + + Compute_Funcs; + end; + +(*******************************************) +(* SPVTCA[a] : Set PVector to Axis *) +(* CodeRange : $02-$03 *) + + procedure Ins_SPVTCA( args : PStorage ); + var A, B : Short; + begin + case (exc.opcode and 1) of + 0 : A := $0000; + 1 : A := $4000; + end; + B := A xor $4000; + + exc.GS.projVector.x := A; + exc.GS.dualVector.x := A; + + exc.GS.projVector.y := B; + exc.GS.dualVector.y := B; + + Compute_Funcs; + end; + +(*******************************************) +(* SFVTCA[a] : Set FVector to Axis *) +(* CodeRange : $04-$05 *) + + procedure Ins_SFVTCA( args : PStorage ); + var A, B : Short; + begin + case (exc.opcode and 1) of + 0 : A := $0000; + 1 : A := $4000; + end; + B := A xor $4000; + + exc.GS.freeVector.x := A; + exc.GS.freeVector.y := B; + + Compute_Funcs; + end; + + + + function Ins_SxVTL( aIdx1 : Int; + aIdx2 : Int; + aOpc : Int; + var Vec : TT_UnitVector ) : boolean; + var + A, B, C : Long; + begin + Ins_SxVTL := False; + + with exc do + begin + + if (aIdx2 >= zp1.n_points) or (aIdx1 >= zp2.n_points) then + begin + Error := TT_Err_Invalid_Reference; + exit; + end; + + with zp1.Cur^[aIdx2] do + begin + A := x; + B := y; + end; + + with zp2.Cur^[aIdx1] do + begin + dec( A, x ); + dec( B, y ); + end; + + if aOpc and 1 <> 0 then + begin + C := B; (* CounterClockwise rotation *) + B := A; + A := -C; + end; + + if not Normalize( A, B, Vec ) then + begin + exc.error := TT_Err_Ok; + Vec.x := $4000; + Vec.y := $0000; + end; + + Ins_SxVTL := True; + end; + end; + + +(*******************************************) +(* SPVTL[a] : Set PVector to Line *) +(* CodeRange : $06-$07 *) + + procedure Ins_SPVTL( args : PStorage ); + begin + if not INS_SxVTL( args^[1], + args^[0], + exc.opcode, + exc.GS.projVector ) then exit; + + exc.GS.dualVector := exc.GS.projVector; + Compute_Funcs; + end; + +(*******************************************) +(* SFVTL[a] : Set FVector to Line *) +(* CodeRange : $08-$09 *) + + procedure Ins_SFVTL( args : PStorage ); + begin + if not INS_SxVTL( args^[1], + args^[0], + exc.opcode, + exc.GS.freeVector ) then exit; + + Compute_Funcs; + end; + +(*******************************************) +(* SFVTPV[] : Set FVector to PVector *) +(* CodeRange : $0E *) + + procedure Ins_SFVTPV( args : PStorage ); + begin + exc.GS.freeVector := exc.GS.projVector; + Compute_Funcs; + end; + +(*******************************************) +(* SDPVTL[a] : Set Dual PVector to Line *) +(* CodeRange : $86-$87 *) + + procedure Ins_SDPVTL( args : PStorage ); + var + A, B, C : Long; + p1, p2 : Int; + begin + + p1 := args^[1]; + p2 := args^[0]; + + if (args^[0] < 0) or (args^[0] >= exc.zp1.n_points) or + (args^[1] < 0) or (args^[1] >= exc.zp2.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + A := exc.zp1.org^[p2].x - exc.zp2.org^[p1].x; + B := exc.zp1.org^[p2].y - exc.zp2.org^[p1].y; + + if exc.opcode and 1 <> 0 then + begin + C := B; (* CounterClockwise rotation *) + B := A; + A := -C; + end; + + Normalize( A, B, exc.GS.dualVector ); + + A := exc.zp1.cur^[p2].x - exc.zp2.cur^[p1].x; + B := exc.zp1.cur^[p2].y - exc.zp2.cur^[p1].y; + + if exc.opcode and 1 <> 0 then + begin + C := B; (* CounterClockwise rotation *) + B := A; + A := -C; + end; + + Normalize( A, B, exc.GS.projVector ); + + Compute_Funcs; + exc.error := TT_Err_Ok; + end; + +(*******************************************) +(* SPVFS[] : Set PVector From Stack *) +(* CodeRange : $0A *) + + procedure Ins_SPVFS( args : PStorage ); + var + S : Short; + X, Y : Long; + begin + S := args^[1]; Y := S; (* type conversion; extends sign *) + S := args^[0]; X := S; (* type conversion; extends sign *) + + if not Normalize( X, Y, exc.GS.projVector ) then exit; + + exc.GS.dualVector := exc.GS.projVector; + + Compute_Funcs; + end; + +(*******************************************) +(* SFVFS[] : Set FVector From Stack *) +(* CodeRange : $0B *) + + procedure Ins_SFVFS( args : PStorage ); + var + S : Short; + X, Y : Long; + begin + S := args^[1]; Y := S; (* type conversion; extends sign *) + S := args^[0]; X := S; (* type conversion; extends sign *) + + if not Normalize( X, Y, exc.GS.freeVector ) then exit; + + Compute_Funcs; + end; + +(*******************************************) +(* GPV[] : Get Projection Vector *) +(* CodeRange : $0C *) + + procedure Ins_GPV( args : PStorage ); + begin + args^[0] := exc.GS.projVector.x; + args^[1] := exc.GS.projVector.y; + end; + +(*******************************************) +(* GFV[] : Get Freedom Vector *) +(* CodeRange : $0D *) + + procedure Ins_GFV( args : PStorage ); + begin + args^[0] := exc.GS.freeVector.x; + args^[1] := exc.GS.freeVector.y; + end; + +(*******************************************) +(* SRP0[] : Set Reference Point 0 *) +(* CodeRange : $10 *) + + procedure Ins_SRP0( args : PStorage ); + begin + exc.GS.rp0 := args^[0]; + end; + +(*******************************************) +(* SRP1[] : Set Reference Point 1 *) +(* CodeRange : $11 *) + + procedure Ins_SRP1( args : PStorage ); + begin + exc.GS.rp1 := args^[0]; + end; + +(*******************************************) +(* SRP2[] : Set Reference Point 2 *) +(* CodeRange : $12 *) + + procedure Ins_SRP2( args : PStorage ); + begin + exc.GS.rp2 := args^[0]; + end; + +(*******************************************) +(* SZP0[] : Set Zone Pointer 0 *) +(* CodeRange : $13 *) + + procedure Ins_SZP0( args : PStorage ); + begin + case args^[0] of + + 0 : exc.zp0 := exc.Twilight; + 1 : exc.zp0 := exc.Pts; + else + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + exc.GS.gep0 := args^[0]; + end; + +(*******************************************) +(* SZP1[] : Set Zone Pointer 1 *) +(* CodeRange : $14 *) + + procedure Ins_SZP1( args : PStorage ); + begin + case args^[0] of + + 0 : exc.zp1 := exc.Twilight; + 1 : exc.zp1 := exc.Pts; + else + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + exc.GS.gep1 := args^[0]; + end; + +(*******************************************) +(* SZP2[] : Set Zone Pointer 2 *) +(* CodeRange : $15 *) + + procedure Ins_SZP2( args : PStorage ); + begin + case args^[0] of + + 0 : exc.zp2 := exc.Twilight; + 1 : exc.zp2 := exc.Pts; + else + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + exc.GS.gep2 := args^[0]; + end; + +(*******************************************) +(* SZPS[] : Set Zone Pointers *) +(* CodeRange : $16 *) + + procedure Ins_SZPS( args : PStorage ); + begin + case args^[0] of + + 0 : exc.zp0 := exc.Twilight; + 1 : exc.zp0 := exc.Pts; + else + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + exc.zp1 := exc.zp0; + exc.zp2 := exc.zp0; + + exc.GS.gep0 := args^[0]; + exc.GS.gep1 := args^[0]; + exc.GS.gep2 := args^[0]; + end; + +(*******************************************) +(* RTHG[] : Round To Half Grid *) +(* CodeRange : $19 *) + + procedure Ins_RTHG( args : PStorage ); + begin + exc.GS.round_state := TT_Round_To_Half_Grid; + +{$IFDEF FPK} + exc.func_round := @Round_To_Half_Grid; +{$ELSE} + exc.func_round := Round_To_Half_Grid; +{$ENDIF} + end; + +(*******************************************) +(* RTG[] : Round To Grid *) +(* CodeRange : $18 *) + + procedure Ins_RTG( args : PStorage ); + begin + exc.GS.round_state := TT_Round_To_Grid; + +{$IFDEF FPK} + exc.func_round := @Round_To_Grid; +{$ELSE} + exc.func_round := Round_To_Grid; +{$ENDIF} + end; + +(*******************************************) +(* RTDG[] : Round To Double Grid *) +(* CodeRange : $3D *) + + procedure Ins_RTDG( args : PStorage ); + begin + exc.GS.round_state := TT_Round_To_Double_Grid; + +{$IFDEF FPK} + exc.func_round := @Round_To_Double_Grid; +{$ELSE} + exc.func_round := Round_To_Double_Grid; +{$ENDIF} + end; + +(*******************************************) +(* RUTG[] : Round Up To Grid *) +(* CodeRange : $7C *) + + procedure Ins_RUTG( args : PStorage ); + begin + exc.GS.round_state := TT_Round_Up_To_Grid; + +{$IFDEF FPK} + exc.func_round := @Round_Up_To_Grid; +{$ELSE} + exc.func_round := Round_Up_To_Grid; +{$ENDIF} + end; + +(*******************************************) +(* RDTG[] : Round Down To Grid *) +(* CodeRange : $7D *) + + procedure Ins_RDTG( args : PStorage ); + begin + exc.GS.round_state := TT_Round_Down_To_Grid; + +{$IFDEF FPK} + exc.func_round := @Round_Down_To_Grid; +{$ELSE} + exc.func_round := Round_Down_To_Grid; +{$ENDIF} + end; + +(*******************************************) +(* ROFF[] : Round OFF *) +(* CodeRange : $7A *) + + procedure Ins_ROFF( args : PStorage ); + begin + exc.GS.round_state := TT_Round_Off; + +{$IFDEF FPK} + exc.func_round := @Round_None; +{$ELSE} + exc.func_round := Round_None; +{$ENDIF} + end; + +(*******************************************) +(* SROUND[] : Super ROUND *) +(* CodeRange : $76 *) + + procedure Ins_SROUND( args : PStorage ); + begin + SetSuperRound( $4000, args^[0] ); + exc.GS.round_state := TT_Round_Super; + +{$IFDEF FPK} + exc.func_round := @Round_Super; +{$ELSE} + exc.func_round := Round_Super; +{$ENDIF} + end; + +(*******************************************) +(* S45ROUND[]: Super ROUND 45 degrees *) +(* CodeRange : $77 *) + + procedure Ins_S45ROUND( args : PStorage ); + begin + SetSuperRound( $2D41, args^[0] ); + exc.GS.round_state := TT_Round_Super_45; + +{$IFDEF FPK} + exc.func_round := @Round_Super_45; +{$ELSE} + exc.func_round := Round_Super_45; +{$ENDIF} + end; + + +(*******************************************) +(* SLOOP[] : Set LOOP variable *) +(* CodeRange : $17 *) + + procedure Ins_SLOOP( args : PStorage ); + begin + exc.GS.Loop := args^[0]; + end; + +(*******************************************) +(* SMD[] : Set Minimum Distance *) +(* CodeRange : $1A *) + + procedure Ins_SMD( args : PStorage ); + begin + exc.GS.minimum_distance := args^[0]; + end; + +(*******************************************) +(* INSTCTRL[]: INSTruction ConTRol *) +(* CodeRange : $8e *) + + procedure Ins_INSTCTRL( args : PStorage ); + var + K, L : Int; + begin + K := args^[1]; + L := args^[0]; + + if ( K < 1 ) or ( K > 2 ) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + if L <> 0 then L := K; + + exc.GS.instruct_control := ( exc.GS.instruct_control and not K ) or L; + end; + +(*******************************************) +(* SCANCTRL[]: SCAN ConTRol *) +(* CodeRange : $85 *) + + procedure Ins_SCANCTRL( args : PStorage ); + var + A : Int; + begin + + (* Get Threshold *) + A := args^[0] and $FF; + + if A = $FF then + exc.GS.scan_Control := True + else + if A = 0 then + exc.GS.scan_Control := False + else + begin + + A := A * 64; + + (* XXX TODO : Add rotation and stretch cases *) + + if ( args^[0] and $100 <> 0 ) and + ( exc.metrics.pointSize <= A ) then exc.GS.scan_Control := True; + + if ( args^[0] and $200 <> 0 ) and + ( false ) then exc.GS.scan_Control := True; + + if ( args^[0] and $400 <> 0 ) and + ( false ) then exc.GS.scan_Control := True; + + if ( args^[0] and $800 <> 0 ) and + ( exc.metrics.pointSize > A ) then exc.GS.scan_Control := False; + + if ( args^[0] and $1000 <> 0 ) and + ( not False ) then exc.GS.scan_Control := False; + + if ( args^[0] and $2000 <> 0 ) and + ( not False ) then exc.GS.scan_Control := False; + end; + end; + +(*******************************************) +(* SCANTYPE[]: SCAN TYPE *) +(* CodeRange : $8D *) + + procedure Ins_SCANTYPE( args : PStorage ); + begin + (* For compatibility with future enhancements, *) + (* we must ignore new modes *) + + if (args^[0] >= 0 ) and (args^[0] <= 5) then + begin + if args^[0] = 3 then args^[0] := 2; + + exc.GS.scan_type := args^[0]; + end; + end; + +(**********************************************) +(* SCVTCI[] : Set Control Value Table Cut In *) +(* CodeRange : $1D *) + + procedure Ins_SCVTCI( args : PStorage ); + begin + exc.GS.control_value_cutin := args^[0]; + end; + +(**********************************************) +(* SSWCI[] : Set Single Width Cut In *) +(* CodeRange : $1E *) + + procedure Ins_SSWCI( args : PStorage ); + begin + exc.GS.single_width_cutin := args^[0]; + end; + +(**********************************************) +(* SSW[] : Set Single Width *) +(* CodeRange : $1F *) + + procedure Ins_SSW( args : PStorage ); + begin + exc.GS.single_width_value := args^[0] div $400; + end; + +(**********************************************) +(* FLIPON[] : Set Auto_flip to On *) +(* CodeRange : $4D *) + + procedure Ins_FLIPON( args : PStorage ); + begin + exc.GS.auto_flip := True; + end; + +(**********************************************) +(* FLIPOFF[] : Set Auto_flip to Off *) +(* CodeRange : $4E *) + + procedure Ins_FLIPOFF( args : PStorage ); + begin + exc.GS.auto_flip := False; + end; + +(**********************************************) +(* SANGW[] : Set Angle Weigth *) +(* CodeRange : $7E *) + + procedure Ins_SANGW( args : PStorage ); + begin + (* instruction not supported anymore *) + end; + +(**********************************************) +(* SDB[] : Set Delta Base *) +(* CodeRange : $5E *) + + procedure Ins_SDB( args : PStorage ); + begin + exc.GS.delta_base := args^[0] + end; + +(**********************************************) +(* SDS[] : Set Delta Shift *) +(* CodeRange : $5F *) + + procedure Ins_SDS( args : PStorage ); + begin + exc.GS.delta_shift := args^[0] + end; + +(**********************************************) +(* GC[a] : Get Coordinate projected onto *) +(* CodeRange : $46-$47 *) + +(* BULLSHIT : Measures from the original glyph must to be taken *) +(* along the dual projection vector !! *) + + procedure Ins_GC( args : PStorage ); + var + L : Int; + begin + L := args^[0]; + + if (L < 0) or (L >= exc.zp2.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + case exc.opcode and 1 of + + 0 : L := exc.func_project ( exc.zp2.cur^[L], Null_Vector ); + 1 : L := exc.func_dualProj( exc.zp2.org^[L], Null_Vector ); + end; + + args^[0] := L; + end; + +(**********************************************) +(* SCFS[] : Set Coordinate From Stack *) +(* CodeRange : $48 *) +(* *) +(* Formule : *) +(* *) +(* OA := OA + ( value - OA.p )/( f.p ) x f *) +(* *) + + procedure Ins_SCFS( args : PStorage ); + var + K, L : Int; + begin + L := args^[0]; + + if (args^[0] < 0) or (args^[0] >= exc.zp2.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + K := exc.func_project( exc.zp2.cur^[L], Null_Vector ); + + exc.func_move( @exc.zp2, L, args^[1] - K ); + + (* not part of the specs, but here for safety *) + + if exc.GS.gep2 = 0 then + exc.zp2.org^[L] := exc.zp2.cur^[L]; + + end; + +(**********************************************) +(* MD[a] : Measure Distance *) +(* CodeRange : $49-$4A *) + +(* BULLSHIT : Measure taken in the original glyph must be along *) +(* the dual projection vector *) + +(* Second BULLSHIT : Flag attributions are inverted !! *) +(* 0 => measure distance in original outline *) +(* 1 => measure distance in grid-fitted outline *) + + procedure Ins_MD( args : PStorage ); + var + K, L : Int; + D : TT_F26dot6; + vec1 : TT_Vector; + vec2 : TT_Vector; + begin + K := args^[1]; + L := args^[0]; + + if (args^[0] < 0) or (args^[0] >= exc.zp0.n_points) or + (args^[1] < 0) or (args^[1] >= exc.zp1.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + case exc.opcode and 1 of + + 0 : D := exc.func_dualProj( exc.zp0.org^[L], exc.zp1.org^[K] ); + 1 : D := exc.func_project ( exc.zp0.cur^[L], exc.zp1.cur^[K] ); + end; + + args^[0] := D; + end; + +(**********************************************) +(* MPPEM[] : Measure Pixel Per EM *) +(* CodeRange : $4B *) + + procedure Ins_MPPEM( args : PStorage ); + begin + args^[0] := Get_Ppem; + end; + +(**********************************************) +(* MPS[] : Measure PointSize *) +(* CodeRange : $4C *) + + procedure Ins_MPS( args : PStorage ); + begin + args^[0] := exc.metrics.pointSize; + end; + +(****************************************************************) +(* *) +(* MANAGING OUTLINES *) +(* *) +(* Instructions appear in the specs' order *) +(* *) +(****************************************************************) + + +(**********************************************) +(* FLIPPT[] : FLIP PoinT *) +(* CodeRange : $80 *) + + procedure Ins_FLIPPT( args : PStorage ); + var + point : Int; + begin + if exc.top < exc.GS.loop then + begin + exc.error := TT_Err_Too_Few_Arguments; + exit; + end; + + while exc.GS.loop > 0 do + begin + dec( exc.args ); + + point := exc.stack^[ exc.args ]; + + if (point < 0) or (point >= exc.pts.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + exc.pts.flags^[point] := exc.pts.flags^[point] xor TT_Flag_On_Curve; + + dec( exc.GS.loop ); + end; + + exc.GS.loop := 1; + exc.new_top := exc.args; + end; + +(**********************************************) +(* FLIPRGON[]: FLIP RanGe ON *) +(* CodeRange : $81 *) + + procedure Ins_FLIPRGON( args : PStorage ); + var + I, K, L : Int; + begin + K := args^[1]; + L := args^[0]; + + if (K < 0) or (K >= exc.pts.n_points) or + (L < 0) or (L >= exc.pts.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + for I := L to K do + exc.pts.flags^[I] := exc.pts.flags^[I] or TT_Flag_On_Curve; + end; + +(**********************************************) +(* FLIPRGOFF : FLIP RanGe OFF *) +(* CodeRange : $82 *) + + procedure Ins_FLIPRGOFF( args : PStorage ); + var + I, K, L : Int; + begin + K := args^[1]; + L := args^[0]; + + if (K < 0) or (K >= exc.pts.n_points) or + (L < 0) or (L >= exc.pts.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + for I := L to K do + exc.pts.flags^[I] := exc.pts.flags^[I] and not TT_Flag_On_Curve; + end; + + + + function Compute_Point_Displacement( var x : TT_F26dot6; + var y : TT_F26dot6; + var zone : PGlyph_Zone; + var refp : Int ) : TError; + var + zp : PGlyph_Zone; + p : Int; + d : TT_F26dot6; + vec1 : TT_Vector; + vec2 : TT_Vector; + begin + + Compute_Point_Displacement := Success; + + case exc.opcode and 1 of + 0 : begin zp := @exc.zp1; p := exc.GS.rp2; end; + 1 : begin zp := @exc.zp0; p := exc.GS.rp1; end; + end; + + if (p < 0) or (p >= zp^.n_points) then + begin + exc.error := TT_Err_Invalid_Displacement; + Compute_Point_Displacement := Failure; + exit; + end; + + zone := zp; + refp := p; + + d := exc.func_project( zp^.cur^[p], zp^.org^[p] ); + + x := MulDiv_Round( d, Long(exc.GS.freeVector.x)*$10000, exc.F_dot_P ); + y := MulDiv_Round( d, Long(exc.GS.freeVector.y)*$10000, exc.F_dot_P ); + + end; + + + procedure Move_Zp2_Point( point : Int; + dx : TT_F26dot6; + dy : TT_F26dot6 ); + begin + if exc.GS.freeVector.x <> 0 then + begin + inc( exc.zp2.cur^[point].x, dx ); + exc.zp2.flags^[point] := exc.zp2.flags^[point] or TT_Flag_Touched_X; + end; + + if exc.GS.freeVector.y <> 0 then + begin + inc( exc.zp2.cur^[point].y, dy ); + exc.zp2.flags^[point] := exc.zp2.flags^[point] or TT_Flag_Touched_Y; + end; + end; + +(**********************************************) +(* SHP[a] : SHift Point by the last point *) +(* CodeRange : $32-33 *) + + procedure Ins_SHP( args : PStorage ); + var + zp : PGlyph_Zone; + refp : Int; + + dx : TT_F26dot6; + dy : TT_F26dot6; + point: Int; + begin + + if Compute_Point_Displacement( dx, dy, zp, refp ) then + exit; + + if exc.top < exc.GS.loop then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + while exc.GS.loop > 0 do + begin + + dec( exc.args ); + + point := exc.stack^[ exc.args ]; + + if (point < 0) or (point >= exc.zp2.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + Move_Zp2_Point( point, dx, dy ); + + dec( exc.GS.loop ); + + end; + + exc.GS.loop := 1; + exc.new_top := exc.args; + end; + +(**********************************************) +(* SHC[a] : SHift Contour *) +(* CodeRange : $34-35 *) + + procedure Ins_SHC( args : PStorage ); + var + zp : PGlyph_Zone; + refp : Int; + dx : TT_F26dot6; + dy : TT_F26dot6; + + contour, i : Int; + + first_point, last_point : Int; + begin + + contour := args^[0]; + + if (args^[0] < 0) or (args^[0] >= exc.pts.n_contours ) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + if Compute_Point_Displacement( dx, dy, zp, refp ) then + exit; + + if contour = 0 then first_point := 0 else + first_point := exc.pts.conEnds^[contour-1]+1; + + last_point := exc.pts.conEnds^[contour]; + + for i := first_point to last_point do + begin + if (zp^.cur <> exc.zp2.cur) or + (refp <> i ) then + + Move_Zp2_Point( i, dx, dy ); + end; + + end; + +(**********************************************) +(* SHZ[a] : SHift Zone *) +(* CodeRange : $36-37 *) + + procedure Ins_SHZ( args : PStorage ); + var + zp : PGlyph_Zone; + refp : Int; + dx : TT_F26dot6; + dy : TT_F26dot6; + + zone, i : Int; + + last_point : Int; + begin + + zone := args^[0]; + + if (args^[0] < 0) or (args^[0] > 1) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + if Compute_Point_Displacement( dx, dy, zp, refp ) then + exit; + + last_point := zp^.n_points-1; + + for i := 0 to last_point do + begin + if (zp^.cur <> exc.zp2.cur) or + (refp <> i ) then + + Move_Zp2_Point( i, dx, dy ); + end; + + end; + +(**********************************************) +(* SHPIX[] : SHift points by a PIXel amount *) +(* CodeRange : $38 *) + + procedure Ins_SHPIX( args : PStorage ); + var + dx : TT_F26dot6; + dy : TT_F26dot6; + point: Int; + begin + + if exc.top < exc.GS.loop then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + dx := MulDiv_Round( args^[0], + exc.GS.freeVector.x, + $4000 ); + + dy := MulDiv_Round( args^[0], + exc.GS.freeVector.y, + $4000 ); + + while exc.GS.loop > 0 do + begin + + dec( exc.args ); + + point := exc.stack^[ exc.args ]; + + if (point < 0) or (point >= exc.zp2.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + Move_Zp2_Point( point, dx, dy ); + + dec( exc.GS.loop ); + + end; + + exc.GS.loop := 1; + exc.new_top := exc.args; + end; + +(**********************************************) +(* MSIRP[a] : Move Stack Indirect Relative *) +(* CodeRange : $3A-$3B *) + + procedure Ins_MSIRP( args : PStorage ); + var + point : Int; + distance : TT_F26dot6; + vec1 : TT_Vector; + vec2 : TT_Vector; + begin + + point := args^[0]; + + if (args^[0] < 0) or (args^[0] >= exc.zp1.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + (* XXX : UNDOCUMENTED - Twilight Zone *) + + (* Again, one stupid undocumented feature found in the *) + (* twilight zone. What did these guys had in mind when *) + (* they wrote the spec ? There _must_ be another *) + (* specification than the published one !! #@%$& !! *) + + if exc.GS.gep0 = 0 then (* if in twilight zone *) + begin + exc.zp1.org^[point] := exc.zp0.org^[exc.GS.rp0]; + exc.zp1.cur^[point] := exc.zp1.org^[point]; + end; + + distance := exc.func_project( exc.zp1.cur^[point], + exc.zp0.cur^[exc.GS.rp0] ); + + exc.func_move( @exc.zp1, point, args^[1] - distance ); + + exc.GS.rp1 := exc.GS.rp0; + exc.GS.rp2 := point; + + if exc.opcode and 1 <> 0 then exc.GS.rp0 := point; + end; + +(**********************************************) +(* MDAP[a] : Move Direct Absolute Point *) +(* CodeRange : $2E-$2F *) + + procedure Ins_MDAP( args : PStorage ); + var + point : Int; + cur_dist : TT_F26dot6; + distance : TT_F26dot6; + begin + point := args^[0]; + + if (args^[0] < 0) or (args^[0] >= exc.zp0.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + (* XXXX Is there some undocumented feature while in the *) + (* twilight zone ?? *) + + if exc.opcode and 1 <> 0 then + begin + + cur_dist := exc.func_project( exc.zp0.cur^[point], Null_Vector ); + + distance := exc.func_round( cur_dist, + exc.metrics.compensations[0] ) - + cur_dist; + end + else + distance := 0; + + exc.func_move( @exc.zp0, point, distance ); + + exc.GS.rp0 := point; + exc.GS.rp1 := point; + end; + +(**********************************************) +(* MIAP[a] : Move Indirect Absolute Point *) +(* CodeRange : $3E-$3F *) + + procedure Ins_MIAP( args : PStorage ); + var + cvtEntry : Int; + point : Int; + distance : TT_F26dot6; + org_dist : TT_F26dot6; + begin + cvtEntry := args^[1]; + point := args^[0]; + + if (args^[0] < 0) or (args^[0] >= exc.zp0.n_points ) or + (args^[1] < 0) or (args^[1] >= exc.cvtSize) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + (* Undocumented : *) + (* *) + (* The behaviour of an MIAP instruction is quite *) + (* different when used in the twilight zone^. *) + (* *) + (* First, no control value cutin test is performed *) + (* as it would fail anyway. Second, the original *) + (* point, i.e. (org_x,org_y) of zp0.point, is set *) + (* to the absolute, unrounded, distance found in *) + (* the CVT. *) + (* *) + (* This is used in the CVT programs of the Microsoft *) + (* fonts Arial, Times, etc.., in order to re-adjust *) + (* some key font heights. It allows the use of the *) + (* IP instruction in the twilight zone, which *) + (* otherwise would be "illegal" per se the specs :) *) + (* *) + (* We implement it with a special sequence for the *) + (* twilight zone. This is a bad hack, but it seems *) + (* to work.. *) + (* - David *) + + distance := exc.func_read_cvt(cvtEntry); + + if exc.GS.gep0 = 0 then (* If in twilight zone *) + begin + exc.zp0.org^[point].y := MulDiv_Round( exc.GS.freeVector.x, + distance, + $4000 ); + + exc.zp0.org^[point].y := MulDiv_Round( exc.GS.freeVector.y, + distance, + $4000 ); + + exc.zp0.cur^[point] := exc.zp0.org^[point]; + end; + + org_dist := exc.func_project( exc.zp0.cur^[point], Null_Vector ); + + if exc.opcode and 1 <> 0 then (* rounding and control cutin flag *) + begin + + if abs( distance-org_dist ) > exc.GS.control_value_cutin then + distance := org_dist; + + distance := exc.func_round( distance, + exc.metrics.compensations[0] ); + end; + + exc.func_move( @exc.zp0, point, distance - org_dist ); + + exc.GS.rp0 := point; + exc.GS.rp1 := point; + + end; + +(**********************************************) +(* MDRP[abcde] : Move Direct Relative Point *) +(* CodeRange : $C0-$DF *) + + procedure Ins_MDRP( args : PStorage ); + var + point : Int; + distance : TT_F26dot6; + org_dist : TT_F26dot6; + begin + point := args^[0]; + + if (args^[0] < 0) or (args^[0] >= exc.zp1.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + (* XXXX Is there some undocumented feature while in the *) + (* twilight zone ?? *) + + org_dist := exc.func_dualProj( exc.zp1.org^[point], + exc.zp0.org^[exc.GS.rp0] ); + (* single width cutin test *) + + if abs(org_dist) < exc.GS.single_width_cutin then + + if org_dist >= 0 then org_dist := exc.GS.single_width_value + else org_dist := -exc.GS.single_width_value; + + (* round flag *) + + if exc.opcode and 4 <> 0 then + + distance := exc.func_round( org_dist, + exc.metrics.compensations[ exc.opcode and 3 ] ) + else + distance := Round_None( org_dist, + exc.metrics.compensations[ exc.opcode and 3 ] ); + + (* minimum distance flag *) + + if exc.opcode and 8 <> 0 then + begin + + if org_dist >= 0 then + + if distance < exc.GS.minimum_distance then + distance := exc.GS.minimum_distance + else + else + if distance > -exc.GS.minimum_distance then + distance := -exc.GS.minimum_distance; + end; + + (* now move the point *) + + org_dist := exc.func_project( exc.zp1.cur^[point], + exc.zp0.cur^[exc.GS.rp0] ); + + exc.func_move( @exc.zp1, point, distance - org_dist ); + + exc.GS.rp1 := exc.GS.rp0; + exc.GS.rp2 := point; + + if exc.opcode and 16 <> 0 then exc.GS.rp0 := point; + end; + +(**********************************************) +(* MIRP[abcde] : Move Indirect Relative Point *) +(* CodeRange : $E0-$FF *) + + procedure Ins_MIRP( args : PStorage ); + var + point : Int; + cvtEntry : Int; + cvt_dist : TT_F26dot6; + distance : TT_F26dot6; + cur_dist : TT_F26dot6; + org_dist : TT_F26dot6; + begin + + point := args^[0]; + cvtEntry := args^[1]; + + (* XXX : UNDOCUMENTED => cvt[-1] = 0 ???? *) + + if (args^[0] < 0 ) or (args^[0] >= exc.zp1.n_points) or + (args^[1] < -1) or (args^[1] >= exc.cvtSize) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + if cvtEntry < 0 then + cvt_dist := 0 + else + cvt_dist := exc.func_read_cvt(cvtEntry); + + (* single width test *) + + if abs(cvt_dist) < exc.GS.single_width_cutin then + + if cvt_dist >= 0 then cvt_dist := exc.GS.single_width_value + else cvt_dist := -exc.GS.single_width_value; + + (* XXX : Undocumented - twilight zone *) + + if exc.GS.gep1 = 0 then (* if in twilight zone *) + begin + exc.zp1.org^[point].x := exc.zp0.org^[exc.GS.rp0].x + + MulDiv_Round( cvt_dist, + exc.GS.freeVector.x, + $4000 ); + + exc.zp1.org^[point].x := exc.zp0.org^[exc.GS.rp0].y + + MulDiv_Round( cvt_dist, + exc.GS.freeVector.y, + $4000 ); + + exc.zp1.cur^[point] := exc.zp1.org^[point]; + end; + + + org_dist := exc.func_dualProj( exc.zp1.org^[point], + exc.zp0.org^[exc.GS.rp0] ); + + cur_dist := exc.func_Project( exc.zp1.cur^[point], + exc.zp0.cur^[exc.GS.rp0] ); + + (* auto-flip test *) + + if exc.GS.auto_flip then + if (org_dist xor cvt_dist < 0) then + cvt_dist := -cvt_dist; + + (* control value cutin and round *) + + if exc.opcode and 4 <> 0 then + begin + (* XXX : UNDOCUMENTED : only perform cut-in test when both *) + (* zone pointers refer to the points zone *) + + if exc.GS.gep0 = exc.GS.gep1 then + if abs( cvt_dist - org_dist ) >= exc.GS.control_value_cutin then + cvt_dist := org_dist; + + distance := exc.func_round( cvt_dist, + exc.metrics.compensations[ exc.opcode and 3 ] ); + end + else + distance := Round_None( cvt_dist, + exc.metrics.compensations[ exc.opcode and 3 ] ); + + (* minimum distance test *) + + if exc.opcode and 8 <> 0 then + begin + if org_dist >= 0 then + + if distance < exc.GS.minimum_distance then + distance := exc.GS.minimum_distance + else + else + if distance > -exc.GS.minimum_distance then + distance := -exc.GS.minimum_distance; + end; + + exc.func_move( @exc.zp1, point, distance - cur_dist ); + + exc.GS.rp1 := exc.GS.rp0; + + if exc.opcode and 16 <> 0 then exc.GS.rp0 := point; + + (* UNDOCUMENTED !! *) + + exc.GS.rp2 := point; + end; + +(**********************************************) +(* ALIGNRP[] : ALIGN Relative Point *) +(* CodeRange : $3C *) + + procedure Ins_ALIGNRP( args : PStorage ); + var + point : Int; + distance : TT_F26dot6; + begin + if exc.top < exc.GS.loop then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + while exc.GS.loop > 0 do + begin + + dec( exc.args ); + + point := exc.stack^[ exc.args ]; + + if (point < 0) or (point >= exc.zp1.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + distance := exc.func_project( exc.zp1.cur^[point], + exc.zp0.cur^[exc.GS.rp0] ); + + exc.func_move( @exc.zp1, point, -distance ); + + dec( exc.GS.loop ); + end; + + exc.GS.loop := 1; + exc.new_top := exc.args; + end; + +(**********************************************) +(* AA[] : Adjust Angle *) +(* CodeRange : $7F *) + + procedure Ins_AA( args : PStorage ); + begin + (* Intentional - no longer supported *) + end; + +(**********************************************) +(* ISECT[] : moves point to InterSECTion *) +(* CodeRange : $0F *) + + procedure Ins_ISECT( args : PStorage ); + var + point : Int; + a0, a1 : Int; + b0, b1 : Int; + + discriminant : TT_F26dot6; + dx, dy, + dax, day, + dbx, dby : TT_F26dot6; + + val : TT_F26dot6; + + R : TT_Vector; + + U, V : TT_UnitVector; + T1, T2 : Int64; + begin + + point := args^[0]; + a0 := args^[1]; + a1 := args^[2]; + b0 := args^[3]; + b1 := args^[4]; + + if (b0 >= exc.zp0.n_points) or (b1 >= exc.zp0.n_points) or + (a0 >= exc.zp1.n_points) or (a1 >= exc.zp1.n_points) or + (point >= exc.zp0.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; +(* + if Normalize( exc.zp1.cur_x^[a1] - exc.zp1.cur_x^[a0], + exc.zp1.cur_y^[a1] - exc.zp1.cur_y^[a0], + U ) + and + Normalize( - exc.zp0.cur_x^[b1] - exc.zp0.cur_x^[b0], + exc.zp0.cur_y^[b1] - exc.zp0.cur_y^[b0], + V ) + then + begin + + dx := MulDiv_Round( exc.zp0.cur_x^[b0] - + exc.zp1.cur_x^[a0], + V.x, + $4000 ) + + + MulDiv_Round( exc.zp0.cur_y^[b0] - + exc.zp1.cur_y^[a0], + V.y, + $4000 ); + + dy := MulDiv_Round( U.x, V.x, $4000 ) + + MulDiv_Round( U.y, V.y, $4000 ); + + if dy <> 0 then + begin + dx := MulDiv_Round( dx, $4000, dy ); + + exc.zp2.flags^[point] := exc.zp2.flags^[point] or + TT_Flag_Touched_Both; + + exc.zp2.cur_x^[point] := exc.zp1.cur_x^[a0] + + + MulDiv_Round( dx, U.x, $4000 ); + + exc.zp2.cur_y^[point] := exc.zp1.cur_y^[a0] + + + MulDiv_Round( dx, U.y, $4000 ); + + exit; + end; + end; + *) + dbx := exc.zp0.cur^[b1].x - exc.zp0.cur^[b0].x; + dby := exc.zp0.cur^[b1].y - exc.zp0.cur^[b0].y; + + dax := exc.zp1.cur^[a1].x - exc.zp1.cur^[a0].x; + day := exc.zp1.cur^[a1].y - exc.zp1.cur^[a0].y; + + dx := exc.zp0.cur^[b0].x - exc.zp1.cur^[a0].x; + dy := exc.zp0.cur^[b0].y - exc.zp1.cur^[a0].y; + + exc.zp2.flags^[point] := exc.zp2.flags^[point] or + TT_Flag_Touched_Both; + + discriminant := MulDiv( dax, -dby, $40 ) + + MulDiv( day, dbx, $40 ); + + if abs(discriminant) >= $40 then + begin + + val := MulDiv( dx, -dby, $40 ) + + MulDiv( dy, dbx, $40 ); + + R.x := MulDiv( val, dax, discriminant ); + R.y := MulDiv( val, day, discriminant ); + + exc.zp2.cur^[point].x := exc.zp1.cur^[a0].x + R.x; + exc.zp2.cur^[point].y := exc.zp1.cur^[a0].y + R.y; + end + else + begin + + (* else, take the middle of the middles of A and B *) + + exc.zp2.cur^[point].x := ( exc.zp1.cur^[a0].x + + exc.zp1.cur^[a1].x + + exc.zp0.cur^[b0].x + + exc.zp0.cur^[b1].x ) div 4; + + exc.zp2.cur^[point].y := ( exc.zp1.cur^[a0].y + + exc.zp1.cur^[a1].y + + exc.zp0.cur^[b0].y + + exc.zp0.cur^[b1].y ) div 4; + end; + end; + +(**********************************************) +(* ALIGNPTS[] : ALIGN PoinTS *) +(* CodeRange : $27 *) + + procedure Ins_ALIGNPTS( args : PStorage ); + var + p1, p2 : Int; + distance : TT_F26dot6; + begin + p1 := args^[0]; + p2 := args^[1]; + + if (args^[0] < 0) or (args^[0] >= exc.zp1.n_points) or + (args^[1] < 0) or (args^[1] >= exc.zp0.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + distance := exc.func_project( exc.zp0.cur^[p2], + exc.zp1.cur^[p1] ) div 2; + + exc.func_move( @exc.zp1, p1, distance ); + exc.func_move( @exc.zp0, p2, -distance ); + end; + +(**********************************************) +(* IP[] : Interpolate Point *) +(* CodeRange : $39 *) + + procedure Ins_IP( args : PStorage ); + var + org_a : TT_F26dot6; + org_b : TT_F26dot6; + org_x : TT_F26dot6; + cur_a : TT_F26dot6; + cur_b : TT_F26dot6; + cur_x : TT_F26dot6; + + distance : TT_F26dot6; + + point : Int; + begin + + if exc.top < exc.GS.loop then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + org_a := exc.func_dualProj( exc.zp0.org^[exc.GS.rp1], Null_Vector ); + + org_b := exc.func_dualProj( exc.zp1.org^[exc.GS.rp2], Null_Vector ); + + cur_a := exc.func_project( exc.zp0.cur^[exc.GS.rp1], Null_Vector ); + + cur_b := exc.func_project( exc.zp1.cur^[exc.GS.rp2], Null_Vector ); + + while exc.GS.loop > 0 do + begin + + dec( exc.args ); + + point := exc.stack^[ exc.args ]; + + org_x := exc.func_dualProj( exc.zp2.org^[point], Null_Vector ); + + cur_x := exc.func_project( exc.zp2.cur^[point], Null_Vector ); + + if (( org_a <= org_b ) and ( org_x <= org_a )) or + (( org_a > org_b ) and ( org_x >= org_a )) then + begin + distance := ( cur_a - org_a ) + ( org_x - cur_x ); + end + else + if (( org_a <= org_b ) and ( org_x >= org_b )) or + (( org_a > org_b ) and ( org_x < org_b )) then + begin + distance := ( cur_b - org_b ) + ( org_x - cur_x ); + end + else + begin + (* note : it seems that rounding this value isn't a good *) + (* idea ( width of capital 'S' in Times *) + + distance := MulDiv( cur_b - cur_a, + org_x - org_a, + org_b - org_a ) + ( cur_a - cur_x ); + end; + + exc.func_move( @exc.zp2, point, distance ); + + dec( exc.GS.loop ); + end; + + exc.GS.loop := 1; + exc.new_top := exc.args; + end; + +(**********************************************) +(* UTP[a] : UnTouch Point *) +(* CodeRange : $29 *) + + procedure Ins_UTP( args : PStorage ); + var + mask : Byte; + begin + if (args^[0] < 0) or (args^[0] >= exc.zp0.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + mask := $FF; + + if exc.GS.freeVector.x <> 0 then mask := mask and not TT_Flag_Touched_X; + if exc.GS.freeVector.y <> 0 then mask := mask and not TT_Flag_Touched_Y; + + exc.zp0.flags^[args^[0]] := exc.zp0.flags^[args^[0]] and mask; + end; + +(**********************************************) +(* IUP[a] : Interpolate Untouched Points *) +(* CodeRange : $30-$31 *) + + procedure Ins_IUP( args : PStorage ); + var + mask : byte; + + first_point, (* first point of contour *) + end_point, (* end point (last+1) of contour *) + + first_touched, (* first touched point in contour *) + cur_touched, (* current touched point in contour *) + + point, (* current point *) + contour : Int; (* current contour *) + + orgs, (* original and current coordinate *) + curs : TT_Points; (* arrays *) + + procedure Shift_X( p1, p2, p : Int ); + var + i : Int; + x : TT_F26dot6; + begin + x := curs^[p].x - orgs^[p].x; + + for i := p1 to p-1 do inc( curs^[i].x, x ); + for i := p+1 to p2 do inc( curs^[i].x, x ); + end; + + procedure Shift_Y( p1, p2, p : Int ); + var + i : Int; + y : TT_F26dot6; + begin + y := curs^[p].y - orgs^[p].y; + + for i := p1 to p-1 do inc( curs^[i].y, y ); + for i := p+1 to p2 do inc( curs^[i].y, y ); + end; + + + procedure Interp_X( p1, p2, ref1, ref2 : Int ); + var + i : Int; + x, x1, x2, d1, d2 : TT_F26dot6; + begin + + if p1 > p2 then exit; + + x1 := orgs^[ref1].x; d1 := curs^[ref1].x - orgs^[ref1].x; + x2 := orgs^[ref2].x; d2 := curs^[ref2].x - orgs^[ref2].x; + + if x1 = x2 then + for i := p1 to p2 do + begin + x := orgs^[i].x; + if x <= x1 then x := x + d1 + else x := x + d2; + + curs^[i].x := x; + end + + else + if x1 < x2 then + + for i := p1 to p2 do + begin + x := orgs^[i].x; + + if (x <= x1) then x := x + d1 + else + if (x >= x2) then x := x + d2 + else + x := curs^[ref1].x + + MulDiv( x-x1, curs^[ref2].x-curs^[ref1].x, x2-x1 ); + + curs^[i].x := x; + end + else + + (* x2 < x1 *) + + for i := p1 to p2 do + begin + x := orgs^[i].x; + + if ( x <= x2 ) then x := x + d2 + else + if ( x >= x1 ) then x := x + d1 + else + x := curs^[ref1].x + + MulDiv( x-x1, curs^[ref2].x-curs^[ref1].x, x2-x1 ); + + curs^[i].x := x; + end; + end; + + procedure Interp_Y( p1, p2, ref1, ref2 : Int ); + var + i : Int; + y, y1, y2, d1, d2 : TT_F26dot6; + begin + + if p1 > p2 then exit; + + y1 := orgs^[ref1].y; d1 := curs^[ref1].y - orgs^[ref1].y; + y2 := orgs^[ref2].y; d2 := curs^[ref2].y - orgs^[ref2].y; + + if y1 = y2 then + for i := p1 to p2 do + begin + y := orgs^[i].y; + if y <= y1 then y := y + d1 + else y := y + d2; + + curs^[i].y := y; + end + + else + if y1 < y2 then + + for i := p1 to p2 do + begin + y := orgs^[i].y; + + if (y <= y1) then y := y + d1 + else + if (y >= y2) then y := y + d2 + else + y := curs^[ref1].y + + MulDiv( y-y1, curs^[ref2].y-curs^[ref1].y, y2-y1 ); + + curs^[i].y := y; + end + else + + (* y2 < y1 *) + + for i := p1 to p2 do + begin + y := orgs^[i].y; + + if ( y <= y2 ) then y := y + d2 + else + if ( y >= y1 ) then y := y + d1 + else + y := curs^[ref1].y + + MulDiv( y-y1, curs^[ref2].y-curs^[ref1].y, y2-y1 ); + + curs^[i].y := y; + end; + end; + + begin + orgs := exc.pts.org; + curs := exc.pts.cur; + + case exc.opcode and 1 of + 0 : mask := TT_Flag_Touched_Y; + 1 : mask := TT_Flag_Touched_X; + end; + + with exc do + begin + + contour := 0; + point := 0; + + repeat + + end_point := pts.conEnds^[contour]; + first_point := point; + + while ( point <= end_point ) and + ( pts.flags^[point] and mask = 0 ) do inc(point); + + if point <= end_point then + begin + + first_touched := point; + cur_touched := point; + + inc( point ); + + while ( point <= end_point ) do + begin + if pts.flags^[point] and mask <> 0 then + begin + if opcode and 1 <> 0 then + Interp_X( cur_touched+1, point-1, cur_touched, point ) + else + Interp_Y( cur_touched+1, point-1, cur_touched, point ); + + cur_touched := point; + end; + + inc( point ); + end; + + if cur_touched = first_touched then + if opcode and 1 <> 0 then + Shift_X( first_point, end_point, cur_touched ) + else + Shift_Y( first_point, end_point, cur_touched ) + else + begin + if opcode and 1 <> 0 then + begin + interp_x( cur_touched+1, end_point, cur_touched, first_touched ); + interp_x( first_point, first_touched-1, cur_touched, first_touched ); + end + else + begin + interp_y( cur_touched+1, end_point, cur_touched, first_touched ); + interp_y( first_point, first_touched-1, cur_touched, first_touched ); + end; + end; + + end; + + inc( contour ); + + until contour >= pts.n_contours; + + end; + + end; + +(**********************************************) +(* DELTAPn[] : DELTA Exceptions P1, P2, P3 *) +(* CodeRange : $5D,$71,$72 *) + + procedure Ins_DELTAP( args : PStorage ); + var + nump : Int; + k : Int; + A, B, C :Int; + begin + + nump := args^[0]; + + for K := 1 to nump do + begin + if exc.args < 2 then + begin + exc.error := TT_Err_Too_Few_Arguments; + exit; + end; + + dec( exc.args, 2 ); + + A := exc.stack^[exc.args+1]; + B := exc.stack^[ exc.args ]; + + (* XXX : *) + (* some commonly fonts have broke programs where the *) + (* the point reference has an invalid value. Here, we *) + (* simply ignore them, because a DeltaP won't change *) + (* a glyph shape dramatically.. *) + (* *) + + if A < exc.zp0.n_points then + begin + C := ( B and $F0 ) shr 4; + + Case exc.opcode of + $5D : ; + $71 : C := C+16; + $72 : C := C+32; + end; + + C := C + exc.GS.delta_Base; + + if GET_Ppem = C then + begin + B := (B and $F) - 8; + if B >= 0 then B := B+1; + B := ( B*64 ) div ( 1 shl exc.GS.delta_Shift ); + + exc.func_move( @exc.zp0, A, B ); + end; + end; + + end; + + exc.new_top := exc.args; + end; + + +(**********************************************) +(* DELTACn[] : DELTA Exceptions C1, C2, C3 *) +(* CodeRange : $73,$74,$75 *) + + procedure Ins_DELTAC( args : PStorage ); + var + nump : Int; + k : Int; + A, B, C :Int; + begin + + nump := args^[0]; + + for K := 1 to nump do + begin + if exc.args < 2 then + begin + exc.error := TT_Err_Too_Few_Arguments; + exit; + end; + + dec( exc.args, 2 ); + + A := exc.stack^[exc.args+1]; + B := exc.stack^[ exc.args ]; + + if A >= exc.cvtSize then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + C := ( B and $F0 ) shr 4; + + Case exc.opcode of + $73 : ; + $74 : C := C+16; + $75 : C := C+32; + end; + + C := C + exc.GS.delta_Base; + + if GET_Ppem = C then + begin + B := (B and $F) - 8; + if B >= 0 then B := B+1; + B := ( B*64 ) div ( 1 shl exc.GS.delta_Shift ); + + exc.func_move_cvt( A, B ); + end; + end; + + exc.new_top := exc.args; + end; + +(****************************************************************) +(* *) +(* MISC. INSTRUCTIONS *) +(* *) +(****************************************************************) + +(***********************************************************) +(* DEBUG[] : DEBUG. Unsupported *) +(* CodeRange : $4F *) + +(* NOTE : The original instruction pops a value from the stack *) + + procedure Ins_DEBUG( args : PStorage ); + begin + exc.error := TT_Err_Debug_Opcode; + end; + +(**********************************************) +(* GETINFO[] : GET INFOrmation *) +(* CodeRange : $88 *) + + procedure Ins_GETINFO( args : PStorage ); + var + K : Int; + begin + K := 0; + + if args^[0] and 1 <> 0 then K := 3; + (* We return then Windows 3.1 version number *) + (* for the font scaler *) + + if false then K := K or $80; + (* Has the glyph been rotated ? *) + (* XXXX TO DO *) + + if false then K := K or $100; + (* Has the glyph been stretched ? *) + (* XXXX TO DO *) + + args^[0] := K; + end; + + + procedure Ins_UNKNOWN( args : PStorage ); + begin + exc.error := TT_Err_Invalid_Opcode; + end; + {$F-} + + + +const + Instruct_Dispatch : array[0..255] of TInstruction_Function + = ( + (* SVTCA y *) Ins_SVTCA, + (* SVTCA x *) Ins_SVTCA, + (* SPvTCA y *) Ins_SPVTCA, + (* SPvTCA x *) Ins_SPVTCA, + (* SFvTCA y *) Ins_SFVTCA, + (* SFvTCA x *) Ins_SFVTCA, + (* SPvTL // *) Ins_SPVTL, + (* SPvTL + *) Ins_SPVTL, + (* SFvTL // *) Ins_SFVTL, + (* SFvTL + *) Ins_SFVTL, + (* SPvFS *) Ins_SPVFS, + (* SFvFS *) Ins_SFVFS, + (* GPV *) Ins_GPV, + (* GFV *) Ins_GFV, + (* SFvTPv *) Ins_SFVTPV, + (* ISECT *) Ins_ISECT, + + (* SRP0 *) Ins_SRP0, + (* SRP1 *) Ins_SRP1, + (* SRP2 *) Ins_SRP2, + (* SZP0 *) Ins_SZP0, + (* SZP1 *) Ins_SZP1, + (* SZP2 *) Ins_SZP2, + (* SZPS *) Ins_SZPS, + (* SLOOP *) Ins_SLOOP, + (* RTG *) Ins_RTG, + (* RTHG *) Ins_RTHG, + (* SMD *) Ins_SMD, + (* ELSE *) Ins_ELSE, + (* JMPR *) Ins_JMPR, + (* SCvTCi *) Ins_SCVTCI, + (* SSwCi *) Ins_SSWCI, + (* SSW *) Ins_SSW, + + (* DUP *) Ins_DUP, + (* POP *) Ins_POP, + (* CLEAR *) Ins_CLEAR, + (* SWAP *) Ins_SWAP, + (* DEPTH *) Ins_DEPTH, + (* CINDEX *) Ins_CINDEX, + (* MINDEX *) Ins_MINDEX, + (* AlignPTS *) Ins_ALIGNPTS, + (* INS_$28 *) Ins_UNKNOWN, + (* UTP *) Ins_UTP, + (* LOOPCALL *) Ins_LOOPCALL, + (* CALL *) Ins_CALL, + (* FDEF *) Ins_FDEF, + (* ENDF *) Ins_ENDF, + (* MDAP[0] *) Ins_MDAP, + (* MDAP[1] *) Ins_MDAP, + + (* IUP[0] *) Ins_IUP, + (* IUP[1] *) Ins_IUP, + (* SHP[0] *) Ins_SHP, + (* SHP[1] *) Ins_SHP, + (* SHC[0] *) Ins_SHC, + (* SHC[1] *) Ins_SHC, + (* SHZ[0] *) Ins_SHZ, + (* SHZ[1] *) Ins_SHZ, + (* SHPIX *) Ins_SHPIX, + (* IP *) Ins_IP, + (* MSIRP[0] *) Ins_MSIRP, + (* MSIRP[1] *) Ins_MSIRP, + (* AlignRP *) Ins_ALIGNRP, + (* RTDG *) Ins_RTDG, + (* MIAP[0] *) Ins_MIAP, + (* MIAP[1] *) Ins_MIAP, + + (* NPushB *) Ins_NPUSHB, + (* NPushW *) Ins_NPUSHW, + (* WS *) Ins_WS, + (* RS *) Ins_RS, + (* WCvtP *) Ins_WCVTP, + (* RCvt *) Ins_RCVT, + (* GC[0] *) Ins_GC, + (* GC[1] *) Ins_GC, + (* SCFS *) Ins_SCFS, + (* MD[0] *) Ins_MD, + (* MD[1] *) Ins_MD, + (* MPPEM *) Ins_MPPEM, + (* MPS *) Ins_MPS, + (* FlipON *) Ins_FLIPON, + (* FlipOFF *) Ins_FLIPOFF, + (* DEBUG *) Ins_DEBUG, + + (* LT *) Ins_LT, + (* LTEQ *) Ins_LTEQ, + (* GT *) Ins_GT, + (* GTEQ *) Ins_GTEQ, + (* EQ *) Ins_EQ, + (* NEQ *) Ins_NEQ, + (* ODD *) Ins_ODD, + (* EVEN *) Ins_EVEN, + (* IF *) Ins_IF, + (* EIF *) Ins_EIF, + (* AND *) Ins_AND, + (* OR *) Ins_OR, + (* NOT *) Ins_NOT, + (* DeltaP1 *) Ins_DELTAP, + (* SDB *) Ins_SDB, + (* SDS *) Ins_SDS, + + (* ADD *) Ins_ADD, + (* SUB *) Ins_SUB, + (* DIV *) Ins_DIV, + (* MUL *) Ins_MUL, + (* ABS *) Ins_ABS, + (* NEG *) Ins_NEG, + (* FLOOR *) Ins_FLOOR, + (* CEILING *) Ins_CEILING, + (* ROUND[0] *) Ins_ROUND, + (* ROUND[1] *) Ins_ROUND, + (* ROUND[2] *) Ins_ROUND, + (* ROUND[3] *) Ins_ROUND, + (* NROUND[0]*) Ins_ROUND, + (* NROUND[1]*) Ins_ROUND, + (* NROUND[2]*) Ins_ROUND, + (* NROUND[3]*) Ins_ROUND, + + (* WCvtF *) Ins_WCVTF, + (* DeltaP2 *) Ins_DELTAP, + (* DeltaP3 *) Ins_DELTAP, + (* DeltaCn[0]*) Ins_DELTAC, + (* DeltaCn[1]*) Ins_DELTAC, + (* DeltaCn[2]*) Ins_DELTAC, + (* SROUND *) Ins_SROUND, + (* S45Round *) Ins_S45ROUND, + (* JROT *) Ins_JROT, + (* JROF *) Ins_JROF, + (* ROFF *) Ins_ROFF, + (* INS_$7B *) Ins_UNKNOWN, + (* RUTG *) Ins_RUTG, + (* RDTG *) Ins_RDTG, + (* SANGW *) Ins_SANGW, + (* AA *) Ins_AA, + + (* FlipPT *) Ins_FLIPPT, + (* FlipRgON *) Ins_FLIPRGON, + (* FlipRgOFF*) Ins_FLIPRGOFF, + (* INS_$83 *) Ins_UNKNOWN, + (* INS_$84 *) Ins_UNKNOWN, + (* ScanCTRL *) Ins_SCANCTRL, + (* SDPVTL[0]*) Ins_SDPVTL, + (* SDPVTL[1]*) Ins_SDPVTL, + (* GetINFO *) Ins_GETINFO, + (* IDEF *) Ins_IDEF, + (* ROLL *) Ins_ROLL, + (* MAX *) Ins_MAX, + (* MIN *) Ins_MIN, + (* ScanTYPE *) Ins_SCANTYPE, + (* InstCTRL *) Ins_INSTCTRL, + (* INS_$8F *) Ins_UNKNOWN, + + (* INS_$90 *) Ins_UNKNOWN, + (* INS_$91 *) Ins_UNKNOWN, + (* INS_$92 *) Ins_UNKNOWN, + (* INS_$93 *) Ins_UNKNOWN, + (* INS_$94 *) Ins_UNKNOWN, + (* INS_$95 *) Ins_UNKNOWN, + (* INS_$96 *) Ins_UNKNOWN, + (* INS_$97 *) Ins_UNKNOWN, + (* INS_$98 *) Ins_UNKNOWN, + (* INS_$99 *) Ins_UNKNOWN, + (* INS_$9A *) Ins_UNKNOWN, + (* INS_$9B *) Ins_UNKNOWN, + (* INS_$9C *) Ins_UNKNOWN, + (* INS_$9D *) Ins_UNKNOWN, + (* INS_$9E *) Ins_UNKNOWN, + (* INS_$9F *) Ins_UNKNOWN, + + (* INS_$A0 *) Ins_UNKNOWN, + (* INS_$A1 *) Ins_UNKNOWN, + (* INS_$A2 *) Ins_UNKNOWN, + (* INS_$A3 *) Ins_UNKNOWN, + (* INS_$A4 *) Ins_UNKNOWN, + (* INS_$A5 *) Ins_UNKNOWN, + (* INS_$A6 *) Ins_UNKNOWN, + (* INS_$A7 *) Ins_UNKNOWN, + (* INS_$A8 *) Ins_UNKNOWN, + (* INS_$A9 *) Ins_UNKNOWN, + (* INS_$AA *) Ins_UNKNOWN, + (* INS_$AB *) Ins_UNKNOWN, + (* INS_$AC *) Ins_UNKNOWN, + (* INS_$AD *) Ins_UNKNOWN, + (* INS_$AE *) Ins_UNKNOWN, + (* INS_$AF *) Ins_UNKNOWN, + + (* PushB[0] *) Ins_PUSHB, + (* PushB[1] *) Ins_PUSHB, + (* PushB[2] *) Ins_PUSHB, + (* PushB[3] *) Ins_PUSHB, + (* PushB[4] *) Ins_PUSHB, + (* PushB[5] *) Ins_PUSHB, + (* PushB[6] *) Ins_PUSHB, + (* PushB[7] *) Ins_PUSHB, + (* PushW[0] *) Ins_PUSHW, + (* PushW[1] *) Ins_PUSHW, + (* PushW[2] *) Ins_PUSHW, + (* PushW[3] *) Ins_PUSHW, + (* PushW[4] *) Ins_PUSHW, + (* PushW[5] *) Ins_PUSHW, + (* PushW[6] *) Ins_PUSHW, + (* PushW[7] *) Ins_PUSHW, + + (* MDRP[00] *) Ins_MDRP, + (* MDRP[01] *) Ins_MDRP, + (* MDRP[02] *) Ins_MDRP, + (* MDRP[03] *) Ins_MDRP, + (* MDRP[04] *) Ins_MDRP, + (* MDRP[05] *) Ins_MDRP, + (* MDRP[06] *) Ins_MDRP, + (* MDRP[07] *) Ins_MDRP, + (* MDRP[08] *) Ins_MDRP, + (* MDRP[09] *) Ins_MDRP, + (* MDRP[10] *) Ins_MDRP, + (* MDRP[11] *) Ins_MDRP, + (* MDRP[12] *) Ins_MDRP, + (* MDRP[13] *) Ins_MDRP, + (* MDRP[14] *) Ins_MDRP, + (* MDRP[15] *) Ins_MDRP, + (* MDRP[16] *) Ins_MDRP, + (* MDRP[17] *) Ins_MDRP, + + (* MDRP[18] *) Ins_MDRP, + (* MDRP[19] *) Ins_MDRP, + (* MDRP[20] *) Ins_MDRP, + (* MDRP[21] *) Ins_MDRP, + (* MDRP[22] *) Ins_MDRP, + (* MDRP[23] *) Ins_MDRP, + (* MDRP[24] *) Ins_MDRP, + (* MDRP[25] *) Ins_MDRP, + (* MDRP[26] *) Ins_MDRP, + (* MDRP[27] *) Ins_MDRP, + (* MDRP[28] *) Ins_MDRP, + (* MDRP[29] *) Ins_MDRP, + (* MDRP[30] *) Ins_MDRP, + (* MDRP[31] *) Ins_MDRP, + + (* MIRP[00] *) Ins_MIRP, + (* MIRP[01] *) Ins_MIRP, + (* MIRP[02] *) Ins_MIRP, + (* MIRP[03] *) Ins_MIRP, + (* MIRP[04] *) Ins_MIRP, + (* MIRP[05] *) Ins_MIRP, + (* MIRP[06] *) Ins_MIRP, + (* MIRP[07] *) Ins_MIRP, + (* MIRP[08] *) Ins_MIRP, + (* MIRP[09] *) Ins_MIRP, + (* MIRP[10] *) Ins_MIRP, + (* MIRP[11] *) Ins_MIRP, + (* MIRP[12] *) Ins_MIRP, + (* MIRP[13] *) Ins_MIRP, + (* MIRP[14] *) Ins_MIRP, + (* MIRP[15] *) Ins_MIRP, + + (* MIRP[16] *) Ins_MIRP, + (* MIRP[17] *) Ins_MIRP, + (* MIRP[18] *) Ins_MIRP, + (* MIRP[19] *) Ins_MIRP, + (* MIRP[20] *) Ins_MIRP, + (* MIRP[21] *) Ins_MIRP, + (* MIRP[22] *) Ins_MIRP, + (* MIRP[23] *) Ins_MIRP, + (* MIRP[24] *) Ins_MIRP, + (* MIRP[25] *) Ins_MIRP, + (* MIRP[26] *) Ins_MIRP, + (* MIRP[27] *) Ins_MIRP, + (* MIRP[28] *) Ins_MIRP, + (* MIRP[29] *) Ins_MIRP, + (* MIRP[30] *) Ins_MIRP, + (* MIRP[31] *) Ins_MIRP + + ); + +(****************************************************************) +(* *) +(* RUN *) +(* *) +(* This function executes a run of opcodes. It will exit *) +(* in the following cases : *) +(* *) +(* - Errors ( in which case it returns FALSE ) *) +(* *) +(* - Reaching the end of the main code range (returns TRUE) *) +(* reaching the end of a code range within a function *) +(* call is an error. *) +(* *) +(* - After executing one single opcode, if the flag *) +(* 'Instruction_Trap' is set to TRUE. (returns TRUE) *) +(* *) +(* On exit whith TRUE, test IP < CodeSize to know wether it *) +(* comes from a instruction trap or a normal termination *) +(* *) +(* *) +(* Note : The documented DEBUG opcode pops a value from *) +(* the stack. This behaviour is unsupported, here *) +(* a DEBUG opcode is always an error. *) +(* *) +(* *) +(* THIS IS THE INTERPRETER'S MAIN LOOP *) +(* *) +(* Instructions appear in the specs' order *) +(* *) +(****************************************************************) + + function Run_Ins( exec : PExec_Context ) : Boolean; + label + SuiteLabel, ErrorLabel, No_Error; + var + A : Int; + begin + + exc := exec^; + + (* set cvt functions *) + + exc.metrics.ratio := 0; + if exc.instance^.metrics.x_ppem <> exc.instance^.metrics.y_ppem then +{$IFDEF FPK} + begin + exc.func_read_cvt := @Read_CVT_Stretched; + exc.func_write_cvt := @Write_CVT_Stretched; + exc.func_move_cvt := @Move_CVT_Stretched; + end + else + begin + exc.func_read_cvt := @Read_CVT; + exc.func_write_cvt := @Write_CVT; + exc.func_move_cvt := @Move_CVT; + end; +{$ELSE} + begin + exc.func_read_cvt := Read_CVT_Stretched; + exc.func_write_cvt := Write_CVT_Stretched; + exc.func_move_cvt := Move_CVT_Stretched; + end + else + begin + exc.func_read_cvt := Read_CVT; + exc.func_write_cvt := Write_CVT; + exc.func_move_cvt := Move_CVT; + end; +{$ENDIF} + Compute_Funcs; + Compute_Round( exc.GS.round_state ); + + repeat + Calc_Length; + + (* First, let's check for empty stack and overflow *) + + exc.args := exc.top - Pop_Push_Count[ exc.opcode*2 ]; + + (* args is the top of the stack once arguments have been popped *) + (* one can also see it as the index of the last argument *) + + if exc.args < 0 then + begin + exc.error := TT_Err_Too_Few_Arguments; + goto ErrorLabel; + end; + + exc.new_top := exc.args + Pop_Push_Count[ exc.opcode*2+1 ]; + + (* new_top is the new top of the stack, after the instruction's *) + (* execution. top will be set to new_top after the 'case' *) + + if exc.new_top > exc.stackSize then + begin + exc.error := TT_Err_Stack_Overflow; + goto ErrorLabel; + end; + + exc.step_ins := true; + exc.error := TT_Err_Ok; + + Instruct_Dispatch[ exc.opcode ]( PStorage(@exc.stack^[exc.args]) ); + + if exc.error <> TT_Err_Ok then + begin + + case exc.error of + + TT_Err_Invalid_Opcode: (* looking for redefined instructions *) + + begin + A := 0; + while ( A < exc.numIDefs ) do + with exc.IDefs^[A] do + + if Active and ( exc.opcode = Opc ) then + begin + if exc.callTop >= exc.callSize then + begin + exc.error := TT_Err_Invalid_Reference; + goto ErrorLabel; + end; + + with exc.callstack^[exc.callTop] do + begin + Caller_Range := exc.curRange; + Caller_IP := exc.IP+1; + Cur_Count := 1; + Cur_Restart := Start; + end; + + if not Goto_CodeRange( Range, Start ) then + goto ErrorLabel; + + goto SuiteLabel; + end + else + inc(A); + + exc.error := TT_Err_Invalid_Opcode; + goto ErrorLabel; + + end; + else + exc.error := exc.error; + goto ErrorLabel; + end; + + end; + + exc.top := exc.new_top; + + if exc.step_ins then inc( exc.IP, exc.length ); + + SuiteLabel: + + if (exc.IP >= exc.codeSize) then + + if exc.callTop > 0 then + begin + exc.error := TT_Err_Code_Overflow; + goto ErrorLabel; + end + else + goto No_Error; + + until exc.instruction_trap; + + No_Error: + Run_Ins := Success; + exec^ := exc; + exit; + + ErrorLabel: + Run_Ins := Failure; + exec^ := exc; + + end; + +end. diff --git a/pascal/lib/ttload.pas b/pascal/lib/ttload.pas new file mode 100644 index 0000000..a7f234a --- /dev/null +++ b/pascal/lib/ttload.pas @@ -0,0 +1,1496 @@ +(******************************************************************* + * + * TTLoad.Pas 1.0 + * + * TrueType Tables loaders + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * Difference between 1.0 and 1.1 : HUGE !! + * + * - Changed the load model to get in touch with TTFile 1.1 + * - Now loads one whole resident table in one call + * - defined resident and instance records/data + * + ******************************************************************) + +Unit TTLoad; + +interface + +uses FreeType, TTTypes, TTTables, TTCMap, TTObjs; + + function LookUp_TrueType_Table( face : PFace; + aTag : string ) : int; + + function Load_TrueType_Directory( face : PFace; + faceIndex : Int ) : TError; + + function Load_TrueType_MaxProfile( face : PFace ) : TError; + function Load_TrueType_Header ( face : PFace ) : TError; + function Load_TrueType_Locations ( face : PFace ) : TError; + function Load_TrueType_CVT ( face : PFace ) : TError; + function Load_TrueType_CMap ( face : PFace ) : TError; + function Load_TrueType_Gasp ( face : PFace ) : TError; + function Load_TrueType_Names ( face : PFace ) : TError; + function Load_TrueType_Programs ( face : PFace ) : TError; + function Load_trueType_Postscript( face : PFace ) : TError; + function Load_TrueType_OS2 ( face : PFace ) : TError; + function Load_TrueType_HDMX ( face : PFace ) : TError; + + function Load_TrueType_Metrics_Header( face : PFace; + vertical : Boolean ) : TError; + + function Load_TrueType_Any( face : PFace; + tag : longint; + offset : longint; + var buffer; + var length : longint ) : TError; + +implementation + +uses TTError, TTMemory, TTFile, TTCalc; + + (* Composite glyph decoding flags *) + +(******************************************************************* + * + * Function : LookUp_TrueType_Table + * + * Description : Looks for a TrueType table by name + * + * Input : face resident table to look for + * aTag searched tag + * + * Output : index of table if found, -1 otherwise. + * + ******************************************************************) + + function LookUp_TrueType_Table( face : PFace; + aTag : string ) : int; + var + ltag : Long; + i : int; + begin + ltag := (Long(ord(aTag[1])) shl 24) + (Long(ord(aTag[2])) shl 16) + + (Long(ord(aTag[3])) shl 8 ) + Long(ord(aTag[4])); + + for i := 0 to face^.numTables-1 do + begin + + if face^.dirTables^[i].Tag = lTag then + begin + LookUp_TrueType_Table := i; + exit; + end + end; + + (* couldn't find the table *) + LookUp_TrueType_Table := -1; + end; + + + function LookUp_Mandatory_Table( face : PFace; + aTag : string ) : int; + var + table : int; + begin + table := LookUp_TrueType_Table( face, aTag ); + if table < 0 then + error := TT_Err_Table_Missing; + + LookUp_Mandatory_Table := table; + end; + +(******************************************************************* + * + * Function : Load_TrueType_Collection + * + * Description : + * + * Input : face + * + * Output : True on success. False on failure + * + * Notes : A table directory doesn't own subttables. There is no + * constructor or destructor for it. + * + ******************************************************************) + + function Load_TrueType_Collection( face : PFace ) : TError; + var + n : Int; + const + TTC_Tag = ( ord('t') shl 24 ) + + ( ord('t') shl 16 ) + + ( ord('c') shl 8 ) + + ( ord(' ') ); + begin + Load_TrueType_Collection := Failure; + + with face^.ttcHeader do + begin + + if TT_Seek_File( 0 ) or + TT_Access_Frame( 12 ) then exit; + + Tag := Get_ULong; + version := Get_Long; + dirCount := Get_Long; + + TT_Forget_Frame; + + if Tag <> TTC_Tag then + begin + Tag := 0; + version := 0; + dirCount := 0; + tableDirectory := nil; + + error := TT_Err_File_Is_Not_Collection; + exit; + end; + + if Alloc( tableDirectory, dirCount * sizeof(ULong) ) or + TT_Access_Frame( dirCount*4 ) then exit; + + for n := 0 to dirCount-1 do + tableDirectory^[n] := Get_ULong; + + TT_Forget_Frame; + end; + + Load_TrueType_Collection := Success; + end; + +(******************************************************************* + * + * Function : Load_TrueType_Directory + * + * Description : + * + * Input : face + * + * Output : True on success. False on failure + * + * Notes : A table directory doesn't own subttables. There is no + * constructor or destructor for it. + * + ******************************************************************) + + function Load_TrueType_Directory( face : PFace; + faceIndex : Int ) : TError; + var + n : Int; + tableDir : TTableDir; + begin + Load_TrueType_Directory := Failure; + + {$IFDEF DEBUG} Write('Directory '); {$ENDIF} + + if Load_TrueType_Collection(face) then + begin + if error <> TT_Err_File_Is_Not_Collection then + exit; + + (* The file isn't a collection, exit if index isn't 0 *) + if faceIndex <> 0 then + exit; + + error := TT_Err_Ok; + + (* Now skip to the beginning of the file *) + if TT_Seek_File(0) then + exit; + end + else + begin + (* file is a collection. Check the index *) + if ( faceIndex < 0 ) or + ( faceIndex >= face^.ttcHeader.dirCount ) then + begin + error := TT_Err_Bad_Argument; + exit; + end; + + (* select a TT Font within the ttc file *) + if TT_Seek_File( face^.ttcHeader.tableDirectory^[faceIndex] ) then + exit; + end; + + if TT_Access_Frame( 12 ) then + exit; + + tableDir.version := GET_Long; + tableDir.numTables := GET_UShort; + + tableDir.searchRange := GET_UShort; + tableDir.entrySelector := GET_UShort; + tableDir.rangeShift := GET_UShort; + + {$IFDEF DEBUG} Writeln('Tables number : ', tableDir.numTables ); {$ENDIF} + + TT_Forget_Frame; + + (* Check that we have a 'sfnt' format there *) + if (tableDir.version <> $10000 ) and (* MS fonts *) + (tableDir.version <> $74727565) then (* Mac fonts *) + begin + {$IFDEF DEBUG} Writeln('Invalid font format'); {$ENDIF} + error := TT_Err_Invalid_File_Format; + exit; + end; + + with face^ do + begin + + numTables := tableDir.numTables; + + if Alloc( dirTables, numTables * sizeof( TTableDirEntry ) ) or + TT_Access_Frame( 16 * numTables ) then exit; + + for n := 0 to numTables-1 do with dirTables^[n] do + begin + Tag := GET_ULong; + Checksum := GET_ULong; + Offset := GET_Long; + Length := Get_Long; + end; + + TT_Forget_Frame; + + end; + + {$IFDEF DEBUG} Writeln('loaded'); {$ENDIF} + + Load_TrueType_Directory := Success; + end; + +(******************************************************************* + * + * Function : Load_TrueType_MaxProfile + * + * Description : + * + * Input : face + * + * Output : True on success. False on failure + * + * Notes : A maximum profile is a static table that owns no + * subttable. It has then no constructor nor destructor + * + ******************************************************************) + + function Load_TrueType_MaxProfile( face : PFace ) : TError; + var + table : int; + begin + + Load_TrueType_MaxProfile := Failure; + + {$IFDEF DEBUG} Write('MaxProfile '); {$ENDIF} + + table := LookUp_Mandatory_Table( face, 'maxp'); + if table < 0 then exit; + + with face^ do + begin + + if TT_Seek_File( dirTables^[table].Offset ) or + TT_Access_Frame( 32 ) then exit; + + with MaxProfile do + begin + + ULong(Version) := GET_ULong; + + numGlyphs := GET_UShort; + maxPoints := GET_UShort; + maxContours := GET_UShort; + + maxCompositePoints := GET_UShort; + maxCompositeContours := GET_UShort; + maxZones := GET_UShort; + maxTwilightPoints := GET_UShort; + maxStorage := GET_UShort; + maxFunctionDefs := GET_UShort; + maxINstructionDefs := GET_UShort; + maxStackElements := GET_UShort; + + maxSizeOfInstructions := GET_UShort; + maxComponentElements := GET_UShort; + maxComponentDepth := GET_UShort; + end; + + TT_Forget_Frame; + + (* XXX : an adjustement that is necessary to load certain */ + /* broken fonts like "Keystrokes MT" :-( */ + /* */ + /* We allocate 64 function entries by default when */ + /* the maxFunctionDefs field is null. *) + + (* otherwise, we increment this field by one, in order *) + (* to load some old Apple fonts.. *) + + if maxProfile.maxFunctionDefs = 0 then + maxProfile.maxFunctionDefs := 64; + + numGlyphs := MaxProfile.numGlyphs; + (* compute number of glyphs *) + + maxPoints := MaxProfile.maxCompositePoints; + if (maxPoints < MaxProfile.maxPoints) then + maxPoints := MaxProfile.maxPoints; + (* compute max number of points *) + + maxContours := MaxProfile.maxCompositeContours; + if maxContours < MaxProfile.maxContours then + maxContours := MaxProfile.maxContours; + (* compute max number of contours *) + + maxComponents := MaxProfile.maxComponentElements + + MaxProfile.maxComponentDepth; + (* compute max number of components for glyph loading *) + + (* XXX: some fonts have maxComponents set to 0; we will *) + (* then use 16 of them by default *) + if maxComponents = 0 then maxComponents := 16; + + (* We also increase maxPoints and maxContours in order to support *) + (* some broken fonts *) + inc( maxPoints, 8 ); + inc( maxContours, 4 ); + end; + + {$IFDEF DEBUG} Writeln('loaded'); {$ENDIF} + + Load_TrueType_MaxProfile := Success; + end; + +(******************************************************************* + * + * Function : Load_TrueType_Gasp + * + * Description : + * + * Input : face + * + ******************************************************************) + + function Load_TrueType_Gasp( face : PFace ) : TError; + var + gRanges : PGaspRanges; + table, i : Int; + label + Fail; + begin + Load_TrueType_Gasp := Failure; + + with face^.gasp do + begin + version := 0; + numRanges := 0; + gaspRanges := nil; + end; + + table := Lookup_TrueType_Table( face, 'gasp' ); + if ( table < 0 ) then + begin + Load_TrueType_Gasp := Success; + exit; + end; + + if TT_Seek_File( face^.dirTables^[table].Offset ) or + TT_Access_Frame( 4 ) then exit; + + with face^.gasp do + begin + version := Get_UShort; + numRanges := Get_UShort; + gaspRanges := nil; + end; + + TT_Forget_Frame; + + if Alloc( gRanges, face^.gasp.numRanges * sizeof(TGaspRange) ) or + TT_Access_Frame( face^.gasp.numRanges * 4 ) then + goto Fail; + + face^.gasp.gaspRanges := gRanges; + + for i := 0 to face^.gasp.numRanges-1 do + with gRanges^[i] do + begin + maxPPEM := Get_UShort; + gaspFlag := Get_UShort; + end; + + TT_Forget_Frame; + + Load_TrueType_Gasp := Success; + exit; + + Fail: + Free( gRanges ); + face^.gasp.numRanges := 0; + end; + + +(******************************************************************* + * + * Function : Load_TrueType_Header + * + * Description : Load the TrueType header table in the resident + * table + * + * Input : face current leading segment. + * + * Output : True on success. False on failure + * + * Notes : A font header is a static table that owns no + * subttable. It has then no constructor nor destructor + * + ******************************************************************) + + function Load_TrueType_Header( face : PFace ) : TError; + var + i : int; + begin + Load_TrueType_Header := Failure; + + {$IFDEF DEBUG} Write('Header '); {$ENDIF} + + i := LookUp_Mandatory_Table(face, 'head'); + if i <= 0 then exit; + + with face^ do + begin + + if TT_Seek_File( dirTables^[i].offset ) or + TT_Access_Frame( 54 ) then exit; + + with FontHeader do + begin + + ULong(Table_Version) := GET_ULong; + ULong(Font_Revision) := GET_ULong; + + Checksum_Adjust := GET_Long; + Magic_Number := GET_Long; + + Flags := GET_UShort; + Units_Per_EM := GET_UShort; + + Created [0] := GET_Long; Created [1] := GET_Long; + Modified[0] := GET_Long; Modified[1] := GET_Long; + + xMin := GET_Short; + yMin := GET_SHort; + xMax := GET_SHort; + yMax := GET_Short; + + Mac_Style := GET_UShort; + Lowest_Rec_PPEM := GET_UShort; + + Font_Direction := GET_Short; + Index_To_Loc_Format := GET_Short; + Glyph_Data_Format := GET_Short; + + {$IFDEF DEBUG} Writeln('Units per EM : ',Units_Per_EM ); {$ENDIF} + + end; + + TT_Forget_Frame; + + end; + + {$IFDEF DEBUG} Writeln('loaded'); {$ENDIF} + + Load_TrueType_Header := Success; + end; + +(******************************************************************* + * + * Function : Load_TrueType_Metrics + * + * Description : Load TrueType metrics either from the "hmtx" or + * "vmtx" table. + * + * Input : face current resident leading segment + * vertical boolean. When set, try to load the vertical + * header. + * + * Output : True on success. False on failure + * + ******************************************************************) + + function Load_TrueType_Metrics( face : PFace; + vertical : Boolean ) : TError; + var + table, n : int; + num_longs : int; + num_shorts : int; + num_shorts_checked : int; + temp : Short; + + header : ^TT_Horizontal_Header; + + shorts : ^PTableShortMetrics; + longs : ^PTableLongMetrics; + + begin + Load_TrueType_Metrics := Failure; + + {$IFDEF DEBUG} + if vertical then + Write('vmtx ') + else + Write('hmtx '); + {$ENDIF} + + if vertical then + begin + + table := LookUp_TrueType_Table( face, 'vmtx' ); + if table < 0 then + begin + (* This is an optional table. Return silently if it *) + (* wasn't found. Note : some fonts have a vertical *) + (* header, but no 'vmtx'. E.g. : mingliu.ttf *) + + face^.verticalHeader.number_Of_VMetrics := 0; + Load_TrueType_Metrics := Success; + exit; + end; + + header := @TT_Horizontal_Header(face^.verticalHeader); + end + else + begin + table := LookUp_Mandatory_Table( face, 'hmtx' ); + if table < 0 then + exit; + + header := @face^.horizontalHeader; + end; + + + shorts := @PTableShortMetrics(header^.short_metrics); + longs := @PTableLongMetrics (header^.long_metrics ); + + num_longs := header^.number_Of_HMetrics; + num_shorts := face^.numGlyphs - num_longs; + + num_shorts_checked := (face^.dirTables^[table].Length - num_longs*4) div 2; + + if num_shorts < 0 then + begin + {$IFDEF DEBUG} Writeln('!! More metrics than glyphs !\n'); {$ENDIF} + if vertical then error := TT_Err_Invalid_Vert_Metrics + else error := TT_Err_Invalid_Horiz_Metrics; + exit; + end; + + if Alloc( longs^, sizeof(TLongMetrics) * num_longs ) or + Alloc( shorts^, sizeof(TShortMetrics)* num_shorts ) or + + TT_Seek_File( face^.dirTables^[table].Offset ) or + TT_Access_Frame( face^.dirTables^[table].Length ) then exit; + + for n := 0 to num_longs-1 do with longs^^[n] do + begin + advance := GET_UShort; + bearing := GET_Short; + end; + + (* do we have an inconsistent number of metric values ? *) + if num_shorts > num_shorts_checked then + begin + for n := 0 to num_shorts_checked-1 do + shorts^^[n] := GET_Short; + + (* we fill up the missing left side bearings with the *) + (* last valid value. Since this will occur for buggy CJK *) + (* fonts usually, nothing serious will happen. *) + + temp := shorts^^[num_shorts_checked-1]; + + for n := num_shorts_checked to num_shorts-1 do + shorts^^[n] := temp; + end + else + for n := 0 to num_shorts-1 do + shorts^^[n] := GET_Short; + + TT_Forget_Frame; + + {$IFDEF DEBUG} Writeln('loaded'); {$ENDIF} + + Load_TrueType_Metrics := Success; + end; + + +(******************************************************************* + * + * Function : Load_TrueType_Metrics_Header + * + * Description : + * + * Input : face current resident leading segment + * vertical boolean. When set, try to load the vertical + * header. + * + * Output : True on success. False on failure + * + ******************************************************************) + + function Load_TrueType_Metrics_Header( face : PFace; + vertical : Boolean ) : TError; + var + table : int; + header : ^TT_Horizontal_Header; + begin + Load_TrueType_Metrics_Header := Failure; + + {$IFDEF DEBUG} + if vertical then + Write('Vertical Header ') + else + Write('Horizontal Header '); + {$ENDIF} + + if vertical then + begin + face^.verticalInfo := False; + + (* the vertical header is an optional table.. so return *) + (* silently if we don't find it *) + table := LookUp_TrueType_Table( face, 'vhea' ); + if (table < 0) then + begin + Load_TrueType_Metrics_Header := Success; + exit; + end; + + face^.verticalInfo := True; + header := @TT_Horizontal_Header(face^.verticalHeader); + end + else + begin + table := LookUp_Mandatory_Table( face, 'hhea'); + if ( table < 0 ) then + exit; + header := @face^.horizontalHeader; + end; + + with face^ do + begin + + if TT_Seek_File( dirTables^[table].Offset ) or + TT_Access_Frame( 36 ) then + exit; + + with header^ do + begin + + Long(Version) := GET_ULong; + Ascender := GET_Short; + Descender := GET_Short; + Line_Gap := GET_Short; + + advance_Width_Max := GET_UShort; + + min_Left_Side_Bearing := GET_Short; + min_Right_Side_Bearing := GET_Short; + xMax_Extent := GET_Short; + caret_Slope_Rise := GET_Short; + caret_Slope_Run := GET_Short; + + Reserved[0] := GET_Short; (* this is cared offset for vertical *) + + Reserved[1] := GET_Short; + Reserved[2] := GET_Short; + Reserved[3] := GET_Short; + Reserved[4] := GET_Short; + + metric_Data_Format := GET_Short; + number_Of_HMetrics := GET_UShort; + + short_metrics := nil; + long_metrics := nil; + + end; + + TT_Forget_Frame; + + end; + + {$IFDEF DEBUG} Writeln('loaded'); {$ENDIF} + + Load_TrueType_Metrics_Header := Load_TrueType_Metrics( face, vertical ); + end; + +(******************************************************************* + * + * Function : Load_TrueType_Locations + * + * Description : Loads the location table in resident table + * + * Input : face Current Resident Leading Segment + * + * Output : True on success. False on failure + * + * NOTES : + * + * The Font Header *must* be loaded in the leading segment + * before calling this function. + * + * This table is destroyed directly by the resident destructor. + * + ******************************************************************) + + function Load_TrueType_Locations( face : PFace ): TError; + var + t, n : int; + LongOffsets : int; + begin + + Load_TrueType_Locations := Failure; + + {$IFDEF DEBUG} Write('Locations '); {$ENDIF} + + with face^ do + begin + + LongOffsets := fontHeader.Index_To_Loc_Format; + + t := LookUp_Mandatory_Table( face, 'loca' ); + if t < 0 then exit; + + if TT_Seek_File( dirTables^[T].Offset ) then exit; + + if LongOffsets <> 0 then + begin + + numLocations := dirTables^[T].Length shr 2; + + {$IFDEF DEBUG} + Writeln('Glyph locations # ( 32 bits offsets ) : ', numLocations ); + {$ENDIF} + + if Alloc( glyphLocations, sizeof(Long)*numLocations ) or + TT_Access_Frame( numLocations*4 ) then exit; + + for n := 0 to numLocations-1 do + glyphLocations^[n] := GET_Long; + + TT_Forget_Frame; + + end + else + begin + numLocations := dirTables^[T].Length shr 1; + + {$IFDEF DEBUG} + Writeln('Glyph locations # ( 16 bits offsets ) : ', numLocations ); + {$ENDIF} + + if Alloc( glyphLocations, sizeof(Long)*numLocations ) or + TT_Access_Frame( numLocations*2 ) then exit; + + for n := 0 to numLocations-1 do + glyphLocations^[n] := Long(GET_UShort) * 2; + + TT_Forget_Frame; + end; + + end; + + {$IFDEF DEBUG} Writeln('loaded'); {$ENDIF} + + Load_TrueType_Locations := Success; + end; + + +(******************************************************************* + * + * Function : Load_TrueType_Names + * + * Description : Loads the name table into the face table + * + * Input : face + * + * Output : True on success. False on failure + * + * Notes : This attribute table is destroyed by the resident + * destructor. + * + ******************************************************************) + + function Load_TrueType_Names( face : PFace ) : TError; + var + table, i : Int; + bytes : Long; + begin + Load_TrueType_Names := Failure; + + table := Lookup_Mandatory_Table( face, 'name' ); + if table < 0 then exit; + + with face^.nameTable do + begin + (* Seek to the beginning of the table and check the frame access. *) + if TT_Seek_File( face^.dirTables^[table].Offset ) or + TT_Access_Frame( 6 ) then exit; + + format := GET_UShort; + numNameRecords := GET_UShort; + storageOffset := GET_UShort; + + TT_Forget_Frame; + + if Alloc( names, numNameRecords*sizeof(TName_Record) ) or + TT_Access_Frame( numNameRecords*12 ) then + begin + numNameRecords := 0; + exit; + end; + + (* Load the name records and determine how much storage is needed *) + (* to hold the strings themselves *) + + bytes := 0; + for i := 0 to numNameRecords-1 do with names^[i] do + begin + platformID := GET_UShort; + encodingID := GET_UShort; + languageID := GET_UShort; + nameID := GET_UShort; + length := GET_UShort; + offset := GET_UShort; + + (* this test takes care of 'holes' in the names tabls, as *) + (* reported by Erwin *) + if Offset + Length > bytes then + bytes := Offset + Length; + end; + + TT_Forget_Frame; + + storage := nil; + if bytes > 0 then + begin + if Alloc( storage, bytes ) then exit; + + if TT_Read_At_File( face^.dirTables^[table].Offset + storageOffset, + storage^, bytes ) then + begin + Free(storage); + exit; + end; + end; + + end; + + Load_TrueType_Names := Success; + exit; + end; + +(******************************************************************* + * + * Function : Load_TrueType_CVT + * + * Description : + * + * Input : face + * + * Output : True on success. False on failure + * + * Notes : This attribute table is destroyed by the resident + * destructor. + * + ******************************************************************) + + function Load_TrueType_CVT( face : PFace ): TError; + var + t, n : Int; + begin + Load_TrueType_CVT := Failure; + + {$IFDEF DEBUG} Write('CVT '); {$ENDIF} + + (* the CVT table is optional *) + + t := LookUp_TrueType_Table( face, 'cvt '); + if t < 0 then + begin + face^.cvt := nil; + face^.cvtSize := 0; + Load_TrueType_CVT := Success; + {$IFDEF DEBUG} writeln('none'); {$ENDIF} + exit; + end; + + with face^ do + begin + + cvtSize := dirTables^[t].Length div 2; + + if Alloc( cvt, sizeof(Short)*cvtSize ) or + + TT_Seek_File( dirTables^[t].Offset ) or + + TT_Access_Frame( 2*cvtSize ) then exit; + + for n := 0 to cvtSize-1 do + cvt^[n] := GET_Short; + + TT_Forget_Frame; + end; + + {$IFDEF DEBUG} Writeln('loaded'); {$ENDIF} + Load_TrueType_CVT := Success; + end; + + +(******************************************************************* + * + * Function : Load_TrueType_CMap + * + * Description : + * + * Input : face + * + * Output : True on success. False on failure + * + * Notes : The Cmap table directory is destroyed by the resident + * destructor. The Cmap subtables must be destroyed by + * Free_CMap_Table. + * + ******************************************************************) + + function Load_TrueType_CMap( face : PFace ) : TError; + var + off, table_start : Longint; + n, limit, t : Int; + + cmap_dir : TCMapDir; + entry : TCMapDirEntry; + cmap : PCMapTable; + label + Fail; + begin + + Load_TrueType_CMap := Failure; + + {$IFDEF DEBUG} Write('CMaps '); {$ENDIF} + + t := LookUp_Mandatory_Table( face,'cmap' ); + if t < 0 then exit; + + with face^ do + begin + + table_start := dirTables^[t].offset; + + if TT_Seek_File( dirTables^[t].Offset ) or + TT_Access_Frame( 4 ) then exit; + + cmap_dir.tableVersionNumber := GET_UShort; + cmap_dir.numCMaps := GET_UShort; + + TT_Forget_Frame; + + off := TT_File_Pos; + + (* save space in face data for cmap tables *) + numCMaps := cmap_dir.numCMaps; + if Alloc( cMaps, numCMaps * sizeof(TCMapTable) ) then exit; + + for n := 0 to numCMaps-1 do + begin + + if TT_Seek_File ( off ) or + TT_Access_Frame( 8 ) then exit; + + cmap := @cMaps^[n]; + + entry.platformID := GET_UShort; + entry.platformEncodingID := GET_UShort; + entry.offset := GET_Long; + + cmap^.loaded := False; + cmap^.platformID := entry.platformID; + cmap^.platformEncodingID := entry.platformEncodingID; + + TT_Forget_Frame; + + off := TT_File_Pos; + + if TT_Seek_File ( table_start + entry.offset ) or + TT_Access_Frame( 6 ) then exit; + + cmap^.format := Get_UShort; + cmap^.length := Get_UShort; + cmap^.version := Get_UShort; + + TT_Forget_Frame; + + cmap^.offset := TT_File_Pos; + + end; (* for n *) + + end; (* with face^ *) + + {$IFDEF DEBUG} Writeln('loaded'); {$ENDIF} + + Load_TrueType_CMap := Success; + exit; + + Fail: + Free( face^.cMaps ); + Load_TrueType_CMap := Failure; + end; + + +(* + procedure Free_CMap_Table( var cmap : TCMapTable ); + begin + if cmap.cmap0 <> nil then + with cmap do + case format of + + 0 : begin + Free( cmap0^.glyphIdArray ); + Free( cmap0 ); + end; + + 2 : begin + Free( cmap2^.glyphIdArray ); + Free( cmap2^.subHeaders ); + Free( cmap2 ); + end; + + 4 : begin + Free( cmap4^.glyphIdArray ); + Free( cmap4^.segments ); + Free( cmap4 ); + end; + + 6 : begin + Free( cmap6^.glyphIdArray ); + Free( cmap6 ); + end; + end; + + cmap.format := 0; + cmap.length := 0; + cmap.version := 0; + end; +*) + +(******************************************************************* + * + * Function : Load_TrueType_Programs + * + * Description : Load the Font and CVT programs in the resident + * table + * + * Input : face + * + * Output : True on success. False on failure + * + ******************************************************************) + + function Load_TrueType_Programs( face : PFace ) : TError; + var + t : Int; + begin + + Load_TrueType_Programs := Failure; + + {$IFDEF DEBUG} Write('Font program '); {$ENDIF} + + (* The font program is optional *) + + t := Lookup_TrueType_Table( face, 'fpgm' ); + + if t < 0 then + + with face^ do + begin + fontProgram := nil; + fontPgmSize := 0; + + {$IFDEF DEBUG} Writeln('none in file'); {$ENDIF} + end + + else + + with face^ do + begin + + fontPgmSize := dirTables^[t].Length; + + if Alloc( fontProgram, fontPgmSize ) or + TT_Read_At_File( dirTables^[t].offset, + fontProgram^, + fontPgmSize ) then exit; + + {$IFDEF DEBUG} Writeln('loaded, ',fontPgmSize,' bytes'); {$ENDIF} + end; + + {$IFDEF DEBUG} Write('CVT program '); {$ENDIF} + + t := LookUp_trueType_Table( face, 'prep' ); + + (* The CVT table is optional *) + + if t < 0 then + + with face^ do + begin + cvtProgram := nil; + cvtPgmSize := 0; + + {$IFDEF DEBUG} Writeln('none in file'); {$ENDIF} + end + + else + + with face^ do + begin + + cvtPgmSize := dirTables^[t].Length; + + if Alloc( cvtProgram, cvtPgmSize ) or + TT_Read_At_File( dirTables^[t].offset, + cvtProgram^, + cvtPgmSize ) then exit; + + {$IFDEF DEBUG} Writeln('loaded, ',cvtPgmSize,' bytes'); {$ENDIF} + end; + + Load_TrueType_Programs := Success; + end; + +(******************************************************************* + * + * Function : Load_TrueType_OS2 + * + * Description : Load the OS2 Table + * + * Input : face + * + * Output : True on success. False on failure + * + ******************************************************************) + + function Load_TrueType_OS2( face : PFace ) : TError; + var + table : Int; + i : Int; + begin + Load_TrueType_OS2 := Failure; + + {$IFDEF DEBUG} Write('OS/2 table '); {$ENDIF} + + (* We now support Apple fonts who do not have an OS/2 table *) + table := LookUp_Mandatory_Table( face, 'OS/2' ); + if table < 0 then begin + face^.os2.version := $FFFF; + Load_TrueType_OS2 := Success; + error := TT_Err_Ok; (* clear error *) + exit; + end; + + if TT_Seek_File( face^.dirTables^[table].offset ) or + TT_Access_Frame( 78 ) then exit; + + with face^.os2 do + begin + version := Get_UShort; + xAvgCharWidth := Get_Short; + usWeightClass := Get_UShort; + usWidthClass := Get_UShort; + fsType := Get_Short; + ySubscriptXSize := Get_Short; + ySubscriptYSize := Get_Short; + ySubscriptXOffset := Get_Short; + ySubscriptYOffset := Get_Short; + ySuperscriptXSize := Get_Short; + ySuperscriptYSize := Get_Short; + ySuperscriptXOffset := Get_Short; + ySuperscriptYOffset := Get_Short; + yStrikeoutSize := Get_Short; + yStrikeoutPosition := Get_Short; + sFamilyClass := Get_Short; + + for i := 0 to 9 do panose[i] := Get_Byte; + + ulUnicodeRange1 := Get_ULong; + ulUnicodeRange2 := Get_ULong; + ulUnicodeRange3 := Get_ULong; + ulUnicodeRange4 := Get_ULong; + + for i := 0 to 3 do achVendID[i] := Get_Byte; + + fsSelection := Get_UShort; + usFirstCharIndex := Get_UShort; + usLastCharIndex := Get_UShort; + sTypoAscender := Get_UShort; + sTypoDescender := Get_UShort; + sTypoLineGap := Get_UShort; + usWinAscent := Get_UShort; + usWinDescent := Get_UShort; + + TT_Forget_Frame; + + if version >= $0001 then + begin + if TT_Access_Frame(8) then exit; + + ulCodePageRange1 := Get_ULong; + ulCodePageRange2 := Get_ULong; + + TT_Forget_Frame; + end + else + begin + ulCodePageRange1 := 0; + ulCodePageRange2 := 0; + end; + + end; + + {$IFDEF DEBUG} Writeln('loaded'); {$ENDIF} + + Load_TrueType_OS2 := Success; + end; + +(******************************************************************* + * + * Function : Load_TrueType_Postscript + * + * Description : Load the 'post' table + * + * Input : face + * + * Output : True on success. False on failure + * + ******************************************************************) + + function Load_TrueType_Postscript( face : PFace ) : TError; + var + table : Int; + i : Int; + begin + Load_TrueType_Postscript := Failure; + + {$IFDEF DEBUG} Write('post table '); {$ENDIF} + + table := LookUp_TrueType_Table( face, 'post' ); + if table < 0 then exit; + + if TT_Seek_File( face^.dirTables^[table].offset ) or + TT_Access_Frame(32) then exit; + + with face^.postscript do + begin + formatType := Get_ULong; + italicAngle := Get_ULong; + underlinePosition := Get_Short; + underlineThickness := Get_Short; + isFixedPitch := Get_ULong; + minMemType42 := Get_ULong; + maxMemType42 := Get_ULong; + minMemType1 := Get_ULong; + maxMemType1 := Get_ULong; + end; + + TT_Forget_Frame; + + {$IFDEF DEBUG} Writeln('loaded'); {$ENDIF} + + Load_trueType_Postscript := Success; + end; + +(******************************************************************* + * + * Function : Load_TrueType_HDMX + * + * Description : Load the 'hdmx' tables + * + * Input : face + * + * Output : True on success. False on failure + * + ******************************************************************) + + function Load_TrueType_Hdmx( face : PFace ) : TError; + var + table, n : Int; + num_glyphs : Int; + + version : UShort; + num_rec : Short; + recs : PHdmx_Records; + rec_size : Long; + rec : PHdmx_Record; + label + Fail; + begin + Load_TrueType_Hdmx := Failure; + + with face^.hdmx do + begin + version := 0; + num_records := 0; + records := nil; + end; + + (* This table is optional *) + + table := LookUp_TrueType_Table( face, 'hdmx' ); + if table < 0 then + begin + Load_TrueType_Hdmx := Success; + exit; + end; + + if TT_Seek_File( face^.dirTables^[table].offset ) or + TT_Access_Frame( 8 ) then exit; + + version := Get_UShort; + num_rec := Get_Short; + rec_size := Get_Long; + + TT_Forget_Frame; + + (* right now, we only recognize format 0 *) + + if version <> 0 then + exit; + + if Alloc( face^.hdmx.records, sizeof(THdmx_Record)*num_rec ) then + exit; + + face^.hdmx.num_records := num_rec; + num_glyphs := face^.NumGlyphs; + + rec_size := rec_size - num_glyphs - 2; + + for n := 0 to num_rec-1 do + begin + rec := @face^.hdmx.records^[n]; + + (* read record *) + + if TT_Access_Frame(2) then + goto Fail; + + rec^.ppem := Get_Byte; + rec^.max_width := Get_Byte; + + TT_Forget_Frame; + + if Alloc( rec^.widths, num_glyphs ) or + TT_Read_File( rec^.widths^, num_glyphs ) then + goto Fail; + + (* skip padding bytes *) + + if rec_size > 0 then + if TT_Skip_File( rec_size ) then + goto Fail; + end; + + Load_TrueType_HDMX := Success; + exit; + + Fail: + for n := 0 to num_rec-1 do + Free( face^.hdmx.records^[n].widths ); + + Free( face^.hdmx.records ); + face^.hdmx.num_records := 0; + end; + + +(******************************************************************* + * + * Function : Load_TrueType_Any + * + * Description : Load any TrueType table in user memory + * + * Input : face the font file's face object + * tag the table + * + * Output : True on success. False on failure + * + ******************************************************************) + + function Load_TrueType_Any( face : PFace; + tag : longint; + offset : longint; + var buffer; + var length : longint ) : TError; + var + stream : TT_Stream; + found, i : integer; + begin + if tag <> 0 then + begin + found := -1; + i := 0; + while i < face^.numTables do + if Longint(face^.dirTables^[i].tag) = tag then + begin + found := i; + i := face^.numTables; + end + else + inc(i); + + if found < 0 then + begin + error := TT_Err_Table_Missing; + Load_TrueType_Any := Failure; + exit; + end; + + inc( offset, face^.dirTables^[found].offset ); + + (* if length = 0, the user requested the table's size *) + if length = 0 then + begin + length := face^.dirTables^[found].length; + Load_TrueType_Any := Success; + exit; + end; + end + else + (* if length = 0 and tag = 0, the user requested the font file's size *) + if length = 0 then + begin + (* return length of font file *) + length := TT_Stream_Size( face^.stream ); + Load_TrueType_Any := Success; + exit; + end; + + TT_Use_Stream( face^.stream, stream ); + Load_TrueType_Any := TT_Read_At_File( offset, buffer, length ); + TT_Done_Stream( face^.stream ); + end; + +end. + diff --git a/pascal/lib/ttmemory.pas b/pascal/lib/ttmemory.pas new file mode 100644 index 0000000..e721f56 --- /dev/null +++ b/pascal/lib/ttmemory.pas @@ -0,0 +1,282 @@ +(******************************************************************* + * + * TTMemory.Pas 2.1 + * + * Memory management component (specification) + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * Differences between 2.1 and 2.0 : + * + * - Added a memory mutex to make the component thread-safe + * + * Differences between 2.0 and 1.1 : + * + * - The growing heap was completely removed in version 2.0 + * + * - The support for small mini-heaps may be re-introduced later + * to allow the storage of several consecutive arrays in one + * single block. + * + * IMPORTANT NOTICE : + * + * The Alloc and Free functions mimic their C equivalent, + * however, some points must be noticed : + * + * - both functions return a boolean. As usual, True indicates + * success, while False indicates failure. + * + * - the Alloc function puts a small header on front of each + * allocated block. The header contains a magic cookie and + * the size of the allocated block. This allows calls to + * Free without passing a block size as an argument, and thus + * reduces the risks of memory leaks. + * + * - it is possible to call Free with a nil pointer, in which + * case nothing happens, and the result is set to True (success) + * + * The pointer is set to nil after a call to Free in all cases. + * + * This is done to clear the destructors code, allowing + * + * if (pointer) then + * begin + * Free(pointer); + * pointer := nil; + * end; + * + * to be replaced by a single line : + * + * Free(pointer); + * + * + ******************************************************************) + +unit TTMemory; + +interface + +uses TTTypes; + +{$I TTCONFIG.INC} + +type + TMarkRecord = record + Magic : longint; + Top : integer; + end; + +const + Font_Pool_Allocated : boolean = False; + + function Alloc( var P; size : Longint ) : TError; + (* Allocates a new memory block in the current heap of 'size' bytes *) + (* - returns failure if no memory is left in the heap *) + + procedure Free ( var P ); + (* Releases a block previously allocated through 'Alloc' *) + (* - returns True (success) of P is nil before the call *) + (* - sets P to nil before exit *) + + function TTMemory_Init : TError; + procedure TTMemory_Done; + +implementation + +uses TTError; + +type + TByte = array[0..0] of Byte; + PByte = ^TByte; + + PBlock_Header = ^TBlock_Header; + TBlock_Header = record + magic : Longint; (* magic cookie *) + size : Longint; (* allocated size, including header *) + end; + + TBlock_Headers = array[0..1] of TBlock_Header; + PBlock_Headers = ^TBlock_Headers; + + (* Note that the Turbo-Pascal GetMem/FreeMem functions use no block *) + (* headers. That's why a byte size is needed for FreeMem. Thus, we *) + (* do not waste space here compared to a C malloc implementation *) + +const + Mark_Magic = $BABE0007; + (* This is the magic cookie used to recognize valide allocated blocks *) + + Header_Size = sizeof(TBlock_Header); + + (************************************************************************) + (* *) + (* MyHeapErr : *) + (* *) + (* By default, a call to GetMem with insufficient memory left will *) + (* generate a runtime error. We define here a function that is used *) + (* to allow GetMem to return nil in such cases. *) + (* *) + (************************************************************************) + + function MyHeapErr( Size: Integer ): Integer; far; + begin + MyHeapErr := 1; + end; + +(******************************************************************* + * + * Function : Alloc + * + * Description : allocate a new block in the current heap + * + * Notes : If you want to replace this function with + * your own, please be sure to respect these + * simple rules : + * + * - P must be set to nil in case of failure + * + * - The allocated block must be zeroed ! + * + *****************************************************************) + + function Alloc( var P; size : Longint ) : TError; + var + OldHeapError : Pointer; + + L : Longint; + P2 : Pointer; + begin + {$IFNDEF DELPHI32} + OldHeapError := HeapError; + HeapError := @MyHeapErr; + {$ENDIF} + + L := ( size + Header_Size + 3 ) and -4; + + {$IFDEF MSDOS} + if L shr 16 <> 0 then + begin + Writeln('Sorry, but this font is too large to be handled by a 16-bit program' ); + Alloc := Failure; + end; + {$ENDIF} + + GetMem( Pointer(P), L ); + + {$IFNDEF DELPHI32} + HeapError := OldHeapError; + {$ENDIF} + + if Pointer(P) <> nil then + begin + PBlock_Headers(P)^[0].magic := Mark_Magic; + PBlock_Headers(P)^[0].size := L; + + P2 := Pointer( @(PBlock_Headers(P)^[1]) ); + + {$IFDEF MSDOS} + if (ofs(P2^) <> ofs(Pointer(P)^)+Header_Size) or + (seg(P2^) <> seg(Pointer(P)^)) then + begin + Writeln('AAARGH !!: Sorry, but I have problems with 64 Kb segments'); + halt(1); + end; + {$ENDIF} + + Pointer(P) := P2; + fillchar( P2^, size, 0 ); + (* zero block *) + + Alloc := Success; + end + else + Alloc := Failure; + + end; + + +(******************************************************************* + * + * Function : Free + * + * Description : frees a block that was previsouly allocated + * by the Alloc function + * + * Notes : Doesn't need any size parameter. + * + * If you want to replace this function with your own, please + * be sure to respect these two rules : + * + * - the argument pointer can be nil, in which case the function + * should return immediately, with a success report. + * + * - the pointer P should be set to nil when exiting the + * function, except in case of failure. + * + *****************************************************************) + + procedure Free( var P ); + var + head : PBlock_Header; + i : Integer; + size : Longint; + begin + if Pointer(P) = nil then exit; + + i := -1; + head := @(PBlock_Headers(P)^[i]); + (* A hack to get the header in PB, as the line *) + (* @(PBlock_Headers(P)^[-1] would give a 'constant error' *) + (* at compile time. I'm unsure this works correctly in BP *) + + if head^.magic <> Mark_Magic then + begin + (* PANIC : An invalid Free call *) + Writeln('Invalid Free call'); + halt(1); + end; + + size := head^.size; + + head^.magic := 0; (* cleans the header *) + head^.size := 0; + + FreeMem( head, size ); + + Pointer(P) := nil; + end; + +(******************************************************************* + * + * Function : TTMemory_Init + * + * Description : Initializes the Memory component + * + *****************************************************************) + + function TTMemory_Init : TError; + begin + (* nothing to be done *) + TTMemory_Init := Success; + end; + +(******************************************************************* + * + * Function : TTMemory_Done + * + * Description : Finalize the memory component + * + *****************************************************************) + + procedure TTMemory_Done; + begin + (* nothing to be done *) + end; + +end. diff --git a/pascal/lib/ttobjs.pas b/pascal/lib/ttobjs.pas new file mode 100644 index 0000000..4f32967 --- /dev/null +++ b/pascal/lib/ttobjs.pas @@ -0,0 +1,1945 @@ +(******************************************************************* + * + * ttobjs.pas 2.0 + * + * Objects definition unit. + * + * Copyright 1996, 1997 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************) + +(* *) +(* The four important objects managed by the library are : *) +(* *) +(* Face : the object for a given typeface *) +(* Instance : the object for a face's given pointsize/transform *) +(* Context : the object for a given glyph loading/hinting execution *) +(* Glyph : the object for a given glyph ( outline and metrics ) *) +(* *) +(* A Face object is described by a TFace record, and its *) +(* associated sub-tables. It is created through a call to the *) +(* 'TT_Open_Face' API. *) +(* *) +(* An Instance object is described by a TInstance record, and *) +(* sub-tables. It is created for a given face through a call to the *) +(* 'TT_Open_Instance' API. Several instances can share the same face *) +(* *) +(* The pointsize and/or transform of a given instance object can be *) +(* changed on the fly through a call to the 'TT_Reset_Instance' API. *) +(* *) +(* A Glyph object is used to describe a glyph to the client application *) +(* It is made of a TGlyph_Record header, with several sub-tables used *) +(* to store, for example, point coordinates or outline info.. *) +(* It can hold metrics information and other attributes, as well as *) +(* the glyph's outline. A client application can request any kind of *) +(* info to the library on a given glyph through the 'TT_Get_Glyph' *) +(* call. *) +(* *) +(* *) +(* A Context is described by a TExec_Context record, and sub-tables *) +(* Execution contexts are created on demand during the following *) +(* operations : *) +(* *) +(* - creating a new instance ( to read and execute the font program ) *) +(* - setting/resetting the pointsize ( to execute the CVT program ) *) +(* - during glyph loading ( when hinting is on ) *) +(* *) +(* They are used to run TrueType instructions and load/store *) +(* glyph data that are not part of the Glyph object ( as they're of *) +(* no meaning to a client application ). *) +(* *) +(* The library keeps track of all objects related to a given face : *) +(* *) +(* A face's instances are kept in two linked lists : one is the 'active' *) +(* list, which tracks the face's current opened instances, while the *) +(* other is the 'idle' list used to collect/recycle instance objects *) +(* when they become unuseful after a 'TT_Close_Instance' call. *) +(* *) +(* In the same way, a face's execution contexts are kept in two *) +(* similar lists. Note that, as contexts are created on demand, *) +(* the active and idle contexts lists should always contain few *) +(* elements. *) +(* *) +(* Look also for the following files : *) +(* *) +(* Face manager : TTFace.pas *) +(* Instance manager : TTInst.pas *) +(* Context manager : TTExec.pas *) +(* Glyph manager : TTGlyph.pas *) +(* *) + +unit TTObjs; + +interface + +{$I TTCONFIG.INC} + +uses FreeType, + TTTypes, + TTError, + TTCache, + TTTables, + TTCMap; + +type + (* Graphics State *) + (* *) + (* The Graphics State (GS) is managed by the *) + (* instruction field, but does not come from *) + (* the font file. Thus, we can use 'int's *) + (* where needed. *) + (* *) + + PGraphicsState = ^TGraphicsState; + TGraphicsState = record + rp0, + rp1, + rp2 : int; + + dualVector, + projVector, + freeVector : TT_UnitVector; + + loop : longint; + minimum_distance : TT_F26dot6; + round_state : int; + + auto_flip : boolean; + control_value_cutin : TT_F26dot6; + single_width_cutin : TT_F26dot6; + single_width_value : TT_F26dot6; + delta_base : int; + delta_shift : int; + + instruct_control : byte; + scan_control : Boolean; + scan_type : Int; + + gep0, + gep1, + gep2 : int; + end; + + +const + Default_GraphicsState : TGraphicsState + = ( + rp0 : 0; + rp1 : 0; + rp2 : 0; + dualVector : ( x:$4000; y:0 ); + projVector : ( x:$4000; y:0 ); + freeVector : ( x:$4000; y:0 ); + loop : 1; + minimum_distance : 64; + round_state : 1; + auto_flip : True; + control_value_cutin : 4*17; + single_width_cutin : 0; + single_width_value : 0; + delta_Base : 9; + delta_Shift : 3; + instruct_control : 0; + scan_control : True; + scan_type : 0; + gep0 : 1; + gep1 : 1; + gep2 : 1 + ); + + (**********************************************************************) + (* *) + (* Execution Subtables : *) + (* *) + (**********************************************************************) + +const + MaxCodeRanges = 3; + (* There can only be 3 active code ranges at once : *) + (* - the Font Program *) + (* - the CVT Program *) + (* - a glyph's instructions set *) + + TT_CodeRange_Font = 1; + TT_CodeRange_Cvt = 2; + TT_CodeRange_Glyph = 3; + + CvtFlag_None = 0; + CvtFlag_X = 1; + CvtFlag_Y = 2; + CvtFlag_Both = 3; + +type + TCodeRange = record + Base : PByte; + Size : Int; + end; + PCodeRange = ^TCodeRange; + + (* defines a code range *) + (* *) + (* code ranges can be resident to a glyph ( i.e. the Font Program) *) + (* while some others are volatile ( Glyph instructions ) *) + (* tracking the state and presence of code ranges allows function *) + (* and instruction definitions within a code range to be forgotten *) + (* when the range is discarded *) + + TCodeRangeTable = array[1..MaxCodeRanges] of TCodeRange; + + (* defines a function/instruction definition record *) + PDefRecord = ^TDefRecord; + TDefRecord = record + Range : Int; (* in which code range is it located ? *) + Start : Int; (* where does it start ? *) + Opc : Byte; (* function #, or instruction code *) + Active : boolean; (* is the entry active ? *) + end; + + PDefArray = ^TDefArray; + TDefArray = array[0..99] of TDefRecord; + + (* defines a call record, used to manage function calls *) + TCallRecord = record + Caller_Range : Int; + Caller_IP : Int; + Cur_Count : Int; + Cur_Restart : Int; + end; + + (* defines a simple call stack *) + TCallStack = array[0..99] of TCallRecord; + PCallStack = ^TCallStack; + + PGlyph_Zone = ^TGlyph_Zone; + TGlyph_Zone = record + n_points : Int; + n_contours : Int; + + org : TT_Points; (* original (scaled) coords *) + cur : TT_Points; (* current coordinates *) + flags : TT_PTouchTable; + + conEnds : PUShort; + end; + + TRound_Function = function( distance, compensation : TT_F26dot6 ) + : TT_F26dot6; + (* Rounding function, as used by the interpreter *) + + TMove_Function = procedure( zone : PGlyph_Zone; + point : Int; + distance : TT_F26dot6 ); + (* Point displacement along the freedom vector routine, as *) + (* used by the interpreter *) + + TProject_Function = function( var P1, P2 : TT_Vector ) : TT_F26dot6; + (* Distance projection along one of the proj. vectors, as used *) + (* by the interpreter *) + + TFunc_Get_CVT = function ( index : Int ) : TT_F26Dot6; + (* Reading a cvt value. Take care of non-square pixels when *) + (* needed *) + + TFunc_Set_CVT = procedure( index : Int; value : TT_F26Dot6 ); + (* Setting or Moving a cvt value. Take care of non-square *) + (* pixels when needed *) + + + (********************************************************************) + (* *) + (* Glyph Sub-Tables *) + (* *) + (********************************************************************) + + PGlyph_Transform = ^TGlyph_Transform; + TGlyph_Transform = record + xx, xy : TT_Fixed; + yx, yy : TT_Fixed; + ox, oy : TT_F26Dot6; + end; + + PSubglyph_Record = ^TSubglyph_Record; + TSubglyph_Record = record + index : Int; + is_scaled : boolean; + is_hinted : boolean; + preserve_pps : boolean; + + bbox : TT_BBox; + zone : TGlyph_Zone; + + arg1, arg2 : Int; + element_flag : Int; + transform : TGlyph_Transform; + file_offset : Long; + + pp1, pp2 : TT_Vector; + + advanceWidth : Int; + leftBearing : Int; + end; + + TSubglyph_Stack = array[0..10] of TSubglyph_Record; + PSubglyph_Stack = ^TSubglyph_Stack; + + (* A note regarding non-squared pixels : *) + (* *) + (* ( This text will probably go into some docs at some time, for *) + (* now, it is kept there to explain some definitions in the *) + (* TIns_Metrics record ). *) + (* *) + (* The CVT is a one-dimensional array containing values that *) + (* control certain important characteristics in a font, like *) + (* the height of all capitals, all lowercase letter, default *) + (* spacing or stem width/height. *) + (* *) + (* These values are found in FUnits in the font file, and must be *) + (* scaled to pixel coordinates before being used by the CVT and *) + (* glyph programs. Unfortunately, when using distinct x and y *) + (* resolutions ( or distinct x and y pointsizes ), there are two *) + (* possible scalings. *) + (* *) + (* A first try was to implement a 'lazy' scheme were all values *) + (* were scaled when first used. However, some values are always *) + (* used in the same direction, and some other are used in many *) + (* different circumstances and orientations. *) + (* *) + (* I have found a simpler way to do the same, and it even seems to *) + (* work in most of the cases : *) + (* *) + (* - all CVT values are scaled to the maximum ppem size *) + (* *) + (* - when performing a read or write in the CVT, a ratio factor *) + (* is used to perform adequate scaling. Example : *) + (* *) + (* x_ppem = 14 *) + (* y_ppem = 10 *) + (* *) + (* we chose ppem = x_ppem = 14 as the CVT scaling size. All cvt *) + (* entries are scaled to it. *) + (* *) + (* x_ratio = 1.0 *) + (* y_ratio = y_ppem/ppem ( < 1.0 ) *) + (* *) + (* we compute the current ratio like : *) + (* *) + (* - if projVector is horizontal, ratio = x_ratio = 1.0 *) + (* - if projVector is vertical, ratop = y_ratio *) + (* - else, ratio = sqrt( (proj.x*x_ratio)ý+(proj.y*y_ratio)ý ) *) + (* *) + (* reading a cvt value returns ratio*cvt[index] *) + (* writing a cvt value in pixels cvt[index]/ratio *) + (* *) + (* the current ppem is simple ratio*ppem *) + (* *) + + TIns_Metrics = record + pointsize : TT_F26Dot6; + x_resolution : Int; + y_resolution : Int; + x_ppem : Int; + y_ppem : Int; + + x_scale1 : Long; + x_scale2 : Long; + y_scale1 : Long; + y_scale2 : Long; + + (* for non-square pixels *) + x_ratio : Long; + y_ratio : Long; + + scale1 : Long; + scale2 : Long; + ppem : Int; + ratio : Long; + + (* compensations *) + compensations : array[0..3] of TT_F26Dot6; + + (* flags *) + rotated : Boolean; + stretched : Boolean; + end; + + (********************************************************************) + (* *) + (* FreeType Face Object *) + (* *) + (********************************************************************) + + PFace = ^TFace; + PInstance = ^TInstance; + PExec_Context = ^TExec_Context; + + TFace = record + + stream : TT_Stream; + (* i/o stream *) + + ttcHeader : TTTCHeader; + (* TrueType collection header, if any was found *) + + maxProfile : TMaxProfile; + (* maximum profile table, as defined by the TT Spec *) + + (* Note : *) + (* it seems that some maximum values cannot be *) + (* taken directly from this table, but rather by *) + (* combining some of its fields ( e.g. the max. *) + (* number of points seems to be given by *) + (* MAX( maxPoints, maxCompositePoints ) *) + (* *) + (* For this reason, we define later our own *) + (* max values that are used to load and allocate *) + (* further tables.. *) + + fontHeader : TT_Header; + (* the font header as defined by the TT Spec *) + + horizontalHeader : TT_Horizontal_Header; + (* the horizontal header, as defined in the spec *) + + verticalInfo : Boolean; + (* set to true when vertical data is in the font *) + + verticalHeader : TT_Vertical_Header; + (* vertical header table *) + + os2 : TT_OS2; + (* 'OS/2' table *) + + postscript : TT_Postscript; + (* 'Post' table *) + + hdmx : THdmx; + (* 'hdmx' = horizontal device metrics table *) + + nameTable : TName_Table; + (* 'name' = name table *) + + numTables : Int; + dirTables : PTableDirEntries; + (* The directory of the TrueType tables found in *) + (* this face's stream *) + + numCMaps : Int; + cMaps : PCMapTables; + (* the directory of character mappings tables found *) + (* for this face.. *) + + numLocations : Int; + glyphLocations : PStorage; + (* the glyph locations table *) + + (* the hmtx table is now within the horizontal header *) + + fontPgmSize : Int; + fontProgram : PByte; + (* the font program, if any.. *) + + cvtPgmSize : Int; + cvtProgram : PByte; + (* the cvt (or 'prep') program, if any.. *) + + cvtSize : Int; + cvt : PShort; + (* the original, unscaled, control value table *) + + gasp : TGasp; + + (* the following values must be set by the *) + (* maximum profile loader.. *) + + numGlyphs : Int; + (* the face's total number of glyphs *) + + maxPoints : Int; + (* max glyph points number, simple and composite *) + + maxContours : Int; + (* max glyph contours number, simple and composite *) + + maxComponents : Int; + (* max components in a composite glyph *) + + (* the following lists are used to track active *) + (* instance and context objects, as well as *) + (* to recycle them.. *) + + (* see 'TTLists'.. *) + + instances : TCache; + glyphs : TCache; + (* various caches for this face's child objects *) + + extension : Pointer; + (* a typeless pointer to the face object's extensions *) + + generic : Pointer; + (* generic pointer - see TT_Set/Get_Face_Pointer *) + end; + + (********************************************************************) + (* *) + (* FreeType Instance Object *) + (* *) + (********************************************************************) + + TInstance = record + + owner : PFace; + + valid : Boolean; + metrics : TIns_Metrics; + + numFDefs : Int; (* number of function defs *) + maxFDefs : Int; + FDefs : PDefArray; (* table of FDefs entries *) + + numIDefs : Int; (* number of instruction defs *) + maxIDefs : Int; + IDefs : PDefArray; (* table of IDefs entries *) + + maxFunc : Int; (* maximum function number *) + maxIns : Int; (* maximum instruction number *) + + codeRangeTable : TCodeRangeTable; + + GS : TGraphicsState; + + storeSize : Int; + storage : PStorage; + (* the storage area *) + + cvtSize : Int; + cvt : PLong; + (* the scaled control value table *) + + twilight : TGlyph_Zone; + (* the instance's twilight zone *) + + (* debugging variables *) + + debug : Boolean; + context : PExec_Context; + (* when using the debugger, we must keep the *) + (* execution context with the instance object *) + (* rather than asking it on demand *) + + generic : Pointer; + (* generic pointer - see TT_Set/Get_Instance_Pointer *) + end; + + (********************************************************************) + (* *) + (* FreeType Execution Context Object *) + (* *) + (********************************************************************) + + TExec_Context = record + + face : PFace; + instance : PInstance; + error : Int; + + stackSize : Int; (* size of instance stack *) + top : Int; (* top of instance stack *) + stack : PStorage; (* current instance stack *) + + args : Int; (* number of arguments in opcode *) + new_top : Int; (* new stack top after opc. exec *) + + zp0, + zp1, + zp2, + twilight, + pts : TGlyph_Zone; + + GS : TGraphicsState; + + curRange : Int; (* current code range number *) + code : PByte; (* current code range *) + IP : Int; (* current instruction pointer *) + codeSize : Int; (* size of current range *) + + opcode : Byte; (* current opcode *) + length : Int; (* length of current opcode *) + + step_ins : boolean; (* used by the interpreter *) + (* if true, go to the next *) + (* instruction.. *) + + loadSize : Int; + loadStack : PSubglyph_Stack; + (* the load stack used to load composite glyphs *) + + glyphIns : PByte; (* glyph instructions *) + glyphSize : Int; (* glyph ins. size *) + + callTop : Int; + callSize : Int; + callStack : PCallStack; (* interpreter call stack *) + + period, (* values used for the *) + phase, (* 'SuperRounding' *) + threshold : TT_F26dot6; + + maxPoints : Int; + maxContours : Int; + + (* the following are copies of the variables found *) + (* in an instance object *) + + numFDefs : Int; (* number of function defs *) + maxFDefs : Int; + FDefs : PDefArray; (* table of FDefs entries *) + + numIDefs : Int; (* number of instruction defs *) + maxIDefs : Int; + IDefs : PDefArray; (* table of IDefs entries *) + + maxFunc : Int; (* maximum function number *) + maxIns : Int; (* maximum instruction number *) + + codeRangeTable : TCodeRangeTable; + + storeSize : Int; (* size of current storage *) + storage : PStorage; (* storage area *) + + metrics : TIns_Metrics; + + cur_ppem : Int; + scale1 : Long; + scale2 : Long; + cached_metrics : Boolean; + +(* + numContours : Int; + endContours : PUShort; +*) + Instruction_Trap : Boolean; + (* used by the full-screen debugger. If set, the *) + (* interpreter will exit after executing one *) + (* opcode. Used to perform single-stepping.. *) + + is_composite : Boolean; + (* this flag is true when the glyph is a composite *) + (* one. In this case, we measure original distances *) + (* in the loaded coordinates (font units), then *) + (* scale them appropriately. This get rids of *) + (* transformation artifacts (like symetries..) *) + + cvtSize : Int; + cvt : PLong; + + (* these variables are proper to the context *) + + F_dot_P : Long; + (* the dot product of the free and projection *) + (* vector is used in frequent operations.. *) + + func_round : TRound_Function; + func_project : TProject_Function; + func_dualproj : TProject_Function; + func_freeProj : TProject_Function; + func_move : TMove_Function; + + func_read_cvt : TFunc_Get_CVT; + func_write_cvt : TFunc_Set_CVT; + func_move_cvt : TFunc_Set_CVT; + (* single width ? *) + + end; + + (********************************************************************) + (* *) + (* FreeType Glyph Object *) + (* *) + (********************************************************************) + + PGlyph = ^TGlyph; + TGlyph = record + face : PFace; + metrics : TT_Big_Glyph_Metrics; + outline : TT_Outline; + + (* temporary - debugging purposes *) + computed_width : Int; + precalc_width : Int; + is_composite : Boolean; + end; + + PFont_Input = ^TFont_Input; + TFont_Input = record + stream : TT_Stream; (* inpute stream *) + fontIndex : Int; (* index of font in collection *) + end; + + (****************************************************************) + (* *) + (* Code Range Functions *) + (* *) + (****************************************************************) + + function Goto_CodeRange( exec : PExec_Context; + range : Int; + IP : Int ) : TError; + (* Go to a specified coderange *) + + function Get_CodeRange( exec : PExec_Context; + range : Int ) : PCodeRange; + (* return a pointer to a given coderange record *) + (* used only by the debugger *) + + function Set_CodeRange( exec : PExec_Context; + range : Int; + base : Pointer; + length : Int ) : TError; + (* Set a given code range properties *) + + function Clear_CodeRange( exec : PExec_Context; + range : Int ) : TError; + (* Clear a given code range *) + + (****************************************************************) + (* *) + (* Management Functions *) + (* *) + (****************************************************************) + + function New_Context( instance : PInstance ) : PExec_Context; + (* Get a new execution context, either fresh or recycled, for *) + (* an instance of the face 'res' *) + (* *) + (* Notes : - called by 'New_Face_Context' *) + (* - assumes that the face mutex is acquired *) + + procedure Done_Context( exec : PExec_Context ); + (* Releases an execution context. The context can be destroyed *) + (* or recycled, depending on implementation *) + (* *) + (* Notes : - called by 'Done_Face_Context' *) + (* - assumes that the face mutex is acquired *) + + (****************************************************************) + (* *) + (* Instance Update Functions *) + (* *) + (****************************************************************) + + procedure Context_Load( exec : PExec_Context; + ins : PInstance ); + (* update exec's data with the one found in 'ins' *) + (* typically before an execution *) + + procedure Context_Save( exec : PExec_Context; + ins : PInstance ); + (* update ins's data with the one found in 'exec' *) + (* typically after an execution *) + + function Context_Run( exec : PExec_Context; + debug : Boolean ) : TError; + + function Instance_Init( ins : PInstance ) : TError; + + function Instance_Reset( ins : PInstance; + debug : boolean ) : TError; + + + function Scale_X( var metrics : TIns_Metrics; x : TT_Pos ) : TT_Pos; + + function Scale_Y( var metrics : TIns_Metrics; y : TT_Pos ) : TT_Pos; + + function TTObjs_Init : TError; + (* Initialize object manager *) + + procedure TTObjs_Done; + (* Finalize object manager *) + +var + face_cache : TCache; + exec_cache : TCache; + +implementation + +uses TTMemory, TTFile, TTCalc, TTLoad, TTInterp; + + function Face_Create( _face : Pointer; + _input : Pointer ) : TError; far; forward; + + function Face_Destroy( _face : Pointer ) : TError; far; forward; + + function Context_Create( _context : Pointer; + _face : Pointer ) : TError; far; forward; + + function Context_Destroy( exec : Pointer ) : TError; far; forward; + + function Instance_Create( _ins : Pointer; + _face : Pointer ) : TError; far; forward; + + function Instance_Destroy( instance : Pointer ) : TError; far; forward; + + function Glyph_Create( _glyph : Pointer; + _face : Pointer ) : TError; far; forward; + + function Glyph_Destroy( _glyph : Pointer ) : TError; far; forward; + + + +const + objs_face_class : TCache_Class + = (object_size: sizeof(TFace); + idle_limit : -1; + init : Face_Create; + done : Face_Destroy ); + + objs_exec_class : TCache_Class + = (object_size: sizeof(TExec_Context); + idle_limit : 1; + init : Context_Create; + done : Context_Destroy ); + + objs_instance_class : TCache_Class + = (object_size: sizeof(TInstance); + idle_limit : -1; + init : Instance_Create; + done : Instance_Destroy ); + + objs_glyph_class : TCache_Class + = (object_size: sizeof(TGlyph); + idle_limit : -1; + init : Glyph_Create; + done : Glyph_Destroy ); + +(******************************************************************* + * + * Function : New_Context + * + * Description : gets a new active execution context for a given + * resident/face object. + * + * Input : aResident + * + * Output : Returns new exec. context. Nil in case of failure + * + * Notes : Don't forget to modify 'Free_Context' if you change + * the fields of a TExec_Context + * + ******************************************************************) + + function New_Context( instance : PInstance ) : PExec_Context; + var + exec : PExec_Context; + begin + if instance = nil then + exec := nil + else + Cache_New( exec_cache, Pointer(exec), instance^.owner ); + + New_Context := exec; + end; + +(******************************************************************* + * + * Function : Done_Context + * + * Description : + * + * Input : aResident + * + * Output : Discards an active execution context when it + * becomes unuseful. It is putin its face's recycle + * list + * + ******************************************************************) + + procedure Done_Context( exec : PExec_Context ); + begin + if exec <> nil then + Cache_Done( exec_cache, Pointer(exec) ); + end; + +(******************************************************************* + * + * Function : New_Instance + * + * Description : gets a new active instance for a given + * face object. + * + * Input : face + * + * Output : Returns new instance. Nil in case of failure + * + ******************************************************************) + + function New_Instance( face : PFace ) : PInstance; + var + ins : PInstance; + begin + if face = nil then + ins := nil + else + Cache_New( face^.instances, Pointer(ins), face ); + + New_Instance := ins; + end; + +(******************************************************************* + * + * Function : Done_Instance + * + * Description : + * + * Input : instance + * + * Output : Discards an active instance when it + * becomes unuseful. It is put in its face's recycle + * list + * + ******************************************************************) + + procedure Done_Instance( instance : PInstance ); + begin + if instance <> nil then + Cache_Done( instance^.owner^.instances, Pointer(instance) ); + end; + + (****************************************************************) + (* *) + (* Code Range Functions *) + (* *) + (****************************************************************) + +(******************************************************************* + * + * Function : Goto_CodeRange + * + * Description : Switch to a new code range (updates Code and IP). + * + * Input : exec target execution context + * range new execution code range + * IP new IP in new code range + * + * Output : SUCCESS on success. FAILURE on error (no code range). + * + *****************************************************************) + + function Goto_CodeRange( exec : PExec_Context; + range : Int; + IP : Int ) : TError; + begin + Goto_CodeRange := Failure; + + if (range < 1) or (range > 3) then + begin + error := TT_Err_Bad_Argument; + exit; + end; + + with exec^.codeRangeTable[range] do + begin + + if base = nil then + begin + error := TT_Err_Invalid_CodeRange; + exit; + end; + + (* NOTE : Because the last instruction of a program may be a CALL *) + (* which will return to the first byte *after* the code *) + (* range, we test for IP <= Size, instead of IP < Size. *) + + if IP > size then + begin + error := TT_Err_Code_Overflow; + exit; + end; + + exec^.code := base; + exec^.codeSize := size; + exec^.IP := IP; + exec^.currange := range; + end; + + Goto_CodeRange := Success; + end; + +(******************************************************************* + * + * Function : Get_CodeRange + * + * Description : Returns a pointer to a given code range. Should + * be used only by the debugger. Returns NULL if + * 'range' is out of current bounds. + * + * Input : exec target execution context + * range new execution code range + * + * Output : Pointer to the code range record. NULL on failure. + * + *****************************************************************) + + function Get_CodeRange( exec : PExec_Context; + range : Int ) : PCodeRange; + begin + if (range < 1) or (range > 3) then + Get_CodeRange := nil + else + Get_CodeRange := @exec^.codeRangeTable[range]; + end; + +(******************************************************************* + * + * Function : Set_CodeRange + * + * Description : Sets a code range. + * + * Input : exec target execution context + * range code range index + * base new code base + * length sange size in bytes + * + * Output : SUCCESS on success. FAILURE on error. + * + *****************************************************************) + + function Set_CodeRange( exec : PExec_Context; + range : Int; + base : Pointer; + length : Int ) : TError; + begin + Set_CodeRange := Failure; + + if (range < 1) or (range > 3) then + begin + error := TT_Err_Invalid_CodeRange; + exit; + end; + + exec^.codeRangeTable[range].base := base; + exec^.codeRangeTable[range].size := length; + + Set_CodeRange := Success; + end; + +(******************************************************************* + * + * Function : Clear_CodeRange + * + * Description : clears a code range. + * + * Input : exec target execution context + * range code range index + * + * Output : SUCCESS on success. FAILURE on error. + * + * Notes : Does not set the Error variable. + * + *****************************************************************) + + function Clear_CodeRange( exec : PExec_Context; + range : Int ) : TError; + begin + Clear_CodeRange := Failure; + + if (range < 1) or (range > 3) then + begin + error := TT_Err_Invalid_CodeRange; + exit; + end; + + exec^.codeRangeTable[range].base := nil; + exec^.codeRangeTable[range].size := 0; + + Clear_CodeRange := Success; + end; + + + (****************************************************************) + (* *) + (* Management Functions *) + (* *) + (****************************************************************) + +(******************************************************************* + * + * Function : Context_Destroy + * + * Description : Frees an execution context + * + * Input : context : execution context + * + * Notes : Allocation is found in the 'New_Context' function + * + ******************************************************************) + + function Context_Destroy( exec : Pointer ) : TError; + begin + Context_Destroy := Success; + + if exec = nil then exit; + + with PExec_Context(exec)^ do + begin + (* Free contours array *) + Free( pts.conEnds ); + pts.n_contours := 0; + + Free( pts.cur ); + Free( pts.org ); + + Free( pts.flags ); + pts.n_points := 0; + + (* Free stack *) + Free( stack ); + stackSize := 0; + + (* Free call stack *) + Free( callStack ); + callSize := 0; + callTop := 0; + + (* Free composite load stack *) + Free( loadStack ); + + (* free glyph code range *) + Free( glyphIns ); + glyphSize := 0; + + instance := nil; + face := nil; + end; + end; + + +(******************************************************************* + * + * Function : Context_Create + * + * Description : Creates a new execution context + * + * Input : _context context record + * _face face record + * + ******************************************************************) + + function Context_Create( _context : Pointer; + _face : Pointer ) : TError; + var + n_points : Int; + n_twilight : Int; + + exec : PExec_Context; + label + Fail_Memory; + begin + Context_Create := Failure; + + exec := PExec_Context(_context); + exec^.face := PFace(_face); + + with exec^ do + begin + + callSize := 32; + loadSize := face^.maxComponents + 1; + storeSize := face^.MaxProfile.maxStorage; + stackSize := face^.MaxProfile.maxStackElements + 32; + (* Allocate a little extra for broken fonts like Courbs.ttf *) + (* and Timesbs.ttf *) + + n_points := face^.maxPoints + 2; + + (* Reserve glyph code range *) + if Alloc( glyphIns, face^.MaxProfile.maxSizeOfInstructions ) or + + (* Reserve call stack *) + Alloc( callStack, callSize*sizeof(TCallRecord) ) or + + (* Reserve stack *) + Alloc( stack, stackSize*sizeof(Long) ) then + + (* we don't reserve the points and contours arrays anymore *) + (* as this will be performed automatically by a Context_Load *) + + (* the same is true for the load stack *) + + goto Fail_Memory; + + maxPoints := 0; + maxContours := 0; + + loadSize := 0; + loadStack := nil; + + pts.n_points := 0; + pts.n_contours := 0; + + instance := nil; + end; + + Context_Create := Success; + exit; + + Fail_Memory: + Context_Destroy(_context); + error := TT_Err_Out_Of_Memory; + exit; + end; + +(******************************************************************* + * + * Function : Context_Run + * + * Description : Run a glyph's bytecode stream + * + * Input : exec context record + * + ******************************************************************) + + function Context_Run( exec : PExec_Context; + debug : Boolean ) : TError; + begin + Context_Run := Failure; + + if Goto_CodeRange( exec, TT_CodeRange_Glyph, 0 ) then + exit; + + with exec^ do + begin + top := 0; + callTop := 0; + zp0 := pts; + zp1 := pts; + zp2 := pts; + GS.gep0 := 1; + GS.gep1 := 1; + GS.gep2 := 1; + + GS.projVector.x := $4000; + GS.projVector.y := $0000; + GS.freeVector := GS.projVector; + GS.dualVector := GS.projVector; + GS.round_state := 1; + GS.loop := 1; + end; + + if not debug and Run_Ins( @exec^ ) then + begin + error := exec^.error; + exit; + end; + + Context_Run := Success; + end; + +(****************************************************************) +(* *) +(* Instance Update Functions *) +(* *) +(****************************************************************) + +(******************************************************************* + * + * Function : Context_Load + * + * Description : loads instance data into a new execution context + * + *******************************************************************) + + procedure Context_Load( exec : PExec_Context; + ins : PInstance ); + + procedure Update_Max( var size : Int; + mult : Int; + var buff; + new_max : Int ); + begin + if size*mult < new_max then + begin + Free(buff); + Alloc( buff, new_max*mult ); + size := new_max; + end; + end; + + + procedure Update_Points( max_points : Int; + max_contours : Int; + exec : PExec_Context ); + begin + if exec^.maxPoints < max_points then + begin + Free( exec^.pts.org ); + Free( exec^.pts.cur ); + Free( exec^.pts.flags ); + + Alloc( exec^.pts.org, 2*sizeof(TT_F26dot6)*max_points ); + Alloc( exec^.pts.cur, 2*sizeof(TT_F26dot6)*max_points ); + Alloc( exec^.pts.flags, sizeof(Byte) *max_points ); + + exec^.maxPoints := max_points; + end; + + if exec^.maxContours < max_contours then + begin + Free( exec^.pts.conEnds ); + Alloc( exec^.pts.conEnds, sizeof(Short)*max_contours ); + exec^.maxContours := max_contours; + end; + end; + + + begin + with exec^ do + begin + + instance := ins; + face := ins^.owner; + + numFDefs := ins^.numFDefs; + numIDefs := ins^.numIDefs; + maxFDefs := ins^.maxFDefs; + maxIDefs := ins^.maxIDefs; + FDefs := ins^.FDefs; + IDefs := ins^.IDefs; + maxFunc := ins^.maxFunc; + maxIns := ins^.maxIns; + + metrics := ins^.metrics; + + codeRangeTable := ins^.codeRangeTable; + + storeSize := ins^.storeSize; + storage := ins^.storage; + + twilight := ins^.twilight; + + (* We reserve some extra space to deal with broken fonts *) + (* like Arial BS, Courier BS, etc.. *) + Update_Max( stackSize, + sizeof(Long), + stack, + face^.maxProfile.maxStackElements+32 ); + + Update_Max( loadSize, + sizeof(TSubglyph_Record), + loadStack, + face^.maxComponents+1 ); + + Update_Max( glyphSize, + sizeof(Byte), + glyphIns, + face^.maxProfile.maxSizeOfInstructions ); + + (* XXXX : Don't forget the phantom points !! *) + Update_Points( face^.maxPoints+2, face^.maxContours, exec ); + + pts.n_points := 0; + pts.n_contours := 0; + + instruction_trap := false; + + (* Set default graphics state *) + GS := ins^.GS; + + cvtSize := ins^.cvtSize; + cvt := ins^.cvt; + end; + end; + + + procedure Context_Save( exec : PExec_Context; + ins : PInstance ); + begin + with ins^ do + begin + error := exec^.error; + + numFDefs := exec^.numFDefs; + numIDefs := exec^.numIDefs; + maxFunc := exec^.maxFunc; + maxIns := exec^.maxIns; + + codeRangeTable := exec^.codeRangeTable; + + (* Set default graphics state *) + + GS := exec^.GS; + end; + end; + +(******************************************************************* + * + * Function : Instance_Destroy + * + * Description : The Instance Record destructor. + * + *****************************************************************) + + function Instance_Destroy( instance : Pointer ) : TError; + var + ins : PInstance; + begin + + Instance_Destroy := Success; + + ins := PInstance(instance); + if ins = nil then + exit; + + with ins^ do + begin + + if debug then + begin + context := nil; + debug := false; + end; + + (* Free twilight zone *) + Free( twilight.org ); + Free( twilight.cur ); + Free( twilight.flags ); + twilight.n_points := 0; + + Free( cvt ); + cvtSize := 0; + + Free( storage ); + storeSize := 0; + + Free( FDefs ); + Free( IDefs ); + numFDefs := 0; + numIDefs := 0; + maxFDefs := 0; + maxIDefs := 0; + + owner := nil; + valid := false; + + end; + end; + +(******************************************************************* + * + * Function : Instance_Create + * + * Description : The Instance constructor. + * + * This functions creates a new instance object for a given face + * + *****************************************************************) + + function Instance_Create( _ins : Pointer; + _face : Pointer ) : TError; + label + Fail_Memory; + var + l : Longint; + ins : PInstance; + face : PFace; + + n_twilight : Int; + begin + Instance_Create := Failure; + + {$IFDEF ASSERT} + if (_face = nil) then + Panic1('TTInst.Init_Instance : void argument' ); + {$ENDIF} + + face := PFace(_face); + ins := PInstance(_ins); + + ins^.owner := face; + + with face^, ins^ do + begin + + (* Reserve function and instruction defs arrays *) + maxFDefs := maxProfile.maxFunctionDefs; + maxIDefs := maxProfile.maxInstructionDefs; + storeSize := maxProfile.maxStorage; + n_twilight := maxProfile.maxTwilightPoints; + + if Alloc( FDefs, maxFDefs * sizeof(TDefRecord) ) or + Alloc( IDefs, maxIDefs * sizeof(TDefRecord) ) or + Alloc( storage, storeSize * sizeof(Long) ) or + + Alloc( twilight.org, 2* n_twilight * sizeof(TT_F26Dot6) ) or + Alloc( twilight.cur, 2* n_twilight * sizeof(TT_F26Dot6) ) or + Alloc( twilight.flags, n_twilight ) + + then goto Fail_Memory; + + twilight.n_points := n_twilight; + + metrics.x_resolution := 96; + metrics.y_resolution := 96; + metrics.pointSize := 10; + metrics.x_scale2 := 1; + metrics.y_scale2 := 1; + metrics.scale2 := 1; + + { Reserve Control Value Table } + cvtSize := face^.cvtSize; + + if Alloc( cvt, cvtSize * sizeof(Long) ) then + goto Fail_Memory; + + end; + + Instance_Create := Success; + exit; + + Fail_Memory: + Instance_Destroy(ins); + (* free all partially allocated tables, including the instance record *) + + error := TT_Err_Out_Of_Memory; + exit; + end; + + +(******************************************************************* + * + * Function : Instance_Init + * + * Description : Initializes a fresh new instance + * Executes the font program if any is found + * + * Input : ins the instance object to initialise + * + *****************************************************************) + + function Instance_Init( ins : PInstance ) : TError; + var + exec : PExec_Context; + face : PFace; + label + Fin; + begin + Instance_Init := Failure; + + face := ins^.owner; + + if ins^.debug then + exec := ins^.context + else + exec := New_Context( ins ); + (* debugging instances have their own context *) + + if exec = nil then + begin + error := TT_Err_Could_Not_Find_Context; + exit; + end; + + with ins^ do begin + GS := Default_GraphicsState; + numFDefs := 0; + numIDefs := 0; + maxFunc := -1; + maxIns := -1; + end; + + Context_Load( exec, ins ); + + with exec^ do + begin + callTop := 0; + top := 0; + period := 64; + phase := 0; + threshold := 0; + + with metrics do + begin + x_ppem := 10; + y_ppem := 10; + pointSize := 10; + x_scale1 := 0; + x_scale2 := 1; + y_scale1 := 0; + y_scale2 := 1; + + scale1 := 0; + scale2 := 1; + ratio := 1 shl 16; + end; + + instruction_trap := false; + + cvtSize := ins^.cvtSize; + cvt := ins^.cvt; + + F_dot_P := $10000; + end; + + Set_CodeRange( exec, + TT_CodeRange_Font, + face^.fontProgram, + face^.fontPgmSize ); + (* Allow font program execution *) + + Clear_CodeRange( exec, TT_CodeRange_Cvt ); + Clear_CodeRange( exec, TT_CodeRange_Glyph ); + (* disable CVT and glyph programs coderanges *) + + if face^.fontPgmSize > 0 then + begin + if Goto_CodeRange( exec, TT_CodeRange_Font, 0 ) then + goto Fin; + + if Run_Ins( @exec^ ) then + begin + error := exec^.error; + goto Fin; + end; + end; + + Instance_Init := Success; + + Fin: + Context_Save( exec, ins ); + + if not ins^.debug then + Done_Context( exec ); + + ins^.valid := False; + end; + +(******************************************************************* + * + * Function : Instance_Reset + * + * Description : Reset an instance to a new pointsize + * Executes the prep/cvt program if any is found + * + * Input : ins the instance object to initialise + * + *****************************************************************) + + function Instance_Reset( ins : PInstance; + debug : boolean ) : TError; + var + exec : PExec_Context; + face : PFace; + i : Int; + label + Fin; + begin + Instance_Reset := Failure; + + if ins^.valid then + begin + Instance_Reset := Success; + exit; + end; + + face := ins^.owner; + + (* compute new transform *) + + with ins^.metrics do + begin + + if x_ppem < 1 then x_ppem := 1; + if y_ppem < 1 then y_ppem := 1; + + if x_ppem >= y_ppem then + begin + scale1 := x_scale1; + scale2 := x_scale2; + ppem := x_ppem; + x_ratio := 1 shl 16; + y_ratio := MulDiv_Round( y_ppem, $10000, x_ppem ); + end + else + begin + scale1 := y_scale1; + scale2 := y_scale2; + ppem := y_ppem; + x_ratio := MulDiv_Round( x_ppem, $10000, y_ppem ); + y_ratio := 1 shl 16 + end; + end; + + (* scale the cvt values to the new ppem *) + + for i := 0 to ins^.cvtSize-1 do + ins^.cvt^[i] := MulDiv_Round( ins^.owner^.cvt^[i], + ins^.metrics.scale1, + ins^.metrics.scale2 ); + + (* Note that we use the y resolution by default to scale the cvt *) + + ins^.GS := Default_GraphicsState; + + if ins^.debug then + exec := ins^.context + else + exec := New_Context(ins); + + if exec = nil then + begin + error := TT_Err_Could_Not_Find_Context; + exit; + end; + + Context_Load( exec, ins ); + + Set_CodeRange( exec, + TT_CodeRange_CVT, + face^.cvtProgram, + face^.cvtPgmSize ); + + Clear_CodeRange( exec, TT_CodeRange_Glyph ); + + with exec^ do + begin + + for i := 0 to storeSize-1 do + storage^[i] := 0; + + instruction_trap := False; + + top := 0; + callTop := 0; + + (* all twilight points are originally zero *) + for i := 0 to twilight.n_points-1 do + begin + twilight.org^[i].x := 0; + twilight.org^[i].y := 0; + twilight.cur^[i].x := 0; + twilight.cur^[i].y := 0; + end; + end; + + if face^.cvtPgmSize > 0 then + if Goto_CodeRange( exec, TT_CodeRange_CVT, 0 ) or + ( (not debug) and Run_Ins( @exec^ ) ) then + goto Fin; + + ins^.GS := exec^.GS; + Instance_Reset := Success; + + Fin: + Context_Save( exec, ins ); + + if not ins^.debug then + Done_Context(exec); + + if error = 0 then + ins^.valid := True; + end; + + +(******************************************************************* + * + * Function : Face_Destroy + * + * Description : The face object destructor + * + *****************************************************************) + + function Face_Destroy( _face : Pointer ) : TError; + var + face : PFace; + n : Int; + begin + Face_Destroy := Success; + + face := PFace(_face); + if face = nil then exit; + + Cache_Destroy( face^.instances ); + Cache_Destroy( face^.glyphs ); + + (* freeing the tables directory *) + Free( face^.dirTables ); + face^.numTables := 0; + + (* freeing the locations table *) + Free( face^.glyphLocations ); + face^.numLocations := 0; + + (* freeing the character mapping tables *) + for n := 0 to face^.numCMaps-1 do + CharMap_Free( face^.cMaps^[n] ); + + Free( face^.cMaps ); + face^.numCMaps := 0; + + (* freeing the CVT *) + Free( face^.cvt ); + face^.cvtSize := 0; + + (* freeing the horizontal header *) + Free( face^.horizontalHeader.short_metrics ); + Free( face^.horizontalHeader.long_metrics ); + if face^.verticalInfo then + begin + Free( face^.verticalHeader.short_metrics ); + Free( face^.verticalHeader.long_metrics ); + face^.verticalInfo := False; + end; + + (* freeing the programs *) + Free( face^.fontProgram ); + Free( face^.cvtProgram ); + face^.fontPgmSize := 0; + face^.cvtPgmSize := 0; + + (* freeing the gasp table - none yet *) + Free( face^.gasp.gaspRanges ); + + (* freeing the names table *) + Free( face^.nameTable.names ); + Free( face^.nameTable.storage ); + face^.nameTable.numNameRecords := 0; + face^.nameTable.format := 0; + + (* freeing the hdmx table *) + for n := 0 to face^.hdmx.num_records-1 do + Free( face^.hdmx.records^[n].widths ); + + Free( face^.hdmx.records ); + face^.hdmx.num_records := 0; + + TT_Close_Stream( face^.stream ); + end; + +(******************************************************************* + * + * Function : Face_Create + * + * Description : The face object constructor + * + *****************************************************************) + + function Face_Create( _face : Pointer; + _input : Pointer ) : TError; + var + input : PFont_Input; + face : PFace; + label + Fail; + begin + Face_Create := Failure; + + face := PFace(_face); + input := PFont_Input(_input); + + face^.stream := input^.stream; + + if Cache_Create( objs_instance_class, face^.instances ) or + Cache_Create( objs_glyph_class, face^.glyphs ) then exit; + + (* Load collection directory if present *) + if Load_TrueType_Directory( face, input^.fontIndex ) then + exit; + + if Load_TrueType_Header ( face ) or + Load_TrueType_MaxProfile ( face ) or + Load_TrueType_Locations ( face ) or + Load_TrueType_CMap ( face ) or + Load_TrueType_CVT ( face ) or + Load_TrueType_Metrics_Header ( face, false ) or + Load_TrueType_Programs ( face ) or + Load_TrueType_Gasp ( face ) or + Load_TrueType_Names ( face ) or + Load_TrueType_OS2 ( face ) or + Load_TrueType_Hdmx ( face ) or + Load_TrueType_Postscript ( face ) or + Load_TrueType_Metrics_Header ( face, true ) then + goto Fail; + + Face_Create := Success; + exit; + + Fail: + Face_Destroy( face ); + end; + + + function Glyph_Destroy( _glyph : Pointer ) : TError; + var + glyph : PGlyph; + begin + Glyph_Destroy := Success; + + glyph := PGlyph(_glyph); + if glyph = nil then + exit; + + glyph^.outline.owner := true; + TT_Done_Outline( glyph^.outline ); + end; + + + function Glyph_Create( _glyph : Pointer; + _face : Pointer ) : TError; + var + glyph : PGlyph; + begin + glyph := PGlyph(_glyph); + + glyph^.face := PFace(_face); + error := TT_New_Outline( glyph^.face^.maxPoints+2, + glyph^.face^.maxContours, + glyph^.outline ); + if error <> TT_Err_Ok then + Glyph_Create := Failure + else + Glyph_Create := Success; + end; + + + + function Scale_X( var metrics : TIns_Metrics; x : TT_Pos ) : TT_Pos; + begin + Scale_X := MulDiv_Round( x, metrics.x_scale1, metrics.x_scale2 ); + end; + + + + function Scale_Y( var metrics : TIns_Metrics; y : TT_Pos ) : TT_Pos; + begin + Scale_Y := MulDiv_Round( y, metrics.y_scale1, metrics.y_scale2 ); + end; + + + + function TTObjs_Init : TError; + begin + TTObjs_Init := Failure; + + Cache_Create( objs_face_class, face_cache ); + Cache_Create( objs_exec_class, exec_cache ); + + TTObjs_Init := success; + end; + + + + procedure TTObjs_Done; + begin + Cache_Destroy( face_cache ); + Cache_Destroy( exec_cache ); + end; + +end. + diff --git a/pascal/lib/ttraster.pas b/pascal/lib/ttraster.pas new file mode 100644 index 0000000..9f17ca2 --- /dev/null +++ b/pascal/lib/ttraster.pas @@ -0,0 +1,3445 @@ +(******************************************************************* + * + * TTRaster.Pas v 1.2 + * + * The FreeType glyph rasterizer. + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTES : This version supports the following : + * + * - direct grayscaling + * - sub-banding + * - drop-out modes 4 and 5 + * - second pass for complete drop-out control ( bitmap only ) + * - variable precision + * + * Re-entrancy is _not_ planned. + * + * Changes between 1.1 and 1.2 : + * + * - no more trace tables, now uses linked list to sort + * coordinates. + * + * - reduced code size using function dispatch within a generic + * draw_sweep function. + * + * - added variable precision for finer rendering at small ppems + * + * + * Note that its interface may change in the future. + * + ******************************************************************) + +Unit TTRASTER; + +interface + +{$I TTCONFIG.INC} + +{ $DEFINE TURNS} + +uses +{$IFDEF VIRTUALPASCAL} + Use32, +{$ENDIF} + FreeType, + TTTypes; + +const + + Err_Ras_None = 0; + Err_Ras_NotIni = -2; (* Rasterizer not Initialized *) + Err_Ras_Overflow = -3; (* Profile Table Overflow *) + Err_Ras_Neg_H = -4; (* Negative Height encountered ! *) + Err_Ras_Invalid = -5; (* Invalid value encountered ! *) + Err_Ras_Invalid_Contours = -6; + + function Render_Glyph( var glyph : TT_Outline; + var target : TT_Raster_Map ) : TError; + + (* Render one glyph in the target bitmap, using drop-out control *) + (* mode 'scan' *) + + function Render_Gray_Glyph( var glyph : TT_Outline; + var target : TT_Raster_Map ) : TError; + + (* Render one gray-level glyph in the target pixmap *) + (* palette points to an array of 5 colors used for the rendering *) + (* use nil to reuse the last palette. Default is VGA graylevels *) + +{$IFDEF SMOOTH} + function Render_Smooth_Glyph( var glyph : TGlyphRecord; + target : PRasterBlock; + scan : Byte; + palette : pointer ) : boolean; +{$ENDIF} + + procedure Set_High_Precision( High : boolean ); + (* Set rendering precision. Should be set to TRUE for small sizes only *) + (* ( typically < 20 ppem ) *) + + procedure Set_Second_Pass( Pass : boolean ); + (* Set second pass flag *) + + function TTRaster_Init : TError; + procedure TTRaster_Done; + +implementation + +uses + TTCalc, { used for MulDiv } + TTError +{$IFDEF DEBUG} + ,GMain { Used to access VRAM pointer VIO during DEBUG } +{$ENDIF} + ; + + +{$DEFINE NO_ASM} + +const + Render_Pool_Size = 64000; + Gray_Lines_Size = 2048; + + MaxBezier = 32; (* Maximum number of stacked B‚ziers. *) + (* Setting this constant to more than 32 *) + (* is a pure waste of space *) + + Pixel_Bits = 6; (* fractional bits of input coordinates *) + + Cell_Bits = 8; + +type + + TEtats = ( Indetermine, Ascendant, Descendant, Plat ); + + PProfile = ^TProfile; + TProfile = record + Flow : Int; (* ascending or descending Profile *) + Height : Int; (* Profile's height in scanlines *) + Start : Int; (* Profile's starting scanline *) + Offset : ULong; (* offset of first coordinate in *) + (* render pool *) + + Link : PProfile; (* link used in several cases *) + + X : Longint; (* current coordinate during sweep *) + CountL : Int; (* number of lines to step before *) + (* this Profile becomes drawable *) + + next : PProfile; (* next Profile of the same contour *) + end; + + TBand = record + Y_Min : Int; + Y_Max : Int; + end; + + (* Simple record used to implement a stack of bands, required *) + (* by the sub-banding mechanism *) + +const + AlignProfileSize = ( sizeOf(TProfile) + 3 ) div 4; + (* You may need to compute this according to your prefered alignement *) + + LMask : array[0..7] of Byte + = ($FF,$7F,$3F,$1F,$0F,$07,$03,$01); + + RMask : array[0..7] of Byte + = ($80,$C0,$E0,$F0,$F8,$FC,$FE,$FF); + + (* left and right fill bitmasks *) + +type + Function_Sweep_Init = procedure( var min, max : Int ); + + Function_Sweep_Span = procedure( y : Int; + x1 : TT_F26dot6; + x2 : TT_F26dot6; + Left : PProfile; + Right : PProfile ); + + Function_Sweep_Step = procedure; + + (* prototypes used for sweep function dispatch *) + + TPoint = record x, y : long; end; + + TBezierStack = array[0..32*2] of TPoint; + PBezierStack = ^TBezierStack; + +{$IFNDEF CONST_PREC} + +var + Precision_Bits : Int; (* Fractional bits of Raster coordinates *) + Precision : Int; + Precision_Half : Int; + Precision_Step : Int; (* Bezier subdivision minimal step *) + Precision_Shift : Int; (* Shift used to convert coordinates *) + Precision_Mask : Longint; (* integer truncatoin mask *) + Precision_Jitter : Int; + +{$ELSE} + +const + Precision_Bits = 6; + Precision = 1 shl Precision_Bits; + Precision_Half = Precision div 2; + Precision_Step = Precision_Half; + Precision_Shift = 0; + Precision_Mask = -Precision; + Precision_Jitter = 2; + +{$ENDIF} + +var + Scale_Shift : Int; + + cProfile : PProfile; (* current Profile *) + fProfile : PProfile; (* head of Profiles linked list *) + oProfile : PProfile; (* old Profile *) + gProfile : PProfile; (* last Profile in case of impact *) + + nProfs : Int; (* current number of Profiles *) + + Etat : TEtats; (* State of current trace *) + + Fresh : Boolean; (* Indicates a new Profile which 'Start' field *) + (* must be set *) + + Joint : Boolean; (* Indicates that the last arc stopped sharp *) + (* on a scan-line. Important to get rid of *) + (* doublets *) + + Buff : PStorage; (* Profiles buffer a.k.a. Render Pool *) + SizeBuff : ULong; (* current render pool's size *) + MaxBuff : ULong; (* current render pool's top *) + profCur : ULong; (* current render pool cursor *) + + Cible : TT_Raster_Map; (* Description of target map *) + + BWidth : integer; + BCible : PByte; (* target bitmap buffer *) + GCible : PByte; (* target pixmap buffer *) + + TraceOfs : Int; (* current offset in target bitmap *) + TraceIncr : Int; (* increment to next line in target map *) + TraceG : Int; (* current offset in targer pixmap *) + + gray_min_x : Int; (* current min x during gray rendering *) + gray_max_x : Int; (* current max x during gray rendering *) + + (* Dispatch variables : *) + + Proc_Sweep_Init : Function_Sweep_Init; (* Sweep initialisation *) + Proc_Sweep_Span : Function_Sweep_Span; (* Span drawing *) + Proc_Sweep_Drop : Function_Sweep_Span; (* Drop out control *) + Proc_Sweep_Step : Function_Sweep_Step; (* Sweep line step *) + + Arcs : TBezierStack; + CurArc : Int; (* stack's top *) + + Points : TT_Points; + + Flags : PByte; (* current flags array *) + Outs : TT_PConStarts; (* current endpoints array *) + + nPoints, (* current number of points *) + nContours : Int; (* current number of contours *) + + LastX, (* Last and extrema coordinates during *) + LastY, (* rendering *) + MinY, + MaxY : LongInt; + +{$IFDEF TURNS} + numTurns : Int; +{$ENDIF} + + DropOutControl : Byte; (* current drop-out control mode *) + + Count_Table : array[0..255] of Word; + (* Look-up table used to quickly count set bits in a gray 2x2 cell *) + + Count_Table2 : array[0..255] of Word; + (* Look-up table used to quickly count set bits in a gray 2x2 cell *) + + Grays : array[0..4] of Byte; + (* gray palette used during gray-levels rendering *) + (* 0 : background .. 4 : foreground *) + + Gray_Lines : PByte; { 2 intermediate bitmap lines } + Gray_Width : integer; { width of the 'gray' lines in pixels } + +{$IFDEF SMOOTH} + Smooth_Cols : integer; + Smooths : array[0..16] of Byte; + (* smooth palette used during smooth-levels rendering *) + (* 0 : background...16 : foreground *) + + smooth_pass : integer; +{$ENDIF} + + Second_Pass : boolean; + (* indicates wether an horizontal pass should be performed *) + (* to control drop-out accurately when calling Render_Glyph *) + (* Note that there is no horizontal pass during gray render *) + + (* better set it off at ppem >= 18 *) + + Band_Stack : array[1..16] of TBand; + Band_Top : Int; + + + +{$IFDEF DEBUG3} +(****************************************************************************) +(* *) +(* Function: Pset *) +(* *) +(* Description: Used only in the "DEBUG3" state. *) +(* *) +(* This procedure simply plots a point on the video screen *) +(* Note that it relies on the value of cProfile->start, *) +(* which may sometimes not be set yet when Pset is called. *) +(* This will usually result in a dot plotted on the first *) +(* screen scanline ( far away its original position ). *) +(* *) +(* This "bug" means not that the current implementation is *) +(* buggy, as the bitmap will be rendered correctly, so don't *) +(* panic if you see 'flying' dots in debugging mode *) +(* *) +(* *) +(* Input: None *) +(* *) +(* Returns: Nada *) +(* *) +(****************************************************************************) + +procedure PSet; +var c : byte; + o : Int; + xz : LongInt; +begin + xz := Buff^[profCur] div Precision; + + with cProfile^ do + begin + + case Flow of + TT_Flow_Up : o := 80 * (profCur-Offset+Start) + xz div 8; + TT_Flow_Down : o := 80 * (Start-profCur+offset) + xz div 8; + end; + + if o > 0 then + begin + c := Vio^[o] or ( $80 shr ( xz and 7 )); + Vio^[o] := c; + end + end; +end; + +(****************************************************************************) +(* *) +(* Function: Clear_Band *) +(* *) +(* Description: Clears a Band on screen during DEBUG3 rendering *) +(* *) +(* Input: y1, y2 top and bottom of screen-wide band *) +(* *) +(* Returns: Nada. *) +(* *) +(****************************************************************************) + +procedure ClearBand( y1, y2 : Int ); +var + Y : Int; + K : Word; +begin + K := y1*80; + FillChar( Vio^[k], (y2-y1+1)*80, 0 ); +end; +{$ENDIF} + +{$IFNDEF CONST_PREC} + +(****************************************************************************) +(* *) +(* Function: Set_High_Precision *) +(* *) +(* Description: Sets precision variables according to param flag *) +(* *) +(* Input: High set to True for high precision ( typically for *) +(* ppem < 18 ), false otherwise. *) +(* *) +(****************************************************************************) + +procedure Set_High_Precision( High : boolean ); +begin + if High then + begin + Precision_Bits := 10; + Precision_Step := 128; + Precision_Jitter := 24; + end + else + begin + Precision_Bits := 6; + Precision_Step := 32; + Precision_Jitter := 2; + end; + + Precision := 1 shl Precision_Bits; + Precision_Half := Precision shr 1; + Precision_Shift := Precision_Bits - Pixel_Bits; + Precision_Mask := -Precision; +end; + +{$ENDIF} + +procedure Set_Second_Pass( Pass : boolean ); +begin + second_pass := pass; +end; + + +function TRUNC( x : Long ) : Long; {$IFDEF INLINE} inline; {$ENDIF} +begin + Trunc := (x and -Precision) div Precision; +end; + +function FRAC( x : Long ) : Int; {$IFDEF INLINE} inline; {$ENDIF} +begin + Frac := x and (Precision-1); +end; + +function FLOOR( x : Long ) : Long; {$IFDEF INLINE} inline; {$ENDIF} +begin + Floor := x and -Precision; +end; + +function CEILING( x : Long ) : Long; {$IFDEF INLINE} inline; {$ENDIF} +begin + Ceiling := (x + Precision-1) and -Precision; +end; + +function SCALED( x : Long ) : Long; {$IFDEF INLINE} inline; {$ENDIF} +begin + SCALED := (x shl scale_shift) - precision_half; +end; + +{$IFDEF USE32} (* speed things a bit on 32-bit systems *) +function MulDiv( a, b, c : Long ) : Long; {$IFDEF INLINE} inline; {$ENDIF} +begin + MulDiv := a*b div c; +end; +{$ENDIF} + +(****************************************************************************) +(* *) +(* Function: New_Profile *) +(* *) +(* Description: Creates a new Profile in the render pool *) +(* *) +(* Input: AEtat state/orientation of the new Profile *) +(* *) +(* Returns: True on sucess *) +(* False in case of overflow or of incoherent Profile *) +(* *) +(****************************************************************************) + +function New_Profile( AEtat : TEtats ) : boolean; +begin + + if fProfile = NIL then + begin + cProfile := PProfile( @Buff^[profCur] ); + fProfile := cProfile; + inc( profCur, AlignProfileSize ); + end; + + if profCur >= MaxBuff then + begin + Error := Err_Ras_Overflow; + New_Profile := False; + exit; + end; + + with cProfile^ do + begin + + Case AEtat of + + Ascendant : Flow := TT_Flow_Up; + Descendant : Flow := TT_Flow_Down; + else +{$IFDEF DEBUG} + Writeln('ERROR : Incoherent Profile' ); + Halt(30); +{$ELSE} + New_Profile := False; + Error := Err_Ras_Invalid; + exit; +{$ENDIF} + end; + + Start := 0; + Height := 0; + Offset := profCur; + Link := nil; + next := nil; + end; + + if gProfile = nil then gProfile := cProfile; + + Etat := AEtat; + Fresh := True; + Joint := False; + + New_Profile := True; +end; + +{$IFDEF TURNS} +(****************************************************************************) +(* *) +(* Function: Insert_Y_Turn *) +(* *) +(* Description: Insert a slaient into the sorted list *) +(* *) +(* Input: new y turn *) +(* *) +(****************************************************************************) + +procedure Insert_Y_Turn( y : Int ); +var + y_turns : PStorage; + y2, n : Int; +begin + n := numTurns-1; + y_turns := @Buff^[SizeBuff-numTurns]; + + (* look for first y value that is <= *) + while (n >= 0) and (y < y_turns^[n]) do dec(n); + + (* if it is <, simply insert it, ignor if we found one == *) + + if (n >= 0) and (y > y_turns^[n]) then + while (n >= 0) do + begin + y2 := y_turns^[n]; + y_turns^[n] := y; + y := y2; + dec( n ); + end; + + if (n < 0) then + begin + dec( MaxBuff ); + inc( numTurns ); + Buff^[SizeBuff-numTurns] := y; + end +end; +{$ENDIF} + + +(****************************************************************************) +(* *) +(* Function: End_Profile *) +(* *) +(* Description: Finalizes the current Profile. *) +(* *) +(* Input: None *) +(* *) +(* Returns: True on success *) +(* False on overflow or incoherency. *) +(* *) +(****************************************************************************) + +function End_Profile : boolean; +var + H : Int; + oldProfile : PProfile; +begin + H := profCur - cProfile^.Offset; + + if H < 0 then + begin + End_Profile := False; + Error := Err_Ras_Neg_H; + exit; + end; + + if H > 0 then + begin + oldProfile := cProfile; + cProfile^.Height := H; + cProfile := PProfile( @Buff^[profCur] ); + + inc( profCur, AlignProfileSize ); + + cProfile^.Height := 0; + cProfile^.Offset := profCur; + oldProfile^.next := cProfile; + inc( nProfs ); + end; + + if profCur >= MaxBuff then + begin + End_Profile := False; + Error := Err_Ras_Overflow; + exit; + end; + + Joint := False; + + End_Profile := True; +end; + +(****************************************************************************) +(* *) +(* Function: Finalize_Profile_Table *) +(* *) +(* Description: Adjusts all links in the Profiles list *) +(* *) +(* Input: None *) +(* *) +(* Returns: Nada *) +(* *) +(****************************************************************************) + +procedure Finalize_Profile_Table; +var + n : int; + p : PProfile; + + Bottom, Top : Int; +begin + + n := nProfs; + + if n > 1 then + begin + + P := fProfile; + + while n > 0 do with P^ do + begin + if n > 1 then + Link := PProfile( @Buff^[ Offset + Height ] ) + else + Link := nil; + + with P^ do + Case Flow of + + TT_Flow_Up : begin + Bottom := Start; + Top := Start+Height-1; + end; + + TT_Flow_Down : begin + Bottom := Start-Height+1; + Top := Start; + + Start := Bottom; + Offset := Offset+Height-1; + end; + end; +{$IFDEF TURNS} + Insert_Y_Turn( Bottom ); + Insert_Y_Turn( Top+1 ); +{$ENDIF} + P := Link; + + dec( n ); + end; + end + else + fProfile := nil; + +end; + +(****************************************************************************) +(* *) +(* Function: Split_Bezier *) +(* *) +(* Description: Subdivises one Bezier arc into two joint *) +(* sub-arcs in the Bezier stack. *) +(* *) +(* Input: None ( subdivised bezier is taken from the top of the *) +(* stack ) *) +(* *) +(* Returns: Nada *) +(* *) +(****************************************************************************) + +procedure Split_Bezier( base : PBezierStack ); +var + arc : PBezierStack; + a, b : Long; +begin +{$IFNDEF NO_ASM} + asm + push esi + push ebx + push ecx + + mov esi, base + + mov eax, [esi+2*8] (* arc^[4].x := arc^[2].x *) + mov ebx, [esi+1*8] (* b := arc^[1].x *) + mov ecx, [esi+0*8] (* b := (arc^[0].x+b) div 2 *) + + mov [esi+4*8], eax + + add eax, ebx (* a := (arc^[2].x+b) div 2 *) + add ebx, ecx + mov edx, eax + mov ecx, ebx + sar edx, 31 + sar ecx, 31 + sub eax, edx + sub ebx, ecx + sar eax, 1 + sar ebx, 1 + + mov [esi+3*8], eax (* arc^[3].x := a *) + mov [esi+1*8], ebx + + add eax, ebx (* arc[2].x := (a+b) div 2 *) + mov edx, eax + sar edx, 31 + sub eax, edx + sar eax, 1 + mov [esi+2*8], eax + + add esi, 4 + + mov eax, [esi+2*8] (* arc^[4].x := arc^[2].x *) + mov ebx, [esi+1*8] (* b := arc^[1].x *) + mov ecx, [esi+0*8] (* b := (arc^[0].x+b) div 2 *) + + mov [esi+4*8], eax + + add eax, ebx (* a := (arc^[2].x+b) div 2 *) + add ebx, ecx + mov edx, eax + mov ecx, ebx + sar edx, 31 + sar ecx, 31 + sub eax, edx + sub ebx, ecx + sar eax, 1 + sar ebx, 1 + + mov [esi+3*8], eax (* arc^[3].x := a *) + mov [esi+1*8], ebx + + add eax, ebx (* arc[2].x := (a+b) div 2 *) + mov edx, eax + sar edx, 31 + sub eax, edx + sar eax, 1 + mov [esi+2*8], eax + + pop ecx + pop ebx + pop esi + end; +{$ELSE} + arc := base; + + arc^[4].x := arc^[2].x; + b := arc^[1].x; + a := (arc^[2].x + b) div 2; arc^[3].x := a; + b := (arc^[0].x + b) div 2; arc^[1].x := b; + arc^[2].x := (a+b) div 2; + + arc^[4].y := arc^[2].y; + b := arc^[1].y; + a := (arc^[2].y + b) div 2; arc^[3].y := a; + b := (arc^[0].y + b) div 2; arc^[1].y := b; + arc^[2].y := (a+b) div 2; +{$ENDIF} +end; + +(****************************************************************************) +(* *) +(* Function: Push_Bezier *) +(* *) +(* Description: Clears the Bezier stack and pushes a new Arc on top of it. *) +(* *) +(* Input: x1,y1 x2,y2 x3,y3 new Bezier arc *) +(* *) +(* Returns: nada *) +(* *) +(****************************************************************************) + +procedure PushBezier( x1, y1, x2, y2, x3, y3 : LongInt ); +begin + curArc:=0; + + with Arcs[CurArc+2] do begin x:=x1; y:=y1; end; + with Arcs[CurArc+1] do begin x:=x2; y:=y2; end; + with Arcs[ CurArc ] do begin x:=x3; y:=y3; end; +end; + +(****************************************************************************) +(* *) +(* Function: Line_Up *) +(* *) +(* Description: Compute the x-coordinates of an ascending line segment *) +(* and stores them in the render pool. *) +(* *) +(* Input: x1,y1 x2,y2 Segment start (x1,y1) and end (x2,y2) points *) +(* *) +(* Returns: True on success *) +(* False if Render Pool overflow. *) +(* *) +(****************************************************************************) + +function Line_Up( x1, y1, x2, y2, miny, maxy : LongInt ) : boolean; +var + Dx, Dy : LongInt; + e1, e2, f1, f2, size : Int; + Ix, Rx, Ax : LongInt; + top : PStorage; +begin + Line_Up := True; + + Dx := x2-x1; Dy := y2-y1; + + if (Dy <= 0) or (y2 < MinY) or (y1 > MaxY) then exit; + + if y1 < MinY then + begin + x1 := x1 + MulDiv( Dx, MinY-y1, Dy ); + e1 := Trunc(MinY); + f1 := 0; + end + else + begin + e1 := Trunc(y1); + f1 := Frac(y1); + end; + + if y2 > MaxY then + begin + (* x2 := x2 + MulDiv( Dx, MaxY-y2, Dy ); *) + e2 := Trunc(MaxY); + f2 := 0; + end + else + begin + e2 := Trunc(y2); + f2 := Frac(y2); + end; + + if f1 > 0 then + if e1 = e2 then exit + else + begin + inc( x1, MulDiv( Dx, precision-f1, Dy ) ); + inc( e1 ); + end + else + if Joint then + dec( profCur ); + + Joint := (f2 = 0); + + (* Indicates that the segment stopped sharp on a ScanLine *) + + if Fresh then + begin + cProfile^.Start := e1; + Fresh := False; + end; + + size := ( e2-e1 )+1; + if ( profCur + size >= MaxBuff ) then + begin + Line_Up := False; + Error := Err_Ras_Overflow; + exit; + end; + + if Dx > 0 then + begin + Ix := (Precision*Dx) div Dy; + Rx := (Precision*Dx) mod Dy; + Dx := 1; + end + else + begin + Ix := -((Precision*-Dx) div Dy); + Rx := (Precision*-Dx) mod Dy; + Dx := -1; + end; + + Ax := -Dy; + {top := @Buff^[profCur];} + + while size > 0 do + begin + Buff^[profCur] := x1; + {$IFDEF DEBUG3} Pset; {$ENDIF} + inc( profCur ); + {top := @top^[1];} + + inc( x1, Ix ); + inc( ax, rx ); + + if ax >= 0 then + begin + dec( ax, dy ); + inc( x1, dx ); + end; + + dec( size ); + end; + +end; + +(****************************************************************************) +(* *) +(* Function: Line_Down *) +(* *) +(* Description: Compute the x-coordinates of a descending line segment *) +(* and stores them in the render pool. *) +(* *) +(* Input: x1,y1 x2,y2 Segment start (x1,y1) and end (x2,y2) points *) +(* *) +(* Returns: True on success *) +(* False if Render Pool overflow. *) +(* *) +(****************************************************************************) + +function Line_Down( x1, y1, x2, y2, miny, maxy : LongInt ): boolean; +var + _fresh : Boolean; +begin + _fresh := fresh; + + Line_Down := Line_Up( x1, -y1, x2, -y2, -maxy, -miny ); + + if _fresh and not fresh then + cProfile^.start := -cProfile^.start; +end; + +(****************************************************************************) +(* *) +(* Function: Bezier_Up *) +(* *) +(* Description: Compute the x-coordinates of an ascending bezier arc *) +(* and stores them in the render pool. *) +(* *) +(* Input: None.The arc is taken from the top of the Bezier stack. *) +(* *) +(* Returns: True on success *) +(* False if Render Pool overflow. *) +(* *) +(****************************************************************************) + +function Bezier_Up( miny, maxy : Long ) : boolean; +var + x1, y1, x2, y2, e, e2, e0 : LongInt; + carc, debArc, f1 : Int; + base : PBezierStack; +label + Fin; +begin + Bezier_Up := True; + + carc := curArc; + base := @Arcs[cArc]; + y1 := base^[2].y; + y2 := base^[0].y; + + if ( y2 < MinY ) or ( y1 > MaxY ) then + goto Fin; + + e2 := FLOOR(y2); + + if e2 > MaxY then e2 := MaxY; + + e0 := MinY; + + if y1 < MinY then + e := MinY + else + begin + e := CEILING(y1); + f1 := FRAC(y1); + e0 := e; + + if f1 = 0 then + begin + + if Joint then begin dec(profCur); Joint:=False; end; + (* ^ Ce test permet d'‚viter les doublons *) + + Buff^[profCur] := base^[2].x; + {$IFDEF DEBUG3} Pset; {$ENDIF} + inc( profCur ); + inc( e, Precision ); + end + end; + + if Fresh then + begin + cProfile^.Start := TRUNC(e0); + Fresh := False; + end; + + if e2 < e then + goto Fin; + + (* overflow ? *) + if ( profCur + TRUNC(e2-e)+ 1 >= MaxBuff ) then + begin + Bezier_Up := False; + Error := Err_Ras_Overflow; + exit; + end; + + debArc := cArc; + + while ( cArc >= debArc ) and ( e <= e2 ) do + begin + Joint := False; + y2 := base^[0].y; + + if y2 > e then + begin + y1 := base^[2].y; + if ( y2-y1 >= precision_step ) then + begin + Split_Bezier( base ); + inc( cArc, 2 ); + base := @base^[2]; + end + else + begin + Buff^[profCur] := base^[2].x + + MulDiv( base^[0].x - base^[2].x, + e - y1, + y2 - y1 ); + + {$IFDEF DEBUG3} Pset; {$ENDIF} + + inc( profCur ); + dec( cArc, 2 ); + base := @Arcs[cArc]; + inc( e, Precision ); + end; + end + else + begin + if y2 = e then + begin + joint := True; + Buff^[profCur] := Arcs[cArc].x; + {$IFDEF DEBUG3} Pset; {$ENDIF} + inc( profCur ); + inc( e, Precision ); + end; + dec( cArc, 2 ); + base := @Arcs[cArc]; + end + end; + +Fin: + dec( curArc, 2); + exit; +end; + + +(****************************************************************************) +(* *) +(* Function: Bezier_Down *) +(* *) +(* Description: Compute the x-coordinates of a descending bezier arc *) +(* and stores them in the render pool. *) +(* *) +(* Input: None. Arc is taken from the top of the Bezier stack. *) +(* *) +(* Returns: True on success *) +(* False if Render Pool overflow. *) +(* *) +(****************************************************************************) + +function Bezier_Down( miny, maxy : Long ) : boolean; +var + base : PBezierStack; + _fresh : Boolean; +begin + _fresh := fresh; + base := @Arcs[curArc]; + + base^[0].y := -base^[0].y; + base^[1].y := -base^[1].y; + base^[2].y := -base^[2].y; + + Bezier_Down := Bezier_Up( -maxy, -miny ); + + if _fresh and not fresh then + cProfile^.start := -cProfile^.start; + + base^[0].y := -base^[0].y; +end; + +(****************************************************************************) +(* *) +(* Function: Line_To *) +(* *) +(* Description: Injects a new line segment and adjust Profiles list. *) +(* *) +(* Input: x, y : segment endpoint ( start point in LastX,LastY ) *) +(* *) +(* Returns: True on success *) +(* False if Render Pool overflow or Incorrect Profile *) +(* *) +(****************************************************************************) + +function Line_To( x, y : LongInt ) : boolean; +begin + Line_To := False; + + case Etat of + + Indetermine : if y > lastY then + if not New_Profile( Ascendant ) then exit else + else + if y < lastY then + if not New_Profile( Descendant ) then exit; + + Ascendant : if y < lastY then + if not End_Profile or + not New_Profile( Descendant ) then exit; + + Descendant : if y > LastY then + if not End_Profile or + not New_Profile( Ascendant ) then exit; + end; + + Case Etat of + Ascendant : if not Line_Up ( LastX, LastY, X, Y, miny, maxy ) then exit; + Descendant : if not Line_Down( LastX, LastY, X, Y, miny, maxy ) then exit; + end; + + LastX := x; + LastY := y; + + Line_To := True; +end; + +(****************************************************************************) +(* *) +(* Function: Bezier_State *) +(* *) +(* Description: Determines the state (ascending/descending/flat/undet) *) +(* of a Bezier arc, along one given axis. *) +(* *) +(* Input: y1, y2, y3 : coordinates of the Bezier arc. *) +(* along the concerned axis. *) +(* *) +(* Returns: State, i.e. Ascending, Descending, Flat or Undetermined *) +(* *) +(****************************************************************************) + + +function Bezier_State( y1, y2, y3 : TT_F26Dot6 ) : TEtats; +begin + (* determine orientation of a Bezier arc *) + if y1 = y2 then + + if y2 = y3 then Bezier_State := Plat + else + if y2 > y3 then Bezier_State := Descendant + else + Bezier_State := Ascendant + else + if y1 > y2 then + + if y2 >= y3 then Bezier_State := Descendant + else + Bezier_State := Indetermine + else + + if y2 <= y3 then Bezier_State := Ascendant + else + Bezier_State := Indetermine; +end; + + +(****************************************************************************) +(* *) +(* Function: Bezier_To *) +(* *) +(* Description: Injects a new bezier arc and adjust Profiles list. *) +(* *) +(* Input: x, y : arc endpoint ( start point in LastX, LastY ) *) +(* Cx, Cy : control point *) +(* *) +(* Returns: True on success *) +(* False if Render Pool overflow or Incorrect Profile *) +(* *) +(****************************************************************************) + + +function Bezier_To( x, y, Cx, Cy : LongInt ) : boolean; +var + y3, x3 : LongInt; + Etat_Bez : TEtats; +begin + Bezier_To := False; + + PushBezier( LastX, LastY, Cx, Cy, X, Y ); + + while ( curArc >= 0 ) do + begin + y3 := Arcs[curArc].y; + x3 := Arcs[curArc].x; + + Etat_Bez := Bezier_State( Arcs[curArc+2].y, Arcs[curArc+1].y, y3 ); + + case Etat_Bez of + + Plat : dec( curArc, 2 ); + + Indetermine : begin + Split_Bezier( @Arcs[curArc] ); + inc( curArc, 2 ); + end; + else + if Etat <> Etat_Bez then + begin + if Etat <> Indetermine then + if not End_Profile then exit; + + if not New_Profile( Etat_Bez ) then exit; + end; + + case Etat of + Ascendant : if not Bezier_Up( miny, maxy ) then exit; + Descendant : if not Bezier_Down( miny, maxy ) then exit; + end; + + end; + end; + + LastX := x3; + LastY := y3; + + Bezier_To := True; +end; + +(****************************************************************************) +(* *) +(* Function: DecomposeCurve *) +(* *) +(* Description: This functions scans the outline arrays in order to *) +(* emit individual segments and beziers by calling the *) +(* functions Line_To and Bezier_To. It handles all weird *) +(* cases, like when the first point is off the curve, or *) +(* when there are simply no "on" points in the contour ! *) +(* *) +(* Input: xCoord, yCoord : array coordinates to use. *) +(* first, last : indexes of first and last point in *) +(* contour. *) +(* *) +(* Returns: True on success *) +(* False if case of error. *) +(* *) +(* Notes: The function assumes that 'first' < 'last' *) +(* *) +(****************************************************************************) + +procedure swap( var x, y : Long ); {$IFDEF INLINE} inline; {$ENDIF} +var + s : Long; +begin + s := x; x := y; y := s; +end; + +function DecomposeCurve( first, last : Int; + flipped : Boolean ) : boolean; +var + index : Int; + + x, y : Long; (* current point *) + cx, cy : Long; (* current Bezier control point *) + mx, my : Long; (* middle point *) + + x_first, y_first : Long; (* first point coordinates *) + x_last, y_last : Long; (* last point coordinates *) + + on_curve : Boolean; +begin + + DecomposeCurve := False; + +(* the following code is miscompiled by Virtual Pascal 1.1 *) +(* although it works OK with 2.0, strange... *) +(* + with points^[first] do + begin + x_first := SCALED( x ); + y_first := SCALED( y ); + end; +*) + x_first := SCALED( points^[first].x ); + y_first := SCALED( points^[first].y ); + + if flipped then swap( x_first, y_first ); + + with points^[last] do + begin + x_last := SCALED( x ); + y_last := SCALED( y ); + end; + + if flipped then swap( x_last, y_last ); + + LastX := x_first; cx := x_first; + LastY := y_first; cy := y_first; + + index := first; + on_curve := Flags^[first] and 1 <> 0; + + (* check first point, and set origin *) + if not on_curve then + begin + (* first point is off the curve - yes, this happens !! *) + + if Flags^[last] and 1 <> 0 then + begin + LastX := x_last; (* start at last point if it is *) + LastY := y_last; (* on the curve *) + end + else + begin + LastX := (LastX + x_last) div 2; (* if both first and last point *) + LastY := (LastY + y_last) div 2; (* are off the curve, start midway *) + + (* record midpoint in x_last,y_last *) + x_last := LastX; + y_last := LastY; + end; + end; + + (* now process each contour point *) + while ( index < last ) do + begin + inc( index ); + + x := SCALED( points^[index].x ); + y := SCALED( points^[index].y ); + + if flipped then swap( x, y ); + + if on_curve then + begin + (* the previous point was on the curve *) + + on_curve := Flags^[index] and 1 <> 0; + if on_curve then + begin + (* two successive on points -> emit segment *) + if not Line_To( x, y ) then exit; + end + else + begin + (* else, keep current point as control for next bezier *) + cx := x; + cy := y; + end; + end + else + begin + (* the previous point was off the curve *) + + on_curve := Flags^[index] and 1 <> 0; + if on_curve then + begin + (* reaching on point -> emit Bezier *) + if not Bezier_To( x, y, cx, cy ) then exit; + end + else + begin + (* two successive off points -> create middle point *) + (* then emit Bezier *) + mx := (cx + x) div 2; + my := (cy + y) div 2; + + if not Bezier_To( mx, my, cx, cy ) then exit; + + cx := x; + cy := y; + end; + end; + end; + + (* end of contour, close curve cleanly *) + if ( Flags^[first] and 1 <> 0 ) then + + if on_curve then + if not Line_To( x_first, y_first ) then exit else + else + if not Bezier_To( x_first, y_first, cx, cy ) then exit else + + else + if not on_curve then + if not Bezier_To( x_last, y_last, cx, cy ) then exit; + + DecomposeCurve := True; +end; + +(****************************************************************************) +(* *) +(* Function: Convert_Glyph *) +(* *) +(* Description: Converts a glyph into a series of segments and arcs *) +(* and make a Profiles list with them. *) +(* *) +(* Input: _xCoord, _yCoord : coordinates tables. *) +(* *) +(* Uses the 'Flag' table too. *) +(* *) +(* Returns: True on success *) +(* False if any error was encountered during render. *) +(* *) +(****************************************************************************) + +Function Convert_Glyph( flipped : Boolean ) : boolean; +var + i, j, First, Last, Start : Int; + + y1, y2, y3 : LongInt; + + lastProfile : PProfile; + +begin + Convert_Glyph := False; + + j := 0; + fProfile := NIL; + Joint := False; + Fresh := False; + + MaxBuff := SizeBuff - AlignProfileSize; + +{$IFDEF TURNS} + numTurns := 0; +{$ENDIF} + + cProfile := PProfile( @Buff^[profCur] ); + cProfile^.Offset := profCur; + nProfs := 0; + + for i := 0 to nContours-1 do + begin + + Etat := Indetermine; + gProfile := nil; + + (* decompose a single contour into individual segments and *) + (* beziers *) + + if not DecomposeCurve( j, outs^[i], flipped ) then exit; + j := outs^[i] + 1; + + (* We _must_ take care of the case when the first and last arcs join *) + (* while having the same orientation *) + + if ( Frac(lastY) = 0 ) and + ( lastY >= MinY ) and + ( lastY <= MaxY ) then + + if ( gProfile <> nil ) and (* gProfile can be nil *) + ( gProfile^.Flow = cProfile^.Flow ) then (* if the contour was *) + (* too small to be drawn *) + dec( profCur ); + + lastProfile := cProfile; + + if not End_Profile then exit; + + if gProfile <> nil then lastProfile^.next := gProfile; + + end; + + Finalize_Profile_Table; + + Convert_Glyph := (profCur < MaxBuff); +end; + + + (************************************************) + (* *) + (* Init_Linked *) + (* *) + (* Init an empty linked list. *) + (* *) + (************************************************) + + procedure Init_Linked( var L : PProfile ); + begin + L := nil; + end; + + (************************************************) + (* *) + (* InsNew : *) + (* *) + (* Inserts a new Profile in a linked list. *) + (* *) + (************************************************) + + procedure InsNew( var List : PProfile; + Profile : PProfile ); + var + current : PProfile; + old : ^PProfile; + x : Long; + label + Place; + begin + + old := @list; + current := old^; + x := profile^.x; + + while current <> nil do + begin + if x < current^.x then + goto Place; + + old := @current^.link; + current := old^; + end; + + Place: + profile^.link := current; + old^ := profile; + end; + + (************************************************) + (* *) + (* DelOld : *) + (* *) + (* Removes an old Profile from a linked list *) + (* *) + (************************************************) + + + procedure DelOld( var List : PProfile; + Profile : PProfile ); + var + current : PProfile; + old : ^PProfile; + + begin + + old := @list; + current := old^; + + while current <> nil do + begin + if current = profile then + begin + old^ := current^.link; + exit; + end; + + old := @current^.link; + current := old^; + end; + + {$IFDEF ASSERT} + Writeln('(Raster:DelOld) Incoherent deletion'); + halt(9); + {$ENDIF} + end; + + +{$IFDEF TURNS} + (************************************************) + (* *) + (* Update: *) + (* *) + (* Update all X offsets in a drawing list *) + (* *) + (************************************************) + + procedure Update( var List : PProfile ); + var + current : PProfile; + begin + (* recompute coordinates *) + current := list; + + while current <> nil do with current^ do + begin + X := Buff^[offset]; + inc( offset, flow ); + dec( height ); + current := link; + end; + end; +{$ENDIF} + + (************************************************) + (* *) + (* Sort : *) + (* *) + (* Sorts 'quickly' (??) a trace list. *) + (* *) + (************************************************) + + procedure Sort( var List : PProfile ); + var + current, next : PProfile; + old : ^PProfile; + begin + + (* First, recompute coordinates *) + + current := list; + + while current <> nil do with current^ do + begin + X := Buff^[offset]; + inc( offset, flow ); + dec( height ); + current := link; + end; + + (* Then, do the sort *) + + old := @list; + current := old^; + + if current = nil then + exit; + + next := current^.link; + + while next <> nil do + begin + if current^.x <= next^.x then + begin + old := @current^.link; + current := old^; + + if current = nil then + exit; + end + else + begin + old^ := next; + current^.link := next^.link; + next^.link := current; + + old := @list; + current := old^; + end; + + next := current^.link; + end; + + end; + +{$IFDEF TURNS} + +(********************************************************************) +(* *) +(* Generic Sweep Drawing routine *) +(* *) +(* *) +(* *) +(********************************************************************) + +function Draw_Sweep : boolean; + +label + Scan_DropOuts, + Next_Line, + Skip_To_Next; + +var + y, k, + I, J : Int; + P, Q : PProfile; + + Top, + Bottom, + y_height, + y_change, + min_Y, + max_Y : Int; + + x1, x2, xs, e1, e2 : LongInt; + + Wait : PProfile; + + Draw_Left : PProfile; + Draw_Right : PProfile; + + Drop_Left : PProfile; + Drop_Right : PProfile; + + P_Left, Q_Left : PProfile; + P_Right, Q_Right : PProfile; + + Phase : Int; + dropouts : Int; + +begin + + Draw_Sweep := False; + + (* Init the empty linked lists *) + + Init_Linked( Wait ); + + Init_Linked( Draw_Left ); + Init_Linked( Draw_Right ); + + Init_Linked( Drop_Left ); + Init_Linked( Drop_Right ); + + (* First, compute min Y and max Y *) + + P := fProfile; + max_Y := TRUNC(MinY); + min_Y := TRUNC(MaxY); + + while P <> nil do + with P^ do + begin + Q := P^.Link; + + Bottom := P^.Start; + Top := Bottom + P^.Height-1; + + if min_Y > Bottom then min_Y := Bottom; + if max_Y < Top then max_Y := Top; + + X := 0; + InsNew( Wait, P ); + + P := Q; + end; + + (* Check the y-turns *) + if (numTurns = 0) then + begin + Error := Err_Ras_Invalid; + exit; + end; + + (* Now inits the sweeps *) + + Proc_Sweep_Init( min_Y, max_Y ); + + (* Then compute the distance of each Profile to min Y *) + + P := Wait; + while P <> nil do + begin + with P^ do CountL := (Start-min_Y); + P := P^.link;; + end; + + (* Let's go *) + + y := min_y; + y_height := 0; + + if ( numTurns > 0 ) and + ( Buff^[sizeBuff-numTurns] = min_y ) then + dec( numTurns ); + + while numTurns > 0 do + begin + (* Look in the wait list for new activations *) + + P := Wait; + while P <> nil do with P^ do + begin + Q := link; + + dec( CountL, y_height ); + if CountL = 0 then + begin + DelOld( Wait, P ); + case Flow of + TT_Flow_Up : InsNew( Draw_Left, P ); + TT_Flow_Down : InsNew( Draw_Right, P ); + end + end; + + P := Q; + end; + + (* Sort the drawing lists *) + + Sort( Draw_Left ); + Sort( Draw_Right ); + + y_change := Buff^[sizebuff-numTurns]; + dec( numTurns ); + + y_height := y_change - y; + + while y < y_change do + begin + + (* Let's trace *) + + dropouts := 0; + + P_Left := Draw_Left; + P_Right := Draw_Right; + + while ( P_Left <> nil ) do + begin + + {$IFDEF ASSERT} + if P_Right = nil then + Halt(13); + {$ENDIF} + + x1 := P_Left^ .X; + x2 := P_Right^.X; + + if x1 > x2 then + begin + xs := x1; + x1 := x2; + x2 := xs; + end; + + if ( x2-x1 <= Precision ) then + begin + e1 := ( x1+Precision-1 ) and Precision_Mask; + e2 := x2 and Precision_Mask; + + if (dropOutControl <> 0) and + ((e1 > e2) or (e2 = e1 + Precision)) then + begin + P_Left ^.x := x1; + P_Right^.x := x2; + + inc( dropouts ); + + (* mark profile for drop-out control *) + P_Left^.CountL := 1; + + goto Skip_To_Next; + end + end; + + Proc_Sweep_Span( y, x1, x2, P_Left, P_Right ); + + Skip_To_Next: + + P_Left := P_Left ^.Link; + P_Right := P_Right^.Link; + end; + + {$IFDEF ASSERT} + if P_Right <> nil then + Halt(10); + {$ENDIF} + + (* Now perform the dropouts only _after_ the span drawing *) + if (dropouts > 0) then + goto Scan_DropOuts; + +Next_Line: + + (* Step to next line *) + Proc_Sweep_Step; + + inc(y); + + if y < y_change then + begin + Update( Draw_Left ); + Update( Draw_Right ); + end + + end; + + (* We finalize the Profiles that need it *) + + P := Draw_Left; + while P <> nil do + begin + Q := P^.Link; + if P^.height = 0 then + DelOld( Draw_Left, P ); + P := Q; + end; + + P := Draw_Right; + while P <> nil do + begin + Q := P^.Link; + if P^.height = 0 then + DelOld( Draw_Right, P ); + P := Q; + end; + + end; + + while y <= max_y do + begin + Proc_Sweep_Step; + inc( y ); + end; + + Draw_Sweep := True; + exit; + +Scan_DropOuts : + P_Left := Draw_Left; + P_Right := Draw_Right; + + while (P_Left <> nil) do + begin + if P_Left^.countL <> 0 then + begin + P_Left^.countL := 0; + Proc_Sweep_Drop( y, P_Left^.x, P_Right^.x, P_Left, P_Right ); + end; + + P_Left := P_Left^.link; + P_Right := P_Right^.Link; + end; + + goto Next_Line; +end; + + +{$ELSE} + +(********************************************************************) +(* *) +(* Generic Sweep Drawing routine *) +(* *) +(* *) +(* *) +(********************************************************************) + +function Draw_Sweep : boolean; + +label + Skip_To_Next; + +var + y, k, + I, J : Int; + P, Q : PProfile; + + Top, + Bottom, + min_Y, + max_Y : Int; + + x1, x2, xs, e1, e2 : LongInt; + + Wait : PProfile; + + Draw_Left : PProfile; + Draw_Right : PProfile; + + Drop_Left : PProfile; + Drop_Right : PProfile; + + P_Left, Q_Left : PProfile; + P_Right, Q_Right : PProfile; + + Phase : Int; + dropouts : Int; + +begin + + Draw_Sweep := False; + + (* Init the empty linked lists *) + + Init_Linked( Wait ); + + Init_Linked( Draw_Left ); + Init_Linked( Draw_Right ); + + Init_Linked( Drop_Left ); + Init_Linked( Drop_Right ); + + (* First, compute min Y and max Y *) + + P := fProfile; + max_Y := TRUNC(MinY); + min_Y := TRUNC(MaxY); + + while P <> nil do + with P^ do + begin + Q := P^.Link; + + Bottom := P^.Start; + Top := Bottom + P^.Height-1; + + if min_Y > Bottom then min_Y := Bottom; + if max_Y < Top then max_Y := Top; + + X := 0; + InsNew( Wait, P ); + + P := Q; + end; + + (* Now inits the sweeps *) + + Proc_Sweep_Init( min_Y, max_Y ); + + (* Then compute the distance of each Profile to min Y *) + + P := Wait; + while P <> nil do + begin + with P^ do CountL := (Start-min_Y); + P := P^.link;; + end; + + (* Let's go *) + + for y := min_Y to max_Y do + begin + + (* Look in the wait list for new activations *) + + P := Wait; + while P <> nil do with P^ do + begin + Q := link; + + if CountL = 0 then + begin + DelOld( Wait, P ); + case Flow of + TT_Flow_Up : InsNew( Draw_Left, P ); + TT_Flow_Down : InsNew( Draw_Right, P ); + end + end + else + dec( CountL ); + + P := Q; + end; + + (* Sort the drawing lists *) + + Sort( Draw_Left ); + Sort( Draw_Right ); + + (* Let's trace *) + + dropouts := 0; + + P_Left := Draw_Left; + P_Right := Draw_Right; + + while ( P_Left <> nil ) do + begin + + {$IFDEF ASSERT} + if P_Right = nil then + Halt(13); + {$ENDIF} + + Q_Left := P_Left^ .Link; + Q_Right := P_Right^.Link; + + {$IFDEF ASSERT} + if Q_Right = nil then + Halt(11); + {$ENDIF} + + x1 := P_Left^ .X; + x2 := P_Right^.X; + + if x1 > x2 then + begin + xs := x1; + x1 := x2; + x2 := xs; + end; + + if ( x2-x1 <= Precision ) then + begin + e1 := ( x1+Precision-1 ) and Precision_Mask; + e2 := x2 and Precision_Mask; + + if (dropOutControl <> 0) and + ((e1 > e2) or (e2 = e1 + Precision)) then + begin + P_Left^.x := x1; + P_Right^.x := x2; + + inc( dropouts ); + + DelOld( Draw_Left, P_Left ); + DelOld( Draw_Right, P_Right ); + + InsNew( Drop_Left, P_Left ); + InsNew( Drop_Right, P_Right ); + + goto Skip_To_Next; + end + end; + + Proc_Sweep_Span( y, x1, x2, P_Left, P_Right ); + + (* We finalize the Profile if needed *) + + if P_Left ^.height = 0 then + DelOld( Draw_Left, P_Left ); + + if P_Right^.height = 0 then + DelOld( Draw_Right, P_Right ); + + Skip_To_Next: + + P_Left := Q_Left; + P_Right := Q_Right; + end; + + {$IFDEF ASSERT} + if P_Right <> nil then + Halt(10); + {$ENDIF} + + (* Now perform the dropouts only _after_ the span drawing *) + + P_Left := Drop_Left; + P_Right := Drop_Right; + + while ( dropouts > 0 ) do + begin + + Q_Left := P_Left^. Link; + Q_Right := P_Right^.Link; + + DelOld( Drop_Left, P_Left ); + DelOld( Drop_Right, P_Right ); + + Proc_Sweep_Drop( y, P_Left^.x, P_Right^.x, P_Left, P_Right ); + + if P_Left^.height > 0 then + InsNew( Draw_Left, P_Left ); + + if P_Right^.height > 0 then + InsNew( Draw_Right, P_Right ); + + P_Left := Q_Left; + P_Right := Q_Right; + + dec( dropouts ); + end; + + (* Step to next line *) + + Proc_Sweep_Step; + + end; + + Draw_Sweep := True; + +end; + +{$ENDIF} + +{$F+ Far calls are necessary for function pointers under BP7} +{ This flag is currently ignored by the Virtual Compiler } + +(***********************************************************************) +(* *) +(* Vertical Sweep Procedure Set : *) +(* *) +(* These three routines are used during the vertical black/white *) +(* sweep phase by the generic Draw_Sweep function. *) +(* *) +(***********************************************************************) + +procedure Vertical_Sweep_Init( var min, max : Int ); +begin + case Cible.flow of + + TT_Flow_Up : begin + traceOfs := min * Cible.cols; + traceIncr := Cible.cols; + end; + else + traceOfs := (Cible.rows - 1 - min)*Cible.cols; + traceIncr := -Cible.cols; + end; + + gray_min_x := 0; + gray_max_x := 0; +end; + + + +procedure Vertical_Sweep_Span( y : Int; + x1, + x2 : TT_F26dot6; + Left, + Right : PProfile ); +var + e1, e2 : Longint; + c1, c2 : Int; + f1, f2 : Int; + base : PByte; +begin +{$IFNDEF NO_ASM} + asm + push esi + push ebx + push ecx + + mov eax, X1 + mov ebx, X2 + mov ecx, [Precision_Bits] + + sub ebx, eax + add eax, [Precision] + dec eax + + sub ebx, [Precision] + cmp ebx, [Precision_Jitter] + jg @No_Jitter + + @Do_Jitter: + mov ebx, eax + jmp @0 + + @No_Jitter: + mov ebx, X2 + + @0: + sar ebx, cl + js @Sortie + + sar eax, cl + mov ecx, [BWidth] + + cmp eax, ebx + jg @Sortie + + cmp eax, ecx + jge @Sortie + + test eax, eax + jns @1 + xor eax, eax + @1: + cmp ebx, ecx + jl @2 + lea ebx, [ecx-1] + @2: + + mov edx, eax + mov ecx, ebx + and edx, 7 + sar eax, 3 + and ecx, 7 + sar ebx, 3 + + cmp eax, [gray_min_X] + jge @3 + mov [gray_min_X], eax + + @3: + cmp ebx, [gray_max_X] + jl @4 + mov [gray_max_X], ebx + + @4: + mov esi, ebx + + mov ebx, [BCible] + add ebx, [TraceOfs] + add ebx, eax + + sub esi, eax + jz @5 + + mov al, [LMask + edx].byte + or [ebx], al + inc ebx + dec esi + jz @6 + mov eax, -1 + @7: + mov [ebx].byte, al + dec esi + lea ebx, [ebx+1] + jnz @7 + + @6: + mov al, [RMask + ecx].byte + or [ebx], al + jmp @8 + + @5: + mov al, [LMask + edx].byte + and al, [RMask + ecx].byte + or [ebx], al + + @8: + @Sortie: + pop ecx + pop ebx + pop esi + end; +{$ELSE} + + e1 := (( x1+Precision-1 ) and Precision_Mask) div Precision; + + if ( x2-x1-Precision <= Precision_Jitter ) then + e2 := e1 + else + e2 := ( x2 and Precision_Mask ) div Precision; + + if (e2 >= 0) and (e1 < BWidth) then + + begin + if e1 < 0 then e1 := 0; + if e2 >= BWidth then e2 := BWidth-1; + + c1 := e1 shr 3; + c2 := e2 shr 3; + + f1 := e1 and 7; + f2 := e2 and 7; + + if gray_min_X > c1 then gray_min_X := c1; + if gray_max_X < c2 then gray_max_X := c2; + + base := @BCible^[TraceOfs + c1]; + + if c1 = c2 then + base^[0] := base^[0] or ( LMask[f1] and Rmask[f2] ) + else + begin + base^[0] := base^[0] or LMask[f1]; + + if c2>c1+1 then + FillChar( base^[1], c2-c1-1, $FF ); + + base := @base^[c2-c1]; + base^[0] := base^[0] or RMask[f2]; + end + end; +{$ENDIF} +end; + + +procedure Vertical_Sweep_Drop( y : Int; + x1, + x2 : TT_F26dot6; + Left, + Right : PProfile ); +var + e1, e2 : Longint; + c1, c2 : Int; + f1, f2 : Int; + + j : Int; +begin + + (* Drop-out control *) + + e1 := ( x1+Precision-1 ) and Precision_Mask; + e2 := x2 and Precision_Mask; + + (* We are guaranteed that x2-x1 <= Precision here *) + + if e1 > e2 then + if e1 = e2 + Precision then + + case DropOutControl of + + (* Drop-out Control Rule #3 *) + 1 : e1 := e2; + + 4 : begin + e1 := ((x1+x2+1) div 2 + Precision-1) and Precision_Mask; + e2 := e1; + end; + + (* Drop-out Control Rule #4 *) + + (* The spec is not very clear regarding rule #4. It *) + (* presents a method that is way too costly to implement *) + (* while the general idea seems to get rid of 'stubs'. *) + (* *) + (* Here, we only get rid of stubs recognized when : *) + (* *) + (* upper stub : *) + (* *) + (* - P_Left and P_Right are in the same contour *) + (* - P_Right is the successor of P_Left in that contour *) + (* - y is the top of P_Left and P_Right *) + (* *) + (* lower stub : *) + (* *) + (* - P_Left and P_Right are in the same contour *) + (* - P_Left is the successor of P_Right in that contour *) + (* - y is the bottom of P_Left *) + (* *) + + 2,5 : begin + + if ( x2-x1 < Precision_Half ) then + begin + (* upper stub test *) + + if ( Left^.next = Right ) and + ( Left^.Height <= 0 ) then exit; + + (* lower stub test *) + + if ( Right^.next = Left ) and + ( Left^.Start = y ) then exit; + end; + + (* Check that the rightmost pixel is not already set *) + e1 := e1 div Precision; + + c1 := e1 shr 3; + f1 := e1 and 7; + + if ( e1 >= 0 ) and ( e1 < BWidth ) and + ( BCible^[TraceOfs+c1] and ($80 shr f1) <> 0 ) then + exit; + + case DropOutControl of + 2 : e1 := e2; + 5 : e1 := ((x1+x2+1) div 2 + Precision-1) and Precision_Mask; + end; + + e2 := e1; + + end; + else + exit; (* unsupported mode *) + end + + else + else + e2 := e1; (* when x1 = e1, x2 = e2, e2 = e1 + 64 *) + + e1 := e1 div Precision; + + if (e1 >= 0) and (e1 < BWidth ) then + begin + c1 := e1 shr 3; + f1 := e1 and 7; + + if gray_min_X > c1 then gray_min_X := c1; + if gray_max_X < c1 then gray_max_X := c1; + + j := TraceOfs + c1; + + BCible^[j] := BCible^[j] or ($80 shr f1); + end; +end; + + + +procedure Vertical_Sweep_Step; +begin + inc( TraceOfs, traceIncr ); +end; + + +(***********************************************************************) +(* *) +(* Horizontal Sweep Procedure Set : *) +(* *) +(* These three routines are used during the horizontal black/white *) +(* sweep phase by the generic Draw_Sweep function. *) +(* *) +(***********************************************************************) + +procedure Horizontal_Sweep_Init( var min, max : Int ); +begin + (* Nothing, really *) +end; + + +procedure Horizontal_Sweep_Span( y : Int; + x1, + x2 : TT_F26dot6; + Left, + Right : PProfile ); +var + e1, e2 : Longint; + c1, c2 : Int; + f1, f2 : Int; + + j : Int; +begin + + if ( x2-x1 < Precision ) then + begin + e1 := ( x1+(Precision-1) ) and Precision_Mask; + e2 := x2 and Precision_Mask; + + if e1 = e2 then + begin + c1 := y shr 3; + f1 := y and 7; + + if (e1 >= 0) then + begin + e1 := e1 shr Precision_Bits; + if Cible.flow = TT_Flow_Up then + j := c1 + e1*Cible.cols + else + j := c1 + (Cible.rows-1-e1)*Cible.cols; + if e1 < Cible.Rows then + BCible^[j] := BCible^[j] or ($80 shr f1); + end; + end; + end; + +{$IFDEF RIEN} + e1 := ( x1+(Precision-1) ) and Precision_Mask; + e2 := x2 and Precision_Mask; + + (* We are here guaranteed that x2-x1 > Precision *) + + c1 := y shr 3; + f1 := y and 7; + + if (e1 >= 0) then + begin + e1 := e1 shr Precision_Bits; + if Cible.flow = TT_Flow_Up then + j := c1 + e1*Cible.cols + else + j := c1 + (Cible.rows-1-e1)*Cible.cols; + if e1 < Cible.Rows then + BCible^[j] := BCible^[j] or ($80 shr f1); + end; + + if (e2 >= 0) then + begin + e2 := e2 shr Precision_Bits; + if Cible.flow = TT_Flow_Up then + j := c1 + e1*Cible.cols + else + j := c1 + (Cible.rows-1-e2)*Cible.cols; + if (e2 <> e1) and (e2 < Cible.Rows) then + BCible^[j] := BCible^[j] or ($80 shr f1); + end; +{$ENDIF} + +end; + + + +procedure Horizontal_Sweep_Drop( y : Int; + x1, + x2 : TT_F26dot6; + Left, + Right : PProfile ); +var + e1, e2 : Longint; + c1, c2 : Int; + f1, f2 : Int; + + j : Int; +begin + + e1 := ( x1+(Precision-1) ) and Precision_Mask; + e2 := x2 and Precision_Mask; + + (* During the horizontal sweep, we only take care of drop-outs *) + + if e1 > e2 then + if e1 = e2 + Precision then + + case DropOutControl of + + 0 : exit; + + (* Drop-out Control Rule #3 *) + 1 : e1 := e2; + + 4 : begin + e1 := ( (x1+x2) div 2 +Precision div 2 ) and Precision_Mask; + e2 := e1; + end; + + (* Drop-out Control Rule #4 *) + + (* The spec is not very clear regarding rule #4. It *) + (* presents a method that is way too costly to implement *) + (* while the general idea seems to get rid of 'stubs'. *) + (* *) + + 2,5 : begin + + (* rightmost stub test *) + + if ( Left^.next = Right ) and + ( Left^.Height <= 0 ) then exit; + + (* leftmost stub test *) + + if ( Right^.next = Left ) and + ( Left^.Start = y ) then exit; + + (* Check that the upmost pixel is not already set *) + + e1 := e1 div Precision; + + c1 := y shr 3; + f1 := y and 7; + + if Cible.flow = TT_Flow_Up then + j := c1 + e1*Cible.cols + else + j := c1 + (Cible.rows-1-e1)*Cible.cols; + + if ( e1 >= 0 ) and ( e1 < Cible.Rows ) and + ( BCible^[j] and ($80 shr f1) <> 0 ) then exit; + + case DropOutControl of + 2 : e1 := e2; + 5 : e1 := ((x1+x2) div 2 + Precision_Half) and Precision_Mask; + end; + + e2 := e1; + end; + else + exit; (* Unsupported mode *) + end; + + c1 := y shr 3; + f1 := y and 7; + + if (e1 >= 0) then + begin + e1 := e1 shr Precision_Bits; + if Cible.flow = TT_Flow_Up then + j := c1 + e1*Cible.cols + else + j := c1 + (Cible.rows-1-e1)*Cible.cols; + if e1 < Cible.Rows then BCible^[j] := BCible^[j] or ($80 shr f1); + end; + +end; + + + +procedure Horizontal_Sweep_Step; +begin + (* Nothing, really *) +end; + +(***********************************************************************) +(* *) +(* Vertical Gray Sweep Procedure Set : *) +(* *) +(* These two routines are used during the vertical gray-levels *) +(* sweep phase by the generic Draw_Sweep function. *) +(* *) +(* *) +(* NOTES : *) +(* *) +(* - The target pixmap's width *must* be a multiple of 4 *) +(* *) +(* - you have to use the function Vertical_Sweep_Span for *) +(* the gray span call. *) +(* *) +(***********************************************************************) + +procedure Vertical_Gray_Sweep_Init( var min, max : Int ); +begin + min := min and -2; + max := (max+3) and -2; + + case Cible.flow of + + TT_Flow_Up : begin + traceG := (min div 2)*Cible.cols; + traceIncr := Cible.cols; + end; + else + traceG := (Cible.rows-1- (min div 2))*Cible.cols; + traceIncr := -Cible.cols; + end; + + TraceOfs := 0; + gray_min_x := Cible.Cols; + gray_max_x := -Cible.Cols; +end; + + +procedure Vertical_Gray_Sweep_Step; +var + j, c1, c2 : Int; +begin + inc( TraceOfs, Gray_Width ); + + if TraceOfs > Gray_Width then + begin + + if gray_max_X >= 0 then + begin + + if gray_max_x > cible.cols-1 then gray_max_x := cible.cols-1; + if gray_min_x < 0 then gray_min_x := 0; + + j := TraceG + gray_min_x*4; + + for c1 := gray_min_x to gray_max_x do + begin + + c2 := Count_Table[ BCible^[c1 ] ] + + Count_Table[ BCible^[c1+Gray_Width] ]; + + if c2 <> 0 then + begin + BCible^[c1 ] := 0; + BCible^[c1+Gray_Width] := 0; + + GCible^[j] := GCible^[j] or Grays[ (c2 and $F000) shr 12 ]; inc(j); + GCible^[j] := GCible^[j] or Grays[ (c2 and $0F00) shr 8 ]; inc(j); + GCible^[j] := GCible^[j] or Grays[ (c2 and $00F0) shr 4 ]; inc(j); + GCible^[j] := GCible^[j] or Grays[ (c2 and $000F) ]; inc(j); + end + else + inc( j, 4 ); + + end; + end; + + TraceOfs := 0; + inc( TraceG, traceIncr ); + + gray_min_x := Cible.Cols; + gray_max_x := -Cible.Cols; + end; +end; + +(***********************************************************************) +(* *) +(* Horizontal Gray Sweep Procedure Set : *) +(* *) +(* These three routines are used during the horizontal gray-levels *) +(* sweep phase by the generic Draw_Sweep function. *) +(* *) +(***********************************************************************) + +procedure Horizontal_Gray_Sweep_Span( y : Int; + x1, + x2 : TT_F26dot6; + Left, + Right : PProfile ); +var + e1, e2 : TT_F26Dot6; + c1, f1, j : Int; +begin + exit; + y := y div 2; + + e1 := ( x1+(Precision-1) ) and Precision_Mask; + e2 := x2 and Precision_Mask; + + if (e1 >= 0) then + begin + e1 := e1 shr (Precision_Bits+1); +(* if Cible.flow = TT_Flow_Up then *) + j := y + e1*Cible.cols; +(* else +// j := c1 + (Cible.rows-1-e1)*Cible.cols; *) + if e1 < Cible.Rows then + if GCible^[j] = Grays[0] then + GCible^[j] := Grays[1]; + end; + + if (e2 >= 0) then + begin + e2 := e2 shr (Precision_Bits+1); +(* if Cible.flow = TT_Flow_Up then *) + j := y + e2*Cible.cols; +(* else +// j := c1 + (Cible.rows-1-e2)*Cible.cols; *) + if (e2 <> e1) and (e2 < Cible.Rows) then + if GCible^[j] = Grays[0] then + GCible^[j] := Grays[1]; + end; + +end; + + +procedure Horizontal_Gray_Sweep_Drop( y : Int; + x1, + x2 : TT_F26dot6; + Left, + Right : PProfile ); +var + e1, e2 : Longint; + f1, f2 : Int; + color : Byte; + j : Int; +begin + + e1 := ( x1+(Precision-1) ) and Precision_Mask; + e2 := x2 and Precision_Mask; + + (* During the horizontal sweep, we only take care of drop-outs *) + + if e1 > e2 then + if e1 = e2 + Precision then + + case DropOutControl of + + 0 : exit; + + (* Drop-out Control Rule #3 *) + 1 : e1 := e2; + + 4 : begin + e1 := ( (x1+x2) div 2 +Precision div 2 ) and Precision_Mask; + e2 := e1; + end; + + (* Drop-out Control Rule #4 *) + + (* The spec is not very clear regarding rule #4. It *) + (* presents a method that is way too costly to implement *) + (* while the general idea seems to get rid of 'stubs'. *) + (* *) + + 2,5 : begin + + (* lowest stub test *) + + if ( Left^.next = Right ) and + ( Left^.Height <= 0 ) then exit; + + (* upper stub test *) + + if ( Right^.next = Left ) and + ( Left^.Start = y ) then exit; + + case DropOutControl of + 2 : e1 := e2; + 5 : e1 := ((x1+x2) div 2 + Precision_Half) and Precision_Mask; + end; + + e2 := e1; + end; + else + exit; (* Unsupported mode *) + end; + + if (e1 >= 0) then + begin + (* A small trick to make 'average' thin line appear in *) + (* medium gray.. *) + + if ( x2-x1 >= Precision_Half ) then + color := Grays[2] + else color := Grays[1]; + + e1 := e1 shr (Precision_Bits+1); + if Cible.flow = TT_Flow_Up then + j := (y div 2) + e1*Cible.cols + else + j := (y div 2) + (Cible.rows-1-e1)*Cible.cols; + if e1 < Cible.Rows then + if GCible^[j] = Grays[0] then + GCible^[j] := color; + end; +end; + +{$IFDEF SMOOTH} + +(***********************************************************************) +(* *) +(* Vertical Smooth Sweep Procedure Set : *) +(* *) +(* These two routines are used during the vertical smooth-levels *) +(* sweep phase by the generic Draw_Sweep function. *) +(* *) +(* *) +(* NOTES : *) +(* *) +(* - The target pixmap's width *must* be a multiple of 2 *) +(* *) +(* - you have to use the function Vertical_Sweep_Span for *) +(* the smooth span call. *) +(* *) +(***********************************************************************) + +procedure Smooth_Sweep_Init( var min, max : Int ); +var + i : integer; +begin + min := min and -4; + max := (max + 7) and -4; + TraceOfs := 0; + TraceG := Cible.Cols * ( min div 4 ); + gray_min_x := Cible.Cols; + gray_max_x := -Cible.Cols; + + smooth_pass := 0; +(* + for i := 0 to Smooth_Cols-1 do + GCible^[i] := 0; +*) +end; + + + +procedure Smooth_Sweep_Step; +var + j, c1, c2 : Int; +begin + + if gray_max_X >= 0 then + begin + + if gray_max_x > cible.cols-1 then gray_max_x := cible.cols-1; + + if gray_min_x < 0 then gray_min_x := 0; + + j := TraceG + gray_min_x*2; + + for c1 := gray_min_x to gray_max_x do + begin + + c2 := Count_Table2[ BCible^[c1] ]; + + if c2 <> 0 then + begin + inc( GCible^[j], c2 shr 4 ); inc(j); + inc( GCible^[j], c2 and 15 ); inc(j); + + BCible^[c1] := 0; + end + else + inc( j, 2 ); + end; + + end; + + traceOfs := 0; + inc( smooth_pass ); + + if smooth_pass >= 4 then + begin + + j := TraceG + gray_min_x*2; + + for c1 := gray_min_x to gray_max_x do + begin + c2 := GCible^[j]; GCible^[j] := Smooths[c2]; inc(j); + c2 := GCible^[j]; GCible^[j] := Smooths[c2]; inc(j); + end; + + smooth_pass := 0; + inc( TraceG, Cible.Cols ); + + gray_min_x := Cible.Cols; + gray_max_x := -Cible.Cols; + end; + +end; + +{$ENDIF} + +{$F- End of dispatching functions definitions } + +(****************************************************************************) +(* *) +(* Function: Render_Single_Pass *) +(* *) +(* Description: Performs one sweep with sub-banding. *) +(* *) +(* Input: _XCoord, _YCoord : x and y coordinates arrays *) +(* *) +(* Returns: True on success *) +(* False if any error was encountered during render. *) +(* *) +(****************************************************************************) + +function Render_Single_Pass( vertical : Boolean ) : boolean; +var + i, j, k : Int; +begin + Render_Single_Pass := False; + + while Band_Top > 0 do + + begin + + with Band_Stack[ Band_Top ] do + begin + MaxY := longint(Y_Max) * Precision; + MinY := longint(Y_Min) * Precision; + end; + + profCur := 0; + Error := Err_Ras_None; + + if not Convert_Glyph( vertical ) then + begin + + if Error <> Err_Ras_Overflow then exit; + Error := Err_Ras_None; + + (* sub-banding *) + + {$IFDEF DEBUG3} + ClearBand( MinY shr Precision_Bits, MaxY shr Precision_Bits ); + {$ENDIF} + + with Band_Stack[Band_Top] do + begin + I := Y_Min; + J := Y_Max; + end; + + K := ( I + J ) div 2; + + if ( Band_Top >= 8 ) or ( K <= I ) then + begin + Band_Top := 0; + Error := Err_Ras_Invalid; + exit; + end + else + begin + + with Band_Stack[Band_Top+1] do + begin + Y_Min := K; + Y_Max := J; + end; + + Band_Stack[Band_Top].Y_Max := K-1; + + inc( Band_Top ); + end + end + else + begin + + if ( fProfile <> nil ) then + if not Draw_Sweep then exit; + + dec( Band_Top ); + end; + + end; + + Render_Single_Pass := true; +end; + +(****************************************************************************) +(* *) +(* Function: Render_Glyph *) +(* *) +(* Description: Renders a glyph in a bitmap. Sub-banding if needed *) +(* *) +(* Input: AGlyph Glyph record *) +(* *) +(* Returns: True on success *) +(* False if any error was encountered during render. *) +(* *) +(****************************************************************************) + +function Render_Glyph( var glyph : TT_Outline; + var target : TT_Raster_Map ) : TError; +begin + + Render_Glyph := Failure; + + if Buff = nil then + begin + Error := Err_Ras_NotIni; + exit; + end; + + if glyph.conEnds^[glyph.n_contours-1] > glyph.n_points then + begin + Error := Err_Ras_Invalid_Contours; + exit; + end; + + Cible := target; + + Outs := glyph.conEnds; + Flags := PByte(glyph.flags); + nPoints := Glyph.n_points; + nContours := Glyph.n_contours; + + points := Glyph.points; + + Set_High_Precision( glyph.high_precision ); + scale_shift := precision_shift; + DropOutControl := glyph.dropout_mode; + second_pass := glyph.second_pass; + + Error := Err_Ras_None; + + (* Vertical Sweep *) + +{$IFDEF FPK} + Proc_Sweep_Init := @Vertical_Sweep_Init; + Proc_Sweep_Span := @Vertical_Sweep_Span; + Proc_Sweep_Drop := @Vertical_Sweep_Drop; + Proc_Sweep_Step := @Vertical_Sweep_Step; +{$ELSE} + Proc_Sweep_Init := Vertical_Sweep_Init; + Proc_Sweep_Span := Vertical_Sweep_Span; + Proc_Sweep_Drop := Vertical_Sweep_Drop; + Proc_Sweep_Step := Vertical_Sweep_Step; +{$ENDIF} + + Band_Top := 1; + Band_Stack[1].Y_Min := 0; + Band_Stack[1].Y_Max := Cible.Rows-1; + + BWidth := Cible.width; + BCible := PByte( Cible.Buffer ); + + if not Render_Single_Pass( False ) then exit; + + (* Horizontal Sweep *) + + if Second_Pass then + begin + +{$IFDEF FPK} + Proc_Sweep_Init := @Horizontal_Sweep_Init; + Proc_Sweep_Span := @Horizontal_Sweep_Span; + Proc_Sweep_Drop := @Horizontal_Sweep_Drop; + Proc_Sweep_Step := @Horizontal_Sweep_Step; +{$ELSE} + Proc_Sweep_Init := Horizontal_Sweep_Init; + Proc_Sweep_Span := Horizontal_Sweep_Span; + Proc_Sweep_Drop := Horizontal_Sweep_Drop; + Proc_Sweep_Step := Horizontal_Sweep_Step; +{$ENDIF} + + Band_Top := 1; + Band_Stack[1].Y_Min := 0; + Band_Stack[1].Y_Max := Cible.Width-1; + + BWidth := Cible.rows; + BCible := PByte( Cible.Buffer ); + + if not Render_Single_Pass( True ) then exit; + + end; + + Render_Glyph := Success; +end; + +(****************************************************************************) +(* *) +(* Function: Render_Gray_Glyph *) +(* *) +(* Description: Renders a glyph with grayscaling. Sub-banding if needed *) +(* *) +(* Input: AGlyph Glyph record *) +(* *) +(* Returns: True on success *) +(* False if any error was encountered during render. *) +(* *) +(****************************************************************************) + + function Render_Gray_Glyph( var glyph : TT_Outline; + var target : TT_Raster_Map ) : TError; +begin + + Render_Gray_Glyph := Failure; + + cible := target; + + Outs := Glyph.conEnds; + Flags := PByte(glyph.flags); + nPoints := Glyph.n_points; + nContours := Glyph.n_contours; + + points := Glyph.points; + + Set_High_Precision( glyph.high_precision ); + scale_shift := precision_shift+1; + DropOutControl := glyph.dropout_mode; + second_pass := glyph.high_precision; + + Error := Err_Ras_None; + + Band_Top := 1; + Band_Stack[1].Y_Min := 0; + Band_Stack[1].Y_Max := 2*Cible.Rows - 1; + + BWidth := Gray_Width; + + if BWidth > Cible.cols div 4 then BWidth := Cible.cols div 4; + + BWidth := BWidth*8; + BCible := PByte( Gray_Lines ); + GCible := PByte( Cible.Buffer ); + +{$IFDEF FPK} + Proc_Sweep_Init := @Vertical_Gray_Sweep_Init; + Proc_Sweep_Span := @Vertical_Sweep_Span; + Proc_Sweep_Drop := @Vertical_Sweep_Drop; + Proc_Sweep_Step := @Vertical_Gray_Sweep_Step; +{$ELSE} + Proc_Sweep_Init := Vertical_Gray_Sweep_Init; + Proc_Sweep_Span := Vertical_Sweep_Span; + Proc_Sweep_Drop := Vertical_Sweep_Drop; + Proc_Sweep_Step := Vertical_Gray_Sweep_Step; +{$ENDIF} + + if not Render_Single_Pass( False ) then exit; + + (* Horizontal Sweep *) + + if Second_Pass then + begin + +{$IFDEF FPK} + Proc_Sweep_Init := @Horizontal_Sweep_Init; + Proc_Sweep_Span := @Horizontal_Gray_Sweep_Span; + Proc_Sweep_Drop := @Horizontal_Gray_Sweep_Drop; + Proc_Sweep_Step := @Horizontal_Sweep_Step; +{$ELSE} + Proc_Sweep_Init := Horizontal_Sweep_Init; + Proc_Sweep_Span := Horizontal_Gray_Sweep_Span; + Proc_Sweep_Drop := Horizontal_Gray_Sweep_Drop; + Proc_Sweep_Step := Horizontal_Sweep_Step; +{$ENDIF} + + Band_Top := 1; + Band_Stack[1].Y_Min := 0; + Band_Stack[1].Y_Max := Cible.Width*2-1; + + BWidth := Cible.rows; + GCible := PByte( Cible.Buffer ); + + if not Render_Single_Pass( True ) then exit; + + end; + + Render_Gray_Glyph := Success; + exit; + +end; + +{$IFDEF SMOOTH} +(****************************************************************************) +(* *) +(* Function: Render_Smooth_Glyph *) +(* *) +(* Description: Renders a glyph with grayscaling. Sub-banding if needed *) +(* *) +(* Input: AGlyph Glyph record *) +(* *) +(* Returns: True on success *) +(* False if any error was encountered during render. *) +(* *) +(****************************************************************************) + +function Render_Smooth_Glyph( var glyph : TGlyphRecord; + target : PRasterBlock; + scan : Byte; + palette : pointer ) : boolean; +begin + + Render_Smooth_Glyph := Failure; + + if target <> nil then + cible := target^; +(* + if palette <> nil then + move( palette^, Grays, 5 ); +*) + Outs := Glyph.endPoints; + Flags := PByte(glyph.Flag); + nPoints := Glyph.Points; + nContours := Glyph.numConts; + + scale_shift := precision_shift+2; + DropOutControl := scan; + + Raster_Error := Err_Ras_None; + + Band_Top := 1; + Band_Stack[1].Y_Min := 0; + Band_Stack[1].Y_Max := 4*Cible.Rows - 1; + + BWidth := Smooth_Cols; + + if BWidth > Cible.cols then BWidth := Cible.cols; + + BWidth := BWidth*8; + BCible := PByte( Gray_Lines ); + GCible := PByte( Cible.Buffer ); + +{$IFDEF FPK} + Proc_Sweep_Init := @Smooth_Sweep_Init; + Proc_Sweep_Span := @Vertical_Sweep_Span; + Proc_Sweep_Drop := @Vertical_Sweep_Drop; + Proc_Sweep_Step := @Smooth_Sweep_Step; +{$ELSE} + Proc_Sweep_Init := Smooth_Sweep_Init; + Proc_Sweep_Span := Vertical_Sweep_Span; + Proc_Sweep_Drop := Vertical_Sweep_Drop; + Proc_Sweep_Step := Smooth_Sweep_Step; +{$ENDIF} + + if not Render_Single_Pass( Glyph.XCoord, Glyph.YCoord ) then exit; + + Render_Smooth_Glyph := Success; + +end; + +{$ENDIF} + +(****************************************************************************) +(* *) +(* Function: Init_Rasterizer *) +(* *) +(* Description: Initializes the rasterizer. *) +(* *) +(* Input: rasterBlock target bitmap/pixmap description *) +(* profBuffer pointer to the render pool *) +(* profSize size in bytes of the render pool *) +(* *) +(* Returns: 1 ( always, but we should check parameters ) *) +(* *) +(****************************************************************************) + +function TTRaster_Init : TError; +var + i, j, c, l : integer; +const + Default_Grays : array[0..4] of Byte + = ( 0, 23, 27, 29, 31 ); + + Default_Smooths : array[0..16] of Byte + = ( 0, 20, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 31, 31, 31 ); +begin + GetMem( Buff, Render_Pool_Size ); + SizeBuff := (Render_Pool_Size div 4); + + GetMem( Gray_Lines, Gray_Lines_Size ); + Gray_Width := Gray_Lines_Size div 2; + +{$IFDEF SMOOTH} + Smooth_Cols := Gray_Lines_Size div 4; +{$ENDIF} + + { Initialisation of Count_Table } + + for i := 0 to 255 do + begin + l := 0; + j := i; + for c := 0 to 3 do + begin + l := l shl 4; + if ( j and $80 <> 0 ) then inc(l); + if ( j and $40 <> 0 ) then inc(l); + j := (j shl 2) and $FF; + end; + Count_table[i] := l; + end; + + (* default Grays takes the gray levels of the standard VGA *) + (* 256 colors mode *) + + Grays[0] := 0; + Grays[1] := 23; + Grays[2] := 27; + Grays[3] := 29; + Grays[4] := 31; + + +{$IFDEF SMOOTH} + + { Initialisation of Count_Table2 } + for i := 0 to 255 do + begin + l := 0; + j := i; + for c := 0 to 1 do + begin + l := l shl 4; + if ( j and $80 <> 0 ) then inc(l); + if ( j and $40 <> 0 ) then inc(l); + if ( j and $20 <> 0 ) then inc(l); + if ( j and $10 <> 0 ) then inc(l); + j := (j shl 4) and $FF; + end; + Count_table2[i] := l; + end; + move( Default_Smooths, Smooths, 17 ); +{$ENDIF} + + Set_High_Precision(False); + Set_Second_Pass(False); + + DropOutControl := 2; + Error := Err_Ras_None; + + TTRaster_Init := Success; +end; + +procedure Cycle_DropOut; +begin + case DropOutControl of + + 0 : DropOutControl := 1; + 1 : DropOutControl := 2; + 2 : DropOutControl := 4; + 4 : DropOutControl := 5; + else + DropOutControl := 0; + end; +end; + +procedure TTRaster_Done; +begin + FreeMem( Buff, Render_Pool_Size ); + FreeMem( Gray_Lines, Gray_Lines_Size ); +end; + + +end. diff --git a/pascal/lib/tttables.pas b/pascal/lib/tttables.pas new file mode 100644 index 0000000..d098558 --- /dev/null +++ b/pascal/lib/tttables.pas @@ -0,0 +1,247 @@ +(******************************************************************* + * + * TTTables.Pas 1.2 + * + * TrueType Tables declarations + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * Difference between 1.1 and 1.2 : + * + * - TTTables now only contains the declarations of the + * TrueType tables. + * + * - Instance, Resident and Execution context declarations + * were moved to TTObjs + * + * - Tables loaders were moved to the new TTLoad component + * + ******************************************************************) + +Unit TTTables; + +interface + +uses FreeType, TTTypes; + +(***************************************************************************) +(* *) +(* TrueType Table Types *) +(* *) +(***************************************************************************) + +type + (* TrueType collection header *) + PTTCHeader = ^TTTCHeader; + TTTCHeader = record + Tag : Long; + version : TT_Fixed; + DirCount : ULong; + TableDirectory : PStorage; + end; + + (* TrueType Table Directory type *) + PTableDir = ^TTableDir; + TTableDir = Record + version : TT_Fixed; (* should be $10000 *) + numTables : UShort; (* Tables number *) + + searchRange, (* These parameters are only used *) + entrySelector, (* for a dichotomy search in the *) + rangeShift : UShort; (* directory. We ignore them *) + end; + + (* The 'TableDir' is followed by 'numTables' TableDirEntries *) + + TTableDirEntry = Record + Tag : Long; (* table type *) + CheckSum : Long; (* table Checksum *) + Offset : Long; (* Table file offset *) + Length : Long; (* Table length *) + end; + + TTableDirEntries = array[0..100] of TTableDirEntry; + PTableDirEntries = ^TTableDirEntries; + + (* 'cmap' tables *) + + TCMapDir = record + tableVersionNumber : UShort; + numCMaps : UShort; + end; + + TCMapDirEntry = record + platformID : UShort; + platformEncodingID : UShort; + offset : Long; + end; + + TCMapDirEntries = array[0..10] of TCMapDirEntry; + PCMapDirEntries = ^TCMapDirEntries; + + (* table "maxp" of Maximum Profiles' *) + + TMaxProfile = Record + Version : TT_Fixed; + numGlyphs, + maxPoints, + maxContours, + maxCompositePoints, + maxCompositeContours, + maxZones, + maxTwilightPoints, + maxStorage, + maxFunctionDefs, + maxInstructionDefs, + maxStackElements, + + maxSizeOfInstructions, + maxComponentElements, + maxComponentDepth : UShort; + end; + + (* table "gasp" *) + +const + Gasp_GridFit = 1; + Gasp_DoGray = 2; + +type + TGaspRange = record + maxPPEM : UShort; + gaspFlag : UShort; + end; + + TGaspRanges = array[0..9] of TGaspRange; + PGaspRanges = ^TGaspRanges; + + TGasp = record + version : UShort; + numRanges : UShort; + gaspRanges : PGaspRanges; + end; + + (* table "HMTX" *) + + TLongMetrics = record + advance : UShort; + bearing : Short; + end; + + TTableLongMetrics = array[0..255] of TLongMetrics; + PTableLongMetrics = ^TTableLongMetrics; + + TShortMetrics = Short; + TTableShortMetrics = array[0..255] of TShortMetrics; + PTableShortMetrics = ^TTableShortMetrics; + +{ + (* table "OS/2" *) + + TOS2_Table = record + version : UShort; (* $0001 *) + xAvgCharWidth : Short; + usWeightClass : UShort; + usWidthClass : UShort; + fsType : Short; + ySubscriptXSize : Short; + ySubscriptYSize : Short; + ySubScriptXOffset : Short; + ySubscriptYOffset : Short; + ySuperscriptXSize : Short; + ySuperscriptYSize : Short; + ySuperscriptXOffset : Short; + ySuperscriptYOffset : Short; + yStrikeoutSize : Short; + yStrikeoutPosition : Short; + sFamilyClass : Short; + panose : array[0..9] of Byte; + ulUnicodeRange1 : ULong; (* bits 0-31 *) + ulUnicodeRange2 : ULong; (* bits 32-63 *) + ulUnicodeRange3 : ULong; (* bits 64-95 *) + ulUnicodeRange4 : ULong; (* bits 96-127 *) + achVendID : array[0..3] of Byte; + fsSelection : UShort; + usFirstCharIndex : UShort; + usLastCharIndex : UShort; + sTypoAscender : UShort; + sTypoDescender : UShort; + sTypoLineGap : UShort; + usWinAscent : UShort; + usWinDescent : UShort; + + (* only version 1 tables *) + ulCodePageRange1 : ULong; + ulCodePageRange2 : ULong; + end; + + (* table "post" *) + + TPostscript = record + FormatType : TT_Fixed; + italicAngle : TT_Fixed; + underlinePosition : Short; + underlineThickness : Short; + isFixedPitch : ULong; + minMemType42 : ULong; + maxMemType42 : ULong; + minMemType1 : ULong; + maxMemType1 : ULong; + end; +} + (* table "name" *) + + (* table "name" *) + + TName_Record = record + + platformID : UShort; + encodingID : UShort; + languageID : UShort; + nameID : UShort; + length : UShort; + offset : UShort; + end; + PName_Record = ^TName_Record; + TName_Records = array[0..0] of TName_Record; + PName_Records = ^TName_Records; + + + PName_Table = ^TName_Table; + TName_Table = record + + format : UShort; + numNameRecords : UShort; + storageOffset : UShort; + names : PName_Records; + storage : PByte; + end; + + + PHdmx_Record = ^THdmx_Record; + THdmx_Record = record + ppem : Byte; + max_width : Byte; + widths : PByte; + end; + + THdmx_Records = array[0..19] of THdmx_Record; + PHdmx_Records = ^THdmx_Records; + + THdmx = record + version : UShort; + num_records : Short; + records : PHdmx_Records; + end; + +implementation + +end. + diff --git a/pascal/lib/tttypes.pas b/pascal/lib/tttypes.pas new file mode 100644 index 0000000..7450b4d --- /dev/null +++ b/pascal/lib/tttypes.pas @@ -0,0 +1,102 @@ +(******************************************************************* + * + * TTTypes.pas 1.0 + * + * Global internal types definitions + * + * Copyright 1996, 1997 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************) + +unit TTTypes; + +interface + +uses FreeType; + +type + + (*********************** SIMPLE PRIMITIVE TYPES *******************) + + (* BYTE is already defined in Pascal *) + (* They are equivalent to C unsigned chars *) + + UShort = Word; (* unsigned short integer, must be on 16 bits *) + Short = Integer; (* signed short integer, must be on 16 bits *) + + Long = Longint; + ULong = LongInt; (* unsigned long integer, must be on 32 bits *) + (* NOTE : There is no 'LongWord' in Pascal, *) + (* but the unsigned ops are all in *) + (* the inline assembly routines *) + +{$IFDEF USE32} + Int = LongInt; (* the 'int' type is used for loop counters and *) +{$ELSE} (* indexes.. Their size must be the one a given *) + Int = Integer; (* system handles most easily ( 16 bits on Turbo *) +{$ENDIF} (* and 32 on Virtual Pascals ) *) + + TByteArray = array[0..1000] of Byte; + PByte = ^TByteArray; + + TShortArray = array[0..1000] of Short; + PShort = ^TShortArray; + + TUShortArray = array[0..1000] of UShort; + PUShort = ^TUShortArray; + + TStorage = array[0..16000] of Long; + PStorage = ^TStorage; + PLong = PStorage; + PULong = PStorage; + + TError = boolean; + + (***************** FreeType Internal Types *****************************) + + TCoordinates = array[0..1023] of TT_F26Dot6; + PCoordinates = ^TCoordinates; + + PTouchTable = PByte; + + TVecRecord = record + n : Int; (* number of points *) + org_x : PCoordinates; (* original coordinates arrays *) + org_y : PCoordinates; + cur_x : PCoordinates; (* current coordinates arrays *) + cur_y : PCoordinates; + touch : PTouchTable; (* touch flags array *) + end; + (* This type is used to describe each point zone in the interpreter *) + +const + + TT_Round_Off = 5; + TT_Round_To_Half_Grid = 0; + TT_Round_To_Grid = 1; + TT_Round_To_Double_Grid = 2; + TT_Round_Up_To_Grid = 4; + TT_Round_Down_To_Grid = 3; + TT_Round_Super = 6; + TT_ROund_Super_45 = 7; + + Success = False; + Failure = True; + + TT_Flag_Touched_X = $02; (* X touched flag *) + TT_Flag_Touched_Y = $04; (* Y touched flag *) + + TT_Flag_Touched_Both = TT_Flag_Touched_X or TT_FLag_Touched_Y; + + TT_Flag_On_Curve = $01; (* Point is On curve *) + +implementation + +end. diff --git a/pascal/test/codetv.pas b/pascal/test/codetv.pas new file mode 100644 index 0000000..9e9b3a0 --- /dev/null +++ b/pascal/test/codetv.pas @@ -0,0 +1,248 @@ +{****************************************************************************} +{* *} +{* CodeView.PAS *} +{* *} +{* This unit implements a simple TrueType bytecode viewer for the *} +{* FREETYPE project debugger. *} +{* *} +{****************************************************************************} + +Unit CodeTV; + +interface + +uses Objects, Views, Drivers, TTTypes, TTDebug; + +{$I DEBUGGER.INC} + +type + + { TCodeViewer } + + { This TView is a simple code list viewer ( IP + focused + breaks ) } + + PCodeViewer = ^TCodeViewer; + TCodeViewer = object( TListViewer ) + + constructor Init( var Bounds : TRect; + ARange : PRangeRec ); + + procedure Draw; virtual; + procedure HandleEvent( var Event : TEvent ); virtual; + + procedure Change_Range( ARange : PRangeRec ); + procedure Change_Focus( ALine : integer ); + + procedure Get_Cursor_Addr( P : PLong ); + + private + CodeRange : PRangeRec; + IP : Int; + end; + + { TCodeWindow } + + PCodeWindow = ^TCodeWindow; + TCodeWindow = object( TWindow ) + CodeView : PCodeViewer; + constructor Init( var Bounds : TRect; + ARange : PRangeRec ); + end; + +implementation + +{ TCodeViewer } + +constructor TCodeViewer.Init; +begin + inherited Init( Bounds, 1, nil, nil ); + + GrowMode := gfGrowHiX or gfGrowHiY; + DragMode := dmDragGrow or dmLimitLoX or dmLimitLoY; + EventMask := EventMask or evWave; + + IP := 0; + + Change_Range( ARange ); +end; + + +procedure TCodeViewer.Change_Range; +begin + codeRange := ARange; + + if codeRange <> nil then + SetRange( codeRange^.NLines ) + else + SetRange( 0 ); +end; + +procedure TCodeViewer.Change_Focus; +begin + + if ALine < 0 then + begin + IP := -1; + DrawView; + exit; + end; + + if ALine >= TopItem + Size.Y then TopItem := ALine; + + if codeRange <> nil then + begin + FocusItem( ALine ); + IP := codeRange^.Disassembled^[ALine]; + end; + DrawView; +end; + + +procedure TCodeViewer.Get_Cursor_Addr( P : PLong ); +begin + with codeRange^ do + begin + if (Focused < 0) or (Focused >= NLines) then + P^[0] := -1 + else + P^[0] := disassembled^[Focused]; + end; +end; + + +procedure TCodeViewer.HandleEvent( var Event : TEvent ); +var + Limits : TRect; + Mini, Maxi : Objects.TPoint; +begin + + inherited HandleEvent(Event); + + case Event.What of + + evCommand : case Event.Command of + + cmChangeRange : Change_Range( Event.InfoPtr ); + + cmQueryCursorAddr : Get_Cursor_Addr( Event.InfoPtr ); + + cmResize: begin + Owner^.GetExtent(Limits); + SizeLimits( Mini, Maxi ); + DragView(Event, DragMode, Limits, Mini, Maxi ); + ClearEvent(Event); + end; + + end; + + evWave : case Event.Command of + + cmReFocus : Change_Focus( Event.InfoInt ); + + end; + end; +end; + + +procedure TCodeViewer.Draw; +const + Colors : array[0..3] of byte + = ($1E,$40,$0E,$30); + Prefix : array[1..3] of Char + = ( 'f', 'c', 'g' ); +var + I, J, Item : Int; + B : TDrawBuffer; + S : String; + Indent : Int; + Ligne : Int; + + Color : word; + + On_BP : boolean; + BP : PBreakPoint; + +begin + +{ + Colors[0] := GetColor(1); (* Normal line *) + Colors[1] := GetColor(2); (* Normal breakpoint *) + Colors[2] := GetColor(3); (* Focused line *) + Colors[3] := GetColor(4); (* Focused breakpoint *) +} + if HScrollBar <> nil then Indent := HScrollBar^.Value + else Indent := 0; + + with CodeRange^ do + begin + + BP := Breaks; + + if (BP <> nil) and (NLines > TopItem) then + while (BP <> nil) and (BP^.Address < Disassembled^[TopItem]) do + BP := BP^.Next; + + for I := 0 to Self.Size.Y-1 do + begin + + Item := TopItem + I; + + Color := 0; + + if Item < NLines then + begin + + Ligne := Disassembled^[Item]; + + if (BP <> nil) and (BP^.Address = Ligne) then + begin + Color := 1; + Repeat + BP := BP^.Next + until (BP = nil) or (BP^.Address > Ligne); + end; + + if (Range > 0) and + ( Focused = Item ) then + + Color := Color or 2; + + S := ' ' + Cur_U_Line( Code, Ligne ); + + S[2] := Prefix[index]; + + S := copy( S, 1 + Indent, Self.Size.X ); + + if Ligne = IP then + begin + S[1] := '='; + S[7] := '>'; + end + end + else + begin + S := ''; + end; + + Color := Colors[Color]; + + MoveChar( B, ' ', Color, Self.Size.X ); + MoveStr( B, S, Color ); + + WriteLine( 0, I, Self.Size.X, 1, B ); + end; + end; +end; + +{ TCodeWindow } + +constructor TCodeWindow.Init; +begin + inherited Init( Bounds,'Code',wnNoNumber ); + GetExtent( Bounds ); + Bounds.Grow(-1,-1); + New( CodeView, Init( Bounds, ARange ) ); + Insert( CodeView ); +end; + +end. diff --git a/pascal/test/common.pas b/pascal/test/common.pas new file mode 100644 index 0000000..daa4064 --- /dev/null +++ b/pascal/test/common.pas @@ -0,0 +1,84 @@ +Unit Common; + +interface + +const + Max_Arguments = 1024; + +var + num_arguments : integer; + (* the number of arguments contained in the 'arguments' array *) + + arguments : array[0..Max_Arguments-1] of ^string; + (* This array will hold all arguments after wildcard expansion *) + (* note that it will not contain the original arguments that *) + (* were before 'first_argument' of Expand_Wildcards *) + + procedure Expand_WildCards( first_argument : integer; + default_extension : string ); + (* expand all wildcards into filenames *) + +implementation + +uses Dos; + + procedure Split( Original : String; + var Base : String; + var Name : String ); + var + n : integer; + begin + n := length(Original); + + while ( n > 0 ) do + if ( Original[n] = '\' ) or + ( Original[n] = '/' ) then + begin + Base := Copy( Original, 1, n-1 ); + Name := Copy( Original, n+1, length(Original) ); + exit; + end + else + dec(n); + + Base := ''; + Name := Original; + end; + + + procedure Expand_WildCards( first_argument : integer; + default_extension : string ); + var + i, n : integer; + base, name : string; + SRec : SearchRec; + begin + num_arguments := 0; + i := first_argument; + + while ( i <= ParamCount ) do + begin + Split( ParamStr(i), base, name ); + if base <> '' then + base := base + '\'; + + FindFirst( base+name, Archive+ReadOnly+Hidden, SRec ); + if DosError <> 0 then + FindFirst( base+name+default_extension, AnyFile, SRec ); + + while (DosError = 0) and (num_arguments < Max_Arguments) do + begin + GetMem( arguments[num_arguments], length(base)+length(SRec.Name)+1 ); + arguments[num_arguments]^ := base + SRec.Name; + inc( num_arguments ); + FindNext( SRec ); + end; + + {$IFDEF OS2} + FindClose( SRec ); + {$ENDIF} + inc( i ); + end; + end; + +end. diff --git a/pascal/test/debugger.inc b/pascal/test/debugger.inc new file mode 100644 index 0000000..cd09439 --- /dev/null +++ b/pascal/test/debugger.inc @@ -0,0 +1,42 @@ +{ DEBUGGER.INC : Constantes des commandes du debugger FREETYPE } + +const + + evWave = $200; { Broadcast messages } + + cmNewWin = 200; + cmFileOpen = 201; + + cmNewExecution = 300; + cmRefocus = 301; + cmChangeRange = 302; + cmQueryCursorAddr = 303; + + cmRun = 400; + kb_val_Run = kbCtrlF9; + kb_str_Run = 'Ctrl-F9'; + + cmGotoCursor = 401; + kb_val_GotoCursor = kbF4; + kb_str_GotoCursor = 'F4'; + + cmTraceInto = 402; + kb_val_TraceInto = kbF7; + kb_str_TraceInto = 'F7'; + + cmStepOver = 403; + kb_val_StepOver = kbF8; + kb_str_StepOver = 'F8'; + + cmUntilReturn = 404; + kb_val_UntilReturn = kbAltF8; + kb_str_UntilReturn = 'Alt-F8'; + + cmToggleBreak = 500; + kb_val_ToggleBreak = kbCtrlF8; + + cmClearBreaks = 501; + + cmViewGlyph = 600; + kb_val_ViewGlyph = kbF9; + kb_str_ViewGlyph = 'F9'; diff --git a/pascal/test/debugger.pas b/pascal/test/debugger.pas new file mode 100644 index 0000000..37544d1 --- /dev/null +++ b/pascal/test/debugger.pas @@ -0,0 +1,924 @@ +program Debugger; + +uses +{$IFDEF OS2} + Use32, +{$ENDIF} + +(* Turbo Vision units *) + Drivers, + Objects, + Views, + Menus, + App, + MsgBox, + + Crt, + +(* FreeType units *) + FreeType, + TTInterp, + TTTypes, + TTMemory, + TTError, + TTTables, + TTObjs, + TTFile, + TTCalc, + TTDebug, + TTRaster, + +(* graphics system units *) + GDriver, + GMain, + GEvents, + +(* Debugger's Turbo Vision enhancements *) + CodeTv, + StackTv, + StateTv, + ZoneTv; + +{$I DEBUGGER.INC} + +(* define this variable if you want to debug the CVT rather than a *) +(* glyph's instruction set.. *) +{ $DEFINE DEBUG_CVT} + +const + Precis = 64; + + Screen_Width = 640; + Screen_Height = 480; + Screen_Cols = Screen_Width div 8; + Screen_Size = Screen_Cols * Screen_Height; + + Grid_Width = Screen_Width div 16; + Grid_Height = Screen_Height div 16; + Grid_Cols = Grid_Width div 8; + Grid_Size = Grid_Cols * Grid_Height; + + Screen_Center_X = Screen_Width div 2; + Screen_Center_Y = Screen_Height div 2; + + Grid_Center_X = Grid_Width div 2; + Grid_Center_Y = Grid_Height div 2; + + Profile_Buff_Size = 64000; + + +type + TDebug_Mode = ( debug_code, view_glyph ); + + TMyApp = object( TApplication ) + constructor Init; + procedure NewWindow; virtual; + procedure InitMenuBar; virtual; + procedure HandleEvent( var Event : TEvent ); virtual; + + procedure Single_Step; + procedure Execute_Loop; + procedure New_Execution; + procedure ReFocus; + end; + + TEtat = ( etat_Termine, etat_Arret, etat_Execution ); + + TVolatileBreakPoint = record + range : Int; + address : Int; + end; + +var + CW : PCodeWindow; + SW : PStackWindow; + GW : PStateWindow; + ZW : PZoneWindow; + + Code_Range : array[1..3] of PCodeRange; + + Gen_Range : array[1..3] of TRangeRec; + + old_Range : Int; + + stream : TT_Stream; + + the_face : TT_Face; + the_glyph : TT_Glyph; + the_instance : TT_Instance; + + face : PFace; + glyph : PGlyph; + glyph2 : PGlyph; + instance : PInstance; + exec : PExec_Context; + + error : TT_Error; + + Etat : TEtat; + + Volatiles : PBreakPoint; + + xCoord : TT_PCoordinates; + yCoord : TT_PCoordinates; + Flag : TT_PTouchTable; + + Bitmap_small : TT_Raster_Map; + Bitmap_big : TT_Raster_Map; + + display_outline : boolean; + hint_glyph : boolean; + + debug_mode : TDebug_Mode; + MyApp : TMyApp; + + Range : Int; + P : PByteArray; + FileName : String; + Font_Buffer : PStorage; + Out_File : Text; + T, I : int; + + glyph_number : Int; + point_size : Int; + +procedure Initialize; +var + i : int; +begin + for i := 1 to 3 do Code_Range[i] := Get_CodeRange(exec,i); + for i := 1 to 3 do Generate_Range( Code_Range[i], i, Gen_Range[i] ); + + Volatiles := nil; + + display_outline := true; + Debug_Mode := debug_code; +end; + +(******************************************************************* + * + * Function : InitRows + * + * Description : Allocates the target bitmaps + * + *****************************************************************) + +Procedure Init_Engine; +var + P: Pointer; +begin + + (* The big bitmap will contain the grid, the glyph contours and *) + (* the magnified bitmap *) + + Bitmap_big.rows := Screen_Height; + Bitmap_big.cols := Screen_Cols; + Bitmap_big.width := Screen_Width; + Bitmap_big.flow := TT_Flow_Up; + Bitmap_big.size := Screen_Size; + + GetMem( Bitmap_big.buffer, Bitmap_big.size ); + if Bitmap_big.buffer = NIL then + begin + Writeln('ERREUR:InitRows:Not enough memory to allocate big BitMap'); + halt(1); + end; + + (* The small bitmap contains the rendered glyph, and is then later *) + (* magnified into the big bitmap *) + + Bitmap_small.rows := Grid_Height; + Bitmap_small.cols := Grid_Cols; + Bitmap_small.width := Grid_Width; + Bitmap_small.flow := TT_Flow_Up; + Bitmap_small.size := Grid_Size; + + GetMem( Bitmap_small.buffer, Bitmap_small.size ); + if Bitmap_small.buffer = NIL then + begin + Writeln('ERREUR:InitRows:Not enough memory to allocate big BitMap'); + halt(1); + end; + + FillChar( Bitmap_big.Buffer^, Bitmap_big.Size, 0 ); + FillChar( Bitmap_small.Buffer^, Bitmap_small.size, 0 ); +end; + +(******************************************************************* + * + * Function : ClearData + * + * Description : Clears the bitmaps + * + *****************************************************************) + +Procedure ClearData; +var i: integer; +begin + FillChar( Bitmap_big. Buffer^, Bitmap_big. Size, 0 ); + FillChar( Bitmap_small.Buffer^, Bitmap_small.size, 0 ); +end; + + +function Render_Magnified : boolean; +label + Exit_1; +type + TBlock = array[0..7] of Byte; + PBlock = ^TBlock; +const +{ + Grid_Empty : TBlock + = ( $10, $10, $10, $FF, $10, $10, $10, $10 ); +} + Grid_Pixel2 : TBlock + = ( $FE, $FE, $FE, $FE, $FE, $FE, $FE, $00 ); + + Pixel_Center_X = 3; + Pixel_Center_Y = 3; + + Grid_Empty : TBlock + = ( $00, $00, $00, $10, $00, $00, $00, $00 ); + + Grid_Pixel1 : TBlock + = ( $00, $00, $38, $38, $38, $00, $00, $00 ); + + Big_Center_X = Grid_Center_X*16 + Pixel_Center_X; + Big_Center_Y = Grid_Center_Y*16 + Pixel_Center_Y; + +var + r, w, w2, u, v, b, c : integer; + + x, y : Long; + + block : PBlock; + G : TT_Outline; + + pixel, + empty : PBlock; + + numPoints : integer; +begin + Render_Magnified := False; + + ClearData; + + numpoints := exec^.pts.n_points - 2; (* Remove phantom points *) + + for r := 0 to numPoints-1 do with exec^.pts do + begin + glyph2^.outline.points^[r].x := exec^.pts.cur^[r].x+64; + glyph2^.outline.points^[r].y := exec^.pts.cur^[r].y+64; + end; + + (* We begin rendering the glyph within the small bitmap *) + + G.n_contours := glyph^.outline.n_contours; + G.conEnds := glyph^.outline.conEnds; + G.Points := glyph^.outline.points; + G.points := glyph2^.outline.points; + G.Flags := glyph^.outline.flags; + + G.second_pass := True; + G.high_precision := True; + G.dropout_mode := 2; + + if Render_Glyph ( G, Bitmap_small ) then goto Exit_1; + + (* Then, we render the glyph outline in the bit bitmap *) + + for r := 0 to numPoints-1 do + begin + x := exec^.pts.cur^[r].x; + y := exec^.pts.cur^[r].y; + + x := (x - Precis*Grid_Center_X)*16 + Big_Center_X*Precis; + y := (y - Precis*Grid_Center_Y)*16 + Big_Center_Y*Precis; + + glyph2^.outline.points^[r].x := x + 8*64; + glyph2^.outline.points^[r].y := y + 8*64; + end; + + (* first compute the magnified coordinates *) + + G.n_contours := glyph^.outline.n_contours; + G.conEnds := glyph^.outline.conEnds; + G.Points := glyph^.outline.points; + G.points := glyph2^.outline.points; + G.Flags := glyph^.outline.flags; + + G.second_pass := True; + G.high_precision := True; + G.dropout_mode := 2; + + if display_outline then + if Render_Glyph ( G, Bitmap_big ) then goto Exit_1; + + (* Now, magnify the small bitmap, XORing it to the big bitmap *) + + r := 0; + w := 0; + b := 0; + + empty := @Grid_Empty; + + if display_outline then pixel := @Grid_Pixel1 + else pixel := @Grid_Pixel2; + + for y := 0 to Grid_Height-1 do + begin + + for x := 0 to Grid_Width-1 do + begin + + w2 := w; + b := b shr 1; + + if b = 0 then + begin + c := PByte(Bitmap_small.Buffer)^[r]; + b := $80; + inc( r ); + end; + + if c and b <> 0 then block := pixel + else block := empty; + + for v := 0 to 7 do + begin + PByte(Bitmap_Big.Buffer)^[w2] := PByte(Bitmap_Big.Buffer)^[w2] + xor block^[v]; + inc( w2, Bitmap_Big.cols ); + end; + + inc( w, 2 ); + + end; + + inc( w, 15*Screen_Cols ); + + end; + + + (* Display the resulting big bitmap *) + + Display_BitMap_On_Screen( Bitmap_big.Buffer^, 450, 80 ); + +Exit_1: + (* Clear the bitmaps *) + + Render_Magnified := True; +end; + + +function Render_Simple : boolean; +label + Exit_1; +var + r, w, w2, u, v, b, c : integer; + + x, y : Long; + + G : TT_Outline; + + numPoints : integer; +begin + Render_Simple := False; + + numpoints := exec^.pts.n_points - 2; (* Remove phantom points *) + + for r := 0 to numPoints-1 do with exec^.pts do + begin + glyph2^.outline.points^[r].x := exec^.pts.cur^[r].x + 32; + glyph2^.outline.points^[r].y := exec^.pts.cur^[r].y + 32; + end; + + (* We begin rendering the glyph within the small bitmap *) + + G.n_contours := glyph^.outline.n_contours; + G.conEnds := glyph^.outline.conEnds; + G.Points := glyph^.outline.points; + G.points := glyph2^.outline.points; + G.Flags := glyph^.outline.flags; + + G.second_pass := True; + G.high_precision := True; + G.dropout_mode := 2; + + + if display_outline then + if Render_Glyph ( G, Bitmap_big ) then goto Exit_1; + + (* Display the resulting big bitmap *) + + Display_BitMap_On_Screen( Bitmap_big.Buffer^, 450, 80 ); + +Exit_1: + (* Clear the bitmaps *) + + ClearData; + + Render_Simple := True; +end; + + +procedure Exit_Viewer; +begin + Restore_Screen; + debug_mode := debug_code; + MyApp.SetScreenMode( smCo80 + smFont8x8 ); + MyApp.Show; + MyApp.ReDraw; +end; + + +procedure Enter_Viewer; +begin + Set_Graph_Screen( Graphics_Mode_Mono ); + + if not Render_Magnified then + Exit_Viewer + else + debug_mode := view_glyph; +end; + + +procedure TMyApp.Execute_Loop; +var + Out : Boolean; + B : PBreakPoint; + + Event : TEvent; +begin + + Out := False; + etat := etat_Execution; + + repeat + + Single_Step; + + B := Find_BreakPoint( Volatiles, exec^.curRange, exec^.IP ); + if B <> nil then + begin + Clear_Break( Volatiles, B ); + Out := True; + end; + + if etat = etat_Execution then + begin + B := Find_BreakPoint( Gen_Range[exec^.curRange].Breaks, + exec^.curRange, + exec^.IP ); + if B <> nil then + begin + Out := True; + Etat := etat_Arret; + end; + end + else + Out := True; + + until Out; + +end; + + +procedure TMyApp.New_Execution; +var + Event : TEvent; +begin + Event.What := evWave; + Event.Command := cmNewExecution; + + HandleEvent( Event ); +end; + + +procedure TMyApp.Single_Step; +var + tempStr : string[6]; +begin + + if Run_Ins( exec ) then + begin + etat := etat_Termine; + str( exec^.error, tempStr ); + MessageBox( 'Error : '+tempStr, nil, mfError+mfOkButton ); + exit; + end; + + if exec^.IP >= exec^.codeSize then + + begin + if (exec^.curRange <> TT_CodeRange_CVT) or + Goto_CodeRange( exec, TT_CodeRange_Glyph, 0 ) then + + begin + etat := etat_Termine; + MessageBox( 'Completed', nil, mfInformation+mfOkButton ); + exit; + end; + end +end; + + +procedure TMyApp.ReFocus; +var + Event : TEvent; +begin + Event.What := evCommand; + + if Old_Range <> exec^.curRange then + begin + Old_Range := exec^.curRange; + Event.Command := cmChangeRange; + Event.InfoPtr := @Gen_Range[Old_Range]; + CW^.HandleEvent( Event ); + end; + + Event.What := evWave; + Event.Command := cmRefocus; + + if etat <> etat_Termine then + Event.InfoInt := Get_Dis_Line( Gen_Range[Old_Range], exec^.IP ) + else + Event.InfoInt := -1; + + HandleEvent( Event ); +end; + + +procedure TMyApp.NewWindow; +var + R : TRect; + RR : TRangeRec; +begin + Desktop^.GetExtent(R); + R.B.X := 32; + + Old_Range := exec^.curRange; + + New( CW, Init( R, @Gen_Range[Old_Range] ) ); + Desktop^.Insert(CW); + + Desktop^.GetExtent(R); + R.A.X := 32; + R.B.X := 50; + R.B.Y := R.B.Y div 2; + + New( SW, Init( R, exec ) ); + Desktop^.Insert(SW); + + Desktop^.GetExtent(R); + R.A.X := 50; + R.B.Y := R.B.Y div 2; + + New( GW, Init( R, exec ) ); + Desktop^.Insert(GW); + + Desktop^.GetExtent(R); + R.A.X := 32; + R.A.Y := R.B.Y div 2; + +{$IFDEF DEBUG_CVT} + New( ZW, Init( R, @exec^.twilight ) ); +{$ELSE} + New( ZW, Init( R, @exec^.pts ) ); +{$ENDIF} + Desktop^.Insert(ZW); + + etat := etat_Arret; +end; + + +procedure TMyApp.InitMenuBar; +var + R : TRect; +begin + GetExtent(R); + R.B.Y := R.A.Y + 1; + MenuBar := New( PMenuBar, Init( R, NewMenu( + NewSubMenu( '~F~ile', hcNoContext, NewMenu( + NewItem( '~O~pen','F3', kbF3, cmFileOpen, + hcNoContext, + nil )), + NewSubMenu( '~R~un', hcNoContext, + NewMenu( + NewItem( '~R~un','Ctrl-F9', kbCtrlF9, + cmRun, hcNoContext, + + NewItem( '~G~o to cursor','F4', kbF4, + cmGoToCursor, hcNoContext, + + NewItem( '~T~race into', 'F7', kbF7, + cmTraceInto, hcNoContext, + + NewItem( '~S~tep over', 'F8', kbF8, + cmStepOver, hcNoContext, + + NewItem( '~V~iew glyph', 'F9', kbF9, + cmViewGlyph, hcNoContext, + nil + ) + ) + ) + ) + ) + ), + nil + ))))); +end; + + +procedure TMyApp.HandleEvent( var Event : TEvent ); +var + Adr : Long; +begin + + if debug_mode = view_glyph then + begin + + case Event.What of + + evKeyDown : case Event.KeyCode of + + kbF2 : begin + display_outline := not display_outline; + + if not Render_Magnified then + Exit_Viewer; + + end; + + kbESC : Exit_Viewer; + + end; + end; + + ClearEvent( Event ); + exit; + + end; + + inherited HandleEvent(Event); + + case Event.What of + + evCommand : case Event.Command of + + cmNewWin : NewWindow; + + cmGoToCursor : begin + if etat = etat_Termine then exit; + + Event.Command := cmQueryCursorAddr; + Event.InfoPtr := @Adr; + + CW^.HandleEvent( Event ); + + Set_Break( Volatiles, + exec^.curRange, + Adr ); + + New_Execution; + Execute_Loop; + ReFocus; + end; + + cmTraceInto : begin + if etat = etat_termine then exit; + + New_Execution; + Single_Step; + ReFocus; + end; + + cmStepOver : begin + if etat = etat_termine then exit; + + New_Execution; + with exec^ do + case code^[IP] of + + $2A, (* LOOPCALL *) + $2B : (* CALL *) + + begin + + Set_Break( Volatiles, + exec^.curRange, + exec^.IP + + Get_Length( exec^.Code, + exec^.IP ) ); + Execute_Loop; + end; + + else + + Single_Step; + end; + + ReFocus; + end; + + cmViewGlyph : + Enter_Viewer; + + else + exit; + end; + + else + exit; + end; + + ClearEvent(Event); +end; + + +constructor TMyApp.Init; +begin + inherited Init; + SetScreenMode( smCo80 + smFont8x8 ); + NewWindow; +end; + + + +(******************************************************************* + * + * Function : LoadTrueTypeChar + * + * Description : + * + * Notes : + * + *****************************************************************) + +Function LoadTrueTypeChar( index : integer ) : boolean; +var + j, load_flag : int; + + rc : TT_Error; + +begin + LoadTrueTypeChar := FALSE; +(* + if hint_glyph then load_flag := TT_Load_Scale_Glyph or TT_Load_Hint_Glyph + else load_flag := TT_Load_Scale_Glyph; +*) + + load_flag := TT_Load_Scale_Glyph or TT_Load_Hint_Glyph or TT_Load_Debug; + + rc := TT_Load_Glyph( the_instance, + the_glyph, + index, + load_flag ); + if rc <> TT_Err_Ok then exit; + + LoadTrueTypeChar := TRUE; +end; + + +procedure Usage; +begin + Writeln('Simple Library Debugger -- part of the FreeType project'); + Writeln('-----------------------------------------------------'); + Writeln; + Writeln(' Usage : debugger glyph_number point_size fontfile[.ttf]'); + Writeln; + halt(2); +end; + + +var + Code : Int; + +begin + + if ParamCount <> 3 then + Usage; + + val( ParamStr(1), glyph_number, Code ); + if Code <> 0 then + Usage; + + val( ParamStr(2), point_size, Code ); + if Code <> 0 then + Usage; + + filename := ParamStr(3); + if Pos( '.', filename ) = 0 then filename := filename + '.ttf'; + + TT_Init_FreeType; + + error := TT_Open_Face( filename, the_face ); + if error <> TT_Err_Ok then + begin + Writeln('Could not open file ',filename ); + halt(1); + end; + + face := PFace(the_face.z); + + error := TT_New_Glyph( the_face, the_glyph ); + if error <> TT_Err_Ok then + begin + Writeln('ERROR : Could not get glyph' ); + Check_Error(error); + end; + + glyph2 := PGlyph( the_glyph.z ); + + error := TT_New_Glyph( the_face, the_glyph ); + if error <> TT_Err_Ok then + begin + Writeln('ERROR : Could not get glyph' ); + Check_Error(error); + end; + + glyph := PGlyph( the_glyph.z ); + + error := TT_New_Instance( the_face, the_instance ); + if error <> TT_Err_Ok then + begin + Writeln('ERROR: Could not create new instance' ); + Check_Error(error); + end; + + instance := PInstance(the_instance.z); + + exec := New_Context( instance ); + if exec = nil then + begin + Writeln( 'could not create execution context' ); + halt(1); + end; + + instance^.debug := true; + instance^.context := exec; + + TT_Set_Instance_Resolutions( the_instance, 96, 96 ); + +{$IFDEF DEBUG_CVT} + exec^.curRange := 1; + + (* code taken from freetype.pas *) + + with instance^.metrics do + begin + x_scale1 := ( Long(point_size*64) * x_resolution ) div 72; + x_scale2 := instance^.owner^.fontHeader.units_per_EM; + + y_scale1 := ( Long(point_size*64) * y_resolution ) div 72; + y_scale2 := x_scale2; + + if instance^.owner^.fontHeader.flags and 8 <> 0 then + begin + x_scale1 := (x_scale1 + 32) and -64; + y_scale1 := (y_scale1 + 32) and -64; + end; + + x_ppem := x_scale1 div 64; + y_ppem := y_scale1 div 64; + end; + + instance^.metrics.pointsize := point_size*64; + instance^.valid := False; + + if Instance_Reset( instance, true ) then + Panic1('Could not reset instance before executing CVT'); +{$ELSE} + error := TT_Set_Instance_PointSize( the_instance, point_size ); + if error <> TT_Err_Ok then + begin + Writeln('Could not execute CVT program' ); + Check_Error(error); + end; +{$ENDIF} + + Init_Engine; + +{$IFNDEF DEBUG_CVT} + if not LoadTrueTypeChar( glyph_number ) then + begin + Writeln('Error while loading glyph' ); + halt(1); + end; +{$ENDIF} + + exec^.instruction_trap := true; + +{$IFNDEF DEBUG_CVT} +(* Run_Context( exec, true ); *) +{$ENDIF} + + Initialize; + + MyApp.Init; + MyApp.Run; + MyApp.Done; + + TT_Done_FreeType; +end. diff --git a/pascal/test/dump.pas b/pascal/test/dump.pas new file mode 100644 index 0000000..7600b78 --- /dev/null +++ b/pascal/test/dump.pas @@ -0,0 +1,551 @@ +{***************************************************************************} +{* *} +{* FreeType Font Tester. *} +{* *} +{* This program is used to compare computed advance widths with the *} +{* values present in the "hdmx" table. It is now useless but remains *} +{* a good base for other quick font metrics checkers.. *} +{* *} +{* This source code has been compiled and run under both Virtual Pascal *} +{* on OS/2 and Borland's BP7. *} +{* *} +{***************************************************************************} + +program Dump; + +uses Crt, + Dos, +{$IFDEF OS2} + Use32, +{$ENDIF} + GMain, + GEvents, + GDriver, + FreeType, + TTCalc, + TTObjs, + TTTables; + +{ &PMTYPE NOVIO} + +{$DEFINE DEBUG} + +type + TPathName = string[128]; + +const + Precis = 64; + + Precis2 = Precis div 2; + + PrecisAux = 1024; + + Profile_Buff_Size = 32000; + + Max_Files = 1024; + +var + face : TT_Face; + instance : TT_Instance; + glyph : TT_Glyph; + + metrics : TT_Glyph_Metrics; + imetrics : TT_Instance_Metrics; + + props : TT_Face_Properties; + + ymin, ymax, xmax, xmin, xsize : longint; + res, old_res : int; + + numPoints, numContours : int; + + Bit : TT_Raster_Map; + + Rotation : int; (* Angle modulo 1024 *) + + num_glyphs : int; + + error : TT_Error; + gray_level : Boolean; + + display_outline : boolean; + hint_glyph : boolean; + scan_type : Byte; + + old_glyph : int; + cur_glyph : int; + + scale_shift : Int; + + grayLines : array[0..2048] of Byte; + + filenames : array[0..Max_Files-1] of ^TPathName; + +(******************************************************************* + * + * Function : Set_Raster_Area + * + *****************************************************************) + + procedure Set_Raster_Area; + begin + Bit.rows := vio_Height; + Bit.width := vio_Width; + Bit.flow := TT_Flow_Up; + + if gray_level then + Bit.cols := Bit.width + else + Bit.cols := (Bit.width+7) div 8; + + Bit.size := Bit.rows * Bit.cols; + end; + +(******************************************************************* + * + * Function : Clear_Data + * + *****************************************************************) + + procedure Clear_Data; + begin + if gray_level then + fillchar( Bit.buffer^, Bit.size, gray_palette[0] ) + else + fillchar( Bit.buffer^, Bit.size, 0 ); + end; + +(******************************************************************* + * + * Function : Init_Engine + * + *****************************************************************) + + procedure Init_Engine( maxRes : Int ); + begin + Set_Raster_Area; + GetMem( Bit.buffer, Bit.size ); + Clear_Data; + end; + +(******************************************************************* + * + * Function : Reset_Scale + * + *****************************************************************) + + function Reset_Scale( res : Int ) : Boolean; + begin + error := TT_Set_Instance_Pointsize( instance, res ); + Reset_Scale := (error = TT_Err_Ok); + end; + + + procedure Split( Original : String; + var Base : String; + var Name : String ); + var + n : integer; + begin + n := length(Original); + + while ( n > 0 ) do + if ( Original[n] = '\' ) or + ( Original[n] = '/' ) then + begin + Base := Copy( Original, 1, n-1 ); + Name := Copy( Original, n+1, length(Original) ); + exit; + end + else + dec(n); + + Base := ''; + Name := Original; + end; + +(******************************************************************* + * + * Function : LoadTrueTypeChar + * + * Description : Loads a single glyph into the xcoord, ycoord and + * flag arrays, from the instance data. + * + *****************************************************************) + +Function LoadTrueTypeChar( index : integer; + hint : boolean ) : boolean; +var + j, load_flag : int; + + result : TT_Error; + +begin + LoadTrueTypeChar := True; + + if hint then load_flag := TT_Load_Scale_Glyph or TT_Load_Hint_Glyph + else load_flag := TT_Load_Scale_Glyph; + + result := TT_Load_Glyph( instance, + glyph, + index, + load_flag ); + if result <> TT_Err_Ok then + exit; + + LoadTrueTypeChar := False; +end; + + +var + Error_String : String; + ine : Int; + +procedure Dump_AW( _face : TT_Face ); +var + i, j, n : integer; + + x, y : longint; + + start_x, + start_y, + step_x, + step_y : longint; + + fail : Int; + face : PFace; + + rec : PHdmx_Record; + +begin + + face := PFace(_face.z); + + rec := nil; + + for n := 0 to face^.hdmx.num_records-1 do + if face^.hdmx.records^[n].ppem = imetrics.x_ppem then + rec := @face^.hdmx.records^[n]; + + if rec = nil then + begin + Writeln('Pas de hdmx record pour ', imetrics.x_ppem, ' ppem'); + exit; + end; + + ine := 0; + while ine < num_glyphs do + begin + + if not LoadTrueTypeChar( ine, true ) then + begin + + TT_Get_Glyph_Metrics( glyph, metrics ); + + x := metrics.advance div 64; + + if rec^.widths^[ine] <> x then + begin + Write( '(',ine:3,':',rec^.widths^[ine]:2,' ',x:2,')' ); + end; + end; + + inc( ine ); + end; + Writeln; + Writeln; +end; + + + +procedure Erreur( s : String ); +begin + Restore_Screen; + Writeln( 'Error : ', s, ', error code = ', error ); + Halt(1); +end; + + +procedure Usage; +begin + Writeln('Simple TrueType Glyphs viewer - part of the FreeType project' ); + Writeln; + Writeln('Usage : ',paramStr(0),' FontName[.TTF]'); + Halt(1); +end; + + + +var + i: integer; + heure, + min1, + min2, + sec1, + sec2, + cent1, + cent2 : +{$IFDEF OS2} + longint; +{$ELSE} + word; +{$ENDIF} + + C : Char; + + Filename : String; + +label Fin; + +var + Fail : Int; + glyphStr : String[4]; + ev : Event; + + Code : Int; + + init_memory, end_memory : LongInt; + + num_args : Integer; + point_size : Integer; + num_files : Integer; + cur_file : Integer; + first_arg : Int; + sortie : Boolean; + + base : string; + name : string; + + SRec : SearchRec; + +begin + TextMode( co80+Font8x8 ); + + TT_Init_FreeType; + + num_args := ParamCount; + + if num_args = 0 then + Usage; + + first_arg := 1; + + gray_level := False; + + if ParamStr(first_arg) = '-g' then + begin + inc( first_arg ); + gray_level := True; + end; + + if first_arg > num_args+1 then + Usage; + + val( ParamStr(first_arg), point_size, Code ); + if Code <> 0 then + point_size := 24 + else + inc( first_arg ); + + num_files := 0; + + while first_arg <= num_args do + begin + Split( ParamStr(first_arg), base, name ); + if base <> '' then + base := base + '\'; + + FindFirst( base+name, Archive+ReadOnly+Hidden, SRec ); + if DosError <> 0 then + FindFirst( base+name+'.ttf', AnyFile, SRec ); + + while (DosError = 0) and (num_files < Max_Files) do + begin + GetMem( filenames[num_files], length(base)+length(SRec.Name)+1 ); + filenames[num_files]^ := base + SRec.Name; + inc( num_files ); + FindNext( SRec ); + end; + + {$IFDEF OS2} + FindClose( SRec ); + {$ENDIF} + inc( first_arg ); + end; + + cur_file := 0; + + if num_files = 0 then + begin + Writeln('Could not find file(s)'); + Halt(3); + end; + +(* + if gray_level then + begin + if not Set_Graph_Screen( Graphics_Mode_Gray ) then + Erreur( 'could not set grayscale graphics mode' ); + end + else + begin + if not Set_Graph_Screen( Graphics_Mode_Mono ) then + Erreur( 'could not set mono graphics mode' ); + end; +*) + + Init_Engine( point_size ); + + repeat + + FileName := Filenames[cur_file]^; + + if Pos('.',FileName) = 0 then FileName:=FileName+'.TTF'; + + error := TT_Open_Face( filename, face ); + if error <> TT_Err_Ok then + Erreur( 'Could not open '+filename ); + + TT_Get_Face_Properties( face, props ); + + num_glyphs := props.num_Glyphs; + + i := length(FileName); + while (i > 1) and (FileName[i] <> '\') do dec(i); + + FileName := Copy( FileName, i+1, length(FileName) ); + + error := TT_New_Glyph( face, glyph ); + if error <> TT_Err_Ok then + Erreur('Could not create glyph container'); + + error := TT_New_Instance( face, instance ); + if error <> TT_Err_Ok then + Erreur('Could not create instance'); + + Rotation := 0; + Fail := 0; + res := point_size; + scan_type := 2; + + if ( gray_level ) then scale_shift := 1 + else scale_shift := 0; + + Reset_Scale( res ); + + display_outline := true; + hint_glyph := true; + + old_glyph := -1; + old_res := res; + cur_glyph := 0; + + sortie := false; + + Repeat + +(* + if Render_ABC( cur_glyph ) then + inc( Fail ) + else + Display_Bitmap_On_Screen( Bit.Buffer^, Bit.rows, Bit.cols ); + + Clear_Data; + + Print_XY( 0, 0, FileName ); + + TT_Get_Instance_Metrics( instance, imetrics ); + + Print_Str(' point size = '); + Str( imetrics.pointSize:3, glyphStr ); + Print_Str( glyphStr ); + + Print_Str(' glyph = '); + Str( cur_glyph, glyphStr ); + Print_Str( glyphStr ); + + Print_XY( 0, 1, 'Hinting (''z'') : ' ); + if hint_glyph then Print_Str('on ') + else Print_Str('off'); + + Print_XY( 0, 2, 'scan type(''e'') : ' ); + case scan_type of + 0 : Print_Str('none '); + 1 : Print_Str('level 1'); + 2 : Print_Str('level 2'); + 4 : Print_Str('level 4'); + 5 : Print_Str('level 5'); + end; +*) + TT_Get_Instance_Metrics( instance, imetrics ); + Writeln( Filename,' ',imetrics.pointsize,' pts = ',imetrics.x_ppem,' ppem' ); + + Dump_AW( face ); + + Get_Event(ev); + + case ev.what of + + event_Quit : goto Fin; + + event_Keyboard : case char(ev.info) of + + 'n' : begin + sortie := true; + if cur_file+1 < num_files then + inc( cur_file ); + end; + + 'p' : begin + sortie := true; + if cur_file > 1 then + dec( cur_file ); + end; + + 'z' : hint_glyph := not hint_glyph; + + + 'e' : begin + inc( scan_type ); + if scan_type = 3 then scan_type := 4; + if scan_type >= 6 then scan_type := 0; + end; + end; + + event_Scale_Glyph : begin + inc( res, ev.info ); + if res < 1 then res := 1; + if res > 1400 then res := 1400; + end; + + event_Change_Glyph : begin + inc( cur_glyph, ev.info ); + if cur_glyph < 0 then cur_glyph := 0; + if cur_glyph >= num_glyphs + then cur_glyph := num_glyphs-1; + end; + end; + + if res <> old_res then + begin + if not Reset_Scale(res) then + Erreur( 'Could not resize font' ); + old_res := res; + end; + + Until sortie; + + TT_Done_Glyph( glyph ); + TT_Close_Face( face ); + + until false; + + Fin: + Restore_Screen; + + Writeln; + Writeln('Fails : ', Fail ); + + TT_Done_FreeType; +end. + diff --git a/pascal/test/gdriver.pas b/pascal/test/gdriver.pas new file mode 100644 index 0000000..89432c9 --- /dev/null +++ b/pascal/test/gdriver.pas @@ -0,0 +1,123 @@ +(******************************************************************* + * + * gdriver : Graphics utility driver generic interface 1.1 + * + * Generic interface for all drivers of the graphics utility used + * by the FreeType test programs. + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************) + +Unit GDriver; + +interface + +uses GEvents, GMain; + + (* Note that we now support an event based model, even with */ + /* full-screen modes. It is the responsability of the driver */ + /* to map its events to the TEvent structure when called */ + /* through Get_Event *) + +type + Event = record + what : GEvent; (* event class *) + info : Int; (* event parameter *) + end; + + (* the event classes are defined in the file 'gevents.h' included *) + (* by the test programs, not by the graphics utility *) + + procedure Get_Event( var ev : Event ); + (* get last event. In full-screen modes, a key-stroke must be */ + /* translated to an event class with a parameter. *) + + function Driver_Set_Graphics( mode : Int ) : boolean; + (* A call to this function must set the graphics mode, the Vio *) + (* variable, as well as the values vio_ScanLineWidth, vio_Width *) + (* and vio_Height *) + + function Driver_Restore_Mode : boolean; + (* Restore previous mode or release display buffer/window *) + + procedure Driver_Display_Bitmap( var buff; line, col : Int ); + (* Display bitmap on screen *) + +implementation + +{$IFDEF OS2} + + uses Os2Base, CRT; + {$I GDRV_OS2.INC} + +{$ELSE} + + uses CRT; + {$I GDRV_DOS.INC} + +{$ENDIF} + +type + Translator = record + key : char; + ev_class : GEvent; + ev_info : Int; + end; + +const + Num_Translators = 15; + + Translators : array[1..Num_Translators] of Translator + = ( + (key:#27; ev_class:event_Quit ; ev_info:0), + + (key:'x'; ev_class: event_Rotate_Glyph; ev_info: -1), + (key:'c'; ev_class: event_Rotate_Glyph; ev_info: 1), + (key:'v'; ev_class: event_Rotate_Glyph; ev_info: -16), + (key:'b'; ev_class: event_Rotate_Glyph; ev_info: 16), + + (key:'9'; ev_class: event_Change_Glyph; ev_info:-100), + (key:'0'; ev_class: event_Change_Glyph; ev_info: 100), + (key:'i'; ev_class: event_Change_Glyph; ev_info: -10), + (key:'o'; ev_class: event_Change_Glyph; ev_info: 10), + (key:'k'; ev_class: event_Change_Glyph; ev_info: -1), + (key:'l'; ev_class: event_Change_Glyph; ev_info: 1), + + (key:'+'; ev_class: event_Scale_Glyph; ev_info: 10), + (key:'-'; ev_class: event_Scale_Glyph; ev_info: -10), + (key:'u'; ev_class: event_Scale_Glyph; ev_info: 1), + (key:'j'; ev_class: event_Scale_Glyph; ev_info: -1) + ); + + procedure Get_Event( var ev : Event ); + var + i : Int; + c : char; + begin + c := ReadKey; + + for i := 1 to Num_Translators do + begin + if c = translators[i].key then + begin + ev.what := translators[i].ev_class; + ev.info := translators[i].ev_info; + exit; + end; + end; + + (* unrecognized keystroke *) + + ev.what := event_Keyboard; + ev.info := Int(c); + end; + +end. + diff --git a/pascal/test/gdrv_dos.inc b/pascal/test/gdrv_dos.inc new file mode 100644 index 0000000..f65daa5 --- /dev/null +++ b/pascal/test/gdrv_dos.inc @@ -0,0 +1,96 @@ + + { Restores screen to the original state } + + function Driver_Restore_Mode: boolean; + begin + asm + mov ax, $0003 + int $10 + end; + Driver_Restore_Mode := True; + end; + + function Driver_Set_Graphics( mode : Int ) : boolean; + var + rc : Int; + begin + Driver_Set_Graphics := False; + + rc := 0; + + case Mode of + + Graphics_Mode_Mono : begin + asm + mov ax, $0012 + int $10 + end; + Vio_ScanLineWidth := 80; + Vio_Width := 640; + Vio_Height := 480; + end; + + Graphics_Mode_Gray : begin + asm + mov ax, $0013 + int $10 + end; + Vio_ScanLineWidth := 320; + Vio_Width := 320; + Vio_Height := 200; + + (* default gray palette takes the gray levels *) + (* the standard VGA 256 colors mode *) + + gray_palette[0] := 0; + gray_palette[1] := 23; + gray_palette[2] := 27; + gray_palette[3] := 29; + gray_palette[4] := 31; + end; + else + rc := -1; + end; + + if rc <> 0 then exit; + + Vio := @Mem[$A000:0]; + + Driver_Set_Graphics := True; + end; + + + procedure Driver_Display_Bitmap; assembler; + asm + push ds + push bp + + les di, [Vio] + + cld + + mov cx,[Vio_ScanLineWidth] + mov bx,[col] + mov ax,[line] + dec ax + mul cx + add di,ax + mov dx,[line] + + lds si,[Buff] + + mov bp,bx + add bx,cx + + @1: + mov cx,bp + rep movsb + sub di,bx + dec dx + jnz @1 + + pop bp + pop ds + end; + + diff --git a/pascal/test/gdrv_os2.inc b/pascal/test/gdrv_os2.inc new file mode 100644 index 0000000..13c56de --- /dev/null +++ b/pascal/test/gdrv_os2.inc @@ -0,0 +1,148 @@ + + {$IFDEF DYNAMIC_VERSION} + {$Dynamic System} + {$L VPRTL.LIB} + {$ENDIF} + + + type + Ptr16Rec = record + Ofs,Sel: SmallWord; + end; + + var + OrgMode : VioModeInfo; + VioBufOfs : Longint; + Status : SmallWord; + + { BIOS Video Mode +#13 } + + const + VioMode_640x480x16 : VioModeInfo = + ( cb: SizeOf(VioModeInfo); + fbType: vgmt_Other + vgmt_Graphics; + Color: colors_16; + Col: 80; + Row: 35; + HRes: 640; + VRes: 480 + ); + + VioMode_320x200x256 : VioModeInfo = + ( cb: SizeOf(VioModeInfo); + fbType: vgmt_Other + vgmt_Graphics; + Color: colors_256; + Col: 40; + Row: 25; + HRes: 320; + VRes: 200 + ); + + VioBuf: VioPhysBuf = + ( pBuf: Ptr($A0000); + cb: 64*1024 + ); + + { Restores screen to the original state } + + function Driver_Restore_Mode: boolean; + begin + VioSetMode(OrgMode, 0); + Driver_Restore_Mode := True; + end; + + function Driver_Set_Graphics( mode : Int ) + : boolean; + var + rc : Int; + begin + Driver_Set_Graphics := False; + + { Save original video mode } + OrgMode.cb := SizeOf(VioModeInfo); + VioGetMode(OrgMode, 0); + + case Mode of + + Graphics_Mode_Mono : begin + rc := VioSetMode( VioMode_640x480x16, 0 ); + Vio_ScanLineWidth := 80; + Vio_Width := 640; + Vio_Height := 480; + end; + + Graphics_Mode_Gray : begin + rc := VioSetMode( VioMode_320x200x256, 0 ); + Vio_ScanLineWidth := 320; + Vio_Width := 320; + Vio_Height := 200; + + (* default gray palette takes the gray levels *) + (* the standard VGA 256 colors mode *) + + gray_palette[0] := 0; + gray_palette[1] := 23; + gray_palette[2] := 27; + gray_palette[3] := 29; + gray_palette[4] := 31; + end; + else + rc := -1; + end; + + { Set VGA 640x400x16 + video mode } + if rc <> 0 then exit; + + { Get selector for physical video buffer } + if VioGetPhysBuf(VioBuf, 0) <> 0 then exit; + + { Make flat pointer that points to the physical video buffer} + Ptr16Rec(VioBufOfs).Ofs := 0; + Ptr16Rec(VioBufOfs).Sel := VioBuf.Sel; + SelToFlat(Pointer(VioBufOfs)); + + { Clear the screen. Unlike function 0 of the BIOS INT 10h } + { VioSetMode doesn't clear the screen. } + FillChar(Pointer(VioBufOfs)^,64*1024,0); + Vio := PVioScreenBuffer(VioBufOfs); + + Driver_Set_Graphics := True; + end; + + + procedure Driver_Display_Bitmap; assembler; + asm + push esi + push edi + push ebx + push ecx + + mov esi,[Buff] + + mov ecx,[Vio_ScanLineWidth] + mov ebx,[Col] + mov eax,[Line] + + dec eax + mul ecx + + mov edi,[VioBufOfs] + add edi,eax + + mov edx,[line] + add ebx,[Vio_ScanLineWidth] + @1: + mov ecx,[col] + rep movsb + sub edi,ebx + dec edx + jnz @1 + + pop ecx + pop ebx + pop edi + pop esi + end; + diff --git a/pascal/test/gevents.pas b/pascal/test/gevents.pas new file mode 100644 index 0000000..c43466a --- /dev/null +++ b/pascal/test/gevents.pas @@ -0,0 +1,42 @@ +(******************************************************************* + * + * gevents test programs events definition 1.1 + * + * This file defines the events used by the FreeType test programs + * It is _not_ included by 'gmain.c'. This file is also used by the + * drivers to translate their own events in GEvents. + * + * Not a very good design, but we're not rewriting X.. + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************) + +Unit GEvents; + +interface + +type + GEvent = ( + event_None, + event_Quit, (* Quit program *) + + event_Keyboard, (* unknown keystroke *) + + event_Change_Glyph, + event_Rotate_Glyph, + event_Scale_Glyph, + + event_Change_ScanType, + event_Change_Instructions + ); + +implementation + +end. diff --git a/pascal/test/gmain.pas b/pascal/test/gmain.pas new file mode 100644 index 0000000..c193261 --- /dev/null +++ b/pascal/test/gmain.pas @@ -0,0 +1,474 @@ +(******************************************************************* + * + * gmain graphics utility main interface 1.1 + * + * This file defines a common interface, implemented in the body + * file 'gmain.c'. It relies on system dependent driver files, + * like 'gfs_os.c', whose interface is described in 'gdriver.h'. + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************) + +Unit GMain; + +interface + +const + Graphics_Mode_Mono = 1; + Graphics_Mode_Gray = 2; + +type + TVioScreenBuffer = array[0..0] of Byte; + PVioScreenBuffer = ^TVioScreenBuffer; + +{$IFDEF OS2} + Int = LongInt; +{$ELSE} + Int = Integer; +{$ENDIF} + +var + + Vio : PVioScreenBuffer; + (* pointer to VRAM or display buffer *) + + vio_ScanLineWidth : Int; + vio_Width : Int; + vio_Height : Int; + + gray_palette : array[0..4] of Byte; (* gray palette *) + + gcursor_x : int; + gcursor_y : int; + + gwindow_width : int; + gwindow_height : int; + + function Set_Graph_Screen( mode : int ) : boolean; + (* Set a Graphics Mode, chosen from the Graphics_Mode_xxx list *) + + function Restore_Screen : boolean; + (* Restore a previous ( or text ) video mode *) + + procedure Display_Bitmap_On_Screen( var buff; line, col : Int ); + (* display bitmap of 'line' line, and 'col' columns ( each *) + (* column mode of 1 byte *) + + procedure Goto_XY( x, y : int ); + + procedure Print_Str( str : string ); + + procedure Print_XY ( x, y : int; str : string ); + +implementation + +uses GDriver; + + type + TFunction_8x8 = procedure( x, y : Int; c : char ); + + TByte = array[0..0] of Byte; + PByte = ^TByte; + + var + Current_Mode : Byte; + Print_8x8 : TFunction_8x8; + + const + Font_8x8 : array[0..2047] of Byte + = ( + $00, $00, $00, $00, $00, $00, $00, $00, + $7E, $81, $A5, $81, $BD, $99, $81, $7E, + $7E, $FF, $DB, $FF, $C3, $E7, $FF, $7E, + $6C, $FE, $FE, $FE, $7C, $38, $10, $00, + $10, $38, $7C, $FE, $7C, $38, $10, $00, + $38, $7C, $38, $FE, $FE, $92, $10, $7C, + $00, $10, $38, $7C, $FE, $7C, $38, $7C, + $00, $00, $18, $3C, $3C, $18, $00, $00, + $FF, $FF, $E7, $C3, $C3, $E7, $FF, $FF, + $00, $3C, $66, $42, $42, $66, $3C, $00, + $FF, $C3, $99, $BD, $BD, $99, $C3, $FF, + $0F, $07, $0F, $7D, $CC, $CC, $CC, $78, + $3C, $66, $66, $66, $3C, $18, $7E, $18, + $3F, $33, $3F, $30, $30, $70, $F0, $E0, + $7F, $63, $7F, $63, $63, $67, $E6, $C0, + $99, $5A, $3C, $E7, $E7, $3C, $5A, $99, + $80, $E0, $F8, $FE, $F8, $E0, $80, $00, + $02, $0E, $3E, $FE, $3E, $0E, $02, $00, + $18, $3C, $7E, $18, $18, $7E, $3C, $18, + $66, $66, $66, $66, $66, $00, $66, $00, + $7F, $DB, $DB, $7B, $1B, $1B, $1B, $00, + $3E, $63, $38, $6C, $6C, $38, $86, $FC, + $00, $00, $00, $00, $7E, $7E, $7E, $00, + $18, $3C, $7E, $18, $7E, $3C, $18, $FF, + $18, $3C, $7E, $18, $18, $18, $18, $00, + $18, $18, $18, $18, $7E, $3C, $18, $00, + $00, $18, $0C, $FE, $0C, $18, $00, $00, + $00, $30, $60, $FE, $60, $30, $00, $00, + $00, $00, $C0, $C0, $C0, $FE, $00, $00, + $00, $24, $66, $FF, $66, $24, $00, $00, + $00, $18, $3C, $7E, $FF, $FF, $00, $00, + $00, $FF, $FF, $7E, $3C, $18, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $00, + $18, $3C, $3C, $18, $18, $00, $18, $00, + $6C, $6C, $6C, $00, $00, $00, $00, $00, + $6C, $6C, $FE, $6C, $FE, $6C, $6C, $00, + $18, $7E, $C0, $7C, $06, $FC, $18, $00, + $00, $C6, $CC, $18, $30, $66, $C6, $00, + $38, $6C, $38, $76, $DC, $CC, $76, $00, + $30, $30, $60, $00, $00, $00, $00, $00, + $18, $30, $60, $60, $60, $30, $18, $00, + $60, $30, $18, $18, $18, $30, $60, $00, + $00, $66, $3C, $FF, $3C, $66, $00, $00, + $00, $18, $18, $7E, $18, $18, $00, $00, + $00, $00, $00, $00, $00, $18, $18, $30, + $00, $00, $00, $7E, $00, $00, $00, $00, + $00, $00, $00, $00, $00, $18, $18, $00, + $06, $0C, $18, $30, $60, $C0, $80, $00, + $7C, $CE, $DE, $F6, $E6, $C6, $7C, $00, + $30, $70, $30, $30, $30, $30, $FC, $00, + $78, $CC, $0C, $38, $60, $CC, $FC, $00, + $78, $CC, $0C, $38, $0C, $CC, $78, $00, + $1C, $3C, $6C, $CC, $FE, $0C, $1E, $00, + $FC, $C0, $F8, $0C, $0C, $CC, $78, $00, + $38, $60, $C0, $F8, $CC, $CC, $78, $00, + $FC, $CC, $0C, $18, $30, $30, $30, $00, + $78, $CC, $CC, $78, $CC, $CC, $78, $00, + $78, $CC, $CC, $7C, $0C, $18, $70, $00, + $00, $18, $18, $00, $00, $18, $18, $00, + $00, $18, $18, $00, $00, $18, $18, $30, + $18, $30, $60, $C0, $60, $30, $18, $00, + $00, $00, $7E, $00, $7E, $00, $00, $00, + $60, $30, $18, $0C, $18, $30, $60, $00, + $3C, $66, $0C, $18, $18, $00, $18, $00, + $7C, $C6, $DE, $DE, $DC, $C0, $7C, $00, + $30, $78, $CC, $CC, $FC, $CC, $CC, $00, + $FC, $66, $66, $7C, $66, $66, $FC, $00, + $3C, $66, $C0, $C0, $C0, $66, $3C, $00, + $F8, $6C, $66, $66, $66, $6C, $F8, $00, + $FE, $62, $68, $78, $68, $62, $FE, $00, + $FE, $62, $68, $78, $68, $60, $F0, $00, + $3C, $66, $C0, $C0, $CE, $66, $3A, $00, + $CC, $CC, $CC, $FC, $CC, $CC, $CC, $00, + $78, $30, $30, $30, $30, $30, $78, $00, + $1E, $0C, $0C, $0C, $CC, $CC, $78, $00, + $E6, $66, $6C, $78, $6C, $66, $E6, $00, + $F0, $60, $60, $60, $62, $66, $FE, $00, + $C6, $EE, $FE, $FE, $D6, $C6, $C6, $00, + $C6, $E6, $F6, $DE, $CE, $C6, $C6, $00, + $38, $6C, $C6, $C6, $C6, $6C, $38, $00, + $FC, $66, $66, $7C, $60, $60, $F0, $00, + $7C, $C6, $C6, $C6, $D6, $7C, $0E, $00, + $FC, $66, $66, $7C, $6C, $66, $E6, $00, + $7C, $C6, $E0, $78, $0E, $C6, $7C, $00, + $FC, $B4, $30, $30, $30, $30, $78, $00, + $CC, $CC, $CC, $CC, $CC, $CC, $FC, $00, + $CC, $CC, $CC, $CC, $CC, $78, $30, $00, + $C6, $C6, $C6, $C6, $D6, $FE, $6C, $00, + $C6, $C6, $6C, $38, $6C, $C6, $C6, $00, + $CC, $CC, $CC, $78, $30, $30, $78, $00, + $FE, $C6, $8C, $18, $32, $66, $FE, $00, + $78, $60, $60, $60, $60, $60, $78, $00, + $C0, $60, $30, $18, $0C, $06, $02, $00, + $78, $18, $18, $18, $18, $18, $78, $00, + $10, $38, $6C, $C6, $00, $00, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $FF, + $30, $30, $18, $00, $00, $00, $00, $00, + $00, $00, $78, $0C, $7C, $CC, $76, $00, + $E0, $60, $60, $7C, $66, $66, $DC, $00, + $00, $00, $78, $CC, $C0, $CC, $78, $00, + $1C, $0C, $0C, $7C, $CC, $CC, $76, $00, + $00, $00, $78, $CC, $FC, $C0, $78, $00, + $38, $6C, $64, $F0, $60, $60, $F0, $00, + $00, $00, $76, $CC, $CC, $7C, $0C, $F8, + $E0, $60, $6C, $76, $66, $66, $E6, $00, + $30, $00, $70, $30, $30, $30, $78, $00, + $0C, $00, $1C, $0C, $0C, $CC, $CC, $78, + $E0, $60, $66, $6C, $78, $6C, $E6, $00, + $70, $30, $30, $30, $30, $30, $78, $00, + $00, $00, $CC, $FE, $FE, $D6, $D6, $00, + $00, $00, $B8, $CC, $CC, $CC, $CC, $00, + $00, $00, $78, $CC, $CC, $CC, $78, $00, + $00, $00, $DC, $66, $66, $7C, $60, $F0, + $00, $00, $76, $CC, $CC, $7C, $0C, $1E, + $00, $00, $DC, $76, $62, $60, $F0, $00, + $00, $00, $7C, $C0, $70, $1C, $F8, $00, + $10, $30, $FC, $30, $30, $34, $18, $00, + $00, $00, $CC, $CC, $CC, $CC, $76, $00, + $00, $00, $CC, $CC, $CC, $78, $30, $00, + $00, $00, $C6, $C6, $D6, $FE, $6C, $00, + $00, $00, $C6, $6C, $38, $6C, $C6, $00, + $00, $00, $CC, $CC, $CC, $7C, $0C, $F8, + $00, $00, $FC, $98, $30, $64, $FC, $00, + $1C, $30, $30, $E0, $30, $30, $1C, $00, + $18, $18, $18, $00, $18, $18, $18, $00, + $E0, $30, $30, $1C, $30, $30, $E0, $00, + $76, $DC, $00, $00, $00, $00, $00, $00, + $00, $10, $38, $6C, $C6, $C6, $FE, $00, + $7C, $C6, $C0, $C6, $7C, $0C, $06, $7C, + $00, $CC, $00, $CC, $CC, $CC, $76, $00, + $1C, $00, $78, $CC, $FC, $C0, $78, $00, + $7E, $81, $3C, $06, $3E, $66, $3B, $00, + $CC, $00, $78, $0C, $7C, $CC, $76, $00, + $E0, $00, $78, $0C, $7C, $CC, $76, $00, + $30, $30, $78, $0C, $7C, $CC, $76, $00, + $00, $00, $7C, $C6, $C0, $78, $0C, $38, + $7E, $81, $3C, $66, $7E, $60, $3C, $00, + $CC, $00, $78, $CC, $FC, $C0, $78, $00, + $E0, $00, $78, $CC, $FC, $C0, $78, $00, + $CC, $00, $70, $30, $30, $30, $78, $00, + $7C, $82, $38, $18, $18, $18, $3C, $00, + $E0, $00, $70, $30, $30, $30, $78, $00, + $C6, $10, $7C, $C6, $FE, $C6, $C6, $00, + $30, $30, $00, $78, $CC, $FC, $CC, $00, + $1C, $00, $FC, $60, $78, $60, $FC, $00, + $00, $00, $7F, $0C, $7F, $CC, $7F, $00, + $3E, $6C, $CC, $FE, $CC, $CC, $CE, $00, + $78, $84, $00, $78, $CC, $CC, $78, $00, + $00, $CC, $00, $78, $CC, $CC, $78, $00, + $00, $E0, $00, $78, $CC, $CC, $78, $00, + $78, $84, $00, $CC, $CC, $CC, $76, $00, + $00, $E0, $00, $CC, $CC, $CC, $76, $00, + $00, $CC, $00, $CC, $CC, $7C, $0C, $F8, + $C3, $18, $3C, $66, $66, $3C, $18, $00, + $CC, $00, $CC, $CC, $CC, $CC, $78, $00, + $18, $18, $7E, $C0, $C0, $7E, $18, $18, + $38, $6C, $64, $F0, $60, $E6, $FC, $00, + $CC, $CC, $78, $30, $FC, $30, $FC, $30, + $F8, $CC, $CC, $FA, $C6, $CF, $C6, $C3, + $0E, $1B, $18, $3C, $18, $18, $D8, $70, + $1C, $00, $78, $0C, $7C, $CC, $76, $00, + $38, $00, $70, $30, $30, $30, $78, $00, + $00, $1C, $00, $78, $CC, $CC, $78, $00, + $00, $1C, $00, $CC, $CC, $CC, $76, $00, + $00, $F8, $00, $B8, $CC, $CC, $CC, $00, + $FC, $00, $CC, $EC, $FC, $DC, $CC, $00, + $3C, $6C, $6C, $3E, $00, $7E, $00, $00, + $38, $6C, $6C, $38, $00, $7C, $00, $00, + $18, $00, $18, $18, $30, $66, $3C, $00, + $00, $00, $00, $FC, $C0, $C0, $00, $00, + $00, $00, $00, $FC, $0C, $0C, $00, $00, + $C6, $CC, $D8, $36, $6B, $C2, $84, $0F, + $C3, $C6, $CC, $DB, $37, $6D, $CF, $03, + $18, $00, $18, $18, $3C, $3C, $18, $00, + $00, $33, $66, $CC, $66, $33, $00, $00, + $00, $CC, $66, $33, $66, $CC, $00, $00, + $22, $88, $22, $88, $22, $88, $22, $88, + $55, $AA, $55, $AA, $55, $AA, $55, $AA, + $DB, $F6, $DB, $6F, $DB, $7E, $D7, $ED, + $18, $18, $18, $18, $18, $18, $18, $18, + $18, $18, $18, $18, $F8, $18, $18, $18, + $18, $18, $F8, $18, $F8, $18, $18, $18, + $36, $36, $36, $36, $F6, $36, $36, $36, + $00, $00, $00, $00, $FE, $36, $36, $36, + $00, $00, $F8, $18, $F8, $18, $18, $18, + $36, $36, $F6, $06, $F6, $36, $36, $36, + $36, $36, $36, $36, $36, $36, $36, $36, + $00, $00, $FE, $06, $F6, $36, $36, $36, + $36, $36, $F6, $06, $FE, $00, $00, $00, + $36, $36, $36, $36, $FE, $00, $00, $00, + $18, $18, $F8, $18, $F8, $00, $00, $00, + $00, $00, $00, $00, $F8, $18, $18, $18, + $18, $18, $18, $18, $1F, $00, $00, $00, + $18, $18, $18, $18, $FF, $00, $00, $00, + $00, $00, $00, $00, $FF, $18, $18, $18, + $18, $18, $18, $18, $1F, $18, $18, $18, + $00, $00, $00, $00, $FF, $00, $00, $00, + $18, $18, $18, $18, $FF, $18, $18, $18, + $18, $18, $1F, $18, $1F, $18, $18, $18, + $36, $36, $36, $36, $37, $36, $36, $36, + $36, $36, $37, $30, $3F, $00, $00, $00, + $00, $00, $3F, $30, $37, $36, $36, $36, + $36, $36, $F7, $00, $FF, $00, $00, $00, + $00, $00, $FF, $00, $F7, $36, $36, $36, + $36, $36, $37, $30, $37, $36, $36, $36, + $00, $00, $FF, $00, $FF, $00, $00, $00, + $36, $36, $F7, $00, $F7, $36, $36, $36, + $18, $18, $FF, $00, $FF, $00, $00, $00, + $36, $36, $36, $36, $FF, $00, $00, $00, + $00, $00, $FF, $00, $FF, $18, $18, $18, + $00, $00, $00, $00, $FF, $36, $36, $36, + $36, $36, $36, $36, $3F, $00, $00, $00, + $18, $18, $1F, $18, $1F, $00, $00, $00, + $00, $00, $1F, $18, $1F, $18, $18, $18, + $00, $00, $00, $00, $3F, $36, $36, $36, + $36, $36, $36, $36, $FF, $36, $36, $36, + $18, $18, $FF, $18, $FF, $18, $18, $18, + $18, $18, $18, $18, $F8, $00, $00, $00, + $00, $00, $00, $00, $1F, $18, $18, $18, + $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, + $00, $00, $00, $00, $FF, $FF, $FF, $FF, + $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, + $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, + $FF, $FF, $FF, $FF, $00, $00, $00, $00, + $00, $00, $76, $DC, $C8, $DC, $76, $00, + $00, $78, $CC, $F8, $CC, $F8, $C0, $C0, + $00, $FC, $CC, $C0, $C0, $C0, $C0, $00, + $00, $00, $FE, $6C, $6C, $6C, $6C, $00, + $FC, $CC, $60, $30, $60, $CC, $FC, $00, + $00, $00, $7E, $D8, $D8, $D8, $70, $00, + $00, $66, $66, $66, $66, $7C, $60, $C0, + $00, $76, $DC, $18, $18, $18, $18, $00, + $FC, $30, $78, $CC, $CC, $78, $30, $FC, + $38, $6C, $C6, $FE, $C6, $6C, $38, $00, + $38, $6C, $C6, $C6, $6C, $6C, $EE, $00, + $1C, $30, $18, $7C, $CC, $CC, $78, $00, + $00, $00, $7E, $DB, $DB, $7E, $00, $00, + $06, $0C, $7E, $DB, $DB, $7E, $60, $C0, + $38, $60, $C0, $F8, $C0, $60, $38, $00, + $78, $CC, $CC, $CC, $CC, $CC, $CC, $00, + $00, $7E, $00, $7E, $00, $7E, $00, $00, + $18, $18, $7E, $18, $18, $00, $7E, $00, + $60, $30, $18, $30, $60, $00, $FC, $00, + $18, $30, $60, $30, $18, $00, $FC, $00, + $0E, $1B, $1B, $18, $18, $18, $18, $18, + $18, $18, $18, $18, $18, $D8, $D8, $70, + $18, $18, $00, $7E, $00, $18, $18, $00, + $00, $76, $DC, $00, $76, $DC, $00, $00, + $38, $6C, $6C, $38, $00, $00, $00, $00, + $00, $00, $00, $18, $18, $00, $00, $00, + $00, $00, $00, $00, $18, $00, $00, $00, + $0F, $0C, $0C, $0C, $EC, $6C, $3C, $1C, + $58, $6C, $6C, $6C, $6C, $00, $00, $00, + $70, $98, $30, $60, $F8, $00, $00, $00, + $00, $00, $3C, $3C, $3C, $3C, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $00 + ); + +{$F+} + procedure Print_8x8_Mono( x, y : Int; c : char ); + var + offset, i : Int; + bitm : PByte; + begin + offset := x + y*Vio_ScanLineWidth*8; + bitm := @Font_8x8[ ord(c)*8 ]; + + for i := 0 to 7 do + begin + Vio^[offset] := bitm^[i]; + inc( offset, Vio_ScanLineWidth ); + end; + end; + + procedure Print_8x8_Gray( x, y : Int; c : char ); + var + offset, i, bit : Int; + + bitm : PByte; + begin + offset := ( x + y*Vio_ScanLineWidth )*8; + bitm := @font_8x8[ ord(c)*8 ]; + + for i := 0 to 7 do + begin + bit := $80; + while bit > 0 do + begin + if ( bit and bitm^[i] <> 0 ) then Vio^[offset] := $FF + else Vio^[offset] := $00; + bit := bit shr 1; + inc( offset ); + end; + + inc( offset, Vio_ScanLineWidth-8 ); + end; + + end; +{$F-} + + function Set_Graph_Screen( mode : Int ): boolean; + begin + Set_Graph_Screen := False; + + gcursor_x := 0; + gcursor_y := 0; + + case mode of + + Graphics_Mode_Mono : begin + if not Driver_Set_Graphics(mode) then exit; + gwindow_width := vio_ScanLineWidth; + gwindow_height := vio_Height div 8; + + Print_8x8 := Print_8x8_Mono; + end; + + Graphics_Mode_Gray : begin + if not Driver_Set_Graphics(mode) then exit; + gwindow_width := vio_ScanLineWidth div 8; + gwindow_height := vio_Height div 8; + + Print_8x8 := Print_8x8_Gray; + end; + else + exit; + end; + + Set_Graph_Screen := True; + end; + + + function Restore_Screen : boolean; + begin + gcursor_x := 0; + gcursor_y := 0; + + gwindow_height := 0; + gwindow_width := 0; + + Restore_Screen := Driver_Restore_Mode; + end; + + procedure Display_Bitmap_On_Screen; + begin + Driver_Display_Bitmap( buff, line, col ); + end; + + procedure Goto_XY( x, y : Int ); + begin + gcursor_x := x; + gcursor_y := y; + end; + + procedure Print_Str( str : string ); + var + i : Int; + begin + for i := 1 to length(str) do + begin + case str[i] of + + #13 : begin + gcursor_x := 0; + inc( gcursor_y ); + if gcursor_y > gwindow_height then gcursor_y := 0; + end; + else + Print_8x8( gcursor_x, gcursor_y, str[i] ); + inc( gcursor_x ); + if gcursor_x >= gwindow_width then + begin + gcursor_x := 0; + inc( gcursor_y ); + if gcursor_y >= gwindow_height then gcursor_y := 0; + end + end + end + end; + + procedure Print_XY( x, y : Int; str : string ); + begin + Goto_XY( x, y ); + Print_Str( str ); + end; + +end. + diff --git a/pascal/test/lint.pas b/pascal/test/lint.pas new file mode 100644 index 0000000..45e009e --- /dev/null +++ b/pascal/test/lint.pas @@ -0,0 +1,277 @@ +{***************************************************************************} +{* *} +{* FreeType Font glyph programs checker *} +{* *} +{* *} +{* This small program will load a TrueType font file and try to *} +{* render it at a given point size. *} +{* *} +{* This version will also catch differences between the engine's *} +{* computed advance widths, and the pre-calc values found in the *} +{* "hdmx" table *} +{* *} +{* This source code has been compiled and run under both Virtual Pascal *} +{* on OS/2 and Borland's BP7. *} +{* *} +{***************************************************************************} + +program Abc; + +uses Crt, + Common, +{$IFDEF OS2} + Use32, +{$ENDIF} + FreeType, + TTObjs; + +const + Precis = 64; + Precis2 = Precis div 2; + + PrecisAux = 1024; + + Screen_Width = 640; + Screen_Height = 480; + Screen_Cols = Screen_Width div 8; + Screen_Size = Screen_Cols * Screen_Height; + + Grid_Width = Screen_Width div 8; + Grid_Height = Screen_Height div 8; + Grid_Cols = Grid_Width div 8; + Grid_Size = Grid_Cols * Grid_Height; + + Screen_Center_X = Screen_Width div 2; + Screen_Center_Y = Screen_Height div 2; + + Grid_Center_X = Grid_Width div 2; + Grid_Center_Y = Grid_Height div 2; + + Profile_Buff_Size = 64000; + +var + + res, old_res : integer; + + numPoints, numContours : integer; + + Bitmap_small : TT_Raster_Map; + Bitmap_big : TT_Raster_Map; + + Rotation : integer; (* Angle modulo 1024 *) + + num_glyphs : integer; + + face : TT_Face; + instance : TT_Instance; + glyph : TT_Glyph; + + metrics : TT_Glyph_Metrics; + imetrics : TT_Instance_Metrics; + + props : TT_Face_Properties; + + point_size : integer; + error : TT_Error; + + display_outline : boolean; + hint_glyph : boolean; + scan_type : Byte; + + old_glyph : integer; + + FOut : Text; + +(******************************************************************* + * + * Function : LoadTrueTypeChar + * + * Description : Loads a single glyph into the xcoord, ycoord and + * flag arrays, from the instance data. + * + *****************************************************************) + +Function LoadTrueTypeChar( index : integer; + hint : boolean ) : TT_Error; +var + j, load_flag : integer; + + result : TT_Error; + +begin + if hint then load_flag := TT_Load_Scale_Glyph or TT_Load_Hint_Glyph + else load_flag := TT_Load_Scale_Glyph; + + result := TT_Load_Glyph( instance, + glyph, + index, + load_flag ); + + LoadTrueTypeChar := result; +end; + + +procedure Usage; +begin + Writeln('Simple TrueType Glyphs viewer - part of the FreeType project' ); + Writeln; + Writeln('Usage : ',paramStr(0),' size fontname[.ttf] [fontname.. ]'); + Writeln; + Halt(1); +end; + + + +var i: integer; + heure, + min1, + min2, + sec1, + sec2, + cent1, + cent2 : +{$IFDEF OS2} + longint; +{$ELSE} + word; +{$ENDIF} + + C : Char; + + Filename : String; + +label Fin; + +var + Fail : Integer; + PtSize : Integer; + Param : Integer; + code : Integer; + glyphStr : String[4]; + cur_file : Integer; + valid : Boolean; + + Mem0 : Longint; + +label + Lopo; + +begin + + Mem0 := MemAvail; + + TT_Init_FreeType; + + if ParamCount < 2 then Usage; + + val( ParamStr(1), point_size, code ); + if code <> 0 then Usage; + + if ( point_size <= 0 ) then + begin + Writeln('Invalid argument : pointsize must be >= 1'); + Usage; + end; + + Expand_WildCards( 2, '.ttf' ); + + for cur_file := 0 to num_arguments-1 do + begin + + FileName := arguments[cur_file]^; + + if Pos('.',FileName) = 0 then FileName:=FileName+'.TTF'; + + Write( MemAvail:6, ' ' ); + + error := TT_Open_Face( filename, face ); + + i := length(FileName); + while (i > 1) and (FileName[i] <> '\') do dec(i); + FileName := Copy( FileName, i+1, length(FileName) ); + + Write( cur_file:3,' ', filename:12, ': ' ); + + if error <> TT_Err_Ok then + begin + Writeln( 'could not open file, error code = ', error ); + goto Lopo; + end; + + TT_Get_Face_Properties( face, props ); + num_glyphs := props.num_Glyphs; + + error := TT_New_Glyph( face, glyph ); + if error <> TT_Err_Ok then + begin + Writeln( 'could not create glyph, error code = ', + error ); + goto Lopo; + end; + + error := TT_New_Instance( face, instance ); + if error <> TT_Err_Ok then + begin + Writeln( 'could not create instance, error code = ', + error ); + goto Lopo; + end; + + error := TT_Set_Instance_PointSize( instance, point_size ); + if error <> TT_Err_Ok then + begin + Writeln( 'could not set point size, error code = ', error ); + goto Lopo; + end; + + Fail := 0; + for i := 0 to num_glyphs-1 do + begin + error := LoadTrueTypeChar( i, true ); + if error <> TT_Err_Ok then + begin + inc( Fail ); + if Fail < 10 then + Writeln( 'error hinting glyph ', i, ', code = ', + error ); + end; + +{$IFDEF RIEN} + with PGlyph(glyph.z)^ do + begin + if (precalc_width >= 0) and + (precalc_width <> computed_width) then + begin + Write( i:5,' hdmx = ',precalc_width:3 ); + Write( ', engine = ',computed_width ); + if is_composite then Write( ' (composite)' ); + Writeln; + end + end; +{$ENDIF} + + end; + + if Fail >= 10 then + Writeln( 'there were ',Fail,' failed glyphs' ); + + if Fail = 0 then + Writeln( 'ok' ); + + Lopo: + + TT_Close_Face( face ); + + end; + + Fin: + + Writeln('Memory consumed by lint = ', Mem0 - MemAvail ); + + TT_Done_FreeType; + + Writeln('Memory leaked after engine termination = ', Mem0 - MemAvail ); + +end. + + diff --git a/pascal/test/stacktv.pas b/pascal/test/stacktv.pas new file mode 100644 index 0000000..ef9c05e --- /dev/null +++ b/pascal/test/stacktv.pas @@ -0,0 +1,148 @@ +(* The Turbo Vision Stack Component. Part of the FreeType Debugger *) + +unit StackTV; + +interface + +uses Objects, Views, Drivers, TTTypes, TTObjs, TTDebug; + +type + + { TStackView } + + { A Simple stack display } + + PStackView = ^TStackView; + TStackView = object( TListViewer ) + constructor Init( var Bounds : TRect; + aexec : PExec_Context; + AVScrollBar : PScrollBar ); + + procedure HandleEvent( var Event : TEvent ); virtual; + procedure Draw; virtual; + procedure Update; + + private + exec : PExec_Context; + end; + + { TStackWindow } + + PStackWindow = ^TStackWindow; + TStackWindow = object( TWindow ) + V : PScrollBar; + S : PStackView; + constructor Init( var Bounds : TRect; + exec : PExec_Context ); + end; + +implementation + +{$I DEBUGGER.INC} + +{ TStackView } + +constructor TStackView.Init; +begin + inherited Init( Bounds, 1, nil, AVScrollBar ); + exec := aexec; + + GrowMode := gfGrowHiX or gfGrowHiY; + DragMode := dmDragGrow or dmLimitLoX or dmLimitLoY; + EventMask := EventMask or evWave; + + SetRange( exec^.stackSize ); +end; + +procedure TStackView.Draw; +const + Colors : array[0..1] of Byte = ($1E,$3E); +var + B : TDrawBuffer; + Color : Byte; + I, Item : Int; + S : String[16]; +begin + Color := Colors[0]; + + if exec^.top <= Size.Y then Item := Size.Y-1 + else Item := exec^.top-1-TopItem; + + for I := 0 to Size.Y-1 do + begin + + MoveChar( B, ' ', Color, Size.X ); + + if Item < exec^.top then + begin + S := ' ' + Hex16( Item ) + ': ' + Hex32( exec^.stack^[Item] ); + MoveStr( B, S, Color ); + end; + + WriteLine( 0, I, Size.X, 1, B ); + dec( Item ); + end; + +end; + + +procedure TStackView.Update; +begin + FocusItem( 0 ); + DrawView; +end; + +procedure TStackView.HandleEvent; +var + Limits : TRect; + Mini, Maxi : Objects.TPoint; +begin + case Event.What of + + evWave : case Event.Command of + + cmReFocus : Update; + + end; + end; + + inherited HandleEvent( Event ); + + case Event.Command of + + cmResize: begin + Owner^.GetExtent(Limits); + SizeLimits( Mini, Maxi ); + DragView(Event, DragMode, Limits, Mini, Maxi ); + ClearEvent(Event); + end; + end; + +end; + + + +{ TStackWindow } + +constructor TStackWindow.Init; +var + R : TRect; +begin + inherited Init( Bounds, 'Pile', wnNoNumber ); + + GetExtent( Bounds ); + R := Bounds; + R.A.X := R.B.X-1; + inc( R.A.Y ); + dec( R.B.Y ); + New( V, Init(R) ); + Insert( V ); + + R := Bounds; + R.Grow(-1,-1); + New( S, Init( R, exec, V )); + + Insert( S ); +end; + +end. diff --git a/pascal/test/statetv.pas b/pascal/test/statetv.pas new file mode 100644 index 0000000..bc27ce7 --- /dev/null +++ b/pascal/test/statetv.pas @@ -0,0 +1,196 @@ +unit StateTV; + +interface + +uses Objects, Views, Drivers, TTTypes, TTObjs, TTDebug; + +{$I DEBUGGER.INC} + +type + + { State Viewer } + + { A simple TView to show the current graphics state } + + PStateViewer = ^TStateViewer; + TStateViewer = object( TView ) + + constructor Init( var Bounds : TRect; + aexec : PExec_Context ); + + procedure HandleEvent( var Event : TEvent ); virtual; + procedure Draw; virtual; + + private + exec : PExec_Context; + end; + + { PStateWindow } + + PStateWindow = ^TStateWindow; + TStateWindow = object( TWindow ) + stateView : PStateViewer; + constructor Init( var Bounds : TRect; + exec : PExec_Context ); + end; + +implementation + +{ TStateViewer } + +constructor TStateViewer.Init; +begin + inherited Init( Bounds ); + exec := aexec; + Options := Options or ofSelectable; + EventMask := EventMask or evWave; +end; + +procedure TStateViewer.Draw; +var + B : TDrawBuffer; + S : String; + Color : Int; + n : Int; +begin + Color := $1E; + n := 0; + MoveChar( B, ' ', Color, Self.Size.X ); + + S := ' Loop ' + Hex16( exec^.GS.loop ); + + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Auto_flip '; + if exec^.GS.auto_flip then S := S + ' Yes' + else S := S + ' No'; + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Dual ('+Hex16(exec^.GS.dualVector.x)+','+ + Hex16(exec^.GS.dualVector.y)+')'; + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Projection ('+Hex16(exec^.GS.projVector.x)+','+ + Hex16(exec^.GS.projVector.y)+')'; + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Freedom ('+Hex16(exec^.GS.freeVector.x)+','+ + Hex16(exec^.GS.freeVector.y)+')'; + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Gep0 ' + Hex8( exec^.GS.gep0 ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Gep1 ' + Hex8( exec^.GS.gep1 ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Gep2 ' + Hex8( exec^.GS.gep2 ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Ins_Control ' + Hex8( exec^.GS.instruct_control ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Rounding ' + Hex8( exec^.GS.round_state ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Min_Distance ' + Hex32( exec^.GS.minimum_distance ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Rp0 ' + Hex8( exec^.GS.rp0 ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Rp1 ' + Hex8( exec^.GS.rp1 ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Rp2 ' + Hex8( exec^.GS.rp2 ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Ctrl_Val_Cutin ' + Hex32( exec^.GS.control_value_cutin ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Sngl_Width_Cutin ' + Hex32( exec^.GS.single_width_cutin ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Sngl_Widht_Value ' + Hex32( exec^.GS.single_width_value ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Scan_type ' + Hex8( exec^.GS.scan_type ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + MoveChar( B, ' ', Color, Self.Size.X ); + WriteLine( 0, n, Self.Size.X, Size.Y-n, B ); + +end; + +procedure TStateViewer.HandleEvent; +var + Limits : TRect; + Mini, Maxi : Objects.TPoint; +begin + + inherited HandleEvent( Event ); + + case Event.What of + + evWave : case Event.Command of + + cmReFocus : DrawView; +(* + cmResize: begin + Owner^.GetExtent(Limits); + SizeLimits( Mini, Maxi ); + DragView(Event, DragMode, Limits, Mini, Maxi ); + ClearEvent(Event); + end; +*) + end; + end; +end; + + +constructor TStateWindow.Init; +begin + inherited Init( Bounds, 'State', wnNoNumber ); + GetExtent( Bounds ); + Bounds.Grow(-1,-1); + New( StateView, Init( Bounds, exec ) ); + Insert( StateView ); +end; + +end. diff --git a/pascal/test/timer.pas b/pascal/test/timer.pas new file mode 100644 index 0000000..d61905e --- /dev/null +++ b/pascal/test/timer.pas @@ -0,0 +1,377 @@ +{***************************************************************************} +{* *} +{* FreeType Performance Timer *} +{* *} +{* *} +{* This source code has been compiled and run under both Virtual Pascal *} +{* on OS/2 and Borland's BP7. *} +{* *} +{* *} +{* The C scan-line converter has been highly optimized, unlike the *} +{* Pascal one which is still 'aged'. Don't be surprised to see drastic *} +{* performance differences then.. *} +{* *} +{***************************************************************************} + +program Timer; + +uses +{$IFDEF OS2} + Use32, +{$ENDIF} + Crt, + Dos, (* for GetTime *) + GMain, + GEvents, + GDriver, + FreeType, + + TTError, (* for CheckError *) + TTTypes; (* for commodity types *) + +{$DEFINE VISUAL} + +{ $DEFINE DEBUG} + +{$IFDEF VISUAL} +{&PMTYPE NOVIO} +{$ENDIF} + +const + Precis = 64; + Precis2 = Precis div 2; + + PrecisAux = 1024; + + Centre_X : int = 320; + Centre_Y : int = 225; + + Max_Glyphs = 512; + +var + xC : TT_PCoordinates; + yC : TT_PCoordinates; + Fl : TT_PTouchTable; + + cons : PUShort; + + outlines : array[0..Max_Glyphs-1] of TT_Outline; + + lastp : int; + lastc : int; + + res : int; + + numPoints, numContours : int; + + Bit : TT_Raster_Map; + + Rotation : int; (* Angle modulo 1024 *) + + num_glyphs : int; + + gray_level : Boolean; + + face : TT_Face; + instance : TT_Instance; + glyph : TT_Glyph; + + metrics : TT_Glyph_Metrics; + imetrics : TT_Instance_Metrics; + + props : TT_Face_Properties; + + old_glyph : int; + cur_glyph : int; + tot_glyph : int; + + grayLines : array[0..2048] of Byte; + + error : TT_Error; + + +Procedure InitRows; +var + i: integer; + P: Pointer; +begin + + if gray_level then + begin + Bit.rows := 200; + Bit.cols := 320; + Bit.width := 320*2; + Bit.flow := TT_Flow_Down; + Bit.size := 320*200; + end + else + begin + Bit.rows := 450; + Bit.cols := 80; + Bit.width := 640; + Bit.flow := TT_Flow_Down; + Bit.size := 80*450; + end; + + GetMem( Bit.buffer, Bit.size ); + if Bit.buffer = NIL then + begin + Writeln('ERREUR:InitRows:Not enough memory to allocate BitMap'); + halt(1); + end; + + FillChar( Bit.Buffer^, Bit.Size, 0 ); +end; + + +Procedure ClearData; +var i: integer; +begin + FillChar( Bit.Buffer^, Bit.Size, 0 ); +end; + + +procedure Preload_Glyphs( var start : Int ); +var + i, j, fin, np, nc : integer; + outline : TT_Outline; + +begin + fin := start + Max_Glyphs; + if fin > num_glyphs then fin := num_glyphs; + + tot_glyph := fin-start; + + cur_glyph := 0; + lastp := 0; + lastc := 0; + + {$IFNDEF VISUAL} + Write('Loading ', fin-start,' glyphs '); + {$ENDIF} + + for i := start to fin-1 do + begin + + if TT_Load_Glyph( instance, + glyph, + i, + TT_Load_Default ) = TT_Err_Ok then + begin + TT_Get_Glyph_Outline( glyph, outline ); + + TT_New_Outline( outline.n_points, + outline.n_contours, + outlines[cur_glyph] ); + + outline.high_precision := false; + outline.second_pass := false; + + TT_Copy_Outline( outline, outlines[cur_glyph] ); + + + TT_Translate_Outline( outlines[cur_glyph], + vio_Width*16, + vio_Height*16 ); + inc( cur_glyph ); + end; + + end; + + start := fin; +end; + + + +function ConvertRaster(index : integer) : boolean; +begin + if gray_level then + error := TT_Get_Outline_Pixmap( outlines[index], Bit ) + else + error := TT_Get_Outline_Bitmap( outlines[index], Bit ); + + ConvertRaster := (error <> TT_Err_Ok); +end; + + +procedure Usage; +begin + Writeln('Simple TrueType Glyphs viewer - part of the FreeType project' ); + Writeln; + Writeln('Usage : ',paramStr(0),' FontName[.TTF]'); + Halt(1); +end; + + +function Get_Time : LongInt; +var + heure, + min, + sec, + cent : +{$IFDEF OS2} + longint; +{$ELSE} + word; +{$ENDIF} +begin + GetTime( heure, min, sec, cent ); + Get_Time := 6000*longint(min) + 100*longint(sec) + cent; +end; + + + +var i : integer; + Filename : String; + Fail : Int; + T, T0, T1 : Long; + + start : Int; + +begin + xC := NIL; + yC := NIL; + Fl := NIL; + + TT_Init_FreeType; + + if ParamCount = 0 then Usage; + + gray_level := ParamStr(1)='-g'; + + if gray_level then + if ParamCount <> 2 then Usage else + else + if ParamCount <> 1 then Usage; + + if gray_level then Filename := ParamStr(2) + else Filename := ParamStr(1); + + if Pos('.',FileName) = 0 then FileName:=FileName+'.TTF'; + + error := TT_Open_Face( filename, face ); + + if error <> TT_Err_Ok then + begin + Writeln('ERROR: Could not open ', FileName ); + Check_Error(error); + end; + + TT_Get_Face_Properties( face, props ); + + num_glyphs := props.num_Glyphs; + + i := length(FileName); + while (i > 1) and (FileName[i] <> '\') do dec(i); + + FileName := Copy( FileName, i+1, length(FileName) ); + + error := TT_New_Glyph( face, glyph ); + if error <> TT_Err_Ok then + begin + Writeln('ERROR : Could not get glyph' ); + Check_Error(error); + end; + + i := props.max_Points * num_glyphs; + + GetMem( fl, i ); + i := i * sizeof(Long); + + GetMem( xC, i ); + GetMem( yC, i ); + + i := props.max_Contours * num_glyphs; + + GetMem( cons, i*sizeof(UShort) ); + + error := TT_New_Instance( face, instance ); + if error <> TT_Err_Ok then + begin + Writeln('ERROR: Could not open face instance from ', Filename ); + Check_Error(error); + end; + + error := TT_Set_Instance_PointSize( instance, 400 ); + if error <> TT_Err_Ok then + begin + Writeln('ERROR: Could set pointsize' ); + Check_Error(error); + end; + + Rotation := 0; + Fail := 0; + + InitRows; + + {$IFDEF VISUAL} + if gray_level then + begin + if not Set_Graph_Screen( Graphics_Mode_Gray ) then + Panic1( 'could not set grayscale graphics mode' ); + end + else + begin + if not Set_Graph_Screen( Graphics_Mode_Mono ) then + Panic1( 'could not set mono graphics mode' ); + end; + + {$ENDIF} + + start := 0; + + T := Get_Time; + T1 := 0; + + while start < num_glyphs do + begin + + Preload_Glyphs(start); + + {$IFNDEF VISUAL} + write('... '); + {$ENDIF} + + T0 := Get_Time; + + for cur_glyph := 0 to tot_glyph-1 do + begin + if not ConvertRaster(cur_glyph) then + {$IFDEF VISUAL} + begin + Display_Bitmap_On_Screen( Bit.Buffer^, Bit.rows, Bit.cols ); + ClearData; + end + {$ELSE} + begin + end + {$ENDIF} + else + inc( Fail ); + end; + + T0 := Get_Time - T0; + writeln( T0/100:0:2,' s' ); + + inc( T1, T0 ); + + for cur_glyph := 0 to tot_glyph-1 do + TT_Done_Outline( outlines[cur_glyph] ); + end; + + T := Get_Time - T; + + {$IFDEF VISUAL} + Restore_Screen; + {$ENDIF} + + writeln; + writeln('Render time : ', T1/100:0:2,' s' ); + writeln('Total time : ', T /100:0:2,' s'); + writeln('Glyphs/second : ', Long(num_glyphs)*100/T1:0:1 ); + writeln('Fails : ',Fail ); +end. + +begin +end. + diff --git a/pascal/test/view.pas b/pascal/test/view.pas new file mode 100644 index 0000000..275e35f --- /dev/null +++ b/pascal/test/view.pas @@ -0,0 +1,523 @@ +{***************************************************************************} +{* *} +{* FreeType Glyph Viewer. *} +{* *} +{* *} +{* This small program will load a TrueType font file and allow *} +{* you to view/scale/rotate its glyphs. Glyphs are in the order *} +{* found within the 'glyf' table. *} +{* *} +{* NOTE : This version displays a magnified view of the glyph *} +{* along with the pixel grid. *} +{* *} +{* This source code has been compiled and run under both Virtual Pascal *} +{* on OS/2 and Borland's BP7. *} +{* *} +{***************************************************************************} + +program View; + +uses Crt, + Common, +{$IFDEF OS2} + Use32, +{$ENDIF} + GMain, + GEvents, + GDriver, + FreeType; + +{&PMTYPE NOVIO} + +{$DEFINE DEBUG} + +const + Precis = 64; + + Precis2 = Precis div 2; + + PrecisAux = 1024; + + Profile_Buff_Size = 32000; + + Max_Files = 1024; + +var + face : TT_Face; + instance : TT_Instance; + glyph : TT_Glyph; + + metrics : TT_Glyph_Metrics; + imetrics : TT_Instance_Metrics; + + props : TT_Face_Properties; + + ymin, ymax, xmax, xmin, xsize : longint; + res, old_res : int; + + numPoints, numContours : int; + + Bit : TT_Raster_Map; + + Rotation : int; (* Angle modulo 1024 *) + + num_glyphs : int; + + error : TT_Error; + gray_level : Boolean; + + display_outline : boolean; + hint_glyph : boolean; + scan_type : Byte; + + old_glyph : int; + cur_glyph : int; + + scale_shift : Int; + + grayLines : array[0..2048] of Byte; + +(******************************************************************* + * + * Function : Set_Raster_Area + * + *****************************************************************) + + procedure Set_Raster_Area; + begin + Bit.rows := vio_Height; + Bit.width := vio_Width; + Bit.flow := TT_Flow_Up; + + if gray_level then + Bit.cols := Bit.width + else + Bit.cols := (Bit.width+7) div 8; + + Bit.size := Bit.rows * Bit.cols; + end; + +(******************************************************************* + * + * Function : Clear_Data + * + *****************************************************************) + + procedure Clear_Data; + begin + if gray_level then + fillchar( Bit.buffer^, Bit.size, gray_palette[0] ) + else + fillchar( Bit.buffer^, Bit.size, 0 ); + end; + +(******************************************************************* + * + * Function : Init_Engine + * + *****************************************************************) + + procedure Init_Engine( maxRes : Int ); + begin + Set_Raster_Area; + GetMem( Bit.buffer, Bit.size ); + Clear_Data; + end; + +(******************************************************************* + * + * Function : Reset_Scale + * + *****************************************************************) + + function Reset_Scale( res : Int ) : Boolean; + begin + error := TT_Set_Instance_CharSize( instance, res*64 ); + Reset_Scale := (error = TT_Err_Ok); + end; + + +(******************************************************************* + * + * Function : LoadTrueTypeChar + * + * Description : Loads a single glyph into the xcoord, ycoord and + * flag arrays, from the instance data. + * + *****************************************************************) + +Function LoadTrueTypeChar( index : integer; + hint : boolean ) : TT_Error; +var + j, load_flag : int; + + result : TT_Error; + +begin + if hint then load_flag := TT_Load_Scale_Glyph or TT_Load_Hint_Glyph + else load_flag := TT_Load_Scale_Glyph; + + result := TT_Load_Glyph( instance, + glyph, + index, + load_flag ); + + LoadTrueTypeChar := result; +end; + + +var + Error_String : String; + ine : Int; + +function Render_ABC( glyph_index : integer ) : boolean; +var + i, j : integer; + + x, y : longint; + + start_x, + start_y, + step_x, + step_y : longint; + + fail : Int; +begin + + Render_ABC := True; + + TT_Get_Instance_Metrics( instance, imetrics ); + + start_x := 4; + start_y := vio_Height - 30 - imetrics.y_ppem; + + step_x := imetrics.x_ppem + 4; + step_y := imetrics.y_ppem + 10; + + x := start_x; + y := start_y; + + fail := 0; + + ine := glyph_index; + while ine < num_glyphs do + begin + + if LoadTrueTypeChar( ine, hint_glyph ) = TT_Err_Ok then + begin + + TT_Get_Glyph_Metrics( glyph, metrics ); + + if gray_level then + TT_Get_Glyph_Pixmap( glyph, Bit, x*64, y*64 ) + else + TT_Get_Glyph_Bitmap( glyph, Bit, x*64, y*64 ); + + inc( x, (metrics.advance div 64) + 1 ); + + if x > vio_Width - 40 then + begin + x := start_x; + dec( y, step_y ); + if y < 10 then + begin + Render_ABC := False; + exit; + end; + end; + end + else + inc( fail ); + + inc(ine); + end; + + Render_ABC := False; +end; + + + +procedure Erreur( s : String ); +begin + Restore_Screen; + Writeln( 'Error : ', s, ', error code = ', error ); + Halt(1); +end; + + +procedure Usage; +begin + Writeln('Simple TrueType Glyphs viewer - part of the FreeType project' ); + Writeln; + Writeln('Usage : ',paramStr(0),' FontName[.TTF]'); + Halt(1); +end; + + + +var + i: integer; + heure, + min1, + min2, + sec1, + sec2, + cent1, + cent2 : +{$IFDEF OS2} + longint; +{$ELSE} + word; +{$ENDIF} + + C : Char; + + Filename : String; + +label Fin; + +var + Fail : Int; + glyphStr : String[4]; + ev : Event; + + Code : Int; + + init_memory, end_memory : LongInt; + + num_args : Integer; + point_size : Integer; + cur_file : Integer; + first_arg : Int; + sortie : Boolean; + valid : Boolean; + errmsg : String; + +label + Lopo; + +begin + TextMode( co80+Font8x8 ); + + TT_Init_FreeType; + + num_args := ParamCount; + + if num_args = 0 then + Usage; + + first_arg := 1; + + gray_level := False; + + if ParamStr(first_arg) = '-g' then + begin + inc( first_arg ); + gray_level := True; + end; + + if first_arg > num_args+1 then + Usage; + + val( ParamStr(first_arg), point_size, Code ); + if Code <> 0 then + point_size := 24 + else + inc( first_arg ); + + Expand_Wildcards( first_arg, '.ttf' ); + + cur_file := 0; + + if num_arguments = 0 then + begin + Writeln('Could not find file(s)'); + Halt(3); + end; + + if gray_level then + begin + if not Set_Graph_Screen( Graphics_Mode_Gray ) then + Erreur( 'could not set grayscale graphics mode' ); + end + else + begin + if not Set_Graph_Screen( Graphics_Mode_Mono ) then + Erreur( 'could not set mono graphics mode' ); + end; + + Init_Engine( 24 ); + + repeat + + valid := True; + + FileName := arguments[cur_file]^; + + if Pos('.',FileName) = 0 then FileName:=FileName+'.TTF'; + + error := TT_Open_Face( filename, face ); + if error <> TT_Err_Ok then + begin + str( error, errmsg ); + errmsg := 'Could not open '+filename+', error code = '+errmsg; + valid := false; + goto Lopo; + end; + + TT_Get_Face_Properties( face, props ); + + num_glyphs := props.num_Glyphs; + + i := length(FileName); + while (i > 1) and (FileName[i] <> '\') do dec(i); + + FileName := Copy( FileName, i+1, length(FileName) ); + + error := TT_New_Glyph( face, glyph ); + if error <> TT_Err_Ok then + Erreur('Could not create glyph container'); + + error := TT_New_Instance( face, instance ); + if error <> TT_Err_Ok then + begin + str( error, errmsg ); + errmsg := 'Could not create instance, error code = '+errmsg; + valid := false; + goto Lopo; + end; + + TT_Set_Instance_Resolutions( instance, 96, 96 ); + + Rotation := 0; + Fail := 0; + res := point_size; + scan_type := 2; + + Reset_Scale( res ); + + Lopo: + + display_outline := true; + hint_glyph := true; + + old_glyph := -1; + old_res := res; + cur_glyph := 0; + + sortie := false; + + Repeat + + if valid then + begin + if Render_ABC( cur_glyph ) then + inc( Fail ) + else + Display_Bitmap_On_Screen( Bit.Buffer^, Bit.rows, Bit.cols ); + + Clear_Data; + + Print_XY( 0, 0, FileName ); + + TT_Get_Instance_Metrics( instance, imetrics ); + + Print_Str(' pt size = '); + Str( imetrics.pointSize div 64:3, glyphStr ); + Print_Str( glyphStr ); + + Print_Str(' ppem = '); + Str( imetrics.y_ppem:3, glyphStr ); + Print_Str( glyphStr ); + + Print_Str(' glyph = '); + Str( cur_glyph, glyphStr ); + Print_Str( glyphStr ); + + Print_XY( 0, 1, 'Hinting (''z'') : ' ); + if hint_glyph then Print_Str('on ') + else Print_Str('off'); + + Print_XY( 0, 2, 'scan type(''e'') : ' ); + case scan_type of + 0 : Print_Str('none '); + 1 : Print_Str('level 1'); + 2 : Print_Str('level 2'); + 4 : Print_Str('level 4'); + 5 : Print_Str('level 5'); + end; + end + else + begin + Clear_Data; + Display_Bitmap_On_Screen( Bit.buffer^, Bit.rows, Bit.cols ); + Print_XY( 0, 0, errmsg ); + end; + + Get_Event(ev); + + case ev.what of + + event_Quit : goto Fin; + + event_Keyboard : case char(ev.info) of + + 'n' : begin + sortie := true; + if cur_file+1 < num_arguments then + inc( cur_file ); + end; + + 'p' : begin + sortie := true; + if cur_file > 0 then + dec( cur_file ); + end; + + 'z' : hint_glyph := not hint_glyph; + + + 'e' : begin + inc( scan_type ); + if scan_type = 3 then scan_type := 4; + if scan_type >= 6 then scan_type := 0; + end; + end; + + event_Scale_Glyph : begin + inc( res, ev.info ); + if res < 1 then res := 1; + if res > 1400 then res := 1400; + end; + + event_Change_Glyph : begin + inc( cur_glyph, ev.info ); + if cur_glyph < 0 then cur_glyph := 0; + if cur_glyph >= num_glyphs + then cur_glyph := num_glyphs-1; + end; + end; + + if res <> old_res then + begin + if not Reset_Scale(res) then + Erreur( 'Could not resize font' ); + old_res := res; + end; + + Until sortie; + + TT_Done_Glyph( glyph ); + TT_Close_Face( face ); + + until false; + + Fin: + Restore_Screen; + + Writeln; + Writeln('Fails : ', Fail ); + + TT_Done_FreeType; +end. + diff --git a/pascal/test/zonetv.pas b/pascal/test/zonetv.pas new file mode 100644 index 0000000..aa6632c --- /dev/null +++ b/pascal/test/zonetv.pas @@ -0,0 +1,222 @@ +{****************************************************************************} +{* *} +{* ZoneTV.PAS *} +{* *} +{* This unit implements a simple TrueType zone points viewer for the *} +{* FREETYPE project debugger. *} +{* *} +{****************************************************************************} + +Unit ZoneTV; + +interface + +uses Objects, Views, Drivers, FreeType, TTTypes, TTTables, TTObjs, TTDebug; + +{$I DEBUGGER.INC} + +type + + { TZoneViewer } + + { This TView is a simple point array viewer } + + PZoneViewer = ^TZoneViewer; + TZoneViewer = object( TListViewer ) + + constructor Init( var Bounds : TRect; + AZone : PGlyph_Zone ); + + procedure Draw; virtual; + procedure HandleEvent( var Event : TEvent ); virtual; + + private + Zone : PGlyph_Zone; { Pointer to the zone being displayed } + Save : TGlyph_Zone; { A copy of the zone to highlight } + { changes } + procedure Copy_Zone; + + end; + + { TCodeWindow } + + PZoneWindow = ^TZoneWindow; + TZoneWindow = object( TWindow ) + ZoneView : PZoneViewer; + constructor Init( var Bounds : TRect; + AZone : PGlyph_Zone ); + end; + +implementation + +{ TZoneViewer } + +constructor TZoneViewer.Init; +var + n : Int; +begin + inherited Init( Bounds, 1, nil, nil ); + + GrowMode := gfGrowHiX or gfGrowHiY; + DragMode := dmDragGrow or dmLimitLoX or dmLimitLoY; + Options := Options or ofSelectable; + EventMask := EventMask or evWave; + + Zone := AZone; + + GetMem( Save.org, zone^.n_points*2*sizeof(Long) ); + GetMem( Save.cur, zone^.n_points*2*sizeof(Long) ); + GetMem( Save.flags, zone^.n_points*sizeof(Byte) ); + + Save.n_points := Zone^.n_points; + Save.n_contours := Zone^.n_contours; + + Copy_Zone; + + SetRange( Save.n_points ); +end; + + +procedure TZoneViewer.Copy_Zone; +var + n : Int; +begin + n := 2*zone^.n_points * sizeof(Long); + + (* Note that we save also the original coordinates, as we're not sure *) + (* that the debugger is debugged ! *) + + move( Zone^.org^, Save.org^, n ); + move( Zone^.cur^, Save.cur^, n ); + move( Zone^.flags^, Save.flags^, zone^.n_points ); +end; + + +procedure TZoneViewer.HandleEvent( var Event : TEvent ); +var + Limits : TRect; + Mini, Maxi : Objects.TPoint; +begin + + inherited HandleEvent(Event); + + Case Event.What of + + evWave : case Event.Command of + + cmNewExecution : Copy_Zone; + + cmRefocus : DrawView; + + end; + + evCommand : case Event.Command of + + cmResize: begin + Owner^.GetExtent(Limits); + SizeLimits( Mini, Maxi ); + DragView(Event, DragMode, Limits, Mini, Maxi ); + ClearEvent(Event); + end; + end; + end; +end; + + +procedure TZoneViewer.Draw; +const + Colors : array[0..3] of byte + = ($30,$3F,$0B,$0E); + Touchs : array[0..3] of Char + = (' ','x','y','b'); + OnOff : array[0..1] of Char + = (' ',':'); +var + I, J, Item : Int; + B : TDrawBuffer; + S : String; + Indent : Int; + Ligne : Int; + + Changed : Boolean; + + Back_Color, + Color : word; + + On_BP : boolean; + BP : PBreakPoint; + +begin + + if HScrollBar <> nil then Indent := HScrollBar^.Value + else Indent := 0; + + with Save do + begin + + for I := 0 to Self.Size.Y-1 do + begin + + MoveChar( B, ' ', Colors[0], Self.Size.X ); + + Item := TopItem + I; + + if (Range > 0) and + ( Focused = Item ) then Back_Color := 2 + else Back_Color := 0; + + if Item < n_points then + begin + + Color := Back_Color; + if ( flags^[item] <> Zone^.flags^[item] ) then inc( Color ); + + S := Hex16( Item ) + ': '; + S[1] := OnOff[Zone^.flags^[item] and 1]; + S[7] := Touchs[(Zone^.flags^[item] and TT_Flag_Touched_Both) shr 1]; + + MoveStr( B, S, Colors[Color] ); + + Color := Back_Color; + if ( org^[item].x <> Zone^.org^[item].x ) then inc( Color ); + + MoveStr ( B[8], Hex32( Zone^.org^[item].x ), Colors[Color] ); + MoveChar( B[16], ',', Colors[0], 1 ); + + Color := Back_Color; + if ( org^[item].y <> Zone^.org^[item].y ) then inc( Color ); + + MoveStr( B[17], Hex32( Zone^.org^[item].y ), Colors[Color] ); + MoveStr( B[25], ' : ', Colors[0] ); + + Color := Back_Color; + if ( cur^[item].x <> Zone^.cur^[item].x ) then inc( Color ); + + MoveStr ( B[28], Hex32( Zone^.cur^[item].x ), Colors[Color] ); + MoveChar( B[36], ',', Colors[0], 1 ); + + Color := Back_Color; + if ( cur^[item].y <> Zone^.cur^[item].y ) then inc( Color ); + + MoveStr( B[37], Hex32( Zone^.cur^[item].y ), Colors[Color] ); + + end; + + WriteLine( 0, I, Self.Size.X, 1, B ); + end; + end; +end; + +{ TZoneWindow } + +constructor TZoneWindow.Init; +begin + inherited Init( Bounds,'Zone',wnNoNumber ); + GetExtent( Bounds ); + Bounds.Grow(-1,-1); + New( ZoneView, Init( Bounds, AZone ) ); + Insert( ZoneView ); +end; + +end. + diff --git a/po/.cvsignore b/po/.cvsignore new file mode 100644 index 0000000..2c68802 --- /dev/null +++ b/po/.cvsignore @@ -0,0 +1,8 @@ +*.gmo +*.mo +Makefile +Makefile.in +POTFILES +cat-id-tbl.c +freetype.pot +stamp-cat-id diff --git a/po/Makefile.in.in b/po/Makefile.in.in new file mode 100644 index 0000000..a4be8ff --- /dev/null +++ b/po/Makefile.in.in @@ -0,0 +1,216 @@ +# +# +# Makefile for freetype I18n, +# based on the Makefile.in.in that comes with gettext +# +# Erwin Dieterich, 20. 1. 1998 Erwin.Dieterich.ED@Bayer-AG.de +# +# +# +# Makefile for program source directory in GNU NLS utilities package. +# Copyright (C) 1995, 1996 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +PACKAGE = freetype +VERSION = @freetype_version@ + +SHELL = /bin/sh +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +datadir = $(prefix)/@DATADIRNAME@ +localedir = @LOCALEDIR@ +gnulocaledir = @LOCALEDIR@ +subdir = po + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ + +CC = @CC@ +GMSGFMT = @GMSGFMT@ +MSGFMT = @MSGFMT@ +XGETTEXT = @XGETTEXT@ +MSGMERGE = @MSGMERGE@ + +DEFS = @DEFS@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ + +INCLUDES = -I.. + +COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) + +DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(PACKAGE).pot + +POTFILES = \ + +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +INSTOBJEXT = @INSTOBJEXT@ + +.SUFFIXES: +.SUFFIXES: .c .o .po .pox .gmo .mo .msg + +.c.o: + $(COMPILE) $< + +.po.pox: + $(MAKE) $(PACKAGE).pot + $(MSGMERGE) $< $(srcdir)/$(PACKAGE).pot -o $*.pox + +.po.mo: + $(MSGFMT) -o $@ $< + +.po.gmo: + file=`echo $* | sed 's,.*/,,'`.gmo \ + && rm -f $$file && $(GMSGFMT) -o $$file $< + + + +all: all-@USE_NLS@ + +all-yes: $(PACKAGE).pot $(CATALOGS) +all-no: + @echo "No support for NLS requested" + +$(PACKAGE).pot: $(POTFILES) + if test -n "$(XGETTEXT)"; then \ + $(XGETTEXT) --default-domain=freetype --directory=$(srcdir)/.. \ + --keyword=_ --files-from=$(srcdir)/POTFILES.in; \ + mv freetype.po freetype.pot; \ + else \ + echo "xgettext not available: $(PACKAGE).pot not updated" 1>&2; \ + fi + + +install: install-exec install-data +install-exec: +install-data: install-data-@USE_NLS@ +install-data-no: all +install-data-yes: all + $(top_srcdir)/mkinstalldirs $(datadir); \ + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + case "$$cat" in \ + *.gmo) destdir=$(gnulocaledir);; \ + *) destdir=$(localedir);; \ + esac; \ + lang=`echo $$cat | sed 's/$(CATOBJEXT)$$//'`; \ + dir=$$destdir/$$lang/LC_MESSAGES; \ + $(top_srcdir)/mkinstalldirs $$dir; \ + if test -r $$cat; then \ + $(INSTALL_DATA) $$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \ + echo "installing $$cat as $$dir/$(PACKAGE)$(INSTOBJEXT)"; \ + else \ + $(INSTALL_DATA) $(srcdir)/$$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \ + echo "installing $(srcdir)/$$cat as" \ + "$$dir/$(PACKAGE)$(INSTOBJEXT)"; \ + fi; \ + if test -r $$cat.m; then \ + $(INSTALL_DATA) $$cat.m $$dir/$(PACKAGE)$(INSTOBJEXT).m; \ + echo "installing $$cat.m as $$dir/$(PACKAGE)$(INSTOBJEXT).m"; \ + else \ + if test -r $(srcdir)/$$cat.m ; then \ + $(INSTALL_DATA) $(srcdir)/$$cat.m \ + $$dir/$(PACKAGE)$(INSTOBJEXT).m; \ + echo "installing $(srcdir)/$$cat as" \ + "$$dir/$(PACKAGE)$(INSTOBJEXT).m"; \ + else \ + true; \ + fi; \ + fi; \ + done + +# Define this as empty until I found a useful application. +installcheck: + +uninstall: + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + lang=`echo $$cat | sed 's/$(CATOBJEXT)$$//'`; \ + rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ + rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \ + rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ + rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \ + done + rm -f $(gettextsrcdir)/po-Makefile.in.in + +check: all + +dvi info tags TAGS ID: + +mostlyclean: + rm -f core core.* *.pox $(PACKAGE).po *.old.po + rm -fr *.o *~ + +clean: mostlyclean + +distclean: clean + rm -f Makefile Makefile.in POTFILES *.mo *.gmo *.msg *.cat.m + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) +dist distdir: update-po $(DISTFILES) + dists="$(DISTFILES)"; \ + for file in $$dists; do \ + ln $(srcdir)/$$file $(distdir) 2> /dev/null \ + || cp -p $(srcdir)/$$file $(distdir); \ + done + +update-po: Makefile + $(MAKE) $(PACKAGE).pot + PATH=`pwd`/../src:$$PATH; \ + cd $(srcdir); \ + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + lang=`echo $$cat | sed 's/$(CATOBJEXT)$$//'`; \ + mv $$lang.po $$lang.old.po; \ + echo "$$lang:"; \ + if $(MSGMERGE) $$lang.old.po $(PACKAGE).pot -o $$lang.po; then \ + rm -f $$lang.old.po; \ + else \ + echo "msgmerge for $$cat failed!"; \ + rm -f $$lang.po; \ + mv $$lang.old.po $$lang.po; \ + fi; \ + done + +POTFILES: POTFILES.in + ( if test 'x$(srcdir)' != 'x.'; then \ + posrcprefix='$(top_srcdir)/'; \ + else \ + posrcprefix="../"; \ + fi; \ + sed -e '/^#/d' -e '/^[ ]*$$/d' \ + -e "s@.*@ $$posrcprefix& \\\\@" \ + -e '$$s/\(.*\) \\/\1/' < $(srcdir)/POTFILES.in > POTFILES ) + +Makefile: Makefile.in.in ../config.status POTFILES + cd .. \ + && CONFIG_FILES=$(subdir)/$@.in CONFIG_HEADERS= \ + $(SHELL) ./config.status + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 0000000..71ce09d --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,10 @@ +# +# List of source files containing translatable strings +# +# +lib/extend/ftxerr18.c +test/fterror.c +test/ftdump.c +test/ftlint.c +test/ftmetric.c +test/ftsbit.c diff --git a/po/cs.po b/po/cs.po new file mode 100644 index 0000000..989a04c --- /dev/null +++ b/po/cs.po @@ -0,0 +1,756 @@ +# Czech messages for FreeType +# Copyright (C) 1998-9 Pavel Kaòkovský +# Pavel Kaòkovský , 1998-9 +# +msgid "" +msgstr "" +"Project-Id-Version: FreeType 1.3\n" +"POT-Creation-Date: 1999-09-07 12:49+0000\n" +"PO-Revision-Date: 1999-08-30\n" +"Last-Translator: Pavel Kaòkovský , 1999\n" +"Language-Team: Czech\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso-8859-2\n" +"Content-Transfer-Encoding: 8bit\n" + +#: lib/extend/ftxerr18.c:47 +msgid "Successful function call, no error." +msgstr "Úspì¹né volání funkce, ¾ádná chyba." + +#: lib/extend/ftxerr18.c:50 +msgid "Invalid face handle." +msgstr "Neplatný manipulátor písma." + +#: lib/extend/ftxerr18.c:52 +msgid "Invalid instance handle." +msgstr "Neplatný manipulátor instance." + +#: lib/extend/ftxerr18.c:54 +msgid "Invalid glyph handle." +msgstr "Neplatný manipulátor litery." + +#: lib/extend/ftxerr18.c:56 +msgid "Invalid charmap handle." +msgstr "Neplatný manipulátor znakové mapy." + +#: lib/extend/ftxerr18.c:58 +msgid "Invalid result address." +msgstr "Neplatná adresa výsledku." + +#: lib/extend/ftxerr18.c:60 +msgid "Invalid glyph index." +msgstr "Neplatný index litery." + +#: lib/extend/ftxerr18.c:62 +msgid "Invalid argument." +msgstr "Neplatný argument." + +#: lib/extend/ftxerr18.c:64 +msgid "Could not open file." +msgstr "Nelze otevøít soubor." + +#: lib/extend/ftxerr18.c:66 +msgid "File is not a TrueType collection." +msgstr "Soubor není kolekce písem TrueType." + +#: lib/extend/ftxerr18.c:69 +msgid "Mandatory table missing." +msgstr "Nìkterá z povinných tabulek chybí." + +#: lib/extend/ftxerr18.c:71 +msgid "Invalid horizontal metrics (hmtx table broken)." +msgstr "Neplatná horizontální metrika (tabulka HMTX po¹kozena)." + +#: lib/extend/ftxerr18.c:73 +msgid "Invalid charmap format." +msgstr "Neplatný formát znakové mapy." + +#: lib/extend/ftxerr18.c:75 +msgid "Invalid ppem value." +msgstr "Neplatné rozmìry liter (ppem)." + +#: lib/extend/ftxerr18.c:77 +msgid "Invalid vertical metrics (vmtx table broken)." +msgstr "Neplatná vertikální metrika (tabulka VMTX po¹kozena)." + +#: lib/extend/ftxerr18.c:80 +msgid "Invalid file format." +msgstr "Neplatný formát souboru." + +#: lib/extend/ftxerr18.c:83 +msgid "Invalid engine." +msgstr "Neplatná globální data knihovny." + +#: lib/extend/ftxerr18.c:85 +msgid "Too many extensions." +msgstr "Pøíli¹ mnoho roz¹íøení." + +#: lib/extend/ftxerr18.c:87 +msgid "Extensions unsupported." +msgstr "Roz¹íøení není podporováno." + +#: lib/extend/ftxerr18.c:89 +msgid "Invalid extension id." +msgstr "Neplatný identifikátor roz¹íøení." + +#: lib/extend/ftxerr18.c:92 +msgid "No vertical data in font." +msgstr "V písmu nejsou obsa¾ena ¾ádná vertikální data." + +#: lib/extend/ftxerr18.c:95 +msgid "Maximum Profile (maxp) table missing." +msgstr "Tabulka maximálních hodnot (MAXP) chybí." + +#: lib/extend/ftxerr18.c:97 +msgid "Font Header (head) table missing." +msgstr "Tabulka HEAD chybí." + +#: lib/extend/ftxerr18.c:99 +msgid "Horizontal Header (hhea) table missing." +msgstr "Tabulka HHEA chybí." + +#: lib/extend/ftxerr18.c:101 +msgid "Index to Location (loca) table missing." +msgstr "Tabulka pozic liter (LOCA) chybí." + +#: lib/extend/ftxerr18.c:103 +msgid "Naming (name) table missing." +msgstr "Tabulka jmen (NAME) chybí." + +#: lib/extend/ftxerr18.c:105 +msgid "Character to Glyph Index Mapping (cmap) tables missing." +msgstr "Tabulky znakových map (CMAP) chybí." + +#: lib/extend/ftxerr18.c:107 +msgid "Horizontal Metrics (hmtx) table missing." +msgstr "Tabulka horizontálních metrik (HTMX) chybí." + +#: lib/extend/ftxerr18.c:109 +msgid "OS/2 table missing." +msgstr "Tabulka OS/2 chybí." + +#: lib/extend/ftxerr18.c:111 +msgid "PostScript (post) table missing." +msgstr "Tabulka dat pro PostScript (POST) chybí." + +#: lib/extend/ftxerr18.c:113 +msgid "Glyph (glyf) table missing." +msgstr "Tabulka liter (GLYF) chybí." + +#: lib/extend/ftxerr18.c:118 +msgid "Out of memory." +msgstr "Nedostatek pamìti." + +#: lib/extend/ftxerr18.c:123 +msgid "Invalid file offset." +msgstr "Neplatná pozice v souboru." + +#: lib/extend/ftxerr18.c:125 +msgid "Invalid file read." +msgstr "Neplatné ètení ze souboru." + +#: lib/extend/ftxerr18.c:127 +msgid "Invalid frame access." +msgstr "Neplatný pøístup k úseku souboru." + +#: lib/extend/ftxerr18.c:132 +msgid "Too many points." +msgstr "Pøíli¹ mnoho bodù." + +#: lib/extend/ftxerr18.c:134 +msgid "Too many contours." +msgstr "Pøíli¹ mnoho kontur." + +#: lib/extend/ftxerr18.c:136 +msgid "Invalid composite glyph." +msgstr "Neplatná kompozitní litera." + +#: lib/extend/ftxerr18.c:138 +msgid "Too many instructions." +msgstr "Pøíli¹ mnoho instrukcí." + +#: lib/extend/ftxerr18.c:143 +msgid "Invalid opcode." +msgstr "Neplatný kód operace." + +#: lib/extend/ftxerr18.c:145 +msgid "Too few arguments." +msgstr "Pøíli¹ málo argumentù." + +#: lib/extend/ftxerr18.c:147 +msgid "Stack overflow." +msgstr "Pøeteèení zásobníku." + +#: lib/extend/ftxerr18.c:149 +msgid "Code overflow." +msgstr "Pøeteèení oblasti instrukcí." + +#: lib/extend/ftxerr18.c:151 +msgid "Bad argument." +msgstr "©patný argument." + +#: lib/extend/ftxerr18.c:153 +msgid "Divide by zero." +msgstr "Dìlení nulou." + +#: lib/extend/ftxerr18.c:155 +msgid "Storage overflow." +msgstr "Pøeteèení oblasti pro ukládání dat." + +#: lib/extend/ftxerr18.c:157 +msgid "Control Value (cvt) table overflow." +msgstr "Pøeteèení tabulky øídících hodnot (CVT)." + +#: lib/extend/ftxerr18.c:159 +msgid "Invalid reference." +msgstr "Neplatný odkaz." + +#: lib/extend/ftxerr18.c:161 +msgid "Invalid distance." +msgstr "Neplatná vzdálenost." + +#: lib/extend/ftxerr18.c:163 +msgid "Interpolate twilight points." +msgstr "Interpolace mezi body v soumraèné zónì." + +#: lib/extend/ftxerr18.c:165 +msgid "`DEBUG' opcode found." +msgstr "Ladící operace." + +#: lib/extend/ftxerr18.c:167 +msgid "`ENDF' in byte-code stream." +msgstr "Operace ENDF nalezena na ¹patném místì." + +#: lib/extend/ftxerr18.c:169 +msgid "Out of code ranges." +msgstr "Mimo oblasti instrukcí." + +#: lib/extend/ftxerr18.c:171 +msgid "Nested function definitions." +msgstr "Vnoøené definice funkcí." + +#: lib/extend/ftxerr18.c:173 +msgid "Invalid code range." +msgstr "Neplatná oblast instrukcí." + +#: lib/extend/ftxerr18.c:175 +msgid "Invalid displacement." +msgstr "Neplatné posunutí." + +#: lib/extend/ftxerr18.c:177 +msgid "Endless loop encountered while executing instructions." +msgstr "Do¹lo k zacyklení bìhem vykonávání instrukcí." + +#: lib/extend/ftxerr18.c:182 +msgid "Nested frame access." +msgstr "Vnoøené pøístupy k úseku souboru." + +#: lib/extend/ftxerr18.c:184 +msgid "Invalid cache list." +msgstr "Neplatný seznam vyrovnávací pamìti." + +#: lib/extend/ftxerr18.c:186 +msgid "Could not find context." +msgstr "Nelze najít kontext." + +#: lib/extend/ftxerr18.c:188 +msgid "Unlisted object." +msgstr "Objekt není v seznamu." + +#: lib/extend/ftxerr18.c:193 +msgid "Raster pool overflow." +msgstr "Pøeteèení pamìti rasterizéru." + +#: lib/extend/ftxerr18.c:195 +msgid "Raster: negative height encountered." +msgstr "Rasterizér: záporná vý¹ka." + +#: lib/extend/ftxerr18.c:197 +msgid "Raster: invalid value." +msgstr "Rasterizér: neplatná hodnota." + +#: lib/extend/ftxerr18.c:199 +msgid "Raster not initialized." +msgstr "Rasterizér není incializován." + +#: lib/extend/ftxerr18.c:204 +msgid "Invalid kerning (kern) table format." +msgstr "Neplatný formát tabulky kernù (KERN)." + +#: lib/extend/ftxerr18.c:206 +msgid "Invalid kerning (kern) table." +msgstr "Neplatná tabulka kernù (KERN)." + +#: lib/extend/ftxerr18.c:208 +msgid "Invalid PostScript (post) table format." +msgstr "Neplatný formát tabulky PostScript (POST)." + +#: lib/extend/ftxerr18.c:210 +msgid "Invalid PostScript (post) table." +msgstr "Neplatná tabulka PostScript (POST)." + +#: lib/extend/ftxerr18.c:216 +msgid "Invalid TrueType Open subtable format." +msgstr "Neplatný formát podtabulky TrueType Open." + +#: lib/extend/ftxerr18.c:218 +msgid "Invalid TrueType Open subtable." +msgstr "Neplatná podtabulka TrueType Open." + +#: lib/extend/ftxerr18.c:220 +msgid "Glyph(s) not covered by lookup." +msgstr "Jedna èi více liter bìhem prohledávání nenalezena." + +#: lib/extend/ftxerr18.c:222 +msgid "Too many nested context substitutions." +msgstr "Pøíli¹ mnoho vlo¾ených kontextových substitucí." + +#: lib/extend/ftxerr18.c:224 +msgid "Invalid glyph substitution (GSUB) table format." +msgstr "Neplatný formát tabulky substitucí liter (GSUB)." + +#: lib/extend/ftxerr18.c:226 +msgid "Invalid glyph substitution (GSUB) table." +msgstr "Neplatná tabulka substitucí liter (GSUB)." + +#: lib/extend/ftxerr18.c:228 +msgid "Invalid glyph positioning (GPOS) table format." +msgstr "Neplatný formát tabulky umís»ování liter (GPOS)." + +#: lib/extend/ftxerr18.c:230 +msgid "Invalid glyph positioning (GPOS) table." +msgstr "Neplatná tabulka umís»ování liter (GPOS)." + +#: lib/extend/ftxerr18.c:237 +msgid "Invalid Error Number." +msgstr "Neznámý kód chyby." + +#: test/fterror.c:60 +msgid "Start of fterror.\n" +msgstr "Zaèátek fterror.\n" + +#: test/fterror.c:68 +msgid "End of fterror.\n" +msgstr "Konec fterror.\n" + +#: test/ftdump.c:168 test/ftlint.c:207 test/ftmetric.c:292 +msgid "Could not create glyph container.\n" +msgstr "Nelze vytvoøit kontejner liter.\n" + +#: test/ftdump.c:178 test/ftlint.c:215 test/ftmetric.c:301 test/ftsbit.c:213 +msgid "Could not create instance.\n" +msgstr "Nelze vytvoøit instanci.\n" + +#: test/ftdump.c:187 +msgid "Could not create second instance.\n" +msgstr "Nelze vytvoøit druhou instanci.\n" + +#: test/ftdump.c:193 +msgid "Memory footprint statistics:\n" +msgstr "Statistika pamì»ových nárokù:\n" + +#: test/ftdump.c:201 +msgid "face object" +msgstr "objekt písma" + +#: test/ftdump.c:202 +msgid "glyph object" +msgstr "objekt litery" + +#: test/ftdump.c:203 +msgid "instance object" +msgstr "objekt instance" + +#: test/ftdump.c:207 +msgid "exec. context object" +msgstr "objekt provádìcího kontextu" + +#: test/ftdump.c:214 +msgid "total memory usage" +msgstr "celková spotøeba pamìti" + +#: test/ftdump.c:222 test/ftdump.c:574 test/ftdump.c:784 test/ftdump.c:921 +#: test/ftlint.c:274 test/ftlint.c:287 test/ftmetric.c:387 test/ftsbit.c:284 +#, c-format +msgid "FreeType error message: %s\n" +msgstr "Chybové hlá¹ení FreeType: %s\n" + +#: test/ftdump.c:299 +msgid "font name table entries\n" +msgstr "polo¾ky v tabulce jmen\n" + +#: test/ftdump.c:309 +#, c-format +msgid "" +"PostScript name: %s\n" +"\n" +msgstr "" +"PostScriptové jméno: %s\n" +"\n" + +#: test/ftdump.c:332 +msgid "character map encodings\n" +msgstr "kódování map znakù\n" + +#: test/ftdump.c:339 test/ftdump.c:483 +msgid "The file doesn't seem to have any encoding table.\n" +msgstr "Soubor zøejmì neobsahuje ¾ádnou mapu znakù.\n" + +#: test/ftdump.c:343 test/ftdump.c:487 +#, c-format +msgid "" +"There are %hu encodings:\n" +"\n" +msgstr "" +"%hu kódování:\n" +"\n" + +#: test/ftdump.c:348 +#, c-format +msgid "encoding %2u: " +msgstr "kódování %2u: " + +#: test/ftdump.c:375 test/ftdump.c:384 test/ftdump.c:447 +#, c-format +msgid "Unknown value %hu" +msgstr "Neznámá hodnota %hu" + +#: test/ftdump.c:454 +msgid "Unknown" +msgstr "Neznámé" + +#: test/ftdump.c:476 +msgid "ftxcmap test\n" +msgstr "test roz¹íøení ftxcmap\n" + +#: test/ftdump.c:493 +#, c-format +msgid "encoding %2u:\n" +msgstr "kódování %2u:\n" + +#: test/ftdump.c:498 +#, c-format +msgid "first: glyph index %hu, character code 0x%lx\n" +msgstr "první: index litery %hu, kód znaku 0x%lx\n" + +#: test/ftdump.c:502 +#, c-format +msgid "next: glyph index %hu, character code 0x%lx\n" +msgstr "dal¹í: index litery %hu, kód znaku 0x%lx\n" + +#: test/ftdump.c:506 +#, c-format +msgid "last: glyph index %hu, character code 0x%lx\n" +msgstr "poslední: glyph index %hu, character code 0x%lx\n" + +#: test/ftdump.c:528 test/ftmetric.c:282 +msgid "Error while retrieving embedded bitmaps table.\n" +msgstr "Chyba bìhem naèítání tabulky vlo¾ených bitmap.\n" + +#: test/ftdump.c:532 +msgid "embedded bitmap table\n" +msgstr "tabulka vlo¾ených bimap\n" + +#: test/ftdump.c:535 +#, c-format +msgid " version of embedded bitmap table: 0x%lx\n" +msgstr " verze tabulky vlo¾ených bitmap: 0x%lx\n" + +#: test/ftdump.c:537 +#, c-format +msgid " number of embedded bitmap strikes: %lu\n" +msgstr " poèet blokù vlo¾ených bitmap: %lu\n" + +#: test/ftdump.c:547 +#, c-format +msgid " bitmap strike %hu/%lu: " +msgstr " blok vlo¾ených bitmap %hu/%lu: " + +#: test/ftdump.c:550 +#, c-format +msgid "%hux%hu pixels, %hu-bit depth, glyphs [%hu..%hu]\n" +msgstr "%hux%hu pixelù, bitová hloubka %hu, litery [%hu..%hu]\n" + +#: test/ftdump.c:559 +#, c-format +msgid " range format (%hu:%hu) glyphs %hu..%hu\n" +msgstr " úsek formátu (%hu:%hu) litery %hu..%hu\n" + +#: test/ftdump.c:610 +msgid "Error while loading GSUB table.\n" +msgstr "Chyba bìhem naèítání tabulky GSUB.\n" + +#: test/ftdump.c:614 +msgid "GSUB table\n" +msgstr "tabulka GSUB\n" + +#: test/ftdump.c:621 +msgid "Error while querying GSUB script list.\n" +msgstr "Chyba bìhem prohledávání seznamu GSUB skriptù.\n" + +#: test/ftdump.c:634 +#, c-format +msgid "Error while selecting GSUB script `%4.4s'.\n" +msgstr "Chyba pøi pokusu vybrat GSUB skript \"%4.4s\".\n" + +#: test/ftdump.c:639 +#, c-format +msgid " script `%4.4s' (index %hu):\n" +msgstr " skript \"%4.4s\" (index %hu):\n" + +#: test/ftdump.c:647 +#, c-format +msgid "Error while querying GSUB default language system for script `%4.4s'.\n" +msgstr "" +"Chyba bìhem zkoumání bì¾ného jazykového systému GSUB skriptu \"%4.4s\".\n" + +#: test/ftdump.c:652 +msgid " default language system:\n" +msgstr " bì¾ný jazykový systém:\n" + +#: test/ftdump.c:665 +#, c-format +msgid "" +"Error while selecting GSUB feature `%4.4s'\n" +"for default language system of script `%4.4s'.\n" +msgstr "" +"Chyba pøi výbìru GSUB vlastnosti \"%4.4s\"\n" +"pro bì¾ný jazykový systém skriptu \"%4.4s\".\n" + +#: test/ftdump.c:671 test/ftdump.c:752 +#, c-format +msgid " feature `%4.4s' (index %hu; lookup " +msgstr " vlastnost \"%4.4s\" (index %hu; vyhledávání " + +#: test/ftdump.c:687 +#, c-format +msgid "Error while querying GSUB language list for script `%4.4s'.\n" +msgstr "Chyba bìhem zkoumání seznamu jazykù pro GSUB skript \"%4.4s\".\n" + +#: test/ftdump.c:704 +#, c-format +msgid "Error while selecting GSUB language `%4.4s' for script `%4.4s'.\n" +msgstr "Chyba bìhem výbìru jazyka \"%4.4s\" pro GSUB skript \"%4.4s\".\n" + +#: test/ftdump.c:709 +#, c-format +msgid " language `%4.4s' (index %hu):\n" +msgstr " jazyk \"%4.4s\" (index %hu):\n" + +#: test/ftdump.c:714 +#, c-format +msgid " required feature index %hu (lookup " +msgstr " po¾adovaná vlastnost (index %hu; vyhledávání " + +#: test/ftdump.c:729 +#, c-format +msgid "" +"Error while querying GSUB feature list\n" +"for script `%4.4s', language `%4.4s'.\n" +msgstr "" +"Chyba bìhem zkoumání seznamu vlastností\n" +"pro GSUB skript \"%4.4s\", jazyk \"%4.4s\".\n" + +#: test/ftdump.c:746 +#, c-format +msgid "" +"Error while selecting GSUB feature `%4.4s'\n" +"for script `%4.4s', language `%4.4s'.\n" +msgstr "" +"Chyba bìhem výbìru vlastnosti \"%4.4s\"\n" +"pro GSUB skript \"%4.4s\", jazyk \"%4.4s\".\n" + +#: test/ftdump.c:771 +msgid "" +"Lookups:\n" +"\n" +msgstr "" +"Vyhledávací údaje:\n" +"\n" + +#: test/ftdump.c:774 +#, c-format +msgid " %hu: type %hu, flag 0x%x\n" +msgstr " %hu: typ %hu, pøíznaky 0x%x\n" + +#: test/ftdump.c:809 +msgid "ftdump: Simple TrueType Dumper -- part of the FreeType project" +msgstr "" +"ftdump: jednoduchý výpis obsahu písma TrueType -- souèást projektu FreeType" + +#: test/ftdump.c:813 +#, c-format +msgid "" +"Usage: %s fontname[.ttf|.ttc]\n" +"\n" +msgstr "" +"Pou¾ití: %s název-písma[.ttf|.ttc]\n" +"\n" + +#: test/ftdump.c:845 test/ftlint.c:134 test/ftmetric.c:226 test/ftsbit.c:126 +msgid "Error while initializing engine.\n" +msgstr "Chyba bìhem inicializace knihovny.\n" + +#: test/ftdump.c:852 test/ftmetric.c:234 test/ftsbit.c:133 +msgid "Error while initializing embedded bitmap extension.\n" +msgstr "Chyba bìhem inicializace roz¹íøení pro vlo¾ené bitmapy.\n" + +#: test/ftdump.c:859 +msgid "Error while initializing GSUB extension.\n" +msgstr "Chyba bìhem inicializace roz¹íøení pro substituce liter (GSUB).\n" + +#: test/ftdump.c:875 test/ftlint.c:187 test/ftmetric.c:249 test/ftsbit.c:181 +#, c-format +msgid "Could not find or open %s.\n" +msgstr "Nelze nalézt nebo otevøít soubor %s.\n" + +#: test/ftdump.c:878 test/ftlint.c:193 test/ftmetric.c:252 test/ftsbit.c:187 +#, c-format +msgid "Error while opening %s.\n" +msgstr "Chyba bìhem otevírání souboru %s.\n" + +#: test/ftlint.c:94 +msgid "" +"ftlint: Simple TrueType instruction tester -- part of the FreeType project" +msgstr "ftlint: test instrukcí písma TrueType -- souèást projektu FreeType" + +#: test/ftlint.c:99 +#, c-format +msgid "" +"Usage: %s ppem fontname[.ttf|.ttc] [fontname2..]\n" +"\n" +msgstr "" +"Pou¾ití: %s ppem název-písma[.ttf|.ttc] [název-dal¹ího-písma..]\n" +"\n" + +#: test/ftlint.c:226 test/ftsbit.c:224 +#, c-format +msgid "Could not set point size to %d.\n" +msgstr "Nelze nastavit velikost písma na %d bodù.\n" + +#: test/ftlint.c:239 +msgid "" +"Error with\n" +" " +msgstr "" +"Výskyt chyb\n" +" " + +#: test/ftlint.c:240 +#, c-format +msgid "glyph %4u: %s\n" +msgstr "litera %4d: %s\n" + +#: test/ftlint.c:253 +msgid "1 fail.\n" +msgstr "poèet chyb: 1\n" + +#: test/ftlint.c:255 +#, c-format +msgid "%d fails.\n" +msgstr "poèet chyb: %d\n" + +#: test/ftmetric.c:68 +msgid "" +"ftmetric: Simple TTF metrics/glyph dumper -- part of the FreeType project" +msgstr "ftmetric: výpis metrik písma TrueType -- souèást projektu FreeType" + +#: test/ftmetric.c:72 +#, c-format +msgid "" +"Usage: %s [options below] point fontname[.ttf|.ttc]\n" +"\n" +" -B show sbit's metrics (default: none)\n" +" -c C use C'th font index of TrueType collection (default: 0)\n" +" -i index glyph index (default: 0)\n" +" -r R use resolution R dpi (default: 72)\n" +"\n" +msgstr "" +"Pou¾ití: %s [volby viz ní¾e] bodová-velikost název-písma[.ttf|.ttc]\n" +"\n" +" -B zobraz rozmìry bitmapy (std: nezobrazuj)\n" +" -c C pou¾ij písmo indexu C z kolekce písem (std: 0)\n" +" -i index index litery (std: 0)\n" +" -r R rozli¹ení R bodù na palec (std: 72 dpi)\n" +"\n" + +#: test/ftmetric.c:259 +#, c-format +msgid "There are %d fonts in this collection.\n" +msgstr "Poèet písem v kolekci: %d.\n" + +#: test/ftmetric.c:264 +#, c-format +msgid "There is no collection with index %d in this font file.\n" +msgstr "V kolekci není ¾ádné písmo s indexem %d.\n" + +#: test/ftmetric.c:278 +msgid "There is no embedded bitmap data in the font.\n" +msgstr "V souboru písma nejsou vlo¾eny ¾ádné bitmapy.\n" + +#: test/ftmetric.c:308 +msgid "Could not set device resolutions.\n" +msgstr "Nelze nastavit rozli¹ení zaøízení.\n" + +#: test/ftmetric.c:315 +msgid "Could not reset instance.\n" +msgstr "Nelze inicializovat instanci.\n" + +#: test/ftmetric.c:321 +#, c-format +msgid "Instance metrics: ppemX %d, ppemY %d\n" +msgstr "Rozmìry instance: ppemX %d, ppemY %d\n" + +#: test/ftmetric.c:331 test/ftsbit.c:233 +msgid "Could not allocate glyph bitmap container.\n" +msgstr "Nelze vytvoøit kontejner vlo¾ených bitmap.\n" + +#: test/ftmetric.c:339 test/ftsbit.c:257 +#, c-format +msgid "Can't load bitmap for glyph %d.\n" +msgstr "Nelze naèíst bitmapu pro literu %d.\n" + +#: test/ftmetric.c:366 +msgid "Outline's metrics" +msgstr "Rozmìry obrysu" + +#: test/ftmetric.c:368 +msgid "Outline glyph\n" +msgstr "Obrys litery\n" + +#: test/ftsbit.c:89 +msgid "ftsbit: Simple TrueType `sbit' dumper -- part of the FreeType project" +msgstr "" +"ftsbit: výpis bitmap vlo¾ených do písma TrueType -- souèást projektu FreeType" + +#: test/ftsbit.c:94 +#, c-format +msgid "" +"Usage: %s ppem fontname[.ttf|.ttc] glyph_index [glyph_index2..]\n" +"\n" +msgstr "" +"Pou¾ití: %s ppem název-písma[.ttf|.ttc] [název-dal¹ího-písma..]\n" +"\n" + +#: test/ftsbit.c:199 +msgid "Could not find embedded bitmaps in this font.\n" +msgstr "V souboru písma nelze nalézt ¾ádné vlo¾ené bitmapy.\n" + +#: test/ftsbit.c:205 +msgid "Error while loading embedded bitmaps.\n" +msgstr "Chyba bìhem naèítání vlo¾ených bitmap.\n" + +#: test/ftsbit.c:251 +#, c-format +msgid " no bitmap for glyph %d.\n" +msgstr " litera %d nemá ¾ádnou vlo¾enou bitmapu.\n" + +#: test/ftsbit.c:263 +#, c-format +msgid "glyph index %d = %dx%d pixels, " +msgstr "litera %d = %dx%d pixelù, " + +#: test/ftsbit.c:266 +#, c-format +msgid "advance = %ld, minBearing = [%ld,%ld]\n" +msgstr "posun = %ld, minBearing = [%ld,%ld]\n" diff --git a/po/de.po b/po/de.po new file mode 100644 index 0000000..7c8b2a7 --- /dev/null +++ b/po/de.po @@ -0,0 +1,760 @@ +# German messages for FreeType. +# Copyright (C) 1997-1998 Erwin Dieterich +# Erwin Dieterich , 1997-1998. +# +msgid "" +msgstr "" +"Project-Id-Version: FreeType 1.0\n" +"POT-Creation-Date: 1999-09-07 12:49+0000\n" +"PO-Revision-Date: 1999-05-26\n" +"Last-Translator: Werner Lemberg \n" +"Language-Team: German\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso-8859-1\n" +"Content-Transfer-Encoding: 8bit\n" + +#: lib/extend/ftxerr18.c:47 +msgid "Successful function call, no error." +msgstr "Funktionsaufruf erfolgreich." + +#: lib/extend/ftxerr18.c:50 +msgid "Invalid face handle." +msgstr "Ungültiger Schrifthenkel." + +#: lib/extend/ftxerr18.c:52 +msgid "Invalid instance handle." +msgstr "Ungültiger Instanzenhenkel." + +#: lib/extend/ftxerr18.c:54 +msgid "Invalid glyph handle." +msgstr "Ungültiger Glyphhenkel." + +#: lib/extend/ftxerr18.c:56 +msgid "Invalid charmap handle." +msgstr "Ungültiger Charmaphenkel." + +#: lib/extend/ftxerr18.c:58 +msgid "Invalid result address." +msgstr "Ungültige Ergebnisadresse." + +#: lib/extend/ftxerr18.c:60 +msgid "Invalid glyph index." +msgstr "Ungültiger Glyphindex." + +#: lib/extend/ftxerr18.c:62 +msgid "Invalid argument." +msgstr "Ungültiger Übergabeparameter" + +#: lib/extend/ftxerr18.c:64 +msgid "Could not open file." +msgstr "Datei konnte nicht geöffnet werden." + +#: lib/extend/ftxerr18.c:66 +msgid "File is not a TrueType collection." +msgstr "Datei ist keine TrueType-Collection." + +#: lib/extend/ftxerr18.c:69 +msgid "Mandatory table missing." +msgstr "Eine obligatorische Tabelle fehlt." + +#: lib/extend/ftxerr18.c:71 +msgid "Invalid horizontal metrics (hmtx table broken)." +msgstr "Ungültige horizontale Metrik (`hmtx'-Tabelle defekt)." + +#: lib/extend/ftxerr18.c:73 +msgid "Invalid charmap format." +msgstr "Ungültiges Format der Zeichenkodierungstabelle." + +#: lib/extend/ftxerr18.c:75 +msgid "Invalid ppem value." +msgstr "Ungültiger ppem-Wert." + +#: lib/extend/ftxerr18.c:77 +msgid "Invalid vertical metrics (vmtx table broken)." +msgstr "Ungültige vertikale Metrik (`vmtx'-Tabelle defekt)." + +#: lib/extend/ftxerr18.c:80 +msgid "Invalid file format." +msgstr "Ungültiges Dateiformat." + +#: lib/extend/ftxerr18.c:83 +msgid "Invalid engine." +msgstr "Ungültige FreeType-Maschine (engine)." + +#: lib/extend/ftxerr18.c:85 +msgid "Too many extensions." +msgstr "Zu viele Erweiterungen." + +#: lib/extend/ftxerr18.c:87 +msgid "Extensions unsupported." +msgstr "Erweiterungen nicht unterstützt." + +#: lib/extend/ftxerr18.c:89 +msgid "Invalid extension id." +msgstr "Ungültige Erweiterungs-ID." + +#: lib/extend/ftxerr18.c:92 +msgid "No vertical data in font." +msgstr "Keine vertikale Informationen in der Schrift." + +#: lib/extend/ftxerr18.c:95 +msgid "Maximum Profile (maxp) table missing." +msgstr "`Maximum Profile (maxp)'-Tabelle fehlt." + +#: lib/extend/ftxerr18.c:97 +msgid "Font Header (head) table missing." +msgstr "`Font Header (head)'-Tabelle fehlt." + +#: lib/extend/ftxerr18.c:99 +msgid "Horizontal Header (hhea) table missing." +msgstr "`Horizontal Header (hhea)'-Tabelle fehlt." + +#: lib/extend/ftxerr18.c:101 +msgid "Index to Location (loca) table missing." +msgstr "`Index to Location (loca)'-Tabelle fehlt." + +#: lib/extend/ftxerr18.c:103 +msgid "Naming (name) table missing." +msgstr "`Naming (name)'-Tabelle fehlt." + +#: lib/extend/ftxerr18.c:105 +msgid "Character to Glyph Index Mapping (cmap) tables missing." +msgstr "`Character to Glyph Index Mapping (cmap)'-Tabellen fehlen." + +#: lib/extend/ftxerr18.c:107 +msgid "Horizontal Metrics (hmtx) table missing." +msgstr "`Horizontal Metrics (hmtx)'-Tabelle fehlt." + +#: lib/extend/ftxerr18.c:109 +msgid "OS/2 table missing." +msgstr "`OS/2'-Tabelle fehlt." + +#: lib/extend/ftxerr18.c:111 +msgid "PostScript (post) table missing." +msgstr "`PostScript (post)'-Tabelle fehlt." + +#: lib/extend/ftxerr18.c:113 +msgid "Glyph (glyf) table missing." +msgstr "`Glyph (glyf)'-Tabelle fehlt." + +#: lib/extend/ftxerr18.c:118 +msgid "Out of memory." +msgstr "Zu wenig Speicher." + +#: lib/extend/ftxerr18.c:123 +msgid "Invalid file offset." +msgstr "Ungültiger Dateioffset." + +#: lib/extend/ftxerr18.c:125 +msgid "Invalid file read." +msgstr "Ungültiger Lesezugriff auf Datei." + +#: lib/extend/ftxerr18.c:127 +msgid "Invalid frame access." +msgstr "Ungültiger Speicherrahmenzugriff." + +#: lib/extend/ftxerr18.c:132 +msgid "Too many points." +msgstr "Zu viele Punkte." + +#: lib/extend/ftxerr18.c:134 +msgid "Too many contours." +msgstr "Zu viele Konturen." + +#: lib/extend/ftxerr18.c:136 +msgid "Invalid composite glyph." +msgstr "Ungültiges zusammengesetztes Glyph." + +#: lib/extend/ftxerr18.c:138 +msgid "Too many instructions." +msgstr "Zu viele Programminstruktionen." + +#: lib/extend/ftxerr18.c:143 +msgid "Invalid opcode." +msgstr "Ungültiger Opcode." + +#: lib/extend/ftxerr18.c:145 +msgid "Too few arguments." +msgstr "Zu wenig Übergabeparameter." + +#: lib/extend/ftxerr18.c:147 +msgid "Stack overflow." +msgstr "Stacküberlauf." + +#: lib/extend/ftxerr18.c:149 +msgid "Code overflow." +msgstr "Codeüberlauf." + +#: lib/extend/ftxerr18.c:151 +msgid "Bad argument." +msgstr "Falscher Übergabeparameter." + +#: lib/extend/ftxerr18.c:153 +msgid "Divide by zero." +msgstr "Division durch Null." + +#: lib/extend/ftxerr18.c:155 +msgid "Storage overflow." +msgstr "Speicherüberlauf." + +#: lib/extend/ftxerr18.c:157 +msgid "Control Value (cvt) table overflow." +msgstr "Überlauf der `Control Value (cvt)'-Tabelle." + +#: lib/extend/ftxerr18.c:159 +msgid "Invalid reference." +msgstr "Ungültige Referenz." + +#: lib/extend/ftxerr18.c:161 +msgid "Invalid distance." +msgstr "Ungültiger Abstand." + +#: lib/extend/ftxerr18.c:163 +msgid "Interpolate twilight points." +msgstr "Interpolation von Punkten der Zwielichtzone." + +#: lib/extend/ftxerr18.c:165 +msgid "`DEBUG' opcode found." +msgstr "`DEBUG'-Opcode gefunden." + +#: lib/extend/ftxerr18.c:167 +msgid "`ENDF' in byte-code stream." +msgstr "`ENDF' in Bytecode-Strom." + +#: lib/extend/ftxerr18.c:169 +msgid "Out of code ranges." +msgstr "Außerhalb des Codebereichs." + +#: lib/extend/ftxerr18.c:171 +msgid "Nested function definitions." +msgstr "Verschachtelte Funktionsdefinitionen." + +#: lib/extend/ftxerr18.c:173 +msgid "Invalid code range." +msgstr "Ungültiger Codebereich." + +#: lib/extend/ftxerr18.c:175 +msgid "Invalid displacement." +msgstr "Ungültige Verschiebung." + +#: lib/extend/ftxerr18.c:177 +msgid "Endless loop encountered while executing instructions." +msgstr "" +"Unendliche Schleife beim Ausführen\n" +"der Programminstruktionen entdeckt." + +#: lib/extend/ftxerr18.c:182 +msgid "Nested frame access." +msgstr "Verschachtelter Speicherrahmenzugriff." + +#: lib/extend/ftxerr18.c:184 +msgid "Invalid cache list." +msgstr "Ungütlige Cacheliste." + +#: lib/extend/ftxerr18.c:186 +msgid "Could not find context." +msgstr "Der Kontext konnte nicht gefunden werden." + +#: lib/extend/ftxerr18.c:188 +msgid "Unlisted object." +msgstr "Objekt ist nicht aufgeführt." + +#: lib/extend/ftxerr18.c:193 +msgid "Raster pool overflow." +msgstr "Überlauf des Rasterpools." + +#: lib/extend/ftxerr18.c:195 +msgid "Raster: negative height encountered." +msgstr "Raster: Negative Höhe gefunden." + +#: lib/extend/ftxerr18.c:197 +msgid "Raster: invalid value." +msgstr "Raster: Ungültiger Wert." + +#: lib/extend/ftxerr18.c:199 +msgid "Raster not initialized." +msgstr "Raster nicht initialisiert." + +#: lib/extend/ftxerr18.c:204 +msgid "Invalid kerning (kern) table format." +msgstr "Ungültiges Format der `Kerning (kern)'-Tabelle." + +#: lib/extend/ftxerr18.c:206 +msgid "Invalid kerning (kern) table." +msgstr "Ungültige `Kerning (kern)'-Tabelle." + +#: lib/extend/ftxerr18.c:208 +msgid "Invalid PostScript (post) table format." +msgstr "Ungültiges Format der `PostScript (post)'-Tabelle." + +#: lib/extend/ftxerr18.c:210 +msgid "Invalid PostScript (post) table." +msgstr "Ungültige `PostScript (post)'-Tabelle." + +#: lib/extend/ftxerr18.c:216 +msgid "Invalid TrueType Open subtable format." +msgstr "Ungültiges Format einer TrueType-Open-Subtabelle." + +#: lib/extend/ftxerr18.c:218 +msgid "Invalid TrueType Open subtable." +msgstr "Ungültige TrueType-Open-Subtabelle." + +#: lib/extend/ftxerr18.c:220 +msgid "Glyph(s) not covered by lookup." +msgstr "Glyph(en) von Lookup-Prozedur nicht erfaßt." + +#: lib/extend/ftxerr18.c:222 +msgid "Too many nested context substitutions." +msgstr "Zu viele verschachtelte Kontext-Substitutionen." + +#: lib/extend/ftxerr18.c:224 +msgid "Invalid glyph substitution (GSUB) table format." +msgstr "Ungültiges Format der `glyph substitution (GSUB)'-Tabelle." + +#: lib/extend/ftxerr18.c:226 +msgid "Invalid glyph substitution (GSUB) table." +msgstr "Ungültige `glyph substitution (GSUB)'-Tabelle." + +#: lib/extend/ftxerr18.c:228 +msgid "Invalid glyph positioning (GPOS) table format." +msgstr "Ungültiges Format der `glyph positioning (GPOS)'-Tabelle." + +#: lib/extend/ftxerr18.c:230 +msgid "Invalid glyph positioning (GPOS) table." +msgstr "Ungültige `glyph positioning (GPOS)'-Tabelle." + +#: lib/extend/ftxerr18.c:237 +msgid "Invalid Error Number." +msgstr "Ungültige Fehler-ID." + +#: test/fterror.c:60 +msgid "Start of fterror.\n" +msgstr "Beginn von fterror.\n" + +#: test/fterror.c:68 +msgid "End of fterror.\n" +msgstr "Ende von fterror.\n" + +#: test/ftdump.c:168 test/ftlint.c:207 test/ftmetric.c:292 +msgid "Could not create glyph container.\n" +msgstr "Konnte den Glyphcontainer nicht erzeugen.\n" + +#: test/ftdump.c:178 test/ftlint.c:215 test/ftmetric.c:301 test/ftsbit.c:213 +msgid "Could not create instance.\n" +msgstr "Konnte die Instanz nicht erzeugen.\n" + +#: test/ftdump.c:187 +msgid "Could not create second instance.\n" +msgstr "Konnte die zweite Instanz nicht erzeugen.\n" + +#: test/ftdump.c:193 +msgid "Memory footprint statistics:\n" +msgstr "Speicherabdruck-Statistik:\n" + +#: test/ftdump.c:201 +msgid "face object" +msgstr "Schriftobjekt" + +#: test/ftdump.c:202 +msgid "glyph object" +msgstr "Glyphobjekt" + +#: test/ftdump.c:203 +msgid "instance object" +msgstr "Instanzobjekt" + +#: test/ftdump.c:207 +msgid "exec. context object" +msgstr "Ausführbares Kontextobjekt" + +#: test/ftdump.c:214 +msgid "total memory usage" +msgstr "Gesamtverbrauch an Speicher" + +#: test/ftdump.c:222 test/ftdump.c:574 test/ftdump.c:784 test/ftdump.c:921 +#: test/ftlint.c:274 test/ftlint.c:287 test/ftmetric.c:387 test/ftsbit.c:284 +#, c-format +msgid "FreeType error message: %s\n" +msgstr "FreeType Fehlermeldung: %s\n" + +#: test/ftdump.c:299 +msgid "font name table entries\n" +msgstr "Einträge in der `name'-Tabelle der Schrift\n" + +#: test/ftdump.c:309 +#, c-format +msgid "" +"PostScript name: %s\n" +"\n" +msgstr "" +"PostScript-Name: %s\n" +"\n" + +#: test/ftdump.c:332 +msgid "character map encodings\n" +msgstr "Zeichenkodierungstabellen\n" + +#: test/ftdump.c:339 test/ftdump.c:483 +msgid "The file doesn't seem to have any encoding table.\n" +msgstr "Diese Datei enthält anscheinend keine `cmap'-Tabelle.\n" + +#: test/ftdump.c:343 test/ftdump.c:487 +#, c-format +msgid "" +"There are %hu encodings:\n" +"\n" +msgstr "" +"Es gibt %hu Kodierungen:\n" +"\n" + +#: test/ftdump.c:348 +#, c-format +msgid "encoding %2u: " +msgstr "Kodierung %2u: " + +#: test/ftdump.c:375 test/ftdump.c:384 test/ftdump.c:447 +#, c-format +msgid "Unknown value %hu" +msgstr "Unbekannter Wert %hu" + +#: test/ftdump.c:454 +msgid "Unknown" +msgstr "Unbekannt" + +#: test/ftdump.c:476 +msgid "ftxcmap test\n" +msgstr "Test von ftxcmap\n" + +#: test/ftdump.c:493 +#, c-format +msgid "encoding %2u:\n" +msgstr "Kodierung %2u:\n" + +#: test/ftdump.c:498 +#, c-format +msgid "first: glyph index %hu, character code 0x%lx\n" +msgstr "Erster Eintrag: Glyphindex %hu, Zeichenkode 0x%lx\n" + +#: test/ftdump.c:502 +#, c-format +msgid "next: glyph index %hu, character code 0x%lx\n" +msgstr "Nächster Eintrag: Glyphindex %hu, Zeichenkode 0x%lx\n" + +#: test/ftdump.c:506 +#, c-format +msgid "last: glyph index %hu, character code 0x%lx\n" +msgstr "Letzter Eintrag: Glyphindex %hu, Zeichenkode 0x%lx\n" + +#: test/ftdump.c:528 test/ftmetric.c:282 +msgid "Error while retrieving embedded bitmaps table.\n" +msgstr "Fehler beim Laden der `embedded bitmaps'-Tabelle.\n" + +#: test/ftdump.c:532 +msgid "embedded bitmap table\n" +msgstr "`embedded bitmap'-Tabelle\n" + +#: test/ftdump.c:535 +#, c-format +msgid " version of embedded bitmap table: 0x%lx\n" +msgstr " Version der `embedded bitmap'-Tabelle: 0x%lx\n" + +#: test/ftdump.c:537 +#, c-format +msgid " number of embedded bitmap strikes: %lu\n" +msgstr " Anzahl der eingebetteten Bitmapsätze: %lu\n" + +#: test/ftdump.c:547 +#, c-format +msgid " bitmap strike %hu/%lu: " +msgstr " Bitmapsatz %hu/%hu: " + +#: test/ftdump.c:550 +#, c-format +msgid "%hux%hu pixels, %hu-bit depth, glyphs [%hu..%hu]\n" +msgstr "%hux%hu Pixel, Tiefe %hu Bit, Glyphbereich [%hu-%hu]\n" + +#: test/ftdump.c:559 +#, c-format +msgid " range format (%hu:%hu) glyphs %hu..%hu\n" +msgstr " Bereichsformat (%hu:%hu) Glyphen %hu-%hu\n" + +#: test/ftdump.c:610 +msgid "Error while loading GSUB table.\n" +msgstr "Fehler beim Laden der `GSUB'-Tabelle.\n" + +#: test/ftdump.c:614 +msgid "GSUB table\n" +msgstr "`GSUB'-Tabelle\n" + +#: test/ftdump.c:621 +msgid "Error while querying GSUB script list.\n" +msgstr "Fehler bei Abfrage der GSUB Schriftenliste.\n" + +#: test/ftdump.c:634 +#, c-format +msgid "Error while selecting GSUB script `%4.4s'.\n" +msgstr "Fehler bei Auswahl der GSUB Schrift `%4.4s'.\n" + +#: test/ftdump.c:639 +#, c-format +msgid " script `%4.4s' (index %hu):\n" +msgstr " Schrift `%4.4s' (Index %hu):\n" + +#: test/ftdump.c:647 +#, c-format +msgid "Error while querying GSUB default language system for script `%4.4s'.\n" +msgstr "" +"Fehler bei Abfrage der GSUB-Standardsprachenwerte für Schrift `%4.4s'.\n" + +#: test/ftdump.c:652 +msgid " default language system:\n" +msgstr " Standardsprachenwerte:\n" + +#: test/ftdump.c:665 +#, c-format +msgid "" +"Error while selecting GSUB feature `%4.4s'\n" +"for default language system of script `%4.4s'.\n" +msgstr "" +"Fehler bei Auswahl des GSUB-Merkmals `%4.4s'\n" +"für Standardsprachenwert der Schrift `%4.4s'.\n" + +#: test/ftdump.c:671 test/ftdump.c:752 +#, c-format +msgid " feature `%4.4s' (index %hu; lookup " +msgstr " Merkmal `%4.4s' (Index %hu; Lookup " + +#: test/ftdump.c:687 +#, c-format +msgid "Error while querying GSUB language list for script `%4.4s'.\n" +msgstr "Fehler bei Abfrage der GSUB-Sprachenliste für Schrift `%4.4s'.\n" + +#: test/ftdump.c:704 +#, c-format +msgid "Error while selecting GSUB language `%4.4s' for script `%4.4s'.\n" +msgstr "Fehler bei Auswahl der GSUB-Sprache `%4.4s' für Schrift `%4.4s'.\n" + +#: test/ftdump.c:709 +#, c-format +msgid " language `%4.4s' (index %hu):\n" +msgstr " Sprache `%4.4s' (Index %hu):\n" + +#: test/ftdump.c:714 +#, c-format +msgid " required feature index %hu (lookup " +msgstr " Benötigtes Merkmal: Index %hu (Lookup " + +#: test/ftdump.c:729 +#, c-format +msgid "" +"Error while querying GSUB feature list\n" +"for script `%4.4s', language `%4.4s'.\n" +msgstr "" +"Fehler bei Abfrage der GSUB-Merkmaltabelle\n" +"für Schrift `%4.4s', Sprache `%4.4s'.\n" + +#: test/ftdump.c:746 +#, c-format +msgid "" +"Error while selecting GSUB feature `%4.4s'\n" +"for script `%4.4s', language `%4.4s'.\n" +msgstr "" +"Fehler bei Auswahl des GSUB-Merkmals `%4.4s'\n" +"für Schrift `%4.4s', Sprache `%4.4s'.\n" + +#: test/ftdump.c:771 +msgid "" +"Lookups:\n" +"\n" +msgstr "" +"Lookups:\n" +"\n" + +#: test/ftdump.c:774 +#, c-format +msgid " %hu: type %hu, flag 0x%x\n" +msgstr " %hu: Typ %hu, Flag 0x%x\n" + +#: test/ftdump.c:809 +msgid "ftdump: Simple TrueType Dumper -- part of the FreeType project" +msgstr "ftdump: Ein einfacher TrueType Dumper -- Teil des FreeType-Projekts" + +#: test/ftdump.c:813 +#, c-format +msgid "" +"Usage: %s fontname[.ttf|.ttc]\n" +"\n" +msgstr "" +"Verwendung: %s Fontname[.ttf|.ttc]\n" +"\n" + +#: test/ftdump.c:845 test/ftlint.c:134 test/ftmetric.c:226 test/ftsbit.c:126 +msgid "Error while initializing engine.\n" +msgstr "Fehler beim Starten von FreeType.\n" + +#: test/ftdump.c:852 test/ftmetric.c:234 test/ftsbit.c:133 +msgid "Error while initializing embedded bitmap extension.\n" +msgstr "Fehler bei Initialisierung der Erweiterung für eingebettete Bitmaps.\n" + +#: test/ftdump.c:859 +msgid "Error while initializing GSUB extension.\n" +msgstr "Fehler beim Starten der GSUB-Erweiterung.\n" + +#: test/ftdump.c:875 test/ftlint.c:187 test/ftmetric.c:249 test/ftsbit.c:181 +#, c-format +msgid "Could not find or open %s.\n" +msgstr "Datei `%s' konnte nicht gefunden oder geöffnet werden.\n" + +#: test/ftdump.c:878 test/ftlint.c:193 test/ftmetric.c:252 test/ftsbit.c:187 +#, c-format +msgid "Error while opening %s.\n" +msgstr "Fehler beim Öffnen von %s.\n" + +#: test/ftlint.c:94 +msgid "" +"ftlint: Simple TrueType instruction tester -- part of the FreeType project" +msgstr "" +"ftlint: Ein einfacher TTF Instruktionen-Tester -- Teil des FreeType-Projekts" + +#: test/ftlint.c:99 +#, c-format +msgid "" +"Usage: %s ppem fontname[.ttf|.ttc] [fontname2..]\n" +"\n" +msgstr "" +"Verwendung: %s ppem Fontname[.ttf|.ttc] [Fontname2..]\n" +"\n" + +#: test/ftlint.c:226 test/ftsbit.c:224 +#, c-format +msgid "Could not set point size to %d.\n" +msgstr "Konnte die Schriftgröße nicht auf %d Punkt setzen.\n" + +#: test/ftlint.c:239 +msgid "" +"Error with\n" +" " +msgstr "" +"Fehler bei\n" +" " + +#: test/ftlint.c:240 +#, c-format +msgid "glyph %4u: %s\n" +msgstr "Glyph %4u: %s\n" + +#: test/ftlint.c:253 +msgid "1 fail.\n" +msgstr "1 mal gescheitert.\n" + +#: test/ftlint.c:255 +#, c-format +msgid "%d fails.\n" +msgstr "%d mal gescheitert.\n" + +#: test/ftmetric.c:68 +msgid "" +"ftmetric: Simple TTF metrics/glyph dumper -- part of the FreeType project" +msgstr "" +"ftmetric: Ein einfacher TTF Metrik/Glyph-Dumper -- Teil des FreeType-Projekts" + +#: test/ftmetric.c:72 +#, c-format +msgid "" +"Usage: %s [options below] point fontname[.ttf|.ttc]\n" +"\n" +" -B show sbit's metrics (default: none)\n" +" -c C use C'th font index of TrueType collection (default: 0)\n" +" -i index glyph index (default: 0)\n" +" -r R use resolution R dpi (default: 72)\n" +"\n" +msgstr "" +"Verwendung: %s [Optionen s.u.] Punktgröße Fontname[.ttf|.ttc]\n" +"\n" +" -B zeige Metriken von eingebetteten Bitmaps (Standardwert: nein)\n" +" -c C verwende den `C'ten Fontindex der TrueType-Collection\n" +" (Standardwert: 0)\n" +" -i Index Glyphindex (Standardwert: 0)\n" +" -r R verwende Auflösung `R' dpi (Standardwert: 72)\n" +"\n" + +#: test/ftmetric.c:259 +#, c-format +msgid "There are %d fonts in this collection.\n" +msgstr "Es gibt %d Fonts in dieser TrueType-Collection.\n" + +#: test/ftmetric.c:264 +#, c-format +msgid "There is no collection with index %d in this font file.\n" +msgstr "In dieser Fontdatei gibt es keine Collection mit Index %d.\n" + +#: test/ftmetric.c:278 +msgid "There is no embedded bitmap data in the font.\n" +msgstr "Konnte keine eingebetteten Bitmaps in Fontdatei finden.\n" + +#: test/ftmetric.c:308 +msgid "Could not set device resolutions.\n" +msgstr "Konnte die Geräteauflösung nicht setzen.\n" + +#: test/ftmetric.c:315 +msgid "Could not reset instance.\n" +msgstr "Konnte die Instanz nicht neu setzen.\n" + +#: test/ftmetric.c:321 +#, c-format +msgid "Instance metrics: ppemX %d, ppemY %d\n" +msgstr "Instanzmetriken: ppemX %d, ppemY %d\n" + +#: test/ftmetric.c:331 test/ftsbit.c:233 +msgid "Could not allocate glyph bitmap container.\n" +msgstr "Konnte den Glyphcontainer für Bitmaps nicht erzeugen.\n" + +#: test/ftmetric.c:339 test/ftsbit.c:257 +#, c-format +msgid "Can't load bitmap for glyph %d.\n" +msgstr "Kann Bitmap für Glyph %d nicht laden.\n" + +#: test/ftmetric.c:366 +msgid "Outline's metrics" +msgstr "Vektormetriken" + +#: test/ftmetric.c:368 +msgid "Outline glyph\n" +msgstr "Vektorglyph\n" + +#: test/ftsbit.c:89 +msgid "ftsbit: Simple TrueType `sbit' dumper -- part of the FreeType project" +msgstr "" +"ftsbit: Ein einfacher TrueType `sbit' Dumper -- Teil des FreeType-Projekts" + +#: test/ftsbit.c:94 +#, c-format +msgid "" +"Usage: %s ppem fontname[.ttf|.ttc] glyph_index [glyph_index2..]\n" +"\n" +msgstr "" +"Verwendung: %s ppem Fontname[.ttf|.ttc] Glyphindex [Glyphindex2..]\n" +"\n" + +#: test/ftsbit.c:199 +msgid "Could not find embedded bitmaps in this font.\n" +msgstr "Konnte keine eingebetteten Bitmaps in Fontdatei finden.\n" + +#: test/ftsbit.c:205 +msgid "Error while loading embedded bitmaps.\n" +msgstr "Fehler beim Laden von eingebettete Bitmaps.\n" + +#: test/ftsbit.c:251 +#, c-format +msgid " no bitmap for glyph %d.\n" +msgstr " keine Bitmap für Glyph %d.\n" + +#: test/ftsbit.c:263 +#, c-format +msgid "glyph index %d = %dx%d pixels, " +msgstr "Glyphindex %d = %dx%d Pixel, " + +#: test/ftsbit.c:266 +#, c-format +msgid "advance = %ld, minBearing = [%ld,%ld]\n" +msgstr "Vorschubbreite = %ld, `minBearing' = [%ld,%ld]\n" diff --git a/po/es.po b/po/es.po new file mode 100644 index 0000000..f502c2c --- /dev/null +++ b/po/es.po @@ -0,0 +1,762 @@ +# Spanish messages for FreeType. +# Copyright (C) 1998-99 Miguel A. Pérez Valdenebro +# Miguel A. Pérez Valdenebro , 1998. +# +msgid "" +msgstr "" +"Project-Id-Version: FreeType 1.3\n" +"POT-Creation-Date: 1999-09-07 12:49+0000\n" +"PO-Revision-Date: 1999-09-01\n" +"Last-Translator: \n" +"Language-Team: Spanish\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso-8859-1\n" +"Content-Transfer-Encoding: 8bit\n" + +#: lib/extend/ftxerr18.c:47 +msgid "Successful function call, no error." +msgstr "Éxito en la llamada a función." + +#: lib/extend/ftxerr18.c:50 +msgid "Invalid face handle." +msgstr "Ticket de diseño inválido." + +#: lib/extend/ftxerr18.c:52 +msgid "Invalid instance handle." +msgstr "Ticket de instancia inválido." + +#: lib/extend/ftxerr18.c:54 +msgid "Invalid glyph handle." +msgstr "Ticket de glifo inválido." + +#: lib/extend/ftxerr18.c:56 +msgid "Invalid charmap handle." +msgstr "Ticket de codificación inválido." + +#: lib/extend/ftxerr18.c:58 +msgid "Invalid result address." +msgstr "Dirección del resultado inválida." + +#: lib/extend/ftxerr18.c:60 +msgid "Invalid glyph index." +msgstr "Índice de glifo inválido." + +#: lib/extend/ftxerr18.c:62 +msgid "Invalid argument." +msgstr "Argumento inválido." + +#: lib/extend/ftxerr18.c:64 +msgid "Could not open file." +msgstr "No se puedo abrir el fichero." + +#: lib/extend/ftxerr18.c:66 +msgid "File is not a TrueType collection." +msgstr "El fichero no es una colección TrueType." + +#: lib/extend/ftxerr18.c:69 +msgid "Mandatory table missing." +msgstr "No se encuentra une tabla obligatoria." + +#: lib/extend/ftxerr18.c:71 +msgid "Invalid horizontal metrics (hmtx table broken)." +msgstr "Dimensiones horizontales (tabla `hmtx') incorrectas." + +#: lib/extend/ftxerr18.c:73 +msgid "Invalid charmap format." +msgstr "Formato de codificación inválido." + +#: lib/extend/ftxerr18.c:75 +msgid "Invalid ppem value." +msgstr "Tamaño en pixel invalido." + +#: lib/extend/ftxerr18.c:77 +msgid "Invalid vertical metrics (vmtx table broken)." +msgstr "Dimensiones verticales (tabla `vmtx') incorrectas." + +#: lib/extend/ftxerr18.c:80 +msgid "Invalid file format." +msgstr "Formato de fichero inválido." + +#: lib/extend/ftxerr18.c:83 +msgid "Invalid engine." +msgstr "Instancia de la biblioteca incorrecta." + +#: lib/extend/ftxerr18.c:85 +msgid "Too many extensions." +msgstr "Demasiadas extensiones (max:8)." + +#: lib/extend/ftxerr18.c:87 +msgid "Extensions unsupported." +msgstr "Extensión no soportada." + +#: lib/extend/ftxerr18.c:89 +msgid "Invalid extension id." +msgstr "Identificador de extensión inválido." + +#: lib/extend/ftxerr18.c:92 +msgid "No vertical data in font." +msgstr "Placa sin datos verticales." + +#: lib/extend/ftxerr18.c:95 +msgid "Maximum Profile (maxp) table missing." +msgstr "No se encuentra la tabla `maxp'." + +#: lib/extend/ftxerr18.c:97 +msgid "Font Header (head) table missing." +msgstr "No se encuentra la cabecera (head) de la placa." + +#: lib/extend/ftxerr18.c:99 +msgid "Horizontal Header (hhea) table missing." +msgstr "No se encuentra la cabecera para la horizontal (hhea)." + +#: lib/extend/ftxerr18.c:101 +msgid "Index to Location (loca) table missing." +msgstr "No se encuentra la tabla de los posiciones (loca)." + +#: lib/extend/ftxerr18.c:103 +msgid "Naming (name) table missing." +msgstr "No se encuentra la tabla de los nombres (name)." + +#: lib/extend/ftxerr18.c:105 +msgid "Character to Glyph Index Mapping (cmap) tables missing." +msgstr "" +"No se encuentra la tabla de correspondencia de carácter a glifo (cmap)." + +#: lib/extend/ftxerr18.c:107 +msgid "Horizontal Metrics (hmtx) table missing." +msgstr "No se encuentra la tabla de dimensiones horizontales (hmtx)." + +#: lib/extend/ftxerr18.c:109 +msgid "OS/2 table missing." +msgstr "No se encuentra la tabla `OS/2'." + +#: lib/extend/ftxerr18.c:111 +msgid "PostScript (post) table missing." +msgstr "No se encuentra la tabla PostScript (post)." + +#: lib/extend/ftxerr18.c:113 +msgid "Glyph (glyf) table missing." +msgstr "No se encuentra los glifos (tabla `glyf')." + +#: lib/extend/ftxerr18.c:118 +msgid "Out of memory." +msgstr "No hay suficiente memoria." + +#: lib/extend/ftxerr18.c:123 +msgid "Invalid file offset." +msgstr "Dirección en el fichero inválido." + +#: lib/extend/ftxerr18.c:125 +msgid "Invalid file read." +msgstr "Lectura de fichero incorrecta." + +#: lib/extend/ftxerr18.c:127 +msgid "Invalid frame access." +msgstr "Ventana de acceso inválida." + +#: lib/extend/ftxerr18.c:132 +msgid "Too many points." +msgstr "Demasiados puntos de control." + +#: lib/extend/ftxerr18.c:134 +msgid "Too many contours." +msgstr "Demasiados contornos." + +#: lib/extend/ftxerr18.c:136 +msgid "Invalid composite glyph." +msgstr "Glifo compuesto inválido." + +#: lib/extend/ftxerr18.c:138 +msgid "Too many instructions." +msgstr "Demasiadas instrucciones." + +#: lib/extend/ftxerr18.c:143 +msgid "Invalid opcode." +msgstr "Código de operación inválido." + +#: lib/extend/ftxerr18.c:145 +msgid "Too few arguments." +msgstr "Hace falta más argumentos." + +#: lib/extend/ftxerr18.c:147 +msgid "Stack overflow." +msgstr "Desbordamiento de pila." + +#: lib/extend/ftxerr18.c:149 +msgid "Code overflow." +msgstr "Desbordamiento de código." + +#: lib/extend/ftxerr18.c:151 +msgid "Bad argument." +msgstr "Argumento incorrecto." + +#: lib/extend/ftxerr18.c:153 +msgid "Divide by zero." +msgstr "División por cero." + +#: lib/extend/ftxerr18.c:155 +msgid "Storage overflow." +msgstr "Desbordamiento de capacidad en el almacen." + +#: lib/extend/ftxerr18.c:157 +msgid "Control Value (cvt) table overflow." +msgstr "Desbordamiento de capacidad (tabla CVT)." + +#: lib/extend/ftxerr18.c:159 +msgid "Invalid reference." +msgstr "Referencia incorrecta." + +#: lib/extend/ftxerr18.c:161 +msgid "Invalid distance." +msgstr "Distancia incorrecta." + +#: lib/extend/ftxerr18.c:163 +msgid "Interpolate twilight points." +msgstr "Interpolación de marcas (puntos de referencia)." + +#: lib/extend/ftxerr18.c:165 +msgid "`DEBUG' opcode found." +msgstr "Se ha encontrado la instrucción `DEBUG'." + +#: lib/extend/ftxerr18.c:167 +msgid "`ENDF' in byte-code stream." +msgstr "Se ha encontrado `ENDF' en el programa de un glifo." + +#: lib/extend/ftxerr18.c:169 +msgid "Out of code ranges." +msgstr "Demasiados espacios de ejecución (code ranges)." + +#: lib/extend/ftxerr18.c:171 +msgid "Nested function definitions." +msgstr "Definiciones de funciones encajadas." + +#: lib/extend/ftxerr18.c:173 +msgid "Invalid code range." +msgstr "Espacio de ejecución (code range) incorrecto." + +#: lib/extend/ftxerr18.c:175 +msgid "Invalid displacement." +msgstr "Desplazamiento inválido." + +#: lib/extend/ftxerr18.c:177 +msgid "Endless loop encountered while executing instructions." +msgstr "" +"Se ha encontrado bucle sin fin durante la ejecución de las instrucciones." + +#: lib/extend/ftxerr18.c:182 +msgid "Nested frame access." +msgstr "Ventanas de acceso encajadas." + +#: lib/extend/ftxerr18.c:184 +msgid "Invalid cache list." +msgstr "Lista de `cache' inválida." + +#: lib/extend/ftxerr18.c:186 +msgid "Could not find context." +msgstr "No se puede encontrar el contexto." + +#: lib/extend/ftxerr18.c:188 +msgid "Unlisted object." +msgstr "Este objeto no es encadenado en el `cache'." + +#: lib/extend/ftxerr18.c:193 +msgid "Raster pool overflow." +msgstr "Tramador: Desbordamiento de memoria." + +#: lib/extend/ftxerr18.c:195 +msgid "Raster: negative height encountered." +msgstr "Tramador: altura negativa." + +#: lib/extend/ftxerr18.c:197 +msgid "Raster: invalid value." +msgstr "Tramador: valor erroneo." + +#: lib/extend/ftxerr18.c:199 +msgid "Raster not initialized." +msgstr "Tramador no inicializado." + +#: lib/extend/ftxerr18.c:204 +msgid "Invalid kerning (kern) table format." +msgstr "Formato de la tabla `kern' incorrecto." + +#: lib/extend/ftxerr18.c:206 +msgid "Invalid kerning (kern) table." +msgstr "Tabla `kern' inválida." + +#: lib/extend/ftxerr18.c:208 +msgid "Invalid PostScript (post) table format." +msgstr "Formato de tabla PostScript (post) incorrecto." + +#: lib/extend/ftxerr18.c:210 +msgid "Invalid PostScript (post) table." +msgstr "Tabla PostScript (post) inválida." + +#: lib/extend/ftxerr18.c:216 +msgid "Invalid TrueType Open subtable format." +msgstr "Formato de la tabla TrueType Open incorrecto." + +#: lib/extend/ftxerr18.c:218 +msgid "Invalid TrueType Open subtable." +msgstr "Tabla TrueType Open inválida." + +#: lib/extend/ftxerr18.c:220 +msgid "Glyph(s) not covered by lookup." +msgstr "Estos glifos no existen en las tablas de busqueda (lookups)." + +#: lib/extend/ftxerr18.c:222 +msgid "Too many nested context substitutions." +msgstr "Demasiados cambios contextuales encajados." + +#: lib/extend/ftxerr18.c:224 +msgid "Invalid glyph substitution (GSUB) table format." +msgstr "Formato de la tabla de cambios de glifos (GSUB) incorrecto." + +#: lib/extend/ftxerr18.c:226 +msgid "Invalid glyph substitution (GSUB) table." +msgstr "Tabla de cambios de glifos (GSUB) inválida." + +#: lib/extend/ftxerr18.c:228 +msgid "Invalid glyph positioning (GPOS) table format." +msgstr "Formato de la tabla de posiciones de los glifos (GPOS) incorrecto." + +#: lib/extend/ftxerr18.c:230 +msgid "Invalid glyph positioning (GPOS) table." +msgstr "Tabla de posiciones de los glifos (GPOS) inválida." + +#: lib/extend/ftxerr18.c:237 +msgid "Invalid Error Number." +msgstr "Número de Error Inválido." + +#: test/fterror.c:60 +msgid "Start of fterror.\n" +msgstr "Inicio de fterror.\n" + +#: test/fterror.c:68 +msgid "End of fterror.\n" +msgstr "Fin de fterror.\n" + +#: test/ftdump.c:168 test/ftlint.c:207 test/ftmetric.c:292 +msgid "Could not create glyph container.\n" +msgstr "No se puede crear una caja de glifo.\n" + +#: test/ftdump.c:178 test/ftlint.c:215 test/ftmetric.c:301 test/ftsbit.c:213 +msgid "Could not create instance.\n" +msgstr "No se puede crear una instancia.\n" + +#: test/ftdump.c:187 +msgid "Could not create second instance.\n" +msgstr "No se puede crear una segunda instancia.\n" + +#: test/ftdump.c:193 +msgid "Memory footprint statistics:\n" +msgstr "Estadísticas de asignación de memoria:\n" + +#: test/ftdump.c:201 +msgid "face object" +msgstr "objeto diseño" + +#: test/ftdump.c:202 +msgid "glyph object" +msgstr "objeto glifo" + +#: test/ftdump.c:203 +msgid "instance object" +msgstr "objeto instancia" + +#: test/ftdump.c:207 +msgid "exec. context object" +msgstr "objeto contexto de calculo" + +#: test/ftdump.c:214 +msgid "total memory usage" +msgstr "uso total de memoria" + +#: test/ftdump.c:222 test/ftdump.c:574 test/ftdump.c:784 test/ftdump.c:921 +#: test/ftlint.c:274 test/ftlint.c:287 test/ftmetric.c:387 test/ftsbit.c:284 +#, c-format +msgid "FreeType error message: %s\n" +msgstr "Mensaje de error FreeType: %s\n" + +#: test/ftdump.c:299 +msgid "font name table entries\n" +msgstr "Entradas en la tabla de nombres\n" + +#: test/ftdump.c:309 +#, c-format +msgid "" +"PostScript name: %s\n" +"\n" +msgstr "" +"Nombre de la PostScript: %s\n" +"\n" + +#: test/ftdump.c:332 +msgid "character map encodings\n" +msgstr "Codificaciones del mapa de caracteres\n" + +#: test/ftdump.c:339 test/ftdump.c:483 +msgid "The file doesn't seem to have any encoding table.\n" +msgstr "La placa no parece tener ninguna tabla de codificación.\n" + +#: test/ftdump.c:343 test/ftdump.c:487 +#, c-format +msgid "" +"There are %hu encodings:\n" +"\n" +msgstr "" +"Hay %hu codificaciones:\n" +"\n" + +#: test/ftdump.c:348 +#, c-format +msgid "encoding %2u: " +msgstr " codificación %2u: " + +#: test/ftdump.c:375 test/ftdump.c:384 test/ftdump.c:447 +#, c-format +msgid "Unknown value %hu" +msgstr "Desconocido %hu" + +#: test/ftdump.c:454 +msgid "Unknown" +msgstr "Desconocido" + +#: test/ftdump.c:476 +msgid "ftxcmap test\n" +msgstr "Muestra de ftxcmap\n" + +#: test/ftdump.c:493 +#, c-format +msgid "encoding %2u:\n" +msgstr "Codificación %2u:\n" + +#: test/ftdump.c:498 +#, c-format +msgid "first: glyph index %hu, character code 0x%lx\n" +msgstr "primero: glifo índice %hu, codigo de carácter 0x%lx\n" + +#: test/ftdump.c:502 +#, c-format +msgid "next: glyph index %hu, character code 0x%lx\n" +msgstr "siguiente: glifo índice %hu, codigo de carácter 0x%lx\n" + +#: test/ftdump.c:506 +#, c-format +msgid "last: glyph index %hu, character code 0x%lx\n" +msgstr "ultimo: glifo índice %hu, codigo de carácter 0x%lx\n" + +#: test/ftdump.c:528 test/ftmetric.c:282 +msgid "Error while retrieving embedded bitmaps table.\n" +msgstr "Error durante la recuperación de los bitmaps.\n" + +#: test/ftdump.c:532 +msgid "embedded bitmap table\n" +msgstr "Tabla de bitmaps\n" + +#: test/ftdump.c:535 +#, c-format +msgid " version of embedded bitmap table: 0x%lx\n" +msgstr " version de la tabla de bitmap: 0x%lx\n" + +#: test/ftdump.c:537 +#, c-format +msgid " number of embedded bitmap strikes: %lu\n" +msgstr " número de tamaños de bitmaps: %lu\n" + +#: test/ftdump.c:547 +#, c-format +msgid " bitmap strike %hu/%lu: " +msgstr " tamaño %hu en %lu: " + +#: test/ftdump.c:550 +#, c-format +msgid "%hux%hu pixels, %hu-bit depth, glyphs [%hu..%hu]\n" +msgstr "%hux%hu pixels, en %hu bits, glifos [%hu...%hu]\n" + +#: test/ftdump.c:559 +#, c-format +msgid " range format (%hu:%hu) glyphs %hu..%hu\n" +msgstr " formato intervalo (%hu:%hu) glifos %hu...%hu\n" + +#: test/ftdump.c:610 +msgid "Error while loading GSUB table.\n" +msgstr "Error durante la creación de la tabla GSUB.\n" + +#: test/ftdump.c:614 +msgid "GSUB table\n" +msgstr "Table de cambios de glifos (GSUB)\n" + +#: test/ftdump.c:621 +msgid "Error while querying GSUB script list.\n" +msgstr "Error durante la busqueda de la lista de las escrituras en GSUB.\n" + +#: test/ftdump.c:634 +#, c-format +msgid "Error while selecting GSUB script `%4.4s'.\n" +msgstr "Error durante la selección de la escritura `%4.4s' en GSUB.\n" + +#: test/ftdump.c:639 +#, c-format +msgid " script `%4.4s' (index %hu):\n" +msgstr " escritura `%4.4s' (índice %hu):\n" + +#: test/ftdump.c:647 +#, c-format +msgid "Error while querying GSUB default language system for script `%4.4s'.\n" +msgstr "" +"Error durante la busqueda en GSUB de las informaciones\n" +"relativas a las lenguas estandar de la escritura `%4.4s'.\n" + +#: test/ftdump.c:652 +msgid " default language system:\n" +msgstr " lenguas estandar:\n" + +#: test/ftdump.c:665 +#, c-format +msgid "" +"Error while selecting GSUB feature `%4.4s'\n" +"for default language system of script `%4.4s'.\n" +msgstr "" +"Error durante la selección de la información `%4.4s' en GSUB\n" +"para las lenguas estandar de la escritura `%4.4s'.\n" + +#: test/ftdump.c:671 test/ftdump.c:752 +#, c-format +msgid " feature `%4.4s' (index %hu; lookup " +msgstr " información `%4.4s' (índice %hu: tabla de busqueda " + +#: test/ftdump.c:687 +#, c-format +msgid "Error while querying GSUB language list for script `%4.4s'.\n" +msgstr "" +"Error durante la busqueda de las lenguas de la escritura `%4.4s' en GSUB.\n" + +#: test/ftdump.c:704 +#, c-format +msgid "Error while selecting GSUB language `%4.4s' for script `%4.4s'.\n" +msgstr "" +"Error durante la selección de la lengua `%4.4s' para `%4.4s' en GSUB.\n" + +#: test/ftdump.c:709 +#, c-format +msgid " language `%4.4s' (index %hu):\n" +msgstr " lengua `%4.4s' (índice %hu):\n" + +#: test/ftdump.c:714 +#, c-format +msgid " required feature index %hu (lookup " +msgstr " información obligatoria índice %hu (tabla de busqueda " + +#: test/ftdump.c:729 +#, c-format +msgid "" +"Error while querying GSUB feature list\n" +"for script `%4.4s', language `%4.4s'.\n" +msgstr "" +"Error durante la busqueda en GSUB de las informaciones\n" +"relativas a la escritura `%4.4s', lengua `%4.4s'.\n" + +#: test/ftdump.c:746 +#, c-format +msgid "" +"Error while selecting GSUB feature `%4.4s'\n" +"for script `%4.4s', language `%4.4s'.\n" +msgstr "" +"Error durante la selección de la información `%4.4s'\n" +"relativa a la escritura `%4.4s', lengua `%4.4s' en GSUB.\n" + +#: test/ftdump.c:771 +msgid "" +"Lookups:\n" +"\n" +msgstr "Tabla de busqueda:\n" + +#: test/ftdump.c:774 +#, c-format +msgid " %hu: type %hu, flag 0x%x\n" +msgstr " %hu: tipo %hu, indicador 0x%x\n" + +# +#: test/ftdump.c:809 +msgid "ftdump: Simple TrueType Dumper -- part of the FreeType project" +msgstr "" +"ftdump: información sobre placas TrueType -- parte del proyecto FreeType" + +#: test/ftdump.c:813 +#, c-format +msgid "" +"Usage: %s fontname[.ttf|.ttc]\n" +"\n" +msgstr "" +"Uso: %s nombre_de_la_placa[.ttf|.ttc]\n" +"\n" + +#: test/ftdump.c:845 test/ftlint.c:134 test/ftmetric.c:226 test/ftsbit.c:126 +msgid "Error while initializing engine.\n" +msgstr "Error durante la inicialización de la biblioteca.\n" + +#: test/ftdump.c:852 test/ftmetric.c:234 test/ftsbit.c:133 +msgid "Error while initializing embedded bitmap extension.\n" +msgstr "Error durante la inicialización de la extensión `bitmap'.\n" + +#: test/ftdump.c:859 +msgid "Error while initializing GSUB extension.\n" +msgstr "Error durante la inicialización de la extensión `GSUB'.\n" + +#: test/ftdump.c:875 test/ftlint.c:187 test/ftmetric.c:249 test/ftsbit.c:181 +#, c-format +msgid "Could not find or open %s.\n" +msgstr "No se puede encontrar o abrir el fichero %s.\n" + +#: test/ftdump.c:878 test/ftlint.c:193 test/ftmetric.c:252 test/ftsbit.c:187 +#, c-format +msgid "Error while opening %s.\n" +msgstr "Error abriendo %s.\n" + +#: test/ftlint.c:94 +msgid "" +"ftlint: Simple TrueType instruction tester -- part of the FreeType project" +msgstr "" +"ftlint: verificador de instrucciones TrueType -- parte del proyecto FreeType" + +#: test/ftlint.c:99 +#, c-format +msgid "" +"Usage: %s ppem fontname[.ttf|.ttc] [fontname2..]\n" +"\n" +msgstr "" +"Uso: %s ppem nombre_de_la_placa[.ttf|.ttc] [nombre2...]\n" +"\n" + +#: test/ftlint.c:226 test/ftsbit.c:224 +#, c-format +msgid "Could not set point size to %d.\n" +msgstr "No se puede asignar el tamaño del punto a %d.\n" + +#: test/ftlint.c:239 +msgid "" +"Error with\n" +" " +msgstr "" +"Error con\n" +" " + +#: test/ftlint.c:240 +#, c-format +msgid "glyph %4u: %s\n" +msgstr "glifo %4u: %s\n" + +#: test/ftlint.c:253 +msgid "1 fail.\n" +msgstr "1 error.\n" + +#: test/ftlint.c:255 +#, c-format +msgid "%d fails.\n" +msgstr "%d errores.\n" + +#: test/ftmetric.c:68 +msgid "" +"ftmetric: Simple TTF metrics/glyph dumper -- part of the FreeType project" +msgstr "" +"ftmetric: información sobre dimensiones TrueType -- parte del proyecto " +"FreeType" + +#: test/ftmetric.c:72 +#, c-format +msgid "" +"Usage: %s [options below] point fontname[.ttf|.ttc]\n" +"\n" +" -B show sbit's metrics (default: none)\n" +" -c C use C'th font index of TrueType collection (default: 0)\n" +" -i index glyph index (default: 0)\n" +" -r R use resolution R dpi (default: 72)\n" +"\n" +msgstr "" +"Uso: %s [optiones] ppem nombre_de_la_placa[.ttf|.ttc]\n" +"\n" +" -B muestra dimensiones de los sbit's (default: no)\n" +" -c C usa (C+1)ª placa de la collección TrueType (default: 1ª)\n" +" -i index muestra esto glifo (default: primero glifo)\n" +" -r R usa resolución R en dpi (default: 72)\n" +"\n" + +#: test/ftmetric.c:259 +#, c-format +msgid "There are %d fonts in this collection.\n" +msgstr "Hay %d placas en esta collección.\n" + +#: test/ftmetric.c:264 +#, c-format +msgid "There is no collection with index %d in this font file.\n" +msgstr "No hay placa con índice %d en esto fichero.\n" + +#: test/ftmetric.c:278 +msgid "There is no embedded bitmap data in the font.\n" +msgstr "No hay bitmaps en esto fichero.\n" + +#: test/ftmetric.c:308 +msgid "Could not set device resolutions.\n" +msgstr "No se puede poner esta resolución.\n" + +#: test/ftmetric.c:315 +msgid "Could not reset instance.\n" +msgstr "No se puede inicializar la instancia.\n" + +#: test/ftmetric.c:321 +#, c-format +msgid "Instance metrics: ppemX %d, ppemY %d\n" +msgstr "Dimensiones: ppemX %d, ppemY %d\n" + +#: test/ftmetric.c:331 test/ftsbit.c:233 +msgid "Could not allocate glyph bitmap container.\n" +msgstr "No se puede crear un contenedor de bitmap.\n" + +#: test/ftmetric.c:339 test/ftsbit.c:257 +#, c-format +msgid "Can't load bitmap for glyph %d.\n" +msgstr "Ne se puede crear un bitmap para el glifo %d.\n" + +#: test/ftmetric.c:366 +msgid "Outline's metrics" +msgstr "Dimensiones del contorno" + +#: test/ftmetric.c:368 +msgid "Outline glyph\n" +msgstr "Glifo utilizando el contorno\n" + +#: test/ftsbit.c:89 +msgid "ftsbit: Simple TrueType `sbit' dumper -- part of the FreeType project" +msgstr "ftsbit: bitmaps de una placa TrueType -- parte del proyecto FreeType" + +#: test/ftsbit.c:94 +#, c-format +msgid "" +"Usage: %s ppem fontname[.ttf|.ttc] glyph_index [glyph_index2..]\n" +"\n" +msgstr "" +"Uso: %s ppem nombre_de_font[.ttf|.ttc] índice_de_glifo [índice2...]\n" +"\n" + +#: test/ftsbit.c:199 +msgid "Could not find embedded bitmaps in this font.\n" +msgstr "No se puede encontrar bitmaps en esto fichero.\n" + +#: test/ftsbit.c:205 +msgid "Error while loading embedded bitmaps.\n" +msgstr "Error durante la lectura de los bitmaps.\n" + +#: test/ftsbit.c:251 +#, c-format +msgid " no bitmap for glyph %d.\n" +msgstr " no bitmap para el glifo %d.\n" + +#: test/ftsbit.c:263 +#, c-format +msgid "glyph index %d = %dx%d pixels, " +msgstr "glifo índice %d = %dx%d pixels, " + +#: test/ftsbit.c:266 +#, c-format +msgid "advance = %ld, minBearing = [%ld,%ld]\n" +msgstr "`advance' = %ld, `bearings' = [%ld,%ld]\n" diff --git a/po/fr.po b/po/fr.po new file mode 100644 index 0000000..7a6af8b --- /dev/null +++ b/po/fr.po @@ -0,0 +1,752 @@ +# French messages for FreeType, without accents. +# Copyright (C) 1998-99 David Turner +# David Turner , 1998 +# +msgid "" +msgstr "" +"Project-Id-Version: FreeType 1.3\n" +"POT-Creation-Date: 1999-09-07 12:49+0000\n" +"PO-Revision-Date: 1999-09-01 20:00+0200\n" +"Last-Translator: David Turner \n" +"Language-Team: French\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=us-ascii\n" +"Content-Transfer-Encoding: 7bit\n" + +#: lib/extend/ftxerr18.c:47 +msgid "Successful function call, no error." +msgstr "Appel de fonction reussi, pas d'erreur." + +#: lib/extend/ftxerr18.c:50 +msgid "Invalid face handle." +msgstr "Mauvais handle d'oeil (face)." + +#: lib/extend/ftxerr18.c:52 +msgid "Invalid instance handle." +msgstr "Mauvais handle d'instance." + +#: lib/extend/ftxerr18.c:54 +msgid "Invalid glyph handle." +msgstr "Mauvais handle de glyphe." + +#: lib/extend/ftxerr18.c:56 +msgid "Invalid charmap handle." +msgstr "Mauvais handle d'encodage (charmap)." + +#: lib/extend/ftxerr18.c:58 +msgid "Invalid result address." +msgstr "Mauvaise adresse de resultat." + +#: lib/extend/ftxerr18.c:60 +msgid "Invalid glyph index." +msgstr "Numero de glyphe incorrect." + +#: lib/extend/ftxerr18.c:62 +msgid "Invalid argument." +msgstr "Argument incorrect." + +#: lib/extend/ftxerr18.c:64 +msgid "Could not open file." +msgstr "Le fichier n'a pas pu etre ouvert." + +#: lib/extend/ftxerr18.c:66 +msgid "File is not a TrueType collection." +msgstr "Ce fichier n'est pas une collection." + +#: lib/extend/ftxerr18.c:69 +msgid "Mandatory table missing." +msgstr "Il manque une table critique." + +#: lib/extend/ftxerr18.c:71 +msgid "Invalid horizontal metrics (hmtx table broken)." +msgstr "Metriques horizontales (table `hmtx') incorrectes." + +#: lib/extend/ftxerr18.c:73 +msgid "Invalid charmap format." +msgstr "Format d'encodage (charmap) invalide." + +#: lib/extend/ftxerr18.c:75 +msgid "Invalid ppem value." +msgstr "Taille en pixels incorrecte." + +#: lib/extend/ftxerr18.c:77 +msgid "Invalid vertical metrics (vmtx table broken)." +msgstr "Metriques verticales (table `vmtx') incorrectes." + +#: lib/extend/ftxerr18.c:80 +msgid "Invalid file format." +msgstr "Format de fichier invalide." + +#: lib/extend/ftxerr18.c:83 +msgid "Invalid engine." +msgstr "Mauvaise instance de bibliotheque (engine)" + +#: lib/extend/ftxerr18.c:85 +msgid "Too many extensions." +msgstr "Trop d'extensions utilisees (max: 8)." + +#: lib/extend/ftxerr18.c:87 +msgid "Extensions unsupported." +msgstr "Extensions non disponibles." + +#: lib/extend/ftxerr18.c:89 +msgid "Invalid extension id." +msgstr "Mauvais numero d'extension." + +#: lib/extend/ftxerr18.c:92 +msgid "No vertical data in font." +msgstr "Pas de donnees verticales dans cette police." + +#: lib/extend/ftxerr18.c:95 +msgid "Maximum Profile (maxp) table missing." +msgstr "Il manque la table `maxp'." + +#: lib/extend/ftxerr18.c:97 +msgid "Font Header (head) table missing." +msgstr "Il manque l'en-tete de police (head)." + +#: lib/extend/ftxerr18.c:99 +msgid "Horizontal Header (hhea) table missing." +msgstr "Il manque l'en-tete pour l'horizontale (hhea)." + +#: lib/extend/ftxerr18.c:101 +msgid "Index to Location (loca) table missing." +msgstr "Il manque les index de glyphes (table `loca')." + +#: lib/extend/ftxerr18.c:103 +msgid "Naming (name) table missing." +msgstr "Il manque la table des noms (name)." + +#: lib/extend/ftxerr18.c:105 +msgid "Character to Glyph Index Mapping (cmap) tables missing." +msgstr "Il manque la table des encodages (cmap)." + +#: lib/extend/ftxerr18.c:107 +msgid "Horizontal Metrics (hmtx) table missing." +msgstr "Il manque les metriques horizontales (hmtx)." + +#: lib/extend/ftxerr18.c:109 +msgid "OS/2 table missing." +msgstr "Il manque la table `OS/2'." + +#: lib/extend/ftxerr18.c:111 +msgid "PostScript (post) table missing." +msgstr "Il manque la table Postscript (post)." + +#: lib/extend/ftxerr18.c:113 +msgid "Glyph (glyf) table missing." +msgstr "Il manque les glyphes (table `glyf')." + +#: lib/extend/ftxerr18.c:118 +msgid "Out of memory." +msgstr "Pas assez de memoire." + +#: lib/extend/ftxerr18.c:123 +msgid "Invalid file offset." +msgstr "Adresse dans le fichier incorrecte." + +#: lib/extend/ftxerr18.c:125 +msgid "Invalid file read." +msgstr "Lecture du fichier impossible." + +#: lib/extend/ftxerr18.c:127 +msgid "Invalid frame access." +msgstr "Fenetre d'access incorrecte." + +#: lib/extend/ftxerr18.c:132 +msgid "Too many points." +msgstr "Trop de points." + +#: lib/extend/ftxerr18.c:134 +msgid "Too many contours." +msgstr "Trop de contours." + +#: lib/extend/ftxerr18.c:136 +msgid "Invalid composite glyph." +msgstr "Glyphe compose invalide." + +#: lib/extend/ftxerr18.c:138 +msgid "Too many instructions." +msgstr "Trop d'instructions." + +#: lib/extend/ftxerr18.c:143 +msgid "Invalid opcode." +msgstr "Code-operation invalide." + +#: lib/extend/ftxerr18.c:145 +msgid "Too few arguments." +msgstr "Il manque un ou des arguments." + +#: lib/extend/ftxerr18.c:147 +msgid "Stack overflow." +msgstr "Debordement de la pile." + +#: lib/extend/ftxerr18.c:149 +msgid "Code overflow." +msgstr "Debordement dans le code." + +#: lib/extend/ftxerr18.c:151 +msgid "Bad argument." +msgstr "Mauvais argument." + +#: lib/extend/ftxerr18.c:153 +msgid "Divide by zero." +msgstr "Division par zero." + +#: lib/extend/ftxerr18.c:155 +msgid "Storage overflow." +msgstr "Depassement de capacite (stockage)." + +#: lib/extend/ftxerr18.c:157 +msgid "Control Value (cvt) table overflow." +msgstr "Depassement de capacite (tableau cvt)." + +#: lib/extend/ftxerr18.c:159 +msgid "Invalid reference." +msgstr "Reference incorrecte." + +#: lib/extend/ftxerr18.c:161 +msgid "Invalid distance." +msgstr "Distance incorrecte." + +#: lib/extend/ftxerr18.c:163 +msgid "Interpolate twilight points." +msgstr "Interpolation de points de repere." + +#: lib/extend/ftxerr18.c:165 +msgid "`DEBUG' opcode found." +msgstr "Le code `DEBUG' a ete rencontre." + +#: lib/extend/ftxerr18.c:167 +msgid "`ENDF' in byte-code stream." +msgstr "'ENDF' invalide dans les instructions d'un glyphe." + +#: lib/extend/ftxerr18.c:169 +msgid "Out of code ranges." +msgstr "Pas assez d'espace d'execution (code ranges)." + +#: lib/extend/ftxerr18.c:171 +msgid "Nested function definitions." +msgstr "Definitions imbriquees de fonction." + +#: lib/extend/ftxerr18.c:173 +msgid "Invalid code range." +msgstr "Espace d'execution (code range) incorrect." + +#: lib/extend/ftxerr18.c:175 +msgid "Invalid displacement." +msgstr "Deplacement invalide." + +#: lib/extend/ftxerr18.c:177 +msgid "Endless loop encountered while executing instructions." +msgstr "Arret force d'une boucle infinie." + +#: lib/extend/ftxerr18.c:182 +msgid "Nested frame access." +msgstr "Fenetres d'acces imbriquees." + +#: lib/extend/ftxerr18.c:184 +msgid "Invalid cache list." +msgstr "(Mauvaise liste chainee de caches)." + +#: lib/extend/ftxerr18.c:186 +msgid "Could not find context." +msgstr "Contexte introuvable." + +#: lib/extend/ftxerr18.c:188 +msgid "Unlisted object." +msgstr "Objet non chaine dans le cache." + +#: lib/extend/ftxerr18.c:193 +msgid "Raster pool overflow." +msgstr "Debordement de memoire de la trameuse." + +#: lib/extend/ftxerr18.c:195 +msgid "Raster: negative height encountered." +msgstr "Trameuse: hauteur negative." + +#: lib/extend/ftxerr18.c:197 +msgid "Raster: invalid value." +msgstr "Trameuse: valeur incorrecte." + +#: lib/extend/ftxerr18.c:199 +msgid "Raster not initialized." +msgstr "Trameuse: non initialisee." + +#: lib/extend/ftxerr18.c:204 +msgid "Invalid kerning (kern) table format." +msgstr "Format de table de crenage (kern) invalide." + +#: lib/extend/ftxerr18.c:206 +msgid "Invalid kerning (kern) table." +msgstr "Table de crenage (kern) incorrecte." + +#: lib/extend/ftxerr18.c:208 +msgid "Invalid PostScript (post) table format." +msgstr "Format de table Postscript (post) invalide." + +#: lib/extend/ftxerr18.c:210 +msgid "Invalid PostScript (post) table." +msgstr "Table Postscript (post) incorrecte." + +#: lib/extend/ftxerr18.c:216 +msgid "Invalid TrueType Open subtable format." +msgstr "Format de table TrueType Open invalide." + +#: lib/extend/ftxerr18.c:218 +msgid "Invalid TrueType Open subtable." +msgstr "Sous-table TrueType Open incorrecte." + +#: lib/extend/ftxerr18.c:220 +msgid "Glyph(s) not covered by lookup." +msgstr "Des glyphes sont absents d'une table de recherche (lookup)." + +#: lib/extend/ftxerr18.c:222 +msgid "Too many nested context substitutions." +msgstr "Substitutions contextuelles imbriquees trop profondement." + +#: lib/extend/ftxerr18.c:224 +msgid "Invalid glyph substitution (GSUB) table format." +msgstr "Format de la table de substitution de glyphes (GSUB) invalide." + +#: lib/extend/ftxerr18.c:226 +msgid "Invalid glyph substitution (GSUB) table." +msgstr "Table de substitution de glyphes (GSUB) incorrecte." + +#: lib/extend/ftxerr18.c:228 +msgid "Invalid glyph positioning (GPOS) table format." +msgstr "Format de table de positionnement des glyphes (GPOS) invalide." + +#: lib/extend/ftxerr18.c:230 +msgid "Invalid glyph positioning (GPOS) table." +msgstr "Table de positionnement des glyphes (GPOS) incorrecte." + +#: lib/extend/ftxerr18.c:237 +msgid "Invalid Error Number." +msgstr "Numero d'erreur inconnu ?" + +#: test/fterror.c:60 +msgid "Start of fterror.\n" +msgstr "Debut de fterror.\n" + +#: test/fterror.c:68 +msgid "End of fterror.\n" +msgstr "Fin de fterror.\n" + +#: test/ftdump.c:168 test/ftlint.c:207 test/ftmetric.c:292 +msgid "Could not create glyph container.\n" +msgstr "Impossible de creer un conteneur de glyphe.\n" + +#: test/ftdump.c:178 test/ftlint.c:215 test/ftmetric.c:301 test/ftsbit.c:213 +msgid "Could not create instance.\n" +msgstr "Impossible de creer une instance\n" + +#: test/ftdump.c:187 +msgid "Could not create second instance.\n" +msgstr "Impossible de creer une deuxieme instance.\n" + +#: test/ftdump.c:193 +msgid "Memory footprint statistics:\n" +msgstr "Statistiques de consommation de la memoire:\n" + +#: test/ftdump.c:201 +msgid "face object" +msgstr "objet oeil" + +#: test/ftdump.c:202 +msgid "glyph object" +msgstr "objet glyphe" + +#: test/ftdump.c:203 +msgid "instance object" +msgstr "objet instance" + +#: test/ftdump.c:207 +msgid "exec. context object" +msgstr "objet contexte" + +#: test/ftdump.c:214 +msgid "total memory usage" +msgstr "consommation totale de memoire" + +#: test/ftdump.c:222 test/ftdump.c:574 test/ftdump.c:784 test/ftdump.c:921 +#: test/ftlint.c:274 test/ftlint.c:287 test/ftmetric.c:387 test/ftsbit.c:284 +#, c-format +msgid "FreeType error message: %s\n" +msgstr "Message d'erreur FreeType : %s\n" + +#: test/ftdump.c:299 +msgid "font name table entries\n" +msgstr "Elements du tableau des noms\n" + +#: test/ftdump.c:309 +#, c-format +msgid "" +"PostScript name: %s\n" +"\n" +msgstr "" +"Nom de Postscript : %s\n" +"\n" + +#: test/ftdump.c:332 +msgid "character map encodings\n" +msgstr "Encodages des caracteres\n" + +#: test/ftdump.c:339 test/ftdump.c:483 +msgid "The file doesn't seem to have any encoding table.\n" +msgstr "Cette police ne semble pas avoir de table d'encodage.\n" + +#: test/ftdump.c:343 test/ftdump.c:487 +#, c-format +msgid "" +"There are %hu encodings:\n" +"\n" +msgstr "" +"Il y a %hu encodage(s) :\n" +"\n" + +#: test/ftdump.c:348 +#, c-format +msgid "encoding %2u: " +msgstr "encodage %2u : " + +#: test/ftdump.c:375 test/ftdump.c:384 test/ftdump.c:447 +#, c-format +msgid "Unknown value %hu" +msgstr "(valeur inconnue %hu)" + +#: test/ftdump.c:454 +msgid "Unknown" +msgstr "(inconnu)" + +#: test/ftdump.c:476 +msgid "ftxcmap test\n" +msgstr "Test de ftxcmap\n" + +#: test/ftdump.c:493 +#, c-format +msgid "encoding %2u:\n" +msgstr "encodage %2u :\n" + +#: test/ftdump.c:498 +#, c-format +msgid "first: glyph index %hu, character code 0x%lx\n" +msgstr "premier : glyphe numero %hu, caractere code 0x%lx\n" + +#: test/ftdump.c:502 +#, c-format +msgid "next: glyph index %hu, character code 0x%lx\n" +msgstr "suivant : glyphe numero %hu, caractere code 0x%lx\n" + +#: test/ftdump.c:506 +#, c-format +msgid "last: glyph index %hu, character code 0x%lx\n" +msgstr "dernier : glyphe numero %hu, caractere code 0x%lx\n" + +#: test/ftdump.c:528 test/ftmetric.c:282 +msgid "Error while retrieving embedded bitmaps table.\n" +msgstr "Erreur pendant la recuperation de la table des bitmaps.\n" + +#: test/ftdump.c:532 +msgid "embedded bitmap table\n" +msgstr "Table des bitmaps incorpores\n" + +#: test/ftdump.c:535 +#, c-format +msgid " version of embedded bitmap table: 0x%lx\n" +msgstr " version de la table de bitmaps : 0x%lx\n" + +#: test/ftdump.c:537 +#, c-format +msgid " number of embedded bitmap strikes: %lu\n" +msgstr " nombre de tailles de bitmaps : %lu\n" + +#: test/ftdump.c:547 +#, c-format +msgid " bitmap strike %hu/%lu: " +msgstr " taille de bitmap %hu sur %lu : " + +#: test/ftdump.c:550 +#, c-format +msgid "%hux%hu pixels, %hu-bit depth, glyphs [%hu..%hu]\n" +msgstr "%hux%hu pixels par %hu bit(s), glyphes de %hu a %hu\n" + +#: test/ftdump.c:559 +#, c-format +msgid " range format (%hu:%hu) glyphs %hu..%hu\n" +msgstr " format intervalle (%hu:%hu) glyphes %hu a %hu\n" + +#: test/ftdump.c:610 +msgid "Error while loading GSUB table.\n" +msgstr "Erreur en chargeant la table GSUB.\n" + +#: test/ftdump.c:614 +msgid "GSUB table\n" +msgstr "Table des substitutions de glyphes (GSUB)\n" + +#: test/ftdump.c:621 +msgid "Error while querying GSUB script list.\n" +msgstr "Erreur en demandant la liste des ecritures dans GSUB.\n" + +#: test/ftdump.c:634 +#, c-format +msgid "Error while selecting GSUB script `%4.4s'.\n" +msgstr "Erreur en selectionnant l'ecriture `%4.4s' dans GSUB.\n" + +#: test/ftdump.c:639 +#, c-format +msgid " script `%4.4s' (index %hu):\n" +msgstr " Ecriture `%4.4s' (numero %hu)\n" + +#: test/ftdump.c:647 +#, c-format +msgid "Error while querying GSUB default language system for script `%4.4s'.\n" +msgstr "Erreur en cherchant pour les langues standards de `%4.4s' dans GSUB.\n" + +#: test/ftdump.c:652 +msgid " default language system:\n" +msgstr " Langue standard :\n" + +#: test/ftdump.c:665 +#, c-format +msgid "" +"Error while selecting GSUB feature `%4.4s'\n" +"for default language system of script `%4.4s'.\n" +msgstr "" +"Erreur en selectionnant dans GSUB l'information `%4.4s'\n" +"pour la langue standard de l'ecriture `%4.4s'.\n" + +#: test/ftdump.c:671 test/ftdump.c:752 +#, c-format +msgid " feature `%4.4s' (index %hu; lookup " +msgstr " information `%4.4s' (numero %hu ; table(s) de recherche " + +#: test/ftdump.c:687 +#, c-format +msgid "Error while querying GSUB language list for script `%4.4s'.\n" +msgstr "Erreur en demandant la liste des langues pour `%4.4s' dans GSUB.\n" + +#: test/ftdump.c:704 +#, c-format +msgid "Error while selecting GSUB language `%4.4s' for script `%4.4s'.\n" +msgstr "Erreur en selectionnant la langue `%4.4s' pour `%4.4s' dans GSUB.\n" + +#: test/ftdump.c:709 +#, c-format +msgid " language `%4.4s' (index %hu):\n" +msgstr " langue `%4.4s' (numero %hu) :\n" + +#: test/ftdump.c:714 +#, c-format +msgid " required feature index %hu (lookup " +msgstr " information requise (table(s) de recherche " + +#: test/ftdump.c:729 +#, c-format +msgid "" +"Error while querying GSUB feature list\n" +"for script `%4.4s', language `%4.4s'.\n" +msgstr "" +"Erreur en recherchant dans GSUB la liste des informations\n" +"pour l'ecriture `%4.4s', langue `%4.4s'.\n" + +#: test/ftdump.c:746 +#, c-format +msgid "" +"Error while selecting GSUB feature `%4.4s'\n" +"for script `%4.4s', language `%4.4s'.\n" +msgstr "" +"Erreur en selectionnant dans GSUB l'information `%4.4s'\n" +"pour l'ecriture `%4.4s', langue `%4.4s'.\n" + +#: test/ftdump.c:771 +msgid "" +"Lookups:\n" +"\n" +msgstr " Tables de recherche :\n" + +#: test/ftdump.c:774 +#, c-format +msgid " %hu: type %hu, flag 0x%x\n" +msgstr "%4hu : type %hu, drapeaux 0x%x\n" + +#: test/ftdump.c:809 +msgid "ftdump: Simple TrueType Dumper -- part of the FreeType project" +msgstr "ftdump : utilitaire d'informations TrueType -- www.freetype.org" + +#: test/ftdump.c:813 +#, c-format +msgid "" +"Usage: %s fontname[.ttf|.ttc]\n" +"\n" +msgstr "" +"Utilisation : %s nompolice[.ttf|.ttc]\n" +"\n" + +#: test/ftdump.c:845 test/ftlint.c:134 test/ftmetric.c:226 test/ftsbit.c:126 +msgid "Error while initializing engine.\n" +msgstr "Erreur lors de l'initialisation de FreeType.\n" + +#: test/ftdump.c:852 test/ftmetric.c:234 test/ftsbit.c:133 +msgid "Error while initializing embedded bitmap extension.\n" +msgstr "Erreur lors de l'initialisation de l'extension `bitmaps'.\n" + +#: test/ftdump.c:859 +msgid "Error while initializing GSUB extension.\n" +msgstr "Erreur lors de l'initialisation de l'extension `GSUB'.\n" + +#: test/ftdump.c:875 test/ftlint.c:187 test/ftmetric.c:249 test/ftsbit.c:181 +#, c-format +msgid "Could not find or open %s.\n" +msgstr "Impossible de trouver ou d'ouvrir %s.\n" + +#: test/ftdump.c:878 test/ftlint.c:193 test/ftmetric.c:252 test/ftsbit.c:187 +#, c-format +msgid "Error while opening %s.\n" +msgstr "Erreur lors de l'ouverture de %s.\n" + +#: test/ftlint.c:94 +msgid "" +"ftlint: Simple TrueType instruction tester -- part of the FreeType project" +msgstr "" +"ftlint : verificateur simple d'instructions TrueType - www.freetype.org" + +#: test/ftlint.c:99 +#, c-format +msgid "" +"Usage: %s ppem fontname[.ttf|.ttc] [fontname2..]\n" +"\n" +msgstr "" +"Utilisation : %s ppem nompolice[.ttf|.ttc] [nompolice2...]\n" +"\n" + +#: test/ftlint.c:226 test/ftsbit.c:224 +#, c-format +msgid "Could not set point size to %d.\n" +msgstr "Impossible de selectionner la taille %d.\n" + +#: test/ftlint.c:239 +msgid "" +"Error with\n" +" " +msgstr "" +"Erreur avec\n" +" " + +#: test/ftlint.c:240 +#, c-format +msgid "glyph %4u: %s\n" +msgstr "glyphe %4u : %s\n" + +#: test/ftlint.c:253 +msgid "1 fail.\n" +msgstr "1 echec.\n" + +#: test/ftlint.c:255 +#, c-format +msgid "%d fails.\n" +msgstr "%d echecs.\n" + +#: test/ftmetric.c:68 +msgid "" +"ftmetric: Simple TTF metrics/glyph dumper -- part of the FreeType project" +msgstr "ftmetric : affichage des metriques TrueType -- www.freetype.org" + +#: test/ftmetric.c:72 +#, c-format +msgid "" +"Usage: %s [options below] point fontname[.ttf|.ttc]\n" +"\n" +" -B show sbit's metrics (default: none)\n" +" -c C use C'th font index of TrueType collection (default: 0)\n" +" -i index glyph index (default: 0)\n" +" -r R use resolution R dpi (default: 72)\n" +"\n" +msgstr "" +"Utilisation : %s [options] point nompolice[.ttf|.ttc]\n" +"\n" +" -B montrer les metriques des bitmaps (defaut : non)\n" +" -c C utilise la police numero C d'une collection (defaut : 0)\n" +" -i index numero du glyphe (default : 0)\n" +" -r R resolution en dpi (defaut : 72)\n" +"\n" + +#: test/ftmetric.c:259 +#, c-format +msgid "There are %d fonts in this collection.\n" +msgstr "Il y a %d polices dans cette collection.\n" + +#: test/ftmetric.c:264 +#, c-format +msgid "There is no collection with index %d in this font file.\n" +msgstr "Il n'y a aucune police d'indice %d dans cette collection.\n" + +#: test/ftmetric.c:278 +msgid "There is no embedded bitmap data in the font.\n" +msgstr "Il n'y a pas de bitmaps dans cette police.\n" + +#: test/ftmetric.c:308 +msgid "Could not set device resolutions.\n" +msgstr "Impossible de changer la resolution.\n" + +#: test/ftmetric.c:315 +msgid "Could not reset instance.\n" +msgstr "Impossible de changer la taile.\n" + +#: test/ftmetric.c:321 +#, c-format +msgid "Instance metrics: ppemX %d, ppemY %d\n" +msgstr "Metriques de l'instance : ppemX %d ppemY %d\n" + +#: test/ftmetric.c:331 test/ftsbit.c:233 +msgid "Could not allocate glyph bitmap container.\n" +msgstr "Impossible d'allouer un conteneur de glyphe.\n" + +#: test/ftmetric.c:339 test/ftsbit.c:257 +#, c-format +msgid "Can't load bitmap for glyph %d.\n" +msgstr "Impossible de charger le bitmap du glyphe %d.\n" + +#: test/ftmetric.c:366 +msgid "Outline's metrics" +msgstr "Metriques du dessin vectorise" + +#: test/ftmetric.c:368 +msgid "Outline glyph\n" +msgstr "glyphe du dessin vectorise\n" + +#: test/ftsbit.c:89 +msgid "ftsbit: Simple TrueType `sbit' dumper -- part of the FreeType project" +msgstr "ftsbit : affichage des `sbit' TrueType -- www.freetype.org" + +#: test/ftsbit.c:94 +#, c-format +msgid "" +"Usage: %s ppem fontname[.ttf|.ttc] glyph_index [glyph_index2..]\n" +"\n" +msgstr "" +"Utilisation : %s ppm nompolice[.ttf|.ttc] numero_glyphe [numero_glyphe2...]\n" +"\n" + +#: test/ftsbit.c:199 +msgid "Could not find embedded bitmaps in this font.\n" +msgstr "Pas de bitmaps dans cette police.\n" + +#: test/ftsbit.c:205 +msgid "Error while loading embedded bitmaps.\n" +msgstr "Erreur lors du chargement des bitmaps.\n" + +#: test/ftsbit.c:251 +#, c-format +msgid " no bitmap for glyph %d.\n" +msgstr " pas de bitmap pour le glyphe %d.\n" + +#: test/ftsbit.c:263 +#, c-format +msgid "glyph index %d = %dx%d pixels, " +msgstr "glyphe numero %d = %dx%d pixels, " + +#: test/ftsbit.c:266 +#, c-format +msgid "advance = %ld, minBearing = [%ld,%ld]\n" +msgstr "chasse = %ld, approches = [%ld,%ld]\n" diff --git a/po/freetype.pot b/po/freetype.pot new file mode 100644 index 0000000..aaad9ca --- /dev/null +++ b/po/freetype.pot @@ -0,0 +1,727 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Free Software Foundation, Inc. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 1999-09-07 12:49+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: ENCODING\n" + +#: lib/extend/ftxerr18.c:47 +msgid "Successful function call, no error." +msgstr "" + +#: lib/extend/ftxerr18.c:50 +msgid "Invalid face handle." +msgstr "" + +#: lib/extend/ftxerr18.c:52 +msgid "Invalid instance handle." +msgstr "" + +#: lib/extend/ftxerr18.c:54 +msgid "Invalid glyph handle." +msgstr "" + +#: lib/extend/ftxerr18.c:56 +msgid "Invalid charmap handle." +msgstr "" + +#: lib/extend/ftxerr18.c:58 +msgid "Invalid result address." +msgstr "" + +#: lib/extend/ftxerr18.c:60 +msgid "Invalid glyph index." +msgstr "" + +#: lib/extend/ftxerr18.c:62 +msgid "Invalid argument." +msgstr "" + +#: lib/extend/ftxerr18.c:64 +msgid "Could not open file." +msgstr "" + +#: lib/extend/ftxerr18.c:66 +msgid "File is not a TrueType collection." +msgstr "" + +#: lib/extend/ftxerr18.c:69 +msgid "Mandatory table missing." +msgstr "" + +#: lib/extend/ftxerr18.c:71 +msgid "Invalid horizontal metrics (hmtx table broken)." +msgstr "" + +#: lib/extend/ftxerr18.c:73 +msgid "Invalid charmap format." +msgstr "" + +#: lib/extend/ftxerr18.c:75 +msgid "Invalid ppem value." +msgstr "" + +#: lib/extend/ftxerr18.c:77 +msgid "Invalid vertical metrics (vmtx table broken)." +msgstr "" + +#: lib/extend/ftxerr18.c:80 +msgid "Invalid file format." +msgstr "" + +#: lib/extend/ftxerr18.c:83 +msgid "Invalid engine." +msgstr "" + +#: lib/extend/ftxerr18.c:85 +msgid "Too many extensions." +msgstr "" + +#: lib/extend/ftxerr18.c:87 +msgid "Extensions unsupported." +msgstr "" + +#: lib/extend/ftxerr18.c:89 +msgid "Invalid extension id." +msgstr "" + +#: lib/extend/ftxerr18.c:92 +msgid "No vertical data in font." +msgstr "" + +#: lib/extend/ftxerr18.c:95 +msgid "Maximum Profile (maxp) table missing." +msgstr "" + +#: lib/extend/ftxerr18.c:97 +msgid "Font Header (head) table missing." +msgstr "" + +#: lib/extend/ftxerr18.c:99 +msgid "Horizontal Header (hhea) table missing." +msgstr "" + +#: lib/extend/ftxerr18.c:101 +msgid "Index to Location (loca) table missing." +msgstr "" + +#: lib/extend/ftxerr18.c:103 +msgid "Naming (name) table missing." +msgstr "" + +#: lib/extend/ftxerr18.c:105 +msgid "Character to Glyph Index Mapping (cmap) tables missing." +msgstr "" + +#: lib/extend/ftxerr18.c:107 +msgid "Horizontal Metrics (hmtx) table missing." +msgstr "" + +#: lib/extend/ftxerr18.c:109 +msgid "OS/2 table missing." +msgstr "" + +#: lib/extend/ftxerr18.c:111 +msgid "PostScript (post) table missing." +msgstr "" + +#: lib/extend/ftxerr18.c:113 +msgid "Glyph (glyf) table missing." +msgstr "" + +#: lib/extend/ftxerr18.c:118 +msgid "Out of memory." +msgstr "" + +#: lib/extend/ftxerr18.c:123 +msgid "Invalid file offset." +msgstr "" + +#: lib/extend/ftxerr18.c:125 +msgid "Invalid file read." +msgstr "" + +#: lib/extend/ftxerr18.c:127 +msgid "Invalid frame access." +msgstr "" + +#: lib/extend/ftxerr18.c:132 +msgid "Too many points." +msgstr "" + +#: lib/extend/ftxerr18.c:134 +msgid "Too many contours." +msgstr "" + +#: lib/extend/ftxerr18.c:136 +msgid "Invalid composite glyph." +msgstr "" + +#: lib/extend/ftxerr18.c:138 +msgid "Too many instructions." +msgstr "" + +#: lib/extend/ftxerr18.c:143 +msgid "Invalid opcode." +msgstr "" + +#: lib/extend/ftxerr18.c:145 +msgid "Too few arguments." +msgstr "" + +#: lib/extend/ftxerr18.c:147 +msgid "Stack overflow." +msgstr "" + +#: lib/extend/ftxerr18.c:149 +msgid "Code overflow." +msgstr "" + +#: lib/extend/ftxerr18.c:151 +msgid "Bad argument." +msgstr "" + +#: lib/extend/ftxerr18.c:153 +msgid "Divide by zero." +msgstr "" + +#: lib/extend/ftxerr18.c:155 +msgid "Storage overflow." +msgstr "" + +#: lib/extend/ftxerr18.c:157 +msgid "Control Value (cvt) table overflow." +msgstr "" + +#: lib/extend/ftxerr18.c:159 +msgid "Invalid reference." +msgstr "" + +#: lib/extend/ftxerr18.c:161 +msgid "Invalid distance." +msgstr "" + +#: lib/extend/ftxerr18.c:163 +msgid "Interpolate twilight points." +msgstr "" + +#: lib/extend/ftxerr18.c:165 +msgid "`DEBUG' opcode found." +msgstr "" + +#: lib/extend/ftxerr18.c:167 +msgid "`ENDF' in byte-code stream." +msgstr "" + +#: lib/extend/ftxerr18.c:169 +msgid "Out of code ranges." +msgstr "" + +#: lib/extend/ftxerr18.c:171 +msgid "Nested function definitions." +msgstr "" + +#: lib/extend/ftxerr18.c:173 +msgid "Invalid code range." +msgstr "" + +#: lib/extend/ftxerr18.c:175 +msgid "Invalid displacement." +msgstr "" + +#: lib/extend/ftxerr18.c:177 +msgid "Endless loop encountered while executing instructions." +msgstr "" + +#: lib/extend/ftxerr18.c:182 +msgid "Nested frame access." +msgstr "" + +#: lib/extend/ftxerr18.c:184 +msgid "Invalid cache list." +msgstr "" + +#: lib/extend/ftxerr18.c:186 +msgid "Could not find context." +msgstr "" + +#: lib/extend/ftxerr18.c:188 +msgid "Unlisted object." +msgstr "" + +#: lib/extend/ftxerr18.c:193 +msgid "Raster pool overflow." +msgstr "" + +#: lib/extend/ftxerr18.c:195 +msgid "Raster: negative height encountered." +msgstr "" + +#: lib/extend/ftxerr18.c:197 +msgid "Raster: invalid value." +msgstr "" + +#: lib/extend/ftxerr18.c:199 +msgid "Raster not initialized." +msgstr "" + +#: lib/extend/ftxerr18.c:204 +msgid "Invalid kerning (kern) table format." +msgstr "" + +#: lib/extend/ftxerr18.c:206 +msgid "Invalid kerning (kern) table." +msgstr "" + +#: lib/extend/ftxerr18.c:208 +msgid "Invalid PostScript (post) table format." +msgstr "" + +#: lib/extend/ftxerr18.c:210 +msgid "Invalid PostScript (post) table." +msgstr "" + +#: lib/extend/ftxerr18.c:216 +msgid "Invalid TrueType Open subtable format." +msgstr "" + +#: lib/extend/ftxerr18.c:218 +msgid "Invalid TrueType Open subtable." +msgstr "" + +#: lib/extend/ftxerr18.c:220 +msgid "Glyph(s) not covered by lookup." +msgstr "" + +#: lib/extend/ftxerr18.c:222 +msgid "Too many nested context substitutions." +msgstr "" + +#: lib/extend/ftxerr18.c:224 +msgid "Invalid glyph substitution (GSUB) table format." +msgstr "" + +#: lib/extend/ftxerr18.c:226 +msgid "Invalid glyph substitution (GSUB) table." +msgstr "" + +#: lib/extend/ftxerr18.c:228 +msgid "Invalid glyph positioning (GPOS) table format." +msgstr "" + +#: lib/extend/ftxerr18.c:230 +msgid "Invalid glyph positioning (GPOS) table." +msgstr "" + +#: lib/extend/ftxerr18.c:237 +msgid "Invalid Error Number." +msgstr "" + +#: test/fterror.c:60 +msgid "Start of fterror.\n" +msgstr "" + +#: test/fterror.c:68 +msgid "End of fterror.\n" +msgstr "" + +#: test/ftdump.c:168 test/ftlint.c:207 test/ftmetric.c:292 +msgid "Could not create glyph container.\n" +msgstr "" + +#: test/ftdump.c:178 test/ftlint.c:215 test/ftmetric.c:301 test/ftsbit.c:213 +msgid "Could not create instance.\n" +msgstr "" + +#: test/ftdump.c:187 +msgid "Could not create second instance.\n" +msgstr "" + +#: test/ftdump.c:193 +msgid "Memory footprint statistics:\n" +msgstr "" + +#: test/ftdump.c:201 +msgid "face object" +msgstr "" + +#: test/ftdump.c:202 +msgid "glyph object" +msgstr "" + +#: test/ftdump.c:203 +msgid "instance object" +msgstr "" + +#: test/ftdump.c:207 +msgid "exec. context object" +msgstr "" + +#: test/ftdump.c:214 +msgid "total memory usage" +msgstr "" + +#: test/ftdump.c:222 test/ftdump.c:574 test/ftdump.c:784 test/ftdump.c:921 +#: test/ftlint.c:274 test/ftlint.c:287 test/ftmetric.c:387 test/ftsbit.c:284 +#, c-format +msgid "FreeType error message: %s\n" +msgstr "" + +#: test/ftdump.c:299 +msgid "font name table entries\n" +msgstr "" + +#: test/ftdump.c:309 +#, c-format +msgid "" +"PostScript name: %s\n" +"\n" +msgstr "" + +#: test/ftdump.c:332 +msgid "character map encodings\n" +msgstr "" + +#: test/ftdump.c:339 test/ftdump.c:483 +msgid "The file doesn't seem to have any encoding table.\n" +msgstr "" + +#: test/ftdump.c:343 test/ftdump.c:487 +#, c-format +msgid "" +"There are %hu encodings:\n" +"\n" +msgstr "" + +#: test/ftdump.c:348 +#, c-format +msgid "encoding %2u: " +msgstr "" + +#: test/ftdump.c:375 test/ftdump.c:384 test/ftdump.c:447 +#, c-format +msgid "Unknown value %hu" +msgstr "" + +#: test/ftdump.c:454 +msgid "Unknown" +msgstr "" + +#: test/ftdump.c:476 +msgid "ftxcmap test\n" +msgstr "" + +#: test/ftdump.c:493 +#, c-format +msgid "encoding %2u:\n" +msgstr "" + +#: test/ftdump.c:498 +#, c-format +msgid "first: glyph index %hu, character code 0x%lx\n" +msgstr "" + +#: test/ftdump.c:502 +#, c-format +msgid "next: glyph index %hu, character code 0x%lx\n" +msgstr "" + +#: test/ftdump.c:506 +#, c-format +msgid "last: glyph index %hu, character code 0x%lx\n" +msgstr "" + +#: test/ftdump.c:528 test/ftmetric.c:282 +msgid "Error while retrieving embedded bitmaps table.\n" +msgstr "" + +#: test/ftdump.c:532 +msgid "embedded bitmap table\n" +msgstr "" + +#: test/ftdump.c:535 +#, c-format +msgid " version of embedded bitmap table: 0x%lx\n" +msgstr "" + +#: test/ftdump.c:537 +#, c-format +msgid " number of embedded bitmap strikes: %lu\n" +msgstr "" + +#: test/ftdump.c:547 +#, c-format +msgid " bitmap strike %hu/%lu: " +msgstr "" + +#: test/ftdump.c:550 +#, c-format +msgid "%hux%hu pixels, %hu-bit depth, glyphs [%hu..%hu]\n" +msgstr "" + +#: test/ftdump.c:559 +#, c-format +msgid " range format (%hu:%hu) glyphs %hu..%hu\n" +msgstr "" + +#: test/ftdump.c:610 +msgid "Error while loading GSUB table.\n" +msgstr "" + +#: test/ftdump.c:614 +msgid "GSUB table\n" +msgstr "" + +#: test/ftdump.c:621 +msgid "Error while querying GSUB script list.\n" +msgstr "" + +#: test/ftdump.c:634 +#, c-format +msgid "Error while selecting GSUB script `%4.4s'.\n" +msgstr "" + +#: test/ftdump.c:639 +#, c-format +msgid " script `%4.4s' (index %hu):\n" +msgstr "" + +#: test/ftdump.c:647 +#, c-format +msgid "Error while querying GSUB default language system for script `%4.4s'.\n" +msgstr "" + +#: test/ftdump.c:652 +msgid " default language system:\n" +msgstr "" + +#: test/ftdump.c:665 +#, c-format +msgid "" +"Error while selecting GSUB feature `%4.4s'\n" +"for default language system of script `%4.4s'.\n" +msgstr "" + +#: test/ftdump.c:671 test/ftdump.c:752 +#, c-format +msgid " feature `%4.4s' (index %hu; lookup " +msgstr "" + +#: test/ftdump.c:687 +#, c-format +msgid "Error while querying GSUB language list for script `%4.4s'.\n" +msgstr "" + +#: test/ftdump.c:704 +#, c-format +msgid "Error while selecting GSUB language `%4.4s' for script `%4.4s'.\n" +msgstr "" + +#: test/ftdump.c:709 +#, c-format +msgid " language `%4.4s' (index %hu):\n" +msgstr "" + +#: test/ftdump.c:714 +#, c-format +msgid " required feature index %hu (lookup " +msgstr "" + +#: test/ftdump.c:729 +#, c-format +msgid "" +"Error while querying GSUB feature list\n" +"for script `%4.4s', language `%4.4s'.\n" +msgstr "" + +#: test/ftdump.c:746 +#, c-format +msgid "" +"Error while selecting GSUB feature `%4.4s'\n" +"for script `%4.4s', language `%4.4s'.\n" +msgstr "" + +#: test/ftdump.c:771 +msgid "" +"Lookups:\n" +"\n" +msgstr "" + +#: test/ftdump.c:774 +#, c-format +msgid " %hu: type %hu, flag 0x%x\n" +msgstr "" + +#: test/ftdump.c:809 +msgid "ftdump: Simple TrueType Dumper -- part of the FreeType project" +msgstr "" + +#: test/ftdump.c:813 +#, c-format +msgid "" +"Usage: %s fontname[.ttf|.ttc]\n" +"\n" +msgstr "" + +#: test/ftdump.c:845 test/ftlint.c:134 test/ftmetric.c:226 test/ftsbit.c:126 +msgid "Error while initializing engine.\n" +msgstr "" + +#: test/ftdump.c:852 test/ftmetric.c:234 test/ftsbit.c:133 +msgid "Error while initializing embedded bitmap extension.\n" +msgstr "" + +#: test/ftdump.c:859 +msgid "Error while initializing GSUB extension.\n" +msgstr "" + +#: test/ftdump.c:875 test/ftlint.c:187 test/ftmetric.c:249 test/ftsbit.c:181 +#, c-format +msgid "Could not find or open %s.\n" +msgstr "" + +#: test/ftdump.c:878 test/ftlint.c:193 test/ftmetric.c:252 test/ftsbit.c:187 +#, c-format +msgid "Error while opening %s.\n" +msgstr "" + +#: test/ftlint.c:94 +msgid "" +"ftlint: Simple TrueType instruction tester -- part of the FreeType project" +msgstr "" + +#: test/ftlint.c:99 +#, c-format +msgid "" +"Usage: %s ppem fontname[.ttf|.ttc] [fontname2..]\n" +"\n" +msgstr "" + +#: test/ftlint.c:226 test/ftsbit.c:224 +#, c-format +msgid "Could not set point size to %d.\n" +msgstr "" + +#: test/ftlint.c:239 +msgid "" +"Error with\n" +" " +msgstr "" + +#: test/ftlint.c:240 +#, c-format +msgid "glyph %4u: %s\n" +msgstr "" + +#: test/ftlint.c:253 +msgid "1 fail.\n" +msgstr "" + +#: test/ftlint.c:255 +#, c-format +msgid "%d fails.\n" +msgstr "" + +#: test/ftmetric.c:68 +msgid "" +"ftmetric: Simple TTF metrics/glyph dumper -- part of the FreeType project" +msgstr "" + +#: test/ftmetric.c:72 +#, c-format +msgid "" +"Usage: %s [options below] point fontname[.ttf|.ttc]\n" +"\n" +" -B show sbit's metrics (default: none)\n" +" -c C use C'th font index of TrueType collection (default: 0)\n" +" -i index glyph index (default: 0)\n" +" -r R use resolution R dpi (default: 72)\n" +"\n" +msgstr "" + +#: test/ftmetric.c:259 +#, c-format +msgid "There are %d fonts in this collection.\n" +msgstr "" + +#: test/ftmetric.c:264 +#, c-format +msgid "There is no collection with index %d in this font file.\n" +msgstr "" + +#: test/ftmetric.c:278 +msgid "There is no embedded bitmap data in the font.\n" +msgstr "" + +#: test/ftmetric.c:308 +msgid "Could not set device resolutions.\n" +msgstr "" + +#: test/ftmetric.c:315 +msgid "Could not reset instance.\n" +msgstr "" + +#: test/ftmetric.c:321 +#, c-format +msgid "Instance metrics: ppemX %d, ppemY %d\n" +msgstr "" + +#: test/ftmetric.c:331 test/ftsbit.c:233 +msgid "Could not allocate glyph bitmap container.\n" +msgstr "" + +#: test/ftmetric.c:339 test/ftsbit.c:257 +#, c-format +msgid "Can't load bitmap for glyph %d.\n" +msgstr "" + +#: test/ftmetric.c:366 +msgid "Outline's metrics" +msgstr "" + +#: test/ftmetric.c:368 +msgid "Outline glyph\n" +msgstr "" + +#: test/ftsbit.c:89 +msgid "ftsbit: Simple TrueType `sbit' dumper -- part of the FreeType project" +msgstr "" + +#: test/ftsbit.c:94 +#, c-format +msgid "" +"Usage: %s ppem fontname[.ttf|.ttc] glyph_index [glyph_index2..]\n" +"\n" +msgstr "" + +#: test/ftsbit.c:199 +msgid "Could not find embedded bitmaps in this font.\n" +msgstr "" + +#: test/ftsbit.c:205 +msgid "Error while loading embedded bitmaps.\n" +msgstr "" + +#: test/ftsbit.c:251 +#, c-format +msgid " no bitmap for glyph %d.\n" +msgstr "" + +#: test/ftsbit.c:263 +#, c-format +msgid "glyph index %d = %dx%d pixels, " +msgstr "" + +#: test/ftsbit.c:266 +#, c-format +msgid "advance = %ld, minBearing = [%ld,%ld]\n" +msgstr "" diff --git a/po/nl.po b/po/nl.po new file mode 100644 index 0000000..d0862c6 --- /dev/null +++ b/po/nl.po @@ -0,0 +1,758 @@ +# Dutch messages for FreeType. +# Copyright (C) 1998-1999 Gertjan de Back +# Gertjan de Back , 1999. +# +msgid "" +msgstr "" +"Project-Id-Version: FreeType 1.0\n" +"POT-Creation-Date: 1999-09-07 12:49+0000\n" +"PO-Revision-Date: 1999-09-07\n" +"Last-Translator: Gertjan de Back \n" +"Language-Team: Dutch\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=8859-1\n" +"Content-Transfer-Encoding: 8bit\n" + +#: lib/extend/ftxerr18.c:47 +msgid "Successful function call, no error." +msgstr "Functieaanroep succesvol." + +#: lib/extend/ftxerr18.c:50 +msgid "Invalid face handle." +msgstr "Ongeldige Face handle." + +#: lib/extend/ftxerr18.c:52 +msgid "Invalid instance handle." +msgstr "Ongeldige Instance handle." + +#: lib/extend/ftxerr18.c:54 +msgid "Invalid glyph handle." +msgstr "Ongeldige Glyph handle." + +#: lib/extend/ftxerr18.c:56 +msgid "Invalid charmap handle." +msgstr "Ongeldige Charmap handle." + +#: lib/extend/ftxerr18.c:58 +msgid "Invalid result address." +msgstr "Ongeldig resultaat adres." + +#: lib/extend/ftxerr18.c:60 +msgid "Invalid glyph index." +msgstr "Ongeldige Glyph index." + +#: lib/extend/ftxerr18.c:62 +msgid "Invalid argument." +msgstr "Ongeldig argument." + +#: lib/extend/ftxerr18.c:64 +msgid "Could not open file." +msgstr "Bestand kon niet geopend worden." + +#: lib/extend/ftxerr18.c:66 +msgid "File is not a TrueType collection." +msgstr "Bestand is geen TrueType collectie." + +#: lib/extend/ftxerr18.c:69 +msgid "Mandatory table missing." +msgstr "Vereiste tabel ontbreekt." + +#: lib/extend/ftxerr18.c:71 +msgid "Invalid horizontal metrics (hmtx table broken)." +msgstr "Ongeldige horizontale metriek (hmtx tabel defect)." + +#: lib/extend/ftxerr18.c:73 +msgid "Invalid charmap format." +msgstr "Ongeldige Charmap opmaak." + +#: lib/extend/ftxerr18.c:75 +msgid "Invalid ppem value." +msgstr "Ongeldige ppem waarde." + +#: lib/extend/ftxerr18.c:77 +msgid "Invalid vertical metrics (vmtx table broken)." +msgstr "Ongeldige vertikale metriek (vmtx tabel defect)." + +#: lib/extend/ftxerr18.c:80 +msgid "Invalid file format." +msgstr "Ongeldige bestandsopmaak." + +#: lib/extend/ftxerr18.c:83 +msgid "Invalid engine." +msgstr "Ongeldige engine." + +#: lib/extend/ftxerr18.c:85 +msgid "Too many extensions." +msgstr "Te veel uitbreidingen." + +#: lib/extend/ftxerr18.c:87 +msgid "Extensions unsupported." +msgstr "Uitbreidingen niet ondersteund." + +#: lib/extend/ftxerr18.c:89 +msgid "Invalid extension id." +msgstr "Ongeldige uitbreiding id." + +#: lib/extend/ftxerr18.c:92 +msgid "No vertical data in font." +msgstr "Geen vertikale informatie in lettertype." + +#: lib/extend/ftxerr18.c:95 +msgid "Maximum Profile (maxp) table missing." +msgstr "`Maximum Profile (maxp)' tabel ontbreekt." + +#: lib/extend/ftxerr18.c:97 +msgid "Font Header (head) table missing." +msgstr "`Font Header (head)' tabel ontbreekt." + +#: lib/extend/ftxerr18.c:99 +msgid "Horizontal Header (hhea) table missing." +msgstr "`Horizontal Header (hhea)' tabel ontbreekt." + +#: lib/extend/ftxerr18.c:101 +msgid "Index to Location (loca) table missing." +msgstr "`Index to Location (loca)' tabel ontbreekt." + +#: lib/extend/ftxerr18.c:103 +msgid "Naming (name) table missing." +msgstr "`Naming (name)' tabel ontbreekt." + +#: lib/extend/ftxerr18.c:105 +msgid "Character to Glyph Index Mapping (cmap) tables missing." +msgstr "`Character to Glyph Index Mapping (cmap)' tabel ontbreekt." + +#: lib/extend/ftxerr18.c:107 +msgid "Horizontal Metrics (hmtx) table missing." +msgstr "`Horizontal Metrics (hmtx)' tabel ontbreekt." + +#: lib/extend/ftxerr18.c:109 +msgid "OS/2 table missing." +msgstr "OS/2 tabel ontbreekt." + +#: lib/extend/ftxerr18.c:111 +msgid "PostScript (post) table missing." +msgstr "`PostScript (post)' tabel ontbreekt." + +#: lib/extend/ftxerr18.c:113 +msgid "Glyph (glyf) table missing." +msgstr "`Naming (glyf)' tabel ontbreekt." + +#: lib/extend/ftxerr18.c:118 +msgid "Out of memory." +msgstr "Onvoldoende geheugen." + +#: lib/extend/ftxerr18.c:123 +msgid "Invalid file offset." +msgstr "Bestand positie ongeldig." + +#: lib/extend/ftxerr18.c:125 +msgid "Invalid file read." +msgstr "Lezen van bestand ongeldig." + +#: lib/extend/ftxerr18.c:127 +msgid "Invalid frame access." +msgstr "Toegang tot frame ongeldig." + +#: lib/extend/ftxerr18.c:132 +msgid "Too many points." +msgstr "Te veel punten." + +#: lib/extend/ftxerr18.c:134 +msgid "Too many contours." +msgstr "Te veel contouren." + +#: lib/extend/ftxerr18.c:136 +msgid "Invalid composite glyph." +msgstr "Samengestelde Glyph ongeldig." + +#: lib/extend/ftxerr18.c:138 +msgid "Too many instructions." +msgstr "Te veel instructies." + +#: lib/extend/ftxerr18.c:143 +msgid "Invalid opcode." +msgstr "Ongeldige opcode." + +#: lib/extend/ftxerr18.c:145 +msgid "Too few arguments." +msgstr "Te weinig argumenten." + +#: lib/extend/ftxerr18.c:147 +msgid "Stack overflow." +msgstr "Stack overloop." + +#: lib/extend/ftxerr18.c:149 +msgid "Code overflow." +msgstr "Code overloop." + +#: lib/extend/ftxerr18.c:151 +msgid "Bad argument." +msgstr "Foutief argument." + +#: lib/extend/ftxerr18.c:153 +msgid "Divide by zero." +msgstr "Deling door nul." + +#: lib/extend/ftxerr18.c:155 +msgid "Storage overflow." +msgstr "Opslag overloop." + +#: lib/extend/ftxerr18.c:157 +msgid "Control Value (cvt) table overflow." +msgstr "`Control Value (cvt)' tabel overloop." + +#: lib/extend/ftxerr18.c:159 +msgid "Invalid reference." +msgstr "Ongeldige referentie." + +#: lib/extend/ftxerr18.c:161 +msgid "Invalid distance." +msgstr "Ongeldige afstand." + +#: lib/extend/ftxerr18.c:163 +msgid "Interpolate twilight points." +msgstr "Interpolatie van schemer (twilight) punten." + +#: lib/extend/ftxerr18.c:165 +msgid "`DEBUG' opcode found." +msgstr "`DEBUG'-opcode gevonden." + +#: lib/extend/ftxerr18.c:167 +msgid "`ENDF' in byte-code stream." +msgstr "`ENDF' in bytecode-stroom." + +#: lib/extend/ftxerr18.c:169 +msgid "Out of code ranges." +msgstr "Onvoldoende codegebieden." + +#: lib/extend/ftxerr18.c:171 +msgid "Nested function definitions." +msgstr "Functiedefinities genest." + +#: lib/extend/ftxerr18.c:173 +msgid "Invalid code range." +msgstr "Ongeldig codegebied." + +#: lib/extend/ftxerr18.c:175 +msgid "Invalid displacement." +msgstr "Ongeldige verplaatsing." + +#: lib/extend/ftxerr18.c:177 +msgid "Endless loop encountered while executing instructions." +msgstr "Oneindige loop aangetrofffen tijdens het uitvoeren van instructies." + +#: lib/extend/ftxerr18.c:182 +msgid "Nested frame access." +msgstr "Frame toegang genest." + +#: lib/extend/ftxerr18.c:184 +msgid "Invalid cache list." +msgstr "Ongeldige cachelijst." + +#: lib/extend/ftxerr18.c:186 +msgid "Could not find context." +msgstr "Context niet gevonden." + +#: lib/extend/ftxerr18.c:188 +msgid "Unlisted object." +msgstr "Object niet aanwezig." + +#: lib/extend/ftxerr18.c:193 +msgid "Raster pool overflow." +msgstr "Overloop van Raster pool." + +#: lib/extend/ftxerr18.c:195 +msgid "Raster: negative height encountered." +msgstr "Raster: negatieve hoogte aangetroffen." + +#: lib/extend/ftxerr18.c:197 +msgid "Raster: invalid value." +msgstr "Raster: ongeldige waarde." + +#: lib/extend/ftxerr18.c:199 +msgid "Raster not initialized." +msgstr "Raster niet geinitialiseerd." + +#: lib/extend/ftxerr18.c:204 +msgid "Invalid kerning (kern) table format." +msgstr "Ongeldige `Kerning (kern)' tabel opmaak." + +#: lib/extend/ftxerr18.c:206 +msgid "Invalid kerning (kern) table." +msgstr "Ongeldige `Kerning (kern)' tabel." + +#: lib/extend/ftxerr18.c:208 +msgid "Invalid PostScript (post) table format." +msgstr "Ongeldige `PostScript (post)' tabel opmaak." + +#: lib/extend/ftxerr18.c:210 +msgid "Invalid PostScript (post) table." +msgstr "Ongeldige `PostScript (post)' tabel." + +#: lib/extend/ftxerr18.c:216 +msgid "Invalid TrueType Open subtable format." +msgstr "Ongeldige opmaak van TrueType Open subtabel." + +#: lib/extend/ftxerr18.c:218 +msgid "Invalid TrueType Open subtable." +msgstr "Ongeldige TrueType Open subtabel." + +#: lib/extend/ftxerr18.c:220 +msgid "Glyph(s) not covered by lookup." +msgstr "Glyph(s) niet door opgenomen in Lookup." + +#: lib/extend/ftxerr18.c:222 +msgid "Too many nested context substitutions." +msgstr "Te veel geneste context vervangingen." + +#: lib/extend/ftxerr18.c:224 +msgid "Invalid glyph substitution (GSUB) table format." +msgstr "Ongeldige Glyph vervanging (GSUB) tabel opmaak." + +#: lib/extend/ftxerr18.c:226 +msgid "Invalid glyph substitution (GSUB) table." +msgstr "Ongeldige Glyph vervanging (GSUB) tabel." + +#: lib/extend/ftxerr18.c:228 +msgid "Invalid glyph positioning (GPOS) table format." +msgstr "Ongeldige Glyph plaatsing (GPOS) tabel opmaak." + +#: lib/extend/ftxerr18.c:230 +msgid "Invalid glyph positioning (GPOS) table." +msgstr "Ongeldige Glyph plaatsing (GPOS) tabel." + +#: lib/extend/ftxerr18.c:237 +msgid "Invalid Error Number." +msgstr "Ongeldig foutnummer." + +#: test/fterror.c:60 +msgid "Start of fterror.\n" +msgstr "Begin van fterror.\n" + +#: test/fterror.c:68 +msgid "End of fterror.\n" +msgstr "Einde van fterror.\n" + +#: test/ftdump.c:168 test/ftlint.c:207 test/ftmetric.c:292 +msgid "Could not create glyph container.\n" +msgstr "Aanmaken Glyph container mislukt.\n" + +#: test/ftdump.c:178 test/ftlint.c:215 test/ftmetric.c:301 test/ftsbit.c:213 +msgid "Could not create instance.\n" +msgstr "Aanmaken Instance mislukt.\n" + +#: test/ftdump.c:187 +msgid "Could not create second instance.\n" +msgstr "Aanmaken tweede Instance mislukt.\n" + +#: test/ftdump.c:193 +msgid "Memory footprint statistics:\n" +msgstr "Statistieken geheugengebruik:\n" + +#: test/ftdump.c:201 +msgid "face object" +msgstr "Face object" + +#: test/ftdump.c:202 +msgid "glyph object" +msgstr "Glyph object" + +#: test/ftdump.c:203 +msgid "instance object" +msgstr "Instance object" + +#: test/ftdump.c:207 +msgid "exec. context object" +msgstr "uitv. context object" + +#: test/ftdump.c:214 +msgid "total memory usage" +msgstr "totaal geheugengebruik" + +#: test/ftdump.c:222 test/ftdump.c:574 test/ftdump.c:784 test/ftdump.c:921 +#: test/ftlint.c:274 test/ftlint.c:287 test/ftmetric.c:387 test/ftsbit.c:284 +#, c-format +msgid "FreeType error message: %s\n" +msgstr "FreeType foutmelding: %s\n" + +#: test/ftdump.c:299 +msgid "font name table entries\n" +msgstr "lettertypen in namentabel\n" + +#: test/ftdump.c:309 +#, c-format +msgid "" +"PostScript name: %s\n" +"\n" +msgstr "" +"PostScript naam: %s\n" +"\n" + +#: test/ftdump.c:332 +msgid "character map encodings\n" +msgstr "tekencodering tabellen\n" + +#: test/ftdump.c:339 test/ftdump.c:483 +msgid "The file doesn't seem to have any encoding table.\n" +msgstr "Het bestand schijnt geen codering tabellen te bevatten.\n" + +#: test/ftdump.c:343 test/ftdump.c:487 +#, c-format +msgid "" +"There are %hu encodings:\n" +"\n" +msgstr "" +"Er zijn %hu coderingen:\n" +"\n" + +#: test/ftdump.c:348 +#, c-format +msgid "encoding %2u: " +msgstr "codering %2u: " + +#: test/ftdump.c:375 test/ftdump.c:384 test/ftdump.c:447 +#, c-format +msgid "Unknown value %hu" +msgstr "Waarde %hu onbekend" + +#: test/ftdump.c:454 +msgid "Unknown" +msgstr "Onbekend" + +#: test/ftdump.c:476 +msgid "ftxcmap test\n" +msgstr "ftxcmap test\n" + +#: test/ftdump.c:493 +#, c-format +msgid "encoding %2u:\n" +msgstr "codering %2u:\n" + +#: test/ftdump.c:498 +#, c-format +msgid "first: glyph index %hu, character code 0x%lx\n" +msgstr "eerste: Glyph index %hu, karakter code 0x%lx\n" + +#: test/ftdump.c:502 +#, c-format +msgid "next: glyph index %hu, character code 0x%lx\n" +msgstr "volgende: Glyph index %hu, karakter code 0x%lx\n" + +#: test/ftdump.c:506 +#, c-format +msgid "last: glyph index %hu, character code 0x%lx\n" +msgstr "laatste: Glyph index %hu, karakter code 0x%lx\n" + +#: test/ftdump.c:528 test/ftmetric.c:282 +msgid "Error while retrieving embedded bitmaps table.\n" +msgstr "Fout bij het ophalen van ingebedde bitmap tabel.\n" + +#: test/ftdump.c:532 +msgid "embedded bitmap table\n" +msgstr "ingebedde bitmap tabel\n" + +#: test/ftdump.c:535 +#, c-format +msgid " version of embedded bitmap table: 0x%lx\n" +msgstr " versie van ingebedde bitmap tabel: 0x%lx\n" + +#: test/ftdump.c:537 +#, c-format +msgid " number of embedded bitmap strikes: %lu\n" +msgstr " aantal ingebedde bitmap treffers: %lu\n" + +#: test/ftdump.c:547 +#, c-format +msgid " bitmap strike %hu/%lu: " +msgstr " bitmap treffer %hu/%lu: " + +#: test/ftdump.c:550 +#, c-format +msgid "%hux%hu pixels, %hu-bit depth, glyphs [%hu..%hu]\n" +msgstr "%hux%hu pixels, %hu-bit diepte, Glyphs [%hu..%hu]\n" + +#: test/ftdump.c:559 +#, c-format +msgid " range format (%hu:%hu) glyphs %hu..%hu\n" +msgstr " bereik formaat (%hu:%hu) Glyphs %hu..%hu\n" + +#: test/ftdump.c:610 +msgid "Error while loading GSUB table.\n" +msgstr "Fout bij het laden van GSUB tabel.\n" + +#: test/ftdump.c:614 +msgid "GSUB table\n" +msgstr "GSUB tabel\n" + +#: test/ftdump.c:621 +msgid "Error while querying GSUB script list.\n" +msgstr "Fout bij het opvragen van GSUB script lijst.\n" + +#: test/ftdump.c:634 +#, c-format +msgid "Error while selecting GSUB script `%4.4s'.\n" +msgstr "Fout bij het selecteren van GSUB script `%4.4s'.\n" + +#: test/ftdump.c:639 +#, c-format +msgid " script `%4.4s' (index %hu):\n" +msgstr " script `%4.4s' (index %hu):\n" + +#: test/ftdump.c:647 +#, c-format +msgid "Error while querying GSUB default language system for script `%4.4s'.\n" +msgstr "" +"Fout bij het opvragen van GSUB standaard taal systeem voor script `%4.4s'.\n" + +#: test/ftdump.c:652 +msgid " default language system:\n" +msgstr " standaard taal systeem:\n" + +#: test/ftdump.c:665 +#, c-format +msgid "" +"Error while selecting GSUB feature `%4.4s'\n" +"for default language system of script `%4.4s'.\n" +msgstr "" +"Fout bij het selecteren van GSUB kenmerk `%4.4s'\n" +"voor standaard taal systeem van script `%4.4s'.\n" + +#: test/ftdump.c:671 test/ftdump.c:752 +#, c-format +msgid " feature `%4.4s' (index %hu; lookup " +msgstr " kenmerk `%4.4s' (index %hu; lookup " + +#: test/ftdump.c:687 +#, c-format +msgid "Error while querying GSUB language list for script `%4.4s'.\n" +msgstr "Fout bij het opvragen van GSUB taal lijst voor script `%4.4s'.\n" + +#: test/ftdump.c:704 +#, c-format +msgid "Error while selecting GSUB language `%4.4s' for script `%4.4s'.\n" +msgstr "Fout bij het selecteren van GSUB taal `%4.4s' voor script `%4.4s'.\n" + +#: test/ftdump.c:709 +#, c-format +msgid " language `%4.4s' (index %hu):\n" +msgstr " taal `%4.4s' (index %hu):\n" + +#: test/ftdump.c:714 +#, c-format +msgid " required feature index %hu (lookup " +msgstr " benodigde kenmerk index %hu (lookup " + +#: test/ftdump.c:729 +#, c-format +msgid "" +"Error while querying GSUB feature list\n" +"for script `%4.4s', language `%4.4s'.\n" +msgstr "" +"Fout bij het opvragen van GSUB kenmerken lijst\n" +"voor script `%4.4s', taal `%4.4s'.\n" + +#: test/ftdump.c:746 +#, c-format +msgid "" +"Error while selecting GSUB feature `%4.4s'\n" +"for script `%4.4s', language `%4.4s'.\n" +msgstr "" +"Fout bij het selecteren van GSUB kenmerk `%4.4s'\n" +"voor script `%4.4s', taal `%4.4s'.\n" + +#: test/ftdump.c:771 +msgid "" +"Lookups:\n" +"\n" +msgstr "" +"Lookups:\n" +"\n" + +#: test/ftdump.c:774 +#, c-format +msgid " %hu: type %hu, flag 0x%x\n" +msgstr " %hu: type %hu, vlag 0x%x\n" + +#: test/ftdump.c:809 +msgid "ftdump: Simple TrueType Dumper -- part of the FreeType project" +msgstr "" +"ftdump: eenvoudige TrueType dumper -- onderdeel van het FreeType project" + +#: test/ftdump.c:813 +#, c-format +msgid "" +"Usage: %s fontname[.ttf|.ttc]\n" +"\n" +msgstr "" +"Gebruik: %s lettertype[.ttf|.ttc]\n" +"\n" + +#: test/ftdump.c:845 test/ftlint.c:134 test/ftmetric.c:226 test/ftsbit.c:126 +msgid "Error while initializing engine.\n" +msgstr "Fout bij het starten van de FreeType engine.\n" + +#: test/ftdump.c:852 test/ftmetric.c:234 test/ftsbit.c:133 +msgid "Error while initializing embedded bitmap extension.\n" +msgstr "Fout bij het starten de ingebedde bitmap toevoeging.\n" + +#: test/ftdump.c:859 +msgid "Error while initializing GSUB extension.\n" +msgstr "Fout bij het starten van de GSUB toevoeging.\n" + +#: test/ftdump.c:875 test/ftlint.c:187 test/ftmetric.c:249 test/ftsbit.c:181 +#, c-format +msgid "Could not find or open %s.\n" +msgstr "Kan %s niet vinden of openen.\n" + +#: test/ftdump.c:878 test/ftlint.c:193 test/ftmetric.c:252 test/ftsbit.c:187 +#, c-format +msgid "Error while opening %s.\n" +msgstr "Fout bij het openen van %s.\n" + +#: test/ftlint.c:94 +msgid "" +"ftlint: Simple TrueType instruction tester -- part of the FreeType project" +msgstr "" +"ftlint: TrueType instructie tester -- onderdeel van het FreeType project" + +#: test/ftlint.c:99 +#, c-format +msgid "" +"Usage: %s ppem fontname[.ttf|.ttc] [fontname2..]\n" +"\n" +msgstr "" +"Gebruik: %s ppem lettertype[.ttf|.ttc] [lettertype2..]\n" +"\n" + +#: test/ftlint.c:226 test/ftsbit.c:224 +#, c-format +msgid "Could not set point size to %d.\n" +msgstr "Instellen van puntgrootte %d mislukt.\n" + +#: test/ftlint.c:239 +msgid "" +"Error with\n" +" " +msgstr "" +"Fout met\n" +" " + +#: test/ftlint.c:240 +#, c-format +msgid "glyph %4u: %s\n" +msgstr "Glyph %4u: %s\n" + +#: test/ftlint.c:253 +msgid "1 fail.\n" +msgstr "1 misser.\n" + +#: test/ftlint.c:255 +#, c-format +msgid "%d fails.\n" +msgstr "%d missers.\n" + +#: test/ftmetric.c:68 +msgid "" +"ftmetric: Simple TTF metrics/glyph dumper -- part of the FreeType project" +msgstr "" +"ftmetric: TTF metriek/Glyph dumper -- onderdeel van het FreeType project" + +#: test/ftmetric.c:72 +#, c-format +msgid "" +"Usage: %s [options below] point fontname[.ttf|.ttc]\n" +"\n" +" -B show sbit's metrics (default: none)\n" +" -c C use C'th font index of TrueType collection (default: 0)\n" +" -i index glyph index (default: 0)\n" +" -r R use resolution R dpi (default: 72)\n" +"\n" +msgstr "" +"Gebruik: %s [opties hieronder] punt lettertype[.ttf|.ttc]\n" +"\n" +" -B toon sbit's metriek (standaard: geen)\n" +" -c C gebruik 'C'e lettertype index van TrueType collectie (standaard: " +"0)\n" +" -i index Glyph index (standaard: 0)\n" +" -r R gebruik resolutie van R dpi (standaard: 72)\n" +"\n" + +#: test/ftmetric.c:259 +#, c-format +msgid "There are %d fonts in this collection.\n" +msgstr "Er zijn %d lettertypen in deze collectie.\n" + +#: test/ftmetric.c:264 +#, c-format +msgid "There is no collection with index %d in this font file.\n" +msgstr "Er is geen collectie met index %d in dit lettertype.\n" + +#: test/ftmetric.c:278 +msgid "There is no embedded bitmap data in the font.\n" +msgstr "Er is geen ingebedde bitmap informatie in het lettertype.\n" + +#: test/ftmetric.c:308 +msgid "Could not set device resolutions.\n" +msgstr "Instellen van resolutie is mislukt.\n" + +#: test/ftmetric.c:315 +msgid "Could not reset instance.\n" +msgstr "Her-instellen van Instance mislukt.\n" + +#: test/ftmetric.c:321 +#, c-format +msgid "Instance metrics: ppemX %d, ppemY %d\n" +msgstr "Instance metriek: ppemX %d, ppemY %d\n" + +#: test/ftmetric.c:331 test/ftsbit.c:233 +msgid "Could not allocate glyph bitmap container.\n" +msgstr "Toewijzen van Glyph bitmap container mislukt.\n" + +#: test/ftmetric.c:339 test/ftsbit.c:257 +#, c-format +msgid "Can't load bitmap for glyph %d.\n" +msgstr "Laden van bitmap voor Glyph %d mislukt.\n" + +#: test/ftmetric.c:366 +msgid "Outline's metrics" +msgstr "Omtrek metriek" + +#: test/ftmetric.c:368 +msgid "Outline glyph\n" +msgstr "Omtrek Glyph\n" + +#: test/ftsbit.c:89 +msgid "ftsbit: Simple TrueType `sbit' dumper -- part of the FreeType project" +msgstr "ftsbit: TrueType `sbit' dumper -- onderdeel van het FreeType project" + +#: test/ftsbit.c:94 +#, c-format +msgid "" +"Usage: %s ppem fontname[.ttf|.ttc] glyph_index [glyph_index2..]\n" +"\n" +msgstr "" +"Gebruik: %s ppem lettertype[.ttf|.ttc] glyph_index [glyph_index2..]\n" +"\n" + +#: test/ftsbit.c:199 +msgid "Could not find embedded bitmaps in this font.\n" +msgstr "Ingebedde bitmaps niet gevonden in dit lettertype.\n" + +#: test/ftsbit.c:205 +msgid "Error while loading embedded bitmaps.\n" +msgstr "Fout bij het laden van ingebedde bitmaps.\n" + +#: test/ftsbit.c:251 +#, c-format +msgid " no bitmap for glyph %d.\n" +msgstr " geen bitmap voor Glyph %d.\n" + +#: test/ftsbit.c:263 +#, c-format +msgid "glyph index %d = %dx%d pixels, " +msgstr "Glyph index %d = %dx%d pixels, " + +#: test/ftsbit.c:266 +#, c-format +msgid "advance = %ld, minBearing = [%ld,%ld]\n" +msgstr "advance = %ld, minBearing = [%ld,%ld]\n" diff --git a/readme.1st b/readme.1st new file mode 100644 index 0000000..81a1c7c --- /dev/null +++ b/readme.1st @@ -0,0 +1,10 @@ + + DISCLAIMER + + + PLEASE READ THE FILE `PATENTS' BEFORE ANYTHING ELSE! IT + CONTAINS *CRITICAL* INFORMATION REGARDING THE FREE USE OF THIS + LIBRARY. + + +--- end of readme.1st --- diff --git a/test/.cvsignore b/test/.cvsignore new file mode 100644 index 0000000..0f0d086 --- /dev/null +++ b/test/.cvsignore @@ -0,0 +1,12 @@ +.libs +ftview +fttimer +ftlint +ftdump +ftzoom +ftstring +ftstrpnm +fterror +ftsbit +ftmetric +ftstrtto diff --git a/test/README b/test/README new file mode 100644 index 0000000..364b1eb --- /dev/null +++ b/test/README @@ -0,0 +1,6 @@ + +The instructions how to use the test programs can be found in the +main `README' file located in the parent directory. + + +--- end of README --- diff --git a/test/arabic.c b/test/arabic.c new file mode 100644 index 0000000..76b9b2b --- /dev/null +++ b/test/arabic.c @@ -0,0 +1,386 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* arabic -- An implementation of the contextual algorithm given in the */ +/* Unicode 2.0 book to assign the `isolated', `initial', `medial', and */ +/* `final' properties to an input string of character codes for the Arabic */ +/* script. */ +/* */ +/****************************************************************************/ + +#include +#include + +#include "arabic.h" +#include "freetype.h" +#include "ftxopen.h" + + + /* + + Here a table of the joining classes for characters in the range + U+0620 - U+06FF. + + The following character also has a joining class: + + U+200C ZERO WIDTH NON-JOINER -> causing + + All other characters are given the joining class `none'. + + */ + + joining_class arabic[] = + { + /* U+0620 */ + none, none, right, right, + right, right, dual, right, + dual, right, dual, dual, + dual, dual, dual, right, + + /* U+0630 */ + right, right, right, dual, + dual, dual, dual, dual, + dual, dual, dual, none, + none, none, none, none, + + /* U+0640 */ + causing, dual, dual, dual, + dual, dual, dual, dual, + right, right, dual, transparent, + transparent, transparent, transparent, transparent, + + /* U+0650 */ + transparent, transparent, transparent, none, + none, none, none, none, + none, none, none, none, + none, none, none, none, + + /* U+0660 */ + none, none, none, none, + none, none, none, none, + none, none, none, none, + none, none, none, none, + + /* U+0670 */ + transparent, none, right, right, + none, right, right, right, + dual, dual, dual, dual, + dual, dual, dual, dual, + + /* U+0680 */ + dual, dual, dual, dual, + dual, dual, dual, dual, + right, right, right, right, + right, right, right, right, + + /* U+0690 */ + right, right, right, right, + right, right, right, right, + right, right, dual, dual, + dual, dual, dual, dual, + + /* U+06A0 */ + dual, dual, dual, dual, + dual, dual, dual, dual, + dual, dual, dual, dual, + dual, dual, dual, dual, + + /* U+06B0 */ + dual, dual, dual, dual, + dual, dual, dual, dual, + dual, dual, dual, dual, + dual, dual, dual, dual, + + /* U+06C0 */ + right, dual, right, right, + right, right, right, right, + right, right, right, right, + dual, right, dual, right, + + /* U+06D0 */ + dual, dual, right, right, + none, none, none, transparent, + transparent, transparent, transparent, transparent, + transparent, transparent, transparent, transparent, + + /* U+06E0 */ + transparent, transparent, transparent, transparent, + transparent, none, none, transparent, + transparent, none, transparent, transparent, + transparent, transparent, none, none, + + /* U+06F0 */ + none, none, none, none, + none, none, none, none, + none, none, dual, dual, + dual, none, none, none + }; + + + struct cgc_ + { + TT_UShort char_code; + TT_UShort glyph_index; + TT_UShort class; + }; + + typedef struct cgc_ cgc; + + + int compare_cgc( const void* a, + const void* b ) + { + return ( ((cgc*)a)->glyph_index > ((cgc*)b)->glyph_index ) ? + 1 : ( ( ((cgc*)a)->glyph_index == ((cgc*)b)->glyph_index ) ? + 0 : -1 ); + } + + + TT_Error Build_Arabic_Glyph_Properties( TT_CharMap char_map, + TT_UShort max_glyphs, + TTO_GDEFHeader** gdef ) + { + TT_UShort i, j, num_glyphs; + + cgc Arabic[0x0700 - 0x0620]; + + TT_UShort glyph_indices[0x700 - 0x0620]; + TT_UShort classes[0x700 - 0x0620]; + + if ( !gdef ) + return TT_Err_Invalid_Argument; + + j = 0; + + for ( i = 0x0620; i < 0x0700; i++ ) + { + Arabic[j].char_code = i; + Arabic[j].class = ( arabic[i - 0x0620] == transparent ) ? + MARK_GLYPH : SIMPLE_GLYPH; + Arabic[j].glyph_index = TT_Char_Index( char_map, i ); + if ( Arabic[j].glyph_index ) + j++; + } + num_glyphs = j; + + if ( !num_glyphs ) + { + /* no Arabic font */ + *gdef = NULL; + return TT_Err_Ok; + } + + /* sort it */ + + qsort( Arabic, num_glyphs, sizeof ( cgc ), compare_cgc ); + + /* write it to the arrays, removing duplicates */ + + glyph_indices[0] = Arabic[0].glyph_index; + classes[0] = Arabic[0].class; + + j = 1; + + for ( i = 1; i < num_glyphs; i++ ) + { + glyph_indices[j] = Arabic[i].glyph_index; + classes[j] = Arabic[i].class; + + if ( glyph_indices[j - 1] != glyph_indices[j] ) + j++; + } + num_glyphs = j; + + TT_GDEF_Build_ClassDefinition( *gdef, max_glyphs, num_glyphs, + glyph_indices, classes ); + + return TT_Err_Ok; + } + + + /* The joining rules as given in the Unicode 2.0 book (characters are + here specified as appearing in the byte stream, i.e. *not* in + visual order). Joining classes are given in angle brackets, glyph + forms in square brackets. Glyphs affected by a specific rule are + enclosed with vertical bars. + + Note: The description of the joining algorithm in the book is + severely broken. You can get a corrected version from + www.unicode.org (as of 29-Jun-1999, this hasn't appeared). + + R1: + + apply joining rules for + -> [shape1] [shape2] + + -> [shape1] [isolated] [shape2] + + R2: || + + -> [final] + + R3: || + + -> [initial] + + R4: || + + -> [medial] + + R5: || + + -> [final] + + R6: || + + -> [initial] + + R7: If R1-R6 fail: + + -> [isolated] */ + + + /* `direction' can be -1, 0, or 1 to indicate the last non-transparent + glyph, the current glyph, and the next non-transparent glyph, + respectively. */ + + static joining_class Get_Joining_Class( TT_UShort* string, + TT_UShort pos, + TT_UShort length, + int direction ) + { + joining_class j; + + + while ( 1 ) + { + if ( pos == 0 && direction < 0 ) + return none; + + pos += direction; + + if ( pos >= length ) + return none; + + if ( string[pos] < 0x0620 || + string[pos] >= 0x0700 ) + { + if ( string[pos] == 0x200C ) + return causing; + else + return none; + } + else + j = arabic[string[pos] - 0x0620]; + + if ( !direction || j != transparent ) + return j; + } + } + + + TT_Error Assign_Arabic_Properties( TT_UShort* string, + TT_UShort* properties, + TT_UShort length ) + { + joining_class previous, current, next; + + TT_UShort i; + + + if ( !string || !properties || length == 0 ) + return TT_Err_Invalid_Argument; + + for ( i = 0; i < length; i++ ) + { + previous = Get_Joining_Class( string, i, length, -1 ); + current = Get_Joining_Class( string, i, length, 0 ); + next = Get_Joining_Class( string, i, length, 1 ); + + /* R1 */ + + if ( current == transparent ) + { + properties[i] |= isolated_p; + continue; + } + + /* R2 */ + + if ( previous == causing || + previous == left || + previous == dual ) + if ( current == right ) + { + properties[i] |= final_p; + continue; + } + + /* R3 */ + + if ( current == left ) + if ( next == causing || + next == right || + next == dual ) + { + properties[i] |= initial_p; + continue; + } + + /* R4 */ + + if ( previous == causing || + previous == left || + previous == dual ) + if ( current == dual ) + if ( next == causing || + next == right || + next == dual ) + { + properties[i] |= medial_p; + continue; + } + + /* R5 */ + + if ( previous == causing || + previous == left || + previous == dual ) + if ( current == dual ) + if ( !( next == causing || + next == right || + next == dual ) ) + { + properties[i] |= final_p; + continue; + } + + /* R6 */ + + if ( !( previous == causing || + previous == left || + previous == dual ) ) + if ( current == dual ) + if ( next == causing || + next == right || + next == dual ) + { + properties[i] |= initial_p; + continue; + } + + /* R7 */ + + if ( current != none ) + properties[i] |= isolated_p; + } + + return TT_Err_Ok; + } + + +/* End */ diff --git a/test/arabic.h b/test/arabic.h new file mode 100644 index 0000000..0e9fe05 --- /dev/null +++ b/test/arabic.h @@ -0,0 +1,66 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* arabic -- An implementation of the contextual algorithm given in the */ +/* Unicode 2.0 book to assign the `isolated', `initial', `medial', and */ +/* `final' properties to an input string of character codes for the Arabic */ +/* script. */ +/* */ +/****************************************************************************/ + + +#include "freetype.h" +#include "ftxopen.h" + + + enum joining_type_ + { + isolated = 1, /* nominal */ + final = 2, /* right_joining */ + initial = 4, /* left_joining */ + medial = 8 /* double_joining */ + }; + + typedef enum joining_type_ joining_type; + + + /* A glyph's property value as needed by e.g. TT_GSUB_Apply_String() + specifies which features should *not* be applied */ + + enum arabic_glyph_property_ + { + isolated_p = final | initial | medial, + final_p = isolated | initial | medial, + initial_p = isolated | final | medial, + medial_p = isolated | final | initial + }; + + typedef enum arabic_glyph_property_ arabic_glyph_property; + + + enum joining_class_ + { + right, + left, /* not used */ + dual, + causing, + none, + transparent + }; + + typedef enum joining_class_ joining_class; + + + TT_Error Assign_Arabic_Properties( TT_UShort* string, + TT_UShort* properties, + TT_UShort length ); + TT_Error Build_Arabic_Glyph_Properties( TT_CharMap char_map, + TT_UShort max_glyphs, + TTO_GDEFHeader** gdef ); + + +/* End */ diff --git a/test/arch/amigaos/Makefile.gcc b/test/arch/amigaos/Makefile.gcc new file mode 100644 index 0000000..b543ce9 --- /dev/null +++ b/test/arch/amigaos/Makefile.gcc @@ -0,0 +1,106 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for amiga using ADE. +# +# You will need GNU make. +# +# Use this file while in the 'test' directory with the following statement: +# +# make -f arch/amigaos/Makefile.gcc + +ARCH = arch/amigaos +FT_MAKEFILE = $(ARCH)/Makefile.gcc + +CC = gcc + +LIBDIR = ../lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)/$(ARCH) -I. -I$(LIBDIR)/extend + +CFLAGS = -ansi -Wall -g -noixemul $(INCDIRS) +# CFLAGS = -Wall -noixemul -O2 -Ilib $(INCDIRS) + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +GSRC = gmain.c display.c blitter.c $(ARCH)/gw_amiga.c +GOBJ = $(GSRC:.c=.o) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +%.exe: + $(CC) $(CFLAGS) -o $@ @^ + + +EXEFILES = ftdump \ + fterror \ + ftlint \ + ftmetric \ + ftsbit \ + ftstring \ + ftstrpnm \ + ftstrtto \ + fttimer \ + ftview \ + ftzoom + +.PHONY: all debug freetype freetype_debug \ + clean distclean do_clean depend + + +all: freetype $(EXEFILES) + +debug: freetype_debug $(EXEFILES) + +freetype: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) all + +freetype_debug: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) debug + +ftzoom: $(GOBJ) ftzoom.o common.o $(LIBDIR)/libttf.a +ftview: $(GOBJ) ftview.o common.o $(LIBDIR)/libttf.a +ftlint: ftlint.o common.o $(LIBDIR)/libttf.a +ftdump: ftdump.o common.o $(LIBDIR)/libttf.a +ftstring: $(GOBJ) ftstring.o common.o $(LIBDIR)/libttf.a +fttimer: $(GOBJ) fttimer.o common.o $(LIBDIR)/libttf.a +ftsbit: ftsbit.o common.o $(LIBDIR)/libttf.a +ftstrpnm: ftstrpnm.o common.o $(LIBDIR)/libttf.a +ftmetric: ftmetric.o common.o $(LIBDIR)/libttf.a +ftstrtto: $(GOBJ) ftstrtto.o common.o arabic.o $(LIBDIR)/libttf.a + + +clean: do_clean + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) clean + +distclean: do_clean + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) distclean + -rm dep.end core + -rm $(EXE) + +do_clean: + -rm *.o + -rm arch/amigaos/*.o + + +depend: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) depend + $(CC) -E -M $(INCDIRS) $(SRC) $(GSRC) > dep.end + +ifeq (dep.end,$(wildcard dep.end)) + include dep.end +endif + +# end of Makefile.gcc diff --git a/test/arch/amigaos/TODO b/test/arch/amigaos/TODO new file mode 100644 index 0000000..d09a4e2 --- /dev/null +++ b/test/arch/amigaos/TODO @@ -0,0 +1,16 @@ + + * To test the window oriented driver. + + * To improve the window oriented driver to use ROM functions like + WriteChunkyPixel() (or similar) instead of the current routine. + + * To build a truetype.library from libttf.a + + * truetype.datatype. + + * Program to convert truetype fonts in Amiga fonts. + + Suggestions, bug reports, code improvements, support for other compilers, + ... are welcome ! + + Send them to: map@medusa.es or to freetype@lists.lrz-muenchen.de diff --git a/test/arch/amigaos/gfsamiga.c b/test/arch/amigaos/gfsamiga.c new file mode 100644 index 0000000..76bac1e --- /dev/null +++ b/test/arch/amigaos/gfsamiga.c @@ -0,0 +1,428 @@ +/******************************************************************* + * + * gfsamiga.c graphics utility fullscreen Amiga driver. 1.0 + * + * This is the driver for fullscreen Amiga display, used by the + * graphics utility of the FreeType test suite. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +/* standard includes */ + +#include +#include + +/* AmigaOS includes */ + +#include +#include +#include +#include + +#ifdef __GNUC__ + +#include +#include +#include +#include + +#else + +#include +#include +#include +#include + +#endif + +/* FreeType includes */ + +#include "gdriver.h" +#include "gevents.h" +#include "gmain.h" + +/* some screen definitions */ + +#define MONO_SCREEN_WIDTH 640 +#define MONO_SCREEN_HEIGHT 512 +#define MONO_SCREEN_DEPTH 1 + +#define GRAY_SCREEN_WIDTH 320 +#define GRAY_SCREEN_HEIGHT 256 +#define GRAY_SCREEN_DEPTH 3 + +#define DISPLAY_MEM ( 1024 * 64 ) + + + /* external variables */ + + extern struct Library* SysBase; + extern struct Library* DOSBase; + + extern int vio_ScanLineWidth; + extern char* Vio; + extern char gray_palette[5]; + + /* global variables */ + + struct Library* IntuitionBase = NULL; + struct Library* GfxBase = NULL; + + typedef struct _Translator + { + char key; + GEvent event_class; + int event_info; + } Translator; + +#define NUM_Translators 20 + + static const Translator trans[NUM_Translators] = + { + { (char)27, event_Quit, 0 }, + { 'q', event_Quit, 0 }, + + { 'x', event_Rotate_Glyph, -1 }, + { 'c', event_Rotate_Glyph, 1 }, + { 'v', event_Rotate_Glyph, -16 }, + { 'b', event_Rotate_Glyph, 16 }, + + { '{', event_Change_Glyph, -10000 }, + { '}', event_Change_Glyph, 10000 }, + { '(', event_Change_Glyph, -1000 }, + { ')', event_Change_Glyph, 1000 }, + { '9', event_Change_Glyph, -100 }, + { '0', event_Change_Glyph, 100 }, + { 'i', event_Change_Glyph, -10 }, + { 'o', event_Change_Glyph, 10 }, + { 'k', event_Change_Glyph, -1 }, + { 'l', event_Change_Glyph, 1 }, + + { '+', event_Scale_Glyph, 10 }, + { '-', event_Scale_Glyph, -10 }, + { 'u', event_Scale_Glyph, 1 }, + { 'j', event_Scale_Glyph, -1 } + }; + + + /* local variables */ + + static struct Screen* fts = NULL; + static struct Window* ftw = NULL; + + static int graphx_mode; + + + /* exit gracefully */ + + static void AmigaCleanUp( void ) + { + if ( ftw ) + CloseWindow( ftw ); + + if ( fts ) + CloseScreen( fts ); + + if ( IntuitionBase ) + CloseLibrary( IntuitionBase ); + + if ( GfxBase ) + CloseLibrary( GfxBase ); + + if ( graphx_mode == Graphics_Mode_Gray ) + if ( Vio ) + FreeMem( Vio, DISPLAY_MEM ); + } + + + static void SetPalette( void ) + { + short color[] = { 0x0000, + 0x0333, + 0x0777, + 0x0BBB, + 0x0FFF, + 0x0A00, + 0x00A0, + 0x000A + }; + short i; + + + for ( i = 0; i < 8; i++ ) + { + if ( i < 5 ) + gray_palette[i] = i; + + SetRGB4( &fts->ViewPort, i, (UBYTE)(color[i] >> 8 & 0x0f), + (UBYTE)(color[i] >> 4 & 0x0f), + (UBYTE)(color[i] & 0x0f ) ); + } + } + + + /* open libraries & custom screen */ + + static int AmigaInit( void ) + { + /* cleanup at exit */ + if ( atexit( AmigaCleanUp ) ) + { + PutStr( "atexit() failed\n" ); + return -1; + } + + /* open intuition library */ + + IntuitionBase = (struct Library*)OpenLibrary( "intuition.library", 37L ); + if ( IntuitionBase == NULL ) + { + PutStr( "Could not open intuition library\n" ); + return -1; + } + + /* Open graphics library */ + + GfxBase = OpenLibrary( "graphics.library", 37L ); + if ( GfxBase == NULL ) + { + PutStr( "Could not open graphics library\n" ); + return -1; + } + + if ( graphx_mode == Graphics_Mode_Gray ) + { + /* open custom screen */ + fts = (struct Screen*)OpenScreenTags( + NULL, + SA_DisplayID, (PAL_MONITOR_ID | LORES_KEY), + SA_Width, GRAY_SCREEN_WIDTH, + SA_Height, GRAY_SCREEN_HEIGHT, + SA_Depth, GRAY_SCREEN_DEPTH, + SA_ShowTitle, FALSE, + TAG_DONE ); + + if ( fts == NULL ) + { + PutStr( "Could not open custom screen\n" ); + return -1; + } + + /* set gray palette */ + SetPalette(); + } + else + { + /* open custom screen */ + fts = (struct Screen*)OpenScreenTags( + NULL, + SA_DisplayID, (PAL_MONITOR_ID | HIRESLACE_KEY), + SA_Width, MONO_SCREEN_WIDTH, + SA_Height, MONO_SCREEN_HEIGHT, + SA_Depth, MONO_SCREEN_DEPTH, + SA_ShowTitle, FALSE, + TAG_DONE ); + + if ( fts == NULL ) + { + PutStr( "Could not open custom screen\n" ); + return -1; + } + } + + /* open intuition window */ + ftw = OpenWindowTags( + NULL, + WA_Left, 0, + WA_Width, fts->Width, + WA_Top, 0, + WA_Height, fts->Height, + WA_IDCMP, IDCMP_VANILLAKEY | IDCMP_MOUSEBUTTONS, + WA_Flags, WFLG_BACKDROP | WFLG_BORDERLESS | + WFLG_RMBTRAP | WFLG_ACTIVATE, + WA_Gadgets, NULL, + WA_Title, NULL, + WA_CustomScreen, fts, + TAG_DONE ); + + if ( ftw == NULL ) + { + PutStr( "Could not open intuition window\n" ); + return -1; + } + + if ( graphx_mode == Graphics_Mode_Gray ) + { + Vio = (char*)AllocMem( DISPLAY_MEM, MEMF_ANY ); + + if ( !Vio ) + { + PutStr( "Cannot AllocMem() display memory\n" ); + return -1; + } + + vio_Width = vio_ScanLineWidth = GRAY_SCREEN_WIDTH; + vio_Height = GRAY_SCREEN_HEIGHT; + } + else + { + Vio = (char*)fts->BitMap.Planes[0]; + vio_ScanLineWidth = fts->BitMap.BytesPerRow; + vio_Width = MONO_SCREEN_WIDTH; + vio_Height = MONO_SCREEN_HEIGHT; + } + + return 0; + } + + + /* get events in the window */ + + static char Get_Intuition_Event( void ) + { + struct IntuiMessage* msg; + ULONG class; + USHORT code; + + + WaitPort( ftw->UserPort ); + + while ( ( msg = (struct IntuiMessage*)GetMsg( ftw->UserPort ) ) ) + { + class = msg->Class; + code = msg->Code; + + ReplyMsg( (struct Message*)msg ); + + switch ( class ) + { + case IDCMP_MOUSEBUTTONS: + return (char)27; + + case IDCMP_VANILLAKEY: + return (char)code; + } + } + + return '\0'; + } + + + /* set Amiga graphics mode */ + + int Driver_Set_Graphics( int mode ) + { + graphx_mode = mode; + + + if ( AmigaInit() == -1 ) + return 0; /* failure */ + + return 1; /* success */ + } + + + /* restore screen to its original state */ + + int Driver_Restore_Mode( void ) + { + /* do nothing */ + + return 1; /* success */ + } + + + /* display bitmap */ + + int Driver_Display_Bitmap( char* buffer, int line, int col ) + { + int y, z; + char* target; + char old = -1; + + + target = Vio + ( line - 1 ) * vio_ScanLineWidth; + + for ( y = 0; y < line; y++ ) + { + CopyMem( buffer, target, col ); + target -= vio_ScanLineWidth; + buffer += col; + } + + if ( graphx_mode == Graphics_Mode_Gray ) + { + /* clear screen */ + SetRast( &fts->RastPort, 0 ); + + /* draw glyph */ + for ( y = 0; y < line; y++ ) + { + for ( z = 0; z < col; z++ ) + { + int c = Vio[y * vio_ScanLineWidth + z]; + + if ( c != 0 ) + { + if ( old != c ) + { + if ( c < 0 || c > 5 ) + { + PutStr( "Unexpected value!\n" ); + SetAPen( &fts->RastPort, 7 ); + } + else + { + old = c; + SetAPen( &fts->RastPort, c ); + } + } + + WritePixel( &fts->RastPort, z, y ); + } + } + } + } + + return 1; /* success */ + } + + + void Get_Event( TEvent* event ) + { + int i; + char c; + + + c = Get_Intuition_Event(); + + if ( c != '\0' ) + for ( i = 0; i < NUM_Translators; i++ ) + { + if ( c == trans[i].key ) + { + event->what = trans[i].event_class; + event->info = trans[i].event_info; + return; + } + } + + /* unrecognized keystroke */ + + event->what = event_Keyboard; + event->info = (int)c; + + return; + } + + +/* End */ diff --git a/test/arch/amigaos/gw_amiga.c b/test/arch/amigaos/gw_amiga.c new file mode 100644 index 0000000..73116bd --- /dev/null +++ b/test/arch/amigaos/gw_amiga.c @@ -0,0 +1,522 @@ +/******************************************************************* + * + * gw_amiga.c graphics utility Intuition Amiga driver. + * + * This is the driver for windowed display under Amiga WorkBench, + * used by the graphics utility of the FreeType test suite. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +/* modified by Richard Griffith + open largest window we can, and adapt accordingly + gray and mono both appear black on white + display Header message in Window title + add simple menus + */ + +/* standard includes */ + +#include +#include + +/* AmigaOS includes */ + +#include +#include +#include +#include +#include + +#ifdef __GNUC__ +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#include +#endif + +/* FreeType includes */ + +#include "gdriver.h" +#include "gevents.h" +#include "gmain.h" + + +/* some screen definitions */ + +#define MONO_WINDOW_WIDTH 0xFFFF +#define MONO_WINDOW_HEIGHT 0xFFFF + +#define GRAY_WINDOW_WIDTH 0xFFFF +#define GRAY_WINDOW_HEIGHT 0xFFFF + +#define DISPLAY_MEM ( 1024 * 64 ) + + + /* external variables */ + extern struct Library* SysBase; + extern struct Library* DOSBase; + + extern int vio_ScanLineWidth; + extern char* Vio; +/* extern char gray_palette[5]; */ + + /* global variables */ + struct Library* IntuitionBase = NULL; + struct Library* GfxBase = NULL; + struct Library *GadToolsBase = NULL; + + typedef struct _Translator + { + char key; + GEvent event_class; + int event_info; + } Translator; + +#define NUM_Translators 20 + + static const Translator trans[NUM_Translators] = + { + { (char)27, event_Quit, 0 }, + { 'q', event_Quit, 0 }, + + { 'x', event_Rotate_Glyph, -1 }, + { 'c', event_Rotate_Glyph, 1 }, + { 'v', event_Rotate_Glyph, -16 }, + { 'b', event_Rotate_Glyph, 16 }, + + { '{', event_Change_Glyph, -10000 }, + { '}', event_Change_Glyph, 10000 }, + { '(', event_Change_Glyph, -1000 }, + { ')', event_Change_Glyph, 1000 }, + { '9', event_Change_Glyph, -100 }, + { '0', event_Change_Glyph, 100 }, + { 'i', event_Change_Glyph, -10 }, + { 'o', event_Change_Glyph, 10 }, + { 'k', event_Change_Glyph, -1 }, + { 'l', event_Change_Glyph, 1 }, + + { '+', event_Scale_Glyph, 10 }, + { '-', event_Scale_Glyph, -10 }, + { 'u', event_Scale_Glyph, 1 }, + { 'j', event_Scale_Glyph, -1 } + }; + + + /* local variables */ + static struct Screen* fts = NULL; + static struct Window* ftw = NULL; + static APTR VisualInfo = NULL; + static struct Menu *ftmenus = NULL; + + static int graphx_mode; + + static ULONG vio_allocsize; + + static struct NewMenu ftNewMenu[] = { + {NM_TITLE, (STRPTR)"File", NULL, 0, NULL, NULL}, + {NM_ITEM, (STRPTR)"Next", (STRPTR)"n", 0, 0L, (APTR)'n'}, + {NM_ITEM, (STRPTR)"Previous",(STRPTR)"p", 0, 0L, (APTR)'p'}, + {NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL}, + {NM_ITEM, (STRPTR)"Quit", (STRPTR)"q", 0, 0L, (APTR)'q'}, + {NM_TITLE, (STRPTR)"Options", NULL, 0, NULL, NULL}, + {NM_ITEM, (STRPTR)"Scale Up", NULL, 0, NULL, NULL}, + {NM_SUB, (STRPTR)"Fine", (STRPTR)"u", 0, 0L, (APTR)'u'}, + {NM_SUB, (STRPTR)"Fast", (STRPTR)"+", 0, 0L, (APTR)'+'}, + {NM_ITEM, (STRPTR)"Scale Down", NULL, 0, NULL, NULL}, + {NM_SUB, (STRPTR)"Fine", (STRPTR)"j", 0, 0L, (APTR)'j'}, + {NM_SUB, (STRPTR)"Fast", (STRPTR)"-", 0, 0L, (APTR)'-'}, + {NM_ITEM, (STRPTR)"Toggle Hinting", (STRPTR)"h", 0, 0L, (APTR)'h'}, + {NM_ITEM, (STRPTR)"Toggle Kerning", (STRPTR)"K", 0, 0L, (APTR)'K'}, + {NM_ITEM, (STRPTR)"Toggle sbit", (STRPTR)"B", 0, 0L, (APTR)'B'}, + {NM_ITEM, (STRPTR)"Toggle GSUB", (STRPTR)"G", 0, 0L, (APTR)'G'}, + {NM_TITLE, (STRPTR)"Glyph", NULL, 0, NULL, NULL}, + {NM_ITEM, (STRPTR)"Next", NULL, 0, NULL, NULL}, + {NM_SUB, (STRPTR)"1", (STRPTR)"l", 0, 0L, (APTR)'l'}, + {NM_SUB, (STRPTR)"10", (STRPTR)"o", 0, 0L, (APTR)'o'}, + {NM_SUB, (STRPTR)"100", (STRPTR)"0", 0, 0L, (APTR)'0'}, + {NM_SUB, (STRPTR)"1000", (STRPTR)")", 0, 0L, (APTR)')'}, + {NM_SUB, (STRPTR)"10000",(STRPTR)"}", 0, 0L, (APTR)'}'}, + {NM_ITEM, (STRPTR)"Previous", NULL, 0, NULL, NULL}, + {NM_SUB, (STRPTR)"1", (STRPTR)"k", 0, 0L, (APTR)'k'}, + {NM_SUB, (STRPTR)"10", (STRPTR)"i", 0, 0L, (APTR)'i'}, + {NM_SUB, (STRPTR)"100", (STRPTR)"9", 0, 0L, (APTR)'9'}, + {NM_SUB, (STRPTR)"1000", (STRPTR)"(", 0, 0L, (APTR)'('}, + {NM_SUB, (STRPTR)"10000",(STRPTR)"{", 0, 0L, (APTR)'{'}, + {NM_TITLE, (STRPTR)"Rotate", NULL, 0, NULL, NULL}, + {NM_ITEM, (STRPTR)"Clockwise", NULL, 0, NULL, NULL}, + {NM_SUB, (STRPTR)"Fine", (STRPTR)"c", 0, 0L, (APTR)'c'}, + {NM_SUB, (STRPTR)"Fast", (STRPTR)"b", 0, 0L, (APTR)'b'}, + {NM_ITEM, (STRPTR)"Counter-clockwise", NULL, 0, NULL, NULL}, + {NM_SUB, (STRPTR)"Fine", (STRPTR)"x", 0, 0L, (APTR)'x'}, + {NM_SUB, (STRPTR)"Fast", (STRPTR)"v", 0, 0L, (APTR)'v'}, + {NM_END, NULL, NULL, 0, 0L, NULL} }; + + + /* Exit gracefully */ + static void AmigaCleanUp( void ) + { + if ( Vio ) + FreeMem( Vio, vio_allocsize ); + + ReleasePen( fts->ViewPort.ColorMap, gray_palette[0] ); + ReleasePen( fts->ViewPort.ColorMap, gray_palette[1] ); + + if ( graphx_mode == Graphics_Mode_Gray ) + { + ReleasePen( fts->ViewPort.ColorMap, gray_palette[2] ); + ReleasePen( fts->ViewPort.ColorMap, gray_palette[3] ); + ReleasePen( fts->ViewPort.ColorMap, gray_palette[4] ); + } + + if ( ftmenus ) + { + ClearMenuStrip( ftw ); + FreeMenus( ftmenus ); + } + + if ( ftw ) + CloseWindow( ftw ); + + if ( VisualInfo ) + FreeVisualInfo( VisualInfo ); + + if ( GfxBase ) + CloseLibrary( GfxBase ); + + if ( GadToolsBase ) + CloseLibrary( GadToolsBase ); + + if ( IntuitionBase ) + CloseLibrary( IntuitionBase ); + + } + + + /* open libraries & custom screen */ + static int AmigaInit( void ) + { + /* cleanup at exit */ + if ( atexit( AmigaCleanUp ) ) + { + PutStr( "atexit() failed\n" ); + return -1; + } + + /* open intuition library */ + IntuitionBase = (struct Library*)OpenLibrary( "intuition.library", 39L ); + if ( IntuitionBase == NULL ) + { + PutStr( "Could not open intuition library\n" ); + return -1; + } + + /* open gaadtools library */ + GadToolsBase = (struct Library*)OpenLibrary( "gadtools.library", 39L ); + if ( GadToolsBase == NULL ) + { + PutStr( "Could not open gadtools library\n" ); + return -1; + } + + /* open graphics library */ + GfxBase = OpenLibrary( "graphics.library", 39L ); + if ( GfxBase == NULL ) + { + PutStr( "Could not open graphics library\n" ); + return -1; + } + + /* get public screen */ + fts = LockPubScreen( NULL ); + + if ( fts == NULL ) + { + PutStr( "Could not lock public screen\n" ); + return -1; + } + + if ( ! ( VisualInfo = GetVisualInfo( fts, TAG_DONE ))) + { + PutStr( "Could not get VisualInfo\n" ); + return -1; + } + + if ( graphx_mode == Graphics_Mode_Gray ) + { + vio_ScanLineWidth = GRAY_WINDOW_WIDTH; + vio_Width = GRAY_WINDOW_WIDTH; + vio_Height = GRAY_WINDOW_HEIGHT; + + gray_palette[4] = ObtainBestPenA( fts->ViewPort.ColorMap, + 0x00000000, 0x00000000, 0x00000000, NULL ); + gray_palette[3] = ObtainBestPenA( fts->ViewPort.ColorMap, + 0x33333300, 0x33333300, 0x33333300, NULL ); + gray_palette[2] = ObtainBestPenA( fts->ViewPort.ColorMap, + 0x77777700, 0x77777700, 0x77777700, NULL ); + gray_palette[1] = ObtainBestPenA( fts->ViewPort.ColorMap, + 0xBBBBBB00, 0xBBBBBB00, 0xBBBBBB00, NULL ); + gray_palette[0] = ObtainBestPenA( fts->ViewPort.ColorMap, + 0xFFFFFF00, 0xFFFFFF00, 0xFFFFFF00, NULL ); + } + else + { + vio_ScanLineWidth = MONO_WINDOW_WIDTH / 8; + vio_Width = MONO_WINDOW_WIDTH; + vio_Height = MONO_WINDOW_HEIGHT; + + gray_palette[0] = ObtainBestPenA( fts->ViewPort.ColorMap, + 0xFFFFFF00, 0xFFFFFF00, 0xFFFFFF00, NULL ); + gray_palette[1] = ObtainBestPenA( fts->ViewPort.ColorMap, + 0x00000000, 0x00000000, 0x00000000, NULL ); + } + + if ( ! ( ftmenus = CreateMenus( ftNewMenu, GTMN_FrontPen, 0L, TAG_DONE))) + { + PutStr( "Could not create menus\n" ); + return -1; + } + + LayoutMenus( ftmenus, VisualInfo, GTMN_NewLookMenus, TRUE, TAG_DONE ); + + /* open intuition window */ + ftw = OpenWindowTags( + NULL, + WA_InnerWidth, vio_Width, + WA_InnerHeight, vio_Height, + WA_IDCMP, IDCMP_MENUPICK | IDCMP_VANILLAKEY | IDCMP_CLOSEWINDOW, + /* WA_AutoAdjust, TRUE, */ + WA_CloseGadget, TRUE, + WA_Activate, TRUE, + WA_DragBar, TRUE, + WA_SmartRefresh, TRUE, + WA_Gadgets, NULL, + WA_Flags, WFLG_DEPTHGADGET | WFLG_SMART_REFRESH, + WA_Title, (UBYTE*)"FreeType Project", + WA_NewLookMenus, TRUE, + WA_PubScreen, fts, + TAG_DONE ); + + if ( ftw == NULL ) + { + PutStr( "Could not open intuition window\n" ); + return -1; + } + + SetMenuStrip( ftw, ftmenus ); + + UnlockPubScreen( NULL, fts ); + + vio_Height = ftw->Height - ftw->BorderTop - ftw->BorderBottom - 2; + vio_Width = (ftw->Width - ftw->BorderLeft - ftw->BorderRight) & 0xFFFFFC; + + if ( graphx_mode == Graphics_Mode_Gray ) + { + vio_ScanLineWidth = vio_Width; + } else { + vio_ScanLineWidth = vio_Width / 8; + } + vio_allocsize = vio_Height * vio_ScanLineWidth; + + Vio = (char*)AllocMem( vio_allocsize, MEMF_ANY ); + if ( Vio == NULL ) + { + PutStr( "Could not allocate memory\n" ); + return -1; + } + + return 0; + } + + + /* get events in the window */ + static char Get_Intuition_Event( void ) + { + struct IntuiMessage* msg; + ULONG class; + USHORT code; + int rc; + struct MenuItem *n; + + + WaitPort( ftw->UserPort ); + + while ( ( msg = (struct IntuiMessage*)GetMsg( ftw->UserPort ) ) ) + { + class = msg->Class; + code = msg->Code; + + ReplyMsg( (struct Message*)msg ); + + switch( class ) + { + case IDCMP_REFRESHWINDOW: + GT_BeginRefresh( ftw ); + GT_EndRefresh( ftw, TRUE ); + break; + + case IDCMP_CLOSEWINDOW: + return (char)27; + + case IDCMP_VANILLAKEY: + return (char)code; + + case IDCMP_MENUPICK: + while( code != MENUNULL ) + { + n = ItemAddress( ftmenus, code ); + rc = (int)GTMENUITEM_USERDATA( n ); + code = n->NextSelect; + } /* despite loop, we only do one */ + return (char)rc; + } + } + + + return '\0'; + } + + + /* Set Amiga graphics mode */ + int Driver_Set_Graphics( int mode ) + { + graphx_mode = mode; + + if ( AmigaInit() == -1 ) + return 0; /* failure */ + + return 1; /* success */ + } + + + /* restore screen to its original state */ + int Driver_Restore_Mode( void ) + { + /* Do nothing */ + + return 1; /* success */ + } + + + /* display bitmap */ + int Driver_Display_Bitmap( char* buffer, int line, int col ) + { + int y, z; + char* target; + char old = 0; + extern char Header[]; + + SetWindowTitles(ftw,Header,Header); + + + target = Vio + ( line - 1 ) * vio_ScanLineWidth; + + for ( y = 0; y < line; y++ ) + { + CopyMem( buffer, target, col ); + target -= vio_ScanLineWidth; + buffer += col; + } + + /* clear window */ + /* SetRast( ftw->RPort, gray_palette[0] ); */ + + SetAPen( ftw->RPort, gray_palette[0] ); + + RectFill( ftw->RPort, ftw->BorderLeft, ftw->BorderTop, + ftw->Width - ftw->BorderRight - 1, + ftw->Height - ftw->BorderBottom - 1 ); + + if ( graphx_mode != Graphics_Mode_Gray ) + { + SetAPen( ftw->RPort, gray_palette[1] ); + old = 1; + } + + /* Draw glyph */ + for ( y = 0; y < line; y++ ) + { + for ( z = 0; z < col; z++ ) + { + int c = Vio[y * vio_ScanLineWidth + z]; + + if ( graphx_mode == Graphics_Mode_Gray ) + { + if ( c != 0 && c != gray_palette[0] ) + { + if ( old != c ) + { + old = c; + /* printf("x = %d, y = %d, color = %d\n", z, y, c ); */ + SetAPen( ftw->RPort, c ); + } + + WritePixel( ftw->RPort, ftw->BorderLeft + z, ftw->BorderTop + y ); + } + } + else + { + int mask = 0x80; + int counter = 0; + + while ( mask ) + { + if ( mask & c ) + WritePixel( ftw->RPort, ftw->BorderLeft + z * 8 + counter, + ftw->BorderTop + y ); + + counter++; + mask >>= 1; + } + } + } + } + + return 1; /* success */ + } + + + void Get_Event( TEvent* event ) + { + int i; + char c; + + + c = Get_Intuition_Event(); + + if ( c != '\0' ) + for ( i = 0; i < NUM_Translators; i++ ) + { + if ( c == trans[i].key ) + { + event->what = trans[i].event_class; + event->info = trans[i].event_info; + return; + } + } + + /* unrecognized keystroke */ + + event->what = event_Keyboard; + event->info = (int)c; + + return; + } + + +/* End */ diff --git a/test/arch/amigaos/smakefile b/test/arch/amigaos/smakefile new file mode 100644 index 0000000..b68944a --- /dev/null +++ b/test/arch/amigaos/smakefile @@ -0,0 +1,180 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for amiga using SAS/C +# and smake +# +# Use this file while in the 'test/arch/amigaos' directory with +# the following statements: +# +# smake assign +# smake +# +# the 'assign' step creates an assignment to simplify referencing +# the core library module, as smake has quite a few limitations in +# dealing with multi-directory projects. + +OBJB = ttapi.o ttcache.o ttcalc.o ttcmap.o ttdebug.o \ + ttextend.o ttfile.o ttgload.o ttinterp.o ttload.o \ + ttmemory.o ttmutex.o ttobjs.o ttraster.o + +OBJS = freetype.o + +OBJX = ftxgasp.o ftxkern.o ftxpost.o ftxcmap.o ftxwidth.o ftxerr18.o \ + ftxsbit.o ftxgsub.o ftxopen.o + +CORE = FT:lib/ +COREXT = $(CORE)extend/ +TST = FT:test/ + +OPTIMIZER = optimize optcomp=5 optdep=4 optinlocal optrdep=4 + +SCFLAGS = idlen=40 idir=$(CORE)arch/amigaos idir=$(CORE) + +TSCFLAGS = $(SCFLAGS) idir=$(TST) idir=$(COREXT) + +LIB=ttf.lib +TOPTS=$(TSCFLAGS) link lib=$(LIB) lib=lib:scm.lib \ + lib=lib:sc.lib lib=lib:amiga.lib + +EXE = ftzoom ftlint ftview fttimer ftmetric \ + ftdump ftstring ftstrpnm ftsbit ftstrtto + +TOBJ = gw_amiga.o gmain.o common.o blitter.o + +all: ttf.lib $(EXE) + +assign: + assign FT: /// + +ttf.lib: $(OBJS) $(OBJX) + oml $@ r $(OBJS) $(OBJX) + +ttfdbg.lib: $(OBJB) $(OBJX) + oml $@ r $(OBJB) $(OBJX) + +clean: + -delete \#?.o + -delete //\#?.o + -delete \#?.lib + -delete $(EXE) + + +# +# freetype library core single object +# +freetype.o: $(CORE)arch/amigaos/freetype.c + sc $(SCFLAGS) code=far $(OPTIMIZER) objname=$@ $< + +# +# freetype library core as separate objects +# +ttapi.o: $(CORE)ttapi.c + sc $(SCFLAGS) objname=$@ $< +ttcache.o: $(CORE)ttcache.c + sc $(SCFLAGS) objname=$@ $< +ttcalc.o: $(CORE)ttcalc.c + sc $(SCFLAGS) objname=$@ $< +ttcmap.o: $(CORE)ttcmap.c + sc $(SCFLAGS) objname=$@ $< +ttdebug.o: $(CORE)ttdebug.c + sc $(SCFLAGS) objname=$@ $< +ttextend.o: $(CORE)ttextend.c + sc $(SCFLAGS) objname=$@ $< +ttfile.o: $(CORE)ttfile.c + sc $(SCFLAGS) objname=$@ $< +ttgload.o: $(CORE)ttgload.c + sc $(SCFLAGS) objname=$@ $< +ttinterp.o: $(CORE)ttinterp.c + sc $(SCFLAGS) objname=$@ $< +ttload.o: $(CORE)ttload.c + sc $(SCFLAGS) objname=$@ $< +ttmemory.o: $(CORE)ttmemory.c + sc $(SCFLAGS) objname=$@ $< +ttmutex.o: $(CORE)ttmutex.c + sc $(SCFLAGS) objname=$@ $< +ttobjs.o: $(CORE)ttobjs.c + sc $(SCFLAGS) objname=$@ $< +ttraster.o: $(CORE)ttraster.c + sc $(SCFLAGS) objname=$@ $< + +# +# library extentions +# +ftxgasp.o: $(COREXT)ftxgasp.c + sc $(SCFLAGS) objname=$@ $< +ftxkern.o: $(COREXT)ftxkern.c + sc $(SCFLAGS) objname=$@ $< +ftxpost.o: $(COREXT)ftxpost.c + sc $(SCFLAGS) objname=$@ $< +ftxcmap.o: $(COREXT)ftxcmap.c + sc $(SCFLAGS) objname=$@ $< +ftxwidth.o: $(COREXT)ftxwidth.c + sc $(SCFLAGS) objname=$@ $< +ftxerr18.o: $(COREXT)ftxerr18.c + sc $(SCFLAGS) objname=$@ $< +ftxsbit.o: $(COREXT)ftxsbit.c + sc $(SCFLAGS) objname=$@ $< +ftxgsub.o: $(COREXT)ftxgsub.c + sc $(SCFLAGS) objname=$@ $< +ftxopen.o: $(COREXT)ftxopen.c + sc $(SCFLAGS) objname=$@ $< + +# +# Test programs +# +ftzoom: $(TST)ftzoom.c $(TOBJ) $(LIB) + sc $(TST)ftzoom.c programname=$@ $(TOBJ) $(TOPTS) + +ftlint: $(TST)ftlint.c common.o $(LIB) + sc $(TST)ftlint.c programname=$@ common.o $(TOPTS) + +ftdump: $(TST)ftdump.c common.o $(LIB) + sc $(TST)ftdump.c programname=$@ common.o $(TOPTS) + +# use unsigned char so full latin1 encoding may be used in string argument +ftstring: $(TST)ftstring.c $(TOBJ) display.o $(LIB) + sc $(TST)ftstring.c uchar programname=$@ $(TOBJ) display.o $(TOPTS) + +ftview: $(TST)ftview.c $(TOBJ) display.o $(LIB) + sc $(TST)ftview.c programname=$@ $(TOBJ) display.o $(TOPTS) + +fttimer: $(TST)fttimer.c $(TOBJ) $(LIB) + sc $(TST)fttimer.c programname=$@ $(TOBJ) $(TOPTS) + +ftstrpnm: $(TST)ftstrpnm.c common.o $(LIB) + sc $(TST)ftstrpnm.c uchar programname=$@ common.o $(TOPTS) + +ftsbit: $(TST)ftsbit.c common.o $(LIB) + sc $(TST)ftsbit.c programname=$@ common.o $(TOPTS) + +ftmetric: $(TST)ftmetric.c common.o $(LIB) + sc $(TST)ftmetric.c programname=$@ common.o $(TOPTS) + +# use unsigned char so full latin1/UTF8 encoding may be used in argument +ftstrtto: $(TST)ftstrtto.c $(TOBJ) display.o arabic.o $(LIB) + sc $(TST)ftstrtto.c uchar programname=$@ $(TOBJ) \ + arabic.o display.o $(TOPTS) + +# +# Test program support modules +# + +gw_amiga.o: gw_amiga.c + sc gw_amiga.c $(TSCFLAGS) + +common.o: $(TST)common.c + sc $(TSCFLAGS) objname=$@ $< + +blitter.o: $(TST)blitter.c + sc $(TSCFLAGS) objname=$@ $< + +display.o: $(TST)display.c + sc $(TSCFLAGS) objname=$@ $< + +gmain.o: $(TST)gmain.c + sc $(TSCFLAGS) objname=$@ $< + +arabic.o: $(TST)arabic.c + sc $(TSCFLAGS) objname=$@ $< + +# end of smakefile diff --git a/test/arch/debugger/Makefile b/test/arch/debugger/Makefile new file mode 100644 index 0000000..9c37019 --- /dev/null +++ b/test/arch/debugger/Makefile @@ -0,0 +1,99 @@ +# This file is part of the FreeType project. +# +# It builds the debugger for emx-gcc under OS/2 resp. under Unix. +# +# You will need GNU make. +# +# Use this file while in the `test' directory with the following statement: +# +# make -f arch/debugger/Makefile + +ARCH = arch/debugger +FT_MAKEFILE = $(ARCH)/Makefile + +CC = gcc + +LIBDIR = ../lib +LIBTTF = $(LIBDIR)/$(ARCH)/libttf.a + +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)/extend -I$(LIBDIR)/$(ARCH) -I. + +# Note: The debugger uses non-ANSI functions to read the keyboard +# on OS/2 -- do not set the `-ansi flag here. +# +CFLAGS = -Wall -O0 -g $(INCDIRS) + + +SRC = fdebug.c common.c + +ALLSRC = $(SRC) +ALLOBJ = $(ALLSRC:.c=.o) + +# on OS/2, do not use the curses library +# +ifdef OS2_SHELL +EXE := fdebug.exe +OS := OS2 +EFENCE := +EXTRAFLAGS := +RM := del +else +EXE := fdebug +OS := UNIX +EFENCE := -lefence +RM := rm -f +# +# POSIX TERMIOS: Do not define if you use OLD U*ix like 4.2BSD. +# +EXTRAFLAGS := HAVE_POSIX_TERMIOS +endif + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< -D$(OS) -D$(EXTRAFLAGS) + +%.exe: + $(CC) $(CFLAGS) -o $@ $^ + + + +EXEFILES = $(EXE) + +.PHONY: all debug freetype freetype_debug \ + clean distclean do_clean depend + + +all: freetype $(EXEFILES) + +debug: freetype_debug $(EXEFILES) + +$(EXE): fdebug.o common.o $(LIBTTF) +$(EXE): + $(CC) $(CFLAGS) -o $@ $^ $(EFENCE) + +freetype: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) all + +freetype_debug: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) debug + + +clean: do_clean + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) clean + +distclean: do_clean + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) distclean + -$(RM) dep.end $(EXEFILES) core + +do_clean: + -$(RM) $(subst /,\,$(ALLOBJ)) + + +depend: $(ALLSRC) + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) depend + $(CC) -E -M $(INCDIRS) $^ > dep.end + +ifeq (dep.end,$(wildcard dep.end)) + include dep.end +endif + +# end of Makefile.emx diff --git a/test/arch/msdos/Makefile.BC b/test/arch/msdos/Makefile.BC new file mode 100644 index 0000000..825395b --- /dev/null +++ b/test/arch/msdos/Makefile.BC @@ -0,0 +1,181 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for BC++ under MSDOS, large model. +# +# Tested with Borland C++ v.3.1, 4.02, 5.0 +# You will need Borland MAKE (v.3.6 and above should be OK, for oldest +# versions refer to the instructions below). +# +# +# Use this file while in the 'test' directory with the following statement: +# +# make -farch\msdos\Makefile.BC +# +# +# Debug versions can be obtained with +# +# make -DDEBUG -farch\msdos\Makefile.BC +# +# A special version enabled to handle big fonts (with more than 16,384 +# glyphs) can be obtained with +# +# make -DBIGFONTS -farch\msdos\Makefile.BC + +ARCH = arch\msdos +FT_MAKEFILE = $(ARCH)\Makefile.BC + +CC = bcc + +LIBDIR = ..\lib +INCDIRS = -I$(LIBDIR);$(LIBDIR)\$(ARCH);.;$(LIBDIR)\extend +SPURIOUS_WARNINGS = -w-nak -w-par -w-use -w-aus -w-stu -w-stv -w-cln -w-sig -w-pia + +# Credits go to Dave Hoo for pointing out that modern +# Borland compilers (from BC++ 3.1 on) can increase the limit of +# the length of identifiers. +!if ! $d(DEBUG) +CFLAGS = -ml -A -O2 -3 -i40 $(INCDIRS) $(SPURIOUS_WARNINGS) +LDFLAGS = -ml +!else +CFLAGS = -v -N -ml -A -i40 $(INCDIRS) $(SPURIOUS_WARNINGS) +LDFLAGS = -v -ml +!endif + + +# full-screen MSDOS driver +GDRIVER = $(ARCH)\.\gfs_dos.c + +DISPLAY = display.c + +G1SRC = gmain.c blitter.c $(GDRIVER) +GSRC = $(DISPLAY) $(G1SRC) + +GOBJ = $(GSRC:.c=.obj) +G1OBJ = $(G1SRC:.c=.obj) + + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +OBJ = $(SRC:.c=.obj) + + +.c.obj: + $(CC) -c -o$* @&&| + $(CFLAGS) $< +| + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + +!if !$d(DEBUG) +# Skipped if DEBUG build +all: freetype $(EXEFILES) + +!endif + +debug: freetype_debug $(EXEFILES) + +!if $d(BIGFONTS) +MAKEBIG = -DBIGFONTS +!endif + +freetype: + cd $(LIBDIR) + make -f$(FT_MAKEFILE) $(MAKEBIG) all + cd ..\test + +freetype_debug: + cd $(LIBDIR) + make -f$(FT_MAKEFILE) -DDEBUG $(MAKEBIG) debug + cd ..\test + + +# Borland C compilers are unable to include in ANSI mode. +# So we have a special rule for this file, to build it outside ANSI. +$(GDRIVER:.c=.obj): + $(CC) -c -o$* @&&| + $(CFLAGS) -A- $*.c +| + +.obj.exe: + $(CC) -e$* @&&| + $(LDFLAGS) $** +| + +# Borland versions of make are unable to use the $** variable inside +# implicit rules (like .obj.exe:). The job has to be done by hand. :-( +ftzoom.exe: $(G1OBJ) ftzoom.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftzoom.obj $(G1OBJ) common.obj $(LIBDIR)\libttf.lib + +ftview.exe: $(GOBJ) ftview.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftview.obj $(GOBJ) common.obj $(LIBDIR)\libttf.lib + +ftstring.exe: $(GOBJ) ftstring.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftstring.obj $(GOBJ) common.obj $(LIBDIR)\libttf.lib + +ftstrtto.exe: $(GOBJ) ftstrtto.obj common.obj arabic.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftstrtto.obj $(GOBJ) common.obj arabic.obj \ + $(LIBDIR)\libttf.lib + +fttimer.exe: $(G1OBJ) fttimer.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) fttimer.obj $(G1OBJ) common.obj $(LIBDIR)\libttf.lib + +ftlint.exe: ftlint.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftlint.obj common.obj $(LIBDIR)\libttf.lib + +ftdump.exe: ftdump.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftdump.obj common.obj $(LIBDIR)\libttf.lib + +ftstrpnm.exe: ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib + +ftsbit.exe: ftsbit.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftsbit.obj common.obj $(LIBDIR)\libttf.lib + +ftmetric.exe: ftmetric.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftmetric.obj common.obj $(LIBDIR)\libttf.lib + +fterror.exe: fterror.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) fterror.obj common.obj $(LIBDIR)\libttf.lib + + +clean: do_clean + cd $(LIBDIR) + make -f$(FT_MAKEFILE) clean + cd ..\test + +distclean: do_clean + cd $(LIBDIR) + make -f$(FT_MAKEFILE) distclean + cd ..\test + -del *.exe + +do_clean: + -del *.obj + -del $(ARCH)\*.obj + del time.h # clean the ugly hack for Turbo C... + +!include "$(ARCH)\depend.dos" + +# end of Makefile diff --git a/test/arch/msdos/Makefile.MS b/test/arch/msdos/Makefile.MS new file mode 100644 index 0000000..46d6950 --- /dev/null +++ b/test/arch/msdos/Makefile.MS @@ -0,0 +1,142 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for Microsoft C for MS-DOS, +# large model. It also works for Visual C++ 1.x 16-bits compiler, but +# you should instead use the Makefile customized for it, Makefile.VC. +# +# You will need NMAKE. +# +# +# Use this file while in the 'test' directory with the following statement: +# +# nmake /f arch\msdos\Makefile.MS +# +# +# Debug versions can be obtained with +# +# nmake DEBUG=1 /f arch\msdos\Makefile.MS +# +# A special version enabled to handle big fonts (with more than 16,384 +# glyphs) can be obtained with +# +# nmake BIGFONTS=1 /f arch\msdos\Makefile.MS + +ARCH = arch\msdos +FT_MAKEFILE = $(ARCH)\Makefile.MS +FT_MAKE = $(MAKE) /nologo + +CC = cl /nologo + +LIBDIR = ..\lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)\$(ARCH) -I. -I$(LIBDIR)\extend + +!ifndef DEBUG +CFLAGS = /Ox /AL /Za /W2 /G2 $(INCDIRS) +LDFLAGS = /AL +!else +CFLAGS = /Zi /AL /Za /W2 /G2 $(INCDIRS) +LDFLAGS = /Zi /AL +!endif + + +# full-screen MSDOS driver +GDRIVER = $(ARCH)\gfs_dos.c + +GSRC = display.c gmain.c blitter.c $(GDRIVER) + +GOBJ = $(GSRC:.c=.obj) + + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +OBJ = $(SRC:.c=.obj) + + +.c.obj: + @$(CC) /c /Fo$* @<< + $(CFLAGS) $< +<< + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + +!ifndef DEBUG +# Skiped if DEBUG build +all: freetype $(EXEFILES) + +!endif + +debug: freetype_debug $(EXEFILES) + +!ifdef BIGFONTS +MAKEBIG = BIGFONTS=1 +!endif + +freetype: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) $(MAKEBIG) all + cd ..\test + +freetype_debug: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) DEBUG=1 $(MAKEBIG) debug + cd ..\test + +.obj.exe: + $(CC) /Fe$* @<< + $(LDFLAGS) $** +<< + +ftzoom.exe: $(GOBJ) ftzoom.obj common.obj $(LIBDIR)\libttf.lib +ftview.exe: $(GOBJ) ftview.obj common.obj $(LIBDIR)\libttf.lib +ftstring.exe: $(GOBJ) ftstring.obj common.obj $(LIBDIR)\libttf.lib +ftstrtto.exe: $(GOBJ) ftstrtto.obj common.obj arabic.obj $(LIBDIR)\libttf.lib +fttimer.exe: $(GOBJ) fttimer.obj common.obj $(LIBDIR)\libttf.lib +ftlint.exe: ftlint.obj common.obj $(LIBDIR)\libttf.lib +ftdump.exe: ftdump.obj common.obj $(LIBDIR)\libttf.lib +ftstrpnm.exe: ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib +ftsbit.exe: ftsbit.obj common.obj $(LIBDIR)\libttf.lib +ftmetric.exe: ftmetric.obj common.obj $(LIBDIR)\libttf.lib +fterror.exe: fterror.obj common.obj $(LIBDIR)\libttf.lib + + +clean: do_clean + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) clean + cd ..\test + +distclean: do_clean + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) distclean + cd ..\test + -del *.exe + +do_clean: + -del *.obj + -del $(ARCH)\*.obj + + +!include "$(ARCH)\depend.dos" + +# end of Makefile.MS diff --git a/test/arch/msdos/Makefile.TC b/test/arch/msdos/Makefile.TC new file mode 100644 index 0000000..9422329 --- /dev/null +++ b/test/arch/msdos/Makefile.TC @@ -0,0 +1,196 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for Turbo C under MSDOS, large model. +# +# You will need Borland MAKE. +# Tested with Turbo C v.1.5, v.2.0, Turbo C++ v.1.0 +# Turbo C v.1.0 (May '87) is too old (lack of structure assignment) +# to compile FreeType. Update your compiler. ;-) +# +# +# Use this file while in the 'test' directory with the following statement: +# +# make -farch\msdos\Makefile.TC +# +# +# Debug versions can be obtained (except for TC 1.5) with +# +# make -DDEBUG -farch\msdos\Makefile.TC + +ARCH = arch\msdos +FT_MAKEFILE = $(ARCH)\Makefile.TC + +CC = tcc + +LIBDIR = ..\lib +INCDIRS = -I$(LIBDIR);$(LIBDIR)\$(ARCH);.;$(LIBDIR)\extend + +!if ! $d(DEBUG) +CFLAGS = -ml -A -O -Z -G -a -w-stv -w-sig $(INCDIRS) +LDFLAGS = -ml +!else +# For Turbo C v.1.5, replace the -v option below by -y. +CFLAGS = -v -N -ml -A -w-par -w-use -w-aus -w-stu -w-stv -w-cln -w-sig $(INCDIRS) +LDFLAGS = -v -ml +!endif + + +# full-screen MSDOS driver +GDRIVER = $(ARCH)\.\gfs_dos.obj + +# the line below does not work with these old versions of make... +# GOBJ = $(GSRC:.c=.o) + +DISPLAY = display.obj + +G1OBJ = gmain.obj blitter.obj $(GDRIVER) +GOBJ = $(DISPLAY) $(G1OBJ) + + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +OBJ = arabic.obj \ + common.obj \ + ftdump.obj \ + fterror.obj \ + ftlint.obj \ + ftmetric.obj \ + ftsbit.obj \ + ftstring.obj \ + ftstrpnm.obj \ + ftstrtto.obj \ + fttimer.obj \ + ftview.obj \ + ftzoom.obj + + +.c.obj: + $(CC) $(CFLAGS) -c -o$* $< + + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + + +!if !$d(DEBUG) +# Skipped if DEBUG build +all: freetype $(EXEFILES) + +!endif + +debug: freetype_debug $(EXEFILES) + +freetype: + cd $(LIBDIR) + make -f$(FT_MAKEFILE) all + cd ..\test + +freetype_debug: + cd $(LIBDIR) + make -f$(FT_MAKEFILE) -DDEBUG debug + cd ..\test + + +# Borland C compilers are unable to include in ANSI mode. +# So we have a special rule for this file, to build it outside ANSI. +$(GDRIVER): + $(CC) $(CFLAGS) -A- -c -o$* $*.c + +!if $(__MAKE__) < 0x0300 +# Also, Turbo C v.1.5 and v.2.0 are not fully ANSI compliant with regard to +# , particularly the clock() function. +# So we use an ugly hack here: a modified version of time.h, with the +# necessary machinery, is included in the arch\msdos directory. +time.h: $(ARCH)\time_tc.h + copy $(ARCH)\time_tc.h time.h + +# Below is the special rule for forcing recompilation of fttimer.obj +# using our , without using the rule that is pulled in by +# !include "$(ARCH)\depend.dos" at the end of the Makefile... +fttimer.exe: $(G1OBJ) fttimer.c time.h common.obj $(LIBDIR)\libttf.lib + $(CC) $(CFLAGS) -c -o$* $*.c + $(CC) $(LDFLAGS) fttimer.obj $(G1OBJ) common.obj $(LIBDIR)\libttf.lib + +!else +# Normal behaviour +fttimer.exe: $(G1OBJ) fttimer.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) fttimer.obj $(G1OBJ) common.obj $(LIBDIR)\libttf.lib +!endif + + +# This old gr... make is unable to have a $ variable to name all the +# dependencies. :-( So the job have to be done by hand... +ftzoom.exe: $(G1OBJ) ftzoom.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftzoom.obj $(G1OBJ) common.obj $(LIBDIR)\libttf.lib + +ftview.exe: $(GOBJ) ftview.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftview.obj $(GOBJ) common.obj $(LIBDIR)\libttf.lib + +ftstring.exe: $(GOBJ) ftstring.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftstring.obj $(GOBJ) common.obj $(LIBDIR)\libttf.lib + +ftstrtto.exe: $(GOBJ) ftstrtto.obj common.obj arabic.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftstrtto.obj $(GOBJ) common.obj \ + arabic.obj $(LIBDIR)\libttf.lib + +# fttimer.exe is handled above (because of hack) + +ftlint.exe: ftlint.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftlint.obj common.obj $(LIBDIR)\libttf.lib + +ftdump.exe: ftdump.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftdump.obj common.obj $(LIBDIR)\libttf.lib + +ftstrpnm.exe: ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib + +ftsbit.exe: ftsbit.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftsbit.obj common.obj $(LIBDIR)\libttf.lib + +ftmetric.exe: ftmetric.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftmetric.obj common.obj $(LIBDIR)\libttf.lib + +fterror.exe: fterror.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) fterror.obj common.obj $(LIBDIR)\libttf.lib + + +clean: do_clean + cd $(LIBDIR) + make -f$(FT_MAKEFILE) clean + cd ..\test + +distclean: do_clean + cd $(LIBDIR) + make -f$(FT_MAKEFILE) distclean + cd ..\test + -del *.exe + +do_clean: + -del *.obj + -del $(ARCH)\*.obj + del time.h # clean the ugly hack for Turbo C... + +!include "$(ARCH)\depend.dos" + +# end of Makefile diff --git a/test/arch/msdos/Makefile.VC b/test/arch/msdos/Makefile.VC new file mode 100644 index 0000000..c39bb16 --- /dev/null +++ b/test/arch/msdos/Makefile.VC @@ -0,0 +1,143 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for Microsoft Visual C++ 1.x +# and Microsoft C/C++ v.7.0 16-bit compilers for MS-DOS, large model. +# +# You will need NMAKE. +# +# +# Use this file while in the 'test' directory with the following statement: +# +# nmake /f arch\msdos\Makefile.VC +# +# +# Debug versions can be obtained with +# +# nmake DEBUG=1 /f arch\msdos\Makefile.VC +# +# A special version enabled to handle big fonts (with more than 16,384 +# glyphs) can be obtained with +# +# nmake BIGFONTS=1 /f arch\msdos\Makefile.VC + +ARCH = arch\msdos +FT_MAKEFILE = $(ARCH)\Makefile.VC +FT_MAKE = $(MAKE) /nologo + +CC = cl /nologo + +LIBDIR = ..\lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)\$(ARCH) -I. -I$(LIBDIR)\extend + +# One can also consider using "set MSC_CMD_FLAGS=/Gr /Op- /Gy /YX". +# With Microsoft C/C++ 7.0, use /G2 instead of /G3. +!ifndef DEBUG +CFLAGS = /Ox /AL /Za /W2 /G3 $(INCDIRS) +LDFLAGS = /AL +!else +CFLAGS = /Zi /Ge /AL /Za /W2 /G3 $(INCDIRS) +LDFLAGS = /Zi /AL +!endif + + +# full-screen MSDOS driver +GDRIVER = $(ARCH)\gfs_dos.c + +GSRC = display.c gmain.c blitter.c $(GDRIVER) + +GOBJ = $(GSRC:.c=.obj) + + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +OBJ = $(SRC:.c=.obj) + + +.c.obj: + @$(CC) /c /Fo$* @<< + $(CFLAGS) $< +<< + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + +!ifndef DEBUG +# Skiped if DEBUG build +all: freetype $(EXEFILES) + +!endif + +debug: freetype_debug $(EXEFILES) + +!ifdef BIGFONTS +MAKEBIG = BIGFONTS=1 +!endif + +freetype: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) $(MAKEBIG) all + cd ..\test + +freetype_debug: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) DEBUG=1 $(MAKEBIG) debug + cd ..\test + +.obj.exe: + $(CC) /Fe$* @<< + $(LDFLAGS) $** +<< + +ftzoom.exe: $(GOBJ) ftzoom.obj common.obj $(LIBDIR)\libttf.lib +ftview.exe: $(GOBJ) ftview.obj common.obj $(LIBDIR)\libttf.lib +ftstring.exe: $(GOBJ) ftstring.obj common.obj $(LIBDIR)\libttf.lib +ftstrtto.exe: $(GOBJ) ftstrtto.obj common.obj arabic.obj $(LIBDIR)\libttf.lib +fttimer.exe: $(GOBJ) fttimer.obj common.obj $(LIBDIR)\libttf.lib +ftlint.exe: ftlint.obj common.obj $(LIBDIR)\libttf.lib +ftdump.exe: ftdump.obj common.obj $(LIBDIR)\libttf.lib +ftstrpnm.exe: ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib +ftsbit.exe: ftsbit.obj common.obj $(LIBDIR)\libttf.lib +ftmetric.exe: ftmetric.obj common.obj $(LIBDIR)\libttf.lib +fterror.exe: fterror.obj common.obj $(LIBDIR)\libttf.lib + + +clean: do_clean + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) clean + cd ..\test + +distclean: do_clean + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) distclean + cd ..\test + -del *.exe + +do_clean: + -del *.obj + -del $(ARCH)\*.obj + + +!include "$(ARCH)\depend.dos" + +# end of Makefile.VC diff --git a/test/arch/msdos/Makefile.dm b/test/arch/msdos/Makefile.dm new file mode 100644 index 0000000..19a4d05 --- /dev/null +++ b/test/arch/msdos/Makefile.dm @@ -0,0 +1,145 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for emx-gcc and djgpp under MSDOS. +# +# You will need dmake. +# +# Use this file while in the 'test' directory with the following statement: +# +# dmake -r -f arch/msdos/Makefile.dm + +ARCH = arch/msdos +FT_MAKEFILE = $(ARCH)/Makefile.dm +FT_MAKE = dmake -r + +.IMPORT: COMSPEC +SHELL := $(COMSPEC) +SHELLFLAGS := /c +GROUPSHELL := $(SHELL) +GROUPFLAGS := $(SHELLFLAGS) +GROUPSUFFIX := .bat +SHELLMETAS := *"?<>&| + +CC = gcc + +LIBDIR = ../lib +LIBDIR_DOS = ..\lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)/$(ARCH) -I. -I$(LIBDIR)/extend + +CFLAGS = -Wall -ansi -O2 -g $(INCDIRS) +# CFLAGS = -ansi -Wall -O2 -s $(INCDIRS) + +# full-screen MSDOS driver +GDRIVER = $(ARCH)/gfs_dos.c + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +GSRC = gmain.c display.c blitter.c $(GDRIVER) +GOBJ = $(GSRC:.c=.o) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +%.exe: + $(CC) $(CFLAGS) -o $@ @$(mktmp $(&:t"\n")\n) + + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + +.PHONY: all debug freetype freetype_debug \ + clean distclean do_clean do_distclean depend + + +all: freetype $(EXEFILES) + +debug: freetype_debug $(EXEFILES) + +freetype: +[ + cd $(LIBDIR_DOS) + $(FT_MAKE) -f $(FT_MAKEFILE) all + cd $(MAKEDIR) +] + +freetype_debug: +[ + cd $(LIBDIR_DOS) + $(FT_MAKE) -f $(FT_MAKEFILE) debug + cd $(MAKEDIR) +] + +ftzoom.exe: $(GOBJ) ftzoom.o common.o $(LIBDIR)/libttf.a +ftview.exe: $(GOBJ) ftview.o common.o $(LIBDIR)/libttf.a +ftlint.exe: ftlint.o common.o $(LIBDIR)/libttf.a +ftdump.exe: ftdump.o common.o $(LIBDIR)/libttf.a +ftstring.exe: $(GOBJ) ftstring.o common.o $(LIBDIR)/libttf.a +fttimer.exe: $(GOBJ) fttimer.o common.o $(LIBDIR)/libttf.a +ftstrpnm.exe: ftstrpnm.o common.o $(LIBDIR)/libttf.a +ftsbit.exe: ftsbit.o common.o $(LIBDIR)/libttf.a +ftmetric.exe: ftmetric.o common.o $(LIBDIR)/libttf.a +ftstrtto.exe: $(GOBJ) ftstrtto.o common.o arabic.o $(LIBDIR)/libttf.a + + +clean: do_clean +[ + cd $(LIBDIR_DOS) + $(FT_MAKE) -f $(FT_MAKEFILE) clean + cd $(MAKEDIR) +] + +distclean: do_clean do_distclean +[ + cd $(LIBDIR_DOS) + $(FT_MAKE) -f $(FT_MAKEFILE) distclean + cd $(MAKEDIR) +] + +do_distclean: +-[ + del dep.end + del *.exe + del core +] + +do_clean: +-[ + del *.o + del $(ARCH)\gfs_dos.o +] + +#depend: $(SRC) $(GSRC) +#[ +# cd $(LIBDIR_DOS) +# $(FT_MAKE) -f $(FT_MAKEFILE) depend +# cd $(MAKEDIR) +# $(CC) -E -M $(INCDIRS) @$(mktmp $(<:t"\n")\n) > dep.end +#] +# +#ifeq (dep.end,$(wildcard dep.end)) +# include dep.end +#endif + +# end of Makefile.dm diff --git a/test/arch/msdos/Makefile.gcc b/test/arch/msdos/Makefile.gcc new file mode 100644 index 0000000..806ca87 --- /dev/null +++ b/test/arch/msdos/Makefile.gcc @@ -0,0 +1,130 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for emx-gcc and djgpp under MSDOS. +# +# You will need a recent GNU make DOS port. +# +# Use this file while in the 'test' directory with the following statement: +# +# make -f arch/msdos/Makefile.gcc +# +# +# If you have the GNU gettext package installed with DJGPP, you can also try +# +# make -f arch/msdos/Makefile.gcc HAVE_GETTEXT + +ARCH = arch/msdos +FT_MAKEFILE = $(ARCH)/Makefile.gcc + +CC = gcc + +LIBDIR = ../lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)/$(ARCH) -I. -I$(LIBDIR)/extend + +ifndef GETTEXT +GETTEXT=NO_GETTEXT +endif + +CFLAGS = -Wall -ansi -O2 -g $(INCDIRS) -D$(GETTEXT) +# CFLAGS = -ansi -Wall -O2 -s $(INCDIRS) -D$(GETTEXT) + + +# full-screen MSDOS driver +GDRIVER = $(ARCH)/gfs_dos.c + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +GSRC = gmain.c display.c blitter.c $(GDRIVER) +GOBJ = $(GSRC:.c=.o) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + + +ifeq ($(GETTEXT),HAVE_GETTEXT) +%.exe: + $(CC) $(CFLAGS) -o $@ $^ -lintl +else +%.exe: + $(CC) $(CFLAGS) -o $@ $^ +endif + + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + +.PHONY: all debug freetype freetype_debug \ + clean distclean do_clean depend + + +all: freetype $(EXEFILES) + +debug: freetype_debug $(EXEFILES) + +HAVE_GETTEXT: + $(MAKE) -f $(FT_MAKEFILE) GETTEXT=HAVE_GETTEXT all + +freetype: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) all + +freetype_debug: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) debug + +ftzoom.exe: $(GOBJ) ftzoom.o common.o $(LIBDIR)/libttf.a +ftview.exe: $(GOBJ) ftview.o common.o $(LIBDIR)/libttf.a +ftlint.exe: ftlint.o common.o $(LIBDIR)/libttf.a +ftdump.exe: ftdump.o common.o $(LIBDIR)/libttf.a +fterror.exe: fterror.o common.o $(LIBDIR)/libttf.a +ftstring.exe: $(GOBJ) ftstring.o common.o $(LIBDIR)/libttf.a +fttimer.exe: $(GOBJ) fttimer.o common.o $(LIBDIR)/libttf.a +ftstrpnm.exe: ftstrpnm.o common.o $(LIBDIR)/libttf.a +ftsbit.exe: ftsbit.o common.o $(LIBDIR)/libttf.a +ftmetric.exe: ftmetric.o common.o $(LIBDIR)/libttf.a +ftstrtto.exe: $(GOBJ) ftstrtto.o common.o arabic.o $(LIBDIR)/libttf.a + + +clean: do_clean + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) clean + +distclean: do_clean + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) distclean + -del dep.end + -del *.exe + -del core + +do_clean: + -del *.o + -del response + -del $(ARCH)\gfs_dos.o + +depend: $(SRC) $(GSRC) + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) depend + $(CC) -E -M $(INCDIRS) $^ > dep.end + +ifeq (dep.end,$(wildcard dep.end)) + include dep.end +endif + +# end of Makefile.gcc diff --git a/test/arch/msdos/depend.dos b/test/arch/msdos/depend.dos new file mode 100644 index 0000000..3abb6f8 --- /dev/null +++ b/test/arch/msdos/depend.dos @@ -0,0 +1,50 @@ +# This dependency file to be used with various MS-DOS compilers +# has been generated automatically with the script `makedep' on +# 03-Sep-1999. + +arabic.obj: arabic.c arabic.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxopen.h ..\lib\extend\ftxgdef.h \ + ..\lib\extend\ftxgsub.h ..\lib\extend\ftxgpos.h +blitter.obj: blitter.c blitter.h +common.obj: common.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h +display.obj: display.c display.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h gmain.h +fdebug.obj: fdebug.c ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\tttypes.h ..\lib\ttconfig.h \ + ..\lib\arch\msdos\ft_conf.h ..\lib\ttdebug.h ..\lib\ttobjs.h \ + ..\lib\ttengine.h ..\lib\ttmutex.h ..\lib\ttcache.h ..\lib\tttables.h \ + ..\lib\ttcmap.h +ftdump.obj: ftdump.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxcmap.h ..\lib\extend\ftxopen.h \ + ..\lib\extend\ftxgdef.h ..\lib\extend\ftxgsub.h \ + ..\lib\extend\ftxgpos.h ..\lib\extend\ftxsbit.h ..\lib\ttobjs.h \ + ..\lib\ttconfig.h ..\lib\arch\msdos\ft_conf.h ..\lib\ttengine.h \ + ..\lib\tttypes.h ..\lib\ttmutex.h ..\lib\ttcache.h ..\lib\tttables.h \ + ..\lib\ttcmap.h +fterror.obj: fterror.c ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxerr18.h \ + ..\lib\arch\msdos\ft_conf.h +ftlint.obj: ftlint.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\arch\msdos\ft_conf.h +ftmetric.obj: ftmetric.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxsbit.h ..\lib\arch\msdos\ft_conf.h +ftsbit.obj: ftsbit.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxsbit.h ..\lib\arch\msdos\ft_conf.h +ftstring.obj: ftstring.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h display.h gevents.h gdriver.h gmain.h +ftstrpnm.obj: ftstrpnm.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h +ftstrtto.obj: ftstrtto.c arabic.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxopen.h ..\lib\extend\ftxgdef.h \ + ..\lib\extend\ftxgsub.h ..\lib\extend\ftxgpos.h blitter.h common.h \ + display.h ..\lib\extend\ftxkern.h ..\lib\extend\ftxsbit.h gdriver.h \ + gevents.h gmain.h +fttimer.obj: fttimer.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h gdriver.h gevents.h gmain.h +ftview.obj: ftview.c blitter.h common.h display.h \ + ..\lib\extend\ftxsbit.h gdriver.h gevents.h gmain.h +ftzoom.obj: ftzoom.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxpost.h gdriver.h gevents.h gmain.h +gmain.obj: gmain.c gdriver.h gmain.h +arch\msdos\gfs_dos.obj: arch\msdos\gfs_dos.c gdriver.h gevents.h gmain.h diff --git a/test/arch/msdos/gfs_dos.c b/test/arch/msdos/gfs_dos.c new file mode 100644 index 0000000..78a7023 --- /dev/null +++ b/test/arch/msdos/gfs_dos.c @@ -0,0 +1,357 @@ +/******************************************************************* + * + * gfs_dos.c graphics utility fullscreen Dos driver. 1.0 + * + * This is the driver for fullscreen Dos display, used by the + * graphics utility of the FreeType test suite. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include +#include +#if defined( __STDC__ ) || defined( __TURBOC__ ) +#include +#else +#include +#endif + +#include "gdriver.h" +#include "gevents.h" +#include "gmain.h" + + +/* The following #ifdef are used to define the following macros : */ +/* */ +/* - int86 : function to call an interrupt */ +/* - reg_ax : the 'ax' register as stored in the REGS struct */ +/* */ + +/* ---- DJGPP dos compiler support --------------------------------------- */ + +/* DJGPP v1.x */ +#if !defined( __DJGPP__ ) && defined( __GO32__ ) + +#define DJGPP1 +#undef __STRICT_ANSI__ +#include +#include +#include +#include + +#define reg_ax regs.x.ax + +#endif + +/* DJGPP v2.x */ +#ifdef __DJGPP__ + +#define DJGPP2 +#undef __STRICT_ANSI__ +#include +#include +#include +#define int86( a, b, c ) int86( a, b, c ) +#define reg_ax regs.x.ax + +#endif + +/* ---- Microsoft C compilers support ------------------------------------ */ + +#if defined( M_I86 ) || defined( _M_I86 ) + +#include +#include + +#define reg_ax regs.x.ax + +#ifdef _M_I86 /* a recent compiler, which do not pollute name spaces */ +#define getch() _getch() +#define REGS _REGS +#define int86( a, b, c ) _int86( a, b, c ) +#endif + +#ifndef MK_FP +#ifdef _MK_FP +#define MK_FP( seg, ofs ) _MK_FP( seg, ofs ) +#else +#ifndef _M_I86 /* old versions */ +#define __far _far +#endif +#define MK_FP( seg, offset ) (void __far *)( ((unsigned long)seg << 16) + \ + (unsigned long)(unsigned)offset ) +#endif /* _MK_FP */ +#endif /* MK_FP */ + +#endif /* Microsoft compilers */ + +/* ---- Borland C compiler support --------------------------------------- */ + +#ifdef __TURBOC__ +#ifdef __STDC__ +#error "MK_FP is incompatible with ANSI mode. Use the `-A-' switch." +#endif + +#include /* Includes the declaration of int86 */ +#include /* for getch */ + +#define reg_ax regs.x.ax +#define int86( a, b, c ) int86( a, b, c ) + +#endif + +/* ---- Phar Lap 286|DOS extender support -------------------------------- */ + +#ifdef DOSX286 +/* The symbol DOSX286 must be specified on the command line. */ + +#include +#endif + +/* ---- EMX/Dos compiler support ----------------------------------------- */ + +#ifdef __EMX__ + +#include +#include +#include /* for getch */ + extern _read_kbd(); /* to avoid an ANSI warning during compilation */ + +#define int86 _int86 +#define reg_ax regs.x.ax + +#endif + +/* ---- WATCOM Dos/16 & Dos/32 support ----------------------------------- */ + +#ifdef __WATCOMC__ + +#include + +#define reg_ax regs.w.ax + +#ifdef __386__ +#define int86 int386 +#endif + +#endif + + +#if !defined( reg_ax ) || !defined( int86 ) +#error "Your compiler is not (yet) supported. Check the source file!" +#endif + + + typedef struct _Translator + { + char key; + GEvent event_class; + int event_info; + } Translator; + +#define NUM_Translators 20 + + static const Translator trans[NUM_Translators] = + { + { (char)27, event_Quit, 0 }, + { 'q', event_Quit, 0 }, + + { 'x', event_Rotate_Glyph, -1 }, + { 'c', event_Rotate_Glyph, 1 }, + { 'v', event_Rotate_Glyph, -16 }, + { 'b', event_Rotate_Glyph, 16 }, + + { '{', event_Change_Glyph, -10000 }, + { '}', event_Change_Glyph, 10000 }, + { '(', event_Change_Glyph, -1000 }, + { ')', event_Change_Glyph, 1000 }, + { '9', event_Change_Glyph, -100 }, + { '0', event_Change_Glyph, 100 }, + { 'i', event_Change_Glyph, -10 }, + { 'o', event_Change_Glyph, 10 }, + { 'k', event_Change_Glyph, -1 }, + { 'l', event_Change_Glyph, 1 }, + + { '+', event_Scale_Glyph, 10 }, + { '-', event_Scale_Glyph, -10 }, + { 'u', event_Scale_Glyph, 1 }, + { 'j', event_Scale_Glyph, -1 } + }; + + + /* Set Graphics Mode */ + + int Driver_Set_Graphics( int mode ) + { + union REGS regs; + + + switch ( mode ) + { + case Graphics_Mode_Mono: /* Standard VGA 640x480x16 mode */ + reg_ax = 0x12; + int86( 0x10, ®s, ®s ); + + vio_ScanLineWidth = 80; + vio_Width = 640; + vio_Height = 480; + break; + + case Graphics_Mode_Gray: /* Standard VGA 320x200x256 mode */ + reg_ax = 0x13; + int86( 0x10, ®s, ®s ); + + vio_ScanLineWidth = 320; + vio_Width = 320; + vio_Height = 200; + + /* default gray_palette takes the gray levels of the standard VGA */ + /* 256 colors mode */ + + gray_palette[0] = 0; + gray_palette[1] = 23; + gray_palette[2] = 27; + gray_palette[3] = 29; + gray_palette[4] = 31; + break; + + default: + return 0; /* failure */ + } + +#if defined( __EMX__ ) + Vio = _memaccess( 0xA0000, 0xAFFFF, 1 ); +#elif defined( DJGPP1 ) || defined( DJGPP2 ) + Vio = (char *)0xA0000; +#elif defined( __WATCOMC__ ) && defined( __386__ ) + Vio = (char *)0xA0000; +#elif defined( DOSX286 ) + { + unsigned short sel; + + + if ( DosMapRealSeg( 0xA000, (long)vio_ScanLineWidth*vio_Height, &sel ) ) + return 0; /* failure */ + + Vio = (char*)MK_FP( sel, 0 ); + } +#else + Vio = (char*)MK_FP( 0xA000, 0 ); +#endif + + return 1; /* success */ + } + + + /* Revert to text mode */ + + int Driver_Restore_Mode() + { + union REGS regs; + + + reg_ax = 0x3; + int86( 0x10, ®s, ®s ); + +#ifdef DOSX286 + +#ifndef FP_SEG +#define FP_SEG(fp) (*((unsigned __far *)&(fp) + 1)) +#endif + + DosFreeSeg( FP_SEG( Vio ) ); +#endif + + return 1; /* success */ + } + + + int Driver_Display_Bitmap( char* buffer, int line, int col ) + { + int y, used_col; + char* target; + + +#ifdef DJGPP2 + char cbuf = 0; + int i; + for( i = 0; i < vio_Height*vio_ScanLineWidth; i++ ) + dosmemput( &cbuf, 1, (unsigned long) Vio+i ); +#else + +#ifdef DJGPP1 + __djgpp_nearptr_enable(); + Vio += __djgpp_conventional_base; + +#else + + memset( Vio, 0, vio_Height * vio_ScanLineWidth ); + +#endif /* DJGPP1 */ + +#endif /* DJGPP2 */ + + if ( line > vio_Height ) + line = vio_Height; + if ( col > vio_ScanLineWidth ) + used_col = vio_ScanLineWidth; + else + used_col = col; + + target = Vio + ( line - 1 ) * vio_ScanLineWidth; + + for ( y = 0; y < line; y++ ) + { +#ifdef DJGPP2 + dosmemput( buffer, used_col, (unsigned long)target ); +#else + memcpy( target, buffer, used_col ); +#endif + target -= vio_ScanLineWidth; + buffer += col; + } + +#ifdef DJGPP1 + __djgpp_nearptr_disable(); + Vio -= __djgpp_conventional_base; +#endif + + return 1; /* success */ + } + + + void Get_Event( TEvent* event ) + { + int i; + char c; + + + c = getch(); + + for ( i = 0; i < NUM_Translators; i++ ) + { + if ( c == trans[i].key ) + { + event->what = trans[i].event_class; + event->info = trans[i].event_info; + return; + } + } + + /* unrecognized keystroke */ + + event->what = event_Keyboard; + event->info = (int)c; + return; + } + + +/* End */ diff --git a/test/arch/msdos/makedep b/test/arch/msdos/makedep new file mode 100644 index 0000000..a5ace5a --- /dev/null +++ b/test/arch/msdos/makedep @@ -0,0 +1,22 @@ +# makedep +# +# This shell script creates a dependency file necessary for older compilers +# on the MS-DOS platform. + +echo "\ +# This dependency file to be used with various MS-DOS compilers +# has been generated automatically with the script \`makedep' on +# `date +%d-%b-%Y`. +" > depend.dos + +(cd ../.. + gcc -MM -I../lib/arch/msdos -I../lib -I../lib/extend -I. *.c | \ + sed -e "s/\.o:/.obj:/" -e "s:/:\\\\:g") >> depend.dos + +(cd ../.. + gcc -MM -I../lib/arch/win16 -I../lib -I../lib/extend -I. \ + -Dreg_ax -Dint86 arch/msdos/*.c | \ + sed -e "s/^\(.*\)\.o:/arch\\\\msdos\\\\\1.obj:/" \ + -e "s:/:\\\\:g") >> depend.dos + +# eof diff --git a/test/arch/msdos/time_tc.h b/test/arch/msdos/time_tc.h new file mode 100644 index 0000000..d28a7c2 --- /dev/null +++ b/test/arch/msdos/time_tc.h @@ -0,0 +1,124 @@ +/******************************************************************* + * + * time.h Replacement for buggy of old Turbo C compilers + * + * This file is a hack! It replaces when compiling with + * old versions of Borland Turbo C compilers that lack clock(), + * and provide its own version. + * + * Written by Antoine Leca + * Copyright 1999 Antoine Leca, David Turner, Robert Wilhelm + * and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#if !defined __TURBOC__ || !defined __MSDOS__ || __TURBOC__>0x200 +/* + * We are not running on a Borland compiler, or either on + * a recent version that does not need the hack. + * Certainly the user does not clean up the directory. + * Stop the compilation. + */ +#error Remove the file time.h in directory test + +#endif + +#ifndef _TIME_H_DEFINED +#define _TIME_H_DEFINED + +#if defined _TM_DEFINED || defined _TIME_T +#error Another version of seems to have been already included +#endif + +#ifndef __TIME_T +#define __TIME_T +typedef long time_t; +#endif + +#ifndef __CLOCK_T +#define __CLOCK_T +typedef long clock_t; +#define CLK_TCK 18.2 +#endif + +#define CLOCKS_PER_SEC CLK_TCK + +struct tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; +}; + + +clock_t clock (void); +double difftime(time_t time2, time_t time1); +time_t time (time_t *timer); + +char *asctime (const struct tm *tblock); +char *ctime (const time_t *time); +struct tm *gmtime (const time_t *timer); +struct tm *localtime(const time_t *timer); + + +#if __TURBOC__ <= 0x0150 + +/******************************************************************* + * + * Function : clock + * + * Description : Turbo C v.1.x lacks the clock() function that is + * needed for at least fttimer. + * So this is a replacement that does more or less + * the functionnality of clock(), using the BIOS. + * Since we do not know exactly when the process + * started (as clock() is supposed to do), we cheat + * a little here. + * + * Input : None + * + * Output : None + * + * Notes : Use two static objects. + * NEED_CLOCK_HERE is a macro that should be defined + * in only ONE module (otherwise, the linker will complain). + * + ******************************************************************/ + +extern long biostime(int cmd, long newtime); + +static long CountOfTicks; +static long DateOfReference = 0; + +clock_t clock (void) +{ + + if (DateOfReference == 0) /* this is the first call */ + { + DateOfReference = time(NULL) / 86400L; + CountOfTicks = biostime(0,0L) - CLOCKS_PER_SEC; + /* pretend we start one second ago */ + return CLOCKS_PER_SEC; /* to avoid returning 0 */ + } + + return (time(NULL) / 86400L - DateOfReference) * 0x1800B0L + + biostime(0,0L) - CountOfTicks; +} + +#endif /* Turbo C v.1.x */ + +#endif /* defined __TIME_H_DEFINED */ + + +/* End */ diff --git a/test/arch/os2/Makefile.dm b/test/arch/os2/Makefile.dm new file mode 100644 index 0000000..c770086 --- /dev/null +++ b/test/arch/os2/Makefile.dm @@ -0,0 +1,143 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for emx-gcc under OS/2 +# +# You will need dmake. +# +# Use this file while in the 'test' directory with the following statement: +# +# dmake -r -f arch/os2/Makefile.dm + +ARCH = arch/os2 +FT_MAKEFILE = $(ARCH)/Makefile.dm +FT_MAKE = dmake -r + +.IMPORT: COMSPEC +SHELL := $(COMSPEC) +SHELLFLAGS := /c +GROUPSHELL := $(SHELL) +GROUPFLAGS := $(SHELLFLAGS) +GROUPSUFFIX := .cmd +SHELLMETAS := *"?<>&| + +CC = gcc + +LIBDIR = ../lib +LIBDIR_OS2 = $(subst,/,\ $(LIBDIR)) +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)/$(ARCH) -I. -I$(LIBDIR)/extend + +# CFLAGS = -Wall -ansi -O2 -g $(INCDIRS) +CFLAGS = -ansi -Wall -O2 -s -Zcrtdll $(INCDIRS) + +# full-screen MSDOS driver +GFSDRIVER = $(ARCH)/gfs_os2.c +GPMDRIVER = $(ARCH)/gpm_os2.c +GPM_DEF = $(ARCH)/gpm_os2.def + +DISPLAY = display.c + +SRC = ftlint.c fttimer.c ftview.c ftzoom.c ftdump.c ftstring.c ftstrpnm.c \ + ftsbit.c common.c blitter.c ftmetric.c ftstrtto.c arabic.c + +GSRC = gmain.c display.c blitter.c +GFSSRC = $(GSRC) $(GFSDRIVER) +GPMSRC = $(GSRC) $(GPMDRIVER) + +GFSOBJ = $(GFSSRC:.c=.o) +GPMOBJ = $(GPMSRC:.c=.o) + +ALLSRC = $(SRC) $(GSRC) $(GFSDRIVER) $(GPMDRIVER) +ALLOBJ = $(ALLSRC:.c=.o) + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +%.exe: + $(CC) $(CFLAGS) -o $@ @$(mktmp $(&:t"\n")\n) + + +EXEFILES = ftview.exe ftviewfs.exe \ + ftlint.exe \ + fttimer.exe fttimefs.exe \ + ftdump.exe \ + ftstring.exe ftstrfs.exe \ + ftzoom.exe ftzoomfs.exe \ + ftstrpnm.exe \ + ftsbit.exe \ + ftmetric.exe \ + ftstrtto.exe ftstrtfs.exe + +.PHONY: all debug freetype freetype_debug \ + clean distclean do_clean do_distclean depend + + +all: freetype $(EXEFILES) + +debug: freetype_debug $(EXEFILES) + + +freetype: +[ + cd $(LIBDIR_OS2) + $(FT_MAKE) -f $(FT_MAKEFILE) all + cd $(MAKEDIR) +] + +freetype_debug: +[ + cd $(LIBDIR_OS2) + $(FT_MAKE) -f $(FT_MAKEFILE) debug + cd $(MAKEDIR) +] + +ftzoom.exe: $(GPMOBJ) ftzoom.o common.o $(LIBDIR)/libttf.a $(GPM_DEF) +ftzoomfs.exe: $(GFSOBJ) ftzoom.o common.o $(LIBDIR)/libttf.a +ftview.exe: $(GPMOBJ) ftview.o common.o $(LIBDIR)/libttf.a $(GPM_DEF) +ftviewfs.exe: $(GFSOBJ) ftview.o common.o $(LIBDIR)/libttf.a +ftlint.exe: ftlint.o common.o $(LIBDIR)/libttf.a +ftdump.exe: ftdump.o common.o $(LIBDIR)/libttf.a +ftstring.exe: $(GPMOBJ) ftstring.o common.o $(LIBDIR)/libttf.a $(GPM_DEF) +ftstrfs.exe: $(GFSOBJ) ftstring.o common.o $(LIBDIR)/libttf.a +ftstrpnm.exe: ftstrpnm.o common.o $(LIBDIR)/libttf.a +fttimer.exe: $(GPMOBJ) fttimer.o common.o $(LIBDIR)/libttf.a $(GPM_DEF) +fttimefs.exe: $(GFSOBJ) fttimer.o common.o $(LIBDIR)/libttf.a +ftsbit.exe: ftsbit.o common.o $(LIBDIR)/libttf.a +ftmetric.exe: ftmetric.o common.o $(LIBDIR)/libttf.a +ftstrtto.exe: $(GPMOBJ) ftstrtto.o common.o arabic.o \ + $(LIBDIR)/libttf.a $(GPM_DEF) +ftstrtfs.exe: $(GFSOBJ) ftstrtto.o common.o arabic.o $(LIBDIR)/libttf.a + + +clean: do_clean +[ + cd $(LIBDIR_OS2) + $(FT_MAKE) -f $(FT_MAKEFILE) clean + cd $(MAKEDIR) +] + +distclean: do_clean do_distclean +[ + cd $(LIBDIR_OS2) + $(FT_MAKE) -f $(FT_MAKEFILE) distclean + cd $(MAKEDIR) +] + +do_distclean: + -+del dep.end $(EXEFILES) core + +do_clean: + -+del $(subst,/,\ $(ALLOBJ)) + +# depend: $(ALLSRC) +#[ +# cd $(LIBDIR_OS2) +# $(FT_MAKE) -f $(FT_MAKEFILE) depend +# cd $(MAKEDIR) +# $(CC) -E -M $(INCDIRS) @$(mktmp $(<:t"\n")\n) > dep.end +#] +# +# ifeq (dep.end,$(wildcard dep.end)) +# include dep.end +# endif + +# end of Makefile.dm diff --git a/test/arch/os2/Makefile.emx b/test/arch/os2/Makefile.emx new file mode 100644 index 0000000..b0b4c5b --- /dev/null +++ b/test/arch/os2/Makefile.emx @@ -0,0 +1,108 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for emx-gcc under OS/2. +# +# You will need GNU make. +# +# Use this file while in the 'test' directory with the following statement: +# +# make -f arch/os2/Makefile.emx + +ARCH = arch/os2 +FT_MAKEFILE = $(ARCH)/Makefile.emx + +CC = gcc + +LIBDIR = ../lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)/extend -I$(LIBDIR)/$(ARCH) -I. + +CFLAGS = -Wall -ansi -O0 -g $(INCDIRS) +# CFLAGS = -ansi -Wall -O2 -s -Zcrtdll $(INCDIRS) + +GFSDRIVER = $(ARCH)/gfs_os2.c +GPMDRIVER = $(ARCH)/gpm_os2.c +GPM_DEF = $(ARCH)/gpm_os2.def + +SRC = fttimer.c ftview.c ftlint.c ftzoom.c ftdump.c ftstring.c ftstrpnm.c \ + ftsbit.c common.c blitter.c ftmetric.c ftstrtto.c arabic.c + +GSRC = gmain.c display.c blitter.c +GFSSRC = $(GSRC) $(GFSDRIVER) +GPMSRC = $(GSRC) $(GPMDRIVER) +GFSOBJ = $(GFSSRC:.c=.o) +GPMOBJ = $(GPMSRC:.c=.o) + +ALLSRC = $(SRC) $(GSRC) $(GFSDRIVER) $(GPMDRIVER) +ALLOBJ = $(ALLSRC:.c=.o) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +%.exe: + $(CC) $(CFLAGS) -o $@ $^ + + +EXEFILES = ftview.exe ftviewfs.exe \ + fttimer.exe fttimefs.exe \ + ftlint.exe \ + ftstring.exe ftstrfs.exe \ + ftstrpnm.exe \ + ftzoom.exe ftzoomfs.exe \ + ftsbit.exe \ + ftdump.exe \ + ftmetric.exe \ + ftstrtto.exe ftstrtfs.exe + +.PHONY: all debug freetype freetype_debug \ + clean distclean do_clean depend + + +all: freetype $(EXEFILES) + +debug: freetype_debug $(EXEFILES) + +freetype: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) all + +freetype_debug: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) debug + +ftzoom.exe: $(GPMOBJ) ftzoom.o common.o $(LIBDIR)/libttf.a $(GPM_DEF) +ftzoomfs.exe: $(GFSOBJ) ftzoom.o common.o $(LIBDIR)/libttf.a +ftview.exe: $(GPMOBJ) ftview.o common.o $(LIBDIR)/libttf.a $(GPM_DEF) +ftviewfs.exe: $(GFSOBJ) ftview.o common.o $(LIBDIR)/libttf.a +ftlint.exe: ftlint.o common.o $(LIBDIR)/libttf.a +ftdump.exe: ftdump.o common.o $(LIBDIR)/libttf.a +ftstring.exe: $(GPMOBJ) ftstring.o common.o $(LIBDIR)/libttf.a $(GPM_DEF) +ftstrfs.exe: $(GFSOBJ) ftstring.o common.o $(LIBDIR)/libttf.a +ftstrpnm.exe: ftstrpnm.o common.o $(LIBDIR)/libttf.a +fttimer.exe: $(GPMOBJ) fttimer.o common.o $(LIBDIR)/libttf.a $(GPM_DEF) +fttimefs.exe: $(GFSOBJ) fttimer.o common.o $(LIBDIR)/libttf.a +ftsbit.exe: ftsbit.o common.o $(LIBDIR)/libttf.a +ftmetric.exe: ftmetric.o common.o $(LIBDIR)/libttf.a +ftstrtto.exe: $(GPMOBJ) ftstrtto.o common.o arabic.o \ + $(LIBDIR)/libttf.a $(GPM_DEF) +ftstrtfs.exe: $(GFSOBJ) ftstrtto.o common.o arabic.o $(LIBDIR)/libttf.a + + +clean: do_clean + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) clean + +distclean: do_clean + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) distclean + -del dep.end $(EXEFILES) core + +do_clean: + -del $(subst /,\,$(ALLOBJ)) + + +depend: $(ALLSRC) + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) depend + $(CC) -E -M $(INCDIRS) $^ > dep.end + +ifeq (dep.end,$(wildcard dep.end)) + include dep.end +endif + +# end of Makefile.emx diff --git a/test/arch/os2/Makefile.icc b/test/arch/os2/Makefile.icc new file mode 100644 index 0000000..4bd3817 --- /dev/null +++ b/test/arch/os2/Makefile.icc @@ -0,0 +1,145 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for IBM VisualAge C++ under OS/2. +# +# You will need nmake. +# +# Use this file while in the 'test' directory with the following statement: +# +# nmake -f arch\os2\Makefile.icc + +ARCH = arch\os2 +FT_MAKEFILE = $(ARCH)\Makefile.icc +FT_MAKE = $(MAKE) -nologo + +CC = icc + +LIBDIR = ..\lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)\extend -I$(LIBDIR)\$(ARCH) -I. +CFLAGS = -O+ -Gd+ -Gn+ -Gl+ -Ti- -Tm- -Q+ -Wpro- -Wcnd- $(INCDIRS) + +# Fullscreen OS/2 driver +GFSDRIVER_SRC = $(ARCH)\gfs_os2.c +GFSDRIVER = $(ARCH)\gfs_os2.obj + +# PM OS/2 Driver +GPMDRIVER = $(ARCH)\gpm_os2.obj +GPMDRIVER_SRC = $(ARCH)\gpm_os2.c +GPM_DEF = $(ARCH)\gpm_os2.def + +SRC = gmain.c display.c common.c arabic.c \ + ftzoom.c ftview.c fttimer.c ftlint.c ftdump.c ftstring.c \ + ftstrpnm.c ftsbit.c ftmetric.c ftstrtto.c \ + $(GFSDRIVER_SRC) + +COMMON = common.obj +GFSOBJS = gmain.obj display.obj $(GFSDRIVER) $(COMMON) blitter.obj +GPMOBJS = gmain.obj display.obj $(GPMDRIVER) $(COMMON) blitter.obj +OBJ1 = ftzoom.obj +OBJ2 = fttimer.obj +OBJ3 = ftview.obj +OBJ4 = ftlint.obj +OBJ5 = ftdump.obj +OBJ6 = ftstring.obj +OBJ7 = ftstrpnm.obj +OBJ8 = ftsbit.obj +OBJ9 = ftmetric.obj +OBJ10 = ftstrtto.obj + + +EXEFILES = fttimefs.exe fttimer.exe \ + ftzoom.exe ftzoomfs.exe \ + ftviewfs.exe ftview.exe \ + ftlint.exe \ + ftdump.exe \ + ftstring.exe ftstrfs.exe \ + ftstrpnm.exe \ + ftsbit.exe \ + ftmetric.exe \ + ftstrtto.exe ftstrtfs.exe + + +all: freetype $(EXEFILES) + +debug: freetype_debug $(EXEFILES) + + +freetype: + cd $(LIBDIR) + $(FT_MAKE) -f $(FT_MAKEFILE) all + cd ..\test + +freetype_debug: + cd $(LIBDIR) + $(FT_MAKE) -f $(FT_MAKEFILE) debug + cd ..\test + +$(GFSDRIVER): $(GFSDRIVER_SRC) + $(CC) $(CFLAGS) /c /Fo$@ $** -I. + +$(GPMDRIVER): $(GPMDRIVER_SRC) + $(CC) $(CFLAGS) /c /Fo$@ $** -I. + +ftzoomfs.exe: $(GFSOBJS) $(OBJ1) $(LIBDIR)\libttf.lib + $(CC) $(CFLAGS) /Fe$@ $** + +ftzoom.exe: $(GPMOBJS) $(OBJ1) $(LIBDIR)\libttf.lib + $(CC) $(CFLAGS) $(GPM_DEF) /Fe$@ $** + +fttimefs.exe: $(GFSOBJS) $(OBJ2) $(LIBDIR)\libttf.lib + $(CC) $(CFLAGS) /Fe$@ $** + +fttimer.exe: $(GPMOBJS) $(OBJ2) $(LIBDIR)\libttf.lib + $(CC) $(CFLAGS) $(GPM_DEF) /Fe$@ $** + +ftviewfs.exe: $(GFSOBJS) $(OBJ3) $(LIBDIR)\libttf.lib + $(CC) $(CFLAGS) /Fe$@ $** + +ftview.exe: $(GPMOBJS) $(OBJ3) $(LIBDIR)\libttf.lib + $(CC) $(CFLAGS) $(GPM_DEF) /Fe$@ $** + +ftlint.exe: $(OBJ4) $(LIBDIR)\libttf.lib $(COMMON) + $(CC) $(CFLAGS) /Fe$@ $** + +ftdump.exe: $(OBJ5) $(LIBDIR)\libttf.lib $(COMMON) + $(CC) $(CFLAGS) /Fe$@ $** + +ftstrfs.exe: $(GFSOBJS) $(OBJ6) $(LIBDIR)\libttf.lib + $(CC) $(CFLAGS) /Fe$@ $** + +ftstring.exe: $(GPMOBJS) $(OBJ6) $(LIBDIR)\libttf.lib + $(CC) $(CFLAGS) $(GPM_DEF) /Fe$@ $** + +ftstrpnm.exe: $(OBJ7) $(LIBDIR)\libttf.lib $(COMMON) + $(CC) $(CFLAGS) /Fe$@ $** + +ftsbit.exe: $(OBJ8) $(LIBDIR)\libttf.lib $(COMMON) + $(CC) $(CFLAGS) /Fe$@ $** + +ftmetric.exe: $(OBJ9) $(LIBDIR)\libttf.lib $(COMMON) + $(CC) $(CFLAGS) /Fe$@ $** + +ftstrtfs.exe: $(GFSOBJS) $(OBJ10) $(LIBDIR)\libttf.lib + $(CC) $(CFLAGS) /Fe$@ $** + +ftstrtto.exe: $(GPMOBJS) $(OBJ10) arabic.obj $(LIBDIR)\libttf.lib + $(CC) $(CFLAGS) $(GPM_DEF) /Fe$@ $** + + +clean: do_clean + cd $(LIBDIR) + $(FT_MAKE) -f $(FT_MAKEFILE) clean + cd ..\test + +distclean: do_clean + cd $(LIBDIR) + $(FT_MAKE) -f $(FT_MAKEFILE) distclean + cd ..\test + -del *.exe + +do_clean: + -del *.obj + -del $(GFSDRIVER) + -del $(GPMDRIVER) + +# end of Makefile.icc diff --git a/test/arch/os2/Makefile.wat b/test/arch/os2/Makefile.wat new file mode 100644 index 0000000..e8df0af --- /dev/null +++ b/test/arch/os2/Makefile.wat @@ -0,0 +1,155 @@ +# This file is part of the FreeType project +# +# This builds the test programs with the Watcom compiler +# +# You'll need Watcom's wmake +# +# Invoke by "wmake -f arch\os2\Makefile.wat" when in the "test" directory + +ARCH = arch\os2 +FT_MAKEFILE = $(ARCH)\Makefile.wat +FT_MAKE = wmake -h + +.EXTENSIONS: +.EXTENSIONS: .exe .obj .c .h +.obj:. +.c:. +.h:.;..\lib + +CC = wcl386 + +LIBDIR = ..\lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)\$(ARCH) -I$(LIBDIR)\extend +LIBFILE = $(LIBDIR)\libttf.lib + +LINK_OPTS = + +OBJ_CFLAGS = /c /otexanl+ /s /w4 /zq $(INCDIRS) + +CCFLAGS = /otexanl+ /s /w4 /zq $(INCDIRS) + +GFSDRIVER = $(ARCH)\gfs_os2.obj +GFSDRIVER_SRC = $(ARCH)\gfs_os2.c + +GPMDRIVER = $(ARCH)\gpm_os2.obj +GPMDRIVER_SRC = $(ARCH)\gpm_os2.c +GPMDRIVER_DEF = $(ARCH)\gpm_os2.def + +SRC = gmain.c display.c blitter.c & + fttimer.c ftview.c ftlint.c ftzoom.c ftdump.c ftstring.c & + ftstrpnm.c ftsbit.c ftmetric.c ftstrtto.c & + $(GPMDRIVER_SRC) $(GFSDRIVER_SRC) + +GFSOBJ = gmain.obj $(GFSDRIVER) blitter.obj display.obj +GPMOBJ = gmain.obj $(GPMDRIVER) blitter.obj display.obj + +PM = $(LIBFILE) $(GPMOBJ) common.obj +FS = $(LIBFILE) $(GFSOBJ) common.obj + + +# graphics utility and test driver + +EXEFILES = ftview.exe ftviewfs.exe & + fttimer.exe fttimefs.exe & + ftlint.exe & + ftdump.exe & + ftstring.exe ftstrfs.exe & + ftzoom.exe ftzoomfs.exe & + ftstrpnm.exe & + ftsbit.exe & + ftmetric.exe & + ftstrtto.exe ftstrtfs.exe + + +all: freetype $(EXEFILES) + +debug: freetype_debug $(EXEFILES) + + +freetype: .symbolic + cd ..\lib + $(FT_MAKE) -f $(FT_MAKEFILE) all + cd ..\test + +freetype_debug: .symbolic + cd ..\lib + $(FT_MAKE) -f $(FT_MAKEFILE) debug + cd ..\test + +# implicit rules +# +.c.obj : + $(CC) $(OBJ_CFLAGS) $[* /fo=$[*.obj + + +# the full-screen graphics driver +# +$(GFSDRIVER): $(GFSDRIVER_SRC) + $(CC) $(OBJ_CFLAGS) $[*.c /fo=$[*.obj + +# the pm graphics driver +# +$(GPMDRIVER): $(GPMDRIVER_SRC) + $(CC) $(OBJ_CFLAGS) $[*.c /fo=$[*.obj + +ftzoom.exe : ftzoom.obj $(LIBFILE) $(PM) $(GPMDRIVER_DEF) + $(CC) $(CCFLAGS) -l=os2v2_pm $(PM) $[*.c /fe=$[*.exe + +ftzoomfs.exe : ftzoom.obj $(LIBFILE) $(FS) + $(CC) $(CCFLAGS) $(FS) $[@ /fe=ftzoomfs.exe + +ftview.exe : ftview.obj $(LIBFILE) $(PM) $(GPMDRIVER_DEF) + $(CC) $(CCFLAGS) -l=os2v2_pm $(PM) $[*.c /fe=$[*.exe + +ftviewfs.exe : ftview.obj $(LIBFILE) $(FS) + $(CC) $(CCFLAGS) $(FS) $[*.c /fe=ftviewfs.exe + +ftstring.exe : ftstring.obj $(LIBFILE) $(PM) $(GPMDRIVER_DEF) + $(CC) $(CCFLAGS) -l=os2v2_pm $(PM) $[*.c /fe=$[*.exe + +ftstrfs.exe : ftstring.obj $(LIBFILE) $(FS) + $(CC) $(CCFLAGS) $(FS) $[*.c /fe=ftstrfs.exe + +fttimer.exe: fttimer.obj $(LIBFILE) $(PM) $(GPMDRIVER_DEF) + $(CC) $(CCFLAGS) -l=os2v2_pm $(PM) $[*.c /fe=$[*.exe + +fttimefs.exe: fttimer.obj $(LIBFILE) $(FS) + $(CC) $(CCFLAGS) $(FS) $[*.c /fe=fttimefs.exe + +ftlint.exe: ftlint.obj $(LIBFILE) + $(CC) $(CCFLAGS) $(LIBFILE) common.obj $[*.c /fe=$[*.exe + +ftdump.exe: ftdump.obj $(LIBFILE) + $(CC) $(CCFLAGS) $(LIBFILE) common.obj $[*.c /fe=$[*.exe + +ftstrpnm.exe: ftstrpnm.obj $(LIBFILE) + $(CC) $(CCFLAGS) $(LIBFILE) common.obj $[*.c /fe=$[*.exe + +ftsbit.exe: ftsbit.obj $(LIBFILE) + $(CC) $(CCFLAGS) $(LIBFILE) common.obj $[*.c /fe=$[*.exe + +ftmetric.exe: ftmetric.obj $(LIBFILE) + $(CC) $(CCFLAGS) $(LIBFILE) common.obj $[*.c /fe=$[*.exe + +ftstrtto.exe : ftstrtto.obj arabic.obj $(LIBFILE) $(PM) $(GPMDRIVER_DEF) + $(CC) $(CCFLAGS) -l=os2v2_pm $(PM) $[*.c /fe=$[*.exe + +ftstrtfs.exe : ftstrtto.obj arabic.obj $(LIBFILE) $(FS) + $(CC) $(CCFLAGS) $(FS) $[*.c /fe=ftstrtfs.exe + + +clean: .symbolic + @-erase *.obj + @-erase $(ARCH)\*.obj + +distclean: .symbolic clean + @-erase *.exe + @-erase *.err + cd ..\lib + $(FT_MAKE) -f $(FT_MAKEFILE) distclean + cd ..\test + +new: .symbolic + @-wtouch *.c + +# end of Makefile.wat diff --git a/test/arch/os2/gfs_os2.c b/test/arch/os2/gfs_os2.c new file mode 100644 index 0000000..0ecd5a5 --- /dev/null +++ b/test/arch/os2/gfs_os2.c @@ -0,0 +1,219 @@ +/******************************************************************* + * + * gfs_os2.c graphics utility fullscreen OS/2 driver. 1.0 + * + * This is the driver for fullscreen OS/2 display, used by the + * graphics utility of the FreeType test suite. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include +#include +#include + +#define INCL_SUB +#include + +#ifdef __EMX__ +#include +#endif + +#if defined(__EMX__)||defined(__IBMC__) +#include /* for getch */ + extern _read_kbd(); /* to avoid an ANSI warning during compilation */ +#endif + +#include "gdriver.h" +#include "gevents.h" +#include "gmain.h" + + + typedef struct _Translator + { + char key; + GEvent event_class; + int event_info; + } Translator; + +#define NUM_Translators 20 + + static const Translator trans[NUM_Translators] = + { + { (char)27, event_Quit, 0 }, + { 'q', event_Quit, 0 }, + + { 'x', event_Rotate_Glyph, -1 }, + { 'c', event_Rotate_Glyph, 1 }, + { 'v', event_Rotate_Glyph, -16 }, + { 'b', event_Rotate_Glyph, 16 }, + + { '{', event_Change_Glyph, -10000 }, + { '}', event_Change_Glyph, 10000 }, + { '(', event_Change_Glyph, -1000 }, + { ')', event_Change_Glyph, 1000 }, + { '9', event_Change_Glyph, -100 }, + { '0', event_Change_Glyph, 100 }, + { 'i', event_Change_Glyph, -10 }, + { 'o', event_Change_Glyph, 10 }, + { 'k', event_Change_Glyph, -1 }, + { 'l', event_Change_Glyph, 1 }, + + { '+', event_Scale_Glyph, 10 }, + { '-', event_Scale_Glyph, -10 }, + { 'u', event_Scale_Glyph, 1 }, + { 'j', event_Scale_Glyph, -1 } + }; + + + static VIOMODEINFO OrgMode; + static long VioBufOfs; + + + /* BIOS video modes */ + + static VIOMODEINFO VioMode_640x480x16 = + { + sizeof ( VIOMODEINFO ), + VGMT_OTHER + VGMT_GRAPHICS, + COLORS_16, + 80, + 35, + 640, + 480 + }; + + static VIOMODEINFO VioMode_320x200x256 = + { + sizeof ( VIOMODEINFO ), + VGMT_OTHER + VGMT_GRAPHICS, + 8, + 40, + 25, + 320, + 200 + }; + + static VIOPHYSBUF VioBuf = + { + (void*)0xA0000L, + 64*1024 + }; + + + /* Restores screen to its original state */ + + int Driver_Restore_Mode() + { + VioSetMode( &OrgMode, 0 ); + return 1; + } + + + /* Sets graphics mode */ + + int Driver_Set_Graphics( int mode ) + { + int rc; + + + OrgMode.cb = sizeof ( VIOMODEINFO ); + VioGetMode( &OrgMode, 0 ); + + switch ( mode ) + { + case Graphics_Mode_Mono: + rc = VioSetMode( &VioMode_640x480x16, 0 ); + vio_ScanLineWidth = 80; + vio_Width = 640; + vio_Height = 480; + break; + + case Graphics_Mode_Gray: + rc = VioSetMode( &VioMode_320x200x256, 0 ); + vio_ScanLineWidth = 320; + vio_Width = 320; + vio_Height = 200; + + /* default gray_palette takes the gray levels of the standard VGA */ + /* 256 colors mode */ + + gray_palette[0] = 0; + gray_palette[1] = 23; + gray_palette[2] = 27; + gray_palette[3] = 29; + gray_palette[4] = 31; + break; + + default: + rc = -1; + break; + } + + if ( rc ) return 0; /* failure */ + + if ( VioGetPhysBuf( &VioBuf, 0 ) ) return 0; /* Could not access VRAM */ + + VioBufOfs = (long)MAKEP( VioBuf.asel[0], 0 ); + + memset( (void*)VioBufOfs, 0, 64 * 1024 ); + + Vio = (char*)VioBufOfs; + + return 1; /* success */ + } + + + int Driver_Display_Bitmap( char* buffer, int line, int col ) + { + int y; + char* target; + + target = Vio + ( line - 1 ) * vio_ScanLineWidth; + + for ( y = 0; y < line; y++ ) + { + memcpy( target, buffer, col ); + target -= vio_ScanLineWidth; + buffer += col; + } + + return 1; /* success */ + } + + + void Get_Event( TEvent* event ) + { + int i; + char c; + + + c = getch(); + + for ( i = 0; i < NUM_Translators; i++ ) + { + if ( c == trans[i].key ) + { + event->what = trans[i].event_class; + event->info = trans[i].event_info; + return; + } + } + + /* unrecognized keystroke */ + + event->what = event_Keyboard; + event->info = (int)c; + return; + } + + +/* End */ diff --git a/test/arch/os2/gpm_os2.c b/test/arch/os2/gpm_os2.c new file mode 100644 index 0000000..22ed397 --- /dev/null +++ b/test/arch/os2/gpm_os2.c @@ -0,0 +1,654 @@ +/******************************************************************* + * + * gpm_os2.c graphics OS/2 Presentation Manager Window driver. 0.2 + * + * This is the driver for windowed OS/2 display, used by the + * graphics utility of the FreeType test suite. + * + * written by Eric Olson (eolson@imag.net) + * + * Borrowing liberally from the other FreeType drivers. + * Some bitmap manipulations are derived from fastgpi.c, + * a sample program written by Donald Graft (dgraft@gate.net). + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include +#include +#include + +#define INCL_DOS +#define INCL_WIN +#define INCL_GPI +#define INCL_SUB + +#include + +#include "gdriver.h" +#include "gevents.h" +#include "gmain.h" + + +#define VIO_WIDTH 640u /* these can be changed but VIO_WIDTH should remain */ +#define VIO_HEIGHT 360u /* for now a multiple of 32 to avoid padding issues */ +#define MAG_WIDTH VIO_WIDTH +#define MAG_HEIGHT 120u +#define MAX_MAG 16 /* should be less than Min(MAG_WIDTH, MAG_HEIGHT) */ + + + typedef struct _Translator + { + char key; + GEvent event_class; + int event_info; + } Translator; + +#define NUM_Translators 20 + + static const Translator trans[NUM_Translators] = + { + { (char)27, event_Quit, 0 }, + { 'q', event_Quit, 0 }, + + { 'x', event_Rotate_Glyph, -1 }, + { 'c', event_Rotate_Glyph, 1 }, + { 'v', event_Rotate_Glyph, -16 }, + { 'b', event_Rotate_Glyph, 16 }, + + { '{', event_Change_Glyph, -10000 }, + { '}', event_Change_Glyph, 10000 }, + { '(', event_Change_Glyph, -1000 }, + { ')', event_Change_Glyph, 1000 }, + { '9', event_Change_Glyph, -100 }, + { '0', event_Change_Glyph, 100 }, + { 'i', event_Change_Glyph, -10 }, + { 'o', event_Change_Glyph, 10 }, + { 'k', event_Change_Glyph, -1 }, + { 'l', event_Change_Glyph, 1 }, + + { '+', event_Scale_Glyph, 10 }, + { '-', event_Scale_Glyph, -10 }, + { 'u', event_Scale_Glyph, 1 }, + { 'j', event_Scale_Glyph, -1 } + }; + + + static HAB habt; + static HAB hab; + static HWND hwndFrame, hwndClient; + static HWND hwndTitle; + static HDC hdcMemory; + static HPS hpsMemory = (HPS) NULL; + + /* Threads and semaphores */ + TID MessageThread; + HMTX hmtxPSMemoryLock; + HEV hevKeyLock; + + /* Bitmap information */ + static PBITMAPINFO2 pbmi; + static HBITMAP hbm; + BYTE Bitmap[VIO_WIDTH * VIO_HEIGHT]; + BOOL ready = FALSE; + + /* Coordinates for the bitblt of whole graphic area */ + POINTL aptlFull[4] = {{ 0u, MAG_HEIGHT }, + { VIO_WIDTH, VIO_HEIGHT + MAG_HEIGHT }, + { 0u, 0u }, + { VIO_WIDTH, VIO_HEIGHT }}; + + /* Coordinates for the magnification bitblt */ + POINTL aptlMagd[4] = {{ 0u, 0u }, + { MAG_WIDTH, MAG_HEIGHT }, /* target */ + { 0u, 0u }, + { VIO_WIDTH, VIO_HEIGHT }}; /* source */ + + /* level of magnification and center of magnification window */ + static int magnification=1; + static POINTL view_target = {0, 0}; + static SIZEL mag_win_size; + + /* local event to pass on */ + TEvent ourevent = { event_Rotate_Glyph, 0 }; + + /* grayscale vs b/w mode */ + int Colourmode; + + /* array defined in the test programs */ + extern char Header[]; + + + void RunPMWindow( ULONG ); + MRESULT EXPENTRY Message_Process( HWND, ULONG, MPARAM, MPARAM ); + + + + /* restores screen to its original state */ + + int Driver_Restore_Mode() + { + /* PMWindow has probably already destroyed itself */ + if ( hwndFrame ) + WinDestroyWindow( hwndFrame ); + + WinReleasePS( hpsMemory ); + WinTerminate( habt ); + + return 1; + } + + + /* set graphics mode */ + + int Driver_Set_Graphics( int mode ) + { + LONG palette[5]; + int x; + POINTL coords; + SIZEL sizl = { 0, 0 }; + + PTIB thread_block; + PPIB process_block; + + /* XXX : This is a very nasty hack, it fools OS/2 and let the program */ + /* call PM functions, even though stdin/stdout/stderr are still */ + /* directed to the standard i/o streams.. */ + /* The program must be compiled with WINDOWCOMPAT */ + /* */ + /* Credits go to Michal for finding this !! */ + /* */ + DosGetInfoBlocks( &thread_block, &process_block ); + process_block->pib_ultype = 3; + + /* save mono vs grayscale status */ + Colourmode = mode; + + /* event semaphore to signal reraster event */ + DosCreateEventSem( NULL, &hevKeyLock, 0, TRUE ); + + /* mutex semaphore for access to the presentation space */ + DosCreateMutexSem( NULL, &hmtxPSMemoryLock, 0, FALSE ); + + /* Start thread with Presentation Manager window */ + DosCreateThread( &MessageThread, (PFNTHREAD)RunPMWindow, 0UL, 0UL, 32920 ); + + /* open anchor block to permit Gpi calls from this thread */ + habt = WinInitialize( 0 ); + + /* create device context and presentation space for our graphic */ + hdcMemory = DevOpenDC( hab, OD_MEMORY, (PSZ)"*", 0L, 0L, 0L ); + + DosRequestMutexSem( hmtxPSMemoryLock, SEM_INDEFINITE_WAIT ); + hpsMemory = GpiCreatePS( + habt, hdcMemory, &sizl, + PU_PELS | GPIT_MICRO | GPIA_ASSOC | GPIF_DEFAULT ); + GpiSetBackMix( hpsMemory, BM_OVERPAINT ); + + /* create bitmap for raster image of graphic */ + + /* find some memory for the bitmap header */ + DosAllocMem( (PPVOID)&pbmi, + sizeof ( BITMAPINFO2 ) + sizeof ( RGB2 ) * 256, + PAG_COMMIT | PAG_READ | PAG_WRITE); + /* 256 should really be 2 if not grayscale */ + + /* initialize the header to appropriate values */ + memset( pbmi, 0, sizeof ( BITMAPINFO2 ) + sizeof ( RGB2 ) * 256 ); + + pbmi->cbFix = sizeof ( BITMAPINFOHEADER2 ); + pbmi->cx = VIO_WIDTH; + pbmi->cy = VIO_HEIGHT; + pbmi->cPlanes = 1; + + switch ( mode ) + { + case Graphics_Mode_Mono: + pbmi->cBitCount = 1; + break; + + case Graphics_Mode_Gray: + pbmi->cBitCount = 8; + break; + } + + hbm = GpiCreateBitmap( hpsMemory, (PBITMAPINFOHEADER2)pbmi, + 0L, NULL, NULL ); + + /* associate it with the presentation space */ + GpiSetBitmap( hpsMemory, hbm ); + pbmi->cbFix = sizeof ( BITMAPINFOHEADER2 ); + GpiQueryBitmapInfoHeader( hbm, (PBITMAPINFOHEADER2) pbmi ); + + switch ( mode ) + { + case Graphics_Mode_Mono: + DosReleaseMutexSem( hmtxPSMemoryLock ); + + vio_ScanLineWidth = VIO_WIDTH / 8; + vio_Width = VIO_WIDTH; + vio_Height = VIO_HEIGHT; + + gray_palette[0] = 0; /* to avoid testing for grayscale... */ + break; + + case Graphics_Mode_Gray: + vio_ScanLineWidth = VIO_WIDTH; + vio_Width = VIO_WIDTH; + vio_Height = VIO_HEIGHT; + + /* set gray_palette by convoluted procedure */ + + /* create logical color palette */ + palette[0] = 0xffffffL; /* White */ + palette[1] = 0xbbbbbbL; + palette[2] = 0x777777L; /* Gray */ + palette[3] = 0x333333L; + palette[4] = 0L; /* Black */ + + GpiCreateLogColorTable( hpsMemory, (ULONG)LCOL_PURECOLOR, + (LONG)LCOLF_CONSECRGB, (LONG)0L, + (LONG)5L, (PLONG)palette ); + + /* plot to presentation space in all five gray shades */ + for (x = 0 ; x < 5 ; x++) + { + GpiSetColor( hpsMemory, (LONG)x ); + coords.x = x; + coords.y = 0; + GpiSetPel( hpsMemory, &coords ); + } + + /* retrieve the 5 pixels as gray_palette */ + GpiQueryBitmapInfoHeader( hbm, (PBITMAPINFOHEADER2) pbmi ); + GpiQueryBitmapBits( hpsMemory, 0L, (LONG)VIO_HEIGHT - 2, + &Bitmap[0], pbmi ); + for ( x = 0; x < 5; x++ ) + { + gray_palette[x] = Bitmap[x]; + } + + /* initialization in case we paint before Driver_Display is called */ + memset( &Bitmap[0], gray_palette[0], vio_Height * vio_ScanLineWidth ); + DosReleaseMutexSem( hmtxPSMemoryLock ); + break; + + default: + return 0; /* Unknown mode */ + } + + return 1; /* success even if windows were not setup right */ + } + + + int Driver_Display_Bitmap( char* buffer, int lines, int cols ) + { + int y, target; + + + /* copy the bitmap and blt to presentation space */ + if ( (lines == vio_Height) & (cols == vio_ScanLineWidth) ) + memcpy( &Bitmap[0], buffer, lines * cols ); + else + { + memset( &Bitmap[0], gray_palette[0], vio_Height * vio_ScanLineWidth ); + /* temporary hack to center any bitmap */ + target = ( vio_Height - lines ) / 2 * vio_ScanLineWidth + + ( vio_ScanLineWidth - cols ) / 2; + + for ( y = 0 ; y < lines ; y++ ) + { + memcpy( &Bitmap[target], buffer, cols ); + target += vio_ScanLineWidth; + buffer += cols; + } + } + + /* Get permission and write to in-memory ps */ + DosRequestMutexSem( hmtxPSMemoryLock, SEM_INDEFINITE_WAIT ); + GpiSetBitmapBits( hpsMemory, 0L, (LONG)VIO_HEIGHT - 2, &Bitmap[0], pbmi ); + DosReleaseMutexSem( hmtxPSMemoryLock ); + ready = TRUE; + + /* Invalidate and ask for redraw now */ + WinInvalidateRect( hwndClient, NULL, FALSE ); + WinUpdateWindow( hwndFrame ); + + return 1; /* success */ + } + + + void Get_Event( TEvent* event ) + { + ULONG ulRequestCount; + + + /* the Get_Event function blocks until there is an event to process */ + DosWaitEventSem( hevKeyLock, SEM_INDEFINITE_WAIT ); + DosQueryEventSem( hevKeyLock, &ulRequestCount ); + DosResetEventSem( hevKeyLock, &ulRequestCount ); + event->what = ourevent.what; + event->info = ourevent.info; + return; + } + + + void RunPMWindow( ULONG dummy ) + { + unsigned char classname[] = "DisplayClass"; + ULONG flClassFlags; + static HMQ hmq; + QMSG qmsg; + + + if ( (hab = WinInitialize( 0 )) == 0 ) + { + printf( "Error doing WinInitialize()\n" ); + return; + } + + if ( (hmq = WinCreateMsgQueue( hab, 0 )) == (HMQ)NULL ) + { + printf( "Error doing WinCreateMsgQueue()\n" ); + return; + } + + if ( !WinRegisterClass( hab, (PSZ)classname, (PFNWP)Message_Process, + CS_SIZEREDRAW, 0 ) ) + { + printf( "Error doing WinRegisterClass()\n" ); + return; + } + + flClassFlags = FCF_TITLEBAR | FCF_MINBUTTON | FCF_DLGBORDER | + FCF_TASKLIST | FCF_SYSMENU; + if ( (hwndFrame = WinCreateStdWindow( HWND_DESKTOP, + WS_VISIBLE, + &flClassFlags, + (PSZ)classname, + (PSZ)"FreeType PM Graphics", + WS_VISIBLE, + 0, 0, &hwndClient )) == 0 ) + { + printf( "Error doing WinCreateStdWindow()\n" ); + return; + } + + /* find the title window handle */ + hwndTitle = WinWindowFromID( hwndFrame, FID_TITLEBAR ); + + /* set Window size and position */ + WinSetWindowPos( + hwndFrame, 0L, + (SHORT)60, + (SHORT)WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ) - + ( VIO_HEIGHT + MAG_HEIGHT + 100 ), + (SHORT)WinQuerySysValue( HWND_DESKTOP, SV_CYDLGFRAME ) * 2 + + VIO_WIDTH, + (SHORT)WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR ) + + WinQuerySysValue( HWND_DESKTOP, SV_CYDLGFRAME ) * 2 + + VIO_HEIGHT + MAG_HEIGHT, + SWP_SIZE | SWP_MOVE ) ; + + /* run the message queue till the end */ + while ( WinGetMsg( hab, &qmsg, (HWND)NULL, 0, 0 ) ) + WinDispatchMsg( hab, &qmsg ); + + /* clean-up */ + WinDestroyWindow( hwndFrame ); + hwndFrame = (HWND)NULL; + WinDestroyMsgQueue( hmq ); + WinTerminate( hab ); + + /* await death... */ + while ( 1 ) + DosSleep( 100 ); + } + + + void Adjust_Mag_Rectangle( void ) + { + SIZEL source, + target; + + + /* Step 1, find optimal source size for this mag and window size */ + source.cx = mag_win_size.cx / magnification; + if (source.cx > vio_Width) source.cx = vio_Width; + source.cy = mag_win_size.cy / magnification; + if (source.cy > vio_Height) source.cy = vio_Height; + + target.cx = source.cx * magnification; + target.cy = source.cy * magnification; + + aptlMagd[0].x = (mag_win_size.cx - target.cx) / 2; + aptlMagd[0].y = (mag_win_size.cy - target.cy) / 2; + aptlMagd[1].x = aptlMagd[0].x + target.cx - 1; + aptlMagd[1].y = aptlMagd[0].x + target.cy - 1; + + /* Step 2, try crosshairs point dependent coordinates */ + aptlMagd[2].x = view_target.x - source.cx / 2; + aptlMagd[2].y = view_target.y - source.cy / 2; + if (aptlMagd[2].x < 0 ) aptlMagd[2].x = 0; + if (aptlMagd[2].y < 0 ) aptlMagd[2].y = 0; + if (aptlMagd[2].x > vio_Width - source.cx) + aptlMagd[2].x = vio_Width - source.cx; + if (aptlMagd[2].y > vio_Height - source.cy) + aptlMagd[2].y = vio_Height - source.cy; + + aptlMagd[3].x = aptlMagd[2].x + source.cx - 1; + aptlMagd[3].y = aptlMagd[2].y + source.cy - 1; + + } /* End of Adjust_Mag_Rectangle; */ + + + /* Message processing for our PM Window class */ + MRESULT EXPENTRY Message_Process( HWND handle, ULONG mess, + MPARAM parm1, MPARAM parm2 ) + { + static HDC hdc; + static HPS hps; + static BOOL minimized; + + POINTL top_corner, bottom_corner; + SWP swp; + int i; + + + switch( mess ) + { + case WM_DESTROY: + /* warn the main thread to quit if it didn't know */ + ourevent.what = event_Quit; + ourevent.info = 0; + DosPostEventSem( hevKeyLock ); + break; + + case WM_CREATE: + /* set original magnification */ + magnification = 4; + minimized = FALSE; + + /* create Device Context and Presentation Space for screen. */ + /* could we use a cached one ? */ + hdc = WinOpenWindowDC( handle ); + mag_win_size.cx = 0; + mag_win_size.cy = 0; + hps = GpiCreatePS( hab, hdc, &mag_win_size, + PU_PELS | GPIT_MICRO | GPIA_ASSOC | GPIF_DEFAULT ); + + /* Set to size of magnifier window */ + mag_win_size.cx = MAG_WIDTH; + mag_win_size.cy = MAG_HEIGHT; + Adjust_Mag_Rectangle(); + + /* take the input focus */ + WinFocusChange( HWND_DESKTOP, handle, 0L ); + break; + + case WM_BUTTON1DOWN: + if ( MOUSEMSG( &mess )->y >= MAG_HEIGHT ) + { + view_target.x = MOUSEMSG( &mess )->x; + view_target.y = MOUSEMSG( &mess )->y - MAG_HEIGHT; + Adjust_Mag_Rectangle(); + WinInvalidateRect( hwndClient, NULL, FALSE ); + } + + return WinDefWindowProc( handle, mess, parm1, parm2 ); + break; + + case WM_MINMAXFRAME: + /* to update minimized if changed */ + swp = *((PSWP) parm1); + if ( swp.fl & SWP_MINIMIZE ) + minimized = TRUE; + if ( swp.fl & SWP_RESTORE ) + minimized = FALSE; + return WinDefWindowProc( handle, mess, parm1, parm2 ); + break; + + case WM_ERASEBACKGROUND: + case WM_PAINT: + /* reset the window title only if not minimized */ + if ( !minimized ) + WinSetWindowText( hwndTitle, Header ); + + /* copy the memory image of the screen out to the real screen */ + DosRequestMutexSem( hmtxPSMemoryLock, SEM_INDEFINITE_WAIT ); + WinBeginPaint( handle, hps, NULL ); + + /* main image and magnified picture */ + GpiBitBlt( hps, hpsMemory, 4L, aptlFull, ROP_SRCCOPY, BBO_AND ); + GpiBitBlt( hps, hpsMemory, 4L, aptlMagd, ROP_SRCCOPY, BBO_AND ); + + /* double-dash the magnifing bounding box. Paint the mag liner? */ + if ( magnification != 1 ) + { + GpiSetLineType( hps, LINETYPE_LONGDASH ); + + bottom_corner.x = aptlMagd[2].x - 1; + bottom_corner.y = aptlMagd[2].y + MAG_HEIGHT - 1; + top_corner.x = aptlMagd[3].x ; + top_corner.y = aptlMagd[3].y + MAG_HEIGHT; + + GpiMove( hps, &bottom_corner ); + GpiBox( hps, DRO_OUTLINE, &top_corner, 0L, 0L ); + +#if 0 + GpiSetClipRegion(); + GpiErase(); +#endif + } + + WinEndPaint( hps ); + DosReleaseMutexSem( hmtxPSMemoryLock ); + break; + + case WM_CHAR: + if ( CHARMSG( &mess )->fs & KC_KEYUP ) + break; + + switch ( CHARMSG( &mess )->vkey ) + { + case VK_ESC: + ourevent.what = event_Quit; + ourevent.info = 0; + DosPostEventSem( hevKeyLock ); + break; + + case VK_PAGEDOWN: + if ( magnification < MAX_MAG ) + { + magnification += 1; + Adjust_Mag_Rectangle(); + WinInvalidateRect( handle, NULL, FALSE ); + } + break; + + case VK_PAGEUP: + if ( magnification > 1 ) + { + magnification -= 1; + Adjust_Mag_Rectangle(); + WinInvalidateRect( handle, NULL, FALSE ); + } + break; + + case VK_LEFT: + if ( view_target.x > 0 ) + { + view_target.x -= 1; + Adjust_Mag_Rectangle(); + WinInvalidateRect( handle, NULL, FALSE ); + } + break; + + case VK_RIGHT: + if ( view_target.x < VIO_WIDTH - 1 ) + { + view_target.x += 1; + Adjust_Mag_Rectangle(); + WinInvalidateRect( handle, NULL, FALSE ); + } + break; + + case VK_DOWN: + if ( view_target.y > 0 ) + { + view_target.y -= 1; + Adjust_Mag_Rectangle(); + WinInvalidateRect( handle, NULL, FALSE ); + } + break; + + case VK_UP: + if ( view_target.y < VIO_HEIGHT - 1 ) + { + view_target.y += 1; + Adjust_Mag_Rectangle(); + WinInvalidateRect( handle, NULL, FALSE ); + } + break; + + case VK_F1: /* bring up help and about dialog window */ + break; + } + + if ( CHARMSG( &mess )->fs & KC_CHAR ) + { + char c = (CHAR)CHARMSG( &mess )->chr ; + + + for ( i = 0; i < NUM_Translators; i++ ) + { + if ( c == trans[i].key ) + { + ourevent.what = trans[i].event_class; + ourevent.info = trans[i].event_info; + DosPostEventSem( hevKeyLock ); + return (MRESULT)TRUE; + } + } + + /* unrecognized keystroke */ + ourevent.what = event_Keyboard; + ourevent.info = (int)c; + DosPostEventSem( hevKeyLock ); + } + break; + + default: + return WinDefWindowProc( handle, mess, parm1, parm2 ); + } + + return (MRESULT) FALSE; + } + + +/* End */ diff --git a/test/arch/os2/gpm_os2.def b/test/arch/os2/gpm_os2.def new file mode 100644 index 0000000..4a77c63 --- /dev/null +++ b/test/arch/os2/gpm_os2.def @@ -0,0 +1,5 @@ +NAME WINDOWCOMPAT + +DESCRIPTION 'FreeType Graphics' +HEAPSIZE 8192 +STACKSIZE 40888 diff --git a/test/arch/unix/.cvsignore b/test/arch/unix/.cvsignore new file mode 100644 index 0000000..f3c7a7c --- /dev/null +++ b/test/arch/unix/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/test/arch/unix/Makefile.in b/test/arch/unix/Makefile.in new file mode 100644 index 0000000..fc6cc2b --- /dev/null +++ b/test/arch/unix/Makefile.in @@ -0,0 +1,170 @@ +# This file is part of the FreeType project. +# +# test/arch/unix/Makefile.in + +ARCH = arch/unix + +top_builddir=.. + +VPATH = @srcdir@/../.. +srcdir = @srcdir@/../.. + +RM = @RM@ +RMF = @RM@ -f +RMDIR = @RMDIR@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ + +CC = @CC@ +CPP = @CPP@ + +LIBTOOL = $(top_builddir)/libtool +MKINSTALLDIRS = $(srcdir)/../mkinstalldirs + +include $(top_builddir)/MakeSub + +FT_LIBDIR = $(srcdir)/../lib +INCDIRS = -I. -I$(srcdir) -I$(top_builddir) \ + -I$(FT_LIBDIR) -I$(FT_LIBDIR)/extend + +CFLAGS = @CFLAGS@ @X_CFLAGS@ @XX_CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +FT_CFLAGS = $(INCDIRS) $(CFLAGS) $(CPPFLAGS) -DX11 -DLOCALEDIR='"@LOCALEDIR@"' + +FT_LIBS = @X_LIBS@ @X_PRE_LIBS@ @X_EXTRA_LIBS@ @LIBS@ + +SRC = $(srcdir)/arabic.c \ + $(srcdir)/common.c \ + $(srcdir)/ftdump.c \ + $(srcdir)/fterror.c \ + $(srcdir)/ftlint.c \ + $(srcdir)/ftmetric.c \ + $(srcdir)/ftsbit.c \ + $(srcdir)/ftstring.c \ + $(srcdir)/ftstrpnm.c \ + $(srcdir)/fttimer.c \ + $(srcdir)/ftview.c \ + $(srcdir)/ftzoom.c \ + $(srcdir)/ftstrtto.c \ + $(srcdir)/gmain.c \ + $(srcdir)/$(ARCH)/gwin_x11.c + +DISPOBJS = common.o gmain.o display.o gwin_x11.o blitter.o + +PROGRAMS = ftview fttimer ftlint ftdump ftzoom ftsbit \ + ftstring ftstrpnm fterror ftmetric ftstrtto + +# set this variable to nil if you don't need to use Electric-Fence +EFENCE = +#EFENCE = -lefence + + +# variables used to compile either with libtool or not +# +PROCESS = $(LIBTOOL) --mode=link $(CC) $(FT_CFLAGS) +#PROCESS = $(CC) $(FT_CFLAGS) + +LIBTTF = $(top_builddir)/lib/libttf.la +#LIBTTF =$(top_builddir)/lib/libttf.a + +.c.o: + $(CC) -c $(FT_CFLAGS) $< + + +all: $(PROGRAMS) + + +gwin_x11.o: $(srcdir)/$(ARCH)/gwin_x11.c + $(CC) -c $(FT_CFLAGS) $(srcdir)/$(ARCH)/gwin_x11.c + +ftzoom: ftzoom.o $(DISPOBJS) $(LIBTTF) + $(PROCESS) -o ftzoom ftzoom.o $(DISPOBJS) \ + $(EFENCE) $(LIBTTF) $(FT_LIBS) -lX11 + +fttimer: fttimer.o $(DISPOBJS) $(LIBTTF) + $(PROCESS) -o fttimer fttimer.o $(DISPOBJS) \ + $(EFENCE) $(LIBTTF) $(FT_LIBS) -lX11 + +ftview: ftview.o $(DISPOBJS) $(LIBTTF) + $(PROCESS) -o ftview ftview.o $(DISPOBJS) \ + $(EFENCE) $(LIBTTF) $(FT_LIBS) -lX11 + +ftlint: ftlint.o common.o $(LIBTTF) + $(PROCESS) -o ftlint ftlint.o common.o \ + $(EFENCE) $(LIBTTF) $(FT_LIBS) + +ftdump: ftdump.o common.o $(LIBTTF) + $(PROCESS) -o ftdump ftdump.o common.o \ + $(EFENCE) $(LIBTTF) $(FT_LIBS) + +ftmetric: ftmetric.o common.o $(LIBTTF) + $(PROCESS) -o ftmetric ftmetric.o common.o \ + $(EFENCE) $(LIBTTF) $(FT_LIBS) + +ftsbit: ftsbit.o common.o $(LIBTTF) + $(PROCESS) -o ftsbit ftsbit.o common.o \ + $(EFENCE) $(LIBTTF) + +ftstring: ftstring.o $(DISPOBJS) $(LIBTTF) + $(PROCESS) -o ftstring ftstring.o $(DISPOBJS) \ + $(EFENCE) $(LIBTTF) $(FT_LIBS) -lX11 + +# ftstrpnm does not need any extra libraries +ftstrpnm: ftstrpnm.o common.o $(LIBTTF) + $(PROCESS) -o ftstrpnm ftstrpnm.o common.o \ + $(EFENCE) $(LIBTTF) + +fterror: fterror.o common.o $(LIBTTF) + $(PROCESS) -o fterror fterror.o common.o \ + $(EFENCE) $(LIBTTF) $(FT_LIBS) + +ftstrtto: ftstrtto.o $(DISPOBJS) arabic.o $(LIBTTF) + $(PROCESS) -o ftstrtto ftstrtto.o $(DISPOBJS) arabic.o \ + $(EFENCE) $(LIBTTF) $(FT_LIBS) -lX11 + + +install: $(PROGRAMS) + $(MKINSTALLDIRS) $(bindir) + for P in $(PROGRAMS) ; do \ + $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$P $(bindir)/$$P ; \ + done + +uninstall: + -for P in $(PROGRAMS) ; do \ + $(LIBTOOL) --mode=uninstall $(RM) $(bindir)/$$P ; \ + done + +clean: do_clean + +distclean: do_clean + -$(RMF) $(PROGRAMS) + -$(RMF) *~ *.orig core *.core + -$(RMF) config.cache config.log config.status + -$(RMF) $(ARCH)/Makefile + -$(RMF) .libs/* + -$(RMDIR) .libs + +do_clean: + -$(RMF) *.o + +depend: + (echo '/^#.* PUT NO STUFF BELOW/,$$d' ; echo w ; echo q) | \ + ed - $(ARCH)/Makefile + echo '# Dependencies generated by make depend: PUT NO STUFF BELOW' \ + >> $(ARCH)/Makefile + for file in $(SRC) ; do \ + $(CPP) $(CPPFLAGS) $(INCDIRS) $$file | \ + sed -n -e 's|^# [1-9][0-9]* "\([^/].*\.h\)".*|\1|p' \ + -e 's|^# [1-9][0-9]* "\($(srcdir)/.*\.h\)".*|\1|p' | \ + sed -e 's|/\./|.|g' -e "s/^/`basename $$file .c`.o: /" ; \ + done | \ + sort -u | \ + awk '{ if (LINE == 1) \ + { line = last = $$1 } \ + else if ($$1 != last) \ + { print line ; line = last = $$1 } \ + line = line " " $$2 } \ + END { print line }' >> $(ARCH)/Makefile + +# Dependencies generated by make depend: PUT NO STUFF BELOW diff --git a/test/arch/unix/gwin_x11.c b/test/arch/unix/gwin_x11.c new file mode 100644 index 0000000..760c213 --- /dev/null +++ b/test/arch/unix/gwin_x11.c @@ -0,0 +1,451 @@ +/******************************************************************* + * + * gwin_x11.c graphics utility X-Window driver. 1.0 + * + * This is the driver for windowed display under X11, used by the + * graphics utility of the FreeType test suite. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "common.h" /* for Panic() */ +#include "freetype.h" + +#include "gdriver.h" +#include "gevents.h" +#include "gmain.h" + + + /* Translator added to ease changes to control keys */ + + typedef struct _Translator + { + char key; + GEvent event_class; + int event_info; + } Translator; + +#define NUM_Translators 20 + + static const Translator trans[NUM_Translators] = + { + { (char)27, event_Quit, 0 }, + { 'q', event_Quit, 0 }, + + { 'x', event_Rotate_Glyph, -1 }, + { 'c', event_Rotate_Glyph, 1 }, + { 'v', event_Rotate_Glyph, -16 }, + { 'b', event_Rotate_Glyph, 16 }, + + { '{', event_Change_Glyph, -10000 }, + { '}', event_Change_Glyph, 10000 }, + { '(', event_Change_Glyph, -1000 }, + { ')', event_Change_Glyph, 1000 }, + { '9', event_Change_Glyph, -100 }, + { '0', event_Change_Glyph, 100 }, + { 'i', event_Change_Glyph, -10 }, + { 'o', event_Change_Glyph, 10 }, + { 'k', event_Change_Glyph, -1 }, + { 'l', event_Change_Glyph, 1 }, + + { '+', event_Scale_Glyph, 10 }, + { '-', event_Scale_Glyph, -10 }, + { 'u', event_Scale_Glyph, 1 }, + { 'j', event_Scale_Glyph, -1 } + }; + + /* End of translators addition. See Get_Event() below */ + + extern char Header[]; /* defined in the test programs */ + + static Window win; + static GC gcblack; + static XColor color[5]; + + Display* display; + static char* displayname = ""; + + static XImage* image; + + static Visual* visual; + static Colormap colormap; + static int depth; + static Bool gray; + + static Cursor idle; + static Cursor busy; + + static int win_origin_x, win_origin_y, + win_width, win_height; + static int image_width, image_height; + + long vioBufOfs; + + + + /* restore acreen to its original state */ + + int Driver_Restore_Mode( void ) + { + XUnmapWindow( display, win ); + XCloseDisplay( display ); + + return 1; /* success */ + } + + + /* set graphics mode */ + + void x11init( void ) + { + int screen_num, i; + XTextProperty xtp; + XSizeHints xsh; + XSetWindowAttributes xswa; + +#if 1 + unsigned short colors[5] = { 0, 16, 32, 48, 63 }; /* gamma = 1.0 */ +#else + unsigned short colors[5] = { 0, 34, 46, 55, 63 }; /* gamma = 2.2 */ +#endif + + + XrmInitialize(); + + if( !( display = XOpenDisplay( displayname ) ) ) + Panic( "ERROR: cannot open display\n" ); + + screen_num = DefaultScreen ( display ); + colormap = DefaultColormap( display, screen_num ); + depth = DefaultDepth ( display, screen_num ); + visual = DefaultVisual ( display, screen_num ); + + idle = XCreateFontCursor( display, XC_left_ptr ); + busy = XCreateFontCursor( display, XC_watch ); + + if ( gray ) + { + int count; + XPixmapFormatValues* formats; + + + formats = XListPixmapFormats( display, &count ); + vio_ScanLineWidth = 0; + + while ( count > 0 ) + { + --count; + if ( formats[count].depth == depth ) + { + int bits; + + bits = win_width * formats[count].bits_per_pixel; + if ( bits % formats[count].scanline_pad ) + { + bits -= bits % formats[count].scanline_pad; + bits += formats[count].scanline_pad; + } + + vio_ScanLineWidth = bits / 8; + break; + } + } + if ( !vio_ScanLineWidth ) + Panic( "ERROR: the display doesn't offer a suitable pixmap format\n" ); + + XFree( formats ); + } + + Vio = (char*)malloc( win_height * vio_ScanLineWidth ); + + if ( !Vio ) + Panic( "ERROR: cannot malloc display memory\n" ); + + xswa.border_pixel = BlackPixel( display, screen_num ); + xswa.background_pixel = WhitePixel( display, screen_num ); + xswa.cursor = busy; + + xswa.event_mask = KeyPressMask | ExposureMask; + + win = XCreateWindow( display, + RootWindow( display, screen_num ), + win_origin_x, + win_origin_y, + win_width, + win_height, + 10, + depth, + InputOutput, + visual, + CWBackPixel | CWBorderPixel | CWEventMask | CWCursor, + &xswa ); + + XMapWindow( display, win ); + + gcblack = XCreateGC( display, RootWindow( display, screen_num ), + 0L, NULL ); + XSetForeground( display, gcblack, BlackPixel( display, screen_num ) ); + XSetBackground( display, gcblack, WhitePixel( display, screen_num ) ); + + /* allocate colors */ + + if ( gray ) + for ( i = 0; i < 5; i++ ) + { + gray_palette[i] = i; + + color[i].red = + color[i].green = + color[i].blue = 65535 - ( colors[i] * 65535 ) / 63; + + if ( !XAllocColor( display, colormap, &color[i] ) ) + Panic( "ERROR: cannot allocate Color\n" ); + } + + image = XCreateImage( display, + visual, + gray ? depth : 1, + gray ? ZPixmap : XYBitmap, + 0, + (char*)Vio, + win_width, + win_height, + 8, + 0 ); + if ( !image ) + Panic( "ERROR: cannot create image\n" ); + + if ( !gray ) + { + image->byte_order = MSBFirst; + image->bitmap_bit_order = MSBFirst; + } + + /* make window manager happy :-) */ + xtp.value = (unsigned char*)"FreeType"; + xtp.encoding = 31; + xtp.format = 8; + xtp.nitems = strlen( (char*)xtp.value ); + + xsh.x = win_origin_x; + xsh.y = win_origin_y; + + xsh.width = win_width; + xsh.height = win_height; + xsh.flags = (PPosition | PSize); + xsh.flags = 0; + + XSetWMProperties( display, win, &xtp, &xtp, NULL, 0, &xsh, NULL, NULL ); + } + + + int Driver_Set_Graphics( int mode ) + { + if ( mode == Graphics_Mode_Gray ) + { + gray = 1; + vio_ScanLineWidth = 320; + + win_origin_x = 0; + win_origin_y = 0; + win_width = 320; + win_height = 200; + } + else if ( mode == Graphics_Mode_Mono ) + { + gray = 0; + vio_ScanLineWidth = 80; + + win_origin_x = 0; + win_origin_y = 0; + win_width = 640; + win_height = 450; + } + else + Panic( "ERROR: mode %d not supported\n", mode ); + + vio_Width = win_width; + vio_Height = win_height; + + x11init(); + + return 1; /* success */ + } + + + void Put_Image( int x, int y, int w, int h ) + { + XPutImage( display, win, gcblack, image, x, y, x, y, w, h ); + } + + + int Driver_Display_Bitmap( char* buffer, int line, int col ) + { + int z, y, used_col; + char* target; + + + XClearWindow( display, win ); + + /* this displays the Header string in the window title */ + XStoreName( display, win, Header ); + + if ( line > win_height ) + line = win_height; + + if ( !gray ) + { + if ( col > vio_ScanLineWidth ) + used_col = vio_ScanLineWidth; + else + used_col = col; + + target = Vio + ( line - 1 ) * vio_ScanLineWidth; + + for ( y = 0; y < line; y++ ) + { + memcpy( (char*)target, buffer, used_col ); + target -= vio_ScanLineWidth; + buffer += col; + } + + Put_Image( 0, 0, used_col * 8, line ); + image_width = used_col * 8; + image_height = line; + } + else + { + if ( col > win_width ) + used_col = win_width; + else + used_col = col; + + for ( y = line - 1; y >= 0; y-- ) + { + char* bufp; + + + bufp = buffer; + + for ( z = 0; z < used_col; z++ ) + { + int c; + + + c = *bufp++; + + if ( c < 0 || c >= 5 ) /* security check */ + { + /* Message( "weird grayshade: %d\n", c ); */ + c = 0; + } + XPutPixel( image, z, y, color[c].pixel ); + } + + buffer += col; + } + + Put_Image( 0, 0, used_col, line ); + image_width = used_col; + image_height = line; + } + + return 1; + } + + + /* This function maps X keystrokes into GEvents. Note that */ + /* currently only keystrokes events exit this function. */ + + void Get_Event( TEvent* event ) + { + static char key_buffer[10]; + static int key_cursor = 0; + static int key_number = 0; + static XEvent x_event; + KeySym key; + + int i, bool_exit; + char c; + + XComposeStatus compose; + + + bool_exit = key_cursor < key_number; + + XDefineCursor( display, win, idle ); + + while ( !bool_exit ) + { + XNextEvent( display, &x_event ); + + switch ( x_event.type ) + { + case KeyPress: + key_number = XLookupString( &x_event.xkey, + key_buffer, + sizeof ( key_buffer ), + &key, + &compose ); + key_cursor = 0; + + if ( key_number > 0 ) + bool_exit = 1; + break; + + case MappingNotify: + XRefreshKeyboardMapping( &x_event.xmapping ); + break; + + case Expose: +#if 0 + Put_Image( x_event.xexpose.x, + x_event.xexpose.y, + x_event.xexpose.width, + x_event.xexpose.height ); +#else + /* we always redraw the whole image */ + Put_Image( 0, 0, image_width, image_height ); +#endif + break; + + /* You should add more cases to handle mouse events, etc. */ + } + } + + XDefineCursor( display, win, busy ); + XFlush ( display ); + + c = key_buffer[key_cursor++]; + + for ( i = 0; i < NUM_Translators; i++ ) + { + if ( c == trans[i].key ) + { + event->what = trans[i].event_class; + event->info = trans[i].event_info; + return; + } + } + + event->what = event_Keyboard; + event->info = (int)c; + } + + +/* End */ diff --git a/test/arch/win16/Makefile.BC b/test/arch/win16/Makefile.BC new file mode 100644 index 0000000..cf246c3 --- /dev/null +++ b/test/arch/win16/Makefile.BC @@ -0,0 +1,212 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for BC++ for 16-bit Windows, +# using large model, and using Easy-Win to display console outputs. +# +# Tested with Borland C++ v.4.02, 5.0 +# You will need Borland MAKE (v.3.6 and above should be OK, for oldest +# versions refer to the instructions below). +# +# +# Use this file while in the 'test' directory with the following statement: +# +# make -farch\win16\Makefile.BC +# +# +# A DLL version of the library can be built and then used with +# +# make -DDLL -farch/win16/Makefile.BC dll +# +# (do not forget to define DLL, otherwise the link phase will fail). +# +# +# Debug versions can be obtained with +# +# make -DDEBUG -farch\win16\Makefile.BC +# +# Special versions enabled to handle big fonts (with more than 16,384 +# glyphs) can be obtained with +# +# make -DBIGFONTS -farch\msdos\Makefile.BC + +ARCH = arch\win16 +FT_MAKEFILE = $(ARCH)\Makefile.BC +FT_DLL = ft13_16.dll + +CC = bcc + +LIBDIR = ..\lib +INCDIRS = -I$(LIBDIR);$(LIBDIR)\$(ARCH);.;$(LIBDIR)\extend +SPURIOUS_WARNINGS = -w-nak -w-par -w-use -w-aus -w-stu -w-stv -w-cln -w-sig -w-pia + +# Credits go to Dave Hoo for pointing out that modern +# Borland compilers (from BC++ 3.1 on) can increase the limit of +# the length of identifiers. +CFLAGS = -WSE -ml -A -i40 $(INCDIRS) $(SPURIOUS_WARNINGS) + +!if ! $d(DEBUG) +CFLAGS = $(CFLAGS) -O2 -3 +LDFLAGS = -ml -W -lC +!else +CFLAGS = $(CFLAGS) -v -N +LDFLAGS = -v -ml -W -lC +!endif + +!if $d(DLL) +CFLAGS = $(CFLAGS) -DFREETYPE_DLL +!endif + + +# Windows graphic driver +GDRIVER = $(ARCH)\gw_win16.c + +DISPLAY = display.c + +G1SRC = gmain.c blitter.c $(GDRIVER) +GSRC = $(DISPLAY) $(G1SRC) + +GOBJ = $(GSRC:.c=.obj) +G1OBJ = $(G1SRC:.c=.obj) + + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +OBJ = $(SRC:.c=.obj) + + +.c.obj: + $(CC) -c -o$* @&&| + $(CFLAGS) $< +| + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + +!if !$d(DEBUG) +# Skipped if DEBUG build +all: freetype $(EXEFILES) + +dll: the_dll $(EXEFILES) + +!else +# Skipped if non-DEBUG build +default_target: debug +dll: the_debug_dll $(EXEFILES) + +!endif + +debug: freetype_debug $(EXEFILES) + + +!if $d(BIGFONTS) +MAKEBIG = -DBIGFONTS +!endif + +freetype: + cd $(LIBDIR) + make -f$(FT_MAKEFILE) $(MAKEBIG) all + cd ..\test + +freetype_debug: + cd $(LIBDIR) + make -f$(FT_MAKEFILE) -DDEBUG $(MAKEBIG) debug + cd ..\test + +the_dll: + cd $(LIBDIR) + make -f$(FT_MAKEFILE) -DDLL $(MAKEBIG) dll + cd ..\test + -copy $(LIBDIR)\$(FT_DLL) + +the_debug_dll: + cd $(LIBDIR) + make -f$(FT_MAKEFILE) -DDEBUG -DDLL $(MAKEBIG) dll + cd ..\test + -copy $(LIBDIR)\$(FT_DLL) + + +# C compilers are unable to include 16-bit in ANSI mode. +# So we have a special rule for this file, to build it outside ANSI. +$(GDRIVER:.c=.obj): + $(CC) -c -o$* @&&| + $(CFLAGS) -A- $*.c +| + + +# Borland versions of make are unable to use the $** variable inside +# implicit rules (like .obj.exe:). The job have to be done by hand. :-( +ftzoom.exe: $(G1OBJ) ftzoom.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftzoom.obj $(G1OBJ) common.obj $(LIBDIR)\libttf.lib + +ftview.exe: $(GOBJ) ftview.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftview.obj $(GOBJ) common.obj $(LIBDIR)\libttf.lib + +ftstring.exe: $(GOBJ) ftstring.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftstring.obj $(GOBJ) common.obj $(LIBDIR)\libttf.lib + +ftstrtto.exe: $(GOBJ) ftstrtto.obj common.obj arabic.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftstrtto.obj $(GOBJ) common.obj arabic.obj \ + $(LIBDIR)\libttf.lib + +fttimer.exe: $(G1OBJ) fttimer.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) fttimer.obj $(G1OBJ) common.obj $(LIBDIR)\libttf.lib + +ftlint.exe: ftlint.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftlint.obj common.obj $(LIBDIR)\libttf.lib + +ftdump.exe: ftdump.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftdump.obj common.obj $(LIBDIR)\libttf.lib + +ftstrpnm.exe: ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib + +ftsbit.exe: ftsbit.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftsbit.obj common.obj $(LIBDIR)\libttf.lib + +ftmetric.exe: ftmetric.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftmetric.obj common.obj $(LIBDIR)\libttf.lib + +fterror.exe: fterror.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) fterror.obj common.obj $(LIBDIR)\libttf.lib + + +clean: do_clean + cd $(LIBDIR) + make -f$(FT_MAKEFILE) clean + cd ..\test + +distclean: do_clean + cd $(LIBDIR) + make -f$(FT_MAKEFILE) distclean + cd ..\test + -del *.exe + -del *.dll + +do_clean: + -del *.obj + -del $(ARCH)\*.obj + +!include "$(ARCH)\depend.win" + +# end of Makefile diff --git a/test/arch/win16/Makefile.MS b/test/arch/win16/Makefile.MS new file mode 100644 index 0000000..6cb13bf --- /dev/null +++ b/test/arch/win16/Makefile.MS @@ -0,0 +1,145 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for Microsoft C compilers +# for 16-bit Windows, large model, using QuickWin to display console +# outputs. It also works for Visual C++ 1.x 16-bits compiler, but +# you should instead use the Makefile customized for it, Makefile.VC. +# +# You will need NMAKE. +# +# +# Use this file while in the 'test' directory with the following statement: +# +# nmake /f arch\win16\Makefile.MS +# +# +# A debug version can be obtained with +# +# nmake DEBUG=1 /f arch\win16\Makefile.MS + +ARCH = arch\win16 +FT_MAKEFILE = $(ARCH)\Makefile.MS +FT_MAKE = $(MAKE) /nologo + +CC = cl /nologo + +LIBDIR = ..\lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)\$(ARCH) -I. -I$(LIBDIR)\extend + +!ifndef DEBUG +CFLAGS = /Ox /AL /Za /W2 /G2 $(INCDIRS) +LDFLAGS = /AL +!else +CFLAGS = /Zi /AL /Za /W2 /G2 $(INCDIRS) +LDFLAGS = /Zi /AL +!endif + +CFLAGS = $(CFLAGS) /GA /Mq +LDFLAGS = $(LDFLAGS) /GA /Mq + + +# Windows graphic driver +GDRIVER = $(ARCH)\gw_win16.c + +GSRC = display.c gmain.c blitter.c $(GDRIVER) + +GOBJ = $(GSRC:.c=.obj) + + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +OBJ = $(SRC:.c=.obj) + + +.c.obj: + @$(CC) /c /Fo$* @<< + $(CFLAGS) $< +<< + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + +!ifndef DEBUG +# Skiped if DEBUG build +all: freetype $(EXEFILES) + +!endif + +debug: freetype_debug $(EXEFILES) + +freetype: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) all + cd ..\test + +freetype_debug: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) DEBUG=1 debug + cd ..\test + + +# C compilers are unable to include 16-bit in ANSI mode. +# So we have a special rule for this file, to build it outside ANSI. +$(GDRIVER:.c=.obj): + @$(CC) /c /Fo$* @<< + $(CFLAGS) /Ze $(GDRIVER) +<< + +.obj.exe: + $(CC) /Fe$* @<< + $(LDFLAGS) $** +<< + +ftzoom.exe: $(GOBJ) ftzoom.obj common.obj $(LIBDIR)\libttf.lib +ftview.exe: $(GOBJ) ftview.obj common.obj $(LIBDIR)\libttf.lib +ftstring.exe: $(GOBJ) ftstring.obj common.obj $(LIBDIR)\libttf.lib +ftstrtto.exe: $(GOBJ) ftstrtto.obj common.obj arabic.obj $(LIBDIR)\libttf.lib +fttimer.exe: $(GOBJ) fttimer.obj common.obj $(LIBDIR)\libttf.lib +ftlint.exe: ftlint.obj common.obj $(LIBDIR)\libttf.lib +ftdump.exe: ftdump.obj common.obj $(LIBDIR)\libttf.lib +ftstrpnm.exe: ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib +ftsbit.exe: ftsbit.obj common.obj $(LIBDIR)\libttf.lib +ftmetric.exe: ftmetric.obj common.obj $(LIBDIR)\libttf.lib +fterror.exe: fterror.obj common.obj $(LIBDIR)\libttf.lib + + +clean: do_clean + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) clean + cd ..\test + +distclean: do_clean + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) distclean + cd ..\test + -del *.exe + +do_clean: + -del *.obj + -del $(ARCH)\*.obj + + +!include "$(ARCH)\depend.win" + +# end of Makefile.MS diff --git a/test/arch/win16/Makefile.VC b/test/arch/win16/Makefile.VC new file mode 100644 index 0000000..2a9205f --- /dev/null +++ b/test/arch/win16/Makefile.VC @@ -0,0 +1,187 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for Microsoft Visual C++ 1.x +# and Microsoft C/C++ v.7.0 compilers for 16-bit Windows, large model, +# using QuickWin to display console outputs. +# +# You will need NMAKE. +# +# +# Use this file while in the 'test' directory with the following statement: +# +# nmake /f arch\win16\Makefile.VC +# +# A DLL version of the library can be built and then used with +# +# nmake DLL=1 /f arch\win16\Makefile.VC dll +# +# (do not forget to define DLL, otherwise the link phase will fail). +# +# +# Debug versions can be obtained with +# +# nmake DEBUG=1 /f arch\win16\Makefile.VC +# +# Special versions enabled to handle big fonts (with more than 16,384 +# glyphs) can be obtained with +# +# nmake BIGFONTS=1 /f arch\win16\Makefile.VC + +ARCH = arch\win16 +FT_MAKEFILE = $(ARCH)\Makefile.VC +FT_MAKE = $(MAKE) /nologo +FT_DLL = ft13_16.dll + +CC = cl /nologo + +LIBDIR = ..\lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)\$(ARCH) -I. -I$(LIBDIR)\extend + +# One can also consider using "set MSC_CMD_FLAGS=/Gr /Op- /Gy /YX". +# With Microsoft C/C++ 7.0, use /G2 instead of /G3. +!ifndef DEBUG +CFLAGS = /Ox /AL /Za /W2 /G3 $(INCDIRS) +LDFLAGS = /AL +!else +CFLAGS = /Zi /Ge /AL /Za /W2 /G3 $(INCDIRS) +LDFLAGS = /Zi /AL +!endif + +CFLAGS = $(CFLAGS) /Mq +LDFLAGS = $(LDFLAGS) /Mq + +!ifdef DLL +CFLAGS = $(CFLAGS) /DFREETYPE_DLL +!endif + + +# Windows graphic driver +GDRIVER = $(ARCH)\gw_win16.c + +GSRC = display.c gmain.c blitter.c $(GDRIVER) + +GOBJ = $(GSRC:.c=.obj) + + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +OBJ = $(SRC:.c=.obj) + + +.c.obj: + @$(CC) /c /Fo$* @<< + $(CFLAGS) $< +<< + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + +!ifndef DEBUG +# Skiped if DEBUG build +all: freetype $(EXEFILES) + +dll: the_dll $(EXEFILES) + +!else +# Skipped if non-DEBUG build +default_target: debug +dll: the_debug_dll $(EXEFILES) + +!endif + +debug: freetype_debug $(EXEFILES) + +!ifdef BIGFONTS +MAKEBIG = BIGFONTS=1 +!endif + +freetype: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) $(MAKEBIG) all + cd ..\test + +freetype_debug: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) DEBUG=1 $(MAKEBIG) debug + cd ..\test + +the_dll: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) DLL=1 $(MAKEBIG) dll + cd ..\test + -copy $(LIBDIR)\$(FT_DLL) + +the_debug_dll: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) DEBUG=1 DLL=1 $(MAKEBIG) dll + cd ..\test + -copy $(LIBDIR)\$(FT_DLL) + + +# C compilers are unable to include 16-bit in ANSI mode. +# So we have a special rule for this file, to build it outside ANSI. +$(GDRIVER:.c=.obj): + @$(CC) /c /Fo$* @<< + $(CFLAGS) /Ze $(GDRIVER) +<< + +.obj.exe: + $(CC) /Fe$* @<< + $(LDFLAGS) $** +<< + +ftzoom.exe: $(GOBJ) ftzoom.obj common.obj $(LIBDIR)\libttf.lib +ftview.exe: $(GOBJ) ftview.obj common.obj $(LIBDIR)\libttf.lib +ftstring.exe: $(GOBJ) ftstring.obj common.obj $(LIBDIR)\libttf.lib +ftstrtto.exe: $(GOBJ) ftstrtto.obj common.obj arabic.obj $(LIBDIR)\libttf.lib +fttimer.exe: $(GOBJ) fttimer.obj common.obj $(LIBDIR)\libttf.lib +ftlint.exe: ftlint.obj common.obj $(LIBDIR)\libttf.lib +ftdump.exe: ftdump.obj common.obj $(LIBDIR)\libttf.lib +ftstrpnm.exe: ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib +ftsbit.exe: ftsbit.obj common.obj $(LIBDIR)\libttf.lib +ftmetric.exe: ftmetric.obj common.obj $(LIBDIR)\libttf.lib +fterror.exe: fterror.obj common.obj $(LIBDIR)\libttf.lib + + +clean: do_clean + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) clean + cd ..\test + +distclean: do_clean + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) distclean + cd ..\test + -del *.exe + -del *.dll + -del *.pdb + +do_clean: + -del *.obj + -del $(ARCH)\*.obj + + +!include "$(ARCH)\depend.win" + +# end of Makefile.VC diff --git a/test/arch/win16/depend.win b/test/arch/win16/depend.win new file mode 100644 index 0000000..7b3dd26 --- /dev/null +++ b/test/arch/win16/depend.win @@ -0,0 +1,52 @@ +# This dependency file to be used with various Windows compilers +# has been generated automatically with the script `makedep' on +# 02-Sep-1999. + +arabic.obj: arabic.c arabic.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxopen.h ..\lib\extend\ftxgdef.h \ + ..\lib\extend\ftxgsub.h ..\lib\extend\ftxgpos.h +blitter.obj: blitter.c blitter.h +common.obj: common.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h +display.obj: display.c display.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h gmain.h +fdebug.obj: fdebug.c ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\tttypes.h ..\lib\ttconfig.h \ + ..\lib\arch\win16\ft_conf.h ..\lib\ttdebug.h ..\lib\ttobjs.h \ + ..\lib\ttengine.h ..\lib\ttmutex.h ..\lib\ttcache.h ..\lib\tttables.h \ + ..\lib\ttcmap.h +ftdump.obj: ftdump.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxcmap.h ..\lib\extend\ftxopen.h \ + ..\lib\extend\ftxgdef.h ..\lib\extend\ftxgsub.h \ + ..\lib\extend\ftxgpos.h ..\lib\extend\ftxsbit.h ..\lib\ttobjs.h \ + ..\lib\ttconfig.h ..\lib\arch\win16\ft_conf.h ..\lib\ttengine.h \ + ..\lib\tttypes.h ..\lib\ttmutex.h ..\lib\ttcache.h ..\lib\tttables.h \ + ..\lib\ttcmap.h +fterror.obj: fterror.c ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxerr18.h \ + ..\lib\arch\win16\ft_conf.h +ftlint.obj: ftlint.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\arch\win16\ft_conf.h +ftmetric.obj: ftmetric.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxsbit.h ..\lib\arch\win16\ft_conf.h +ftsbit.obj: ftsbit.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxsbit.h ..\lib\arch\win16\ft_conf.h +ftstring.obj: ftstring.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h display.h gevents.h gdriver.h gmain.h +ftstrpnm.obj: ftstrpnm.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h +ftstrtto.obj: ftstrtto.c arabic.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxopen.h ..\lib\extend\ftxgdef.h \ + ..\lib\extend\ftxgsub.h ..\lib\extend\ftxgpos.h blitter.h common.h \ + display.h ..\lib\extend\ftxkern.h ..\lib\extend\ftxsbit.h gdriver.h \ + gevents.h gmain.h +fttimer.obj: fttimer.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h gdriver.h gevents.h gmain.h +ftview.obj: ftview.c blitter.h common.h display.h \ + ..\lib\extend\ftxsbit.h gdriver.h gevents.h gmain.h +ftzoom.obj: ftzoom.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxpost.h gdriver.h gevents.h gmain.h +gmain.obj: gmain.c gdriver.h gmain.h +!ifndef __MAKE__ +arch\win16\gw_win16.obj: arch\win16\gw_win16.c gdriver.h gevents.h gmain.h +!endif diff --git a/test/arch/win16/gw_win16.c b/test/arch/win16/gw_win16.c new file mode 100644 index 0000000..be4bdc3 --- /dev/null +++ b/test/arch/win16/gw_win16.c @@ -0,0 +1,430 @@ +/******************************************************************* + * + * gw_win16.c graphics driver for 16-bit Windows platform. 0.1 + * + * This is the driver for displaying inside a window under 16-bit + * Microsoft Windows, used by the graphics utility of the + * FreeType test suite. + * + * Written by Antoine Leca. + * Copyright 1999 by Antoine Leca, + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * Borrowing liberally from the other FreeType drivers. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include +#include +#include + +#include + +#include "gdriver.h" +#include "gevents.h" +#include "gmain.h" + + +/* The following #ifdef are used to define the following macros : */ +/* */ +/* - hInst : variable containing the handle of the current instance. */ +/* - hPrev : variable containing the handle of the previous instance. */ +/* */ + +/* ---- Microsoft C compilers support ------------------------------------ */ + +#if defined( M_I86 ) || defined( _M_I86 ) + +extern HINSTANCE _hInstance, _hPrevInstance; +#define hInst _hInstance +#define hPrev _hPrevInstance + +#endif + +/* ---- Borland C compiler support --------------------------------------- */ + +#ifdef __TURBOC__ + +#pragma option -A- + +extern HINSTANCE _hInstance, _hPrev; +#define hInst _hInstance +#define hPrev _hPrev + +#endif + + +#if !defined ( hInst ) || !defined ( hPrev ) +#error Your compiler is not (yet) supported. Check the source file! +#endif + +/* ---- Common initialisations ------------------------------------------- */ + +/* Size of the window. */ +#define WIN_WIDTH 640u +#define WIN_HEIGHT 400u +/* The values will be divided by 2 for gray-scale rendering. */ + +/* These values can be changed, but WIN_WIDTH should remain for now a */ +/* multiple of 32 to avoid padding issues. */ + +/* Also, to avoid 16-bit overflowing issues, the product */ +/* WIN_WIDTH * WIN_HEIGHT should not excess 512K for monochrome */ +/* rendering, and 256K for gray-scale rendering. */ + + + typedef struct _Translator + { + char key; + GEvent event_class; + int event_info; + } Translator; + +#define NUM_Translators 20 + + static const Translator trans[NUM_Translators] = + { + { (char)27, event_Quit, 0 }, + { 'q', event_Quit, 0 }, + + { 'x', event_Rotate_Glyph, -1 }, + { 'c', event_Rotate_Glyph, 1 }, + { 'v', event_Rotate_Glyph, -16 }, + { 'b', event_Rotate_Glyph, 16 }, + + { '{', event_Change_Glyph, -10000 }, + { '}', event_Change_Glyph, 10000 }, + { '(', event_Change_Glyph, -1000 }, + { ')', event_Change_Glyph, 1000 }, + { '9', event_Change_Glyph, -100 }, + { '0', event_Change_Glyph, 100 }, + { 'i', event_Change_Glyph, -10 }, + { 'o', event_Change_Glyph, 10 }, + { 'k', event_Change_Glyph, -1 }, + { 'l', event_Change_Glyph, 1 }, + + { '+', event_Scale_Glyph, 10 }, + { '-', event_Scale_Glyph, -10 }, + { 'u', event_Scale_Glyph, 1 }, + { 'j', event_Scale_Glyph, -1 } + }; + + /* handle of the window. */ + static HWND hwndGraphic; + + /* bitmap information */ + static LPBITMAPINFO pbmi; + static HBITMAP hbm; + + /* local event to pass on */ + static TEvent ourevent = { event_Quit, 0 }; + static int eventToProcess = 0; + + /* array defined in the test programs */ + extern char Header[]; + + +/* restores screen to its original state */ + +int Driver_Restore_Mode() + { + /* The graphical window has perhaps already destroyed itself */ + if ( hwndGraphic ) { + DestroyWindow ( hwndGraphic ); + PostMessage ( hwndGraphic, WM_QUIT, 0, 0 ); + } + + if ( pbmi ) free ( pbmi ); + + return 1; + } + + +/* + * set graphics mode + * and create the window class and the message handling. + */ + +/* Declarations of the Windows-specific functions that are below. */ +static BOOL RegisterTheClass ( void ); +static BOOL CreateTheWindow ( int width, int height ); + + +int Driver_Set_Graphics ( int mode ) + { + int i; + static const RGBQUAD gray_scale[5] = { + { 0xFF, 0xFF, 0xFF, 0 }, /* white */ + { 0xC0, 0xC0, 0xC0, 0 }, + { 0x80, 0x80, 0x80, 0 }, + { 0x40, 0x40, 0x40, 0 }, + { 0, 0, 0, 0 } }; /* black */ + + if( ! RegisterTheClass() ) return 0; /* if already running, fails. */ + + /* find some memory for the bitmap header */ + if ( (pbmi = malloc ( sizeof ( BITMAPINFO ) + sizeof ( RGBQUAD ) * 256 ) ) + /* 256 should really be 2 if not grayscale */ + == NULL ) + /* lack of memory; fails the process */ + return 0; + + /* initialize the header to appropriate values */ + memset( pbmi, 0, sizeof ( BITMAPINFO ) + sizeof ( RGBQUAD ) * 256 ); + + switch ( mode ) + { + case Graphics_Mode_Mono: + pbmi->bmiHeader.biBitCount = 1; + pbmi->bmiColors[0] = gray_scale[0]; + pbmi->bmiColors[1] = gray_scale[4]; + + vio_ScanLineWidth = WIN_WIDTH / 8; + vio_Width = WIN_WIDTH; + vio_Height = WIN_HEIGHT; + + break; + + case Graphics_Mode_Gray: + pbmi->bmiHeader.biBitCount = 8; + pbmi->bmiHeader.biClrUsed = 5; + + memcpy ( &pbmi->bmiColors[0], gray_scale, sizeof gray_scale ); + + vio_ScanLineWidth = WIN_WIDTH / 2; + vio_Width = WIN_WIDTH / 2; + vio_Height = WIN_HEIGHT/ 2; + + for ( i = 0; i < 5; ++i ) + gray_palette[i] = i; + + break; + + default: + + free ( pbmi ); + return 0; /* Unknown mode */ + } + + pbmi->bmiHeader.biSize = sizeof ( BITMAPINFOHEADER ); + pbmi->bmiHeader.biWidth = vio_Width; + pbmi->bmiHeader.biHeight = vio_Height; + pbmi->bmiHeader.biPlanes = 1; + + if ( (long) vio_Height * vio_ScanLineWidth > 0xFFE0ul ) + /* too big to work on 16-bit; fails the process */ + { + free ( pbmi ); + return 0; + } + + if( ! CreateTheWindow ( vio_Width, vio_Height ) ) + { + free ( pbmi ); + return 0; + } + + return 1; /* success even if the window was not built. */ + } + + +int Driver_Display_Bitmap ( char* buffer, int lines, int cols ) + { + HDC hDC; + + if ( cols * 8 != pbmi->bmiHeader.biWidth * pbmi->bmiHeader.biBitCount ) + pbmi->bmiHeader.biWidth = cols * 8 / pbmi->bmiHeader.biBitCount; + + hDC = GetDC ( hwndGraphic ); + SetDIBits ( hDC, hbm, 0, lines, buffer, pbmi, DIB_RGB_COLORS ); + ReleaseDC ( hwndGraphic, hDC ); + + ShowWindow( hwndGraphic, SW_SHOW ); + InvalidateRect ( hwndGraphic, NULL, FALSE ); + UpdateWindow ( hwndGraphic ); + + return 1; /* success */ + } + + +void Get_Event( TEvent* event ) + { + MSG msg; + + if ( hwndGraphic ) + { + SetWindowText ( hwndGraphic, Header ); + } + + do { + while ( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) ) { + TranslateMessage ( &msg ); + DispatchMessage ( &msg ); + } + if ( ! eventToProcess ) + WaitMessage(); + } while ( ! eventToProcess ); + + event->what = ourevent.what; + event->info = ourevent.info; + eventToProcess = 0; + return; + } + + +/* ---- Windows-specific stuff ------------------------------------------- */ + +LRESULT CALLBACK Message_Process( HWND, UINT, WPARAM, LPARAM ); + +static +BOOL RegisterTheClass ( void ) + { + WNDCLASS ourClass = { + /* UINT style */ 0, + /* WNDPROC lpfnWndProc */ Message_Process, + /* int cbClsExtra */ 0, + /* int cbWndExtra */ 0, + /* HANDLE hInstance */ 0, + /* HICON hIcon */ 0, + /* HCURSOR hCursor */ 0, + /* HBRUSH hbrBackground*/ 0, + /* LPCTSTR lpszMenuName */ NULL, + /* LPCTSTR lpszClassName*/ "FreeTypeTestGraphicDriver16" + }; + + if( hPrev ) + /* There is another instance of the same program. */ + /* No need to register the class. */ + return 1; + + ourClass.hInstance = hInst; + ourClass.hIcon = LoadIcon(0, IDI_APPLICATION); + ourClass.hCursor = LoadCursor(0, IDC_ARROW); + ourClass.hbrBackground= GetStockObject(BLACK_BRUSH); + + return RegisterClass(&ourClass) != 0; /* return False if it fails. */ + } + +static +BOOL CreateTheWindow ( int width, int height ) + { + if ( ! (hwndGraphic = CreateWindow( + /* LPCSTR lpszClassName; */ "FreeTypeTestGraphicDriver16", + /* LPCSTR lpszWindowName; */ "FreeType Test Graphic Driver", + /* DWORD dwStyle; */ WS_OVERLAPPED | WS_SYSMENU, + /* int x; */ CW_USEDEFAULT, + /* int y; */ CW_USEDEFAULT, + /* int nWidth; */ width + 2*GetSystemMetrics(SM_CXBORDER), + /* int nHeight; */ height+ GetSystemMetrics(SM_CYBORDER) + + GetSystemMetrics(SM_CYCAPTION), + /* HWND hwndParent; */ HWND_DESKTOP, + /* HMENU hmenu; */ 0, + /* HINSTANCE hinst; */ hInst, + /* void FAR* lpvParam; */ NULL)) + ) + /* creation failed... */ + return 0; + + return 1; + } + + /* Message processing for our Windows class */ +LRESULT CALLBACK Message_Process( HWND handle, UINT mess, + WPARAM wParam, LPARAM lParam ) + { + + switch( mess ) + { + case WM_DESTROY: + /* warn the main thread to quit if it didn't know */ + ourevent.what = event_Quit; + ourevent.info = 0; + eventToProcess = 1; + hwndGraphic = 0; + PostQuitMessage ( 0 ); + DeleteObject ( hbm ); + break; + + case WM_CREATE: + { + HDC hDC; + + hDC = GetDC ( handle ); + hbm = CreateDIBitmap ( + /* HDC hdc; handle of device context */ hDC, + /* BITMAPINFOHEADER FAR* lpbmih; addr.of header*/ &pbmi->bmiHeader, + /* DWORD dwInit; CBM_INIT to initialize bitmap */ 0, + /* const void FAR* lpvBits; address of values */ NULL, + /* BITMAPINFO FAR* lpbmi; addr.of bitmap data */ pbmi, + /* UINT fnColorUse; RGB or palette indices */ DIB_RGB_COLORS); + ReleaseDC ( handle, hDC ); + break; + } + + case WM_PAINT: + { + HDC hDC, memDC; + HANDLE oldbm; + PAINTSTRUCT ps; + + hDC = BeginPaint ( handle, &ps ); + memDC = CreateCompatibleDC(hDC); + oldbm = SelectObject(memDC, hbm); + BitBlt ( hDC, 0, 0, vio_Width, vio_Height, memDC, 0, 0, SRCCOPY); + ReleaseDC ( handle, hDC ); + SelectObject ( memDC, oldbm ); + DeleteObject ( memDC ); + EndPaint ( handle, &ps ); + } + + case WM_KEYDOWN: + switch ( wParam ) + { + case VK_ESCAPE: + ourevent.what = event_Quit; + ourevent.info = 0; + eventToProcess = 1; + break; + + case VK_F1: /* bring up help and about dialog window */ + break; + } + break; + + case WM_CHAR: + { + char c = wParam ; + int i; + + for ( i = 0; i < NUM_Translators; i++ ) + { + if ( c == trans[i].key ) + { + ourevent.what = trans[i].event_class; + ourevent.info = trans[i].event_info; + eventToProcess = 1; + return 0; + } + } + + /* unrecognized keystroke */ + ourevent.what = event_Keyboard; + ourevent.info = (int)c; + eventToProcess = 1; + } + break; + + default: + return DefWindowProc( handle, mess, wParam, lParam ); + } + + return 0; + } + +/* End */ diff --git a/test/arch/win16/makedep b/test/arch/win16/makedep new file mode 100644 index 0000000..6bfe565 --- /dev/null +++ b/test/arch/win16/makedep @@ -0,0 +1,30 @@ +# makedep +# +# This shell script creates a dependency file necessary for older compilers +# on the Windows 16-bit platform. +# +# If you run this script under non-Windows operating systems, expect +# warnings that `windows.h' can't be found. + +echo "\ +# This dependency file to be used with various Windows compilers +# has been generated automatically with the script \`makedep' on +# `date +%d-%b-%Y`. +" > depend.win + +(cd ../.. + gcc -MM -I../lib/arch/win16 -I../lib -I../lib/extend -I. \ + *.c | \ + sed -e "s/\.o:/.obj:/" -e "s:/:\\\\:g") >> depend.win + +echo "!ifndef __MAKE__" >> depend.win + +(cd ../.. + gcc -MM -I../lib/arch/win16 -I../lib -I../lib/extend -I. \ + -DhInst -DhPrev arch/win16/*.c | \ + sed -e "s/^\(.*\)\.o:/arch\\\\win16\\\\\1.obj:/" \ + -e "s:/:\\\\:g") >> depend.win + +echo "!endif" >> depend.win + +# eof diff --git a/test/arch/win32/Makefile.BC b/test/arch/win32/Makefile.BC new file mode 100644 index 0000000..9acb6ca --- /dev/null +++ b/test/arch/win32/Makefile.BC @@ -0,0 +1,197 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for BC++ for Win32. +# +# Tested with Borland C++ v.4.02, 5.0, and Borland C++ builder 4. +# You will need Borland MAKE. +# +# +# Use this file while in the 'test' directory with the following statement: +# +# make -farch\win32\Makefile.BC +# +# +# A DLL version of the library can be built and then used with +# +# make -DDLL -farch/win16/Makefile.BC dll +# +# (do not forget to define DLL, otherwise the link phase will fail). +# +# +# A debug version can be obtained with +# +# make -DDEBUG -farch\win32\Makefile.BC + +ARCH = arch\win32 +FT_MAKEFILE = $(ARCH)\Makefile.BC +FT_DLL = ft13_32.dll + +CC = bcc32 + +LIBDIR = ..\lib +INCDIRS = -I$(LIBDIR);$(LIBDIR)\$(ARCH);.;$(LIBDIR)\extend +SPURIOUS_WARNINGS = -w-nak -w-par -w-use -w-aus -w-stu -w-stv -w-cln -w-sig -w-pia +CFLAGS = -i48 $(INCDIRS) $(SPURIOUS_WARNINGS) + +!ifndef DEBUG +CFLAGS = $(CFLAGS) -O2 -A +LDFLAGS = -WC +!else +CFLAGS = $(CFLAGS) -v +LDFLAGS = -v -WC +!endif + +!ifdef DLL +CFLAGS = $(CFLAGS) -DFREETYPE_DLL +!endif + +# Windows graphic driver +GDRIVER = $(ARCH)\gw_win32.c + +DISPLAY = display.c + +G1SRC = gmain.c blitter.c $(GDRIVER) +GSRC = $(DISPLAY) $(G1SRC) + +GOBJ = $(GSRC:.c=.obj) +G1OBJ = $(G1SRC:.c=.obj) + + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +OBJ = $(SRC:.c=.obj) + + +.c.obj: + $(CC) -c -o$* @&&| + $(CFLAGS) $< +| + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + +!ifndef DEBUG +# Skipped if DEBUG build +all: freetype $(EXEFILES) + +dll: the_dll $(EXEFILES) + +!else +# Skipped if non-DEBUG build +default_target: debug +dll: the_debug_dll $(EXEFILES) + +!endif + +debug: freetype_debug $(EXEFILES) + +freetype: + cd $(LIBDIR) + make -f$(FT_MAKEFILE) all + cd ..\test + +freetype_debug: + cd $(LIBDIR) + make -f$(FT_MAKEFILE) -DDEBUG debug + cd ..\test + +the_dll: + cd $(LIBDIR) + make -f$(FT_MAKEFILE) -DDLL dll + cd ..\test + -copy $(LIBDIR)\$(FT_DLL) + +the_debug_dll: + cd $(LIBDIR) + make -f$(FT_MAKEFILE) -DDEBUG -DDLL dll + cd ..\test + -copy $(LIBDIR)\$(FT_DLL) + + +# C compilers are unable to include in ANSI mode, +# because of the // comments... +# So we have a special rule for this file, to build it outside ANSI. +$(GDRIVER:.c=.obj): + $(CC) -c -o$* @&&| + $(CFLAGS) -A- $*.c +| + + +# Borland versions of make are unable to use the $** variable inside +# implicit rules (like .obj.exe:). The job have to be done by hand. :-( +ftzoom.exe: $(G1OBJ) ftzoom.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftzoom.obj $(G1OBJ) common.obj $(LIBDIR)\libttf.lib + +ftview.exe: $(GOBJ) ftview.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftview.obj $(GOBJ) common.obj $(LIBDIR)\libttf.lib + +ftstring.exe: $(GOBJ) ftstring.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftstring.obj $(GOBJ) common.obj $(LIBDIR)\libttf.lib + +ftstrtto.exe: $(GOBJ) ftstrtto.obj common.obj arabic.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftstrtto.obj $(GOBJ) common.obj arabic.obj \ + $(LIBDIR)\libttf.lib + +fttimer.exe: $(G1OBJ) fttimer.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) fttimer.obj $(G1OBJ) common.obj $(LIBDIR)\libttf.lib + +ftlint.exe: ftlint.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftlint.obj common.obj $(LIBDIR)\libttf.lib + +ftdump.exe: ftdump.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftdump.obj common.obj $(LIBDIR)\libttf.lib + +ftstrpnm.exe: ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib + +ftsbit.exe: ftsbit.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftsbit.obj common.obj $(LIBDIR)\libttf.lib + +ftmetric.exe: ftmetric.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftmetric.obj common.obj $(LIBDIR)\libttf.lib + +fterror.exe: fterror.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) fterror.obj common.obj $(LIBDIR)\libttf.lib + + +clean: do_clean + cd $(LIBDIR) + make -f$(FT_MAKEFILE) clean + cd ..\test + +distclean: do_clean + cd $(LIBDIR) + make -f$(FT_MAKEFILE) distclean + cd ..\test + -del *.exe + -del *.dll + +do_clean: + -del *.obj + -del $(ARCH)\*.obj + -del *.tds + +!include "$(ARCH)\depend.win" + +# end of Makefile diff --git a/test/arch/win32/Makefile.CL b/test/arch/win32/Makefile.CL new file mode 100644 index 0000000..246c71f --- /dev/null +++ b/test/arch/win32/Makefile.CL @@ -0,0 +1,175 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for Microsoft Visual C++. +# +# You will need NMAKE. +# +# +# Use this file while in the 'test' directory with the following statement: +# +# nmake /f arch\win32\Makefile.CL +# +# A DLL version of the library can be built and then used with +# +# nmake DLL=1 /f arch\win32\Makefile.CL dll +# +# (do not forget to define DLL, otherwise the link phase will fail). +# +# +# Debug versions can be obtained with +# +# nmake DEBUG=1 /f arch\win32\Makefile.CL + +ARCH = arch\win32 +FT_MAKEFILE = $(ARCH)\Makefile.CL +FT_MAKE = $(MAKE) /nologo +FT_DLL = ft13_32.dll + +CC = cl /nologo + +LIBDIR = ..\lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)\$(ARCH) -I. -I$(LIBDIR)\extend + +CFLAGS_ANSI = /Za +!ifndef DEBUG +CFLAGS = /Ox /W2 $(INCDIRS) +LDFLAGS = +!else +CFLAGS = /Zi /Ge /W2 $(INCDIRS) +LDFLAGS = /Zi +!endif + +!ifdef DLL +CFLAGS = $(CFLAGS) /DEXPORT_DEF=__declspec(dllexport) /DFREETYPE_DLL +!endif + + +# Windows graphic driver +GDRIVER = $(ARCH)\gw_win32.c + +GSRC = display.c gmain.c blitter.c $(GDRIVER) + +GOBJ = $(GSRC:.c=.obj) + + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +OBJ = $(SRC:.c=.obj) + + +.c.obj: + @$(CC) /c /Fo$* @<< + $(CFLAGS) $(CFLAGS_ANSI) $< +<< + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + +!ifndef DEBUG +# Skiped if DEBUG build +all: freetype $(EXEFILES) + +dll: the_dll $(EXEFILES) + +!else +# Skipped if non-DEBUG build +default_target: debug +dll: the_debug_dll $(EXEFILES) + +!endif + +debug: freetype_debug $(EXEFILES) + +freetype: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) all + cd ..\test + +freetype_debug: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) DEBUG=1 debug + cd ..\test + +the_dll: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) DLL=1 dll + cd ..\test + -copy $(LIBDIR)\$(FT_DLL) + +the_debug_dll: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) DEBUG=1 DLL=1 dll + cd ..\test + -copy $(LIBDIR)\$(FT_DLL) + + +# C compilers are unable to include 32-bit in ANSI mode. +# So we have a special rule for this file, to build it outside ANSI. +$(GDRIVER:.c=.obj): + $(CC) /c /Fo$* @<< + $(CFLAGS) /Ze $(GDRIVER) +<< + +.obj.exe: + $(CC) /Fe$* @<< + $(LDFLAGS) $** GDI32.LIB USER32.LIB +<< + +ftzoom.exe: $(GOBJ) ftzoom.obj common.obj $(LIBDIR)\libttf.lib +ftview.exe: $(GOBJ) ftview.obj common.obj $(LIBDIR)\libttf.lib +ftstring.exe: $(GOBJ) ftstring.obj common.obj $(LIBDIR)\libttf.lib +ftstrtto.exe: $(GOBJ) ftstrtto.obj common.obj arabic.obj $(LIBDIR)\libttf.lib +fttimer.exe: $(GOBJ) fttimer.obj common.obj $(LIBDIR)\libttf.lib +ftlint.exe: ftlint.obj common.obj $(LIBDIR)\libttf.lib +ftdump.exe: ftdump.obj common.obj $(LIBDIR)\libttf.lib +ftstrpnm.exe: ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib +ftsbit.exe: ftsbit.obj common.obj $(LIBDIR)\libttf.lib +ftmetric.exe: ftmetric.obj common.obj $(LIBDIR)\libttf.lib +fterror.exe: fterror.obj common.obj $(LIBDIR)\libttf.lib + + +clean: do_clean + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) clean + cd ..\test + +distclean: do_clean + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) distclean + cd ..\test + -del *.exe + -del *.dll + -del *.pdb + +do_clean: + -del *.obj + -del $(ARCH)\*.obj + -del *.ilk + -del *.pch + -del *.exp + + +!include "$(ARCH)\depend.win" + +# end of Makefile.CL diff --git a/test/arch/win32/Makefile.Min b/test/arch/win32/Makefile.Min new file mode 100644 index 0000000..e0c05c2 --- /dev/null +++ b/test/arch/win32/Makefile.Min @@ -0,0 +1,122 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for MinGW32 gcc under Win9x. +# +# You will need a port of GNU make; the MingW32 port works. +# +# Use this file while in the 'test' directory with the following statement: +# +# make -f arch/win32/Makefile.min + +ARCH = arch/win32 +FT_MAKEFILE = $(ARCH)/Makefile.min + +CC = gcc + +LIBDIR = ../lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)/$(ARCH) -I. -I$(LIBDIR)/extend + +ifdef DEBUG + +CFLAGS = -ansi -pedantic -Wall -O2 -g $(INCDIRS) +LDFLAGS = -g -luser32 -lgdi32 + +else + +CFLAGS = -ansi -pedantic -Wall -O2 -s $(INCDIRS) +LDFLAGS = -s -luser32 -lgdi32 + +endif + + +# graphic Windows driver +GDRIVER = $(ARCH)/gw_win32.c + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +GSRC = gmain.c display.c blitter.c $(GDRIVER) +GOBJ = $(GSRC:.c=.o) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + + +%.exe: + $(CC) $(LDFLAGS) -o $@ $^ + + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + +.PHONY: all debug freetype freetype_debug \ + clean distclean do_clean depend + + +all: freetype $(EXEFILES) + +debug: freetype_debug $(EXEFILES) + +freetype: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) all + +freetype_debug: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) debug + +ftzoom.exe: $(GOBJ) ftzoom.o common.o $(LIBDIR)/libttf.a +ftview.exe: $(GOBJ) ftview.o common.o $(LIBDIR)/libttf.a +ftlint.exe: ftlint.o common.o $(LIBDIR)/libttf.a +ftdump.exe: ftdump.o common.o $(LIBDIR)/libttf.a +fterror.exe: fterror.o common.o $(LIBDIR)/libttf.a +ftstring.exe: $(GOBJ) ftstring.o common.o $(LIBDIR)/libttf.a +fttimer.exe: $(GOBJ) fttimer.o common.o $(LIBDIR)/libttf.a +ftstrpnm.exe: ftstrpnm.o common.o $(LIBDIR)/libttf.a +ftsbit.exe: ftsbit.o common.o $(LIBDIR)/libttf.a +ftmetric.exe: ftmetric.o common.o $(LIBDIR)/libttf.a +ftstrtto.exe: $(GOBJ) ftstrtto.o common.o arabic.o $(LIBDIR)/libttf.a + + +clean: do_clean + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) clean + +distclean: do_clean + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) distclean + -del dep.end + -del *.exe + -del core + +do_clean: + -del *.o + -del response + -del $(subst /,\,$(GDRIVER:.c=.o)) + +depend: $(SRC) $(GSRC) + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) depend + $(CC) -E -M $(INCDIRS) $^ > dep.end + +ifeq (dep.end,$(wildcard dep.end)) + include dep.end +endif + +# end of Makefile.gcc diff --git a/test/arch/win32/Makefile.gcc b/test/arch/win32/Makefile.gcc new file mode 100644 index 0000000..01ccb6c --- /dev/null +++ b/test/arch/win32/Makefile.gcc @@ -0,0 +1,131 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for gcc under Win32. +# +# You will need GNU make. +# +# Use this file while in the 'test' directory with the following statement: +# +# make -f arch/win32/Makefile.gcc +# +# +# If you have the GNU gettext package installed, you can also try +# +# make -f arch/win32/Makefile.gcc HAVE_GETTEXT + +ARCH = arch/win32 +FT_MAKEFILE = $(ARCH)/Makefile.gcc + +CC = gcc + +LIBDIR = ../lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)/$(ARCH) -I. -I$(LIBDIR)/extend + +ifndef GETTEXT +GETTEXT=NO_GETTEXT +endif + +CFLAGS = -Wall -ansi -O2 -g $(INCDIRS) +# -D$(GETTEXT) +# CFLAGS = -ansi -Wall -O2 -s $(INCDIRS) -D$(GETTEXT) + + +# graphic Windows driver +GDRIVER = $(ARCH)/gw_win32.c + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +GSRC = gmain.c display.c blitter.c $(GDRIVER) +GOBJ = $(GSRC:.c=.o) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + + +ifeq ($(GETTEXT),HAVE_GETTEXT) +%.exe: + $(CC) $(CFLAGS) -o $@ $^ -lintl +else +%.exe: + $(CC) $(CFLAGS) -o $@ $^ +endif + + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + +.PHONY: all debug freetype freetype_debug \ + clean distclean do_clean depend + + +all: freetype $(EXEFILES) + +debug: freetype_debug $(EXEFILES) + +HAVE_GETTEXT: + $(MAKE) -f $(FT_MAKEFILE) GETTEXT=HAVE_GETTEXT all + +freetype: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) all + +freetype_debug: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) debug + +ftzoom.exe: $(GOBJ) ftzoom.o common.o $(LIBDIR)/libttf.a +ftview.exe: $(GOBJ) ftview.o common.o $(LIBDIR)/libttf.a +ftlint.exe: ftlint.o common.o $(LIBDIR)/libttf.a +ftdump.exe: ftdump.o common.o $(LIBDIR)/libttf.a +fterror.exe: fterror.o common.o $(LIBDIR)/libttf.a +ftstring.exe: $(GOBJ) ftstring.o common.o $(LIBDIR)/libttf.a +fttimer.exe: $(GOBJ) fttimer.o common.o $(LIBDIR)/libttf.a +ftstrpnm.exe: ftstrpnm.o common.o $(LIBDIR)/libttf.a +ftsbit.exe: ftsbit.o common.o $(LIBDIR)/libttf.a +ftmetric.exe: ftmetric.o common.o $(LIBDIR)/libttf.a +ftstrtto.exe: $(GOBJ) ftstrtto.o common.o arabic.o $(LIBDIR)/libttf.a + + +clean: do_clean + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) clean + +distclean: do_clean + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) distclean + -del dep.end + -del *.exe + -del core + +do_clean: + -del *.o + -del response + -del $(GDRIVER:.c=.o) + +depend: $(SRC) $(GSRC) + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) depend + $(CC) -E -M $(INCDIRS) $^ > dep.end + +ifeq (dep.end,$(wildcard dep.end)) + include dep.end +endif + +# end of Makefile.gcc diff --git a/test/arch/win32/depend.win b/test/arch/win32/depend.win new file mode 100644 index 0000000..69916dd --- /dev/null +++ b/test/arch/win32/depend.win @@ -0,0 +1,52 @@ +# This dependency file to be used with various Windows compilers +# has been generated automatically with the script `makedep' on +# 03-Sep-1999. + +arabic.obj: arabic.c arabic.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxopen.h ..\lib\extend\ftxgdef.h \ + ..\lib\extend\ftxgsub.h ..\lib\extend\ftxgpos.h +blitter.obj: blitter.c blitter.h +common.obj: common.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h +display.obj: display.c display.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h gmain.h +fdebug.obj: fdebug.c ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\tttypes.h ..\lib\ttconfig.h \ + ..\lib\arch\win32\ft_conf.h ..\lib\ttdebug.h ..\lib\ttobjs.h \ + ..\lib\ttengine.h ..\lib\ttmutex.h ..\lib\ttcache.h ..\lib\tttables.h \ + ..\lib\ttcmap.h +ftdump.obj: ftdump.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxcmap.h ..\lib\extend\ftxopen.h \ + ..\lib\extend\ftxgdef.h ..\lib\extend\ftxgsub.h \ + ..\lib\extend\ftxgpos.h ..\lib\extend\ftxsbit.h ..\lib\ttobjs.h \ + ..\lib\ttconfig.h ..\lib\arch\win32\ft_conf.h ..\lib\ttengine.h \ + ..\lib\tttypes.h ..\lib\ttmutex.h ..\lib\ttcache.h ..\lib\tttables.h \ + ..\lib\ttcmap.h +fterror.obj: fterror.c ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxerr18.h \ + ..\lib\arch\win32\ft_conf.h +ftlint.obj: ftlint.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\arch\win32\ft_conf.h +ftmetric.obj: ftmetric.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxsbit.h ..\lib\arch\win32\ft_conf.h +ftsbit.obj: ftsbit.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxsbit.h ..\lib\arch\win32\ft_conf.h +ftstring.obj: ftstring.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h display.h gevents.h gdriver.h gmain.h +ftstrpnm.obj: ftstrpnm.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h +ftstrtto.obj: ftstrtto.c arabic.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxopen.h ..\lib\extend\ftxgdef.h \ + ..\lib\extend\ftxgsub.h ..\lib\extend\ftxgpos.h blitter.h common.h \ + display.h ..\lib\extend\ftxkern.h ..\lib\extend\ftxsbit.h gdriver.h \ + gevents.h gmain.h +fttimer.obj: fttimer.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h gdriver.h gevents.h gmain.h +ftview.obj: ftview.c blitter.h common.h display.h \ + ..\lib\extend\ftxsbit.h gdriver.h gevents.h gmain.h +ftzoom.obj: ftzoom.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxpost.h gdriver.h gevents.h gmain.h +gmain.obj: gmain.c gdriver.h gmain.h +!ifndef __MAKE__ +arch\win32\gw_win32.obj: arch\win32\gw_win32.c gdriver.h gevents.h gmain.h +!endif diff --git a/test/arch/win32/gw_win32.c b/test/arch/win32/gw_win32.c new file mode 100644 index 0000000..3b34c80 --- /dev/null +++ b/test/arch/win32/gw_win32.c @@ -0,0 +1,378 @@ +/******************************************************************* + * + * gw_win32.c graphics driver for Win32 platform. 0.1 + * + * This is the driver for displaying inside a window under Win32, + * used by the graphics utility of the FreeType test suite. + * + * Written by Antoine Leca. + * Copyright 1999 by Antoine Leca, + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * Borrowing liberally from the other FreeType drivers. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include +#include +#include + +#define WIN32_LEAN_AND_MEAN +#include + +#include "gdriver.h" +#include "gevents.h" +#include "gmain.h" + + +/* Size of the window. */ +#define WIN_WIDTH 640u +#define WIN_HEIGHT 450u + +/* These values can be changed, but WIN_WIDTH should remain for now a */ +/* multiple of 32 to avoid padding issues. */ + + + typedef struct _Translator + { + char key; + GEvent event_class; + int event_info; + } Translator; + +#define NUM_Translators 20 + + static const Translator trans[NUM_Translators] = + { + { (char)27, event_Quit, 0 }, + { 'q', event_Quit, 0 }, + + { 'x', event_Rotate_Glyph, -1 }, + { 'c', event_Rotate_Glyph, 1 }, + { 'v', event_Rotate_Glyph, -16 }, + { 'b', event_Rotate_Glyph, 16 }, + + { '{', event_Change_Glyph, -10000 }, + { '}', event_Change_Glyph, 10000 }, + { '(', event_Change_Glyph, -1000 }, + { ')', event_Change_Glyph, 1000 }, + { '9', event_Change_Glyph, -100 }, + { '0', event_Change_Glyph, 100 }, + { 'i', event_Change_Glyph, -10 }, + { 'o', event_Change_Glyph, 10 }, + { 'k', event_Change_Glyph, -1 }, + { 'l', event_Change_Glyph, 1 }, + + { '+', event_Scale_Glyph, 10 }, + { '-', event_Scale_Glyph, -10 }, + { 'u', event_Scale_Glyph, 1 }, + { 'j', event_Scale_Glyph, -1 } + }; + + /* handle of the window. */ + static HWND hwndGraphic; + + /* bitmap information */ + static LPBITMAPINFO pbmi; + static HBITMAP hbm; + + /* local event to pass on */ + static TEvent ourevent = { event_Quit, 0 }; + static int eventToProcess = 0; + + /* array defined in the test programs */ + extern char Header[]; + + +/* restores screen to its original state */ + +int Driver_Restore_Mode() + { + /* The graphical window has perhaps already destroyed itself */ + if ( hwndGraphic ) { + DestroyWindow ( hwndGraphic ); + PostMessage( hwndGraphic, WM_QUIT, 0, 0 ); + } + + if ( pbmi ) free ( pbmi ); + + return 1; + } + + +/* + * set graphics mode + * and create the window class and the message handling. + */ + +/* Declarations of the Windows-specific functions that are below. */ +static BOOL RegisterTheClass ( void ); +static BOOL CreateTheWindow ( int width, int height ); + + +int Driver_Set_Graphics ( int mode ) + { + int i; + static RGBQUAD gray_scale[5] = { + { 0xFF, 0xFF, 0xFF, 0 }, /* white */ + { 0xC0, 0xC0, 0xC0, 0 }, + { 0x80, 0x80, 0x80, 0 }, + { 0x40, 0x40, 0x40, 0 }, + { 0, 0, 0, 0 } }; /* black */ + + if( ! RegisterTheClass() ) return 0; /* if already running, fails. */ + + /* find some memory for the bitmap header */ + if ( (pbmi = malloc ( sizeof ( BITMAPINFO ) + sizeof ( RGBQUAD ) * 256 ) ) + /* 256 should really be 2 if not grayscale */ + == NULL ) + /* lack of memory; fails the process */ + return 0; + + /* initialize the header to appropriate values */ + memset( pbmi, 0, sizeof ( BITMAPINFO ) + sizeof ( RGBQUAD ) * 256 ); + + switch ( mode ) + { + case Graphics_Mode_Mono: + pbmi->bmiHeader.biBitCount = 1; + pbmi->bmiColors[0] = gray_scale[0]; + pbmi->bmiColors[1] = gray_scale[4]; + + vio_ScanLineWidth = WIN_WIDTH / 8; + vio_Width = WIN_WIDTH; + vio_Height = WIN_HEIGHT; + + break; + + case Graphics_Mode_Gray: + pbmi->bmiHeader.biBitCount = 8; + pbmi->bmiHeader.biClrUsed = 5; + + memcpy ( &pbmi->bmiColors[0], gray_scale, sizeof gray_scale ); + + vio_ScanLineWidth = WIN_WIDTH; + vio_Width = WIN_WIDTH; + vio_Height = WIN_HEIGHT; + + for ( i = 0; i < 5; ++i ) + gray_palette[i] = i; + + break; + + default: + free ( pbmi ); + return 0; /* Unknown mode */ + } + + pbmi->bmiHeader.biSize = sizeof ( BITMAPINFOHEADER ); + pbmi->bmiHeader.biWidth = vio_Width; + pbmi->bmiHeader.biHeight = vio_Height; + pbmi->bmiHeader.biPlanes = 1; + + if( ! CreateTheWindow(vio_Width, vio_Height) ) + { + free ( pbmi ); + return 0; + } + + return 1; /* success even if the window was not built. */ + } + + +int Driver_Display_Bitmap ( char* buffer, int lines, int cols ) + { + HDC hDC; + + if ( cols * 8 != pbmi->bmiHeader.biWidth * pbmi->bmiHeader.biBitCount ) + pbmi->bmiHeader.biWidth = cols * 8 / pbmi->bmiHeader.biBitCount; + + hDC = GetDC ( hwndGraphic ); + SetDIBits ( hDC, hbm, 0, lines, buffer, pbmi, DIB_RGB_COLORS ); + ReleaseDC ( hwndGraphic, hDC ); + + ShowWindow( hwndGraphic, SW_SHOW ); + InvalidateRect ( hwndGraphic, NULL, FALSE ); + UpdateWindow ( hwndGraphic ); + + return 1; /* success */ + } + + +void Get_Event( TEvent* event ) + { + MSG msg; + + if ( hwndGraphic ) + { + SetWindowText ( hwndGraphic, Header ); + } + + do { + while ( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) ) { + TranslateMessage ( &msg ); + DispatchMessage ( &msg ); + } + if ( ! eventToProcess ) + WaitMessage(); + } while ( ! eventToProcess ); + + event->what = ourevent.what; + event->info = ourevent.info; + eventToProcess = 0; + return; + } + + +/* ---- Windows-specific stuff ------------------------------------------- */ + +LRESULT CALLBACK Message_Process( HWND, UINT, WPARAM, LPARAM ); + +static +BOOL RegisterTheClass ( void ) + { + WNDCLASS ourClass = { + /* UINT style */ 0, + /* WNDPROC lpfnWndProc */ Message_Process, + /* int cbClsExtra */ 0, + /* int cbWndExtra */ 0, + /* HANDLE hInstance */ 0, + /* HICON hIcon */ 0, + /* HCURSOR hCursor */ 0, + /* HBRUSH hbrBackground*/ 0, + /* LPCTSTR lpszMenuName */ NULL, + /* LPCTSTR lpszClassName*/ "FreeTypeTestGraphicDriver" + }; + + ourClass.hInstance = GetModuleHandle( NULL ); + ourClass.hIcon = LoadIcon(0, IDI_APPLICATION); + ourClass.hCursor = LoadCursor(0, IDC_ARROW); + ourClass.hbrBackground= GetStockObject(BLACK_BRUSH); + + return RegisterClass(&ourClass) != 0; /* return False if it fails. */ + } + +static +BOOL CreateTheWindow ( int width, int height ) + { + + if ( ! (hwndGraphic = CreateWindow( + /* LPCSTR lpszClassName; */ "FreeTypeTestGraphicDriver", + /* LPCSTR lpszWindowName; */ "FreeType Test Graphic Driver", + /* DWORD dwStyle; */ WS_OVERLAPPED | WS_SYSMENU, + /* int x; */ CW_USEDEFAULT, + /* int y; */ CW_USEDEFAULT, + /* int nWidth; */ width + 2*GetSystemMetrics(SM_CXBORDER), + /* int nHeight; */ height+ GetSystemMetrics(SM_CYBORDER) + + GetSystemMetrics(SM_CYCAPTION), + /* HWND hwndParent; */ HWND_DESKTOP, + /* HMENU hmenu; */ 0, + /* HINSTANCE hinst; */ GetModuleHandle( NULL ), + /* void FAR* lpvParam; */ NULL)) + ) + /* creation failed... */ + return 0; + + return 1; + } + + /* Message processing for our Windows class */ +LRESULT CALLBACK Message_Process( HWND handle, UINT mess, + WPARAM wParam, LPARAM lParam ) + { + + switch( mess ) + { + case WM_DESTROY: + /* warn the main thread to quit if it didn't know */ + ourevent.what = event_Quit; + ourevent.info = 0; + eventToProcess = 1; + hwndGraphic = 0; + PostQuitMessage ( 0 ); + DeleteObject ( hbm ); + break; + + case WM_CREATE: + { + HDC hDC; + + hDC = GetDC ( handle ); + hbm = CreateDIBitmap ( + /* HDC hdc; handle of device context */ hDC, + /* BITMAPINFOHEADER FAR* lpbmih; addr.of header*/ &pbmi->bmiHeader, + /* DWORD dwInit; CBM_INIT to initialize bitmap */ 0, + /* const void FAR* lpvBits; address of values */ NULL, + /* BITMAPINFO FAR* lpbmi; addr.of bitmap data */ pbmi, + /* UINT fnColorUse; RGB or palette indices */ DIB_RGB_COLORS); + ReleaseDC ( handle, hDC ); + break; + } + + case WM_PAINT: + { + HDC hDC, memDC; + HANDLE oldbm; + PAINTSTRUCT ps; + + hDC = BeginPaint ( handle, &ps ); + memDC = CreateCompatibleDC(hDC); + oldbm = SelectObject(memDC, hbm); + BitBlt ( hDC, 0, 0, vio_Width, vio_Height, memDC, 0, 0, SRCCOPY); + ReleaseDC ( handle, hDC ); + SelectObject ( memDC, oldbm ); + DeleteObject ( memDC ); + EndPaint ( handle, &ps ); + } + + case WM_KEYDOWN: + switch ( wParam ) + { + case VK_ESCAPE: + ourevent.what = event_Quit; + ourevent.info = 0; + eventToProcess = 1; + break; + + case VK_F1: /* bring up help and about dialog window */ + break; + } + break; + + case WM_CHAR: + { + char c = wParam ; + int i; + + for ( i = 0; i < NUM_Translators; i++ ) + { + if ( c == trans[i].key ) + { + ourevent.what = trans[i].event_class; + ourevent.info = trans[i].event_info; + eventToProcess = 1; + return 0; + } + } + + /* unrecognized keystroke */ + ourevent.what = event_Keyboard; + ourevent.info = (int)c; + eventToProcess = 1; + } + break; + + default: + return DefWindowProc( handle, mess, wParam, lParam ); + } + + return 0; + } + +/* End */ diff --git a/test/arch/win32/makedep b/test/arch/win32/makedep new file mode 100644 index 0000000..8336f57 --- /dev/null +++ b/test/arch/win32/makedep @@ -0,0 +1,29 @@ +# makedep +# +# This shell script creates a dependency file necessary for some compilers +# on the Windows 32-bit platform. +# +# If you run this script under non-Windows operating systems, expect +# warnings that `windows.h' can't be found. + +echo "\ +# This dependency file to be used with various Windows compilers +# has been generated automatically with the script \`makedep' on +# `date +%d-%b-%Y`. +" > depend.win + +(cd ../.. + gcc -MM -I../lib/arch/win32 -I../lib -I../lib/extend -I. *.c | \ + sed -e "s/\.o:/.obj:/" -e "s:/:\\\\:g") >> depend.win + +echo "!ifndef __MAKE__" >> depend.win + +(cd ../.. + gcc -MM -I../lib/arch/win32 -I../lib -I../lib/extend -I. \ + arch/win32/*.c | \ + sed -e "s/^\(.*\)\.o:/arch\\\\win32\\\\\1.obj:/" \ + -e "s:/:\\\\:g") >> depend.win + +echo "!endif" >> depend.win + +# eof diff --git a/test/blitter.c b/test/blitter.c new file mode 100644 index 0000000..26f040c --- /dev/null +++ b/test/blitter.c @@ -0,0 +1,492 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* blitter.c: Support for blitting of bitmaps with various depth. */ +/* */ +/****************************************************************************/ + +#include "blitter.h" + + + typedef struct TBlitter_ + { + int width; /* width in pixels of the written area */ + int height; /* height in pixels of the written area */ + + int xread; /* x position of start point in read area */ + int yread; /* y position of start point in read area */ + + int xwrite; /* x position of start point in write area */ + int ywrite; /* y position of start point in write area */ + + int right_clip; /* amount of right clip */ + + char* read; /* top left corner of source map */ + char* write; /* top left corner of target map */ + + int read_line; /* byte increment to go down one row in read area */ + int write_line; /* byte increment to go down one row in write area */ + + TT_Raster_Map source; + TT_Raster_Map target; + + int source_depth; + int target_depth; + + } TBlitter; + + + static + int compute_clips( TBlitter* blit, + int x_offset, + int y_offset ) + { + int xmin, ymin, xmax, ymax, width, height, target_width; + + + /* perform clipping and setup variables */ + width = blit->source.width; + height = blit->source.rows; + + switch ( blit->source_depth ) + { + case 1: + width = (width + 7) & -8; + break; + + case 4: + width = (width + 1) & -2; + break; + } + + xmin = x_offset; + ymin = y_offset; + xmax = xmin + width-1; + ymax = ymin + height-1; + + /* clip if necessary */ + if ( width == 0 || height == 0 || + xmax < 0 || xmin >= blit->target.width || + ymax < 0 || ymin >= blit->target.rows ) + return 1; + + /* set up clipping and cursors */ + blit->yread = 0; + if ( ymin < 0 ) + { + blit->yread -= ymin; + height += ymin; + blit->ywrite = 0; + } + else + blit->ywrite = ymin; + + if ( ymax >= blit->target.rows ) + height -= ymax - blit->target.rows + 1; + + blit->xread = 0; + if ( xmin < 0 ) + { + blit->xread -= xmin; + width += xmin; + blit->xwrite = 0; + } + else + blit->xwrite = xmin; + + target_width = blit->target.width; + + switch ( blit->target_depth ) + { + case 1: + target_width = (target_width + 7) & -8; + break; + case 4: + target_width = (target_width + 1) & -2; + break; + } + + blit->right_clip = xmax - target_width + 1; + if ( blit->right_clip > 0 ) + width -= blit->right_clip; + else + blit->right_clip = 0; + + blit->width = width; + blit->height = height; + + /* set read and write to the top-left corner of the the read */ + /* and write area before clipping. */ + + blit->read = (char*)blit->source.bitmap; + blit->write = (char*)blit->target.bitmap; + + if ( blit->source.flow == TT_Flow_Up ) + { + blit->read_line = -blit->source.cols; + blit->read += (blit->source.rows-1) * blit->source.cols; + } + else + blit->read_line = blit->source.cols; + + if ( blit->target.flow == TT_Flow_Up ) + { + blit->write_line = -blit->target.cols; + blit->write += (blit->target.rows-1) * blit->target.cols; + } + else + blit->write_line = blit->target.cols; + + /* now go to the start line. Note that we do not move the */ + /* x position yet, as this is dependent on the pixel format */ + blit->read += blit->yread * blit->read_line; + blit->write += blit->ywrite * blit->write_line; + + return 0; + } + + +/**************************************************************************/ +/* */ +/* blit_bitmap_to_bitmap */ +/* */ +/**************************************************************************/ + + static + void blit_bitmap_to_bitmap( TBlitter* blit ) + { + int shift, left_clip, x, y; + unsigned char* read; + unsigned char* write; + + + left_clip = ( blit->xread > 0 ); + shift = ( blit->xwrite - blit->xread ) & 7; + + read = (unsigned char*)blit->read + (blit->xread >> 3); + write = (unsigned char*)blit->write + (blit->xwrite >> 3); + + if ( shift == 0 ) + { + y = blit->height; + do + { + unsigned char* _read = read; + unsigned char* _write = write; + + + x = blit->width; + + do + { + *_write++ |= *_read++; + x -= 8; + } while ( x > 0 ); + + read += blit->read_line; + write += blit->write_line; + y--; + } while ( y > 0 ); + } + else + { + int first, last, count; + + + first = blit->xwrite >> 3; + last = (blit->xwrite + blit->width-1) >> 3; + + count = last - first; + + if ( blit->right_clip ) + count++; + + y = blit->height; + + do + { + unsigned char* _read = read; + unsigned char* _write = write; + unsigned char old; + int shift2 = (8-shift); + + + if ( left_clip ) + old = (*_read++) << shift2; + else + old = 0; + + x = count; + while ( x > 0 ) + { + unsigned char val; + + + val = *_read++; + *_write++ |= ( (val >> shift) | old ); + old = val << shift2; + x--; + } + + if ( !blit->right_clip ) + *_write |= old; + + read += blit->read_line; + write += blit->write_line; + y--; + + } while ( y > 0 ); + } + } + + +/**************************************************************************/ +/* */ +/* blit_bitmap_to_pixmap8 */ +/* */ +/**************************************************************************/ + + static + void blit_bitmap_to_pixmap8( TBlitter* blit, + unsigned char color ) + { + int x, y; + unsigned int left_mask; + unsigned char* read; + unsigned char* write; + + + read = (unsigned char*)blit->read + (blit->xread >> 3); + write = (unsigned char*)blit->write + blit->xwrite; + + left_mask = 0x80 >> (blit->xread & 7); + + y = blit->height; + do + { + unsigned char* _read = read; + unsigned char* _write = write; + unsigned int mask = left_mask; + unsigned int val = 0; + + + x = blit->width; + do + { + if ( mask == 0x80 ) + val = *_read++; + + if ( val & mask ) + *_write = (unsigned char)color; + + mask >>= 1; + if ( mask == 0 ) + mask = 0x80; + + _write++; + x--; + } while ( x > 0 ); + + read += blit->read_line; + write += blit->write_line; + y--; + } while ( y > 0 ); + } + + +/**************************************************************************/ +/* */ +/* blit_bitmap_to_pixmap4 */ +/* */ +/**************************************************************************/ + + static + void blit_bitmap_to_pixmap4( TBlitter* blit, + unsigned char color ) + { + int x, y, phase; + unsigned int left_mask; + unsigned char* read; + unsigned char* write; + + + color = color & 15; + + read = (unsigned char*)blit->read + (blit->xread >> 3); + write = (unsigned char*)blit->write + (blit->xwrite >> 1); + + /* now begin blit */ + left_mask = 0x80 >> (blit->xread & 7); + phase = blit->xwrite & 1; + + y = blit->height; + do + { + unsigned char* _read = read; + unsigned char* _write = write; + unsigned int mask = left_mask; + int _phase = phase; + unsigned int val = 0; + + x = blit->width; + do + { + if ( mask == 0x80 ) + val = *_read++; + + if ( val & mask ) + { + if ( _phase ) + *_write = (*_write & 0xF0) | color; + else + *_write = (*_write & 0x0F) | (color << 4); + } + + mask >>= 1; + if ( mask == 0 ) + mask = 0x80; + + _write += _phase; + _phase ^= 1; + x--; + } while ( x > 0 ); + + read += blit->read_line; + write += blit->write_line; + y--; + } while ( y > 0 ); + } + + +/**************************************************************************/ +/* */ +/* blit_bitmap_to_pixmap16 */ +/* */ +/**************************************************************************/ + + static + void blit_bitmap_to_pixmap16( TBlitter* blit, + unsigned short color ) + { + int x, y; + unsigned int left_mask; + unsigned char* read; + unsigned short* write; + + + read = (unsigned char*)blit->read + (blit->xread >> 3); + write = (unsigned short*)(blit->write + blit->xwrite*2); + + left_mask = 0x80 >> (blit->xread & 7); + + y = blit->height; + do + { + unsigned char* _read = read; + unsigned short* _write = write; + unsigned int mask = left_mask; + unsigned int val = 0; + + x = blit->width; + do + { + if ( mask == 0x80 ) + val = *_read++; + + if ( val & mask ) + *_write = color; + + mask >>= 1; + if ( mask == 0 ) + mask = 0x80; + + _write++; + x--; + } while ( x > 0 ); + + read += blit->read_line; + write += blit->write_line; + y--; + } while ( y > 0 ); + } + + + /* */ + /* Blit_Bitmap */ + /* */ + /* */ + /* blit a source bitmap to a target bitmap or pixmap */ + /* */ + /* */ + /* target :: target bitmap or pixmap */ + /* source :: source bitmap (depth must be 1) */ + /* target_depth :: pixel bit depth of target map */ + /* x_offset :: horizontal offset of source in target */ + /* y_offset :: vertical offset of source in target */ + /* color :: color to use when blitting to color pixmap */ + /* */ + /* */ + /* error code. 0 means success */ + /* */ + /* */ + /* an error occurs when the target bit depth isn't supported, or */ + /* if the source's bit depth isn't 1. */ + /* */ + /* the offsets are relative to the top-left corner of the target */ + /* map. Positive y are downwards. */ + /* */ + extern + int Blit_Bitmap( TT_Raster_Map* target, + TT_Raster_Map* source, + int target_depth, + int x_offset, + int y_offset, + int color ) + { + TBlitter blit; + + + if ( !target || !source ) + return -1; + + blit.source = *source; + blit.target = *target; + blit.source_depth = 1; + blit.target_depth = target_depth; + + /* set up blitter and compute clipping. Return immediately if needed */ + if ( compute_clips( &blit, x_offset, y_offset ) ) + return 0; + + /* now perform the blit */ + switch ( target_depth ) + { + case 1: + blit_bitmap_to_bitmap( &blit ); + break; + + case 4: + blit_bitmap_to_pixmap4( &blit, (unsigned char)color ); + break; + + case 8: + blit_bitmap_to_pixmap8( &blit, (unsigned char)color ); + break; + + case 16: + blit_bitmap_to_pixmap16( &blit, (unsigned short)color ); + break; + + default: + return -2; + } + + return 0; + } + + +/* End */ diff --git a/test/blitter.h b/test/blitter.h new file mode 100644 index 0000000..a506ea4 --- /dev/null +++ b/test/blitter.h @@ -0,0 +1,52 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* blitter.h: Support for blitting of bitmaps with various depth. */ +/* */ +/****************************************************************************/ + +#ifndef BLITTER_H +#define BLITTER_H + +#include + + /* */ + /* Blit_Bitmap */ + /* */ + /* */ + /* blit a source bitmap to a target bitmap or pixmap */ + /* */ + /* */ + /* target :: target bitmap or pixmap */ + /* source :: source bitmap (depth must be 1) */ + /* target_depth :: pixel bit depth of target map */ + /* x_offset :: horizontal offset of source in target */ + /* y_offset :: vertical offset of source in target */ + /* color :: color to use when blitting to color pixmap */ + /* */ + /* */ + /* error code. 0 means success */ + /* */ + /* */ + /* an error occurs when the target bit depth isn't supported, or */ + /* if the source's bit depth isn't 1. */ + /* */ + /* the offsets are relative to the top-left corner of the target */ + /* map. Positive y are downwards. */ + /* */ + extern + int Blit_Bitmap( TT_Raster_Map* target, + TT_Raster_Map* source, + int target_depth, + int x_offset, + int y_offset, + int color ); + +#endif + + +/* End */ diff --git a/test/common.c b/test/common.c new file mode 100644 index 0000000..f77ade3 --- /dev/null +++ b/test/common.c @@ -0,0 +1,310 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* common.c: Various utility functions. */ +/* */ +/****************************************************************************/ + + +/* + * This is a cheap replacement for getopt() because that routine is not + * available on some platforms and behaves differently on other platforms. + * This code was written from scratch without looking at any other + * implementation. + * + * This code is hereby expressly placed in the public domain. + * mleisher@crl.nmsu.edu (Mark Leisher) + * 10 October 1997 + */ + +#ifndef lint +#ifdef __GNUC__ + static char rcsid[] __attribute__ ((unused)) = "$Id: common.c,v 1.14 1999/08/13 12:54:34 werner Exp $"; +#else + static char rcsid[] = "$Id: common.c,v 1.14 1999/08/13 12:54:34 werner Exp $"; +#endif +#endif + +#include +#include +#include +#include + +#include "common.h" +#include "freetype.h" /* TT_Raster_Map */ + + /* + * Externals visible to programs. + */ + + int ft_opterr = 1; + int ft_optind = 1; + char* ft_optarg; + + /* + * Internal variables that are used to detect when the global values + * need to be reset. + */ + + static int cmdac; +#ifdef __STDC__ + static const char* cmdname; + static char* const* cmdav; +#else + static char* cmdname; + static char** cmdav; +#endif + + + int +#ifdef __STDC__ + ft_getopt( int ac, char* const* av, const char* pat ) +#else + ft_getopt( ac, av, pat ) + int ac; + char** av; + char* pat; +#endif + { + int opt; +#ifdef __STDC__ + const char* p; + const char* pp; +#else + char* p; + char* pp; +#endif + + + /* + * If there is no pattern, indicate the parsing is done. + */ + if ( pat == 0 || *pat == 0 ) + return -1; + + /* + * Always reset the option argument to NULL. + */ + ft_optarg = 0; + + /* + * If the number of arguments or argument list do not match the last + * values seen, reset the internal pointers and the globals. + */ + if ( ac != cmdac || av != cmdav ) + { + ft_optind = 1; + cmdac = ac; + cmdav = av; + + /* + * Determine the command name in case it is needed for warning + * messages. + */ + for ( cmdname = 0, p = av[0]; *p; p++ ) + { + if ( *p == '/' || *p == '\\' ) + cmdname = p; + } + + /* + * Skip the path separator if the name was assigned. + */ + if ( cmdname ) + cmdname++; + else + cmdname = av[0]; + } + + /* + * If the next index is greater than or equal to the number of + * arguments, then the command line is done. + */ + if ( ft_optind >= ac ) + return -1; + + /* + * Test the next argument for one of three cases: + * 1. The next argument does not have an initial '-'. + * 2. The next argument is '-'. + * 3. The next argument is '--'. + * + * In either of these cases, command line processing is done. + */ + if ( av[ft_optind][0] != '-' || + strcmp( av[ft_optind], "-" ) == 0 || + strcmp( av[ft_optind], "--" ) == 0 ) + return -1; + + /* + * Point at the next command line argument and increment the + * command line index. + */ + p = av[ft_optind++]; + + /* + * Look for the first character of the command line option. + */ + for ( opt = *(p + 1), pp = pat; *pp && *pp != opt; pp++ ) + ; + + /* + * If nothing in the pattern was recognized, then issue a warning + * and return a '?'. + */ + if ( *pp == 0 ) + { + if ( ft_opterr ) + fprintf( stderr, "%s: illegal option -- %c\n", cmdname, opt ); + return '?'; + } + + /* + * If the option expects an argument, get it. + */ + if ( *(pp + 1) == ':' && (ft_optarg = av[ft_optind]) == 0 ) + { + /* + * If the option argument is NULL, issue a warning and return a '?'. + */ + if ( ft_opterr ) + fprintf( stderr, "%s: option requires an argument -- %c\n", + cmdname, opt ); + opt = '?'; + } + else if ( ft_optarg ) + /* + * Increment the option index past the argument. + */ + ft_optind++; + + /* + * Return the option character. + */ + return opt; + } + + +/****************************************************************************/ +/* */ +/* ft_basename(): */ +/* */ +/* a stupid but useful function... */ +/* */ +/* rewritten by DavidT to get rid of GPLed programs in the FreeType engine. */ +/* */ +/****************************************************************************/ + + char* +#ifdef __STDC__ + ft_basename( const char* name ) +#else + ft_basename( name ) + char* name; +#endif + { +#ifdef __STDC__ + const char* base; + const char* current; +#else + char* base; + char* current; +#endif + char c; + + + base = name; + current = name; + + c = *current; + + while ( c ) + { + if ( c == '/' || c == '\\' ) + base = current + 1; + + current++; + c = *current; + } + + return (char*)base; + } + + + void +#ifdef __STDC__ + Panic( const char* fmt, ... ) +#else + Panic( fmt ) + const char* fmt; +#endif + { + va_list ap; + + + va_start( ap, fmt ); + vprintf( fmt, ap ); + va_end( ap ); + + exit( EXIT_FAILURE ); + } + + + void +#ifdef __STDC__ + Show_Single_Glyph( const TT_Raster_Map* map ) +#else + Show_Single_Glyph( map ) + const TT_Raster_Map* map; +#endif + { + int y; + + unsigned char* line = map->bitmap; + + + for ( y = 0; y < map->rows; y++, line += map->cols ) + { + unsigned char* ptr = line; + int x; + unsigned char mask = 0x80; + + + for ( x = 0; x < map->width; x++ ) + { + printf( "%c", (ptr[0] & mask) ? '*' : '.' ); + mask >>= 1; + if ( mask == 0 ) + { + mask = 0x80; + ptr++; + } + } + printf( "\n" ); + } + } + + + void +#ifdef __STDC__ + separator_line( FILE* out, const int length ) +#else + separator_line( out, length ) + FILE* out; + int length; +#endif + { + int i; + + + for ( i = 0; i < length; i++ ) + fputc( '-', out ); + fprintf( out, "\n\n" ); + } + + +/* End */ diff --git a/test/common.h b/test/common.h new file mode 100644 index 0000000..c214f6c --- /dev/null +++ b/test/common.h @@ -0,0 +1,82 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* common.h: Various utility functions. */ +/* */ +/****************************************************************************/ + +#ifndef COMMON_H +#define COMMON_H + +#include + +#include "freetype.h" /* TT_Raster_Map */ + +/* + * This is a cheap replacement for getopt() because that routine is not + * available on some platforms and behaves differently on other platforms. + * + * This code is hereby expressly placed in the public domain. + * mleisher@crl.nmsu.edu (Mark Leisher) + * 10 October 1997 + */ + +#ifdef __cplusplus + extern "C" { +#endif + + extern int ft_opterr; + extern int ft_optind; + extern char* ft_optarg; + + extern int ft_getopt( +#ifdef __STDC__ + int argc, + char* const* argv, + const char* pattern +#endif + ); + + + extern char* ft_basename( +#ifdef __STDC__ + const char* name +#endif + ); + + + /* print a message and exit */ + extern void Panic( +#ifdef __STDC__ + const char* fmt, ... +#endif + ); + + + extern void Show_Single_Glyph( +#ifdef __STDC__ + const TT_Raster_Map* map +#endif + ); + + + extern void separator_line( +#ifdef __STDC__ + FILE* out, + const int length +#endif + ); + + +#ifdef __cplusplus + } +#endif + +#endif /* COMMON_H */ + + +/* End */ diff --git a/test/display.c b/test/display.c new file mode 100644 index 0000000..5df26d1 --- /dev/null +++ b/test/display.c @@ -0,0 +1,299 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* display.c: Display component used by all test programs. */ +/* */ +/* This file is used to display glyphs and strings in a target window */ +/* using the graphics drivers provided by gmain.c, gevents.h, etc. */ +/* */ +/* Its role is to be shared and heavely commented to let people understand */ +/* how we do the job... */ +/* */ +/****************************************************************************/ + +#include /* malloc() and free() */ +#include /* memset() */ + +#include "display.h" +#include "freetype.h" +#include "gmain.h" + + /* The target bitmap or pixmap -- covering the full display window/screen */ + TT_Raster_Map Bit; + + /* A smaller intermediate bitmap used to render individual glyphs when */ + /* font smoothing mode is activated. It is then or-ed to `Bit'. */ + TT_Raster_Map Small_Bit; + +/* The magic of or-ing gray-levels: */ +/* */ +/* When gray-level mode (a.k.a. font-smoothing) is on, `Bit' is an 8-bit */ +/* pixmap of the size of the display window or screen. */ +/* */ +/* The gray-level palette to use for display is system-dependent, and */ +/* given by the "gray_palette" variable defined in 'gmain.c'. It is */ +/* set up by the graphics driver, and we cannot assume anything about its */ +/* values. */ +/* */ +/* The function TT_Get_Glyph_Pixmap() can use any palette to render each */ +/* individual glyph, however we'll later need to "or" the glyph to */ +/* the display pixmap `Bit' to be able to form strings of text by */ +/* juxtaposing several glyphs together. */ +/* */ +/* If we use the gray_palette directly, we'll encounter trouble doing */ +/* the "or". Example: */ +/* */ +/* Suppose that gray_palette = { 0, 32, 64, 128, 255 } */ +/* */ +/* Let's render a glyph with this palette and "or" it to */ +/* the `Bit' pixmap. If, by chance, we superpose two distinct non-zero */ +/* colors, we will get strange results, like 32+64 = 96, which isn't in */ +/* our gray palette! */ +/* */ +/* There are two ways to solve this problem: */ +/* */ +/* - perform a "slow or" where we check all possible combinations */ +/* and solve conflicts. */ +/* */ +/* - render all pixmaps using a special "virtual" palette that eases */ +/* the "oring" process, then convert the whole display pixmap to */ +/* "display" colors at once. */ +/* */ +/* We choose the second solution, of course; this means that: */ +/* */ +/* - the virtual palette used is simply = { 0, 1, 2, 3, 4 }, defined in */ +/* the variable "palette" below. The `Bit' and `Small_Bit' pixmaps will */ +/* always contain pixels within these values, with the exception of */ +/* post-render display, where `Bit' will be converted to display values */ +/* by the Convert_To_Display_Palette() function. */ +/* */ +/* - as or-ing values between 0 and 4 will give us values between */ +/* 0 and 7, we use a second palette, called "bounding_palette" */ +/* to maintain all values within the virtual palette. */ +/* */ +/* in effect bounding_palette = { 0, 1, 2, 3, 4, 4, 4, 4 } */ +/* */ +/* which means that (3|4) == 7 => 4 after bounding */ +/* */ + + /* the virtual palette */ + unsigned char virtual_palette[5] = { 0, 1, 2, 3, 4 }; + + /* Or-ing the possible palette values gets us from 0 to 7 */ + /* We must bound check these... */ + unsigned char bounded_palette[8] = { 0, 1, 2, 3, 4, 4, 4, 4 }; + + + /* Clears the Bit bitmap/pixmap */ + void Clear_Display( void ) + { + memset( Bit.bitmap, 0, Bit.size ); + } + + + /* Clears the Small_Bit pixmap */ + void Clear_Small( void ) + { + memset( Small_Bit.bitmap, 0, Small_Bit.size ); + } + + + /* Initialize the display bitmap named Bit */ + int Init_Display( int font_smoothing ) + { + Bit.rows = vio_Height; /* the whole window */ + Bit.width = vio_Width; + Bit.flow = TT_Flow_Up; + + if ( font_smoothing ) + Bit.cols = (Bit.width+3) & -4; /* must be 32-bits aligned */ + else + Bit.cols = (Bit.width+7) >> 3; + + Bit.size = (long)Bit.cols * Bit.rows; + + if ( Bit.bitmap ) + free( Bit.bitmap ); + Bit.bitmap = malloc( (int)Bit.size ); + if ( !Bit.bitmap ) + return -1; + + Clear_Display(); + return 0; + } + + + /* Convert the display pixmap from virtual to display palette */ + void Convert_To_Display_Palette( void ) + { + unsigned char* p; + long i; + + p = Bit.bitmap; + for ( i = 0; i < Bit.size; i++ ) + { + *p = gray_palette[(int)*p]; + p++; + } + } + + + /* Init Small Bitmap */ + int Init_Small( int x_ppem, int y_ppem ) + { + if ( Small_Bit.bitmap ) + free( Small_Bit.bitmap ); + + Small_Bit.rows = y_ppem + 32; + Small_Bit.width = x_ppem + 32; + Small_Bit.cols = ( Small_Bit.width+3 ) & -4; /* pad to 32-bits */ + Small_Bit.flow = TT_Flow_Up; + Small_Bit.size = (long)Small_Bit.rows * Small_Bit.cols; + + Small_Bit.bitmap = malloc( (int)Small_Bit.size ); + if ( Small_Bit.bitmap ) + return -1; + + Clear_Small(); + return 0; + } + + + /* Render a single glyph into the display bit/pixmap */ + /* */ + /* Note that in b/w mode, we simply render the glyph directly into */ + /* the display map, as the scan-line converter or-es the glyph into */ + /* the target bitmap. */ + /* */ + /* In gray mode, however, the glyph is first rendered indivdually in */ + /* the Small_Bit map, then 'or-ed' with bounding into the display */ + /* pixmap. */ + /* */ + + TT_Error Render_Single_Glyph( int font_smoothing, + TT_Glyph glyph, + int x_offset, + int y_offset ) + { + if ( !font_smoothing ) + return TT_Get_Glyph_Bitmap( glyph, &Bit, + (long)x_offset*64, (long)y_offset*64 ); + else + { + TT_Glyph_Metrics metrics; + + TT_Error error; + TT_F26Dot6 x, y, xmin, ymin, xmax, ymax; + int ioff, iread; + char *off, *read, *_off, *_read; + + + /* font-smoothing mode */ + + /* we begin by grid-fitting the bounding box */ + TT_Get_Glyph_Metrics( glyph, &metrics ); + + xmin = metrics.bbox.xMin & -64; + ymin = metrics.bbox.yMin & -64; + xmax = (metrics.bbox.xMax+63) & -64; + ymax = (metrics.bbox.yMax+63) & -64; + + /* now render the glyph in the small pixmap */ + + /* IMPORTANT NOTE: the offset parameters passed to the function */ + /* TT_Get_Glyph_Bitmap() must be integer pixel values, i.e., */ + /* multiples of 64. HINTING WILL BE RUINED IF THIS ISN'T THE CASE! */ + /* This is why we _did_ grid-fit the bounding box, especially xmin */ + /* and ymin. */ + + Clear_Small(); + error = TT_Get_Glyph_Pixmap( glyph, &Small_Bit, -xmin, -ymin ); + if ( error ) + return error; + + /* Blit-or the resulting small pixmap into the biggest one */ + /* We do that by hand, and provide also clipping. */ + + xmin = (xmin >> 6) + x_offset; + ymin = (ymin >> 6) + y_offset; + xmax = (xmax >> 6) + x_offset; + ymax = (ymax >> 6) + y_offset; + + /* Take care of comparing xmin and ymin with signed values! */ + /* This was the cause of strange misplacements when Bit.rows */ + /* was unsigned. */ + + if ( xmin >= (int)Bit.width || + ymin >= (int)Bit.rows || + xmax < 0 || + ymax < 0 ) + return TT_Err_Ok; /* nothing to do */ + + /* Note that the clipping check is performed _after_ rendering */ + /* the glyph in the small bitmap to let this function return */ + /* potential error codes for all glyphs, even hidden ones. */ + + /* In exotic glyphs, the bounding box may be larger than the */ + /* size of the small pixmap. Take care of that here. */ + + if ( xmax-xmin + 1 > Small_Bit.width ) + xmax = xmin + Small_Bit.width - 1; + + if ( ymax-ymin + 1 > Small_Bit.rows ) + ymax = ymin + Small_Bit.rows - 1; + + /* set up clipping and cursors */ + + iread = 0; + if ( ymin < 0 ) + { + iread -= ymin * Small_Bit.cols; + ioff = 0; + ymin = 0; + } + else + ioff = ymin * Bit.cols; + + if ( ymax >= Bit.rows ) + ymax = Bit.rows-1; + + if ( xmin < 0 ) + { + iread -= xmin; + xmin = 0; + } + else + ioff += xmin; + + if ( xmax >= Bit.width ) + xmax = Bit.width - 1; + + _read = (char*)Small_Bit.bitmap + iread; + _off = (char*)Bit.bitmap + ioff; + + for ( y = ymin; y <= ymax; y++ ) + { + read = _read; + off = _off; + + for ( x = xmin; x <= xmax; x++ ) + { + *off = bounded_palette[*off | *read]; + off++; + read++; + } + _read += Small_Bit.cols; + _off += Bit.cols; + } + + return TT_Err_Ok; + } + } + + + +/* End */ diff --git a/test/display.h b/test/display.h new file mode 100644 index 0000000..2e9e634 --- /dev/null +++ b/test/display.h @@ -0,0 +1,73 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* display.h: Display component interface used by test programs */ +/* */ +/* This file is used to display glyphs and strings in a target window */ +/* using the graphics drivers provided by gmain.c, gevents.h, etc. */ +/* */ +/* Its role is to be shared and heavely commented to let people understand */ +/* how we do the job... */ +/* */ +/* See comments in display.c for a full description! */ +/* */ +/****************************************************************************/ + +#ifndef DISPLAY_H +#define DISPLAY_H + +#include "freetype.h" /* TT_Raster_Map */ + + /* The target bitmap or pixmap -- covering the full display window/screen */ + extern TT_Raster_Map Bit; + + /* A smaller intermediate bitmap used to render individual glyphs when */ + /* font smoothing mode is activated. It is then or-ed to `Bit'. */ + extern TT_Raster_Map Small_Bit; + + /* the virtual palette */ + extern unsigned char virtual_palette[5]; + + /* Or-ing the possible palette values gets us from 0 to 7 */ + /* We must bound check these... */ + extern unsigned char bounded_palette[8]; + + + /* Clears the Bit bitmap/pixmap */ + void Clear_Display( void ); + + /* Clears the Small_Bit pixmap */ + void Clear_Small( void ); + + /* Initialize the display bitmap named Bit */ + int Init_Display( int font_smoothing ); + + /* Initialize Small Bitmap */ + int Init_Small( int x_ppem, int y_ppem ); + + /* Convert the display pixmap from virtual to display palette */ + void Convert_To_Display_Palette( void ); + + /* Render a single glyph into the display bit/pixmap. */ + /* */ + /* Note that in b/w mode, we simply render the glyph directly into */ + /* the display map, as the scan-line converter or-es the glyph into */ + /* the target bitmap. */ + /* */ + /* In gray mode, however, the glyph is first rendered individually in */ + /* the Small_Bit map, then 'or-ed' with bounding into the display */ + /* pixmap. */ + /* */ + TT_Error Render_Single_Glyph( int font_smoothing, + TT_Glyph glyph, + int x_offset, + int y_offset ); + +#endif /* DISPLAY_H */ + + +/* End */ diff --git a/test/fdebug.c b/test/fdebug.c new file mode 100644 index 0000000..31025ba --- /dev/null +++ b/test/fdebug.c @@ -0,0 +1,285 @@ +/****************************************************************************} +{* *} +{* The FreeType project - a Free and Portable Quality TrueType Renderer. *} +{* *} +{* Copyright 1996-1999 by *} +{* D. Turner, R.Wilhelm, and W. Lemberg *} +{* *} +{* fdebug : A very simple TrueType bytecode debugger. *} +{* *} +{* NOTE : You must compile the interpreter with the DEBUG_INTERPRETER *} +{* macro defined in order to link this program! *} +{* *} +{****************************************************************************/ + +#include /* libc ANSI */ +#include +#include +#include + +#include "freetype.h" +#include "tttypes.h" +#include "ttdebug.h" +#include "ttobjs.h" + + +#ifdef UNIX +#ifndef HAVE_POSIX_TERMIOS +#include +#include +#else +#ifndef HAVE_TCGETATTR +#define HAVE_TCGETATTR +#endif /* HAVE_TCGETATTR */ +#ifndef HAVE_TCSETATTR +#define HAVE_TCSETATTR +#endif /* HAVE_TCSETATTR */ +#include +#endif /* HAVE_POSIX_TERMIOS */ +#endif + + /* MAGIC: This variable is only defined in ttinterp.c if the */ + /* macro DEBUG_INTERPRETER is set. It specifies the code */ + /* range to debug. By default, it is TT_CodeRange_Glyph. */ + /* */ + extern + int debug_coderange; + + +#define Font_Buff_Size 256000 /* this buffer holds all */ + /* font specific data. */ + + TT_Engine engine; + TT_Face face; + TT_Instance instance; + TT_Glyph glyph; + TT_Error error; + + TT_Face_Properties properties; + + int num_glyphs; + int ptsize; + + Int Fail; + Int Num; + int mode = 2; + unsigned char autorun; + +/********************************************************************* + * + * Usage : print usage message + * + *********************************************************************/ + + static + void Usage( const char* execname ) + { + TT_Message( "fdebug: a simple TrueType bytecode debugger - part of the FreeType project\n" ); + TT_Message( "--------------------------------------------------------------------------\n\n"); + TT_Message( "Usage: %s glyphnum ppem fontname[.ttf]\n", execname ); + TT_Message( " or %s --cvt ppem fontname[.ttf]\n", execname ); + TT_Message( " or %s --font fontname[.ttf]\n\n", execname ); + exit( EXIT_FAILURE ); + } + + +/********************************************************************* + * + * Init_Keyboard : set the input file descriptor to char-by-char + * mode on Unix.. + * + *********************************************************************/ + +#ifdef UNIX + + struct termios old_termio; + + static + void Init_Keyboard( void ) + { + struct termios termio; + + +#ifndef HAVE_TCGETATTR + ioctl( 0, TCGETS, &old_termio ); +#else + tcgetattr( 0, &old_termio ); +#endif + + termio = old_termio; + + termio.c_lflag &= ~(ICANON+ECHO+ECHOE+ECHOK+ECHONL+ECHOKE); + +#ifndef HAVE_TCSETATTR + ioctl( 0, TCSETS, &termio ); +#else + tcsetattr( 0, TCSANOW, &termio ); +#endif + } + + static + void Reset_Keyboard( voi ) + { +#ifndef HAVE_TCSETATTR + ioctl( 0, TCSETS, &old_termio ); +#else + tcsetattr( 0, TCSANOW, &old_termio ); +#endif + + } + +#else + + static + void Init_Keyboard( void ) + { + } + + static + void Reset_Keyboard( voi ) + { + } + +#endif + + static + void Print_Banner( void ) + { + TT_Message( "fdebug - a simple TrueType bytecode debugger for FreeType\n" ); + TT_Message( "------------------------------------------------------------\n" ); + TT_Message( "type '?' for help - copyright 1996-1999 the FreeType Project\n\n" ); + } + + + static + void Error( const char* message, + const char* filename ) + { + static char tempstr[256]; + + sprintf( tempstr, "ERROR (%s): %s\n", filename, message ); + TT_Message( tempstr ); + + sprintf( tempstr, " code = 0x%04lx\n", error ); + TT_Message( tempstr ); + + Reset_Keyboard(); + exit( EXIT_FAILURE ); + } + + + static + void Init_Face( const char* filename ) + { + error = TT_Init_FreeType(&engine); + if (error) Error( "could not initialise FreeType", filename ); + + /* open face object */ + error = TT_Open_Face( engine, filename, &face ); + if (error) Error( "could not find or open file", filename ); + + /* get properties */ + TT_Get_Face_Properties( face, &properties ); + num_glyphs = properties.num_Glyphs; + + /* create instance */ + error = TT_New_Instance( face, &instance ); + if (error) Error( "could not create instance", filename ); + + error = TT_New_Glyph( face, &glyph ); + if (error) Error( "could not create glyph container", filename ); + + TT_Set_Instance_Resolutions( instance, 96, 96 ); + + error = TT_Set_Instance_CharSize( instance, ptsize << 6 ); + if (error) Error( "could not set text size", filename ); + } + + + int main( int argc, char** argv ) + { + int i; + char filename[128+4]; + char* execname; + + + execname = argv[0]; + if ( argc < 2 ) + Usage( execname ); + + if ( strcmp( argv[1], "--font" ) == 0 ) + { + debug_coderange = TT_CodeRange_Font; + mode = 0; + argc--; + argv++; + } + else if ( strcmp( argv[1], "--cvt" ) == 0 ) + { + debug_coderange = TT_CodeRange_Cvt; + argv++; + argc--; + mode = 1; + } + else if ( sscanf( argv[1], "%d", &Num ) == 1 ) + { + mode = 2; + argv++; + argc--; + } + else + Usage( execname ); + + /* read the point size for cvt and glyph modes */ + if (mode > 0) + { + if ( sscanf( argv[1], "%d", &ptsize ) != 1 ) + Usage( execname ); + argc--; + argv++; + } + + if ( argc != 2 ) + Usage(execname); + + i = strlen( argv[1] ); + while ( i > 0 && argv[1][i] != '\\' ) + { + if ( argv[1][i] == '.' ) + i = 0; + i--; + } + + filename[128] = 0; + + strncpy( filename, argv[1], 128 ); + if ( i >= 0 ) + strncpy( filename + strlen(filename), ".ttf", 4 ); + + Init_Keyboard(); + + if (mode == 2) + { + Init_Face( filename ); + Print_Banner(); + + error = TT_Load_Glyph( instance, glyph, Num, TTLOAD_DEFAULT ); + if (error) Error( "Error during bytecode execution", filename ); + } + else + { + Print_Banner(); + Init_Face( filename ); + } + + TT_Done_FreeType(engine); + + Reset_Keyboard(); + + exit( EXIT_SUCCESS ); /* for safety reasons */ + + return 0; /* never reached */ + } + + +/* End */ diff --git a/test/ftdump.c b/test/ftdump.c new file mode 100644 index 0000000..655aab4 --- /dev/null +++ b/test/ftdump.c @@ -0,0 +1,928 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* ftdump: Simple TrueType font file resource profiler. */ +/* */ +/* This program dumps various properties of a given font file. */ +/* */ +/* */ +/* */ +/* NOTE: This is just a test program that is used to show off and */ +/* debug the current engine. */ +/* */ +/****************************************************************************/ + +#include +#include +#include + +#include "common.h" /* for Panic() etc. */ +#include "freetype.h" +#include "ftxcmap.h" +#include "ftxopen.h" /* TrueType Open support */ +#include "ftxsbit.h" /* embedded bitmap support */ + +/* + * The following comment should be ignored. The "ttobjs.h" file does + * already include ft_conf.h. + * + * ------------------------------------------------------------------ + * + * IGNORE> Basically, an external program using FreeType shouldn't depend on an + * IGNORE> internal file of the FreeType library, especially not on ft_conf.h -- but + * IGNORE> to avoid another configure script which tests for the existence of the + * IGNORE> i18n stuff we include ft_conf.h here since we can be sure that our test + * IGNORE> programs use the same configuration options as the library itself. + */ + +#include "ttobjs.h" /* We're going to access internal tables directly */ + +#ifdef HAVE_LIBINTL_H + +#ifdef HAVE_LOCALE_H +#include +#endif + +#include "ftxerr18.h" +#include +#else +#define gettext( x ) ( x ) +#endif + + + TT_Error error; + + TT_Engine engine; + TT_Face face; + TT_Instance instance; + TT_Glyph glyph; + + TT_Instance_Metrics imetrics; + TT_Outline outline; + TT_Glyph_Metrics metrics; + + TT_Face_Properties properties; + + int num_glyphs; + int ptsize; + + int Fail; + int Num; + + int flag_memory = 1; + int flag_names = 1; + int flag_encodings = 1; + int flag_cmap = 1; + int flag_sbits = 1; + int flag_ttopen = 1; + +#ifdef FREETYPE_DLL + + /* If the library is linked as a DLL, TTMemory_Allocated() */ + /* (which is not exported) cannot be accessed. */ + /* In this case, some compilers report an error because */ + /* they try to link against a non-existing symbol. */ + /* */ + /* We thus avoid the external reference on these compilers. */ + + #define TTMemory_Allocated 0L + +#else + extern long TTMemory_Allocated; +#endif + + long org_memory, old_memory, cur_memory; + + const char* Apple_Encodings[33] = + { + "Roman", "Japanese", "Chinese", "Korean", "Arabic", "Hebrew", + "Greek", "Russian", "RSymbol", "Devanagari", "Gurmukhi", + "Gujarati", "Oriya", "Bengali", "Tamil", "Telugu", "Kannada", + "Malayalam", "Sinhalese", "Burmese", "Khmer", "Tai", "Laotian", + "Georgian", "Armenian", "Maldivian/Simplif. Chinese", "Tibetan", + "Mongolian", "Geez", "Slavic", "Vietnamese", "Sindhi", "Uninterpreted" + }; + + struct + { + long initial_overhead; + long face_object; + long glyph_object; + long first_instance; + long second_instance; + + } memory_footprint; + + + /* We ignore error message strings with this function */ + +#ifndef HAVE_LIBINTL_H + static char* + TT_ErrToString18( TT_Error error ) + { + static char temp[32]; + + + sprintf( temp, "0x%04lx", error ); + return temp; + } +#endif + + + void + Save_Memory( long* var ) + { + *var = TTMemory_Allocated - old_memory; + old_memory += *var; + } + +#define FOOTPRINT( field ) Save_Memory( &memory_footprint.##field ) + + + static void + Print_Mem( long val, char* string ) + { + printf( "%6ld Bytes (%4ld kByte): %s\n", + val, + ( val + 1023L ) / 1024, + string ); + } + +#define PRINT_MEM( field, string ) \ + Print_Mem( memory_footprint.##field, string ) + + + /* Print the memory footprint */ + + void + Print_Memory( void ) + { + /* create glyph */ + error = TT_New_Glyph( face, &glyph ); + if ( error ) + { + fprintf( stderr, gettext( "Could not create glyph container.\n" ) ); + goto Failure; + } + + FOOTPRINT( glyph_object ); + + /* create instance */ + error = TT_New_Instance( face, &instance ); + if ( error ) + { + fprintf( stderr, gettext( "Could not create instance.\n" ) ); + goto Failure; + } + + FOOTPRINT( first_instance ); + + error = TT_New_Instance( face, &instance ); + if ( error ) + { + fprintf( stderr, gettext( "Could not create second instance.\n" ) ); + goto Failure; + } + + FOOTPRINT( second_instance ); + + printf( gettext( "Memory footprint statistics:\n" ) ); + separator_line( stdout, 78 ); + + /* NOTE: In our current implementation, the face's execution */ + /* context object is created lazily with the first */ + /* instance. However, all later instances share the */ + /* the same context. */ + + PRINT_MEM( face_object, gettext( "face object" ) ); + PRINT_MEM( glyph_object, gettext( "glyph object" ) ); + PRINT_MEM( second_instance, gettext( "instance object" ) ); + + Print_Mem( memory_footprint.first_instance - + memory_footprint.second_instance, + gettext( "exec. context object" ) ); + + separator_line( stdout, 78 ); + + Print_Mem( memory_footprint.face_object + + memory_footprint.glyph_object + + memory_footprint.first_instance, + gettext( "total memory usage" ) ); + + printf( "\n" ); + + return; + + Failure: + fprintf( stderr, " " ); + Panic( gettext( "FreeType error message: %s\n" ), + TT_ErrToString18( error ) ); + } + + + static char name_buffer[257]; + static int name_len = 0; + + + static char* + LookUp_Name( int index ) + { + unsigned short i, n; + + unsigned short platform, encoding, language, id; + char* string; + unsigned short string_len; + + int j, found; + + + n = properties.num_Names; + + for ( i = 0; i < n; i++ ) + { + TT_Get_Name_ID( face, i, &platform, &encoding, &language, &id ); + TT_Get_Name_String( face, i, &string, &string_len ); + + if ( id == index ) + { + + /* The following code was inspired from Mark Leisher's */ + /* ttf2bdf package */ + + found = 0; + + /* Try to find a Microsoft English name */ + + if ( platform == 3 ) + for ( j = 1; j >= 0; j-- ) + if ( encoding == j ) /* Microsoft ? */ + if ( (language & 0x3FF) == 0x009 ) /* English language */ + { + found = 1; + break; + } + + if ( !found && platform == 0 && language == 0 ) + found = 1; + + /* Found a Unicode Name. */ + + if ( found ) + { + if ( string_len > 512 ) + string_len = 512; + + name_len = 0; + + for ( i = 1; i < string_len; i += 2 ) + name_buffer[name_len++] = string[i]; + + name_buffer[name_len] = '\0'; + + return name_buffer; + } + } + } + + /* Not found */ + return NULL; + } + + + static void + Print_Names( void ) + { + printf( gettext( "font name table entries\n" ) ); + separator_line( stdout, 78 ); + + if ( LookUp_Name( 4 ) ) + printf( "%s - ", name_buffer ); + + if ( LookUp_Name( 5 ) ) + printf( "%s\n\n", name_buffer ); + + if ( LookUp_Name( 6 ) ) + printf( gettext( "PostScript name: %s\n\n" ), name_buffer ); + + if ( LookUp_Name( 0 ) ) + printf( "%s\n\n", name_buffer ); + + if ( LookUp_Name( 7 ) ) + printf( name_buffer ); + + printf( "\n" ); + separator_line( stdout, 78 ); + } + + + static void + Print_Encodings( void ) + { + unsigned short n, i; + unsigned short platform, encoding; + char* platStr, *encoStr; + + char tempStr[128]; + + + printf( gettext( "character map encodings\n" ) ); + separator_line( stdout, 78 ); + + n = properties.num_CharMaps; + if ( n == 0 ) + { + printf( gettext( + "The file doesn't seem to have any encoding table.\n" ) ); + return; + } + + printf( gettext( "There are %hu encodings:\n\n" ), n ); + + for ( i = 0; i < n; i++ ) + { + TT_Get_CharMap_ID( face, i, &platform, &encoding ); + printf( gettext( "encoding %2u: " ), i ); + + platStr = encoStr = NULL; + + switch ( platform ) + { + case TT_PLATFORM_APPLE_UNICODE: + platStr = "Apple Unicode"; + switch ( encoding ) + { + case TT_APPLE_ID_DEFAULT: + encoStr = ""; + break; + + case TT_APPLE_ID_UNICODE_1_1: + encoStr = "(v.1.1)"; + break; + + case TT_APPLE_ID_ISO_10646: + encoStr = "(ISO 10646-1:1993)"; + break; + + case TT_APPLE_ID_UNICODE_2_0: + encoStr = "(v.2.0)"; + break; + + default: + sprintf( tempStr, gettext( "Unknown value %hu" ), encoding ); + encoStr = tempStr; + } + break; + + case TT_PLATFORM_MACINTOSH: + platStr = "Apple"; + if ( encoding > 32 ) + { + sprintf( tempStr, gettext( "Unknown value %hu" ), encoding ); + encoStr = tempStr; + } + else + encoStr = (char*)Apple_Encodings[encoding]; + break; + + case TT_PLATFORM_ISO: + platStr = "Iso"; + switch ( encoding ) + { + case TT_ISO_ID_7BIT_ASCII: + platStr = "Ascii"; + encoStr = "7-bit"; + break; + + case TT_ISO_ID_10646: + encoStr = "10646"; + break; + + case TT_ISO_ID_8859_1: + encoStr = "8859-1"; + break; + + default: + sprintf( tempStr, "%hu", encoding ); + encoStr = tempStr; + } + break; + + case TT_PLATFORM_MICROSOFT: + platStr = "Windows"; + switch ( encoding ) + { + case TT_MS_ID_SYMBOL_CS: + encoStr = "Symbol"; + break; + + case TT_MS_ID_UNICODE_CS: + encoStr = "Unicode"; + break; + + case TT_MS_ID_SJIS: + encoStr = "Shift-JIS"; + break; + + case TT_MS_ID_GB2312: + encoStr = "GB2312"; + break; + + case TT_MS_ID_BIG_5: + encoStr = "Big 5"; + break; + + case TT_MS_ID_WANSUNG: + encoStr = "WanSung"; + break; + + case TT_MS_ID_JOHAB: + encoStr = "Johab"; + break; + + default: + sprintf( tempStr, gettext( "Unknown value %hu" ), encoding ); + encoStr = tempStr; + } + break; + + default: + sprintf( tempStr, "%hu - %hu", platform, encoding ); + platStr = gettext( "Unknown" ); + encoStr = tempStr; + } + + printf( "%s %s\n", platStr, encoStr ); + } + + printf( "\n" ); + separator_line( stdout, 78 ); + } + + + static void + Print_Cmap( void ) + { + TT_CharMap charmap; + TT_UShort glyph_index; + TT_Long char_index; + unsigned short n, i; + unsigned short platform, encoding; + + + printf( gettext( "ftxcmap test\n" ) ); + separator_line( stdout, 78 ); + + n = properties.num_CharMaps; + if ( n == 0 ) + { + printf( gettext( + "The file doesn't seem to have any encoding table.\n" ) ); + return; + } + + printf( gettext( "There are %hu encodings:\n\n" ), n ); + + for ( i = 0; i < n; i++ ) + { + + TT_Get_CharMap_ID( face, i, &platform, &encoding ); + printf( gettext( "encoding %2u:\n" ), i ); + + TT_Get_CharMap( face, i, &charmap); + + char_index = TT_CharMap_First( charmap, &glyph_index ); + printf( gettext( "first: glyph index %hu, character code 0x%lx\n" ), + glyph_index, char_index ); + + char_index = TT_CharMap_Next( charmap, char_index, &glyph_index ); + printf( gettext( "next: glyph index %hu, character code 0x%lx\n" ), + glyph_index, char_index ); + + char_index = TT_CharMap_Last( charmap, &glyph_index ); + printf( gettext( "last: glyph index %hu, character code 0x%lx\n" ), + glyph_index, char_index ); + } + + printf( "\n" ); + separator_line( stdout, 78 ); + } + + + static void + Print_SBits( void ) + { + TT_EBLC eblc; + TT_Error error; + + + error = TT_Get_Face_Bitmaps( face, &eblc ); + if ( error == TT_Err_Table_Missing ) + return; + if ( error ) + { + fprintf( stderr, gettext( + "Error while retrieving embedded bitmaps table.\n" ) ); + goto Failure; + } + + printf( gettext( "embedded bitmap table\n" ) ); + separator_line( stdout, 78 ); + + printf( gettext( " version of embedded bitmap table: 0x%lx\n" ), + eblc.version ); + printf( gettext( " number of embedded bitmap strikes: %lu\n" ), + eblc.num_strikes ); + + { + TT_SBit_Strike* strike = eblc.strikes; + int count = 0; + + + for ( ; count < eblc.num_strikes; count++, strike++ ) + { + printf( gettext( " bitmap strike %hu/%lu: " ), + count + 1, eblc.num_strikes ); + + printf( gettext( "%hux%hu pixels, %hu-bit depth, glyphs [%hu..%hu]\n" ), + strike->x_ppem, strike->y_ppem, strike->bit_depth, + strike->start_glyph, strike->end_glyph ); + { + TT_SBit_Range* range = strike->sbit_ranges; + TT_SBit_Range* limit = range + strike->num_ranges; + + + for ( ; range < limit; range++ ) + printf( gettext( " range format (%hu:%hu) glyphs %hu..%hu\n" ), + range->index_format, + range->image_format, + range->first_glyph, + range->last_glyph ); + } + } + } + printf( "\n" ); + separator_line( stdout, 78 ); + + return; + + Failure: + fprintf( stderr, " " ); + Panic( gettext( "FreeType error message: %s\n" ), + TT_ErrToString18( error ) ); + } + + +#define TAG2STRING( t, s ) s[0] = (char)(t >> 24), \ + s[1] = (char)(t >> 16), \ + s[2] = (char)(t >> 8), \ + s[3] = (char)(t ) + + + static void + Print_GSUB( void ) + { + TTO_GSUBHeader gsub; + TT_Error error; + + TT_UShort i; + TTO_Feature f; + TTO_Lookup* lo; + + TT_ULong *script_tag_list, *stl; + TT_ULong *language_tag_list, *ltl; + TT_ULong *feature_tag_list, *ftl; + + TT_UShort script_index, language_index, + feature_index, req_feature_index; + + char script_tag[4], language_tag[4], feature_tag[4]; + + + error = TT_Load_GSUB_Table( face, &gsub, NULL ); + if ( error == TT_Err_Table_Missing ) + return; + if ( error ) + { + fprintf( stderr, gettext( "Error while loading GSUB table.\n" ) ); + goto Failure; + } + + printf( gettext( "GSUB table\n" ) ); + separator_line( stdout, 78 ); + + error = TT_GSUB_Query_Scripts( &gsub, &script_tag_list ); + if ( error ) + { + fprintf( stderr, gettext( + "Error while querying GSUB script list.\n" ) ); + goto Failure; + } + + stl = script_tag_list; + for ( ; *stl; stl++ ) + { + TAG2STRING( *stl, script_tag ); + + error = TT_GSUB_Select_Script( &gsub, *stl, &script_index ); + if ( error ) + { + fprintf( stderr, gettext( + "Error while selecting GSUB script `%4.4s'.\n" ), + script_tag ); + goto Failure; + } + + printf( gettext( " script `%4.4s' (index %hu):\n" ), + script_tag, script_index ); + + error = TT_GSUB_Query_Features( &gsub, script_index, 0xFFFF, + &feature_tag_list ); + if ( error ) + { + fprintf( stderr, gettext( + "Error while querying GSUB default language system for script `%4.4s'.\n" ), + script_tag ); + goto Failure; + } + + printf( gettext( " default language system:\n" ) ); + + ftl = feature_tag_list; + for ( ; *ftl; ftl++ ) + { + TAG2STRING( *ftl, feature_tag ); + + error = TT_GSUB_Select_Feature( &gsub, *ftl, + script_index, 0xFFFF, + &feature_index ); + if ( error ) + { + fprintf( stderr, gettext( + "Error while selecting GSUB feature `%4.4s'\n" + "for default language system of script `%4.4s'.\n" ), + feature_tag, script_tag ); + goto Failure; + } + + printf( gettext( " feature `%4.4s' (index %hu; lookup " ), + feature_tag, feature_index ); + + f = gsub.FeatureList.FeatureRecord[feature_index].Feature; + + for ( i = 0; i < f.LookupListCount - 1; i++ ) + printf( "%hu, ", f.LookupListIndex[i] ); + printf( "%hu)\n", f.LookupListIndex[i] ); + } + free( feature_tag_list ); + + error = TT_GSUB_Query_Languages( &gsub, script_index, + &language_tag_list ); + if ( error ) + { + fprintf( stderr, gettext( + "Error while querying GSUB language list for script `%4.4s'.\n" ), + script_tag ); + goto Failure; + } + + ltl = language_tag_list; + for ( ; *ltl; ltl++ ) + { + TAG2STRING( *ltl, language_tag ); + + error = TT_GSUB_Select_Language( &gsub, *ltl, + script_index, + &language_index, + &req_feature_index ); + if ( error ) + { + fprintf( stderr, gettext( + "Error while selecting GSUB language `%4.4s' for script `%4.4s'.\n" ), + language_tag, script_tag ); + goto Failure; + } + + printf( gettext( " language `%4.4s' (index %hu):\n" ), + language_tag, language_index ); + + if ( req_feature_index != 0xFFFF ) + { + printf( gettext( " required feature index %hu (lookup " ), + req_feature_index ); + + f = gsub.FeatureList.FeatureRecord[req_feature_index].Feature; + + for ( i = 0; i < f.LookupListCount - 1; i++ ) + printf( "%hu, ", f.LookupListIndex[i] ); + printf( "%hu)\n", f.LookupListIndex[i] ); + } + + error = TT_GSUB_Query_Features( &gsub, script_index, language_index, + &feature_tag_list ); + if ( error ) + { + fprintf( stderr, gettext( + "Error while querying GSUB feature list\n" + "for script `%4.4s', language `%4.4s'.\n" ), + script_tag, language_tag ); + goto Failure; + } + + ftl = feature_tag_list; + for ( ; *ftl; ftl++ ) + { + TAG2STRING( *ftl, feature_tag ); + + error = TT_GSUB_Select_Feature( &gsub, *ftl, + script_index, language_index, + &feature_index ); + if ( error ) + { + fprintf( stderr, gettext( + "Error while selecting GSUB feature `%4.4s'\n" + "for script `%4.4s', language `%4.4s'.\n" ), + feature_tag, script_tag, language_tag ); + goto Failure; + } + + printf( gettext( " feature `%4.4s' (index %hu; lookup " ), + feature_tag, feature_index ); + + f = gsub.FeatureList.FeatureRecord[feature_index].Feature; + + for ( i = 0; i < f.LookupListCount - 1; i++ ) + printf( "%hu, ", f.LookupListIndex[i] ); + printf( "%hu)\n", f.LookupListIndex[i] ); + } + free( feature_tag_list ); + } + free( language_tag_list ); + } + free( script_tag_list ); + + printf( "\n" ); + + lo = gsub.LookupList.Lookup; + + printf( gettext( "Lookups:\n\n" ) ); + + for ( i = 0; i < gsub.LookupList.LookupCount; i++ ) + printf( gettext( " %hu: type %hu, flag 0x%x\n" ), + i, lo[i].LookupType, lo[i].LookupFlag ); + + printf( "\n" ); + separator_line( stdout, 78 ); + + return; + + Failure: + fprintf( stderr, " " ); + Panic( gettext( "FreeType error message: %s\n" ), + TT_ErrToString18( error ) ); + } + + + int + main( int argc, char** argv ) + { + int i; + char filename[128 + 4]; + char alt_filename[128 + 4]; + char* execname; + char* gt; + + +#ifdef HAVE_LIBINTL_H + setlocale( LC_ALL, "" ); + bindtextdomain( "freetype", LOCALEDIR ); + textdomain( "freetype" ); +#endif + + execname = argv[0]; + + if ( argc != 2 ) + { + gt = gettext( "ftdump: Simple TrueType Dumper -- part of the FreeType project" ); + fprintf( stderr, "%s\n", gt ); + separator_line( stderr, strlen( gt ) ); + + fprintf( stderr, gettext( "Usage: %s fontname[.ttf|.ttc]\n\n" ), + execname ); + + exit( EXIT_FAILURE ); + } + + i = strlen( argv[1] ); + while ( i > 0 && argv[1][i] != '\\' ) + { + if ( argv[1][i] == '.' ) + i = 0; + i--; + } + + filename[128] = '\0'; + alt_filename[128] = '\0'; + + strncpy( filename, argv[1], 128 ); + strncpy( alt_filename, argv[1], 128 ); + + if ( i >= 0 ) + { + strncpy( filename + strlen( filename ), ".ttf", 4 ); + strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 ); + } + + /* Initialize engine */ + + old_memory = 0; + + if ( (error = TT_Init_FreeType( &engine )) ) + { + fprintf( stderr, gettext( "Error while initializing engine.\n" ) ); + goto Failure; + } + + if ( (error = TT_Init_SBit_Extension( engine )) ) + { + fprintf( stderr, gettext( + "Error while initializing embedded bitmap extension.\n" ) ); + goto Failure; + } + + if ( (error = TT_Init_GSUB_Extension( engine )) ) + { + fprintf( stderr, gettext( + "Error while initializing GSUB extension.\n" ) ); + goto Failure; + } + + FOOTPRINT( initial_overhead ); + + /* Open and Load face */ + + error = TT_Open_Face( engine, filename, &face ); + if ( error == TT_Err_Could_Not_Open_File ) + { + strcpy( filename, alt_filename ); + error = TT_Open_Face( engine, alt_filename, &face ); + } + + if ( error == TT_Err_Could_Not_Open_File ) + Panic( gettext( "Could not find or open %s.\n" ), filename ); + if ( error ) + { + fprintf( stderr, gettext( "Error while opening %s.\n" ), filename ); + goto Failure; + } + + FOOTPRINT( face_object ); + + /* get face properties and allocate preload arrays */ + + TT_Get_Face_Properties( face, &properties ); + num_glyphs = properties.num_Glyphs; + + /* Now do various dumps */ + + if ( flag_names ) + Print_Names(); + + if ( flag_encodings ) + Print_Encodings(); + + if ( flag_cmap ) + Print_Cmap(); + + if ( flag_sbits ) + Print_SBits(); + + if ( flag_ttopen ) + Print_GSUB(); + +#ifndef FREETYPE_DLL /* the statistics are meaningless if we use a DLL. */ + if ( flag_memory ) + Print_Memory(); +#endif + + TT_Close_Face( face ); + + TT_Done_FreeType( engine ); + + exit( EXIT_SUCCESS ); /* for safety reasons */ + + return 0; /* never reached */ + + Failure: + fprintf( stderr, " " ); + Panic( gettext( "FreeType error message: %s\n" ), + TT_ErrToString18( error ) ); + + return 0; /* never reached */ +} + + +/* End */ diff --git a/test/fterror.c b/test/fterror.c new file mode 100644 index 0000000..b15d9fb --- /dev/null +++ b/test/fterror.c @@ -0,0 +1,76 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* E. Dieterich */ +/* */ +/* fterror: test errstr functionality. */ +/* */ +/****************************************************************************/ + + +#include +#include + +#include "freetype.h" +#include "ftxerr18.h" + +/* + * Basically, an external program using FreeType shouldn't depend on an + * internal file of the FreeType library, especially not on ft_conf.h -- but + * to avoid another configure script which tests for the existence of the + * i18n stuff we include ft_conf.h here since we can be sure that our test + * programs use the same configuration options as the library itself. + */ + +#include "ft_conf.h" + + +#ifdef HAVE_LIBINTL_H + +#ifdef HAVE_LOCALE_H +#include +#endif + +#include + +#else /* HAVE_LIBINTL_H */ + +#define gettext( x ) ( x ) + +#endif /* HAVE_LIBINTL_H */ + + + int + main( void ) + { + int i; +#ifdef HAVE_LIBINTL_H + char* domain; + + + setlocale( LC_ALL, "" ); + bindtextdomain( "freetype", LOCALEDIR ); + domain = textdomain( "freetype" ); +#endif + +#if 0 + printf( "domain: %s\n", domain = textdomain( "" ) ); +#endif + printf( gettext( "Start of fterror.\n" ) ); + + for ( i = 0; i < 10; i++ ) + printf( "Code: %i, %s\n", i, TT_ErrToString18( i ) ); + +#if 0 + printf( "domain: %s\n", domain = textdomain( "" ) ); +#endif + printf( gettext( "End of fterror.\n" ) ); + + exit( EXIT_SUCCESS ); /* for safety reasons */ + + return 0; /* never reached */ + } + + +/* End */ diff --git a/test/ftlint.c b/test/ftlint.c new file mode 100644 index 0000000..3cf137f --- /dev/null +++ b/test/ftlint.c @@ -0,0 +1,296 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* ftlint: a simple TrueType instruction tester. */ +/* */ +/* NOTE: This is just a test program that is used to show off and */ +/* debug the current engine. */ +/* */ +/****************************************************************************/ + +#include +#include +#include + +#include "common.h" +#include "freetype.h" + +/* + * Basically, an external program using FreeType shouldn't depend on an + * internal file of the FreeType library, especially not on ft_conf.h -- but + * to avoid another configure script which tests for the existence of the + * i18n stuff we include ft_conf.h here since we can be sure that our test + * programs use the same configuration options as the library itself. + */ + +#include "ft_conf.h" + + +#ifdef HAVE_LIBINTL_H + +#ifdef HAVE_LOCALE_H +#include +#endif + +#include +#include "ftxerr18.h" + +#else /* !HAVE_LIBINTL */ + +#define gettext( x ) ( x ) + + /* We ignore error message strings with this function */ + + static char* + TT_ErrToString18( TT_Error error ) + { + static char temp[32]; + + + sprintf( temp, "0x%04lx", error ); + return temp; + } + +#endif /* !HAVE_LIBINTL */ + + + TT_Error error; + + TT_Engine engine; + + TT_Face face; + TT_Instance instance; + TT_Glyph glyph; + + TT_Outline outline; + TT_Glyph_Metrics metrics; + + TT_Face_Properties properties; + + unsigned int num_glyphs; + int ptsize; + + int Fail; + int Num; + + + static TT_Error + LoadTrueTypeChar( int idx ) + { + return TT_Load_Glyph( instance, glyph, idx, TTLOAD_DEFAULT ); + } + + + static void + Usage( char* name ) + { + char* gt; + + + gt = gettext( "ftlint: Simple TrueType instruction tester -- part of the FreeType project" ); + fprintf( stderr, "%s\n", gt ); + separator_line( stderr, strlen( gt ) ); + + fprintf( stderr, gettext( + "Usage: %s ppem fontname[.ttf|.ttc] [fontname2..]\n\n" ), name ); + + exit( EXIT_FAILURE ); + } + + + int + main( int argc, char** argv ) + { + int i, file_index; + unsigned int id; + char filename[128 + 4]; + char alt_filename[128 + 4]; + char* execname; + char* fname; + + +#ifdef HAVE_LIBINTL_H + setlocale( LC_ALL, "" ); + bindtextdomain( "freetype", LOCALEDIR ); + textdomain( "freetype" ); +#endif + + execname = argv[0]; + + if ( argc < 3 ) + Usage( execname ); + + if ( sscanf( argv[1], "%d", &ptsize ) != 1 ) + Usage( execname ); + + /* Initialize engine */ + if ( (error = TT_Init_FreeType( &engine )) ) + { + fprintf( stderr, + gettext( "Error while initializing engine.\n" ) ); + goto Failure; + } + + /* Now check all files */ + for ( file_index = 2; file_index < argc; file_index++ ) + { + fname = argv[file_index]; + i = strlen( fname ); + while ( i > 0 && fname[i] != '\\' && fname[i] != '/' ) + { + if ( fname[i] == '.' ) + i = 0; + i--; + } + + filename[128] = '\0'; + alt_filename[128] = '\0'; + + strncpy( filename, fname, 128 ); + strncpy( alt_filename, fname, 128 ); + + if ( i >= 0 ) + { + strncpy( filename + strlen( filename ), ".ttf", 4 ); + strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 ); + } + + /* Load face */ + error = TT_Open_Face( engine, filename, &face ); + + if ( error == TT_Err_Could_Not_Open_File ) + { + strcpy( filename, alt_filename ); + error = TT_Open_Face( engine, alt_filename, &face ); + } + + i = strlen( filename ); + fname = filename; + + while ( i >= 0 ) + if ( filename[i] == '/' || filename[i] == '\\' ) + { + fname = filename + i + 1; + i = -1; + } + else + i--; + + fprintf( stderr, "%s: ", fname ); + + if ( error == TT_Err_Could_Not_Open_File ) + { + fprintf( stderr, gettext( "Could not find or open %s.\n" ), + filename ); + goto Fail_Face; + } + if ( error ) + { + fprintf( stderr, gettext( "Error while opening %s.\n" ), filename ); + goto Fail_Face; + } + + /* get face properties */ + + TT_Get_Face_Properties( face, &properties ); + num_glyphs = properties.num_Glyphs; + + /* create glyph */ + error = TT_New_Glyph( face, &glyph ); + if ( error ) + { + fprintf( stderr, + gettext( "Could not create glyph container.\n" ) ); + goto Fail_Glyph; + } + + /* create instance */ + error = TT_New_Instance( face, &instance ); + if ( error ) + { + fprintf( stderr, gettext( "Could not create instance.\n" ) ); + goto Fail_Instance; + } + + error = TT_Set_Instance_PixelSizes( instance, + ptsize, + ptsize, + ptsize*3/4 ); + if ( error ) + { + fprintf( stderr, + gettext( "Could not set point size to %d.\n" ), + ptsize ); + goto Fail_Set; + } + + Fail = 0; + + for ( id = 0; id < num_glyphs; id++ ) + { + if ( (error = LoadTrueTypeChar( id )) ) + { + if ( Fail < 10 ) + { + fprintf( stderr, !Fail ? gettext( "Error with\n " ) : " " ); + fprintf( stderr, gettext( "glyph %4u: %s\n" ), + id, TT_ErrToString18( error ) ); + } + Fail++; + } + } + + if ( Fail == 0 ) + fprintf( stderr, "OK.\n" ); + else + { + fprintf( stderr, " " ); + if ( Fail == 1 ) + fprintf( stderr, gettext( "1 fail.\n" ) ); + else + fprintf( stderr, gettext( "%d fails.\n" ), Fail ); + } + + /* hush complaints at the end of the loop */ + error = 0; + + Fail_Set: + TT_Done_Instance( instance ); + Fail_Instance: + TT_Done_Glyph( glyph ); + Fail_Glyph: + TT_Close_Face( face ); + Fail_Face: + ; + + + if ( error ) + { + fprintf( stderr, " " ); + fprintf( stderr, gettext( "FreeType error message: %s\n" ), + TT_ErrToString18( error ) ); + } + } + + TT_Done_FreeType( engine ); + + exit( EXIT_SUCCESS ); /* for safety reasons */ + + return 0; /* never reached */ + + Failure: + fprintf( stderr, " " ); + fprintf( stderr, gettext( "FreeType error message: %s\n" ), + TT_ErrToString18( error ) ); + + exit( EXIT_FAILURE ); + + return 0; /* never reached */ + } + + +/* End */ diff --git a/test/ftmetric.c b/test/ftmetric.c new file mode 100644 index 0000000..7b5f02b --- /dev/null +++ b/test/ftmetric.c @@ -0,0 +1,396 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1999 by */ +/* Yamano'uchi H. and W. Lemberg */ +/* */ +/* ftmetric: dump metrics and a glyph. */ +/* */ +/* NOTE: This is just a test program that is used to debug */ +/* the current engine. */ +/* */ +/****************************************************************************/ + +#include +#include +#include + +#include "common.h" +#include "freetype.h" +#include "ftxsbit.h" + +/* + * Basically, an external program using FreeType shouldn't depend on an + * internal file of the FreeType library, especially not on ft_conf.h -- but + * to avoid another configure script which tests for the existence of the + * i18n stuff we include ft_conf.h here since we can be sure that our test + * programs use the same configuration options as the library itself. + */ + +#include "ft_conf.h" + + +#ifdef HAVE_LIBINTL_H + +#ifdef HAVE_LOCALE_H +#include +#endif + +#include +#include "ftxerr18.h" + +#else /* !HAVE_LIBINTL */ + +#define gettext( x ) ( x ) + + /* We ignore error message strings with this function */ + + static char* + TT_ErrToString18( TT_Error error ) + { + static char temp[32]; + + + sprintf( temp, "0x%04lx", error ); + return temp; + } + +#endif /* !HAVE_LIBINTL */ + + static void + usage( char* execname ) + { + char* gt; + + + fprintf( stderr, "\n" ); + gt = gettext( "ftmetric: Simple TTF metrics/glyph dumper -- part of the FreeType project" ); + fprintf( stderr, "%s\n", gt ); + separator_line( stderr, strlen( gt ) ); + fprintf( stderr, gettext( + "Usage: %s [options below] point fontname[.ttf|.ttc]\n" + "\n" + " -B show sbit's metrics (default: none)\n" + " -c C use C'th font index of TrueType collection (default: 0)\n" + " -i index glyph index (default: 0)\n" + " -r R use resolution R dpi (default: 72)\n" + "\n" ), execname ); + + exit( EXIT_FAILURE ); + } + + + static void + Show_Metrics( TT_Big_Glyph_Metrics metrics, + char* title ) + { + int show_advance = 1; + + + printf("%s: xMin %d, xMax %d, yMin %d, yMax %d", + title, + (int)(metrics.bbox.xMin / 64), + (int)(metrics.bbox.xMax / 64), + (int)(metrics.bbox.yMin / 64), + (int)(metrics.bbox.yMax / 64)); + + + if ( show_advance ) + printf( ", advance width %d", (int)(metrics.horiAdvance / 64) ); + + printf("\n"); + return; + } + + + int + main( int argc, char** argv ) + { + int i, orig_ptsize, file; + char filename[128 + 4]; + char alt_filename[128 + 4]; + char* execname; + int option; + + int ptsize; + int num_Faces = 0; + int glyph_index = 0; + int load_flags = TTLOAD_DEFAULT; + + int force_sbit = 0; + + TT_Engine engine; + + TT_Face face; + TT_Instance instance; + TT_Glyph glyph; + + TT_Raster_Map map; + + TT_Big_Glyph_Metrics metrics; + TT_Face_Properties properties; + TT_Instance_Metrics imetrics; + + TT_EBLC eblc; + TT_SBit_Image* bitmap = NULL; + + TT_Error error; + + + int res = 72; + +#ifdef HAVE_LIBINTL_H + setlocale( LC_ALL, "" ); + bindtextdomain( "freetype", LOCALEDIR ); + textdomain( "freetype" ); +#endif + + execname = ft_basename( argv[0] ); + + while ( 1 ) + { + option = ft_getopt( argc, argv, "c:r:i:B" ); + + if ( option == -1 ) + break; + + switch ( option ) + { + case 'r': + res = atoi( ft_optarg ); + if ( res < 1 ) + usage( execname ); + break; + + case 'c': + num_Faces = atoi( ft_optarg ); + if ( num_Faces < 0 ) + usage( execname ); + break; + + case 'i': + glyph_index = atoi( ft_optarg ); + if ( glyph_index < 0 ) + usage( execname ); + break; + + case 'B': + force_sbit = 1; + break; + + default: + usage( execname ); + break; + } + } + + argc -= ft_optind; + argv += ft_optind; + + if ( argc <= 1 ) + usage( execname ); + + if ( sscanf( argv[0], "%d", &orig_ptsize ) != 1 ) + orig_ptsize = 64; + + file = 1; + + ptsize = orig_ptsize; + + i = strlen( argv[file] ); + while ( i > 0 && argv[file][i] != '\\' && argv[file][i] != '/' ) + { + if ( argv[file][i] == '.' ) + i = 0; + i--; + } + + filename[128] = '\0'; + alt_filename[128] = '\0'; + + strncpy( filename, argv[file], 128 ); + strncpy( alt_filename, argv[file], 128 ); + + if ( i >= 0 ) + { + strncpy( filename + strlen( filename ), ".ttf", 4 ); + strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 ); + } + + /* Initialize engine */ + + error = TT_Init_FreeType( &engine ); + if ( error ) + { + fprintf( stderr, gettext( "Error while initializing engine.\n" ) ); + goto Failure; + } + + error = TT_Init_SBit_Extension( engine ); + if ( error ) + { + fprintf( stderr, gettext( + "Error while initializing embedded bitmap extension.\n" ) ); + goto Failure; + } + + /* Load face */ + + error = TT_Open_Face( engine, filename, &face ); + + if ( error == TT_Err_Could_Not_Open_File ) + { + strcpy( filename, alt_filename ); + error = TT_Open_Face( engine, alt_filename, &face ); + } + + if ( error == TT_Err_Could_Not_Open_File ) + Panic( gettext( "Could not find or open %s.\n" ), filename ); + if ( error ) + { + fprintf( stderr, gettext( "Error while opening %s.\n" ), + filename ); + goto Failure; + } + + TT_Get_Face_Properties( face, &properties ); + + printf( gettext( "There are %d fonts in this collection.\n" ), + (int)(properties.num_Faces) ); + + if ( num_Faces >= properties.num_Faces ) + Panic( gettext( + "There is no collection with index %d in this font file.\n" ), + num_Faces ); + + TT_Close_Face( face ); + + error = TT_Open_Collection( engine, filename, num_Faces, &face ); + + /* get face properties and eblc */ + + TT_Get_Face_Properties( face, &properties ); + if ( force_sbit ) + { + error = TT_Get_Face_Bitmaps( face, &eblc ); + if ( error == TT_Err_Table_Missing ) + Panic( gettext( "There is no embedded bitmap data in the font.\n" ) ); + if ( error ) + { + fprintf( stderr, gettext( + "Error while retrieving embedded bitmaps table.\n" ) ); + goto Failure; + } + } + + /* create glyph */ + + error = TT_New_Glyph( face, &glyph ); + if ( error ) + { + fprintf( stderr, gettext( "Could not create glyph container.\n" ) ); + goto Failure; + } + + /* create instance */ + + error = TT_New_Instance( face, &instance ); + if ( error ) + { + fprintf( stderr, gettext( "Could not create instance.\n" ) ); + goto Failure; + } + + error = TT_Set_Instance_Resolutions( instance, res, res ); + if ( error ) + { + fprintf( stderr, gettext( "Could not set device resolutions.\n" ) ); + goto Failure; + } + + error = TT_Set_Instance_CharSize( instance, ptsize*64 ); + if ( error ) + { + fprintf( stderr, gettext( "Could not reset instance.\n" ) ); + goto Failure; + } + + TT_Get_Instance_Metrics( instance, &imetrics ); + + printf( gettext( "Instance metrics: ppemX %d, ppemY %d\n" ), + imetrics.x_ppem, + imetrics.y_ppem ); + + if ( force_sbit ) + { + error = TT_New_SBit_Image( &bitmap ); + if ( error ) + { + fprintf( stderr, gettext( + "Could not allocate glyph bitmap container.\n" ) ); + goto Failure; + } + + error = TT_Load_Glyph_Bitmap( face, instance, glyph_index, bitmap ); + if ( error ) + { + fprintf( stderr, gettext( + "Can't load bitmap for glyph %d.\n" ), glyph_index ); + goto Failure; + } + + Show_Metrics( bitmap->metrics, "SBit's metrics" ); + + printf( "SBit glyph:\n" ); + Show_Single_Glyph( &bitmap->map ); + } + else + { + TT_Load_Glyph( instance, glyph, glyph_index, load_flags ); + TT_Get_Glyph_Big_Metrics( glyph, &metrics ); + + map.width = ( metrics.bbox.xMax - metrics.bbox.xMin ) / 64; + map.rows = ( metrics.bbox.yMax - metrics.bbox.yMin ) / 64; + map.cols = ( map.width + 7 ) / 8; + map.size = map.cols * map.rows; + map.bitmap = malloc( map.size ); + map.flow = TT_Flow_Down; + + memset( map.bitmap, 0, map.size ); + + error = TT_Get_Glyph_Bitmap( glyph, &map, + -metrics.bbox.xMin, + -metrics.bbox.yMin ); + + Show_Metrics( metrics, gettext( "Outline's metrics" ) ); + + printf( gettext( "Outline glyph\n" ) ); + Show_Single_Glyph( &map ); + } + + free( map.bitmap ); + + if ( bitmap ) + TT_Done_SBit_Image( bitmap ); + + TT_Done_Instance( instance ); + TT_Done_Glyph( glyph ); + TT_Done_FreeType( engine ); + + exit( EXIT_SUCCESS ); /* for safety reasons */ + + return 0; /* never reached */ + + Failure: + fprintf( stderr, " " ); + fprintf( stderr, gettext( "FreeType error message: %s\n" ), + TT_ErrToString18( error ) ); + + exit( EXIT_FAILURE ); + + return 0; /* never reached */ + } + + +/* End */ diff --git a/test/ftsbit.c b/test/ftsbit.c new file mode 100644 index 0000000..b6d1fa1 --- /dev/null +++ b/test/ftsbit.c @@ -0,0 +1,293 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* ftsbit: a _very_ simple embedded bitmap dumper for FreeType 1.x. */ +/* */ +/* NOTE: This is just a test program that is used to show off and */ +/* debug the current engine. */ +/* */ +/****************************************************************************/ + +#include +#include +#include + +#include "common.h" + +#include "freetype.h" +#include "ftxsbit.h" + +/* + * Basically, an external program using FreeType shouldn't depend on an + * internal file of the FreeType library, especially not on ft_conf.h -- but + * to avoid another configure script which tests for the existence of the + * i18n stuff we include ft_conf.h here since we can be sure that our test + * programs use the same configuration options as the library itself. + */ + +#include "ft_conf.h" + + +#ifdef HAVE_LIBINTL_H + +#ifdef HAVE_LOCALE_H +#include +#endif + +#include +#include "ftxerr18.h" + +#else /* !HAVE_LIBINTL */ + +#define gettext( x ) ( x ) + + /* We ignore error message strings with this function */ + + static char* TT_ErrToString18( TT_Error error ) + { + static char temp[32]; + + + sprintf( temp, "0x%04lx", error ); + return temp; + } + +#endif /* !HAVE_LIBINTL */ + + + TT_Error error; + + TT_Engine engine; + + TT_Face face; + TT_Instance instance; + TT_Glyph glyph; + + TT_Outline outline; + TT_Glyph_Metrics metrics; + + TT_Face_Properties properties; + TT_EBLC eblc; + TT_SBit_Image* bitmap; + + unsigned int num_glyphs; + int ptsize; + + int Fail; + int Num; + + + static void Usage( char* name ) + { + char* gt; + + + gt = gettext( "ftsbit: Simple TrueType `sbit' dumper -- part of the FreeType project" ); + fprintf( stderr, "%s\n", gt ); + separator_line( stderr, strlen( gt ) ); + + fprintf( stderr, gettext( + "Usage: %s ppem fontname[.ttf|.ttc] glyph_index [glyph_index2..]\n\n" ), name ); + + exit( EXIT_FAILURE ); + } + + + int main( int argc, char** argv ) + { + int i; + char filename[128 + 4]; + char alt_filename[128 + 4]; + char* execname; + char* fname; + + +#ifdef HAVE_LIBINTL_H + setlocale( LC_ALL, "" ); + bindtextdomain( "freetype", LOCALEDIR ); + textdomain( "freetype" ); +#endif + + execname = argv[0]; + + if ( argc < 3 ) + Usage( execname ); + + if ( sscanf( argv[1], "%d", &ptsize ) != 1 ) + Usage( execname ); + + /* Initialize engine */ + if ( (error = TT_Init_FreeType( &engine )) ) + { + fprintf( stderr, gettext( "Error while initializing engine.\n" ) ); + goto Failure; + } + + if ( (error = TT_Init_SBit_Extension( engine )) ) + { + fprintf( stderr, gettext( + "Error while initializing embedded bitmap extension.\n" ) ); + goto Failure; + } + + /* Now check all files */ + fname = argv[2]; + i = strlen( fname ); + while ( i > 0 && fname[i] != '\\' && fname[i] != '/' ) + { + if ( fname[i] == '.' ) + i = 0; + i--; + } + + filename[128] = '\0'; + alt_filename[128] = '\0'; + + strncpy( filename, fname, 128 ); + strncpy( alt_filename, fname, 128 ); + + if ( i >= 0 ) + { + strncpy( filename + strlen( filename ), ".ttf", 4 ); + strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 ); + } + + /* Load face */ + error = TT_Open_Face( engine, filename, &face ); + if ( error == TT_Err_Could_Not_Open_File ) + { + strcpy( filename, alt_filename ); + error = TT_Open_Face( engine, alt_filename, &face ); + } + + i = strlen( filename ); + fname = filename; + + while ( i >= 0 ) + if ( filename[i] == '/' || filename[i] == '\\' ) + { + fname = filename + i + 1; + i = -1; + } + else + i--; + + if ( error ) + { + fprintf( stderr, gettext( "Could not find or open %s.\n" ), + filename ); + goto Failure; + } + if ( error ) + { + fprintf( stderr, gettext( "Error while opening %s.\n" ), filename ); + goto Failure; + } + + /* get face properties */ + TT_Get_Face_Properties( face, &properties ); + num_glyphs = properties.num_Glyphs; + + error = TT_Get_Face_Bitmaps( face, &eblc ); + if ( error == TT_Err_Table_Missing ) + { + fprintf( stderr, gettext( + "Could not find embedded bitmaps in this font.\n" ) ); + goto Failure; + } + if ( error ) + { + fprintf( stderr, gettext( + "Error while loading embedded bitmaps.\n" ) ); + goto Failure; + } + + /* create instance */ + error = TT_New_Instance( face, &instance ); + if ( error ) + { + fprintf( stderr, gettext( "Could not create instance.\n" ) ); + goto Failure; + } + + error = TT_Set_Instance_PixelSizes( instance, + ptsize, + ptsize, + ptsize*3/4 ); + if ( error ) + { + fprintf( stderr, + gettext( "Could not set point size to %d.\n" ), + ptsize ); + goto Failure; + } + + error = TT_New_SBit_Image( &bitmap ); + if ( error ) + { + fprintf( stderr, gettext( + "Could not allocate glyph bitmap container.\n" ) ); + goto Failure; + } + + for ( i = 3; i < argc; i++ ) + { + unsigned short glyph_index; + + + /* we use %i to allow the prefixes `0x' and `0' */ + if ( sscanf( argv[i], "%hi", &glyph_index ) != 1 ) + Usage( execname ); + + error = TT_Load_Glyph_Bitmap( face, instance, glyph_index, bitmap ); + + if ( error == TT_Err_Invalid_Glyph_Index ) + { + fprintf( stderr, gettext( + " no bitmap for glyph %d.\n" ), glyph_index ); + continue; + } + if ( error ) + { + fprintf( stderr, gettext( + "Can't load bitmap for glyph %d.\n" ), glyph_index ); + goto Failure; + } + + /* Dump the resulting bitmap */ + { + printf( gettext( "glyph index %d = %dx%d pixels, " ), + glyph_index, bitmap->map.rows, bitmap->map.width ); + + printf( gettext( "advance = %ld, minBearing = [%ld,%ld]\n" ), + (long)(bitmap->metrics.horiAdvance / 64), + (long)(bitmap->metrics.horiBearingX / 64), + (long)(bitmap->metrics.horiBearingY / 64)); + + Show_Single_Glyph( &bitmap->map ); + } + } + + TT_Done_SBit_Image( bitmap ); + TT_Done_FreeType( engine ); + + exit( EXIT_SUCCESS ); /* for safety reasons */ + + return 0; /* never reached */ + + Failure: + fprintf( stderr, " " ); + fprintf( stderr, gettext( "FreeType error message: %s\n" ), + TT_ErrToString18( error ) ); + + exit( EXIT_FAILURE ); + + return 0; /* never reached */ + } + + +/* End */ diff --git a/test/ftstring.c b/test/ftstring.c new file mode 100644 index 0000000..286a136 --- /dev/null +++ b/test/ftstring.c @@ -0,0 +1,486 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* ftstring: Making string text from individual glyph information. */ +/* */ +/* Keys: */ +/* */ +/* + : fast scale up */ +/* - : fast scale down */ +/* u : fine scale down */ +/* j : fine scale up */ +/* */ +/* h : toggle hinting */ +/* */ +/* ESC : exit */ +/* */ +/* */ +/* NOTE: This is just a test program that is used to show off and */ +/* debug the current engine. */ +/* */ +/****************************************************************************/ + +#include +#include +#include + +#include "common.h" /* for Panic() and Message() only */ +#include "display.h" +#include "freetype.h" + +#include "gevents.h" +#include "gdriver.h" +#include "gmain.h" + +#define Pi 3.1415926535 + +#define MAXPTSIZE 500 /* dtp */ +#define Center_X ( Bit.width / 2 ) /* dtp */ +#define Center_Y ( Bit.rows / 2 ) /* dtp */ + + char Header[128]; + + TT_Engine engine; + TT_Face face; + TT_Instance instance; + TT_Glyph glyph; + TT_CharMap char_map; + + TT_Glyph_Metrics metrics; + TT_Outline outline; + TT_Face_Properties properties; + TT_Instance_Metrics imetrics; + + int num_glyphs; + + int ptsize; + int hinted; + + int Rotation; + int Fail; + int Num; + unsigned char autorun; + + int gray_render; + + short glyph_code[128]; + int num_codes; + +/* Convert an ASCII string to a string of glyph indexes. */ +/* */ +/* IMPORTANT NOTE: */ +/* */ +/* There is no portable way to convert from any system's char. code */ +/* to Unicode. This function simply takes a char. string as argument */ +/* and "interprets" each character as a Unicode char. index with no */ +/* further check. */ +/* */ +/* This mapping is only valid for the ASCII character set (i.e., */ +/* codes 32 to 127); all other codes (like accentuated characters) */ +/* will produce more or less random results, depending on the system */ +/* being run. */ + + static void CharToUnicode( char* source ) + { + unsigned short i, n; + unsigned short platform, encoding; + + /* First, look for a Unicode charmap */ + + n = properties.num_CharMaps; + + for ( i = 0; i < n; i++ ) + { + TT_Get_CharMap_ID( face, i, &platform, &encoding ); + if ( (platform == 3 && encoding == 1 ) || + (platform == 0 && encoding == 0 ) ) + { + TT_Get_CharMap( face, i, &char_map ); + i = n + 1; + } + } + + if ( i == n ) + Panic( "Sorry, but this font doesn't contain any Unicode mapping table\n" ); + + for ( n = 0; n < 128 && source[n]; n++ ) + glyph_code[n] = TT_Char_Index( char_map, (short)source[n] ); + +#if 0 + /* Note, if you have a function, say ToUnicode(), to convert from */ + /* char codes to Unicode, use the following line instead: */ + + glyph_code[n] = TT_Char_Index( char_map, ToUnicode( source[n] ) ); +#endif + + num_codes = n; + } + + + static TT_Error Reset_Scale( int pointSize ) + { + TT_Error error; + + + if ( (error = TT_Set_Instance_PointSize( instance, pointSize )) ) + { + RestoreScreen(); + printf( "error = 0x%x\n", (int)error ); + Panic( "could not reset instance\n" ); + } + + TT_Get_Instance_Metrics( instance, &imetrics ); + + /* now re-allocate the small bitmap */ + if ( gray_render ) + { + Init_Small( imetrics.x_ppem, imetrics.y_ppem ); + Clear_Small(); + } + + return TT_Err_Ok; + } + + + static TT_Error LoadTrueTypeChar( int idx, int hint ) + { + int flags; + + + flags = TTLOAD_SCALE_GLYPH; + if ( hint ) + flags |= TTLOAD_HINT_GLYPH; + + return TT_Load_Glyph( instance, glyph, idx, flags ); + } + + + static TT_Error Render_All( void ) + { + TT_F26Dot6 x, y, z, minx, miny, maxx, maxy; + int i; + + TT_Error error; + + + /* On the first pass, we compute the compound bounding box */ + + x = y = 0; + + minx = miny = maxx = maxy = 0; + + for ( i = 0; i < num_codes; i++ ) + { + if ( !(error = LoadTrueTypeChar( glyph_code[i], hinted )) ) + { + TT_Get_Glyph_Metrics( glyph, &metrics ); + + z = x + metrics.bbox.xMin; + if ( minx > z ) + minx = z; + + z = x + metrics.bbox.xMax; + if ( maxx < z ) + maxx = z; + + z = y + metrics.bbox.yMin; + if ( miny > z ) + miny = z; + + z = y + metrics.bbox.yMax; + if ( maxy < z ) + maxy = z; + + x += metrics.advance & -64; + } + else + Fail++; + } + + /* We now center the bbox inside the target bitmap */ + + minx = ( minx & -64 ) >> 6; + miny = ( miny & -64 ) >> 6; + + maxx = ( (maxx+63) & -64 ) >> 6; + maxy = ( (maxy+63) & -64 ) >> 6; + + maxx -= minx; + maxy -= miny; + + minx = (Bit.width - maxx)/2; + miny = (Bit.rows + miny)/2; + + maxx += minx; + maxy += maxy; + + /* On the second pass, we render each glyph to its centered position. */ + /* This is slow, because we reload each glyph to render it! */ + + x = minx; + y = miny; + + for ( i = 0; i < num_codes; i++ ) + { + if ( !(error = LoadTrueTypeChar( glyph_code[i], hinted )) ) + { + TT_Get_Glyph_Metrics( glyph, &metrics ); + + Render_Single_Glyph( gray_render, glyph, x, y ); + + x += metrics.advance/64; + } + } + + return TT_Err_Ok; + } + + + static int Process_Event( TEvent* event ) + { + switch ( event->what ) + { + case event_Quit: /* ESC or q */ + return 0; + + case event_Keyboard: + if ( event->info == 'h' ) /* Toggle hinting */ + hinted = !hinted; + break; + + case event_Rotate_Glyph: + break; + + case event_Scale_Glyph: + ptsize += event->info; + if ( ptsize < 1 ) ptsize = 1; + if ( ptsize > MAXPTSIZE ) ptsize = MAXPTSIZE; + break; + + case event_Change_Glyph: + break; + } + + return 1; + } + + + static void usage( char* execname ) + { + printf( "\n" ); + printf( "ftstring: simple String Test Display -- part of the FreeType project\n" ); + printf( "--------------------------------------------------------------------\n" ); + printf( "\n" ); + printf( "Usage: %s [options below] ppem fontname[.ttf|.ttc] [string]\n", + execname ); + printf( "\n" ); + printf( " -g gray-level rendering (default: none)\n" ); + printf( " -r R use resolution R dpi (default: 96)\n" ); + printf( "\n" ); + + exit( EXIT_FAILURE ); + } + + + int main( int argc, char** argv ) + { + int i, old_ptsize, orig_ptsize, file; + int XisSetup = 0; + char filename[128 + 4]; + char alt_filename[128 + 4]; + char* execname; + int option; + int res = 96; + + TT_Error error; + TEvent event; + + + execname = argv[0]; + + while ( 1 ) + { + option = ft_getopt( argc, argv, "gr:" ); + + if ( option == -1 ) + break; + + switch ( option ) + { + case 'g': + gray_render = 1; + break; + + case 'r': + res = atoi( ft_optarg ); + if ( res < 1 ) + usage( execname ); + break; + + default: + usage( execname ); + break; + } + } + + argc -= ft_optind; + argv += ft_optind; + + if ( argc <= 1 ) + usage( execname ); + + if ( sscanf( argv[0], "%d", &orig_ptsize ) != 1 ) + orig_ptsize = 64; + + file = 1; + + /* Initialize engine */ + + if ( (error = TT_Init_FreeType( &engine )) ) + Panic( "Error while initializing engine, code = 0x%x.\n", error ); + + ptsize = orig_ptsize; + hinted = 1; + + i = strlen( argv[file] ); + while ( i > 0 && argv[file][i] != '\\' && argv[file][i] != '/' ) + { + if ( argv[file][i] == '.' ) + i = 0; + i--; + } + + filename[128] = '\0'; + alt_filename[128] = '\0'; + + strncpy( filename, argv[file], 128 ); + strncpy( alt_filename, argv[file], 128 ); + + if ( i >= 0 ) + { + strncpy( filename + strlen( filename ), ".ttf", 4 ); + strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 ); + } + + /* Load face */ + + error = TT_Open_Face( engine, filename, &face ); + + if ( error == TT_Err_Could_Not_Open_File ) + { + strcpy( filename, alt_filename ); + error = TT_Open_Face( engine, alt_filename, &face ); + } + + if ( error == TT_Err_Could_Not_Open_File ) + Panic( "Could not find/open %s.\n", filename ); + else if (error) + Panic( "Error while opening %s, error code = 0x%x.\n", + filename, error ); + + /* get face properties and allocate preload arrays */ + + TT_Get_Face_Properties( face, &properties ); + + num_glyphs = properties.num_Glyphs; + + /* create glyph */ + + error = TT_New_Glyph( face, &glyph ); + if ( error ) + Panic( "Could not create glyph container.\n" ); + + /* create instance */ + + error = TT_New_Instance( face, &instance ); + if ( error ) + Panic( "Could not create instance for %s.\n", filename ); + + error = TT_Set_Instance_Resolutions( instance, res, res ); + if ( error ) + Panic( "Could not set device resolutions." ); + + if ( !XisSetup ) + { + XisSetup = 1; + + if ( gray_render ) + { + if ( !SetGraphScreen( Graphics_Mode_Gray ) ) + Panic( "Could not set up grayscale graphics mode.\n" ); + + TT_Set_Raster_Gray_Palette( engine, virtual_palette ); + } + else + { + if ( !SetGraphScreen( Graphics_Mode_Mono ) ) + Panic( "Could not set up mono graphics mode.\n" ); + } + } + + Init_Display( gray_render ); + + Reset_Scale( ptsize ); + + old_ptsize = ptsize; + + Fail = 0; + Num = 0; + + CharToUnicode( ( argv[2] ? argv[2] : + "The quick brown fox jumps over the lazy dog" ) ); + + for ( ;; ) + { + int key; + + + Clear_Display(); + Render_All(); + if ( gray_render ) + Convert_To_Display_Palette(); + + sprintf( Header, "%s: ptsize: %4d hinting: %s", + ft_basename( filename ), ptsize, + hinted ? "on" : "off" ); + + Display_Bitmap_On_Screen( Bit.bitmap, Bit.rows, Bit.cols ); + +#ifndef X11 +#ifndef OS2 + Print_XY( 0, 0, Header ); +#endif +#endif + + Get_Event( &event ); + if ( !( key = Process_Event( &event ) ) ) + goto Fin; + + if ( ptsize != old_ptsize ) + { + if ( Reset_Scale( ptsize ) ) + Panic( "Could not resize font.\n" ); + + old_ptsize = ptsize; + } + } + + Fin: + RestoreScreen(); + + TT_Done_FreeType( engine ); + + printf( "Execution completed successfully.\n" ); + printf( "Fails = %d.\n", Fail ); + + exit( EXIT_SUCCESS ); /* for safety reasons */ + + return 0; /* never reached */ +} + + +/* End */ diff --git a/test/ftstrpnm.c b/test/ftstrpnm.c new file mode 100644 index 0000000..a5ee67e --- /dev/null +++ b/test/ftstrpnm.c @@ -0,0 +1,510 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* ftstrpnm: convert text to image (in PGM or PBM format) */ +/* */ +/* NOTE: This is just a test program that is used to show off and */ +/* debug the current engine. */ +/* */ +/****************************************************************************/ + +#define PROGNAME "ftstrpnm" + +#include +#include +#include + +#include "common.h" /* for ft_getopt() */ +#include "freetype.h" + +#define TT_VALID( handle ) ( ( handle ).z != NULL ) + + + /* Global variables */ + + TT_Engine engine; + TT_Face face; + TT_Instance instance; + + TT_Face_Properties properties; + + TT_Raster_Map bit; + TT_Raster_Map small_bit; /* used when font-smoothing is enabled */ + + int pnm_width, pnm_height; + int pnm_x_shift, pnm_y_shift; + + + /* Loaded glyphs for all characters */ + + TT_Glyph *glyphs = NULL; + + + /* Options */ + + int dpi = 96; + int ptsize = 12; + int hinted = 1; + int smooth = 0; + int border = 0; + + + /* raster map management */ + + static void Init_Raster_Map( TT_Raster_Map* bit, int width, int height ) + { + bit->rows = height; + bit->width = ( width + 3 ) & -4; + bit->flow = TT_Flow_Down; + + if ( smooth ) + { + bit->cols = bit->width; + bit->size = bit->rows * bit->width; + } + else + { + bit->cols = ( bit->width + 7 ) / 8; /* convert to # of bytes */ + bit->size = bit->rows * bit->cols; /* number of bytes in buffer */ + } + + bit->bitmap = (void *) malloc( bit->size ); + if ( !bit->bitmap ) + Panic( "Not enough memory to allocate bitmap!\n" ); + } + + + static void Done_Raster_Map( TT_Raster_Map *bit ) + { + free( bit->bitmap ); + bit->bitmap = NULL; + } + + + static void Clear_Raster_Map( TT_Raster_Map* bit ) + { + memset( bit->bitmap, 0, bit->size ); + } + + + static void Blit_Or( TT_Raster_Map* dst, TT_Raster_Map* src, + int x_off, int y_off ) + { + int x, y; + int x1, x2, y1, y2; + char *s, *d; + + + /* clipping */ + + x1 = x_off < 0 ? -x_off : 0; + y1 = y_off < 0 ? -y_off : 0; + + x2 = (int)dst->cols - x_off; + if ( x2 > src->cols ) + x2 = src->cols; + + y2 = (int)dst->rows - y_off; + if ( y2 > src->rows ) + y2 = src->rows; + + if ( x1 >= x2 ) + return; + + /* do the real work now */ + + for ( y = y1; y < y2; ++y ) + { + s = ( (char*)src->bitmap ) + y * src->cols + x1; + d = ( (char*)dst->bitmap ) + ( y + y_off ) * dst->cols + x1 + x_off; + + for ( x = x1; x < x2; ++x ) + *d++ |= *s++; + } + } + + + static void Dump_Raster_Map( TT_Raster_Map* bit, FILE* file ) + { + /* kudos for this code snippet go to Norman Walsh */ + + char* bmap; + int i; + + + bmap = (char *)bit->bitmap; + + if ( smooth ) + { + fprintf( file, "P5\n%d %d\n4\n", pnm_width, pnm_height ); + for ( i = bit->size - 1; i >= 0; --i ) + bmap[i] = bmap[i] > 4 ? 0 : 4 - bmap[i]; + for ( i = pnm_height; i > 0; --i, bmap += bit->cols ) + fwrite( bmap, 1, pnm_width, file ); + } + else + { + fprintf( file, "P4\n%d %d\n", pnm_width, pnm_height ); + for ( i = pnm_height; i > 0; --i, bmap += bit->cols ) + fwrite( bmap, 1, (pnm_width+7) / 8, file ); + } + + fflush( file ); + } + + + /* glyph management */ + + static void Load_Glyphs( char* txt, int txtlen ) + { + unsigned short i, n, code, load_flags; + unsigned short num_glyphs = 0, no_cmap = 0; + unsigned short platform, encoding; + TT_Error error; + TT_CharMap char_map; + + + /* First, look for a Unicode charmap */ + + n = properties.num_CharMaps; + + for ( i = 0; i < n; i++ ) + { + TT_Get_CharMap_ID( face, i, &platform, &encoding ); + if ( (platform == 3 && encoding == 1 ) || + (platform == 0 && encoding == 0 ) ) + { + TT_Get_CharMap( face, i, &char_map ); + break; + } + } + + if ( i == n ) + { + TT_Face_Properties properties; + + + TT_Get_Face_Properties( face, &properties ); + + no_cmap = 1; + num_glyphs = properties.num_Glyphs; + } + + + /* Second, allocate the array */ + + glyphs = (TT_Glyph*)malloc( 256 * sizeof ( TT_Glyph ) ); + memset( glyphs, 0, 256 * sizeof ( TT_Glyph ) ); + + /* Finally, load the glyphs you need */ + + load_flags = TTLOAD_SCALE_GLYPH; + if ( hinted ) + load_flags |= TTLOAD_HINT_GLYPH; + + for ( i = 0; i < txtlen; ++i ) + { + unsigned char j = txt[i]; + + + if ( TT_VALID( glyphs[j] ) ) + continue; + + if ( no_cmap ) + { + code = (j - ' ' + 1) < 0 ? 0 : (j - ' ' + 1); + if ( code >= num_glyphs ) + code = 0; + } + else + code = TT_Char_Index( char_map, j ); + + (void)( + ( error = TT_New_Glyph( face, &glyphs[j] ) ) || + ( error = TT_Load_Glyph( instance, glyphs[j], code, load_flags ) ) + ); + + if ( error ) + Panic( "Cannot allocate and load glyph: error 0x%x.\n", error ); + } + } + + + static void Done_Glyphs( void ) + { + int i; + + + if ( !glyphs ) + return; + + for ( i = 0; i < 256; ++i ) + TT_Done_Glyph( glyphs[i] ); + + free( glyphs ); + + glyphs = NULL; + } + + + /* face & instance management */ + + static void Init_Face( const char* filename ) + { + TT_Error error; + + + /* load the typeface */ + + error = TT_Open_Face( engine, filename, &face ); + if ( error ) + { + if ( error == TT_Err_Could_Not_Open_File ) + Panic( "Could not find/open %s.\n", filename ); + else + Panic( "Error while opening %s, error code = 0x%x.\n", + filename, error ); + } + + TT_Get_Face_Properties( face, &properties ); + + /* create and initialize instance */ + + (void) ( + ( error = TT_New_Instance( face, &instance ) ) || + ( error = TT_Set_Instance_Resolutions( instance, dpi, dpi ) ) || + ( error = TT_Set_Instance_PointSize( instance, ptsize ) ) + ); + + if ( error ) + Panic( "Could not create and initialize instance: error 0x%x.\n", + error ); + } + + + static void Done_Face( void ) + { + TT_Done_Instance( instance ); + TT_Close_Face( face ); + } + + + /* rasterization stuff */ + + static void Init_Raster_Areas( const char* txt, int txtlen ) + { + int i, upm, ascent, descent; + TT_Face_Properties properties; + TT_Instance_Metrics imetrics; + TT_Glyph_Metrics gmetrics; + + + /* allocate the large bitmap */ + + TT_Get_Face_Properties( face, &properties ); + TT_Get_Instance_Metrics( instance, &imetrics ); + + upm = properties.header->Units_Per_EM; + ascent = ( properties.horizontal->Ascender * imetrics.y_ppem ) / upm; + descent = ( properties.horizontal->Descender * imetrics.y_ppem ) / upm; + + pnm_width = 2 * border; + pnm_height = 2 * border + ascent - descent; + + for ( i = 0; i < txtlen; ++i ) + { + unsigned char j = txt[i]; + + + if ( !TT_VALID( glyphs[j] ) ) + continue; + + TT_Get_Glyph_Metrics( glyphs[j], &gmetrics ); + pnm_width += gmetrics.advance / 64; + } + + Init_Raster_Map( &bit, pnm_width, pnm_height ); + Clear_Raster_Map( &bit ); + + pnm_x_shift = border; + pnm_y_shift = border - descent; + + /* allocate the small bitmap if you need it */ + + if ( smooth ) + Init_Raster_Map( &small_bit, imetrics.x_ppem + 32, pnm_height ); + } + + + static void Done_Raster_Areas( void ) + { + Done_Raster_Map( &bit ); + if ( smooth ) + Done_Raster_Map( &small_bit ); + } + + + static void Render_Glyph( TT_Glyph glyph, + int x_off, int y_off, + TT_Glyph_Metrics* gmetrics ) + { + if ( !smooth ) + TT_Get_Glyph_Bitmap( glyph, &bit, x_off * 64L, y_off * 64L); + else + { + TT_F26Dot6 xmin, ymin, xmax, ymax; + + + /* grid-fit the bounding box */ + + xmin = gmetrics->bbox.xMin & -64; + ymin = gmetrics->bbox.yMin & -64; + xmax = (gmetrics->bbox.xMax + 63) & -64; + ymax = (gmetrics->bbox.yMax + 63) & -64; + + /* now render the glyph in the small pixmap */ + /* and blit-or the resulting small pixmap into the biggest one */ + + Clear_Raster_Map( &small_bit ); + TT_Get_Glyph_Pixmap( glyph, &small_bit, -xmin, -ymin ); + Blit_Or( &bit, &small_bit, xmin/64 + x_off, -ymin/64 - y_off ); + } + } + + + static void Render_All_Glyphs( char* txt, int txtlen ) + { + int i; + TT_F26Dot6 x, y, adjx; + TT_Glyph_Metrics gmetrics; + + + x = pnm_x_shift; + y = pnm_y_shift; + + for ( i = 0; i < txtlen; i++ ) + { + unsigned char j = txt[i]; + + if ( !TT_VALID( glyphs[j] ) ) + continue; + + TT_Get_Glyph_Metrics( glyphs[j], &gmetrics ); + + adjx = x; /* ??? lsb */ + Render_Glyph( glyphs[j], adjx, y, &gmetrics ); + + x += gmetrics.advance / 64; + } + } + + + static void usage( void ) + { + printf( "\n" ); + printf( "%s: simple text to image converter -- part of the FreeType project\n", PROGNAME ); + printf( "\n" ); + printf( "Usage: %s [options below] filename [string]\n", PROGNAME ); + printf( "\n" ); + printf( " -g gray-level rendering (default: off)\n" ); + printf( " -h hinting off (default: on)\n" ); + printf( " -r X resolution X dpi (default: 96)\n" ); + printf( " -p X pointsize X pt (default: 12)\n" ); + printf( " -b X border X pixels wide (default: 0)\n" ); + printf( "\n" ); + + exit( EXIT_FAILURE ); + } + + + int main( int argc, char** argv ) + { + int option, txtlen; + char *txt, *filename; + TT_Error error; + + + /* Parse options */ + + while ( 1 ) + { + option = ft_getopt( argc, argv, "ghr:p:b:" ); + + if ( option == -1 ) + break; + + switch ( option ) + { + case 'g': + smooth = 1; + break; + case 'h': + hinted = 0; + break; + case 'r': + dpi = atoi( ft_optarg ); + break; + case 'p': + ptsize = atoi( ft_optarg ); + break; + case 'b': + border = atoi( ft_optarg ); + break; + + default: + usage(); + break; + } + } + + argc -= ft_optind; + argv += ft_optind; + + if ( argc <= 0 || argc > 2 || dpi <= 0 || ptsize <= 0 || border < 0 ) + usage(); + + filename = argv[0]; + + if ( argc > 1 ) + txt = argv[1]; + else + txt = "The quick brown fox jumps over the lazy dog"; + + txtlen = strlen( txt ); + + /* Initialize engine and other stuff */ + + error = TT_Init_FreeType( &engine ); + if ( error ) + Panic( "Error while initializing engine, code = 0x%x.\n", error ); + + Init_Face( filename ); + Load_Glyphs( txt, txtlen ); + Init_Raster_Areas( txt, txtlen ); + + /* Do the real work now */ + + Render_All_Glyphs( txt, txtlen ); + Dump_Raster_Map( &bit, stdout ); + + /* Clean up */ + + Done_Raster_Areas(); + Done_Glyphs(); + Done_Face(); + + /* That's all, folks! */ + + TT_Done_FreeType( engine ); + + exit( EXIT_SUCCESS ); /* for safety reasons */ + + return 0; /* never reached */ +} + + +/* End */ diff --git a/test/ftstrtto.c b/test/ftstrtto.c new file mode 100644 index 0000000..f23ced3 --- /dev/null +++ b/test/ftstrtto.c @@ -0,0 +1,1158 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* ftstrtto: Making string text from individual glyph information, using */ +/* TrueType Open features. */ +/* */ +/* Keys: */ +/* */ +/* + : fast scale up */ +/* - : fast scale down */ +/* u : fine scale down */ +/* j : fine scale up */ +/* */ +/* h : toggle hinting */ +/* K : toggle kerning */ +/* B : toggle sbit */ +/* G : toggle GSUB */ +/* */ +/* q : */ +/* ESC : exit */ +/* */ +/* */ +/* NOTE: This is just a test program that is used to show off and */ +/* debug the current engine. */ +/* */ +/****************************************************************************/ + +#include +#include +#include + +#include "arabic.h" +#include "blitter.h" +#include "common.h" /* for Panic() only */ +#include "display.h" + +#include "freetype.h" +#include "ftxkern.h" +#include "ftxopen.h" +#include "ftxsbit.h" + +#include "gdriver.h" +#include "gevents.h" +#include "gmain.h" + + +#define MAXPTSIZE 500 /* dtp */ +#define Center_X ( Bit.width / 2 ) /* dtp */ +#define Center_Y ( Bit.rows / 2 ) /* dtp */ + +#define FEATURE_init MAKE_TT_TAG( 'i', 'n', 'i', 't' ) +#define FEATURE_medi MAKE_TT_TAG( 'm', 'e', 'd', 'i' ) +#define FEATURE_fina MAKE_TT_TAG( 'f', 'i', 'n', 'a' ) +#define FEATURE_isol MAKE_TT_TAG( 'i', 's', 'o', 'l' ) + + + char Header[128]; + + TT_Engine engine; + TT_Face face; + TT_Instance instance; + TT_Glyph glyph; + TT_CharMap char_map; + TT_Kerning directory; + + TTO_GSUBHeader gsub_; + TTO_GSUBHeader* gsub; + TTO_GDEFHeader gdef_; + TTO_GDEFHeader* gdef; + + TT_Big_Glyph_Metrics metrics; + TT_Outline outline; + TT_Face_Properties face_properties; + TT_Instance_Metrics imetrics; + + TT_SBit_Image* sbit; + + int pt_size; + int ttc_index; + TT_Bool hinted; + TT_Bool gray_render; + TT_Bool r2l; + TT_Bool vertical; + + TT_Bool has_kern; + TT_Bool use_kern; + TT_Bool has_gdef; + TT_Bool has_gsub; + TT_Bool use_gsub; + TT_Bool has_sbit; + TT_Bool use_sbit; + TT_Bool glyph_has_sbit; + + TT_Bool default_language_system; + + int Fail; + + char* char_string; + + TT_UShort glyph_code_array[129]; + TT_UShort char_code[128]; + TT_UShort properties[128]; + + TT_UShort* glyph_code; + int num_glyphs; + + TT_ULong script_tag; + char* script_tag_string; + TT_UShort script_index; + + TT_ULong language_tag; + char* language_tag_string; + TT_UShort language_index; + TT_UShort req_feature_index = 0xFFFF; + + TT_ULong* feature_tags; + char** feature_tag_strings; + TT_UShort* feature_indices; + int num_features; + + + static void Select_CMap( void ) + { + TT_UShort i, n; + TT_UShort platform, encoding; + + + n = face_properties.num_CharMaps; + + for ( i = 0; i < n; i++ ) + { + TT_Get_CharMap_ID( face, i, &platform, &encoding ); + if ( platform == 3 && encoding == 1 ) + { + TT_Get_CharMap( face, i, &char_map ); + break; + } + } + + /* we try only pid/eid (0,0) if no (3,1) map is found -- many Windows + fonts have only rudimentary (0,0) support. */ + + if ( i == n ) + { + for ( i = 0; i < n; i++ ) + { + TT_Get_CharMap_ID( face, i, &platform, &encoding ); + if ( platform == 0 && encoding == 0 ) + { + TT_Get_CharMap( face, i, &char_map ); + break; + } + } + + if ( i == n ) + Panic( "Sorry, but this font doesn't contain" + " any Unicode mapping table\n" ); + } + } + + + /* Convert a Latin 1 string to a string of glyph indexes. */ + /* */ + /* IMPORTANT NOTE: */ + /* */ + /* There is no portable way to convert from any system's char. code */ + /* to Unicode. This function simply takes a char. string as argument */ + /* and `interprets' each character as a Unicode char. index with no */ + /* further check. */ + /* */ + /* We interpret the command line string as Unicode with the high byte */ + /* set to zero. This is equivalent to Latin-1. */ + + static void Latin1Char_To_Glyph( char* source ) + { + TT_UShort n; + + + glyph_code = glyph_code_array + 1; /* we want to make glyph_code[-1] */ + glyph_code[-1] = 0; /* possible. */ + + for ( n = 0; n < 128 && source[n]; n++ ) + { + char_code[n] = (TT_UShort)( (unsigned char)source[n] ); + glyph_code[n] = TT_Char_Index( char_map, char_code[n] ); + } + + num_glyphs = n; + } + + + static void UTF8Char_To_Glyph( char* source ) + { + TT_UShort in, out, in_code, out_code; + TT_UShort count, limit; + + + glyph_code = glyph_code_array + 1; /* we want to make glyph_code[-1] */ + glyph_code[-1] = 0; /* possible. */ + + for ( in = out = 0, count = limit = 1, in_code = out_code = 0; + in < 128 && source[in]; in++ ) + { + in_code = (TT_UShort)( (unsigned char)source[in] ); + + if ( in_code >= 0xC0 ) + { + limit = 1; + count = 1; + + if ( in_code < 0xE0 ) /* U+0080 - U+07FF */ + { + limit = 2; + out_code = in_code & 0x1F; + } + else if ( in_code < 0xF0 ) /* U+0800 - U+FFFF */ + { + limit = 3; + out_code = in_code & 0x0F; + } + continue; + } + else if ( in_code >= 0x80 ) + { + count++; + + if ( count <= limit ) + { + out_code <<= 6; + out_code += in_code & 0x3F; + } + if ( count != limit ) + continue; + } + else + out_code = in_code; + + char_code[out] = out_code; + glyph_code[out++] = TT_Char_Index( char_map, out_code ); + } + + num_glyphs = out; + } + + + static TT_Error Reset_Scale( int pointSize ) + { + TT_Error error; + + + error = TT_Set_Instance_CharSize( instance, pointSize * 64L ); + if ( error ) + { + RestoreScreen(); + Panic( "Could not reset instance, code = 0x%x.\n", error ); + } + + TT_Get_Instance_Metrics( instance, &imetrics ); + + /* now re-allocate the small bitmap */ + if ( gray_render ) + { + Init_Small( imetrics.x_ppem, imetrics.y_ppem ); + Clear_Small(); + } + + return TT_Err_Ok; + } + + + static TT_Error Load_TrueType_Char( TT_UShort idx, + int hint ) + { + int flags; + TT_Error error; + + + glyph_has_sbit = 0; + + error = TT_Load_Glyph_Bitmap( face, instance, idx, sbit ); + if ( error == TT_Err_Ok ) + { + has_sbit = 1; + glyph_has_sbit = 1; + } + + if ( glyph_has_sbit && use_sbit ) + return TT_Err_Ok; + + flags = TTLOAD_SCALE_GLYPH; + if ( hint ) + flags |= TTLOAD_HINT_GLYPH; + + return TT_Load_Glyph( instance, glyph, idx, flags ); + } + + + static TT_Error Get_Kern_Values( TT_UShort idx, + TT_Pos* x, + TT_Pos* y ) + { + TT_UShort i; + TT_Kern_Subtable table; + TT_Kern_0_Pair* pairs_0; + + TT_UShort min, max, new_min, new_max, middle; + TT_Long target_idx, current_idx; + + + *x = 0; + *y = 0; + + for ( i = 0; i < directory.nTables; i++ ) + { + table = directory.tables[i]; + + /* handle only horizontal kerning tables */ + + if ( table.coverage & 0x0001 ) + { + switch ( table.format ) + { + case 0: + pairs_0 = table.t.kern0.pairs; + target_idx = ( glyph_code[idx - 1] << 16 ) + glyph_code[idx]; + + /* binary search */ + + new_min = 0; + new_max = table.t.kern0.nPairs - 1; + + do + { + min = new_min; + max = new_max; + middle = max - ( ( max - min ) >> 1 ); + + current_idx = ( pairs_0[middle].left << 16 ) + + pairs_0[middle].right; + + if ( target_idx == current_idx ) + { + *x += pairs_0[middle].value; + break; + } + else if ( target_idx < current_idx ) + { + if ( middle == min ) + break; + new_max = middle - 1; + } + else + { + if ( middle == max ) + break; + new_min = middle + 1; + } + } while ( min < max ); + + break; + + /* we currently ignore format 2 kerning tables */ + + case 2: + break; + } + } + } + + /* scaling and rounding */ + + *x = ( ( ( *x * imetrics.x_scale ) / 0x10000 ) + 32 ) & -64; + *y = ( ( ( *y * imetrics.y_scale ) / 0x10000 ) + 32 ) & -64; + + return TT_Err_Ok; + } + + + /* for testing purposes, we always select the last available alternate + glyph, not using the `data' field. */ + + static TT_UShort alternate_function( TT_ULong pos, + TT_UShort glyphID, + TT_UShort num_alternates, + TT_UShort* alternates, + void* data ) + { + return num_alternates - 1; + } + + + static TT_Error Render_All( void ) + { + TT_Pos x, y, z, min_x, min_y, max_x, max_y; + TT_Pos kern_x, kern_y; + int i, n; + TT_UShort* gc; + TT_UShort glyph_property = 0; + + TT_Error error; + + TTO_GSUB_String in, out; + + + /* On the first pass, we compute the compound bounding box */ + + x = y = 0; + kern_x = kern_y = 0; + min_x = min_y = max_x = max_y = 0; + + in.length = num_glyphs; + in.pos = 0; + in.string = glyph_code; + in.properties = properties; + + out.pos = 0; + out.allocated = 0; + out.string = NULL; + out.properties = NULL; + + if ( has_gsub && use_gsub ) + { + error = TT_GSUB_Apply_String( gsub, &in, &out ); + if ( error && error != TTO_Err_Not_Covered ) + return error; + + n = out.length; + gc = out.string; + } + else + { + n = in.length; + gc = in.string; + } + + has_sbit = 0; + + for ( i = 0; i < n; i++ ) + { + error = Load_TrueType_Char( gc[i], hinted ); + if ( error == TT_Err_Ok ) + { + if ( glyph_has_sbit && use_sbit ) + metrics = sbit->metrics; + else + TT_Get_Glyph_Big_Metrics( glyph, &metrics ); + if ( has_kern && use_kern ) + Get_Kern_Values( i, &kern_x, &kern_y ); + + z = x + metrics.bbox.xMin + kern_x; + if ( min_x > z ) + min_x = z; + + z = x + metrics.bbox.xMax + kern_x; + if ( max_x < z ) + max_x = z; + + z = y + metrics.bbox.yMin + kern_y; + if ( min_y > z ) + min_y = z; + + z = y + metrics.bbox.yMax + kern_y; + if ( max_y < z ) + max_y = z; + + if ( has_gdef ) + { + error = TT_GDEF_Get_Glyph_Property( gdef, gc[i], &glyph_property ); + if ( error ) + return error; + } + + /* advance only if it is not a mark glyph */ + + if ( !( glyph_property & TTO_MARK ) ) + { + if ( vertical ) + y += ( metrics.vertAdvance & -64 ) + kern_y; + else + x += ( metrics.horiAdvance & -64 ) + kern_x; + } + } + else + Fail++; + } + + /* We now center the bbox inside the target bitmap */ + + min_x = ( min_x & -64 ) >> 6; + min_y = ( min_y & -64 ) >> 6; + + max_x = ( (max_x + 63) & -64 ) >> 6; + max_y = ( (max_y + 63) & -64 ) >> 6; + + max_x -= min_x; + max_y -= min_y; + + min_x = ( Bit.width - max_x ) / 2; + min_y = ( Bit.rows - max_y ) / 2; + + max_x += min_x; + max_y += min_y; + + /* On the second pass, we render each glyph to its centered position. */ + /* This is slow, because we reload each glyph to render it! */ + + x = vertical ? min_x : ( r2l ? max_x : min_x ); + y = vertical ? ( r2l ? min_y : max_y ) : min_y; + + for ( i = 0; i < n; i++ ) + { + error = Load_TrueType_Char( gc[i], hinted ); + if ( error == TT_Err_Ok ) + { + if ( glyph_has_sbit && use_sbit ) + metrics = sbit->metrics; + else + TT_Get_Glyph_Big_Metrics( glyph, &metrics ); + if ( has_kern && use_kern ) + Get_Kern_Values( i, &kern_x, &kern_y ); + + if ( has_gdef ) + (void)TT_GDEF_Get_Glyph_Property( gdef, gc[i], &glyph_property ); + + if ( !( glyph_property & TTO_MARK ) ) + { + if ( r2l ) + { + if ( vertical ) + y += metrics.vertAdvance / 64; + else + x -= metrics.horiAdvance / 64; + } + else + { + if ( vertical ) + y -= kern_y / 64; + else + x += kern_x / 64; + } + } + + /* We must specify the upper left corner of the bitmap, but the + lower left corner for the outline. Another complication is that + Blit_Bitmap() assumes that increasing y values means moving + downwards. + + For vertical layout, the origin of the horizontal and vertical + bearings of embedded bitmaps is the top, thus we shift the + outline glyphs down. */ + + if ( glyph_has_sbit && use_sbit ) + Blit_Bitmap( &Bit, + &sbit->map, + gray_render ? 8 : 1, + x + + ( vertical ? metrics.vertBearingX : + metrics.horiBearingX ) / 64, + Bit.rows - y - + ( vertical ? metrics.vertBearingY : + metrics.horiBearingY ) / 64, + gray_palette[4] ); + else + Render_Single_Glyph( + gray_render, + glyph, + x, + y - + ( vertical ? metrics.vertBearingY + metrics.bbox.yMax : + 0 ) / 64 ); + + if ( !( glyph_property & TTO_MARK ) ) + { + if ( r2l ) + { + if ( vertical ) + y += kern_y / 64; + else + x -= kern_x / 64; + } + else + { + if ( vertical ) + y -= metrics.vertAdvance / 64; + else + x += metrics.horiAdvance / 64; + } + } + } + } + + if ( out.string ) + free( out.string ); + if ( out.properties ) + free( out.properties ); + + return TT_Err_Ok; + } + + + static int Process_Event( TEvent* event ) + { + switch ( event->what ) + { + case event_Quit: /* ESC or q */ + return 0; + + case event_Keyboard: + if ( event->info == 'h' ) /* Toggle hinting */ + hinted = !hinted; + else if ( event->info == 'K' ) /* Toggle kerning */ + use_kern = !use_kern; + else if ( event->info == 'B' ) /* Toggle sbit */ + use_sbit = !use_sbit; + else if ( event->info == 'G' ) /* Toggle gsub */ + use_gsub = !use_gsub; + break; + + case event_Rotate_Glyph: + break; + + case event_Scale_Glyph: + pt_size += event->info; + if ( pt_size < 1 ) pt_size = 1; + if ( pt_size > MAXPTSIZE ) pt_size = MAXPTSIZE; + break; + + case event_Change_Glyph: + break; + } + + return 1; + } + + + static void Usage( char* execname ) + { + fprintf( stderr, + "\n" + "ftstrtto: TrueType Open String Test Display -- part of the FreeType project\n" + "---------------------------------------------------------------------------\n" + "\n" + "Usage: %s [options below] ppem fontname[.ttf|.ttc] [string|-]\n" + "\n" + " -c C use font with index C in TrueType collection (default: 0)\n" + " -f F use feature F (can be specified more than once)\n" + " -g gray-level rendering\n" + " -l L use language L\n" + " -r R use resolution R dpi (default: 96)\n" + " -s S use script S\n" + " -u interpret input data as UTF8-encoded\n" + " -v display string vertically\n" + " -x display string from right to left\n" + "\n" + " F, L, and S must be specified as 4-character tags.\n" + " Specifying only F and S selects default language system of S.\n" + " Specifying only L and S selects the req. feature of L only (if any).\n" + "\n" + " If `-' is specified as input string, stdin is read instead.\n" + "\n", execname ); + + exit( EXIT_FAILURE ); + } + + + static TT_ULong Make_Tag( char* tag_string ) + { + char t1 = ' ', t2 = ' ', t3 = ' ', t4 = ' '; + + + if ( !tag_string ) + return 0; + + t1 = tag_string[0]; + if ( tag_string[1] ) + t2 = tag_string[1]; + if ( tag_string[2] ) + t3 = tag_string[2]; + if ( tag_string[3] ) + t4 = tag_string[3]; + + return MAKE_TT_TAG( t1, t2, t3, t4 ); + } + + + int main( int argc, + char** argv ) + { + int i, old_pt_size, orig_pt_size, file; + + int graphics_initialized = 0; + + char filename[128 + 4]; + char alt_filename[128 + 4]; + char* execname; + + int option; + int res = 96; + int utf8 = 0; + + TT_Error error; + TEvent event; + + + execname = argv[0]; + + while ( 1 ) + { + option = ft_getopt( argc, argv, "c:f:gl:r:s:uvx" ); + + if ( option == -1 ) + break; + + switch ( option ) + { + case 'c': + ttc_index = atoi( ft_optarg ); + if ( ttc_index < 0 ) + Usage( execname ); + break; + + case 'f': + num_features++; + feature_tag_strings = (char**) + realloc( feature_tag_strings, + num_features * sizeof ( char* ) ); + feature_tags = (TT_ULong*) + realloc( feature_tags, + num_features * sizeof ( TT_ULong ) ); + feature_tag_strings[num_features - 1] = ft_optarg; + if ( !(feature_tags[num_features - 1] = Make_Tag( ft_optarg ) ) ) + Usage( execname ); + break; + + case 'g': + gray_render = 1; + break; + + case 'l': + language_tag_string = ft_optarg; + if ( !(language_tag = Make_Tag( ft_optarg ) ) ) + Usage( execname ); + break; + + case 'r': + res = atoi( ft_optarg ); + if ( res < 1 ) + Usage( execname ); + break; + + case 's': + script_tag_string = ft_optarg; + if ( !(script_tag = Make_Tag( ft_optarg ) ) ) + Usage( execname ); + break; + + case 'u': + utf8 = 1; + break; + + case 'v': + vertical = 1; + break; + + case 'x': + r2l = 1; + break; + + default: + Usage( execname ); + break; + } + } + + argc -= ft_optind; + argv += ft_optind; + + if ( argc <= 1 ) + Usage( execname ); + + if ( sscanf( argv[0], "%d", &orig_pt_size ) != 1 ) + orig_pt_size = 64; + + file = 1; + + /* Initialize engine */ + + error = TT_Init_FreeType( &engine ); + if ( error ) + Panic( "Error while initializing engine, code = 0x%x.\n", error ); + + error = TT_Init_Kerning_Extension( engine ); + if ( error ) + Panic( "Error while initializing kerning extension, code = 0x%x.\n", + error ); + + error = TT_Init_SBit_Extension( engine ); + if ( error ) + Panic( "Error while initializing sbit extension, code = 0x%x.\n", + error ); + + error = TT_Init_GDEF_Extension( engine ); + if ( error ) + Panic( "Error while initializing GDEF extension, code = 0x%x.\n", + error ); + + error = TT_Init_GSUB_Extension( engine ); + if ( error ) + Panic( "Error while initializing GSUB extension, code = 0x%x.\n", + error ); + + pt_size = orig_pt_size; + hinted = 1; + use_gsub = 1; + use_kern = 1; + use_sbit = 1; + + i = strlen( argv[file] ); + while ( i > 0 && argv[file][i] != '\\' && argv[file][i] != '/' ) + { + if ( argv[file][i] == '.' ) + i = 0; + i--; + } + + filename[128] = '\0'; + alt_filename[128] = '\0'; + + strncpy( filename, argv[file], 128 ); + strncpy( alt_filename, argv[file], 128 ); + + if ( i >= 0 ) + { + strncpy( filename + strlen( filename ), ".ttf", 4 ); + strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 ); + } + + /* Load face */ + + error = TT_Open_Face( engine, filename, &face ); + if ( error == TT_Err_Could_Not_Open_File ) + { + strcpy( filename, alt_filename ); + error = TT_Open_Face( engine, alt_filename, &face ); + } + if ( error == TT_Err_Could_Not_Open_File ) + Panic( "Could not find/open `%s'.\n", filename ); + else if ( error ) + Panic( "Error while opening `%s', code = 0x%x.\n", + filename, error ); + + /* get face properties and allocate preload arrays */ + + TT_Get_Face_Properties( face, &face_properties ); + + /* open font in collection */ + + if ( ttc_index >= face_properties.num_Faces ) + Panic( "There is no collection with index %d in this font file.\n", + ttc_index ); + + TT_Close_Face( face ); + + error = TT_Open_Collection( engine, filename, ttc_index, &face ); + if ( error ) + Panic( "Error while opening collection %d in `%s', code = 0x%x.\n", + ttc_index, filename, error ); + + /* create glyph */ + + error = TT_New_Glyph( face, &glyph ); + if ( error ) + Panic( "Could not create glyph container, code = 0x%x.\n", error ); + + /* create sbit slot */ + + error = TT_New_SBit_Image( &sbit ); + if ( error ) + Panic( "Could not create sbit slot, code = 0x%x.\n" , error); + + /* create instance */ + + error = TT_New_Instance( face, &instance ); + if ( error ) + Panic( "Could not create instance for `%s', code = 0x%x.\n", + filename, error ); + + error = TT_Set_Instance_Resolutions( instance, res, res ); + if ( error ) + Panic( "Could not set device resolutions, code = 0x%x.\n", error ); + + error = TT_Get_Kerning_Directory( face, &directory ); + if ( error ) + Panic( "Could not get kerning directory, code = 0x%x.\n", error ); + + /* load all kerning tables */ + + for ( i = 0; i < directory.nTables; i++ ) + { + error = TT_Load_Kerning_Table( face, i ); + if ( error ) + Panic( "Could not load kerning table, code = 0x%x.\n", error ); + } + + if ( directory.nTables ) + has_kern = 1; + + Select_CMap(); + + /* GDEF support */ + + gdef = &gdef_; + + error = TT_Load_GDEF_Table( face, gdef ); + if ( !error ) + has_gdef = 1; + else if ( error != TT_Err_Table_Missing ) + Panic( "Error while loading GDEF table, code = 0x%x.\n", error ); + + /* we must assign glyph properties in case no GDEF table is available */ + + if ( !has_gdef ) + { + Build_Arabic_Glyph_Properties( char_map, face_properties.num_Glyphs, + &gdef ); + if ( gdef ) + has_gdef = 1; + } + + /* GSUB support */ + + gsub = &gsub_; + + error = TT_Load_GSUB_Table( face, gsub, gdef ); + if ( !error ) + { + if ( script_tag && feature_tags ) + has_gsub = 1; + if ( script_tag && language_tag ) + has_gsub = 1; + } + else if ( error != TT_Err_Table_Missing ) + Panic( "Error while loading GSUB table, code = 0x%x.\n", error ); + + TT_GSUB_Clear_Features( gsub ); + + if ( has_gsub && !language_tag ) + default_language_system = 1; + + feature_indices = (TT_UShort*) + malloc( num_features * sizeof ( TT_UShort ) ); + + if ( has_gsub ) + { + error = TT_GSUB_Select_Script( gsub, + script_tag, + &script_index ); + if ( error ) + Panic( "Requested script `%-4.4s' not found.\n", + script_tag_string ); + + if ( default_language_system ) + { + for ( i = 0; i < num_features; i++ ) + { + error = TT_GSUB_Select_Feature( gsub, + feature_tags[i], + script_index, 0xFFFF, + &feature_indices[i] ); + if ( error ) + Panic( "Requested feature `%-4.4s'\n" + "for default language system of script `%-4.4s' not found.\n", + feature_tag_strings[i], script_tag_string ); + } + } + else + { + error = TT_GSUB_Select_Language( gsub, + language_tag, + script_index, + &language_index, + &req_feature_index ); + if ( error ) + Panic( "Requested language `%-4.4s'\n" + "for script `%-4.4s' not found.\n", + language_tag_string, script_tag_string ); + + for ( i = 0; i < num_features; i++ ) + { + error = TT_GSUB_Select_Feature( gsub, + feature_tags[i], + script_index, language_index, + &feature_indices[i] ); + if ( error ) + Panic( "Requested feature `%-4.4s'\n" + "for script `%-4.4s', language `%-4.4s' not found.\n", + feature_tag_strings[i], script_tag_string, + language_tag_string ); + } + } + + if ( req_feature_index != 0xFFFF ) + TT_GSUB_Add_Feature( gsub, req_feature_index, ALL_GLYPHS ); + else if ( !num_features ) + has_gsub = 0; + + for ( i = 0; i < num_features; i++ ) + { + if ( feature_tags[i] == FEATURE_init ) + TT_GSUB_Add_Feature( gsub, feature_indices[i], initial ); + else if ( feature_tags[i] == FEATURE_medi ) + TT_GSUB_Add_Feature( gsub, feature_indices[i], medial ); + else if ( feature_tags[i] == FEATURE_fina ) + TT_GSUB_Add_Feature( gsub, feature_indices[i], final ); + else if ( feature_tags[i] == FEATURE_isol ) + TT_GSUB_Add_Feature( gsub, feature_indices[i], isolated ); + else + TT_GSUB_Add_Feature( gsub, feature_indices[i], ALL_GLYPHS ); + } + + TT_GSUB_Register_Alternate_Function( gsub, alternate_function, NULL ); + } + + + if ( !graphics_initialized ) + { + graphics_initialized = 1; + + if ( gray_render ) + { + if ( !SetGraphScreen( Graphics_Mode_Gray ) ) + Panic( "Could not set up grayscale graphics mode.\n" ); + + TT_Set_Raster_Gray_Palette( engine, virtual_palette ); + } + else + { + if ( !SetGraphScreen( Graphics_Mode_Mono ) ) + Panic( "Could not set up mono graphics mode.\n" ); + } + } + + Init_Display( gray_render ); + + Reset_Scale( pt_size ); + + old_pt_size = pt_size; + + Fail = 0; + + /* get string to display, if any */ + + if ( argv[2] ) + { + if ( argv[2][0] == '-' ) + { + int ch; + char* p; + + + char_string = (char*)malloc( 128 * sizeof ( char ) ); + p = char_string; + + for ( i = 0; i < 128; i++ ) + { + ch = getchar(); + if ( ch == '\n' || ch == EOF ) + { + *p = '\0'; + break; + } + + *p++ = (char)ch; + } + + *p = '\0'; + } + else + char_string = argv[2]; + } + else + char_string = "The quick brown fox jumps over the lazy dog"; + + if ( utf8 ) + UTF8Char_To_Glyph( char_string ); + else + Latin1Char_To_Glyph( char_string ); + + /* we assign Arabic script features (e.g. `initial' or `final') */ + + Assign_Arabic_Properties( char_code, properties, num_glyphs ); + + for ( ;; ) + { + int key; + + + Clear_Display(); + + error = Render_All(); + if ( error ) + Panic( "Error while rendering string, code = 0x%x.\n", error ); + + if ( gray_render ) + Convert_To_Display_Palette(); + + sprintf( Header, + "%s: ptsize: %d hinting: %s%s%s%s%s%s%s", + ft_basename( filename ), + pt_size, + hinted ? "on" : "off", + has_kern ? " kerning: " : "", + has_kern ? ( use_kern ? "on" : "off" ) : "", + has_sbit ? " sbit: " : "", + has_sbit ? ( use_sbit ? "on" : "off" ) : "", + has_gsub ? " GSUB: " : "", + has_gsub ? ( use_gsub ? "on" : "off" ) : "" ); + + Display_Bitmap_On_Screen( Bit.bitmap, Bit.rows, Bit.cols ); + +#ifndef X11 +#ifndef OS2 + Print_XY( 0, 0, Header ); +#endif +#endif + + Get_Event( &event ); + if ( !( key = Process_Event( &event ) ) ) + goto Fin; + + if ( pt_size != old_pt_size ) + { + if ( Reset_Scale( pt_size ) ) + Panic( "Could not resize font.\n" ); + + old_pt_size = pt_size; + } + } + + Fin: + RestoreScreen(); + + TT_Done_FreeType( engine ); + + printf( "Execution completed successfully.\n" ); + printf( "Fails = %d.\n", Fail ); + + exit( EXIT_SUCCESS ); /* for safety reasons */ + + return 0; /* never reached */ +} + + +/* End */ diff --git a/test/fttimer.c b/test/fttimer.c new file mode 100644 index 0000000..2372afd --- /dev/null +++ b/test/fttimer.c @@ -0,0 +1,455 @@ +/****************************************************************************/ +/* */ +/* The FreeType project - a Free and Portable Quality TrueType Renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* fttimer: A simple performance benchmark. Now with graylevel rendering */ +/* with the '-g' option. */ +/* */ +/* Be aware that the timer program benchmarks different things */ +/* in each release of the FreeType library. Thus, performance */ +/* should only be compared between similar release numbers. */ +/* */ +/* */ +/* NOTE: This is just a test program that is used to show off and */ +/* debug the current engine. In no way does it shows the final */ +/* high-level interface that client applications will use. */ +/* */ +/****************************************************************************/ + +#include +#include +#include + +#include "common.h" /* for Panic() */ +#include "freetype.h" + +#include "gdriver.h" +#include "gevents.h" +#include "gmain.h" + +#ifndef __USE_MISC +#define __USE_MISC /* MkLinux needs this to get a definition of + CLOCKS_PER_SEC */ +#endif + +#include /* for clock() */ + +/* SunOS 4.1.* does not define CLOCKS_PER_SEC, so include */ +/* to get the HZ macro which is the equivalent. */ +#if defined(__sun__) && !defined(SVR4) && !defined(__SVR4) +#include +#define CLOCKS_PER_SEC HZ +#endif + +#define MAX_GLYPHS 512 /* Maximum number of glyphs rendered at one time */ + + char Header[128]; + + TT_Error error; + + TT_Engine engine; + TT_Face face; + TT_Instance instance; + TT_Glyph glyph; + + TT_Outline outline; + TT_Glyph_Metrics metrics; + + TT_Face_Properties properties; + + TT_F26Dot6* cur_x; + TT_F26Dot6* cur_y; + + unsigned short* cur_endContour; + unsigned char* cur_touch; + + TT_Outline outlines[MAX_GLYPHS]; + + int num_glyphs; + int tab_glyphs; + int cur_glyph; + int cur_point; + unsigned short cur_contour; + + TT_Raster_Map Bit; + + int Fail; + int Num; + + short visual; /* display glyphs while rendering */ + short gray_render; /* smooth fonts with gray levels */ + + + static void Clear_Buffer( void ); + + +/*******************************************************************/ +/* */ +/* Get_Time: */ +/* */ +/* Returns the current time in milliseconds. */ +/* */ +/*******************************************************************/ + + long Get_Time( void ) + { + return clock() * 1000 / CLOCKS_PER_SEC; + } + + +/*******************************************************************/ +/* */ +/* Init_Engine: */ +/* */ +/* Allocates bitmap, render pool and other structs... */ +/* */ +/*******************************************************************/ + + void Init_Engine( void ) + { + Bit.rows = vio_Height; /* The whole window */ + Bit.width = vio_Width; + + if ( gray_render ) + { + Bit.cols = Bit.width; + Bit.flow = TT_Flow_Up; + Bit.size = Bit.rows * Bit.width; + } + else + { + Bit.cols = (Bit.width + 7) / 8; /* convert to # of bytes */ + Bit.flow = TT_Flow_Up; + Bit.size = Bit.rows * Bit.cols; /* number of bytes in buffer */ + } + + Bit.bitmap = (void*)malloc( Bit.size ); + if ( !Bit.bitmap ) + Panic( "ERROR: not enough memory to allocate bitmap!\n" ); + + Clear_Buffer(); + } + + +/*******************************************************************/ +/* */ +/* Clear_Buffer: */ +/* */ +/* Clears current bitmap. */ +/* */ +/*******************************************************************/ + + static void Clear_Buffer( void ) + { + if ( gray_render ) + memset( Bit.bitmap, gray_palette[0], Bit.size ); + else + memset( Bit.bitmap, 0, Bit.size ); + } + + +/*******************************************************************/ +/* */ +/* LoadTrueTypeChar: */ +/* */ +/* Loads a glyph into memory. */ +/* */ +/*******************************************************************/ + + TT_Error LoadTrueTypeChar( int idx ) + { + error = TT_Load_Glyph( instance, glyph, idx, TTLOAD_DEFAULT ); + if ( error ) + return error; + + TT_Get_Glyph_Outline( glyph, &outline ); + + outline.second_pass = 0; + outline.high_precision = 0; + outline.dropout_mode = 0; + + /* debugging */ +#if 0 + if ( idx == 0 && !visual ) + { + printf( "points = %d\n", outline.points ); + for ( j = 0; j < outline.points; j++ ) + printf( "%02x (%01hx,%01hx)\n", + j, outline.xCoord[j], outline.yCoord[j] ); + printf( "\n" ); + } +#endif + + /* create a new outline */ + TT_New_Outline( outline.n_points, + outline.n_contours, + &outlines[cur_glyph] ); + + /* copy the glyph outline into it */ + outline.high_precision = 0; + outline.second_pass = 0; + TT_Copy_Outline( &outline, &outlines[cur_glyph] ); + + /* translate it */ + TT_Translate_Outline( &outlines[cur_glyph], + vio_Width * 16, + vio_Height * 16 ); + cur_glyph++; + + return TT_Err_Ok; + } + + +/*******************************************************************/ +/* */ +/* ConvertRaster: */ +/* */ +/* Performs scan conversion. */ +/* */ +/*******************************************************************/ + + TT_Error ConvertRaster( int index ) + { + outlines[index].second_pass = 0; + outlines[index].high_precision = 0; + + if ( gray_render ) + return TT_Get_Outline_Pixmap( engine, &outlines[index], &Bit ); + else + return TT_Get_Outline_Bitmap( engine, &outlines[index], &Bit ); + } + + + int main( int argc, char** argv ) + { + int i, total, mode, base, rendered_glyphs; + char filename[128 + 4]; + char alt_filename[128 + 4]; + char* execname; + + long t, t0, tz0; + + + execname = argv[0]; + + gray_render = 0; + visual = 0; + + while ( argc > 1 && argv[1][0] == '-' ) + { + switch ( argv[1][1] ) + { + case 'g': + gray_render = 1; + break; + + case 'v': + visual = 1; + break; + + default: + Panic( "Unknown argument '%s'!\n", argv[1] ); + } + argc--; + argv++; + } + + if ( argc != 2 ) + { + fprintf( stderr, "fttimer: simple performance timer -- part of the FreeType project\n" ); + fprintf( stderr,"-----------------------------------------------------------------\n\n" ); + fprintf( stderr,"Usage: %s [-g] [-v] fontname[.ttf|.ttc]\n\n", execname ); + fprintf( stderr," where '-g' asks for gray-levels rendering\n" ); + fprintf( stderr," '-v' displays while rendering (slower)\n" ); + + exit( EXIT_FAILURE ); + } + + i = strlen( argv[1] ); + while ( i > 0 && argv[1][i] != '\\' ) + { + if ( argv[1][i] == '.' ) + i = 0; + i--; + } + + filename[128] = '\0'; + alt_filename[128] = '\0'; + + strncpy( filename, argv[1], 128 ); + strncpy( alt_filename, argv[1], 128 ); + + if ( i >= 0 ) + { + strncpy( filename + strlen( filename ), ".ttf", 4 ); + strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 ); + } + + /* Initialize engine */ + + if ( (error = TT_Init_FreeType( &engine )) ) + Panic( "Error while initializing engine, code = 0x%x.\n", error ); + + /* Load face */ + + error = TT_Open_Face( engine, filename, &face ); + + if ( error == TT_Err_Could_Not_Open_File ) + { + strcpy( filename, alt_filename ); + error = TT_Open_Face( engine, alt_filename, &face ); + } + + if ( error == TT_Err_Could_Not_Open_File ) + Panic( "Could not find/open %s.\n", filename ); + else if ( error ) + Panic( "Error while opening %s, error code = 0x%x.\n", + filename, error ); + + /* get face properties and allocate preload arrays */ + + TT_Get_Face_Properties( face, &properties ); + + num_glyphs = properties.num_Glyphs; + + tab_glyphs = MAX_GLYPHS; + if ( tab_glyphs > num_glyphs ) + tab_glyphs = num_glyphs; + + /* create glyph */ + + error = TT_New_Glyph( face, &glyph ); + if ( error ) + Panic( "Could not create glyph container.\n" ); + + /* create instance */ + + error = TT_New_Instance( face, &instance ); + if ( error ) + Panic( "Could not create instance for %s.\n", filename ); + + error = TT_Set_Instance_CharSize( instance, 400*64 ); + if ( error ) + Panic( "Could not reset instance for %s.\n", filename ); + + if ( gray_render ) + mode = Graphics_Mode_Gray; + else + mode = Graphics_Mode_Mono; + + if ( visual ) + { + if ( !SetGraphScreen( mode ) ) + Panic( "Could not set graphics mode.\n" ); + TT_Set_Raster_Gray_Palette( engine, gray_palette ); + } + else + { + /* This is the default bitmap size used */ + vio_Width = 640; + vio_Height = 450; + } + + Init_Engine(); + + Num = 0; + Fail = 0; + + total = num_glyphs; + base = 0; + + rendered_glyphs = 0; + + t0 = 0; /* Initial time */ + + tz0 = Get_Time(); + + while ( total > 0 ) + { + /* First, preload 'tab_glyphs' in memory */ + + cur_glyph = 0; + cur_point = 0; + cur_contour = 0; + + printf( "loading %d glyphs", tab_glyphs ); + + for ( Num = 0; Num < tab_glyphs; Num++ ) + { + error = LoadTrueTypeChar( base + Num ); + if ( error ) + Fail++; + + total--; + } + + base += tab_glyphs; + + if ( tab_glyphs > total ) + tab_glyphs = total; + + printf( ", rendering... " ); + + /* Now, render the loaded glyphs */ + + t = Get_Time(); + + for ( Num = 0; Num < cur_glyph; Num++ ) + { + if ( (error = ConvertRaster( Num )) ) + Fail++; + else + { + rendered_glyphs ++; + + if ( visual ) + { + sprintf( Header, "Glyph: %5d", Num ); + Display_Bitmap_On_Screen( Bit.bitmap, Bit.rows, Bit.cols ); + + Clear_Buffer(); + } + } + } + + t = Get_Time() - t; + if ( t < 0 ) + t += 100L * 60 * 60; + + printf( " = %f s\n", (double)t / 1000 ); + t0 += t; + + /* Now free all loaded outlines */ + for ( Num = 0; Num < cur_glyph; Num++ ) + TT_Done_Outline( &outlines[Num] ); + } + + tz0 = Get_Time() - tz0; + + if ( visual ) + RestoreScreen(); + + TT_Close_Face( face ); + + printf( "\n" ); + printf( "rendered glyphs = %d\n", rendered_glyphs ); + printf( "render time = %f s\n", (double)t0 / 1000 ); + printf( "fails = %d\n", Fail ); + printf( "average glyphs/s = %f\n", + (double)rendered_glyphs / t0 * 1000 ); + + printf( "total timing = %f s\n", (double)tz0 / 1000 ); + printf( "Fails = %d\n", Fail ); + + TT_Done_FreeType( engine ); + + exit( EXIT_SUCCESS ); /* for safety reasons */ + + return 0; /* never reached */ + } + + +/* End */ diff --git a/test/ftview.c b/test/ftview.c new file mode 100644 index 0000000..7e753d1 --- /dev/null +++ b/test/ftview.c @@ -0,0 +1,540 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* ftview: A simple font viewer. Now supports hinting and grayscaling */ +/* with the '-g' option. */ +/* */ +/* */ +/* Keys: */ +/* */ +/* x : fine counter-clockwise rotation */ +/* c : fine clockwise rotation */ +/* */ +/* v : fast counter-clockwise rotation */ +/* b : fast clockwise rotation */ +/* */ +/* + : fast scale up */ +/* - : fast scale down */ +/* u : fine scale down */ +/* j : fine scale up */ +/* */ +/* l : go to next glyph */ +/* k : go to previous glyph */ +/* */ +/* o : go to tenth next glyph */ +/* i : go to tenth previous glyph */ +/* */ +/* 0 : go to hundredth next glyph */ +/* 9 : go to hundredth previous glyph */ +/* */ +/* ) : go to 1000th next glyph */ +/* ( : go to 1000th previous glyph */ +/* */ +/* } : go to 10000th next glyph */ +/* { : go to 10000th previous glyph */ +/* */ +/* n : go to next (or last) .ttf file */ +/* p : go to previous (or first) .ttf file */ +/* */ +/* h : toggle hinting */ +/* */ +/* B : toggle sbit */ +/* */ +/* ESC : exit */ +/* */ +/* */ +/* NOTE: This is just a test program that is used to show off and */ +/* debug the current engine. */ +/* */ +/****************************************************************************/ + +#include +#include +#include + +#include "blitter.h" +#include "common.h" /* for Panic() only */ +#include "display.h" +#include "freetype.h" +#include "ftxsbit.h" + +#include "gdriver.h" +#include "gevents.h" +#include "gmain.h" + +#define Pi 3.1415926535 + +#define MAXPTSIZE 500 /* dtp */ +#define Center_X ( Bit.width / 2 ) /* dtp */ +#define Center_Y ( Bit.rows / 2 ) /* dtp */ + +/* + * If Ignore_Err_Not_SBit is not defined, + * "Fail" increase when the glyph does not have sbit and + * sbit_flag is 1. + */ +#define Ignore_Err_Not_SBit 1 + + char Header[128]; + + TT_Engine engine; + + TT_Face face; + TT_Instance instance; + TT_Glyph glyph; + TT_CharMap char_map; + + TT_Big_Glyph_Metrics metrics; + TT_Outline outline; + TT_Face_Properties properties; + TT_Instance_Metrics imetrics; + + TT_SBit_Image* sbit; + + int num_glyphs; + + int ptsize; + int hinted; + + int Rotation; + int Fail; + int Num; + unsigned char autorun; + + int gray_render; + unsigned int sbit_flag; /* 0 if to display outlines + * 1 if to use embedded bitmaps + * 2 if to show sbit and outline glyphs + */ + + int glyph_has_sbit; + + + + static TT_Error Reset_Scale( int pointSize ) + { + TT_Error error; + TT_SBit_Strike strike; + + if ( (error = TT_Set_Instance_PointSize( instance, pointSize )) ) + { + RestoreScreen(); + fprintf( stderr, "Error = 0x%x.\n", (int)error ); + Panic( "Could not reset instance.\n" ); + } + TT_Get_Instance_Metrics( instance, &imetrics ); + + /* now re-allocates the small bitmap */ + if ( gray_render ) + { + Init_Small( imetrics.x_ppem, imetrics.y_ppem ); + Clear_Small(); + } + + if ( TT_Get_SBit_Strike( face, instance, &strike ) ) + glyph_has_sbit = 0; + else + glyph_has_sbit = 1; + + return TT_Err_Ok; + } + + + static TT_Error LoadTrueTypeChar( int idx, + int hint ) + { + int flags; + + + flags = TTLOAD_SCALE_GLYPH; + if ( hint ) + flags |= TTLOAD_HINT_GLYPH; + + return TT_Load_Glyph( instance, glyph, idx, flags ); + } + + + static TT_Error Render_All( int first_glyph, + int ptsize ) + { + TT_F26Dot6 start_x, start_y, step_x, step_y, x, y; + int i; + + TT_Error error = 0; + + + start_x = 4; + start_y = vio_Height - ( ( ptsize * 96 + 36 ) / 72 + 10 ); + + step_x = imetrics.x_ppem + 4; + step_y = imetrics.y_ppem + 10; + + x = start_x; + y = start_y; + + i = first_glyph; + + while ( i < num_glyphs ) + { + if ( ( glyph_has_sbit ) && + ( ( sbit_flag + 1 ) & 2 ) && + !(error = TT_Load_Glyph_Bitmap( face, instance, i, sbit )) ) + { + Blit_Bitmap( &Bit, + &sbit->map, + gray_render ? 8 : 1, + x + (sbit->metrics.horiBearingX/64), + Bit.rows - y - (sbit->metrics.horiBearingY/64), + gray_palette[4] ); + metrics = sbit->metrics; + goto Step; + } + + if ( ( ( !glyph_has_sbit ) || + ( ( sbit_flag + 1 ) & 1 ) ) && + !(error = LoadTrueTypeChar( i, hinted )) ) + { + TT_Get_Glyph_Outline( glyph, &outline ); + TT_Get_Glyph_Big_Metrics( glyph, &metrics ); + + Render_Single_Glyph( gray_render, glyph, x, y ); + } + else + { +#ifdef Ignore_Err_Not_SBit + if (!(( glyph_has_sbit ) && + ( sbit_flag == 1 ) && + ( error == TT_Err_Invalid_Glyph_Index ))) +#endif + Fail++; + } + Step: + x += ( metrics.horiAdvance / 64 ) + 1; + + if ( x + imetrics.x_ppem > vio_Width ) + { + x = start_x; + y -= step_y; + + if ( y < 10 ) + return TT_Err_Ok; + } + i++; + } + return TT_Err_Ok; + } + + + static int Process_Event( TEvent* event ) + { + switch ( event->what ) + { + case event_Quit: /* ESC or q */ + return 0; + + case event_Keyboard: + if ( event->info == 'n' ) /* Next file */ + return 'n'; + if ( event->info == 'p' ) /* Previous file */ + return 'p'; + if ( event->info == 'h' ) /* Toggle hinting */ + hinted = !hinted; + if ( ( event->info == 'B' ) && ( glyph_has_sbit ) ) /* Toggle sbit */ + sbit_flag = ( sbit_flag + 1 ) % 3; + break; + + case event_Rotate_Glyph: + Rotation = ( Rotation + event->info ) & 1023; + break; + + case event_Scale_Glyph: + ptsize += event->info; + if ( ptsize < 1 ) ptsize = 1; + if ( ptsize > MAXPTSIZE ) ptsize = MAXPTSIZE; + break; + + case event_Change_Glyph: + Num += event->info; + if ( Num < 0 ) Num = 0; + if ( Num >= num_glyphs ) Num = num_glyphs - 1; + break; + } + + return 1; + } + + + static void usage( char* execname ) + { + fprintf( stderr, "\n" ); + fprintf( stderr, "ftview: simple TrueType interpreter tester -- part of the FreeType project\n" ); + fprintf( stderr, "--------------------------------------------------------------------------\n" ); + fprintf( stderr, "\n" ); + fprintf( stderr, "Usage: %s [options below] ppem fontname[.ttf|.ttc] ...\n", + execname ); + fprintf( stderr, "\n" ); + fprintf( stderr, " -g gray-level rendering (default: none)\n" ); + fprintf( stderr, " -r R use resolution R dpi (default: 96)\n" ); + fprintf( stderr, " -B use embedded bitmaps (default: none)\n" ); + fprintf( stderr, "\n" ); + + exit( EXIT_FAILURE ); + } + + + int main( int argc, + char** argv ) + { + int i, old_ptsize, orig_ptsize, file; + int XisSetup = 0; + char filename[128 + 4]; + char alt_filename[128 + 4]; + char* execname; + int option; + int res = 96; + + TT_Error error; + TEvent event; + + TT_EBLC eblc_table; + + + execname = ft_basename( argv[0] ); + + while ( 1 ) + { + option = ft_getopt( argc, argv, "gr:B" ); + + if ( option == -1 ) + break; + + switch ( option ) + { + case 'g': + gray_render = 1; + sbit_flag = 0; + break; + + case 'r': + res = atoi( ft_optarg ); + if ( res < 1 ) + usage( execname ); + break; + + case 'B': + if (!gray_render) +#if 0 + sbit_flag = 1; +#else + sbit_flag = 2; +#endif + break; + + default: + usage( execname ); + break; + } + } + + argc -= ft_optind; + argv += ft_optind; + + if ( argc <= 1 ) + usage( execname ); + + if ( sscanf( argv[0], "%d", &orig_ptsize ) != 1 ) + orig_ptsize = 64; + + file = 1; + + /* Initialize engine */ + + if ( (error = TT_Init_FreeType( &engine )) ) + Panic( "Error while initializing engine, code = 0x%x.\n", error ); + + if ( (error = TT_Init_SBit_Extension( engine )) ) + Panic( "Error while initializing sbit extention, code = 0x%x.\n", error ); + + NewFile: + ptsize = orig_ptsize; + hinted = 1; + + i = strlen( argv[file] ); + while ( i > 0 && argv[file][i] != '\\' && argv[file][i] != '/' ) + { + if ( argv[file][i] == '.' ) + i = 0; + i--; + } + + filename[128] = '\0'; + alt_filename[128] = '\0'; + + strncpy( filename, argv[file], 128 ); + strncpy( alt_filename, argv[file], 128 ); + + if ( i >= 0 ) + { + strncpy( filename + strlen( filename ), ".ttf", 4 ); + strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 ); + } + + /* Load face */ + + error = TT_Open_Face( engine, filename, &face ); + + if ( error == TT_Err_Could_Not_Open_File ) + { + strcpy( filename, alt_filename ); + error = TT_Open_Face( engine, alt_filename, &face ); + } + + if ( error == TT_Err_Could_Not_Open_File ) + Panic( "Could not find/open %s.\n", filename ); + else if ( error ) + Panic( "Error while opening %s, code = 0x%x.\n", filename, error ); + + /* get face properties and allocate preload arrays */ + + TT_Get_Face_Properties( face, &properties ); + + num_glyphs = properties.num_Glyphs; + + glyph_has_sbit = 0; + + error = TT_Get_Face_Bitmaps( face, &eblc_table ); + if ( error == TT_Err_Ok ) + glyph_has_sbit = 1; + if ( sbit_flag && !glyph_has_sbit ) + Panic( "%s does not have embedded bitmap glyphs.\n", filename ); + + /* create glyph */ + + error = TT_New_Glyph( face, &glyph ); + if ( error ) + Panic( "Could not create glyph container.\n" ); + + error = TT_New_SBit_Image( &sbit ); + if ( error ) + Panic( "Could not create sbit slot.\n" ); + + /* create instance */ + + error = TT_New_Instance( face, &instance ); + if ( error ) + Panic( "Could not create instance for %s.\n", filename ); + + error = TT_Set_Instance_Resolutions( instance, res, res ); + if ( error ) + Panic( "Could not set device resolutions." ); + + if ( !XisSetup ) + { + XisSetup = 1; + + if ( gray_render ) + { + if ( !SetGraphScreen( Graphics_Mode_Gray ) ) + Panic( "Could not set up grayscale graphics mode.\n" ); + + TT_Set_Raster_Gray_Palette( engine, virtual_palette ); + } + else + { + if ( !SetGraphScreen( Graphics_Mode_Mono ) ) + Panic( "Could not set up mono graphics mode.\n" ); + } + } + + Init_Display( gray_render ); + + Reset_Scale( ptsize ); + + old_ptsize = ptsize; + + Fail = 0; + Num = 0; + + for ( ;; ) + { + int key; + char* sbit_string; + static char* sbit_messages[4] = + { "off", "on", " if available", "NONE" }; + + sbit_string = sbit_messages[3]; + if ( glyph_has_sbit ) + { + if (sbit_flag >= 0 && sbit_flag < 3) + sbit_string = sbit_messages[sbit_flag]; + } + + Clear_Display(); + Render_All( Num, ptsize ); + if ( gray_render ) + Convert_To_Display_Palette(); + + sprintf( Header, "%s: Glyph: %4d ptsize: %4d hinting: %s sbit: %s", + ft_basename( filename ), Num, ptsize, + hinted ? "on" : "off", + sbit_string ); + Display_Bitmap_On_Screen( Bit.bitmap, Bit.rows, Bit.cols ); + +#ifndef X11 +#ifndef OS2 + Print_XY( 0, 0, Header ); +#endif +#endif + + Get_Event( &event ); + if ( !( key = Process_Event( &event ) ) ) + goto End; + + if ( key == 'n' ) + { + TT_Close_Face( face ); + + if ( file < argc - 1 ) + file++; + + goto NewFile; + } + + if ( key == 'p' ) + { + TT_Close_Face( face ); + + if ( file > 1 ) + file--; + + goto NewFile; + } + + if ( ptsize != old_ptsize ) + { + if ( Reset_Scale( ptsize ) ) + Panic( "Could not resize font.\n" ); + + old_ptsize = ptsize; + } + } + + End: + RestoreScreen(); + + TT_Done_FreeType( engine ); + + printf( "Execution completed successfully.\n" ); + printf( "Fails = %d\n", Fail ); + + exit( EXIT_SUCCESS ); /* for safety reasons */ + + return 0; /* never reached */ +} + + +/* End */ diff --git a/test/ftzoom.c b/test/ftzoom.c new file mode 100644 index 0000000..98e4db2 --- /dev/null +++ b/test/ftzoom.c @@ -0,0 +1,681 @@ +/****************************************************************************/ +/* */ +/* The FreeType project - a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* ftzoom : A simple glyph viewer. Now supports graylevel rendering */ +/* with the '-g' option. */ +/* */ +/* Use `-p ' together with `-e ' to */ +/* select a cmap. */ +/* */ +/* Keys: */ +/* */ +/* x : fine counter_clockwise rotation */ +/* c : fine clockwise rotation */ +/* */ +/* v : fast counter_clockwise rotation */ +/* b : fast clockwise rotation */ +/* */ +/* + : fast scale up */ +/* - : fast scale down */ +/* u : fine scale down */ +/* j : fine scale up */ +/* */ +/* l : go to next glyph */ +/* k : go to previous glyph */ +/* */ +/* o : go to tenth next glyph */ +/* i : go to tenth previous glyph */ +/* */ +/* 0 : go to hundredth next glyph */ +/* 9 : go to hundredth previous glyph */ +/* */ +/* ) : go to 1000th next glyph */ +/* ( : go to 1000th previous glyph */ +/* */ +/* } : go to 10000th next glyph */ +/* { : go to 10000th previous glyph */ +/* */ +/* q : */ +/* ESC : exit */ +/* */ +/* */ +/* NOTE 1: This is just a test program that is used to show off and */ +/* debug the current engine. In no way does it show the final */ +/* high-level interface that client applications will use. */ +/* */ +/* NOTE 2: The `post' engine is used to display the PS glyph names. */ +/* Use the `-n' switch if you don't want that. */ +/* */ +/****************************************************************************/ + +#include +#include +#include +#include + +#include "common.h" /* for Panic() only */ +#include "freetype.h" +#include "ftxpost.h" + +#include "gdriver.h" +#include "gevents.h" +#include "gmain.h" + +#ifdef DEBUG_LEVEL_TRACE +#include "ttdebug.h" +#endif + + +#define Pi 3.1415926535 + +#define MAXPTSIZE 5000 /* dtp */ + + char Header[128]; + + TT_Engine engine; + TT_Face face; + TT_Instance instance; + TT_Glyph glyph; + TT_CharMap char_map; + + TT_Glyph_Metrics metrics; + TT_Outline outline; + TT_Face_Properties properties; + TT_Instance_Metrics imetrics; + + int num_glyphs; + int xcenter_upem; + int ycenter_upem; + int units_per_em; + + int ptsize; + int old_ptsize; + int rotation; + int old_rotation; + + TT_Matrix matrix; + TT_Matrix zoom_matrix; + int apply_matrix; + int xcenter; + int ycenter; + int xoffset; + int yoffset; + + TT_Raster_Map Bit; + + int Fail; + int Num; + int Code; + + int gray_render = 0; + int hinted = 1; + int use_cmap = 0; + int zoom_factor = 1; + int grid = 0; + int use_post = 1; + + char palette[5] = { 0, 1, 2, 3, 4 }; + + + static void ClearData( void ) + { + if ( gray_render ) + memset( Bit.bitmap, gray_palette[0], Bit.size ); + else + memset( Bit.bitmap, 0, Bit.size ); + } + + + void Init_Raster_Area( void ) + { + Bit.rows = vio_Height; /* The whole window */ + Bit.width = vio_Width; + Bit.flow = TT_Flow_Up; + + if ( gray_render ) + { + Bit.cols = Bit.width; + Bit.size = Bit.rows * Bit.width; + } + else + { + Bit.cols = ( Bit.width + 7 ) / 8; /* convert to # of bytes */ + Bit.size = Bit.rows * Bit.cols; /* number of bytes in buffer */ + } + + Bit.bitmap = (void*)malloc( (int)Bit.size ); + if ( !Bit.bitmap ) + Panic( "Not enough memory to allocate bitmap!\n" ); + + ClearData(); + } + + + static TT_Error Reset_PtSize( int pointSize ) + { + TT_Error error; + + + if ( (error = TT_Set_Instance_PointSize( instance, pointSize )) ) + { + RestoreScreen(); + printf( "Error = 0x%x.\n", (int)error ); + Panic( "Could not reset instance.\n" ); + } + + TT_Get_Instance_Metrics( instance, &imetrics ); + + xcenter = imetrics.x_ppem * xcenter_upem / units_per_em / 4; + ycenter = imetrics.y_ppem * ycenter_upem / units_per_em / 4; + + xoffset = vio_Width/2 - xcenter; + yoffset = vio_Height/2 - ycenter; + + return TT_Err_Ok; + } + + + static TT_Error Reset_Rotation( int rotation ) + { + if ( rotation ) + { + float angle; + + + TT_Set_Instance_Transform_Flags( instance, 1, 0 ); + + angle = rotation * Pi / 512; + + matrix.xx = (TT_Fixed)(cos( angle ) * (1L<<16)); + matrix.xy = (TT_Fixed)(sin( angle ) * (1L<<16)); + matrix.yx = -matrix.xy; + matrix.yy = matrix.xx; + + apply_matrix = 1; + } + else + apply_matrix = 0; + + if ( zoom_factor != 1 ) + { + zoom_matrix.xx = zoom_matrix.yy = zoom_factor * (1L<<16); + zoom_matrix.xy = zoom_matrix.yx = 0; + } + + return TT_Err_Ok; + } + + + static TT_Error LoadTrueTypeChar( int idx, int hint ) + { + TT_Error error; + int flags; + + + flags = TTLOAD_SCALE_GLYPH; + if ( hint ) + flags |= TTLOAD_HINT_GLYPH; + + error = TT_Load_Glyph( instance, glyph, idx, flags ); + if ( error ) + return error; + + if ( apply_matrix || zoom_factor != 1 ) + { + TT_Get_Glyph_Outline( glyph, &outline ); + TT_Translate_Outline( &outline, -xcenter*64L, -ycenter*64L ); + if ( apply_matrix ) + TT_Transform_Outline( &outline, &matrix ); + if ( zoom_factor != 1 ) + TT_Transform_Outline( &outline, &zoom_matrix ); + TT_Translate_Outline( &outline, xcenter*64L, ycenter*64L ); + } + + return error; + } + + + static TT_Error ConvertRaster( void ) + { + if ( gray_render ) + return TT_Get_Glyph_Pixmap( glyph, &Bit, xoffset*64L, yoffset*64L ); + else + return TT_Get_Glyph_Bitmap( glyph, &Bit, xoffset*64L, yoffset*64L ); + } + + + static void DrawGrid( void ) + { + char *bmap, mask; + int x, y, shift, toggle; + + + bmap = (char *)Bit.bitmap; + + for ( y = 0; y < Bit.rows; ++y ) + { + if ( ( y - xoffset ) % zoom_factor == 0 ) + { + if ( gray_render ) + for ( x = y & 1; x < Bit.cols; x += 2 ) + bmap[x] = 4 - bmap[x]; + else { + mask = y & 1 ? 0x55 : 0xAA; + for ( x = 0; x < Bit.cols; ++x ) + bmap[x] ^= mask; + } + } + else + { + toggle = y & 1; + + if ( gray_render ) + { + for ( x = xoffset % zoom_factor; x < Bit.cols; x += zoom_factor ) + if ( ( x & 1 ) == toggle ) + bmap[x] = 4 - bmap[x]; + } + else + { + /* tricky business */ + shift = xoffset % zoom_factor; + for ( x = 0; x < Bit.cols; ++x ) + { + for ( mask = 0; shift < 8; shift += zoom_factor ) + if ( ( shift & 1 ) == toggle ) + mask |= 0x80 >> shift; + bmap[x] ^= mask; + shift -= 8; + } + } + } + bmap += Bit.cols; + } + } + + + static int Process_Event( TEvent* event ) + { + switch ( event->what ) + { + case event_Quit: /* ESC or q */ + return 0; + + case event_Keyboard: + if ( event->info == 'h' ) /* Toggle hinting */ + hinted = !hinted; + break; + + case event_Rotate_Glyph: + rotation = ( rotation + event->info ) & 1023; + break; + + case event_Scale_Glyph: + ptsize += event->info; + if ( ptsize < 1 ) + ptsize = 1; + if ( ptsize > MAXPTSIZE / zoom_factor ) + ptsize = MAXPTSIZE / zoom_factor; + break; + + case event_Change_Glyph: + if ( use_cmap ) + { + if ( event->info < 0 ) + { + if ( Code > -event->info ) + Code += event->info; + else + Code = 0; + + for ( ; Code >= 0; Code-- ) + { + Num = TT_Char_Index( char_map, Code ); + if ( Num > 0 ) + break; + } + } + else + { + if ( Code < 65536 - event->info - 1 ) + Code += event->info; + else + Code = 65536 - 1; + + for ( ; Code < 65536; Code++ ) + { + Num = TT_Char_Index( char_map, Code ); + if ( Num > 0 ) + break; + } + } + } + else + { + if ( event->info < 0 ) + { + if ( Num > -event->info ) + Num += event->info; + else + Num = 0; + } + else + { + if ( Num < num_glyphs - event->info - 1 ) + Num += event->info; + else + Num = num_glyphs - 1; + } + } + break; + } + + return 1; + } + + + void usage( char* execname ) + { + printf( "\n" ); + printf( "ftzoom: simple TrueType glyph viewer -- part of the FreeType project\n" ); + printf( "--------------------------------------------------------------------\n" ); + printf( "\n" ); + printf( "Usage: %s [options below] fontname[.ttf|.ttc]\n", execname ); + printf( "\n" ); + printf( " -g gray-level rendering (default: none)\n" ); + printf( " -r R use resolution R dpi (default: 96)\n" ); + printf( " -z Z Z:1 magnification (default: 1:1)\n" ); + printf( " -p id platform id (default: none)\n" ); + printf( " -e id encoding id (default: none)\n" ); + printf( " -n don't use the `post' table\n" ); + printf( " If either -p or -e is not set, no cmap will be used.\n" ); + printf( "\n" ); + + exit( EXIT_FAILURE ); + } + + + /* stack check dtp */ + + int main( int argc, char** argv ) + { + int i; + int platform = -1, encoding = -1; + char filename[128 + 4]; + char alt_filename[128 + 4]; + char* execname; + int option; + int res = 96; + TT_Error error; + TT_Post post; + + TEvent event; + + + execname = argv[0]; + gray_render = 0; + + +#ifdef DEBUG_LEVEL_TRACE + + set_tt_trace_levels( trace_raster, 7 ); + set_tt_trace_levels( trace_gload, 7 ); + +#endif + + + while ( 1 ) + { + option = ft_getopt( argc, argv, "e:gnp:r:z:" ); + + if ( option == -1 ) + break; + + switch ( option ) + { + case 'e': + encoding = atoi( ft_optarg ); + break; + + case 'g': + gray_render = 1; + break; + + case 'n': + use_post = 0; + break; + + case 'p': + platform = atoi( ft_optarg ); + break; + + case 'r': + res = atoi( ft_optarg ); + if ( res < 1 ) + usage( execname ); + break; + + case 'z': + zoom_factor = atoi( ft_optarg ); + if ( zoom_factor < 1 || zoom_factor > 16 ) + usage( execname ); + if ( zoom_factor > 4 ) + grid = 1; + break; + + default: + usage( execname ); + break; + } + } + + if ( ft_optind == argc ) + usage( execname ); + + i = strlen( argv[ft_optind] ); + while ( i > 0 && argv[ft_optind][i] != '\\' && argv[ft_optind][i] != '/' ) + { + if ( argv[ft_optind][i] == '.' ) + i = 0; + i--; + } + + filename[128] = '\0'; + alt_filename[128] = '\0'; + + strncpy( filename, argv[ft_optind], 128 ); + strncpy( alt_filename, argv[ft_optind], 128 ); + + if ( i >= 0 ) + { + strncpy( filename + strlen( filename ), ".ttf", 4 ); + strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 ); + } + + if ( platform >= 0 || encoding >= 0 ) + use_cmap = 1; + + /* Initialization */ + TT_Init_FreeType( &engine ); + + /* Initialization of the post extension */ + if ( use_post ) + TT_Init_Post_Extension( engine ); + + /* Load face */ + + error = TT_Open_Face( engine, filename, &face ); + + if ( error == TT_Err_Could_Not_Open_File ) + { + strcpy( filename, alt_filename ); + error = TT_Open_Face( engine, alt_filename, &face ); + } + + if ( error == TT_Err_Could_Not_Open_File ) + Panic( "Could not find/open %s.\n", filename ); + else if ( error ) + Panic( "Error while opening %s, error code = 0x%x.\n", + filename, error ); + + /* get face properties and allocate preload arrays */ + + TT_Get_Face_Properties( face, &properties ); + + num_glyphs = properties.num_Glyphs; + xcenter_upem = (properties.header->xMax - properties.header->xMin) / 2; + ycenter_upem = (properties.header->yMax - properties.header->yMin) / 2; + units_per_em = properties.header->Units_Per_EM; + + /* load full post table */ + if ( use_post ) + { + error = TT_Load_PS_Names( face, &post ); + if ( error ) + Panic( "Could not load PS names.\n" ); + } + + /* create glyph */ + + error = TT_New_Glyph( face, &glyph ); + if ( error ) + Panic( "Could not create glyph container.\n" ); + + /* create instance */ + + error = TT_New_Instance( face, &instance ); + if ( error ) + Panic( "Could not create instance for %s.\n", filename ); + + error = TT_Set_Instance_Resolutions( instance, res, res ); + if ( error ) + Panic( "Could not set device resolutions." ); + + if ( gray_render ) + { + if ( !SetGraphScreen( Graphics_Mode_Gray ) ) + Panic( "Could not set up grayscale graphics mode.\n" ); + + TT_Set_Raster_Gray_Palette( engine, gray_palette ); + } + else + { + if ( !SetGraphScreen( Graphics_Mode_Mono ) ) + Panic( "Could not set up mono graphics mode.\n" ); + } + + Init_Raster_Area(); + + old_ptsize = ptsize = 150 / zoom_factor; + old_rotation = rotation = 0; + + Reset_PtSize ( ptsize ); + Reset_Rotation( rotation ); + + if ( use_cmap ) + { + unsigned short num_cmap; + unsigned short cmap_plat; + unsigned short cmap_enc; + + + num_cmap = properties.num_CharMaps; + for ( i = 0; i < num_cmap; i++ ) + { + error = TT_Get_CharMap_ID( face, i, &cmap_plat, &cmap_enc ); + if ( error ) + Panic( "Cannot query cmap, error = 0x%x.\n", error ); + if ( cmap_plat == platform && cmap_enc == encoding ) + break; + } + + if ( i == num_cmap ) + Panic( "Invalid platform and/or encoding ID.\n" ); + + error = TT_Get_CharMap( face, i, &char_map ); + if ( error ) + Panic( "Cannot load cmap, error = 0x%x.\n", error ); + + num_glyphs = (1L << 16) - 1; + } + + Code = 0; + Num = 0; + Fail = 0; + + for ( ;; ) + { + char *glyphname; + + + glyphname = NULL; + + ClearData(); + + if ( ptsize != old_ptsize ) + { + Reset_PtSize( ptsize ); + old_ptsize = ptsize; + } + + if ( rotation != old_rotation ) + { + Reset_Rotation( rotation ); + old_rotation = rotation; + } + + if ( (error = LoadTrueTypeChar( Num, hinted )) == TT_Err_Ok ) + { + ConvertRaster(); + if ( grid ) + DrawGrid(); + + if ( use_post ) + (void)TT_Get_PS_Name(face, Num, &glyphname); + + if ( use_cmap ) + sprintf( Header, "\"%s\": index = %3d, code = 0x%x, hinting = %s", + use_post ? glyphname : "", Num, Code, + hinted ? "ON" : "OFF" ); + else + sprintf( Header, "\"%s\": index = %3d, hinting = %s", + use_post ? glyphname : "", Num, hinted ? "ON" : "OFF" ); + } + else { + Fail++; + sprintf( Header, "\"%s\": index = %3d, hinting = %s (ERROR 0x%lx)", + glyphname ? glyphname : "", Num, + hinted ? "ON" : "OFF", error ); + } + + Display_Bitmap_On_Screen( Bit.bitmap, Bit.rows, Bit.cols ); + +#ifndef X11 +#ifndef OS2 + Print_XY( 0, 0, Header ); +#endif +#endif + + Get_Event( &event ); + if ( !Process_Event( &event ) ) goto End; + } + + End: + + RestoreScreen(); + + TT_Done_FreeType( engine ); + + printf( "Fails = %d.\n", Fail ); + + exit( EXIT_SUCCESS ); /* for safety reasons */ + + return 0; /* never reached */ + } + + +/* End */ diff --git a/test/gdriver.h b/test/gdriver.h new file mode 100644 index 0000000..0caf42f --- /dev/null +++ b/test/gdriver.h @@ -0,0 +1,55 @@ +/******************************************************************* + * + * gdriver.h : Graphics utility driver generic interface 1.1 + * + * Generic interface for all drivers of the graphics utility used + * by the FreeType test programs. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef GDRIVER_H +#define GDRIVER_H + + /* Note that we now support an event based model, even with */ + /* full-screen modes. It is the responsability of the driver */ + /* to map its events to the TEvent structure when called */ + /* through Get_Event. */ + + /* The event classes are defined in the file 'gevents.h' included */ + /* by the test programs, not by the graphics utility. */ + + typedef struct _TEvent + { + int what; /* event class */ + int info; /* event parameter */ + } TEvent; + + + /* Get last event. In full-screen modes, a keystroke must be */ + /* translated to an event class with a parameter. */ + void Get_Event( TEvent* event ); + + /* A call to this function must set the graphics mode, the Vio */ + /* variable, as well as the values vio_ScanLineWidth, vio_Width */ + /* and vio_Height. */ + int Driver_Set_Graphics( int mode ); + + /* Restore previous mode or release display buffer/window */ + int Driver_Restore_Mode( void ); + + /* display bitmap on screen */ + int Driver_Display_Bitmap( char* buffer, int line, int col ); + +#endif /* GDRIVER_H */ + + +/* End */ diff --git a/test/gevents.h b/test/gevents.h new file mode 100644 index 0000000..5b2f73f --- /dev/null +++ b/test/gevents.h @@ -0,0 +1,43 @@ +/******************************************************************* + * + * gevents.h test programs events definition 1.1 + * + * This file defines the events used by the FreeType test programs + * It is _not_ included by 'gmain.c'. This file is also used by the + * drivers to translate their own events in GEvents. + * + * Not a very good design, but we're not rewriting X... + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef GEVENTS_H +#define GEVENTS_H + + typedef enum _GEvent + { + event_None, + event_Quit, /* Quit program */ + + event_Keyboard, /* unknown keystroke */ + + event_Change_Glyph, + event_Rotate_Glyph, + event_Scale_Glyph, + + event_Change_ScanType, + event_Change_Instructions + } GEvent; + +#endif /* GEVENTS_H */ + + +/* End */ diff --git a/test/gmain.c b/test/gmain.c new file mode 100644 index 0000000..e5b1e7e --- /dev/null +++ b/test/gmain.c @@ -0,0 +1,475 @@ +/******************************************************************* + * + * gmain.c graphics utility main body 1.1 + * + * This file defines a common implementation of the graphics + * utility used by the FreeType test programs. It relies on + * system-specific drivers, like 'gfs_os.c', which interface is + * described in the file 'gdriver.h'. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include "gdriver.h" +#include "gmain.h" + +#ifndef FAILURE +#define FAILURE 0 +#endif + +#ifndef SUCCESS +#define SUCCESS 1 +#endif + + char* Vio; /* pointer to VRAM or display buffer */ + + int vio_ScanLineWidth; /* scan line width in bytes */ + + int vio_Width; + int vio_Height; + + int gcursor_x = 0; + int gcursor_y = 0; + + int gwindow_width = 0; + int gwindow_height = 0; + + unsigned char gray_palette[5]; + + + typedef void TFunction_Print_8x8_Char( int x, + int y, + unsigned char c ); + + TFunction_Print_8x8_Char* Print_8x8_Char; + + /* font characters */ + + unsigned char font_8x8[2048] = + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E, + 0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E, + 0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, + 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00, + 0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x92, 0x10, 0x7C, + 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C, + 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00, + 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF, + 0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00, + 0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF, + 0x0F, 0x07, 0x0F, 0x7D, 0xCC, 0xCC, 0xCC, 0x78, + 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18, + 0x3F, 0x33, 0x3F, 0x30, 0x30, 0x70, 0xF0, 0xE0, + 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0, + 0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99, + 0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00, + 0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00, + 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, + 0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00, + 0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0x86, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00, + 0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF, + 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, + 0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00, + 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, + 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00, + 0x00, 0x24, 0x66, 0xFF, 0x66, 0x24, 0x00, 0x00, + 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00, + 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, + 0x18, 0x7E, 0xC0, 0x7C, 0x06, 0xFC, 0x18, 0x00, + 0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00, + 0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00, + 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, + 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, + 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, + 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, + 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, + 0x7C, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0x7C, 0x00, + 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00, + 0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00, + 0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00, + 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00, + 0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00, + 0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00, + 0xFC, 0xCC, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00, + 0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00, + 0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00, + 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, + 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30, + 0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00, + 0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00, + 0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00, + 0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00, + 0x7C, 0xC6, 0xDE, 0xDE, 0xDC, 0xC0, 0x7C, 0x00, + 0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00, + 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, + 0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00, + 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00, + 0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00, + 0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00, + 0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3A, 0x00, + 0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00, + 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00, + 0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00, + 0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00, + 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00, + 0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00, + 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00, + 0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00, + 0x7C, 0xC6, 0xC6, 0xC6, 0xD6, 0x7C, 0x0E, 0x00, + 0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00, + 0x7C, 0xC6, 0xE0, 0x78, 0x0E, 0xC6, 0x7C, 0x00, + 0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00, + 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, + 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00, + 0xC6, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0xC6, 0x00, + 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00, + 0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00, + 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, + 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00, + 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, + 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, + 0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00, + 0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00, + 0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, + 0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, + 0x38, 0x6C, 0x64, 0xF0, 0x60, 0x60, 0xF0, 0x00, + 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, + 0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00, + 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x0C, 0x00, 0x1C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, + 0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00, + 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x00, 0x00, 0xCC, 0xFE, 0xFE, 0xD6, 0xD6, 0x00, + 0x00, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, + 0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00, + 0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0, + 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E, + 0x00, 0x00, 0xDC, 0x76, 0x62, 0x60, 0xF0, 0x00, + 0x00, 0x00, 0x7C, 0xC0, 0x70, 0x1C, 0xF8, 0x00, + 0x10, 0x30, 0xFC, 0x30, 0x30, 0x34, 0x18, 0x00, + 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, + 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, + 0x00, 0x00, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00, + 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00, + 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, + 0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00, + 0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00, + 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, + 0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00, + 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00, + 0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x0C, 0x06, 0x7C, + 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, + 0x1C, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, + 0x7E, 0x81, 0x3C, 0x06, 0x3E, 0x66, 0x3B, 0x00, + 0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, + 0xE0, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, + 0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, + 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0x78, 0x0C, 0x38, + 0x7E, 0x81, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00, + 0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, + 0xE0, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, + 0xCC, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x7C, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00, + 0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0xC6, 0x10, 0x7C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00, + 0x30, 0x30, 0x00, 0x78, 0xCC, 0xFC, 0xCC, 0x00, + 0x1C, 0x00, 0xFC, 0x60, 0x78, 0x60, 0xFC, 0x00, + 0x00, 0x00, 0x7F, 0x0C, 0x7F, 0xCC, 0x7F, 0x00, + 0x3E, 0x6C, 0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00, + 0x78, 0x84, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + 0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + 0x78, 0x84, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, + 0x00, 0xE0, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, + 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, + 0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00, + 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00, + 0x18, 0x18, 0x7E, 0xC0, 0xC0, 0x7E, 0x18, 0x18, + 0x38, 0x6C, 0x64, 0xF0, 0x60, 0xE6, 0xFC, 0x00, + 0xCC, 0xCC, 0x78, 0x30, 0xFC, 0x30, 0xFC, 0x30, + 0xF8, 0xCC, 0xCC, 0xFA, 0xC6, 0xCF, 0xC6, 0xC3, + 0x0E, 0x1B, 0x18, 0x3C, 0x18, 0x18, 0xD8, 0x70, + 0x1C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, + 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + 0x00, 0x1C, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, + 0x00, 0xF8, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0x00, + 0xFC, 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00, + 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00, + 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00, + 0x18, 0x00, 0x18, 0x18, 0x30, 0x66, 0x3C, 0x00, + 0x00, 0x00, 0x00, 0xFC, 0xC0, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00, + 0xC6, 0xCC, 0xD8, 0x36, 0x6B, 0xC2, 0x84, 0x0F, + 0xC3, 0xC6, 0xCC, 0xDB, 0x37, 0x6D, 0xCF, 0x03, + 0x18, 0x00, 0x18, 0x18, 0x3C, 0x3C, 0x18, 0x00, + 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00, + 0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00, + 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, + 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, + 0xDB, 0xF6, 0xDB, 0x6F, 0xDB, 0x7E, 0xD7, 0xED, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18, + 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36, + 0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, + 0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36, + 0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00, + 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36, + 0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, + 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36, + 0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36, + 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xDC, 0xC8, 0xDC, 0x76, 0x00, + 0x00, 0x78, 0xCC, 0xF8, 0xCC, 0xF8, 0xC0, 0xC0, + 0x00, 0xFC, 0xCC, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, + 0x00, 0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, + 0xFC, 0xCC, 0x60, 0x30, 0x60, 0xCC, 0xFC, 0x00, + 0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0x70, 0x00, + 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xC0, + 0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x00, + 0xFC, 0x30, 0x78, 0xCC, 0xCC, 0x78, 0x30, 0xFC, + 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x6C, 0x38, 0x00, + 0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x6C, 0xEE, 0x00, + 0x1C, 0x30, 0x18, 0x7C, 0xCC, 0xCC, 0x78, 0x00, + 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x00, 0x00, + 0x06, 0x0C, 0x7E, 0xDB, 0xDB, 0x7E, 0x60, 0xC0, + 0x38, 0x60, 0xC0, 0xF8, 0xC0, 0x60, 0x38, 0x00, + 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, + 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, + 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x7E, 0x00, + 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xFC, 0x00, + 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xFC, 0x00, + 0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70, + 0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18, 0x00, + 0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00, + 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x0F, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, + 0x58, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, + 0x70, 0x98, 0x30, 0x60, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + + void Print_8x8_Mono( int x, int y, unsigned char c ) + { + int offset, i; + unsigned char* bitm; + + if ( !Vio ) + return; + + offset = x + y * vio_ScanLineWidth * 8; + bitm = font_8x8 + (int)c * 8; + + for ( i = 0; i < 8; i++ ) + { + Vio[offset] = *bitm; + bitm++; + offset += vio_ScanLineWidth; + } + } + + + void Print_8x8_Gray( int x, int y, unsigned char c ) + { + int offset, i, bit; + unsigned char* bitm; + + if ( !Vio ) + return; + + offset = x * 8 + y * vio_ScanLineWidth * 8; + bitm = font_8x8 + (int)c * 8; + + for ( i = 0; i < 8; i++ ) + { + bit = 0x80; + while ( bit > 0 ) + { + if ( bit & *bitm ) + Vio[offset] = (char)0x0f; + else + Vio[offset] = 0x00; + + bit >>= 1; + offset++; + } + offset += vio_ScanLineWidth - 8; + bitm++; + } + } + + + int SetGraphScreen( int mode ) + { + gcursor_x = 0; + gcursor_y = 0; + + switch( mode ) + { + case Graphics_Mode_Mono: + if ( !Driver_Set_Graphics( mode ) ) + return FAILURE; + + gwindow_width = vio_ScanLineWidth; + gwindow_height = vio_Height / 8; + + Print_8x8_Char = Print_8x8_Mono; + break; + + case Graphics_Mode_Gray: + if ( !Driver_Set_Graphics( mode ) ) + return FAILURE; + + gwindow_width = vio_ScanLineWidth / 8; + gwindow_height = vio_Height / 8; + + Print_8x8_Char = Print_8x8_Gray; + break; + + default: + /* Invalid function call */ + return FAILURE; + } + + return SUCCESS; + } + + + /* restore previous (or text) video mode */ + + int RestoreScreen( void ) + { + gcursor_x = 0; + gcursor_y = 0; + gwindow_height = 0; + gwindow_height = 0; + + return Driver_Restore_Mode(); + } + + + void Display_Bitmap_On_Screen( char* buffer, int line, int col ) + { + Driver_Display_Bitmap( buffer, line, col ); + } + + + void Goto_XY( int x, int y ) + { + gcursor_x = x; + gcursor_y = y; + } + + + void Print_Str( char* string ) + { + if ( !string ) return; + + while ( *string ) + { + switch ( *string ) + { + case '\n': + gcursor_x = 0; + gcursor_y++; + if ( gcursor_y > gwindow_height ) gcursor_y = 0; + break; + + default: + (*Print_8x8_Char)( gcursor_x, gcursor_y, *string ); + + gcursor_x++; + + if ( gcursor_x >= gwindow_width ) + { + gcursor_x = 0; + gcursor_y++; + + if ( gcursor_y >= gwindow_height ) gcursor_y = 0; + } + } + string++; + } + } + + + void Print_XY( int x, int y, char* string ) + { + Goto_XY( x, y ); + Print_Str( string ); + } + + + + + + + + + +/* End */ diff --git a/test/gmain.h b/test/gmain.h new file mode 100644 index 0000000..3cf16f4 --- /dev/null +++ b/test/gmain.h @@ -0,0 +1,71 @@ +/******************************************************************* + * + * gmain.h graphics utility main interface 1.1 + * + * This file defines a common interface, implemented in the body + * file 'gmain.c'. It relies on system dependent driver files, + * like 'gfs_os.c', whose interface is described in 'gdriver.h'. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef GMAIN_H +#define GMAIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Graphics mode definitions */ + +#define Graphics_Mode_Mono 1 /* monochrome graphics mode */ +#define Graphics_Mode_Gray 2 /* 8-bit palette graphics mode */ + + extern char* Vio; /* Pointer to VRAM or display buffer */ + + extern int vio_ScanLineWidth; /* Scan Line width in bytes */ + + extern int vio_Width; + extern int vio_Height; + + extern unsigned char gray_palette[5]; /* standard gray_palette */ + + + /* set a graphics mode, chosen from the FS_Graphics_xxx list */ + int SetGraphScreen( int mode ); + + /* restore previous (or text) video mode */ + int RestoreScreen( void ); + + /* display a bitmap of 'line' lines, and 'col' columns (each */ + /* column made of 8 bits) */ + void Display_Bitmap_On_Screen( char* buffer, int line, int col ); + + void Goto_XY( int x, int y ); + + + extern int gcursor_x; + extern int gcursor_y; + + extern int gwindow_width; + extern int gwindow_height; + + void Print_Str( char* string ); + void Print_XY ( int x, int y, char* string ); + +#ifdef __cplusplus +} +#endif + +#endif /* GMAIN_H */ + + +/* End */