ref: d2b1f357049f6b5e6766af9f3dfa134d2527feec
author: David Turner <[email protected]>
date: Thu Dec 16 18:11:37 EST 1999
Initial revision
--- /dev/null
+++ b/CHANGES
@@ -1,0 +1,176 @@
+This file summarizes the changes that occured since the last "beta" of FreeType 2.
+Because the list is important, it has been divided into separate sections:
+
+
+-----------------------------------------------------------------------------------------
+High-Level Interface :
+
+ The high-level API has been considerably simplified. Here is how :
+
+ - resource objects have disappeared. this means that face objects can now
+ be created with a single function call (see FT_New_Face and
+ FT_Open_Face)
+
+ - when calling either FT_New_Face & FT_Open_Face, a size object and a
+ glyph slot object are automatically created for the face, and can be
+ accessed through "face->glyph" and "face->size" if one really needs to.
+ In most cases, there's no need to call FT_New_Size or FT_New_Glyph.
+
+ - similarly, FT_Load_Glyph now only takes a "face" argument (instead of
+ a glyph slot and a size). Also, it's "result" parameter is gone, as
+ the glyph image type is returned in the field "face->glyph.format"
+
+ - the list of available charmaps is directly accessible through
+ "face->charmaps", counting "face->num_charmaps" elements. Each
+ charmap has an 'encoding' field which specifies which known encoding
+ it deals with. Valid values are, for example :
+
+ ft_encoding_unicode (for ASCII, Latin-1 and Unicode)
+ ft_encoding_apple_roman
+ ft_encoding_sjis
+ ft_encoding_adobe_standard
+
+ other values may be added in the future. Each charmap still holds its
+ "platform_id" and "encoding_id" values in case the encoding is too
+ exotic for the current library
+
+
+-----------------------------------------------------------------------------------------
+Directory Structure:
+
+ Should seem obvious to most of you:
+
+ freetype/
+ config/ -- configuration sub-makefiles
+ ansi/
+ unix/
+ win32/
+ os2/
+ msdos/
+
+ include/ -- public header files, those to be included directly
+ by client apps
+
+ src/ -- sources of the library
+ base/ -- the base layer
+ sfnt/ -- the sfnt "driver" (see the drivers section below)
+ truetype/ -- the truetype driver
+ type1/ -- the type1 driver
+ shared/ -- some header files shared between drivers
+
+ demos/ -- demos/tools
+
+ docs/ -- documentation (a bit empty for now)
+
+-----------------------------------------------------------------------------------------
+Glyph Image Formats :
+
+ Drivers are now able to register new glyph image formats within the library.
+ For now, the base layer supports of course bitmaps and vector outlines, but
+ one could imagine something different like colored bitmaps, bi-color
+ vectors or wathever else (Metafonts anyone ??).
+
+ See the file `include/ftimage.h'. Note also that the type FT_Raster_Map is
+ gone, and is now replaced by FT_Bitmap, which should encompass all known
+ bitmap types.
+
+ Each new image format must provide at least one "raster", i.e. a module
+ capable of transforming the glyph image into a bitmap. It is also possible
+ to change the default raster used for a given glyph image format.
+
+ The default outline scan-converter now uses 128 levels of grays by default,
+ which tends to smooth many things. Note that the demo programs have been
+ updated significantly to be able to display these..
+
+
+-----------------------------------------------------------------------------------------
+Build system :
+
+ You still need GNU Make to build the library. The build system has been
+ very seriously re-vamped in order to provide things like :
+
+ - automatic host platform detection (reverting to 'config/ansi'
+ if it is not detected, with pseudo-standard compilation flags)
+
+ - the ability to compile from the Makefiles with very different and
+ exotic compilers. Note that linking the library can be difficult for
+ some platforms.
+
+ For example, the file `config/win32/lcclib.bat' is invoked by the
+ build system to create the ".lib" file with LCC-Win32 because its
+ librarian has too many flaws to be invoked directly from the Makefile.
+
+ Here's how it works :
+
+ - the first time you type `make', the build system runs a series of
+ sub-makefiles in order to detect your host platform. It then dumps
+ what it found, and creates a file called `config.mk' in the current
+ directory. This is a sub-Makefile used to define many important Make
+ variables used to build the library.
+
+ - the second time, the build system detects the `config.mk' then use it
+ to build the library. All object files go into 'obj' by default, as
+ well as the library file, but this can easily be changed.
+
+ Note that you can run "make setup" to force another host platform detection
+ even if a `config.mk' is present in the current directory. Another solution
+ is simply to delete the file, then re-run make.
+
+ Finally, the default compiler for all platforms is gcc (for now, this will
+ hopefully changed in the future). You can however specify a different
+ compiler by specifying it after the 'setup' target as in :
+
+ gnumake setup lcc on Win32 to use the LCC compiler
+ gnumake setup visualc on Win32 to use Visual C++
+
+ See the file `config/<system>/detect.mk' for a list of supported compilers
+ for your platforms.
+
+ It should be relatively easy to write new detection rules files and
+ config.mk..
+
+ Finally, to build the demo programs, go to `demos' and launch GNU Make,
+ it will use the `config.mk' in the top directory to build the test
+ programs..
+
+-----------------------------------------------------------------------------------------
+Portability :
+
+ In the previous beta, a single FT_System object was used to encompass
+ all low-level operations like thread synchronisation, memory management
+ and i/o access. This has been greatly simplified :
+
+ - thread synchronisation has been dropped, for the simple reason that
+ the library is already re-entrant, and that if you really need two
+ threads accessing the same FT_Library, you should really synchronize
+ access to it yourself with a simple mutex.
+
+ - memory management is performed through a very simple object called
+ "FT_Memory", which really is a table containing a table of pointers
+ to functions like malloc, realloc and free as well as some user data
+ (closure).
+
+ - resources have disappeared (they created more problems than they
+ solved), and i/o management have been simplified greatly as a
+ result. Streams are defined through FT_Stream objects, which can
+ be either memory-based or disk-based.
+
+ Note that each face has its own stream, which is closed only when
+ the face object is destroyed. Hence, a function like TT_Flush_Face
+ in 1.x cannot be directly supported. However, if you really need
+ something like this, you can easily tailor your own streams to achieve
+ the same feature at a lower level (and use FT_Open_Face instead of
+ FT_New_Face to create the face).
+
+ See the file "include/ftsystem.h" for more details, as well as the
+ implementations found in "config/unix" and "config/ansi".
+
+
+-----------------------------------------------------------------------------------------
+Drivers Interface :
+ (To be written)
+
+-----------------------------------------------------------------------------------------
+Extensions support :
+ (To be defined)
+
--- /dev/null
+++ b/Makefile
@@ -1,0 +1,90 @@
+#******************************************************************************
+#*
+#* FreeType build system - top-level Makefile
+#*
+#* This file is designed for GNU Make, do not use it with another Make tool.
+#* It works as follows :
+#*
+#* - when invoked for the first time, this Makefile will include
+#* the rules found in `freetype/config/detect.mk'. They are in charge
+#* of detecting the current platform.
+#*
+#* A summary of the detection will be displayed, and the file `config.mk'
+#* will be created in the current directory
+#*
+#*
+#* - when invoked later, this Makefile will include the rules found in
+#* `config.mk'. This sub-Makefile will define some system-specific
+#* variables (like compiler, compilation flags, object suffix, etc..),
+#* then include the rules found in `freetype/config/freetype.mk',
+#* used to build the library.
+#*
+#* See the comments in `config/detect.mk' and `config/freetype.mk' for
+#* more details on host platform detection and library builds..
+#*
+#******************************************************************************
+
+.PHONY: setup
+
+#
+# The variable TOP holds the path to the topmost directory in the FreeType
+# engine source hierarchy. If it is not defined, default it to '.'
+#
+ifndef TOP
+TOP := .
+endif
+
+CONFIG_MK := config.mk
+
+#############################################################################
+#
+# If no configuration sub-makefile is present, or if "setup" is the target
+# to be built, run the auto-detection rules to figure out which configuration
+# rules file to use..
+#
+# Note that the configuration file is put in the current directory, which is
+# not necessarily TOP.
+#
+
+# if `config.mk' is not present, set "check_platform" and "first_time"
+#
+ifeq ($(wildcard $(CONFIG_MK)),)
+check_platform := 1
+first_time := 1
+endif
+
+# if `setup' is one of the targets requested, set "check_platform"
+#
+ifneq ($(findstring setup,$(MAKECMDGOALS)),)
+check_platform := 1
+endif
+
+
+#########################################################################
+#
+# include the automatic host platform detection rules when we need to
+# check the platform.
+#
+#
+ifdef check_platform
+
+all: setup
+
+include $(TOP)/config/detect.mk
+
+# "setup" must be defined by the host platform detection rules
+
+else
+
+########################################################################
+#
+# A configuration sub-Makefile is present, simply run it..
+#
+#
+all: build_freetype
+
+BUILD_FREETYPE := yes
+include $(CONFIG_MK)
+
+endif #test check_platform
+
--- /dev/null
+++ b/config/ansi/Makefile
@@ -1,0 +1,178 @@
+#*******************************************************************
+#*
+#* FreeType 2 Configuration rules for a `normal' ANSI compiler
+#*
+#* 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 purpose of this sub-Makefile is to define various build and
+#* platform specific variables before including the sub-Makefile
+#* containing the FreeType library rules, found in
+#*
+#* $(TOP)/config/freetype.mk
+#*
+#* The following variables must be defined before including this
+#* file :
+#*
+#* TOP Pathname to the top of the FreeType sources
+#* hierarchy
+#*
+#* This file should define the following variables before including
+#* the FreeType library rules file :
+#*
+#* BUILD Pathname to the platform-specific files used
+#* for the build. Usually `$(TOP)/config/<system>'
+#*
+#* SEP Directory separator for the current platform.
+#* Either / or \ (maybe : on Macs)
+#*
+#* DELETE The forced remove/delete command to erase one or more
+#* files
+#*
+#* INCLUDE The location of all public header files. e.g.
+#* `$(TOP)/include'include' *
+#*
+#* SRC The directory containing all sources. e.g.
+#* '$(TOP)/src'
+#*
+#* OBJ_DIR The location where compiled object files will be
+#* placed, e.g. '$(TOP)/obj'
+#*
+#* LIB_DIR The location where the resulting library file will be
+#* placed, e.g. '$(TOP)/obj'
+#*
+#* LIBRARY The filename of the resulting library file, without
+#* its extension.. e.g. 'libfreetype' or 'freetype'
+#*
+#* O The object file suffix. Can be '.o', '.obj,' '.lo,'
+#* ';coff,' etc.
+#*
+#* A The library file suffix. Can be '.a' '.so,' '.lib'
+#* '.dll,' etc.
+#*
+#* I The path inclusion flag. Some compilers use a
+#* different flag than '-I' to specify an additional
+#* include path. Examples are '/i=' or '-J ', etc.
+#*
+#* D The macro definition flag. I haven't met compilers
+#* which don't use the '-D' switch to define a macro, but
+#* who knows...
+#*
+#* T The compilation flag used to identify the target. Some
+#* compilers use a different flag than '-o ' to specify
+#* the name of the target object file.
+#*
+#* CFLAGS The set of flags used to compile object files.
+#* (usually contains the flag '-c').
+#*
+#*
+#*
+#*******************************************************************
+
+ifndef TOP
+TOP := .
+endif
+
+DELETE := rm -f
+SEP := /
+BUILD := $(TOP)/config/ansi
+PLATFORM := ansi
+
+# the directory where all object files are placed
+#
+OBJ_DIR := $(TOP)/obj
+
+
+# the directory where all library files are placed
+#
+# by default, this is the same as OBJ_DIR, however, this can be
+# changed to suit particular needs..
+#
+LIB_DIR := $(OBJ_DIR)
+
+
+# the object file extension, this can be .o, .tco, .obj, etc..
+# depending on the platform
+#
+O := o
+
+# the library file extension, this can be .a, .lib, etc..
+# depending on the platform
+#
+A := a
+
+
+# The name of the final library file.
+# Note that the DOS-specific Makefile uses a shorter (8.3) name
+#
+LIBRARY := libfreetype
+
+
+# path inclusion flag.
+#
+# Some compilers use a different flag than '-I' to specify an
+# additional include path. Examples are "/i=" or "-J", etc...
+#
+I := -I
+
+
+# C flag used to define a macro before the compilation of a given
+# source object. Usually is '-D' like in "-DDEBUG"
+#
+D := -D
+
+
+# Target flag - beware, there is a space after the 'o' !!
+#
+#
+T := -o
+
+
+# The link flag used to specify a given library file on link.
+# Note that this is only used to compile the demo programs, not
+# the library itself.
+#
+L := -l
+
+
+# C flags
+#
+# These should concern :
+#
+# - debug output
+# - optimization
+# - warnings
+# - ansi compliance..
+#
+ifndef CFLAGS
+CFLAGS := -c
+endif
+
+# Now include the main sub-makefile. It contains all the rules used
+# to build the library with the previous variables defined
+#
+include $(TOP)/config/freetype.mk
+
+
+# Librarian to use to build the static library
+#
+FT_LIBRARIAN := $(AR) -r
+
+
+# This final rule is used to link all object files into a single
+# library. It is part of the system-specific sub-Makefile because not
+# all librarians accept a simple syntax like :
+#
+# librarian library_file {list of object files}
+#
+$(FT_LIBRARY): $(OBJECTS_LIST)
+ -$(DELETE) $@
+ $(FT_LIBRARIAN) $@ $(OBJECTS_LIST)
+
--- /dev/null
+++ b/config/ansi/ftconfig.h
@@ -1,0 +1,182 @@
+/***************************************************************************/
+/* */
+/* ftconfig.h */
+/* */
+/* ANSI-specific configuration file (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. */
+/* */
+/***************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* This header file contains a number of macro definitions that are used */
+ /* by the rest of the engine. Porters are free to copy this file and */
+ /* adapt it to suit their own system. */
+ /* */
+ /* IMPORTANT NOTE: */
+ /* */
+ /* Porters, read carefully the comments in `ftsys.h' before trying to */
+ /* port this file to your system. It contains many essential */
+ /* remarks, and will ease your work greatly. */
+ /* */
+ /*************************************************************************/
+
+
+#ifndef FTCONFIG_H
+#define FTCONFIG_H
+
+/* Include the header file containing all developer build options */
+#include <ftoption.h>
+
+ /*************************************************************************/
+ /* */
+ /* PLATFORM-SPECIFIC CONFIGURATION MACROS */
+ /* */
+ /* These macros can be toggled to suit a specific system. The current */
+ /* ones are defaults used to compile FreeType in an ANSI C environment */
+ /* (16bit compilers are also supported). Copy this file to your own */
+ /* `freetype/arch/<system>' directory, and edit it to port the engine. */
+ /* */
+ /*************************************************************************/
+
+
+/* Define to empty if the keyword does not work. */
+/* #undef const */
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* We use <limits.h> values to know the sizes of the types. */
+#include <limits.h>
+
+/* The number of bytes in an `int' type. */
+#if UINT_MAX == 0xFFFFFFFF
+#define SIZEOF_INT 4
+#elif UINT_MAX == 0xFFFF
+#define SIZEOF_INT 2
+#elif UINT_MAX > 0xFFFFFFFF && UINT_MAX == 0xFFFFFFFFFFFFFFFF
+#define SIZEOF_INT 8
+#else
+#error "Unsupported number of bytes in `int' type!"
+#endif
+
+/* The number of bytes in a `long' type. */
+#if ULONG_MAX == 0xFFFFFFFF
+#define SIZEOF_LONG 4
+#elif ULONG_MAX > 0xFFFFFFFF && ULONG_MAX == 0xFFFFFFFFFFFFFFFF
+#define SIZEOF_LONG 8
+#else
+#error "Unsupported number of bytes in `long' type!"
+#endif
+
+/* Define if you have the memcpy function. */
+#define HAVE_MEMCPY 1
+
+/* Define if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 0
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 0
+
+
+/* Preferred alignment of data */
+#define FT_ALIGNMENT 8
+
+
+
+ /*************************************************************************/
+ /* */
+ /* AUTOMATIC CONFIGURATION MACROS */
+ /* */
+ /* These macros are computed from the ones defined above. Don't touch */
+ /* their definition, unless you know precisely what you're doing. No */
+ /* porter should need to mess with them. */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* IntN types */
+ /* */
+ /* Used to guarantee the size of some specific integers. */
+ /* */
+ typedef signed short FT_Int16;
+ typedef unsigned short FT_Word16;
+
+#if SIZEOF_INT == 4
+
+ typedef signed int FT_Int32;
+ typedef unsigned int FT_Word32;
+
+#elif SIZEOF_LONG == 4
+
+ typedef signed long FT_Int32;
+ typedef unsigned long FT_Word32;
+
+#else
+#error "no 32bit type found - please check your configuration files"
+#endif
+
+#if SIZEOF_LONG == 8
+
+ /* LONG64 must be defined when a 64-bit type is available */
+#define LONG64
+#define INT64 long
+
+#else
+
+
+ /*************************************************************************/
+ /* */
+ /* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */
+ /* it by defining the FTCALC_USE_LONG_LONG macro in `ftconfig.h'. Note */
+ /* that this will produce many -ansi warnings during library */
+ /* compilation. */
+ /* */
+#ifdef FTCALC_USE_LONG_LONG
+
+#define LONG64
+#define INT64 long long
+
+#endif /* FTCALC_USE_LONG_LONG */
+#endif
+
+
+#ifdef FT_MAKE_OPTION_SINGLE_OBJECT
+#define LOCAL_DEF static
+#define LOCAL_FUNC static
+#else
+#define LOCAL_DEF extern
+#define LOCAL_FUNC /* nothing */
+#endif
+
+#ifdef FT_MAKE_OPTION_SINGLE_LIBRARY_OBJECT
+#define BASE_DEF LOCAL_DEF
+#define BASE_FUNC LOCAL_FUNC
+#else
+#define BASE_DEF extern
+#define BASE_FUNC /* nothing */
+#endif
+
+#ifndef EXPORT_DEF
+#define EXPORT_DEF extern
+#endif
+
+#ifndef EXPORT_FUNC
+#define EXPORT_FUNC /* nothing */
+#endif
+
+#endif /* FTCONFIG_H */
+
+
+/* END */
--- /dev/null
+++ b/config/ansi/ftoption.h
@@ -1,0 +1,162 @@
+#ifndef FTOPTION_H
+#define FTOPTION_H
+
+ /*************************************************************************/
+ /* */
+ /* USER-SELECTABLE CONFIGURATION MACROS */
+ /* */
+ /* These macros can be toggled by developers to enable or disable */
+ /* certain aspects of FreeType. This file contains macros that apply to */
+ /* all of FreeType. Driver-specific configurations are placed in each */
+ /* driver directory (e.g. `freetype/drivers/ttlib/ttconfig.h'). */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* Alternate Glyph Image Format support */
+ /* */
+ /* By default, the glyph images returned by the FreeType glyph loader */
+ /* can either be a pixmap or a vectorial outline defined through */
+ /* bezier control points. When defining the following configuration */
+ /* macro, some font drivers will be able to register alternate */
+ /* glyph image formats. */
+ /* */
+ /* Unset this macro if you're sure that you'll never use a font driver */
+ /* with an alternate glyph format, this will reduce the size of the */
+ /* base layer code. */
+ /* */
+#define FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS
+
+ /*************************************************************************/
+ /* */
+ /* GCC provides the non-ANSI `long long' 64-bit type. You can activate */
+ /* it by defining the FTCALC_USE_LONG_LONG macro here. Note however */
+ /* that we did not experience any improvement in speed with gcc, and */
+ /* that the final code seems bigger when linked. */
+ /* */
+#undef FTCALC_USE_LONG_LONG
+
+
+ /*************************************************************************/
+ /* */
+ /* When compiling FreeType as a DLL, some systems/compilers need a */
+ /* special keyword in front of each function definition instead of */
+ /* `extern'. */
+ /* */
+ /* The macros EXPORT_DEF and EXPORT_FUNC are thus used to define */
+ /* exported library function interfaces and exported library functions */
+ /* implementations respectively. */
+ /* */
+ /* If not defined here, they automatically default to `extern' and void */
+ /* later in this header file. */
+ /* */
+#undef EXPORT_DEF
+#undef EXPORT_FUNC
+
+
+ /*************************************************************************/
+ /* */
+ /* Debug level */
+ /* */
+ /* FreeType can be compiled in debug or trace mode. In debug mode, */
+ /* errors are reported through the `ftdebug' component. In trace */
+ /* mode, additional messages are sent to the standard output during */
+ /* execution. */
+ /* */
+ /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */
+ /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */
+ /* */
+ /* Don't define any of these macros to compile in `release' mode. */
+ /* */
+#undef FT_DEBUG_LEVEL_ERROR
+#undef FT_DEBUG_LEVEL_TRACE
+
+
+ /*************************************************************************/
+ /* */
+ /* Anti-aliasing support */
+ /* */
+ /* Undefine this macro only if you want to disable the anti-aliasing */
+ /* support in FreeType. This will save you about 5 Kb of code. It */
+ /* may be important for some embedded systems. */
+ /* */
+#define FT_CONFIG_OPTION_ANTI_ALIAS
+
+
+ /*************************************************************************/
+ /* */
+ /* Endianess performance improvement */
+ /* */
+ /* FreeType is completely endian-independent, and can thus be compiled */
+ /* directly on _any_ machine. However, some components of the library */
+ /* provide improved routines for the cases where endianess is known. */
+ /* */
+ /* It usually results in speed-ups and reduced code size. Note that */
+ /* you should not define both of these macros. */
+ /* */
+ /* */
+ /* NOTE: For now, only the scan-line converter (base/ftraster.c) uses */
+ /* these macros to speed-up some anti-alias rendering routines. */
+ /* */
+#undef FT_CONFIG_OPTION_LITTLE_ENDIAN
+#undef FT_CONFIG_OPTION_BIG_ENDIAN
+
+
+ /*************************************************************************/
+ /* */
+ /* Define this configuration macro whenever you want to build a version */
+ /* of FreeType that does not include a default `system' component. */
+ /* */
+ /* Note that this will prevent the compilation of `ftinit', hence the */
+ /* function FT_Init_FreeType */
+ /* */
+#undef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
+
+
+ /*************************************************************************/
+ /* */
+ /* The size in bytes of the render pool used by the scan-line */
+ /* converter to do all of its work. */
+ /* */
+ /* This must be greater than 4 Kb */
+ /* */
+#define FT_RENDER_POOL_SIZE 32768
+
+
+ /*************************************************************************/
+ /* */
+ /* FT_MAX_DRIVERS */
+ /* */
+ /* The maximum number of font drivers that can be registered in a */
+ /* single FreeType library object. 8 seems to be a good choice due */
+ /* to the relative low actual number of drivers ;-) */
+ /* */
+#define FT_MAX_DRIVERS 8
+
+
+ /*************************************************************************/
+ /* */
+ /* FT_MAX_EXTENSIONS */
+ /* */
+ /* The maximum number of extensions that can be registered in a */
+ /* single font driver. 8 seems to be a good choice for now.. */
+ /* */
+#define FT_MAX_EXTENSIONS 8
+
+
+ /*************************************************************************/
+ /* */
+ /* FT_MAX_GLYPH_FORMATS */
+ /* */
+ /* The maximum number of glyph image formats that might be registered */
+ /* in a given library instance. 8 seems to be a good choice due to */
+ /* the relatively low number of current formats ;-) */
+ /* */
+
+#define FT_MAX_GLYPH_FORMATS 8
+
+
+
+#endif /* FTOPTION_H */
--- /dev/null
+++ b/config/ansi/ftsys.c
@@ -1,0 +1,971 @@
+/***************************************************************************/
+/* */
+/* ftsys.c */
+/* */
+/* ANSI-specific system operations (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. */
+/* */
+/***************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* This implementation of the `ftsys' component uses the standard ANSI C */
+ /* library. */
+ /* */
+ /* IMPORTANT NOTE: */
+ /* */
+ /* Porters, read carefully the comments in ftsys.h before trying to */
+ /* port this file to your system. It contains many essential */
+ /* remarks, and will ease your work greatly. */
+ /* */
+ /*************************************************************************/
+
+
+#include "ftsys.h"
+#include "ftstream.h"
+#include "ftdebug.h"
+
+
+#ifdef FT_CONFIG_OPTION_DEBUG_MEMORY
+#include "memdebug.c"
+#endif
+
+
+ /*************************************************************************/
+ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+ /* parameter of the PTRACE() and PERROR() macros, used to print/log */
+ /* messages during execution. */
+ /* */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_io
+
+
+#undef CUR_SYSTEM /* just in case */
+
+
+ /*************************************************************************/
+ /* */
+ /* To ease porting, we use the macro SYS_STREAM to name the */
+ /* system-specific stream type. For example, it is a `FILE*' with the */
+ /* ANSI libc, it will be a file descriptor, i.e. an integer, when using */
+ /* the Unix system API, etc. */
+ /* */
+#define SYS_STREAM FILE*
+
+
+ /*************************************************************************/
+ /* */
+ /* This implementation of ftsys uses the ANSI C library. Memory */
+ /* management is performed through malloc/free, i/o access through */
+ /* fopen/fread/fseek, and no synchronisation primitive is implemented */
+ /* (they contain dummy code) */
+ /* */
+ /*************************************************************************/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+ /*************************************************************************/
+ /* */
+ /* I/O ACCESS AND MANAGEMENT */
+ /* */
+ /* We only define the `ANSI' resource class in this class. It is */
+ /* disk-based and provides a MRU cache in order to only keep the file */
+ /* descriptors of the 10 most recently used resource files. */
+ /* */
+ /* It simply contains two lists. One contains the `cached' resources */
+ /* with a valid FILE* pointer, the second contains all other `flushed' */
+ /* resource objects. */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* FT_AnsiFileRec */
+ /* */
+ /* <Description> */
+ /* The FT_AnsiFile class derives from FT_ResourceRec. */
+ /* */
+ /* <Fields> */
+ /* root :: The root resource class fields. */
+ /* */
+ /* pathname :: This is a copy of the ANSI file pathname used to open */
+ /* streams for the resource. A different implementation */
+ /* is free to use Unicode chars, or file i-node numbers, */
+ /* etc. */
+ /* */
+ /* file_size :: The size in bytes of the resource. This field should */
+ /* be set to -1 until the resource is first opened. */
+ /* */
+ typedef struct FT_AnsiFileRec_
+ {
+ FT_ResourceRec root;
+ char* pathname; /* the font file's pathname */
+ FT_Long file_size; /* file size in bytes */
+
+ } FT_AnsiFileRec, *FT_AnsiFile;
+
+
+ /*************************************************************************/
+ /* */
+ /* We use the macro STREAM_Name() as a convenience to return a given */
+ /* ANSI resource's pathname. Its `stream' argument is a FT_Resource */
+ /* which is typecasted to the FT_AnsiFile class. */
+ /* */
+#define STREAM_Name( stream ) ((FT_AnsiFile)stream->resource)->pathname
+
+
+ /*************************************************************************/
+ /* */
+ /* We use the macro STREAM_File() as a convenience to extract the */
+ /* system-specific stream handle from a given FreeType stream object. */
+ /* */
+#define STREAM_File( stream ) ((FILE*)stream->stream_id.pointer)
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* AnsiFile_Open */
+ /* */
+ /* <Description> */
+ /* This function is used to open a system-stream for a given */
+ /* resource. */
+ /* */
+ /* Note that it must update the target FreeType stream object with */
+ /* the system-stream handle and the resource's size. */
+ /* */
+ /* Also, the `stream->base' field must be set to NULL for disk-based */
+ /* resources, and to the address in memory of the resource's first */
+ /* byte for memory-based ones. */
+ /* */
+ /* <Input> */
+ /* resource :: The source resource. */
+ /* stream :: The target stream object. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* This function simply calls fopen() in the resource's file */
+ /* pathname. */
+ /* */
+ /* The stream object IS NOT CREATED by this function, but by its */
+ /* caller. */
+ /* */
+ static
+ FT_Error AnsiFile_Open( FT_AnsiFile resource,
+ FT_Stream stream )
+ {
+ FILE* file;
+
+ /* open the file */
+ file = fopen( resource->pathname, "rb" );
+ if ( !file )
+ {
+ PERROR(( "AnsiFile_Open: Could not open file `%s'\n",
+ resource->pathname ));
+ return FT_Err_Cannot_Open_Stream;
+ }
+
+ /* compute file size if necessary */
+ if ( resource->file_size < 0 )
+ {
+ fseek( file, 0, SEEK_END );
+ resource->file_size = ftell( file );
+ fseek( file, 0, SEEK_SET );
+ }
+
+ stream->resource = (FT_Resource)resource;
+ stream->stream_id.pointer = file;
+ stream->size = resource->file_size;
+
+ /* it's a disk-based resource, we don't need to use the `base' and */
+ /* `cursor' fields of the stream objects */
+ stream->base = NULL;
+ stream->cursor = NULL;
+
+ PTRACE1(( "AnsiFile_Open: Opened `%s' (%d bytes) successfully\n",
+ resource->pathname, resource->file_size ));
+
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* AnsiFile_Close */
+ /* */
+ /* <Description> */
+ /* Closes a given stream. */
+ /* */
+ /* <Input> */
+ /* stream :: The target stream object. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* This function simply calls fclose() on the stream's ANSI FILE */
+ /* object. */
+ /* */
+ static
+ FT_Error AnsiFile_Close( FT_Stream stream )
+ {
+ PTRACE1(( "AnsiFile_Close: Closing file `%s'\n", STREAM_Name( stream ) ));
+
+ fclose( STREAM_File( stream ) );
+
+ stream->resource = NULL;
+ stream->stream_id.pointer = NULL;
+ stream->size = 0;
+
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* AnsiFile_Seek */
+ /* */
+ /* <Description> */
+ /* Seeks a stream to a given position. */
+ /* */
+ /* <Input> */
+ /* stream :: The target stream object. */
+ /* position :: The offset in bytes from the start of the */
+ /* resource/stream. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* This function simply calls fseek() on the stream. */
+ /* */
+ /* The `seek' method is never called by the stream manager in case */
+ /* of a memory-based resource (i.e., when `stream->base' isn't NULL). */
+ /* */
+ static
+ FT_Error AnsiFile_Seek( FT_Stream stream,
+ FT_Long position )
+ {
+ if ( fseek( STREAM_File( stream ), position, SEEK_SET ) )
+ {
+ PERROR(( "AnsiFile_Seek: FAILED! Pos. %ld of `%s'\n",
+ position, STREAM_Name( stream ) ));
+
+ return FT_Err_Invalid_Stream_Seek;
+ }
+
+ PTRACE2(( "AnsiFile_Seek: Pos. %ld of `%s'\n",
+ position, STREAM_Name( stream ) ));
+
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* AnsiFile_Skip */
+ /* */
+ /* <Description> */
+ /* Skips a given number of bytes in an ANSI stream. Useful to skip */
+ /* pad bytes, for example. */
+ /* */
+ /* <Input> */
+ /* stream :: The target stream object. */
+ /* count :: The number of bytes to skip in the stream. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* This function simply calls fseek() on the stream. */
+ /* */
+ /* The `skip' method is never called by the stream manager in case */
+ /* of a memory-based resource (i.e., when `stream->base' isn't NULL). */
+ /* */
+ static
+ FT_Error AnsiFile_Skip( FT_Stream stream,
+ FT_Long count )
+ {
+ if ( fseek( STREAM_File( stream ), count, SEEK_CUR ) )
+ {
+ PERROR(( "AnsiFile_Skip: FAILED! %ld bytes in `%s'\n",
+ count, STREAM_Name( stream ) ));
+
+ return FT_Err_Invalid_Stream_Seek;
+ }
+
+ PTRACE2(( "AnsiFile_Skip: %ld bytes in `%s'\n",
+ count, STREAM_Name( stream ) ));
+
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* AnsiFile_Pos */
+ /* */
+ /* <Description> */
+ /* Returns the current offset within an ANSI stream's resource. */
+ /* */
+ /* <Input> */
+ /* stream :: The target stream object. */
+ /* */
+ /* <Output> */
+ /* position :: The current offset. -1 in case of error. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* This function simply calls ftell() on the stream. */
+ /* */
+ /* The `pos' method is never called by the stream manager in case */
+ /* of a memory-based resource (i.e., when `stream->base' isn't NULL). */
+ /* */
+ static
+ FT_Error AnsiFile_Pos( FT_Stream stream,
+ FT_Long* position )
+ {
+ *position = ftell( STREAM_File( stream ) );
+ if ( *position == -1 )
+ {
+ PTRACE2(( "AnsiFile_Pos: FAILED! In `%s'\n", STREAM_Name( stream ) ));
+ return FT_Err_Invalid_Stream_Seek;
+ }
+
+ PTRACE2(( "AnsiFile_Pos: For `%s'\n", STREAM_Name( stream ) ));
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* AnsiFile_Read */
+ /* */
+ /* <Description> */
+ /* Reads a given number of bytes from an ANSI stream into memory. */
+ /* */
+ /* <Input> */
+ /* stream :: The target stream object. */
+ /* buffer :: The target read buffer where data is copied. */
+ /* size :: The number of bytes to read from the stream. */
+ /* */
+ /* <Output> */
+ /* read_bytes :: The number of bytes effectively read from the */
+ /* stream. Used in case of error */
+ /* (i.e. FT_Err_Invalid_Stream_Read) by some parts of */
+ /* the library. */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* This function simply calls fread() on the stream. */
+ /* */
+ /* It MUST return the error FT_Err_Invalid_Stream_Read in case of */
+ /* an over-read (i.e., reading more bytes from the stream that what */
+ /* is left), as the stream component checks for this specific value. */
+ /* */
+ /* The `read' method is never called by the stream manager in case */
+ /* of a memory-based resource (i.e., when `stream->base' isn't NULL). */
+ /* */
+ static
+ FT_Error AnsiFile_Read( FT_Stream stream,
+ FT_Char* buffer,
+ FT_Long size,
+ FT_Long* read_bytes )
+ {
+ *read_bytes = fread( buffer, 1, size, STREAM_File( stream ) );
+ if ( *read_bytes != size )
+ {
+ /* Note : we can have an over-read here when called by the */
+ /* function FT_Access_Compressed_Frame. This means */
+ /* that the following message should be a trace, */
+ /* rather than an error for disk-based resources.. */
+ /* */
+ /* the function must set the value of 'read_bytes' */
+ /* even if it returns an error code.. */
+ PTRACE2(( "AnsiFile_Read: FAILED! Read %ld bytes from '%s'\n",
+ size, STREAM_Name( stream ) ));
+
+ return FT_Err_Invalid_Stream_Read;
+ }
+
+ PTRACE2(( "AnsiFile_Read: Read %ld bytes to buffer 0x%08lx from `%s'\n",
+ size, (long)buffer, STREAM_Name( stream ) ));
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* The following table is the `virtual method table' for the `ANSI */
+ /* resource class', which methods are defined above. Its address is set */
+ /* in the `interface' field of all resource objects created by the */
+ /* function FT_Create_AnsiFile() (see below). */
+ /* */
+ static
+ FTRes_InterfaceRec FT_AnsiFile_Interface =
+ {
+ (FTRes_Open_Func) AnsiFile_Open,
+ (FTRes_Close_Func)AnsiFile_Close,
+ (FTRes_Seek_Func) AnsiFile_Seek,
+ (FTRes_Skip_Func) AnsiFile_Skip,
+ (FTRes_Pos_Func) AnsiFile_Pos,
+ (FTRes_Read_Func) AnsiFile_Read,
+ };
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Create_Resource */
+ /* */
+ /* <Description> */
+ /* Creates a new resource object. This function is called by the */
+ /* FT_New_Resource() function of the base layer. */
+ /* */
+ /* <Input> */
+ /* library :: The input library object. */
+ /* pathname :: The file's pathname as an ASCII string. */
+ /* */
+ /* <Output> */
+ /* aresource :: A handle to new resource object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* This functions does not open a stream. It simply copies the */
+ /* pathname within a fresh new resource object. */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_Create_Resource( FT_Library library,
+ const char* pathname,
+ FT_Resource* aresource )
+ {
+ FT_Int len;
+ FT_AnsiFile resource;
+ FT_Error error;
+ FT_System system;
+
+
+ if ( !library )
+ return FT_Err_Invalid_Library_Handle;
+
+ system = library->system;
+
+ if ( !pathname )
+ goto Fail_Null;
+
+ len = strlen( pathname );
+ if ( len == 0 )
+ goto Fail_Null;
+
+ resource = NULL;
+
+ if ( ALLOC( resource, sizeof ( *resource ) ) ||
+ ALLOC( resource->pathname, len + 1 ) )
+ goto Fail_Memory;
+
+ resource->root.library = library;
+ resource->root.interface = &FT_AnsiFile_Interface;
+ resource->root.flags = FT_RESOURCE_TYPE_DISK_BASED;
+ resource->file_size = -1;
+ strcpy( resource->pathname, pathname );
+
+ PTRACE1(( "Create_AnsiFile: Ansi resource created for `%s'\n",
+ pathname ));
+
+ *aresource = (FT_Resource)resource;
+ return FT_Err_Ok;
+
+ Fail_Null:
+ PERROR(( "Create_AnsiFile: Null pathname!\n" ));
+ return FT_Err_Invalid_Argument;
+
+ Fail_Memory:
+ if ( resource )
+ FREE( resource->pathname );
+ FREE( resource );
+ PERROR(( "Create_AnsiFile: Not enough memory to create resource!\n" ));
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Destroy_Resource */
+ /* */
+ /* <Description> */
+ /* Discards a given resource object explicitly. */
+ /* */
+ /* <Input> */
+ /* resource :: The ANSI resource object. */
+ /* */
+ /* <Note> */
+ /* This function does not check whether runs or streams are opened */
+ /* for the resource (for now, we assume developer intelligence. */
+ /* We'll most probably lower our standard later to ease debugging :-) */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_Destroy_Resource( FT_Resource resource )
+ {
+ FT_System system = resource->library->system;
+ FT_AnsiFile ansi = (FT_AnsiFile)resource;
+
+ if ( !ansi || ansi->root.interface != &FT_AnsiFile_Interface )
+ {
+ PERROR((
+ "Destroy_AnsiFile: Trying to destroy an invalid resource!\n" ));
+ return FT_Err_Invalid_Resource_Handle;
+ }
+
+ PTRACE1(( "Destroy_AnsiFile: Destroying resource for `%s'\n",
+ ansi->pathname ));
+
+ FREE( ansi->pathname );
+ FREE( ansi );
+
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* MEMORY MANAGEMENT */
+ /* */
+ /* */
+ /* This part copies the old FreeType 1.0 and 1.1 memory management */
+ /* scheme that was defined in the file `ttmemory.h'. One can see that */
+ /* */
+ /* - a set of macros is defined for the memory operations used by the */
+ /* engine (MEM_Copy(), MEM_Move(), MEM_Set()). This comes from the */
+ /* fact that many compilers are able to inline these operations */
+ /* directly within the compiled code, rather than generating a call */
+ /* to the C library. However, this obliges us to include the */
+ /* `<string.h>' header file. */
+ /* */
+ /* If you provide your own memory operations, you can get rid of the */
+ /* `#include <string.h>' below. */
+ /* */
+ /* */
+ /* - the FT_Alloc() function has several essential properties that MUST */
+ /* be retained by each port: */
+ /* */
+ /* - It returns an error code, NOT the allocated block's base */
+ /* address. */
+ /* */
+ /* - It takes the address of a target pointer, where the block's base */
+ /* address will be set. If the size is zero, its value will be */
+ /* NULL, and the function returns successfully. */
+ /* */
+ /* - In case of error, the pointer's value is set to NULL and an */
+ /* error code is returned. */
+ /* */
+ /* - The new allocated block MUST be zero-filled. This is a strong */
+ /* convention the rest of the engine relies on. */
+ /* */
+ /* */
+ /* - the FT_Free() function has also its essentials: */
+ /* */
+ /* - It takes the address of a pointer which value is the block's */
+ /* base address. This is UNLIKE a standard `free()' which takes */
+ /* the block's base directly. */
+ /* */
+ /* - It accepts successfully the address of a pointer which value is */
+ /* NULL, in which case it simply returns. */
+ /* */
+ /* - The pointer is always set to NULL by the function. */
+ /* */
+ /* */
+ /* - The MEM_Alloc(), ALLOC(), and ALLOC_ARRAY() macros are used by the */
+ /* library and should NOT be modified by porters! */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+ /* parameter of the PTRACE() and PERROR() macros, used to print/log */
+ /* messages during execution. */
+ /* */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_memory
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Alloc */
+ /* */
+ /* <Description> */
+ /* Allocates a new block of memory. The returned area is always */
+ /* zero-filled, this is a strong convention in many FreeType parts. */
+ /* */
+ /* <Input> */
+ /* system :: A handle to a given `system object' where allocation */
+ /* occurs. */
+ /* */
+ /* size :: The size in bytes of the block to allocate. */
+ /* */
+ /* <Output> */
+ /* P :: A pointer to the fresh new block. It should be set to */
+ /* NULL if `size' is 0, or in case of error. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ BASE_FUNC
+ FT_Error FT_Alloc( FT_System system,
+ FT_Long size,
+ void** P )
+ {
+ if ( !P )
+ {
+ PERROR(( "FT_Alloc: Invalid pointer address!\n" ));
+ return FT_Err_Invalid_Argument;
+ }
+
+ if ( size > 0 )
+ {
+ *P = malloc( size );
+ if ( !*P )
+ {
+ PERROR(( "FT_Alloc: Out of memory (%ld bytes requested)!\n",
+ size ));
+
+ return FT_Err_Out_Of_Memory;
+ }
+
+#ifdef FT_CONFIG_OPTION_DEBUG_MEMORY
+ DM_Record( (char*)*P, size );
+#endif
+
+ system->total_alloc += size;
+
+ /* ALWAYS ZERO-FILL THE BLOCK! */
+ MEM_Set( *P, 0, size );
+ }
+ else
+ *P = NULL;
+
+ PTRACE2(( "FT_Alloc: Size = %ld, pointer = 0x%08lx, block = 0x%08lx\n",
+ size, (long)P, (long)*P ));
+
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Realloc */
+ /* */
+ /* <Description> */
+ /* Reallocates a block of memory pointed to by `*P' to `Size' bytes */
+ /* from the heap, possibly changing `*P'. */
+ /* */
+ /* <Input> */
+ /* system :: A handle to a given `system object' where allocation */
+ /* occurs. */
+ /* */
+ /* size :: The size in bytes of the block to allocate. */
+ /* */
+ /* <InOut> */
+ /* P :: A pointer to the fresh new block. It should be set to */
+ /* NULL if `size' is 0, or in case of error. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ BASE_FUNC
+ FT_Error FT_Realloc( FT_System system,
+ FT_Long size,
+ void* *P )
+ {
+ void* Q;
+
+
+ if ( !P )
+ {
+ PERROR(( "FT_Realloc: Invalid pointer address!\n" ));
+ return FT_Err_Invalid_Argument;
+ }
+
+ /* if the original pointer is NULL, call FT_Alloc() */
+ if ( !*P )
+ return FT_Alloc( system, size, P );
+
+ /* if the new block if zero-sized, clear the current one */
+ if ( size <= 0 )
+ return FT_Free( system, P );
+
+#ifdef FT_CONFIG_OPTION_DEBUG_MEMORY
+ DM_Forget( (char*)*P );
+#endif
+
+ Q = (void*)realloc( *P, size );
+ if ( !Q )
+ {
+ PERROR(( "FT_Realloc: Reallocation failed!\n" ));
+ return FT_Err_Out_Of_Memory;
+ }
+
+#ifdef FT_CONFIG_OPTION_DEBUG_MEMORY
+ DM_Record( (char*)Q, size );
+#endif
+
+ *P = Q;
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Free */
+ /* */
+ /* <Description> */
+ /* Releases a given block of memory allocated through FT_Alloc(). */
+ /* */
+ /* <Input> */
+ /* system :: A handle to a given `system object' where allocation */
+ /* occured. */
+ /* */
+ /* P :: This is the _address_ of a _pointer_ which points to the */
+ /* allocated block. It is always set to NULL on exit. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* If P or *P are NULL, this function should return successfully. */
+ /* This is a strong convention within all of FreeType and its */
+ /* drivers. */
+ /* */
+ BASE_FUNC
+ FT_Error FT_Free( FT_System system,
+ void* *P )
+ {
+ UNUSED( system );
+
+ PTRACE2(( "FT_Free: Freeing pointer 0x%08lx (block 0x%08lx)\n",
+ (long)P, (P ? (long)*P : -1) ));
+
+ if ( !P || !*P )
+ return FT_Err_Ok;
+
+ free( *P );
+
+#ifdef FT_CONFIG_OPTION_DEBUG_MEMORY
+ DM_Forget( (char*)*P );
+#endif
+
+ *P = NULL;
+
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SYNCHRONIZATION MANAGEMENT */
+ /* */
+ /* */
+ /* This section deals with mutexes. The library can be compiled to */
+ /* two distinct thread support levels (namely single threaded and */
+ /* re-entrant modes). */
+ /* */
+ /* It protects its variables through the MUTEX_Lock() and */
+ /* MUTEX_Release() macros which are void in single threaded mode. */
+ /* */
+ /* It defines a typeless mutex reference type, `FT_Mutex', that you're */
+ /* free to redefine for your system's needs. */
+ /* */
+ /* The default implementation of ftsys.c contains only dummy functions */
+ /* which always return successfully. You NEED to specialize them in */
+ /* order to port ftsys.c to any multi-threaded environment. */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+ /* parameter of the PTRACE() and PERROR() macros, used to print/log */
+ /* messages during execution. */
+ /* */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_sync
+
+
+#ifdef FT_CONFIG_THREADS
+
+ BASE_FUNC
+ FT_Error FT_Mutex_Create( FT_System system,
+ TMutex* mutex )
+ {
+ UNUSED( system );
+
+ mutex = (void*)-1;
+ system->num_mutexes++;
+
+ /* Insert your own mutex creation code here */
+
+ return FT_Err_Ok;
+ }
+
+
+ BASE_FUNC
+ void FT_Mutex_Delete( FT_System system,
+ TMutex* mutex )
+ {
+ UNUSED( system );
+
+ mutex = (void*)0;
+ system->num_mutexes--;
+
+ /* Insert your own mutex destruction code here */
+ }
+
+
+ BASE_FUNC
+ void FT_Mutex_Lock( FT_System system,
+ TMutex* mutex )
+ {
+ /* NOTE: It is legal to call this function with a NULL argument */
+ /* in which case an immediate return is appropriate. */
+
+ UNUSED( system );
+
+ if ( !mutex )
+ return;
+
+ /* Insert your own mutex locking code here */
+ }
+
+
+ BASE_FUNC
+ void FT_Mutex_Release( FT_System system,
+ TMutex* mutex )
+ {
+ /* NOTE: It is legal to call this function with a NULL argument */
+ /* in which case an immediate return is appropriate */
+
+ UNUSED( system );
+
+ if ( !mutex )
+ return;
+
+ /* Insert your own mutex release code here */
+ }
+
+#endif /* FT_CONFIG_THREADS */
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_New_System */
+ /* */
+ /* <Description> */
+ /* This function is used to create and initialize new system objects. */
+ /* These are mainly used to let client applications and font servers */
+ /* specify their own memory allocators and synchronization */
+ /* procedures. */
+ /* */
+ /* <Output> */
+ /* system :: A handle to a given `system object'. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_New_System( FT_System* system )
+ {
+ *system = (FT_System)malloc( sizeof ( **system ) );
+
+ if ( !*system )
+ return FT_Err_Out_Of_Memory;
+
+ /* the ANSI function `free()' is unable to return the number */
+ /* of released bytes. Hence, the `current_alloc' field of the */
+ /* system object cannot be used. */
+
+ (*system)->system_flags = FT_SYSTEM_FLAG_TOTAL_ALLOC |
+ FT_SYSTEM_FLAG_MUTEXES;
+ (*system)->total_alloc = 0;
+ (*system)->num_mutexes = 0;
+
+#ifdef FT_CONFIG_OPTION_DEBUG_MEMORY
+ DM_Init_Mem();
+#endif
+
+ /* initialize i/o management (nothing) */
+
+ /* initialize synchronisation (nothing) */
+
+ /* initialize streams (nothing) */
+
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Done_System */
+ /* */
+ /* <Description> */
+ /* Destroys a given FreeType system object. */
+ /* */
+ /* <Input> */
+ /* system :: A handle to a given `system object'. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_Done_System( FT_System system )
+ {
+ /* finalize synchronization (nothing) */
+
+ /* finalize i/o management (nothing) */
+
+ /* finalize memory management */
+
+#ifdef FT_CONFIG_OPTION_DEBUG_MEMORY
+ DM_Done_Mem();
+#endif
+
+ free( system );
+
+ return FT_Err_Ok;
+ }
+
+
+/* END */
--- /dev/null
+++ b/config/ansi/ftsystem.c
@@ -1,0 +1,214 @@
+/**************************************************************************
+ *
+ * ftsystem.h 1.0
+ *
+ * ANSI-specific FreeType low-level system interface
+ *
+ * This file contains the definition of interface used by FreeType
+ * to access low-level, i.e. memory management, i/o access as well
+ * as thread synchronisation.
+ *
+ *
+ * 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 <ftsystem.h>
+#include <fterrors.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+ /*********************************************************************/
+ /* */
+ /* MEMORY MANAGEMENT INTERFACE */
+ /* */
+
+/************************************************************************
+ *
+ * <FuncType>
+ * FT_Alloc_Func
+ *
+ * <Description>
+ * The memory allocator function type
+ *
+ * <Input>
+ * system :: pointer to the system object
+ * size :: requested size in bytes
+ *
+ * <Output>
+ * block :: address of newly allocated block
+ *
+ * <Return>
+ * Error code. 0 means success.
+ *
+ * <Note>
+ * If your allocation routine ALWAYS zeroes the new block, you
+ * should set the flag FT_SYSTEM_FLAG_ALLOC_ZEROES in your system
+ * object 'flags' field.
+ *
+ * If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ * your system's "system_flags" field, this function should update
+ * the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+ static
+ void* ft_alloc( FT_Memory memory,
+ long size )
+ {
+ (void)memory;
+ return malloc(size);
+ }
+
+
+/************************************************************************
+ *
+ * <FuncType>
+ * FT_Realloc_Func
+ *
+ * <Description>
+ * The memory reallocator function type
+ *
+ * <Input>
+ * system :: pointer to the system object
+ * new_size :: new requested size in bytes
+ *
+ * <InOut>
+ * block :: address of block in memory
+ *
+ * <Return>
+ * Error code. 0 means success.
+ *
+ * <Note>
+ * This function is _never_ called when the system flag
+ * FT_SYSTEM_FLAG_NO_REALLOC is set. Instead, the engine will emulate
+ * realloc through "alloc" and "free".
+ *
+ * Note that this is possible due to the fact that FreeType's
+ * "FT_Realloc" always requests the _current_ size of the reallocated
+ * block as a parameter, thus avoiding memory leaks.
+ *
+ * If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ * your system's "system_flags" field, this function should update
+ * the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+ static
+ void* ft_realloc( FT_Memory memory,
+ long cur_size,
+ long new_size,
+ void* block )
+ {
+ (void)memory;
+ (void)cur_size;
+
+ return realloc( block, new_size );
+ }
+
+
+/************************************************************************
+ *
+ * <FuncType>
+ * FT_Free_Func
+ *
+ * <Description>
+ * The memory release function type
+ *
+ * <Input>
+ * system :: pointer to the system object
+ * block :: address of block in memory
+ *
+ * <Note>
+ * If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ * your system's "system_flags" field, this function should update
+ * the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+ static
+ void ft_free( FT_Memory memory,
+ void* block )
+ {
+ (void)memory;
+ free( block );
+ }
+
+ /*********************************************************************/
+ /* */
+ /* RESOURCE MANAGEMENT INTERFACE */
+ /* */
+
+
+#define STREAM_FILE(stream) ((FILE*)stream->descriptor.pointer)
+
+ static
+ void ft_close_stream( FT_Stream stream )
+ {
+ fclose( STREAM_FILE(stream) );
+ }
+
+ static
+ unsigned long ft_io_stream( FT_Stream stream,
+ unsigned long offset,
+ char* buffer,
+ unsigned long count )
+ {
+ FILE* file;
+
+ file = STREAM_FILE(stream);
+
+ fseek( file, offset, SEEK_SET );
+ return (unsigned long)fread( buffer, count, 1, file );
+ }
+
+
+ extern
+ int FT_New_Stream( const char* filepathname,
+ FT_Stream stream )
+ {
+ FILE* file;
+
+ file = fopen( filepathname, "rb" );
+ if (!file)
+ return FT_Err_Cannot_Open_Resource;
+
+ fseek( file, 0, SEEK_END );
+ stream->size = ftell(file);
+ fseek( file, 0, SEEK_SET );
+
+ stream->descriptor.pointer = file;
+ stream->pos = 0;
+
+ stream->read = ft_io_stream;
+ stream->close = ft_close_stream;
+
+ return 0;
+ }
+
+
+ extern
+ FT_Memory FT_New_Memory( void )
+ {
+ FT_Memory memory;
+
+ memory = (FT_Memory)malloc( sizeof(*memory) );
+ if (memory)
+ {
+ memory->user = 0;
+ memory->alloc = ft_alloc;
+ memory->realloc = ft_realloc;
+ memory->free = ft_free;
+ }
+ return memory;
+ }
+
--- /dev/null
+++ b/config/ansi/memdebug.c
@@ -1,0 +1,143 @@
+/***************************************************************************/
+/* */
+/* memdebug.c */
+/* */
+/* Memory debugging functions (body 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. */
+/* */
+/***************************************************************************/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+ typedef struct TBlockRec_
+ {
+ char* base;
+ long size;
+
+ } TBlockRec;
+
+
+ static TBlockRec* mem_blocks;
+ static int num_mem_blocks;
+ static int max_mem_blocks;
+
+
+ void DM_Init_Mem()
+ {
+ num_mem_blocks = 0;
+ max_mem_blocks = 4096;
+ mem_blocks = (TBlockRec*)malloc( max_mem_blocks *
+ sizeof ( *mem_blocks ) );
+ }
+
+
+ void DM_Done_Mem()
+ {
+ /* Now print the remaining blocks */
+ if ( num_mem_blocks == 0 )
+ {
+ fprintf( stderr, "No memory leaked!\n" );
+ }
+ else
+ {
+ int i;
+
+
+ fprintf( stderr, "There were %d leaked memory blocks\n\n",
+ num_mem_blocks );
+
+ fprintf( stderr, "base size\n" );
+ fprintf( stderr, "------------------\n" );
+
+ for ( i = 0; i < num_mem_blocks; i++ )
+ {
+ fprintf( stderr, "%08lx %04lx\n",
+ (long)mem_blocks[i].base, mem_blocks[i].size );
+ }
+ }
+ free( mem_blocks );
+ }
+
+
+ void DM_Record( char* base,
+ long size )
+ {
+ TBlockRec* block;
+
+
+#if 0
+ /* First, check that the block is not located within one of the */
+ /* recorded blocks */
+ for ( i = 0; i < num_mem_blocks; i++ )
+ {
+ char *start, *end, *_limit, *_base;
+
+
+ _base = mem_blocks[i].base;
+ _limit = _base + mem_blocks[i].size;
+
+ start = base;
+ end = base + size - 1;
+
+ if ( ( start >= base && start < limit ) ||
+ ( end >= base && end < limit ) )
+ {
+ fprintf( stderr, "Warning: Recording an invalid block!\n" );
+ }
+ }
+#endif
+
+ /* Add block to list */
+ if ( num_mem_blocks >= max_mem_blocks )
+ {
+ max_mem_blocks *= 2;
+ mem_blocks = realloc( mem_blocks,
+ max_mem_blocks * sizeof ( *mem_blocks ) );
+ }
+ block = mem_blocks + num_mem_blocks;
+ block->base = base;
+ block->size = size;
+ num_mem_blocks++;
+ }
+
+
+ void DM_Forget( char* base )
+ {
+ TBlockRec* block = mem_blocks;
+ int i;
+
+
+ for ( i = 0; i < num_mem_blocks; i++, block++ )
+ {
+ if ( block->base == base )
+ {
+ /* simply move last block to the current position */
+ if ( num_mem_blocks > 1 )
+ *block = mem_blocks[num_mem_blocks - 1];
+
+ num_mem_blocks--;
+ return;
+ }
+
+#if 1
+ if ( base >= block->base && base < block->base + block->size )
+ {
+ fprintf( stderr, "Invalid block forgotten!\n" );
+ }
+#endif
+ }
+ }
+
+
+/* END */
--- /dev/null
+++ b/config/detect.mk
@@ -1,0 +1,127 @@
+#****************************************************************************
+#* *
+#* FreeType host platform detection rules *
+#* *
+#* 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 sub-Makefile is in charge of detecting the current platform *
+#* It sets some variables accordingly. Namely : *
+#* *
+#* PLATFORM The detected platform. This will default to "ansi" if *
+#* auto-detection fails. *
+#* *
+#* BUILD The configuration and system-specific directory. Usually *
+#* 'freetype/config/$(PLATFORM)' but can be different when *
+#* a specific compiler has been requested on the *
+#* command line.. *
+#* *
+#* CONFIG_RULES The Makefile to use. This usually depends on the compiler *
+#* defined in the 'CC' environment variable. *
+#* *
+#* DELETE The shell command used to remove a given file *
+#* COPY The shell command used to copy one file *
+#* *
+#* You need to set the following variable(s) before calling it: *
+#* *
+#* TOP The top-most directory in the FreeType library source *
+#* hierarchy. If not defined, it will default to '.' *
+#* *
+#****************************************************************************
+
+# If TOP is not defined, default it to '.'
+#
+ifndef TOP
+TOP := .
+endif
+
+#
+# set auto-detection default to ANSI.
+# Note that we delay the valuation of BUILD and RULES
+#
+PLATFORM := ansi
+CONFIG = $(TOP)$(SEP)config
+DELETE := $(RM)
+COPY := cp
+SEP := /
+
+BUILD = $(CONFIG)$(SEP)$(PLATFORM)
+CONFIG_FILE = $(BUILD)/Makefile
+
+
+###########################################################################
+#
+# Now, include each detection rules file found in a `config/<system>'
+# directory..
+#
+#
+
+# we define the BACKSLASH variable to hold a single back-slash character
+# This is needed because a line like
+#
+# SEP := \
+#
+# does not work with GNU Make (the back-slash is interpreted as a line
+# continuation). While a line like :
+#
+# SEP := \\
+#
+# really define $(SEP) as "\" on Unix, and "\\" on Dos and Windows !!
+#
+BACKSLASH := $(strip \ )
+
+include $(wildcard $(CONFIG)/*/detect.mk)
+
+
+# The following targets are equivalent, with the exception that they use
+# slightly different syntaxes for the `echo' command. This is due to
+#
+# std_setup: is defined for most platforms
+# dos_setup: is defined for Dos-ish platforms like Dos, Windows & OS/2
+#
+
+.PHONY: std_setup dos_setup
+
+std_setup:
+ @echo ""
+ @echo "FreeType build system - automatic system detection"
+ @echo ""
+ @echo "The following settings were detected :"
+ @echo ""
+ @echo " platform : $(PLATFORM)"
+ @echo " compiler : $(CC)"
+ @echo " configuration directory : $(BUILD)"
+ @echo " configuration rules : $(CONFIG_RULES)"
+ @echo ""
+ @echo "If this does not correspond to your system or settings please remove the file"
+ @echo "\`$(CONFIG_MK)' from this directory then read the INSTALL file for help."
+ @echo ""
+ @echo "Otherwise, simple type \`make' again to build the library"
+ @echo ""
+ @$(COPY) $(CONFIG_RULES) $(CONFIG_MK)
+
+dos_setup:
+ @echo + @echo FreeType build system - automatic system detection
+ @echo + @echo The following settings were detected :
+ @echo + @echo ��platform�����������������: $(PLATFORM)
+ @echo ��compiler�����������������: $(CC)
+ @echo ��configuration directory��: $(BUILD)
+ @echo ��configuration rules������: $(CONFIG_RULES)
+ @echo + @echo If this does not correspond to your system or settings please remove the file
+ @echo '$(CONFIG_MK)' from this directory then read the INSTALL file for help.
+ @echo + @echo Otherwise, simple type 'make' again to build the library
+ @echo + @$(COPY) $(CONFIG_RULES) $(CONFIG_MK) > nul
+
--- /dev/null
+++ b/config/dos/FTCONFIG.H
@@ -1,0 +1,182 @@
+/***************************************************************************/
+/* */
+/* ftconfig.h */
+/* */
+/* ANSI-specific configuration file (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. */
+/* */
+/***************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* This header file contains a number of macro definitions that are used */
+ /* by the rest of the engine. Porters are free to copy this file and */
+ /* adapt it to suit their own system. */
+ /* */
+ /* IMPORTANT NOTE: */
+ /* */
+ /* Porters, read carefully the comments in `ftsys.h' before trying to */
+ /* port this file to your system. It contains many essential */
+ /* remarks, and will ease your work greatly. */
+ /* */
+ /*************************************************************************/
+
+
+#ifndef FTCONFIG_H
+#define FTCONFIG_H
+
+/* Include the header file containing all developer build options */
+#include <ftoption.h>
+
+ /*************************************************************************/
+ /* */
+ /* PLATFORM-SPECIFIC CONFIGURATION MACROS */
+ /* */
+ /* These macros can be toggled to suit a specific system. The current */
+ /* ones are defaults used to compile FreeType in an ANSI C environment */
+ /* (16bit compilers are also supported). Copy this file to your own */
+ /* `freetype/arch/<system>' directory, and edit it to port the engine. */
+ /* */
+ /*************************************************************************/
+
+
+/* Define to empty if the keyword does not work. */
+/* #undef const */
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* We use <limits.h> values to know the sizes of the types. */
+#include <limits.h>
+
+/* The number of bytes in an `int' type. */
+#if UINT_MAX == 0xFFFFFFFF
+#define SIZEOF_INT 4
+#elif UINT_MAX == 0xFFFF
+#define SIZEOF_INT 2
+#elif UINT_MAX > 0xFFFFFFFF && UINT_MAX == 0xFFFFFFFFFFFFFFFF
+#define SIZEOF_INT 8
+#else
+#error "Unsupported number of bytes in `int' type!"
+#endif
+
+/* The number of bytes in a `long' type. */
+#if ULONG_MAX == 0xFFFFFFFF
+#define SIZEOF_LONG 4
+#elif ULONG_MAX > 0xFFFFFFFF && ULONG_MAX == 0xFFFFFFFFFFFFFFFF
+#define SIZEOF_LONG 8
+#else
+#error "Unsupported number of bytes in `long' type!"
+#endif
+
+/* Define if you have the memcpy function. */
+#define HAVE_MEMCPY 1
+
+/* Define if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 0
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 0
+
+
+/* Preferred alignment of data */
+#define FT_ALIGNMENT 8
+
+
+
+ /*************************************************************************/
+ /* */
+ /* AUTOMATIC CONFIGURATION MACROS */
+ /* */
+ /* These macros are computed from the ones defined above. Don't touch */
+ /* their definition, unless you know precisely what you're doing. No */
+ /* porter should need to mess with them. */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* IntN types */
+ /* */
+ /* Used to guarantee the size of some specific integers. */
+ /* */
+ typedef signed short FT_Int16;
+ typedef unsigned short FT_Word16;
+
+#if SIZEOF_INT == 4
+
+ typedef signed int FT_Int32;
+ typedef unsigned int FT_Word32;
+
+#elif SIZEOF_LONG == 4
+
+ typedef signed long FT_Int32;
+ typedef unsigned long FT_Word32;
+
+#else
+#error "no 32bit type found - please check your configuration files"
+#endif
+
+#if SIZEOF_LONG == 8
+
+ /* LONG64 must be defined when a 64-bit type is available */
+#define LONG64
+#define INT64 long
+
+#else
+
+
+ /*************************************************************************/
+ /* */
+ /* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */
+ /* it by defining the FTCALC_USE_LONG_LONG macro in `ftconfig.h'. Note */
+ /* that this will produce many -ansi warnings during library */
+ /* compilation. */
+ /* */
+#ifdef FTCALC_USE_LONG_LONG
+
+#define LONG64
+#define INT64 long long
+
+#endif /* FTCALC_USE_LONG_LONG */
+#endif
+
+
+#ifdef FT_MAKE_OPTION_SINGLE_OBJECT
+#define LOCAL_DEF static
+#define LOCAL_FUNC static
+#else
+#define LOCAL_DEF extern
+#define LOCAL_FUNC /* nothing */
+#endif
+
+#ifdef FT_MAKE_OPTION_SINGLE_LIBRARY_OBJECT
+#define BASE_DEF LOCAL_DEF
+#define BASE_FUNC LOCAL_FUNC
+#else
+#define BASE_DEF extern
+#define BASE_FUNC /* nothing */
+#endif
+
+#ifndef EXPORT_DEF
+#define EXPORT_DEF extern
+#endif
+
+#ifndef EXPORT_FUNC
+#define EXPORT_FUNC /* nothing */
+#endif
+
+#endif /* FTCONFIG_H */
+
+
+/* END */
--- /dev/null
+++ b/config/dos/FTOPTION.H
@@ -1,0 +1,152 @@
+#ifndef FTOPTION_H
+#define FTOPTION_H
+
+ /*************************************************************************/
+ /* */
+ /* USER-SELECTABLE CONFIGURATION MACROS */
+ /* */
+ /* These macros can be toggled by developers to enable or disable */
+ /* certain aspects of FreeType. This file contains macros that apply to */
+ /* all of FreeType. Driver-specific configurations are placed in each */
+ /* driver directory (e.g. `freetype/drivers/ttlib/ttconfig.h'). */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* Alternate Glyph Image Format support */
+ /* */
+ /* By default, the glyph images returned by the FreeType glyph loader */
+ /* can either be a pixmap or a vectorial outline defined through */
+ /* bezier control points. When defining the following configuration */
+ /* macro, some font drivers will be able to register alternate */
+ /* glyph image formats. */
+ /* */
+ /* Unset this macro if you're sure that you'll never use a font driver */
+ /* with an alternate glyph format, this will reduce the size of the */
+ /* base layer code. */
+ /* */
+#define FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS
+
+ /*************************************************************************/
+ /* */
+ /* GCC provides the non-ANSI `long long' 64-bit type. You can activate */
+ /* it by defining the FTCALC_USE_LONG_LONG macro here. Note however */
+ /* that we did not experience any improvement in speed with gcc, and */
+ /* that the final code seems bigger when linked. */
+ /* */
+#undef FTCALC_USE_LONG_LONG
+
+
+ /*************************************************************************/
+ /* */
+ /* When compiling FreeType as a DLL, some systems/compilers need a */
+ /* special keyword in front of each function definition instead of */
+ /* `extern'. */
+ /* */
+ /* The macros EXPORT_DEF and EXPORT_FUNC are thus used to define */
+ /* exported library function interfaces and exported library functions */
+ /* implementations respectively. */
+ /* */
+ /* If not defined here, they automatically default to `extern' and void */
+ /* later in this header file. */
+ /* */
+#undef EXPORT_DEF
+#undef EXPORT_FUNC
+
+
+ /*************************************************************************/
+ /* */
+ /* Debug level */
+ /* */
+ /* FreeType can be compiled in debug or trace mode. In debug mode, */
+ /* errors are reported through the `ftdebug' component. In trace */
+ /* mode, additional messages are sent to the standard output during */
+ /* execution. */
+ /* */
+ /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */
+ /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */
+ /* */
+ /* Don't define any of these macros to compile in `release' mode. */
+ /* */
+#undef FT_DEBUG_LEVEL_ERROR
+#undef FT_DEBUG_LEVEL_TRACE
+
+
+ /*************************************************************************/
+ /* */
+ /* Anti-aliasing support */
+ /* */
+ /* Undefine this macro only if you want to disable the anti-aliasing */
+ /* support in FreeType. This will save you about 5 Kb of code. It */
+ /* may be important for some embedded systems. */
+ /* */
+#define FT_CONFIG_OPTION_ANTI_ALIAS
+
+
+ /*************************************************************************/
+ /* */
+ /* Endianess performance improvement */
+ /* */
+ /* FreeType is completely endian-independent, and can thus be compiled */
+ /* directly on _any_ machine. However, some components of the library */
+ /* provide improved routines for the cases where endianess is known. */
+ /* */
+ /* It usually results in speed-ups and reduced code size. Note that */
+ /* you should not define both of these macros. */
+ /* */
+ /* */
+ /* NOTE: For now, only the scan-line converter (base/ftraster.c) uses */
+ /* these macros to speed-up some anti-alias rendering routines. */
+ /* */
+#undef FT_CONFIG_OPTION_LITTLE_ENDIAN
+#undef FT_CONFIG_OPTION_BIG_ENDIAN
+
+
+ /*************************************************************************/
+ /* */
+ /* Define this configuration macro whenever you want to build a version */
+ /* of FreeType that does not include a default `system' component. */
+ /* */
+ /* Note that this will prevent the compilation of `ftinit', hence the */
+ /* function FT_Init_FreeType */
+ /* */
+#undef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
+
+
+ /*************************************************************************/
+ /* */
+ /* The size in bytes of the render pool used by the scan-line */
+ /* converter to do all of its work. */
+ /* */
+ /* This must be greater than 4 Kb */
+ /* */
+#define FT_RENDER_POOL_SIZE 32768
+
+
+ /*************************************************************************/
+ /* */
+ /* FT_MAX_DRIVERS */
+ /* */
+ /* The maximum number of font drivers that can be registered in a */
+ /* single FreeType library object. 8 seems to be a good choice due */
+ /* to the relative low actual number of drivers ;-) */
+ /* */
+#define FT_MAX_DRIVERS 8
+
+
+ /*************************************************************************/
+ /* */
+ /* FT_MAX_GLYPH_FORMATS */
+ /* */
+ /* The maximum number of glyph image formats that might be registered */
+ /* in a given library instance. 8 seems to be a good choice due to */
+ /* the relatively low number of current formats ;-) */
+ /* */
+
+#define FT_MAX_GLYPH_FORMATS 8
+
+
+
+#endif /* FTOPTION_H */
--- /dev/null
+++ b/config/dos/FTSYSTEM.C
@@ -1,0 +1,214 @@
+/**************************************************************************
+ *
+ * ftsystem.h 1.0
+ *
+ * ANSI-specific FreeType low-level system interface
+ *
+ * This file contains the definition of interface used by FreeType
+ * to access low-level, i.e. memory management, i/o access as well
+ * as thread synchronisation.
+ *
+ *
+ * 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 <ftsystem.h>
+#include <fterrors.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+ /*********************************************************************/
+ /* */
+ /* MEMORY MANAGEMENT INTERFACE */
+ /* */
+
+/************************************************************************
+ *
+ * <FuncType>
+ * FT_Alloc_Func
+ *
+ * <Description>
+ * The memory allocator function type
+ *
+ * <Input>
+ * system :: pointer to the system object
+ * size :: requested size in bytes
+ *
+ * <Output>
+ * block :: address of newly allocated block
+ *
+ * <Return>
+ * Error code. 0 means success.
+ *
+ * <Note>
+ * If your allocation routine ALWAYS zeroes the new block, you
+ * should set the flag FT_SYSTEM_FLAG_ALLOC_ZEROES in your system
+ * object 'flags' field.
+ *
+ * If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ * your system's "system_flags" field, this function should update
+ * the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+ static
+ void* ft_alloc( FT_Memory memory,
+ long size )
+ {
+ (void)memory;
+ return malloc(size);
+ }
+
+
+/************************************************************************
+ *
+ * <FuncType>
+ * FT_Realloc_Func
+ *
+ * <Description>
+ * The memory reallocator function type
+ *
+ * <Input>
+ * system :: pointer to the system object
+ * new_size :: new requested size in bytes
+ *
+ * <InOut>
+ * block :: address of block in memory
+ *
+ * <Return>
+ * Error code. 0 means success.
+ *
+ * <Note>
+ * This function is _never_ called when the system flag
+ * FT_SYSTEM_FLAG_NO_REALLOC is set. Instead, the engine will emulate
+ * realloc through "alloc" and "free".
+ *
+ * Note that this is possible due to the fact that FreeType's
+ * "FT_Realloc" always requests the _current_ size of the reallocated
+ * block as a parameter, thus avoiding memory leaks.
+ *
+ * If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ * your system's "system_flags" field, this function should update
+ * the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+ static
+ void* ft_realloc( FT_Memory memory,
+ long cur_size,
+ long new_size,
+ void* block )
+ {
+ (void)memory;
+ (void)cur_size;
+
+ return realloc( block, new_size );
+ }
+
+
+/************************************************************************
+ *
+ * <FuncType>
+ * FT_Free_Func
+ *
+ * <Description>
+ * The memory release function type
+ *
+ * <Input>
+ * system :: pointer to the system object
+ * block :: address of block in memory
+ *
+ * <Note>
+ * If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ * your system's "system_flags" field, this function should update
+ * the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+ static
+ void ft_free( FT_Memory memory,
+ void* block )
+ {
+ (void)memory;
+ free( block );
+ }
+
+ /*********************************************************************/
+ /* */
+ /* RESOURCE MANAGEMENT INTERFACE */
+ /* */
+
+
+#define STREAM_FILE(stream) ((FILE*)stream->descriptor.pointer)
+
+ static
+ void ft_close_stream( FT_Stream stream )
+ {
+ fclose( STREAM_FILE(stream) );
+ }
+
+ static
+ unsigned long ft_io_stream( FT_Stream stream,
+ unsigned long offset,
+ char* buffer,
+ unsigned long count )
+ {
+ FILE* file;
+
+ file = STREAM_FILE(stream);
+
+ fseek( file, offset, SEEK_SET );
+ return (unsigned long)fread( buffer, count, 1, file );
+ }
+
+
+ extern
+ int FT_New_Stream( const char* filepathname,
+ FT_Stream stream )
+ {
+ FILE* file;
+
+ file = fopen( filepathname, "rb" );
+ if (!file)
+ return FT_Err_Cannot_Open_Resource;
+
+ fseek( file, 0, SEEK_END );
+ stream->size = ftell(file);
+ fseek( file, 0, SEEK_SET );
+
+ stream->descriptor.pointer = file;
+ stream->pos = 0;
+
+ stream->read = ft_io_stream;
+ stream->close = ft_close_stream;
+
+ return 0;
+ }
+
+
+ extern
+ FT_Memory FT_New_Memory( void )
+ {
+ FT_Memory memory;
+
+ memory = (FT_Memory)malloc( sizeof(*memory) );
+ if (memory)
+ {
+ memory->user = 0;
+ memory->alloc = ft_alloc;
+ memory->realloc = ft_realloc;
+ memory->free = ft_free;
+ }
+ return memory;
+ }
+
--- /dev/null
+++ b/config/dos/MAKEFILE.GCC
@@ -1,0 +1,172 @@
+#*******************************************************************
+#*
+#* FreeType 2 Configuration rules for Unix + gcc
+#*
+#* 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 purpose of this sub-Makefile is to define various build and
+#* platform specific variables before including the sub-Makefile
+#* containing the FreeType library rules, found in
+#*
+#* $(TOP)/config/freetype.mk
+#*
+#* The following variables must be defined before including this
+#* file :
+#*
+#* TOP Pathname to the top of the FreeType sources
+#* hierarchy
+#*
+#* This file should define the following variables before including
+#* the FreeType library rules file :
+#*
+#* BUILD Pathname to the platform-specific files used
+#* for the build. Usually `$(TOP)/config/<system>'
+#*
+#* SEP Directory separator for the current platform.
+#* Either / or \ (maybe : on Macs)
+#*
+#* DELETE The forced remove/delete command to erase one or more
+#* files
+#*
+#* INCLUDE The location of all public header files. e.g.
+#* `$(TOP)/include'include' *
+#*
+#* SRC The directory containing all sources. e.g.
+#* '$(TOP)/src'
+#*
+#* OBJ_DIR The location where compiled object files will be
+#* placed, e.g. '$(TOP)/obj'
+#*
+#* LIB_DIR The location where the resulting library file will be
+#* placed, e.g. '$(TOP)/obj'
+#*
+#* LIBRARY The filename of the resulting library file, without
+#* its extension.. e.g. 'libfreetype' or 'freetype'
+#*
+#* O The object file suffix. Can be '.o', '.obj,' '.lo,'
+#* ';coff,' etc.
+#*
+#* A The library file suffix. Can be '.a' '.so,' '.lib'
+#* '.dll,' etc.
+#*
+#* I The path inclusion flag. Some compilers use a
+#* different flag than '-I' to specify an additional
+#* include path. Examples are '/i=' or '-J ', etc.
+#*
+#* D The macro definition flag. I haven't met compilers
+#* which don't use the '-D' switch to define a macro, but
+#* who knows...
+#*
+#* T The compilation flag used to identify the target. Some
+#* compilers use a different flag than '-o ' to specify
+#* the name of the target object file.
+#*
+#* CFLAGS The set of flags used to compile object files.
+#* (usually contains the flag '-c').
+#*
+#*
+#*
+#*******************************************************************
+
+ifndef TOP
+TOP := .
+endif
+
+DELETE := rm -f
+SEP := /
+BUILD := $(TOP)/config/dos
+PLATFORM := dos
+
+# the directory where all object files are placed
+#
+OBJ_DIR := $(TOP)/obj
+
+
+# the directory where all library files are placed
+#
+# by default, this is the same as OBJ_DIR, however, this can be
+# changed to suit particular needs..
+#
+LIB_DIR := $(OBJ_DIR)
+
+
+# the object file extension, this can be .o, .tco, .obj, etc..
+# depending on the platform
+#
+O := o
+
+# the library file extension, this can be .a, .lib, etc..
+# depending on the platform
+#
+A := a
+
+
+# The name of the final library file.
+# Note that the DOS-specific Makefile uses a shorter (8.3) name
+#
+LIBRARY := libfreetype
+
+
+# path inclusion flag.
+#
+# Some compilers use a different flag than '-I' to specify an
+# additional include path. Examples are "/i=" or "-J", etc...
+#
+I := -I
+
+
+# The link flag used to specify a given library file on link.
+# Note that this is only used to compile the demo programs, not
+# the library itself.
+#
+L := -l
+
+
+# C flag used to define a macro before the compilation of a given
+# source object. Usually is '-D' like in "-DDEBUG"
+#
+D := -D
+
+
+# Target flag - beware, there is a space after the 'o' !!
+#
+#
+T := -o
+
+# C flags
+#
+# These should concern :
+#
+# - debug output
+# - optimization
+# - warnings
+# - ansi compliance..
+#
+ifndef CFLAGS
+CFLAGS := -c -g -O6 -Wall
+endif
+
+ifdef BUILD_FREETYPE
+
+include $(TOP)/config/freetype.mk
+
+
+# This final rule is used to link all object files into a single
+# library. It is part of the system-specific sub-Makefile because not
+# all librarians accept a simple syntax like :
+#
+# librarian library_file {list of object files}
+#
+$(FT_LIBRARY): $(OBJECTS_LIST)
+ -$(DELETE) $@
+ $(AR) -r $@ $(OBJECTS_LIST)
+
+endif
--- /dev/null
+++ b/config/dos/detect.mk
@@ -1,0 +1,87 @@
+#
+# This file is used to detect a DOS host platform.
+#
+# This configuration file to be used depends on the value of the CC
+# environment variable.
+#
+#
+
+# We test for the COMSPEC environment variable, then run the 'ver'
+# command-line program to see if its output contains the word "Dos"
+#
+# If this is true, we're running a Dos-ish platform (or an emulation)
+#
+
+ifeq ($(PLATFORM),ansi)
+
+ifdef COMSPEC
+
+is_dos := $(findstring Dos,$(shell ver))
+
+# We try to recognize a Dos session under OS/2. The "ver" command
+# returns 'Operating System/2 ...' there so 'is_dos' should be empty
+# there.
+#
+# To recognize a Dos session under OS/2, we check COMSPEC for the
+# substring "MDOS\COMMAND"
+#
+ifeq ($(is_dos),)
+is_dos := $(findstring MDOS\COMMAND,$(COMSPEC))
+endif
+
+ifneq ($(is_dos),)
+
+PLATFORM := dos
+DELETE := del
+COPY := copy
+
+#####################################################################
+#
+# Use gcc, i.e. DJGPP by default. Aren't we biased ;-)
+#
+#
+CONFIG_FILE := Makefile.gcc
+SEP := /
+ifndef CC
+CC := gcc
+endif
+
+
+ifneq ($(findstring turboc,$(MAKECMDGOALS)),) # Turbo C
+CONFIG_FILE := Makefile.tcc
+SEP := $(BACKSLASH)
+CC := tcc
+.PHONY: turboc
+endif
+
+ifneq ($(findstring watcom,$(MAKECMDGOALS)),) # Watcom C/C++
+CONFIG_FILE := Makefile.wat
+SEP := $(BACKSLASH)
+CC := wcc386
+.PHONY: watcom
+endif
+
+ifneq ($(findstring borlandc16,$(MAKECMDGOALS)),) # Borland C/C++ 16 bits
+CONFIG_FILE := Makefile.bcc
+SEP := $(BACKSLASH)
+CC := bcc
+.PHONY: borlandc16
+endif
+
+ifneq ($(findstring borlandc,$(MAKECMDGOALS)),) # Borland C/C++ 32 bits
+CONFIG_FILE := Makefile.bcc
+SEP := $(BACKSLASH)
+CC := bcc32
+.PHONY: borlandc
+endif
+
+CONFIG_RULES := $(TOP)\config\dos\$(CONFIG_FILE)
+
+# use the Dos version of the "setup dump"
+#
+setup: dos_setup
+
+endif # test Dos
+endif # test COMSPEC
+endif # test PLATFORM
+
--- /dev/null
+++ b/config/dos/ftoption.h
@@ -1,0 +1,162 @@
+#ifndef FTOPTION_H
+#define FTOPTION_H
+
+ /*************************************************************************/
+ /* */
+ /* USER-SELECTABLE CONFIGURATION MACROS */
+ /* */
+ /* These macros can be toggled by developers to enable or disable */
+ /* certain aspects of FreeType. This file contains macros that apply to */
+ /* all of FreeType. Driver-specific configurations are placed in each */
+ /* driver directory (e.g. `freetype/drivers/ttlib/ttconfig.h'). */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* Alternate Glyph Image Format support */
+ /* */
+ /* By default, the glyph images returned by the FreeType glyph loader */
+ /* can either be a pixmap or a vectorial outline defined through */
+ /* bezier control points. When defining the following configuration */
+ /* macro, some font drivers will be able to register alternate */
+ /* glyph image formats. */
+ /* */
+ /* Unset this macro if you're sure that you'll never use a font driver */
+ /* with an alternate glyph format, this will reduce the size of the */
+ /* base layer code. */
+ /* */
+#define FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS
+
+ /*************************************************************************/
+ /* */
+ /* GCC provides the non-ANSI `long long' 64-bit type. You can activate */
+ /* it by defining the FTCALC_USE_LONG_LONG macro here. Note however */
+ /* that we did not experience any improvement in speed with gcc, and */
+ /* that the final code seems bigger when linked. */
+ /* */
+#undef FTCALC_USE_LONG_LONG
+
+
+ /*************************************************************************/
+ /* */
+ /* When compiling FreeType as a DLL, some systems/compilers need a */
+ /* special keyword in front of each function definition instead of */
+ /* `extern'. */
+ /* */
+ /* The macros EXPORT_DEF and EXPORT_FUNC are thus used to define */
+ /* exported library function interfaces and exported library functions */
+ /* implementations respectively. */
+ /* */
+ /* If not defined here, they automatically default to `extern' and void */
+ /* later in this header file. */
+ /* */
+#undef EXPORT_DEF
+#undef EXPORT_FUNC
+
+
+ /*************************************************************************/
+ /* */
+ /* Debug level */
+ /* */
+ /* FreeType can be compiled in debug or trace mode. In debug mode, */
+ /* errors are reported through the `ftdebug' component. In trace */
+ /* mode, additional messages are sent to the standard output during */
+ /* execution. */
+ /* */
+ /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */
+ /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */
+ /* */
+ /* Don't define any of these macros to compile in `release' mode. */
+ /* */
+#undef FT_DEBUG_LEVEL_ERROR
+#undef FT_DEBUG_LEVEL_TRACE
+
+
+ /*************************************************************************/
+ /* */
+ /* Anti-aliasing support */
+ /* */
+ /* Undefine this macro only if you want to disable the anti-aliasing */
+ /* support in FreeType. This will save you about 5 Kb of code. It */
+ /* may be important for some embedded systems. */
+ /* */
+#define FT_CONFIG_OPTION_ANTI_ALIAS
+
+
+ /*************************************************************************/
+ /* */
+ /* Endianess performance improvement */
+ /* */
+ /* FreeType is completely endian-independent, and can thus be compiled */
+ /* directly on _any_ machine. However, some components of the library */
+ /* provide improved routines for the cases where endianess is known. */
+ /* */
+ /* It usually results in speed-ups and reduced code size. Note that */
+ /* you should not define both of these macros. */
+ /* */
+ /* */
+ /* NOTE: For now, only the scan-line converter (base/ftraster.c) uses */
+ /* these macros to speed-up some anti-alias rendering routines. */
+ /* */
+#undef FT_CONFIG_OPTION_LITTLE_ENDIAN
+#undef FT_CONFIG_OPTION_BIG_ENDIAN
+
+
+ /*************************************************************************/
+ /* */
+ /* Define this configuration macro whenever you want to build a version */
+ /* of FreeType that does not include a default `system' component. */
+ /* */
+ /* Note that this will prevent the compilation of `ftinit', hence the */
+ /* function FT_Init_FreeType */
+ /* */
+#undef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
+
+
+ /*************************************************************************/
+ /* */
+ /* The size in bytes of the render pool used by the scan-line */
+ /* converter to do all of its work. */
+ /* */
+ /* This must be greater than 4 Kb */
+ /* */
+#define FT_RENDER_POOL_SIZE 32768
+
+
+ /*************************************************************************/
+ /* */
+ /* FT_MAX_DRIVERS */
+ /* */
+ /* The maximum number of font drivers that can be registered in a */
+ /* single FreeType library object. 8 seems to be a good choice due */
+ /* to the relative low actual number of drivers ;-) */
+ /* */
+#define FT_MAX_DRIVERS 8
+
+
+ /*************************************************************************/
+ /* */
+ /* FT_MAX_EXTENSIONS */
+ /* */
+ /* The maximum number of extensions that can be registered in a */
+ /* single font driver. 8 seems to be a good choice for now.. */
+ /* */
+#define FT_MAX_EXTENSIONS 8
+
+
+ /*************************************************************************/
+ /* */
+ /* FT_MAX_GLYPH_FORMATS */
+ /* */
+ /* The maximum number of glyph image formats that might be registered */
+ /* in a given library instance. 8 seems to be a good choice due to */
+ /* the relatively low number of current formats ;-) */
+ /* */
+
+#define FT_MAX_GLYPH_FORMATS 8
+
+
+
+#endif /* FTOPTION_H */
--- /dev/null
+++ b/config/dos/ftsys.c
@@ -1,0 +1,866 @@
+/*******************************************************************
+ *
+ * ftsys.c
+ *
+ * ANSI-specific system operations.
+ *
+ * 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 implementation of the 'ftsys' component uses the standard
+ * ANSI C library.
+ *
+ * IMPORTANT NOTE :
+ *
+ * Porters, read carefully the comments in ftsys.h before trying
+ * to port this file to your system. It contains many essential
+ * remarks, and will ease your work greatly..
+ *
+ ******************************************************************/
+
+#include "ftsys.h"
+#include "ftstream.h"
+#include "ftdebug.h"
+
+
+/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+/* parameter of the PTRACE and PERROR macros, used to print/log */
+/* messages during execution.. */
+/* */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_io
+
+
+#undef CUR_SYSTEM /* just in case */
+
+
+/* To ease porting, we use the macro SYS_STREAM to name the system-specific */
+/* stream type. For example, it is a "FILE*" with the ANSI libc, it will be */
+/* a file descriptor, i.e. an integer, when using the Unix system api, etc. */
+
+#define SYS_STREAM FILE*
+
+
+ /* This implementation of ftsys uses the ANSI C library. Memory */
+ /* management is performed through malloc/free, i/o access through */
+ /* fopen/fread/fseek, and no synchronisation primitive is implemented */
+ /* (they contain dummy code) */
+
+
+
+/**************************************************************************/
+/* */
+/* I/O ACCESS AND MANAGEMENT */
+/* */
+/* We only define the "ANSI" resource class in this class. It is */
+/* disk-based, and provides a MRU cache, in order to only keep the file */
+/* descriptors of the 10 most recently used resource files. */
+/* */
+/* it simply contains two lists. One contains the "cached" resources */
+/* with a valid FILE* pointer, the second contains all other "flushed" */
+/* resource objects. */
+/* */
+
+/* The FT_ANSI_File class derives from FT_ResourceRec - description : */
+/* */
+/* <Struct> FT_AnsiFileRec */
+/* */
+/* <Fields> */
+/* */
+/* root :: */
+/* the root resource class fields. */
+/* */
+/* pathname :: */
+/* this is a copy of the ANSI file pathname used to open streams */
+/* for the resource. A different implementation is free to use */
+/* unicode chars, or file i-node numbers, etc.. */
+/* */
+/* file_size :: */
+/* the size in bytes of the resource. This field should be set to */
+/* -1 until the resource is first opened.. */
+/* */
+
+#include <stdio.h>
+
+ typedef struct FT_AnsiFileRec_
+ {
+ FT_ResourceRec root;
+ char* pathname; /* the font file's pathname */
+ FT_Long file_size; /* file size in bytes */
+
+ } FT_AnsiFileRec, *FT_AnsiFile;
+
+
+/* We use the macro STREAM_Name as a convenience to return a given */
+/* ANSI resource's pathname. Its "stream" argument is a FT_Resource */
+/* which is typecasted to the FT_AnsiFile class */
+#define STREAM_Name(stream) ((FT_AnsiFile)stream->resource)->pathname
+
+/* We use the macro STREAM_File as a convenience to extract the */
+/* system-specific stream handle from a given FreeType stream object */
+#define STREAM_File(stream) ((FILE*)stream->stream_id.pointer)
+
+
+
+/***************************************************************************/
+/* */
+/* <Function> AnsiFile_Open */
+/* */
+/* <Description> */
+/* This function is used to open a system-stream for a given resource. */
+/* */
+/* Note that it must update the target FreeType stream object with the */
+/* system-stream handle and the resource's size. */
+/* */
+/* Also, the 'stream->base' field must be set to NULL for disk-based */
+/* resource, and to the address in memory of the resource's first byte */
+/* for a memory-based one. */
+/* */
+/* <Input> */
+/* resource :: the source resource */
+/* stream :: the target stream object */
+/* */
+/* <Return> */
+/* Error code */
+/* */
+/* <Note> */
+/* This function simply calls fopen in the resource's file pathname */
+/* */
+/* The stream object IS NOT CREATED by this function, but by its caller. */
+/* */
+/***************************************************************************/
+
+ static
+ FT_Error AnsiFile_Open( FT_AnsiFile resource,
+ FT_Stream stream )
+ {
+ FILE* file;
+
+ /* open the file */
+ file = fopen( resource->pathname, "rb" );
+ if (!file)
+ {
+ PERROR(( "AnsiFile_Open: could not open file '%s'\n",
+ resource->pathname ));
+ return FT_Err_Cannot_Open_Stream;
+ }
+
+ /* compute file size if necessary */
+ if ( resource->file_size < 0 )
+ {
+ fseek( file, 0, SEEK_END );
+ resource->file_size = ftell(file);
+ fseek( file, 0, SEEK_SET );
+ }
+
+ stream->resource = (FT_Resource)resource;
+ stream->stream_id.pointer = file;
+ stream->size = resource->file_size;
+
+ /* it's a disk-based resource, we don't need to use the "base" and */
+ /* "cursor" fields of the stream objects */
+ stream->base = NULL;
+ stream->cursor = NULL;
+
+ PTRACE1(( "AnsiFile_Open: opened '%s' (%d bytes) succesfully\n",
+ resource->pathname, resource->file_size ));
+
+ return FT_Err_Ok;
+ }
+
+
+/***************************************************************************/
+/* */
+/* <Function> AnsiFile_Close */
+/* */
+/* <Description> Closes a given stream */
+/* */
+/* <Input> */
+/* stream :: the target stream object */
+/* */
+/* <Return> */
+/* Error code */
+/* */
+/* <Note> */
+/* This function simply calls fclose on the stream's ANSI FILE object */
+/* */
+/***************************************************************************/
+
+ static
+ FT_Error AnsiFile_Close( FT_Stream stream )
+ {
+ PTRACE1(( "Closing file '%s'\n", STREAM_Name(stream) ));
+
+ fclose( STREAM_File(stream) );
+
+ stream->resource = NULL;
+ stream->stream_id.pointer = NULL;
+ stream->size = 0;
+
+ return FT_Err_Ok;
+ }
+
+
+/***************************************************************************/
+/* */
+/* <Function> AnsiFile_Seek */
+/* */
+/* <Description> Seek a stream to a given position */
+/* */
+/* <Input> */
+/* stream :: the target stream object */
+/* position :: offset in bytes from start of resource/stream */
+/* */
+/* <Return> */
+/* Error code */
+/* */
+/* <Note> */
+/* This function simply calls fseek on the stream. */
+/* */
+/* The "seek" method is never called by the stream manager in the case */
+/* of a memory-based resource (i.e. when 'stream->base' isn't NULL). */
+/* */
+/***************************************************************************/
+
+ static
+ FT_Error AnsiFile_Seek( FT_Stream stream,
+ FT_Long position )
+ {
+ if ( fseek( STREAM_File(stream), position, SEEK_SET ) )
+ {
+ PERROR(( "AnsiFile_Seek : FAILED !! pos. %ld of '%s'\n",
+ position, STREAM_Name(stream) ));
+
+ return FT_Err_Invalid_Stream_Seek;
+ }
+
+ PTRACE2(( "AnsiFile_Seek : pos. %ld of '%s'\n",
+ position, STREAM_Name(stream) ));
+
+ return FT_Err_Ok;
+ }
+
+
+/***************************************************************************/
+/* */
+/* <Function> AnsiFile_Skip */
+/* */
+/* <Description> Skip a given number of bytes in an ANSI stream. */
+/* Useful to skip pad bytes, for example. */
+/* */
+/* <Input> */
+/* stream :: the target stream object */
+/* count :: number of bytes to skip in the stream */
+/* */
+/* <Return> */
+/* Error code */
+/* */
+/* <Note> */
+/* This function simply calls fseek on the stream. */
+/* */
+/* The "skip" method is never called by the stream manager in the case */
+/* of a memory-based resource (i.e. when 'stream->base' isn't NULL). */
+/* */
+/***************************************************************************/
+
+ static
+ FT_Error AnsiFile_Skip( FT_Stream stream,
+ FT_Long count )
+ {
+ if ( fseek( STREAM_File(stream), count, SEEK_CUR ) )
+ {
+ PERROR(( "AnsiFile_Skip : FAILED !! %ld bytes in '%s'\n",
+ count, STREAM_Name(stream) ));
+
+ return FT_Err_Invalid_Stream_Seek;
+ }
+
+ PTRACE2(( "AnsiFile_Skip : %ld bytes in '%s'\n",count,
+ STREAM_Name(stream) ));
+
+ return FT_Err_Ok;
+ }
+
+/***************************************************************************/
+/* */
+/* <Function> AnsiFile_Pos */
+/* */
+/* <Description> Returns the current offset within an ANSI stream's */
+/* resource. */
+/* */
+/* <Input> */
+/* stream :: the target stream object */
+/* */
+/* <Output> */
+/* position :: current offset. -1 in case of error */
+/* */
+/* <Return> */
+/* Error code. */
+/* */
+/* <Note> */
+/* This function simply calls ftell on the stream. */
+/* */
+/* The "pos" method is never called by the stream manager in the case */
+/* of a memory-based resource (i.e. when 'stream->base' isn't NULL). */
+/* */
+/***************************************************************************/
+
+ static
+ FT_Error AnsiFile_Pos( FT_Stream stream,
+ FT_Long* position )
+ {
+ *position = ftell( STREAM_File(stream) );
+ if ( *position == -1 )
+ {
+ PTRACE2(( "AnsiFile_Pos : FAILED !! in '%s'\n", STREAM_Name(stream) ));
+ return FT_Err_Invalid_Stream_Seek;
+ }
+
+ PTRACE2(( "AnsiFile_Pos : for '%s'\n", STREAM_Name(stream) ));
+ return FT_Err_Ok;
+ }
+
+/***************************************************************************/
+/* */
+/* <Function> AnsiFile_Read */
+/* */
+/* <Description> Read a given number of bytes from an ANSI stream into */
+/* memory. */
+/* */
+/* <Input> */
+/* stream :: the target stream object */
+/* buffer :: the target read buffer where data is copied */
+/* size :: number of bytes to read from the stream */
+/* */
+/* <Output> */
+/* read_bytes :: the number of bytes effectively read from the stream */
+/* used in case of error (i.e. FT_Err_Invalid_Stream_Read) */
+/* by some parts of the library.. */
+/* <Return> */
+/* Error code */
+/* */
+/* <Note> */
+/* This function simply calls fread on the stream. */
+/* */
+/* It MUST return the error FT_Err_Invalid_Stream_Read in case of */
+/* an over-read (i.e. reading more bytes from the stream that what */
+/* is left int), as the stream component checks for this specific */
+/* value.. */
+/* */
+/* The "read" method is never called by the stream manager in the case */
+/* of a memory-based resource (i.e. when 'stream->base' isn't NULL). */
+/* */
+/***************************************************************************/
+
+ static
+ FT_Error AnsiFile_Read( FT_Stream stream,
+ FT_Char* buffer,
+ FT_Long size,
+ FT_Long* read_bytes )
+ {
+ *read_bytes = fread( buffer, 1, size, STREAM_File(stream) );
+ if ( *read_bytes != size )
+ {
+ /* Note : we can have an over-read here when called by the */
+ /* function FT_Access_Compressed_Frame. This means */
+ /* that the following message should be a trace, */
+ /* rather than an error for disk-based resources.. */
+ /* */
+ /* the function must set the value of 'read_bytes' */
+ /* even if it returns an error code.. */
+ PTRACE2(( "AnsiFile_Read : FAILED !! read %ld bytes from '%s'\n",
+ size, STREAM_Name(stream) ));
+
+ return FT_Err_Invalid_Stream_Read;
+ }
+
+ PTRACE2(( "AnsiFile_Read : read %ld bytes to buffer 0x%08lx from '%s'\n",
+ size, (long)buffer, STREAM_Name(stream) ));
+ return FT_Err_Ok;
+ }
+
+/* The following table is the "virtual method table" for the 'ANSI */
+/* resource class', which methods are defined above. Its address is */
+/* set in the 'interface' field of all resource objects created by */
+/* the function FT_Create_AnsiFile (see below) */
+
+ static
+ FTRes_InterfaceRec FT_AnsiFile_Interface =
+ {
+ (FTRes_Open_Func) AnsiFile_Open,
+ (FTRes_Close_Func) AnsiFile_Close,
+ (FTRes_Seek_Func) AnsiFile_Seek,
+ (FTRes_Skip_Func) AnsiFile_Skip,
+ (FTRes_Pos_Func) AnsiFile_Pos,
+ (FTRes_Read_Func) AnsiFile_Read,
+ };
+
+
+/***************************************************************************/
+/* */
+/* <Function> FT_Create_Resource */
+/* */
+/* <Description> Creates a new resource object, of class "AnsiFile". */
+/* This function is never called directly by the font */
+/* drivers. Only by the higher-level part of FreeType */
+/* (called the HLib), or client applications */
+/* */
+/* <Input> */
+/* pathname :: the file's pathname, in ASCII */
+/* */
+/* <Return> */
+/* Handle/pointer to the new resource object. NULL in case of error */
+/* */
+/* <Note> */
+/* This functions does not open a stream. It simply copies the */
+/* pathname within a fresh new resource object. */
+/* */
+/***************************************************************************/
+
+ EXPORT_FUNC
+ FT_Error FT_Create_Resource( FT_Library library,
+ const char* pathname,
+ FT_Resource* aresource )
+ {
+ FT_Int len;
+ FT_AnsiFile resource;
+ FT_Error error;
+ FT_System system = library->system;
+
+ if ( !pathname )
+ goto Fail_Null;
+
+ len = strlen(pathname);
+ if (len == 0)
+ goto Fail_Null;
+
+ resource = NULL;
+
+ if ( ALLOC( resource, sizeof(*resource) ) ||
+ ALLOC( resource->pathname, len+1 ) )
+ goto Fail_Memory;
+
+ resource->root.library = library;
+ resource->root.interface = &FT_AnsiFile_Interface;
+ resource->root.flags = FT_RESOURCE_TYPE_DISK_BASED;
+ resource->file_size = -1;
+ strcpy( resource->pathname, pathname );
+
+ PTRACE1(( "Create_AnsiFile : Ansi resource created for '%s'\n",
+ pathname ));
+
+ *aresource = (FT_Resource)resource;
+ return FT_Err_Ok;
+
+ Fail_Null:
+ PERROR(( "Create_AnsiFile : null pathname !!\n" ));
+ return FT_Err_Invalid_Argument;
+
+ Fail_Memory:
+ if (resource)
+ FREE( resource->pathname );
+ FREE( resource );
+ PERROR(( "Create_AnsiFile : not enough memory to create resource !\n" ));
+ return error;
+ }
+
+
+/***************************************************************************/
+/* */
+/* <Function> FT_Destroy_Resource */
+/* */
+/* <Description> Destroys an ANSI resource object. */
+/* This function is never called directly by the font */
+/* drivers. Only by the higher-level part of FreeType */
+/* (called the HLib), or client applications */
+/* */
+/* <Input> */
+/* resource :: the Ansi resource object */
+/* */
+/* <Note> */
+/* This functions does not check that runs or streams are opened for */
+/* the resource (for now, we assume developer intelligence. We'll most */
+/* probably lower our standard later to ease debugging ;-) */
+/* */
+/***************************************************************************/
+
+ EXPORT_FUNC
+ FT_Error FT_Destroy_Resource( FT_Resource resource )
+ {
+ FT_System system = resource->library->system;
+ FT_AnsiFile ansi = (FT_AnsiFile)resource;
+
+ if ( !ansi || ansi->root.interface != &FT_AnsiFile_Interface )
+ {
+ PERROR((
+ "Destroy_AnsiFile : Trying to destroy an invalid resource !!\n" ));
+ return FT_Err_Invalid_Resource_Handle;
+ }
+
+ PTRACE1(( "Destroy_AnsiFile : destroying resource for '%s'\n",
+ ansi->pathname ));
+
+ FREE( ansi->pathname );
+ FREE( ansi );
+
+ return FT_Err_Ok;
+ }
+
+
+
+/**************************************************************************/
+/* */
+/* MEMORY MANAGEMENT */
+/* */
+/* */
+/* This part copies the old FreeType 1.0 and 1.1 memory management */
+/* scheme that was defined in the file "ttmemory.h". One can see that */
+/* */
+/* - a set of macros is defined for the memory operations used */
+/* by the engine ( MEM_Copy, MEM_Move, MEM_Set ). This comes from */
+/* the fact that many compilers are able to inline these ops directly */
+/* within the compiled code, rather than generating a call to the */
+/* C library. However, this obliges us to include the <string.h> */
+/* header file. */
+/* */
+/* If you provide your own memory operations routine, you can get */
+/* rid of the #include <string.h> below. */
+/* */
+/* */
+/* - the FT_Alloc function has several essential properties that */
+/* MUST be retained by each port : */
+/* */
+/* - it returns an error code, NOT the allocated block's base */
+/* address */
+/* */
+/* - it takes the address of a target pointer, where the block's */
+/* base address will be set. if the size is zero, its value */
+/* will be NULL and the function returns successfully */
+/* */
+/* - in case of error, the pointer's value is set to NULL and */
+/* an error code is returned.. */
+/* */
+/* - the new allocated block MUST be zero-filled. This is a strong */
+/* convetion the rest of the engine relies on */
+/* */
+/* */
+/* */
+/* - the FT_Free function has also its essentials : */
+/* */
+/* - it takes the address of a pointer which value is the block's */
+/* base address. This is UNLIKE a standard "free" which takes the */
+/* the block's base directly. */
+/* */
+/* - it accepts succesfully the address of a pointer which value */
+/* is NULL, in which case it simply returns. */
+/* */
+/* - the pointer is always set to NULL by the function */
+/* */
+/* */
+/* - the MEM_Alloc, ALLOC and ALLOC_ARRAY macros are used by the */
+/* library, and should NOT be modified by porters !! */
+/* */
+
+/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+/* parameter of the PTRACE and PERROR macros, used to print/log */
+/* messages during execution.. */
+/* */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_memory
+
+
+#include <stdlib.h>
+
+/**************************************************************************/
+/* */
+/* <Function> FT_Alloc */
+/* */
+/* <Description> */
+/* Allocates a new bloc of memory. The returned area is always */
+/* zero-filled, this is a strong convention in many FreeType parts */
+/* */
+/* <Input> */
+/* system :: handle to a given 'system object' where allocation */
+/* occurs.. */
+/* */
+/* size :: size in bytes of the block to allocate */
+/* */
+/* <Output> */
+/* P :: pointer to the fresh new block. It should be set */
+/* to NULL if 'size' is 0, of in case of error.. */
+/* */
+/* <Return> */
+/* FreeType error code. 0 means success. */
+/* */
+/**************************************************************************/
+
+ BASE_FUNC
+ FT_Error FT_Alloc( FT_System system,
+ long size,
+ void* *P )
+ {
+
+ if (!P)
+ {
+ PERROR(( "FT_Alloc : invalid pointer address !!\n" ));
+ return FT_Err_Invalid_Argument;
+ }
+
+ if ( size > 0 )
+ {
+ *P = malloc( size );
+ if ( !*P )
+ {
+ PERROR(( "FT_Alloc : out of memory (%ld bytes requested) !!\n",
+ size ));
+
+ return FT_Err_Out_Of_Memory;
+ }
+
+ system->total_alloc += size;
+
+ /* ALWAYS ZERO-FILL THE BLOCK !!!!! */
+ MEM_Set( *P, 0, size );
+ }
+ else
+ *P = NULL;
+
+ PTRACE2(( "FT_Alloc : size = %ld, pointer = 0x%08lx, block = 0x%08lx\n",
+ size, (long)P, (long)*P ));
+
+ return FT_Err_Ok;
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> FT_Realloc */
+/* */
+/* <Description> */
+/* Reallocates a block of memory pointed to by '*P' to 'Size' */
+/* bytes from the hea^, possibly changing '*P'. */
+/* */
+/* <Input> */
+/* system :: handle to a given 'system object' where allocation */
+/* occurs.. */
+/* */
+/* size :: size in bytes of the block to allocate */
+/* */
+/* <InOut> */
+/* P :: pointer to the fresh new block. It should be set */
+/* to NULL if 'size' is 0, of in case of error.. */
+/* */
+/* <Return> */
+/* FreeType error code. 0 means success. */
+/* */
+
+ BASE_FUNC
+ int FT_Realloc( FT_System system,
+ long size,
+ void* *P )
+ {
+ void* Q;
+
+ if (!P)
+ {
+ PERROR(( "FT_Realloc : invalid pointer address !!\n" ));
+ return FT_Err_Invalid_Argument;
+ }
+
+ /* if the original pointer is NULL, call FT_Alloc */
+ if (!*P)
+ return FT_Alloc( system, size, P );
+
+ /* if the new block if zero-sized, clear the current one */
+ if (size <= 0)
+ return FT_Free( system, P );
+
+ Q = (void*)realloc( *P, size );
+ if (!Q)
+ {
+ PERROR(( "FT_Realloc : reallocation failed\n" ));
+ return FT_Err_Out_Of_Memory;
+ }
+
+ *P = Q;
+ return FT_Err_Ok;
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> FT_Free */
+/* */
+/* <Description> */
+/* Releases a given block of memory allocated through FT_Alloc */
+/* */
+/* <Input> */
+/* system :: handle to a given 'system object' where allocation */
+/* occured.. */
+/* */
+/* P :: This is the _address_ of a _pointer_ which points to */
+/* the allocated block. It is always set to NULL on exit */
+/* */
+/* <Return> */
+/* FreeType error code. 0 means success. */
+/* */
+/* <Note> */
+/* If P or *P are NULL, this function should return successfuly. This */
+/* is a strong convention within all of FreeType and its drivers.. */
+/* */
+
+ BASE_FUNC
+ FT_Error FT_Free( FT_System system,
+ void* *P )
+ {
+ (void)system; /* unused parameter. Gets rid of warnings */
+
+ PTRACE2(( "FT_Free : freeing pointer 0x%08lx (block 0x%08lx)\n",
+ (long)P, (P ? (long)*P : -1) ));
+
+ if ( !P || !*P )
+ return FT_Err_Ok;
+
+ free( *P );
+ *P = NULL;
+
+ return FT_Err_Ok;
+ }
+
+/**************************************************************************/
+/* */
+/* SYNCHRONIZATION MANAGEMENT */
+/* */
+/* */
+/* This section deals with mutexes. The library can be compiled to */
+/* three distinct thread-support levels ( namely single-threaded, */
+/* thread-safe and re-entrant modes ). */
+/* */
+/* It protects its variables through the MUTEX_Lock and MUTEX_Release */
+/* macros which are void in single-threaded mode. */
+/* */
+/* */
+/* It defines a type-less mutex reference type, "TMutex", that you're */
+/* free to redefine for your system's needs.. */
+/* */
+/* The default implementation of ftsys.c contains only dummy functions */
+/* which always return succesfully. you NEED to specialize them in */
+/* order to port ftsys.c in any multi-threaded environment... */
+/* */
+
+/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+/* parameter of the PTRACE and PERROR macros, used to print/log */
+/* messages during execution.. */
+/* */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_sync
+
+#ifdef FT_CONFIG_THREADS
+
+
+ BASE_FUNC
+ FT_Error FT_Mutex_Create ( FT_System system,
+ TMutex* mutex )
+ {
+ (void)system; /* unused parameter. Gets rid of warnings */
+
+ mutex = (void*)-1;
+ system->num_mutexes++;
+ return FT_Err_Ok;
+ /* Replace this line with your own mutex creation code */
+ }
+
+
+ BASE_FUNC
+ void FT_Mutex_Delete ( FT_System system,
+ TMutex* mutex )
+ {
+ (void)system; /* unused parameter. Gets rid of warnings */
+
+ mutex = (void*)0;
+ system->num_mutexes--;
+ /* Replace this line with your own mutex destruction code */
+ }
+
+ BASE_FUNC
+ void FT_Mutex_Lock ( FT_System system,
+ TMutex* mutex )
+ {
+ /* NOTE: It is legal to call this function with a NULL argument */
+ /* in which case an immediate return is appropriate. */
+ (void)system; /* unused parameter. Gets rid of warnings */
+
+ if ( !mutex )
+ return;
+
+ ; /* Insert your own mutex locking code here */
+ }
+
+
+ void FT_Mutex_Release( FT_System system,
+ TMutex* mutex )
+ {
+ /* NOTE: It is legal to call this function with a NULL argument */
+ /* in which case an immediate return is appropriate */
+ (void)system; /* unused parameter. Gets rid of warnings */
+
+ if ( !mutex )
+ return;
+ ; /* Insert your own mutex release code here */
+ }
+
+#endif /* FT_CONFIG_THREADS */
+
+
+
+
+ EXPORT_FUNC
+ FT_Error FT_New_System( FT_System* system )
+ {
+ *system = (FT_System)malloc( sizeof(**system) );
+ if ( !*system )
+ return FT_Err_Out_Of_Memory;
+
+ /* the ANSI function 'free' is unable to return the number */
+ /* of released bytes. Hence, the 'current_alloc' field of the */
+ /* system object cannot be used */
+
+ (*system)->system_flags = FT_SYSTEM_FLAG_TOTAL_ALLOC |
+ FT_SYSTEM_FLAG_MUTEXES;
+ (*system)->total_alloc = 0;
+ (*system)->num_mutexes = 0;
+
+ /* initialise i/o management (nothing) */
+
+ /* initialise synchronisation (nothing) */
+
+ /* initialise streams */
+
+ return FT_Err_Ok;
+ }
+
+
+
+ EXPORT_FUNC
+ FT_Error FT_Done_System( FT_System system )
+ {
+ /* finalise syncrhonisation (nothing) */
+
+ /* finalise i/o management (nothing) */
+
+ /* finalise memory management */
+ free( system );
+
+ return FT_Err_Ok;
+ }
+
+
+
+
--- /dev/null
+++ b/config/freetype.mk
@@ -1,0 +1,199 @@
+#****************************************************************************
+#* *
+#* FreeType library sub-Makefile *
+#* *
+#* 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. *
+#* *
+#* *
+#* *
+#* DO NOT INVOKE THIS MAKEFILE DIRECTLY. IT IS MEANT TO BE INCLUDED BY *
+#* OTHER MAKEFILES. *
+#* *
+#****************************************************************************
+
+
+# The targets `objects', `library' and `multiple' are defined
+# at the end of this Makefile when all rules have been included..
+#
+.PHONY: build_freetype objects library
+
+# default target - build objects and library
+#
+build_freetype: objects library
+
+# `multi' target - build multiple objects and library
+#
+multi: objects library
+
+
+# The FreeType sources directory.
+#
+SRC := $(TOP)$(SEP)src
+
+
+# The directory where the base layer components are placed.
+# By default, this is 'freetype/src/base'
+#
+BASE_DIR := $(SRC)$(SEP)base
+
+
+# A Few short-cuts in order to avoid typing $(SEP) all the time for
+# the directory separator
+#
+# For example: SRC_ equals to './src/' where '.' is $(TOP)
+#
+#
+SRC_ := $(SRC)$(SEP)
+BASE_ := $(BASE_DIR)$(SEP)
+OBJ_ := $(OBJ_DIR)$(SEP)
+LIB_ := $(LIB_DIR)$(SEP)
+PUBLIC_ := $(TOP)$(SEP)include$(SEP)
+
+# The name of the final library file.
+#
+FT_LIBRARY := $(LIB_DIR)$(SEP)$(LIBRARY).$A
+
+
+# include paths
+#
+# IMPORTANT NOTE: The architecture-dependent directory must ALWAYS be placed
+# in front of the include list. Porters are then able to put
+# their own version of some of the FreeType components in
+# the 'freetype/arch/<system>' directory, as these files
+# will override the default sources.
+#
+INCLUDES := $(BUILD) $(TOP)$(SEP)include $(INCLUDES)
+
+INCLUDE_FLAGS = $(INCLUDES:%=$I%)
+
+
+# C flags used for the compilation of an object file. This must include at
+# least the paths for the 'base' and 'config/<system>' directories,
+# debug/optimization/warning flags + ansi compliance if needed.
+#
+FT_CFLAGS = $(CFLAGS) $(INCLUDE_FLAGS)
+FT_CC = $(CC) $(FT_CFLAGS)
+FT_COMPILE = $(FT_CC)
+
+
+#
+# Free the lists of driver objects
+#
+COMPONENTS_LIST :=
+DRIVERS_LIST :=
+OBJECTS_LIST :=
+
+# free the list of 'ftinit' variables
+#
+FTINIT_DRIVER_PATHS :=
+FTINIT_DRIVER_H :=
+FTINIT_DRIVER_MACROS :=
+
+
+# System-specific component - this must be defined in this Makefile
+# for easy updates
+#
+# BASE_H is defined in src/base/rules.mk and contains the list of all
+# base layer header files.
+#
+FTSYS_SRC = $(BUILD)$(SEP)ftsystem.c
+FTSYS_OBJ = $(OBJ_DIR)$(SEP)ftsystem.$O
+
+OBJECTS_LIST += $(FTSYS_OBJ)
+
+$(FTSYS_OBJ): $(FTSYS_SRC) $(BASE_H)
+ $(FT_COMPILE) $T$@ $<
+
+
+# ftdebug component
+#
+#
+#
+
+FTDEBUG_SRC = $(BASE_)ftdebug.c
+FTDEBUG_OBJ = $(OBJ_)ftdebug.$O
+
+OBJECTS_LIST += $(FTDEBUG_OBJ)
+
+$(FTDEBUG_OBJ): $(FTDEBUG_SRC) $(BASE_H)
+ $(FT_COMPILE) $T$@ $<
+
+
+
+# Define PUBLIC_H as the list of all public header files located in
+# `$(TOP)/include'
+#
+PUBLIC_H := $(wildcard $(PUBLIC_)*.h)
+
+
+# Include all rule files from FreeType components
+#
+#
+include $(wildcard $(SRC)/*/rules.mk)
+
+# FTInit file:
+#
+# The C source 'ftinit.c' contains the FreeType initialisation routines.
+# It is able to automatically register one or more drivers when the API
+# function FT_Init_FreeType() is called.
+#
+# The set of initial drivers is determined by the driver Makefiles
+# includes above. Each driver Makefile updates the FTINIT_xxxx lists
+# which contain additional include paths and macros used to compile the
+# single 'ftapi.c' source.
+#
+FTINIT_SRC := $(BASE_DIR)$(SEP)ftinit.c
+FTINIT_OBJ := $(OBJ_)ftinit.$O
+
+$(FTINIT_OBJ): $(FTINIT_SRC) $(BASE_H) $(FTINIT_DRIVER_H)
+ $(FT_COMPILE) $(FTINIT_DRIVER_PATHS:%=$I%) \
+ $(FTINIT_DRIVER_MACROS:%=$D%) $T$@ $<
+
+
+# All FreeType library objects
+#
+# By default, we include the base layer extensions. These could be
+# ommitted on builds which do not want them.
+#
+OBJ_M = $(BASE_OBJ_M) $(BASE_EXT_OBJ) $(DRV_OBJS_M) \
+ $(FTSYS_OBJ) $(FTINIT_OBJ) $(FTDEBUG_OBJ)
+
+OBJ_S = $(BASE_OBJ_S) $(BASE_EXT_OBJ) $(DRV_OBJS_S) \
+ $(FTSYS_OBJ) $(FTINIT_OBJ) $(FTDEBUG_OBJ)
+
+ifneq ($(findstring multi,$(MAKECMDGOALS)),)
+OBJECTS_LIST += $(OBJ_M)
+else
+OBJECTS_LIST += $(OBJ_S)
+endif
+
+objects: $(OBJECTS_LIST)
+
+library: $(FT_LIBRARY)
+
+.c.$O:
+ $(FT_COMPILE) $T$@ $<
+
+
+clean_freetype:
+ -$(DELETE) $(OBJ_S:/=$(SEP)) $(OBJ_M:/=$(SEP))
+
+
+distclean_freetype: clean_freetype
+ -$(DELETE) $(FT_LIBRARY:/=$(SEP))
+ -$(DELETE) *.orig *~ core *.core
+
+remove_config_mk:
+ -$(DELETE) $(CONFIG_MK:/=$(SEP))
+
+clean: clean_freetype
+distclean: distclean_freetype remove_config_mk
+
+# END
--- /dev/null
+++ b/config/os2/Makefile.emx
@@ -1,0 +1,196 @@
+#*******************************************************************
+#*
+#* FreeType 2 Configuration rules for Unix + gcc
+#*
+#* 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 purpose of this sub-Makefile is to define various build and
+#* platform specific variables before including the sub-Makefile
+#* containing the FreeType library rules, found in
+#*
+#* $(TOP)/config/freetype.mk
+#*
+#* The following variables must be defined before including this
+#* file :
+#*
+#* TOP Pathname to the top of the FreeType sources
+#* hierarchy
+#*
+#* This file should define the following variables before including
+#* the FreeType library rules file :
+#*
+#* BUILD Pathname to the platform-specific files used
+#* for the build. Usually `$(TOP)/config/<system>'
+#*
+#* SEP Directory separator for the current platform.
+#* Either / or \ (maybe : on Macs)
+#*
+#* DELETE The forced remove/delete command to erase one or more
+#* files
+#*
+#* INCLUDE The location of all public header files. e.g.
+#* `$(TOP)/include'include' *
+#*
+#* SRC The directory containing all sources. e.g.
+#* '$(TOP)/src'
+#*
+#* OBJ_DIR The location where compiled object files will be
+#* placed, e.g. '$(TOP)/obj'
+#*
+#* LIB_DIR The location where the resulting library file will be
+#* placed, e.g. '$(TOP)/obj'
+#*
+#* LIBRARY The filename of the resulting library file, without
+#* its extension.. e.g. 'libfreetype' or 'freetype'
+#*
+#* O The object file suffix. Can be '.o', '.obj,' '.lo,'
+#* ';coff,' etc.
+#*
+#* A The library file suffix. Can be '.a' '.so,' '.lib'
+#* '.dll,' etc.
+#*
+#* I The path inclusion flag. Some compilers use a
+#* different flag than '-I' to specify an additional
+#* include path. Examples are '/i=' or '-J ', etc.
+#*
+#* D The macro definition flag. I haven't met compilers
+#* which don't use the '-D' switch to define a macro, but
+#* who knows...
+#*
+#* T The compilation flag used to identify the target. Some
+#* compilers use a different flag than '-o ' to specify
+#* the name of the target object file.
+#*
+#* CFLAGS The set of flags used to compile object files.
+#* (usually contains the flag '-c').
+#*
+#*
+#*
+#*******************************************************************
+
+ifndef TOP
+TOP := .
+endif
+
+DELETE := del
+SEP := /
+BUILD := $(TOP)/config/os2
+PLATFORM := os2
+CC := gcc
+
+# the directory where all object files are placed
+#
+OBJ_DIR := $(TOP)/obj
+
+
+# the directory where all library files are placed
+#
+# by default, this is the same as OBJ_DIR, however, this can be
+# changed to suit particular needs..
+#
+LIB_DIR := $(OBJ_DIR)
+
+
+# the object file extension, this can be .o, .tco, .obj, etc..
+# depending on the platform
+#
+O := o
+
+# the library file extension, this can be .a, .lib, etc..
+# depending on the platform
+#
+A := a
+
+
+# The name of the final library file.
+# Note that the DOS-specific Makefile uses a shorter (8.3) name
+#
+LIBRARY := libfreetype
+
+
+# path inclusion flag.
+#
+# Some compilers use a different flag than '-I' to specify an
+# additional include path. Examples are "/i=" or "-J", etc...
+#
+I := -I
+
+
+# The link flag used to specify a given library file on link.
+# Note that this is only used to compile the demo programs, not
+# the library itself.
+#
+L := -l
+
+
+# C flag used to define a macro before the compilation of a given
+# source object. Usually is '-D' like in "-DDEBUG"
+#
+D := -D
+
+
+# Target flag - beware, there is a space after the 'o' !!
+#
+#
+T := -o
+
+# C flags
+#
+# These should concern :
+#
+# - debug output
+# - optimization
+# - warnings
+# - ansi compliance..
+#
+ifndef CFLAGS
+CFLAGS := -c -g -O6 -Wall
+endif
+
+
+ifdef BUILD_FREETYPE
+
+include $(TOP)/config/freetype.mk
+
+
+# Librarian to use to build the static library
+#
+FT_LIBRARIAN := $(AR) -r
+
+
+# This final rule is used to link all object files into a single
+# library. It is part of the system-specific sub-Makefile because not
+# all librarians accept a simple syntax like :
+#
+# librarian library_file {list of object files}
+#
+$(FT_LIBRARY): $(OBJECTS_LIST)
+ -$(DELETE) $@
+ $(FT_LIBRARIAN) $@ $(OBJECTS_LIST)
+
+
+# Cleaning rules
+#
+DIR_OBJ := $(subst $(SEP),\,$(OBJ_DIR))
+
+clean_freetype_objects:
+ -del $(DIR_OBJ)\*.$O
+
+clean_freetype_lib:
+ -del $(subst $(SEP),\,$(FT_LIBRARY))
+
+clean: clean_freetype_objects
+
+
+
+endif
+
+
--- /dev/null
+++ b/config/os2/detect.mk
@@ -1,0 +1,47 @@
+#
+# This file is used to detect an OS/2 host, and set the build variables
+# accordingly..
+#
+# which Makefile to use based on the value of the CC environment variable.
+#
+# OS/2
+#
+#
+
+ifeq ($(PLATFORM),ansi)
+ifdef OS2_SHELL
+
+PLATFORM := os2
+COPY := copy
+DELETE := del
+
+CONFIG_FILE := Makefile.emx # gcc-emx by default
+SEP := /
+
+ifneq ($(findstring visualage,$(MAKECMDGOALS)),) # Visual Age C++
+CONFIG_FILE := Makefile.icc
+SEP := $(BACKSLASH)
+CC := icc
+.PHONY: visualage
+endif
+
+ifneq ($(findstring watcom,$(MAKECMDGOALS)),) # Watcom C/C++
+CONFIG_FILE := Makefile.wat
+SEP := $(BACKSLASH)
+CC := wcc386
+.PHONY: watcom
+endif
+
+ifneq ($(findstring borlandc,$(MAKECMDGOALS)),) # Borland C++ 32 bits
+CONFIG_FILE := Makefile.bcc
+SEP := $(BACKSLASH)
+CC := bcc32
+.PHONY: borlandc
+endif
+
+CONFIG_RULES := $(TOP)\config\os2\$(CONFIG_FILE)
+
+setup: dos_setup
+
+endif #test OS2_SHELL
+endif #test PLATFORM
--- /dev/null
+++ b/config/os2/ftconfig.h
@@ -1,0 +1,182 @@
+/***************************************************************************/
+/* */
+/* ftconfig.h */
+/* */
+/* ANSI-specific configuration file (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. */
+/* */
+/***************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* This header file contains a number of macro definitions that are used */
+ /* by the rest of the engine. Porters are free to copy this file and */
+ /* adapt it to suit their own system. */
+ /* */
+ /* IMPORTANT NOTE: */
+ /* */
+ /* Porters, read carefully the comments in `ftsys.h' before trying to */
+ /* port this file to your system. It contains many essential */
+ /* remarks, and will ease your work greatly. */
+ /* */
+ /*************************************************************************/
+
+
+#ifndef FTCONFIG_H
+#define FTCONFIG_H
+
+/* Include the header file containing all developer build options */
+#include <ftoption.h>
+
+ /*************************************************************************/
+ /* */
+ /* PLATFORM-SPECIFIC CONFIGURATION MACROS */
+ /* */
+ /* These macros can be toggled to suit a specific system. The current */
+ /* ones are defaults used to compile FreeType in an ANSI C environment */
+ /* (16bit compilers are also supported). Copy this file to your own */
+ /* `freetype/arch/<system>' directory, and edit it to port the engine. */
+ /* */
+ /*************************************************************************/
+
+
+/* Define to empty if the keyword does not work. */
+/* #undef const */
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* We use <limits.h> values to know the sizes of the types. */
+#include <limits.h>
+
+/* The number of bytes in an `int' type. */
+#if UINT_MAX == 0xFFFFFFFF
+#define SIZEOF_INT 4
+#elif UINT_MAX == 0xFFFF
+#define SIZEOF_INT 2
+#elif UINT_MAX > 0xFFFFFFFF && UINT_MAX == 0xFFFFFFFFFFFFFFFF
+#define SIZEOF_INT 8
+#else
+#error "Unsupported number of bytes in `int' type!"
+#endif
+
+/* The number of bytes in a `long' type. */
+#if ULONG_MAX == 0xFFFFFFFF
+#define SIZEOF_LONG 4
+#elif ULONG_MAX > 0xFFFFFFFF && ULONG_MAX == 0xFFFFFFFFFFFFFFFF
+#define SIZEOF_LONG 8
+#else
+#error "Unsupported number of bytes in `long' type!"
+#endif
+
+/* Define if you have the memcpy function. */
+#define HAVE_MEMCPY 1
+
+/* Define if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 0
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 0
+
+
+/* Preferred alignment of data */
+#define FT_ALIGNMENT 8
+
+
+
+ /*************************************************************************/
+ /* */
+ /* AUTOMATIC CONFIGURATION MACROS */
+ /* */
+ /* These macros are computed from the ones defined above. Don't touch */
+ /* their definition, unless you know precisely what you're doing. No */
+ /* porter should need to mess with them. */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* IntN types */
+ /* */
+ /* Used to guarantee the size of some specific integers. */
+ /* */
+ typedef signed short FT_Int16;
+ typedef unsigned short FT_Word16;
+
+#if SIZEOF_INT == 4
+
+ typedef signed int FT_Int32;
+ typedef unsigned int FT_Word32;
+
+#elif SIZEOF_LONG == 4
+
+ typedef signed long FT_Int32;
+ typedef unsigned long FT_Word32;
+
+#else
+#error "no 32bit type found - please check your configuration files"
+#endif
+
+#if SIZEOF_LONG == 8
+
+ /* LONG64 must be defined when a 64-bit type is available */
+#define LONG64
+#define INT64 long
+
+#else
+
+
+ /*************************************************************************/
+ /* */
+ /* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */
+ /* it by defining the FTCALC_USE_LONG_LONG macro in `ftconfig.h'. Note */
+ /* that this will produce many -ansi warnings during library */
+ /* compilation. */
+ /* */
+#ifdef FTCALC_USE_LONG_LONG
+
+#define LONG64
+#define INT64 long long
+
+#endif /* FTCALC_USE_LONG_LONG */
+#endif
+
+
+#ifdef FT_MAKE_OPTION_SINGLE_OBJECT
+#define LOCAL_DEF static
+#define LOCAL_FUNC static
+#else
+#define LOCAL_DEF extern
+#define LOCAL_FUNC /* nothing */
+#endif
+
+#ifdef FT_MAKE_OPTION_SINGLE_LIBRARY_OBJECT
+#define BASE_DEF LOCAL_DEF
+#define BASE_FUNC LOCAL_FUNC
+#else
+#define BASE_DEF extern
+#define BASE_FUNC /* nothing */
+#endif
+
+#ifndef EXPORT_DEF
+#define EXPORT_DEF extern
+#endif
+
+#ifndef EXPORT_FUNC
+#define EXPORT_FUNC /* nothing */
+#endif
+
+#endif /* FTCONFIG_H */
+
+
+/* END */
--- /dev/null
+++ b/config/os2/ftoption.h
@@ -1,0 +1,162 @@
+#ifndef FTOPTION_H
+#define FTOPTION_H
+
+ /*************************************************************************/
+ /* */
+ /* USER-SELECTABLE CONFIGURATION MACROS */
+ /* */
+ /* These macros can be toggled by developers to enable or disable */
+ /* certain aspects of FreeType. This file contains macros that apply to */
+ /* all of FreeType. Driver-specific configurations are placed in each */
+ /* driver directory (e.g. `freetype/drivers/ttlib/ttconfig.h'). */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* Alternate Glyph Image Format support */
+ /* */
+ /* By default, the glyph images returned by the FreeType glyph loader */
+ /* can either be a pixmap or a vectorial outline defined through */
+ /* bezier control points. When defining the following configuration */
+ /* macro, some font drivers will be able to register alternate */
+ /* glyph image formats. */
+ /* */
+ /* Unset this macro if you're sure that you'll never use a font driver */
+ /* with an alternate glyph format, this will reduce the size of the */
+ /* base layer code. */
+ /* */
+#define FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS
+
+ /*************************************************************************/
+ /* */
+ /* GCC provides the non-ANSI `long long' 64-bit type. You can activate */
+ /* it by defining the FTCALC_USE_LONG_LONG macro here. Note however */
+ /* that we did not experience any improvement in speed with gcc, and */
+ /* that the final code seems bigger when linked. */
+ /* */
+#undef FTCALC_USE_LONG_LONG
+
+
+ /*************************************************************************/
+ /* */
+ /* When compiling FreeType as a DLL, some systems/compilers need a */
+ /* special keyword in front of each function definition instead of */
+ /* `extern'. */
+ /* */
+ /* The macros EXPORT_DEF and EXPORT_FUNC are thus used to define */
+ /* exported library function interfaces and exported library functions */
+ /* implementations respectively. */
+ /* */
+ /* If not defined here, they automatically default to `extern' and void */
+ /* later in this header file. */
+ /* */
+#undef EXPORT_DEF
+#undef EXPORT_FUNC
+
+
+ /*************************************************************************/
+ /* */
+ /* Debug level */
+ /* */
+ /* FreeType can be compiled in debug or trace mode. In debug mode, */
+ /* errors are reported through the `ftdebug' component. In trace */
+ /* mode, additional messages are sent to the standard output during */
+ /* execution. */
+ /* */
+ /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */
+ /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */
+ /* */
+ /* Don't define any of these macros to compile in `release' mode. */
+ /* */
+#undef FT_DEBUG_LEVEL_ERROR
+#undef FT_DEBUG_LEVEL_TRACE
+
+
+ /*************************************************************************/
+ /* */
+ /* Anti-aliasing support */
+ /* */
+ /* Undefine this macro only if you want to disable the anti-aliasing */
+ /* support in FreeType. This will save you about 5 Kb of code. It */
+ /* may be important for some embedded systems. */
+ /* */
+#define FT_CONFIG_OPTION_ANTI_ALIAS
+
+
+ /*************************************************************************/
+ /* */
+ /* Endianess performance improvement */
+ /* */
+ /* FreeType is completely endian-independent, and can thus be compiled */
+ /* directly on _any_ machine. However, some components of the library */
+ /* provide improved routines for the cases where endianess is known. */
+ /* */
+ /* It usually results in speed-ups and reduced code size. Note that */
+ /* you should not define both of these macros. */
+ /* */
+ /* */
+ /* NOTE: For now, only the scan-line converter (base/ftraster.c) uses */
+ /* these macros to speed-up some anti-alias rendering routines. */
+ /* */
+#undef FT_CONFIG_OPTION_LITTLE_ENDIAN
+#undef FT_CONFIG_OPTION_BIG_ENDIAN
+
+
+ /*************************************************************************/
+ /* */
+ /* Define this configuration macro whenever you want to build a version */
+ /* of FreeType that does not include a default `system' component. */
+ /* */
+ /* Note that this will prevent the compilation of `ftinit', hence the */
+ /* function FT_Init_FreeType */
+ /* */
+#undef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
+
+
+ /*************************************************************************/
+ /* */
+ /* The size in bytes of the render pool used by the scan-line */
+ /* converter to do all of its work. */
+ /* */
+ /* This must be greater than 4 Kb */
+ /* */
+#define FT_RENDER_POOL_SIZE 32768
+
+
+ /*************************************************************************/
+ /* */
+ /* FT_MAX_DRIVERS */
+ /* */
+ /* The maximum number of font drivers that can be registered in a */
+ /* single FreeType library object. 8 seems to be a good choice due */
+ /* to the relative low actual number of drivers ;-) */
+ /* */
+#define FT_MAX_DRIVERS 8
+
+
+ /*************************************************************************/
+ /* */
+ /* FT_MAX_EXTENSIONS */
+ /* */
+ /* The maximum number of extensions that can be registered in a */
+ /* single font driver. 8 seems to be a good choice for now.. */
+ /* */
+#define FT_MAX_EXTENSIONS 8
+
+
+ /*************************************************************************/
+ /* */
+ /* FT_MAX_GLYPH_FORMATS */
+ /* */
+ /* The maximum number of glyph image formats that might be registered */
+ /* in a given library instance. 8 seems to be a good choice due to */
+ /* the relatively low number of current formats ;-) */
+ /* */
+
+#define FT_MAX_GLYPH_FORMATS 8
+
+
+
+#endif /* FTOPTION_H */
--- /dev/null
+++ b/config/os2/ftsys.c
@@ -1,0 +1,940 @@
+/***************************************************************************/
+/* */
+/* ftsys.c */
+/* */
+/* OS/2-specific system operations (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. */
+/* */
+/***************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* This implementation of the `ftsys' component uses malloc()/free() for */
+ /* memory management, and the OS/2 DosXXXXX() API functionss for file */
+ /* access. */
+ /* */
+ /* IMPORTANT NOTE: */
+ /* */
+ /* Porters, read carefully the comments in ftsys.h before trying to */
+ /* port this file to your system. It contains many essential */
+ /* remarks, and will ease your work greatly. */
+ /* */
+ /*************************************************************************/
+
+
+#include "ftsys.h"
+#include "ftstream.h"
+#include "ftdebug.h"
+
+#include <os2.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+
+ /*************************************************************************/
+ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+ /* parameter of the PTRACE() and PERROR() macros, used to print/log */
+ /* messages during execution. */
+ /* */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_io
+
+
+#undef CUR_SYSTEM /* just in case */
+
+
+ /*************************************************************************/
+ /* */
+ /* To ease porting, we use the macro SYS_STREAM to name the */
+ /* system-specific stream type. For example, it is a `FILE*' with the */
+ /* ANSI libc, it will be a file descriptor, i.e. an integer, when using */
+ /* the Unix system API, etc. */
+ /* */
+#define SYS_STREAM HFILE
+
+
+ /*************************************************************************/
+ /* */
+ /* I/O ACCESS AND MANAGEMENT */
+ /* */
+ /* We only define the `ANSI' resource class in this class. It is */
+ /* disk-based and provides a MRU cache in order to only keep the file */
+ /* descriptors of the 10 most recently used resource files. */
+ /* */
+ /* It simply contains two lists. One contains the `cached' resources */
+ /* with a valid FILE* pointer, the second contains all other `flushed' */
+ /* resource objects. */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* FT_Os2FileRec */
+ /* */
+ /* <Description> */
+ /* The FT_Os2File class derives from FT_ResourceRec. */
+ /* */
+ /* <Fields> */
+ /* root :: The root resource class fields. */
+ /* */
+ /* pathname :: This is a copy of the ANSI file pathname used to open */
+ /* streams for the resource. A different implementation */
+ /* is free to use Unicode chars, or file i-node numbers, */
+ /* etc. */
+ /* */
+ /* file_size :: The size in bytes of the resource. This field should */
+ /* be set to -1 until the resource is first opened. */
+ /* */
+ typedef struct FT_Os2FileRec_
+ {
+ FT_ResourceRec root;
+ char* pathname; /* the font file's pathname */
+ FT_Long file_size; /* file size in bytes */
+
+ } FT_Os2FileRec, *FT_Os2File;
+
+
+ /*************************************************************************/
+ /* */
+ /* We use the macro STREAM_Name() as a convenience to return a given */
+ /* ANSI resource's pathname. Its `stream' argument is a FT_Resource */
+ /* which is typecasted to the FT_Os2File class. */
+ /* */
+#define STREAM_Name( stream ) ((FT_Os2File)stream->resource)->pathname
+
+
+ /*************************************************************************/
+ /* */
+ /* We use the macro STREAM_File() as a convenience to extract the */
+ /* system-specific stream handle from a given FreeType stream object. */
+ /* */
+#define STREAM_File(stream) ((HFILE)stream->stream_id.pointer)
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Os2File_Open */
+ /* */
+ /* <Description> */
+ /* This function is used to open a system-stream for a given */
+ /* resource. */
+ /* */
+ /* Note that it must update the target FreeType stream object with */
+ /* the system-stream handle and the resource's size. */
+ /* */
+ /* Also, the `stream->base' field must be set to NULL for disk-based */
+ /* resources, and to the address in memory of the resource's first */
+ /* byte for memory-based ones. */
+ /* */
+ /* <Input> */
+ /* resource :: The source resource. */
+ /* stream :: The target stream object. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* The stream object IS NOT CREATED by this function, but by its */
+ /* caller. */
+ /* */
+ static
+ FT_Error Os2File_Open( FT_Os2File resource,
+ FT_Stream stream )
+ {
+ HFILE file;
+ ULONG ulAction;
+
+
+ /* open the file */
+#ifdef __EMX__
+ if ( DosOpen( (FT_Byte*)resource->pathname,
+ &file,
+ &ulAction, 0, 0, OPEN_ACTION_OPEN_IF_EXISTS,
+ OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY,
+ NULL ) )
+#else
+ if ( DosOpen( resource->pathname,
+ &file,
+ &ulAction, 0, 0, OPEN_ACTION_OPEN_IF_EXISTS,
+ OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY,
+ NULL ) )
+#endif /* __EMX__ */
+ {
+ PERROR(( "Os2File_Open: Could not open file `%s'\n",
+ resource->pathname ));
+ return FT_Err_Cannot_Open_Stream;
+ }
+
+ /* compute file size if necessary */
+ if ( resource->file_size < 0 )
+ {
+ DosSetFilePtr( file, 0, FILE_END, (ULONG*)&resource->file_size );
+ DosSetFilePtr( file, 0, FILE_BEGIN, &ulAction );
+ }
+
+ stream->resource = (FT_Resource)resource;
+ stream->stream_id.pointer = (void*)file;
+ stream->size = resource->file_size;
+
+ /* it's a disk-based resource, we don't need to use the "base" and */
+ /* "cursor" fields of the stream objects */
+ stream->base = NULL;
+ stream->cursor = NULL;
+
+ PTRACE1(( "Os2File_Open: Opened `%s' (%d bytes) successfully\n",
+ resource->pathname, resource->file_size ));
+
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Os2File_Close */
+ /* */
+ /* <Description> */
+ /* Closes a given stream. */
+ /* */
+ /* <Input> */
+ /* stream :: The target stream object. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ static
+ FT_Error Os2File_Close( FT_Stream stream )
+ {
+ PTRACE1(( "OS2File_Close: Closing file `%s'\n", STREAM_Name( stream ) ));
+
+ DosClose( STREAM_File( stream ) );
+
+ stream->resource = NULL;
+ stream->stream_id.pointer = NULL;
+ stream->size = 0;
+
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Os2File_Seek */
+ /* */
+ /* <Description> */
+ /* Seeks a stream to a given position. */
+ /* */
+ /* <Input> */
+ /* stream :: The target stream object. */
+ /* position :: The offset in bytes from the start of the */
+ /* resource/stream. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* The `seek' method is never called by the stream manager in case */
+ /* of a memory-based resource (i.e., when `stream->base' isn't NULL). */
+ /* */
+ static
+ FT_Error Os2File_Seek( FT_Stream stream,
+ FT_Long position )
+ {
+ ULONG ibActual;
+
+
+ if ( DosSetFilePtr( STREAM_File( stream ), position,
+ FILE_BEGIN, &ibActual ) )
+ {
+ PERROR(( "Os2File_Seek: FAILED! Pos. %ld of `%s'\n",
+ position, STREAM_Name( stream ) ));
+
+ return FT_Err_Invalid_Stream_Seek;
+ }
+
+ PTRACE2(( "Os2File_Seek: Pos. %ld of `%s'\n",
+ position, STREAM_Name( stream ) ));
+
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Os2File_Skip */
+ /* */
+ /* <Description> */
+ /* Skips a given number of bytes in an OS/2 stream. Useful to skip */
+ /* pad bytes, for example. */
+ /* */
+ /* <Input> */
+ /* stream :: The target stream object. */
+ /* count :: The number of bytes to skip in the stream. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* The `skip' method is never called by the stream manager in case */
+ /* of a memory-based resource (i.e., when `stream->base' isn't NULL). */
+ /* */
+ static
+ FT_Error Os2File_Skip( FT_Stream stream,
+ FT_Long count )
+ {
+ ULONG ibActual;
+
+
+ DosSetFilePtr( STREAM_File( stream ), 0, FILE_CURRENT, &ibActual );
+ return Os2File_Seek( stream, ibActual + count );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Os2File_Pos */
+ /* */
+ /* <Description> */
+ /* Returns the current offset within an OS/2 stream's resource. */
+ /* */
+ /* <Input> */
+ /* stream :: The target stream object. */
+ /* */
+ /* <Output> */
+ /* position :: The current offset. -1 in case of error. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* The `pos' method is never called by the stream manager in case */
+ /* of a memory-based resource (i.e., when `stream->base' isn't NULL). */
+ /* */
+ static
+ FT_Error Os2File_Pos( FT_Stream stream,
+ FT_Long* position )
+ {
+ ULONG ibActual;
+
+
+ if ( DosSetFilePtr( STREAM_File( stream ), 0, FILE_CURRENT, &ibActual ) )
+ {
+ PTRACE2(( "Os2File_Pos: FAILED! in `%s'\n", STREAM_Name( stream ) ));
+ return FT_Err_Invalid_Stream_Seek;
+ }
+
+ *position = ibActual;
+
+ PTRACE2(( "Os2File_Pos: For `%s'\n", STREAM_Name( stream ) ));
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Os2File_Read */
+ /* */
+ /* <Description> */
+ /* Reads a given number of bytes from an OS/2 stream into memory. */
+ /* */
+ /* <Input> */
+ /* stream :: The target stream object. */
+ /* buffer :: The target read buffer where data is copied. */
+ /* size :: The number of bytes to read from the stream. */
+ /* */
+ /* <Output> */
+ /* read_bytes :: The number of bytes effectively read from the */
+ /* stream. Used in case of error */
+ /* (i.e. FT_Err_Invalid_Stream_Read) by some parts of */
+ /* the library. */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* It MUST return the error FT_Err_Invalid_Stream_Read in case of */
+ /* an over-read (i.e., reading more bytes from the stream that what */
+ /* is left), as the stream component checks for this specific value. */
+ /* */
+ /* The `read' method is never called by the stream manager in case */
+ /* of a memory-based resource (i.e., when `stream->base' isn't NULL). */
+ /* */
+ static
+ FT_Error Os2File_Read( FT_Stream stream,
+ char* buffer,
+ FT_Long size,
+ FT_Long* read_bytes )
+ {
+ ULONG cbActual;
+
+
+ DosRead( STREAM_File( stream ), buffer, size, &cbActual );
+
+ *read_bytes = cbActual;
+
+ if ( cbActual != (ULONG)size )
+ {
+ /* Note : we can have an over-read here when called by the */
+ /* function FT_Access_Compressed_Frame. This means */
+ /* that the following message should be a trace, */
+ /* rather than an error for disk-based resources.. */
+ /* */
+ /* the function must set the value of 'read_bytes' */
+ /* even if it returns an error code.. */
+ PTRACE2(( "Os2File_Read: FAILED! Read %ld bytes from '%s'\n",
+ size, STREAM_Name( stream ) ));
+
+ return FT_Err_Invalid_Stream_Read;
+ }
+
+ PTRACE2(( "Os2File_Read: Read %ld bytes to buffer 0x%08lx from `%s'\n",
+ size, (long)buffer, STREAM_Name( stream ) ));
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* The following table is the `virtual method table' for the `OS/2 */
+ /* resource class', which methods are defined above. Its address is set */
+ /* in the `interface' field of all resource objects created by the */
+ /* function FT_Create_Os2File() (see below). */
+ /* */
+ static
+ FTRes_InterfaceRec FT_Os2File_Interface =
+ {
+ (FTRes_Open_Func) Os2File_Open,
+ (FTRes_Close_Func) Os2File_Close,
+ (FTRes_Seek_Func) Os2File_Seek,
+ (FTRes_Skip_Func) Os2File_Skip,
+ (FTRes_Pos_Func) Os2File_Pos,
+ (FTRes_Read_Func) Os2File_Read,
+ };
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Create_Resource */
+ /* */
+ /* <Description> */
+ /* Creates a new resource object. This function is called by the */
+ /* FT_New_Resource() function of the base layer. */
+ /* */
+ /* <Input> */
+ /* library :: The input library object. */
+ /* pathname :: The file's pathname as an ASCII string. */
+ /* */
+ /* <Output> */
+ /* aresource :: A handle to new resource object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* This functions does not open a stream. It simply copies the */
+ /* pathname within a fresh new resource object. */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_Create_Resource( FT_Library library,
+ const char* pathname,
+ FT_Resource* aresource )
+ {
+ FT_Int len;
+ FT_Os2File resource;
+ FT_Error error;
+ FT_System system;
+
+
+ if ( !library )
+ return FT_Err_Invalid_Library_Handle;
+
+ system = library->system;
+
+ if ( !pathname )
+ goto Fail_Null;
+
+ len = strlen( pathname );
+ if ( len == 0 )
+ goto Fail_Null;
+
+ resource = NULL;
+
+ if ( ALLOC( resource, sizeof ( *resource ) ) ||
+ ALLOC( resource->pathname, len + 1 ) )
+ goto Fail_Memory;
+
+ resource->root.library = library;
+ resource->root.interface = &FT_Os2File_Interface;
+ resource->root.flags = FT_RESOURCE_TYPE_DISK_BASED;
+ resource->file_size = -1;
+ strcpy( resource->pathname, pathname );
+
+ PTRACE1(( "Create_Os2File: OS/2 resource created for '%s'\n",
+ pathname ));
+
+ *aresource = (FT_Resource)resource;
+ return FT_Err_Ok;
+
+ Fail_Null:
+ PERROR(( "Create_Os2File: Null pathname!\n" ));
+ return FT_Err_Invalid_Argument;
+
+ Fail_Memory:
+ if ( resource )
+ FREE( resource->pathname );
+ FREE( resource );
+ PERROR(( "Create_Os2File: Not enough memory to create resource!\n" ));
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Destroy_Resource */
+ /* */
+ /* <Description> */
+ /* Discards a given resource object explicitly. */
+ /* */
+ /* <Input> */
+ /* resource :: The OS/2 resource object. */
+ /* */
+ /* <Note> */
+ /* This function does not check whether runs or streams are opened */
+ /* for the resource (for now, we assume developer intelligence. */
+ /* We'll most probably lower our standard later to ease debugging :-) */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_Destroy_Resource( FT_Resource resource )
+ {
+ FT_System system = resource->library->system;
+ FT_Os2File ansi = (FT_Os2File)resource;
+
+ if ( !ansi || ansi->root.interface != &FT_Os2File_Interface )
+ {
+ PERROR((
+ "Destroy_Os2File: Trying to destroy an invalid resource!\n" ));
+ return FT_Err_Invalid_Resource_Handle;
+ }
+
+ PTRACE1(( "Destroy_Os2File: Destroying resource for `%s'\n",
+ ansi->pathname ));
+
+ FREE( ansi->pathname );
+ FREE( ansi );
+
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* MEMORY MANAGEMENT */
+ /* */
+ /* */
+ /* This part copies the old FreeType 1.0 and 1.1 memory management */
+ /* scheme that was defined in the file `ttmemory.h'. One can see that */
+ /* */
+ /* - a set of macros is defined for the memory operations used by the */
+ /* engine (MEM_Copy(), MEM_Move(), MEM_Set()). This comes from the */
+ /* fact that many compilers are able to inline these operations */
+ /* directly within the compiled code, rather than generating a call */
+ /* to the C library. However, this obliges us to include the */
+ /* `<string.h>' header file. */
+ /* */
+ /* If you provide your own memory operations, you can get rid of the */
+ /* `#include <string.h>' below. */
+ /* */
+ /* */
+ /* - the FT_Alloc() function has several essential properties that MUST */
+ /* be retained by each port: */
+ /* */
+ /* - It returns an error code, NOT the allocated block's base */
+ /* address. */
+ /* */
+ /* - It takes the address of a target pointer, where the block's base */
+ /* address will be set. If the size is zero, its value will be */
+ /* NULL, and the function returns successfully. */
+ /* */
+ /* - In case of error, the pointer's value is set to NULL and an */
+ /* error code is returned. */
+ /* */
+ /* - The new allocated block MUST be zero-filled. This is a strong */
+ /* convention the rest of the engine relies on. */
+ /* */
+ /* */
+ /* - the FT_Free() function has also its essentials: */
+ /* */
+ /* - It takes the address of a pointer which value is the block's */
+ /* base address. This is UNLIKE a standard `free()' which takes */
+ /* the block's base directly. */
+ /* */
+ /* - It accepts successfully the address of a pointer which value is */
+ /* NULL, in which case it simply returns. */
+ /* */
+ /* - The pointer is always set to NULL by the function. */
+ /* */
+ /* */
+ /* - The MEM_Alloc(), ALLOC(), and ALLOC_ARRAY() macros are used by the */
+ /* library and should NOT be modified by porters! */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+ /* parameter of the PTRACE() and PERROR() macros, used to print/log */
+ /* messages during execution. */
+ /* */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_memory
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Alloc */
+ /* */
+ /* <Description> */
+ /* Allocates a new block of memory. The returned area is always */
+ /* zero-filled, this is a strong convention in many FreeType parts. */
+ /* */
+ /* <Input> */
+ /* system :: A handle to a given `system object' where allocation */
+ /* occurs. */
+ /* */
+ /* size :: The size in bytes of the block to allocate. */
+ /* */
+ /* <Output> */
+ /* P :: A pointer to the fresh new block. It should be set to */
+ /* NULL if `size' is 0, or in case of error. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ BASE_FUNC
+ FT_Error FT_Alloc( FT_System system,
+ FT_Long size,
+ void** P )
+ {
+ if ( !P )
+ {
+ PERROR(( "FT_Alloc: Invalid pointer address!\n" ));
+ return FT_Err_Invalid_Argument;
+ }
+
+ if ( size > 0 )
+ {
+ *P = malloc( size );
+ if ( !*P )
+ {
+ PERROR(( "FT_Alloc: Out of memory (%ld bytes requested)!\n",
+ size ));
+
+ return FT_Err_Out_Of_Memory;
+ }
+
+ system->total_alloc += size;
+
+ /* ALWAYS ZERO-FILL THE BLOCK! */
+ MEM_Set( *P, 0, size );
+ }
+ else
+ *P = NULL;
+
+ PTRACE2(( "FT_Alloc: Size = %ld, pointer = 0x%08lx, block = 0x%08lx\n",
+ size, (long)P, (long)*P ));
+
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Realloc */
+ /* */
+ /* <Description> */
+ /* Reallocates a block of memory pointed to by `*P' to `Size' bytes */
+ /* from the heap, possibly changing `*P'. */
+ /* */
+ /* <Input> */
+ /* system :: A handle to a given `system object' where allocation */
+ /* occurs. */
+ /* */
+ /* size :: The size in bytes of the block to allocate. */
+ /* */
+ /* <InOut> */
+ /* P :: A pointer to the fresh new block. It should be set to */
+ /* NULL if `size' is 0, or in case of error. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ BASE_FUNC
+ FT_Error FT_Realloc( FT_System system,
+ FT_Long size,
+ void** P )
+ {
+ void* Q;
+
+
+ if ( !P )
+ {
+ PERROR(( "FT_Realloc: Invalid pointer address!\n" ));
+ return FT_Err_Invalid_Argument;
+ }
+
+ /* if the original pointer is NULL, call FT_Alloc() */
+ if ( !*P )
+ return FT_Alloc( system, size, P );
+
+ /* if the new block if zero-sized, clear the current one */
+ if ( size <= 0 )
+ return FT_Free( system, P );
+
+ Q = (void*)realloc( *P, size );
+ if ( !Q )
+ {
+ PERROR(( "FT_Realloc: Reallocation failed!\n" ));
+ return FT_Err_Out_Of_Memory;
+ }
+
+ *P = Q;
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Free */
+ /* */
+ /* <Description> */
+ /* Releases a given block of memory allocated through FT_Alloc(). */
+ /* */
+ /* <Input> */
+ /* system :: A handle to a given `system object' where allocation */
+ /* occured. */
+ /* */
+ /* P :: This is the _address_ of a _pointer_ which points to the */
+ /* allocated block. It is always set to NULL on exit. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* If P or *P are NULL, this function should return successfully. */
+ /* This is a strong convention within all of FreeType and its */
+ /* drivers. */
+ /* */
+ BASE_FUNC
+ FT_Error FT_Free( FT_System system,
+ void* *P )
+ {
+ UNUSED( system );
+
+ PTRACE2(( "FT_Free: Freeing pointer 0x%08lx (block 0x%08lx)\n",
+ (long)P, (P ? (long)*P : -1) ));
+
+ if ( !P || !*P )
+ return FT_Err_Ok;
+
+ free( *P );
+ *P = NULL;
+
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SYNCHRONIZATION MANAGEMENT */
+ /* */
+ /* */
+ /* This section deals with mutexes. The library can be compiled to */
+ /* two distinct thread support levels (namely single threaded and */
+ /* re-entrant modes). */
+ /* */
+ /* It protects its variables through the MUTEX_Lock() and */
+ /* MUTEX_Release() macros which are void in single threaded mode. */
+ /* */
+ /* It defines a typeless mutex reference type, `FT_Mutex', that you're */
+ /* free to redefine for your system's needs. */
+ /* */
+ /* The default implementation of ftsys.c contains only dummy functions */
+ /* which always return successfully. You NEED to specialize them in */
+ /* order to port ftsys.c to any multi-threaded environment. */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+ /* parameter of the PTRACE() and PERROR() macros, used to print/log */
+ /* messages during execution. */
+ /* */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_sync
+
+
+#ifdef FT_CONFIG_THREADS
+
+ BASE_FUNC
+ FT_Error FT_Mutex_Create( FT_System system,
+ TMutex* mutex )
+ {
+ UNUSED( system );
+
+ mutex = (void*)-1;
+ system->num_mutexes++;
+
+ /* Insert your own mutex creation code here */
+
+ return FT_Err_Ok;
+ }
+
+
+ BASE_FUNC
+ void FT_Mutex_Delete( FT_System system,
+ TMutex* mutex )
+ {
+ UNUSED( system );
+
+ mutex = (void*)0;
+ system->num_mutexes--;
+
+ /* Insert your own mutex destruction code here */
+ }
+
+
+ BASE_FUNC
+ void FT_Mutex_Lock( FT_System system,
+ TMutex* mutex )
+ {
+ /* NOTE: It is legal to call this function with a NULL argument */
+ /* in which case an immediate return is appropriate. */
+
+ UNUSED( system );
+
+ if ( !mutex )
+ return;
+
+ /* Insert your own mutex locking code here */
+ }
+
+
+ BASE_FUNC
+ void FT_Mutex_Release( FT_System system,
+ TMutex* mutex )
+ {
+ /* NOTE: It is legal to call this function with a NULL argument */
+ /* in which case an immediate return is appropriate */
+
+ UNUSED( system );
+
+ if ( !mutex )
+ return;
+
+ /* Insert your own mutex release code here */
+ }
+
+#endif /* FT_CONFIG_THREADS */
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_New_System */
+ /* */
+ /* <Description> */
+ /* This function is used to create and initialize new system objects. */
+ /* These are mainly used to let client applications and font servers */
+ /* specify their own memory allocators and synchronization */
+ /* procedures. */
+ /* */
+ /* <Output> */
+ /* system :: A handle to a given `system object'. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_New_System( FT_System* system )
+ {
+ *system = (FT_System)malloc( sizeof ( **system ) );
+
+ if ( !*system )
+ return FT_Err_Out_Of_Memory;
+
+ /* initialize memory management */
+
+ (*system)->system_flags = FT_SYSTEM_FLAG_TOTAL_ALLOC |
+ FT_SYSTEM_FLAG_MUTEXES;
+ (*system)->total_alloc = 0;
+ (*system)->num_mutexes = 0;
+
+ /* initialize i/o management (nothing) */
+
+ /* initialize synchronisation (nothing) */
+
+ /* initialize streams (nothing) */
+
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Done_System */
+ /* */
+ /* <Description> */
+ /* Destroys a given FreeType system object. */
+ /* */
+ /* <Input> */
+ /* system :: A handle to a given `system object'. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_Done_System( FT_System system )
+ {
+ /* finalize synchronization (nothing) */
+
+ /* finalize i/o management (nothing) */
+
+ /* finalize memory management */
+
+ free( system );
+
+ return FT_Err_Ok;
+ }
+
+
+/* END */
--- /dev/null
+++ b/config/os2/ftsystem.c
@@ -1,0 +1,214 @@
+/**************************************************************************
+ *
+ * ftsystem.h 1.0
+ *
+ * ANSI-specific FreeType low-level system interface
+ *
+ * This file contains the definition of interface used by FreeType
+ * to access low-level, i.e. memory management, i/o access as well
+ * as thread synchronisation.
+ *
+ *
+ * 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 <ftsystem.h>
+#include <fterrors.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+ /*********************************************************************/
+ /* */
+ /* MEMORY MANAGEMENT INTERFACE */
+ /* */
+
+/************************************************************************
+ *
+ * <FuncType>
+ * FT_Alloc_Func
+ *
+ * <Description>
+ * The memory allocator function type
+ *
+ * <Input>
+ * system :: pointer to the system object
+ * size :: requested size in bytes
+ *
+ * <Output>
+ * block :: address of newly allocated block
+ *
+ * <Return>
+ * Error code. 0 means success.
+ *
+ * <Note>
+ * If your allocation routine ALWAYS zeroes the new block, you
+ * should set the flag FT_SYSTEM_FLAG_ALLOC_ZEROES in your system
+ * object 'flags' field.
+ *
+ * If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ * your system's "system_flags" field, this function should update
+ * the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+ static
+ void* ft_alloc( FT_Memory memory,
+ long size )
+ {
+ (void)memory;
+ return malloc(size);
+ }
+
+
+/************************************************************************
+ *
+ * <FuncType>
+ * FT_Realloc_Func
+ *
+ * <Description>
+ * The memory reallocator function type
+ *
+ * <Input>
+ * system :: pointer to the system object
+ * new_size :: new requested size in bytes
+ *
+ * <InOut>
+ * block :: address of block in memory
+ *
+ * <Return>
+ * Error code. 0 means success.
+ *
+ * <Note>
+ * This function is _never_ called when the system flag
+ * FT_SYSTEM_FLAG_NO_REALLOC is set. Instead, the engine will emulate
+ * realloc through "alloc" and "free".
+ *
+ * Note that this is possible due to the fact that FreeType's
+ * "FT_Realloc" always requests the _current_ size of the reallocated
+ * block as a parameter, thus avoiding memory leaks.
+ *
+ * If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ * your system's "system_flags" field, this function should update
+ * the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+ static
+ void* ft_realloc( FT_Memory memory,
+ long cur_size,
+ long new_size,
+ void* block )
+ {
+ (void)memory;
+ (void)cur_size;
+
+ return realloc( block, new_size );
+ }
+
+
+/************************************************************************
+ *
+ * <FuncType>
+ * FT_Free_Func
+ *
+ * <Description>
+ * The memory release function type
+ *
+ * <Input>
+ * system :: pointer to the system object
+ * block :: address of block in memory
+ *
+ * <Note>
+ * If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ * your system's "system_flags" field, this function should update
+ * the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+ static
+ void ft_free( FT_Memory memory,
+ void* block )
+ {
+ (void)memory;
+ free( block );
+ }
+
+ /*********************************************************************/
+ /* */
+ /* RESOURCE MANAGEMENT INTERFACE */
+ /* */
+
+
+#define STREAM_FILE(stream) ((FILE*)stream->descriptor.pointer)
+
+ static
+ void ft_close_stream( FT_Stream stream )
+ {
+ fclose( STREAM_FILE(stream) );
+ }
+
+ static
+ unsigned long ft_io_stream( FT_Stream stream,
+ unsigned long offset,
+ char* buffer,
+ unsigned long count )
+ {
+ FILE* file;
+
+ file = STREAM_FILE(stream);
+
+ fseek( file, offset, SEEK_SET );
+ return (unsigned long)fread( buffer, count, 1, file );
+ }
+
+
+ extern
+ int FT_New_Stream( const char* filepathname,
+ FT_Stream stream )
+ {
+ FILE* file;
+
+ file = fopen( filepathname, "rb" );
+ if (!file)
+ return FT_Err_Cannot_Open_Resource;
+
+ fseek( file, 0, SEEK_END );
+ stream->size = ftell(file);
+ fseek( file, 0, SEEK_SET );
+
+ stream->descriptor.pointer = file;
+ stream->pos = 0;
+
+ stream->read = ft_io_stream;
+ stream->close = ft_close_stream;
+
+ return 0;
+ }
+
+
+ extern
+ FT_Memory FT_New_Memory( void )
+ {
+ FT_Memory memory;
+
+ memory = (FT_Memory)malloc( sizeof(*memory) );
+ if (memory)
+ {
+ memory->user = 0;
+ memory->alloc = ft_alloc;
+ memory->realloc = ft_realloc;
+ memory->free = ft_free;
+ }
+ return memory;
+ }
+
--- /dev/null
+++ b/config/os2/makefile.devel
@@ -1,0 +1,192 @@
+#*******************************************************************
+#*
+#* FreeType 2 Configuration rules for Unix + gcc
+#*
+#* 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 purpose of this sub-Makefile is to define various build and
+#* platform specific variables before including the sub-Makefile
+#* containing the FreeType library rules, found in
+#*
+#* $(TOP)/config/freetype.mk
+#*
+#* The following variables must be defined before including this
+#* file :
+#*
+#* TOP Pathname to the top of the FreeType sources
+#* hierarchy
+#*
+#* This file should define the following variables before including
+#* the FreeType library rules file :
+#*
+#* BUILD Pathname to the platform-specific files used
+#* for the build. Usually `$(TOP)/config/<system>'
+#*
+#* SEP Directory separator for the current platform.
+#* Either / or \ (maybe : on Macs)
+#*
+#* DELETE The forced remove/delete command to erase one or more
+#* files
+#*
+#* INCLUDE The location of all public header files. e.g.
+#* `$(TOP)/include'include' *
+#*
+#* SRC The directory containing all sources. e.g.
+#* '$(TOP)/src'
+#*
+#* OBJ_DIR The location where compiled object files will be
+#* placed, e.g. '$(TOP)/obj'
+#*
+#* LIB_DIR The location where the resulting library file will be
+#* placed, e.g. '$(TOP)/obj'
+#*
+#* LIBRARY The filename of the resulting library file, without
+#* its extension.. e.g. 'libfreetype' or 'freetype'
+#*
+#* O The object file suffix. Can be '.o', '.obj,' '.lo,'
+#* ';coff,' etc.
+#*
+#* A The library file suffix. Can be '.a' '.so,' '.lib'
+#* '.dll,' etc.
+#*
+#* I The path inclusion flag. Some compilers use a
+#* different flag than '-I' to specify an additional
+#* include path. Examples are '/i=' or '-J ', etc.
+#*
+#* D The macro definition flag. I haven't met compilers
+#* which don't use the '-D' switch to define a macro, but
+#* who knows...
+#*
+#* T The compilation flag used to identify the target. Some
+#* compilers use a different flag than '-o ' to specify
+#* the name of the target object file.
+#*
+#* CFLAGS The set of flags used to compile object files.
+#* (usually contains the flag '-c').
+#*
+#*
+#*
+#*******************************************************************
+
+DELETE := del
+SEP := /
+BUILD := $(TOP)/config/os2
+PLATFORM := os2
+CC := gcc
+
+# the directory where all object files are placed
+#
+OBJ_DIR := $(TOP)/obj
+
+
+# the directory where all library files are placed
+#
+# by default, this is the same as OBJ_DIR, however, this can be
+# changed to suit particular needs..
+#
+LIB_DIR := $(OBJ_DIR)
+
+
+# the object file extension, this can be .o, .tco, .obj, etc..
+# depending on the platform
+#
+O := o
+
+# the library file extension, this can be .a, .lib, etc..
+# depending on the platform
+#
+A := a
+
+
+# The name of the final library file.
+# Note that the DOS-specific Makefile uses a shorter (8.3) name
+#
+LIBRARY := libfreetype
+
+
+# path inclusion flag.
+#
+# Some compilers use a different flag than '-I' to specify an
+# additional include path. Examples are "/i=" or "-J", etc...
+#
+I := -I
+
+
+# The link flag used to specify a given library file on link.
+# Note that this is only used to compile the demo programs, not
+# the library itself.
+#
+L := -L
+
+
+# C flag used to define a macro before the compilation of a given
+# source object. Usually is '-D' like in "-DDEBUG"
+#
+D := -D
+
+
+# Target flag - beware, there is a space after the 'o' !!
+#
+#
+T := -o
+
+# C flags
+#
+# These should concern :
+#
+# - debug output
+# - optimization
+# - warnings
+# - ansi compliance..
+#
+ifndef CFLAGS
+CFLAGS := -c -g -O0 -Wall
+endif
+
+
+ifdef BUILD_FREETYPE
+
+include $(TOP)/config/freetype.mk
+
+
+# Librarian to use to build the static library
+#
+FT_LIBRARIAN := $(AR) -r
+
+
+# This final rule is used to link all object files into a single
+# library. It is part of the system-specific sub-Makefile because not
+# all librarians accept a simple syntax like :
+#
+# librarian library_file {list of object files}
+#
+$(FT_LIBRARY): $(OBJECTS_LIST)
+ -$(DELETE) $@
+ $(FT_LIBRARIAN) $@ $(OBJECTS_LIST)
+
+
+# Cleaning rules
+#
+DIR_OBJ := $(subst $(SEP),\,$(OBJ_DIR))
+
+clean_freetype_objects:
+ -del $(DIR8OBJ)\*.$O
+
+clean_freetype_lib:
+ -del $(FT_LIBRARY)
+
+clean: clean_freetype_objects
+
+
+
+endif
+
+
--- /dev/null
+++ b/config/os2/makefile.gcc
@@ -1,0 +1,190 @@
+#*******************************************************************
+#*
+#* FreeType 2 Configuration rules for Unix + gcc
+#*
+#* 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 purpose of this sub-Makefile is to define various build and
+#* platform specific variables before including the sub-Makefile
+#* containing the FreeType library rules, found in
+#*
+#* $(TOP)/config/freetype.mk
+#*
+#* The following variables must be defined before including this
+#* file :
+#*
+#* TOP Pathname to the top of the FreeType sources
+#* hierarchy
+#*
+#* This file should define the following variables before including
+#* the FreeType library rules file :
+#*
+#* BUILD Pathname to the platform-specific files used
+#* for the build. Usually `$(TOP)/config/<system>'
+#*
+#* SEP Directory separator for the current platform.
+#* Either / or \ (maybe : on Macs)
+#*
+#* DELETE The forced remove/delete command to erase one or more
+#* files
+#*
+#* INCLUDE The location of all public header files. e.g.
+#* `$(TOP)/include'include' *
+#*
+#* SRC The directory containing all sources. e.g.
+#* '$(TOP)/src'
+#*
+#* OBJ_DIR The location where compiled object files will be
+#* placed, e.g. '$(TOP)/obj'
+#*
+#* LIB_DIR The location where the resulting library file will be
+#* placed, e.g. '$(TOP)/obj'
+#*
+#* LIBRARY The filename of the resulting library file, without
+#* its extension.. e.g. 'libfreetype' or 'freetype'
+#*
+#* O The object file suffix. Can be '.o', '.obj,' '.lo,'
+#* ';coff,' etc.
+#*
+#* A The library file suffix. Can be '.a' '.so,' '.lib'
+#* '.dll,' etc.
+#*
+#* I The path inclusion flag. Some compilers use a
+#* different flag than '-I' to specify an additional
+#* include path. Examples are '/i=' or '-J ', etc.
+#*
+#* D The macro definition flag. I haven't met compilers
+#* which don't use the '-D' switch to define a macro, but
+#* who knows...
+#*
+#* T The compilation flag used to identify the target. Some
+#* compilers use a different flag than '-o ' to specify
+#* the name of the target object file.
+#*
+#* CFLAGS The set of flags used to compile object files.
+#* (usually contains the flag '-c').
+#*
+#*
+#*
+#*******************************************************************
+
+DELETE := del
+SEP := /
+BUILD := $(TOP)/config/os2
+PLATFORM := os2
+CC := gcc
+
+# the directory where all object files are placed
+#
+OBJ_DIR := $(TOP)/obj
+
+
+# the directory where all library files are placed
+#
+# by default, this is the same as OBJ_DIR, however, this can be
+# changed to suit particular needs..
+#
+LIB_DIR := $(OBJ_DIR)
+
+
+# the object file extension, this can be .o, .tco, .obj, etc..
+# depending on the platform
+#
+O := o
+
+# the library file extension, this can be .a, .lib, etc..
+# depending on the platform
+#
+A := a
+
+
+# The name of the final library file.
+# Note that the DOS-specific Makefile uses a shorter (8.3) name
+#
+LIBRARY := libfreetype
+
+
+# path inclusion flag.
+#
+# Some compilers use a different flag than '-I' to specify an
+# additional include path. Examples are "/i=" or "-J", etc...
+#
+I := -I
+
+
+# The link flag used to specify a given library file on link.
+# Note that this is only used to compile the demo programs, not
+# the library itself.
+#
+L := -L
+
+
+# C flag used to define a macro before the compilation of a given
+# source object. Usually is '-D' like in "-DDEBUG"
+#
+D := -D
+
+
+# Target flag - beware, there is a space after the 'o' !!
+#
+#
+T := -o
+
+# C flags
+#
+# These should concern :
+#
+# - debug output
+# - optimization
+# - warnings
+# - ansi compliance..
+#
+ifndef CFLAGS
+CFLAGS := -c -g -O0 -Wall
+endif
+
+
+ifdef BUILD_FREETYPE
+
+include $(TOP)/config/freetype.mk
+
+# A rule used to clean all objects from OBJ_DIR
+#
+# The OS/2 command shell does not support very long list of arguments
+# so we're stuck with wildcards
+#
+
+DIR_OBJ := $(subst $(SEP),\,$(OBJ_DIR))
+
+clean_freetype_objects:
+ -del $(DIR8OBJ)\*.$O
+
+clean_freetype_lib:
+ -del $(FT_LIBRARY)
+
+clean: clean_freetype_objects
+
+# Librarian to use to build the static library
+#
+FT_LIBRARIAN := $(AR) -r
+
+# This final rule is used to link all object files into a single
+# library. It is part of the system-specific sub-Makefile because not
+# all librarians accept a simple syntax like :
+#
+# librarian library_file {list of object files}
+#
+$(FT_LIBRARY): $(OBJECTS_LIST)
+ -$(DELETE) $@
+ $(FT_LIBRARIAN) $@ $(OBJECTS_LIST)
+
+endif
+
--- /dev/null
+++ b/config/unix/Makefile
@@ -1,0 +1,172 @@
+#*******************************************************************
+#*
+#* FreeType 2 Configuration rules for Unix + gcc
+#*
+#* 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 purpose of this sub-Makefile is to define various build and
+#* platform specific variables before including the sub-Makefile
+#* containing the FreeType library rules, found in
+#*
+#* $(TOP)/config/freetype.mk
+#*
+#* The following variables must be defined before including this
+#* file :
+#*
+#* TOP Pathname to the top of the FreeType sources
+#* hierarchy
+#*
+#* This file should define the following variables before including
+#* the FreeType library rules file :
+#*
+#* BUILD Pathname to the platform-specific files used
+#* for the build. Usually `$(TOP)/config/<system>'
+#*
+#* SEP Directory separator for the current platform.
+#* Either / or \ (maybe : on Macs)
+#*
+#* DELETE The forced remove/delete command to erase one or more
+#* files
+#*
+#* INCLUDE The location of all public header files. e.g.
+#* `$(TOP)/include'include' *
+#*
+#* SRC The directory containing all sources. e.g.
+#* '$(TOP)/src'
+#*
+#* OBJ_DIR The location where compiled object files will be
+#* placed, e.g. '$(TOP)/obj'
+#*
+#* LIB_DIR The location where the resulting library file will be
+#* placed, e.g. '$(TOP)/obj'
+#*
+#* LIBRARY The filename of the resulting library file, without
+#* its extension.. e.g. 'libfreetype' or 'freetype'
+#*
+#* O The object file suffix. Can be '.o', '.obj,' '.lo,'
+#* ';coff,' etc.
+#*
+#* A The library file suffix. Can be '.a' '.so,' '.lib'
+#* '.dll,' etc.
+#*
+#* I The path inclusion flag. Some compilers use a
+#* different flag than '-I' to specify an additional
+#* include path. Examples are '/i=' or '-J ', etc.
+#*
+#* D The macro definition flag. I haven't met compilers
+#* which don't use the '-D' switch to define a macro, but
+#* who knows...
+#*
+#* T The compilation flag used to identify the target. Some
+#* compilers use a different flag than '-o ' to specify
+#* the name of the target object file.
+#*
+#* CFLAGS The set of flags used to compile object files.
+#* (usually contains the flag '-c').
+#*
+#*
+#*
+#*******************************************************************
+
+ifndef TOP
+TOP := .
+endif
+
+DELETE := rm -f
+SEP := /
+BUILD := $(TOP)/config/unix
+PLATFORM := unix
+
+# the directory where all object files are placed
+#
+OBJ_DIR := $(TOP)/obj
+
+
+# the directory where all library files are placed
+#
+# by default, this is the same as OBJ_DIR, however, this can be
+# changed to suit particular needs..
+#
+LIB_DIR := $(OBJ_DIR)
+
+
+# the object file extension, this can be .o, .tco, .obj, etc..
+# depending on the platform
+#
+O := o
+
+# the library file extension, this can be .a, .lib, etc..
+# depending on the platform
+#
+A := a
+
+
+# The name of the final library file.
+# Note that the DOS-specific Makefile uses a shorter (8.3) name
+#
+LIBRARY := libfreetype
+
+
+# path inclusion flag.
+#
+# Some compilers use a different flag than '-I' to specify an
+# additional include path. Examples are "/i=" or "-J", etc...
+#
+I := -I
+
+
+# The link flag used to specify a given library file on link.
+# Note that this is only used to compile the demo programs, not
+# the library itself.
+#
+L := -l
+
+
+# C flag used to define a macro before the compilation of a given
+# source object. Usually is '-D' like in "-DDEBUG"
+#
+D := -D
+
+
+# Target flag - beware, there is a space after the 'o' !!
+#
+#
+T := -o
+
+# C flags
+#
+# These should concern :
+#
+# - debug output
+# - optimization
+# - warnings
+# - ansi compliance..
+#
+ifndef CFLAGS
+CFLAGS := -c -g -O6 -Wall
+endif
+
+ifdef BUILD_FREETYPE
+
+include $(TOP)/config/freetype.mk
+
+
+# This final rule is used to link all object files into a single
+# library. It is part of the system-specific sub-Makefile because not
+# all librarians accept a simple syntax like :
+#
+# librarian library_file {list of object files}
+#
+$(FT_LIBRARY): $(OBJECTS_LIST)
+ -$(DELETE) $@
+ $(AR) -r $@ $(OBJECTS_LIST)
+
+endif
--- /dev/null
+++ b/config/unix/Makefile.devel
@@ -1,0 +1,172 @@
+#*******************************************************************
+#*
+#* FreeType 2 Configuration rules for Unix + gcc
+#*
+#* 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 purpose of this sub-Makefile is to define various build and
+#* platform specific variables before including the sub-Makefile
+#* containing the FreeType library rules, found in
+#*
+#* $(TOP)/config/freetype.mk
+#*
+#* The following variables must be defined before including this
+#* file :
+#*
+#* TOP Pathname to the top of the FreeType sources
+#* hierarchy
+#*
+#* This file should define the following variables before including
+#* the FreeType library rules file :
+#*
+#* BUILD Pathname to the platform-specific files used
+#* for the build. Usually `$(TOP)/config/<system>'
+#*
+#* SEP Directory separator for the current platform.
+#* Either / or \ (maybe : on Macs)
+#*
+#* DELETE The forced remove/delete command to erase one or more
+#* files
+#*
+#* INCLUDE The location of all public header files. e.g.
+#* `$(TOP)/include'include' *
+#*
+#* SRC The directory containing all sources. e.g.
+#* '$(TOP)/src'
+#*
+#* OBJ_DIR The location where compiled object files will be
+#* placed, e.g. '$(TOP)/obj'
+#*
+#* LIB_DIR The location where the resulting library file will be
+#* placed, e.g. '$(TOP)/obj'
+#*
+#* LIBRARY The filename of the resulting library file, without
+#* its extension.. e.g. 'libfreetype' or 'freetype'
+#*
+#* O The object file suffix. Can be '.o', '.obj,' '.lo,'
+#* ';coff,' etc.
+#*
+#* A The library file suffix. Can be '.a' '.so,' '.lib'
+#* '.dll,' etc.
+#*
+#* I The path inclusion flag. Some compilers use a
+#* different flag than '-I' to specify an additional
+#* include path. Examples are '/i=' or '-J ', etc.
+#*
+#* D The macro definition flag. I haven't met compilers
+#* which don't use the '-D' switch to define a macro, but
+#* who knows...
+#*
+#* T The compilation flag used to identify the target. Some
+#* compilers use a different flag than '-o ' to specify
+#* the name of the target object file.
+#*
+#* CFLAGS The set of flags used to compile object files.
+#* (usually contains the flag '-c').
+#*
+#*
+#*
+#*******************************************************************
+
+ifndef TOP
+TOP := .
+endif
+
+DELETE := rm -f
+SEP := /
+BUILD := $(TOP)/config/unix
+PLATFORM := unix
+
+# the directory where all object files are placed
+#
+OBJ_DIR := $(TOP)/obj
+
+
+# the directory where all library files are placed
+#
+# by default, this is the same as OBJ_DIR, however, this can be
+# changed to suit particular needs..
+#
+LIB_DIR := $(OBJ_DIR)
+
+
+# the object file extension, this can be .o, .tco, .obj, etc..
+# depending on the platform
+#
+O := o
+
+# the library file extension, this can be .a, .lib, etc..
+# depending on the platform
+#
+A := a
+
+
+# The name of the final library file.
+# Note that the DOS-specific Makefile uses a shorter (8.3) name
+#
+LIBRARY := libfreetype
+
+
+# path inclusion flag.
+#
+# Some compilers use a different flag than '-I' to specify an
+# additional include path. Examples are "/i=" or "-J", etc...
+#
+I := -I
+
+
+# The link flag used to specify a given library file on link.
+# Note that this is only used to compile the demo programs, not
+# the library itself.
+#
+L := -l
+
+
+# C flag used to define a macro before the compilation of a given
+# source object. Usually is '-D' like in "-DDEBUG"
+#
+D := -D
+
+
+# Target flag - beware, there is a space after the 'o' !!
+#
+#
+T := -o
+
+# C flags
+#
+# These should concern :
+#
+# - debug output
+# - optimization
+# - warnings
+# - ansi compliance..
+#
+ifndef CFLAGS
+CFLAGS := -c -g -O0 -Wall
+endif
+
+ifdef BUILD_FREETYPE
+
+include $(TOP)/config/freetype.mk
+
+
+# This final rule is used to link all object files into a single
+# library. It is part of the system-specific sub-Makefile because not
+# all librarians accept a simple syntax like :
+#
+# librarian library_file {list of object files}
+#
+$(FT_LIBRARY): $(OBJECTS_LIST)
+ -$(DELETE) $@
+ $(AR) -r $@ $(OBJECTS_LIST)
+
+endif
--- /dev/null
+++ b/config/unix/detect.mk
@@ -1,0 +1,31 @@
+#
+# This file is used to detect which Makefile to use based on the
+# value of the CC environment variable.
+#
+# Unix
+#
+#
+# This will _much_ probably change in the future if we're going to use
+# Automake/Autoconf..
+#
+
+ifeq ($(PLATFORM),ansi)
+has_inittab := $(strip $(wildcard /etc/inittab))
+ifneq ($(has_inittab),)
+
+PLATFORM := unix
+COPY := cp
+DELETE := rm -f
+
+CONFIG_RULES := $(BUILD)$(SEP)Makefile
+
+setup: std_setup
+
+endif # test Unix
+endif # test PLATFORM
+
+
+
+
+
+
--- /dev/null
+++ b/config/unix/ftconfig.h
@@ -1,0 +1,172 @@
+/*******************************************************************
+ *
+ * ftconfig.h
+ *
+ * Unix-specific configuration file
+ *
+ * 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 header file contains a number of macro definitions that are
+ * used by the rest of the engine. Porters are free to copy this file
+ * and adapt it to suit their own system..
+ *
+ * IMPORTANT NOTE :
+ *
+ * Porters, read carefully the comments in ftsys.h before trying
+ * to port this file to your system. It contains many essential
+ * remarks, and will ease your work greatly..
+ *
+ ******************************************************************/
+
+#ifndef FTCONFIG_H
+#define FTCONFIG_H
+
+/*************************************************************************/
+/* */
+/* PLATFORM-SPECIFIC CONFIGURATION MACROS */
+/* */
+/* These macros can be toggled to suit a specific system. The current */
+/* ones are defaults used to compile FreeType in a 32-bits ANSI C */
+/* environment. Copy this file to your own "freetype/arch/<system>" */
+/* directory, and edit it to port the engine.. */
+/* */
+/*************************************************************************/
+
+/* Define to empty if the keyword does not work. */
+/* #undef const */
+
+/* Define if you have a working `mmap' system call. */
+#define HAVE_MMAP
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define if your processor stores words with the most significant
+ byte first (like Motorola and SPARC, unlike Intel and VAX). */
+/* #undef WORDS_BIGENDIAN */
+
+/* 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 <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define if you have the <locale.h> header file. */
+#define HAVE_LOCALE_H 1
+
+/* Define if you have the <libintl.h> header file. */
+#undef HAVE_LIBINTL_H
+
+/* Define if you have the libintl library. */
+/* #undef HAVE_LIBINTL */
+
+/* Preferred alignment of data */
+#define FT_ALIGNMENT 8
+
+/* See the definition of the macro FT_CONFIG_OPTION_LITTLE_ENDIAN */
+/* and FT_CONFIG_OPTION_BIG_ENDIAN below, they may need to be set */
+/* according to the platform too.. */
+
+
+#include <ftoption.h>
+
+/*************************************************************************/
+/* */
+/* AUTOMATIC CONFIGURATION MACROS */
+/* */
+/* These macros are computed from the ones defined above. Don't touch */
+/* their definition, unless you know precisely what you're doing. No */
+/* porter should need to mess with them. */
+/* */
+/*************************************************************************/
+
+ /* IntN types: */
+ /* */
+ /* Used to guarantee the size of some specific integers. */
+ /* */
+
+ typedef signed short FT_Int16;
+ typedef unsigned short FT_Word16;
+
+#if SIZEOF_INT == 4
+
+ typedef signed int FT_Int32;
+ typedef unsigned int FT_Word32;
+
+#elif SIZEOF_LONG == 4
+
+ typedef signed long FT_Int32;
+ typedef unsigned long FT_Word32;
+
+#else
+#error "no 32bit type found - please check your configuration files"
+#endif
+
+#if SIZEOF_LONG == 8
+
+/* LONG64 must be defined when a 64-bit type is available */
+#define LONG64
+#define INT64 long
+
+#else
+
+/* GCC provides the non-ANSI 'long long' 64-bit type. You can activate it */
+/* by defining the FTCALC_USE_LONG_LONG macro in 'ftconfig.h'. Note that */
+/* this will produce many -ansi warnings during library compilation. */
+#ifdef FTCALC_USE_LONG_LONG
+
+#define LONG64
+#define INT64 long long
+
+#endif /* FTCALC_USE_LONG_LONG */
+#endif
+
+#ifdef FT_MAKE_OPTION_SINGLE_OBJECT
+#define LOCAL_DEF static
+#define LOCAL_FUNC static
+#else
+#define LOCAL_DEF extern
+#define LOCAL_FUNC /* nothing */
+#endif
+
+#ifdef FT_MAKE_OPTION_SINGLE_LIBRARY_OBJECT
+#define BASE_DEF LOCAL_DEF
+#define BASE_FUNC LOCAL_FUNC
+#else
+#define BASE_DEF extern
+#define BASE_FUNC /* nothing */
+#endif
+
+#ifndef EXPORT_DEF
+#define EXPORT_DEF extern
+#endif
+
+#ifndef EXPORT_FUNC
+#define EXPORT_FUNC /* nothing */
+#endif
+
+
+#endif /* FTCONFIG_H */
--- /dev/null
+++ b/config/unix/ftoption.h
@@ -1,0 +1,162 @@
+#ifndef FTOPTION_H
+#define FTOPTION_H
+
+ /*************************************************************************/
+ /* */
+ /* USER-SELECTABLE CONFIGURATION MACROS */
+ /* */
+ /* These macros can be toggled by developers to enable or disable */
+ /* certain aspects of FreeType. This file contains macros that apply to */
+ /* all of FreeType. Driver-specific configurations are placed in each */
+ /* driver directory (e.g. `freetype/drivers/ttlib/ttconfig.h'). */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* Alternate Glyph Image Format support */
+ /* */
+ /* By default, the glyph images returned by the FreeType glyph loader */
+ /* can either be a pixmap or a vectorial outline defined through */
+ /* bezier control points. When defining the following configuration */
+ /* macro, some font drivers will be able to register alternate */
+ /* glyph image formats. */
+ /* */
+ /* Unset this macro if you're sure that you'll never use a font driver */
+ /* with an alternate glyph format, this will reduce the size of the */
+ /* base layer code. */
+ /* */
+#define FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS
+
+ /*************************************************************************/
+ /* */
+ /* GCC provides the non-ANSI `long long' 64-bit type. You can activate */
+ /* it by defining the FTCALC_USE_LONG_LONG macro here. Note however */
+ /* that we did not experience any improvement in speed with gcc, and */
+ /* that the final code seems bigger when linked. */
+ /* */
+#undef FTCALC_USE_LONG_LONG
+
+
+ /*************************************************************************/
+ /* */
+ /* When compiling FreeType as a DLL, some systems/compilers need a */
+ /* special keyword in front of each function definition instead of */
+ /* `extern'. */
+ /* */
+ /* The macros EXPORT_DEF and EXPORT_FUNC are thus used to define */
+ /* exported library function interfaces and exported library functions */
+ /* implementations respectively. */
+ /* */
+ /* If not defined here, they automatically default to `extern' and void */
+ /* later in this header file. */
+ /* */
+#undef EXPORT_DEF
+#undef EXPORT_FUNC
+
+
+ /*************************************************************************/
+ /* */
+ /* Debug level */
+ /* */
+ /* FreeType can be compiled in debug or trace mode. In debug mode, */
+ /* errors are reported through the `ftdebug' component. In trace */
+ /* mode, additional messages are sent to the standard output during */
+ /* execution. */
+ /* */
+ /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */
+ /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */
+ /* */
+ /* Don't define any of these macros to compile in `release' mode. */
+ /* */
+#undef FT_DEBUG_LEVEL_ERROR
+#undef FT_DEBUG_LEVEL_TRACE
+
+
+ /*************************************************************************/
+ /* */
+ /* Anti-aliasing support */
+ /* */
+ /* Undefine this macro only if you want to disable the anti-aliasing */
+ /* support in FreeType. This will save you about 5 Kb of code. It */
+ /* may be important for some embedded systems. */
+ /* */
+#define FT_CONFIG_OPTION_ANTI_ALIAS
+
+
+ /*************************************************************************/
+ /* */
+ /* Endianess performance improvement */
+ /* */
+ /* FreeType is completely endian-independent, and can thus be compiled */
+ /* directly on _any_ machine. However, some components of the library */
+ /* provide improved routines for the cases where endianess is known. */
+ /* */
+ /* It usually results in speed-ups and reduced code size. Note that */
+ /* you should not define both of these macros. */
+ /* */
+ /* */
+ /* NOTE: For now, only the scan-line converter (base/ftraster.c) uses */
+ /* these macros to speed-up some anti-alias rendering routines. */
+ /* */
+#undef FT_CONFIG_OPTION_LITTLE_ENDIAN
+#undef FT_CONFIG_OPTION_BIG_ENDIAN
+
+
+ /*************************************************************************/
+ /* */
+ /* Define this configuration macro whenever you want to build a version */
+ /* of FreeType that does not include a default `system' component. */
+ /* */
+ /* Note that this will prevent the compilation of `ftinit', hence the */
+ /* function FT_Init_FreeType */
+ /* */
+#undef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
+
+
+ /*************************************************************************/
+ /* */
+ /* The size in bytes of the render pool used by the scan-line */
+ /* converter to do all of its work. */
+ /* */
+ /* This must be greater than 4 Kb */
+ /* */
+#define FT_RENDER_POOL_SIZE 32768
+
+
+ /*************************************************************************/
+ /* */
+ /* FT_MAX_DRIVERS */
+ /* */
+ /* The maximum number of font drivers that can be registered in a */
+ /* single FreeType library object. 8 seems to be a good choice due */
+ /* to the relative low actual number of drivers ;-) */
+ /* */
+#define FT_MAX_DRIVERS 8
+
+
+ /*************************************************************************/
+ /* */
+ /* FT_MAX_EXTENSIONS */
+ /* */
+ /* The maximum number of extensions that can be registered in a */
+ /* single font driver. 8 seems to be a good choice for now.. */
+ /* */
+#define FT_MAX_EXTENSIONS 8
+
+
+ /*************************************************************************/
+ /* */
+ /* FT_MAX_GLYPH_FORMATS */
+ /* */
+ /* The maximum number of glyph image formats that might be registered */
+ /* in a given library instance. 8 seems to be a good choice due to */
+ /* the relatively low number of current formats ;-) */
+ /* */
+
+#define FT_MAX_GLYPH_FORMATS 8
+
+
+
+#endif /* FTOPTION_H */
--- /dev/null
+++ b/config/unix/ftsys.c
@@ -1,0 +1,871 @@
+/*******************************************************************
+ *
+ * ftsys.c
+ *
+ * Unix-specific system operations.
+ *
+ * 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 implementation of the 'ftsys' component uses memory-mapped
+ * files, as well as the ANSI malloc/free functions..
+ *
+ * IMPORTANT NOTE :
+ *
+ * Porters, read carefully the comments in ftsys.h before trying
+ * to port this file to your system. It contains many essential
+ * remarks, and will ease your work greatly..
+ *
+ ******************************************************************/
+
+#include "ftsys.h"
+#include "ftobjs.h"
+#include "ftstream.h"
+#include "ftdebug.h"
+
+/* Memory-mapping includes and definitions.. */
+/* */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <sys/mman.h>
+#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 <sys/stat.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+
+/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+/* parameter of the PTRACE and PERROR macros, used to print/log */
+/* messages during execution.. */
+/* */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_io
+
+
+
+
+/* To ease porting, we use the macro SYS_STREAM to name the system-specific */
+/* stream type. For example, it is a "FILE*" with the ANSI libc, it will be */
+/* a file descriptor, i.e. an integer, when using the Unix system api, etc. */
+
+/* we identify each memory-mapped file through its address in memory */
+/* hence the following macro definition.. */
+
+#define SYS_STREAM void*
+
+
+/**************************************************************************/
+/* */
+/* I/O ACCESS AND MANAGEMENT */
+/* */
+/* We only define the "ANSI" resource class in this class. It is */
+/* disk-based, and provides a MRU cache, in order to only keep the file */
+/* descriptors of the 10 most recently used resource files. */
+/* */
+/* it simply contains two lists. One contains the "cached" resources */
+/* with a valid FILE* pointer, the second contains all other "flushed" */
+/* resource objects. */
+/* */
+
+/* The FT_MMapFile class derives from FT_ResourceRec - description : */
+/* */
+/* <Struct> FT_AnsiFileRec */
+/* */
+/* <Fields> */
+/* */
+/* root :: */
+/* the root resource class fields. */
+/* */
+/* pathname :: */
+/* the file's pathname. Needed because we open and close font */
+/* resources dynamically in order to limit the number of */
+/* concurrently active mappings (this saves kernel resources). */
+/* */
+/* file_size :: */
+/* the size in bytes of the resource. This field should be set to */
+/* -1 until the resource is first opened.. */
+/* */
+
+#include <stdio.h>
+
+ typedef struct FT_MMapFileRec_
+ {
+ FT_ResourceRec root;
+ const char* pathname;
+ FT_Long file_size; /* file size in bytes */
+
+ } FT_MMapFileRec, *FT_MMapFile;
+
+
+/* We use the macro STREAM_Name as a convenience to return a given */
+/* ANSI resource's pathname. Its "stream" argument is a FT_Resource */
+/* which is typecasted to the FT_AnsiFile class */
+#define STREAM_Name(stream) ((FT_MMapFile)stream->resource)->pathname
+
+/* We use the macro STREAM_File as a convenience to extract the */
+/* system-specific stream handle from a given FreeType stream object */
+#define STREAM_File(stream) ((void*)stream->stream_id.pointer)
+
+
+
+/***************************************************************************/
+/* */
+/* <Function> MMapFile_Open */
+/* */
+/* <Description> */
+/* This function is used to open a system-stream for a given resource. */
+/* */
+/* Note that it must update the target FreeType stream object with the */
+/* system-stream handle and the resource's size. */
+/* */
+/* Also, the 'stream->base' field must be set to NULL for disk-based */
+/* resource, and to the address in memory of the resource's first byte */
+/* for a memory-based one. */
+/* */
+/* <Input> */
+/* resource :: the source resource */
+/* stream :: the target stream object */
+/* */
+/* <Return> */
+/* Error code */
+/* */
+/* <Note> */
+/* This function simply opens and maps the resource's file pathname */
+/* */
+/* The stream object IS NOT CREATED by this function, but by its caller. */
+/* */
+/***************************************************************************/
+
+ static
+ FT_Error MMapFile_Open( FT_MMapFile resource,
+ FT_Stream stream )
+ {
+ int file;
+ struct stat stat_buf;
+
+ /* open the file */
+ file = open( resource->pathname, O_RDONLY );
+ if (file < 0)
+ {
+ PERROR(( "UnixSys.MMapFile_Open : could not open '%s'\n",
+ resource->pathname ));
+ return FT_Err_Cannot_Open_Stream;
+ }
+
+ if (fstat( file, &stat_buf ) < 0)
+ {
+ PERROR(( "UnixSys.MMapFile_Open : could not 'fstat' file '%s'\n",
+ resource->pathname ));
+ goto Fail_Map;
+ }
+
+ if ( resource->file_size < 0 )
+ resource->file_size = stat_buf.st_size;
+
+ stream->resource = (FT_Resource)resource;
+ stream->system = resource->root.driver->system;
+ stream->size = resource->file_size;
+ stream->stream_id.pointer = mmap( NULL,
+ resource->file_size,
+ PROT_READ,
+ MAP_FILE | MAP_PRIVATE,
+ file,
+ 0 );
+
+ if ( (long)stream->stream_id.pointer == -1 )
+ {
+ PERROR(( "UnixSys.MMapFile_Open : Could not map file '%s'\n",
+ resource->pathname ));
+ goto Fail_Map;
+ }
+
+ close(file);
+ stream->base = (FT_Byte*)stream->stream_id.pointer;
+ stream->cursor = stream->base;
+
+ PTRACE1(( "UnixSys.MMapFile_Open: opened '%s' (%d bytes) succesfully\n",
+ resource->pathname, resource->file_size ));
+
+ return FT_Err_Ok;
+
+ Fail_Map:
+ close(file);
+ stream->resource = NULL;
+ stream->size = 0;
+ stream->stream_id.pointer = NULL;
+ stream->base = NULL;
+ stream->cursor = NULL;
+
+ return FT_Err_Cannot_Open_Stream;
+ }
+
+
+/***************************************************************************/
+/* */
+/* <Function> MMapFile_Close */
+/* */
+/* <Description> Closes a given stream */
+/* */
+/* <Input> */
+/* stream :: the target stream object */
+/* */
+/* <Return> */
+/* Error code */
+/* */
+/* <Note> */
+/* This function simply unmaps the resource.. */
+/* */
+/***************************************************************************/
+
+ static
+ FT_Error MMapFile_Close( FT_Stream stream )
+ {
+ PTRACE1(( "Closing file '%s'\n", STREAM_Name(stream) ));
+
+ munmap ( (void*)stream->stream_id.pointer, stream->size );
+
+ stream->resource = NULL;
+ stream->stream_id.pointer = NULL;
+ stream->size = 0;
+ stream->base = NULL;
+ stream->cursor = NULL;
+
+ return FT_Err_Ok;
+ }
+
+
+/***************************************************************************/
+/* */
+/* <Function> MMapFile_Seek */
+/* */
+/* <Description> Seek a stream to a given position */
+/* */
+/* <Input> */
+/* stream :: the target stream object */
+/* position :: offset in bytes from start of resource/stream */
+/* */
+/* <Return> */
+/* Error code */
+/* */
+/* <Note> */
+/* This function should never be called for memory-based resources.. */
+/* */
+/***************************************************************************/
+
+ static
+ FT_Error MMapFile_Seek( FT_Stream stream,
+ FT_Long position )
+ {
+ (void)stream;
+ (void)position;
+ return FT_Err_Invalid_Stream_Operation;
+ }
+
+
+/***************************************************************************/
+/* */
+/* <Function> MMapFile_Skip */
+/* */
+/* <Description> Skip a given number of bytes in an MMap stream. */
+/* Useful to skip pad bytes, for example. */
+/* */
+/* <Input> */
+/* stream :: the target stream object */
+/* count :: number of bytes to skip in the stream */
+/* */
+/* <Return> */
+/* Error code */
+/* */
+/* <Note> */
+/* This function should never be called for memory-based resources.. */
+/* */
+/***************************************************************************/
+
+ static
+ FT_Error MMapFile_Skip( FT_Stream stream,
+ FT_Long count )
+ {
+ (void)stream;
+ (void)count;
+ return FT_Err_Invalid_Stream_Operation;
+ }
+
+/***************************************************************************/
+/* */
+/* <Function> MMapFile_Pos */
+/* */
+/* <Description> Returns the current offset within an MMap stream's */
+/* resource. */
+/* */
+/* <Input> */
+/* stream :: the target stream object */
+/* */
+/* <Output> */
+/* position :: current offset. -1 in case of error */
+/* */
+/* <Return> */
+/* Error code. */
+/* */
+/* <Note> */
+/* This function should never be called for memory-based resources.. */
+/* */
+/***************************************************************************/
+
+ static
+ FT_Error MMapFile_Pos( FT_Stream stream,
+ FT_Long* position )
+ {
+ (void)stream;
+ (void)position;
+ return FT_Err_Invalid_Stream_Operation;
+ }
+
+/***************************************************************************/
+/* */
+/* <Function> MMapFile_Read */
+/* */
+/* <Description> Read a given number of bytes from an MMap stream into */
+/* memory. */
+/* */
+/* <Input> */
+/* stream :: the target stream object */
+/* buffer :: the target read buffer where data is copied */
+/* size :: number of bytes to read from the stream */
+/* */
+/* <Output> */
+/* read_bytes :: the number of bytes effectively read from the stream */
+/* used in case of error (i.e. FT_Err_Invalid_Stream_Read) */
+/* by some parts of the library.. */
+/* <Return> */
+/* Error code */
+/* */
+/* <Note> */
+/* This function should never be called for memory-based resources.. */
+/* */
+/***************************************************************************/
+
+ static
+ FT_Error MMapFile_Read( FT_Stream stream,
+ FT_Byte* buffer,
+ FT_Long size,
+ FT_Long* read_bytes )
+ {
+ (void)stream;
+ (void)buffer;
+ (void)size;
+ (void)read_bytes;
+ return FT_Err_Invalid_Stream_Operation;
+ }
+
+/* The following table is the "virtual method table" for the 'MMap */
+/* resource class', which methods are defined above. Its address is */
+/* set in the 'interface' field of all resource objects created by */
+/* the function FT_Create_MMapFile (see below) */
+
+ static
+ FTRes_InterfaceRec FT_MMapFile_Interface =
+ {
+ (FTRes_Open_Func) MMapFile_Open,
+ (FTRes_Close_Func) MMapFile_Close,
+ (FTRes_Seek_Func) MMapFile_Seek,
+ (FTRes_Skip_Func) MMapFile_Skip,
+ (FTRes_Pos_Func) MMapFile_Pos,
+ (FTRes_Read_Func) MMapFile_Read,
+ };
+
+
+ /************************************************************************/
+ /* */
+ /* <Function> FT_Create_Resource */
+ /* */
+ /* <Description> */
+ /* Create a new resource object for a given library. Note that this */
+ /* function takes an ASCII 'pathname' as an argument. */
+ /* */
+ /* <Input> */
+ /* library :: handle to target library object */
+ /* pathanme :: ASCII pathname of the font file */
+ /* */
+ /* <Output> */
+ /* resource :: handle to new resource object */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success */
+ /* */
+ /* <Note> */
+ /* When porting the library to exotic environments, where an */
+ /* ASCII pathname isn't used to name files, developers should */
+ /* invoke directly their own resource creation function which */
+ /* must be placed in their port of the "ftsys" component. */
+ /* */
+ /* See the porting guide for more information.. */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_Create_Resource( FT_Library library,
+ const char* pathname,
+ FT_Resource* aresource )
+ {
+ FT_Int len;
+ FT_System system;
+ FT_MMapFile resource;
+ FT_Error error;
+
+ *aresource = NULL;
+
+ if (!library)
+ {
+ PERROR(( "Unix.New_Resource : null library handle\n" ));
+ return FT_Err_Invalid_Library_Handle;
+ }
+
+ system = library->system;
+
+ if ( !pathname )
+ goto Fail_Null;
+
+ len = strlen(pathname);
+ if (len == 0)
+ goto Fail_Null;
+
+ resource = NULL;
+
+ if ( ALLOC( resource, sizeof(*resource) ) ||
+ ALLOC( resource->pathname, len+1 ) )
+ goto Fail_Memory;
+
+ resource->root.library = library;
+ resource->root.interface = &FT_MMapFile_Interface;
+ resource->root.flags = FT_RESOURCE_TYPE_MEMORY_BASED;
+ resource->file_size = -1;
+ strcpy( (char*)resource->pathname, pathname );
+
+ PTRACE1(( "Create_MMapFile : MMap resource created for '%s'\n",
+ pathname ));
+
+ *aresource = (FT_Resource)resource;
+ return FT_Err_Ok;
+
+ Fail_Null:
+ PERROR(( "Create_MMapFile : null pathname !!\n" ));
+ return FT_Err_Invalid_Argument;
+
+ Fail_Memory:
+ if (resource)
+ FREE( resource->pathname );
+ FREE( resource );
+ PERROR(( "Create_MMapFile : error when creating resource !\n" ));
+ return error;
+ }
+
+
+/***************************************************************************/
+/* */
+/* <Function> FT_Destroy_Resource */
+/* */
+/* <Description> Destroys an MMap resource object. */
+/* This function is never called directly by the font */
+/* drivers. Only by the higher-level part of FreeType */
+/* (called the HLib), or client applications */
+/* */
+/* <Input> */
+/* resource :: the MMap resource object */
+/* */
+/* <Note> */
+/* This functions does not check that runs or streams are opened for */
+/* the resource (for now, we assume developer intelligence. We'll most */
+/* probably lower our standard later to ease debugging ;-) */
+/* */
+/***************************************************************************/
+
+ EXPORT_FUNC
+ FT_Error FT_Destroy_Resource( FT_Resource resource )
+ {
+ FT_System system = resource->library->system;
+ FT_MMapFile res = (FT_MMapFile)resource;
+
+ if ( !res || res->root.interface != &FT_MMapFile_Interface )
+ {
+ PERROR((
+ "Destroy_MMapFile : Trying to destroy an invalid resource !!\n" ));
+ return FT_Err_Invalid_Resource_Handle;
+ }
+
+ PTRACE1(( "Destroy_MMapFile : destroying resource for '%s'\n",
+ res->pathname ));
+
+ FREE( res->pathname );
+ FREE( res );
+
+ return FT_Err_Ok;
+ }
+
+
+
+/**************************************************************************/
+/* */
+/* MEMORY MANAGEMENT */
+/* */
+/* */
+/* This part copies the old FreeType 1.0 and 1.1 memory management */
+/* scheme that was defined in the file "ttmemory.h". One can see that */
+/* */
+/* - a set of macros is defined for the memory operations used */
+/* by the engine ( MEM_Copy, MEM_Move, MEM_Set ). This comes from */
+/* the fact that many compilers are able to inline these ops directly */
+/* within the compiled code, rather than generating a call to the */
+/* C library. However, this obliges us to include the <string.h> */
+/* header file. */
+/* */
+/* If you provide your own memory operations routine, you can get */
+/* rid of the #include <string.h> below. */
+/* */
+/* */
+/* - the FT_Alloc function has several essential properties that */
+/* MUST be retained by each port : */
+/* */
+/* - it returns an error code, NOT the allocated block's base */
+/* address */
+/* */
+/* - it takes the address of a target pointer, where the block's */
+/* base address will be set. if the size is zero, its value */
+/* will be NULL and the function returns successfully */
+/* */
+/* - in case of error, the pointer's value is set to NULL and */
+/* an error code is returned.. */
+/* */
+/* - the new allocated block MUST be zero-filled. This is a strong */
+/* convetion the rest of the engine relies on */
+/* */
+/* */
+/* */
+/* - the FT_Free function has also its essentials : */
+/* */
+/* - it takes the address of a pointer which value is the block's */
+/* base address. This is UNLIKE a standard "free" which takes the */
+/* the block's base directly. */
+/* */
+/* - it accepts succesfully the address of a pointer which value */
+/* is NULL, in which case it simply returns. */
+/* */
+/* - the pointer is always set to NULL by the function */
+/* */
+/* */
+/* - the MEM_Alloc, ALLOC and ALLOC_ARRAY macros are used by the */
+/* library, and should NOT be modified by porters !! */
+/* */
+
+/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+/* parameter of the PTRACE and PERROR macros, used to print/log */
+/* messages during execution.. */
+/* */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_memory
+
+
+#include <stdlib.h>
+
+/**************************************************************************/
+/* */
+/* <Function> FT_Alloc */
+/* */
+/* <Description> */
+/* Allocates a new bloc of memory. The returned area is always */
+/* zero-filled, this is a strong convention in many FreeType parts */
+/* */
+/* <Input> */
+/* system :: handle to a given 'system object' where allocation */
+/* occurs.. */
+/* */
+/* size :: size in bytes of the block to allocate */
+/* */
+/* <Output> */
+/* P :: pointer to the fresh new block. It should be set */
+/* to NULL if 'size' is 0, of in case of error.. */
+/* */
+/* <Return> */
+/* FreeType error code. 0 means success. */
+/* */
+/**************************************************************************/
+
+ BASE_FUNC
+ FT_Error FT_Alloc( FT_System system,
+ long size,
+ void* *P )
+ {
+
+ if (!P)
+ {
+ PERROR(( "FT_Alloc : invalid pointer address !!\n" ));
+ return FT_Err_Invalid_Argument;
+ }
+
+ if ( size > 0 )
+ {
+ *P = malloc( size );
+ if ( !*P )
+ {
+ PERROR(( "FT_Alloc : out of memory (%ld bytes requested) !!\n",
+ size ));
+
+ return FT_Err_Out_Of_Memory;
+ }
+
+ system->total_alloc += size;
+
+ /* ALWAYS ZERO-FILL THE BLOCK !!!!! */
+ MEM_Set( *P, 0, size );
+ }
+ else
+ *P = NULL;
+
+ PTRACE2(( "FT_Alloc : size = %ld, pointer = 0x%08lx, block = 0x%08lx\n",
+ size, (long)P, (long)*P ));
+
+ return FT_Err_Ok;
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> FT_Realloc */
+/* */
+/* <Description> */
+/* Reallocates a block of memory pointed to by '*P' to 'Size' */
+/* bytes from the hea^, possibly changing '*P'. */
+/* */
+/* <Input> */
+/* system :: handle to a given 'system object' where allocation */
+/* occurs.. */
+/* */
+/* size :: size in bytes of the block to allocate */
+/* */
+/* <InOut> */
+/* P :: pointer to the fresh new block. It should be set */
+/* to NULL if 'size' is 0, of in case of error.. */
+/* */
+/* <Return> */
+/* FreeType error code. 0 means success. */
+/* */
+
+ BASE_FUNC
+ int FT_Realloc( FT_System system,
+ long size,
+ void* *P )
+ {
+ void* Q;
+
+ if (!P)
+ {
+ PERROR(( "FT_Realloc : invalid pointer address !!\n" ));
+ return FT_Err_Invalid_Argument;
+ }
+
+ /* if the original pointer is NULL, call FT_Alloc */
+ if (!*P)
+ return FT_Alloc( system, size, P );
+
+ /* if the new block if zero-sized, clear the current one */
+ if (size <= 0)
+ return FT_Free( system, P );
+
+ Q = (void*)realloc( *P, size );
+ if (!Q)
+ {
+ PERROR(( "FT_Realloc : reallocation failed\n" ));
+ return FT_Err_Out_Of_Memory;
+ }
+
+ *P = Q;
+ return FT_Err_Ok;
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> FT_Free */
+/* */
+/* <Description> */
+/* Releases a given block of memory allocated through FT_Alloc */
+/* */
+/* <Input> */
+/* system :: handle to a given 'system object' where allocation */
+/* occured.. */
+/* */
+/* P :: This is the _address_ of a _pointer_ which points to */
+/* the allocated block. It is always set to NULL on exit */
+/* */
+/* <Return> */
+/* FreeType error code. 0 means success. */
+/* */
+/* <Note> */
+/* If P or *P are NULL, this function should return successfuly. This */
+/* is a strong convention within all of FreeType and its drivers.. */
+/* */
+
+ BASE_FUNC
+ FT_Error FT_Free( FT_System system,
+ void* *P )
+ {
+ (void)system; /* unused parameter. Gets rid of warnings */
+
+ PTRACE2(( "FT_Free : freeing pointer 0x%08lx (block 0x%08lx)\n",
+ (long)P, (P ? (long)*P : -1) ));
+
+ if ( !P || !*P )
+ return FT_Err_Ok;
+
+ free( *P );
+ *P = NULL;
+
+ return FT_Err_Ok;
+ }
+
+/**************************************************************************/
+/* */
+/* SYNCHRONIZATION MANAGEMENT */
+/* */
+/* */
+/* This section deals with mutexes. The library can be compiled to */
+/* three distinct thread-support levels ( namely single-threaded, */
+/* thread-safe and re-entrant modes ). */
+/* */
+/* It protects its variables through the MUTEX_Lock and MUTEX_Release */
+/* macros which are void in single-threaded mode. */
+/* */
+/* */
+/* It defines a type-less mutex reference type, "TMutex", that you're */
+/* free to redefine for your system's needs.. */
+/* */
+/* The default implementation of ftsys.c contains only dummy functions */
+/* which always return succesfully. you NEED to specialize them in */
+/* order to port ftsys.c in any multi-threaded environment... */
+/* */
+
+/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+/* parameter of the PTRACE and PERROR macros, used to print/log */
+/* messages during execution.. */
+/* */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_sync
+
+#ifdef FT_CONFIG_THREADS
+
+
+ BASE_FUNC
+ FT_Error FT_Mutex_Create ( FT_System system,
+ TMutex* mutex )
+ {
+ (void)system; /* unused parameter. Gets rid of warnings */
+
+ mutex = (void*)-1;
+ system->num_mutexes++;
+ return FT_Err_Ok;
+ /* Replace this line with your own mutex creation code */
+ }
+
+
+ BASE_FUNC
+ void FT_Mutex_Delete ( FT_System system,
+ TMutex* mutex )
+ {
+ (void)system; /* unused parameter. Gets rid of warnings */
+
+ mutex = (void*)0;
+ system->num_mutexes--;
+ /* Replace this line with your own mutex destruction code */
+ }
+
+ BASE_FUNC
+ void FT_Mutex_Lock ( FT_System system,
+ TMutex* mutex )
+ {
+ /* NOTE: It is legal to call this function with a NULL argument */
+ /* in which case an immediate return is appropriate. */
+ (void)system; /* unused parameter. Gets rid of warnings */
+
+ if ( !mutex )
+ return;
+
+ ; /* Insert your own mutex locking code here */
+ }
+
+
+ void FT_Mutex_Release( FT_System system,
+ TMutex* mutex )
+ {
+ /* NOTE: It is legal to call this function with a NULL argument */
+ /* in which case an immediate return is appropriate */
+ (void)system; /* unused parameter. Gets rid of warnings */
+
+ if ( !mutex )
+ return;
+ ; /* Insert your own mutex release code here */
+ }
+
+#endif /* FT_CONFIG_THREADS */
+
+
+
+
+ EXPORT_FUNC
+ FT_Error FT_New_System( FT_System* system )
+ {
+ *system = (FT_System)malloc( sizeof(FT_SystemRec) );
+ if ( !*system )
+ return FT_Err_Out_Of_Memory;
+
+ /* the ANSI function 'free' is unable to return the number */
+ /* of released bytes. Hence, the 'current_alloc' field of the */
+ /* system object cannot be used */
+
+ (*system)->system_flags = FT_SYSTEM_FLAG_TOTAL_ALLOC |
+ FT_SYSTEM_FLAG_MUTEXES;
+ (*system)->total_alloc = 0;
+ (*system)->num_mutexes = 0;
+
+ /* initialise i/o management (nothing) */
+
+ /* initialise synchronisation (nothing) */
+
+ /* initialise streams */
+
+ return FT_Err_Ok;
+ }
+
+
+
+ EXPORT_FUNC
+ FT_Error FT_Done_System( FT_System system )
+ {
+ /* finalise syncrhonisation (nothing) */
+
+ /* finalise i/o management (nothing) */
+
+ /* finalise memory management */
+ free( system );
+
+ return FT_Err_Ok;
+ }
+
--- /dev/null
+++ b/config/unix/ftsystem.c
@@ -1,0 +1,277 @@
+/**************************************************************************
+ *
+ * ftsystem.h 1.0
+ *
+ * Unix-specific FreeType low-level system interface
+ *
+ * This file contains the definition of interface used by FreeType
+ * to access low-level, i.e. memory management, i/o access as well
+ * as thread synchronisation.
+ *
+ *
+ * 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 <ftsystem.h>
+#include <fterrors.h>
+#include <ftconfig.h>
+#include <ftdebug.h>
+
+/* Memory-mapping includes and definitions.. */
+/* */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <sys/mman.h>
+#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 <sys/stat.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+ /*********************************************************************/
+ /* */
+ /* MEMORY MANAGEMENT INTERFACE */
+ /* */
+
+/************************************************************************
+ *
+ * <FuncType>
+ * FT_Alloc_Func
+ *
+ * <Description>
+ * The memory allocator function type
+ *
+ * <Input>
+ * system :: pointer to the system object
+ * size :: requested size in bytes
+ *
+ * <Output>
+ * block :: address of newly allocated block
+ *
+ * <Return>
+ * Error code. 0 means success.
+ *
+ * <Note>
+ * If your allocation routine ALWAYS zeroes the new block, you
+ * should set the flag FT_SYSTEM_FLAG_ALLOC_ZEROES in your system
+ * object 'flags' field.
+ *
+ * If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ * your system's "system_flags" field, this function should update
+ * the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+ static
+ void* ft_alloc( FT_Memory memory,
+ long size )
+ {
+ (void)memory;
+ return malloc(size);
+ }
+
+
+/************************************************************************
+ *
+ * <FuncType>
+ * FT_Realloc_Func
+ *
+ * <Description>
+ * The memory reallocator function type
+ *
+ * <Input>
+ * system :: pointer to the system object
+ * new_size :: new requested size in bytes
+ *
+ * <InOut>
+ * block :: address of block in memory
+ *
+ * <Return>
+ * Error code. 0 means success.
+ *
+ * <Note>
+ * This function is _never_ called when the system flag
+ * FT_SYSTEM_FLAG_NO_REALLOC is set. Instead, the engine will emulate
+ * realloc through "alloc" and "free".
+ *
+ * Note that this is possible due to the fact that FreeType's
+ * "FT_Realloc" always requests the _current_ size of the reallocated
+ * block as a parameter, thus avoiding memory leaks.
+ *
+ * If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ * your system's "system_flags" field, this function should update
+ * the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+ static
+ void* ft_realloc( FT_Memory memory,
+ long cur_size,
+ long new_size,
+ void* block )
+ {
+ (void)memory;
+ (void)cur_size;
+
+ return realloc( block, new_size );
+ }
+
+
+/************************************************************************
+ *
+ * <FuncType>
+ * FT_Free_Func
+ *
+ * <Description>
+ * The memory release function type
+ *
+ * <Input>
+ * system :: pointer to the system object
+ * block :: address of block in memory
+ *
+ * <Note>
+ * If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ * your system's "system_flags" field, this function should update
+ * the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+ static
+ void ft_free( FT_Memory memory,
+ void* block )
+ {
+ (void)memory;
+ free( block );
+ }
+
+ /*********************************************************************/
+ /* */
+ /* RESOURCE MANAGEMENT INTERFACE */
+ /* */
+
+/* We use the macro STREAM_File as a convenience to extract the */
+/* system-specific stream handle from a given FreeType stream object */
+#define STREAM_File(stream) ((void*)stream->descriptor.pointer)
+
+
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_io
+
+ static
+ void ft_close_stream( FT_Stream stream )
+ {
+ munmap ( stream->descriptor.pointer, stream->size );
+
+ stream->descriptor.pointer = NULL;
+ stream->size = 0;
+ stream->base = 0;
+ }
+
+
+ extern
+ int FT_New_Stream( const char* filepathname,
+ FT_Stream stream )
+ {
+ int file;
+ struct stat stat_buf;
+
+ /* open the file */
+ file = open( filepathname, O_RDONLY );
+ if (file < 0)
+ {
+ FT_ERROR(( "FT.Unix.Open:" ));
+ FT_ERROR(( " could not open '%s'\n", filepathname ));
+ return FT_Err_Cannot_Open_Stream;
+ }
+
+ if (fstat( file, &stat_buf ) < 0)
+ {
+ FT_ERROR(( "FT.Unix.Open:" ));
+ FT_ERROR(( " could not 'fstat' file '%s'\n", filepathname ));
+ goto Fail_Map;
+ }
+
+ stream->size = stat_buf.st_size;
+ stream->pos = 0;
+ stream->base = mmap( NULL,
+ stream->size,
+ PROT_READ,
+ MAP_FILE | MAP_PRIVATE,
+ file,
+ 0 );
+
+ if ( (long)stream->base == -1 )
+ {
+ FT_ERROR(( "FT.Unix.Open:" ));
+ FT_ERROR(( " Could not map file '%s'\n", filepathname ));
+ goto Fail_Map;
+ }
+
+ close(file);
+
+ stream->descriptor.pointer = stream->base;
+ stream->pathname.pointer = (char*)filepathname;
+
+ stream->close = ft_close_stream;
+ stream->read = 0;
+
+ FT_TRACE1(( "FT.Unix.Open:" ));
+ FT_TRACE1(( " opened '%s' (%d bytes) succesfully\n",
+ filepathname, stream->size ));
+
+ return FT_Err_Ok;
+
+ Fail_Map:
+ close(file);
+ stream->base = NULL;
+ stream->size = 0;
+ stream->pos = 0;
+
+ return FT_Err_Cannot_Open_Stream;
+ }
+
+
+ extern
+ FT_Memory FT_New_Memory( void )
+ {
+ FT_Memory memory;
+
+ memory = (FT_Memory)malloc( sizeof(*memory) );
+ if (memory)
+ {
+ memory->user = 0;
+ memory->alloc = ft_alloc;
+ memory->realloc = ft_realloc;
+ memory->free = ft_free;
+ }
+ return memory;
+ }
+
--- /dev/null
+++ b/config/win32/Makefile.gcc
@@ -1,0 +1,179 @@
+#*******************************************************************
+#*
+#* FreeType 2 Configuration rules for Unix + gcc
+#*
+#* 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 purpose of this sub-Makefile is to define various build and
+#* platform specific variables before including the sub-Makefile
+#* containing the FreeType library rules, found in
+#*
+#* $(TOP)/config/freetype.mk
+#*
+#* The following variables must be defined before including this
+#* file :
+#*
+#* TOP Pathname to the top of the FreeType sources
+#* hierarchy
+#*
+#* This file should define the following variables before including
+#* the FreeType library rules file :
+#*
+#* BUILD Pathname to the platform-specific files used
+#* for the build. Usually `$(TOP)/config/<system>'
+#*
+#* SEP Directory separator for the current platform.
+#* Either / or \ (maybe : on Macs)
+#*
+#* DELETE The forced remove/delete command to erase one or more
+#* files
+#*
+#* INCLUDE The location of all public header files. e.g.
+#* `$(TOP)/include'include' *
+#*
+#* SRC The directory containing all sources. e.g.
+#* '$(TOP)/src'
+#*
+#* OBJ_DIR The location where compiled object files will be
+#* placed, e.g. '$(TOP)/obj'
+#*
+#* LIB_DIR The location where the resulting library file will be
+#* placed, e.g. '$(TOP)/obj'
+#*
+#* LIBRARY The filename of the resulting library file, without
+#* its extension.. e.g. 'libfreetype' or 'freetype'
+#*
+#* O The object file suffix. Can be '.o', '.obj,' '.lo,'
+#* ';coff,' etc.
+#*
+#* A The library file suffix. Can be '.a' '.so,' '.lib'
+#* '.dll,' etc.
+#*
+#* I The path inclusion flag. Some compilers use a
+#* different flag than '-I' to specify an additional
+#* include path. Examples are '/i=' or '-J ', etc.
+#*
+#* D The macro definition flag. I haven't met compilers
+#* which don't use the '-D' switch to define a macro, but
+#* who knows...
+#*
+#* T The compilation flag used to identify the target. Some
+#* compilers use a different flag than '-o ' to specify
+#* the name of the target object file.
+#*
+#* CFLAGS The set of flags used to compile object files.
+#* (usually contains the flag '-c').
+#*
+#*
+#*
+#*******************************************************************
+
+ifndef TOP
+TOP := .
+endif
+
+DELETE := del
+SEP := /
+BUILD := $(TOP)/config/win32
+PLATFORM := win32
+CC := gcc
+
+# the directory where all object files are placed
+#
+OBJ_DIR := $(TOP)/obj
+
+
+# the directory where all library files are placed
+#
+# by default, this is the same as OBJ_DIR, however, this can be
+# changed to suit particular needs..
+#
+LIB_DIR := $(OBJ_DIR)
+
+
+# the object file extension, this can be .o, .tco, .obj, etc..
+# depending on the platform
+#
+O := o
+
+# the library file extension, this can be .a, .lib, etc..
+# depending on the platform
+#
+A := a
+
+
+# The name of the final library file.
+# Note that the DOS-specific Makefile uses a shorter (8.3) name
+#
+LIBRARY := libfreetype
+
+
+# path inclusion flag.
+#
+# Some compilers use a different flag than '-I' to specify an
+# additional include path. Examples are "/i=" or "-J", etc...
+#
+I := -I
+
+
+# The link flag used to specify a given library file on link.
+# Note that this is only used to compile the demo programs, not
+# the library itself.
+#
+L := -l
+
+
+# C flag used to define a macro before the compilation of a given
+# source object. Usually is '-D' like in "-DDEBUG"
+#
+D := -D
+
+
+# Target flag - beware, there is a space after the 'o' !!
+#
+#
+T := -o
+
+# C flags
+#
+# These should concern :
+#
+# - debug output
+# - optimization
+# - warnings
+# - ansi compliance..
+#
+ifndef CFLAGS
+CFLAGS := -c -g -O6 -Wall
+endif
+
+
+ifdef BUILD_FREETYPE
+
+include $(TOP)/config/freetype.mk
+
+# Librarian to use to build the static library
+#
+FT_LIBRARIAN := $(AR) -r
+
+
+# This final rule is used to link all object files into a single
+# library. It is part of the system-specific sub-Makefile because not
+# all librarians accept a simple syntax like :
+#
+# librarian library_file {list of object files}
+#
+$(FT_LIBRARY): $(OBJECTS_LIST)
+ -$(DELETE) $@
+ $(FT_LIBRARIAN) $@ $(OBJECTS_LIST)
+
+endif
+
--- /dev/null
+++ b/config/win32/Makefile.lcc
@@ -1,0 +1,180 @@
+#*******************************************************************
+#*
+#* FreeType 2 Configuration rules for Unix + gcc
+#*
+#* 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 purpose of this sub-Makefile is to define various build and
+#* platform specific variables before including the sub-Makefile
+#* containing the FreeType library rules, found in
+#*
+#* $(TOP)/config/freetype.mk
+#*
+#* The following variables must be defined before including this
+#* file :
+#*
+#* TOP Pathname to the top of the FreeType sources
+#* hierarchy
+#*
+#* This file should define the following variables before including
+#* the FreeType library rules file :
+#*
+#* BUILD Pathname to the platform-specific files used
+#* for the build. Usually `$(TOP)/config/<system>'
+#*
+#* SEP Directory separator for the current platform.
+#* Either / or \ (maybe : on Macs)
+#*
+#* DELETE The forced remove/delete command to erase one or more
+#* files
+#*
+#* INCLUDE The location of all public header files. e.g.
+#* `$(TOP)/include'include' *
+#*
+#* SRC The directory containing all sources. e.g.
+#* '$(TOP)/src'
+#*
+#* OBJ_DIR The location where compiled object files will be
+#* placed, e.g. '$(TOP)/obj'
+#*
+#* LIB_DIR The location where the resulting library file will be
+#* placed, e.g. '$(TOP)/obj'
+#*
+#* LIBRARY The filename of the resulting library file, without
+#* its extension.. e.g. 'libfreetype' or 'freetype'
+#*
+#* O The object file suffix. Can be '.o', '.obj,' '.lo,'
+#* ';coff,' etc.
+#*
+#* A The library file suffix. Can be '.a' '.so,' '.lib'
+#* '.dll,' etc.
+#*
+#* I The path inclusion flag. Some compilers use a
+#* different flag than '-I' to specify an additional
+#* include path. Examples are '/i=' or '-J ', etc.
+#*
+#* D The macro definition flag. I haven't met compilers
+#* which don't use the '-D' switch to define a macro, but
+#* who knows...
+#*
+#* T The compilation flag used to identify the target. Some
+#* compilers use a different flag than '-o ' to specify
+#* the name of the target object file.
+#*
+#* CFLAGS The set of flags used to compile object files.
+#* (usually contains the flag '-c').
+#*
+#*
+#*
+#*******************************************************************
+
+ifndef TOP
+TOP := .
+endif
+
+DELETE := del
+SEP := /
+BUILD := $(TOP)$(SEP)config$(SEP)win32
+PLATFORM := win32
+CC := lcc
+
+# the directory where all object files are placed
+#
+OBJ_DIR := $(TOP)$(SEP)obj
+
+
+# the directory where all library files are placed
+#
+# by default, this is the same as OBJ_DIR, however, this can be
+# changed to suit particular needs..
+#
+LIB_DIR := $(OBJ_DIR)
+
+
+# the object file extension, this can be .o, .tco, .obj, etc..
+# depending on the platform
+#
+O := obj
+
+# the library file extension, this can be .a, .lib, etc..
+# depending on the platform
+#
+A := lib
+
+
+# The name of the final library file.
+# Note that the DOS-specific Makefile uses a shorter (8.3) name
+#
+LIBRARY := freetype
+
+
+# path inclusion flag.
+#
+# Some compilers use a different flag than '-I' to specify an
+# additional include path. Examples are "/i=" or "-J", etc...
+#
+I := -I
+
+
+# C flag used to define a macro before the compilation of a given
+# source object. Usually is '-D' like in "-DDEBUG"
+#
+D := -D
+
+
+# Target flag - LCC uses "-Fo" instead of "-o ", what a broken compiler
+#
+#
+T := -Fo
+
+# The link flag used to specify a given library file on link.
+# Note that this is only used to compile the demo programs, not
+# the library itself.
+#
+L := -Fl
+
+
+
+# C flags
+#
+# These should concern :
+#
+# - debug output
+# - optimization
+# - warnings
+# - ansi compliance..
+#
+ifndef CFLAGS
+CFLAGS := -c -g2 -O
+endif
+
+ifdef BUILD_FREETYPE
+
+include $(TOP)/config/freetype.mk
+
+# This final rule is used to link all object files into a single
+# library. It is part of the system-specific sub-Makefile because not
+# all librarians accept a simple syntax like :
+#
+# librarian library_file {list of object files}
+#
+# The LCC-Win32 Librarian, called LCCLIB needs all object files in the current
+# directory. That _is_ stupid, but we'll have to deal with it..
+#
+
+DIR_OBJ := $(subst /,\\,$(OBJ_DIR))
+
+$(FT_LIBRARY): $(OBJECTS_LIST)
+ @$(TOP)/config/win32/lcclib.bat
+
+endif
+
+
--- /dev/null
+++ b/config/win32/Makefile.vcc
@@ -1,0 +1,174 @@
+#*******************************************************************
+#*
+#* FreeType 2 Configuration rules for Visual C++ on Win32
+#*
+#* 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 purpose of this sub-Makefile is to define various build and
+#* platform specific variables before including the sub-Makefile
+#* containing the FreeType library rules, found in
+#*
+#* $(TOP)/config/freetype.mk
+#*
+#* The following variables must be defined before including this
+#* file :
+#*
+#* TOP Pathname to the top of the FreeType sources
+#* hierarchy
+#*
+#* This file should define the following variables before including
+#* the FreeType library rules file :
+#*
+#* BUILD Pathname to the platform-specific files used
+#* for the build. Usually `$(TOP)/config/<system>'
+#*
+#* SEP Directory separator for the current platform.
+#* Either / or \ (maybe : on Macs)
+#*
+#* DELETE The forced remove/delete command to erase one or more
+#* files
+#*
+#* INCLUDE The location of all public header files. e.g.
+#* `$(TOP)/include'include' *
+#*
+#* SRC The directory containing all sources. e.g.
+#* '$(TOP)/src'
+#*
+#* OBJ_DIR The location where compiled object files will be
+#* placed, e.g. '$(TOP)/obj'
+#*
+#* LIB_DIR The location where the resulting library file will be
+#* placed, e.g. '$(TOP)/obj'
+#*
+#* LIBRARY The filename of the resulting library file, without
+#* its extension.. e.g. 'libfreetype' or 'freetype'
+#*
+#* O The object file suffix. Can be '.o', '.obj,' '.lo,'
+#* ';coff,' etc.
+#*
+#* A The library file suffix. Can be '.a' '.so,' '.lib'
+#* '.dll,' etc.
+#*
+#* I The path inclusion flag. Some compilers use a
+#* different flag than '-I' to specify an additional
+#* include path. Examples are '/i=' or '-J ', etc.
+#*
+#* D The macro definition flag. I haven't met compilers
+#* which don't use the '-D' switch to define a macro, but
+#* who knows...
+#*
+#* T The compilation flag used to identify the target. Some
+#* compilers use a different flag than '-o ' to specify
+#* the name of the target object file.
+#*
+#* CFLAGS The set of flags used to compile object files.
+#* (usually contains the flag '-c').
+#*
+#*
+#*
+#*******************************************************************
+
+DELETE := del
+SEP := /
+BUILD := $(TOP)$(SEP)config$(SEP)win32
+PLATFORM := win32
+CC := cl
+
+# the directory where all object files are placed
+#
+OBJ_DIR := $(TOP)$(SEP)obj
+
+
+# the directory where all library files are placed
+#
+# by default, this is the same as OBJ_DIR, however, this can be
+# changed to suit particular needs..
+#
+LIB_DIR := $(OBJ_DIR)
+
+
+# the object file extension, this can be .o, .tco, .obj, etc..
+# depending on the platform
+#
+O := obj
+
+# the library file extension, this can be .a, .lib, etc..
+# depending on the platform
+#
+A := lib
+
+
+# The name of the final library file.
+# Note that the DOS-specific Makefile uses a shorter (8.3) name
+#
+LIBRARY := freetype
+
+
+# path inclusion flag.
+#
+# Some compilers use a different flag than '-I' to specify an
+# additional include path. Examples are "/i=" or "-J", etc...
+#
+I := /I
+
+
+# The link flag used to specify a given library file on link.
+# Note that this is only used to compile the demo programs, not
+# the library itself.
+#
+L := /Fl
+
+
+# C flag used to define a macro before the compilation of a given
+# source object. Usually is '-D' like in "-DDEBUG"
+#
+D := /D
+
+# Target flag - LCC uses "-Fo" instead of "-o ", what a broken compiler
+#
+#
+T := /Fo
+
+# C flags
+#
+# These should concern :
+#
+# - debug output
+# - optimization
+# - warnings
+# - ansi compliance..
+#
+ifndef CFLAGS
+CFLAGS := /nologo /c /Ox /G5 /Za /W3 /WX
+endif
+
+ifdef BUILD_FREETYPE
+
+include $(TOP)/config/freetype.mk
+
+# This final rule is used to link all object files into a single
+# library. It is part of the system-specific sub-Makefile because not
+# all librarians accept a simple syntax like :
+#
+# librarian library_file {list of object files}
+#
+# The LCC-Win32 Librarian, called LCCLIB needs all object files in the current
+# directory. That _is_ stupid, but we'll have to deal with it..
+#
+
+DIR_OBJ := $(subst /,\\,$(OBJ_DIR))
+
+$(FT_LIBRARY): $(OBJECTS_LIST)
+ lib /out:$@ $(OBJECTS_LIST)
+
+endif
+
+
--- /dev/null
+++ b/config/win32/detect.mk
@@ -1,0 +1,66 @@
+#
+# This file is used to detect a Win32 host platform.
+#
+# This configuration file to be used depends on the value of the CC
+# environment variable.
+#
+#
+
+# We test for the COMSPEC environment variable, then run the 'ver'
+# command-line program to see if its output contains the word "Windows"
+#
+# If this is true, we're running a win32 platform (or an emulation)
+#
+
+ifeq ($(PLATFORM),ansi)
+ifdef COMSPEC
+
+is_windows := $(findstring Windows,$(strip $(shell ver)))
+ifneq ($(is_windows),)
+
+PLATFORM := win32
+DELETE := del
+COPY := copy
+
+CONFIG_FILE := Makefile.gcc # gcc Makefile by default - aren't we biased ;-)
+SEP := /
+ifeq ($(CC),cc)
+CC := gcc
+endif
+
+ifneq ($(findstring visualc,$(MAKECMDGOALS)),) # Visual C/C++
+CONFIG_FILE := Makefile.vcc
+SEP := $(BACKSLASH)
+CC := cl
+visualc: setup
+endif
+
+ifneq ($(findstring watcom,$(MAKECMDGOALS)),) # Watcom C/C++
+CONFIG_FILE := Makefile.wat
+SEP := $(BACKSLASH)
+CC := wcc386
+watcom: setup
+endif
+
+ifneq ($(findstring visualage,$(MAKECMDGOALS)),) # Visual Age C++
+CONFIG_FILE := Makefile.icc
+SEP := $(BACKSLASH)
+CC := icc
+visualage: setup
+endif
+
+ifneq ($(findstring lcc,$(MAKECMDGOALS)),) # LCC-Win32
+CONFIG_FILE := Makefile.lcc
+SEP := $(BACKSLASH)
+CC := lcc
+lcc: setup
+endif
+
+CONFIG_RULES := $(TOP)\config\win32\$(CONFIG_FILE)
+
+setup: dos_setup
+
+endif #test Windows
+endif #test COMSPEC
+endif #test PLATFORM
+
--- /dev/null
+++ b/config/win32/ftconfig.h
@@ -1,0 +1,182 @@
+/***************************************************************************/
+/* */
+/* ftconfig.h */
+/* */
+/* ANSI-specific configuration file (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. */
+/* */
+/***************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* This header file contains a number of macro definitions that are used */
+ /* by the rest of the engine. Porters are free to copy this file and */
+ /* adapt it to suit their own system. */
+ /* */
+ /* IMPORTANT NOTE: */
+ /* */
+ /* Porters, read carefully the comments in `ftsys.h' before trying to */
+ /* port this file to your system. It contains many essential */
+ /* remarks, and will ease your work greatly. */
+ /* */
+ /*************************************************************************/
+
+
+#ifndef FTCONFIG_H
+#define FTCONFIG_H
+
+/* Include the header file containing all developer build options */
+#include <ftoption.h>
+
+ /*************************************************************************/
+ /* */
+ /* PLATFORM-SPECIFIC CONFIGURATION MACROS */
+ /* */
+ /* These macros can be toggled to suit a specific system. The current */
+ /* ones are defaults used to compile FreeType in an ANSI C environment */
+ /* (16bit compilers are also supported). Copy this file to your own */
+ /* `freetype/arch/<system>' directory, and edit it to port the engine. */
+ /* */
+ /*************************************************************************/
+
+
+/* Define to empty if the keyword does not work. */
+/* #undef const */
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* We use <limits.h> values to know the sizes of the types. */
+#include <limits.h>
+
+/* The number of bytes in an `int' type. */
+#if UINT_MAX == 0xFFFFFFFF
+#define SIZEOF_INT 4
+#elif UINT_MAX == 0xFFFF
+#define SIZEOF_INT 2
+#elif UINT_MAX > 0xFFFFFFFF && UINT_MAX == 0xFFFFFFFFFFFFFFFF
+#define SIZEOF_INT 8
+#else
+#error "Unsupported number of bytes in `int' type!"
+#endif
+
+/* The number of bytes in a `long' type. */
+#if ULONG_MAX == 0xFFFFFFFF
+#define SIZEOF_LONG 4
+#elif ULONG_MAX > 0xFFFFFFFF && ULONG_MAX == 0xFFFFFFFFFFFFFFFF
+#define SIZEOF_LONG 8
+#else
+#error "Unsupported number of bytes in `long' type!"
+#endif
+
+/* Define if you have the memcpy function. */
+#define HAVE_MEMCPY 1
+
+/* Define if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 0
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 0
+
+
+/* Preferred alignment of data */
+#define FT_ALIGNMENT 8
+
+
+
+ /*************************************************************************/
+ /* */
+ /* AUTOMATIC CONFIGURATION MACROS */
+ /* */
+ /* These macros are computed from the ones defined above. Don't touch */
+ /* their definition, unless you know precisely what you're doing. No */
+ /* porter should need to mess with them. */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* IntN types */
+ /* */
+ /* Used to guarantee the size of some specific integers. */
+ /* */
+ typedef signed short FT_Int16;
+ typedef unsigned short FT_Word16;
+
+#if SIZEOF_INT == 4
+
+ typedef signed int FT_Int32;
+ typedef unsigned int FT_Word32;
+
+#elif SIZEOF_LONG == 4
+
+ typedef signed long FT_Int32;
+ typedef unsigned long FT_Word32;
+
+#else
+#error "no 32bit type found - please check your configuration files"
+#endif
+
+#if SIZEOF_LONG == 8
+
+ /* LONG64 must be defined when a 64-bit type is available */
+#define LONG64
+#define INT64 long
+
+#else
+
+
+ /*************************************************************************/
+ /* */
+ /* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */
+ /* it by defining the FTCALC_USE_LONG_LONG macro in `ftconfig.h'. Note */
+ /* that this will produce many -ansi warnings during library */
+ /* compilation. */
+ /* */
+#ifdef FTCALC_USE_LONG_LONG
+
+#define LONG64
+#define INT64 long long
+
+#endif /* FTCALC_USE_LONG_LONG */
+#endif
+
+
+#ifdef FT_MAKE_OPTION_SINGLE_OBJECT
+#define LOCAL_DEF static
+#define LOCAL_FUNC static
+#else
+#define LOCAL_DEF extern
+#define LOCAL_FUNC /* nothing */
+#endif
+
+#ifdef FT_MAKE_OPTION_SINGLE_LIBRARY_OBJECT
+#define BASE_DEF LOCAL_DEF
+#define BASE_FUNC LOCAL_FUNC
+#else
+#define BASE_DEF extern
+#define BASE_FUNC /* nothing */
+#endif
+
+#ifndef EXPORT_DEF
+#define EXPORT_DEF extern
+#endif
+
+#ifndef EXPORT_FUNC
+#define EXPORT_FUNC /* nothing */
+#endif
+
+#endif /* FTCONFIG_H */
+
+
+/* END */
--- /dev/null
+++ b/config/win32/ftoption.h
@@ -1,0 +1,162 @@
+#ifndef FTOPTION_H
+#define FTOPTION_H
+
+ /*************************************************************************/
+ /* */
+ /* USER-SELECTABLE CONFIGURATION MACROS */
+ /* */
+ /* These macros can be toggled by developers to enable or disable */
+ /* certain aspects of FreeType. This file contains macros that apply to */
+ /* all of FreeType. Driver-specific configurations are placed in each */
+ /* driver directory (e.g. `freetype/drivers/ttlib/ttconfig.h'). */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* Alternate Glyph Image Format support */
+ /* */
+ /* By default, the glyph images returned by the FreeType glyph loader */
+ /* can either be a pixmap or a vectorial outline defined through */
+ /* bezier control points. When defining the following configuration */
+ /* macro, some font drivers will be able to register alternate */
+ /* glyph image formats. */
+ /* */
+ /* Unset this macro if you're sure that you'll never use a font driver */
+ /* with an alternate glyph format, this will reduce the size of the */
+ /* base layer code. */
+ /* */
+#define FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS
+
+ /*************************************************************************/
+ /* */
+ /* GCC provides the non-ANSI `long long' 64-bit type. You can activate */
+ /* it by defining the FTCALC_USE_LONG_LONG macro here. Note however */
+ /* that we did not experience any improvement in speed with gcc, and */
+ /* that the final code seems bigger when linked. */
+ /* */
+#undef FTCALC_USE_LONG_LONG
+
+
+ /*************************************************************************/
+ /* */
+ /* When compiling FreeType as a DLL, some systems/compilers need a */
+ /* special keyword in front of each function definition instead of */
+ /* `extern'. */
+ /* */
+ /* The macros EXPORT_DEF and EXPORT_FUNC are thus used to define */
+ /* exported library function interfaces and exported library functions */
+ /* implementations respectively. */
+ /* */
+ /* If not defined here, they automatically default to `extern' and void */
+ /* later in this header file. */
+ /* */
+#undef EXPORT_DEF
+#undef EXPORT_FUNC
+
+
+ /*************************************************************************/
+ /* */
+ /* Debug level */
+ /* */
+ /* FreeType can be compiled in debug or trace mode. In debug mode, */
+ /* errors are reported through the `ftdebug' component. In trace */
+ /* mode, additional messages are sent to the standard output during */
+ /* execution. */
+ /* */
+ /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */
+ /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */
+ /* */
+ /* Don't define any of these macros to compile in `release' mode. */
+ /* */
+#undef FT_DEBUG_LEVEL_ERROR
+#undef FT_DEBUG_LEVEL_TRACE
+
+
+ /*************************************************************************/
+ /* */
+ /* Anti-aliasing support */
+ /* */
+ /* Undefine this macro only if you want to disable the anti-aliasing */
+ /* support in FreeType. This will save you about 5 Kb of code. It */
+ /* may be important for some embedded systems. */
+ /* */
+#define FT_CONFIG_OPTION_ANTI_ALIAS
+
+
+ /*************************************************************************/
+ /* */
+ /* Endianess performance improvement */
+ /* */
+ /* FreeType is completely endian-independent, and can thus be compiled */
+ /* directly on _any_ machine. However, some components of the library */
+ /* provide improved routines for the cases where endianess is known. */
+ /* */
+ /* It usually results in speed-ups and reduced code size. Note that */
+ /* you should not define both of these macros. */
+ /* */
+ /* */
+ /* NOTE: For now, only the scan-line converter (base/ftraster.c) uses */
+ /* these macros to speed-up some anti-alias rendering routines. */
+ /* */
+#undef FT_CONFIG_OPTION_LITTLE_ENDIAN
+#undef FT_CONFIG_OPTION_BIG_ENDIAN
+
+
+ /*************************************************************************/
+ /* */
+ /* Define this configuration macro whenever you want to build a version */
+ /* of FreeType that does not include a default `system' component. */
+ /* */
+ /* Note that this will prevent the compilation of `ftinit', hence the */
+ /* function FT_Init_FreeType */
+ /* */
+#undef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
+
+
+ /*************************************************************************/
+ /* */
+ /* The size in bytes of the render pool used by the scan-line */
+ /* converter to do all of its work. */
+ /* */
+ /* This must be greater than 4 Kb */
+ /* */
+#define FT_RENDER_POOL_SIZE 32768
+
+
+ /*************************************************************************/
+ /* */
+ /* FT_MAX_DRIVERS */
+ /* */
+ /* The maximum number of font drivers that can be registered in a */
+ /* single FreeType library object. 8 seems to be a good choice due */
+ /* to the relative low actual number of drivers ;-) */
+ /* */
+#define FT_MAX_DRIVERS 8
+
+
+ /*************************************************************************/
+ /* */
+ /* FT_MAX_EXTENSIONS */
+ /* */
+ /* The maximum number of extensions that can be registered in a */
+ /* single font driver. 8 seems to be a good choice for now.. */
+ /* */
+#define FT_MAX_EXTENSIONS 8
+
+
+ /*************************************************************************/
+ /* */
+ /* FT_MAX_GLYPH_FORMATS */
+ /* */
+ /* The maximum number of glyph image formats that might be registered */
+ /* in a given library instance. 8 seems to be a good choice due to */
+ /* the relatively low number of current formats ;-) */
+ /* */
+
+#define FT_MAX_GLYPH_FORMATS 8
+
+
+
+#endif /* FTOPTION_H */
--- /dev/null
+++ b/config/win32/ftsystem.c
@@ -1,0 +1,214 @@
+/**************************************************************************
+ *
+ * ftsystem.h 1.0
+ *
+ * ANSI-specific FreeType low-level system interface
+ *
+ * This file contains the definition of interface used by FreeType
+ * to access low-level, i.e. memory management, i/o access as well
+ * as thread synchronisation.
+ *
+ *
+ * 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 <ftsystem.h>
+#include <fterrors.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+ /*********************************************************************/
+ /* */
+ /* MEMORY MANAGEMENT INTERFACE */
+ /* */
+
+/************************************************************************
+ *
+ * <FuncType>
+ * FT_Alloc_Func
+ *
+ * <Description>
+ * The memory allocator function type
+ *
+ * <Input>
+ * system :: pointer to the system object
+ * size :: requested size in bytes
+ *
+ * <Output>
+ * block :: address of newly allocated block
+ *
+ * <Return>
+ * Error code. 0 means success.
+ *
+ * <Note>
+ * If your allocation routine ALWAYS zeroes the new block, you
+ * should set the flag FT_SYSTEM_FLAG_ALLOC_ZEROES in your system
+ * object 'flags' field.
+ *
+ * If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ * your system's "system_flags" field, this function should update
+ * the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+ static
+ void* ft_alloc( FT_Memory memory,
+ long size )
+ {
+ (void)memory;
+ return malloc(size);
+ }
+
+
+/************************************************************************
+ *
+ * <FuncType>
+ * FT_Realloc_Func
+ *
+ * <Description>
+ * The memory reallocator function type
+ *
+ * <Input>
+ * system :: pointer to the system object
+ * new_size :: new requested size in bytes
+ *
+ * <InOut>
+ * block :: address of block in memory
+ *
+ * <Return>
+ * Error code. 0 means success.
+ *
+ * <Note>
+ * This function is _never_ called when the system flag
+ * FT_SYSTEM_FLAG_NO_REALLOC is set. Instead, the engine will emulate
+ * realloc through "alloc" and "free".
+ *
+ * Note that this is possible due to the fact that FreeType's
+ * "FT_Realloc" always requests the _current_ size of the reallocated
+ * block as a parameter, thus avoiding memory leaks.
+ *
+ * If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ * your system's "system_flags" field, this function should update
+ * the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+ static
+ void* ft_realloc( FT_Memory memory,
+ long cur_size,
+ long new_size,
+ void* block )
+ {
+ (void)memory;
+ (void)cur_size;
+
+ return realloc( block, new_size );
+ }
+
+
+/************************************************************************
+ *
+ * <FuncType>
+ * FT_Free_Func
+ *
+ * <Description>
+ * The memory release function type
+ *
+ * <Input>
+ * system :: pointer to the system object
+ * block :: address of block in memory
+ *
+ * <Note>
+ * If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ * your system's "system_flags" field, this function should update
+ * the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+ static
+ void ft_free( FT_Memory memory,
+ void* block )
+ {
+ (void)memory;
+ free( block );
+ }
+
+ /*********************************************************************/
+ /* */
+ /* RESOURCE MANAGEMENT INTERFACE */
+ /* */
+
+
+#define STREAM_FILE(stream) ((FILE*)stream->descriptor.pointer)
+
+ static
+ void ft_close_stream( FT_Stream stream )
+ {
+ fclose( STREAM_FILE(stream) );
+ }
+
+ static
+ unsigned long ft_io_stream( FT_Stream stream,
+ unsigned long offset,
+ char* buffer,
+ unsigned long count )
+ {
+ FILE* file;
+
+ file = STREAM_FILE(stream);
+
+ fseek( file, offset, SEEK_SET );
+ return (unsigned long)fread( buffer, count, 1, file );
+ }
+
+
+ extern
+ int FT_New_Stream( const char* filepathname,
+ FT_Stream stream )
+ {
+ FILE* file;
+
+ file = fopen( filepathname, "rb" );
+ if (!file)
+ return FT_Err_Cannot_Open_Resource;
+
+ fseek( file, 0, SEEK_END );
+ stream->size = ftell(file);
+ fseek( file, 0, SEEK_SET );
+
+ stream->descriptor.pointer = file;
+ stream->pos = 0;
+
+ stream->read = ft_io_stream;
+ stream->close = ft_close_stream;
+
+ return 0;
+ }
+
+
+ extern
+ FT_Memory FT_New_Memory( void )
+ {
+ FT_Memory memory;
+
+ memory = (FT_Memory)malloc( sizeof(*memory) );
+ if (memory)
+ {
+ memory->user = 0;
+ memory->alloc = ft_alloc;
+ memory->realloc = ft_realloc;
+ memory->free = ft_free;
+ }
+ return memory;
+ }
+
--- /dev/null
+++ b/config/win32/lcclib.bat
@@ -1,0 +1,12 @@
+@cd obj
+@LCCLIB /out:freetype.lib *.obj
+@echo The library file `obj/freetype.lib' was generated.
+@exit 0
+
+; the LCC Librarian has many flaws, one of them is that it *requires* that
+; all object files be placed in the current directory. Another flaw is that
+; it cannot accept a long list of object files.
+;
+; this file is used to build the library file `obj/freetype.lib'
+;
+
--- /dev/null
+++ b/demos/Makefile
@@ -1,0 +1,227 @@
+.PHONY: exes
+all: exes
+
+####################################################################
+#
+# TOP is the directory where the main FreeType source is found,
+# as well as the 'config.mk' file
+#
+
+ifndef TOP
+TOP := ..
+endif
+
+####################################################################
+#
+# Check that we have a working `config.mk' in the above directory.
+# If not, issue a warning message, then stop there..
+#
+ifeq ($(wildcard $(TOP)/config.mk),)
+no_config_mk := 1
+endif
+
+ifdef no_config_mk
+
+exes:
+ @echo Please compile the library before the demo programs !!
+
+else
+
+####################################################################
+#
+# Good, now include the `config.mk' in order to know how to build
+# object files from sources, as well as other things (compiler flags)
+#
+include ../config.mk
+
+####################################################################
+#
+# Detect DOS-like platforms, currently DOS, Win 3.1, Win32 & OS/2
+#
+#
+ifneq ($(findstring $(PLATFORM),os2 win16 win32 dos),)
+DOSLIKE := 1
+endif
+
+
+###################################################################
+#
+# Clean-up rules. Because the `del' command on DOS-like platforms
+# cannot take a long list of arguments, we simply erase the directory
+# contents..
+#
+.PHONY: clean distclean
+
+ifdef DOSLIKE
+clean_demo:
+ -del obj\*.$O
+ -del src\*.bak
+
+distclean_demo: clean_demo
+ -del obj\*.*
+ -del bin\*.exe
+else
+clean_demo:
+ -$(DELETE) $(OBJ_)*.$O
+ -$(DELETE) $(SRC_)*.bak graph$(SEP)*.bak
+ -$(DELETE) $(SRC_)*~ graph$(SEP)*~
+
+
+distclean_demo: clean_demo
+ -$(DELETE) $(BIN_)*
+endif
+
+clean: clean_demo
+distclean: distclean_demo
+
+####################################################################
+#
+# Define a few important variables now
+#
+#
+TOP_ := $(TOP)$(SEP)
+SRC_ := $(TOP)$(SEP)src$(SEP)
+
+BIN_ := bin$(SEP)
+OBJ_ := obj$(SEP)
+
+GRAPH_DIR := graph
+
+SRC_DIR := src
+SRC_DIR_ := $(SRC_DIR)$(SEP)
+
+
+FT_INCLUDES := $(BUILD) $(TOP_)include $(SRC_)base
+TT_INCLUDES := $(SRC_)shared $(SRC_)truetype
+T1_INCLUDES := $(SRC_)shared $(SRC_)type1
+
+CFLAGS = -c -O0 -g $(INCLUDES:%=$I%) -Wall -W -ansi
+CC := $(CC)
+LINK := $(CC)
+FTLIB := $(LIB_DIR)$(SEP)$(LIBRARY).$A
+
+
+####################################################################
+#
+# Compute the executable suffix to use, and put it in `E'.
+# It is ".exe" on DOS-ish platforms, and nothing otherwise
+#
+ifdef DOSLIKE
+E := .exe
+else
+E :=
+endif
+
+###################################################################
+#
+# The list of demonstration programs to build.
+#
+EXES := ftlint t1dump ftview fttimer
+
+ifneq ($(findstring $(PLATFORM),os2 unix),)
+EXES += ttdebug
+endif
+
+###################################################################
+#
+# Include the rules needed to compile the graphics sub-system.
+# This will also select which graphics driver to compile to the
+# sub-system..
+#
+include $(GRAPH_DIR)/rules.mk
+
+exes: $(EXES:%=$(BIN_)%$E)
+
+
+INCLUDES := $(FT_INCLUDES)
+
+####################################################################
+#
+# Rules for compiling object files for text-only demos
+#
+
+COMMON_OBJ := $(OBJ_)common.o
+$(COMMON_OBJ): $(SRC_DIR_)common.c
+ $(CC) $(CFLAGS) $T$@ $<
+
+$(OBJ_)%.$O: $(SRC_DIR_)%.c $(FTLIB)
+ $(CC) $(CFLAGS) $T$@ $<
+
+$(OBJ_)ftlint.$O: $(SRC_DIR_)ftlint.c
+ $(CC) $(CFLAGS) $T$@ $<
+
+$(OBJ_)fttry.$O: $(SRC_DIR_)fttry.c
+ $(CC) $(CFLAGS) $T$@ $<
+
+
+$(OBJ_)ftview.$O: $(SRC_DIR_)ftview.c $(GRAPH_LIB)
+ $(CC) $(CFLAGS) $(GRAPH_INCLUDES:%=$I%) $T$@ $<
+
+$(OBJ_)fttimer.$O: $(SRC_DIR_)fttimer.c $(GRAPH_LIB)
+ $(CC) $(CFLAGS) $(GRAPH_INCLUDES:%=$I%) $T$@ $<
+
+#$(OBJ_)ftsbit.$O: $(SRC_DIR)/ftsbit.c $(GRAPH_LIB)
+# $(CC) $(CFLAGS) $T$@ $<
+
+
+####################################################################
+#
+# Special rule to compile the `t1dump' program as it includes
+# the Type1 source path
+#
+$(OBJ_)t1dump.$O: $(SRC_DIR)/t1dump.c
+ $(CC) $(CFLAGS) $(T1_INCLUDES:%=$I%) $T$@ $<
+
+
+####################################################################
+#
+# Special rule to compile the `ttdebug' program as it includes
+# the TrueType source path and needs extra flags for correct keyboard
+# handling on Unix
+#
+
+# POSIX TERMIOS: Do not define if you use OLD U*ix like 4.2BSD.
+#
+# detect a Unix system
+ifeq ($(PLATFORM),unix)
+EXTRAFLAGS = $DUNIX $DHAVE_POSIX_TERMIOS
+endif
+
+$(OBJ_)ttdebug.$O: $(SRC_DIR)/ttdebug.c
+ $(CC) $(CFLAGS) $(TT_INCLUDES:%=$I%) $T$@ $< $(EXTRAFLAGS)
+
+
+####################################################################
+#
+# Rules used to link the executables. Note that they could be
+# over-ridden by system-specific things..
+#
+
+$(BIN_)ftlint$E: $(OBJ_)ftlint.$O $(FTLIB)
+ $(LINK) $(LFLAGS) $T$@ $< $(FTLIB) $(EFENCE)
+
+
+$(BIN_)fttry$E: $(OBJ_)fttry.$O $(FTLIB)
+ $(LINK) $(LFLAGS) $T$@ $< $(FTLIB) $(EFENCE)
+
+
+$(BIN_)ftsbit$E: $(OBJ_)ftsbit.$O $(FTLIB)
+ $(LINK) $(LFLAGS) $T$@ $< $(FTLIB) $(EFENCE)
+
+
+$(BIN_)t1dump$E: $(OBJ_)t1dump.$O $(FTLIB)
+ $(LINK) $(LFLAGS) $T$@ $< $(FTLIB) $(EFENCE)
+
+$(BIN_)ttdebug$E: $(OBJ_)ttdebug.$O $(FTLIB)
+ $(LINK) $(LFLAGS) $T$@ $< $(FTLIB) $(EFENCE)
+
+
+$(BIN_)ftview$E: $(OBJ_)ftview.$O $(FTLIB) $(GRAPH_LIB) $(COMMON_OBJ)
+ $(LINK) $(LFLAGS) $T$@ $< $(FTLIB) $(GRAPH_LINK) $(COMMON_OBJ) $(EFENCE)
+
+$(BIN_)fttimer$E: $(OBJ_)fttimer.$O $(FTLIB) $(GRAPH_LIB) $(COMMON_OBJ)
+ $(LINK) $(LFLAGS) $T$@ $< $(FTLIB) $(GRAPH_LINK) $(EFENCE)
+
+endif
+
+
--- /dev/null
+++ b/demos/config/os2/gros2pm.c
@@ -1,0 +1,887 @@
+#include "gros2pm.h"
+#include "grdevice.h"
+
+#define INCL_DOS
+#define INCL_WIN
+#define INCL_GPI
+#define INCL_SUB
+
+#include <os2.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+
+ static void Panic( const char* message )
+ {
+ fprintf( stderr, "%s", message );
+ exit(1);
+ }
+
+ typedef struct Translator
+ {
+ ULONG os2key;
+ grKey grkey;
+
+ } Translator;
+
+
+ static
+ Translator key_translators[] =
+ {
+ { VK_BACKSPACE, grKeyBackSpace },
+ { VK_TAB, grKeyTab },
+ { VK_ENTER, grKeyReturn },
+ { VK_ESC, grKeyEsc },
+ { VK_HOME, grKeyHome },
+ { VK_LEFT, grKeyLeft },
+ { VK_UP, grKeyUp },
+ { VK_RIGHT, grKeyRight },
+ { VK_DOWN, grKeyDown },
+ { VK_PAGEUP, grKeyPageUp },
+ { VK_PAGEDOWN, grKeyPageDown },
+ { VK_END, grKeyEnd },
+ { VK_F1, grKeyF1 },
+ { VK_F2, grKeyF2 },
+ { VK_F3, grKeyF3 },
+ { VK_F4, grKeyF4 },
+ { VK_F5, grKeyF5 },
+ { VK_F6, grKeyF6 },
+ { VK_F7, grKeyF7 },
+ { VK_F8, grKeyF8 },
+ { VK_F9, grKeyF9 },
+ { VK_F10, grKeyF10 },
+ { VK_F11, grKeyF11 },
+ { VK_F12, grKeyF12 }
+ };
+
+
+#define MAX_PIXEL_MODES 32
+
+ static int num_pixel_modes = 0;
+ static grPixelMode pixel_modes[ MAX_PIXEL_MODES ];
+ static int pixel_depth[ MAX_PIXEL_MODES ];
+
+ static HAB gr_anchor; /* device anchor block */
+
+ typedef POINTL PMBlitPoints[4];
+
+
+ typedef struct grPMSurface_
+ {
+ grSurface root;
+ grBitmap image;
+
+ HAB anchor; /* handle to anchor block for surface's window */
+ HWND frame_window; /* handle to window's frame */
+ HWND client_window; /* handle to window's client */
+ HWND title_window; /* handle to window's title bar */
+
+ HPS image_ps; /* memory presentation space used to hold */
+ /* the surface's content under PM */
+ HDC image_dc; /* memory device context for the image */
+
+ HEV event_lock; /* semaphore used in listen_surface */
+ HMTX image_lock; /* a mutex used to synchronise access */
+ /* to the memory presentation space */
+ /* used to hold the surface */
+
+ TID message_thread; /* thread used to process this surface's */
+ /* messages.. */
+
+ PBITMAPINFO2 bitmap_header;/* os/2 bitmap descriptor */
+ HBITMAP os2_bitmap; /* Handle to OS/2 bitmap contained in image */
+ BOOL ready; /* ??? */
+
+ long shades[256]; /* indices of gray levels in pixel_mode_gray */
+
+ POINTL surface_blit[4]; /* surface blitting table */
+ POINTL magnify_blit[4]; /* magnifier blitting table */
+ int magnification; /* level of magnification */
+ POINTL magnify_center;
+ SIZEL magnify_size;
+
+ grEvent event;
+
+ PMBlitPoints blit_points;
+
+ } grPMSurface;
+
+
+
+ static
+ void enable_os2_iostreams( void )
+ {
+ 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;
+ }
+
+
+
+ static
+ int init_device( void )
+ {
+ enable_os2_iostreams();
+
+ /* create an anchor block. This will allow this thread (i.e. the */
+ /* main one) to call Gpi functions.. */
+ gr_anchor = WinInitialize(0);
+ if (!gr_anchor)
+ {
+ /* could not initialise Presentation Manager */
+ return -1;
+ }
+
+ return 0;
+ }
+
+
+
+ static
+ void done_device( void )
+ {
+ /* Indicates that we do not use the Presentation Manager, this */
+ /* will also release all associated resources.. */
+ WinTerminate( gr_anchor );
+ }
+
+
+
+ /* close a given window */
+ static
+ void done_surface( grPMSurface* surface )
+ {
+ if ( surface->frame_window )
+ WinDestroyWindow( surface->frame_window );
+
+ WinReleasePS( surface->image_ps );
+
+ grDoneBitmap( &surface->image );
+ grDoneBitmap( &surface->root.bitmap );
+ }
+
+
+
+
+
+ static
+ void add_pixel_mode( grPixelMode pixel_mode,
+ int depth )
+ {
+ if ( num_pixel_modes >= MAX_PIXEL_MODES )
+ Panic( "X11.Too many pixel modes\n" );
+
+ pixel_modes[ num_pixel_modes ] = pixel_mode;
+ pixel_depth[ num_pixel_modes ] = depth;
+
+ num_pixel_modes++;
+ }
+
+
+#define LOCK(x) DosRequestMutexSem( x, SEM_INDEFINITE_WAIT );
+#define UNLOCK(x) DosReleaseMutexSem( x )
+
+
+ static
+ const int pixel_mode_bit_count[] =
+ {
+ 0,
+ 1, /* mono */
+ 4, /* pal4 */
+ 8, /* pal8 */
+ 8, /* grays */
+ 15, /* rgb15 */
+ 16, /* rgb16 */
+ 24, /* rgb24 */
+ 32 /* rgb32 */
+ };
+
+
+ /************************************************************************
+ *
+ * Technical note : how the OS/2 Presntation Manager driver works
+ *
+ * PM is, in my opinion, a bloated and over-engineered graphics
+ * sub-system, even though it has lots of nice features. Here are
+ * a few tidbits about it :
+ *
+ *
+ * - under PM, a "bitmap" is a device-specific object whose bits are
+ * not directly accessible to the client application. This means
+ * that we must use a scheme like the following to display our
+ * surfaces :
+ *
+ * - hold, for each surface, its own bitmap buffer where the
+ * rest of MiGS writes directly.
+ *
+ * - create a PM bitmap object with the same dimensions (and
+ * possibly format).
+ *
+ * - copy the content of each updated rectangle into the
+ * PM bitmap with the function 'GpiSetBitmapBits'.
+ *
+ * - finally, "blit" the PM bitmap to the screen calling
+ * 'GpiBlitBlt'
+ *
+ * - but there is more : you cannot directly blit a PM bitmap to the
+ * screen with PM. The 'GpiBlitBlt' only works with presentation
+ * spaces. This means that we also need to create, for each surface :
+ *
+ * - a memory presentation space, used to hold the PM bitmap
+ * - a "memory device context" for the presentation space
+ *
+ * The blit is then performed from the memory presentation space
+ * to the screen's presentation space..
+ *
+ *
+ * - because each surface creates its own event-handling thread,
+ * we must protect the surface's presentation space from concurrent
+ * accesses (i.e. calls to 'GpiSetBitmapBits' when drawing to the
+ * surface, and calls to 'GpiBlitBlt' when drawing it on the screen
+ * are performed in two different threads).
+ *
+ * we use a simple mutex to do this.
+ *
+ *
+ * - we also use a semaphore to perform a rendez-vous between the
+ * main and event-handling threads (needed in "listen_event").
+ *
+ ************************************************************************/
+
+ static
+ void RunPMWindow( grPMSurface* surface );
+
+
+
+
+ static
+ void convert_gray_to_pal8( grPMSurface* surface,
+ int x,
+ int y,
+ int w,
+ int h )
+ {
+ grBitmap* target = &surface->image;
+ grBitmap* source = &surface->root.bitmap;
+ byte* write = (byte*)target->buffer + y*target->pitch + x;
+ byte* read = (byte*)source->buffer + y*source->pitch + x;
+ long* palette = surface->shades;
+
+ while (h > 0)
+ {
+ byte* _write = write;
+ byte* _read = read;
+ byte* limit = _write + w;
+
+ for ( ; _write < limit; _write++, _read++ )
+ *_write = (byte) palette[ *_read ];
+
+ write += target->pitch;
+ read += source->pitch;
+ h--;
+ }
+ }
+
+
+ static
+ void convert_gray_to_16( grPMSurface* surface,
+ int x,
+ int y,
+ int w,
+ int h )
+ {
+ grBitmap* target = &surface->image;
+ grBitmap* source = &surface->root.bitmap;
+ byte* write = (byte*)target->buffer + y*target->pitch + 2*x;
+ byte* read = (byte*)source->buffer + y*source->pitch + x;
+ long* palette = surface->shades;
+
+ while (h > 0)
+ {
+ byte* _write = write;
+ byte* _read = read;
+ byte* limit = _write + 2*w;
+
+ for ( ; _write < limit; _write += 2, _read++ )
+ *(short*)_write = (short)palette[ *_read ];
+
+ write += target->pitch;
+ read += source->pitch;
+ h--;
+ }
+ }
+
+
+ static
+ void convert_gray_to_24( grPMSurface* surface,
+ int x,
+ int y,
+ int w,
+ int h )
+ {
+ grBitmap* target = &surface->image;
+ grBitmap* source = &surface->root.bitmap;
+ byte* write = (byte*)target->buffer + y*target->pitch + 3*x;
+ byte* read = (byte*)source->buffer + y*source->pitch + x;
+
+ while (h > 0)
+ {
+ byte* _write = write;
+ byte* _read = read;
+ byte* limit = _write + 3*w;
+
+ for ( ; _write < limit; _write += 3, _read++ )
+ {
+ byte color = *_read;
+
+ _write[0] =
+ _write[1] =
+ _write[2] = color;
+ }
+
+ write += target->pitch;
+ read += source->pitch;
+ h--;
+ }
+ }
+
+
+ static
+ void convert_gray_to_32( grPMSurface* surface,
+ int x,
+ int y,
+ int w,
+ int h )
+ {
+ grBitmap* target = &surface->image;
+ grBitmap* source = &surface->root.bitmap;
+ byte* write = (byte*)target->buffer + y*target->pitch + 4*x;
+ byte* read = (byte*)source->buffer + y*source->pitch + x;
+
+ while (h > 0)
+ {
+ byte* _write = write;
+ byte* _read = read;
+ byte* limit = _write + 4*w;
+
+ for ( ; _write < limit; _write += 4, _read++ )
+ {
+ byte color = *_read;
+
+ _write[0] =
+ _write[1] =
+ _write[2] =
+ _write[3] = color;
+ }
+
+ write += target->pitch;
+ read += source->pitch;
+ h--;
+ }
+ }
+
+
+ static
+ void convert_rectangle( grPMSurface* surface,
+ int x,
+ int y,
+ int w,
+ int h )
+ {
+ int z;
+
+ /* first of all, clip to the surface's area */
+ if ( x >= surface->image.width ||
+ x+w <= 0 ||
+ y >= surface->image.rows ||
+ y+h <= 0 )
+ return;
+
+ if ( x < 0 )
+ {
+ w += x;
+ x = 0;
+ }
+
+ z = (x + w) - surface->image.width;
+ if (z > 0)
+ w -= z;
+
+ z = (y + h) - surface->image.rows;
+ if (z > 0)
+ h -= z;
+
+ /* convert the rectangle to the target depth for gray surfaces */
+ if (surface->root.bitmap.mode == gr_pixel_mode_gray)
+ {
+ switch (surface->image.mode)
+ {
+ case gr_pixel_mode_pal8 :
+ convert_gray_to_pal8( surface, x, y, w, h );
+ break;
+
+ case gr_pixel_mode_rgb555:
+ case gr_pixel_mode_rgb565:
+ convert_gray_to_16 ( surface, x, y, w, h );
+ break;
+
+ case gr_pixel_mode_rgb24:
+ convert_gray_to_24 ( surface, x, y, w, h );
+ break;
+
+ case gr_pixel_mode_rgb32:
+ convert_gray_to_32 ( surface, x, y, w, h );
+ break;
+
+ default:
+ ;
+ }
+ }
+ }
+
+
+ static
+ void refresh_rectangle( grPMSurface* surface,
+ int x,
+ int y,
+ int w,
+ int h )
+ {
+ convert_rectangle( surface, x, y, w, h );
+
+ WinInvalidateRect( surface->client_window, NULL, FALSE );
+ WinUpdateWindow( surface->frame_window );
+ }
+
+
+ static
+ void set_title( grPMSurface* surface,
+ const char* title )
+ {
+ WinSetWindowText( surface->title_window, (PSZ)title );
+ }
+
+
+
+ static
+ void listen_event( grPMSurface* surface,
+ int event_mask,
+ grEvent* grevent )
+ {
+ ULONG ulRequestCount;
+
+ (void) event_mask; /* ignored for now */
+
+ /* the listen_event function blocks until there is an event to process */
+ DosWaitEventSem( surface->event_lock, SEM_INDEFINITE_WAIT );
+ DosQueryEventSem( surface->event_lock, &ulRequestCount );
+ *grevent = surface->event;
+ DosResetEventSem( surface->event_lock, &ulRequestCount );
+
+ return;
+ }
+
+
+ static
+ grPMSurface* init_surface( grPMSurface* surface,
+ grBitmap* bitmap )
+ {
+ PBITMAPINFO2 bit;
+ SIZEL sizl = { 0, 0 };
+ LONG palette[256];
+
+ /* create the bitmap - under OS/2, we support all modes as PM */
+ /* handles all conversions automatically.. */
+ if ( grNewBitmap( bitmap->mode,
+ bitmap->grays,
+ bitmap->width,
+ bitmap->rows,
+ bitmap ) )
+ return 0;
+
+ surface->root.bitmap = *bitmap;
+
+ /* create the image and event lock */
+ DosCreateEventSem( NULL, &surface->event_lock, 0, TRUE );
+ DosCreateMutexSem( NULL, &surface->image_lock, 0, FALSE );
+
+ /* create the image's presentation space */
+ surface->image_dc = DevOpenDC( gr_anchor,
+ OD_MEMORY, (PSZ)"*", 0L, 0L, 0L );
+
+ surface->image_ps = GpiCreatePS( gr_anchor,
+ surface->image_dc,
+ &sizl,
+ PU_PELS | GPIT_MICRO |
+ GPIA_ASSOC | GPIF_DEFAULT );
+
+ GpiSetBackMix( surface->image_ps, BM_OVERPAINT );
+
+ /* create the image's PM bitmap */
+ bit = (PBITMAPINFO2)grAlloc( sizeof(BITMAPINFO2) + 256*sizeof(RGB2) );
+ surface->bitmap_header = bit;
+
+ bit->cbFix = sizeof( BITMAPINFOHEADER2 );
+ bit->cx = surface->root.bitmap.width;
+ bit->cy = surface->root.bitmap.rows;
+ bit->cPlanes = 1;
+
+ bit->argbColor[0].bBlue = 0;
+ bit->argbColor[0].bGreen = 0;
+ bit->argbColor[0].bRed = 0;
+
+ bit->argbColor[1].bBlue = 255;
+ bit->argbColor[1].bGreen = 255;
+ bit->argbColor[1].bRed = 255;
+
+ bit->cBitCount = pixel_mode_bit_count[ surface->root.bitmap.mode ];
+
+ surface->os2_bitmap = GpiCreateBitmap( surface->image_ps,
+ (PBITMAPINFOHEADER2)bit,
+ 0L, NULL, NULL );
+
+ GpiSetBitmap( surface->image_ps, surface->os2_bitmap );
+
+ bit->cbFix = sizeof( BITMAPINFOHEADER2 );
+ GpiQueryBitmapInfoHeader( surface->os2_bitmap,
+ (PBITMAPINFOHEADER2)bit );
+
+ /* for gr_pixel_mode_gray, create a gray-levels logical palette */
+ if ( bitmap->mode == gr_pixel_mode_gray )
+ {
+ int x, count;
+
+ count = bitmap->grays;
+ for ( x = 0; x < count; x++ )
+ palette[x] = (((count-x)*255)/count) * 0x010101;
+
+ /* create logical color table */
+ GpiCreateLogColorTable( surface->image_ps,
+ (ULONG) LCOL_PURECOLOR,
+ (LONG) LCOLF_CONSECRGB,
+ (LONG) 0L,
+ (LONG) count,
+ (PLONG) palette );
+
+ /* now, copy the color indexes to surface->shades */
+ for ( x = 0; x < count; x++ )
+ surface->shades[x] = GpiQueryColorIndex( surface->image_ps,
+ 0, palette[x] );
+ }
+
+ /* set up the blit points array */
+ surface->blit_points[1].x = surface->root.bitmap.width;
+ surface->blit_points[1].y = surface->root.bitmap.rows;
+ surface->blit_points[3] = surface->blit_points[1];
+
+ /* Finally, create the event handling thread for the surface's window */
+ DosCreateThread( &surface->message_thread,
+ (PFNTHREAD) RunPMWindow,
+ (ULONG) surface,
+ 0UL,
+ 32920 );
+
+ surface->root.done = (grDoneSurfaceFunc) done_surface;
+ surface->root.refresh_rect = (grRefreshRectFunc) refresh_rectangle;
+ surface->root.set_title = (grSetTitleFunc) set_title;
+ surface->root.listen_event = (grListenEventFunc) listen_event;
+
+ convert_rectangle( surface, 0, 0, bitmap->width, bitmap->rows );
+ return surface;
+ }
+
+
+
+ MRESULT EXPENTRY Message_Process( HWND handle,
+ ULONG mess,
+ MPARAM parm1,
+ MPARAM parm2 );
+
+
+ static
+ void RunPMWindow( grPMSurface* surface )
+ {
+ unsigned char class_name[] = "DisplayClass";
+ ULONG class_flags;
+
+ static HMQ queue;
+ QMSG message;
+
+ /* create an anchor to allow this thread to use PM */
+ surface->anchor = WinInitialize(0);
+ if (!surface->anchor)
+ {
+ printf( "Error doing WinInitialize()\n" );
+ return;
+ }
+
+ /* create a message queue */
+ queue = WinCreateMsgQueue( surface->anchor, 0 );
+ if (!queue)
+ {
+ printf( "Error doing >inCreateMsgQueue()\n" );
+ return;
+ }
+
+ /* register the window class */
+ if ( !WinRegisterClass( surface->anchor,
+ (PSZ) class_name,
+ (PFNWP) Message_Process,
+ CS_SIZEREDRAW,
+ 0 ) )
+ {
+ printf( "Error doing WinRegisterClass()\n" );
+ return;
+ }
+
+ /* create the PM window */
+ class_flags = FCF_TITLEBAR | FCF_MINBUTTON | FCF_DLGBORDER |
+ FCF_TASKLIST | FCF_SYSMENU;
+
+ surface->frame_window = WinCreateStdWindow(
+ HWND_DESKTOP,
+ WS_VISIBLE,
+ &class_flags,
+ (PSZ) class_name,
+ (PSZ) "FreeType PM Graphics",
+ WS_VISIBLE,
+ 0, 0,
+ &surface->client_window );
+ if (!surface->frame_window)
+ {
+ printf( "Error doing WinCreateStdWindow()\n" );
+ return;
+ }
+
+ /* find the title window handle */
+ surface->title_window = WinWindowFromID( surface->frame_window,
+ FID_TITLEBAR );
+
+ /* set Window size and position */
+ WinSetWindowPos( surface->frame_window,
+ 0L,
+ (SHORT) 60,
+ (SHORT) WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ) -
+ surface->root.bitmap.rows + 100,
+
+ (SHORT) WinQuerySysValue( HWND_DESKTOP, SV_CYDLGFRAME )*2 +
+ surface->root.bitmap.width,
+
+ (SHORT) WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR ) +
+ WinQuerySysValue( HWND_DESKTOP, SV_CYDLGFRAME )*2 +
+ surface->root.bitmap.rows,
+
+ SWP_SIZE | SWP_MOVE );
+
+ /* save the handle to the current surface within the window words */
+ WinSetWindowPtr( surface->frame_window,QWL_USER, surface );
+
+ /* run the message queue till the end */
+ while ( WinGetMsg( surface->anchor, &message, (HWND)NULL, 0, 0 ) )
+ WinDispatchMsg( surface->anchor, &message );
+
+ /* clean-up */
+ WinDestroyWindow( surface->frame_window );
+ surface->frame_window = 0;
+
+ WinDestroyMsgQueue( queue );
+ WinTerminate( surface->anchor );
+
+ /* await death... */
+ while ( 1 )
+ DosSleep( 100 );
+ }
+
+
+
+
+ /* Message processing for our PM Window class */
+ MRESULT EXPENTRY Message_Process( HWND handle,
+ ULONG mess,
+ MPARAM parm1,
+ MPARAM parm2 )
+ {
+ static HDC screen_dc;
+ static HPS screen_ps;
+ static BOOL minimized;
+
+ SIZEL sizl;
+ SWP swp;
+
+ grPMSurface* surface;
+
+ /* get the handle to the window's surface */
+ surface = (grPMSurface*)WinQueryWindowPtr( handle, QWL_USER );
+
+ switch( mess )
+ {
+ case WM_DESTROY:
+ /* warn the main thread to quit if it didn't know */
+ surface->event.type = gr_event_key;
+ surface->event.key = grKeyEsc;
+ DosPostEventSem( surface->event_lock );
+ break;
+
+ case WM_CREATE:
+ /* set original magnification */
+ minimized = FALSE;
+
+ /* create Device Context and Presentation Space for screen. */
+ screen_dc = WinOpenWindowDC( handle );
+ screen_ps = GpiCreatePS( surface->anchor,
+ screen_dc,
+ &sizl,
+ PU_PELS | GPIT_MICRO |
+ GPIA_ASSOC | GPIF_DEFAULT );
+
+ /* take the input focus */
+ WinFocusChange( HWND_DESKTOP, handle, 0L );
+ 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:
+ /* copy the memory image of the screen out to the real screen */
+ DosRequestMutexSem( surface->image_lock, SEM_INDEFINITE_WAIT );
+ WinBeginPaint( handle, screen_ps, NULL );
+
+ /* main image and magnified picture */
+ GpiBitBlt( screen_ps,
+ surface->image_ps,
+ 4L,
+ surface->blit_points,
+ ROP_SRCCOPY, BBO_AND );
+
+ WinEndPaint( screen_ps );
+ DosReleaseMutexSem( surface->image_lock );
+ break;
+
+ case WM_CHAR:
+ if ( CHARMSG( &mess )->fs & KC_KEYUP )
+ break;
+
+ /* look for a specific vkey */
+ {
+ int count = sizeof( key_translators )/sizeof( key_translators[0] );
+ Translator* trans = key_translators;
+ Translator* limit = trans + count;
+
+ for ( ; trans < limit; trans++ )
+ if ( CHARMSG(&mess)->vkey == trans->os2key )
+ {
+ surface->event.key = trans->grkey;
+ goto Do_Key_Event;
+ }
+ }
+
+ /* otherwise, simply record the character code */
+ if ( (CHARMSG( &mess )->fs & KC_CHAR) == 0 )
+ break;
+
+ surface->event.key = CHARMSG(&mess)->chr;
+
+ Do_Key_Event:
+ surface->event.type = gr_event_key;
+ DosPostEventSem( surface->event_lock );
+ break;
+
+ default:
+ return WinDefWindowProc( handle, mess, parm1, parm2 );
+ }
+
+ return (MRESULT) FALSE;
+ }
+
+
+
+
+
+
+
+#if 0
+ static
+ grKey KeySymTogrKey( key )
+ {
+ grKey k;
+ int count = sizeof(key_translators)/sizeof(key_translators[0]);
+ Translator* trans = key_translators;
+ Translator* limit = trans + count;
+
+ k = grKeyNone;
+
+ while ( trans < limit )
+ {
+ if ( trans->xkey == key )
+ {
+ k = trans->grkey;
+ break;
+ }
+ trans++;
+ }
+
+ return k;
+ }
+
+
+
+ static
+ void listen_event( grPMSurface* surface,
+ int event_mask,
+ grEvent* grevent )
+ {
+ grKey grkey;
+
+ /* XXXX : For now, ignore the event mask, and only exit when */
+ /* a key is pressed.. */
+ (void)event_mask;
+
+
+ /* Now, translate the keypress to a grKey */
+ /* If this wasn't part of the simple translated keys, simply get the charcode */
+ /* from the character buffer */
+ grkey = grKEY(key_buffer[key_cursor++]);
+
+ Set_Key:
+ grevent->type = gr_key_down;
+ grevent->key = grkey;
+ }
+
+#endif
+
+
+
+ grDevice gr_os2pm_device =
+ {
+ sizeof( grPMSurface ),
+ "os2pm",
+
+ init_device,
+ done_device,
+
+ (grDeviceInitSurfaceFunc) init_surface,
+
+ 0,
+ 0
+
+ };
+
+
--- /dev/null
+++ b/demos/config/os2/gros2pm.def
@@ -1,0 +1,5 @@
+NAME WINDOWCOMPAT
+
+DESCRIPTION 'FreeType Graphics'
+HEAPSIZE 8192
+STACKSIZE 40888
--- /dev/null
+++ b/demos/config/os2/gros2pm.h
@@ -1,0 +1,23 @@
+#ifndef GROS2PM_H
+#define GROS2PM_H
+
+#include "grobjs.h"
+
+ extern
+ grDevice gr_os2pm_device;
+
+#ifdef GR_INIT_BUILD
+ static
+ grDeviceChain gr_os2pm_device_chain =
+ {
+ "os2pm",
+ &gr_os2pm_device,
+ GR_INIT_DEVICE_CHAIN
+ };
+
+#undef GR_INIT_DEVICE_CHAIN
+#define GR_INIT_DEVICE_CHAIN &gr_os2pm_device_chain
+
+#endif /* GR_INIT_BUILD */
+
+#endif /* GROS2PM_H */
--- /dev/null
+++ b/demos/config/os2/rules.mk
@@ -1,0 +1,32 @@
+#**************************************************************************
+#*
+#* OS/2 specific rules file, used to compile the OS/2 graphics driver
+#* to the graphics subsystem
+#*
+#**************************************************************************
+
+ifeq ($(PLATFORM),os2)
+
+GR_OS2 := config$(SEP)os2
+GR_OS2_ := $(GR_OS2)$(SEP)
+
+# the GRAPH_LINK is expanded each time an executable is linked with the
+# graphics library.
+#
+GRAPH_LINK += $(GR_OS2_)gros2pm.def
+
+# Add the OS/2 driver object file to the graphics library "graph.a"
+#
+GRAPH_OBJS += $(OBJ_)gros2pm.$O
+
+DEVICES += OS2_PM
+DEVICE_INCLUDES += $(GR_OS2)
+
+# the rule used to compile the graphics driver
+#
+$(OBJ_)gros2pm.$O: $(GR_OS2_)gros2pm.c $(GR_OS2_)gros2pm.h
+ $(CC) $(CFLAGS) $(GRAPH_INCLUDES:%=$I%) $I$(GR_OS2) $T$@ $<
+
+endif
+
+
--- /dev/null
+++ b/demos/config/x11/grx11.c
@@ -1,0 +1,936 @@
+#include "grx11.h"
+
+
+#ifdef TEST
+#include "grfont.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/cursorfont.h>
+#include <X11/keysym.h>
+
+ static void Panic( const char* message )
+ {
+ fprintf( stderr, "%s", message );
+ exit(1);
+ }
+
+ typedef struct Translator
+ {
+ KeySym xkey;
+ grKey grkey;
+
+ } Translator;
+
+ static
+ Translator key_translators[] =
+ {
+ { XK_BackSpace, grKeyBackSpace },
+ { XK_Tab, grKeyTab },
+ { XK_Return, grKeyReturn },
+ { XK_Escape, grKeyEsc },
+ { XK_Home, grKeyHome },
+ { XK_Left, grKeyLeft },
+ { XK_Up, grKeyUp },
+ { XK_Right, grKeyRight },
+ { XK_Down, grKeyDown },
+ { XK_Page_Up, grKeyPageUp },
+ { XK_Page_Down, grKeyPageDown },
+ { XK_End, grKeyEnd },
+ { XK_Begin, grKeyHome },
+ { XK_F1, grKeyF1 },
+ { XK_F2, grKeyF2 },
+ { XK_F3, grKeyF3 },
+ { XK_F4, grKeyF4 },
+ { XK_F5, grKeyF5 },
+ { XK_F6, grKeyF6 },
+ { XK_F7, grKeyF7 },
+ { XK_F8, grKeyF8 },
+ { XK_F9, grKeyF9 },
+ { XK_F10, grKeyF10 },
+ { XK_F11, grKeyF11 },
+ { XK_F12, grKeyF12 }
+ };
+
+
+#ifdef TEST
+
+#define grAlloc malloc
+
+#endif
+
+
+ static Display* display;
+ static char* displayname = "";
+
+ static Cursor idle;
+ static Cursor busy;
+
+#define MAX_PIXEL_MODES 32
+
+ typedef XPixmapFormatValues XDepth;
+
+ static int num_pixel_modes = 0;
+ static grPixelMode pixel_modes[ MAX_PIXEL_MODES ];
+ static XDepth pixel_depth[ MAX_PIXEL_MODES ];
+
+ typedef struct grXSurface_
+ {
+ grSurface root;
+ grBitmap image;
+
+ Window win;
+ Visual* visual;
+ Colormap colormap;
+ int depth;
+ Bool gray;
+
+ GC gc;
+
+ XColor color[256]; /* gray levels palette for 8-bit modes */
+ XImage* ximage;
+
+ int win_org_x;
+ int win_org_y;
+ int win_width;
+ int win_height;
+
+ int image_width;
+ int image_height;
+
+ } grXSurface;
+
+
+
+
+ /* close a given window */
+ static
+ void done_surface( grXSurface* surface )
+ {
+ XUnmapWindow( display, surface->win );
+ }
+
+
+
+ /* close the device, i.e. the display connection */
+ static
+ void done_device( void )
+ {
+ XCloseDisplay( display );
+ }
+
+
+
+ static
+ void add_pixel_mode( grPixelMode pixel_mode,
+ XDepth* depth )
+ {
+ if ( num_pixel_modes >= MAX_PIXEL_MODES )
+ Panic( "X11.Too many pixel modes\n" );
+
+ pixel_modes[ num_pixel_modes ] = pixel_mode;
+ pixel_depth[ num_pixel_modes ] = *depth;
+
+ num_pixel_modes++;
+ }
+
+
+
+ static
+ int init_device( void )
+ {
+ XDepth dummy;
+
+ XrmInitialize();
+
+ display = XOpenDisplay( displayname );
+ if (!display)
+ {
+ return -1;
+ /* Panic( "Gr:error: cannot open X11 display\n" ); */
+ }
+
+ idle = XCreateFontCursor( display, XC_left_ptr );
+ busy = XCreateFontCursor( display, XC_watch );
+
+ num_pixel_modes = 0;
+
+ /* always enable the 8-bit gray levels pixel mode */
+ /* even if its display is emulated through a constrained palette */
+ /* or another color mode */
+ dummy.depth = 8;
+ dummy.bits_per_pixel = 8;
+ dummy.scanline_pad = 8;
+ add_pixel_mode( gr_pixel_mode_gray, &dummy );
+
+ {
+ int count;
+ XDepth* format;
+ XDepth* formats;
+ XVisualInfo template;
+
+ formats = XListPixmapFormats( display, &count );
+ format = formats;
+
+#ifdef TEST
+ printf( "available pixmap formats\n" );
+ printf( "depth pixbits scanpad\n" );
+#endif
+
+ while ( count-- > 0 )
+ {
+#ifdef TEST
+ printf( " %3d %3d %3d\n",
+ format->depth,
+ format->bits_per_pixel,
+ format->scanline_pad );
+#endif
+
+ if ( format->depth == 1 )
+ /* usually, this should be the first format */
+ add_pixel_mode( gr_pixel_mode_mono, format );
+
+ else if ( format->depth == 8 )
+ add_pixel_mode( gr_pixel_mode_pal8, format );
+
+ /* note, the 32-bit modes return a depth of 24, and 32 bits per pixel */
+ else if ( format->depth == 24 )
+ {
+ if ( format->bits_per_pixel == 24 )
+ add_pixel_mode( gr_pixel_mode_rgb24, format );
+
+ else if ( format->bits_per_pixel == 32 )
+ add_pixel_mode( gr_pixel_mode_rgb32, format );
+ }
+
+ else if ( format->depth == 16 )
+ {
+ int count2;
+ XVisualInfo* visuals;
+ XVisualInfo* visual;
+
+ template.depth = format->depth;
+ visuals = XGetVisualInfo( display,
+ VisualDepthMask,
+ &template,
+ &count2 );
+ visual = visuals;
+
+ while ( count2-- > 0 )
+ {
+#ifdef TEST
+ const char* string = "unknown";
+
+ switch (visual->class)
+ {
+ case TrueColor: string = "TrueColor"; break;
+ case DirectColor: string = "DirectColor"; break;
+ case PseudoColor: string = "PseudoColor"; break;
+ case StaticGray : string = "StaticGray"; break;
+ case StaticColor: string = "StaticColor"; break;
+ case GrayScale: string = "GrayScale"; break;
+ }
+
+ printf( "> RGB %02x:%02x:%02x, colors %3d, bits %2d %s\n",
+ visual->red_mask,
+ visual->green_mask,
+ visual->blue_mask,
+ visual->colormap_size,
+ visual->bits_per_rgb,
+ string );
+#endif
+ if ( visual->red_mask == 0xf800 &&
+ visual->green_mask == 0x07e0 &&
+ visual->blue_mask == 0x001f )
+ add_pixel_mode( gr_pixel_mode_rgb565, format );
+
+ else if ( visual->red_mask == 0x7c00 &&
+ visual->green_mask == 0x03e0 &&
+ visual->blue_mask == 0x001f )
+ add_pixel_mode( gr_pixel_mode_rgb555, format );
+
+ /* other 16-bit modes are ignored */
+ visual++;
+ }
+
+ XFree( visuals );
+ }
+
+ format++;
+ }
+
+ XFree( formats );
+ }
+
+ gr_x11_device.num_pixel_modes = num_pixel_modes;
+ gr_x11_device.pixel_modes = pixel_modes;
+
+ return 0;
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+ static
+ void convert_gray_to_pal8( grXSurface* surface,
+ int x,
+ int y,
+ int w,
+ int h )
+ {
+ grBitmap* target = &surface->image;
+ grBitmap* source = &surface->root.bitmap;
+ byte* write = (byte*)target->buffer + y*target->pitch + x;
+ byte* read = (byte*)source->buffer + y*source->pitch + x;
+ XColor* palette = surface->color;
+
+ while (h > 0)
+ {
+ byte* _write = write;
+ byte* _read = read;
+ byte* limit = _write + w;
+
+ for ( ; _write < limit; _write++, _read++ )
+ *_write = (byte) palette[ *_read ].pixel;
+
+ write += target->pitch;
+ read += source->pitch;
+ h--;
+ }
+ }
+
+
+ static
+ void convert_gray_to_16( grXSurface* surface,
+ int x,
+ int y,
+ int w,
+ int h )
+ {
+ grBitmap* target = &surface->image;
+ grBitmap* source = &surface->root.bitmap;
+ byte* write = (byte*)target->buffer + y*target->pitch + 2*x;
+ byte* read = (byte*)source->buffer + y*source->pitch + x;
+ XColor* palette = surface->color;
+
+ while (h > 0)
+ {
+ byte* _write = write;
+ byte* _read = read;
+ byte* limit = _write + 2*w;
+
+ for ( ; _write < limit; _write += 2, _read++ )
+ *(short*)_write = (short)palette[ *_read ].pixel;
+
+ write += target->pitch;
+ read += source->pitch;
+ h--;
+ }
+ }
+
+
+ static
+ void convert_gray_to_24( grXSurface* surface,
+ int x,
+ int y,
+ int w,
+ int h )
+ {
+ grBitmap* target = &surface->image;
+ grBitmap* source = &surface->root.bitmap;
+ byte* write = (byte*)target->buffer + y*target->pitch + 3*x;
+ byte* read = (byte*)source->buffer + y*source->pitch + x;
+
+ while (h > 0)
+ {
+ byte* _write = write;
+ byte* _read = read;
+ byte* limit = _write + 3*w;
+
+ for ( ; _write < limit; _write += 3, _read++ )
+ {
+ byte color = *_read;
+
+ _write[0] =
+ _write[1] =
+ _write[2] = color;
+ }
+
+ write += target->pitch;
+ read += source->pitch;
+ h--;
+ }
+ }
+
+
+ static
+ void convert_gray_to_32( grXSurface* surface,
+ int x,
+ int y,
+ int w,
+ int h )
+ {
+ grBitmap* target = &surface->image;
+ grBitmap* source = &surface->root.bitmap;
+ byte* write = (byte*)target->buffer + y*target->pitch + 4*x;
+ byte* read = (byte*)source->buffer + y*source->pitch + x;
+
+ while (h > 0)
+ {
+ byte* _write = write;
+ byte* _read = read;
+ byte* limit = _write + 4*w;
+
+ for ( ; _write < limit; _write += 4, _read++ )
+ {
+ byte color = *_read;
+
+ _write[0] =
+ _write[1] =
+ _write[2] =
+ _write[3] = color;
+ }
+
+ write += target->pitch;
+ read += source->pitch;
+ h--;
+ }
+ }
+
+
+ static
+ void convert_rectangle( grXSurface* surface,
+ int x,
+ int y,
+ int w,
+ int h )
+ {
+ int z;
+
+ /* first of all, clip to the surface's area */
+ if ( x >= surface->image.width ||
+ x+w <= 0 ||
+ y >= surface->image.rows ||
+ y+h <= 0 )
+ return;
+
+ if ( x < 0 )
+ {
+ w += x;
+ x = 0;
+ }
+
+ z = (x + w) - surface->image.width;
+ if (z > 0)
+ w -= z;
+
+ z = (y + h) - surface->image.rows;
+ if (z > 0)
+ h -= z;
+
+ /* convert the rectangle to the target depth for gray surfaces */
+ if (surface->gray)
+ {
+ switch (surface->depth)
+ {
+ case 8 : convert_gray_to_pal8( surface, x, y, w, h ); break;
+ case 16: convert_gray_to_16 ( surface, x, y, w, h ); break;
+ case 24: convert_gray_to_24 ( surface, x, y, w, h ); break;
+ case 32: convert_gray_to_32 ( surface, x, y, w, h ); break;
+ }
+ }
+ }
+
+
+ static
+ void refresh_rectangle( grXSurface* surface,
+ int x,
+ int y,
+ int w,
+ int h )
+ {
+ if (surface->gray)
+ convert_rectangle( surface, x, y, w, h );
+
+ XPutImage( display,
+ surface->win,
+ surface->gc,
+ surface->ximage,
+ x, y, x, y, w, h );
+ }
+
+
+ static
+ void set_title( grXSurface* surface,
+ const char* title )
+ {
+ XStoreName( display, surface->win, title );
+ }
+
+
+
+ static
+ grKey KeySymTogrKey( KeySym key )
+ {
+ grKey k;
+ int count = sizeof(key_translators)/sizeof(key_translators[0]);
+ Translator* trans = key_translators;
+ Translator* limit = trans + count;
+
+ k = grKeyNone;
+
+ while ( trans < limit )
+ {
+ if ( trans->xkey == key )
+ {
+ k = trans->grkey;
+ break;
+ }
+ trans++;
+ }
+
+ return k;
+ }
+
+
+
+ static
+ void listen_event( grXSurface* surface,
+ int event_mask,
+ grEvent* grevent )
+ {
+ static char key_buffer[10];
+ static int key_cursor = 0;
+ static int key_number = 0;
+ static XEvent x_event;
+ KeySym key;
+
+ int bool_exit;
+ grKey grkey;
+
+ XComposeStatus compose;
+
+ /* XXXX : For now, ignore the event mask, and only exit when */
+ /* a key is pressed.. */
+ (void)event_mask;
+
+ bool_exit = key_cursor < key_number;
+
+ XDefineCursor( display, surface->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 ||
+ key > 512 )
+ {
+ /* this may be a special key like F1, F2, etc.. */
+ grkey = KeySymTogrKey(key);
+ if (grkey != grKeyNone)
+ goto Set_Key;
+ }
+ else
+ bool_exit = 1;
+ break;
+
+ case MappingNotify:
+ XRefreshKeyboardMapping( &x_event.xmapping );
+ break;
+
+ case Expose:
+ refresh_rectangle( surface,
+ x_event.xexpose.x,
+ x_event.xexpose.y,
+ x_event.xexpose.width,
+ x_event.xexpose.height );
+ break;
+
+ /* You should add more cases to handle mouse events, etc. */
+ }
+ }
+
+ XDefineCursor( display, surface->win, busy );
+ XFlush ( display );
+
+ /* Now, translate the keypress to a grKey */
+ /* If this wasn't part of the simple translated keys, simply get the charcode */
+ /* from the character buffer */
+ grkey = grKEY(key_buffer[key_cursor++]);
+
+ Set_Key:
+ grevent->type = gr_key_down;
+ grevent->key = grkey;
+ }
+
+
+
+
+ grXSurface* init_surface( grXSurface* surface,
+ grBitmap* bitmap )
+ {
+ int screen;
+ grBitmap* image;
+ char grays;
+ XDepth* format;
+ int image_depth;
+
+ screen = DefaultScreen( display );
+
+ surface->colormap = DefaultColormap( display, screen );
+ surface->depth = DefaultDepth( display, screen );
+ surface->visual = DefaultVisual( display, screen );
+
+ image = &surface->image;
+
+ /* force the surface image depth to 1 if necessary */
+ /* as this should be supported by all windows */
+ image_depth = surface->depth;
+ if (bitmap->mode == gr_pixel_mode_mono)
+ image_depth = 1;
+
+ grays = ( bitmap->mode == gr_pixel_mode_gray &&
+ bitmap->grays >= 2 );
+
+ surface->gray = grays;
+
+ /* copy dimensions */
+ image->width = bitmap->width;
+ image->rows = bitmap->rows;
+ image->mode = bitmap->mode;
+ image->pitch = 0;
+ image->grays = 0;
+ image->buffer = 0;
+
+ /* find the supported format corresponding to the request */
+ format = 0;
+
+ if (grays)
+ {
+ /* choose the default depth in case of grays rendering */
+ int i;
+ for ( i = 0; i < num_pixel_modes; i++ )
+ if ( image_depth == pixel_depth[i].depth )
+ {
+ format = pixel_depth + i;
+ break;
+ }
+ }
+ else
+ {
+ /* otherwise, select the format depending on the pixel mode */
+ int i;
+
+ format = 0;
+ for ( i = 0; i < num_pixel_modes; i++ )
+ if ( pixel_modes[i] == bitmap->mode )
+ {
+ format = pixel_depth + i;
+ break;
+ }
+ }
+
+ if (!format)
+ {
+ grError = gr_err_bad_argument;
+ return 0;
+ }
+
+
+ /* correct surface.depth. This is required because in the case */
+ /* of 32-bits pixels, the value of "format.depth" is 24 under X11 */
+ if ( format->depth == 24 &&
+ format->bits_per_pixel == 32 )
+ image_depth = 32;
+
+ /* allocate surface image */
+ {
+ int bits, over;
+
+ bits = image->width * format->bits_per_pixel;
+ over = bits % format->scanline_pad;
+
+ if (over)
+ bits += format->scanline_pad - over;
+
+ if (!grays)
+ {
+ image->width = bits;
+ bitmap->width = bits;
+ }
+ image->pitch = bits >> 3;
+ }
+
+ image->buffer = grAlloc( image->pitch * image->rows );
+ if (!image->buffer) return 0;
+
+ /* now, allocate a gray pal8 pixmap, only when we asked */
+ /* for an 8-bit pixmap */
+ if ( grays )
+ {
+ /* pad pitch to 32 bits */
+ bitmap->pitch = (bitmap->width + 3) & -4;
+ bitmap->buffer = grAlloc( bitmap->pitch * bitmap->rows );
+ if (!bitmap->buffer)
+ Panic( "grX11: could not allocate surface bitmap!\n" );
+ }
+ else /* otherwise */
+ {
+ *bitmap = *image;
+ }
+
+ surface->root.bitmap = *bitmap;
+
+ /* Now create the surface X11 image */
+ surface->ximage = XCreateImage( display,
+ surface->visual,
+ format->depth,
+ format->depth == 1 ? XYBitmap : ZPixmap,
+ 0,
+ (char*)image->buffer,
+ image->width,
+ image->rows,
+ 8,
+ 0 );
+ if ( !surface->ximage )
+ Panic( "grX11: cannot create surface X11 image\n" );
+
+
+ /* allocate gray levels in the case of gray surface */
+ if ( grays )
+ {
+ XColor* color = surface->color;
+ int i;
+
+ for ( i = 0; i < bitmap->grays; i++, color++ )
+ {
+ color->red =
+ color->green =
+ color->blue = 65535 - ( i * 65535 ) / bitmap->grays;
+
+ if ( !XAllocColor( display, surface->colormap, color ) )
+ Panic( "ERROR: cannot allocate Color\n" );
+ }
+ }
+ else if ( image_depth == 1 )
+ {
+ surface->ximage->byte_order = MSBFirst;
+ surface->ximage->bitmap_bit_order = MSBFirst;
+ }
+
+ {
+ XTextProperty xtp;
+ XSizeHints xsh;
+ XSetWindowAttributes xswa;
+
+ xswa.border_pixel = BlackPixel( display, screen );
+ xswa.background_pixel = WhitePixel( display, screen );
+ xswa.cursor = busy;
+
+ xswa.event_mask = KeyPressMask | ExposureMask;
+
+ surface->win = XCreateWindow( display,
+ RootWindow( display, screen ),
+ 0,
+ 0,
+ image->width,
+ image->rows,
+ 10,
+ surface->depth,
+ InputOutput,
+ surface->visual,
+ CWBackPixel | CWBorderPixel |
+ CWEventMask | CWCursor,
+ &xswa );
+
+ XMapWindow( display, surface->win );
+
+ surface->gc = XCreateGC( display, RootWindow( display, screen ), 0L, NULL );
+ XSetForeground( display, surface->gc, xswa.border_pixel );
+ XSetBackground( display, surface->gc, xswa.background_pixel );
+
+
+ /* make window manager happy :-) */
+ xtp.value = (unsigned char*)"FreeType";
+ xtp.encoding = 31;
+ xtp.format = 8;
+ xtp.nitems = strlen( (char*)xtp.value );
+
+ xsh.x = 0;
+ xsh.y = 0;
+
+ xsh.width = image->width;
+ xsh.height = image->rows;
+ xsh.flags = (PPosition | PSize);
+ xsh.flags = 0;
+
+ XSetWMProperties( display, surface->win, &xtp, &xtp, NULL, 0, &xsh, NULL, NULL );
+ }
+
+ surface->root.done = (grDoneSurfaceFunc) done_surface;
+ surface->root.refresh_rect = (grRefreshRectFunc) refresh_rectangle;
+ surface->root.set_title = (grSetTitleFunc) set_title;
+ surface->root.listen_event = (grListenEventFunc) listen_event;
+
+ convert_rectangle( surface, 0, 0, bitmap->width, bitmap->rows );
+ return surface;
+ }
+
+
+
+
+ grDevice gr_x11_device =
+ {
+ sizeof( grXSurface ),
+ "x11",
+
+ init_device,
+ done_device,
+
+ (grDeviceInitSurfaceFunc) init_surface,
+
+ 0,
+ 0
+
+ };
+
+#ifdef TEST
+
+typedef struct grKeyName
+{
+ grKey key;
+ const char* name;
+
+} grKeyName;
+
+
+static
+const grKeyName key_names[] =
+{
+ { grKeyF1, "F1" },
+ { grKeyF2, "F2" },
+ { grKeyF3, "F3" },
+ { grKeyF4, "F4" },
+ { grKeyF5, "F5" },
+ { grKeyF6, "F6" },
+ { grKeyF7, "F7" },
+ { grKeyF8, "F8" },
+ { grKeyF9, "F9" },
+ { grKeyF10, "F10" },
+ { grKeyF11, "F11" },
+ { grKeyF12, "F12" },
+ { grKeyEsc, "Esc" },
+ { grKeyHome, "Home" },
+ { grKeyEnd, "End" },
+
+ { grKeyPageUp, "Page_Up" },
+ { grKeyPageDown, "Page_Down" },
+ { grKeyLeft, "Left" },
+ { grKeyRight, "Right" },
+ { grKeyUp, "Up" },
+ { grKeyDown, "Down" },
+ { grKeyBackSpace, "BackSpace" },
+ { grKeyReturn, "Return" }
+};
+
+int main( void )
+{
+ grSurface* surface;
+ int n;
+
+ grInit();
+ surface = grNewScreenSurface( 0, gr_pixel_mode_gray, 320, 400, 128 );
+ if (!surface)
+ Panic("Could not create window\n" );
+ else
+ {
+ grColor color;
+ grEvent event;
+ const char* string;
+ int x;
+
+ grSetSurfaceRefresh( surface, 1 );
+ grSetTitle(surface,"X11 driver demonstration" );
+
+ for ( x = -10; x < 10; x++ )
+ {
+ for ( n = 0; n < 128; n++ )
+ {
+ color.value = (n*3) & 127;
+ grWriteCellChar( surface,
+ x + ((n % 60) << 3),
+ 80 + (x+10)*8*3 + ((n/60) << 3), n, color );
+ }
+
+ }
+ color.value = 64;
+ grWriteCellString( surface, 0, 0, "just an example", color );
+
+ do
+ {
+ listen_event((grXSurface*)surface, 0, &event);
+
+ /* return if ESC was pressed */
+ if ( event.key == grKeyEsc )
+ return 0;
+
+ /* otherwise, display key string */
+ color.value = (color.value + 8) & 127;
+ {
+ int count = sizeof(key_names)/sizeof(key_names[0]);
+ grKeyName* name = key_names;
+ grKeyName* limit = name + count;
+ const char* kname = 0;
+ char kname_temp[16];
+
+ while (name < limit)
+ {
+ if ( name->key == event.key )
+ {
+ kname = name->name;
+ break;
+ }
+ name++;
+ }
+
+ if (!kname)
+ {
+ sprintf( kname_temp, "char '%c'", (char)event.key );
+ kname = kname_temp;
+ }
+
+ grWriteCellString( surface, 30, 30, kname, color );
+ grRefreshSurface(surface);
+ paint_rectangle( surface, 0, 0, surface->bitmap.width, surface->bitmap.rows );
+ }
+ } while (1);
+ }
+
+ return 0;
+
+
+}
+#endif /* TEST */
+
--- /dev/null
+++ b/demos/config/x11/grx11.h
@@ -1,0 +1,24 @@
+#ifndef GRX11_H
+#define GRX11_H
+
+#include "grobjs.h"
+#include "grdevice.h"
+
+ extern
+ grDevice gr_x11_device;
+
+#ifdef GR_INIT_BUILD
+ static
+ grDeviceChain gr_x11_device_chain =
+ {
+ "x11",
+ &gr_x11_device,
+ GR_INIT_DEVICE_CHAIN
+ };
+
+#undef GR_INIT_DEVICE_CHAIN
+#define GR_INIT_DEVICE_CHAIN &gr_x11_device_chain
+
+#endif /* GR_INIT_BUILD */
+
+#endif /* GRX11_H */
--- /dev/null
+++ b/demos/config/x11/rules.mk
@@ -1,0 +1,69 @@
+#**************************************************************************
+#*
+#* X11-specific rules files, used to compile the X11 graphics driver
+#* when supported by the current platform
+#*
+#**************************************************************************
+
+#########################################################################
+#
+# Try to detect an X11 setup.
+#
+# We simply try to detect a `X11R6/bin', `X11R5/bin' or `X11/bin' in
+# the current path.
+#
+ifneq ($(findstring X11R6$(SEP)bin,$(PATH)),)
+xversion := X11R6
+endif
+
+ifneq ($(findstring X11R5$(SEP)bin,$(PATH)),)
+xversion := X11R5
+endif
+
+ifneq ($(findstring X11$(SEP)bin,$(PATH)),)
+xversion := X11
+endif
+
+ifdef xversion
+X11_PATH := $(subst ;, ,$(PATH)) $(subst :, ,$(PATH))
+X11_PATH := $(filter %$(xversion)$(SEP)bin,$(X11_PATH))
+X11_PATH := $(X11_PATH:%$(SEP)bin=%)
+endif
+
+##########################################################################
+#
+# Update some variables to compile the X11 graphics module. Note that
+# X11 is available on Unix, or on OS/2. However, it only compiles with
+# gcc on the latter platform, which is why it is safe to use the flags
+# `-L' and `-l'
+#
+ifneq ($(X11_PATH),)
+
+X11_INCLUDE := $(X11_PATH)$(SEP)include
+X11_LIB := $(X11_PATH)$(SEP)lib
+
+# the GRAPH_LINK variable is expanded each time an executable is linked against
+# the graphics library..
+#
+GRAPH_LINK += -L$(X11_LIB) -lX11
+
+# add the X11 driver object file to the graphics library
+#
+GRAPH_OBJS += $(OBJ_)grx11.$O
+
+GR_X11 := config$(SEP)x11
+GR_X11_ := $(GR_X11)$(SEP)
+
+DEVICES += X11
+DEVICE_INCLUDES += $(GR_X11)
+
+# the rule used to compile the X11 driver
+#
+$(OBJ_)grx11.$O: $(GR_X11_)grx11.c $(GR_X11_)grx11.h
+ $(CC) $(CFLAGS) $(GRAPH_INCLUDES:%=$I%) $I$(GR_X11) \
+ $(X11_INCLUDE:%=$I%) $T$@ $<
+endif
+
+
+
+
--- /dev/null
+++ b/demos/graph/gpm_os2.def
@@ -1,0 +1,5 @@
+NAME WINDOWCOMPAT
+
+DESCRIPTION 'FreeType Graphics'
+HEAPSIZE 8192
+STACKSIZE 40888
--- /dev/null
+++ b/demos/graph/graph.h
@@ -1,0 +1,632 @@
+/***************************************************************************
+ *
+ * graph.h
+ *
+ * Graphics Subsystem interface
+ *
+ * Copyright 1999 - The FreeType Development Team - www.freetype.org
+ *
+ *
+ *
+ *
+ ***************************************************************************/
+
+#ifndef GRAPH_H
+#define GRAPH_H
+
+#include "grevents.h"
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /******** ********/
+ /******** GENERAL DEFINITIONS AND BLITTING ROUTINES ********/
+ /******** ********/
+ /******** ********/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /* define the global error variable */
+ extern int grError;
+
+ /* initialisation */
+ extern int grInit( void );
+
+ /* finalisation */
+ extern void grDone( void );
+
+
+ /* pixel mode constants */
+ typedef enum grPixelMode
+ {
+ gr_pixel_mode_none = 0,
+ gr_pixel_mode_mono, /* monochrome bitmaps */
+ gr_pixel_mode_pal4, /* 4-bit paletted - 16 colors */
+ gr_pixel_mode_pal8, /* 8-bit paletted - 256 colors */
+ gr_pixel_mode_gray, /* 8-bit gray levels */
+ gr_pixel_mode_rgb555, /* 15-bits mode - 32768 colors */
+ gr_pixel_mode_rgb565, /* 16-bits mode - 65536 colors */
+ gr_pixel_mode_rgb24, /* 24-bits mode - 16 million colors */
+ gr_pixel_mode_rgb32, /* 32-bits mode - 16 million colors */
+
+ gr_pixel_mode_max /* don't remove */
+
+ } grPixelMode;
+
+
+ /* forward declaration of the surface class */
+ typedef struct grSurface_ grSurface;
+
+
+ /*********************************************************************
+ *
+ * <Struct>
+ * grBitmap
+ *
+ * <Description>
+ * a simple bitmap descriptor
+ *
+ * <Fields>
+ * rows :: height in pixels
+ * width :: width in pixels
+ * pitch :: + or - the number of bytes per row
+ * mode :: pixel mode of bitmap buffer
+ * grays :: number of grays in palette for PAL8 mode. 0 otherwise
+ * buffer :: pointer to pixel buffer
+ *
+ * <Note>
+ * the 'pitch' is positive for downward flows, and negative otherwise
+ * Its absolute value is always the number of bytes taken by each
+ * bitmap row.
+ *
+ * All drawing operations will be performed within the first
+ * "width" pixels of each row (clipping is always performed).
+ *
+ ********************************************************************/
+
+ typedef struct grBitmap_
+ {
+ int rows;
+ int width;
+ int pitch;
+ grPixelMode mode;
+ int grays;
+ char* buffer;
+
+ } grBitmap;
+
+
+
+ typedef long grPos;
+ typedef char grBool;
+
+ typedef struct grVector_
+ {
+ grPos x;
+ grPos y;
+
+ } grVector;
+
+
+ typedef union grColor_
+ {
+ long value;
+ unsigned char chroma[4];
+
+ } grColor;
+
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grNewBitmap
+ *
+ * <Description>
+ * creates a new bitmap
+ *
+ * <Input>
+ * pixel_mode :: the target surface's pixel_mode
+ * num_grays :: number of grays levels for PAL8 pixel mode
+ * width :: width in pixels
+ * height :: height in pixels
+ *
+ * <Output>
+ * bit :: descriptor of the new bitmap
+ *
+ * <Return>
+ * Error code. 0 means success.
+ *
+ * <Note>
+ * This function really allocates a pixel buffer, zero it, then
+ * returns a descriptor for it.
+ *
+ * Call grDoneBitmap when you're done with it..
+ *
+ **********************************************************************/
+
+ extern int grNewBitmap( grPixelMode pixel_mode,
+ int num_grays,
+ int width,
+ int height,
+ grBitmap *bit );
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grBlitGlyphToBitmap
+ *
+ * <Description>
+ * writes a given glyph bitmap to a target surface.
+ *
+ * <Input>
+ * target :: handle to target bitmap
+ * glyph :: handle to source glyph bitmap
+ * x :: position of left-most pixel of glyph image in target surface
+ * y :: position of top-most pixel of glyph image in target surface
+ * color :: color to be used to draw a monochrome glyph
+ *
+ * <Return>
+ * Error code. 0 means success
+ *
+ * <Note>
+ * There are only two supported source pixel modes : monochrome
+ * and gray. The 8-bit images can have any number of grays between
+ * 2 and 128, and conversions to the target surface is handled
+ * _automatically_.
+ *
+ * Note however that you should avoid blitting a gray glyph to a gray
+ * bitmap with fewer levels of grays, as this would much probably
+ * give unpleasant results..
+ *
+ * This function performs clipping
+ *
+ **********************************************************************/
+
+ extern int grBlitGlyphToBitmap( grBitmap* target,
+ grBitmap* glyph,
+ grPos x,
+ grPos y,
+ grColor color );
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grFillRectangle
+ *
+ * <Description>
+ * this function is used to fill a given rectangle on a surface
+ *
+ * <Input>
+ * surface :: handle to target surface
+ * x :: x coordinate of the top-left corner of the rectangle
+ * y :: y coordinate of the top-left corner of the rectangle
+ * width :: rectangle width in pixels
+ * height :: rectangle height in pixels
+ * color :: fill color
+ *
+ **********************************************************************/
+
+ extern void grFillRectangle( grBitmap* surface,
+ grPos x,
+ grPos y,
+ grPos width,
+ grPos height,
+ grColor color );
+
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grWriteCellChar
+ *
+ * <Description>
+ * The graphics sub-system contains an internal Latin1 8x8 font
+ * which can be used to display simple strings of text without
+ * using FreeType.
+ *
+ * This function writes a single 8x8 character on the target bitmap.
+ *
+ * <Input>
+ * target :: handle to target surface
+ * x :: x pixel position of character cell's top left corner
+ * y :: y pixel position of character cell's top left corner
+ * charcode :: Latin-1 character code
+ * color :: color to be used to draw the character
+ *
+ **********************************************************************/
+
+ extern
+ void grWriteCellChar( grBitmap* target,
+ int x,
+ int y,
+ int charcode,
+ grColor color );
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grWriteCellString
+ *
+ * <Description>
+ * The graphics sub-system contains an internal Latin1 8x8 font
+ * which can be used to display simple strings of text without
+ * using FreeType.
+ *
+ * This function writes a string with the internal font
+ *
+ * <Input>
+ * target :: handle to target bitmap
+ * x :: x pixel position of string's top left corner
+ * y :: y pixel position of string's top left corner
+ * string :: Latin-1 text string
+ * color :: color to be used to draw the character
+ *
+ **********************************************************************/
+
+ extern
+ void grWriteCellString( grBitmap* target,
+ int x,
+ int y,
+ const char* string,
+ grColor color );
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grDoneBitmap
+ *
+ * <Description>
+ * destroys a bitmap
+ *
+ * <Input>
+ * bitmap :: handle to bitmap descriptor
+ *
+ * <Note>
+ * This function does NOT release the bitmap descriptor, only
+ * the pixel buffer.
+ *
+ **********************************************************************/
+
+ extern void grDoneBitmap( grBitmap* bit );
+
+
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /******** ********/
+ /******** DEVICE-SPECIFIC DEFINITIONS AND ROUTINES ********/
+ /******** ********/
+ /******** ********/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /* forward declaration - the definition of grDevice is not visible */
+ /* to clients.. */
+ typedef struct grDevice_ grDevice;
+
+
+ /**********************************************************************
+ *
+ * <Struct>
+ * grDeviceChain
+ *
+ * <Description>
+ * a simple structure used to implement a linked list of
+ * graphics device descriptors. The list is called a
+ * "device chain"
+ *
+ * <Fields>
+ * name :: ASCII name of the device, e.g. "x11", "os2pm", etc..
+ * device :: handle to the device descriptor.
+ * next :: next element in chain
+ *
+ * <Note>
+ * the 'device' field is a blind pointer; it is thus unusable by
+ * client applications..
+ *
+ **********************************************************************/
+
+ typedef struct grDeviceChain_ grDeviceChain;
+
+ struct grDeviceChain_
+ {
+ const char* name;
+ grDevice* device;
+ grDeviceChain* next;
+ };
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grInitDevices
+ *
+ * <Description>
+ * This function is in charge of initialising all system-specific
+ * devices. A device is responsible for creating and managing one
+ * or more "surfaces". A surface is either a window or a screen,
+ * depending on the system.
+ *
+ * <Return>
+ * a pointer to the first element of a device chain. The chain can
+ * be parsed to find the available devices on the current system
+ *
+ * <Note>
+ * If a device cannot be initialised correctly, it is not part of
+ * the device chain returned by this function. For example, if an
+ * X11 device was compiled in the library, it will be part of
+ * the returned device chain only if a connection to the display
+ * could be establisged
+ *
+ * If no driver could be initialised, this function returns NULL.
+ *
+ **********************************************************************/
+
+ extern
+ grDeviceChain* grInitDevices( void );
+
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grGetDeviceModes
+ *
+ * <Description>
+ * queries the available pixel modes for a device.
+ *
+ * <Input>
+ * device_name :: name of device to be used. 0 for the default
+ * device. For a list of available devices, see
+ * grInitDevices.
+ *
+ * <Output>
+ * num_modes :: number of available modes. 0 in case of error,
+ * which really is an invalid device name.
+ *
+ * pixel_modes :: array of available pixel modes for this device
+ * this table is internal to the device and should
+ * not be freed by client applications.
+ *
+ * <Return>
+ * error code. 0 means success. invalid device name otherwise
+ *
+ * <Note>
+ * All drivers are _required_ to support at least the following
+ * pixel formats :
+ *
+ * - gr_pixel_mode_mono : i.e. monochrome bitmaps
+ * - gr_pixel_mode_gray : with any number of gray levels between
+ * 2 and 256.
+ *
+ * the pixel modes do not provide the number of grays in the case
+ * of "gray" devices. You should try to create a surface with the
+ * maximal number (256, that is) and see the value returned in
+ * the bitmap descriptor.
+ *
+ **********************************************************************/
+
+ extern void grGetDeviceModes( const char* device_name,
+ int *num_modes,
+ grPixelMode* *pixel_modes );
+
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grNewSurface
+ *
+ * <Description>
+ * creates a new device-specific surface. A surface is either
+ * a window or a screen, depending on the device.
+ *
+ * <Input>
+ * device :: name of the device to use. A value of NULL means
+ * the default device (which depends on the system).
+ * for a list of available devices, see grInitDevices.
+ *
+ * <InOut>
+ * bitmap :: handle to a bitmap descriptor containing the
+ * requested pixel mode, number of grays and dimensions
+ * for the surface. the bitmap's 'pitch' and 'buffer'
+ * fields are ignored on input.
+ *
+ * On output, the bitmap describes the surface's image
+ * completely. It is possible to write directly in it
+ * with grBlitGlyphToBitmap, even though the use of
+ * grBlitGlyphToSurface is recommended.
+ *
+ * <Return>
+ * handle to the corresponding surface object. 0 in case of error
+ *
+ * <Note>
+ * All drivers are _required_ to support at least the following
+ * pixel formats :
+ *
+ * - gr_pixel_mode_mono : i.e. monochrome bitmaps
+ * - gr_pixel_mode_gray : with any number of gray levels between
+ * 2 and 256.
+ *
+ * This function might change the bitmap descriptor's fields. For
+ * example, when displaying a full-screen surface, the bitmap's
+ * dimensions will be set to those of the screen (e.g. 640x480
+ * or 800x600); also, the bitmap's 'buffer' field might point to
+ * the Video Ram depending on the mode requested..
+ *
+ * The surface contains a copy of the returned bitmap descriptor,
+ * you can thus discard the 'bitmap' parameter after the call.
+ *
+ **********************************************************************/
+
+ extern grSurface* grNewSurface( const char* device,
+ grBitmap* bitmap );
+
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grRefreshRectangle
+ *
+ * <Description>
+ * this function is used to indicate that a given surface rectangle
+ * was modified and thus needs re-painting. It really is useful for
+ * windowed or gray surfaces.
+ *
+ * <Input>
+ * surface :: handle to target surface
+ * x :: x coordinate of the top-left corner of the rectangle
+ * y :: y coordinate of the top-left corner of the rectangle
+ * width :: rectangle width in pixels
+ * height :: rectangle height in pixels
+ *
+ **********************************************************************/
+
+ extern void grRefreshRectangle( grSurface* surface,
+ grPos x,
+ grPos y,
+ grPos width,
+ grPos height );
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grRefreshSurface
+ *
+ * <Description>
+ * a variation of grRefreshRectangle which repaints the whole surface
+ * to the screen.
+ *
+ * <Input>
+ * surface :: handle to target surface
+ *
+ **********************************************************************/
+
+ extern void grRefreshSurface( grSurface* surface );
+
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grWriteSurfaceChar
+ *
+ * <Description>
+ * This function is equivalent to calling grWriteCellChar on the
+ * surface's bitmap, then invoking grRefreshRectangle.
+ *
+ * The graphics sub-system contains an internal Latin1 8x8 font
+ * which can be used to display simple strings of text without
+ * using FreeType.
+ *
+ * This function writes a single 8x8 character on the target bitmap.
+ *
+ * <Input>
+ * target :: handle to target surface
+ * x :: x pixel position of character cell's top left corner
+ * y :: y pixel position of character cell's top left corner
+ * charcode :: Latin-1 character code
+ * color :: color to be used to draw the character
+ *
+ **********************************************************************/
+
+ extern
+ void grWriteSurfaceChar( grSurface* target,
+ int x,
+ int y,
+ int charcode,
+ grColor color );
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grWriteSurfaceString
+ *
+ * <Description>
+ * This function is equivalent to calling grWriteCellString on the
+ * surface's bitmap, then invoking grRefreshRectangle.
+ *
+ * The graphics sub-system contains an internal Latin1 8x8 font
+ * which can be used to display simple strings of text without
+ * using FreeType.
+ *
+ * This function writes a string with the internal font
+ *
+ * <Input>
+ * target :: handle to target bitmap
+ * x :: x pixel position of string's top left corner
+ * y :: y pixel position of string's top left corner
+ * string :: Latin-1 text string
+ * color :: color to be used to draw the character
+ *
+ **********************************************************************/
+
+ extern
+ void grWriteSurfaceString( grSurface* target,
+ int x,
+ int y,
+ const char* string,
+ grColor color );
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grSetTitle
+ *
+ * <Description>
+ * set the window title of a given windowed surface.
+ *
+ * <Input>
+ * surface :: handle to target surface
+ * title_string :: the new title
+ *
+ **********************************************************************/
+
+ extern void grSetTitle( grSurface* surface,
+ const char* title_string );
+
+
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grListenSurface
+ *
+ * <Description>
+ * listen the events for a given surface
+ *
+ * <Input>
+ * surface :: handle to target surface
+ * event_mask :: the event mask (mode)
+ *
+ * <Output>
+ * event :: the returned event
+ *
+ * <Note>
+ * XXX : For now, only keypresses are supported.
+ *
+ **********************************************************************/
+
+ extern
+ int grListenSurface( grSurface* surface,
+ int event_mask,
+ grEvent *event );
+
+
+#endif /* GRAPH_H */
--- /dev/null
+++ b/demos/graph/grblit.c
@@ -1,0 +1,1268 @@
+/****************************************************************************/
+/* */
+/* 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 "grblit.h"
+#include "grobjs.h"
+
+ static
+ int compute_clips( grBlitter* 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.mode )
+ {
+ case gr_pixel_mode_mono:
+ width = (width + 7) & -8;
+ break;
+
+ case gr_pixel_mode_pal4:
+ width = (width + 1) & -2;
+ break;
+
+ default:
+ ;
+ }
+
+ 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.mode )
+ {
+ case gr_pixel_mode_mono:
+ target_width = (target_width + 7) & -8;
+ break;
+ case gr_pixel_mode_pal4:
+ target_width = (target_width + 1) & -2;
+ break;
+
+ default:
+ ;
+ }
+
+ 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 read */
+ /* and write areas before clipping. */
+
+ blit->read = (unsigned char*)blit->source.buffer;
+ blit->write = (unsigned char*)blit->target.buffer;
+
+ blit->read_line = blit->source.pitch;
+ blit->write_line = blit->target.pitch;
+
+ if ( blit->read_line < 0 )
+ blit->read -= (blit->source.rows-1) * blit->read_line;
+
+ if ( blit->write_line < 0 )
+ blit->write -= (blit->target.rows-1) * blit->write_line;
+
+ /* 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;
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_mono_to_mono */
+/* */
+/**************************************************************************/
+
+ static
+ void blit_mono_to_mono( grBlitter* blit,
+ grColor color )
+ {
+ int shift, left_clip, x, y;
+ byte* read;
+ byte* write;
+
+ (void)color; /* unused argument */
+
+ left_clip = ( blit->xread > 0 );
+ shift = ( blit->xwrite - blit->xread ) & 7;
+
+ read = blit->read + (blit->xread >> 3);
+ write = blit->write + (blit->xwrite >> 3);
+
+ if ( shift == 0 )
+ {
+ y = blit->height;
+ do
+ {
+ byte* _read = read;
+ byte* _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 );
+ }
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_mono_to_pal8 */
+/* */
+/**************************************************************************/
+
+ static
+ void blit_mono_to_pal8( grBlitter* blit,
+ grColor color )
+ {
+ int x, y;
+ unsigned int left_mask;
+ unsigned char* read;
+ unsigned char* write;
+
+ read = blit->read + (blit->xread >> 3);
+ write = 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 = *_read;
+
+
+ x = blit->width;
+ do
+ {
+ if ( mask == 0x80 )
+ val = *_read++;
+
+ if ( val & mask )
+ *_write = (unsigned char)color.value;
+
+ mask >>= 1;
+ if ( mask == 0 )
+ mask = 0x80;
+
+ _write++;
+ x--;
+ } while ( x > 0 );
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ } while ( y > 0 );
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_mono_to_pal4 */
+/* */
+/**************************************************************************/
+
+ static
+ void blit_mono_to_pal4( grBlitter* blit,
+ grColor color )
+ {
+ int x, y, phase;
+ unsigned int left_mask;
+ unsigned char* read;
+ unsigned char* write;
+ unsigned char col;
+
+
+ col = color.value & 15;
+ read = blit->read + (blit->xread >> 3);
+ write = 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 = *_read;
+
+ x = blit->width;
+ do
+ {
+ if ( mask == 0x80 )
+ val = *_read++;
+
+ if ( val & mask )
+ {
+ if ( _phase )
+ *_write = (*_write & 0xF0) | col;
+ else
+ *_write = (*_write & 0x0F) | (col << 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 );
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_mono_to_rgb16 */
+/* */
+/**************************************************************************/
+
+ static
+ void blit_mono_to_rgb16( grBlitter* blit,
+ grColor color )
+ {
+ int x, y;
+ unsigned int left_mask;
+ unsigned char* read;
+ unsigned char* write;
+
+ read = blit->read + (blit->xread >> 3);
+ write = blit->write + blit->xwrite*2;
+
+ 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 = *_read;
+
+ x = blit->width;
+ do
+ {
+ if ( mask == 0x80 )
+ val = *_read++;
+
+ if ( val & mask )
+ *(short*)_write = (short)color.value;
+
+ mask >>= 1;
+ if ( mask == 0 )
+ mask = 0x80;
+
+ _write +=2;
+ x--;
+ } while ( x > 0 );
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ } while ( y > 0 );
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_mono_to_rgb24 */
+/* */
+/**************************************************************************/
+
+ static
+ void blit_mono_to_rgb24( grBlitter* blit,
+ grColor color )
+ {
+ int x, y;
+ unsigned int left_mask;
+ unsigned char* read;
+ unsigned char* write;
+
+ read = blit->read + (blit->xread >> 3);
+ write = blit->write + blit->xwrite*3;
+
+ 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 = *_read;
+
+ x = blit->width;
+ do
+ {
+ if ( mask == 0x80 )
+ val = *_read++;
+
+ if ( val & mask )
+ {
+ _write[0] = color.chroma[0];
+ _write[1] = color.chroma[1];
+ _write[2] = color.chroma[2];
+ }
+
+ mask >>= 1;
+ if ( mask == 0 )
+ mask = 0x80;
+
+ _write += 3;
+ x--;
+ } while ( x > 0 );
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ } while ( y > 0 );
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_mono_to_rgb32 */
+/* */
+/**************************************************************************/
+
+ static
+ void blit_mono_to_rgb32( grBlitter* blit,
+ grColor color )
+ {
+ int x, y;
+ unsigned int left_mask;
+ unsigned char* read;
+ unsigned char* write;
+
+ read = blit->read + (blit->xread >> 3);
+ write = blit->write + blit->xwrite*4;
+
+ 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 = *_read;
+
+ x = blit->width;
+ do
+ {
+ if ( mask == 0x80 )
+ val = *_read++;
+
+ if ( val & mask )
+ {
+ /* this could be greatly optimised as a *(long*)_write = color.value */
+ /* but this wouldn't work on 64-bits systems... stupid C types! */
+ _write[0] = color.chroma[0];
+ _write[1] = color.chroma[1];
+ _write[2] = color.chroma[2];
+ _write[3] = color.chroma[3];
+ }
+
+ mask >>= 1;
+ if ( mask == 0 )
+ mask = 0x80;
+
+ _write += 4;
+ x--;
+ } while ( x > 0 );
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ } while ( y > 0 );
+ }
+
+
+
+ static
+ const grBlitterFunc gr_mono_blitters[gr_pixel_mode_max] =
+ {
+ 0,
+ blit_mono_to_mono,
+ blit_mono_to_pal4,
+ blit_mono_to_pal8,
+ blit_mono_to_pal8,
+ blit_mono_to_rgb16,
+ blit_mono_to_rgb16,
+ blit_mono_to_rgb24,
+ blit_mono_to_rgb32
+ };
+
+
+ /*******************************************************************/
+ /* */
+ /* Saturation tables */
+ /* */
+ /*******************************************************************/
+
+ typedef struct grSaturation_
+ {
+ int count;
+ const byte* table;
+
+ } grSaturation;
+
+
+ static
+ const byte gr_saturation_5[8] = { 0, 1, 2, 3, 4, 4, 4, 4 };
+
+
+ static
+ const byte gr_saturation_17[32] =
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ };
+
+
+ static
+ grSaturation gr_saturations[ GR_MAX_SATURATIONS ] =
+ {
+ { 5, gr_saturation_5 },
+ { 17, gr_saturation_17 }
+ };
+
+ static
+ int gr_num_saturations = 2;
+
+ static
+ grSaturation* gr_last_saturation = gr_saturations;
+
+
+ extern
+ const byte* grGetSaturation( int num_grays )
+ {
+ /* first of all, scan the current saturations table */
+ grSaturation* sat = gr_saturations;
+ grSaturation* limit = sat + gr_num_saturations;
+
+ if ( num_grays < 2 )
+ {
+ grError = gr_err_bad_argument;
+ return 0;
+ }
+
+ for ( ; sat < limit; sat++ )
+ {
+ if ( sat->count == num_grays )
+ {
+ gr_last_saturation = sat;
+ return sat->table;
+ }
+ }
+
+ /* not found, simply create a new entry if there is room */
+ if (gr_num_saturations < GR_MAX_SATURATIONS)
+ {
+ int i;
+ const byte* table;
+
+ table = (const byte*)grAlloc( (3*num_grays-1)*sizeof(byte) );
+ if (!table) return 0;
+
+ sat->count = num_grays;
+ sat->table = table;
+
+ for ( i = 0; i < num_grays; i++, table++ )
+ *(unsigned char*)table = (unsigned char)i;
+
+ for ( i = 2*num_grays-1; i > 0; i--, table++ )
+ *(unsigned char*)table = (unsigned char)(num_grays-1);
+
+ gr_num_saturations++;
+ gr_last_saturation = sat;
+ return sat->table;
+ }
+ grError = gr_err_saturation_overflow;
+ return 0;
+ }
+
+
+
+ /*******************************************************************/
+ /* */
+ /* conversion tables */
+ /* */
+ /*******************************************************************/
+
+ typedef struct grConversion_
+ {
+ int target_grays;
+ int source_grays;
+ const byte* table;
+
+ } grConversion;
+
+
+
+ static
+ const byte gr_gray5_to_gray17[5] = { 0, 4, 8, 12, 16 };
+
+
+ static
+ const byte gr_gray5_to_gray128[5] = { 0, 32, 64, 96, 127 };
+
+
+ static
+ const unsigned char gr_gray17_to_gray128[17] =
+ {
+ 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 127
+ };
+
+ static
+ grConversion gr_conversions[ GR_MAX_CONVERSIONS ] =
+ {
+ { 17, 5, gr_gray5_to_gray17 },
+ { 128, 5, gr_gray5_to_gray128 },
+ { 128, 17, gr_gray17_to_gray128 }
+ };
+
+ static
+ int gr_num_conversions = 3;
+
+ static
+ grConversion* gr_last_conversion = gr_conversions;
+
+
+ extern
+ const byte* grGetConversion( int target_grays,
+ int source_grays )
+ {
+ grConversion* conv = gr_conversions;
+ grConversion* limit = conv + gr_num_conversions;
+
+ if ( target_grays < 2 || source_grays < 2 )
+ {
+ grError = gr_err_bad_argument;
+ return 0;
+ }
+
+ /* otherwise, scan table */
+ for ( ; conv < limit; conv++ )
+ {
+ if ( conv->target_grays == target_grays &&
+ conv->source_grays == source_grays )
+ {
+ gr_last_conversion = conv;
+ return conv->table;
+ }
+ }
+
+ /* not found, add a new conversion to the table */
+ if (gr_num_conversions < GR_MAX_CONVERSIONS)
+ {
+ const byte* table;
+ int n;
+
+ table = (const byte*)grAlloc( source_grays*sizeof(byte) );
+ if (!table)
+ return 0;
+
+ conv->target_grays = target_grays;
+ conv->source_grays = source_grays;
+ conv->table = table;
+
+ for ( n = 0; n < source_grays; n++ )
+ ((unsigned char*)table)[n] = (unsigned char)(n*(target_grays-1)) /
+ (source_grays-1);
+
+ gr_num_conversions++;
+ gr_last_conversion = conv;
+ return table;
+ }
+ grError = gr_err_conversion_overflow;
+ return 0;
+ }
+
+
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_gray_to_gray */
+/* */
+/**************************************************************************/
+
+ static
+ void blit_gray_to_gray( grBlitter* blit,
+ const byte* saturation,
+ const byte* conversion )
+ {
+ int y;
+ unsigned char* read;
+ unsigned char* write;
+ unsigned char max1;
+ unsigned char max2;
+
+ max1 = (unsigned char)(blit->source.grays-1);
+ max2 = (unsigned char)(blit->target.grays-1);
+
+ read = (unsigned char*)blit->read + blit->xread;
+ write = (unsigned char*)blit->write + blit->xwrite;
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ int x = blit->width;
+
+ while (x > 0)
+ {
+#ifdef GR_CONFIG_GRAY_SKIP_WHITE
+ unsigned char val = *_read;
+
+ if (val)
+ {
+ if (val == max)
+ *_write = max2;
+ else
+ *_write = saturation[ (int)*_write + conversion[ *_read ] ];
+ }
+#else
+ *_write = saturation[ (int)*_write + conversion[ *_read ] ];
+#endif
+ _write++;
+ _read++;
+ x--;
+ }
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ }
+ while (y > 0);
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_gray_to_gray_simple */
+/* */
+/**************************************************************************/
+
+ static
+ void blit_gray_to_gray_simple( grBlitter* blit,
+ const byte* saturation )
+ {
+ int y;
+ unsigned char* read;
+ unsigned char* write;
+ unsigned char max;
+
+ max = (unsigned char)(blit->source.grays-1);
+
+ read = (unsigned char*)blit->read + blit->xread;
+ write = (unsigned char*)blit->write + blit->xwrite;
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ int x = blit->width;
+
+ while (x > 0)
+ {
+#ifdef GR_CONFIG_GRAY_SKIP_WHITE
+ unsigned char val = *_read;
+
+ if (val)
+ {
+ if (val == max)
+ *_write = val;
+ else
+ *_write = saturation[ (int)*_write + *_read ];
+ }
+#else
+ *_write = saturation[ (int)*_write + *_read ];
+#endif
+ _write++;
+ _read++;
+ x--;
+ }
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ }
+ while (y > 0);
+ }
+
+
+
+#define compose_pixel( a, b, n, max ) \
+ { \
+ int d, half = max >> 1; \
+ \
+ d = (int)b.chroma[0] - a.chroma[0]; \
+ a.chroma[0] += (n*d + half)/max; \
+ \
+ d = (int)b.chroma[1] - a.chroma[1]; \
+ a.chroma[1] += (n*d + half)/max; \
+ \
+ d = (int)b.chroma[2] - a.chroma[2]; \
+ a.chroma[2] += (n*d + half)/max; \
+ }
+
+
+#define extract555( pixel, color ) \
+ color.chroma[0] = (pixel >> 10) & 0x1F; \
+ color.chroma[1] = (pixel >> 5) & 0x1F; \
+ color.chroma[2] = (pixel ) & 0x1F;
+
+
+#define extract565( pixel, color ) \
+ color.chroma[0] = (pixel >> 11) & 0x1F; \
+ color.chroma[1] = (pixel >> 5) & 0x3F; \
+ color.chroma[2] = (pixel ) & 0x1F;
+
+
+#define inject555( color ) \
+ ( ( (unsigned short)color.chroma[0] << 10 ) | \
+ ( (unsigned short)color.chroma[1] << 5 ) | \
+ color.chroma[2] )
+
+
+#define inject565( color ) \
+ ( ( (unsigned short)color.chroma[0] << 11 ) | \
+ ( (unsigned short)color.chroma[1] << 5 ) | \
+ color.chroma[2] )
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_gray_to_555 */
+/* */
+/**************************************************************************/
+
+ static
+ void blit_gray_to_555( grBlitter* blit,
+ grColor color,
+ int max )
+ {
+ int y;
+ unsigned char* read;
+ unsigned char* write;
+ long color2;
+
+ read = blit->read + blit->xread;
+ write = blit->write + 2*blit->xwrite;
+
+ /* convert color to R:G:B triplet */
+ color2 = color.value;
+ extract555( color2, color );
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ int x = blit->width;
+
+ while (x > 0)
+ {
+ unsigned char val;
+
+ val = *_read;
+ if (val)
+ {
+ unsigned short* pixel = (unsigned short*)_write;
+
+ if (val == max)
+ {
+ pixel[0] = (short)color2;
+ }
+ else
+ {
+ /* compose gray value */
+ unsigned short pix16 = *pixel;
+ grColor pix;
+
+ extract555( pix16, pix );
+
+ compose_pixel( pix, color, val, max );
+ *pixel = inject555(pix);
+ }
+ }
+ _write += 2;
+ _read ++;
+ x--;
+ }
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ }
+ while (y > 0);
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_gray_to_565 */
+/* */
+/**************************************************************************/
+
+ static
+ void blit_gray_to_565( grBlitter* blit,
+ grColor color,
+ int max )
+ {
+ int y;
+ unsigned char* read;
+ unsigned char* write;
+ long color2;
+
+ read = blit->read + blit->xread;
+ write = blit->write + 2*blit->xwrite;
+
+ color2 = color.value;
+ extract565( color2, color );
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ int x = blit->width;
+
+ while (x > 0)
+ {
+ unsigned char val;
+
+ val = *_read;
+ if (val)
+ {
+ unsigned short* pixel = (unsigned short*)_write;
+
+ if (val == max)
+ {
+ pixel[0] = (short)color2;
+ }
+ else
+ {
+ /* compose gray value */
+ unsigned short pix16 = *pixel;
+ grColor pix;
+
+ extract565( pix16, pix );
+
+ compose_pixel( pix, color, val, max );
+ *pixel = inject565( pix );
+ }
+ }
+ _write +=2;
+ _read ++;
+ x--;
+ }
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ }
+ while (y > 0);
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_gray_to_24 */
+/* */
+/**************************************************************************/
+
+ static
+ void blit_gray_to_24( grBlitter* blit,
+ grColor color,
+ int max )
+ {
+ int y;
+ unsigned char* read;
+ unsigned char* write;
+
+ read = blit->read + blit->xread;
+ write = blit->write + 3*blit->xwrite;
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ int x = blit->width;
+
+ while (x > 0)
+ {
+ unsigned char val;
+
+ val = *_read;
+ if (val)
+ {
+ if (val == max)
+ {
+ _write[0] = color.chroma[0];
+ _write[1] = color.chroma[1];
+ _write[2] = color.chroma[2];
+ }
+ else
+ {
+ /* compose gray value */
+ grColor pix;
+
+ pix.chroma[0] = _write[0];
+ pix.chroma[1] = _write[1];
+ pix.chroma[2] = _write[2];
+
+ compose_pixel( pix, color, val, max );
+
+ _write[0] = pix.chroma[0];
+ _write[1] = pix.chroma[1];
+ _write[2] = pix.chroma[2];
+ }
+ }
+ _write += 3;
+ _read ++;
+ x--;
+ }
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ }
+ while (y > 0);
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> blit_gray_to_32 */
+/* */
+/**************************************************************************/
+
+ static
+ void blit_gray_to_32( grBlitter* blit,
+ grColor color,
+ int max )
+ {
+ int y;
+ unsigned char* read;
+ unsigned char* write;
+
+ read = blit->read + blit->xread;
+ write = blit->write + 4*blit->xwrite;
+
+ y = blit->height;
+ do
+ {
+ unsigned char* _read = read;
+ unsigned char* _write = write;
+ int x = blit->width;
+
+ while (x > 0)
+ {
+ unsigned char val;
+
+ val = *_read;
+ if (val)
+ {
+ if (val == max)
+ {
+ _write[0] = color.chroma[0];
+ _write[1] = color.chroma[1];
+ _write[2] = color.chroma[2];
+ _write[3] = color.chroma[3];
+ }
+ else
+ {
+ /* compose gray value */
+ grColor pix;
+
+ pix.chroma[0] = _write[0];
+ pix.chroma[1] = _write[1];
+ pix.chroma[2] = _write[2];
+
+ compose_pixel( pix, color, val, max );
+
+ _write[0] = pix.chroma[0];
+ _write[1] = pix.chroma[1];
+ _write[2] = pix.chroma[2];
+ }
+ }
+ _write += 4;
+ _read ++;
+ x--;
+ }
+
+ read += blit->read_line;
+ write += blit->write_line;
+ y--;
+ }
+ while (y > 0);
+ }
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grBlitGlyphBitmap
+ *
+ * <Description>
+ * writes a given glyph bitmap to a target surface.
+ *
+ * <Input>
+ * surface :: handle to target surface
+ * x :: position of left-most pixel of glyph image in surface
+ * y :: position of top-most pixel of glyph image in surface
+ * bitmap :: source glyph image
+ *
+ * <Return>
+ * Error code. 0 means success
+ *
+ **********************************************************************/
+
+ typedef void (*grColorGlyphBlitter)( grBlitter* blit,
+ grColor color,
+ int max_gray );
+
+ static
+ const grColorGlyphBlitter gr_color_blitters[gr_pixel_mode_max] =
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ blit_gray_to_555,
+ blit_gray_to_565,
+ blit_gray_to_24,
+ blit_gray_to_32
+ };
+
+
+ extern int grBlitGlyphToBitmap( grBitmap* target,
+ grBitmap* glyph,
+ grPos x,
+ grPos y,
+ grColor color )
+ {
+ grBlitter blit;
+ grPixelMode mode;
+
+ /* check arguments */
+ if (!target || !glyph)
+ {
+ grError = gr_err_bad_argument;
+ return -1;
+ }
+
+
+ /* set up blitter and compute clipping. Return immediately if needed */
+ blit.source = *glyph;
+ blit.target = *target;
+ mode = target->mode;
+
+ if ( compute_clips( &blit, x, y ) )
+ return 0;
+
+
+ /* handle monochrome bitmap blitting */
+ if (glyph->mode == gr_pixel_mode_mono)
+ {
+ if ( mode <= gr_pixel_mode_none || mode >= gr_pixel_mode_max )
+ {
+ grError = gr_err_bad_source_depth;
+ return -1;
+ }
+
+ gr_mono_blitters[mode]( &blit, color );
+ goto End;
+ }
+
+ /* handle gray bitmap composition */
+ if (glyph->mode == gr_pixel_mode_gray &&
+ glyph->grays > 1 )
+ {
+ int target_grays = target->grays;
+ int source_grays = glyph->grays;
+ const byte* saturation;
+
+ if ( mode == gr_pixel_mode_gray && target_grays > 1 )
+ {
+ /* rendering into a gray target - use special composition */
+ /* routines.. */
+ if ( gr_last_saturation->count == target_grays )
+ saturation = gr_last_saturation->table;
+ else
+ {
+ saturation = grGetSaturation( target_grays );
+ if (!saturation) return -3;
+ }
+
+
+ if ( target_grays == source_grays )
+ blit_gray_to_gray_simple( &blit, saturation );
+ else
+ {
+ const byte* conversion;
+
+ if ( gr_last_conversion->target_grays == target_grays &&
+ gr_last_conversion->source_grays == source_grays )
+ conversion = gr_last_conversion->table;
+ else
+ {
+ conversion = grGetConversion( target_grays, source_grays );
+ if (!conversion) return -3;
+ };
+
+ blit_gray_to_gray( &blit, saturation, conversion );
+ }
+ }
+ else
+ {
+ /* rendering into a color target */
+ if ( mode <= gr_pixel_mode_gray ||
+ mode >= gr_pixel_mode_max )
+ {
+ grError = gr_err_bad_target_depth;
+ return -1;
+ }
+
+ gr_color_blitters[mode]( &blit, color, source_grays-1 );
+ }
+ goto End;
+ }
+
+ /* we don't support the blitting of bitmaps of the following */
+ /* types : pal4, pal8, rgb555, rgb565, rgb24, rgb32 */
+ /* */
+ grError = gr_err_bad_source_depth;
+ return -2;
+
+ End:
+ return 0;
+ }
+
+
+/* End */
--- /dev/null
+++ b/demos/graph/grblit.h
@@ -1,0 +1,25 @@
+/****************************************************************************/
+/* */
+/* 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 GRBLIT_H
+#define GRBLIT_H
+
+#include "grobjs.h"
+
+ int grBlitMono( grBitmap* target,
+ grBitmap* source,
+ int x_offset,
+ int y_offset,
+ grColor color );
+
+
+#endif /* GRBLIT_H */
+/* End */
--- /dev/null
+++ b/demos/graph/grconfig.h
@@ -1,0 +1,9 @@
+#ifndef GRCONFIG_H
+#define GRCONFIG_H
+
+#define GR_MAX_SATURATIONS 8
+#define GR_MAX_CONVERSIONS 16
+
+#define GR_MAX_DEVICES 8
+
+#endif /* GRCONFIG_H */
--- /dev/null
+++ b/demos/graph/grdevice.c
@@ -1,0 +1,361 @@
+#include "grobjs.h"
+#include "grdevice.h"
+#include <stdlib.h>
+
+ grDeviceChain gr_device_chain[ GR_MAX_DEVICES ];
+ int gr_num_devices = 0;
+
+ static
+ grDevice* find_device( const char* device_name )
+ {
+ int index = 0;
+
+ if (device_name)
+ {
+ for ( index = gr_num_devices-1; index > 0; index-- )
+ if ( strcmp( device_name, gr_device_chain[index].name ) == 0 )
+ break;
+ }
+
+ if ( index < 0 || gr_num_devices <= 0 || !gr_device_chain[index].device )
+ {
+ grError = gr_err_invalid_device;
+ return 0;
+ }
+
+ return gr_device_chain[index].device;
+ }
+
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grGetDeviceModes
+ *
+ * <Description>
+ * queries the available pixel modes for a device.
+ *
+ * <Input>
+ * device_name :: name of device to be used. 0 for the default
+ * device. For a list of available devices, see
+ * grInitDevices.
+ *
+ * <Output>
+ * num_modes :: number of available modes. 0 in case of error,
+ * which really is an invalid device name.
+ *
+ * pixel_modes :: array of available pixel modes for this device
+ * this table is internal to the device and should
+ * not be freed by client applications.
+ *
+ * <Return>
+ * error code. 0 means success. invalid device name otherwise
+ *
+ * <Note>
+ * All drivers are _required_ to support at least the following
+ * pixel formats :
+ *
+ * - gr_pixel_mode_mono : i.e. monochrome bitmaps
+ * - gr_pixel_mode_gray : with any number of gray levels between
+ * 2 and 256.
+ *
+ * the pixel modes do not provide the number of grays in the case
+ * of "gray" devices. You should try to create a surface with the
+ * maximal number (256, that is) and see the value returned in
+ * the bitmap descriptor.
+ *
+ **********************************************************************/
+
+ extern void grGetDeviceModes( const char* device_name,
+ int *num_modes,
+ grPixelMode* *pixel_modes )
+ {
+ grDevice* device;
+
+ *num_modes = 0;
+ *pixel_modes = 0;
+
+ device = find_device( device_name );
+ if (device)
+ {
+ *num_modes = device->num_pixel_modes;
+ *pixel_modes = device->pixel_modes;
+ }
+ }
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grNewSurface
+ *
+ * <Description>
+ * creates a new device-specific surface. A surface is either
+ * a window or a screen, depending on the device.
+ *
+ * <Input>
+ * device :: name of the device to use. A value of NULL means
+ * the default device (which depends on the system).
+ * for a list of available devices, see grInitDevices.
+ *
+ * <InOut>
+ * bitmap :: handle to a bitmap descriptor containing the
+ * requested pixel mode, number of grays and dimensions
+ * for the surface. the bitmap's 'pitch' and 'buffer'
+ * fields are ignored on input.
+ *
+ * On output, the bitmap describes the surface's image
+ * completely. It is possible to write directly in it
+ * with grBlitGlyphToBitmap, even though the use of
+ * grBlitGlyphToSurface is recommended.
+ *
+ * <Return>
+ * handle to the corresponding surface object. 0 in case of error
+ *
+ * <Note>
+ * All drivers are _required_ to support at least the following
+ * pixel formats :
+ *
+ * - gr_pixel_mode_mono : i.e. monochrome bitmaps
+ * - gr_pixel_mode_gray : with any number of gray levels between
+ * 2 and 256.
+ *
+ * This function might change the bitmap descriptor's fields. For
+ * example, when displaying a full-screen surface, the bitmap's
+ * dimensions will be set to those of the screen (e.g. 640x480
+ * or 800x600); also, the bitmap's 'buffer' field might point to
+ * the Video Ram depending on the mode requested..
+ *
+ * The surface contains a copy of the returned bitmap descriptor,
+ * you can thus discard the 'bitmap' parameter after the call.
+ *
+ **********************************************************************/
+
+ extern grSurface* grNewSurface( const char* device_name,
+ grBitmap* bitmap )
+ {
+ grDevice* device;
+ grSurface* surface;
+
+ /* Now find the device */
+ device = find_device( device_name );
+ if (!device) return 0;
+
+ surface = (grSurface*)grAlloc( device->surface_objsize );
+ if (!surface) return 0;
+
+ if ( !device->init_surface( surface, bitmap ) )
+ {
+ grFree( surface );
+ surface = 0;
+ }
+ return surface;
+ }
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grRefreshRectangle
+ *
+ * <Description>
+ * this function is used to indicate that a given surface rectangle
+ * was modified and thus needs re-painting. It really is useful for
+ * windowed or gray surfaces.
+ *
+ * <Input>
+ * surface :: handle to target surface
+ * x :: x coordinate of the top-left corner of the rectangle
+ * y :: y coordinate of the top-left corner of the rectangle
+ * width :: rectangle width in pixels
+ * height :: rectangle height in pixels
+ *
+ **********************************************************************/
+
+ extern void grRefreshRectangle( grSurface* surface,
+ grPos x,
+ grPos y,
+ grPos width,
+ grPos height )
+ {
+ if (surface->refresh_rect)
+ surface->refresh_rect( surface, x, y, width, height );
+ }
+
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grWriteSurfaceChar
+ *
+ * <Description>
+ * This function is equivalent to calling grWriteCellChar on the
+ * surface's bitmap, then invoking grRefreshRectangle.
+ *
+ * The graphics sub-system contains an internal Latin1 8x8 font
+ * which can be used to display simple strings of text without
+ * using FreeType.
+ *
+ * This function writes a single 8x8 character on the target bitmap.
+ *
+ * <Input>
+ * target :: handle to target surface
+ * x :: x pixel position of character cell's top left corner
+ * y :: y pixel position of character cell's top left corner
+ * charcode :: Latin-1 character code
+ * color :: color to be used to draw the character
+ *
+ **********************************************************************/
+
+ extern
+ void grWriteSurfaceChar( grSurface* target,
+ int x,
+ int y,
+ int charcode,
+ grColor color )
+ {
+ grWriteCellChar( &target->bitmap, x, y, charcode, color );
+ if (target->refresh_rect)
+ target->refresh_rect( target, x, y, 8, 8 );
+ }
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grWriteSurfaceString
+ *
+ * <Description>
+ * This function is equivalent to calling grWriteCellString on the
+ * surface's bitmap, then invoking grRefreshRectangle.
+ *
+ * The graphics sub-system contains an internal Latin1 8x8 font
+ * which can be used to display simple strings of text without
+ * using FreeType.
+ *
+ * This function writes a string with the internal font
+ *
+ * <Input>
+ * target :: handle to target bitmap
+ * x :: x pixel position of string's top left corner
+ * y :: y pixel position of string's top left corner
+ * string :: Latin-1 text string
+ * color :: color to be used to draw the character
+ *
+ **********************************************************************/
+
+ extern
+ void grWriteSurfaceString( grSurface* target,
+ int x,
+ int y,
+ const char* string,
+ grColor color )
+ {
+ int len;
+
+ len = strlen(string);
+ grWriteCellString( &target->bitmap, x, y, string, color );
+ if (target->refresh_rect)
+ target->refresh_rect( target, x, y, 8*len, 8 );
+ }
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grRefreshSurface
+ *
+ * <Description>
+ * a variation of grRefreshRectangle which repaints the whole surface
+ * to the screen.
+ *
+ * <Input>
+ * surface :: handle to target surface
+ *
+ **********************************************************************/
+
+ extern void grRefreshSurface( grSurface* surface )
+ {
+ if (surface->refresh_rect)
+ surface->refresh_rect( surface, 0, 0,
+ surface->bitmap.width,
+ surface->bitmap.rows );
+ }
+
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grSetTitle
+ *
+ * <Description>
+ * set the window title of a given windowed surface.
+ *
+ * <Input>
+ * surface :: handle to target surface
+ * title_string :: the new title
+ *
+ **********************************************************************/
+
+ extern void grSetTitle( grSurface* surface,
+ const char* title_string )
+ {
+ if (surface->set_title)
+ surface->set_title( surface, title_string );
+ }
+
+
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grListenSurface
+ *
+ * <Description>
+ * listen the events for a given surface
+ *
+ * <Input>
+ * surface :: handle to target surface
+ * event_mask :: the event mask (mode)
+ *
+ * <Output>
+ * event :: the returned event
+ *
+ * <Note>
+ * XXX : For now, only keypresses are supported.
+ *
+ **********************************************************************/
+
+ extern
+ int grListenSurface( grSurface* surface,
+ int event_mask,
+ grEvent *event )
+ {
+ return surface->listen_event( surface, event_mask, event );
+ }
+
+
+#if 0
+ static
+ void gr_done_surface( grSurface* surface )
+ {
+ if (surface)
+ {
+ /* first of all, call the device-specific destructor */
+ surface->done(surface);
+
+ /* then remove the bitmap if we're owner */
+ if (surface->owner)
+ grFree( surface->bitmap.buffer );
+
+ surface->owner = 0;
+ surface->bitmap.buffer = 0;
+ grFree( surface );
+ }
+ }
+#endif
+
--- /dev/null
+++ b/demos/graph/grdevice.h
@@ -1,0 +1,126 @@
+/***************************************************************************
+ *
+ * grdevice.h
+ *
+ * Graphics device interface
+ *
+ * Copyright 1999 - The FreeType Development Team - www.freetype.org
+ *
+ *
+ ***************************************************************************/
+
+#ifndef GRDEVICE_H
+#define GRDEVICE_H
+
+#include "graph.h"
+
+
+ /********************************************************************
+ *
+ * <FuncType>
+ * grDeviceInitFunc
+ *
+ * <Description>
+ * Simple device initialiser function
+ *
+ * <Return>
+ * error code. 0 means success
+ *
+ ********************************************************************/
+
+ typedef int (*grDeviceInitFunc)( void );
+
+
+ /********************************************************************
+ *
+ * <FuncType>
+ * grDeviceDoneFunc
+ *
+ * <Description>
+ * Simple device finaliser function
+ *
+ * <Return>
+ * error code. 0 means success
+ *
+ ********************************************************************/
+
+ typedef void (*grDeviceDoneFunc)( void );
+
+
+ /********************************************************************
+ *
+ * <FuncType>
+ * grDeviceInitSurfaceFunc
+ *
+ * <Description>
+ * initializes a new surface for the device. This may be a window
+ * or a video screen, depending on the device.
+ *
+ * <Input>
+ * surface :: handle to target surface
+ *
+ * <InOut>
+ * bitmap :: handle to bitmap descriptor
+ *
+ ********************************************************************/
+
+ typedef int (*grDeviceInitSurfaceFunc)( grSurface* surface,
+ grBitmap* bitmap );
+
+
+ /********************************************************************
+ *
+ * <Struct>
+ * grDevice
+ *
+ * <Description>
+ * Simple device interface structure
+ *
+ * <Fields>
+ * surface_objsize :: size in bytes of a single surface object for
+ * this device.
+ *
+ * device_name :: name of device, e.g. "x11", "os2pm", "directx" etc..
+ * init :: device initialisation routine
+ * done :: device finalisation
+ * new_surface :: function used to create a new surface (screen or
+ * window) from the device
+ *
+ * num_pixel_modes :: the number of pixel modes supported by this
+ * device. This value _must_ be set to -1
+ * default, unless the device provides a
+ * static set of pixel modes (fullscreen).
+ *
+ * pixel_modes :: an array of pixel modes supported by this
+ * device
+ *
+ * <Note>
+ * the fields "num_pixel_modes" and "pixel_modes" must be
+ * set by the "init" function.
+ *
+ * This allows windowed devices to "discover" at run-time the
+ * available pixel modes they can provide depending on the
+ * current screen depth.
+ *
+ ********************************************************************/
+
+ struct grDevice_
+ {
+ int surface_objsize;
+ const char* device_name; /* name of device */
+
+ grDeviceInitFunc init;
+ grDeviceDoneFunc done;
+
+ grDeviceInitSurfaceFunc init_surface;
+
+ int num_pixel_modes;
+ grPixelMode* pixel_modes;
+ };
+
+
+ extern grDeviceChain gr_device_chain[];
+ extern int gr_num_devices;
+
+
+#endif /* GRDEVICE_H */
--- /dev/null
+++ b/demos/graph/grevents.h
@@ -1,0 +1,117 @@
+#ifndef GREVENTS_H
+#define GREVENTS_H
+
+
+#define gr_event_none 0
+#define gr_event_wait 1
+#define gr_event_poll 2
+#define gr_event_flush 3
+
+#define gr_mouse_down 0x04
+#define gr_mouse_move 0x08
+#define gr_mouse_up 0x10
+#define gr_mouse_drag 0x20
+
+#define gr_key_down 0x40
+#define gr_key_up 0x80
+
+
+#define gr_event_mouse 0x3C
+#define gr_event_key 0xC0
+
+#define gr_event_type (gr_event_mouse | gr_event_key)
+
+
+ typedef enum grKey_
+ {
+ grKeyNone = 0,
+
+ grKeyF1,
+ grKeyF2,
+ grKeyF3,
+ grKeyF4,
+ grKeyF5,
+ grKeyF6,
+ grKeyF7,
+ grKeyF8,
+ grKeyF9,
+ grKeyF10,
+ grKeyF11,
+ grKeyF12,
+
+ grKeyLeft,
+ grKeyRight,
+ grKeyUp,
+ grKeyDown,
+
+ grKeyIns,
+ grKeyDel,
+ grKeyHome,
+ grKeyEnd,
+ grKeyPageUp,
+ grKeyPageDown,
+
+ grKeyEsc,
+ grKeyTab,
+ grKeyBackSpace,
+ grKeyReturn,
+
+ grKeyMax,
+ grKeyForceShort = 0x7FFF /* this forces the grKey to be stored */
+ /* on at least one short ! */
+
+ } grKey;
+
+#define grKEY(c) ((grKey)(c))
+
+#define grKeyAlt ((grKey)0x8000)
+#define grKeyCtrl ((grKey)0x4000)
+#define grKeyShift ((grKey)0x2000)
+
+#define grKeyModifiers ((grKey)0xE000)
+
+#define grKey0 grKEY('0')
+#define grKey1 grKEY('1')
+#define grKey2 grKEY('2')
+#define grKey3 grKEY('3')
+#define grKey4 grKEY('4')
+#define grKey5 grKEY('5')
+#define grKey6 grKEY('6')
+#define grKey7 grKEY('7')
+#define grKey8 grKEY('8')
+#define grKey9 grKEY('9')
+
+
+#define grKeyPlus grKEY('+')
+#define grKeyLess grKEY('-')
+#define grKeyEqual grKEY('=')
+#define grKeyMult grKEY('*')
+#define grKeyDollar grKEY('$')
+#define grKeySmaller grKEY('<')
+#define grKeyGreater grKEY('>')
+#define grKeyQuestion grKEY('?')
+#define grKeyComma grKEY(',')
+#define grKeyDot grKEY('.')
+#define grKeySemiColumn grKEY(';')
+#define grKeyColumn grKEY(':')
+#define grKeyDiv grKEY('/')
+#define grKeyExclam grKEY('!')
+#define grKeyPercent grKEY('%')
+#define grKeyLeftParen grKEY('(')
+#define grKeyRightParen grKEY('(')
+#define grKeyAt grKEY('@')
+#define grKeyUnder grKEY('_')
+
+
+ typedef struct grEvent_
+ {
+ int type;
+ grKey key;
+ int x, y;
+
+ } grEvent;
+
+
+
+#endif /* GREVENTS_H */
+
--- /dev/null
+++ b/demos/graph/grfont.c
@@ -1,0 +1,354 @@
+#include "grfont.h"
+
+ /* font characters */
+
+ const unsigned char font_8x8[2048] =
+ {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E,
+ 0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E,
+ 0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00,
+ 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00,
+ 0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x92, 0x10, 0x7C,
+ 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C,
+ 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00,
+ 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF,
+ 0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00,
+ 0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF,
+ 0x0F, 0x07, 0x0F, 0x7D, 0xCC, 0xCC, 0xCC, 0x78,
+ 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18,
+ 0x3F, 0x33, 0x3F, 0x30, 0x30, 0x70, 0xF0, 0xE0,
+ 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0,
+ 0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99,
+ 0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00,
+ 0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00,
+ 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18,
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00,
+ 0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00,
+ 0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0x86, 0xFC,
+ 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00,
+ 0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF,
+ 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00,
+ 0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00,
+ 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00,
+ 0x00, 0x24, 0x66, 0xFF, 0x66, 0x24, 0x00, 0x00,
+ 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x00, 0x00,
+ 0x00, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00,
+ 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00,
+ 0x18, 0x7E, 0xC0, 0x7C, 0x06, 0xFC, 0x18, 0x00,
+ 0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00,
+ 0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00,
+ 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00,
+ 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00,
+ 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00,
+ 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30,
+ 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
+ 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00,
+ 0x7C, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0x7C, 0x00,
+ 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00,
+ 0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00,
+ 0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00,
+ 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00,
+ 0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00,
+ 0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00,
+ 0xFC, 0xCC, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00,
+ 0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00,
+ 0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00,
+ 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00,
+ 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30,
+ 0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00,
+ 0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00,
+ 0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00,
+ 0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00,
+ 0x7C, 0xC6, 0xDE, 0xDE, 0xDC, 0xC0, 0x7C, 0x00,
+ 0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00,
+ 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00,
+ 0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00,
+ 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00,
+ 0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00,
+ 0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00,
+ 0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3A, 0x00,
+ 0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00,
+ 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00,
+ 0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00,
+ 0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00,
+ 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00,
+ 0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00,
+ 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00,
+ 0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00,
+ 0x7C, 0xC6, 0xC6, 0xC6, 0xD6, 0x7C, 0x0E, 0x00,
+ 0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00,
+ 0x7C, 0xC6, 0xE0, 0x78, 0x0E, 0xC6, 0x7C, 0x00,
+ 0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00,
+ 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00,
+ 0xC6, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0xC6, 0x00,
+ 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00,
+ 0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00,
+ 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00,
+ 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00,
+ 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00,
+ 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
+ 0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00,
+ 0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00,
+ 0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00,
+ 0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
+ 0x38, 0x6C, 0x64, 0xF0, 0x60, 0x60, 0xF0, 0x00,
+ 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
+ 0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00,
+ 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0x0C, 0x00, 0x1C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78,
+ 0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00,
+ 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0x00, 0x00, 0xCC, 0xFE, 0xFE, 0xD6, 0xD6, 0x00,
+ 0x00, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00,
+ 0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00,
+ 0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0,
+ 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E,
+ 0x00, 0x00, 0xDC, 0x76, 0x62, 0x60, 0xF0, 0x00,
+ 0x00, 0x00, 0x7C, 0xC0, 0x70, 0x1C, 0xF8, 0x00,
+ 0x10, 0x30, 0xFC, 0x30, 0x30, 0x34, 0x18, 0x00,
+ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
+ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00,
+ 0x00, 0x00, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00,
+ 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00,
+ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
+ 0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00,
+ 0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00,
+ 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00,
+ 0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00,
+ 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00,
+ 0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x0C, 0x06, 0x7C,
+ 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
+ 0x1C, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
+ 0x7E, 0x81, 0x3C, 0x06, 0x3E, 0x66, 0x3B, 0x00,
+ 0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
+ 0xE0, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
+ 0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
+ 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0x78, 0x0C, 0x38,
+ 0x7E, 0x81, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00,
+ 0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
+ 0xE0, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
+ 0xCC, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0x7C, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00,
+ 0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0xC6, 0x10, 0x7C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00,
+ 0x30, 0x30, 0x00, 0x78, 0xCC, 0xFC, 0xCC, 0x00,
+ 0x1C, 0x00, 0xFC, 0x60, 0x78, 0x60, 0xFC, 0x00,
+ 0x00, 0x00, 0x7F, 0x0C, 0x7F, 0xCC, 0x7F, 0x00,
+ 0x3E, 0x6C, 0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00,
+ 0x78, 0x84, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
+ 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
+ 0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
+ 0x78, 0x84, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
+ 0x00, 0xE0, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
+ 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
+ 0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00,
+ 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00,
+ 0x18, 0x18, 0x7E, 0xC0, 0xC0, 0x7E, 0x18, 0x18,
+ 0x38, 0x6C, 0x64, 0xF0, 0x60, 0xE6, 0xFC, 0x00,
+ 0xCC, 0xCC, 0x78, 0x30, 0xFC, 0x30, 0xFC, 0x30,
+ 0xF8, 0xCC, 0xCC, 0xFA, 0xC6, 0xCF, 0xC6, 0xC3,
+ 0x0E, 0x1B, 0x18, 0x3C, 0x18, 0x18, 0xD8, 0x70,
+ 0x1C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
+ 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
+ 0x00, 0x1C, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
+ 0x00, 0xF8, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0x00,
+ 0xFC, 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00,
+ 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00,
+ 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00,
+ 0x18, 0x00, 0x18, 0x18, 0x30, 0x66, 0x3C, 0x00,
+ 0x00, 0x00, 0x00, 0xFC, 0xC0, 0xC0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00,
+ 0xC6, 0xCC, 0xD8, 0x36, 0x6B, 0xC2, 0x84, 0x0F,
+ 0xC3, 0xC6, 0xCC, 0xDB, 0x37, 0x6D, 0xCF, 0x03,
+ 0x18, 0x00, 0x18, 0x18, 0x3C, 0x3C, 0x18, 0x00,
+ 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00,
+ 0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00,
+ 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88,
+ 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
+ 0xDB, 0xF6, 0xDB, 0x6F, 0xDB, 0x7E, 0xD7, 0xED,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36,
+ 0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36,
+ 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
+ 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x76, 0xDC, 0xC8, 0xDC, 0x76, 0x00,
+ 0x00, 0x78, 0xCC, 0xF8, 0xCC, 0xF8, 0xC0, 0xC0,
+ 0x00, 0xFC, 0xCC, 0xC0, 0xC0, 0xC0, 0xC0, 0x00,
+ 0x00, 0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x00,
+ 0xFC, 0xCC, 0x60, 0x30, 0x60, 0xCC, 0xFC, 0x00,
+ 0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0x70, 0x00,
+ 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xC0,
+ 0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x00,
+ 0xFC, 0x30, 0x78, 0xCC, 0xCC, 0x78, 0x30, 0xFC,
+ 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x6C, 0x38, 0x00,
+ 0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x6C, 0xEE, 0x00,
+ 0x1C, 0x30, 0x18, 0x7C, 0xCC, 0xCC, 0x78, 0x00,
+ 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x00, 0x00,
+ 0x06, 0x0C, 0x7E, 0xDB, 0xDB, 0x7E, 0x60, 0xC0,
+ 0x38, 0x60, 0xC0, 0xF8, 0xC0, 0x60, 0x38, 0x00,
+ 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00,
+ 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00,
+ 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x7E, 0x00,
+ 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xFC, 0x00,
+ 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xFC, 0x00,
+ 0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70,
+ 0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18, 0x00,
+ 0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00,
+ 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
+ 0x0F, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C,
+ 0x58, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00,
+ 0x70, 0x98, 0x30, 0x60, 0xF8, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+
+ static
+ grBitmap gr_charcell =
+ {
+ 8, /* rows */
+ 8, /* width */
+ gr_pixel_mode_mono, /* mode */
+ 1, /* pitch */
+ 0, /* grays */
+ 0 /* buffer */
+ };
+
+ void grWriteCellChar( grBitmap* target,
+ int x,
+ int y,
+ int charcode,
+ grColor color )
+ {
+ if (charcode < 0 || charcode > 255)
+ return;
+
+ gr_charcell.buffer = (char*)font_8x8 + 8*charcode;
+ grBlitGlyphToBitmap( target, &gr_charcell, x, y, color );
+ }
+
+
+ void grWriteCellString( grBitmap* target,
+ int x,
+ int y,
+ const char* string,
+ grColor color )
+ {
+ while (*string)
+ {
+ gr_charcell.buffer = (char*)font_8x8 + 8*(int)(unsigned char)*string++;
+ grBlitGlyphToBitmap( target, &gr_charcell, x, y, color );
+ x += 8;
+ }
+ }
+
+ static int gr_cursor_x = 0;
+ static int gr_cursor_y = 0;
+ static grBitmap* gr_text_bitmap = 0;
+ static int gr_margin_right = 0;
+ static int gr_margin_top = 0;
+
+ extern void grGotobitmap( grBitmap* bitmap )
+ {
+ gr_text_bitmap = bitmap;
+ }
+
+ extern void grSetMargin( int right, int top )
+ {
+ gr_margin_top = top << 3;
+ gr_margin_right = right << 3;
+ }
+
+ extern void grGotoxy ( int x, int y )
+ {
+ gr_cursor_x = x;
+ gr_cursor_y = y;
+ }
+
+ extern void grWrite ( const char* string )
+ {
+ if (string)
+ {
+ grWriteCellString( gr_text_bitmap,
+ gr_margin_right + (gr_cursor_x << 3),
+ gr_margin_top + (gr_cursor_y << 3),
+ string,
+ (grColor)127L );
+
+ gr_cursor_x += strlen(string);
+ }
+ }
+
+ extern void grLn()
+ {
+ gr_cursor_y ++;
+ gr_cursor_x = 0;
+ }
+
+ extern void grWriteln( const char* string )
+ {
+ grWrite( string );
+ grLn();
+ }
+
+
--- /dev/null
+++ b/demos/graph/grfont.h
@@ -1,0 +1,16 @@
+#ifndef GRFONT_H
+#define GRFONT_H
+
+#include "graph.h"
+
+ extern const unsigned char font_8x8[];
+
+ extern void grGotobitmap( grBitmap* bitmap );
+ extern void grSetMargin( int right, int top );
+ extern void grGotoxy ( int x, int y );
+
+ extern void grWrite ( const char* string );
+ extern void grWriteln( const char* string );
+ extern void grLn();
+
+#endif /* GRFONT_H */
--- /dev/null
+++ b/demos/graph/grinit.c
@@ -1,0 +1,78 @@
+#include "grobjs.h"
+#include "grdevice.h"
+#include <stdio.h>
+
+#define GR_INIT_DEVICE_CHAIN ((grDeviceChain*)0)
+#define GR_INIT_BUILD
+
+#ifdef DEVICE_X11
+#include "grx11.h"
+#endif
+
+#ifdef DEVICE_OS2_PM
+#include "gros2pm.h"
+#endif
+
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grInitDevices
+ *
+ * <Description>
+ * This function is in charge of initialising all system-specific
+ * devices. A device is responsible for creating and managing one
+ * or more "surfaces". A surface is either a window or a screen,
+ * depending on the system.
+ *
+ * <Return>
+ * a pointer to the first element of a device chain. The chain can
+ * be parsed to find the available devices on the current system
+ *
+ * <Note>
+ * If a device cannot be initialised correctly, it is not part of
+ * the device chain returned by this function. For example, if an
+ * X11 device was compiled in the library, it will be part of
+ * the returned device chain only if a connection to the display
+ * could be establisged
+ *
+ * If no driver could be initialised, this function returns NULL.
+ *
+ **********************************************************************/
+
+ extern
+ grDeviceChain* grInitDevices( void )
+ {
+ grDeviceChain* chain = GR_INIT_DEVICE_CHAIN;
+ grDeviceChain* cur = gr_device_chain;
+
+ while (chain)
+ {
+ /* initialie the device */
+ grDevice* device;
+
+ device = chain->device;
+ if ( device->init() == 0 &&
+ gr_num_devices < GR_MAX_DEVICES )
+
+ {
+ /* successful device initialisation - add it to our chain */
+ cur->next = 0;
+ cur->device = device;
+ cur->name = device->device_name;
+
+ if (cur > gr_device_chain)
+ cur[-1].next = cur;
+
+ cur++;
+ gr_num_devices++;
+ }
+ chain = chain->next;
+ }
+
+ return (gr_num_devices > 0 ? gr_device_chain : 0 );
+ }
+
+
+
--- /dev/null
+++ b/demos/graph/grobjs.c
@@ -1,0 +1,213 @@
+#include "grobjs.h"
+#include <stdlib.h>
+
+
+ int grError = 0;
+
+
+ /********************************************************************
+ *
+ * <Function>
+ * grRealloc
+ *
+ * <Description>
+ * Simple memory re-allocation.
+ *
+ * <Input>
+ * block :: original memory block address
+ * size :: new requested block size in bytes
+ *
+ * <Return>
+ * the memory block address. 0 in case of error
+ *
+ ********************************************************************/
+
+ char* grAlloc( long size )
+ {
+ char* p;
+
+ p = (char*)malloc(size);
+ if (!p && size > 0)
+ {
+ grError = gr_err_memory;
+ }
+
+ if (p)
+ memset( p, 0, size );
+
+ return p;
+ }
+
+
+ /********************************************************************
+ *
+ * <Function>
+ * grRealloc
+ *
+ * <Description>
+ * Simple memory re-allocation.
+ *
+ * <Input>
+ * block :: original memory block address
+ * size :: new requested block size in bytes
+ *
+ * <Return>
+ * the memory block address. 0 in case of error
+ *
+ ********************************************************************/
+
+ char* grRealloc( const char* block, long size )
+ {
+ char* p;
+
+ p = realloc( (char*)block, size );
+ if (!p && size > 0)
+ {
+ grError = gr_err_memory;
+ }
+ return p;
+ }
+
+
+ /********************************************************************
+ *
+ * <Function>
+ * grFree
+ *
+ * <Description>
+ * Simple memory release
+ *
+ * <Input>
+ * block :: target block
+ *
+ ********************************************************************/
+
+ void grFree( const void* block )
+ {
+ if (block)
+ free( (char*)block );
+ }
+
+
+
+ static
+ int check_mode( grPixelMode pixel_mode,
+ int num_grays )
+ {
+ if ( pixel_mode <= gr_pixel_mode_none ||
+ pixel_mode >= gr_pixel_mode_max )
+ goto Fail;
+
+ if ( pixel_mode != gr_pixel_mode_gray ||
+ ( num_grays >= 2 && num_grays < 256 ) )
+ return 0;
+
+ Fail:
+ grError = gr_err_bad_argument;
+ return grError;
+ }
+
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grNewBitmap
+ *
+ * <Description>
+ * creates a new bitmap
+ *
+ * <Input>
+ * pixel_mode :: the target surface's pixel_mode
+ * num_grays :: number of grays levels for PAL8 pixel mode
+ * width :: width in pixels
+ * height :: height in pixels
+ *
+ * <Output>
+ * bit :: descriptor of the new bitmap
+ *
+ * <Return>
+ * Error code. 0 means success.
+ *
+ **********************************************************************/
+
+ extern int grNewBitmap( grPixelMode pixel_mode,
+ int num_grays,
+ int width,
+ int height,
+ grBitmap *bit )
+ {
+ int pitch;
+
+ /* check mode */
+ if (check_mode(pixel_mode,num_grays))
+ goto Fail;
+
+ /* check dimensions */
+ if (width < 0 || height < 0)
+ {
+ grError = gr_err_bad_argument;
+ goto Fail;
+ }
+
+ bit->width = width;
+ bit->rows = height;
+ bit->mode = pixel_mode;
+ bit->grays = num_grays;
+
+ pitch = width;
+
+ switch (pixel_mode)
+ {
+ case gr_pixel_mode_mono : pitch = (width+7) >> 3; break;
+ case gr_pixel_mode_pal4 : pitch = (width+3) >> 2; break;
+
+ case gr_pixel_mode_pal8 :
+ case gr_pixel_mode_gray : pitch = width; break;
+
+ case gr_pixel_mode_rgb555:
+ case gr_pixel_mode_rgb565: pitch = width*2; break;
+
+ case gr_pixel_mode_rgb24 : pitch = width*3; break;
+
+ case gr_pixel_mode_rgb32 : pitch = width*4; break;
+
+ default:
+ grError = gr_err_bad_target_depth;
+ return 0;
+ }
+
+ bit->pitch = pitch;
+ bit->buffer = grAlloc( (long)bit->pitch * bit->rows );
+ if (!bit->buffer) goto Fail;
+
+ return 0;
+
+ Fail:
+ return grError;
+ }
+
+ /**********************************************************************
+ *
+ * <Function>
+ * grDoneBitmap
+ *
+ * <Description>
+ * destroys a bitmap
+ *
+ * <Input>
+ * bitmap :: handle to bitmap descriptor
+ *
+ * <Note>
+ * This function does NOT release the bitmap descriptor, only
+ * the pixel buffer.
+ *
+ **********************************************************************/
+
+ extern void grDoneBitmap( grBitmap* bit )
+ {
+ grFree( bit->buffer );
+ bit->buffer = 0;
+ }
+
+
+
--- /dev/null
+++ b/demos/graph/grobjs.h
@@ -1,0 +1,186 @@
+/***************************************************************************
+ *
+ * grobjs.h
+ *
+ * basic object classes defintions
+ *
+ * Copyright 1999 - The FreeType Development Team - www.freetype.org
+ *
+ *
+ *
+ *
+ ***************************************************************************/
+
+#ifndef GROBJS_H
+#define GROBJS_H
+
+#include "graph.h"
+#include "grconfig.h"
+#include "grtypes.h"
+
+
+ typedef struct grBiColor_
+ {
+ grColor foreground;
+ grColor background;
+
+ int num_levels;
+ int max_levels;
+ grColor* levels;
+
+ } grBiColor;
+
+
+
+ /**********************************************************************
+ *
+ * Technical note : explaining how the blitter works.
+ *
+ * The blitter is used to "draw" a given source bitmap into
+ * a given target bitmap.
+ *
+ * The function called 'compute_clips' is used to compute clipping
+ * constraints. These lead us to compute two areas :
+ *
+ * - the read area : is the rectangle, within the source bitmap,
+ * which will be effectively "drawn" in the
+ * target bitmap.
+ *
+ * - the write area : is the rectangle, within the target bitmap,
+ * which will effectively "receive" the pixels
+ * from the read area
+ *
+ * Note that both areas have the same dimensions, but are
+ * located in distinct surfaces.
+ *
+ * These areas are computed by 'compute_clips' which is called
+ * by each blitting function.
+ *
+ * Note that we use the Y-downwards convention within the blitter
+ *
+ **********************************************************************/
+
+ typedef struct grBlitter_
+ {
+ int width; /* width in pixels of the areas */
+ int height; /* height in pixels of the areas */
+
+ 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 */
+
+ unsigned char* read; /* top left corner of read area in source map */
+ unsigned char* write; /* top left corner of write area in 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 */
+
+ grBitmap source; /* source bitmap descriptor */
+ grBitmap target; /* target bitmap descriptor */
+
+ } grBlitter;
+
+
+
+ typedef void (*grBlitterFunc)( grBlitter* blitter,
+ grColor color );
+
+ typedef void (*grSetTitleFunc)( grSurface* surface,
+ const char* title_string );
+
+ typedef void (*grRefreshRectFunc)( grSurface* surface,
+ int x,
+ int y,
+ int width,
+ int height );
+
+ typedef void (*grDoneSurfaceFunc)( grSurface* surface );
+
+ typedef int (*grListenEventFunc)( grSurface* surface,
+ int event_mode,
+ grEvent *event );
+
+
+
+ struct grSurface_
+ {
+ grDevice* device;
+ grBitmap bitmap;
+ grBool refresh;
+ grBool owner;
+
+ const byte* saturation; /* used for gray surfaces only */
+ grBlitterFunc blit_mono; /* 0 by default, set by grBlit.. */
+
+ grRefreshRectFunc refresh_rect;
+ grSetTitleFunc set_title;
+ grListenEventFunc listen_event;
+ grDoneSurfaceFunc done;
+ };
+
+
+
+ /********************************************************************
+ *
+ * <Function>
+ * grAlloc
+ *
+ * <Description>
+ * Simple memory allocation. The returned block is always zero-ed
+ *
+ * <Input>
+ * size :: size in bytes of the requested block
+ *
+ * <Return>
+ * the memory block address. 0 in case of error
+ *
+ ********************************************************************/
+
+ extern char* grAlloc( long size );
+
+
+ /********************************************************************
+ *
+ * <Function>
+ * grRealloc
+ *
+ * <Description>
+ * Simple memory re-allocation.
+ *
+ * <Input>
+ * block :: original memory block address
+ * size :: new requested block size in bytes
+ *
+ * <Return>
+ * the memory block address. 0 in case of error
+ *
+ ********************************************************************/
+
+ extern char* grRealloc( const char* block, long size );
+
+
+ /********************************************************************
+ *
+ * <Function>
+ * grFree
+ *
+ * <Description>
+ * Simple memory release
+ *
+ * <Input>
+ * block :: target block
+ *
+ ********************************************************************/
+
+ extern void grFree( const void* block );
+
+
+ extern grDevice* gr_devices[];
+ extern int gr_num_devices;
+ extern int gr_max_devices;
+
+#endif /* GROBJS_H */
--- /dev/null
+++ b/demos/graph/gros2pm.c
@@ -1,0 +1,895 @@
+#include "gros2pm.h"
+
+
+#define INCL_DOS
+#define INCL_WIN
+#define INCL_GPI
+#define INCL_SUB
+
+#include <os2.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+
+ static void Panic( const char* message )
+ {
+ fprintf( stderr, "%s", message );
+ exit(1);
+ }
+
+ typedef struct Translator
+ {
+ ULONG os2key;
+ grKey grkey;
+
+ } Translator;
+
+
+ static
+ Translator key_translators[] =
+ {
+ { VK_BACKSPACE, grKeyBackSpace },
+ { VK_TAB, grKeyTab },
+ { VK_ENTER, grKeyReturn },
+ { VK_ESC, grKeyEsc },
+ { VK_HOME, grKeyHome },
+ { VK_LEFT, grKeyLeft },
+ { VK_UP, grKeyUp },
+ { VK_RIGHT, grKeyRight },
+ { VK_DOWN, grKeyDown },
+ { VK_PAGEUP, grKeyPageUp },
+ { VK_PAGEDOWN, grKeyPageDown },
+ { VK_END, grKeyEnd },
+ { VK_F1, grKeyF1 },
+ { VK_F2, grKeyF2 },
+ { VK_F3, grKeyF3 },
+ { VK_F4, grKeyF4 },
+ { VK_F5, grKeyF5 },
+ { VK_F6, grKeyF6 },
+ { VK_F7, grKeyF7 },
+ { VK_F8, grKeyF8 },
+ { VK_F9, grKeyF9 },
+ { VK_F10, grKeyF10 },
+ { VK_F11, grKeyF11 },
+ { VK_F12, grKeyF12 }
+ };
+
+
+#define MAX_PIXEL_MODES 32
+
+ static int num_pixel_modes = 0;
+ static grPixelMode pixel_modes[ MAX_PIXEL_MODES ];
+ static int pixel_depth[ MAX_PIXEL_MODES ];
+
+ static HAB gr_anchor; /* device anchor block */
+
+ typedef POINTL PMBlitPoints[4];
+
+
+ typedef struct grPMSurface_
+ {
+ grSurface root;
+ grBitmap image;
+
+ HAB anchor; /* handle to anchor block for surface's window */
+ HWND frame_window; /* handle to window's frame */
+ HWND client_window; /* handle to window's client */
+ HWND title_window; /* handle to window's title bar */
+
+ HPS image_ps; /* memory presentation space used to hold */
+ /* the surface's content under PM */
+ HDC image_dc; /* memory device context for the image */
+
+ HEV event_lock; /* semaphore used in listen_surface */
+ HMTX image_lock; /* a mutex used to synchronise access */
+ /* to the memory presentation space */
+ /* used to hold the surface */
+
+ TID message_thread; /* thread used to process this surface's */
+ /* messages.. */
+
+ PBITMAPINFO2 bitmap_header;/* os/2 bitmap descriptor */
+ HBITMAP os2_bitmap; /* Handle to OS/2 bitmap contained in image */
+ BOOL ready; /* ??? */
+
+ long shades[256]; /* indices of gray levels in pixel_mode_gray */
+
+ POINTL surface_blit[4]; /* surface blitting table */
+ POINTL magnify_blit[4]; /* magnifier blitting table */
+ int magnification; /* level of magnification */
+ POINTL magnify_center;
+ SIZEL magnify_size;
+
+ grEvent event;
+
+ PMBlitPoints blit_points;
+
+ } grPMSurface;
+
+
+
+ static
+ void enable_os2_iostreams( void )
+ {
+ 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;
+ }
+
+
+
+ static
+ int init_device( void )
+ {
+ enable_os2_iostreams();
+
+ /* create an anchor block. This will allow this thread (i.e. the */
+ /* main one) to call Gpi functions.. */
+ gr_anchor = WinInitialize(0);
+ if (!gr_anchor)
+ {
+ /* could not initialise Presentation Manager */
+ return -1;
+ }
+
+ return 0;
+ }
+
+
+
+ static
+ void done_device( void )
+ {
+ /* Indicates that we do not use the Presentation Manager, this */
+ /* will also release all associated resources.. */
+ WinTerminate( gr_anchor );
+ }
+
+
+
+ /* close a given window */
+ static
+ void done_surface( grPMSurface* surface )
+ {
+ if ( surface->frame_window )
+ WinDestroyWindow( surface->frame_window );
+
+ WinReleasePS( surface->image_ps );
+
+ grDoneBitmap( &surface->image );
+ grDoneBitmap( &surface->root.bitmap );
+ }
+
+
+
+
+
+ static
+ void add_pixel_mode( grPixelMode pixel_mode,
+ int depth )
+ {
+ if ( num_pixel_modes >= MAX_PIXEL_MODES )
+ Panic( "X11.Too many pixel modes\n" );
+
+ pixel_modes[ num_pixel_modes ] = pixel_mode;
+ pixel_depth[ num_pixel_modes ] = depth;
+
+ num_pixel_modes++;
+ }
+
+
+#define LOCK(x) DosRequestMutexSem( x, SEM_INDEFINITE_WAIT );
+#define UNLOCK(x) DosReleaseMutexSem( x )
+
+
+ static
+ const int pixel_mode_bit_count[] =
+ {
+ 0,
+ 1,
+ 4,
+ 8, /* pal8 */
+ 8, /* gray */
+ 15,
+ 16,
+ 24,
+ 32
+ };
+
+
+ /************************************************************************
+ *
+ * Technical note : how the OS/2 Presntation Manager driver works
+ *
+ * PM is, in my opinion, a bloated and over-engineered graphics
+ * sub-system, even though it has lots of nice features. Here are
+ * a few tidbits about it :
+ *
+ *
+ * - under PM, a "bitmap" is a device-specific object whose bits are
+ * not directly accessible to the client application. This means
+ * that we must use a scheme like the following to display our
+ * surfaces :
+ *
+ * - hold, for each surface, its own bitmap buffer where the
+ * rest of MiGS writes directly.
+ *
+ * - create a PM bitmap object with the same dimensions (and
+ * possibly format).
+ *
+ * - copy the content of each updated rectangle into the
+ * PM bitmap with the function 'GpiSetBitmapBits'.
+ *
+ * - finally, "blit" the PM bitmap to the screen calling
+ * 'GpiBlitBlt'
+ *
+ * - but there is more : you cannot directly blit a PM bitmap to the
+ * screen with PM. The 'GpiBlitBlt' only works with presentation
+ * spaces. This means that we also need to create, for each surface :
+ *
+ * - a memory presentation space, used to hold the PM bitmap
+ * - a "memory device context" for the presentation space
+ *
+ * The blit is then performed from the memory presentation space
+ * to the screen's presentation space..
+ *
+ *
+ * - because each surface creates its own event-handling thread,
+ * we must protect the surface's presentation space from concurrent
+ * accesses (i.e. calls to 'GpiSetBitmapBits' when drawing to the
+ * surface, and calls to 'GpiBlitBlt' when drawing it on the screen
+ * are performed in two different threads).
+ *
+ * we use a simple mutex to do this.
+ *
+ *
+ * - we also use a semaphore to perform a rendez-vous between the
+ * main and event-handling threads (needed in "listen_event").
+ *
+ ************************************************************************/
+
+ static
+ void RunPMWindow( grPMSurface* surface );
+
+
+
+
+
+
+
+
+
+
+
+
+ static
+ void convert_gray_to_pal8( grPMSurface* surface,
+ int x,
+ int y,
+ int w,
+ int h )
+ {
+ grBitmap* target = &surface->image;
+ grBitmap* source = &surface->root.bitmap;
+ byte* write = (byte*)target->buffer + y*target->pitch + x;
+ byte* read = (byte*)source->buffer + y*source->pitch + x;
+ long* palette = surface->shades;
+
+ while (h > 0)
+ {
+ byte* _write = write;
+ byte* _read = read;
+ byte* limit = _write + w;
+
+ for ( ; _write < limit; _write++, _read++ )
+ *_write = (byte) palette[ *_read ];
+
+ write += target->pitch;
+ read += source->pitch;
+ h--;
+ }
+ }
+
+
+ static
+ void convert_gray_to_16( grPMSurface* surface,
+ int x,
+ int y,
+ int w,
+ int h )
+ {
+ grBitmap* target = &surface->image;
+ grBitmap* source = &surface->root.bitmap;
+ byte* write = (byte*)target->buffer + y*target->pitch + 2*x;
+ byte* read = (byte*)source->buffer + y*source->pitch + x;
+ long* palette = surface->shades;
+
+ while (h > 0)
+ {
+ byte* _write = write;
+ byte* _read = read;
+ byte* limit = _write + 2*w;
+
+ for ( ; _write < limit; _write += 2, _read++ )
+ *(short*)_write = (short)palette[ *_read ];
+
+ write += target->pitch;
+ read += source->pitch;
+ h--;
+ }
+ }
+
+
+ static
+ void convert_gray_to_24( grPMSurface* surface,
+ int x,
+ int y,
+ int w,
+ int h )
+ {
+ grBitmap* target = &surface->image;
+ grBitmap* source = &surface->root.bitmap;
+ byte* write = (byte*)target->buffer + y*target->pitch + 3*x;
+ byte* read = (byte*)source->buffer + y*source->pitch + x;
+
+ while (h > 0)
+ {
+ byte* _write = write;
+ byte* _read = read;
+ byte* limit = _write + 3*w;
+
+ for ( ; _write < limit; _write += 3, _read++ )
+ {
+ byte color = *_read;
+
+ _write[0] =
+ _write[1] =
+ _write[2] = color;
+ }
+
+ write += target->pitch;
+ read += source->pitch;
+ h--;
+ }
+ }
+
+
+ static
+ void convert_gray_to_32( grPMSurface* surface,
+ int x,
+ int y,
+ int w,
+ int h )
+ {
+ grBitmap* target = &surface->image;
+ grBitmap* source = &surface->root.bitmap;
+ byte* write = (byte*)target->buffer + y*target->pitch + 4*x;
+ byte* read = (byte*)source->buffer + y*source->pitch + x;
+
+ while (h > 0)
+ {
+ byte* _write = write;
+ byte* _read = read;
+ byte* limit = _write + 4*w;
+
+ for ( ; _write < limit; _write += 4, _read++ )
+ {
+ byte color = *_read;
+
+ _write[0] =
+ _write[1] =
+ _write[2] =
+ _write[3] = color;
+ }
+
+ write += target->pitch;
+ read += source->pitch;
+ h--;
+ }
+ }
+
+
+ static
+ void convert_rectangle( grPMSurface* surface,
+ int x,
+ int y,
+ int w,
+ int h )
+ {
+ int z;
+
+ /* first of all, clip to the surface's area */
+ if ( x >= surface->image.width ||
+ x+w <= 0 ||
+ y >= surface->image.rows ||
+ y+h <= 0 )
+ return;
+
+ if ( x < 0 )
+ {
+ w += x;
+ x = 0;
+ }
+
+ z = (x + w) - surface->image.width;
+ if (z > 0)
+ w -= z;
+
+ z = (y + h) - surface->image.rows;
+ if (z > 0)
+ h -= z;
+
+ /* convert the rectangle to the target depth for gray surfaces */
+ if (surface->root.bitmap.mode == gr_pixel_mode_gray)
+ {
+ switch (surface->image.mode)
+ {
+ case gr_pixel_mode_pal8 :
+ convert_gray_to_pal8( surface, x, y, w, h );
+ break;
+
+ case gr_pixel_mode_rgb555:
+ case gr_pixel_mode_rgb565:
+ convert_gray_to_16 ( surface, x, y, w, h );
+ break;
+
+ case gr_pixel_mode_rgb24:
+ convert_gray_to_24 ( surface, x, y, w, h );
+ break;
+
+ case gr_pixel_mode_rgb32:
+ convert_gray_to_32 ( surface, x, y, w, h );
+ break;
+
+ default:
+ ;
+ }
+ }
+ }
+
+
+ static
+ void refresh_rectangle( grPMSurface* surface,
+ int x,
+ int y,
+ int w,
+ int h )
+ {
+ convert_rectangle( surface, x, y, w, h );
+
+ WinInvalidateRect( surface->client_window, NULL, FALSE );
+ WinUpdateWindow( surface->frame_window );
+ }
+
+
+ static
+ void set_title( grPMSurface* surface,
+ const char* title )
+ {
+ WinSetWindowText( surface->title_window, (PSZ)title );
+ }
+
+
+
+ static
+ void listen_event( grPMSurface* surface,
+ int event_mask,
+ grEvent* grevent )
+ {
+ ULONG ulRequestCount;
+
+ (void) event_mask; /* ignored for now */
+
+ /* the listen_event function blocks until there is an event to process */
+ DosWaitEventSem( surface->event_lock, SEM_INDEFINITE_WAIT );
+ DosQueryEventSem( surface->event_lock, &ulRequestCount );
+ *grevent = surface->event;
+ DosResetEventSem( surface->event_lock, &ulRequestCount );
+
+ return;
+ }
+
+
+ static
+ int init_surface( grPMSurface* surface,
+ grBitmap* bitmap )
+ {
+ PBITMAPINFO2 bit;
+ SIZEL sizl = { 0, 0 };
+ LONG palette[256];
+
+ /* create the bitmap - under OS/2, we support all modes as PM */
+ /* handles all conversions automatically.. */
+ if ( grNewBitmap( surface->root.bitmap.mode,
+ surface->root.bitmap.grays,
+ surface->root.bitmap.width,
+ surface->root.bitmap.rows,
+ bitmap ) )
+ return grError;
+
+ surface->root.bitmap = *bitmap;
+
+ /* create the image and event lock */
+ DosCreateEventSem( NULL, &surface->event_lock, 0, TRUE );
+ DosCreateMutexSem( NULL, &surface->image_lock, 0, FALSE );
+
+ /* create the image's presentation space */
+ surface->image_dc = DevOpenDC( gr_anchor,
+ OD_MEMORY, (PSZ)"*", 0L, 0L, 0L );
+
+ surface->image_ps = GpiCreatePS( gr_anchor,
+ surface->image_dc,
+ &sizl,
+ PU_PELS | GPIT_MICRO |
+ GPIA_ASSOC | GPIF_DEFAULT );
+
+ GpiSetBackMix( surface->image_ps, BM_OVERPAINT );
+
+ /* create the image's PM bitmap */
+ bit = (PBITMAPINFO2)grAlloc( sizeof(BITMAPINFO2) + 256*sizeof(RGB2) );
+ surface->bitmap_header = bit;
+
+ bit->cbFix = sizeof( BITMAPINFOHEADER2 );
+ bit->cx = surface->root.bitmap.width;
+ bit->cy = surface->root.bitmap.rows;
+ bit->cPlanes = 1;
+
+ bit->argbColor[0].bBlue = 0;
+ bit->argbColor[0].bGreen = 0;
+ bit->argbColor[0].bRed = 0;
+
+ bit->argbColor[1].bBlue = 255;
+ bit->argbColor[1].bGreen = 255;
+ bit->argbColor[1].bRed = 255;
+
+ bit->cBitCount = pixel_mode_bit_count[ surface->root.bitmap.mode ];
+
+ surface->os2_bitmap = GpiCreateBitmap( surface->image_ps,
+ (PBITMAPINFOHEADER2)bit,
+ 0L, NULL, NULL );
+
+ GpiSetBitmap( surface->image_ps, surface->os2_bitmap );
+
+ bit->cbFix = sizeof( BITMAPINFOHEADER2 );
+ GpiQueryBitmapInfoHeader( surface->os2_bitmap,
+ (PBITMAPINFOHEADER2)bit );
+
+ /* for gr_pixel_mode_gray, create a gray-levels logical palette */
+ if ( bitmap->mode == gr_pixel_mode_gray )
+ {
+ int x, count;
+
+ count = bitmap->grays;
+ for ( x = 0; x < count; x++ )
+ palette[x] = (((count-x)*255)/count) * 0x010101;
+
+ /* create logical color table */
+ GpiCreateLogColorTable( surface->image_ps,
+ (ULONG) LCOL_PURECOLOR,
+ (LONG) LCOLF_CONSECRGB,
+ (LONG) 0L,
+ (LONG) count,
+ (PLONG) palette );
+
+ /* now, copy the color indexes to surface->shades */
+ for ( x = 0; x < count; x++ )
+ surface->shades[x] = GpiQueryColorIndex( surface->image_ps,
+ 0, palette[x] );
+ }
+
+ /* set up the blit points array */
+ surface->blit_points[1].x = surface->root.bitmap.width;
+ surface->blit_points[1].y = surface->root.bitmap.rows;
+ surface->blit_points[3] = surface->blit_points[1];
+
+ /* Finally, create the event handling thread for the surface's window */
+ DosCreateThread( &surface->message_thread,
+ (PFNTHREAD) RunPMWindow,
+ (ULONG) surface,
+ 0UL,
+ 32920 );
+
+ surface->root.done = (grDoneSurfaceFunc) done_surface;
+ surface->root.refresh_rect = (grRefreshRectFunc) refresh_rectangle;
+ surface->root.set_title = (grSetTitleFunc) set_title;
+ surface->root.listen_event = (grListenEventFunc) listen_event;
+
+ convert_rectangle( surface, 0, 0, bitmap->width, bitmap->rows );
+ return 0;
+ }
+
+
+
+ MRESULT EXPENTRY Message_Process( HWND handle,
+ ULONG mess,
+ MPARAM parm1,
+ MPARAM parm2 );
+
+
+ static
+ void RunPMWindow( grPMSurface* surface )
+ {
+ unsigned char class_name[] = "DisplayClass";
+ ULONG class_flags;
+
+ static HMQ queue;
+ QMSG message;
+
+ /* create an anchor to allow this thread to use PM */
+ surface->anchor = WinInitialize(0);
+ if (!surface->anchor)
+ {
+ printf( "Error doing WinInitialize()\n" );
+ return;
+ }
+
+ /* create a message queue */
+ queue = WinCreateMsgQueue( surface->anchor, 0 );
+ if (!queue)
+ {
+ printf( "Error doing >inCreateMsgQueue()\n" );
+ return;
+ }
+
+ /* register the window class */
+ if ( !WinRegisterClass( surface->anchor,
+ (PSZ) class_name,
+ (PFNWP) Message_Process,
+ CS_SIZEREDRAW,
+ 0 ) )
+ {
+ printf( "Error doing WinRegisterClass()\n" );
+ return;
+ }
+
+ /* create the PM window */
+ class_flags = FCF_TITLEBAR | FCF_MINBUTTON | FCF_DLGBORDER |
+ FCF_TASKLIST | FCF_SYSMENU;
+
+ surface->frame_window = WinCreateStdWindow(
+ HWND_DESKTOP,
+ WS_VISIBLE,
+ &class_flags,
+ (PSZ) class_name,
+ (PSZ) "FreeType PM Graphics",
+ WS_VISIBLE,
+ 0, 0,
+ &surface->client_window );
+ if (!surface->frame_window)
+ {
+ printf( "Error doing WinCreateStdWindow()\n" );
+ return;
+ }
+
+ /* find the title window handle */
+ surface->title_window = WinWindowFromID( surface->frame_window,
+ FID_TITLEBAR );
+
+ /* set Window size and position */
+ WinSetWindowPos( surface->frame_window,
+ 0L,
+ (SHORT) 60,
+ (SHORT) WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ) -
+ surface->root.bitmap.rows + 100,
+
+ (SHORT) WinQuerySysValue( HWND_DESKTOP, SV_CYDLGFRAME )*2 +
+ surface->root.bitmap.width,
+
+ (SHORT) WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR ) +
+ WinQuerySysValue( HWND_DESKTOP, SV_CYDLGFRAME )*2 +
+ surface->root.bitmap.rows,
+
+ SWP_SIZE | SWP_MOVE );
+
+ /* save the handle to the current surface within the window words */
+ WinSetWindowPtr( surface->frame_window,QWL_USER, surface );
+
+ /* run the message queue till the end */
+ while ( WinGetMsg( surface->anchor, &message, (HWND)NULL, 0, 0 ) )
+ WinDispatchMsg( surface->anchor, &message );
+
+ /* clean-up */
+ WinDestroyWindow( surface->frame_window );
+ surface->frame_window = 0;
+
+ WinDestroyMsgQueue( queue );
+ WinTerminate( surface->anchor );
+
+ /* await death... */
+ while ( 1 )
+ DosSleep( 100 );
+ }
+
+
+
+
+ /* Message processing for our PM Window class */
+ MRESULT EXPENTRY Message_Process( HWND handle,
+ ULONG mess,
+ MPARAM parm1,
+ MPARAM parm2 )
+ {
+ static HDC screen_dc;
+ static HPS screen_ps;
+ static BOOL minimized;
+
+ SIZEL sizl;
+ SWP swp;
+
+ grPMSurface* surface;
+
+ /* get the handle to the window's surface */
+ surface = (grPMSurface*)WinQueryWindowPtr( handle, QWL_USER );
+
+ switch( mess )
+ {
+ case WM_DESTROY:
+ /* warn the main thread to quit if it didn't know */
+ surface->event.type = gr_event_key;
+ surface->event.key = grKeyEsc;
+ DosPostEventSem( surface->event_lock );
+ break;
+
+ case WM_CREATE:
+ /* set original magnification */
+ minimized = FALSE;
+
+ /* create Device Context and Presentation Space for screen. */
+ screen_dc = WinOpenWindowDC( handle );
+ screen_ps = GpiCreatePS( surface->anchor,
+ screen_dc,
+ &sizl,
+ PU_PELS | GPIT_MICRO |
+ GPIA_ASSOC | GPIF_DEFAULT );
+
+ /* take the input focus */
+ WinFocusChange( HWND_DESKTOP, handle, 0L );
+ 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:
+ /* copy the memory image of the screen out to the real screen */
+ DosRequestMutexSem( surface->image_lock, SEM_INDEFINITE_WAIT );
+ WinBeginPaint( handle, screen_ps, NULL );
+
+ /* main image and magnified picture */
+ GpiBitBlt( screen_ps,
+ surface->image_ps,
+ 4L,
+ surface->blit_points,
+ ROP_SRCCOPY, BBO_AND );
+
+ WinEndPaint( screen_ps );
+ DosReleaseMutexSem( surface->image_lock );
+ break;
+
+ case WM_CHAR:
+ if ( CHARMSG( &mess )->fs & KC_KEYUP )
+ break;
+
+ /* look for a specific vkey */
+ {
+ int count = sizeof( key_translators )/sizeof( key_translators[0] );
+ Translator* trans = key_translators;
+ Translator* limit = trans + count;
+
+ for ( ; trans < limit; trans++ )
+ if ( CHARMSG(&mess)->vkey == trans->os2key )
+ {
+ surface->event.key = trans->grkey;
+ goto Do_Key_Event;
+ }
+ }
+
+ /* otherwise, simply record the character code */
+ if ( (CHARMSG( &mess )->fs & KC_CHAR) == 0 )
+ break;
+
+ surface->event.key = CHARMSG(&mess)->chr;
+
+ Do_Key_Event:
+ surface->event.type = gr_event_key;
+ DosPostEventSem( surface->event_lock );
+ break;
+
+ default:
+ return WinDefWindowProc( handle, mess, parm1, parm2 );
+ }
+
+ return (MRESULT) FALSE;
+ }
+
+
+
+
+
+
+
+#if 0
+ static
+ grKey KeySymTogrKey( key )
+ {
+ grKey k;
+ int count = sizeof(key_translators)/sizeof(key_translators[0]);
+ Translator* trans = key_translators;
+ Translator* limit = trans + count;
+
+ k = grKeyNone;
+
+ while ( trans < limit )
+ {
+ if ( trans->xkey == key )
+ {
+ k = trans->grkey;
+ break;
+ }
+ trans++;
+ }
+
+ return k;
+ }
+
+
+
+ static
+ void listen_event( grPMSurface* surface,
+ int event_mask,
+ grEvent* grevent )
+ {
+ grKey grkey;
+
+ /* XXXX : For now, ignore the event mask, and only exit when */
+ /* a key is pressed.. */
+ (void)event_mask;
+
+
+ /* Now, translate the keypress to a grKey */
+ /* If this wasn't part of the simple translated keys, simply get the charcode */
+ /* from the character buffer */
+ grkey = grKEY(key_buffer[key_cursor++]);
+
+ Set_Key:
+ grevent->type = gr_key_down;
+ grevent->key = grkey;
+ }
+
+#endif
+
+
+
+ grDevice gr_os2pm_device =
+ {
+ sizeof( grPMSurface ),
+ "os2pm",
+
+ init_device,
+ done_device,
+
+ (grDeviceInitSurfaceFunc) init_surface,
+
+ 0,
+ 0
+
+ };
+
+
--- /dev/null
+++ b/demos/graph/gros2pm.h
@@ -1,0 +1,23 @@
+#ifndef GROS2PM_H
+#define GROS2PM_H
+
+#include "grobjs.h"
+
+ extern
+ grDevice gr_os2pm_device;
+
+#ifdef GR_INIT_BUILD
+ static
+ grDeviceChain gr_os2pm_device_chain =
+ {
+ "os2pm",
+ &gr_os2pm_device,
+ GR_INIT_DEVICE_CHAIN
+ };
+
+#undef GR_INIT_DEVICE_CHAIN
+#define GR_INIT_DEVICE_CHAIN &gr_os2pm_device_chain
+
+#endif /* GR_INIT_BUILD */
+
+#endif /* GROS2PM_H */
--- /dev/null
+++ b/demos/graph/grtypes.h
@@ -1,0 +1,52 @@
+/***************************************************************************
+ *
+ * grtypes.h
+ *
+ * basic type defintions
+ *
+ * Copyright 1999 - The FreeType Development Team - www.freetype.org
+ *
+ *
+ *
+ *
+ ***************************************************************************/
+
+#ifndef GRTYPES_H
+#define GRTYPES_H
+
+ typedef unsigned char byte;
+
+#if 0
+ typedef signed char uchar;
+
+ typedef unsigned long ulong;
+ typedef unsigned short ushort;
+ typedef unsigned int uint;
+#endif
+
+ typedef struct grDimension_
+ {
+ int x;
+ int y;
+
+ } grDimension;
+
+#define gr_err_ok 0
+#define gr_err_memory -1
+#define gr_err_bad_argument -2
+#define gr_err_bad_target_depth -3
+#define gr_err_bad_source_depth -4
+#define gr_err_saturation_overflow -5
+#define gr_err_conversion_overflow -6
+#define gr_err_invalid_device -7
+
+
+#ifdef GR_MAKE_OPTION_SINGLE_OBJECT
+#define GR_LOCAL_DECL static
+#define GR_LOCAL_FUNC static
+#else
+#define GR_LOCAL_DECL extern
+#define GR_LOCAL_FUNC /* void */
+#endif
+
+#endif /* GRTYPES_H */
--- /dev/null
+++ b/demos/graph/grx11.c
@@ -1,0 +1,936 @@
+#include "grx11.h"
+
+
+#ifdef TEST
+#include "grfont.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/cursorfont.h>
+#include <X11/keysym.h>
+
+ static void Panic( const char* message )
+ {
+ fprintf( stderr, "%s", message );
+ exit(1);
+ }
+
+ typedef struct Translator
+ {
+ KeySym xkey;
+ grKey grkey;
+
+ } Translator;
+
+ static
+ Translator key_translators[] =
+ {
+ { XK_BackSpace, grKeyBackSpace },
+ { XK_Tab, grKeyTab },
+ { XK_Return, grKeyReturn },
+ { XK_Escape, grKeyEsc },
+ { XK_Home, grKeyHome },
+ { XK_Left, grKeyLeft },
+ { XK_Up, grKeyUp },
+ { XK_Right, grKeyRight },
+ { XK_Down, grKeyDown },
+ { XK_Page_Up, grKeyPageUp },
+ { XK_Page_Down, grKeyPageDown },
+ { XK_End, grKeyEnd },
+ { XK_Begin, grKeyHome },
+ { XK_F1, grKeyF1 },
+ { XK_F2, grKeyF2 },
+ { XK_F3, grKeyF3 },
+ { XK_F4, grKeyF4 },
+ { XK_F5, grKeyF5 },
+ { XK_F6, grKeyF6 },
+ { XK_F7, grKeyF7 },
+ { XK_F8, grKeyF8 },
+ { XK_F9, grKeyF9 },
+ { XK_F10, grKeyF10 },
+ { XK_F11, grKeyF11 },
+ { XK_F12, grKeyF12 }
+ };
+
+
+#ifdef TEST
+
+#define grAlloc malloc
+
+#endif
+
+
+ static Display* display;
+ static char* displayname = "";
+
+ static Cursor idle;
+ static Cursor busy;
+
+#define MAX_PIXEL_MODES 32
+
+ typedef XPixmapFormatValues XDepth;
+
+ static int num_pixel_modes = 0;
+ static grPixelMode pixel_modes[ MAX_PIXEL_MODES ];
+ static XDepth pixel_depth[ MAX_PIXEL_MODES ];
+
+ typedef struct grXSurface_
+ {
+ grSurface root;
+ grBitmap image;
+
+ Window win;
+ Visual* visual;
+ Colormap colormap;
+ int depth;
+ Bool gray;
+
+ GC gc;
+
+ XColor color[256]; /* gray levels palette for 8-bit modes */
+ XImage* ximage;
+
+ int win_org_x;
+ int win_org_y;
+ int win_width;
+ int win_height;
+
+ int image_width;
+ int image_height;
+
+ } grXSurface;
+
+
+
+
+ /* close a given window */
+ static
+ void done_surface( grXSurface* surface )
+ {
+ XUnmapWindow( display, surface->win );
+ }
+
+
+
+ /* close the device, i.e. the display connection */
+ static
+ void done_device( void )
+ {
+ XCloseDisplay( display );
+ }
+
+
+
+ static
+ void add_pixel_mode( grPixelMode pixel_mode,
+ XDepth* depth )
+ {
+ if ( num_pixel_modes >= MAX_PIXEL_MODES )
+ Panic( "X11.Too many pixel modes\n" );
+
+ pixel_modes[ num_pixel_modes ] = pixel_mode;
+ pixel_depth[ num_pixel_modes ] = *depth;
+
+ num_pixel_modes++;
+ }
+
+
+
+ static
+ int init_device( void )
+ {
+ XDepth dummy;
+
+ XrmInitialize();
+
+ display = XOpenDisplay( displayname );
+ if (!display)
+ {
+ return -1;
+ /* Panic( "Gr:error: cannot open X11 display\n" ); */
+ }
+
+ idle = XCreateFontCursor( display, XC_left_ptr );
+ busy = XCreateFontCursor( display, XC_watch );
+
+ num_pixel_modes = 0;
+
+ /* always enable the 8-bit gray levels pixel mode */
+ /* even if its display is emulated through a constrained palette */
+ /* or another color mode */
+ dummy.depth = 8;
+ dummy.bits_per_pixel = 8;
+ dummy.scanline_pad = 8;
+ add_pixel_mode( gr_pixel_mode_gray, &dummy );
+
+ {
+ int count;
+ XDepth* format;
+ XDepth* formats;
+ XVisualInfo template;
+
+ formats = XListPixmapFormats( display, &count );
+ format = formats;
+
+#ifdef TEST
+ printf( "available pixmap formats\n" );
+ printf( "depth pixbits scanpad\n" );
+#endif
+
+ while ( count-- > 0 )
+ {
+#ifdef TEST
+ printf( " %3d %3d %3d\n",
+ format->depth,
+ format->bits_per_pixel,
+ format->scanline_pad );
+#endif
+
+ if ( format->depth == 1 )
+ /* usually, this should be the first format */
+ add_pixel_mode( gr_pixel_mode_mono, format );
+
+ else if ( format->depth == 8 )
+ add_pixel_mode( gr_pixel_mode_pal8, format );
+
+ /* note, the 32-bit modes return a depth of 24, and 32 bits per pixel */
+ else if ( format->depth == 24 )
+ {
+ if ( format->bits_per_pixel == 24 )
+ add_pixel_mode( gr_pixel_mode_rgb24, format );
+
+ else if ( format->bits_per_pixel == 32 )
+ add_pixel_mode( gr_pixel_mode_rgb32, format );
+ }
+
+ else if ( format->depth == 16 )
+ {
+ int count2;
+ XVisualInfo* visuals;
+ XVisualInfo* visual;
+
+ template.depth = format->depth;
+ visuals = XGetVisualInfo( display,
+ VisualDepthMask,
+ &template,
+ &count2 );
+ visual = visuals;
+
+ while ( count2-- > 0 )
+ {
+#ifdef TEST
+ const char* string = "unknown";
+
+ switch (visual->class)
+ {
+ case TrueColor: string = "TrueColor"; break;
+ case DirectColor: string = "DirectColor"; break;
+ case PseudoColor: string = "PseudoColor"; break;
+ case StaticGray : string = "StaticGray"; break;
+ case StaticColor: string = "StaticColor"; break;
+ case GrayScale: string = "GrayScale"; break;
+ }
+
+ printf( "> RGB %02x:%02x:%02x, colors %3d, bits %2d %s\n",
+ visual->red_mask,
+ visual->green_mask,
+ visual->blue_mask,
+ visual->colormap_size,
+ visual->bits_per_rgb,
+ string );
+#endif
+ if ( visual->red_mask == 0xf800 &&
+ visual->green_mask == 0x07e0 &&
+ visual->blue_mask == 0x001f )
+ add_pixel_mode( gr_pixel_mode_rgb565, format );
+
+ else if ( visual->red_mask == 0x7c00 &&
+ visual->green_mask == 0x03e0 &&
+ visual->blue_mask == 0x001f )
+ add_pixel_mode( gr_pixel_mode_rgb555, format );
+
+ /* other 16-bit modes are ignored */
+ visual++;
+ }
+
+ XFree( visuals );
+ }
+
+ format++;
+ }
+
+ XFree( formats );
+ }
+
+ gr_x11_device.num_pixel_modes = num_pixel_modes;
+ gr_x11_device.pixel_modes = pixel_modes;
+
+ return 0;
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+ static
+ void convert_gray_to_pal8( grXSurface* surface,
+ int x,
+ int y,
+ int w,
+ int h )
+ {
+ grBitmap* target = &surface->image;
+ grBitmap* source = &surface->root.bitmap;
+ byte* write = (byte*)target->buffer + y*target->pitch + x;
+ byte* read = (byte*)source->buffer + y*source->pitch + x;
+ XColor* palette = surface->color;
+
+ while (h > 0)
+ {
+ byte* _write = write;
+ byte* _read = read;
+ byte* limit = _write + w;
+
+ for ( ; _write < limit; _write++, _read++ )
+ *_write = (byte) palette[ *_read ].pixel;
+
+ write += target->pitch;
+ read += source->pitch;
+ h--;
+ }
+ }
+
+
+ static
+ void convert_gray_to_16( grXSurface* surface,
+ int x,
+ int y,
+ int w,
+ int h )
+ {
+ grBitmap* target = &surface->image;
+ grBitmap* source = &surface->root.bitmap;
+ byte* write = (byte*)target->buffer + y*target->pitch + 2*x;
+ byte* read = (byte*)source->buffer + y*source->pitch + x;
+ XColor* palette = surface->color;
+
+ while (h > 0)
+ {
+ byte* _write = write;
+ byte* _read = read;
+ byte* limit = _write + 2*w;
+
+ for ( ; _write < limit; _write += 2, _read++ )
+ *(short*)_write = (short)palette[ *_read ].pixel;
+
+ write += target->pitch;
+ read += source->pitch;
+ h--;
+ }
+ }
+
+
+ static
+ void convert_gray_to_24( grXSurface* surface,
+ int x,
+ int y,
+ int w,
+ int h )
+ {
+ grBitmap* target = &surface->image;
+ grBitmap* source = &surface->root.bitmap;
+ byte* write = (byte*)target->buffer + y*target->pitch + 3*x;
+ byte* read = (byte*)source->buffer + y*source->pitch + x;
+
+ while (h > 0)
+ {
+ byte* _write = write;
+ byte* _read = read;
+ byte* limit = _write + 3*w;
+
+ for ( ; _write < limit; _write += 3, _read++ )
+ {
+ byte color = *_read;
+
+ _write[0] =
+ _write[1] =
+ _write[2] = color;
+ }
+
+ write += target->pitch;
+ read += source->pitch;
+ h--;
+ }
+ }
+
+
+ static
+ void convert_gray_to_32( grXSurface* surface,
+ int x,
+ int y,
+ int w,
+ int h )
+ {
+ grBitmap* target = &surface->image;
+ grBitmap* source = &surface->root.bitmap;
+ byte* write = (byte*)target->buffer + y*target->pitch + 4*x;
+ byte* read = (byte*)source->buffer + y*source->pitch + x;
+
+ while (h > 0)
+ {
+ byte* _write = write;
+ byte* _read = read;
+ byte* limit = _write + 4*w;
+
+ for ( ; _write < limit; _write += 4, _read++ )
+ {
+ byte color = *_read;
+
+ _write[0] =
+ _write[1] =
+ _write[2] =
+ _write[3] = color;
+ }
+
+ write += target->pitch;
+ read += source->pitch;
+ h--;
+ }
+ }
+
+
+ static
+ void convert_rectangle( grXSurface* surface,
+ int x,
+ int y,
+ int w,
+ int h )
+ {
+ int z;
+
+ /* first of all, clip to the surface's area */
+ if ( x >= surface->image.width ||
+ x+w <= 0 ||
+ y >= surface->image.rows ||
+ y+h <= 0 )
+ return;
+
+ if ( x < 0 )
+ {
+ w += x;
+ x = 0;
+ }
+
+ z = (x + w) - surface->image.width;
+ if (z > 0)
+ w -= z;
+
+ z = (y + h) - surface->image.rows;
+ if (z > 0)
+ h -= z;
+
+ /* convert the rectangle to the target depth for gray surfaces */
+ if (surface->gray)
+ {
+ switch (surface->depth)
+ {
+ case 8 : convert_gray_to_pal8( surface, x, y, w, h ); break;
+ case 16: convert_gray_to_16 ( surface, x, y, w, h ); break;
+ case 24: convert_gray_to_24 ( surface, x, y, w, h ); break;
+ case 32: convert_gray_to_32 ( surface, x, y, w, h ); break;
+ }
+ }
+ }
+
+
+ static
+ void refresh_rectangle( grXSurface* surface,
+ int x,
+ int y,
+ int w,
+ int h )
+ {
+ if (surface->gray)
+ convert_rectangle( surface, x, y, w, h );
+
+ XPutImage( display,
+ surface->win,
+ surface->gc,
+ surface->ximage,
+ x, y, x, y, w, h );
+ }
+
+
+ static
+ void set_title( grXSurface* surface,
+ const char* title )
+ {
+ XStoreName( display, surface->win, title );
+ }
+
+
+
+ static
+ grKey KeySymTogrKey( KeySym key )
+ {
+ grKey k;
+ int count = sizeof(key_translators)/sizeof(key_translators[0]);
+ Translator* trans = key_translators;
+ Translator* limit = trans + count;
+
+ k = grKeyNone;
+
+ while ( trans < limit )
+ {
+ if ( trans->xkey == key )
+ {
+ k = trans->grkey;
+ break;
+ }
+ trans++;
+ }
+
+ return k;
+ }
+
+
+
+ static
+ void listen_event( grXSurface* surface,
+ int event_mask,
+ grEvent* grevent )
+ {
+ static char key_buffer[10];
+ static int key_cursor = 0;
+ static int key_number = 0;
+ static XEvent x_event;
+ KeySym key;
+
+ int bool_exit;
+ grKey grkey;
+
+ XComposeStatus compose;
+
+ /* XXXX : For now, ignore the event mask, and only exit when */
+ /* a key is pressed.. */
+ (void)event_mask;
+
+ bool_exit = key_cursor < key_number;
+
+ XDefineCursor( display, surface->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 ||
+ key > 512 )
+ {
+ /* this may be a special key like F1, F2, etc.. */
+ grkey = KeySymTogrKey(key);
+ if (grkey != grKeyNone)
+ goto Set_Key;
+ }
+ else
+ bool_exit = 1;
+ break;
+
+ case MappingNotify:
+ XRefreshKeyboardMapping( &x_event.xmapping );
+ break;
+
+ case Expose:
+ refresh_rectangle( surface,
+ x_event.xexpose.x,
+ x_event.xexpose.y,
+ x_event.xexpose.width,
+ x_event.xexpose.height );
+ break;
+
+ /* You should add more cases to handle mouse events, etc. */
+ }
+ }
+
+ XDefineCursor( display, surface->win, busy );
+ XFlush ( display );
+
+ /* Now, translate the keypress to a grKey */
+ /* If this wasn't part of the simple translated keys, simply get the charcode */
+ /* from the character buffer */
+ grkey = grKEY(key_buffer[key_cursor++]);
+
+ Set_Key:
+ grevent->type = gr_key_down;
+ grevent->key = grkey;
+ }
+
+
+
+
+ grXSurface* init_surface( grXSurface* surface,
+ grBitmap* bitmap )
+ {
+ int screen;
+ grBitmap* image;
+ char grays;
+ XDepth* format;
+ int image_depth;
+
+ screen = DefaultScreen( display );
+
+ surface->colormap = DefaultColormap( display, screen );
+ surface->depth = DefaultDepth( display, screen );
+ surface->visual = DefaultVisual( display, screen );
+
+ image = &surface->image;
+
+ /* force the surface image depth to 1 if necessary */
+ /* as this should be supported by all windows */
+ image_depth = surface->depth;
+ if (bitmap->mode == gr_pixel_mode_mono)
+ image_depth = 1;
+
+ grays = ( bitmap->mode == gr_pixel_mode_gray &&
+ bitmap->grays >= 2 );
+
+ surface->gray = grays;
+
+ /* copy dimensions */
+ image->width = bitmap->width;
+ image->rows = bitmap->rows;
+ image->mode = bitmap->mode;
+ image->pitch = 0;
+ image->grays = 0;
+ image->buffer = 0;
+
+ /* find the supported format corresponding to the request */
+ format = 0;
+
+ if (grays)
+ {
+ /* choose the default depth in case of grays rendering */
+ int i;
+ for ( i = 0; i < num_pixel_modes; i++ )
+ if ( image_depth == pixel_depth[i].depth )
+ {
+ format = pixel_depth + i;
+ break;
+ }
+ }
+ else
+ {
+ /* otherwise, select the format depending on the pixel mode */
+ int i;
+
+ format = 0;
+ for ( i = 0; i < num_pixel_modes; i++ )
+ if ( pixel_modes[i] == bitmap->mode )
+ {
+ format = pixel_depth + i;
+ break;
+ }
+ }
+
+ if (!format)
+ {
+ grError = gr_err_bad_argument;
+ return 0;
+ }
+
+
+ /* correct surface.depth. This is required because in the case */
+ /* of 32-bits pixels, the value of "format.depth" is 24 under X11 */
+ if ( format->depth == 24 &&
+ format->bits_per_pixel == 32 )
+ image_depth = 32;
+
+ /* allocate surface image */
+ {
+ int bits, over;
+
+ bits = image->width * format->bits_per_pixel;
+ over = bits % format->scanline_pad;
+
+ if (over)
+ bits += format->scanline_pad - over;
+
+ if (!grays)
+ {
+ image->width = bits;
+ bitmap->width = bits;
+ }
+ image->pitch = bits >> 3;
+ }
+
+ image->buffer = grAlloc( image->pitch * image->rows );
+ if (!image->buffer) return 0;
+
+ /* now, allocate a gray pal8 pixmap, only when we asked */
+ /* for an 8-bit pixmap */
+ if ( grays )
+ {
+ /* pad pitch to 32 bits */
+ bitmap->pitch = (bitmap->width + 3) & -4;
+ bitmap->buffer = grAlloc( bitmap->pitch * bitmap->rows );
+ if (!bitmap->buffer)
+ Panic( "grX11: could not allocate surface bitmap!\n" );
+ }
+ else /* otherwise */
+ {
+ *bitmap = *image;
+ }
+
+ surface->root.bitmap = *bitmap;
+
+ /* Now create the surface X11 image */
+ surface->ximage = XCreateImage( display,
+ surface->visual,
+ format->depth,
+ format->depth == 1 ? XYBitmap : ZPixmap,
+ 0,
+ (char*)image->buffer,
+ image->width,
+ image->rows,
+ 8,
+ 0 );
+ if ( !surface->ximage )
+ Panic( "grX11: cannot create surface X11 image\n" );
+
+
+ /* allocate gray levels in the case of gray surface */
+ if ( grays )
+ {
+ XColor* color = surface->color;
+ int i;
+
+ for ( i = 0; i < bitmap->grays; i++, color++ )
+ {
+ color->red =
+ color->green =
+ color->blue = 65535 - ( i * 65535 ) / bitmap->grays;
+
+ if ( !XAllocColor( display, surface->colormap, color ) )
+ Panic( "ERROR: cannot allocate Color\n" );
+ }
+ }
+ else if ( image_depth == 1 )
+ {
+ surface->ximage->byte_order = MSBFirst;
+ surface->ximage->bitmap_bit_order = MSBFirst;
+ }
+
+ {
+ XTextProperty xtp;
+ XSizeHints xsh;
+ XSetWindowAttributes xswa;
+
+ xswa.border_pixel = BlackPixel( display, screen );
+ xswa.background_pixel = WhitePixel( display, screen );
+ xswa.cursor = busy;
+
+ xswa.event_mask = KeyPressMask | ExposureMask;
+
+ surface->win = XCreateWindow( display,
+ RootWindow( display, screen ),
+ 0,
+ 0,
+ image->width,
+ image->rows,
+ 10,
+ surface->depth,
+ InputOutput,
+ surface->visual,
+ CWBackPixel | CWBorderPixel |
+ CWEventMask | CWCursor,
+ &xswa );
+
+ XMapWindow( display, surface->win );
+
+ surface->gc = XCreateGC( display, RootWindow( display, screen ), 0L, NULL );
+ XSetForeground( display, surface->gc, xswa.border_pixel );
+ XSetBackground( display, surface->gc, xswa.background_pixel );
+
+
+ /* make window manager happy :-) */
+ xtp.value = (unsigned char*)"FreeType";
+ xtp.encoding = 31;
+ xtp.format = 8;
+ xtp.nitems = strlen( (char*)xtp.value );
+
+ xsh.x = 0;
+ xsh.y = 0;
+
+ xsh.width = image->width;
+ xsh.height = image->rows;
+ xsh.flags = (PPosition | PSize);
+ xsh.flags = 0;
+
+ XSetWMProperties( display, surface->win, &xtp, &xtp, NULL, 0, &xsh, NULL, NULL );
+ }
+
+ surface->root.done = (grDoneSurfaceFunc) done_surface;
+ surface->root.refresh_rect = (grRefreshRectFunc) refresh_rectangle;
+ surface->root.set_title = (grSetTitleFunc) set_title;
+ surface->root.listen_event = (grListenEventFunc) listen_event;
+
+ convert_rectangle( surface, 0, 0, bitmap->width, bitmap->rows );
+ return surface;
+ }
+
+
+
+
+ grDevice gr_x11_device =
+ {
+ sizeof( grXSurface ),
+ "x11",
+
+ init_device,
+ done_device,
+
+ (grDeviceInitSurfaceFunc) init_surface,
+
+ 0,
+ 0
+
+ };
+
+#ifdef TEST
+
+typedef struct grKeyName
+{
+ grKey key;
+ const char* name;
+
+} grKeyName;
+
+
+static
+const grKeyName key_names[] =
+{
+ { grKeyF1, "F1" },
+ { grKeyF2, "F2" },
+ { grKeyF3, "F3" },
+ { grKeyF4, "F4" },
+ { grKeyF5, "F5" },
+ { grKeyF6, "F6" },
+ { grKeyF7, "F7" },
+ { grKeyF8, "F8" },
+ { grKeyF9, "F9" },
+ { grKeyF10, "F10" },
+ { grKeyF11, "F11" },
+ { grKeyF12, "F12" },
+ { grKeyEsc, "Esc" },
+ { grKeyHome, "Home" },
+ { grKeyEnd, "End" },
+
+ { grKeyPageUp, "Page_Up" },
+ { grKeyPageDown, "Page_Down" },
+ { grKeyLeft, "Left" },
+ { grKeyRight, "Right" },
+ { grKeyUp, "Up" },
+ { grKeyDown, "Down" },
+ { grKeyBackSpace, "BackSpace" },
+ { grKeyReturn, "Return" }
+};
+
+int main( void )
+{
+ grSurface* surface;
+ int n;
+
+ grInit();
+ surface = grNewScreenSurface( 0, gr_pixel_mode_gray, 320, 400, 128 );
+ if (!surface)
+ Panic("Could not create window\n" );
+ else
+ {
+ grColor color;
+ grEvent event;
+ const char* string;
+ int x;
+
+ grSetSurfaceRefresh( surface, 1 );
+ grSetTitle(surface,"X11 driver demonstration" );
+
+ for ( x = -10; x < 10; x++ )
+ {
+ for ( n = 0; n < 128; n++ )
+ {
+ color.value = (n*3) & 127;
+ grWriteCellChar( surface,
+ x + ((n % 60) << 3),
+ 80 + (x+10)*8*3 + ((n/60) << 3), n, color );
+ }
+
+ }
+ color.value = 64;
+ grWriteCellString( surface, 0, 0, "just an example", color );
+
+ do
+ {
+ listen_event((grXSurface*)surface, 0, &event);
+
+ /* return if ESC was pressed */
+ if ( event.key == grKeyEsc )
+ return 0;
+
+ /* otherwise, display key string */
+ color.value = (color.value + 8) & 127;
+ {
+ int count = sizeof(key_names)/sizeof(key_names[0]);
+ grKeyName* name = key_names;
+ grKeyName* limit = name + count;
+ const char* kname = 0;
+ char kname_temp[16];
+
+ while (name < limit)
+ {
+ if ( name->key == event.key )
+ {
+ kname = name->name;
+ break;
+ }
+ name++;
+ }
+
+ if (!kname)
+ {
+ sprintf( kname_temp, "char '%c'", (char)event.key );
+ kname = kname_temp;
+ }
+
+ grWriteCellString( surface, 30, 30, kname, color );
+ grRefreshSurface(surface);
+ paint_rectangle( surface, 0, 0, surface->bitmap.width, surface->bitmap.rows );
+ }
+ } while (1);
+ }
+
+ return 0;
+
+
+}
+#endif /* TEST */
+
--- /dev/null
+++ b/demos/graph/grx11.h
@@ -1,0 +1,24 @@
+#ifndef GRX11_H
+#define GRX11_H
+
+#include "grobjs.h"
+#include "grdevice.h"
+
+ extern
+ grDevice gr_x11_device;
+
+#ifdef GR_INIT_BUILD
+ static
+ grDeviceChain gr_x11_device_chain =
+ {
+ "x11",
+ &gr_x11_device,
+ GR_INIT_DEVICE_CHAIN
+ };
+
+#undef GR_INIT_DEVICE_CHAIN
+#define GR_INIT_DEVICE_CHAIN &gr_x11_device_chain
+
+#endif /* GR_INIT_BUILD */
+
+#endif /* GRX11_H */
--- /dev/null
+++ b/demos/graph/migs.html
@@ -1,0 +1,304 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.6 [en] (X11; I; Linux 2.2.9-19mdk i586) [Netscape]">
+</head>
+<body>
+
+<center><font size=+2>MiGS Overview</font>
+<br><font size=+2>A Minimalist Graphics Subsystem</font>
+<p>
+<hr WIDTH="100%"></center>
+
+<h1>
+<font size=+0>Introduction</font></h1>
+
+<blockquote>This document details the design and implementation of MiGS,
+the minimalist graphics subsystem used by the FreeType 2 demonstration
+programs. Its purpose is mainly to help writers of new demo programs, as
+well as developers who would like port the subsystem to other platforms.</blockquote>
+
+<hr WIDTH="100%">
+<h1>
+I - Design goals</h1>
+
+<blockquote>MiGS is a tiny graphics subsystem used to demo text rendering
+through the FreeType library. It was mainly written to provide the abilities
+to :</blockquote>
+
+<ul>
+<ul>
+<li>
+draw a monochrome glyph bitmap to many kinds of target surfaces (i.e. really
+bitmaps/pixmaps)</li>
+
+<li>
+draw an anti-aliased glyph bitmap, with any level of grays, to many kinds
+of target surfaces</li>
+
+<li>
+display a simple window on many systems like X11, OS/2 and Windows</li>
+
+<li>
+accept simple events (keypresses and mouse buttons) in this window.</li>
+
+<li>
+to be portable and present a unified API on all running systems</li>
+</ul>
+
+<p><br>MiGS uses system-specific "drivers" in order to perform display
+and event handling. The blitting functions are not device-specific. MiGS
+can be built and/or used with no system-specific features, like for example,
+to generate simple GIF, PNG, TIFF, etc.. images without ever needing to
+display them.</ul>
+
+<h1>
+
+<hr WIDTH="100%"></h1>
+
+<h1>
+II - Surfaces, bitmaps and windows</h1>
+
+<blockquote>A surface in MiGS models a drawable region where glyph images
+can be rendered, a surface always contains a bitmap descriptor as well
+as a few other things that will be described later in this section.
+<p>Some surfaces can be displayed, they are then either called <i>windowed
+surfaces</i> or <i>screen surfaces</i> depending on the nature of the <i>device</i>
+used to display them. Each <i>device</i> is implemented by a very simple
+<i>driver</i> in the MiGS code. Here are a few example devices that are
+or could be written to display surfaces :
+<p>- an X11 device
+<br>- a Win 32 GDI device
+<br>- an OS/2 Presentation Manager device
+<br>- a fullscreen SVGALib device on Linux
+<br>- a GGI visual device
+<br>- an OS/2 "Dive" device, or the equivalent Win32 "DirectX" device
+<p>etc..
+<p><b>NOTE: </b>For now, only the X11 device was written and tested.. More
+devices should come later
+<p>Before explaining how to create a surface, we need to explain how MiGS
+manages bitmaps and renders glyph images to them.
+<h3>
+1. Bitmaps :</h3>
+
+<blockquote>A bitmap in MiGS features the following things :
+<ul>
+<li>
+a <b><i>width</i></b> in pixels</li>
+
+<li>
+a <b><i>height</i></b> in pixels</li>
+
+<li>
+a <b><i>pixel mode</i></b>, which indicates how the pixels are stored in
+the surface's buffer</li>
+
+<li>
+a <b><i>pitch</i></b>, whose absolute values is the number of bytes taken
+by each surface row</li>
+
+<li>
+a <b><i>number</i></b> of valid <b><i>gray</i></b> levels (see below)</li>
+
+<li>
+a <b><i>buffer</i></b>, holding the surface's pixels</li>
+</ul>
+
+<p><br>MiGS uses the <i>"Y downwards"</i> convention, which means that
+<i>increasing
+Y</i> coordinates correspond to <i>lower rows</i> of the bitmap. Hence,
+the coordinate <i>(0,0)</i> always corresponds to the bitmap's
+<i>top-left
+pixel</i>.
+<p>The bitmap's rows can be stored either <i>"downwards"</i> or <i>"upwards"</i>
+in the pixel buffer.
+<p>In the first case (<i>downwards</i>), increasing memory addresses in
+the pixel buffer correspond to lower rows of the bitmap(e.g. PC video modes),
+and the <b><i>pitch</i></b> should be equal to <b><i>the number of bytes
+taken by each row</i></b>. The first pixel buffer byte corresponds to the
+upper row.
+<p>In the second case (<i>upwards</i>), increasing memory addresses in
+the pixel buffer correspond to upper rows of the bitmap and the <b><i>pitch</i></b>
+should be equal to the <b><i>opposite</i></b> of <i>the number of bytes
+taken by each row</i>. The first pixel buffer byte corresponds to the lower
+row.
+<p>In all cases, the <b><i>pitch</i></b> is the <i>increment to be used
+to go from one bitmap row to the one below it</i>.
+<p>The supported pixel modes are :
+<ul>
+<li>
+1-bit monochrome bitmaps. With "0" as the background, and "1" as the foreground.</li>
+
+<li>
+4-bit color bitmaps, using an arbitrary palette.</li>
+
+<li>
+8-bit color bitmaps, using an arbitrary palette.</li>
+
+<li>
+8-bit gray bitmaps, using a given N number of gray levels in the range
+0..N-1.</li>
+
+<li>
+15-bit color bitmaps, also known as RGB555</li>
+
+<li>
+16-bit color bitmaps, also known as RGB565</li>
+
+<li>
+24-bit color bitmaps, also known as RGB</li>
+
+<li>
+32-bit color bitmaps, also known as RGBA (though the A is ignored by MiGS)</li>
+</ul>
+The bitmap's <b><i>number of gray levels</i></b> is only relevant for <b><i>8-bit
+gray bitmaps</i></b>, and indicates the range of gray levels that can be
+found in the bitmap. If a bitmap as N gray levels, it is said to be <i>N-grayscales</i>,
+and the pixels within it must all have values between 0, considered as
+the <i>background</i> color, and N-1, considered as the <i>foreground</i>
+color.
+<p>N-grayscale bitmaps are crucial for the rendering of anti-aliased text.
+<br> </blockquote>
+
+<h3>
+2. Glyph images :</h3>
+
+<blockquote>The glyph images that can be drawn on bitmaps through MiGS
+are bitmaps themselves, though limited to the following pixel modes :
+<p><b>1-bit monochrome glyph bitmaps</b>
+<blockquote>These can be drawn on any kind of bitmap. Note that <i>only
+the "lit" pixels</i> (i.e. the bits set to 1) are effectively drawn to
+the target, as opaque blitting isn't supported (remember, it's a minimalist
+library !)</blockquote>
+
+<p><br><b>N-grayscales glyph images </b>(with any value of N >= 2)
+<blockquote>These can be drawn to <i>all RGB bitmaps</i> (15, 16, 24 &
+32 bits/pixel), as well as any other M-grayscales bitmaps. In the latter
+case, the values of N and M <i>need not be equal</i>, as the library is
+able to perform automatic conversions <i>on the fly</i>.
+<p>For example, it is possible to render a 5-grayscales glyph image into
+a 128-grayscales bitmap. Moreover, it is also possible to render a 17-grayscales
+glyph image into a 5-grayscales bitmap, even if this will result in <i>a
+loss of quality</i>. This feature is crucial in order to experiment easily
+with other anti-aliasing algorithms for FreeType
+<br> </blockquote>
+Note that you can <i>only</i> draw <i>monochrome</i> bitmaps to the following
+pixel modes : monochrome, 4-bit color and 8-bit color.</blockquote>
+
+<h3>
+3. Windows and Screens:</h3>
+
+<blockquote>In order to debug FreeType, displaying a surface in a window
+or in full-screen mode, is required. MiGS thus makes a difference between
+<i>simple
+surfaces</i>, which only contain a bitmap, <i>windowed surfaces</i>, which
+are used to display their content in a window, and <i>screen surfaces</i>,
+which are used to display their content in a full-screen mode (SVGAlib,
+DirectX, GGI or wathever).
+<p>A few important things must be said about non-simple surfaces.
+<br>
+<ul>
+<li>
+First, they might contain some system-specific data which is used to manage
+the display in a window or on the screen. This must be <i>completely hidden</i>
+to MiGS clients. Indeed, rendering to any kind of surface is achieved through
+<i>exactly
+the same function calls</i>.</li>
+</ul>
+
+<ul>
+<li>
+Second, they may contain a bitmap whose pixel mode doesn't correspond to
+the screen's depth used to display it. For example, the surface might contain
+an 128-grayscale bitmap, while the screen is in RGB24 mode. Some conversion
+must be performed to display the surface. This can either happen in the
+system-specific graphics library (e.g. on OS/2, a single Presentation Manager
+call is used to blit a N-grayscale image to <i>any</i> kind of window)
+or in the system-specific part of MiGS (e.g. the X11 MiGS driver must convert
+the surface's bitmap into the appropriate <i>X11 image</i> each time a
+repaint is requested). Again this must be completely hidden to MiGS clients</li>
+</ul>
+Surfaces have also a few fields that are only used when displaying them
+in Windows :
+<p><b>a title string</b>
+<blockquote>This is simply a text string that is displayed on the title
+bar of the surface's window. It can also appear at the top or bottom of
+full-screen surfaces if the MiGS driver supports it. The title string can
+be changed with a call to <tt>grSetTitle</tt>, and is ignored for simple
+surfaces.</blockquote>
+
+<p><br><b>a refresh flag</b>
+<blockquote>This boolean flag is only used for window surfaces, and some
+fullscreen ones (depending on the driver implementation). When set, it
+indicates that each glyph image blit must be displayed immediately. By
+default, this flag is set to False, which means that demo programs must
+call the <tt>grRefreshSurface(surface)</tt> function to display the whole
+contents of a surface one it has been updated.
+<p>The refresh flag can be set with <tt>grSetSurfaceRefresh(surface,flag)</tt>.
+Note that a single surface rectangle can be forced to be displayed with
+a call to <tt>grRefreshRectangle(surface,x,y,w,h)</tt> at any time.</blockquote>
+</blockquote>
+
+<h3>
+4. Devices :</h3>
+
+<blockquote>As said before, each device is in charge of displaying a surface
+in a given window or screen. Each device is managed through a very simple
+driver, described to MiGS through a very simple "grDevice" structure.
+<p>A grDevice contains, among other things, pointers to the functions used
+to:
+<p>- refresh/display a given rectangle of the surface to the window/screen
+<br>- listen events (key presses and mouse) and send them back to client
+apps.
+<br>- for windowed devices, update the title bar.
+<p>As said before, this is a highly minimalist system..
+<br> </blockquote>
+</blockquote>
+
+<hr WIDTH="100%">
+<h1>
+III - Important implementation issues :</h1>
+
+<blockquote>
+<h3>
+1. Display surface negociation :</h3>
+
+<blockquote>A display surface is created with the function grNewScreenSurface
+which takes parameters indicating which device should be used, the pixel
+dimensions of the requested surface, as well as its pixel mode.
+<p>Because of some device-specific limitations, the resulting surface's
+properties might not match exactly those requested for the call. Hence,
+a developper should <b>always take care </b>of reading a new display surface's
+<b>bitmap</b> descriptor in order to get its <i>real</i> dimensions, pixel
+mode and eventually number of grays.
+<p>The function grNewSurface will create a memory surface with the corresponding
+bitmap.
+<br>The function grNewBitmapSurface will create a surface from a pre-existing
+bitmap. This is useful to draw text on loaded images, for example.
+<p>Any surface (display or not) is destroyed with grDoneSurface.</blockquote>
+
+<h3>
+</h3>
+
+<h3>
+2. Supporting 8-bit grayscale mode :</h3>
+
+<blockquote>It is important, for the debugging of FreeType anti-aliased
+renderer(s), that <b><i>_all_ devices should support the 8-bit gray mode</i></b>.
+The number of gray levels can be fixed or negociated as required by implementation-specific
+issues.
+<p>As most existing devices do not provide direct support for such a mode,
+each 8-bit surface must thus contain :
+<p>- an internal N-grayscale bitmap, used as the target of all glyph drawings
+<br>- its own device-specific "image", which matches the display depth.
+<p>Each time the device's "refresh_rect" function is called, it should
+then :
+<br>- convert the grayscales within the bitmap's rectangle into the image's
+buffer and format.
+<br>- display the corresponding image rectangle.
+<p>This scheme is used, for example, by the X11 device.</blockquote>
+</blockquote>
+
+</body>
+</html>
--- /dev/null
+++ b/demos/graph/rules.mk
@@ -1,0 +1,99 @@
+#**************************************************************************
+#*
+#* FreeType demo utilities sub-Makefile
+#*
+#* This Makefile is to be included by "freetype/demo/Makefile". Its
+#* purpose is to compile MiGS (the Minimalist Graphics Subsystem)
+#*
+#* It is written for GNU Make. Other make utilities are not
+#* supported.. !!
+#*
+#*
+#* The following variables must be defined :
+#*
+#* CFLAGS : C flags to use when compiling the utilities. This
+#* must NOT include the '-c' flag used to specify a
+#* simple compilation.
+#*
+#* IFLAG : include path flag. This is typically "-I" but some
+#* compilers use a different convention..
+#*
+#* LFLAG : add link directory flag. Usually '-L' but could be
+#* different..
+#*
+#* OBJ_DIR : target location of the object files
+#*
+#* UTIL_DIR : location of the utilities sources. I.e. this
+#* directory (usually "freetype/demo/graph").
+#*
+#*
+#* It also defines the following variables
+#*
+#* SIMPLE_UTILS : list of object files for the non-graphical utilities
+#*
+#* GRAPH_UTILS : all object files, including the graphics sub-system
+#*
+#* GRAPH_FLAGS : additional compile flags for graphical apps
+#* GRAPH_LINK : additional link flags for graphical apps
+#*
+#**************************************************************************
+
+##########################################################################
+#
+#
+#
+#
+#
+
+GRAPH_INCLUDES := graph
+GRAPH_LIB := $(OBJ_)graph.a
+GRAPH_LINK := $(GRAPH_LIB)
+
+GRAPH_ := graph$(SEP)
+
+GRAPH_H := $(GRAPH_)graph.h \
+ $(GRAPH_)grtypes.h \
+ $(GRAPH_)grobjs.h \
+ $(GRAPH_)grdevice.h \
+ $(GRAPH_)grblit.h
+
+
+GRAPH_OBJS := $(OBJ_)grblit.$O \
+ $(OBJ_)grobjs.$O \
+ $(OBJ_)grfont.$O \
+ $(OBJ_)grdevice.$O \
+ $(OBJ_)grinit.$O
+
+
+# Add the rules used to detect and compile graphics driver depending
+# on the current platform..
+#
+include $(wildcard config/*/rules.mk)
+
+#########################################################################
+#
+# Build the "graph" library from its objects. This should be changed
+# in the future in order to support more systems. Probably something
+# like a `config/<system>' hierarchy with a system-specific rules file
+# to indicate how to make a library file, but for know, I'll stick to
+# unix and OS/2-gcc..
+#
+#
+$(GRAPH_LIB): $(GRAPH_OBJS)
+ ar -r $@ $(GRAPH_OBJS)
+
+
+# pattern rule for normal sources
+#
+$(OBJ_)%.$O: $(GRAPH_)%.c $(GRAPH_H)
+ $(CC) $(CFLAGS) $(GRAPH_INCLUDES:%=$I%) $T$@ $<
+
+
+# a special rule is used for 'grinit.o' as it needs the definition
+# of some macros like "-DDEVICE_X11" or "-DDEVICE_OS2_PM"
+#
+$(OBJ_)grinit.$O: $(GRAPH_)grinit.c
+ $(CC) $(CFLAGS) $(GRAPH_INCLUDES:%=$I%) $I$(DEVICE_INCLUDES:%=$I%) $T$@ $< \
+ $(DEVICES:%=$DDEVICE_%)
+
+
--- /dev/null
+++ b/demos/graph/xtest.c
@@ -1,0 +1,125 @@
+#include "graph.h"
+#include "grfont.h" /* dispara^itra bientot */
+#include <stdio.h>
+
+
+static
+void Panic( const char* message )
+{
+ fprintf( stderr, "PANIC: %s\n", message );
+ exit(1);
+}
+
+
+typedef struct grKeyName
+{
+ grKey key;
+ const char* name;
+
+} grKeyName;
+
+
+static
+const grKeyName key_names[] =
+{
+ { grKeyF1, "F1" },
+ { grKeyF2, "F2" },
+ { grKeyF3, "F3" },
+ { grKeyF4, "F4" },
+ { grKeyF5, "F5" },
+ { grKeyF6, "F6" },
+ { grKeyF7, "F7" },
+ { grKeyF8, "F8" },
+ { grKeyF9, "F9" },
+ { grKeyF10, "F10" },
+ { grKeyF11, "F11" },
+ { grKeyF12, "F12" },
+ { grKeyEsc, "Esc" },
+ { grKeyHome, "Home" },
+ { grKeyEnd, "End" },
+
+ { grKeyPageUp, "Page_Up" },
+ { grKeyPageDown, "Page_Down" },
+ { grKeyLeft, "Left" },
+ { grKeyRight, "Right" },
+ { grKeyUp, "Up" },
+ { grKeyDown, "Down" },
+ { grKeyBackSpace, "BackSpace" },
+ { grKeyReturn, "Return" }
+};
+
+int main( void )
+{
+ grSurface* surface;
+ int n;
+
+ grInit();
+ surface = grNewScreenSurface( 0, gr_pixel_mode_gray, 320, 400, 128 );
+ if (!surface)
+ Panic("Could not create window\n" );
+ else
+ {
+ grColor color;
+ grEvent event;
+ const char* string;
+ int x;
+
+ grSetSurfaceRefresh( surface, 1 );
+ grSetTitle(surface,"X11 driver demonstration" );
+
+ for ( x = -10; x < 10; x++ )
+ {
+ for ( n = 0; n < 128; n++ )
+ {
+ color.value = (n*3) & 127;
+ grWriteCellChar( surface,
+ x + ((n % 60) << 3),
+ 80 + (x+10)*8*3 + ((n/60) << 3), n, color );
+ }
+
+ }
+ color.value = 64;
+ grWriteCellString( surface, 0, 0, "just an example", color );
+
+ do
+ {
+ grListenSurface( surface, 0, &event);
+
+ /* return if ESC was pressed */
+ if ( event.key == grKeyEsc )
+ return 0;
+
+ /* otherwise, display key string */
+ color.value = (color.value + 8) & 127;
+ {
+ int count = sizeof(key_names)/sizeof(key_names[0]);
+ grKeyName* name = (grKeyName*)key_names;
+ grKeyName* limit = name + count;
+ const char* kname = 0;
+ char kname_temp[16];
+
+ while (name < limit)
+ {
+ if ( name->key == event.key )
+ {
+ kname = (const char*)name->name;
+ break;
+ }
+ name++;
+ }
+
+ if (!kname)
+ {
+ sprintf( kname_temp, "char '%c'", (char)event.key );
+ kname = kname_temp;
+ }
+
+ grWriteCellString( surface, 30, 30, kname, color );
+ grRefreshSurface(surface);
+ }
+ } while (1);
+ }
+
+ return 0;
+}
+
--- /dev/null
+++ b/demos/obj/README
@@ -1,0 +1,1 @@
+This directory contains all the object files generated for the demonstration programs
--- /dev/null
+++ b/demos/src/common.c
@@ -1,0 +1,244 @@
+/*
+ * 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.
+ * [email protected] (Mark Leisher)
+ * 10 October 1997
+ */
+
+#ifndef lint
+#ifdef __GNUC__
+ static char rcsid[] __attribute__ ((unused)) = "$Id$";
+#else
+ static char rcsid[] = "$Id$";
+#endif
+#endif
+
+#include "common.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+ /*
+ * Externals visible to programs.
+ */
+
+ int opterr = 1;
+ int optind = 1;
+ char* 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__
+ getopt( int ac, char* const* av, const char* pat )
+#else
+ 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.
+ */
+ 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 )
+ {
+ 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 ( 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[optind][0] != '-' ||
+ strcmp( av[optind], "-" ) == 0 ||
+ strcmp( av[optind], "--" ) == 0 )
+ return -1;
+
+ /*
+ * Point at the next command line argument and increment the
+ * command line index.
+ */
+ p = av[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 ( opterr )
+ fprintf( stderr, "%s: illegal option -- %c\n", cmdname, opt );
+ return '?';
+ }
+
+ /*
+ * If the option expects an argument, get it.
+ */
+ if ( *(pp + 1) == ':' && (optarg = av[optind]) == 0 )
+ {
+ /*
+ * If the option argument is NULL, issue a warning and return a '?'.
+ */
+ if ( opterr )
+ fprintf( stderr, "%s: option requires an argument -- %c\n",
+ cmdname, opt );
+ opt = '?';
+ }
+ else if ( optarg )
+ /*
+ * Increment the option index past the argument.
+ */
+ optind++;
+
+ /*
+ * Return the option character.
+ */
+ return opt;
+ }
+
+
+/****************************************************************************/
+/* */
+/* The FreeType project -- a free and portable quality TrueType renderer. */
+/* */
+/* Copyright 1996-1998 by */
+/* D. Turner, R.Wilhelm, and W. Lemberg */
+/* */
+/* ft_basename(): */
+/* */
+/* a stupid but useful function... */
+/* */
+/* rewritten by DavidT to get rid of GPLed programs in the FreeType demos. */
+/* */
+/****************************************************************************/
+
+ 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;
+ }
+
+
+#ifdef __STDC__
+ void Panic( const char* fmt, ... )
+#else
+ void Panic( fmt )
+ const char* fmt;
+#endif
+ {
+ va_list ap;
+
+
+ va_start( ap, fmt );
+ vprintf( fmt, ap );
+ va_end( ap );
+
+ exit( 1 );
+ }
+
+
+/* End */
--- /dev/null
+++ b/demos/src/common.h
@@ -1,0 +1,53 @@
+/*
+ * 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.
+ * [email protected] (Mark Leisher)
+ * 10 October 1997
+ */
+
+#ifndef _H_COMMON
+#define _H_COMMON
+
+/* Note that by default, both functions are implemented in common.c */
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+ extern int opterr;
+ extern int optind;
+ extern char* optarg;
+
+ extern int 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
+ );
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _H_COMMON */
+
+
+/* End */
--- /dev/null
+++ b/demos/src/ftlint.c
@@ -1,0 +1,169 @@
+/****************************************************************************/
+/* */
+/* The FreeType project -- a free and portable quality TrueType renderer. */
+/* */
+/* Copyright 1996-1998 by */
+/* D. Turner, R.Wilhelm, and W. Lemberg */
+/* */
+/* ftlint: a simple font tester. This program tries to load all the */
+/* glyphs of a given font. */
+/* */
+/* NOTE: This is just a test program that is used to show off and */
+/* debug the current engine. */
+/* */
+/****************************************************************************/
+
+#include "freetype.h"
+#include "ftobjs.h"
+#include "ftdriver.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#define gettext( x ) ( x )
+
+ FT_Error error;
+
+ FT_Library library;
+ FT_Face face;
+ FT_Size size;
+ FT_GlyphSlot slot;
+
+ unsigned int num_glyphs;
+ int ptsize;
+
+ int Fail;
+ int Num;
+
+
+
+ static void Usage( char* name )
+ {
+ printf( "ftlint: simple font tester -- part of the FreeType project\n" );
+ printf( "----------------------------------------------------------\n" );
+ printf( "\n" );
+ printf( "Usage: %s ppem fontname[.ttf|.ttc] [fontname2..]\n", name );
+ printf( "\n" );
+
+ exit( 1 );
+ }
+
+
+ static void Panic( const char* message )
+ {
+ fprintf( stderr, "%s\n error code = 0x%04x\n", message, error );
+ exit(1);
+ }
+
+
+ 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;
+
+
+ execname = argv[0];
+
+ if ( argc < 3 )
+ Usage( execname );
+
+ if ( sscanf( argv[1], "%d", &ptsize ) != 1 )
+ Usage( execname );
+
+ error = FT_Init_FreeType( &library );
+ if (error) Panic( "Could not create library object" );
+
+ /* 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 );
+ }
+
+ i = strlen( filename );
+ fname = filename;
+
+ while ( i >= 0 )
+ if ( filename[i] == '/' || filename[i] == '\\' )
+ {
+ fname = filename + i + 1;
+ i = -1;
+ }
+ else
+ i--;
+
+ printf( "%s: ", fname );
+
+ /* Load face */
+ error = FT_New_Face( library, filename, 0, &face );
+ if (error)
+ {
+ if (error == FT_Err_Invalid_File_Format)
+ printf( "unknow format\n" );
+ else
+ printf( "could not find/open file\n" );
+ continue;
+ }
+ if (error) Panic( "Could not open file" );
+
+ num_glyphs = face->num_glyphs;
+
+ error = FT_Set_Char_Size( face, ptsize << 6, ptsize << 6, 72, 72 );
+ if (error) Panic( "Could not set character size" );
+
+ Fail = 0;
+ {
+ for ( id = 0; id < num_glyphs; id++ )
+ {
+ error = FT_Load_Glyph( face, id, FT_LOAD_DEFAULT );
+ if (error)
+ {
+ if ( Fail < 10 )
+ printf( "glyph %4u: 0x%04x\n" , id, error );
+ Fail++;
+ }
+ }
+ }
+
+ if ( Fail == 0 )
+ printf( "OK.\n" );
+ else
+ if ( Fail == 1 )
+ printf( "1 fail.\n" );
+ else
+ printf( "%d fails.\n", Fail );
+
+ FT_Done_Face( face );
+ }
+
+ FT_Done_FreeType(library);
+ exit( 0 ); /* for safety reasons */
+
+ return 0; /* never reached */
+ }
+
+
+/* End */
--- /dev/null
+++ b/demos/src/ftsbit.c
@@ -1,0 +1,313 @@
+/****************************************************************************/
+/* */
+/* The FreeType project -- a free and portable quality TrueType renderer. */
+/* */
+/* Copyright 1996-1998 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "freetype.h"
+
+
+#ifdef HAVE_LIBINTL_H
+
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
+#include <libintl.h>
+#include "ftxerr18.h"
+
+#else /* !HAVE_LIBINTL */
+
+#define gettext( x ) ( x )
+
+ /* We ignore error message strings with this function */
+
+ static char* TT_ErrToString18( FT_Error error )
+ {
+ static char temp[32];
+
+ sprintf( temp, "0x%04lx", error );
+ return temp;
+ }
+
+#endif /* !HAVE_LIBINTL */
+
+
+ FT_Error error;
+ FT_Library engine;
+ FT_Resource resource;
+
+ FT_Face face;
+ FT_Size instance;
+ FT_GlyphSlot glyph;
+
+ unsigned int num_glyphs;
+ int ptsize;
+
+ int Fail;
+ int Num;
+
+
+
+ static void Usage( char* name )
+ {
+ printf( gettext( "ftsbit: simple TrueType 'sbit' dumper -- part of the FreeType project\n" ) );
+ printf( "---------------------------------------------------------------------\n" );
+ printf( "\n" );
+ printf( gettext( "Usage: %s ppem fontname (index)* (index1-index2)*\n\n" ), name );
+ printf( gettext( " or %s -a ppem fontname (dumps all glyphs)\n" ), name );
+ printf( "\n" );
+
+ exit( EXIT_FAILURE );
+ }
+
+
+
+ static
+ void dump_bitmap( FT_GlyphSlot glyph, int glyph_index )
+ {
+ /* Dump the resulting bitmap */
+ {
+ int y;
+ unsigned char* line = (unsigned char*)glyph->bitmap.buffer;
+
+ printf( "glyph index %d = %dx%d pixels, ",
+ glyph_index, glyph->bitmap.rows, glyph->bitmap.width );
+
+ printf( "advance = %d, minBearing = [%d,%d]\n",
+ glyph->metrics.horiAdvance >> 6,
+ glyph->metrics.horiBearingX >> 6,
+ glyph->metrics.horiBearingY >> 6 );
+
+ for ( y = 0; y < glyph->bitmap.rows; y++, line += glyph->bitmap.cols )
+ {
+ unsigned char* ptr = line;
+ int x;
+ unsigned char mask = 0x80;
+
+ for ( x = 0; x < glyph->bitmap.width; x++ )
+ {
+ printf( "%c", (ptr[0] & mask) ? '*' : '.' );
+ mask >>= 1;
+ if (mask == 0)
+ {
+ mask = 0x80;
+ ptr++;
+ }
+ }
+
+ printf( "\n" );
+ }
+ }
+ }
+
+
+
+ static
+ void dump_range( FT_GlyphSlot glyph,
+ int first_glyph,
+ int last_glyph )
+ {
+ int i;
+
+ for ( i = first_glyph; i <= last_glyph; i++ )
+ {
+ error = FT_Load_Glyph( glyph,
+ instance,
+ (unsigned short)i,
+ FT_LOAD_NO_OUTLINE,
+ 0 );
+ if (error)
+ {
+ printf( " no bitmap for glyph %d\n", i );
+ printf( gettext( "FreeType error message: %s\n" ),
+ TT_ErrToString18( error ) );
+ continue;
+ }
+
+ dump_bitmap(glyph,i);
+ }
+ }
+
+
+
+
+ int main( int argc, char** argv )
+ {
+ int i;
+ char filename[128 + 4];
+ char alt_filename[128 + 4];
+ char* execname;
+ char* fname;
+ int dump_all = 0;
+
+
+#ifdef HAVE_LIBINTL_H
+ setlocale( LC_ALL, "" );
+ bindtextdomain( "freetype", LOCALEDIR );
+ textdomain( "freetype" );
+#endif
+
+ execname = argv[0];
+
+ if ( argc < 3 )
+ Usage( execname );
+
+ if ( argv[1][0] == '-' &&
+ argv[1][1] == 'a' )
+ {
+ argv++;
+ argc--;
+ dump_all = 1;
+ }
+
+ if ( sscanf( argv[1], "%d", &ptsize ) != 1 )
+ Usage( execname );
+
+ /* Initialize engine */
+ if ( (error = FT_Init_FreeType( &engine )) )
+ {
+ fprintf( stderr, gettext( "Error while initializing engine\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 = FT_New_Resource( engine, filename, &resource );
+ if (error)
+ {
+ strcpy( filename, alt_filename );
+ error = FT_New_Resource( engine, alt_filename, &resource );
+ }
+
+ i = strlen( filename );
+ fname = filename;
+
+ while ( i >= 0 )
+ if ( filename[i] == '/' || filename[i] == '\\' )
+ {
+ fname = filename + i + 1;
+ i = -1;
+ }
+ else
+ i--;
+
+ if ( error )
+ {
+ printf( gettext( "Could not find or open file.\n" ) );
+ goto Failure;
+ }
+
+ error = FT_New_Face( resource, 0, &face );
+ if (error)
+ {
+ printf( gettext( "Could not create face object.\n " ) );
+ goto Failure;
+ }
+
+ /* get face properties */
+ num_glyphs = face->num_glyphs;
+
+ /* create instance */
+ error = FT_New_Size( face, &instance );
+ if ( error )
+ {
+ printf( gettext( "Could not create instance.\n" ) );
+ goto Failure;
+ }
+
+ error = FT_Set_Pixel_Sizes( instance, ptsize, ptsize );
+ if (error)
+ {
+ printf( gettext( "Could not set character size.\n" ) );
+ goto Failure;
+ }
+
+ glyph = face->slot;
+
+ if (dump_all)
+ dump_range( glyph, 0, num_glyphs-1 );
+ else
+ {
+ for ( i = 3; i < argc; i++ )
+ {
+ /* check for range in argument string */
+ int range_check = 0;
+ char* base = argv[i];
+ char* cur = base;
+ int first, last;
+
+ while (*cur)
+ {
+ if (*cur == '-')
+ {
+ range_check = 1;
+ break;
+ }
+ cur++;
+ }
+
+ if (range_check)
+ {
+ if ( sscanf( argv[i], "%d-%d", &first, &last ) != 2 )
+ Usage( execname );
+
+ dump_range( glyph, first, last );
+ }
+ else
+ {
+ if ( sscanf( argv[i], "%d", &first ) != 1 )
+ Usage( execname );
+
+ dump_range( glyph, first, first );
+ }
+ }
+ }
+
+ FT_Done_FreeType( engine );
+ exit( EXIT_SUCCESS ); /* for safety reasons */
+
+ return 0; /* never reached */
+
+ Failure:
+ printf( gettext( "FreeType error message: %s\n" ),
+ TT_ErrToString18( error ) );
+ exit( EXIT_FAILURE );
+ }
+
+
+/* End */
--- /dev/null
+++ b/demos/src/fttimer.c
@@ -1,0 +1,460 @@
+/****************************************************************************/
+/* */
+/* The FreeType project - a Free and Portable Quality TrueType Renderer. */
+/* */
+/* Copyright 1996-1998 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 "freetype.h"
+#include "ftoutln.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h> /* for clock() */
+
+#include "graph.h"
+
+/* SunOS 4.1.* does not define CLOCKS_PER_SEC, so include <sys/param.h> */
+/* to get the HZ macro which is the equivalent. */
+#if defined(__sun__) && !defined(SVR4) && !defined(__SVR4)
+#include <sys/param.h>
+#define CLOCKS_PER_SEC HZ
+#endif
+
+#define CHARSIZE 400 /* character point size */
+#define MAX_GLYPHS 512 /* Maximum number of glyphs rendered at one time */
+
+ char Header[128];
+
+ FT_Error error;
+ FT_Library library;
+
+ FT_Face face;
+ FT_Size size;
+ FT_GlyphSlot glyph;
+
+ FT_Outline outline;
+
+ FT_Pos* cur_x;
+ FT_Pos* cur_y;
+
+ unsigned short* cur_endContour;
+ unsigned char* cur_touch;
+
+ FT_Outline outlines[MAX_GLYPHS];
+
+ int num_glyphs;
+ int tab_glyphs;
+ int cur_glyph;
+ int cur_point;
+ unsigned short cur_contour;
+
+ int pixel_size = CHARSIZE*96/72;
+ int repeat_count = 1;
+
+ FT_Bitmap Bit;
+ grBitmap bit;
+
+ int Fail;
+ int Num;
+
+ int vio_Height, vio_Width;
+
+ short visual; /* display glyphs while rendering */
+ short gray_render; /* smooth fonts with gray levels */
+
+
+
+ static void Clear_Buffer();
+
+ static void Panic( const char* message )
+ {
+ fprintf( stderr, "%s\n error code = 0x%04x\n", message, error );
+ }
+
+/*******************************************************************/
+/* */
+/* Get_Time: */
+/* */
+/* Returns the current time in milliseconds. */
+/* */
+/*******************************************************************/
+
+ long Get_Time( void )
+ {
+ return clock() * 10000 / CLOCKS_PER_SEC;
+ }
+
+
+/*******************************************************************/
+/* */
+/* Init_Engine: */
+/* */
+/* Allocates bitmap, render pool and other structs... */
+/* */
+/*******************************************************************/
+
+ void Init_Engine( void )
+ {
+ Bit.rows = bit.rows;
+ Bit.width = bit.width;
+ Bit.pitch = bit.pitch;
+ Bit.buffer = bit.buffer;
+ Bit.pixel_mode = gray_render ? ft_pixel_mode_grays : ft_pixel_mode_mono;
+ Bit.num_grays = bit.grays;
+ Clear_Buffer();
+ }
+
+
+/*******************************************************************/
+/* */
+/* Clear_Buffer: */
+/* */
+/* Clears current bitmap. */
+/* */
+/*******************************************************************/
+
+ static void Clear_Buffer( void )
+ {
+ long size = Bit.rows * Bit.pitch;
+
+ memset( Bit.buffer, 0, size );
+ }
+
+
+/*******************************************************************/
+/* */
+/* LoadTrueTypeChar: */
+/* */
+/* Loads a glyph into memory. */
+/* */
+/*******************************************************************/
+
+ FT_Error LoadChar( int idx )
+ {
+ error = FT_Load_Glyph( face, idx, FT_LOAD_DEFAULT );
+ if ( error )
+ return error;
+
+ glyph->outline.second_pass = 0;
+ glyph->outline.high_precision = 0;
+ glyph->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 */
+ FT_New_Outline( library,
+ glyph->outline.n_points,
+ glyph->outline.n_contours,
+ &outlines[cur_glyph] );
+
+ /* copy the glyph outline into it */
+ glyph->outline.high_precision = 0;
+ glyph->outline.second_pass = 0;
+ FT_Copy_Outline( &glyph->outline, &outlines[cur_glyph] );
+
+ /* center outline around 0 */
+ {
+ FT_BBox bbox;
+
+ FT_Get_Outline_CBox( &glyph->outline, &bbox );
+ FT_Translate_Outline( &outlines[cur_glyph],
+ - ( bbox.xMax - bbox.xMin )/2,
+ - ( bbox.yMax - bbox.yMin )/2 );
+ }
+ /* translate it */
+ FT_Translate_Outline( &outlines[cur_glyph],
+ Bit.width * 32 ,
+ Bit.rows * 32 );
+ cur_glyph++;
+
+ return FT_Err_Ok;
+ }
+
+
+/*******************************************************************/
+/* */
+/* ConvertRaster: */
+/* */
+/* Performs scan conversion. */
+/* */
+/*******************************************************************/
+
+ FT_Error ConvertRaster( int index )
+ {
+ outlines[index].second_pass = 0;
+ outlines[index].high_precision = 0;
+
+ return FT_Get_Outline_Bitmap( library, &outlines[index], &Bit );
+ }
+
+
+ static void Usage()
+ {
+ fprintf( stderr, "fttimer: simple performance timer -- part of the FreeType project\n" );
+ fprintf( stderr, "-----------------------------------------------------------------\n\n" );
+ fprintf( stderr, "Usage: fttimer [options] fontname[.ttf|.ttc]\n\n" );
+ fprintf( stderr, "options:\n");
+ fprintf( stderr, " -r : repeat count to be used (default is 1)\n" );
+ fprintf( stderr, " -s : character pixel size (default is 600)\n" );
+ fprintf( stderr, " -v : display results..\n" );
+ fprintf( stderr, " -g : render anti-aliased glyphs\n" );
+ exit(1);
+ }
+
+
+ int main( int argc, char** argv )
+ {
+ int i, total, base, rendered_glyphs;
+ char filename[128 + 4];
+ char alt_filename[128 + 4];
+ char* execname;
+ grSurface* surface = 0;
+
+ 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;
+
+ case 's':
+ argc--;
+ argv++;
+ if ( argc < 2 ||
+ sscanf( argv[1], "%d", &pixel_size ) != 1 )
+ Usage();
+ break;
+
+ case 'r':
+ argc--;
+ argv++;
+ if ( argc < 2 ||
+ sscanf( argv[1], "%d", &repeat_count ) != 1 )
+ Usage();
+ if (repeat_count < 1)
+ repeat_count = 1;
+ break;
+
+ default:
+ fprintf( stderr, "Unknown argument '%s'!\n", argv[1] );
+ Usage();
+ }
+ argc--;
+ argv++;
+ }
+
+ if ( argc != 2 )
+ Usage();
+
+ 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 = FT_Init_FreeType( &library )) )
+ Panic( "Error while initializing engine" );
+
+ /* Load face */
+
+ error = FT_New_Face( library, filename, 0, &face );
+ if ( error == FT_Err_Cannot_Open_Stream )
+ Panic( "Could not find/open font resource" );
+ else if ( error )
+ Panic( "Error while opening font resource" );
+
+ /* get face properties and allocate preload arrays */
+
+ num_glyphs = face->num_glyphs;
+ glyph = face->glyph;
+
+ tab_glyphs = MAX_GLYPHS;
+ if ( tab_glyphs > num_glyphs )
+ tab_glyphs = num_glyphs;
+
+ /* create size */
+
+ error = FT_Set_Pixel_Sizes( face, pixel_size, pixel_size );
+ if ( error ) Panic( "Could not reset instance" );
+
+ bit.mode = gray_render ? gr_pixel_mode_gray : gr_pixel_mode_mono;
+ bit.width = 640;
+ bit.rows = 480;
+ bit.grays = 128;
+
+ if ( visual )
+ {
+ if ( !grInitDevices() )
+ Panic( "Could not initialize graphics.\n" );
+
+ surface = grNewSurface( 0, &bit );
+ if (!surface)
+ Panic( "Could not open graphics window/screen.\n" );
+ }
+ else
+ {
+ if ( grNewBitmap( bit.mode,
+ bit.grays,
+ bit.width,
+ bit.rows,
+ &bit ) )
+ Panic( "Could not create rendering buffer.\n" );
+ }
+
+ Init_Engine();
+
+ Num = 0;
+ Fail = 0;
+
+ total = num_glyphs;
+ base = 0;
+
+ rendered_glyphs = 0;
+
+ t0 = 0; /* Initial time */
+
+ tz0 = Get_Time();
+
+ while ( total > 0 )
+ {
+ int repeat;
+
+ /* 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 = LoadChar( 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 ( repeat = 0; repeat < repeat_count; repeat++ )
+ {
+ for ( Num = 0; Num < cur_glyph; Num++ )
+ {
+ if ( (error = ConvertRaster( Num )) )
+ Fail++;
+
+ else
+ {
+ rendered_glyphs ++;
+
+ if ( Num == 0 && visual )
+ {
+ sprintf( Header, "Glyph: %5d", Num );
+ grSetTitle( surface, Header );
+ grRefreshSurface( surface );
+ Clear_Buffer();
+ }
+ }
+ }
+ }
+
+ t = Get_Time() - t;
+ if ( t < 0 )
+ t += 1000 * 60 * 60;
+
+ printf( " = %f s\n", (double)t / 10000 );
+ t0 += t;
+
+ /* Now free all loaded outlines */
+ for ( Num = 0; Num < cur_glyph; Num++ )
+ FT_Done_Outline( library, &outlines[Num] );
+ }
+
+ tz0 = Get_Time() - tz0;
+
+ FT_Done_Face( face );
+
+ printf( "\n" );
+ printf( "rendered glyphs = %d\n", rendered_glyphs );
+ printf( "render time = %f s\n", (double)t0 / 10000 );
+ printf( "fails = %d\n", Fail );
+ printf( "average glyphs/s = %f\n",
+ (double)rendered_glyphs / t0 * 10000 );
+
+ printf( "total timing = %f s\n", (double)tz0 / 10000 );
+ printf( "Fails = %d\n", Fail );
+
+ FT_Done_FreeType( library );
+
+ exit( 0 ); /* for safety reasons */
+
+ return 0; /* never reached */
+ }
+
+
+/* End */
--- /dev/null
+++ b/demos/src/fttry.c
@@ -1,0 +1,155 @@
+/****************************************************************************/
+/* */
+/* The FreeType project -- a free and portable quality TrueType renderer. */
+/* */
+/* Copyright 1996-1998 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 "freetype.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#define gettext( x ) ( x )
+
+ FT_Error error;
+
+ FT_Library library;
+ FT_Face face;
+
+ unsigned int num_glyphs;
+ int ptsize;
+
+ int Fail;
+ int Num;
+
+
+
+ static void Usage( char* name )
+ {
+ printf( "fttry: simple TrueType instruction tester -- part of the FreeType project\n" );
+ printf( "--------------------------------------------------------------------------\n" );
+ printf( "\n" );
+ printf( "Usage: %s ppem glyph fontname [fontname2..]\n\n", name );
+ printf( " or %s -u glyph fontname [fontname2..]\n", name );
+ printf( " to load an unscaled glyph\n\n" );
+
+ exit( 1 );
+ }
+
+
+ static void Panic( const char* message )
+ {
+ fprintf( stderr, "%s\n error code = 0x%04x\n", message, error );
+ exit(1);
+ }
+
+ int main( int argc, char** argv )
+ {
+ int i, file_index, glyph_index;
+ char filename[128 + 4];
+ char alt_filename[128 + 4];
+ char* execname;
+ char* fname;
+ int load_unscaled = 0;
+
+ execname = argv[0];
+
+ if ( argc < 3 )
+ Usage( execname );
+
+ if ( argv[1][0] == '-' &&
+ argv[1][1] == 'u' )
+ {
+ load_unscaled = 1;
+ }
+ else
+ {
+ if ( sscanf( argv[1], "%d", &ptsize ) != 1 )
+ Usage( execname );
+ }
+ argc--;
+ argv++;
+
+ if ( sscanf( argv[1], "%d", &glyph_index ) != 1 )
+ Usage( execname );
+
+ error = FT_Init_FreeType( &library );
+ if (error) Panic( "Could not create library object" );
+
+ /* 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 );
+ }
+
+ i = strlen( filename );
+ fname = filename;
+
+ while ( i >= 0 )
+ if ( filename[i] == '/' || filename[i] == '\\' )
+ {
+ fname = filename + i + 1;
+ i = -1;
+ }
+ else
+ i--;
+
+ printf( "%s: ", fname );
+
+ /* Load face */
+ error = FT_New_Face( library, filename, 0, &face );
+ if (error) Panic( "Could not create face object" );
+
+ num_glyphs = face->num_glyphs;
+
+ error = FT_Set_Char_Size( face, ptsize << 6, 0, 0, 0 );
+ if (error) Panic( "Could not set character size" );
+
+ error = FT_Load_Glyph( face,
+ glyph_index,
+ load_unscaled ? FT_LOAD_NO_SCALE
+ : FT_LOAD_DEFAULT );
+ if ( error == 0 )
+ printf( "OK.\n" );
+ else
+ printf( "Fail with error 0x%04x\n", error );
+
+ FT_Done_Face( face );
+ }
+
+ FT_Done_FreeType(library);
+ exit( 0 ); /* for safety reasons */
+
+ return 0; /* never reached */
+ }
+
+
+/* End */
--- /dev/null
+++ b/demos/src/ftview.c
@@ -1,0 +1,615 @@
+/****************************************************************************/
+/* */
+/* 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. */
+/* */
+/* This is a new version using the MiGS graphics subsystem for */
+/* blitting and display. */
+/* */
+/* Press F1 when running this program to have a list of key-bindings */
+/* */
+/****************************************************************************/
+
+#include "freetype.h"
+#include "ftoutln.h"
+#include "common.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "graph.h"
+#include "grfont.h"
+
+#define DIM_X 500
+#define DIM_Y 400
+
+#define CENTER_X (bit.width/2)
+#define CENTER_Y (bit.rows/2)
+
+#define MAXPTSIZE 500 /* dtp */
+
+
+ char Header[128];
+ char* new_header = 0;
+
+ FT_Library library; /* the FreeType library */
+ FT_Face face; /* the font face */
+ FT_Size size; /* the font size */
+ FT_GlyphSlot glyph; /* the glyph slot */
+
+ FT_Error error; /* error returned by FreeType ? */
+
+ grSurface* surface; /* current display surface */
+ grBitmap bit; /* current display bitmap */
+
+ int num_glyphs; /* number of glyphs */
+ int ptsize; /* current point size */
+
+ int hinted = 1; /* is glyph hinting active ? */
+ int gray_render = 1; /* is anti-aliasing active ? */
+ int use_sbits = 1; /* do we use embedded bitmaps ? */
+ int low_prec = 1; /* force low precision */
+ int Num; /* current first glyph index */
+
+ int res = 96;
+
+ int Fail;
+ unsigned char autorun;
+
+ int graph_init = 0;
+
+
+ /* PanicZ */
+ static void PanicZ( const char* message )
+ {
+ fprintf( stderr, "%s\n error = 0x%04x\n", message, error );
+ exit(1);
+ }
+
+
+ /* Clears the Bit bitmap/pixmap */
+ static void Clear_Display( void )
+ {
+ long size = (long)bit.pitch * bit.rows;
+ memset( bit.buffer, 0, size );
+ }
+
+
+ /* Initialize the display bitmap named Bit */
+ static int Init_Display()
+ {
+ grInitDevices();
+
+ bit.mode = gr_pixel_mode_gray;
+ bit.width = DIM_X;
+ bit.rows = DIM_Y;
+ bit.grays = 128;
+
+ surface = grNewSurface( 0, &bit );
+ if (!surface)
+ PanicZ( "could not allocate display surface\n" );
+
+ graph_init = 1;
+ return 0;
+ }
+
+
+#define MAX_BUFFER 65000
+
+#define FLOOR(x) ((x) & -64)
+#define CEIL(x) (((x)+63) & -64)
+#define TRUNC(x) ((x) >> 6)
+
+ static
+ char bit_buffer[ MAX_BUFFER ];
+
+ /* Render a single glyph */
+ static FT_Error Render_Glyph( int x_offset,
+ int y_offset )
+ {
+ /* first, render the glyph into an intermediate buffer */
+ FT_Bitmap bit2;
+ grBitmap bit3;
+ int width, height, pitch, size;
+ int left, right, top, bottom;
+
+ left = FLOOR( glyph->metrics.horiBearingX );
+ right = CEIL( glyph->metrics.horiBearingX + glyph->metrics.width );
+ width = TRUNC(right - left);
+
+ top = CEIL( glyph->metrics.horiBearingY );
+ bottom = FLOOR( glyph->metrics.horiBearingY - glyph->metrics.height );
+ height = TRUNC( top - bottom );
+
+ if ( glyph->format == ft_glyph_format_outline )
+ {
+ pitch = ( gray_render ? (width+3) & -4 : (width+7) >> 3 );
+ size = pitch*height;
+
+ if (size > MAX_BUFFER)
+ return FT_Err_Out_Of_Memory;
+
+ bit2.width = width;
+ bit2.rows = height;
+ bit2.pitch = pitch;
+ bit2.pixel_mode = gray_render ? ft_pixel_mode_grays : ft_pixel_mode_mono;
+ bit2.buffer = bit_buffer;
+
+ bit3.rows = bit2.rows;
+ bit3.width = bit2.width;
+ bit3.pitch = bit2.pitch;
+ bit3.mode = gray_render ? bit.mode : gr_pixel_mode_mono;
+ bit3.buffer = bit_buffer;
+ bit3.grays = 128;
+
+ FT_Translate_Outline( &glyph->outline, -left, -bottom );
+ memset( bit_buffer, 0, size );
+
+ if (low_prec)
+ glyph->outline.high_precision = 0;
+
+ FT_Get_Outline_Bitmap( library, &glyph->outline, &bit2 );
+ }
+ else
+ {
+ bit3.rows = glyph->bitmap.rows;
+ bit3.width = glyph->bitmap.width;
+ bit3.pitch = glyph->bitmap.pitch;
+ bit3.mode = gr_pixel_mode_mono;
+ bit3.buffer = glyph->bitmap.buffer;
+ bit3.grays = 0;
+ }
+
+ /* Then, blit the image to the target surface */
+ grBlitGlyphToBitmap( &bit,
+ &bit3,
+ x_offset + TRUNC(left),
+ y_offset - TRUNC(top),
+ (grColor)127L );
+ return 0;
+ }
+
+
+ static FT_Error Reset_Scale( int pointSize )
+ {
+ FT_Error error;
+
+ error = FT_Set_Char_Size( face, pointSize << 6,
+ pointSize << 6,
+ res,
+ res );
+ if ( error )
+ {
+ }
+ return FT_Err_Ok;
+ }
+
+
+ static FT_Error LoadChar( int idx, int hint )
+ {
+ int flags;
+
+ flags = FT_LOAD_DEFAULT;
+
+ if ( !hint )
+ flags |= FT_LOAD_NO_HINTING;
+
+ if ( !use_sbits )
+ flags |= FT_LOAD_NO_BITMAP;
+
+ return FT_Load_Glyph( face, idx, flags );
+ }
+
+
+
+ static FT_Error Render_All( int first_glyph, int ptsize )
+ {
+ FT_F26Dot6 start_x, start_y, step_x, step_y, x, y;
+ int i;
+
+ FT_Error error;
+
+
+ start_x = 4;
+ start_y = 16 + ptsize ;
+
+ step_x = size->metrics.x_ppem + 4;
+ step_y = size->metrics.y_ppem + 10;
+
+ x = start_x;
+ y = start_y;
+
+ i = first_glyph;
+
+ while ( i < num_glyphs )
+ {
+ if ( !(error = LoadChar( i, hinted )) )
+ {
+ Render_Glyph( x, y );
+
+ x += ( glyph->metrics.horiAdvance >> 6 ) + 1;
+
+ if ( x + size->metrics.x_ppem > bit.width )
+ {
+ x = start_x;
+ y += step_y;
+
+ if ( y >= bit.rows )
+ return FT_Err_Ok;
+ }
+ }
+ else
+ Fail++;
+
+ i++;
+ }
+
+ return FT_Err_Ok;
+ }
+
+
+ static void Help( )
+ {
+ grEvent dummy_event;
+
+ Clear_Display();
+ grGotoxy( 0, 0 );
+ grSetMargin( 2, 1 );
+ grGotobitmap( &bit );
+
+ grWriteln("FreeType Glyph Viewer - part of the FreeType test suite" );
+ grLn();
+ grWriteln("This program is used to display all glyphs from one or" );
+ grWriteln("several font files, with the FreeType library.");
+ grLn();
+ grWriteln("Use the following keys :");
+ grLn();
+ grWriteln(" F1 or ? : display this help screen" );
+ grWriteln(" a : toggle anti-aliasing" );
+ grWriteln(" h : toggle outline hinting" );
+ grWriteln(" b : toggle embedded bitmaps" );
+ grWriteln(" l : toggle low precision rendering" );
+ grLn();
+ grWriteln(" Up : increase pointsize by 1 unit" );
+ grWriteln(" Down : decrease pointsize by 1 unit" );
+ grWriteln(" Page Up : increase pointsize by 10 units" );
+ grWriteln(" Page Down : decrease pointsize by 10 units" );
+ grLn();
+ grWriteln(" Right : increment first glyph index" );
+ grWriteln(" Left : decrement first glyph index" );
+ grLn();
+ grWriteln(" F5 : decrement first glyph index by 10" );
+ grWriteln(" F6 : increment first glyph index by 10" );
+ grWriteln(" F7 : decrement first glyph index by 100");
+ grWriteln(" F8 : increment first glyph index by 100");
+ grWriteln(" F9 : decrement first glyph index by 1000");
+ grWriteln(" F10 : increment first glyph index by 1000");
+ grLn();
+ grWriteln("press any key to exit this help screen");
+
+ grRefreshSurface( surface );
+ grListenSurface( surface, gr_event_key, &dummy_event );
+ }
+
+
+
+ static int Process_Event( grEvent* event )
+ {
+ int i;
+
+ switch ( event->key )
+ {
+ case grKeyEsc: /* ESC or q */
+ case grKEY('q'):
+ return 0;
+
+ case grKEY('a'):
+ gray_render = !gray_render;
+ new_header = ( gray_render
+ ? "anti-aliasing is now on"
+ : "anti-aliasing is now off" );
+ return 1;
+
+ case grKEY('b'):
+ use_sbits = !use_sbits;
+ new_header = ( use_sbits
+ ? "embedded bitmaps are now used when available"
+ : "embedded bitmaps are now ignored" );
+ return 1;
+
+ case grKEY('n'):
+ case grKEY('p'):
+ return (int)event->key;
+
+ case grKEY('l'):
+ low_prec = !low_prec;
+ new_header = ( low_prec
+ ? "rendering precision is now forced to low"
+ : "rendering precision is now normal" );
+ break;
+
+ case grKEY('h'):
+ hinted = !hinted;
+ new_header = ( hinted
+ ? "glyph hinting is now active"
+ : "glyph hinting is now ignored" );
+ break;
+
+ case grKeyF1:
+ case grKEY('?'):
+ Help();
+ return 1;
+
+#if 0
+ case grKeyF3: i = 16; goto Do_Rotate;
+ case grKeyF4: i = -16; goto Do_Rotate;
+ case grKeyF5: i = 1; goto Do_Rotate;
+ case grKeyF6: i = -1; goto Do_Rotate;
+#endif
+
+ case grKeyPageUp: i = 10; goto Do_Scale;
+ case grKeyPageDown: i = -10; goto Do_Scale;
+ case grKeyUp: i = 1; goto Do_Scale;
+ case grKeyDown: i = -1; goto Do_Scale;
+
+ case grKeyLeft: i = -1; goto Do_Glyph;
+ case grKeyRight: i = 1; goto Do_Glyph;
+ case grKeyF7: i = -10; goto Do_Glyph;
+ case grKeyF8: i = 10; goto Do_Glyph;
+ case grKeyF9: i = -100; goto Do_Glyph;
+ case grKeyF10: i = 100; goto Do_Glyph;
+ case grKeyF11: i = -1000; goto Do_Glyph;
+ case grKeyF12: i = 1000; goto Do_Glyph;
+ default:
+ ;
+ }
+ return 1;
+
+#if 0
+ Do_Rotate:
+ Rotation = (Rotation + i) & 1023;
+ return 1;
+#endif
+
+ Do_Scale:
+ ptsize += i;
+ if (ptsize < 1) ptsize = 1;
+ if (ptsize > MAXPTSIZE) ptsize = MAXPTSIZE;
+ return 1;
+
+ Do_Glyph:
+ Num += i;
+ if (Num < 0) Num = 0;
+ if (Num >= num_glyphs) Num = num_glyphs-1;
+ return 1;
+ }
+
+
+
+ static void usage( char* execname )
+ {
+ fprintf( stderr, "\n" );
+ fprintf( stderr, "ftview: simple glyph viewer -- 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, " -r R use resolution R dpi (default: 72 dpi)\n" );
+ fprintf( stderr, " -f index specify first glyph index to display\n" );
+ fprintf( stderr, "\n" );
+
+ exit( 1 );
+ }
+
+
+ int main( int argc, char** argv )
+ {
+ int i, old_ptsize, orig_ptsize, file;
+ int first_glyph = 0;
+ int XisSetup = 0;
+ char filename[128 + 4];
+ char alt_filename[128 + 4];
+ char* execname;
+ int option;
+ int file_loaded;
+
+ FT_Error error;
+ grEvent event;
+
+ execname = ft_basename( argv[0] );
+
+ while ( 1 )
+ {
+ option = getopt( argc, argv, "f:r:" );
+
+ if ( option == -1 )
+ break;
+
+ switch ( option )
+ {
+ case 'f':
+ first_glyph = atoi( optarg );
+ break;
+
+ case 'r':
+ res = atoi( optarg );
+ if ( res < 1 )
+ usage( execname );
+ break;
+
+ default:
+ usage( execname );
+ break;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if ( argc <= 1 )
+ usage( execname );
+
+ if ( sscanf( argv[0], "%d", &orig_ptsize ) != 1 )
+ orig_ptsize = 64;
+
+ file = 1;
+
+ /* Initialize engine */
+ error = FT_Init_FreeType( &library );
+ if (error) PanicZ( "Could not initialise FreeType library" );
+
+/* FT_Set_Raster_Palette( library, 17, palette_17 ); */
+
+ NewFile:
+ ptsize = orig_ptsize;
+ hinted = 1;
+ file_loaded = 0;
+
+ 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 = FT_New_Face( library, filename, 0, &face );
+ if (error) goto Display_Font;
+
+ file_loaded++;
+
+ error = Reset_Scale( ptsize );
+ if (error) goto Display_Font;
+
+ num_glyphs = face->num_glyphs;
+ glyph = face->glyph;
+ size = face->size;
+
+ Display_Font:
+ /* initialise graphics if needed */
+ if ( !XisSetup )
+ {
+ XisSetup = 1;
+ Init_Display();
+ }
+
+ grSetTitle( surface, "FreeType Glyph Viewer - press F1 for help" );
+ old_ptsize = ptsize;
+
+ if ( file_loaded >= 1 )
+ {
+ Fail = 0;
+ Num = first_glyph;
+
+ if ( Num >= num_glyphs )
+ Num = num_glyphs-1;
+
+ if ( Num < 0 )
+ Num = 0;
+ }
+
+ for ( ;; )
+ {
+ int key;
+
+ Clear_Display();
+
+ if ( file_loaded >= 1 )
+ {
+ Render_All( Num, ptsize );
+
+ sprintf( Header, "%s %s (file %s)",
+ face->family_name,
+ face->style_name,
+ ft_basename( filename ) );
+
+ if (!new_header)
+ new_header = Header;
+
+ grWriteCellString( &bit, 0, 0, new_header, (grColor)127L );
+ new_header = 0;
+
+ sprintf( Header, "at %d points, first glyph = %d",
+ ptsize,
+ Num );
+ }
+ else
+ {
+ sprintf( Header, "%s : is not a font file or could not be opened",
+ ft_basename(filename) );
+ }
+
+ grWriteCellString( &bit, 0, 8, Header, (grColor)127L );
+ grRefreshSurface( surface );
+
+ grListenSurface( surface, 0, &event );
+ if ( !( key = Process_Event( &event ) ) )
+ goto Fin;
+
+ if ( key == 'n' )
+ {
+ if (file_loaded >= 1)
+ FT_Done_Face( face );
+
+ if ( file < argc - 1 )
+ file++;
+
+ goto NewFile;
+ }
+
+ if ( key == 'p' )
+ {
+ if (file_loaded >= 1)
+ FT_Done_Face( face );
+
+ if ( file > 1 )
+ file--;
+
+ goto NewFile;
+ }
+
+ if ( ptsize != old_ptsize )
+ {
+ if ( Reset_Scale( ptsize ) )
+ PanicZ( "Could not resize font." );
+
+ old_ptsize = ptsize;
+ }
+ }
+
+ Fin:
+#if 0
+ grDoneSurface(surface);
+ grDone();
+#endif
+ printf( "Execution completed successfully.\n" );
+ printf( "Fails = %d\n", Fail );
+
+ exit( 0 ); /* for safety reasons */
+ return 0; /* never reached */
+}
+
+
+/* End */
+
--- /dev/null
+++ b/demos/src/t1dump.c
@@ -1,0 +1,1031 @@
+/****************************************************************************/
+/* */
+/* t1dump.c 1.0 */
+/* */
+/* Copyright 1999 - The FreeType Project http://www.freetype.org */
+/* */
+/* T1Dump is a very simply Type 1 font dumper. It can be used to */
+/* write the following information to the standard ouput, or any */
+/* given file: */
+/* */
+/* - a description of the font file (including name, properties, etc..) */
+/* - the decrypted private dictionary, 'as is', i.e. in binary form */
+/* - the stream of tokens from the font file (useful to debug the */
+/* Type1 driver or to look at the font's internal structure..) */
+/* - the charstring commands of a given subroutine */
+/* - the charstring commands of a given glyph */
+/* - the encoding */
+/* - the glyph names */
+/* */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "freetype.h"
+#include <t1tokens.h>
+#include <t1gload.h>
+#include <t1load.h>
+#include <t1parse.h>
+
+FT_Library library; /* root library object */
+FT_Face face; /* truetype face */
+T1_Face t1_face;
+FT_Error error;
+FILE* target;
+
+ void Panic( const char* message )
+ {
+ fprintf( stderr, "%s\n error code = 0x%04x\n", message, error );
+ exit(1);
+ }
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/********** *********/
+/********** *********/
+/********** DUMP FONT INFORMATION *********/
+/********** *********/
+/********** *********/
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+
+
+ static
+ T1_Error Dump_Font_Info( void )
+ {
+ T1_FontInfo* info = &t1_face->font_info;
+ T1_Private* priv = &t1_face->private_dict;
+ T1_Int n;
+
+ fprintf( target, "Font Name : %s\n", t1_face->font_name );
+
+ fprintf( target, "Version : %s\n", info->version );
+ fprintf( target, "Full Name : %s\n", info->full_name );
+ fprintf( target, "Family : %s\n", info->family_name );
+ fprintf( target, "Weight : %s\n", info->weight );
+ fprintf( target, "Italic angle : %ld\n", info->italic_angle );
+
+ fprintf( target, "Fixed pitch : %s\n",
+ info->is_fixed_pitch ? "yes" : "no" );
+
+ fprintf( target, "Underline : pos %d, thickness %d\n",
+ info->underline_position,
+ info->underline_thickness );
+
+ fprintf( target, "Unique ID : %d\n", priv->unique_id );
+ fprintf( target, "lenIV : %d\n", priv->lenIV );
+
+ fprintf( target, "blues : [" );
+ for ( n = 0; n < priv->num_blues; n++ )
+ fprintf( target, " %d", priv->blue_values[n] );
+ fprintf( target, " ]\n" );
+
+ fprintf( target, "other blues : [" );
+ for ( n = 0; n < priv->num_other_blues; n++ )
+ fprintf( target, " %d", priv->other_blues[n] );
+ fprintf( target, " ]\n" );
+
+ fprintf( target, "family blues : [" );
+ for ( n = 0; n < priv->num_family_blues; n++ )
+ fprintf( target, " %d", priv->family_blues[n] );
+ fprintf( target, " ]\n" );
+
+ fprintf( target, "family other : [" );
+ for ( n = 0; n < priv->num_family_other_blues; n++ )
+ fprintf( target, " %d", priv->family_other_blues[n] );
+ fprintf( target, " ]\n" );
+
+ fprintf( target, "Blue scale : %f\n", priv->blue_scale*1.0/65536.0 );
+ fprintf( target, "Blue shift : %d\n", priv->blue_shift );
+ fprintf( target, "Blue fuzz : %d\n", priv->blue_fuzz );
+
+ fprintf( target, "Std width : %d\n", priv->standard_width );
+ fprintf( target, "Std height : %d\n", priv->standard_height );
+ fprintf( target, "Force bold : %s\n", priv->force_bold ? "yes" : "no" );
+ fprintf( target, "Round stem : %s\n", priv->round_stem_up ? "yes" : "no" );
+
+ fprintf( target, "Stem snap W : [" );
+ for ( n = 0; n < priv->num_snap_widths; n++ )
+ fprintf( target, " %d", priv->stem_snap_widths[n] );
+ fprintf( target, " ]\n" );
+
+ fprintf( target, "Stem snap H : [" );
+ for ( n = 0; n < priv->num_snap_heights; n++ )
+ fprintf( target, " %d", priv->stem_snap_heights[n] );
+ fprintf( target, " ]\n" );
+
+ fprintf( target, "Language : %ld\n", priv->language_group );
+ fprintf( target, "Password : %ld\n", priv->password );
+ fprintf( target, "Min feature : [ %d %d ]\n",
+ priv->min_feature[0],
+ priv->min_feature[1] );
+
+ fprintf( target, "Font BBOX : [ %ld %ld %ld %ld ]\n",
+ t1_face->font_bbox.xMin,
+ t1_face->font_bbox.yMin,
+ t1_face->font_bbox.xMax,
+ t1_face->font_bbox.yMax );
+
+ fprintf( target, "Font matrix : [ %f %f %f %f ]\n",
+ 1.0*t1_face->font_matrix.xx/65536000.0,
+ 1.0*t1_face->font_matrix.xy/65536000.0,
+ 1.0*t1_face->font_matrix.yx/65536000.0,
+ 1.0*t1_face->font_matrix.yy/65536000.0 );
+#if 0
+ fprintf( target,
+ fprintf( target,
+ fprintf( target,
+ fprintf( target,
+ fprintf( target,
+ fprintf( target,
+#endif
+ fprintf( target, "Num glyphs : %d\n", t1_face->num_glyphs );
+ fprintf( target, "Num subrs : %d\n", t1_face->num_subrs );
+
+ return 0;
+ }
+
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/********** *********/
+/********** *********/
+/********** DUMP PRIVATE DICT IN RAW FORM *********/
+/********** *********/
+/********** *********/
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+
+
+ static
+ T1_Error parse_int( T1_Tokenizer tokzer,
+ T1_Long* result )
+ {
+ T1_Bool sign = 0;
+ T1_Long sum = 0;
+ T1_Token* token = &tokzer->token;
+ T1_Byte* base = tokzer->base + token->start;
+ T1_Byte* limit = base + token->len;
+
+ if (base >= limit)
+ goto Fail;
+
+ /* check sign */
+ if ( *base == '+' )
+ base++;
+
+ else if ( *base == '-' )
+ {
+ sign++;
+ base++;
+ }
+
+ /* parse digits */
+ if ( base >= limit )
+ goto Fail;
+
+ do
+ {
+ sum = ( 10*sum + (*base++ - '0') );
+
+ } while (base < limit);
+
+ if (sign)
+ sum = -sum;
+
+ *result = sum;
+ return T1_Err_Ok;
+
+ Fail:
+ *result = 0;
+ return T1_Err_Syntax_Error;
+ }
+
+
+
+
+
+ static
+ T1_Error Dump_Private_Dict( const char* filename )
+ {
+ struct FT_StreamRec_ stream_rec;
+ FT_Stream stream = &stream_rec;
+ T1_Error error;
+ T1_Tokenizer tokenizer;
+
+ error = FT_New_Stream( filename, stream );
+ if (error) return error;
+
+ stream->memory = library->memory;
+
+ error = New_Tokenizer( stream, &tokenizer );
+ if (error) goto Exit;
+
+ /* go directly to the Private dictionary */
+ error = Open_PrivateDict( tokenizer );
+ if (error)
+ Panic( "Could not open private dictionary !!" );
+
+ /* Write it to the target file */
+ fwrite( tokenizer->base, tokenizer->limit, 1, target );
+
+ Exit:
+ if (stream->close)
+ stream->close(stream);
+
+ return error;
+ }
+
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/********** *********/
+/********** *********/
+/********** DUMP TYPE 1 TOKEN STREAM *********/
+/********** *********/
+/********** *********/
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+
+
+ static
+ T1_Error Dump_Type1_Tokens( const char* filename )
+ {
+ struct FT_StreamRec_ stream_rec;
+ FT_Stream stream = &stream_rec;
+
+ T1_Error error;
+ T1_Tokenizer tokenizer;
+
+ error = FT_New_Stream( filename, stream );
+ if (error) return error;
+
+ stream->memory = library->memory;
+
+ error = New_Tokenizer( stream, &tokenizer );
+ if (error) goto Exit;
+
+ /* Dump the first segment of the Type1 font */
+ do
+ {
+ T1_Token* token;
+ T1_String temp_string[128];
+ T1_Int len;
+
+ error = Read_Token( tokenizer );
+ if (error) { error = 0; break; }
+
+ /* dump the token */
+ token = &tokenizer->token;
+ len = token->len;
+ if (len > 127) len = 127;
+
+ strncpy( temp_string,
+ (T1_String*)(tokenizer->base + token->start),
+ len );
+ temp_string[len] = '\0';
+
+ fprintf( target, "%s\n", temp_string );
+
+ /* Exit the loop when we encounter a "currentfile" token */
+ if ( token->kind == tok_keyword &&
+ token->kind2 == key_currentfile )
+ break;
+
+ } while (1);
+
+ error = Open_PrivateDict( tokenizer );
+ if (error)
+ Panic( "** could not open private dictionary **\n" );
+ else
+ {
+ T1_Int num = 0;
+ T1_Bool last_num = 0;
+
+ do
+ {
+ T1_Token* token;
+ T1_String temp_string[128];
+ T1_Int len;
+
+ error = Read_Token( tokenizer );
+ if (error) { error = 0; break; }
+
+ /* dump the token */
+ token = &tokenizer->token;
+ len = token->len;
+ if (len > 127) len = 127;
+
+ strncpy( temp_string,
+ (T1_String*)(tokenizer->base + token->start),
+ len );
+ temp_string[len] = '\0';
+
+ /* detect "RD" uses */
+ if ( token->kind == tok_keyword &&
+ ( token->kind2 == key_RD ||
+ token->kind2 == key_RD_alternate ) &&
+ last_num )
+ {
+ fprintf( target, "%s [%d binary bytes] ", temp_string, num );
+ tokenizer->cursor += num;
+ }
+ else
+ {
+ fprintf( target, "%s\n", temp_string );
+
+ /* exit dump when we encounter a 'closefile' */
+ if ( token->kind == tok_keyword &&
+ token->kind2 == key_closefile )
+ break;
+
+ /* record numerical value if any */
+ if ( token->kind == tok_number )
+ {
+ T1_Long sum;
+
+ if ( !parse_int( tokenizer, &sum ) )
+ {
+ num = sum;
+ last_num = 1;
+ }
+ else
+ last_num = 0;
+ }
+ else
+ last_num = 0;
+ }
+
+ } while (1);
+ }
+
+ Exit:
+ if (stream->close)
+ stream->close(stream);
+ return error;
+ }
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/********** *********/
+/********** *********/
+/********** DUMP CHARACTER ENCODING *********/
+/********** *********/
+/********** *********/
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+
+
+ static
+ void Dump_Encoding( void )
+ {
+ T1_Encoding* encode = &t1_face->encoding;
+ int n;
+
+ fprintf( target, "characters count = %d\n", encode->num_chars );
+
+ fprintf( target, "first code = %d, last code = %d\n",
+ encode->code_first, encode->code_last );
+
+ for ( n = 0; n < encode->num_chars; n++ )
+ {
+ int code = (int)encode->char_index[n];
+
+ if (code || n == 0)
+ fprintf( target, "%3d %s\n", n, t1_face->glyph_names[code] );
+ }
+ }
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/********** *********/
+/********** *********/
+/********** DUMP SUBROUTINES AND GLYPH CHARSTRINGS *********/
+/********** *********/
+/********** *********/
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+
+
+ static
+ void Dump_CharStrings( T1_Byte* base,
+ T1_Int len )
+ {
+ T1_Byte* cur = base;
+ T1_Byte* limit = base + len;
+ T1_String temp_name[128];
+ T1_String* string;
+
+ T1_Int x = 0;
+
+ while ( cur < limit )
+ {
+ switch (*cur++)
+ {
+ case 1: string = "hstem"; break;
+
+ case 3: string = "vstem"; break;
+ case 4: string = "vmoveto"; break;
+ case 5: string = "rlineto"; break;
+ case 6: string = "hlineto"; break;
+ case 7: string = "vlineto"; break;
+ case 8: string = "rrcurveto"; break;
+ case 9: string = "closepath"; break;
+ case 10: string = "callsubr"; break;
+ case 11: string = "return"; break;
+
+ case 13: string = "hsbw"; break;
+ case 14: string = "endchar"; break;
+
+ case 21: string = "rmoveto"; break;
+ case 22: string = "hmoveto"; break;
+
+ case 30: string = "vhcurveto"; break;
+ case 31: string = "hvcurveto"; break;
+
+ case 12:
+ {
+ if (cur > limit)
+ Panic( "invalid charstrings stream\n" );
+
+ switch (*cur++)
+ {
+ case 0: string = "dotsection"; break;
+ case 1: string = "vstem3"; break;
+ case 2: string = "hstem3"; break;
+ case 6: string = "seac"; break;
+ case 7: string = "sbw"; break;
+ case 12: string = "div"; break;
+ case 16: string = "callothersubr"; break;
+ case 17: string = "pop"; break;
+ case 33: string = "setcurrentpoint"; break;
+
+ default:
+ sprintf( temp_name, "escape(12)+unknown(%d)", cur[1] );
+ string = temp_name;
+ }
+ }
+ break;
+
+ case 255: /* four bytes integer */
+ {
+ T1_Long sum;
+
+ if (cur+4 > limit)
+ Panic( "invalid charstrings stream\n" );
+
+ sum = ((long)cur[0] << 24) |
+ ((long)cur[1] << 16) |
+ ((long)cur[2] << 8) |
+ cur[3];
+ sprintf( temp_name, "%ld ", sum );
+ string = temp_name;
+ cur += 4;
+ }
+ break;
+
+ default:
+ if (cur[-1] >= 32)
+ {
+ if (cur[-1] < 247)
+ {
+ sprintf( temp_name, "%ld", (long)cur[-1] - 139 );
+ }
+ else if (cur[-1] < 251)
+ {
+ cur++;
+ sprintf( temp_name, "%ld",
+ ((long)(cur[-2]-247) << 8) + cur[-1] + 108 );
+ }
+ else
+ {
+ cur++;
+ sprintf( temp_name, "%ld",
+ -((long)(cur[-2]-251) << 8) - cur[-1] - 108 );
+ }
+ string = temp_name;
+ }
+ else
+ {
+ sprintf( temp_name, "unknown(%d)", cur[-1] );
+ string = temp_name;
+ }
+ }
+
+ /* now print the charstring command */
+ {
+ int len = strlen(string)+1;
+
+ if ( x+len > 60 )
+ {
+ x = 0;
+ fprintf( target, "\n" );
+ }
+ else
+ fprintf( target, " " );
+
+ fprintf( target, "%s", string );
+ x += len;
+ }
+ }
+ }
+
+
+
+ static
+ void Dump_Glyph( int glyph_index )
+ {
+ fprintf( target, "glyph name: %s\n", t1_face->glyph_names[glyph_index] );
+ Dump_CharStrings( t1_face->charstrings [glyph_index],
+ t1_face->charstrings_len [glyph_index] );
+ }
+
+ static
+ void Dump_Subrs( int subrs_index )
+ {
+ Dump_CharStrings( t1_face->subrs [ subrs_index ],
+ t1_face->subrs_len[ subrs_index ] );
+ }
+
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/********** *********/
+/********** *********/
+/********** EXECUTE GLYPH CHARSTRINGS *********/
+/********** *********/
+/********** *********/
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+
+
+ static
+ T1_Error operator_endchar( T1_Builder* builder )
+ {
+ (void)builder;
+ fprintf( target, "endchar\n" );
+ return 0;
+ }
+
+
+ static
+ T1_Error operator_sbw( T1_Builder* builder,
+ T1_Pos sbx,
+ T1_Pos sby,
+ T1_Pos wx,
+ T1_Pos wy )
+ {
+ (void)builder;
+ fprintf( target, "set bearing [%ld,%ld] width [%ld,%ld]\n",
+ sbx, sby, wx, wy );
+ return 0;
+ }
+
+#if 0
+ static
+ T1_Error operator_seac( T1_Builder* builder,
+ T1_Pos asb,
+ T1_Pos adx,
+ T1_Pos ady,
+ T1_Int bchar,
+ T1_Int achar )
+ {
+ (void)builder;
+ fprintf( target, "accented char: %ld [%ld,%ld] b=%d, a=%d\n",
+ asb, adx, ady, bchar, achar );
+ return 0;
+ }
+#endif
+
+ static
+ T1_Error operator_closepath( T1_Builder* builder )
+ {
+ (void)builder;
+ fprintf( target, "closepath\n" );
+ return 0;
+ }
+
+
+ static
+ T1_Error operator_rlineto( T1_Builder* builder,
+ T1_Pos dx,
+ T1_Pos dy )
+ {
+ (void)builder;
+ fprintf( target, "%ld %ld rlineto\n", dx, dy );
+ return 0;
+ }
+
+
+ static
+ T1_Error operator_rmoveto( T1_Builder* builder,
+ T1_Pos dx,
+ T1_Pos dy )
+ {
+ (void)builder;
+ fprintf( target, "%ld %ld rmoveto\n", dx, dy );
+ return 0;
+ }
+
+
+ static
+ T1_Error operator_rrcurveto( T1_Builder* builder,
+ T1_Pos dx1,
+ T1_Pos dy1,
+ T1_Pos dx2,
+ T1_Pos dy2,
+ T1_Pos dx3,
+ T1_Pos dy3 )
+ {
+ (void)builder;
+ fprintf( target, "%ld %ld %ld %ld %ld %ld rrcurveto\n",
+ dx1, dy1, dx2, dy2, dx3, dy3 );
+ return 0;
+ }
+
+
+ static
+ T1_Error operator_dotsection( T1_Builder* builder )
+ {
+ (void)builder;
+ fprintf( target, "dotsection\n" );
+ return 0;
+ }
+
+
+ static
+ T1_Error operator_stem( T1_Builder* builder,
+ T1_Pos pos,
+ T1_Pos width,
+ T1_Bool vertical )
+ {
+ (void)builder;
+ fprintf( target, "%ld %ld %s\n", pos, width,
+ vertical ? "vstem" : "hstem" );
+ return 0;
+ }
+
+
+ static
+ T1_Error operator_stem3( T1_Builder* builder,
+ T1_Pos pos0,
+ T1_Pos width0,
+ T1_Pos pos1,
+ T1_Pos width1,
+ T1_Pos pos2,
+ T1_Pos width2,
+ T1_Bool vertical )
+ {
+ (void)builder;
+ fprintf( target, "%ld %ld %ld %ld %ld %ld %s\n",
+ pos0, width0, pos1, width1, pos2, width2,
+ vertical ? "vstem3" : "hstem3" );
+ return 0;
+ }
+
+
+#if 0
+ static
+ T1_Error operator_flex( T1_Builder* builder,
+ T1_Pos threshold,
+ T1_Pos end_x,
+ T1_Pos end_y )
+ {
+ (void)builder;
+ fprintf( target, "%ld %ld %ld flex\n", threshold, end_x, end_y );
+ return 0;
+ }
+#endif
+
+ static
+ T1_Error operator_changehints( T1_Builder* builder )
+ {
+ (void)builder;
+ fprintf( target, "-- change hints --\n" );
+ return 0;
+ }
+
+
+ static
+ T1_Error Execute_CharString( int glyph_index )
+ {
+ static const T1_Builder_Funcs builds =
+ {
+ operator_endchar,
+ operator_sbw,
+ operator_closepath,
+ operator_rlineto,
+ operator_rmoveto,
+ operator_rrcurveto,
+ };
+
+ static const T1_Hinter_Funcs hints =
+ {
+ operator_dotsection,
+ operator_changehints,
+ operator_stem,
+ operator_stem3,
+ };
+
+ T1_Decoder decoder;
+ T1_Error error;
+
+ T1_Init_Decoder( &decoder, &hints );
+ T1_Init_Builder( &decoder.builder, t1_face, 0, 0, &builds );
+
+ error = T1_Parse_CharStrings( &decoder,
+ t1_face->charstrings [glyph_index],
+ t1_face->charstrings_len[glyph_index],
+ t1_face->num_subrs,
+ t1_face->subrs,
+ t1_face->subrs_len );
+ return error;
+ }
+
+
+
+
+
+
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/********** *********/
+/********** *********/
+/********** DEBUG FONT LOADING *********/
+/********** *********/
+/********** *********/
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+
+ static
+ T1_Error Debug_Type1_Font( const char* filename )
+ {
+ struct FT_StreamRec_ stream_rec;
+ T1_FaceRec t1facerec;
+ T1_Tokenizer tokenizer;
+ T1_Parser parser;
+ T1_Error error;
+ FT_Stream stream = &stream_rec;
+
+ error = FT_New_Stream( filename, stream );
+ if (error) goto Exit;
+
+ stream->memory = library->memory;
+
+ /* create an empty face record */
+ memset( &t1facerec, 0, sizeof(t1facerec) );
+ t1facerec.root.memory = library->memory;
+ t1facerec.root.stream = stream;
+
+ t1_face = &t1facerec;
+
+ /* open the tokenizer, this will also check the font format */
+ error = New_Tokenizer( stream, &tokenizer );
+ if (error) goto Fail;
+
+ /* Now, load the font program into the face object */
+ Init_T1_Parser( &parser, t1_face, tokenizer );
+
+ /* force token dump */
+ parser.dump_tokens = 1;
+
+ error = Parse_T1_FontProgram( &parser );
+
+ Done_Tokenizer( tokenizer );
+
+ Fail:
+ if (stream->close)
+ stream->close( stream );
+ Exit:
+ return error;
+ }
+
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/********** *********/
+/********** *********/
+/********** MAIN PROGRAM *********/
+/********** *********/
+/********** *********/
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+
+
+ static
+ void Usage()
+ {
+ fprintf( stderr, "t1dump - a simple Type 1 font dumper\n" );
+ fprintf( stderr, "(c) The FreeType project - www.freetype.org\n" );
+ fprintf( stderr, "-------------------------------------------\n\n" );
+
+ fprintf( stderr, "usage : t1dump [options] fontfile(.pfb|.pfa)\n\n" );
+
+ fprintf( stderr, " options\n" );
+ fprintf( stderr, " -o filename : dumps to a specific file\n" );
+ fprintf( stderr, " -g index : dump glyph charstring\n" );
+ fprintf( stderr, " -s index : dump subrs charstring\n" );
+ fprintf( stderr, " -x index : execute glyph charstring\n" );
+ fprintf( stderr, " -e : dump encoding\n" );
+ fprintf( stderr, " -t : dumps the Type 1 token stream\n" );
+ fprintf( stderr, " -d : debug font loading\n" );
+ fprintf( stderr, " -p : dumps private dictionary 'as is'\n\n" );
+
+ exit(1);
+ }
+
+
+typedef enum Request_
+{
+ req_dump_info,
+ req_dump_private,
+ req_dump_tokens,
+ req_dump_encoding,
+ req_dump_glyph,
+ req_dump_subr,
+ req_load_font,
+ req_execute_glyph,
+ req_debug_font
+
+} Request;
+
+
+static char* file_name;
+static int glyph_index;
+static Request request = req_dump_info;
+
+static FT_Driver t1_driver;
+
+ int main( int argc, char** argv )
+ {
+ char valid;
+
+
+ /* Check number of arguments */
+ if ( argc < 2 ) Usage();
+
+ /* Check options */
+ target = stdout;
+
+ argv++;
+ while (argv[0][0] == '-')
+ {
+ valid = 0;
+ switch (argv[0][1])
+ {
+ case 'p':
+ request = req_dump_private;
+ valid = 1;
+ break;
+
+ case 't':
+ request = req_dump_tokens;
+ valid = 1;
+ break;
+
+ case 'e':
+ request = req_dump_encoding;
+ valid = 1;
+ break;
+
+ case 'd':
+ request = req_debug_font;
+ valid = 1;
+ break;
+
+ case 'o':
+ if (argc < 2) Usage();
+ target = fopen( argv[1], "w" );
+ if (!target)
+ Panic( "Could not open/create destination file" );
+ argv++;
+ argc--;
+ valid = 1;
+ break;
+
+ case 'g':
+ case 's':
+ case 'x':
+ if (argc < 2) Usage();
+ if ( sscanf( argv[1], "%d", &glyph_index ) != 1 )
+ Usage();
+
+ switch (argv[0][1])
+ {
+ case 'g': request = req_dump_glyph; break;
+ case 's': request = req_dump_subr; break;
+ case 'x': request = req_execute_glyph; break;
+ }
+ argv++;
+ argc--;
+ valid = 1;
+ break;
+
+ default:
+ ;
+ }
+
+ if (valid)
+ {
+ argv++;
+ argc--;
+ if (argc < 2) Usage();
+ }
+ else
+ break;
+ }
+
+ /* Get file name */
+ file_name = argv[0];
+
+ /* Instead of calling FT_Init_FreeType, we set up our own system */
+ /* object and library. This is reserved for FreeType 2 wizards !! */
+
+ /* Init library, read face object, get driver, create size */
+ error = FT_Init_FreeType( &library );
+ if (error) Panic( "could not initialise FreeType library" );
+
+ t1_driver = FT_Get_Driver( library, "type1" );
+ if (!t1_driver) Panic( "no Type1 driver in current FreeType lib" );
+
+ error = FT_New_Face( library, file_name, 0, &face );
+ if (error) Panic( "could not find/open/create font file" );
+
+ if (face->driver != t1_driver)
+ Panic( "font format is not Type 1 !" );
+
+ switch (request)
+ {
+ case req_dump_private:
+ error = Dump_Private_Dict(file_name);
+ break;
+
+ case req_dump_tokens:
+ error = Dump_Type1_Tokens(file_name);
+ break;
+
+ case req_debug_font:
+ error = Debug_Type1_Font(file_name);
+ break;
+
+ default:
+ error = FT_New_Face( library, file_name, 0, &face );
+ if (error) Panic( "could not load Type 1 font" );
+
+ t1_face = (T1_Face)face;
+
+ /* check glyph index, it is 0 by default */
+ if ( glyph_index < 0 || glyph_index >= t1_face->num_glyphs )
+ Panic( "invalid glyph index\n" );
+
+ switch (request)
+ {
+ case req_dump_glyph:
+ Dump_Glyph( glyph_index );
+ break;
+
+ case req_dump_subr:
+ Dump_Subrs( glyph_index );
+ break;
+
+ case req_execute_glyph:
+ Execute_CharString( glyph_index );
+ break;
+
+ case req_dump_encoding:
+ Dump_Encoding();
+ break;
+
+ default:
+ Dump_Font_Info();
+ }
+ }
+
+ if (error) Panic( "could not dump Type 1 font" );
+
+ FT_Done_FreeType( library );
+ return 0;
+ }
--- /dev/null
+++ b/demos/src/ttdebug.c
@@ -1,0 +1,1247 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef UNIX
+#ifndef HAVE_POSIX_TERMIOS
+#include <sys/ioctl.h>
+#include <termio.h>
+#else
+#ifndef HAVE_TCGETATTR
+#define HAVE_TCGETATTR
+#endif /* HAVE_TCGETATTR */
+#ifndef HAVE_TCSETATTR
+#define HAVE_TCSETATTR
+#endif /* HAVE_TCSETATTR */
+#include <termios.h>
+#endif /* HAVE_POSIX_TERMIOS */
+#endif
+
+/* 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. */
+#ifndef UNIX
+#include <conio.h>
+#else
+#define getch getchar
+#endif
+
+
+#include "freetype.h"
+#include "ttobjs.h"
+#include "ttdriver.h"
+#include "ttinterp.h"
+
+
+FT_Library library; /* root library object */
+FT_Memory memory; /* system object */
+TT_Driver driver; /* truetype driver */
+TT_Face face; /* truetype face */
+TT_Size size; /* truetype size */
+TT_GlyphSlot glyph; /* truetype glyph slot */
+TT_ExecContext exec; /* truetype execution context */
+TT_Error error;
+
+TT_CodeRange_Tag debug_coderange = tt_coderange_glyph;
+
+ typedef FT_Byte ByteStr[2];
+ typedef FT_Byte WordStr[4];
+ typedef FT_Byte LongStr[8];
+ typedef FT_Byte DebugStr[128];
+
+ static DebugStr tempStr;
+
+#undef PACK
+#define PACK( x, y ) ((x << 4) | y)
+
+ static const TT_Byte Pop_Push_Count[256] =
+ {
+ /* opcodes are gathered in groups of 16 */
+ /* please keep the spaces as they are */
+
+ /* SVTCA y */ PACK( 0, 0 ),
+ /* SVTCA x */ PACK( 0, 0 ),
+ /* SPvTCA y */ PACK( 0, 0 ),
+ /* SPvTCA x */ PACK( 0, 0 ),
+ /* SFvTCA y */ PACK( 0, 0 ),
+ /* SFvTCA x */ PACK( 0, 0 ),
+ /* SPvTL // */ PACK( 2, 0 ),
+ /* SPvTL + */ PACK( 2, 0 ),
+ /* SFvTL // */ PACK( 2, 0 ),
+ /* SFvTL + */ PACK( 2, 0 ),
+ /* SPvFS */ PACK( 2, 0 ),
+ /* SFvFS */ PACK( 2, 0 ),
+ /* GPV */ PACK( 0, 2 ),
+ /* GFV */ PACK( 0, 2 ),
+ /* SFvTPv */ PACK( 0, 0 ),
+ /* ISECT */ PACK( 5, 0 ),
+
+ /* SRP0 */ PACK( 1, 0 ),
+ /* SRP1 */ PACK( 1, 0 ),
+ /* SRP2 */ PACK( 1, 0 ),
+ /* SZP0 */ PACK( 1, 0 ),
+ /* SZP1 */ PACK( 1, 0 ),
+ /* SZP2 */ PACK( 1, 0 ),
+ /* SZPS */ PACK( 1, 0 ),
+ /* SLOOP */ PACK( 1, 0 ),
+ /* RTG */ PACK( 0, 0 ),
+ /* RTHG */ PACK( 0, 0 ),
+ /* SMD */ PACK( 1, 0 ),
+ /* ELSE */ PACK( 0, 0 ),
+ /* JMPR */ PACK( 1, 0 ),
+ /* SCvTCi */ PACK( 1, 0 ),
+ /* SSwCi */ PACK( 1, 0 ),
+ /* SSW */ PACK( 1, 0 ),
+
+ /* DUP */ PACK( 1, 2 ),
+ /* POP */ PACK( 1, 0 ),
+ /* CLEAR */ PACK( 0, 0 ),
+ /* SWAP */ PACK( 2, 2 ),
+ /* DEPTH */ PACK( 0, 1 ),
+ /* CINDEX */ PACK( 1, 1 ),
+ /* MINDEX */ PACK( 1, 0 ),
+ /* AlignPTS */ PACK( 2, 0 ),
+ /* INS_$28 */ PACK( 0, 0 ),
+ /* UTP */ PACK( 1, 0 ),
+ /* LOOPCALL */ PACK( 2, 0 ),
+ /* CALL */ PACK( 1, 0 ),
+ /* FDEF */ PACK( 1, 0 ),
+ /* ENDF */ PACK( 0, 0 ),
+ /* MDAP[0] */ PACK( 1, 0 ),
+ /* MDAP[1] */ PACK( 1, 0 ),
+
+ /* IUP[0] */ PACK( 0, 0 ),
+ /* IUP[1] */ PACK( 0, 0 ),
+ /* SHP[0] */ PACK( 0, 0 ),
+ /* SHP[1] */ PACK( 0, 0 ),
+ /* SHC[0] */ PACK( 1, 0 ),
+ /* SHC[1] */ PACK( 1, 0 ),
+ /* SHZ[0] */ PACK( 1, 0 ),
+ /* SHZ[1] */ PACK( 1, 0 ),
+ /* SHPIX */ PACK( 1, 0 ),
+ /* IP */ PACK( 0, 0 ),
+ /* MSIRP[0] */ PACK( 2, 0 ),
+ /* MSIRP[1] */ PACK( 2, 0 ),
+ /* AlignRP */ PACK( 0, 0 ),
+ /* RTDG */ PACK( 0, 0 ),
+ /* MIAP[0] */ PACK( 2, 0 ),
+ /* MIAP[1] */ PACK( 2, 0 ),
+
+ /* NPushB */ PACK( 0, 0 ),
+ /* NPushW */ PACK( 0, 0 ),
+ /* WS */ PACK( 2, 0 ),
+ /* RS */ PACK( 1, 1 ),
+ /* WCvtP */ PACK( 2, 0 ),
+ /* RCvt */ PACK( 1, 1 ),
+ /* GC[0] */ PACK( 1, 1 ),
+ /* GC[1] */ PACK( 1, 1 ),
+ /* SCFS */ PACK( 2, 0 ),
+ /* MD[0] */ PACK( 2, 1 ),
+ /* MD[1] */ PACK( 2, 1 ),
+ /* MPPEM */ PACK( 0, 1 ),
+ /* MPS */ PACK( 0, 1 ),
+ /* FlipON */ PACK( 0, 0 ),
+ /* FlipOFF */ PACK( 0, 0 ),
+ /* DEBUG */ PACK( 1, 0 ),
+
+ /* LT */ PACK( 2, 1 ),
+ /* LTEQ */ PACK( 2, 1 ),
+ /* GT */ PACK( 2, 1 ),
+ /* GTEQ */ PACK( 2, 1 ),
+ /* EQ */ PACK( 2, 1 ),
+ /* NEQ */ PACK( 2, 1 ),
+ /* ODD */ PACK( 1, 1 ),
+ /* EVEN */ PACK( 1, 1 ),
+ /* IF */ PACK( 1, 0 ),
+ /* EIF */ PACK( 0, 0 ),
+ /* AND */ PACK( 2, 1 ),
+ /* OR */ PACK( 2, 1 ),
+ /* NOT */ PACK( 1, 1 ),
+ /* DeltaP1 */ PACK( 1, 0 ),
+ /* SDB */ PACK( 1, 0 ),
+ /* SDS */ PACK( 1, 0 ),
+
+ /* ADD */ PACK( 2, 1 ),
+ /* SUB */ PACK( 2, 1 ),
+ /* DIV */ PACK( 2, 1 ),
+ /* MUL */ PACK( 2, 1 ),
+ /* ABS */ PACK( 1, 1 ),
+ /* NEG */ PACK( 1, 1 ),
+ /* FLOOR */ PACK( 1, 1 ),
+ /* CEILING */ PACK( 1, 1 ),
+ /* ROUND[0] */ PACK( 1, 1 ),
+ /* ROUND[1] */ PACK( 1, 1 ),
+ /* ROUND[2] */ PACK( 1, 1 ),
+ /* ROUND[3] */ PACK( 1, 1 ),
+ /* NROUND[0] */ PACK( 1, 1 ),
+ /* NROUND[1] */ PACK( 1, 1 ),
+ /* NROUND[2] */ PACK( 1, 1 ),
+ /* NROUND[3] */ PACK( 1, 1 ),
+
+ /* WCvtF */ PACK( 2, 0 ),
+ /* DeltaP2 */ PACK( 1, 0 ),
+ /* DeltaP3 */ PACK( 1, 0 ),
+ /* DeltaCn[0] */ PACK( 1, 0 ),
+ /* DeltaCn[1] */ PACK( 1, 0 ),
+ /* DeltaCn[2] */ PACK( 1, 0 ),
+ /* SROUND */ PACK( 1, 0 ),
+ /* S45Round */ PACK( 1, 0 ),
+ /* JROT */ PACK( 2, 0 ),
+ /* JROF */ PACK( 2, 0 ),
+ /* ROFF */ PACK( 0, 0 ),
+ /* INS_$7B */ PACK( 0, 0 ),
+ /* RUTG */ PACK( 0, 0 ),
+ /* RDTG */ PACK( 0, 0 ),
+ /* SANGW */ PACK( 1, 0 ),
+ /* AA */ PACK( 1, 0 ),
+
+ /* FlipPT */ PACK( 0, 0 ),
+ /* FlipRgON */ PACK( 2, 0 ),
+ /* FlipRgOFF */ PACK( 2, 0 ),
+ /* INS_$83 */ PACK( 0, 0 ),
+ /* INS_$84 */ PACK( 0, 0 ),
+ /* ScanCTRL */ PACK( 1, 0 ),
+ /* SDVPTL[0] */ PACK( 2, 0 ),
+ /* SDVPTL[1] */ PACK( 2, 0 ),
+ /* GetINFO */ PACK( 1, 1 ),
+ /* IDEF */ PACK( 1, 0 ),
+ /* ROLL */ PACK( 3, 3 ),
+ /* MAX */ PACK( 2, 1 ),
+ /* MIN */ PACK( 2, 1 ),
+ /* ScanTYPE */ PACK( 1, 0 ),
+ /* InstCTRL */ PACK( 2, 0 ),
+ /* INS_$8F */ PACK( 0, 0 ),
+
+ /* INS_$90 */ PACK( 0, 0 ),
+ /* INS_$91 */ PACK( 0, 0 ),
+ /* INS_$92 */ PACK( 0, 0 ),
+ /* INS_$93 */ PACK( 0, 0 ),
+ /* INS_$94 */ PACK( 0, 0 ),
+ /* INS_$95 */ PACK( 0, 0 ),
+ /* INS_$96 */ PACK( 0, 0 ),
+ /* INS_$97 */ PACK( 0, 0 ),
+ /* INS_$98 */ PACK( 0, 0 ),
+ /* INS_$99 */ PACK( 0, 0 ),
+ /* INS_$9A */ PACK( 0, 0 ),
+ /* INS_$9B */ PACK( 0, 0 ),
+ /* INS_$9C */ PACK( 0, 0 ),
+ /* INS_$9D */ PACK( 0, 0 ),
+ /* INS_$9E */ PACK( 0, 0 ),
+ /* INS_$9F */ PACK( 0, 0 ),
+
+ /* INS_$A0 */ PACK( 0, 0 ),
+ /* INS_$A1 */ PACK( 0, 0 ),
+ /* INS_$A2 */ PACK( 0, 0 ),
+ /* INS_$A3 */ PACK( 0, 0 ),
+ /* INS_$A4 */ PACK( 0, 0 ),
+ /* INS_$A5 */ PACK( 0, 0 ),
+ /* INS_$A6 */ PACK( 0, 0 ),
+ /* INS_$A7 */ PACK( 0, 0 ),
+ /* INS_$A8 */ PACK( 0, 0 ),
+ /* INS_$A9 */ PACK( 0, 0 ),
+ /* INS_$AA */ PACK( 0, 0 ),
+ /* INS_$AB */ PACK( 0, 0 ),
+ /* INS_$AC */ PACK( 0, 0 ),
+ /* INS_$AD */ PACK( 0, 0 ),
+ /* INS_$AE */ PACK( 0, 0 ),
+ /* INS_$AF */ PACK( 0, 0 ),
+
+ /* PushB[0] */ PACK( 0, 1 ),
+ /* PushB[1] */ PACK( 0, 2 ),
+ /* PushB[2] */ PACK( 0, 3 ),
+ /* PushB[3] */ PACK( 0, 4 ),
+ /* PushB[4] */ PACK( 0, 5 ),
+ /* PushB[5] */ PACK( 0, 6 ),
+ /* PushB[6] */ PACK( 0, 7 ),
+ /* PushB[7] */ PACK( 0, 8 ),
+ /* PushW[0] */ PACK( 0, 1 ),
+ /* PushW[1] */ PACK( 0, 2 ),
+ /* PushW[2] */ PACK( 0, 3 ),
+ /* PushW[3] */ PACK( 0, 4 ),
+ /* PushW[4] */ PACK( 0, 5 ),
+ /* PushW[5] */ PACK( 0, 6 ),
+ /* PushW[6] */ PACK( 0, 7 ),
+ /* PushW[7] */ PACK( 0, 8 ),
+
+ /* MDRP[00] */ PACK( 1, 0 ),
+ /* MDRP[01] */ PACK( 1, 0 ),
+ /* MDRP[02] */ PACK( 1, 0 ),
+ /* MDRP[03] */ PACK( 1, 0 ),
+ /* MDRP[04] */ PACK( 1, 0 ),
+ /* MDRP[05] */ PACK( 1, 0 ),
+ /* MDRP[06] */ PACK( 1, 0 ),
+ /* MDRP[07] */ PACK( 1, 0 ),
+ /* MDRP[08] */ PACK( 1, 0 ),
+ /* MDRP[09] */ PACK( 1, 0 ),
+ /* MDRP[10] */ PACK( 1, 0 ),
+ /* MDRP[11] */ PACK( 1, 0 ),
+ /* MDRP[12] */ PACK( 1, 0 ),
+ /* MDRP[13] */ PACK( 1, 0 ),
+ /* MDRP[14] */ PACK( 1, 0 ),
+ /* MDRP[15] */ PACK( 1, 0 ),
+
+ /* MDRP[16] */ PACK( 1, 0 ),
+ /* MDRP[17] */ PACK( 1, 0 ),
+ /* MDRP[18] */ PACK( 1, 0 ),
+ /* MDRP[19] */ PACK( 1, 0 ),
+ /* MDRP[20] */ PACK( 1, 0 ),
+ /* MDRP[21] */ PACK( 1, 0 ),
+ /* MDRP[22] */ PACK( 1, 0 ),
+ /* MDRP[23] */ PACK( 1, 0 ),
+ /* MDRP[24] */ PACK( 1, 0 ),
+ /* MDRP[25] */ PACK( 1, 0 ),
+ /* MDRP[26] */ PACK( 1, 0 ),
+ /* MDRP[27] */ PACK( 1, 0 ),
+ /* MDRP[28] */ PACK( 1, 0 ),
+ /* MDRP[29] */ PACK( 1, 0 ),
+ /* MDRP[30] */ PACK( 1, 0 ),
+ /* MDRP[31] */ PACK( 1, 0 ),
+
+ /* MIRP[00] */ PACK( 2, 0 ),
+ /* MIRP[01] */ PACK( 2, 0 ),
+ /* MIRP[02] */ PACK( 2, 0 ),
+ /* MIRP[03] */ PACK( 2, 0 ),
+ /* MIRP[04] */ PACK( 2, 0 ),
+ /* MIRP[05] */ PACK( 2, 0 ),
+ /* MIRP[06] */ PACK( 2, 0 ),
+ /* MIRP[07] */ PACK( 2, 0 ),
+ /* MIRP[08] */ PACK( 2, 0 ),
+ /* MIRP[09] */ PACK( 2, 0 ),
+ /* MIRP[10] */ PACK( 2, 0 ),
+ /* MIRP[11] */ PACK( 2, 0 ),
+ /* MIRP[12] */ PACK( 2, 0 ),
+ /* MIRP[13] */ PACK( 2, 0 ),
+ /* MIRP[14] */ PACK( 2, 0 ),
+ /* MIRP[15] */ PACK( 2, 0 ),
+
+ /* MIRP[16] */ PACK( 2, 0 ),
+ /* MIRP[17] */ PACK( 2, 0 ),
+ /* MIRP[18] */ PACK( 2, 0 ),
+ /* MIRP[19] */ PACK( 2, 0 ),
+ /* MIRP[20] */ PACK( 2, 0 ),
+ /* MIRP[21] */ PACK( 2, 0 ),
+ /* MIRP[22] */ PACK( 2, 0 ),
+ /* MIRP[23] */ PACK( 2, 0 ),
+ /* MIRP[24] */ PACK( 2, 0 ),
+ /* MIRP[25] */ PACK( 2, 0 ),
+ /* MIRP[26] */ PACK( 2, 0 ),
+ /* MIRP[27] */ PACK( 2, 0 ),
+ /* MIRP[28] */ PACK( 2, 0 ),
+ /* MIRP[29] */ PACK( 2, 0 ),
+ /* MIRP[30] */ PACK( 2, 0 ),
+ /* MIRP[31] */ PACK( 2, 0 )
+ };
+
+
+ static const FT_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?]"
+ };
+
+
+/*********************************************************************
+ *
+ * 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); */
+ termio.c_lflag &= ~(ICANON+ECHO+ECHOE+ECHOK+ECHONL);
+
+#ifndef HAVE_TCSETATTR
+ ioctl( 0, TCSETS, &termio );
+#else
+ tcsetattr( 0, TCSANOW, &termio );
+#endif
+ }
+
+ static
+ void Reset_Keyboard( void )
+ {
+#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( void )
+ {
+ }
+
+#endif
+
+
+ void Panic( const char* message )
+ {
+ fprintf( stderr, "%s\n error code = 0x%04x\n", message, error );
+ Reset_Keyboard();
+ exit(1);
+ }
+
+
+/******************************************************************
+ *
+ * Function : Calc_Length
+ *
+ * Description : Computes the length in bytes of current opcode.
+ *
+ *****************************************************************/
+
+#define CUR (*exc)
+
+
+ static void Calc_Length( TT_ExecContext exc )
+ {
+ CUR.opcode = CUR.code[CUR.IP];
+
+ switch ( CUR.opcode )
+ {
+ case 0x40:
+ if ( CUR.IP + 1 >= CUR.codeSize )
+ Panic( "code range overflow !!" );
+
+ CUR.length = CUR.code[CUR.IP + 1] + 2;
+ break;
+
+ case 0x41:
+ if ( CUR.IP + 1 >= CUR.codeSize )
+ Panic( "code range overflow !!" );
+
+ 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 )
+ Panic( "code range overflow !!" );
+ }
+
+
+ /* Disassemble the current line */
+ /* */
+ const FT_String* Cur_U_Line( TT_ExecContext exec )
+ {
+ FT_String s[32];
+ FT_Int op, i, n;
+
+ op = exec->code[ exec->IP ];
+
+ sprintf( tempStr, "%04lx: %02hx %s", exec->IP, op, 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 (FT_String*)tempStr;
+ }
+
+
+ static
+ TT_Error RunIns( TT_ExecContext exc )
+ {
+ FT_Int A, diff, key;
+ FT_Long next_IP;
+ FT_Char ch, oldch, *temp;
+
+ TT_Error error = 0;
+
+ TT_GlyphZone save;
+ TT_GlyphZone pts;
+
+ const FT_String* round_str[8] =
+ {
+ "to half-grid",
+ "to grid",
+ "to double grid",
+ "down to grid",
+ "up to grid",
+ "off",
+ "super",
+ "super 45"
+ };
+
+ /* only debug the requested code range */
+ if (exc->curRange != (TT_Int)debug_coderange)
+ return TT_RunIns(exc);
+
+ exc->pts.n_points = exc->zp0.n_points;
+ exc->pts.n_contours = exc->zp0.n_contours;
+
+ pts = exc->pts;
+
+
+ save.n_points = pts.n_points;
+ save.n_contours = pts.n_contours;
+
+ save.org = (TT_Vector*)malloc( 2 * sizeof( TT_F26Dot6 ) *
+ save.n_points );
+ save.cur = (TT_Vector*)malloc( 2 * sizeof( TT_F26Dot6 ) *
+ save.n_points );
+ save.touch = (TT_Byte*)malloc( save.n_points );
+
+ exc->instruction_trap = 1;
+
+ do
+ {
+ if ( CUR.IP < CUR.codeSize )
+ {
+ Calc_Length( exc );
+
+ 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. */
+
+ /* 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';
+ printf( "%s", temp );
+ }
+
+ /* First, check for empty stack and overflow */
+ if ( CUR.args < 0 )
+ {
+ printf( "ERROR : Too Few Arguments\n" );
+ 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 'case' */
+
+ if ( CUR.new_top > CUR.stackSize )
+ {
+ printf( "ERROR : Stack overflow\n" );
+ CUR.error = TT_Err_Stack_Overflow;
+ goto LErrorLabel_;
+ }
+ }
+ else
+ printf( "End of program reached.\n" );
+
+ key = 0;
+ do
+ {
+ /* read keyboard */
+
+ ch = getch();
+
+ switch ( ch )
+ {
+ /* Help - show keybindings */
+ case '?':
+ printf( "TTDebug Help\n\n" );
+ printf( "? Show this page\n" );
+ printf( "q Quit debugger\n" );
+ printf( "n Skip to next instruction\n" );
+ printf( "s Step into\n" );
+ printf( "v Show vector info\n" );
+ printf( "g Show graphics state\n" );
+ printf( "p Show points zone\n\n" );
+ break;
+
+ /* Show vectors */
+ case 'v':
+ printf( "freedom (%04hx,%04hx)\n", exc->GS.freeVector.x,
+ exc->GS.freeVector.y );
+ printf( "projection (%04hx,%04hx)\n", exc->GS.projVector.x,
+ exc->GS.projVector.y );
+ printf( "dual (%04hx,%04hx)\n\n", exc->GS.dualVector.x,
+ exc->GS.dualVector.y );
+ break;
+
+ /* Show graphics state */
+ case 'g':
+ printf( "rounding %s\n", round_str[exc->GS.round_state] );
+ printf( "min dist %04lx\n", exc->GS.minimum_distance );
+ printf( "cvt_cutin %04lx\n", exc->GS.control_value_cutin );
+ break;
+
+ /* Show points table */
+ case 'p':
+ for ( A = 0; A < exc->pts.n_points; A++ )
+ {
+ printf( "%02hx ", A );
+ printf( "%08lx,%08lx - ", pts.org[A].x, pts.org[A].y );
+ printf( "%08lx,%08lx\n", pts.cur[A].x, pts.cur[A].y );
+ }
+ printf(( "\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 = TT_RunIns( exc ) ) )
+ goto LErrorLabel_;
+ }
+ }
+ oldch = ch;
+ break;
+
+ /* Step into */
+ case 's':
+ if ( exc->IP < exc->codeSize )
+
+ Step_into:
+ if ( ( error = TT_RunIns( exc ) ) )
+ goto LErrorLabel_;
+ oldch = ch;
+ break;
+
+ default:
+ printf( "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 )
+ {
+ printf( "%02hx ", A );
+
+ if ( diff & 16 ) temp = "(%01hx)"; else temp = " %01hx ";
+ printf( temp, save.touch[A] & 7 );
+
+ if ( diff & 1 ) temp = "(%08lx)"; else temp = " %08lx ";
+ printf( temp, save.org[A].x );
+
+ if ( diff & 2 ) temp = "(%08lx)"; else temp = " %08lx ";
+ printf( temp, save.org[A].y );
+
+ if ( diff & 4 ) temp = "(%08lx)"; else temp = " %08lx ";
+ printf( temp, save.cur[A].x );
+
+ if ( diff & 8 ) temp = "(%08lx)"; else temp = " %08lx ";
+ printf( temp, save.cur[A].y );
+
+ printf( "\n" );
+
+ printf( "%02hx ", A );
+
+ if ( diff & 16 ) temp = "[%01hx]"; else temp = " %01hx ";
+ printf( temp, pts.touch[A] & 7 );
+
+ if ( diff & 1 ) temp = "[%08lx]"; else temp = " %08lx ";
+ printf( temp, pts.org[A].x );
+
+ if ( diff & 2 ) temp = "[%08lx]"; else temp = " %08lx ";
+ printf( temp, pts.org[A].y );
+
+ if ( diff & 4 ) temp = "[%08lx]"; else temp = " %08lx ";
+ printf( temp, pts.cur[A].x );
+
+ if ( diff & 8 ) temp = "[%08lx]"; else temp = " %08lx ";
+ printf( temp, pts.cur[A].y );
+
+ printf( "\n\n" );
+ }
+ }
+ } while ( TRUE );
+
+ LErrorLabel_:
+
+ if (error)
+ Panic( "error during execution" );
+ return error;
+ }
+
+
+
+
+
+ static
+ void Usage()
+ {
+ fprintf( stderr, "ttdebug - a simply TrueType font debugger\n" );
+ fprintf( stderr, "(c) The FreeType project - www.freetype.org\n" );
+ fprintf( stderr, "-------------------------------------------\n\n" );
+
+ fprintf( stderr, "usage : ttdebug [options] glyph size fontfile[.ttf]\n\n" );
+
+ fprintf( stderr, " glyph - glyph index within the font file. Can be negative to query \n" );
+ fprintf( stderr, " the debugging of the font 'cvt' program\n\n" );
+
+ fprintf( stderr, " size - size of glyph in pixels\n\n" );
+
+ fprintf( stderr, " fontfile - a valid TrueType file.\n\n" );
+
+ fprintf( stderr, " valid options are:\n\n" );
+ fprintf( stderr, " -d : Dump mode. Shows the glyph program and exit immediately\n" );
+ fprintf( stderr, " -n : Non-interactive mode. Dumps the execution trace and exit\n" );
+
+ exit(1);
+ }
+
+
+int dump_mode;
+int non_interactive_mode;
+char* file_name;
+int glyph_index;
+int glyph_size;
+
+ int main( int argc, char** argv )
+ {
+ char valid;
+
+ /* Check number of arguments */
+ if ( argc < 4 ) Usage();
+
+ /* Check options */
+ dump_mode = 0;
+ non_interactive_mode = 0;
+
+ argv++;
+ while (argv[0][0] == '-')
+ {
+ valid = 0;
+ switch (argv[0][1])
+ {
+ case 'd':
+ dump_mode = 1;
+ valid = 1;
+ break;
+
+ case 'n':
+ non_interactive_mode = 1;
+ valid = 1;
+ break;
+
+ default:
+ ;
+ }
+
+ if (valid)
+ {
+ argv++;
+ argc--;
+ if (argc < 4) Usage();
+ }
+ else
+ break;
+ }
+
+ /* Get Glyph index */
+ if ( sscanf( argv[0], "%d", &glyph_index ) != 1 )
+ {
+ printf( "invalid glyph index = %s\n", argv[1] );
+ Usage();
+ }
+
+ /* Get Glyph size */
+ if ( sscanf( argv[1], "%d", &glyph_size ) != 1 )
+ {
+ printf( "invalid glyph size = %s\n", argv[1] );
+ Usage();
+ }
+
+ /* Get file name */
+ file_name = argv[2];
+
+ Init_Keyboard();
+
+ /* Init library, read face object, get driver, create size */
+ error = FT_Init_FreeType( &library );
+ if (error) Panic( "could not initialise FreeType library" );
+
+ memory = library->memory;
+
+ FT_Set_Debug_Hook( library,
+ FT_DEBUG_HOOK_TRUETYPE,
+ (FT_DebugHook_Func)RunIns );
+
+ error = FT_New_Face( library, file_name, 0, (FT_Face*)&face );
+ if (error) Panic( "could not open font resource" );
+
+ /* find driver and check format */
+ driver = (TT_Driver)face->root.driver;
+ if (driver->root.interface.init_face != tt_driver_interface.init_face)
+ {
+ error = FT_Err_Invalid_File_Format;
+ Panic( "This is not a TrueType font" );
+ }
+
+ size = (TT_Size)face->root.size;
+
+ if (glyph_index < 0)
+ {
+ exec = TT_New_Context( face );
+ size->debug = 1;
+ size->context = exec;
+
+ error = FT_Set_Char_Size( (FT_Face)face, glyph_size << 6, glyph_size << 6, 72, 72 );
+ if (error) Panic( "could not set character sizes" );
+ }
+ else
+ {
+ error = FT_Set_Char_Size( (FT_Face)face, glyph_size << 6, glyph_size << 6, 72, 72 );
+ if (error) Panic( "could not set character sizes" );
+
+ glyph = (TT_GlyphSlot)face->root.glyph;
+
+ /* Now load glyph */
+ error = FT_Load_Glyph( (FT_Face)face, glyph_index, FT_LOAD_DEFAULT );
+ if (error) Panic( "could not load glyph" );
+ }
+
+ Reset_Keyboard();
+ return 0;
+ }
--- /dev/null
+++ b/docs/BUILD
@@ -1,0 +1,375 @@
+ The FreeType Build System Internals
+ -----------------------------------
+
+Introduction:
+
+ This document describes the details of the FreeType build system. The
+ build system is a set of Makefiles and other configuration files used
+ to select, compile and link together the various FreeType components
+ according to the current platform, compiler and requested feature set.
+
+ This document also explains how to use the build system to develop
+ third-party font drivers or extensions to the engine, without altering
+ the general FreeType hierarchy;
+
+
+I. Portability issues :
+
+ Given that the design of FreeType 2 is much more modular and flexible than
+ in previous versions, its build system is entirely based on GNU Make. There
+ are several reasons for this :
+
+ - It is by far the most available make tool on the planet, and
+ has probably been ported to every development environment known
+ to homo programmaticus.
+
+ - It provides useful features (like conditional defines, pattern
+ and wildcard matching) which are essential when implementing a
+ flexible configuration system, as described below
+
+ Note that you do not need to have a unix-like shell (like "sh" or "csh")
+ on your system in order to build FreeType.
+
+
+
+
+II. The library design :
+
+ FreeType is made of several components, each with a specific role :
+
+ - THE BASE LAYER:
+ It is used to implement generic font services as well as provide
+ the high-level API used by client applications.
+
+ - ONE OR MORE FONT DRIVERS:
+ Each driver is a small component used to read and process a given
+ font format. Note that with FreeType 2, it is possible to add,
+ remove or upgrade a font driver at *runtime*.
+
+ - ONE OR MORE RASTERS:
+ A raster is a module used to render a vectorial glyph outline into
+ a bitmap or an anti-aliased pixmap. They differ in their output
+ quality, speed and memory usage.
+
+ - A LOW-LEVEL MODULE, CALLED "FTSYSTEM":
+ It is used to implement memory management and file i/o. Uses the
+ Ansi C Library by default, though some system-specific replacements
+ are provided in order to improve performance.
+
+ - AN "INIT" LAYER:
+ A tiny module used to implement the library initialisation routine,
+ i.e. FT_Init_FreeType. It is in charge of registering the font drivers
+ and rasters selected at build time.
+
+ - AN "OLD API" LAYER:
+ A simple layer used to link legacy applications using the FreeType
+ 1.x API. Note that it is binary backwards compatible, which means that
+ applications do not need to be recompiled, only re-linked to this
+ layer.
+
+ For more details, please read the "FreeType Internals" Document.
+
+
+ The FreeType build system is in charge of the following tasks :
+
+ - detect (or select) the current platform in order to select the
+ best version of the "ftsystem" module. By default, it will use
+ the pure-ANSI version.
+
+ - determine which font drivers, and which rasters, should be
+ statically linked to the library at build time. These will always
+ be available after the library has been initialised through a call
+ to FT_Init_FreeType.
+
+ - eventually compile other font drivers or rasters in order to later
+ link them dynamically to the library at runtime, through
+ FT_Add_Driver / FT_Upgrade_Driver..
+
+ - compile the "init" layer, putting code in the implementation of
+ the FT_Init_FreeType function to register each selected font driver
+ or raster to the library.
+
+
+
+III. General overview :
+
+ The FreeType build system uses a hierarchy of included sub-Makefiles
+ to compile and link the library.
+
+ Each included sub-Makefile is called a "rules" file, and has a very
+ specific purpose. The suffix for rules files is ".mk" as in :
+
+ detect.mk
+ config.mk
+ rules.mk
+ etc...
+
+
+ Here's a simple diagram of the build hierarchy, which is then explained
+ with details :
+
+
+
+ Makefile ( ./Makefile )
+
+ |
+ |
+ v
+
+ Config Rules ( ./config/<system>/config.mk )
+
+ |
+ |
+ v
+
+ Library Rules ( ./config/freetype.mk )
+
+ | | |
+ | | |
+ v v v
+
+ Component(s) Rules ( ./src/<component>/rules.mk )
+
+
+
+ 1. The "root" Makefile :
+
+ This file must be invoked from the "freetype" directory with GNU Make.
+
+ a. Host platform auto-detection:
+
+ When run for the first time, this Makefile will try to auto-detect
+ the current host platform, by running the rules file named
+ `./config/detect.mk'. If the host system cannot be detected,
+ it will default to the `ansi' system.
+
+ It will then copy the rules file `./config/<system>/config.mk' to
+ the current directory and display the results of the auto-detection.
+
+ You can, at any time, re-run the auto-detection routine by invoking
+ the root Makefile with the "setup" target, as in :
+
+ % make setup
+
+ Note also that it is possible to use a second argument to indicate
+ a specific compiler. For example, here are the lignes to be used
+ in order to configure a build with LCC, Visual C++ and Visual Age
+ on a Win32 machine
+
+ > gmake setup lcc
+ > gmake setup visualc
+ > gmake setup visualage
+
+ The list of compilers is platform-specific and should be contained
+ in `config/<system>/detect.mk'.
+
+ If the detection results do not correspond to your platform or
+ settings, refer to chapter VI which describes the auto-detection
+ system in great details..
+
+
+ b. Building the library:
+
+ Once the host platform has been detected, you can run `make' once
+ again. The root Makefile will then detect the configuration rules
+ file in the current directory then include it.
+
+ Note also that the root Makefile is responsible for defining, if it
+ is not already part of the current environment, the variable TOP, which
+ designates the top of the FreeType source hierarchy.
+
+ When undefined, it defaults to `.'
+
+
+ 2. The Configuration file :
+
+ The configuration rules file is used to set many important variables
+ before including/calling the library rules file (see below).
+
+ These variables are mainly used to describe the host environment
+ and compilers. Indeed, this file defines, among others, the following:
+
+ SEP The directory path separator. This can be `/',`\' or ':'
+ depending on the current platform. Note that all pathnames
+ are composed with $(SEP) in all rules file (except in
+ `include' statements which work well with '/' on all
+ platforms)
+
+ CC The compiler to use
+
+ CFLAGS The compiler flags used to compile a given source to an
+ object file. Usually contains flags for optimisation,
+ debugging and/or ansi-compliance
+
+ I The flag to be used to indicate an additionnal include path
+ to the compiler. This defaults to `-I' for an "ansi" system,
+ but can be different for others (e.g. `/i=',`-J ', etc..)
+
+ D The flag to be used to indicate a macro definition to the
+ compiler. This defaults to `-D' for an ANSI system.
+
+ T The flag to be used to indicate a target object file to the
+ compiler. This defaults to `-o ' for an ANSI system. Note the
+ space after the `o'.
+
+ O The object file extension to be used on the current platform.
+ Defaults to `o' for an ANSI system, but can be `obj', `coff'
+ or others.. There is no dot in the extension !
+
+ A The library file extension to be used on the current platform.
+ Defaults to 'a' for an ANSI system, but can be `lib', `so',
+ `dll' or others.. There is no dot in the extension !
+
+
+ BUILD The directory where the build system should grab the
+ configuration header file `ftconfig.h' as well as the
+ system-specific implementation of `ftsystem'.
+
+ OBJ The directory where all object files will be placed
+
+
+ 3. The Library Rules files :
+
+ Once the variables defined in the configuration rules file, the
+ library rules file is included. This one contains all rules required
+ to build the library objects into OBJ
+
+ Its structure works as follows:
+
+ - provide rules to compile the low-level `ftsystem' module
+
+ - include the rules files from each font driver or component
+
+ - include the rules file for the "old api" layer
+
+ - provide rules to compile the initialisation layer
+
+ - provide additional targets like `clean', ..
+
+
+ Note that linking all objects files together into a library is not
+ performed in this file, though it might seem reasonable at first
+ glance. The reason for this is that not all linkers have a simple
+ syntax of the form:
+
+ librarian archive_file object1 object2 ....
+
+ hence, linking is performed through rules provided in the configuration
+ rules file, using the phony `library' target, which has been defined for
+ this very specific purpose.
+
+
+ 4. The Components Rules files :
+
+ Each font driver has its own rules file, called `rules.mk' located
+ in its own directory. The library rules file includes these component
+ rules for each font driver.
+
+ These rules must perform the following:
+
+ - provide rules to compile the component, either into a single `large'
+ object, or into multiple small ones
+
+ - for font drivers and rasters, update some variables, that are
+ initially defined in the library rules file, which indicate wether
+ the component must be registered in the library initialisation code
+
+
+ a. Component Compile Modes :
+
+ There are two ways to compile a given component :
+
+ i. Single-object compilation:
+
+ In this mode, the component is compiled into a single object
+ file. This is performed easily by defining a single C file whose
+ sole purpose is to include all other component sources. For
+ example, the truetype driver is compiled as a single object
+ named `truetype.o'.
+
+
+ ii. Multiple objects compilation:
+
+ In this mode, all source files for a single component are compiled
+ individually into an object file.
+
+ Due to the way the FreeType source code is written, single mode
+ has the following advantages over multiple mode:
+
+ - with many compilers, the resulting object code is smaller than
+ the concatenation of all individual objects from multiple mode.
+ this, because all functions internal to the component as a whole
+ are declared static, allowing more optimisation. It often also
+ compiles much faster.
+
+
+ - most importantly, the single object only contains the external
+ symbols it needs to be linked to the base layer (all extern that
+ are due to inter-source calls within the component are removed).
+ this can reduce tremendously the size of dynamic libraries on
+ some platforms
+
+ Multiple mode is useful however to check some dependencies problems
+ that might not appear when compiling in single mode, so it has been
+ kept as a possibility.
+
+
+ b. Driver initialisation code :
+
+ The source file `./src/base/ftinit.c' contains the implementation
+ of the FT_Init_FreeType function which must, among other things,
+ register all font drivers that are statically linked to the library.
+
+ Controlling which drivers are registered at initialisation time is
+ performed by exploiting the state of the C-preprocessor in order to
+ build a linked list (a "chain") of driver interfaces.
+
+ More precisely, each font driver interface file (like `ttdriver.h'
+ or `t1driver.h') has some special lines that look like this :
+
+
+ #ifdef FTINIT_DRIVER_CHAIN
+
+ static
+ const FT_DriverChain ftinit_<FORMAT>_driver_chain =
+ {
+ FT_INIT_LAST_DRIVER_CHAIN,
+ &<FORMAT>_driver_interface
+ };
+
+ #undef FT_INIT_LAST_DRIVER_CHAIN
+ #define FT_INIT_LAST_DRIVER_CHAIN &ftinit_<FORMAT>_driver_chain
+
+ #endif
+
+ As one can see, this code is strictly reserved for `ftinit.c' which
+ defines FTINIT_DRIVER_CHAIN before including all font driver header
+ files.
+
+ When the C-processor parses these headers, it builds a linked list of
+ FT_DriverChain element. For exemple, the sequence :
+
+ #define FTINIT_DRIVER_CHAIN
+ #include <ttdriver.h>
+ #include <t1driver.h>
+
+ Will really generate something like:
+
+ static
+ *----> const FT_DriverChain ftinit_tt_driver_chain =
+ | {
+ | 0,
+ | &tt_driver_interface
+ | };
+ |
+ | static
+ | const FT_DriverChain ftinit_t1_driver_chain =
+ | {
+ *------ &ftinit_tt_driver_chain,
+ &t1_driver_interface
+ };
+
+ with the FT_INIT_LAST_DRIVER_CHAIN set to "&ftinit_t1_driver_chain"
+
+ Hence, the last included driver will be registered first in the library
+
--- /dev/null
+++ b/docs/DESIGN
@@ -1,0 +1,216 @@
+The Design of FreeType 2.0
+==========================
+
+Introduction:
+
+ This short document presents the design of version 2 of the FreeType
+ library. It is a must read for anyone willing to port, debug or hack
+ the FreeType sources.
+
+
+I. Goals :
+
+ FreeType 2 was designed to provide a unified and universal API to
+ manage (i.e. read) the content of font files.
+
+ Its main features are :
+
+
+ - A FORMAT-INDEPENDENT HIGH-LEVEL API
+
+ Used to open, read and manage font files.
+
+
+ - THE USE OF PLUGGABLE "FONT DRIVERS"
+
+ Each font driver is used to support a given font format. For
+ example, the default build of FreeType 2 comes with drivers for the
+ TrueType and Type 1 font formats.
+
+ Font drivers can also be added, removed or upgraded at *runtime*,
+ in order to support more font formats, or improve the current ones.
+
+ Each font driver also provides its own "public interface" to client
+ applications who would like to use format-specific features.
+
+
+ - THE USE OF PLUGGABLE "RASTERS"
+
+ A raster is a tiny module used to render a glyph image
+ into a bitmap or anti-aliased pixmap. Rasters differ in their
+ output quality (especially with regards to anti-aliasing), speed
+ and memory usage.
+
+ An application can also provide its own raster if it needs to.
+
+
+ - HIGH PORTABILITY AND PERFORMANCE
+
+ The FreeType source code is written in industry-standard ANSI C.
+
+ Moreover, it abstracts memory management and i/o operations within
+ a single module, called "ftsystem". The FreeType build system tries
+ to auto-detect the host platform in order to select its most
+ efficient implementation. It defaults otherwise to using the
+ standard ANSI C Library.
+
+ Note that, independently of the host platform and build, an
+ application is able to provide its own memory and i/o routines.
+
+ This make FreeType suitable for use in any kind of environment,
+ from embedded to distributed systems.
+
+
+II. Components Layout :
+
+ FreeType 2 is made of distinct components which relate directly to the
+ design described previously:
+
+
+ 1. THE BASE LAYER:
+
+ The base layer implements the high-level API, as well as provide
+ generic font services that can be used by each font driver.
+
+
+ 2. THE FONT DRIVERS:
+
+ Each font driver can be registered in the base layer by providing
+ an "interface", which really is a table of function pointers.
+
+ At build time, the set of default font drivers is selected. These
+ drivers are then compiled and statically linked to the library.
+
+ They will then be available after the library initialisation.
+
+
+ 3. THE RASTERS:
+
+ FreeType 2 provides the ability to hook various raster modules into
+ its base layer. This provides several advantages :
+
+ - different systems mean different requirements, hence the need for
+ flexibility.
+
+ - for now, FreeType 2 only supports glyph images stored in the
+ following formats :
+
+ * bitmaps
+ * gray-level pixmaps
+ * monochrome vectorial outlines (using bezier control points)
+
+ should a new "technology" come for glyph images, it is possible
+ to write a new raster for it, without altering the rest of the
+ engine. Some examples could be :
+
+ * multi-colored vectorial outlines
+ * on-the-fly rendering of TeX's MetaFonts !!
+
+
+
+ 4. THE SYSTEM MODULE "FTSYSTEM":
+
+ The system module is used to implement basic memory and i/o management
+ services. By default, it uses the ANSI C library, but some replacements
+ are also provided (and automatically selected by the build system) when
+ available.
+
+ As a simple example, the unix build uses memory-mapped files to read
+ font files, instead of the slow ANSI "fopen/fseek/fread". This results
+ in tremendous performance enhancements.
+
+ Note that, even if the build system chooses an implementation for
+ "ftsystem" at compile time, an application is still able to provide
+ its own memory or i/o routines to the library at runtime.
+
+
+
+
+ 5. THE "INIT" LAYER:
+
+ A tiny module used to implement the function FT_Init_FreeType.
+
+ As its name suggests, it is responsible for initialising the library,
+ which really means the following :
+
+ - bind the implementation of "ftsystem" that best matches the
+ host platform to the library. This choice can be overriden
+ later by client applications however.
+
+ - register the set of default font drivers within the base layer.
+ these drivers are statically linked to the library. Other drivers
+ can be added at runtime later through FT_Add_Driver though..
+
+ - register the set of default rasters. Client applications are
+ able to add their own rasters at runtime though.
+
+ The details regarding these operations is given in the document
+ named "FreeType Build Internals"
+
+
+
+III. Objects Layout :
+
+ Even though it is written in ANSI C, the desing of FreeType 2 is object
+ oriented, as it's the best way to implement the flexible font format
+ support that we wanted.
+
+ Indeed, the base layer defines a set of base classes that can be derived
+ by each font driver in order to support a given format. The base layer
+ also includes many book-keeping routines that need not be included in the
+ drivers.
+
+ The base classes are the following:
+
+
+ 1. FACE OBJECTS:
+
+ As in FreeType 1.x, a face object models the content of a given font
+ that isn't dependent on a given size, transformation or glyph index.
+
+ This includes, for example, the font name, font style(s), available
+ charmaps and encodings, and all other kinds of data and tables that
+ help describe the font as a whole.
+
+
+ 2. SIZE OBJECTS: (previously known as INSTANCE OBJECTS in 1.x)
+
+ A face object can have one or more associated size objects. A Size
+ object is used to stored the font data that is dependent on the current
+ character size or transform used to load glyphs.
+
+ Typical data in a size object include scaled metrics, factors, and
+ various kind of control data related to grid-fitting. The size object
+ is changed each time the character size is modified.
+
+
+ 3. GLYPH SLOT OBJECTS:
+
+ Each face object has one "glyph slot", which is a simple container
+ where individual glyph images can be loaded and processed.
+
+ The glyph image can be stored in the following formats in the glyph
+ slot :
+
+ - monochrome bitmaps
+ - gray-level pixmaps
+ - vectorial glyph outlines (defined with bezier control points)
+
+ Note that a module, called the "raster" is provided to convert vector
+ outlines into either monochrome or anti-aliased bitmaps. The outline
+ is also directly accessible and can be walked or processed freely by
+ client applications.
+
+ more glyph images formats can be defined, but they will require
+ a specific raster module if one wants to display them on a typical
+ display surface.
+
+ 4. CHARMAP OBJECTS:
+
+ A charmap is used to convert character codes, for a given encoding,
+ into glyph indices. A given face might contain several charmaps, for
+ example, most TrueType fonts contain both the "Windows Unicode" and
+ "
+ it is not rare to see TrueType fonts with both the
+ "Windows Unicode" and "Apple Roman" charmap
+
--- /dev/null
+++ b/docs/essai
@@ -1,0 +1,173 @@
+Un apercu du layout des fichiers sources de FreeType 2:
+
+ docs/ - documentation
+ html/ - documentation au format html
+
+ txt/ - documentation au format texte
+
+
+ include/ - les headers publiques de la librairie, ce sont ceux
+ qui sont installes avec le paquet freetype-devel.rpm
+
+ config/ - le repertoire de configuration.
+ ansi/
+ ft_conf.h - fichier de configuration
+ ftsys.c - fichier implementation bas-niveau
+
+ unix/
+
+ os2/
+
+ dos/
+
+ amiga/
+
+ debug/
+
+
+ src/ - sources de la librairie
+ base/ - couche de base (services generiques + API)
+
+ truetype/ - pilote truetype
+ options/ - options du pilote truetype
+ extend/ - extensions du pilote truetype
+
+ type1/ - pilote type 1
+ options/ - options du pilote type 1
+ extend/ - extensions du pilote type 1
+
+ type2/ - pilote type 2
+
+ speedo/ - pilote speedo
+
+ shared/ - sources partagees par plusieurs pilotes
+
+
+ tests/ - programmes de test
+ data/ - donnees des tests = fichiers de police => copies dans bin
+ test1/ - source du test numero 1
+ test2/ - source du test numero 2
+ test3/ - ...
+ ...
+
+ obj/ - emplacement des fichiers objets compiles + librairie ?
+ bin/ - emplacement des executables (demos+tests)
+
+ demos/ - programmes de demonstration
+ graph/ - sous-systeme graphique des programmes de demo
+
+
+ contrib/ - contributions de toutes sortes..
+
+
+=============================================================================
+Quelques autres idees au hasard :
+
+- virer le controle des threads, on s'en tape magistralement
+
+- separer l'allocation memoire de l'acces disque (+flexible)
+
+- l'api de base doit permettre "d'ouvrir" un fichier de police se trouvant
+ deja en memoire..
+
+- expliquer les differents types de dictionnaires :
+
+ char_code -> glyph_index charmap (truetype)
+ char_code -> glyph_name encoding (type 1)
+ glyph_index -> glyph_name repertoire (...)
+
+- plusieurs "raster" possibles (le raster par defaut peut etre d�termin� � la compilation,
+ sinon l'ajout se fait simplement en passant un pointeur d'interface..)
+
+
+- l'api de base doit etre simplifiee. La plupart des developpeurs ne veulent
+ pas savoir ce qu'est une "size", un "glyph_slot", etc.., on conseille donc
+ d'en creer une par defaut, lors de l'appel de :
+
+ ------------------- initialisation et lecture des polices ------------
+
+ FT_Init_FreeType( &library );
+
+ FT_Set_Memory_Manager( library, &mem_manager_rec );
+
+ FT_Set_IO_Manager( library, &io_manager_rec );
+
+
+ FT_New_Face( library, file_pathname, face_index, &face );
+
+ FT_New_Memory_Face( library, first_byte, length, face_index, &face );
+
+ ou encore:
+
+ FT_New_Face( library, &new_face_rec, &face );
+
+ avec new_face_rec ::
+
+ face_index
+
+ pathname
+
+ memory_address
+ bytes_size
+
+
+ FT_Flush_Face( face ); // ferme le stream correspondant..
+
+
+ ------------------------------------------ changement de taille ------
+
+ FT_Set_Size( face, &face_size_rec );
+
+ face_size_rec ::
+ char_height
+ char_width
+ horz_resolution
+ vert_resolution
+
+ FT_Set_Pixel_Sizes( face, 64, 64 );
+
+
+ ----------------------------------------- selection de la charmap ----
+
+ FT_Select_Charmap( face, ft_charmap_unicode );
+
+ FT_Select_Charmap_Index( face, index );
+
+ FT_List_Charmaps( face, buffer, max, first );
+
+ face->charmap => pointe vers la charmap actuelle..
+
+
+ -------------------------------------- chargement des glyphes --------
+
+ FT_Load_Glyph( face, glyph_index );
+
+ FT_Load_Char( face, char_code );
+
+ FT_Transform_Glyph( face->glyph, &trans );
+
+
+ ---------------------------------------------- rendu final -----------
+
+ FT_Get_Outline_Bitmap( library, face->glyph, &bit );
+
+ FT_Set_Raster( library, "default" );
+
+ FT_Set_Raster_Mode( library, major_mode, minor_mode );
+
+
+
+
+=======================================================================================
+
+Syst�me de configuration automatique
+
+ freetype2/
+ Makefile
+ config/
+ ansi/
+ config.mk
+
+ make setup => autodetection du syst�me + copie de fichier include ???
+
+ make
binary files /dev/null b/docs/glyph_conventions/bbox1.gif differ
binary files /dev/null b/docs/glyph_conventions/bbox2.gif differ
binary files /dev/null b/docs/glyph_conventions/body_comparison.gif differ
binary files /dev/null b/docs/glyph_conventions/bravo_kerned.gif differ
binary files /dev/null b/docs/glyph_conventions/bravo_unkerned.gif differ
binary files /dev/null b/docs/glyph_conventions/build_diagram.gif differ
binary files /dev/null b/docs/glyph_conventions/clipping.gif differ
binary files /dev/null b/docs/glyph_conventions/down_flow.gif differ
--- /dev/null
+++ b/docs/glyph_conventions/glyph_conventions.html
@@ -1,0 +1,1626 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="blob">
+ <meta name="GENERATOR" content="Mozilla/4.5 [fr] (Win98; I) [Netscape]">
+ <title>FreeType Glyph Conventions</title>
+</head>
+<body>
+
+<body text="#000000"
+ bgcolor="#FFFFFF"
+ link="#0000EF"
+ vlink="#51188E"
+ alink="#FF0000">
+
+<center>
+<h1>
+FreeType Glyph Conventions</h1></center>
+
+<center>
+<h2>
+version 2.0</h2></center>
+
+<center>
+<h3>
+Copyright 1998-1999David Turner (<a href="mailto:[email protected]">[email protected]</a>)<br>
+Copyright 1999 The FreeType Development Team (<a href="[email protected]">[email protected]</a>)</h3></center>
+
+<p><br>
+<hr WIDTH="100%">
+<h2>
+Introduction</h2>
+
+<blockquote>This document discusses in great details the definition of
+various concepts related to digital typography, as well as a few specific
+to the FreeType library. It also explains the ways typographic information,
+like glyph metrics, kerning distances, etc.. is to be managed and used.
+It relates to the layout and display of text strings, either in a conventional
+(i.e. Roman) layout, or with right-to-left or vertical ones. Some aspects
+like rotation and transformation are explained too.
+<p>Comments and corrections are highly welcomed, and can be sent to the
+<a href="[email protected]">FreeType
+developers list</a>.</blockquote>
+
+<hr WIDTH="100%">
+<h2>
+I. Basic typographic concepts</h2>
+
+<blockquote>
+<h3>
+1. Font files, format and information</h3>
+
+<blockquote>A font is a collection of various character images that can
+be used to display or print text. The images in a single font share some
+common properties, including look, style, serifs, etc.. Typographically
+speaking, one has to distinguish between a <b>font family</b> and its multiple
+<b>font
+faces</b>, which usually differ in style though come from the same template.
+For example, "<i>Palatino Regular</i>" and "<i>Palatino Italic</i>" are
+two distinct <i>faces</i> from the same famous <i>family</i>, called "<i>Palatino</i>"
+itself.
+<p>The single term font is nearly always used in ambiguous ways to refer
+to either a given family or given face, depending on the context. For example,
+most users of word-processors use "font" to describe a font family (e.g.
+Courier, Palatino, etc..); however most of these families are implemented
+through several data files depending on the file format : for TrueType,
+this is usually one per face (i.e. ARIAL.TFF for "Arial Regular", ARIALI.TTF
+for "Arial Italic", etc..). The file is also called a "font" but really
+contains a font face.
+<p>A <i>digital font</i> is thus a data file that may contain <i>one or
+more font faces</i>. For each of these, it contains character images, character
+metrics, as well as other kind of information important to the layout of
+text and the processing of specific character encodings. In some awkward
+formats, like Adobe Type1, a single font face is described through several
+files (i.e. one contains the character images, another one the character
+metrics). We will ignore this implementation issue in most of this document
+and consider digital fonts as single files, though FreeType 2.0 is able
+to support multiple-files fonts correctly.
+<p>As a convenience, a font file containing more than one face is called
+a font collection. This case is rather rare but can be seen in many asian
+fonts, which contain images for two or more scripts for a given language.</blockquote>
+
+<h3>
+2. Character images and mappings :</h3>
+
+<blockquote>The character images are called <b>glyphs</b>. A single character
+can have several distinct images, i.e. several glyphs, depending on script,
+usage or context. Several characters can also take a single glyph (good
+examples are roman ligatures like "oe" and "fi" which can be represented
+by a single glyph like "�" and "?"). The relationships between characters
+and glyphs can be a very complex one but won't be detailed in this document.
+Moreover, some formats use more or less awkward schemes to store and access
+the glyphs. For the sake of clarity, we'll only retain the following notions
+when working with FreeType :
+<br>
+<ul>
+<li>
+A font file contains a set of glyphs, each one can be stored as a bitmap,
+a vector representation or any other scheme (e.g. most scalable formats
+use a combination of math representation and control data/programs). These
+glyphs can be stored in any order in the font file, and is typically accessed
+through a simple glyph index.</li>
+</ul>
+</blockquote>
+</blockquote>
+
+<ul>
+<ul>
+<ul>
+<li>
+The font file contains one (or more) table, called a character map (or
+charmap in short), which is used to convert character codes for a given
+encoding (e.g. ASCII, Unicode, DBCS, Big5, etc..) into glyph indexes relative
+to the font file. A single font face may contain several charmaps. For
+example, most TrueType fonts contain an Apple-specific charmap as well
+as a Unicode charmap, which makes them usable on both Mac and Windows platforms.</li>
+</ul>
+</ul>
+
+<h3>
+3. Character and font metrics :</h3>
+
+<ul>Each glyph image is associated to various metrics which are used to
+describe the way it must be placed and managed when rendering text. Though
+they are described in more details in section III, they relate to glyph
+placement, cursor advances as well as text layouts. They are extremely
+important to compute the flow of text when rendering string of text.
+<p>Each scalable format also contains some global metrics, expressed in
+notional units, used to describe some properties of all glyphs in a same
+face. For example : the maximum glyph bounding box, the ascender, descender
+and text height for the font.
+<p>Though these metrics also exist for non-scalable formats, they only
+apply for a set of given character dimensions and resolutions, and they're
+usually expressed in pixels then.</ul>
+</ul>
+
+<p><br>
+<hr WIDTH="100%">
+<h2>
+II. Glyph Outlines</h2>
+
+<blockquote>This section describes the vectorial representation of glyph
+images, called outlines.
+<br>
+<h3>
+1. Pixels, Points and Device Resolutions :</h3>
+
+<blockquote>Though it is a very common assumption when dealing with computer
+graphics programs, the physical dimensions of a given pixel (be it for
+screens or printers) are not squared. Often, the output device, be it a
+screen or printer exhibits varying resolutions in the horizontal and vertical
+directions, and this must be taken care of when rendering text.
+<p>It is thus common to define a device's characteristics through two numbers
+expressed in <b>dpi</b> (dots per inch). For example, a printer with a
+resolution of 300x600 dpi has 300 pixels per inch in the horizontal direction,
+and 600 in the vertical one. The resolution of a typical computer monitor
+varies with its size (a 15" and 17" monitors don't have the same pixel
+sizes at 640x480), and of course the graphics mode resolution.
+<p>As a consequence, the size of text is usually given in <b>points</b>,
+rather than device-specific pixels. Points are a simple <i>physical</i>
+unit, where 1 point = 1/72th of an inch, in digital typography. As an example,
+most roman books are printed with a body text which size is chosen between
+10 and 14 points.
+<p>It is thus possible to compute the size of text in pixels from the size
+in points through the following computation :
+<center>
+<p><tt>pixel_size = point_size * resolution / 72</tt></center>
+
+<p>Where resolution is expressed in dpi. Note that because the horizontal
+and vertical resolutions may differ, a single point size usually defines
+different text width and height in pixels.
+<br>
+<p><b>IMPORTANT NOTE:</b>
+<br><i>Unlike what is often thought, the "size of text in pixels" is not
+directly related to the real dimensions of characters when they're displayed
+or printed. The relationship between these two concepts is a bit more complex
+and relate to some design choice made by the font designer. This is described
+in more details the next sub-section (see the explanations on the EM square).</i></blockquote>
+
+<h3>
+2. Vectorial representation :</h3>
+
+<blockquote>The source format of outlines is a collection of closed paths
+called <b>contours</b>. Each contour delimits an outer or inner <i>region</i>
+of the glyph, and can be made of either <b>line segments</b> or <b>bezier
+arcs</b>.
+<p>The arcs are defined through <b>control points</b>, and can be either
+second-order (these are "conic beziers") or third-order ("cubic" beziers)
+polynomials, depending on the font format. Hence, each point of the outline
+has an associated <b>flag</b> indicating its type (normal or control point).
+And scaling the points will scale the whole outline.
+<p>Each glyph's original outline points are located on a grid of indivisible
+units. The points are usually stored in a font file as 16-bit integer grid
+coordinates, with the grid origin's being at (0,0); they thus range from
+-16384 to 16383. (even though point coordinates can be floats in other
+formats such as Type 1, we'll restrict our analysis to integer ones, driven
+by the need for simplicity..).
+<p><b>IMPORTANT NOTE:</b>
+<br><i>The grid is always oriented like the traditional mathematical 2D
+plane, i.e. the X axis from the left to the right, and the Y axis from
+bottom to top.</i>
+<p>In creating the glyph outlines, a type designer uses an imaginary square
+called the "EM square". Typically, the EM square can be thought of as a
+tablet on which the character are drawn. The square's size, i.e., the number
+of grid units on its sides, is very important for two reasons:
+<br>
+<blockquote>
+<li>
+it is the reference used to scale the outlines to a given text dimension.
+For example, a size of 12pt at 300x300 dpi corresponds to 12*300/72 = 50
+pixels. This is the size the EM square would appear on the output device
+if it was rendered directly. In other words, scaling from grid units to
+pixels uses the formula:</li>
+</blockquote>
+
+<center><tt>pixel_size = point_size * resolution / 72</tt>
+<br><tt>pixel_coordinate = grid_coordinate * pixel_size / EM_size</tt></center>
+
+<blockquote>
+<li>
+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).</li>
+</blockquote>
+Note that glyphs can freely extend beyond the EM square if the font designer
+wants so. The EM is used as a convenience, and is a valuable convenience
+from traditional typography.
+<center>
+<p><b>Note : Grid units are very often called "font units" or "EM units".</b></center>
+
+<p><b>NOTE:</b>
+<br><i>As said before, the pixel_size computed in the above formula
+does not relate directly to the size of characters on the screen. It simply
+is the size of the EM square if it was to be displayed directly. Each font
+designer is free to place its glyphs as it pleases him within the square.
+This explains why the letters of the following text have not the same height,
+even though they're displayed at the same point size with distinct fonts
+:</i>
+<center>
+<p><img SRC="body_comparison.gif" height=40 width=580></center>
+
+<p>As one can see, the glyphs of the Courier family are smaller than those
+of Times New Roman, which themselves are slightly smaller than those of
+Arial, even though everything is displayed or printed at a size of
+16 points. This only reflect design choices.
+<br> </blockquote>
+
+<h3>
+3. Hinting and Bitmap rendering</h3>
+
+<blockquote>The outline as stored in a font file is called the "master"
+outline, as its points coordinates are expressed in font units. Before
+it can be converted into a bitmap, it must be scaled to a given size/resolution.
+This is done through a very simple transform, but always creates undesirable
+artifacts, e.g. stems of different widths or heights in letters like "E"
+or "H".
+<p>As a consequence, proper glyph rendering needs the scaled points to
+be aligned along the target device pixel grid, through an operation called
+"grid-fitting", and often "hinting". One of its main purpose is to ensure
+that important widths and heights are respected throughout the whole font
+(for example, it is very often desirable that the "I" and the "T" have
+their central vertical line of the same pixel width), as well as manage
+features like stems and overshoots, which can cause problems at small pixel
+sizes.
+<p>There are several ways to perform grid-fitting properly, for example
+most scalable formats associate some control data or programs with each
+glyph outline. Here is an overview :
+<br>
+<blockquote>
+<blockquote><b>explicit grid-fitting :</b>
+<blockquote>The TrueType format defines a stack-based virtual machine,
+for which programs can be written with the help of more than 200 opcodes
+(most of these relating to geometrical operations). Each glyph is thus
+made of both an outline and a control program, its purpose being to perform
+the actual grid-fitting in the way defined by the font designer.</blockquote>
+
+<p><br><b>implicit grid-fitting (also called hinting) :</b>
+<blockquote>The Type 1 format takes a much simpler approach : each glyph
+is made of an outline as well as several pieces called "hints" which are
+used to describe some important features of the glyph, like the presence
+of stems, some width regularities, and the like. There aren't a lot of
+hint types, and it's up to the final renderer to interpret the hints in
+order to produce a fitted outline.</blockquote>
+
+<p><br><b>automatic grid-fitting :</b>
+<blockquote>Some formats simply include no control information with each
+glyph outline, apart metrics like the advance width and height. It's then
+up to the renderer to "guess" the more interesting features of the outline
+in order to perform some decent grid-fitting.</blockquote>
+</blockquote>
+</blockquote>
+
+<center>
+<p><br>The following table summarises the pros and cons of each scheme
+:</center>
+</blockquote>
+
+<center><table BORDER=0 WIDTH="80%" BGCOLOR="#CCCCCC" >
+<tr BGCOLOR="#999999">
+<td>
+<blockquote>
+<center><b><font color="#000000">Grid-fitting scheme</font></b></center>
+</blockquote>
+</td>
+
+<td>
+<blockquote>
+<center><b><font color="#000000">Pros</font></b></center>
+</blockquote>
+</td>
+
+<td>
+<blockquote>
+<center><b><font color="#000000">Cons</font></b></center>
+</blockquote>
+</td>
+</tr>
+
+<tr>
+<td>
+<blockquote>
+<center><b><font color="#000000">Explicit</font></b></center>
+</blockquote>
+</td>
+
+<td>
+<blockquote>
+<center><b><font color="#000000">Quality</font></b>
+<br><font color="#000000">excellence at small sizes is possible. This is
+very important for screen display.</font>
+<p><b><font color="#000000">Consistency</font></b>
+<br><font color="#000000">all renderers produce the same glyph bitmaps.</font></center>
+</blockquote>
+</td>
+
+<td>
+<blockquote>
+<center><b><font color="#000000">Speed</font></b>
+<br><font color="#000000">intepreting bytecode can be slow if the glyph
+programs are complex.</font>
+<p><b><font color="#000000">Size</font></b>
+<br><font color="#000000">glyph programs can be long</font>
+<p><b><font color="#000000">Technicity</font></b>
+<br><font color="#000000">it is extremely difficult to write good hinting
+programs. Very few tools available.</font></center>
+</blockquote>
+</td>
+</tr>
+
+<tr>
+<td>
+<blockquote>
+<center><b><font color="#000000">Implicit</font></b></center>
+</blockquote>
+</td>
+
+<td>
+<blockquote>
+<center><b><font color="#000000">Size</font></b>
+<br><font color="#000000">hints are usually much smaller than explicit
+glyph programs.</font>
+<p><b><font color="#000000">Speed</font></b>
+<br><font color="#000000">grid-fitting is usually a fast process</font></center>
+</blockquote>
+</td>
+
+<td>
+<blockquote>
+<center><b><font color="#000000">Quality</font></b>
+<br><font color="#000000">often questionable at small sizes. Better with
+anti-aliasing though.</font>
+<p><b><font color="#000000">Inconsistency</font></b>
+<br><font color="#000000">results can vary between different renderers,
+or even distinct versions of the same engine.</font></center>
+</blockquote>
+</td>
+</tr>
+
+<tr>
+<td>
+<blockquote>
+<center><b><font color="#000000">Automatic</font></b></center>
+</blockquote>
+</td>
+
+<td>
+<blockquote>
+<center><b><font color="#000000">Size</font></b>
+<br><font color="#000000">no need for control information, resulting in
+smaller font files.</font>
+<p><b><font color="#000000">Speed</font></b>
+<br><font color="#000000">depends on the grid-fitting algo.Usually faster
+than explicit grid-fitting.</font></center>
+</blockquote>
+</td>
+
+<td>
+<blockquote>
+<center><b><font color="#000000">Quality</font></b>
+<br><font color="#000000">often questionable at small sizes. Better with
+anti-aliasing though</font>
+<p><b><font color="#000000">Speed</font></b>
+<br><font color="#000000">depends on the grid-fitting algo.</font>
+<p><b><font color="#000000">Inconsistency</font></b>
+<br><font color="#000000">results can vary between different renderers,
+or even distinct versions of the same engine.</font></center>
+</blockquote>
+</td>
+</tr>
+</table></center>
+</blockquote>
+
+<hr WIDTH="100%">
+<h2>
+III. Glyph metrics</h2>
+
+<blockquote>
+<h3>
+1. Baseline, Pens and Layouts</h3>
+The baseline is an imaginary line that is used to "guide" glyphs when rendering
+text. It can be horizontal (e.g. Roman, Cyrillic, Arabic, etc.) or vertical
+(e.g. Chinese, Japanese, Korean, etc). Moreover, to render text, a virtual
+point, located on the baseline, called the "pen position" or "origin",
+is used to locate glyphs.
+<p>Each layout uses a different convention for glyph placement:
+<br>
+<blockquote>
+<li>
+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.</li>
+</blockquote>
+</blockquote>
+
+<ul>
+<ul>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.
+<p>IMPORTANT NOTE: The pen position is always placed on the baseline.</ul>
+
+<center><img SRC="Image1.gif" height=179 width=458></center>
+
+<ul>
+<li>
+with a vertical layout, glyphs are centered around the baseline:</li>
+</ul>
+
+<center><img SRC="Image2.gif" height=275 width=162></center>
+
+<p><br>
+<h3>
+2. Typographic metrics and bounding boxes</h3>
+
+<ul>A various number of face metrics are defined for all glyphs in a given
+font.
+<p><b>the ascent</b>
+<ul>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.</ul>
+
+<p><br><b>the descent</b>
+<ul>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.</ul>
+
+<p><br><b>the linegap</b>
+<ul>the distance that must be placed between two lines of text. The baseline-to-baseline
+distance should be computed as:
+<center>
+<p><tt>ascent - descent + linegap</tt></center>
+if you use the typographic values.</ul>
+Other, simpler metrics are:
+<p><b>the glyph's bounding box</b>, also called "<b>bbox</b>"
+<ul>this is an imaginary box that encloses all glyphs from the font, as
+tightly as possible. It is represented by four fields, namely <tt>xMin</tt>,
+<tt>yMin</tt>,
+<tt>xMax</tt>,
+and <tt>yMax</tt>, that can be computed for any outline. Their values can
+be in font units (if measured in the original outline) or in fractional/integer
+pixel units (when measured on scaled outlines).
+<p>Note that if it wasn't for grid-fitting, you wouldn't need to know a
+box's complete values, but only its dimensions to know how big is a glyph
+outline/bitmap. However, correct rendering of hinted glyphs needs the preservation
+of important grid alignment on each glyph translation/placement on the
+baseline.</ul>
+<b>the internal leading</b>
+<ul>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:
+<center>
+<p><tt>internal leading = ascent - descent - EM_size</tt></center>
+</ul>
+<b>the external leading</b>
+<ul>this is another name for the line gap.</ul>
+</ul>
+
+<h3>
+3. Bearings and Advances</h3>
+
+<ul>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:
+<p><b>the left side bearing: a.k.a. bearingX</b>
+<ul>this is the horizontal distance from the current pen position to the
+glyph's left bbox edge. It is positive for horizontal layouts, and most
+generally negative for vertical one.</ul>
+
+<p><br><b>the top side bearing: a.k.a. bearingY</b>
+<ul>this is the vertical distance from the baseline to the top of the glyph's
+bbox. It is usually positive for horizontal layouts, and negative for vertical
+ones</ul>
+
+<p><br><b>the advance width: a.k.a. advanceX</b>
+<ul>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.</ul>
+
+<p><br><b>the advance height: a.k.a. advanceY</b>
+<ul>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.</ul>
+
+<p><br><b>the glyph width</b>
+<ul>this is simply the glyph's horizontal extent. More simply it is (bbox.xMax-bbox.xMin)
+for unscaled font coordinates. For scaled glyphs, its computation requests
+specific care, described in the grid-fitting chapter below.</ul>
+
+<p><br><b>the glyph height</b>
+<ul>this is simply the glyph's vertical extent. More simply, it is (bbox.yMax-bbox.yMin)
+for unscaled font coordinates. For scaled glyphs, its computation requests
+specific care, described in the grid-fitting chapter below.</ul>
+
+<p><br><b>the right side bearing</b>
+<ul>is only used for horizontal layouts to describe the distance from the
+bbox's right edge to the advance width. It is in most cases a non-negative
+number.</ul>
+
+<center><tt>advance_width - left_side_bearing - (xMax-xMin)</tt></center>
+
+<p>Here is a picture giving all the details for horizontal metrics :
+<center>
+<p><img SRC="Image3.gif" height=253 width=388></center>
+
+<p>And here is another one for the vertical metrics :
+<center>
+<p><img SRC="Image4.gif" height=278 width=294></center>
+</ul>
+
+<h3>
+4. The effects of grid-fitting</h3>
+
+<ul>Because hinting aligns the glyph's control points to the pixel grid,
+this process slightly modifies the dimensions of character images in ways
+that differ from simple scaling.
+<p>For example, the image of the lowercase "m" letter sometimes fits a
+square in the master grid. However, to make it readable at small pixel
+sizes, hinting tends to enlarge its scaled outline in order to keep its
+three legs distinctly visible, resulting in a larger character bitmap.
+<p>The glyph metrics are also influenced by the grid-fitting process. Mainly
+because :
+<br>
+<ul>
+<li>
+The image's width and height are altered. Even if this is only by one pixel,
+it can make a big difference at small pixel sizes</li>
+
+<li>
+The image's bounding box is modified, thus modifying the bearings</li>
+
+<li>
+The advances must be updated. For example, the advance width must be incremented
+when the hinted bitmap is larger than the scaled one, to reflect the augmented
+glyph width.</li>
+</ul>
+
+<p><br>Note also that :
+<br>
+<ul>
+<li>
+Because of hinting, simply scaling the font ascent or descent might not
+give correct results. A simple solution consists in keeping the ceiling
+of the scaled ascent, and floor of the scaled descent.</li>
+</ul>
+
+<ul>
+<li>
+There is no easy way to get the hinted glyph and advance widths of a range
+of glyphs, as hinting works differently on each outline. The only solution
+is to hint each glyph separately and record the returned values. Some formats,
+like TrueType, even include a table of pre-computed values for a small
+set of common character pixel sizes.</li>
+</ul>
+
+<ul>
+<li>
+Hinting depends on the final character width and height in pixels, which
+means that it is highly resolution-dependent. This property makes correct
+WYSIWYG layouts difficult to implement.</li>
+</ul>
+
+<p><br><b>IMPORTANT NOTE:</b>
+<br>Performing 2D transforms on glyph outlines is very easy with FreeType.
+However, when using translation on a hinted outlines, one should aways
+take care of <b>exclusively using integer pixel distances</b> (which
+means that the parameters to the FT_Translate_Outline API should all be
+multiples of 64, as the point coordinates are in 26.6 fixed float format).
+<p><b>Otherwise</b>, the translation will simply <b>ruin the hinter's work</b>,
+resulting in a very low quality bitmaps.
+<br>
+<br> </ul>
+
+<h3>
+ 5. Text widths and bounding box :</h3>
+
+<ul>As seen before, the "origin" of a given glyph corresponds to the position
+of the pen on the baseline. It is not necessarily located on one of the
+glyph's bounding box corners, unlike many typical bitmapped font formats.
+In some cases, the origin can be out of the bounding box, in others, it
+can be within it, depending on the shape of the given glyph.
+<p>Likewise, the glyph's "advance width" is the increment to apply to the
+pen position during layout, and is not related to the glyph's "width",
+which really is the glyph's bounding width.
+<br>
+<p>The same conventions apply to strings of text. This means that :
+<br>
+<ul>
+<ul>
+<li>
+The bounding box of a given string of text doesn't necessarily contain
+the text cursor, nor is the latter located on one of its corners.</li>
+</ul>
+
+<ul>
+<li>
+The string's advance width isn't related to its bounding box's dimensions.
+Especially if it contains beginning and terminal spaces or tabs.</li>
+</ul>
+
+<ul>
+<li>
+Finally, additional processing like kerning creates strings of text whose
+dimensions are not directly related to the simple juxtaposition of individual
+glyph metrics. For example, the advance width of "VA" isn't the sum of
+the advances of "V" and "A" taken separately.</li>
+</ul>
+</ul>
+</ul>
+</ul>
+
+<hr WIDTH="100%">
+<h2>
+ IV. Kerning</h2>
+
+<blockquote>The term 'kerning' refers to specific information used to adjust
+the relative positions of coincident glyphs in a string of text. This section
+describes several types of kerning information, as well as the way to process
+them when performing text layout.
+<br>
+<h3>
+1. Kerning pairs</h3>
+
+<blockquote>Kerning consists in modifying the spacing between two successive
+glyphs according to their outlines. For example, a "T" and a "y" can be
+easily moved closer, as the top of the "y" fits nicely under the "T"'s
+upper right bar.
+<p>When laying out text with only their standard widths, some consecutive
+glyphs sometimes seem a bit too close or too distant. For example, the
+space between the 'A' and the 'V' in the following word seems a little
+wider than needed.
+<center>
+<p><img SRC="bravo_unkerned.gif" height=37 width=116></center>
+
+<p>Compare this to the same word, when the distance between these two letters
+has been slightly reduced :
+<center>
+<p><img SRC="bravo_kerned.gif" height=37 width=107></center>
+
+<p>As you can see, this adjustment can make a great difference. Some font
+faces thus include a table containing kerning distances for a set of given
+glyph pairs, used during text layout. Note that :
+<br>
+<blockquote>
+<ul>
+<li>
+The pairs are ordered, i.e. the space for pair (A,V) isn't necessarily
+the space for pair (V,A). They also index glyphs, and not characters.</li>
+</ul>
+
+<ul>
+<li>
+Kerning distances can be expressed in horizontal or vertical directions,
+depending on layout and/or script. For example, some horizontal layouts
+like arabic can make use of vertical kerning adjustments between successive
+glyphs. A vertical script can have vertical kerning distances.</li>
+</ul>
+
+<ul>
+<li>
+Kerning distances are expressed in grid units. They are usually oriented
+in the X axis, which means that a negative value indicates that two glyphs
+must be set closer in a horizontal layout.</li>
+</ul>
+</blockquote>
+</blockquote>
+
+<h3>
+2. Applying kerning</h3>
+
+<blockquote>Applying kerning when rendering text is a rather easy process.
+It merely consists in adding the scaled kern distance to the pen position
+before writing each next glyph. However, the typographically correct renderer
+must take a few more details in consideration.
+<p>The "sliding dot" problem is a good example : many font faces include
+a kerning distance between capital letters like "T" or "F" and a following
+dot ("."), in order to slide the latter glyph just right to their main
+leg. I.e.
+<center>
+<p><img SRC="twlewis1.gif" height=38 width=314></center>
+
+<p>However, this sometimes requires additional adjustments between the
+dot and the letter following it, depending on the shapes of the enclosing
+letters. When applying "standard" kerning adjustments, the previous sentence
+would become :
+<center>
+<p><img SRC="twlewis2.gif" height=36 width=115></center>
+
+<p>Which clearly is too contracted. The solution here, as exhibited in
+the first example is to only slide the dots when possible. Of course, this
+requires a certain knowledge of the text's meaning. The above adjustments
+would not necessarily be welcomed if we were rendering the final dot of
+a given paragraph.
+<p>This is only one example, and there are many others showing that a real
+typographer is needed to layout text properly. If not available, some kind
+of user interaction or tagging of the text could be used to specify some
+adjustments, but in all cases, this requires some support in applications
+and text libraries.
+<p>For more mundane and common uses, however, we can have a very simple
+algorithm, which avoids the sliding dot problem, and others, though
+not producing optimal results. It can be seen as :
+<br>
+<blockquote>
+<ol>
+<li>
+place the first glyph on the baseline</li>
+
+<li>
+save the location of the pen position/origin in pen1</li>
+
+<li>
+adjust the pen position with the kerning distance between the first and
+second glyph</li>
+
+<li>
+place the second glyph and compute the next pen position/origin in pen2.</li>
+
+<li>
+use pen1 as the next pen position if it is beyond pen2, use pen2 otherwise.</li>
+</ol>
+</blockquote>
+</blockquote>
+</blockquote>
+
+<h2>
+
+<hr WIDTH="100%"></h2>
+
+<h2>
+V. Text processing</h2>
+
+<blockquote>This section demonstrates how to use the concepts previously
+defined to render text, whatever the layout you use.
+<br>
+<h3>
+1. Writing simple text strings :</h3>
+
+<blockquote>In this first example, we'll generate a simple string of Roman
+text, i.e. with a horizontal left-to-right layout. Using exclusively pixel
+metrics, the process looks like :
+<blockquote><tt>1) convert the character string into a series of glyph
+indexes.</tt>
+<br><tt>2) place the pen to the cursor position.</tt>
+<br><tt>3) get or load the glyph image.</tt>
+<br><tt>4) translate the glyph so that its 'origin' matches the pen position</tt>
+<br><tt>5) render the glyph to the target device</tt>
+<br><tt>6) increment the pen position by the glyph's advance width in pixels</tt>
+<br><tt>7) start over at step 3 for each of the remaining glyphs</tt>
+<br><tt>8) when all glyphs are done, set the text cursor to the new pen
+position</tt></blockquote>
+Note that kerning isn't part of this algorithm.</blockquote>
+
+<h3>
+2. Sub-pixel positioning :</h3>
+
+<blockquote>It is somewhat useful to use sub-pixel positioning when rendering
+text. This is crucial, for example, to provide semi-WYSIWYG text layouts.
+Text rendering is very similar to the algorithm described in sub-section
+1, with the following few differences :
+<ul>
+<li>
+The pen position is expressed in fractional pixels.</li>
+
+<li>
+Because translating a hinted outline by a non-integer distance will ruin
+its grid-fitting, the position of the glyph origin must be rounded before
+rendering the character image.</li>
+
+<li>
+The advance width is expressed in fractional pixels, and isn't necessarily
+an integer.</li>
+</ul>
+
+<p><br>Which finally looks like :
+<blockquote><tt>1. convert the character string into a series of glyph
+indexes.</tt>
+<br><tt>2. place the pen to the cursor position. This can be a non-integer
+point.</tt>
+<br><tt>3. get or load the glyph image.</tt>
+<br><tt>4. translate the glyph so that its 'origin' matches the rounded
+pen position.</tt>
+<br><tt>5. render the glyph to the target device</tt>
+<br><tt>6. increment the pen position by the glyph's advance width in fractional
+pixels.</tt>
+<br><tt>7. start over at step 3 for each of the remaining glyphs</tt>
+<br><tt>8. when all glyphs are done, set the text cursor to the new pen
+position</tt></blockquote>
+Note that with fractional pixel positioning, the space between two given
+letters isn't fixed, but determined by the accumulation of previous rounding
+errors in glyph positioning.</blockquote>
+
+<h3>
+3. Simple kerning :</h3>
+
+<blockquote>Adding kerning to the basic text rendering algorithm is easy
+: when a kerning pair is found, simply add the scaled kerning distance
+to the pen position before step 4. Of course, the distance should be rounded
+in the case of algorithm 1, though it doesn't need to for algorithm 2.
+This gives us :
+<p>Algorithm 1 with kerning:
+<blockquote><tt>3) get or load the glyph image.</tt>
+<br><tt>4) Add the rounded scaled kerning distance, if any, to the pen
+position</tt>
+<br><tt>5) translate the glyph so that its 'origin' matches the pen position</tt>
+<br><tt>6) render the glyph to the target device</tt>
+<br><tt>7) increment the pen position by the glyph's advance width in pixels</tt>
+<br><tt>8) start over at step 3 for each of the remaining glyphs</tt></blockquote>
+
+<p><br>Algorithm 2 with kerning:
+<blockquote><tt>3) get or load the glyph image.</tt>
+<br><tt>4) Add the scaled unrounded kerning distance, if any, to the pen
+position.</tt>
+<br><tt>5) translate the glyph so that its 'origin' matches the rounded
+pen position.</tt>
+<br><tt>6) render the glyph to the target device</tt>
+<br><tt>7) increment the pen position by the glyph's advance width in fractional
+pixels.</tt>
+<br><tt>8) start over at step 3 for each of the remaining glyphs</tt></blockquote>
+Of course, the algorithm described in section IV can also be applied to
+prevent the sliding dot problem if one wants to..</blockquote>
+
+<h3>
+4. Right-To-Left Layout :</h3>
+
+<blockquote>The process of laying out arabic or hebrew text is extremely
+similar. The only difference is that the pen position must be decremented
+before the glyph rendering (remember : the advance width is always positive,
+even for arabic glyphs). Thus, algorithm 1 becomes :
+<p>Right-to-left Algorithm 1:
+<blockquote><tt>3) get or load the glyph image.</tt>
+<br><tt>4) Decrement the pen position by the glyph's advance width in pixels</tt>
+<br><tt>5) translate the glyph so that its 'origin' matches the pen position</tt>
+<br><tt>6) render the glyph to the target device</tt>
+<br><tt>7) start over at step 3 for each of the remaining glyphs</tt></blockquote>
+
+<p><br>The changes to Algorithm 2, as well as the inclusion of kerning
+are left as an exercise to the reader.
+<br>
+<br> </blockquote>
+
+<h3>
+5. Vertical layouts :</h3>
+
+<blockquote>Laying out vertical text uses exactly the same processes, with
+the following significant differences :
+<br>
+<blockquote>
+<li>
+The baseline is vertical, and the vertical metrics must be used instead
+of the horizontal one.</li>
+
+<li>
+The left bearing is usually negative, but this doesn't change the fact
+that the glyph origin must be located on the baseline.</li>
+
+<li>
+The advance height is always positive, so the pen position must be decremented
+if one wants to write top to bottom (assuming the Y axis is oriented upwards).</li>
+</blockquote>
+Through the following algorithm :
+<blockquote><tt>1) convert the character string into a series of glyph
+indexes.</tt>
+<br><tt>2) place the pen to the cursor position.</tt>
+<br><tt>3) get or load the glyph image.</tt>
+<br><tt>4) translate the glyph so that its 'origin' matches the pen position</tt>
+<br><tt>5) render the glyph to the target device</tt>
+<br><tt>6) decrement the vertical pen position by the glyph's advance height
+in pixels</tt>
+<br><tt>7) start over at step 3 for each of the remaining glyphs</tt>
+<br><tt>8) when all glyphs are done, set the text cursor to the new pen
+position</tt></blockquote>
+</blockquote>
+
+<h3>
+6. WYSIWYG text layouts :</h3>
+
+<blockquote>As you probably know, the acronym WYSIWYG stands for '<i>What
+You See Is What You Get</i>'. Basically, this means that the output of
+a document on the screen should match "perfectly" its printed version.
+A <b><i>true</i></b> wysiwyg system requires two things :
+<p><b>device-independent text layout</b>
+<blockquote>Which means that the document's formatting is the same on the
+screen than on any printed output, including line breaks, justification,
+ligatures, fonts, position of inline images, etc..</blockquote>
+
+<p><br><b>matching display and print character sizes</b>
+<blockquote>Which means that the displayed size of a given character should
+match its dimensions when printed. For example, a text string which is
+exactly 1 inch tall when printed should also appear 1 inch tall on the
+screen (when using a scale of 100%).</blockquote>
+
+<p><br>It is clear that matching sizes cannot be possible if the computer
+has no knowledge of the physical resolutions of the display device(s) it
+is using. And of course, this is the most common case ! That's not too
+unfortunate, however because most users really don't care about this
+feature. Legibility is much more important.
+<p>When the Mac appeared, Apple decided to choose a resolution of 72 dpi
+to describe the Macintosh screen to the font sub-system (whatever the monitor
+used). This choice was most probably driven by the fact that, at this resolution,
+1 point = 1 pixel. However; it neglected one crucial fact : as most users
+tend to choose a document character size between 10 and 14 points, the
+resultant displayed text was rather small and not too legible without scaling.
+Microsoft engineers took notice of this problem and chose a resolution
+of 96 dpi on Windows, which resulted in slightly larger, and more legible,
+displayed characters (for the same printed text size).
+<p>These distinct resolutions explain some differences when displaying
+text at the same character size on a Mac and a Windows machine. Moreover,
+it is not unusual to find some TrueType fonts with enhanced hinting (tech
+note: through delta-hinting) for the sizes of 10, 12, 14 and 16 points
+at 96 dpi.
+<br>
+<p>As for device-independent text, it is a notion that is, unfortunately,
+often abused. For example, many word processors, including MS Word, do
+not really use device-independent glyph positioning algorithms when laying
+out text. Rather, they use the target printer's resolution to compute <i>hinted</i>
+glyph metrics for the layout. Though it guarantees that the printed version
+is always the "nicest" it can be, especially for very low resolution printers
+(like dot-matrix), it has a very sad effect : changing the printer can
+have dramatic effects on the <i>whole</i> document layout, especially if
+it makes strong use of justification, uses few page breaks, etc..
+<p>Because the glyph metrics vary slightly when the resolution changes
+(due to hinting), line breaks can change enormously, when these differences
+accumulate over long runs of text. Try for example printing a very long
+document (with no page breaks) on a 300 dpi ink-jet printer, then the same
+one on a 3000 dpi laser printer : you'll be extremely lucky if your final
+page count didn't change between the prints ! Of course, we can still call
+this WYSIWYG, as long as the printer resolution is fixed !!
+<p>Some applications, like Adobe Acrobat, which targeted device-independent
+placement from the start, do not suffer from this problem. There are two
+ways to achieve this : either use the scaled and unhinted glyph metrics
+when laying out text both in the rendering and printing processes, or simply
+use wathever metrics you want and store them with the text in order to
+get sure they're printed the same on all devices (the latter being probably
+the best solution, as it also enables font substitution without breaking
+text layouts).
+<p>Just like matching sizes, device-independent placement isn't necessarily
+a feature that most users want. However, it is pretty clear that for any
+kind of professional document processing work, it <b><i>is</i></b> a requirement.</blockquote>
+</blockquote>
+
+<h2>
+
+<hr WIDTH="100%"></h2>
+
+<h2>
+VI. FreeType outlines :</h2>
+
+<blockquote>The purpose of this section is to present the way FreeType
+manages vectorial outlines, as well as the most common operations that
+can be applied on them.
+<br>
+<h3>
+1. FreeType outline description and structure :</h3>
+
+<blockquote>
+<h4>
+a. Outline curve decomposition :</h4>
+
+<blockquote>An outline is described as a series of closed contours in the
+2D plane. Each contour is made of a series of line segments and bezier
+arcs. Depending on the file format, these can be second-order or third-order
+polynomials. The former are also called quadratic or conic arcs, and they
+come from the TrueType format. The latter are called cubic arcs and mostly
+come from the Type1 format.
+<p>Each arc is described through a series of start, end and control points.
+Each point of the outline has a specific tag which indicates wether it
+is used to describe a line segment or an arc. The tags can take the following
+values :
+<br>
+<br> </blockquote>
+
+<center><table CELLSPACING=5 CELLPADDING=5 WIDTH="60%" >
+<tr VALIGN=TOP>
+<td>
+<blockquote><b>FT_Curve_Tag_On </b></blockquote>
+</td>
+
+<td VALIGN=TOP>
+<blockquote>Used when the point is "on" the curve. This corresponds to
+start and end points of segments and arcs. The other tags specify what
+is called an "off" point, i.e. one which isn't located on the contour itself,
+but serves as a control point for a bezier arc.</blockquote>
+</td>
+</tr>
+
+<tr>
+<td>
+<blockquote><b>FT_Curve_Tag_Conic</b></blockquote>
+</td>
+
+<td>
+<blockquote>Used for an "off" point used to control a conic bezier arc.</blockquote>
+</td>
+</tr>
+
+<tr>
+<td>
+<blockquote><b>FT_Curve_Tag_Cubic</b></blockquote>
+</td>
+
+<td>
+<blockquote>Used for an "off" point used to control a cubic bezier arc.</blockquote>
+</td>
+</tr>
+</table></center>
+
+<blockquote>
+<p>The following rules are applied to decompose the contour's points into
+segments and arcs :
+<blockquote>
+<li>
+two successive "on" points indicate a line segment joining them.</li>
+</blockquote>
+</blockquote>
+
+<ul>
+<ul>
+<li>
+one conic "off" point amidst two "on" points indicates a conic bezier arc,
+the "off" point being the control point, and the "on" ones the start and
+end points.</li>
+</ul>
+</ul>
+
+<ul>
+<ul>
+<li>
+Two successive cubic "off" points amidst two "on" points indicate a cubic
+bezier arc. There must be exactly two cubic control points and two on points
+for each cubic arc (using a single cubic "off" point between two "on" points
+is forbidden, for example).</li>
+</ul>
+</ul>
+
+<ul>
+<ul>
+<li>
+finally, two successive conic "off" points forces the rasterizer to create
+(during the scan-line conversion process exclusively) a virtual "on" point
+amidst them, at their exact middle. This greatly facilitates the definition
+of successive conic bezier arcs. Moreover, it's the way outlines are described
+in the TrueType specification.</li>
+</ul>
+
+<p><br>Note that it is possible to mix conic and cubic arcs in a single
+contour, even though no current font driver produces such outlines.
+<br> </ul>
+
+<center><table>
+<tr>
+<td>
+<blockquote><img SRC="points_segment.gif" height=166 width=221></blockquote>
+</td>
+
+<td>
+<blockquote><img SRC="points_conic.gif" height=183 width=236></blockquote>
+</td>
+</tr>
+
+<tr>
+<td>
+<blockquote><img SRC="points_cubic.gif" height=162 width=214></blockquote>
+</td>
+
+<td>
+<blockquote><img SRC="points_conic2.gif" height=204 width=225></blockquote>
+</td>
+</tr>
+</table></center>
+
+<h4>
+b. Outline descriptor :</h4>
+
+<blockquote>A FreeType outline is described through a simple structure,
+called <tt>FT_Outline</tt>, which fields are :
+<br>
+<br>
+<center><table CELLSPACING=3 CELLPADDING=3 BGCOLOR="#CCCCCC" >
+<tr>
+<td><b><tt>n_points</tt></b></td>
+
+<td>the number of points in the outline</td>
+</tr>
+
+<tr>
+<td><b><tt>n_contours</tt></b></td>
+
+<td>the number of contours in the outline</td>
+</tr>
+
+<tr>
+<td><b><tt>points</tt></b></td>
+
+<td>array of point coordinates</td>
+</tr>
+
+<tr>
+<td><b><tt>contours</tt></b></td>
+
+<td>array of contour end indices</td>
+</tr>
+
+<tr>
+<td><b><tt>flags</tt></b></td>
+
+<td>array of point flags</td>
+</tr>
+</table></center>
+
+<p>Here, <b><tt>points</tt></b> is a pointer to an array of <tt>FT_Vector</tt>
+records, used to store the vectorial coordinates of each outline point.
+These are expressed in 1/64th of a pixel, which is also known as the <i>26.6
+fixed float format</i>.
+<p><b><tt>contours</tt></b> is an array of point indices used to delimit
+contours in the outline. For example, the first contour always starts at
+point 0, and ends a point <b><tt>contours[0]</tt></b>. The second contour
+starts at point "<b><tt>contours[0]+1</tt></b>" and ends at <b><tt>contours[1]</tt></b>,
+etc..
+<p>Note that each contour is closed, and that <b><tt>n_points</tt></b>
+should be equal to "<b><tt>contours[n_contours-1]+1</tt></b>" for a valid
+outline.
+<p>Finally, <b><tt>flags</tt></b> is an array of bytes, used to store each
+outline point's tag.
+<br>
+<br> </blockquote>
+</blockquote>
+
+<h3>
+2. Bounding and control box computations :</h3>
+
+<blockquote>A <b>bounding box</b> (also called "<b>bbox</b>") is simply
+the smallest possible rectangle that encloses the shape of a given outline.
+Because of the way arcs are defined, bezier control points are not necessarily
+contained within an outline's bounding box.
+<p>This situation happens when one bezier arc is, for example, the upper
+edge of an outline and an off point happens to be above the bbox. However,
+it is very rare in the case of character outlines because most font designers
+and creation tools always place on points at the extrema of each curved
+edges, as it makes hinting much easier.
+<p>We thus define the <b>control box</b> (a.k.a. the "<b>cbox</b>") as
+the smallest possible rectangle that encloses all points of a given outline
+(including its off points). Clearly, it always includes the bbox, and equates
+it in most cases.
+<p>Unlike the bbox, the cbox is also much faster to compute.
+<br>
+<center><table>
+<tr>
+<td><img SRC="bbox1.gif" height=264 width=228></td>
+
+<td><img SRC="bbox2.gif" height=229 width=217></td>
+</tr>
+</table></center>
+
+<p>Control and bounding boxes can be computed automatically through the
+functions <b><tt>FT_Get_Outline_CBox</tt></b> and <b><tt>FT_Get_Outline_BBox</tt></b>.
+The former function is always very fast, while the latter <i>may</i> be
+slow in the case of "outside" control points (as it needs to find the extreme
+of conic and cubic arcs for "perfect" computations). If this isn't the
+case, it's as fast as computing the control box.
+<p>Note also that even though most glyph outlines have equal cbox and bbox
+to ease hinting, this is not necessary the case anymore when a
+<br>transform like rotation is applied to them.
+<br> </blockquote>
+
+<h3>
+ 3. Coordinates, scaling and grid-fitting :</h3>
+
+<blockquote>An outline point's vectorial coordinates are expressed in the
+26.6 format, i.e. in 1/64th of a pixel, hence coordinates (1.0, -2.5) is
+stored as the integer pair ( x:64, y: -192 ).
+<p>After a master glyph outline is scaled from the EM grid to the current
+character dimensions, the hinter or grid-fitter is in charge of aligning
+important outline points (mainly edge delimiters) to the pixel grid. Even
+though this process is much too complex to be described in a few lines,
+its purpose is mainly to round point positions, while trying to preserve
+important properties like widths, stems, etc..
+<p>The following operations can be used to round vectorial distances in
+the 26.6 format to the grid :
+<center>
+<p><tt>round(x) == (x+32) & -64</tt>
+<br><tt>floor(x) == x &
+-64</tt>
+<br><tt>ceiling(x) == (x+63) & -64</tt></center>
+
+<p>Once a glyph outline is grid-fitted or transformed, it often is interesting
+to compute the glyph image's pixel dimensions before rendering it. To do
+so, one has to consider the following :
+<p>The scan-line converter draws all the pixels whose <i>centers</i> fall
+inside the glyph shape. It can also detect "<b><i>drop-outs</i></b>", i.e.
+discontinuities coming from extremely thin shape fragments, in order to
+draw the "missing" pixels. These new pixels are always located at a distance
+less than half of a pixel but one cannot predict easily where they'll appear
+before rendering.
+<p>This leads to the following computations :
+<br>
+<ul>
+<li>
+compute the bbox</li>
+</ul>
+
+<ul>
+<li>
+grid-fit the bounding box with the following :</li>
+</ul>
+
+<ul>
+<ul><tt>xmin = floor( bbox.xMin )</tt>
+<br><tt>xmax = ceiling( bbox.xMax )</tt>
+<br><tt>ymin = floor( bbox.yMin )</tt>
+<br><tt>ymax = ceiling( bbox.yMax )</tt></ul>
+
+<li>
+return pixel dimensions, i.e. <tt>width = (xmax - xmin)/64</tt> and <tt>height
+= (ymax - ymin)/64</tt></li>
+</ul>
+
+<p><br>By grid-fitting the bounding box, one guarantees that all the pixel
+centers that are to be drawn, <b><i>including those coming from drop-out
+control</i></b>, will be <b><i>within</i></b> the adjusted box. Then the
+box's dimensions in pixels can be computed.
+<p>Note also that, when <i>translating</i> a <i>grid-fitted outline</i>,
+one should <b><i>always</i></b> use <b><i>integer distances</i></b> to
+move an outline in the 2D plane. Otherwise, glyph edges won't be aligned
+on the pixel grid anymore, and the hinter's work will be lost, producing
+<b><i>very
+low quality </i></b>bitmaps and pixmaps..</blockquote>
+</blockquote>
+
+<hr WIDTH="100%">
+<h2>
+VII. FreeType bitmaps :</h2>
+
+<blockquote>The purpose of this section is to present the way FreeType
+manages bitmaps and pixmaps, and how they relate to the concepts previously
+defined. The relationships between vectorial and pixel coordinates is explained.
+<br>
+<h3>
+1. FreeType bitmap and pixmap descriptor :</h3>
+
+<blockquote>A bitmap or pixmap is described through a single structure,
+called <tt>FT_Raster_Map</tt>. It is a simple descriptor whose fields are
+:
+<br>
+<br>
+<center><table CELLSPACING=3 CELLPADDING=5 BGCOLOR="#CCCCCC" >
+<caption><tt>FT_Raster_Map</tt></caption>
+
+<tr>
+<td><b>rows</b></td>
+
+<td>the number of rows, i.e. lines, in the bitmap</td>
+</tr>
+
+<tr>
+<td><b>width</b></td>
+
+<td>the number of horizontal pixels in the bitmap</td>
+</tr>
+
+<tr>
+<td><b>cols</b></td>
+
+<td>the number of "columns", i.e. bytes per line, in the bitmap</td>
+</tr>
+
+<tr>
+<td><b>flow</b></td>
+
+<td>the bitmap's flow, i.e. orientation of rows (see below)</td>
+</tr>
+
+<tr>
+<td><b>pix_bits</b></td>
+
+<td>the number of bits per pixels. valid values are 1, 4, 8 and 16</td>
+</tr>
+
+<tr>
+<td><b>buffer</b></td>
+
+<td>a typeless pointer to the bitmap pixel bufer</td>
+</tr>
+</table></center>
+
+<p>The bitmap's <b><tt>flow</tt></b> determines wether the rows in the
+pixel buffer are stored in ascending or descending order. Possible values
+are <b><tt>FT_Flow_Up</tt></b> (value 1) and <b><tt>FT_Flow_Down</tt></b>
+(value -1).
+<p>Remember that FreeType uses the <i>Y upwards</i> convention in the 2D
+plane. Which means that a coordinate of (0,0) always refer to the <i>lower-left
+corner</i> of a bitmap.
+<p>In the case of an '<i>up</i>' flow, the rows are stored in increasing
+vertical position, which means that the first bytes of the pixel buffer
+are part of the <i>lower</i> bitmap row. On the opposite, a '<i>down</i>'
+flow means that the first buffer bytes are part of the <i>upper</i> bitmap
+row, i.e. the last one in ascending order.
+<p>As a hint, consider that when rendering an outline into a Windows or
+X11 bitmap buffer, one should always use a down flow in the bitmap descriptor.
+<br>
+<center><table>
+<tr>
+<td><img SRC="up_flow.gif" height=298 width=291></td>
+
+<td><img SRC="down_flow.gif" height=298 width=313></td>
+</tr>
+
+<tr>
+<td></td>
+
+<td></td>
+</tr>
+</table></center>
+</blockquote>
+
+<h3>
+2. Vectorial versus pixel coordinates :</h3>
+
+<blockquote>This sub-section explains the differences between vectorial
+and pixel coordinates. To make things clear, brackets will be used to describe
+pixel coordinates, e.g. [3,5], while parentheses will be used for vectorial
+ones, e.g. (-2,3.5).
+<p>In the pixel case, as we use the <i>Y upwards</i> convention, the coordinate
+[0,0] always refers to the <i>lower left pixel</i> of a bitmap, while coordinate
+[width-1, rows-1] to its <i>upper right pixel</i>.
+<p>In the vectorial case, point coordinates are expressed in floating units,
+like (1.25, -2.3). Such a position doesn't refer to a given pixel, but
+simply to an immaterial point in the 2D plane
+<p>The pixels themselves are indeed <i>square boxes</i> of the 2D plane,
+which centers lie in half pixel coordinates. For example, the <i>lower
+left pixel</i> of a bitmap is delimited by the <i>square</i> (0,0)-(1,1),
+its center being at location (0.5,0.5).
+<p>This introduces some differences when computing distances. For example,
+the "<i>length</i>" in pixels of the line [0,0]-[10,0] is 11. However,
+the vectorial distance between (0,0)-(10,0) covers exactly 10 pixel centers,
+hence its length if 10.
+<center><img SRC="grid_1.gif" height=390 width=402></center>
+</blockquote>
+
+<h3>
+3. Converting outlines into bitmaps and pixmaps :</h3>
+
+<blockquote>Generating a bitmap or pixmap image from a vectorial image
+is easy with FreeType. However, one must understand a few points regarding
+the positioning of the outline in the 2D plane before calling the function
+<b><tt>FT_Get_Outline_Bitmap</tt></b>.
+These are :
+<br>
+<ul>
+<li>
+The glyph loader and hinter always places the outline in the 2D plane so
+that (0,0) matches its character origin. This means that the glyph�s outline,
+and corresponding bounding box, can be placed anywhere in the 2D plane
+(see the graphics in section III).</li>
+</ul>
+
+<ul>
+<li>
+The target bitmap�s area is mapped to the 2D plane, with its lower left
+corner at (0,0). This means that a bitmap or pixmap of dimensions [<tt>w,h</tt>]
+will be mapped to a 2D rectangle window delimited by (0,0)-(<tt>w,h</tt>).</li>
+</ul>
+
+<ul>
+<li>
+When calling <b><tt>FT_Get_Outline_Bitmap</tt></b>, everything that falls
+within the bitmap window is rendered, the rest is ignored.</li>
+</ul>
+
+<p><br>A common mistake made by many developers when they begin using FreeType
+is believing that a loaded outline can be directly rendered in a bitmap
+of adequate dimensions. The following images illustrate why this is a problem
+:
+<ul>
+<ul>
+<li>
+the first image shows a loaded outline in the 2D plane.</li>
+
+<li>
+the second one shows the target window for a bitmap of arbitrary dimensions
+[w,h]</li>
+
+<li>
+the third one shows the juxtaposition of the outline and window in the
+2D plane</li>
+
+<li>
+the last image shows what will really be rendered in the bitmap.</li>
+</ul>
+</ul>
+
+<center><img SRC="clipping.gif" height=151 width=539></center>
+
+<p><br>
+<br>
+<br>
+<br>
+<br>
+<p>Indeed, in nearly all cases, the loaded or transformed outline must
+be translated before it is rendered into a target bitmap, in order to adjust
+its position relative to the target window.
+<p>For example, the correct way of creating a <i>standalone</i> glyph bitmap
+is thus to :
+<br>
+<ul>
+<li>
+Compute the size of the glyph bitmap. It can be computed directly from
+the glyph metrics, or by computing its bounding box (this is useful when
+a transform has been applied to the outline after the load, as the glyph
+metrics are not valid anymore).</li>
+</ul>
+
+<ul>
+<li>
+Create the bitmap with the computed dimensions. Don�t forget to fill the
+pixel buffer with the background color.</li>
+</ul>
+
+<ul>
+<li>
+Translate the outline so that its lower left corner matches (0,0). Don�t
+forget that in order to preserve hinting, one should use integer, i.e.
+rounded distances (of course, this isn�t required if preserving hinting
+information doesn�t matter, like with rotated text). Usually, this means
+translating with a vector <tt>( -ROUND(xMin), -ROUND(yMin) )</tt>.</li>
+</ul>
+
+<ul>
+<li>
+Call the function <b><tt>FT_Get_Outline_Bitmap</tt></b>.</li>
+</ul>
+
+<p><br>In the case where one wants to write glyph images directly into
+a large bitmap, the outlines must be translated so that their vectorial
+position correspond to the current text cursor/character origin.</blockquote>
+</blockquote>
+
+<h2>
+
+<hr WIDTH="100%"></h2>
+
+<h2>
+VII. FreeType anti-aliasing :</h2>
+<b><i>IMPORTANT NOTE :</i></b>
+<br>This section is still in progress, as the way FreeType 2 handles anti-aliased
+rendering hasn't been definitely set yet. The main reason being that a
+flexible way of doing things is needed in order to allow further improvements
+in the raster (i.e. number of gray levels > 100, etc..).
+<blockquote>
+<h3>
+1. What is anti-aliasing :</h3>
+
+<blockquote>Anti-aliasing works by using various levels of grays to reduce
+the "staircase" artefacts visible on the diagonals and curves of glyph
+bitmaps. It is a way to artificially enhance the display resolution of
+the target device. It can smooth out considerably displayed or printed
+text.</blockquote>
+
+<h3>
+2. How does it work with FreeType :</h3>
+
+<blockquote>FreeType's scan-line converter is able to produce anti-aliased
+output directly. It is however limited to 8-bit pixmaps and 5 levels of
+grays (or 17 levels, depending on a build configuration option). Here's
+how one should use it :
+<h4>
+a. Set the gray-level palette :</h4>
+
+<blockquote>The scan-line converter uses 5 levels for anti-aliased output.
+Level 0 corresponds to the text background color (e.g. white), and level
+5 to the text foreground color. Intermediate levels are used for intermediate
+shades of grays.
+<p>You must set the raster's palette when you want to use different colors,
+use the function <b><tt>FT_Raster_Set_Palette</tt></b> as in :
+<p><tt>{</tt>
+<br><tt> static const char gray_palette[5] = { 0, 7, 15, 31,
+63 };</tt>
+<br><tt> �</tt>
+<br><tt> error = FT_Set_Raster_Palette( library, 5, palette );</tt>
+<br><tt>}</tt>
+<br>
+<ul>
+<li>
+The first parameter is a handle to a FreeType library object. See the user
+guide for more details (the library contains a scan-line converter object).</li>
+</ul>
+
+<ul>
+<li>
+The second parameter is the number of entries in the gray-level palette.
+Valid values are 5 and 17 for now, but this may change in later implementations.</li>
+</ul>
+
+<ul>
+<li>
+The last parameter is a pointer to a char table containing the pixel value
+for each of the gray-levels. In this example, we use a background color
+of 0, a foreground color of 63, and intermediate values in-between.</li>
+</ul>
+
+<p><br>The palette is copied in the raster object, as well as processed
+to build several lookup-tables necessary for the internal anti-aliasing
+algorithm.
+<br> </blockquote>
+
+<h4>
+b. Render the pixmap :</h4>
+
+<blockquote>The scan-line converter doesn't create bitmaps or pixmaps,
+it simply renders into those that are passed as parameters to the function
+<b><tt>FT_Get_Outline_Bitmap</tt></b>.
+To render an anti-aliased pixmap, simply set the target bitmap�s depth
+to 8. Note however that this target 8-bit pixmap must always have a '<b><tt>cols</tt></b>'
+field padded to 32-bits, which means that the number of bytes per lines
+of the pixmap must be a multiple of 4 !
+<p>Once the palette has been set, and the pixmap buffer has been created
+to receive the glyph image, simply call <b><tt>FT_Get_Outline_Bitmap</tt></b>.
+Take care of clearing the target pixmap with the background color before
+calling this function. For the sake of simplicity and efficiency, the raster
+is not able to compose anti-aliased glyph images on a pre-existing images.
+<p>Here's some code demonstrating how to load and render a single glyph
+pixmap :
+<p><tt>{</tt>
+<br><tt> FT_Outline outline;</tt>
+<br><tt> FT_Raster_Map pixmap;</tt>
+<br><tt> FT_BBox cbox;</tt>
+<br><tt> �</tt>
+<p><i><tt> // load the outline</tt></i>
+<br><tt> �</tt>
+<p><i><tt> // compute glyph dimensions (grid-fit cbox, etc..)</tt></i>
+<br><tt> FT_Get_Outline_CBox( &outline, &cbox );</tt>
+<p><tt> cbox.xMin = cbox.xMin & -64;
+// floor(xMin)</tt>
+<br><tt> cbox.yMin = cbox.yMin & -64;
+// floor(yMin)</tt>
+<br><tt> cbox.xMax = (cbox.xMax+32) & -64; // ceiling(xMax)</tt>
+<br><tt> cbox.yMax = (cbox.yMax+32) & -64; // ceiling(yMax)</tt>
+<p><tt> pixmap.width = (cbox.xMax - cbox.xMin)/64;</tt>
+<br><tt> pixmap.rows = (cbox.yMax - cbox.yMin)/64;</tt>
+<p><i><tt> // fill the pixmap descriptor and create the pixmap buffer</tt></i>
+<br><i><tt> // don't forget to pad the 'cols' field to 32 bits</tt></i>
+<br><tt> pixmap.pix_bits = 8;</tt>
+<br><tt> pixmap.flow = FT_Flow_Down;</tt>
+<br><tt> pixmap.cols = (pixmap.width+3) &
+-4; // pad 'cols' to 32 bits</tt>
+<br><tt> pixmap.buffer = malloc( pixmap.cols * pixmap.rows
+);</tt>
+<p><i><tt> // fill the pixmap buffer with the background color</tt></i>
+<br><i><tt> //</tt></i>
+<br><tt> memset( pixmap.buffer, 0, pixmap.cols*pixmap.rows );</tt>
+<p><i><tt> // translate the outline to match (0,0) with the glyph's</tt></i>
+<br><i><tt> // lower left corner (ignore the bearings)</tt></i>
+<br><i><tt> // the cbox is grid-fitted, we won't ruin the hinting.</tt></i>
+<br><i><tt> //</tt></i>
+<br><tt> FT_Translate_Outline( &outline, -cbox.xMin, -cbox.yMin
+);</tt>
+<p><i><tt> // render the anti-aliased glyph pixmap</tt></i>
+<br><tt> error = FT_Get_Outline_Bitmap( library, &outline, &pixmap
+);</tt>
+<p><tt> // save the bearings for later use..</tt>
+<br><tt> corner_x = cbox.xMin / 64;</tt>
+<br><tt> corner_y = cbox.yMin / 64;</tt>
+<br><tt>}</tt>
+<p>The resulting pixmap is always anti-aliased.</blockquote>
+</blockquote>
+
+<h3>
+3. Possible enhancements :</h3>
+
+<blockquote>FreeType's raster (i.e. its scan-line converter) is currently
+limited to producing either 1-bit bitmaps or anti-aliased 8-bit pixmaps.
+It is not possible, for example, to draw directly a bitmapped glyph image
+into a 4, 8 or 16-bit pixmap through a call to FT_Get_Outline_Bitmap.
+<p>Moreover, the anti-aliasing filter is limited to use 5 or 17 levels
+of grays (through 2x2 and 4x4 sub-sampling). There are cases where this
+could seem insufficient for optimal results and where a higher number of
+levels like 64 or 128 would be a good thing.
+<p>These enhancements are all possible but not planned for an immediate
+future of the FreeType engine.</blockquote>
+</blockquote>
+
+</body>
+</html>
binary files /dev/null b/docs/glyph_conventions/grid_1.gif differ
binary files /dev/null b/docs/glyph_conventions/objects_diagram.gif differ
binary files /dev/null b/docs/glyph_conventions/objects_diagram2.gif differ
binary files /dev/null b/docs/glyph_conventions/points_conic.gif differ
binary files /dev/null b/docs/glyph_conventions/points_conic2.gif differ
binary files /dev/null b/docs/glyph_conventions/points_cubic.gif differ
binary files /dev/null b/docs/glyph_conventions/points_segment.gif differ
binary files /dev/null b/docs/glyph_conventions/twlewis1.gif differ
binary files /dev/null b/docs/glyph_conventions/twlewis2.gif differ
binary files /dev/null b/docs/glyph_conventions/up_flow.gif differ
binary files /dev/null b/docs/internals/Image1.gif differ
binary files /dev/null b/docs/internals/Image2.gif differ
binary files /dev/null b/docs/internals/Image3.gif differ
binary files /dev/null b/docs/internals/Image4.gif differ
--- /dev/null
+++ b/docs/internals/freetype_internals.html
@@ -1,0 +1,788 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="David Turner">
+ <meta name="GENERATOR" content="Mozilla/4.5 [fr] (Win98; I) [Netscape]">
+ <title>FreeType 2 Internals</title>
+</head>
+<body>
+
+<body text="#000000"
+ bgcolor="#FFFFFF"
+ link="#0000EF"
+ vlink="#51188E"
+ alink="#FF0000">
+
+<center>
+<h1>
+FreeType 2.0 Internals</h1></center>
+
+<center>
+<h2>
+Version 1.0</h2></center>
+
+<center>
+<h3>
+© 1999 David Turner (<a href="fichier :///[email protected]">[email protected]</a>)<br>
+© 1999 The FreeType Development Team (<a href="fichier :///[email protected]">[email protected]</a>)</h3></center>
+
+<p><br>
+<hr WIDTH="100%">
+<br>
+<h2>
+Introduction:</h2>
+
+<blockquote>This document describes in great details the internals of the
+FreeType 2.0 library. It is a must read for porters and developers alike.
+Its purpose is to present the engine's objects, their roles and interactions.
+It is assumed that the <b><i>FreeType Glyph Conventions</i></b> document
+has been read.
+<p>We advise porters to also read the <b><i>FreeType Porting Guide</i></b>
+after this document. Would-be hackers and maintainers are of course encouraged
+to read the <b><i>FreeType Coding Conventions</i></b> document too. The
+development of a new driver is described in more details in the <b><i>FreeType
+Driver HowTo</i></b> document.</blockquote>
+
+<p><br>
+<hr WIDTH="100%">
+<h2>
+I. Overview :</h2>
+
+<blockquote>
+<h3>
+1. Features (and what's new) :</h3>
+
+<blockquote>FreeType 2.0 has a number of important new features that were
+not found in the 1.x releases :
+<br>
+<blockquote><b>font-format independent API</b>
+<br>FreeType 2.0 is able to support any kind of font format, be it fixed
+or scalable, through the use of pluggable "font drivers". These drivers
+can be added or replaced at run time, while applications use a new font
+format-independent API.
+<p><b>advanced stream caching</b>
+<br>2.0 is able to control the number of concurrently opened streams when
+using fonts. It is thus possible to open dozens or hundreds of font faces
+without running out of system resources.
+<p><b>real reentrancy support</b>
+<br>It is now possible to use FreeType as a shared library with no static
+data in a multi-threaded environment. The synchronization model has also
+been simplified in order to make font driver writing easier. Of course,
+you can build FreeType with no thread support to get a smaller library.
+<p><b>support for cubic beziers and 17-levels anti-aliasing</b>
+<br>The FreeType scan-line converter (a.k.a. raster) now supports cubic
+bezier arcs seamlessly. It also provides a new anti-aliasing mode which
+uses a palette of 17 levels of grays.
+<br> </blockquote>
+It also features the following :
+<blockquote><b>performance improvements :</b>
+<br>The FreeType raster has been optimized, and the generation of anti-aliased
+pixmaps is now 60% faster than in the 1.x release. Moreover, the TrueType
+bytecode interpreter has been profiled and greatly optimised.
+<p><b>easier portability</b>
+<br>Porting and configuring FreeType is now much easier. A single file
+must be provided for system-specific operations (like memory, i/o, thread
+management), and a single configuration header is used to select the build
+you need.
+<br> </blockquote>
+</blockquote>
+
+<h3>
+2. Architecture :</h3>
+
+<blockquote>The engine is now split in several parts, which are :
+<h4>
+a. The base layer :</h4>
+
+<blockquote>This part contains all the font-format independent features
+of the engine which are :
+<ul>
+<li>
+computations/scaling</li>
+
+<li>
+list processing</li>
+
+<li>
+outline processing</li>
+
+<li>
+scan-line converter</li>
+
+<li>
+stream manager</li>
+
+<li>
+base object classes</li>
+
+<li>
+debugging & traces</li>
+
+<li>
+high-level API functions</li>
+
+<li>
+low-level system object (memory, i/o, threads)</li>
+</ul>
+</blockquote>
+
+<h4>
+b. The font drivers :</h4>
+
+<blockquote>Each font format is managed with the use of a single font driver
+object. The base layer is able to manage several drivers, and these can
+be easily added, removed or upgraded at runtime. Each driver has the following
+features and functions :
+<ul>
+<li>
+auto-check font format when opening a font resource (i.e. file)</li>
+
+<li>
+access, load and/or extract all tables and data from the font file</li>
+
+<li>
+grid-fit/hint the glyph outlines (in the case of scalable formats like
+TrueType or Type1)</li>
+
+<li>
+provide extensions to access font format-specific data and tables from
+the font file</li>
+</ul>
+Note that FreeType 2.0 is a font service. Its purpose is to provide a unified
+API for all kinds of fonts and extract individual glyph images and metrics.
+However, it does not render text itself, as this operation is left to the
+developer, or to higher-level libraries built on top of FreeType. Here
+are a few features that are thus not implemented :
+<blockquote>1) Text string rendering
+<br>2) Glyph bitmap/outline caching for improved performance
+<br>3) Synthetic fonts (i.e. italicising, emboldening, underlining)
+<br>4) Contextual glyph substitution and other advanced layout processes</blockquote>
+Note that features 1 through 3 should be provided by the SemTex library,
+which may soon become part of the standard FreeType distribution.</blockquote>
+</blockquote>
+</blockquote>
+
+<p><br>
+<hr WIDTH="100%">
+<h2>
+II. Design :</h2>
+
+<blockquote>
+<h3>
+1. Objects :</h3>
+
+<blockquote>They are several kinds of objects in FreeType, which can be
+described as follows :
+<blockquote><b>Base objects</b>
+<br>These objects do not relate directly to font data, but to the way it
+is organised and managed. It is the basic core and provides functions that
+are heavily used by each font driver. Examples are the resource objects,
+used to describe font files, the system object used to manage low-level
+system operations, or the raster object, used to convert vector outlines
+into bitmaps or anti-aliased pixmaps. Most of the base objects are not
+directly visible for client applications of FreeType.
+<p><b>Font objects</b>
+<br>The font objects directly model the data as it is found in font files.
+The root classes implemented in the base layer like <tt>FT_Face</tt>, <tt>FT_Size</tt>,
+<tt>FT_GlyphSlot</tt>,
+must be derived in each font driver.</blockquote>
+Objects are defined in the files "<tt>base/freetype.h</tt>" and "<tt>base/ftobjs.h</tt>".
+The former contains all the public object definitions usable by client
+applications. The latter contains private definitions used by the rest
+of the base layer and each font driver.</blockquote>
+
+<h3>
+2. List management</h3>
+
+<blockquote>The "<tt>base/ftlist.c</tt>" component a very simple doubly-linked
+list facility which is used by the rest of the engine to create and process
+lists, including iteration and finalisation. The definition of the list
+node and functions are placed in the "<tt>base/freetype.h</tt>" to let
+client applications access listed objects as they like.
+<p>The base list type is <tt>FT_List</tt>, which links nodes of type <tt>FT_ListNode</tt>
+together.
+<br> </blockquote>
+
+<h3>
+3. Limited encapsulation</h3>
+
+<blockquote>Unlike what happened in the 1.x releases, the <tt>FT_Face</tt>,
+<tt>FT_Size</tt>,
+<tt>FT_GlyphSlot</tt> and <tt>FT_CharMap</tt> types are no longer blind
+pointers to opaque types. Rather, the corresponding structures are now
+public (and defined in "<tt>base/freetype.h</tt>", see <tt>FT_FaceRec</tt>,
+<tt>FT_SizeRec</tt>,
+etc..) in order to let client applications read directly the various object
+attributes they're interested in.
+<p>This breaks encapsulation of implementation, famed by OOP, but was chosen
+because:
+<br>
+<ul>
+<li>
+it simplifies a lot the work of client applications and libraries which
+don't need to perform a function call everytime they want to read one important
+object attribute (nor does it force them to cache these attributes in their
+own structures).</li>
+</ul>
+
+<ul>
+<li>
+It reduces greatly the API, as many <tt>FT_Get_XXX</tt> functions are avoided.</li>
+</ul>
+
+<ul>
+<li>
+Higher-level libraries are able to access data directly. When it
+is used frequently, they don't need to cache it in their own structures.</li>
+</ul>
+
+<ul>
+<li>
+It is possible to tightly link FreeType objects with higher-level ones,
+in a clearer and more efficient way. This is very important when one wants
+to write a C++ wrapper or a text rendering library on top of FreeType (actually,
+both projects were performed in an earlier version of FreeType 2.0 which
+featured classic encapsulation through get/set methods. The resulting code
+was ugly and slow. Moving to a limited encapsulation approach simplified
+so many things that the compiled code size was reduced by a factor of two
+!).</li>
+</ul>
+
+<ul>
+<li>
+Finally, the API and font object structures were designed after the creation
+of two scalable font drivers and one bitmap font driver. They are now very
+stable and the public (visible) attributes are not going to change.</li>
+</ul>
+</blockquote>
+</blockquote>
+
+<p><br>
+<hr WIDTH="100%">
+<h2>
+III. Base objects :</h2>
+
+<blockquote>This section describes the FreeType base object classes :
+<br>
+<h3>
+1. System objects :</h3>
+
+<blockquote>The system class is in charge of managing all low-level and
+system-specific operations. This means simply memory management, i/o access
+and thread synchronisation. It is implemented by the "<tt>ftsys.c</tt>"
+component, whose source must be located in the configuration directory
+when building FreeType. (e.g. "<tt>lib/arch/ansi/ftsys.c</tt>" for an ANSI
+build, "<tt>lib/arch/unix/ftsys.c</tt>" for a Unix one, etc..).
+<p>Porting FreeType 2.0 really means providing a new implementation of
+<tt>ftsys</tt>
+(along with a few configuration file changes). Note however that its interface
+is common to all ports, and located in "<tt>base/ftsys.h</tt>".</blockquote>
+
+<h3>
+2. Resources and Streams:</h3>
+
+<blockquote>The concepts of files as storages, and files as streams has
+been separated for FreeType 2.0. The "<b><i>resource</i></b>" concept was
+introduced while the "<b><i>stream</i></b>" one has been redefined. Here
+is how they work together :
+<ul>
+<li>
+a "<b>resource</b>" is an object which models a file, seen as a storage.
+There are several classes of resources, which differ usually in two ways
+: the way their data is accessed by applications, and the way they're named
+within the system.</li>
+</ul>
+
+<ul>For example, when parsing files with the ANSI C library, data has to
+be read (through fseek/fread) into intermediate buffers before it can be
+decoded. This scheme is highly portable, but rather inefficient; when using
+it, we'll describe the file as a disk-based resource.
+<p>As most modern operating systems now provide memory-mapped files, which
+allow direct access while improving performance and reducing memory usage.
+Because data can be read directly in memory, we'll speak of a memory-based
+resource in this case. For embedded systems (like printers, PDAs, etc..),
+ROM-fonts fit into this category as well.
+<p>Regarding naming, most systems use a string to name files in their storage
+hierarchy. Though a typical pathname is an ASCII string (<tt>'c:\windows\fonts\times.ttf'</tt>
+on Windows, <tt>'/home/fonts/times.ttf'</tt> on Unix), some OSes use different
+schemes, varying from Unicode character strings to file i-node numbers.
+These details are platform-specific and must be hidden to the rest of the
+library in resource objects.
+<p>A resource encapsulates the lowest details regarding a file, though
+it should have NO STATE. Note that the nature or type of a resource (i.e.
+disk or memory based) is important to the "stream" component only. The
+rest of the library and font drivers work transparently from their implementation.
+<p>Note also that it is perfectly possible to mix resources of distinct
+natures in a single build</ul>
+
+<ul>
+<li>
+a "<b>stream</b>" is an object which is used to extract bytes from a resource.
+Only resource objects can create streams, through its <i><tt>Open_Stream()</tt></i>
+method. A stream has state, which typically consist of a file "cursor",
+some intermediate buffers, a "current frame" and, of course, methods used
+to extract the data from streams, resolving endianess and alignement issues.</li>
+</ul>
+Data can be extracted from streams through direct reads, or through the
+use of <b>frames</b>. A frame models <i>a run of contiguous bytes</i> starting
+from the current stream position, and of liberal size.
+<p>Methods exist to extract successive integers of any sizes, while resolving
+endianess and alignement issues. Rather than a long rethorical explanation,
+here's how frames are typically used :
+<blockquote><tt>{</tt>
+<br><tt> �</tt>
+<br><tt> FT_Error error;</tt>
+<p><tt> error = FT_Access_Frame( stream, 14 );</tt>
+<br><tt> if (error) goto Fail;</tt>
+<p><tt> val1 = FT_Get_Short(stream);</tt>
+<br><tt> val2 = FT_Get_Long(stream);</tt>
+<br><tt> val3 = FT_Get_Long(stream);</tt>
+<br><tt> val4 = FT_Get_Long(stream);</tt>
+<p><tt> FT_Forget_Frame(stream);</tt>
+<br><tt> �</tt>
+<br><tt>}</tt></blockquote>
+This code does the following :
+<blockquote>
+<ol>
+<li>
+ first, it "loads" the next 14 bytes from the current cursor position
+into the stream's frame, using the <tt>FT_Access_Frame</tt> API. An error
+is returned if, for example, less than 14 bytes are left in the stream
+when the call occurs..</li>
+</ol>
+
+<ol>
+<li>
+ it extract four integers (one 16-bit short, three 32-bit longs) from
+the frame using <tt>FT_Get_Short</tt> and <tt>FT_Get_Long</tt>. These function
+increment the frame's cursor finally, it "releases" the stream's frame.</li>
+</ol>
+
+<ol>
+<li>
+ Each stream has its own frame which can be accessed independently,
+however, nested frame accesses are not allowed. Note also that the bytes
+are effectively read from the stream on the call to <tt>FT_Access_Frame</tt>.
+Any subsequent read will occur after these 14 bytes, even if less are extracted
+through <tt>FT_Get_xxxx</tt> functions.</li>
+</ol>
+</blockquote>
+The implementation of the resource class is located in the system component
+(i.e. "<tt>arch/<i><system></i>/ftsys.c</tt>") and can thus be tailored
+for a specific port of the engine.
+<p>A resource can be created through the <tt>FT_New_Resource</tt> API;
+however this function only accepts an 8-bit pathname to name the target
+font file, which may be inappropriate for systems using a different naming
+scheme (e.g. UTF-16 pathname, i-node number, etc..). It's up to the porter
+then to provide its own resource creation function (like. <tt>FT_New_UTF16_Resource</tt>,
+for example) in its version of "<tt>ftsys.c</tt>".
+<p>Note that <tt>FT_New_Resource</tt> will fail and return an error code
+if the font file cannot be found, or when its font format isn't recognized
+by one of the drivers installed in the library. The list or resources created
+for a given library instance is thus the list of "installed font files".
+<br> </blockquote>
+
+<h3>
+3. Stream Manager :</h3>
+
+<blockquote>As said before, resources do not bear states, while streams
+do. Stream creation is also a very lengthy process, depending on the target
+operating system (e.g. "<tt>fopen</tt>" is usually very slow).
+<p>Because a typical font driver will want to use a new stream on each
+access to individual glyphs, being able to cache the most recently used
+streams is a requirement in order to avoid considerable performance penalties.
+<p>Stream caching is thus implemented in the "<tt>ftstream</tt>" component.
+It maintains a simple LRU list of the least recently used streams. Each
+stream in the cache is still opened and available for immediate processing.
+When a resource is destroyed, the stream cache is parsed to remove all
+related cached streams.
+<p>Stream caching can also be disabled with a configuration macro when
+using only ROM based resources (where stream opening is really quick).
+It is implemented through a Stream Manager object (see <tt>ftstream.c</tt>).
+<br> </blockquote>
+
+<h3>
+4. Raster :</h3>
+
+<blockquote>The raster is the component is charge of generating bitmaps
+and anti-aliased pixmaps from vectorial outline definitions. It is also
+sometimes called the scan-line converter. It has been completely rewritten
+for FreeType 2.0 in order to support third-order bezier arcs, 17-levels
+anti-aliasing (through 4x4 sub-sampling), improved performance, as well
+as stand-alone compilation (in order to include it in other graphics package
+without requiring the rest of the FreeType engine).
+<p>Because it was designed for easy re-use and embedded systems, the raster
+is a rtaher 'unusual' piece of code, because it doesn't perform a single
+memory allocation, nor contain any static or global variable. Rather, it
+is up to client applications to allocate a raster object in their own heap
+or memory space.
+<p>Each raster object also needs a rather large block of memory called
+its render pool. The pool is used during rendering (and only during it)
+in order to perform the scan-line conversion. Because it accesses and manages
+data directly within the pool, the raster yelds impressive performance
+as well as bounded memory consumption. It can also automatically decompose
+large requests into smaller individual sub-tasks.
+<p>Finally, it never creates bitmaps or pixmaps, but simply renders into
+them (providing clipping too). These must be described to the raster with
+the help of a <tt>FT_Raster_Map</tt> structure (a very simple bitmap/pixmap
+descriptor).
+<p>Note that when rendering anti-aliased pixmaps, the raster doesn't use
+an intermediate bitmap buffer, as filtering is part of the scan-line conversion
+process.
+<br> </blockquote>
+
+<h3>
+5. Library objects :</h3>
+
+<blockquote>A library object models a single instance of the FreeType engine.
+This is useful when FreeType is compiled as a shared object (DLL), as it
+can then be used by several applications, each with its own resources and
+objects.
+<p>The <tt>FT_Library</tt> type is an opaque handle to a library object.
+Such an object is created through a call to <tt>FT_Init_FreeType</tt>.
+Once you don't need it anymore, one can destroy a library object through
+<tt>FT_Done_FreeType</tt>.
+<p>Note that in reentrant builds, several threads can access a single library
+object concurrently. Such a build can be chosen by switching one configuration
+macro in the file '<tt>arch/<i><system></i>/ftconfig.h</tt>'</blockquote>
+
+<h3>
+6. Driver objects :</h3>
+
+<blockquote>A driver object models an instance of a given font driver,
+i.e. an element of FreeType code in charge of handling a given font format,
+like TrueType, Type1, FNT, PCF, etc..
+<p>Each library object contains a given set of driver objects when it is
+created through FT_Init_FreeType, this set being determined at compile
+time (see the file 'base/ftapi.c'). However, removing or adding drivers
+is possible at run-time, in order to make upgrades easy.</blockquote>
+
+<h3>
+7. Diagram</h3>
+
+<blockquote>This diagram show the object relationships for the sole base
+layer. The library object is the root of the object graph :
+<center>
+<p><img SRC="objects_diagram.gif" height=300 width=562></center>
+
+<p>It can be read as follows :
+<br>
+<ul>
+<li>
+Each library object has one system, one raster and one stream manager objects.
+These objects can only belong to one given library.</li>
+</ul>
+
+<ul>
+<li>
+Each library contains one list of 0 or more resources, as well as one list
+of 0 or more driver objects.</li>
+</ul>
+
+<ul>
+<li>
+Each stream manager holds a bounded list ("0..n" where 'n' is the stream
+cache's size) of stream objects. Each stream is related to one given resource
+object. Each resource may be related to zero or one stream.</li>
+</ul>
+
+<ul>
+<li>
+Each resource is related to one driver object. A driver is related to 0
+or more resources.</li>
+</ul>
+</blockquote>
+</blockquote>
+
+<p><br>
+<hr WIDTH="100%">
+<h2>
+IV. Font objects :</h2>
+
+<blockquote>Font objects are used to directly map the information found
+in font files into several categories :
+<br>
+<h3>
+1. Face objects :</h3>
+
+<blockquote>Face objects are used to model individual font faces. They
+encapsulate data which isn't related to a specific character size, or a
+specific glyph or glyph set. Usually, this means :
+<ul>
+<li>
+the font face's family and style names (e.g. "Palatino" + "Regular")</li>
+
+<li>
+some flags indicating which kind of font this is (scalable or fixed ? fixed-width
+or proportional ? horizontal or vertical ? etc�)</li>
+
+<li>
+the number of glyphs, charmaps and eventually fixed character sizes (for
+bitmap formats) found in the font face.</li>
+
+<li>
+for scalable formats, some important metrics like the ascender, descender,
+global font bounding box, maximum advance width, etc.. expressed in notional
+font/grid units (as well as the number of units on the EM grid).</li>
+</ul>
+A face is created from a resource object, with the <tt>FT_New_Face</tt>
+API. Each driver contains a list of opened face objects for the resources
+it manages. When a driver is removed or destroyed, all its child faces
+are discarded automatically with it.</blockquote>
+
+<h3>
+2. Size objects :</h3>
+
+<blockquote>Size objects are used to model a given character dimension
+for a given device resolution (which really means a given character pixel
+dimensions).
+<p>Each size object is created from a parent face object. The object can
+be reset to new dimensions at any time. Each face object holds a list of
+all its child sizes, these are destroyed automatically when the face object
+is discarded.
+<p>The metrics contains metrics, expressed in pixels, for the ascender,
+descender, maximum advance width, etc..
+<br> </blockquote>
+
+<h3>
+3. Glyph Slot objects :</h3>
+
+<blockquote>A glyph slot is a container where one can load individual glyphs,
+be they in vector of bitmap format. Each slot also contains metrics for
+the glyph it contains.
+<p>Each face object contains one or more glyph slot object : the first
+glyph slot is created automatically with its parent face, and it is possible
+to add new glyph slots (this is rarely used outside of debugging purposes).
+<br> </blockquote>
+
+<h3>
+4. CharMap objects :</h3>
+
+<blockquote>A charmap object is a sort of dictionary whose task is to translate
+character codes in a given character encoding (like ShiftJIS, Unicode,
+ANSI, etc..) into glyph indexes in a given font face.
+<p>A face object contains one or more charmap objects. All charmap objects
+are created when the parent face is created, though they're not directly
+visible to client applications (rather, they can be enumerated through
+FT_Get_First_CharMap and FT_Get_Next_CharMap, or more simply picked adequately
+with FT_Find_CharMap for a set of given encodings).
+<br> </blockquote>
+
+<h3>
+5. Diagram</h3>
+
+<blockquote>The following diagram illustrates the relationships between
+font objects :
+<center>
+<p><img SRC="objects_diagram2.gif" height=327 width=561></center>
+
+<p>Which can be read as :
+<br>
+<ul>
+<li>
+each resource may have zero or more child face objects "opened" for it.
+The number of faces is bounded by the number of font faces within the font
+resource.</li>
+</ul>
+
+<ul>
+<li>
+each driver holds a list of all the faces opened for the resources it manages.
+When the driver is removed, its child faces are discarded automatically.</li>
+</ul>
+
+<ul>
+<li>
+each face object has one single parent resource, and one single driver.</li>
+</ul>
+
+<ul>
+<li>
+each face has one or more charmaps, and one or more glyph slots</li>
+</ul>
+
+<ul>
+<li>
+each face holds a list of zero or more child size objects</li>
+</ul>
+
+<ul>
+<li>
+each charmap, glyph slot and size is related to one given parent face.
+These objects are destroyed automatically when the parent face is discarded.</li>
+</ul>
+</blockquote>
+</blockquote>
+
+<p><br>
+<hr WIDTH="100%">
+<h2>
+V. Driver Interface :</h2>
+
+<blockquote>A font driver is added to a given library object through the
+<tt>FT_Add_Driver</tt>
+API. This function receives a structure known as a <tt>FT_DriverInterface</tt>,
+which describes the driver's basic properties.
+<p>The <tt>FT_DriverInterface</tt> contains a set of function pointers
+used for the base FreeType functionalities. However, each driver can also
+provide a font-format-specific extended interface to allow client applications
+to use more advanced features.
+<br>
+<h3>
+1. Common Interface</h3>
+
+<blockquote>The structure of <tt>FT_DriverInterface</tt> is rather simple,
+and defined in "<tt>base/ftdriver.h</tt>". It must be well known by any
+developer who wants to write a new driver for the engine. We advise reading
+the <b><i>FreeType Driver HowTo</i></b> as well as the source code of existing
+drivers. Source comments.</blockquote>
+
+<h3>
+2. Driver-specific extensions</h3>
+
+<blockquote>The field of the <tt>FT_DriverInterface</tt> structure is a
+typeless pointer to a format-specific interface. This extended interface
+is usually a structure containing function pointers as well as other kind
+of information related to the driver.
+<p>It is assumed that client applications that wish to use the driver-specific
+extensions are able to <tt>#include</tt> the relevant header files to understand
+the format-specific interface structure.</blockquote>
+</blockquote>
+
+<hr WIDTH="100%">
+<h2>
+VI. Configuration:</h2>
+
+<blockquote>This section relates to the configuration of the FreeType library.
+By configuration, we mean selection of build options as well as the choice
+of font drivers to be used for each new library object.
+<br>
+<h3>
+1. Configuration files :</h3>
+
+<blockquote>A single file is used to configure the FreeType base engine.
+As it is considered system-specific, it is located in the architecture
+directories of the library, under the name "arch/<system>/ftconfig.h".
+Note that the same directory should also contain a platform-specific implementation
+of "ftsys.c".
+<p>The configuration files is a simple C header which is included by the
+engine's sources during compilation. It is not included in "freetype.h",
+and hence doesn't need to be copied when installing the FreeType headers
+on your system.
+<p>It is made of a series of #define or #undef statements, which are used
+to select or turn off a specific option. Each option is documented with
+heavy comments, and some of them are explained below.</blockquote>
+
+<h3>
+2. Building and Makefiles :</h3>
+
+<blockquote>FreeType 2.0 is more complex than its 1.x release. In order
+to facilitate maintenance, as well as ease considerably the writing of
+new font drivers, <b><i>only GNU Make is supported with FreeType 2.0</i></b>.
+However, it is possible to use any compiler, as well as any object or library
+prefix (<tt>.o, .obj, .a, .lib</tt> etc..) with them.
+<p>To build FreeType 2.0, one has to be in the library directory, then
+invoke its platform-specific makefile. For a Unix system, this would be
+:
+<blockquote>
+<blockquote><tt>% cd freetype2/lib</tt>
+<br><tt>% make -f arch/unix/Makefile</tt>
+<p>where '<tt>make</tt>' is really GNU Make !</blockquote>
+</blockquote>
+The system-specific <tt>Makefile</tt> located in '<tt>arch/<i><system></i></tt>'
+is a tiny file used to define several variables. It then includes the file
+<tt>freetype2/lib/Makefile.lib</tt>,
+which contains all the gory details about library compilation. The system-specific
+<tt>Makefile</tt> can be very easily modified to accomodate a new compiler/platform
+(see the comments within one of these files).
+<p>Each font driver is located in a directory like "<tt>freetype2/lib/drivers/<i><formatdir></i></tt>".
+For example, the TrueType driver is located in "<tt>drivers/truetype</tt>".
+Each driver directory must contain a <tt>Makefile</tt> which will be included
+by <tt>Makefile.lib</tt>. The former is used to define and build driver
+object files.
+<br>
+<p><br>
+<center>
+<p><img SRC="build_diagram.gif" height=284 width=559></center>
+</blockquote>
+
+<h3>
+3. Make options :</h3>
+
+<blockquote>The base layer, as well as each font driver, are made up of
+several C sources. Traditionally, one compiles each source (i.e. '<tt>.c</tt>'
+file) into an object ('<tt>.o</tt>' or '<tt>.obj</tt>') file, and all of
+them are grouped into a library file (i.e. '<tt>.a</tt>' or '<tt>.lib</tt>').
+<p>By default, FreeType takes a slightly different approach when it comes
+to compiling each part of the engine. Usually, a single tiny source is
+compiled, which includes all other component sources. This results in a
+single object files, with the benefits or reduced code size, usually better
+compilation as well as a drastic reduction of the number of symbols exported
+by the library. Of course, it is made possible through the use of specific
+declaration macros in the FreeType source (see the definition of <tt>LOCAL_DEF</tt>
+and <tt>LOCAL_FUNC</tt> in <tt>ftconfig.h</tt> for details).
+<p>For a concrete example, see the source code in "<tt>base/ftbase.c</tt>"
+which generates the whole base layer in a single object file. The same
+build process is applied to font drivers, in order to generate one single
+object file per given font format (e.g. <tt>truetype.o</tt>, <tt>type1.o</tt>,
+etc..).
+<p>Compiling the library and drivers in "normal" mode is possible, through
+the use of the '<tt>multi</tt>' target (which really means « multiple
+objects »). For example, calling :
+<blockquote><tt>% make -f arch/ansi/Makefile multi</tt></blockquote>
+Will build the FreeType library by compiling each source file to an individual
+object, then linking them together. You'll notice that the library is significantly
+bigger in this case. Creating a shared dll from a 'multi' build is certainly
+a very poor idea, as this will export a huge quantity of symbols that aren't
+useful to any client application.</blockquote>
+
+<h3>
+4. Adding a driver at compile time</h3>
+
+<blockquote>A driver can be included very easily in the build process by
+including its <tt>Makefile</tt> in <tt>Makefile.lib</tt>. For example,
+the TrueType driver is simply included with the following lines (see <tt>Makefile.lib</tt>):
+<blockquote><tt># TrueType driver rules</tt>
+<br><tt>#</tt>
+<br><tt>include $(DRIVERS_DIR)/truetype/Makefile</tt></blockquote>
+
+<p><br>Where <tt>DRIVERS_DIR</tt> really is "<tt>freetype2/lib/drivers</tt>",
+though this can be redefined. You can, of course specify a different path
+if you want to place your driver sources in another location.
+<p>Note that this only adds the driver's object files to the generated
+library file. A few more steps are needed to make your <tt>FT_Library</tt>
+objects use the driver. They consist in modifying the file "<tt>base/ftinit.c</tt>",
+whose sole purpose is to define the set of driver objects that are to be
+created with each new library object.
+<br> </blockquote>
+
+<h3>
+5. Adding a driver at run time</h3>
+
+<blockquote>New driver objects can be added at run-time through the <tt>FT_Add_Driver</tt>
+API. This function takes a handle to an existing library object, as well
+as a pointer to a given driver interface. This interface is used to create
+a new driver object and register it within the library.
+<p>Similarly, a single driver can be removed from a library anytime through
+<tt>FT_Remove_Driver</tt>.
+This will automatically discard the resources and face objects managed
+by the driver.</blockquote>
+
+<h3>
+6. Custom library objects :</h3>
+
+<blockquote>Finally, it is possible to build custom library objects. You
+need to pass a handle to a valid <tt>FT_System</tt> object to the <tt>FT_Build_Library</tt>
+API. The function will return a handle to the new fresh library object.
+Note that the library has no registered drivers after the call, developers
+have to add them by hand with <tt>FT_Add_Driver</tt>.
+<p>It is thus possible to create two distinct library objects with distinct
+<tt>FT_System</tt>
+implementations in the same session, which can be useful for debugging
+purpose.</blockquote>
+
+<br> </blockquote>
+
+</body>
+</html>
--- /dev/null
+++ b/include/freetype.h
@@ -1,0 +1,2156 @@
+/***************************************************************************/
+/* */
+/* freetype.h */
+/* */
+/* FreeType high-level API and common types (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 FREETYPE_H
+#define FREETYPE_H
+
+
+ /*************************************************************************/
+ /* */
+ /* The `raster' component duplicates some of the declarations in */
+ /* freetype.h for stand-alone use if _FREETYPE_ isn't defined. */
+ /* */
+#define _FREETYPE_
+
+
+ /*************************************************************************/
+ /* */
+ /* The FREETYPE_MAJOR and FREETYPE_MINOR macros are used to version the */
+ /* new FreeType design, which is able to host several kinds of font */
+ /* drivers. It starts at 2.0. Note that each driver has its own */
+ /* version number (for example, the TrueType driver is at 1.2, as */
+ /* defined by the macros TT_FREETYPE_MAJOR and TT_FREETYPE_MINOR in the */
+ /* file `ttlib/truetype.h'. */
+ /* */
+#define FREETYPE_MAJOR 2
+#define FREETYPE_MINOR 0
+
+
+ /*************************************************************************/
+ /* */
+ /* To make freetype.h independent from configuration files we check */
+ /* whether EXPORT_DEF has been defined already. */
+ /* */
+ /* On some systems and compilers (Win32 mostly), an extra keyword is */
+ /* necessary to compile the library as a DLL. */
+ /* */
+#ifndef EXPORT_DEF
+#define EXPORT_DEF extern
+#endif
+
+#include <fterrors.h>
+#include <ftsystem.h>
+#include <ftimage.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_Bool */
+ /* */
+ /* <Description> */
+ /* A typedef of unsigned char, used for simple booleans. */
+ /* */
+ typedef unsigned char FT_Bool;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_FWord */
+ /* */
+ /* <Description> */
+ /* A signed 16-bit integer used to store a distance in original font */
+ /* units. */
+ /* */
+ typedef signed short FT_FWord; /* Distance in FUnits */
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_UFWord */
+ /* */
+ /* <Description> */
+ /* An unsigned 16-bit integer used to store a distance in original */
+ /* font units. */
+ /* */
+ typedef unsigned short FT_UFWord; /* Unsigned distance */
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_Char */
+ /* */
+ /* <Description> */
+ /* A simple typedef for the _signed_ char type. */
+ /* */
+ typedef signed char FT_Char;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_Byte */
+ /* */
+ /* <Description> */
+ /* A simple typedef for the _unsigned_ char type. */
+ /* */
+ typedef unsigned char FT_Byte;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_String */
+ /* */
+ /* <Description> */
+ /* A simple typedef for the char type, usually used for strings. */
+ /* */
+ typedef char FT_String;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_Short */
+ /* */
+ /* <Description> */
+ /* A typedef for signed short. */
+ /* */
+ typedef signed short FT_Short;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_UShort */
+ /* */
+ /* <Description> */
+ /* A typedef for unsigned short. */
+ /* */
+ typedef unsigned short FT_UShort;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_Int */
+ /* */
+ /* <Description> */
+ /* A typedef for the int type. */
+ /* */
+ typedef int FT_Int;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_UInt */
+ /* */
+ /* <Description> */
+ /* A typedef for the unsigned int type. */
+ /* */
+ typedef unsigned int FT_UInt;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_Long */
+ /* */
+ /* <Description> */
+ /* A typedef for signed long. */
+ /* */
+ typedef signed long FT_Long;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_ULong */
+ /* */
+ /* <Description> */
+ /* A typedef for unsigned long. */
+ /* */
+ typedef unsigned long FT_ULong;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_F2Dot14 */
+ /* */
+ /* <Description> */
+ /* A signed 2.14 fixed float type used for unit vectors. */
+ /* */
+ typedef signed short FT_F2Dot14;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_F26Dot6 */
+ /* */
+ /* <Description> */
+ /* A signed 26.6 fixed float type used for vectorial pixel */
+ /* coordinates. */
+ /* */
+ typedef signed long FT_F26Dot6;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_Fixed */
+ /* */
+ /* <Description> */
+ /* This type is used to store 16.16 fixed float values, like scales */
+ /* or matrix coefficients. */
+ /* */
+ typedef signed long FT_Fixed;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_Error */
+ /* */
+ /* <Description> */
+ /* The FreeType error code type. A value of 0 is always interpreted */
+ /* as a successful operation. */
+ /* */
+ typedef int FT_Error;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* FT_UnitVector */
+ /* */
+ /* <Description> */
+ /* A simple structure used to store a 2d vector unit vector. Uses */
+ /* FT_F2Dot14 types. */
+ /* */
+ /* <Fields> */
+ /* x :: Horizontal coordinate. */
+ /* y :: Vertical coordinate. */
+ /* */
+ typedef struct FT_UnitVector_
+ {
+ FT_F2Dot14 x;
+ FT_F2Dot14 y;
+
+ } FT_UnitVector;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* FT_Matrix */
+ /* */
+ /* <Description> */
+ /* A simple structure used to store a 2x2 matrix. Coefficients are */
+ /* in 16.16 fixed float format. The computation performed is: */
+ /* */
+ /* { */
+ /* x' = x*xx + y*xy */
+ /* y' = x*yx + y*yy */
+ /* } */
+ /* */
+ /* <Fields> */
+ /* xx :: Matrix coefficient. */
+ /* xy :: Matrix coefficient. */
+ /* yx :: Matrix coefficient. */
+ /* yy :: Matrix coefficient. */
+ /* */
+ typedef struct FT_Matrix_
+ {
+ FT_Fixed xx, xy;
+ FT_Fixed yx, yy;
+
+ } FT_Matrix;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* FT_BBox */
+ /* */
+ /* <Description> */
+ /* A structure used to hold an outline's bounding box, i.e., the */
+ /* coordinates of its extrema in the horizontal and vertical */
+ /* directions. */
+ /* */
+ /* <Fields> */
+ /* xMin :: The horizontal minimum (left-most). */
+ /* yMin :: The vertical minimum (bottom-most). */
+ /* xMax :: The horizontal maximum (right-most). */
+ /* yMax :: The vertical maximum (top-most). */
+ /* */
+ typedef struct FT_BBox_
+ {
+ FT_Pos xMin, yMin;
+ FT_Pos xMax, yMax;
+
+ } FT_BBox;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Macro> */
+ /* FT_MAKE_TAG */
+ /* */
+ /* <Description> */
+ /* This macro converts four letter tags which are used to label */
+ /* TrueType tables into an unsigned long to be used within FreeType. */
+ /* */
+#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \
+ (((FT_ULong)_x1 << 24) | \
+ ((FT_ULong)_x2 << 16) | \
+ ((FT_ULong)_x3 << 8) | \
+ (FT_ULong)_x4)
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /* */
+ /* L I S T M A N A G E M E N T */
+ /* */
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_ListNode */
+ /* */
+ /* <Description> */
+ /* Many elements and objects in FreeType are listed through a */
+ /* FT_List record (see FT_ListRec). As its name suggests, a */
+ /* FT_ListNode is a handle to a single list element. */
+ /* */
+ typedef struct FT_ListNodeRec_* FT_ListNode;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_List */
+ /* */
+ /* <Description> */
+ /* A handle to a list record (see FT_ListRec). */
+ /* */
+ typedef struct FT_ListRec_* FT_List;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* FT_ListNodeRec */
+ /* */
+ /* <Description> */
+ /* A structure used to hold a single list element. */
+ /* */
+ /* <Fields> */
+ /* prev :: Previous element in the list. NULL if first. */
+ /* next :: Next element in the list. NULL if last. */
+ /* data :: Typeless pointer to the listed object. */
+ /* */
+ typedef struct FT_ListNodeRec_
+ {
+ FT_ListNode prev;
+ FT_ListNode next;
+ void* data;
+
+ } FT_ListNodeRec;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* FT_ListRec */
+ /* */
+ /* <Description> */
+ /* A structure used to hold a simple doubly-linked list. These are */
+ /* used in many parts of FreeType. */
+ /* */
+ /* <Fields> */
+ /* head :: Head (first element) of doubly-linked list. */
+ /* tail :: Tail (last element) of doubly-linked list. */
+ /* */
+ typedef struct FT_ListRec_
+ {
+ FT_ListNode head;
+ FT_ListNode tail;
+
+ } FT_ListRec;
+
+
+#define FT_IS_EMPTY(list) ( (list).head == 0 )
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /* */
+ /* B A S I C T Y P E S */
+ /* */
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* FT_Glyph_Metrics */
+ /* */
+ /* <Description> */
+ /* A structure used to model the metrics of a single glyph. Note */
+ /* that values are expressed in 26.6 fractional pixel format or in */
+ /* font units, depending on context. */
+ /* */
+ /* <Fields> */
+ /* width :: The glyph's width. */
+ /* height :: The glyph's height. */
+ /* */
+ /* horiBearingX :: Horizontal left side bearing. */
+ /* horiBearingY :: Horizontal top side bearing. */
+ /* horiAdvance :: Horizontal advance width. */
+ /* */
+ /* vertBearingX :: Vertical left side bearing. */
+ /* vertBearingY :: Vertical top side bearing. */
+ /* vertAdvance :: Vertical advance height. */
+ /* */
+ typedef struct FT_Glyph_Metrics_
+ {
+ FT_Pos width; /* glyph width */
+ FT_Pos height; /* glyph height */
+
+ FT_Pos horiBearingX; /* left side bearing in horizontal layouts */
+ FT_Pos horiBearingY; /* top side bearing in horizontal layouts */
+ FT_Pos horiAdvance; /* advance width for horizontal layout */
+
+ FT_Pos vertBearingX; /* left side bearing in vertical layouts */
+ FT_Pos vertBearingY; /* top side bearing in vertical layouts */
+ FT_Pos vertAdvance; /* advance height for vertical layout */
+
+ } FT_Glyph_Metrics;
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* FT_Generic_Finalizer */
+ /* */
+ /* <Description> */
+ /* Describes a function used to destroy the `client' data of any */
+ /* FreeType object. See the description of the FT_Generic type for */
+ /* details of usage. */
+ /* */
+ /* <Input> */
+ /* The address of the FreeType object which is under finalisation. */
+ /* Its client data is accessed through its `generic' field. */
+ /* */
+ typedef void (*FT_Generic_Finalizer)(void* object);
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* FT_Generic */
+ /* */
+ /* <Description> */
+ /* Client applications often need to associate their own data to a */
+ /* variety of FreeType core objects. For example, a text layout API */
+ /* might want to associate a glyph cache to a given size object. */
+ /* */
+ /* Most FreeType object contains a `generic' field, of type */
+ /* FT_Generic, which usage is left to client applications and font */
+ /* servers. */
+ /* */
+ /* It can be used to store a pointer to client-specific data, as well */
+ /* as the address of a `finalizer' function, which will be called by */
+ /* FreeType when the object is destroyed (for example, the previous */
+ /* client example would put the address of the glyph cache destructor */
+ /* in the `finalizer' field). */
+ /* */
+ /* <Fields> */
+ /* data :: A typeless pointer to any client-specified data. This */
+ /* field is completely ignored by the FreeType library. */
+ /* */
+ /* finalizer :: A pointer to a `generic finalizer' function, which */
+ /* will be called when the object is destroyed. If this */
+ /* field is set to NULL, no code will be called. */
+ /* */
+ typedef struct FT_Generic_
+ {
+ void* data;
+ FT_Generic_Finalizer finalizer;
+
+ } FT_Generic;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* FT_Bitmap_Size */
+ /* */
+ /* <Description> */
+ /* An extremely simple structure used to model the size of a bitmap */
+ /* strike (i.e., a bitmap instance of the font for a given */
+ /* resolution) in a fixed-size font face. This is used for the */
+ /* `available_sizes' field of the FT_Face_Properties structure. */
+ /* */
+ /* <Fields> */
+ /* height :: The character height in pixels. */
+ /* width :: The character width in pixels. */
+ /* */
+ typedef struct FT_Bitmap_Size_
+ {
+ FT_Short height;
+ FT_Short width;
+
+ } FT_Bitmap_Size;
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /* */
+ /* O B J E C T C L A S S E S */
+ /* */
+ /*************************************************************************/
+ /*************************************************************************/
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_Library */
+ /* */
+ /* <Description> */
+ /* A handle to a FreeType library instance. Each `library' is */
+ /* completely independent from the others; it is the `root' of a set */
+ /* of objects like fonts, faces, sizes, etc. */
+ /* */
+ /* It also embeds a system object (see FT_System), as well as a */
+ /* scan-line converter object (see FT_Raster). */
+ /* */
+ /* <Note> */
+ /* Library objects are created through FT_Init_FreeType(). */
+ /* */
+ typedef struct FT_LibraryRec_ *FT_Library;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_Driver */
+ /* */
+ /* <Description> */
+ /* A handle to a given FreeType font driver object. Each font driver */
+ /* is able to create faces, sizes, glyph slots, and charmaps from the */
+ /* resources whose format it supports. */
+ /* */
+ /* A driver can support either bitmap, graymap, or scalable font */
+ /* formats. */
+ /* */
+ typedef struct FT_DriverRec_* FT_Driver;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_Face */
+ /* */
+ /* <Description> */
+ /* A handle to a given driver face object. A face object contains */
+ /* all the instance and glyph independent data of a font file */
+ /* typeface. */
+ /* */
+ /* A face object is created from a resource object through the */
+ /* new_face() method of a given driver. */
+ /* */
+ typedef struct FT_FaceRec_* FT_Face;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_Size */
+ /* */
+ /* <Description> */
+ /* A handle to a given driver size object. Such an object models the */
+ /* _resolution_ AND _size_ dependent state of a given driver face */
+ /* size. */
+ /* */
+ /* A size object is always created from a given face object. It is */
+ /* discarded automatically by its parent face. */
+ /* */
+ typedef struct FT_SizeRec_* FT_Size;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_GlyphSlot */
+ /* */
+ /* <Description> */
+ /* A handle to a given `glyph slot'. A slot is a container where it */
+ /* is possible to load any of the glyphs contained within its parent */
+ /* face. */
+ /* */
+ /* A glyph slot is created from a given face object. It is discarded */
+ /* automatically by its parent face. */
+ /* */
+ typedef struct FT_GlyphSlotRec_* FT_GlyphSlot;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_CharMap */
+ /* */
+ /* <Description> */
+ /* A handle to a given character map. A charmap is used to translate */
+ /* character codes in a given encoding into glyph indexes for its */
+ /* parent's face. Some font formats may provide several charmaps per */
+ /* font. */
+ /* */
+ /* A charmap is created from a given face object. It is discarded */
+ /* automatically by its parent face. */
+ /* */
+ typedef struct FT_CharMapRec_* FT_CharMap;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Enum> */
+ /* FT_Encoding */
+ /* */
+ /* <Description> */
+ /* An enumeration used to specify encodings supported by charmaps. */
+ /* Used in the FT_Select_CharMap() API function. */
+ /* */
+ /* <Note> */
+ /* Because of 32-bit charcodes defined in Unicode (i.e., surrogates), */
+ /* all character codes must be expressed as FT_Longs. */
+ /* */
+ typedef enum FT_Encoding_
+ {
+ ft_encoding_none = 0,
+ ft_encoding_symbol = 0,
+ ft_encoding_unicode = FT_MAKE_TAG('u','n','i','c'),
+ ft_encoding_latin_2 = FT_MAKE_TAG('l','a','t','2'),
+ ft_encoding_sjis = FT_MAKE_TAG('s','j','i','s'),
+ ft_encoding_big5 = FT_MAKE_TAG('b','i','g','5'),
+
+ ft_encoding_adobe_standard = FT_MAKE_TAG('a','d','o','b'),
+ ft_encoding_adobe_expert = FT_MAKE_TAG('a','d','b','e'),
+
+ ft_encoding_apple_roman = FT_MAKE_TAG('a','r','m','n')
+
+ /* other encodings might be defined in the future */
+
+ } FT_Encoding;
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* FT_CharMapRec */
+ /* */
+ /* <Description> */
+ /* The base charmap class. */
+ /* */
+ /* <Fields> */
+ /* face :: A handle to the parent face object. */
+ /* */
+ /* flags :: A set of bit flags used to describe the charmap. */
+ /* Each bit indicates that a given encoding is */
+ /* supported. */
+ /* */
+ /* platform_id :: An ID number describing the platform for the */
+ /* following encoding ID. This comes directly from */
+ /* the TrueType specification and should be emulated */
+ /* for other formats. */
+ /* */
+ /* encoding_id :: A platform specific encoding number. This also */
+ /* comes from the TrueType specification and should be */
+ /* emulated similarly. */
+ /* */
+ /* <Note> */
+ /* We STRONGLY recommmend emulating a Unicode charmap for drivers */
+ /* that do not support TrueType or OpenType. */
+ /* */
+ typedef struct FT_CharMapRec_
+ {
+ FT_Face face;
+ FT_Encoding encoding;
+ FT_UShort platform_id;
+ FT_UShort encoding_id;
+
+ } FT_CharMapRec;
+
+
+
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /* */
+ /* B A S E O B J E C T C L A S S E S */
+ /* */
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+
+ /*************************************************************************/
+ /* */
+ /* FreeType base face class */
+ /* */
+ /* <Struct> */
+ /* FT_FaceRec */
+ /* */
+ /* <Description> */
+ /* FreeType root face class structure. A face object models the */
+ /* resolution and point-size independent data found in a font file. */
+ /* */
+ /* <Fields> */
+ /* driver :: A handle to the face's parent driver */
+ /* object. */
+ /* */
+ /* memory :: A handle to the face's parent memory */
+ /* object. Used for the allocation of */
+ /* subsequent objects. */
+ /* */
+ /* stream :: A handle to the face's stream. */
+ /* */
+ /* num_faces :: In the case where the face is located in a */
+ /* collection (i.e., a resource which embeds */
+ /* several faces), this is the total number of */
+ /* faces found in the resource. 1 by default. */
+ /* */
+ /* face_index :: The index of the face in its resource. */
+ /* Usually, this is 0 for all normal font */
+ /* formats. It can be more in the case of */
+ /* collections (which embed several fonts in a */
+ /* single resource/file). */
+ /* */
+ /* generic :: A field reserved for client uses. See the */
+ /* FT_Generic type description. */
+ /* */
+ /* glyph :: The face's associated glyph slot(s). This */
+ /* object is created automatically with a new */
+ /* face object. However, certain kinds of */
+ /* applications (mainly tools like converters) */
+ /* can need more than one slot to ease their */
+ /* task. */
+ /* */
+ /* sizes_list :: The list of child sizes for this face. */
+ /* */
+ /* face_flags :: A set of bit flags that give important */
+ /* information about the face; see the */
+ /* FT_FACE_FLAG_XXX macros for details. */
+ /* */
+ /* style_flags :: A set of bit flags indicating the style of */
+ /* the face (i.e., italic, bold, underline, */
+ /* etc). */
+ /* */
+ /* num_glyphs :: The total number of glyphs in the face. */
+ /* */
+ /* num_charmaps :: The total number of character maps in the */
+ /* face. */
+ /* */
+ /* family_name :: The face's family name. This is an ASCII */
+ /* string, usually in English, which describes */
+ /* the typeface's family (like `Times New */
+ /* Roman', `Bodoni', `Garamond', etc). This */
+ /* is a least common denominator used to list */
+ /* fonts. Some formats (TrueType & OpenType) */
+ /* provide localized and Unicode versions of */
+ /* this string. Applications should use the */
+ /* format specific interface to access them. */
+ /* */
+ /* style_name :: The face's style name. This is an ASCII */
+ /* string, usually in English, which describes */
+ /* the typeface's style (like `Italic', */
+ /* `Bold', `Condensed', etc). Not all font */
+ /* formats provide a style name, so this field */
+ /* is optional, and can be set to NULL. As */
+ /* for `family_name', some formats provide */
+ /* localized/Unicode versions of this string. */
+ /* Applications should use the format specific */
+ /* interface to access them. */
+ /* */
+ /* num_fixed_sizes :: The number of fixed sizes available in this */
+ /* face. This should be set to 0 for scalable */
+ /* fonts, unless its resource includes a */
+ /* complete set of glyphs (called a `strike') */
+ /* for the specified size. */
+ /* */
+ /* available_sizes :: An array of sizes specifying the available */
+ /* bitmap/graymap sizes that are contained in */
+ /* in the font resource. Should be set to */
+ /* NULL if the field `num_fixed_sizes' is set */
+ /* to 0. */
+ /* */
+ /* bbox :: The font bounding box. Coordinates are */
+ /* expressed in font units (see units_per_EM). */
+ /* The box is large enough to contain any */
+ /* glyph from the font. Thus, bbox.yMax can */
+ /* be seen as the `maximal ascender', */
+ /* bbox.yMin as the `minimal descender', and */
+ /* the maximum glyph width is given by */
+ /* `bbox.xMax-bbox.xMin' (not to be confused */
+ /* with the maximum _advance_width_). Only */
+ /* relevant for scalable formats. */
+ /* */
+ /* units_per_EM :: The number of font units per EM square for */
+ /* this face. This is typically 2048 for */
+ /* TrueType fonts, 1000 for Type1 fonts, and */
+ /* should be set to the (unrealistic) value 1 */
+ /* for fixed-sizes fonts. Only relevant for */
+ /* scalable formats. */
+ /* */
+ /* ascender :: The face's ascender is the vertical */
+ /* distance from the baseline to the topmost */
+ /* point of any glyph in the face. This */
+ /* field's value is positive, expressed in */
+ /* font units. Some font designs use a value */
+ /* different from `bbox.yMax'. Only relevant */
+ /* for scalable formats. */
+ /* */
+ /* descender :: The face's descender is the vertical */
+ /* distance from the baseline to the */
+ /* bottommost point of any glyph in the face. */
+ /* This field's value is positive, expressed */
+ /* in font units. Some font designs use a */
+ /* value different from `-bbox.yMin'. Only */
+ /* relevant for scalable formats. */
+ /* */
+ /* height :: The face's height is the vertical distance */
+ /* from one baseline to the next when writing */
+ /* several lines of text. Its value is always */
+ /* positive, expressed in font units. The */
+ /* value can be computed as */
+ /* `ascender+descender+line_gap' where the */
+ /* value of `line_gap' is also called */
+ /* `external leading'. Only relevant for */
+ /* scalable formats. */
+ /* */
+ /* max_advance_width :: The maximum advance width, in font units, */
+ /* for all glyphs in this face. This can be */
+ /* used to make word wrapping computations */
+ /* faster. Only relevant for scalable */
+ /* formats. */
+ /* */
+ /* max_advance_height :: The maximum advance height, in font units, */
+ /* for all glyphs in this face. This is only */
+ /* relevant for vertical layouts, and should */
+ /* be set to the `height' for fonts that do */
+ /* not provide vertical metrics. Only */
+ /* relevant for scalable formats. */
+ /* */
+ /* underline_position :: The position, in font units, of the */
+ /* underline line for this face. It's the */
+ /* center of the underlining stem. Only */
+ /* relevant for scalable formats. */
+ /* */
+ /* underline_thickness :: The thickness, in font units, of the */
+ /* underline for this face. Only relevant for */
+ /* scalable formats. */
+ /* */
+ /* max_points :: The maximum number of points used to store */
+ /* the vectorial outline of any glyph in this */
+ /* face. If this value cannot be known in */
+ /* advance, or if the face isn't scalable, */
+ /* this should be set to 0. Only relevant for */
+ /* scalable formats. */
+ /* */
+ /* max_contours :: The maximum number of contours used to */
+ /* store the vectorial outline of any glyph in */
+ /* this face. If this value cannot be known */
+ /* in advance, or if the face isn't scalable, */
+ /* this should be set to 0. Only relevant for */
+ /* scalable formats. */
+ /* */
+ typedef struct FT_FaceRec_
+ {
+ FT_Driver driver;
+ FT_Memory memory;
+ FT_Stream stream;
+
+ FT_Long num_faces;
+ FT_Long face_index;
+
+ /* a generic pointer for client use */
+ FT_Generic generic;
+
+ /* the face's current glyph slot(s) */
+ FT_GlyphSlot glyph;
+
+ /* the face's current size, may be nil */
+ FT_Size size;
+
+ /* the face's current charmap */
+ FT_CharMap charmap;
+
+ /* the face's table of available charmaps */
+ FT_Int num_charmaps;
+ FT_CharMap* charmaps;
+
+ /* the face's current sizes list */
+ FT_ListRec sizes_list;
+
+ /* a pointer to the face's extensions block, if supported */
+ void* extensions;
+
+ FT_Long face_flags;
+ FT_Long style_flags;
+
+ FT_Long num_glyphs;
+
+ FT_String* family_name;
+ FT_String* style_name;
+
+ FT_Int num_fixed_sizes;
+ FT_Bitmap_Size* available_sizes;
+
+ /* the following are only relevant for scalable outlines */
+
+ FT_BBox bbox;
+
+ FT_UShort units_per_EM;
+ FT_Short ascender;
+ FT_Short descender;
+ FT_Short height;
+
+ FT_Short max_advance_width;
+ FT_Short max_advance_height;
+
+ FT_Short underline_position;
+ FT_Short underline_thickness;
+
+ FT_UShort max_points;
+ FT_Short max_contours;
+
+ } FT_FaceRec;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Constant> */
+ /* FT_FACE_FLAG_SCALABLE */
+ /* */
+ /* <Description> */
+ /* A bit-field constant, used to indicate that a given face provides */
+ /* vectorial outlines (i.e., TrueType or Type1). This doesn't */
+ /* prevent embedding of bitmap strikes though, i.e., a given face can */
+ /* have both this bit set, and a `num_fixed_sizes' property > 0. */
+ /* */
+#define FT_FACE_FLAG_SCALABLE 1
+
+
+ /*************************************************************************/
+ /* */
+ /* <Constant> */
+ /* FT_FACE_FLAG_FIXED_WIDTH */
+ /* */
+ /* <Description> */
+ /* A bit-field constant, used to indicate that a given face contains */
+ /* fixed-width characters (like Courier, MonoType, etc). */
+ /* */
+#define FT_FACE_FLAG_FIXED_WIDTH 4
+
+
+ /*************************************************************************/
+ /* */
+ /* <Constant> */
+ /* FT_FACE_FLAG_FIXED_WIDTH */
+ /* */
+ /* <Description> */
+ /* A bit-field constant, used to indicate that a given face contains */
+ /* `fixed sizes', i.e., bitmap strikes for some given pixel sizes. */
+ /* See the `num_fixed_sizes' and `available_sizes' face properties */
+ /* for more information. */
+ /* */
+#define FT_FACE_FLAG_FIXED_SIZES 2
+
+
+ /*************************************************************************/
+ /* */
+ /* <Constant> */
+ /* FT_FACE_FLAG_SFNT */
+ /* */
+ /* <Description> */
+ /* A bit-field constant, used to indicate that a given face uses the */
+ /* `sfnt' storage fomat. For now, this means TrueType or OpenType. */
+ /* */
+#define FT_FACE_FLAG_SFNT 8
+
+
+ /*************************************************************************/
+ /* */
+ /* <Constant> */
+ /* FT_FACE_FLAG_HORIZONTAL */
+ /* */
+ /* <Description> */
+ /* A bit-field constant, used to indicate that a given face contains */
+ /* horizontal glyph metrics. This should be set for all common */
+ /* formats, but who knows... */
+ /* */
+#define FT_FACE_FLAG_HORIZONTAL 0x10
+
+
+ /*************************************************************************/
+ /* */
+ /* <Constant> */
+ /* FT_FACE_FLAG_VERTICAL */
+ /* */
+ /* <Description> */
+ /* A bit-field constant, used to indicate that a given face contains */
+ /* vertical glyph metrics. If not set, the glyph loader will */
+ /* synthetize vertical metrics itself to help display vertical text */
+ /* correctly. */
+ /* */
+#define FT_FACE_FLAG_VERTICAL 0x20
+
+
+ /*************************************************************************/
+ /* */
+ /* <Constant> */
+ /* FT_FACE_FLAG_KERNING */
+ /* */
+ /* <Description> */
+ /* A bit-field constant, used to indicate that a given face contains */
+ /* kerning information. When set, this information can be retrieved */
+ /* through the function FT_Get_Kerning(). Note that when unset, this */
+ /* function will always return the kerning vector (0,0). */
+ /* */
+#define FT_FACE_FLAG_KERNING 0x40
+
+
+ /*************************************************************************/
+ /* */
+ /* <Constant> */
+ /* FT_FACE_FLAG_FAST_GLYPHS */
+ /* */
+ /* <Description> */
+ /* A bit-field constant, used to indicate that the glyphs in a given */
+ /* font can be retrieved very quickly, and that a glyph cache is thus */
+ /* not necessary for any of its child size objects. */
+ /* */
+ /* This flag should really be set for fixed-size formats like FNT, */
+ /* where each glyph bitmap is available directly in binary form */
+ /* without any kind of compression. */
+ /* */
+#define FT_FACE_FLAG_FAST_GLYPHS 0x80
+
+
+#define FT_HAS_HORIZONTAL(face) (face->face_flags & FT_FACE_FLAG_HORIZONTAL)
+#define FT_HAS_VERTICAL(face) (face->face_flags & FT_FACE_FLAG_VERTICAL)
+#define FT_HAS_KERNING(face) (face->face_flags & FT_FACE_FLAG_KERNING)
+#define FT_IS_SCALABLE(face) (face->face_flags & FT_FACE_FLAG_SCALABLE)
+#define FT_IS_SFNT(face) (face->face_flags & FT_FACE_FLAG_SFNT)
+#define FT_IS_FIXED_WIDTH(face) (face->face_flags & FT_FACE_FLAG_FIXED_WIDTH)
+#define FT_HAS_FIXED_SIZES(face) (face->face_flags & FT_FACE_FLAG_FIXED_SIZES)
+#define FT_HAS_FAST_GLYPHS(face) (face->face_flags & FT_FACE_FLAG_FAST_GLYPHS)
+
+
+ /*************************************************************************/
+ /* */
+ /* <Constant> */
+ /* FT_STYLE_FLAG_ITALIC */
+ /* */
+ /* <Description> */
+ /* A bit-field constant, used to indicate that a given face is */
+ /* italicized. */
+ /* */
+#define FT_STYLE_FLAG_ITALIC 1
+
+
+ /*************************************************************************/
+ /* */
+ /* <Constant> */
+ /* FT_STYLE_FLAG_BOLD */
+ /* */
+ /* <Description> */
+ /* A bit-field constant, used to indicate that a given face is */
+ /* emboldened. */
+ /* */
+#define FT_STYLE_FLAG_BOLD 2
+
+
+
+ /*************************************************************************/
+ /* */
+ /* FreeType base size metrics */
+ /* */
+ /* <Struct> */
+ /* FT_Size_Metrics */
+ /* */
+ /* <Description> */
+ /* The size metrics structure returned scaled important distances for */
+ /* a given size object. */
+ /* */
+ /* <Fields> */
+ /* pointSize :: The current point size in 26.6 points, where */
+ /* 1 point equals 1/72 inch. */
+ /* */
+ /* x_ppem :: The character width, expressed in integer pixels. */
+ /* This is the width of the EM square expressed in */
+ /* pixels, hence the term `ppem' (pixels per EM). */
+ /* */
+ /* y_ppem :: The character height, expressed in integer pixels. */
+ /* This is the height of the EM square expressed in */
+ /* pixels, hence the term `ppem' (pixels per EM). */
+ /* */
+ /* x_scale :: A simple 16.16 fixed point format coefficient used */
+ /* to scale horizontal distances expressed in font */
+ /* units to fractional (26.6) pixel coordinates. */
+ /* */
+ /* y_scale :: A simple 16.16 fixed point format coefficient used */
+ /* to scale vertical distances expressed in font */
+ /* units to fractional (26.6) pixel coordinates. */
+ /* */
+ /* x_resolution :: The horizontal device resolution for this size */
+ /* object, expressed in integer dots per inches */
+ /* (dpi). As a convention, fixed font formats set */
+ /* this value to 72. */
+ /* */
+ /* y_resolution :: The vertical device resolution for this size */
+ /* object, expressed in integer dots per inches */
+ /* (dpi). As a convention, fixed font formats set */
+ /* this value to 72. */
+ /* */
+ /* ascender :: The ascender, expressed in 26.6 fixed point */
+ /* pixels. Always positive. */
+ /* */
+ /* descender :: The descender, expressed in 26.6 fixed point */
+ /* pixels. Always positive. */
+ /* */
+ /* height :: The text height, expressed in 26.6 fixed point */
+ /* pixels. Always positive. */
+ /* */
+ /* max_advance :: Maximum horizontal advance, expressed in 26.6 */
+ /* fixed point pixels. Always positive. */
+ /* */
+ /* <Note> */
+ /* This structure doesn't return the vertical ascender, descender, */
+ /* and height, as well as a few other esoteric properties. One can */
+ /* however compute these through the size's x_scale and y_scale, */
+ /* applied to the relevant face properties. */
+ /* */
+ typedef struct FT_Size_Metrics_
+ {
+ FT_UShort x_ppem; /* horizontal pixels per EM */
+ FT_UShort y_ppem; /* vertical pixels per EM */
+
+ FT_Fixed x_scale; /* two scales used to convert font units */
+ FT_Fixed y_scale; /* to 26.6 frac. pixel coordinates.. */
+
+ FT_Pos ascender; /* ascender in 26.6 frac. pixels */
+ FT_Pos descender; /* descender in 26.6 frac. pixels */
+ FT_Pos height; /* text height in 26.6 frac. pixels */
+ FT_Pos max_advance; /* max horizontal advance, in 26.6 pixels */
+
+ } FT_Size_Metrics;
+
+
+ /*************************************************************************/
+ /* */
+ /* FreeType base size class */
+ /* */
+ /* <Struct> */
+ /* FT_SizeRec */
+ /* */
+ /* <Description> */
+ /* FreeType root size class structure. A size object models the */
+ /* resolution and pointsize dependent data of a given face. */
+ /* */
+ /* <Fields> */
+ /* face :: Handle to the parent face object. */
+ /* */
+ /* generic :: A typeless pointer, which is unused by the FreeType */
+ /* library or any of its drivers. It can be used by */
+ /* client applications to link their own data to each size */
+ /* object. */
+ /* */
+ /* metrics :: Metrics for this size object. This field is read-only. */
+ /* */
+ typedef struct FT_SizeRec_
+ {
+ FT_Face face; /* parent face object */
+ FT_Generic generic; /* generic pointer for client uses */
+ FT_Size_Metrics metrics; /* size metrics */
+
+ } FT_SizeRec;
+
+
+
+ typedef struct FT_SubGlyph_ FT_SubGlyph;
+
+ struct FT_SubGlyph_
+ {
+ FT_Int index;
+
+ FT_Byte* control_data;
+ FT_Int control_len;
+
+ FT_UShort flags;
+
+ FT_Int arg1;
+ FT_Int arg2;
+
+ FT_Matrix transform;
+ FT_SubGlyph* parent;
+ };
+
+
+#define FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS 1
+#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES 2
+#define FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID 4
+#define FT_SUBGLYPH_FLAG_SCALE 8
+#define FT_SUBGLYPH_FLAG_XY_SCALE 0x40
+#define FT_SUBGLYPH_FLAG_2X2 0x80
+#define FT_SUBGLYPH_FLAG_USE_MY_METRICS 0x200
+
+
+ /*************************************************************************/
+ /* */
+ /* FreeType Glyph Slot base class */
+ /* */
+ /* <Struct> */
+ /* FT_GlyphSlotRec */
+ /* */
+ /* <Description> */
+ /* FreeType root glyph slot class structure. A glyph slot is a */
+ /* container where individual glyphs can be loaded, be they */
+ /* vectorial or bitmap/graymaps.. */
+ /* */
+ /* <Fields> */
+ /* face :: A handle to the parent face object. */
+ /* */
+ /* next :: In some cases (like some font tools), several glyph */
+ /* slots per face object can be a good thing. As this is */
+ /* rare, the glyph slots are listed through a direct, */
+ /* single-linked list using its `next' field. */
+ /* */
+ /* metrics :: The metrics of the last loaded glyph in the slot. The */
+ /* returned values depend on the last load flags (see the */
+ /* FT_Load_Glyph() API function) and can be expressed */
+ /* either in 26.6 fractional pixels or font units. */
+ /* */
+ /* metrics2 :: This field can be used to return alternate glyph */
+ /* metrics after a single load. It can contain either */
+ /* the glyph's metrics in font units, or the scaled but */
+ /* unhinted ones. See the load flags that apply when */
+ /* calling the API function FT_Load_Glyph(). */
+ /* */
+ /* generic :: A typeless pointer which is unused by the FreeType */
+ /* library or any of its drivers. It can be used by */
+ /* client applications to link their own data to each */
+ /* size object. */
+ /* */
+ /* outline :: The outline descriptor for the current glyph, if it */
+ /* is a vectorial one. The nature of the last loaded */
+ /* glyph can be retrieved through the result value */
+ /* returned by FT_Load_Glyph(). */
+ /* */
+ /* bitmap :: The bitmap/graymap descriptor for the current glyph, */
+ /* if it is a fixed-width one. The nature of the last */
+ /* loaded glyph can be retrieved through the result value */
+ /* returned by FT_Load_Glyph(). */
+ /* */
+ /* */
+ typedef struct FT_GlyphSlotRec_
+ {
+ FT_Face face;
+ FT_GlyphSlot next;
+
+ FT_Glyph_Metrics metrics;
+ FT_Glyph_Metrics metrics2;
+
+ FT_Glyph_Tag format;
+ FT_Bitmap bitmap;
+ FT_Outline outline;
+
+ FT_Int num_subglyphs;
+ FT_Int max_subglyphs;
+ FT_SubGlyph* subglyphs;
+
+ void* control_data;
+ void* control_len;
+
+ void* other;
+
+ } FT_GlyphSlotRec;
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /* */
+ /* F U N C T I O N S */
+ /* */
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Init_FreeType */
+ /* */
+ /* <Description> */
+ /* Initializes a new FreeType library object. The set of drivers */
+ /* that are registered by this function is determined at build time. */
+ /* */
+ /* <Output> */
+ /* library :: A handle to a new library object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_Init_FreeType( FT_Library* library );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Done_FreeType */
+ /* */
+ /* <Description> */
+ /* Destroys a given FreeType library object, and all of its childs, */
+ /* including resources, drivers, faces, sizes, etc. */
+ /* */
+ /* <Input> */
+ /* library :: A handle to a target library object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_Done_FreeType( FT_Library library );
+
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Open_Face */
+ /* */
+ /* <Description> */
+ /* Creates a new face object from a given resource and typeface */
+ /* index. */
+ /* */
+ /* <Input> */
+ /* resource :: A handle to a source resource. */
+ /* */
+ /* face_index :: The index of the face within the resource. The */
+ /* first face has index 0. */
+ /* <Output> */
+ /* face :: A handle to a new face object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* Unlike FreeType 1.1, this function automatically creates a glyph */
+ /* slot for the face object which can be accessed directly through */
+ /* `face->slot'. */
+ /* */
+ /* Note that additional slots can be added to each face through the */
+ /* FT_New_GlyphSlot() API function. Slots are linked in a single */
+ /* list through their `next' field. */
+ /* */
+ /* FT_New_Face() can be used to determine and/or check the font */
+ /* format of a given font resource. If the `face_index' field is */
+ /* negative, the function will _not_ return any face handle in */
+ /* `*face'. Its return value should be 0 if the resource is */
+ /* recognized, or non-zero if not. */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_New_Face( FT_Library library,
+ const char* filepathname,
+ FT_Long face_index,
+ FT_Face* face );
+
+
+ EXPORT_DEF
+ FT_Error FT_Open_Face( FT_Library library,
+ FT_Stream stream,
+ FT_Long face_index,
+ FT_Face* face );
+
+ EXPORT_DEF
+ FT_Error FT_New_Memory_Face( FT_Library library,
+ void* file_base,
+ FT_Long file_size,
+ FT_Long face_index,
+ FT_Face *face );
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Done_Face */
+ /* */
+ /* <Description> */
+ /* Discards a given face object, as well as all of its child slots */
+ /* and sizes. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to a target face object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_Done_Face( FT_Face face );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_New_Size */
+ /* */
+ /* <Description> */
+ /* Creates a new size object from a given face object. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to a parent face object. */
+ /* */
+ /* <Output> */
+ /* size :: A handle to a new size object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_New_Size( FT_Face face,
+ FT_Size* size );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Done_Size */
+ /* */
+ /* <Description> */
+ /* Discards a given size object. */
+ /* */
+ /* <Input> */
+ /* size :: A handle to a target size object */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_Done_Size( FT_Size size );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Set_Char_Size */
+ /* */
+ /* <Description> */
+ /* Sets the character dimensions of a given size object. The */
+ /* `char_size' value is used for the width and height, expressed in */
+ /* 26.6 fractional points. 1 point = 1/72 inch. */
+ /* */
+ /* <Input> */
+ /* size :: A handle to a target size object. */
+ /* char_size :: The character size, in 26.6 fractional points. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* When dealing with fixed-size faces (i.e., non-scalable formats), */
+ /* use the function FT_Set_Pixel_Sizes(). */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_Set_Char_Size( FT_Face face,
+ FT_F26Dot6 char_width,
+ FT_F26Dot6 char_height,
+ FT_UInt horz_resolution,
+ FT_UInt vert_resolution );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Set_Pixel_Sizes */
+ /* */
+ /* <Description> */
+ /* Sets the character dimensions of a given size object. The width */
+ /* and height are expressed in integer pixels. */
+ /* */
+ /* <Input> */
+ /* size :: A handle to a target size object. */
+ /* pixel_width :: The character width, in integer pixels. */
+ /* pixel_height :: The character height, in integer pixels. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_Set_Pixel_Sizes( FT_Face face,
+ FT_UInt pixel_width,
+ FT_UInt pixel_height );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_New_GlyphSlot */
+ /* */
+ /* <Description> */
+ /* It is sometimes useful to have more than one glyph slot for a */
+ /* given face object. This function is used to create additional */
+ /* slots. All of them are automatically discarded when the face is */
+ /* destroyed. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to a parent face object. */
+ /* */
+ /* <Output> */
+ /* slot :: A handle to a new glyph slot object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_New_GlyphSlot( FT_Face face,
+ FT_GlyphSlot* aslot );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Done_GlyphSlot */
+ /* */
+ /* <Description> */
+ /* Destroys a given glyph slot. Remember however that all slots are */
+ /* automatically destroyed with its parent. Using this function is */
+ /* not always mandatory. */
+ /* */
+ /* <Input> */
+ /* slot :: A handle to a target glyph slot. */
+ /* */
+ EXPORT_DEF
+ void FT_Done_GlyphSlot( FT_GlyphSlot slot );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Load_Glyph */
+ /* */
+ /* <Description> */
+ /* A function used to load a single glyph within a given glyph slot, */
+ /* for a given size. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object where the glyph */
+ /* will be loaded. */
+ /* */
+ /* glyph_index :: The index of the glyph in the font file. */
+ /* */
+ /* load_flags :: A flag indicating what to load for this glyph. The */
+ /* FT_LOAD_XXX constants can be used to control the */
+ /* glyph loading process (e.g., whether the outline */
+ /* should be scaled, whether to load bitmaps or not, */
+ /* whether to hint the outline, etc). */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_Load_Glyph( FT_Face face,
+ FT_UInt glyph_index,
+ FT_Int load_flags );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Load_Char */
+ /* */
+ /* <Description> */
+ /* A function used to load a single glyph within a given glyph slot, */
+ /* for a given size, according to its character code ! */
+ /* */
+ /* <Input> */
+ /* face :: A handle to a target face object where the glyph */
+ /* will be loaded. */
+ /* */
+ /* char_code :: The glyph's character code, according to the */
+ /* current charmap used in the face. */
+ /* */
+ /* load_flags :: A flag indicating what to load for this glyph. The */
+ /* FT_LOAD_XXX constants can be used to control the */
+ /* glyph loading process (e.g., whether the outline */
+ /* should be scaled, whether to load bitmaps or not, */
+ /* whether to hint the outline, etc). */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* If the face has no current charmap, or if the character code */
+ /* is not defined in the charmap, this function will return an */
+ /* error.. */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_Load_Char( FT_Face face,
+ FT_ULong char_code,
+ FT_Int load_flags );
+
+ /*************************************************************************/
+ /* */
+ /* <Constant> */
+ /* FT_LOAD_NO_SCALE */
+ /* */
+ /* <Description> */
+ /* A bit field constant, used with FT_Load_Glyph() to indicate that */
+ /* the vector outline being loaded should not be scaled to 26.6 */
+ /* fractional pixels, but kept in notional units. */
+ /* */
+#define FT_LOAD_NO_SCALE 1
+
+
+ /*************************************************************************/
+ /* */
+ /* <Constant> */
+ /* FT_LOAD_NO_HINTING */
+ /* */
+ /* <Description> */
+ /* A bit-field constant, used with FT_Load_Glyph() to indicate that */
+ /* the vector outline being loaded should not be fitted to the pixel */
+ /* grid but simply scaled to 26.6 fractional pixels. */
+ /* */
+ /* This flag is ignored when FT_LOAD_NO_SCALE is set. */
+ /* */
+#define FT_LOAD_NO_HINTING 2
+
+
+ /*************************************************************************/
+ /* */
+ /* <Constant> */
+ /* FT_LOAD_NO_OUTLINE */
+ /* */
+ /* <Description> */
+ /* A bit-field constant, used with FT_Load_Glyph() to indicate that */
+ /* the function should not load the vector outline of a given glyph. */
+ /* If an embedded bitmap exists for the glyph in the font, it will be */
+ /* loaded, otherwise nothing is returned and an error is produced. */
+ /* */
+#define FT_LOAD_NO_OUTLINE 4
+
+
+ /*************************************************************************/
+ /* */
+ /* <Constant> */
+ /* FT_LOAD_NO_BITMAP */
+ /* */
+ /* <Description> */
+ /* A bit-field constant, used with FT_Load_Glyph() to indicate that */
+ /* the function should not load the bitmap or pixmap of a given */
+ /* glyph. If an outline exists for the glyph in the font, it is */
+ /* loaded, otherwise nothing is returned and an error is produced. */
+ /* */
+#define FT_LOAD_NO_BITMAP 8
+
+
+ /*************************************************************************/
+ /* */
+ /* <Constant> */
+ /* FT_LOAD_LINEAR */
+ /* */
+ /* <Description> */
+ /* A bit-field constant, used with FT_Load_Glyph() to indicate that */
+ /* the function should return the linearly scaled metrics for the */
+ /* glyph in `slot->metrics2' (these metrics are not grid-fitted). */
+ /* Otherwise, `metrics2' gives the original font units values. */
+ /* */
+#define FT_LOAD_LINEAR 16
+
+
+ /*************************************************************************/
+ /* */
+ /* <Constant> */
+ /* FT_LOAD_PEDANTIC */
+ /* */
+ /* <Description> */
+ /* A bit-field constant, used with FT_Load_Glyph() to indicate that */
+ /* the glyph loader should perform a pedantic bytecode. */
+ /* interpretation. Many popular fonts come with broken glyph */
+ /* programs. When this flag is set, loading them will return an */
+ /* error. Otherwise, errors are ignored by the loader, sometimes */
+ /* resulting in ugly glyphs. */
+ /* */
+#define FT_LOAD_PEDANTIC 128
+
+
+ /*************************************************************************/
+ /* */
+ /* <Constant> */
+ /* FT_LOAD_NO_RECURSE */
+ /* */
+ /* <Description> */
+ /* A bit-field constant, used with FT_Load_Glyph() to indicate that */
+ /* the glyph loader should not load composite glyph recursively. */
+ /* Rather, when a composite glyph is encountered, it should set */
+ /* the values of `num_subglyphs' and `subglyphs', as well as set */
+ /* `face->glyph.format' to ft_glyph_format_composite. */
+ /* */
+ /* XXXXX : IMPORTANT NOTE, THIS FLAG IS NOT YET IMPLEMENTED !! */
+ /* */
+#define FT_LOAD_NO_RECURSE 256
+
+
+ /*************************************************************************/
+ /* */
+ /* <Constant> */
+ /* FT_LOAD_DEFAULT */
+ /* */
+ /* <Description> */
+ /* A bit-field constant, used with FT_Load_Glyph() to indicate that */
+ /* the function should try to load the glyph normally, i.e., */
+ /* embedded bitmaps are favored over outlines, vectors are always */
+ /* scaled and grid-fitted. */
+ /* */
+#define FT_LOAD_DEFAULT 0
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Get_Glyph_Bitmap */
+ /* */
+ /* <Description> */
+ /* Renders a given glyph into a bitmap or pixmap. This function will */
+ /* use the registered rasters to render the glyph image. */
+ /* */
+ /* <Input> */
+ /* face :: handle to the face object whose glyph slot contains */
+ /* the glyph image */
+ /* map :: A pointer to the target bitmap descriptor. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <MT-Note> */
+ /* YES. Rendering is synchronized, so that concurrent calls to the */
+ /* scan-line converter will be serialized. */
+ /* */
+ /* <Note> */
+ /* This function does NOT CREATE the bitmap, it only renders a */
+ /* glyph image into it! */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_Get_Glyph_Bitmap( FT_Face face,
+ FT_Bitmap* map );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Get_Kerning */
+ /* */
+ /* <Description> */
+ /* Returns the kerning vector between two glyphs of a same face. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to a source face object. */
+ /* */
+ /* left_glyph :: The index of the left glyph in the kern pair. */
+ /* */
+ /* right_glyph :: The index of the right glyph in the kern pair. */
+ /* */
+ /* <Output> */
+ /* kerning :: The kerning vector. This is in font units for */
+ /* scalable formats, and in pixels for fixed-sizes */
+ /* formats. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* Only horizontal layouts (left-to-right & right-to-left) are */
+ /* supported by this method. Other layouts, or more sophisticated */
+ /* kernings, are out of the scope of this API function -- they can be */
+ /* implemented through format-specific interfaces. */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_Get_Kerning( FT_Face face,
+ FT_UInt left_glyph,
+ FT_UInt right_glyph,
+ FT_Vector* kerning );
+
+
+
+/* XXX : Not implemented yet, but should come soon */
+#if 0
+ EXPORT_DEF
+ FT_Error FT_Select_Charmap( FT_Face face,
+ FT_Encoding encoding );
+
+
+ EXPORT_DEF
+ FT_Error FT_Set_Charmap( FT_Face face,
+ FT_CharMap charmap );
+#endif
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Get_Char_Index */
+ /* */
+ /* <Description> */
+ /* Returns the glyph index of a given character code. This function */
+ /* uses a charmap object to do the translation. */
+ /* */
+ /* <Input> */
+ /* charmap :: A handle to a filter charmap object. */
+ /* charcode :: The character code. */
+ /* */
+ /* <Return> */
+ /* The glyph index. 0 means `undefined character code'. */
+ /* */
+ EXPORT_DEF
+ FT_UInt FT_Get_Char_Index( FT_Face face,
+ FT_ULong charcode );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_MulDiv */
+ /* */
+ /* <Description> */
+ /* A very simple function used to perform the computation `(A*B)/C' */
+ /* with maximum accuracy (it uses a 64-bit intermediate integer */
+ /* whenever necessary). */
+ /* */
+ /* This function isn't necessarily as fast as some processor specific */
+ /* operations, but is at least completely portable. */
+ /* */
+ /* <Input> */
+ /* a :: The first multiplier. */
+ /* b :: The second multiplier. */
+ /* c :: The divisor. */
+ /* */
+ /* <Return> */
+ /* The result of `(a*b)/c'. This function never traps when trying to */
+ /* divide by zero, it simply returns `MaxInt' or `MinInt' depending */
+ /* on the signs of `a' and `b'. */
+ /* */
+ EXPORT_DEF
+ FT_Long FT_MulDiv( FT_Long a,
+ FT_Long b,
+ FT_Long c );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_MulFix */
+ /* */
+ /* <Description> */
+ /* A very simple function used to perform the computation */
+ /* `(A*B)/0x10000' with maximum accuracy. Most of the time, this is */
+ /* used to multiply a given value by a 16.16 fixed float factor. */
+ /* */
+ /* <Input> */
+ /* a :: The first multiplier. */
+ /* b :: The second multiplier. Use a 16.16 factor here whenever */
+ /* possible (see note below). */
+ /* */
+ /* <Return> */
+ /* The result of `(a*b)/0x10000'. */
+ /* */
+ /* <Note> */
+ /* This function has been optimized for the case where the absolute */
+ /* value of `a' is less than 2048, and `b' is a 16.16 scaling factor. */
+ /* As this happens mainly when scaling from notional units to */
+ /* fractional pixels in FreeType, it resulted in noticeable speed */
+ /* improvements between versions 2.0 and 1.x. */
+ /* */
+ /* As a conclusion, always try to place a 16.16 factor as the */
+ /* _second_ argument of this function; this can make a great */
+ /* difference. */
+ /* */
+ EXPORT_DEF
+ FT_Long FT_MulFix( FT_Long a,
+ FT_Long b );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_DivFix */
+ /* */
+ /* <Description> */
+ /* A very simple function used to perform the computation */
+ /* `(A*0x10000)/B' with maximum accuracy. Most of the time, this is */
+ /* used to divide a given value by a 16.16 fixed float factor. */
+ /* */
+ /* <Input> */
+ /* a :: The first multiplier. */
+ /* b :: The second multiplier. Use a 16.16 factor here whenever */
+ /* possible (see note below). */
+ /* */
+ /* <Return> */
+ /* The result of `(a*0x10000)/b'. */
+ /* */
+ /* <Note> */
+ /* The optimisation for FT_DivFix() is simple : if (a << 16) fits */
+ /* in 32 bits, then the division is computed directly. Otherwise, */
+ /* we use a specialised version of the old FT_MulDiv64 */
+ /* */
+ EXPORT_DEF
+ FT_Long FT_DivFix( FT_Long a,
+ FT_Long b );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Decompose_Outline */
+ /* */
+ /* <Description> */
+ /* Walks over an outline's structure to decompose it into individual */
+ /* segments and Bezier arcs. This function is also able to emit */
+ /* `move to' and `close to' operations to indicate the start and end */
+ /* of new contours in the outline. */
+ /* */
+ /* <Input> */
+ /* outline :: A pointer to the source target. */
+ /* */
+ /* interface :: A table of `emitters', i.e,. function pointers called */
+ /* during decomposition to indicate path operations. */
+ /* */
+ /* user :: A typeless pointer which is passed to each emitter */
+ /* during the decomposition. It can be used to store */
+ /* the state during the decomposition. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means sucess. */
+ /* */
+ EXPORT_DEF
+ int FT_Decompose_Outline( FT_Outline* outline,
+ FT_Outline_Funcs* interface,
+ void* user );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_New_Outline */
+ /* */
+ /* <Description> */
+ /* Creates a new outline of a given size. */
+ /* */
+ /* <Input> */
+ /* library :: A handle to the library object from where the */
+ /* outline is allocated. Note however that the new */
+ /* outline will NOT necessarily be FREED when */
+ /* destroying the library, by FT_Done_FreeType(). */
+ /* */
+ /* numPoints :: The maximum number of points within the outline. */
+ /* */
+ /* numContours :: The maximum number of contours within the outline. */
+ /* */
+ /* <Output> */
+ /* outline :: A handle to the new outline. NULL in case of */
+ /* error. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <MT-Note> */
+ /* No. */
+ /* */
+ /* <Note> */
+ /* The reason why this function takes a `library' parameter is simply */
+ /* to use the library's memory allocator. You can copy the source */
+ /* code of this function, replacing allocations with `malloc()' if */
+ /* you want to control where the objects go. */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_New_Outline( FT_Library library,
+ FT_UInt numPoints,
+ FT_Int numContours,
+ FT_Outline* outline );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Done_Outline */
+ /* */
+ /* <Description> */
+ /* Destroys an outline created with FT_New_Outline(). */
+ /* */
+ /* <Input> */
+ /* library :: A handle of the library object used to allocate the */
+ /* outline. */
+ /* */
+ /* outline :: A pointer to the outline object to be discarded. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <MT-Note> */
+ /* No. */
+ /* */
+ /* <Note> */
+ /* If the outline's `owner' field is not set, only the outline */
+ /* descriptor will be released. */
+ /* */
+ /* The reason why this function takes an `outline' parameter is */
+ /* simply to use FT_Alloc()/FT_Free(). You can copy the source code */
+ /* of this function, replacing allocations with `malloc()' in your */
+ /* application if you want something simpler. */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_Done_Outline( FT_Library library,
+ FT_Outline* outline );
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Get_Outline_CBox */
+ /* */
+ /* <Description> */
+ /* Returns an outline's `control box'. The control box encloses all */
+ /* the outline's points, including Bezier control points. Though it */
+ /* coincides with the exact bounding box for most glyphs, it can be */
+ /* slightly larger in some situations (like when rotating an outline */
+ /* which contains Bezier outside arcs). */
+ /* */
+ /* Computing the control box is very fast, while getting the bounding */
+ /* box can take much more time as it needs to walk over all segments */
+ /* and arcs in the outline. To get the latter, you can use the */
+ /* `ftbbox' component which is dedicated to this single task. */
+ /* */
+ /* <Input> */
+ /* outline :: A pointer to the source outline descriptor. */
+ /* */
+ /* <Output> */
+ /* cbox :: The outline's control box. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <MT-Note> */
+ /* Yes. */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_Get_Outline_CBox( FT_Outline* outline,
+ FT_BBox* cbox );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Translate_Outline */
+ /* */
+ /* <Description> */
+ /* Applies a simple translation to the points of an outline. */
+ /* */
+ /* <Input> */
+ /* outline :: A pointer to the target outline descriptor. */
+ /* xOffset :: The horizontal offset. */
+ /* yOffset :: The vertical offset. */
+ /* */
+ /* <MT-Note> */
+ /* Yes. */
+ /* */
+ EXPORT_DEF
+ void FT_Translate_Outline( FT_Outline* outline,
+ FT_Pos xOffset,
+ FT_Pos yOffset );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Set_Raster */
+ /* */
+ /* <Description> */
+ /* Register a given raster to the library. */
+ /* */
+ /* <Input> */
+ /* library :: A handle to a target library object. */
+ /* */
+ /* interface :: pointer to the raster's interface */
+ /* */
+ /* raster :: if this field is nil, this function will allocate */
+ /* a new objet. Otherwise, it will simply use the one */
+ /* provided here. */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_Set_Raster( FT_Library library,
+ FT_Raster_Interface* interface,
+ FT_Raster raster );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Set_Raster_Mode */
+ /* */
+ /* <Description> */
+ /* Set a raster-specific mode. */
+ /* */
+ /* <Input> */
+ /* library :: A handle to a target library object. */
+ /* format :: the glyph format used to select the raster */
+ /* mode :: the raster-specific mode descriptor */
+ /* args :: the mode arguments */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_Set_Raster_Mode( FT_Library library,
+ FT_Glyph_Tag format,
+ const char* mode,
+ const char* args );
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+
+#endif /* FREETYPE_H */
+
+
+/* END */
--- /dev/null
+++ b/include/ftbbox.h
@@ -1,0 +1,73 @@
+/***************************************************************************/
+/* */
+/* ftbbox.h */
+/* */
+/* FreeType bbox computation (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 has a _single_ role: to compute exact outline bounding */
+ /* boxes. */
+ /* */
+ /* It is separated from the rest of the engine for various technical */
+ /* reasons. It may well be integrated in `ftoutln' later. */
+ /* */
+ /*************************************************************************/
+
+
+#ifndef FTBBOX_H
+#define FTBBOX_H
+
+#include <freetype.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Get_Outline_BBox */
+ /* */
+ /* <Description> */
+ /* Computes the exact bounding box of an outline. This is slower */
+ /* than computing the control box. However, it uses an advanced */
+ /* algorithm which returns _very_ quickly when the two boxes */
+ /* coincide. Otherwise, the outline Bezier arcs are walked over to */
+ /* extract their extrema. */
+ /* */
+ /* <Input> */
+ /* outline :: A pointer to the source outline. */
+ /* */
+ /* <Output> */
+ /* bbox :: The outline's exact bounding box. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_Get_Outline_BBox( FT_Outline* outline,
+ FT_BBox* bbox );
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* FTBBOX_H */
+
+
+/* END */
--- /dev/null
+++ b/include/fterrors.h
@@ -1,0 +1,82 @@
+/***************************************************************************/
+/* */
+/* fterrors.h */
+/* */
+/* FreeType error codes (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. */
+/* */
+/***************************************************************************/
+
+
+#define FT_Err_Ok 0x000
+
+#define FT_Err_Cannot_Open_Resource 0x001
+#define FT_Err_Unknown_File_Format 0x002
+#define FT_Err_Invalid_File_Format 0x002
+
+#define FT_Err_Invalid_Argument 0x003
+#define FT_Err_Invalid_Handle 0x004
+#define FT_Err_Invalid_Glyph_Index 0x00A
+#define FT_Err_Invalid_Character_Code 0x00B
+
+#define FT_Err_Unimplemented_Feature 0x010
+#define FT_Err_Invalid_Glyph_Format 0x00D
+
+#define FT_Err_Invalid_Library_Handle 0x004
+#define FT_Err_Invalid_Driver_Handle 0x005
+#define FT_Err_Invalid_Face_Handle 0x006
+#define FT_Err_Invalid_Size_Handle 0x007
+#define FT_Err_Invalid_Slot_Handle 0x008
+#define FT_Err_Invalid_CharMap_Handle 0x009
+#define FT_Err_Invalid_Outline 0x00B
+#define FT_Err_Invalid_Dimensions 0x00C
+
+#define FT_Err_Unavailable_Outline 0x011
+#define FT_Err_Unavailable_Bitmap 0x012
+#define FT_Err_Unavailable_Pixmap 0x013
+#define FT_Err_File_Is_Not_Collection 0x014
+#define FT_Err_Too_Many_Drivers 0x015
+#define FT_Err_Too_Many_Glyph_Formats 0x016
+#define FT_Err_Too_Many_Extensions 0x017
+
+#define FT_Err_Out_Of_Memory 0x100
+#define FT_Err_Unlisted_Object 0x101
+
+#define FT_Err_Invalid_Resource_Handle 0x200
+#define FT_Err_Invalid_Stream_Handle 0x201
+#define FT_Err_Cannot_Open_Stream 0x202
+#define FT_Err_Invalid_Stream_Seek 0x203
+#define FT_Err_Invalid_Stream_Skip 0x204
+#define FT_Err_Invalid_Stream_Read 0x205
+#define FT_Err_Invalid_Stream_Operation 0x206
+#define FT_Err_Invalid_Frame_Operation 0x207
+#define FT_Err_Nested_Frame_Access 0x208
+#define FT_Err_Invalid_Frame_Read 0x209
+
+#define FT_Err_Too_Many_Points 0x300
+#define FT_Err_Too_Many_Contours 0x301
+#define FT_Err_Invalid_Composite 0x302
+#define FT_Err_Too_Many_Hints 0x303
+#define FT_Err_Too_Many_Edges 0x304
+#define FT_Err_Too_Many_Strokes 0x305
+
+/* range 0x400 - 0x4FF is reserved for TrueType specific stuff */
+
+/* range 0x500 - 0x5FF is reserved for TrueDoc specific stuff */
+
+/* range 0x600 - 0x6FF is reserved for Type1 specific stuff */
+
+#define FT_Err_Raster_Uninitialized 0xF00
+#define FT_Err_Raster_Corrupted 0xF01
+#define FT_Err_Raster_Overflow 0xF02
+
+
+/* END */
--- /dev/null
+++ b/include/ftimage.h
@@ -1,0 +1,627 @@
+/***************************************************************************/
+/* */
+/* ftimage.h */
+/* */
+/* This file defines the glyph image formats recognized by FreeType, as */
+/* well as the default raster 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. */
+/* */
+/***************************************************************************/
+
+#ifndef FTIMAGE_H
+#define FTIMAGE_H
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_Pos */
+ /* */
+ /* <Description> */
+ /* The type FT_Pos is a 32-bit integer used to store vectorial */
+ /* coordinates. Depending on the context, these can represent */
+ /* distances in integer font units, or 26.6 fixed float pixel */
+ /* coordinates. */
+ /* */
+ typedef signed long FT_Pos;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* FT_Vector */
+ /* */
+ /* <Description> */
+ /* A simple structure used to store a 2d vector; coordinates are of */
+ /* the FT_Pos type. */
+ /* */
+ /* <Fields> */
+ /* x :: The horizontal coordinate. */
+ /* y :: The vertical coordinate. */
+ /* */
+ typedef struct FT_Vector_
+ {
+ FT_Pos x;
+ FT_Pos y;
+
+ } FT_Vector;
+
+
+ /*************************************************************************
+ *
+ * <Enum>
+ * FT_Pixel_Mode
+ *
+ * <Description>
+ * An enumeration type used to describe the format of pixels
+ * in a given bitmap. Note that additional formats may be added
+ * in the future.
+ *
+ * <Fields>
+ * ft_pixel_mode_mono :: a monochrome bitmap (1 bit/pixel)
+ *
+ * ft_pixel_mode_grays :: an 8-bit gray-levels bitmap. Note that
+ * the total number of gray levels is given
+ * in the `num_grays' field of the FT_Bitmap
+ * structure.
+ *
+ * ft_pixel_mode_pal2 :: a 2-bit paletted bitmap.
+ * currently unused by FreeType.
+ *
+ * ft_pixel_mode_pal4 :: a 4-bit paletted bitmap.
+ * currently unused by FreeType.
+ *
+ * ft_pixel_mode_pal8 :: an 8-bit paletted bitmap.
+ * currently unused by FreeType.
+ *
+ * ft_pixel_mode_rgb15 :: a 15-bit RGB bitmap. Uses 5:5:5 encoding
+ * currently unused by FreeType.
+ *
+ * ft_pixel_mode_rgb16 :: a 16-bit RGB bitmap. Uses 5:6:5 encoding
+ * currently unused by FreeType.
+ *
+ * ft_pixel_mode_rgb24 :: a 24-bit RGB bitmap.
+ * currently unused by FreeType.
+ *
+ * ft_pixel_mode_rgb32 :: a 32-bit RGB bitmap.
+ * currently unused by FreeType.
+ *
+ * <Note>
+ * Some anti-aliased bitmaps might be embedded in TrueType fonts
+ * using formats pal2 or pal4, though no fonts presenting those
+ * have been found to date..
+ *
+ *************************************************************************/
+
+ typedef enum FT_Pixel_Mode_
+ {
+ ft_pixel_mode_none = 0,
+ ft_pixel_mode_mono,
+ ft_pixel_mode_grays,
+ ft_pixel_mode_pal2,
+ ft_pixel_mode_pal4,
+ ft_pixel_mode_pal8,
+ ft_pixel_mode_rgb15,
+ ft_pixel_mode_rgb16,
+ ft_pixel_mode_rgb24,
+ ft_pixel_mode_rgb32,
+
+ ft_pixel_mode_max /* do not remove */
+
+ } FT_Pixel_Mode;
+
+
+
+ /*************************************************************************
+ *
+ * <Enum>
+ * FT_Palette_Mode
+ *
+ * <Description>
+ * An enumeration type used to describe the format of a bitmap
+ * palette, used with ft_pixel_mode_pal4 and ft_pixel_mode_pal8
+ *
+ * <Fields>
+ * ft_palette_mode_rgb :: the palette is an array of 3-bytes RGB records
+ *
+ * ft_palette_mode_rgba :: the palette is an array of 4-bytes RGBA records
+ *
+ * <Note>
+ * As ft_pixel_mode_pal2, pal4 and pal8 are currently unused by
+ * FreeType, these types are not handled by the library itself.
+ *
+ *************************************************************************/
+
+ typedef enum FT_Palette_Mode_
+ {
+ ft_palette_mode_rgb = 0,
+ ft_palette_mode_rgba,
+
+ ft_palettte_mode_max /* do not remove */
+
+ } FT_Palette_Mode;
+
+
+ /*************************************************************************
+ *
+ * <Struct>
+ * FT_Bitmap
+ *
+ * <Description>
+ * A structure used to describe a bitmap or pixmap to the raster.
+ * Note that we now manage pixmaps of various depths through the
+ * `pixel_mode' field.
+ *
+ * <Fields>
+ * rows :: The number of bitmap rows.
+ *
+ * width :: The number of pixels in bitmap row.
+ *
+ * pitch :: The pitch's absolute value is the number of bytes
+ * taken by one bitmap row, including padding. However,
+ * the pitch is positive when the bitmap has a `down'
+ * flow, and negative when it has an `up' flow. In all
+ * cases, the pitch is an offset to add to a bitmap
+ * pointer in order to go down one row.
+ *
+ * buffer :: A typeless pointer to the bitmap buffer. This value
+ * should be aligned on 32-bit boundaries in most cases.
+ *
+ * num_grays :: this field is only used with ft_pixel_mode_grays,
+ * it gives the number of gray levels used in the
+ * bitmap.
+ *
+ * pixel_mode :: the pixel_mode, i.e. how pixel bits are stored
+ *
+ * palette_mode :: this field is only used with paletted pixel modes,
+ * it indicates how the palette is stored
+ *
+ * palette :: a typeless pointer to the bitmap palette. only used
+ * for paletted pixel modes.
+ *
+ * <Note>
+ * When using pixel modes pal2, pal4 and pal8 with a void `palette'
+ * field, a gray pixmap with respectively 4, 16 and 256 levels of gray
+ * is assumed. This, in order to be compatible with some embedded bitmap
+ * formats defined in the TrueType spec.
+ *
+ * Note that no font was found presenting such embedded bitmaps, so this
+ * is currently completely unhandled by the library.
+ *
+ *
+ *************************************************************************/
+
+ typedef struct FT_Bitmap_
+ {
+ int rows;
+ int width;
+ int pitch;
+ void* buffer;
+ short num_grays;
+ char pixel_mode;
+ char palette_mode;
+ void* palette;
+
+ } FT_Bitmap;
+
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* FT_Outline */
+ /* */
+ /* <Description> */
+ /* This structure is used to describe an outline to the scan-line */
+ /* converter. It's a copy of the TT_Outline type that was defined */
+ /* in FreeType 1.x. */
+ /* */
+ /* <Fields> */
+ /* n_contours :: The number of contours in the outline. */
+ /* */
+ /* n_points :: The number of points in the outline. */
+ /* */
+ /* points :: A pointer to an array of `n_points' FT_Vector */
+ /* elements, giving the outline's point */
+ /* coordinates. */
+ /* */
+ /* flags :: A pointer to an array of `n_points' chars, */
+ /* giving each outline point's type. If bit 0 is */
+ /* set, the point is `off' the curve, i.e., a */
+ /* Bezier control point, while it is `on' when */
+ /* unset. */
+ /* */
+ /* Bit 1 is meaningful for `off' points only. If */
+ /* set, it indicates a third-order Bezier arc */
+ /* control point; and a second-order control point */
+ /* if unset. */
+ /* */
+ /* contours :: An array of `n_contours' shorts, giving the end */
+ /* point of each contour within the outline. For */
+ /* example, the first contour is defined by the */
+ /* points `0' to `contours[0]', the second one is */
+ /* defined by the points `contours[0]+1' to */
+ /* `contours[1]', etc. */
+ /* */
+ /* owner :: This flag is a boolean which is set whenever the */
+ /* outline structure/object owns the arrays it */
+ /* refers to in the fields `points', `flags', and */
+ /* `contours'. */
+ /* */
+ /* high_precision :: This flag is set automatically by the FreeType */
+ /* library. It indicates that the scan-line */
+ /* converter should use a higher precision when */
+ /* rendering the outline. This is useful at small */
+ /* pixel sizes to get adequate results, though at */
+ /* the price of slower rendering. Don't try to */
+ /* render large outlines with this flag set. Note */
+ /* that it may be ignored in later implementations. */
+ /* */
+ /* second_pass :: A boolean which is set when the scan-line */
+ /* converter should perform a second pass to */
+ /* eliminate vertical drop-outs (only vertical */
+ /* drop-outs are checked on the first pass). This */
+ /* field may be ignored by later implementations. */
+ /* */
+ /* dropout_mode :: Specifies the drop-out control mode to use while */
+ /* rendering an outline. Valid values are 0 (no */
+ /* drop out check), 1, 2, 4, and 5. See the */
+ /* TrueType specification for more details. A */
+ /* value of 2 is usually an excellent generic */
+ /* choice. This field may be ignored by some */
+ /* raster implementations. */
+ /* */
+ /* */
+ typedef struct FT_Outline_
+ {
+ short n_contours; /* number of contours in glyph */
+ short n_points; /* number of points in the glyph */
+
+ FT_Vector* points; /* the outline's points */
+ char* flags; /* the points flags */
+ short* contours; /* the contour end points */
+
+ char owner; /* the outline owns the coordinates, */
+ /* flags, and contours array it uses */
+
+ char high_precision; /* high precision rendering */
+ char second_pass; /* two sweeps rendering */
+ char dropout_mode; /* dropout mode */
+
+ } FT_Outline;
+
+
+#define FT_CURVE_TAG( flag ) (flag & 3)
+
+#define FT_Curve_Tag_On 1
+#define FT_Curve_Tag_Conic 0
+#define FT_Curve_Tag_Cubic 2
+
+#define FT_Curve_Tag_Touch_X 8 /* reserved for the TrueType hinter */
+#define FT_Curve_Tag_Touch_Y 16 /* reserved for the TrueType hinter */
+
+#define FT_Curve_Tag_Touch_Both ( FT_Curve_Tag_Touch_X | \
+ FT_Curve_Tag_Touch_Y)
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* FT_Outline_MoveTo_Func */
+ /* */
+ /* <Description> */
+ /* A function pointer type used to describe the signature of a `move */
+ /* to' function during outline walking/decomposition. */
+ /* */
+ /* A `move to' is emitted to start a new contour in an outline. */
+ /* */
+ /* <Input> */
+ /* to :: A pointer to the target point of the `move to'. */
+ /* user :: A typeless pointer which is passed from the caller of the */
+ /* decomposition function. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ typedef int (*FT_Outline_MoveTo_Func)( FT_Vector* to,
+ void* user );
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* FT_Outline_LineTo_Func */
+ /* */
+ /* <Description> */
+ /* A function pointer type used to describe the signature of a `line */
+ /* to' function during outline walking/decomposition. */
+ /* */
+ /* A `line to' is emitted to indicate a segment in the outline. */
+ /* */
+ /* <Input> */
+ /* to :: A pointer to the target point of the `line to'. */
+ /* user :: A typeless pointer which is passed from the caller of the */
+ /* decomposition function. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ typedef int (*FT_Outline_LineTo_Func)( FT_Vector* to,
+ void* user );
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* FT_Outline_ConicTo_Func */
+ /* */
+ /* <Description> */
+ /* A function pointer type use to describe the signature of a `conic */
+ /* to' function during outline walking/decomposition. */
+ /* */
+ /* A `conic to' is emitted to indicate a second-order Bezier arc in */
+ /* the outline. */
+ /* */
+ /* <Input> */
+ /* control :: An intermediate control point between the last position */
+ /* and the new target in `to'. */
+ /* */
+ /* to :: A pointer to the target end point of the conic arc. */
+ /* */
+ /* user :: A typeless pointer which is passed from the caller of */
+ /* the decomposition function. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ typedef int (*FT_Outline_ConicTo_Func)( FT_Vector* control,
+ FT_Vector* to,
+ void* user );
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* FT_Outline_CubicTo_Func */
+ /* */
+ /* <Description> */
+ /* A function pointer type used to describe the signature of a `cubic */
+ /* to' function during outline walking/decomposition. */
+ /* */
+ /* A `cubic to' is emitted to indicate a third-order Bezier arc. */
+ /* */
+ /* <Input> */
+ /* control1 :: A pointer to the first Bezier control point. */
+ /* control2 :: A pointer to the second Bezier control point. */
+ /* to :: A pointer to the target end point. */
+ /* user :: A typeless pointer which is passed from the caller of */
+ /* the decomposition function. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ typedef int (*FT_Outline_CubicTo_Func)( FT_Vector* control1,
+ FT_Vector* control2,
+ FT_Vector* to,
+ void* user );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* FT_Outline_Funcs */
+ /* */
+ /* <Description> */
+ /* A structure to hold various function pointers used during outline */
+ /* decomposition in order to emit segments, conic, and cubic Beziers, */
+ /* as well as `move to' and `close to' operations. */
+ /* */
+ /* <Fields> */
+ /* move_to :: The `move to' emitter. */
+ /* line_to :: The segment emitter. */
+ /* conic_to :: The second-order Bezier arc emitter. */
+ /* cubic_to :: The third-order Bezier arc emitter. */
+ /* */
+ typedef struct FT_Outline_Funcs_
+ {
+ FT_Outline_MoveTo_Func move_to;
+ FT_Outline_LineTo_Func line_to;
+ FT_Outline_ConicTo_Func conic_to;
+ FT_Outline_CubicTo_Func cubic_to;
+
+ } FT_Outline_Funcs;
+
+
+
+
+ /*************************************************************************/
+ /* */
+ /* <Macro> */
+ /* FT_IMAGE_TAG */
+ /* */
+ /* <Description> */
+ /* This macro converts four letter tags which are used to label */
+ /* TrueType tables into an unsigned long to be used within FreeType. */
+ /* */
+#define FT_IMAGE_TAG( _x1, _x2, _x3, _x4 ) \
+ (((unsigned long)_x1 << 24) | \
+ ((unsigned long)_x2 << 16) | \
+ ((unsigned long)_x3 << 8) | \
+ (unsigned long)_x4)
+
+
+ /***********************************************************************
+ *
+ * <Enum>
+ * FT_Glyph_Tag
+ *
+ * <Description>
+ * An enumeration type used to describethe format of a given glyph
+ * image. Note that this version of FreeType only supports two image
+ * formats, even though future font drivers will be able to register
+ * their own format.
+ *
+ * <Fields>
+ * ft_glyph_format_bitmap :: the glyph image is a bitmap, and can
+ * be described as a FT_Bitmap
+ *
+ * ft_glyph_format_outline :: the glyph image is a vectorial image
+ * made of bezier control points, and can
+ * be described as a FT_Outline
+ *
+ ***********************************************************************/
+
+ typedef enum FT_Glyph_Tag_
+ {
+ ft_glyph_format_none = 0,
+ ft_glyph_format_composite = FT_IMAGE_TAG('c','o','m','p'),
+ ft_glyph_format_bitmap = FT_IMAGE_TAG('b','i','t','s'),
+ ft_glyph_format_outline = FT_IMAGE_TAG('o','u','t','l')
+
+ } FT_Glyph_Tag;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FT_Raster */
+ /* */
+ /* <Description> */
+ /* A handle (pointer) to a raster object. Each object can be used */
+ /* independently to convert an outline into a bitmap or pixmap. */
+ /* */
+ typedef struct FT_RasterRec_* FT_Raster;
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* FT_Raster_Init_Proc */
+ /* */
+ /* <Description> */
+ /* Initializes a fresh raster object which should have been allocated */
+ /* by client applications. This function is also used to set the */
+ /* object's render pool. It can be used repeatedly on a single */
+ /* object if one wants to change the pool's address or size. */
+ /* */
+ /* Note that the render pool has no state and is only used during a */
+ /* call to FT_Raster_Render(). It is thus theorically possible to */
+ /* share it between several non-concurrent components of your */
+ /* applications when memory is a scarce resource. */
+ /* */
+ /* <Input> */
+ /* raster :: a handle to the target raster object. */
+ /* pool_base :: the render pool's base address in memory */
+ /* pool_size :: the render pool's size in bytes. this must be at */
+ /* least 4 kByte. */
+ /* <Return> */
+ /* An error condition, used as a FT_Error in the FreeType library. */
+ /* 0 means success. */
+ /* */
+ typedef int (*FT_Raster_Init_Proc)( FT_Raster raster,
+ const char* pool_base,
+ long pool_size );
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* FT_Raster_Set_Mode_Proc */
+ /* */
+ /* <Description> */
+ /* Some raster implementations may have several modes of operation. */
+ /* This function is used to select one of them, as well as pass some */
+ /* arguments. */
+ /* */
+ /* <Input> */
+ /* raster :: The target raster object. */
+ /* */
+ /* mode :: A pointer used to describe the mode to set. This is */
+ /* completely raster-specific, and could be, for example, */
+ /* a text string. */
+ /* */
+ /* args :: An argument to the set_mode command. This is completely */
+ /* specific to the raster and the mode used. */
+ /* */
+ /* <Return> */
+ /* An error code, used as a FT_Error by the FreeType library. */
+ /* 0 means success. */
+ /* */
+ typedef int (*FT_Raster_Set_Mode_Proc)( FT_Raster raster,
+ const char* mode,
+ const char* args );
+
+
+ /*************************************************************************
+ *
+ * <FuncType>
+ * FT_Raster_Render_Proc
+ *
+ * <Description>
+ * Renders an outline into a target bitmap/pixmap.
+ *
+ * <Input>
+ * raster :: A handle to a raster object used during rendering.
+ *
+ * source_image :: a typeless pointer to the source glyph image.
+ * (usually a FT_Outline*).
+ *
+ * target_bitmap :: descriptor to the target bitmap.
+ *
+ * <Return>
+ * Error code, interpreted as a FT_Error by FreeType library.
+ * 0 means success.
+ *
+ *************************************************************************/
+
+ typedef int (*FT_Raster_Render_Proc)( FT_Raster raster,
+ void* source_image,
+ FT_Bitmap* target_bitmap );
+
+
+ /**************************************************************************
+ *
+ * <Struct>
+ * FT_Raster_Interface
+ *
+ * <Description>
+ * A structure used to model the default raster interface. A raster
+ * is a module in charge of converting a glyph image into a bitmap.
+ *
+ * <Fields>
+ * size :: the size in bytes of the given raster object. This
+ * is used to allocate a new raster when calling
+ * `FT_Set_Raster'.
+ *
+ * format :: the source glyph image format this raster is able to
+ * handle.
+ *
+ * init :: the raster's initialisation routine
+ *
+ * set_mode :: the raster's mode set routine
+ *
+ * render :: the raster's rendering routine
+ *
+ **************************************************************************/
+
+ typedef struct FT_Raster_Interface_
+ {
+ long size;
+ FT_Glyph_Tag format_tag;
+ FT_Raster_Init_Proc init;
+ FT_Raster_Set_Mode_Proc set_mode;
+ FT_Raster_Render_Proc render;
+
+
+ } FT_Raster_Interface;
+
+
+#endif /* FTIMAGE_H */
+
+
--- /dev/null
+++ b/include/ftsystem.h
@@ -1,0 +1,95 @@
+/**************************************************************************
+ *
+ * ftsystem.h 1.0
+ *
+ * FreeType low-level system interface definition
+ *
+ * This file contains the definitions of the stream and memory interfaces
+ * used by FreeType.
+ *
+ *
+ * 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 FTSYSTEM_H
+#define FTSYSTEM_H
+
+/*************************************************************************
+ *
+ * M E M O R Y M A N A G E M E N T
+ *
+ *************************************************************************/
+
+ typedef struct FT_MemoryRec_* FT_Memory;
+
+ typedef void* (*FT_Alloc_Func)( FT_Memory memory,
+ long size );
+
+ typedef void (*FT_Free_Func)( FT_Memory memory,
+ void* block );
+
+ typedef void* (*FT_Realloc_Func)( FT_Memory memory,
+ long cur_size,
+ long new_size,
+ void* block );
+
+ struct FT_MemoryRec_
+ {
+ void* user;
+ FT_Alloc_Func alloc;
+ FT_Free_Func free;
+ FT_Realloc_Func realloc;
+ };
+
+
+
+/*************************************************************************
+ *
+ * I / O M A N A G E M E N T
+ *
+ *************************************************************************/
+
+ typedef union FT_StreamDesc_
+ {
+ long value;
+ void* pointer;
+
+ } FT_StreamDesc;
+
+
+ typedef struct FT_StreamRec_* FT_Stream;
+
+ typedef unsigned long (*FT_Stream_IO)( FT_Stream stream,
+ unsigned long offset,
+ char* buffer,
+ unsigned long count );
+
+ typedef void (*FT_Stream_Close)( FT_Stream stream );
+
+ struct FT_StreamRec_
+ {
+ char* base;
+ unsigned long size;
+ unsigned long pos;
+
+ FT_StreamDesc descriptor;
+ FT_StreamDesc pathname; /* ignored by FreeType - useful for debugging */
+
+ FT_Stream_IO read;
+ FT_Stream_Close close;
+
+ FT_Memory memory;
+ char* cursor;
+ char* limit;
+ };
+
+
+#endif /* FTSYSTEM_H */
--- /dev/null
+++ b/include/ttnamedid.h
@@ -1,0 +1,624 @@
+/*******************************************************************
+ *
+ * ttnameid.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 TTNAMEID_H
+#define TTNAMEID_H
+
+/*
+ * possible values for the 'Platform' identifier code in the name
+ * records of the TTF "name" table
+ */
+
+#define TT_PLATFORM_APPLE_UNICODE 0
+#define TT_PLATFORM_MACINTOSH 1
+#define TT_PLATFORM_ISO 2
+#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 <[email protected]> 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 /* TTNAMEID_H */
+
+
+/* END */
--- /dev/null
+++ b/obj/README
@@ -1,0 +1,1 @@
+This directory contains all the object files created when building the library
--- /dev/null
+++ b/src/base/ftbase.c
@@ -1,0 +1,6 @@
+#include <ftcalc.c>
+#include <ftobjs.c>
+#include <ftstream.c>
+#include <ftlist.c>
+
+#include <ftextend.c>
--- /dev/null
+++ b/src/base/ftbbox.c
@@ -1,0 +1,447 @@
+/***************************************************************************/
+/* */
+/* ftbbox.c */
+/* */
+/* FreeType bbox computation (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. */
+/* */
+/***************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* This component has a _single_ role: to compute exact outline bounding */
+ /* boxes. */
+ /* */
+ /* It is separated from the rest of the engine for various technical */
+ /* reasons. It may well be integrated in `ftoutln' later. */
+ /* */
+ /*************************************************************************/
+
+
+#include <ftbbox.h>
+#include <ftimage.h>
+#include <ftobjs.h>
+
+ typedef struct TBBox_Rec_
+ {
+ FT_Vector last;
+ FT_BBox bbox;
+
+ } TBBox_Rec;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* BBox_Move_To */
+ /* */
+ /* <Description> */
+ /* This function is used as a `move_to' and `line_to' emitter during */
+ /* FT_Raster_Decompose(). It simply records the destination point in */
+ /* user->last. */
+ /* */
+ /* <Input> */
+ /* to :: The destination vector. */
+ /* user :: The current walk context. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ static
+ int BBox_Move_To( FT_Vector* to,
+ TBBox_Rec* user )
+ {
+ user->last = *to;
+
+ return 0;
+ }
+
+
+#define CHECK_X( p, bbox ) \
+ ( p->x < bbox.xMin || p->x > bbox.xMax )
+
+#define CHECK_Y( p, bbox ) \
+ ( p->y < bbox.yMin || p->y > bbox.yMax )
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* BBox_Conic_Check */
+ /* */
+ /* <Description> */
+ /* Finds the extrema of a 1-dimensional conic Bezier curve and update */
+ /* a bounding range. This version uses direct computation, as it */
+ /* doesn't need square roots. */
+ /* */
+ /* <Input> */
+ /* y1 :: The start coordinate. */
+ /* y2 :: The coordinate of the control point. */
+ /* y3 :: The end coordinate. */
+ /* */
+ /* <Output> */
+ /* min :: The address of the current minimum. */
+ /* max :: The address of the current maximum. */
+ /* */
+ static
+ void BBox_Conic_Check( FT_Pos y1,
+ FT_Pos y2,
+ FT_Pos y3,
+ FT_Pos* min,
+ FT_Pos* max )
+ {
+ if( y1 == y3 )
+ {
+ if ( y2 == y1 ) /* Flat arc */
+ {
+ y3 = y1;
+ goto Suite;
+ }
+ }
+ else if ( y1 < y3 )
+ {
+ if ( y2 >= y1 && y2 <= y3 ) /* Ascending arc */
+ goto Suite;
+ }
+ else
+ {
+ if ( y2 >= y3 && y2 <= y1 ) /* Descending arc */
+ {
+ y2 = y1;
+ y1 = y3;
+ y3 = y2;
+ goto Suite;
+ }
+ }
+
+ y1 = y3 = FT_MulDiv( y2 - y1, y2 - y1, y1 - 2*y2 + y3 );
+
+ Suite:
+ if ( y1 < *min ) *min = y1;
+ if ( y3 > *max ) *max = y3;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* BBox_Conic_To */
+ /* */
+ /* <Description> */
+ /* This function is used as a `conic_to' emitter during */
+ /* FT_Raster_Decompose(). It checks a conic Bezier curve with the */
+ /* current bounding box, and computes its extrema if necessary to */
+ /* update it. */
+ /* */
+ /* <Input> */
+ /* control :: A control point. */
+ /* to :: The destination vector. */
+ /* */
+ /* <InOut> */
+ /* user :: The current walk context. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* In the case of a non-monotonous arc, we compute directly the */
+ /* extremum coordinates, as it is sufficiently fast. */
+ /* */
+ static
+ int BBox_Conic_To( FT_Vector* control,
+ FT_Vector* to,
+ TBBox_Rec* user )
+ {
+ if ( CHECK_X( control, user->bbox ) ||
+ CHECK_X( to, user->bbox ) )
+
+ BBox_Conic_Check( user->last.x,
+ control->x,
+ to->x,
+ &user->bbox.xMin,
+ &user->bbox.xMax );
+
+ if ( CHECK_Y( control, user->bbox ) ||
+ CHECK_Y( to, user->bbox ) )
+
+ BBox_Conic_Check( user->last.y,
+ control->y,
+ to->y,
+ &user->bbox.yMin,
+ &user->bbox.yMax );
+
+ return 0;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* BBox_Cubic_Check */
+ /* */
+ /* <Description> */
+ /* Finds the extrema of a 1-dimensional cubic Bezier curve and */
+ /* updates a bounding range. This version uses splitting because we */
+ /* don't want to use square roots and extra accuracies. */
+ /* */
+ /* <Input> */
+ /* p1 :: The start coordinate. */
+ /* p2 :: The coordinate of the first control point. */
+ /* p3 :: The coordinate of the second control point. */
+ /* p4 :: The end coordinate. */
+ /* */
+ /* <InOut> */
+ /* min :: The address of the current minimum. */
+ /* max :: The address of the current maximum. */
+ /* */
+ static
+ void BBox_Cubic_Check( FT_Pos p1,
+ FT_Pos p2,
+ FT_Pos p3,
+ FT_Pos p4,
+ FT_Pos* min,
+ FT_Pos* max )
+ {
+ FT_Pos stack[33], *arc;
+
+
+ arc = stack;
+
+ arc[0] = p1;
+ arc[1] = p2;
+ arc[2] = p3;
+ arc[3] = p4;
+
+ do
+ {
+ FT_Pos y1 = arc[0];
+ FT_Pos y2 = arc[1];
+ FT_Pos y3 = arc[2];
+ FT_Pos y4 = arc[3];
+
+
+ if ( y1 == y4 )
+ {
+ if ( y1 == y2 && y1 == y3 ) /* Flat */
+ {
+ y4 = y1;
+ goto Test;
+ }
+ }
+ else if ( y1 < y4 )
+ {
+ if ( y2 >= y1 && y2 <= y4 && y3 >= y1 && y3 <= y4 ) /* Ascending */
+ goto Test;
+ }
+ else
+ {
+ if ( y2 >= y4 && y2 <= y1 && y3 >= y4 && y3 <= y1 ) /* Descending */
+ {
+ y2 = y1;
+ y1 = y4;
+ y4 = y2;
+ goto Test;
+ }
+ }
+
+ /* Unknown direction, split the arc in two */
+ arc[6] = y4;
+ arc[1] = y1 = ( y1 + y2 ) / 2;
+ arc[5] = y4 = ( y4 + y3 ) / 2;
+ y2 = ( y2 + y3 ) / 2;
+ arc[2] = y1 = ( y1 + y2 ) / 2;
+ arc[4] = y4 = ( y4 + y2 ) / 2;
+ arc[3] = ( y1 + y4 ) / 2;
+
+ arc += 3;
+ goto Suite;
+
+ Test:
+ if ( y1 < *min ) *min = y1;
+ if ( y4 > *max ) *max = y4;
+ arc -= 3;
+
+ Suite:
+ ;
+ } while (arc >= stack);
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* BBox_Cubic_To */
+ /* */
+ /* <Description> */
+ /* This function is used as a `cubic_to' emitter during */
+ /* FT_Raster_Decompose(). It checks a cubic Bezier curve with the */
+ /* current bounding box, and computes its extrema if necessary to */
+ /* update it. */
+ /* */
+ /* <Input> */
+ /* control1 :: The first control point. */
+ /* control2 :: The second control point. */
+ /* to :: The destination vector. */
+ /* */
+ /* <InOut> */
+ /* user :: The current walk context. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* In the case of a non-monotonous arc, we don't compute directly */
+ /* extremum coordinates, we subdivise instead. */
+ /* */
+ static
+ int BBox_Cubic_To( FT_Vector* control1,
+ FT_Vector* control2,
+ FT_Vector* to,
+ TBBox_Rec* user )
+ {
+ if ( CHECK_X( control1, user->bbox ) ||
+ CHECK_X( control2, user->bbox ) ||
+ CHECK_X( to, user->bbox ) )
+
+ BBox_Cubic_Check( user->last.x,
+ control1->x,
+ control2->x,
+ to->x,
+ &user->bbox.xMin,
+ &user->bbox.xMax );
+
+ if ( CHECK_Y( control1, user->bbox ) ||
+ CHECK_Y( control2, user->bbox ) ||
+ CHECK_Y( to, user->bbox ) )
+
+ BBox_Cubic_Check( user->last.y,
+ control1->y,
+ control2->y,
+ to->y,
+ &user->bbox.yMin,
+ &user->bbox.yMax );
+
+ return 0;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Raster_GetBBox */
+ /* */
+ /* <Description> */
+ /* Computes the exact bounding box of an outline. This is slower */
+ /* than computing the control box. However, it uses an advanced */
+ /* algorithm which returns _very_ quickly when the two boxes */
+ /* coincide. Otherwise, the outline Bezier arcs are walked over to */
+ /* extract their extrema. */
+ /* */
+ /* <Input> */
+ /* outline :: A pointer to the source outline. */
+ /* */
+ /* <Output> */
+ /* bbox :: The outline's exact bounding box. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_Raster_GetBBox( FT_Outline* outline,
+ FT_BBox* abbox )
+ {
+ FT_BBox cbox;
+ FT_BBox bbox;
+ FT_Vector* vec;
+ FT_UShort n;
+
+
+ /* if outline is empty, return (0,0,0,0) */
+ if ( !outline )
+ return FT_Err_Invalid_Outline;
+
+ if ( outline->n_points == 0 || outline->n_contours <= 0 )
+ {
+ abbox->xMin = abbox->xMax = 0;
+ abbox->yMin = abbox->yMax = 0;
+ return 0;
+ }
+
+ /* We compute the control box, as well as the bounding box */
+ /* of all `on' points in the outline. Then, if the two boxes */
+ /* coincide, we exit immediately. */
+
+ vec = outline->points;
+ bbox.xMin = bbox.xMax = cbox.xMin = cbox.xMax = vec->x;
+ bbox.yMin = bbox.yMin = cbox.yMin = cbox.yMax = vec->y;
+
+ for ( n = 1; n < outline->n_points; n++ )
+ {
+ FT_Pos x = vec->x;
+ FT_Pos y = vec->y;
+
+
+ /* update control box */
+ if ( x < cbox.xMin ) cbox.xMin = x;
+ if ( x > cbox.xMax ) cbox.xMax = x;
+
+ if ( y < cbox.yMin ) cbox.yMin = y;
+ if ( y > cbox.yMax ) cbox.yMax = y;
+
+ if ( FT_CURVE_TAG( outline->flags[n] ) == FT_Curve_Tag_On )
+ {
+ /* update bbox for `on' points only */
+ if ( x < bbox.xMin ) bbox.xMin = x;
+ if ( x > bbox.xMax ) bbox.xMax = x;
+
+ if ( y < bbox.yMin ) bbox.yMin = y;
+ if ( y > bbox.yMax ) bbox.yMax = y;
+ }
+
+ vec++;
+ }
+
+ /* test two boxes for equality */
+ if ( cbox.xMin < bbox.xMin || cbox.xMax > bbox.xMax ||
+ cbox.yMin < bbox.yMin || cbox.yMax > bbox.yMax )
+ {
+ /* the two boxes are different, now walk over the outline to */
+ /* get the Bezier arc extrema. */
+
+ static FT_Outline_Funcs interface =
+ {
+ (FT_Outline_MoveTo_Func) BBox_Move_To,
+ (FT_Outline_LineTo_Func) BBox_Move_To,
+ (FT_Outline_ConicTo_Func) BBox_Conic_To,
+ (FT_Outline_CubicTo_Func) BBox_Cubic_To
+ };
+
+ FT_Error error;
+ TBBox_Rec user;
+
+
+ user.bbox = bbox;
+
+ error = FT_Decompose_Outline( outline, &interface, &user );
+ if ( error )
+ return error;
+
+ *abbox = user.bbox;
+ }
+ else
+ *abbox = bbox;
+
+ return FT_Err_Ok;
+ }
+
+
+/* END */
--- /dev/null
+++ b/src/base/ftcalc.c
@@ -1,0 +1,505 @@
+/***************************************************************************/
+/* */
+/* ftcalc.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. */
+/* */
+/***************************************************************************/
+
+ /*************************************************************************/
+ /* */
+ /* Support for 1-complement arithmetic has been totally dropped in this */
+ /* release. You can still write your own code if you need it. */
+ /* */
+ /*************************************************************************/
+
+ /*************************************************************************/
+ /* */
+ /* Implementing basic computation routines. */
+ /* */
+ /* FT_MulDiv() and FT_MulFix() are declared in freetype.h. */
+ /* */
+ /*************************************************************************/
+
+#include <ftcalc.h>
+#include <ftdebug.h>
+#include <ftobjs.h> /* for ABS() */
+
+
+ BASE_FUNC
+ FT_Int32 FT_Sqrt32( FT_Int32 x )
+ {
+ FT_ULong val, root, newroot, mask;
+
+ root = 0;
+ mask = 0x40000000;
+ val = (FT_ULong)x;
+ do
+ {
+ newroot = root+mask;
+ if (newroot <= val)
+ {
+ val -= newroot;
+ root = newroot+mask;
+ }
+ root >>= 1;
+ mask >>= 2;
+ }
+ while (mask != 0);
+
+ return root;
+ }
+
+
+#ifdef LONG64
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_MulDiv */
+ /* */
+ /* <Description> */
+ /* A very simple function used to perform the computation `(A*B)/C' */
+ /* with maximum accuracy (it uses a 64-bit intermediate integer */
+ /* whenever necessary). */
+ /* */
+ /* This function isn't necessarily as fast as some processor specific */
+ /* operations, but is at least completely portable. */
+ /* */
+ /* <Input> */
+ /* a :: The first multiplier. */
+ /* b :: The second multiplier. */
+ /* c :: The divisor. */
+ /* */
+ /* <Return> */
+ /* The result of `(a*b)/c'. This function never traps when trying to */
+ /* divide by zero, it simply returns `MaxInt' or `MinInt' depending */
+ /* on the signs of `a' and `b'. */
+ /* */
+ EXPORT_FUNC
+ FT_Long FT_MulDiv( FT_Long a,
+ FT_Long b,
+ FT_Long c )
+ {
+ FT_Int s;
+
+ s = 1;
+ if ( a < 0 ) { a = -a; s = -s; }
+ if ( b < 0 ) { b = -b; s = -s; }
+ if ( c < 0 ) { c = -c; s = -s; }
+
+ return s*( ((FT_Int64)a * b + (c >> 1) )/c);
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_MulFix */
+ /* */
+ /* <Description> */
+ /* A very simple function used to perform the computation */
+ /* `(A*B)/0x10000' with maximum accuracy. Most of the time, this is */
+ /* used to multiply a given value by a 16.16 fixed float factor. */
+ /* */
+ /* <Input> */
+ /* a :: The first multiplier. */
+ /* b :: The second multiplier. Use a 16.16 factor here whenever */
+ /* possible (see note below). */
+ /* */
+ /* <Return> */
+ /* The result of `(a*b)/0x10000'. */
+ /* */
+ /* <Note> */
+ /* This function has been optimized for the case where the absolute */
+ /* value of `a' is less than 2048, and `b' is a 16.16 scaling factor. */
+ /* As this happens mainly when scaling from notional units to */
+ /* fractional pixels in FreeType, it resulted in noticeable speed */
+ /* improvements between versions 2.0 and 1.x. */
+ /* */
+ /* As a conclusion, always try to place a 16.16 factor as the */
+ /* _second_ argument of this function; this can make a great */
+ /* difference. */
+ /* */
+ EXPORT_FUNC
+ FT_Long FT_MulFix( FT_Long a,
+ FT_Long b )
+ {
+ FT_Int s;
+
+ s = 1;
+ if ( a < 0 ) { a = -a; s = -s; }
+ if ( b < 0 ) { b = -b; s = -s; }
+
+ return s*(FT_Long)((FT_Int64)a * b + 0x8000) >> 16);
+ }
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_DivFix */
+ /* */
+ /* <Description> */
+ /* A very simple function used to perform the computation */
+ /* `(A*0x10000)/B' with maximum accuracy. Most of the time, this is */
+ /* used to divide a given value by a 16.16 fixed float factor. */
+ /* */
+ /* <Input> */
+ /* a :: The first multiplier. */
+ /* b :: The second multiplier. Use a 16.16 factor here whenever */
+ /* possible (see note below). */
+ /* */
+ /* <Return> */
+ /* The result of `(a*0x10000)/b'. */
+ /* */
+ /* <Note> */
+ /* The optimisation for FT_DivFix() is simple : if (a << 16) fits */
+ /* in 32 bits, then the division is computed directly. Otherwise, */
+ /* we use a specialised version of the old FT_MulDiv64 */
+ /* */
+ EXPORT_FUNC
+ FT_Int32 FT_DivFix( FT_Long a,
+ FT_Long b )
+ {
+ FT_Int32 s;
+ FT_Word32 q;
+
+ s = a; a = ABS(a);
+ s ^= b; b = ABS(b);
+
+ if ( b == 0 )
+ /* check for divide by 0 */
+ q = 0x7FFFFFFF;
+
+ else
+ /* compute result directly */
+ q = ((FT_Int64)a << 16) / b;
+
+ return (FT_Int32)( s < 0 ? -q : q );
+ }
+
+
+#else /* LONG64 */
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_MulDiv */
+ /* */
+ /* <Description> */
+ /* A very simple function used to perform the computation `(A*B)/C' */
+ /* with maximum accuracy (it uses a 64-bit intermediate integer */
+ /* whenever necessary). */
+ /* */
+ /* This function isn't necessarily as fast as some processor specific */
+ /* operations, but is at least completely portable. */
+ /* */
+ /* <Input> */
+ /* a :: The first multiplier. */
+ /* b :: The second multiplier. */
+ /* c :: The divisor. */
+ /* */
+ /* <Return> */
+ /* The result of `(a*b)/c'. This function never traps when trying to */
+ /* divide by zero, it simply returns `MaxInt' or `MinInt' depending */
+ /* on the signs of `a' and `b'. */
+ /* */
+ /* <Note> */
+ /* The FT_MulDiv() function has been optimized thanks to ideas from */
+ /* Graham Asher. The trick is to optimize computation if everything */
+ /* fits within 32 bits (a rather common case). */
+ /* */
+ /* We compute `a*b+c/2', then divide it by `c'. (positive values) */
+ /* */
+ /* 46340 is FLOOR(SQRT(2^31-1)). */
+ /* */
+ /* if ( a <= 46340 && b <= 46340 ) then ( a*b <= 0x7FFEA810 ) */
+ /* */
+ /* 0x7FFFFFFF - 0x7FFEA810 = 0x157F0 */
+ /* */
+ /* if ( c < 0x157F0*2 ) then ( a*b+c/2 <= 0x7FFFFFFF ) */
+ /* */
+ /* and 2*0x157F0 = 176096 */
+ /* */
+ EXPORT_FUNC
+ FT_Long FT_MulDiv( FT_Long a,
+ FT_Long b,
+ FT_Long c )
+ {
+ long s;
+
+
+ if ( a == 0 || b == c )
+ return a;
+
+ s = a; a = ABS( a );
+ s ^= b; b = ABS( b );
+ s ^= c; c = ABS( c );
+
+ if ( a <= 46340 && b <= 46340 && c <= 176095L )
+ {
+ a = ( a*b + (c >> 1) ) / c;
+ }
+ else
+ {
+ FT_Int64 temp, temp2;
+
+ FT_MulTo64( a, b, &temp );
+ temp2.hi = (FT_Int32)(c >> 31);
+ temp2.lo = (FT_Word32)(c / 2);
+ FT_Add64( &temp, &temp2, &temp );
+ a = FT_Div64by32( &temp, c );
+ }
+
+ return ( s < 0 ) ? -a : a;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_MulFix */
+ /* */
+ /* <Description> */
+ /* A very simple function used to perform the computation */
+ /* `(A*B)/0x10000' with maximum accuracy. Most of the time, this is */
+ /* used to multiply a given value by a 16.16 fixed float factor. */
+ /* */
+ /* <Input> */
+ /* a :: The first multiplier. */
+ /* b :: The second multiplier. Use a 16.16 factor here whenever */
+ /* possible (see note below). */
+ /* */
+ /* <Return> */
+ /* The result of `(a*b)/0x10000'. */
+ /* */
+ /* <Note> */
+ /* The optimisation for FT_MulFix() is different. We could simply be */
+ /* happy by applying the same principles as with FT_MulDiv(), because */
+ /* */
+ /* c = 0x10000 < 176096 */
+ /* */
+ /* However, in most cases, we have a `b' with a value around 0x10000 */
+ /* which is greater than 46340. */
+ /* */
+ /* According to some testing, most cases have `a' < 2048, so a good */
+ /* idea is to use bounds like 2048 and 1048576 (=floor((2^31-1)/2048) */
+ /* for `a' and `b' respectively. */
+ /* */
+ EXPORT_FUNC
+ FT_Long FT_MulFix( FT_Long a,
+ FT_Long b )
+ {
+ FT_Long s;
+
+ if ( a == 0 || b == 0x10000L )
+ return a;
+
+ s = a; a = ABS(a);
+ s ^= b; b = ABS(b);
+
+ if ( a <= 2048 && b <= 1048576L )
+ {
+ a = ( a*b + 0x8000 ) >> 16;
+ }
+ else
+ {
+ FT_Long al = a & 0xFFFF;
+
+ a = (a >> 16)*b + al*(b >> 16) + ( al*(b & 0xFFFF) >> 16 );
+ }
+
+ return ( s < 0 ? -a : a );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_DivFix */
+ /* */
+ /* <Description> */
+ /* A very simple function used to perform the computation */
+ /* `(A*0x10000)/B' with maximum accuracy. Most of the time, this is */
+ /* used to divide a given value by a 16.16 fixed float factor. */
+ /* */
+ /* <Input> */
+ /* a :: The first multiplier. */
+ /* b :: The second multiplier. Use a 16.16 factor here whenever */
+ /* possible (see note below). */
+ /* */
+ /* <Return> */
+ /* The result of `(a*0x10000)/b'. */
+ /* */
+ /* <Note> */
+ /* The optimisation for FT_DivFix() is simple : if (a << 16) fits */
+ /* in 32 bits, then the division is computed directly. Otherwise, */
+ /* we use a specialised version of the old FT_MulDiv64 */
+ /* */
+ EXPORT_FUNC
+ FT_Long FT_DivFix( FT_Long a,
+ FT_Long b )
+ {
+ FT_Int32 s;
+ FT_Word32 q;
+
+ s = a; a = ABS(a);
+ s ^= b; b = ABS(b);
+
+ if ( b == 0 )
+ /* check for divide by 0 */
+ q = 0x7FFFFFFF;
+
+ else if ( (a >> 16) == 0 )
+ {
+ /* compute result directly */
+ q = (FT_Word32)(a << 16) / (FT_Word32)b;
+ }
+ else
+ {
+ /* we need more bits, we'll have to do it by hand */
+ FT_Word32 c;
+
+ q = (a/b) << 16;
+ c = a%b;
+
+ /* we must compute C*0x10000/B, we simply shift C and B so */
+ /* C becomes smaller than 16 bits */
+ while (c >> 16)
+ {
+ c >>= 1;
+ b <<= 1;
+ }
+
+ q += (c << 16)/b;
+ }
+
+ return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );
+ }
+
+
+ BASE_FUNC
+ void FT_Add64( FT_Int64* x,
+ FT_Int64* y,
+ FT_Int64* z )
+ {
+ register FT_Word32 lo, hi;
+
+ lo = x->lo + y->lo;
+ hi = x->hi + y->hi + ( lo < x->lo );
+
+ z->lo = lo;
+ z->hi = hi;
+ }
+
+
+ BASE_FUNC
+ void FT_MulTo64( FT_Int32 x,
+ FT_Int32 y,
+ FT_Int64* z )
+ {
+ FT_Int32 s;
+
+
+ s = x; x = ABS( x );
+ s ^= y; y = ABS( y );
+
+ {
+ FT_Word32 lo1, hi1, lo2, hi2, lo, hi, i1, i2;
+
+ lo1 = x & 0x0000FFFF; hi1 = x >> 16;
+ lo2 = y & 0x0000FFFF; hi2 = y >> 16;
+
+ lo = lo1 * lo2;
+ i1 = lo1 * hi2;
+ i2 = lo2 * hi1;
+ hi = hi1 * hi2;
+
+ /* Check carry overflow of i1 + i2 */
+ i1 += i2;
+ if ( i1 < i2 )
+ hi += 1L << 16;
+
+ hi += (i1 >> 16);
+ i1 = i1 << 16;
+
+ /* Check carry overflow of i1 + lo */
+ lo += i1;
+ hi += (lo < i1);
+
+ z->lo = lo;
+ z->hi = hi;
+ }
+
+ if ( s < 0 )
+ {
+ z->lo = (FT_Word32)-(FT_Int32)z->lo;
+ z->hi = ~z->hi + !(z->lo);
+ }
+ }
+
+
+ BASE_FUNC
+ FT_Int32 FT_Div64by32( FT_Int64* x,
+ FT_Int32 y )
+ {
+ FT_Int32 s;
+ FT_Word32 q, r, i, lo;
+
+
+ s = x->hi;
+ if ( s < 0 )
+ {
+ x->lo = (FT_Word32)-(FT_Int32)x->lo;
+ x->hi = ~x->hi + !(x->lo);
+ }
+ s ^= y; y = ABS( y );
+
+ /* Shortcut */
+ if ( x->hi == 0 )
+ {
+ q = x->lo / y;
+ return ( s < 0 ) ? -(FT_Int32)q : (FT_Int32)q;
+ }
+
+ r = x->hi;
+ lo = x->lo;
+
+ if ( r >= (FT_Word32)y ) /* we know y is to be treated as unsigned here */
+ return ( s < 0 ) ? 0x80000001L : 0x7FFFFFFFL;
+ /* 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 >= (FT_Word32)y )
+ {
+ r -= y;
+ q |= 1;
+ }
+ lo <<= 1;
+ }
+
+ return ( s < 0 ) ? -(FT_Int32)q : (FT_Int32)q;
+ }
+
+
+#endif /* LONG64 */
+
+
+/* END */
--- /dev/null
+++ b/src/base/ftcalc.h
@@ -1,0 +1,85 @@
+/***************************************************************************/
+/* */
+/* ftcalc.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 FTCALC_H
+#define FTCALC_H
+
+#include <freetype.h>
+#include <ftconfig.h> /* for LONG64 */
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+#ifdef LONG64
+
+ typedef INT64 FT_Int64;
+
+#define ADD_64( x, y, z ) z = (x) + (y)
+#define MUL_64( x, y, z ) z = (FT_Int64)(x) * (y)
+
+#define DIV_64( x, y ) ( (x) / (y) )
+
+#else /* LONG64 */
+
+ typedef struct FT_Int64_
+ {
+ FT_Word32 lo;
+ FT_Word32 hi;
+
+ } FT_Int64;
+
+#define ADD_64( x, y, z ) FT_Add64( &x, &y, &z )
+#define MUL_64( x, y, z ) FT_MulTo64( x, y, &z )
+#define DIV_64( x, y ) FT_Div64by32( &x, y )
+
+ BASE_DEF void FT_Add64 ( FT_Int64* x, FT_Int64* y, FT_Int64* z );
+ BASE_DEF void FT_MulTo64 ( FT_Int32 x, FT_Int32 y, FT_Int64* z );
+ BASE_DEF FT_Int32 FT_Div64by32( FT_Int64* x, FT_Int32 y );
+
+#endif /* LONG64 */
+
+#define SQRT_32( x ) FT_Sqrt32( x )
+
+ BASE_DEF FT_Int32 FT_Sqrt32( FT_Int32 l );
+
+ /*************************************************************************/
+ /* */
+ /* FT_MulDiv() and FT_MulFix() are declared in freetype.h. */
+ /* */
+ /*************************************************************************/
+
+
+#define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 )
+#define INT_TO_F2DOT14( x ) ( (FT_Long)(x) << 14 )
+#define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 )
+#define F2DOT14_TO_FIXED( x ) ( (FT_Long)(x) << 2 )
+#define FLOAT_TO_FIXED( x ) ( (FT_Long)(x * 65536.0) )
+
+#define ROUND_F26DOT6( x ) ( x >= 0 ? ( ((x) + 32) & -64) \
+ : ( -((32 - (x)) & -64) ) )
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* FTCALC_H */
+
+
+/* END */
--- /dev/null
+++ b/src/base/ftdebug.c
@@ -1,0 +1,93 @@
+/***************************************************************************/
+/* */
+/* ftdebug.c */
+/* */
+/* Debugging and logging 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. */
+/* */
+/***************************************************************************/
+
+
+#include <ftdebug.h>
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+ char ft_trace_levels[trace_max];
+#endif
+
+
+#if defined( FT_DEBUG_LEVEL_ERROR ) || defined( FT_DEBUG_LEVEL_TRACE )
+
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+ /*************************************************************************/
+ /* */
+ /* The Print() function is defined in ftconfig.h. It defaults to */
+ /* vprintf() on systems which have it. */
+ /* */
+ /*************************************************************************/
+
+
+ void FT_Message( const char* fmt, ... )
+ {
+ va_list ap;
+
+
+ va_start( ap, fmt );
+ vprintf( fmt, ap );
+ va_end( ap );
+ }
+
+
+ void FT_Panic( const char* fmt, ... )
+ {
+ va_list ap;
+
+
+ va_start( ap, fmt );
+ vprintf( fmt, ap );
+ va_end( ap );
+
+ exit( EXIT_FAILURE );
+ }
+
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+
+ EXPORT_FUNC
+ void FT_SetTraceLevel( FT_Trace component,
+ char level )
+ {
+ if ( component >= trace_max )
+ return;
+
+ /* if component is `trace_any', then change _all_ levels at once */
+ if ( component == trace_any )
+ {
+ int n;
+
+
+ for ( n = trace_any; n < trace_max; n++ )
+ ft_trace_levels[n] = level;
+ }
+ else /* otherwise, only change individual component */
+ ft_trace_levels[component] = level;
+ }
+
+#endif /* FT_DEBUG_LEVEL_TRACE */
+
+#endif /* FT_DEBUG_LEVEL_TRACE || FT_DEBUG_LEVEL_ERROR */
+
+
+/* END */
--- /dev/null
+++ b/src/base/ftdebug.h
@@ -1,0 +1,191 @@
+/***************************************************************************/
+/* */
+/* ftdebug.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). */
+ /* */
+ /* - error mode */
+ /* */
+ /* Only error messages are generated. */
+ /* */
+ /* - release mode: */
+ /* */
+ /* No error message is sent nor generated. The code is free from any */
+ /* debugging parts. */
+ /* */
+ /*************************************************************************/
+
+
+#ifndef FTDEBUG_H
+#define FTDEBUG_H
+
+#include <ftconfig.h> /* for FT_DEBUG_LEVEL_TRACE, FT_DEBUG_LEVEL_ERROR */
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+
+
+ typedef enum FT_Trace_
+ {
+ trace_any = 0,
+
+ /* first, define an enum for each common component */
+ trace_io, /* in ftsys */
+ trace_memory, /* in ftsys */
+ trace_sync, /* in ftsys */
+ trace_stream, /* stream manager - see ftstream.c */
+ trace_calc, /* computations - see ftcalc.c */
+ trace_raster, /* raster - see ftraster.c */
+ trace_list, /* list manager - see ftlist.c */
+ trace_objs, /* base objects - see ftobjs.c */
+
+ /* then define an enum for each TrueType driver component */
+ trace_ttobjs,
+ trace_ttload,
+ trace_ttgload,
+ trace_ttinterp,
+ trace_ttcmap,
+ trace_ttextend,
+ trace_ttdriver,
+
+ /* define an enum for each TrueDoc driver component */
+ trace_tdobjs,
+ trace_tdload,
+ trace_tdgload,
+ trace_tdhint,
+ trace_tddriver,
+
+ /* define an enum for each Type1 driver component */
+ trace_t1objs,
+ trace_t1load,
+ trace_t1gload,
+ trace_t1hint,
+ trace_t1driver,
+
+ /* other trace levels */
+ trace_init,
+
+ /* the last level must always be `trace_max' */
+ trace_max
+
+ } FT_Trace;
+
+ extern char ft_trace_levels[trace_max];
+
+
+ /*************************************************************************/
+ /* */
+ /* IMPORTANT! */
+ /* */
+ /* Each component must define the macro FT_COMPONENT to a valid */
+ /* Trace_Component value before using any TRACE macro. */
+ /* */
+ /*************************************************************************/
+
+
+#define FT_TRACE( level, varformat ) \
+ if ( ft_trace_levels[FT_COMPONENT] >= level ) \
+ FT_Message##varformat
+
+
+ EXPORT_DEF
+ void FT_SetTraceLevel( FT_Trace component,
+ char level );
+
+
+#elif defined( FT_DEBUG_LEVEL_ERROR )
+
+
+#define FT_TRACE( level, varformat ) /* nothing */
+
+
+#else /* release mode */
+
+
+#define FT_Assert( condition ) /* nothing */
+
+#define FT_TRACE( level, varformat ) /* nothing */
+#define FT_ERROR( varformat ) /* nothing */
+
+
+#endif /* FT_DEBUG_LEVEL_TRACE, FT_DEBUG_LEVEL_ERROR */
+
+
+ /*************************************************************************/
+ /* */
+ /* Define macros and functions that are common to the debug and trace */
+ /* modes. */
+ /* */
+ /* You need vprintf() to be able to compile ttdebug.c. */
+ /* */
+ /*************************************************************************/
+
+#if defined( FT_DEBUG_LEVEL_TRACE ) || defined( FT_DEBUG_LEVEL_ERROR )
+
+
+#include "stdio.h" /* for vprintf() */
+
+#define FT_Assert( condition ) \
+ if ( !(condition) ) \
+ FT_Panic( "assertion failed on line %d of file %s\n", __LINE__, __FILE__ );
+
+ extern void FT_Message( const char* fmt, ... );
+
+ /* print a message and exit */
+ extern void FT_Panic ( const char* fmt, ... );
+
+#define FT_ERROR( varformat ) FT_Message##varformat
+
+
+#endif /* FT_DEBUG_LEVEL_TRACE || FT_DEBUG_LEVEL_ERROR */
+
+
+#define FT_TRACE0( varformat ) FT_TRACE( 0, varformat )
+#define FT_TRACE1( varformat ) FT_TRACE( 1, varformat )
+#define FT_TRACE2( varformat ) FT_TRACE( 2, varformat )
+#define FT_TRACE3( varformat ) FT_TRACE( 3, varformat )
+#define FT_TRACE4( varformat ) FT_TRACE( 4, varformat )
+#define FT_TRACE5( varformat ) FT_TRACE( 5, varformat )
+#define FT_TRACE6( varformat ) FT_TRACE( 6, varformat )
+#define FT_TRACE7( varformat ) FT_TRACE( 7, varformat )
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+
+#endif /* FTDEBUG_H */
+
+
+/* END */
--- /dev/null
+++ b/src/base/ftdriver.h
@@ -1,0 +1,641 @@
+/***************************************************************************/
+/* */
+/* ftdriver.h */
+/* */
+/* FreeType driver 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. */
+/* */
+/***************************************************************************/
+
+#ifndef FTDRIVER_H
+#define FTDRIVER_H
+
+#include <freetype.h>
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** D R I V E R S ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* FTDriver_initDriver */
+ /* */
+ /* <Description> */
+ /* A driver method used to create a new driver object for a given */
+ /* format. */
+ /* */
+ /* <Input> */
+ /* driver :: A handle to the `new' driver object. The fields */
+ /* `library', `system', and `lock' are already set when the */
+ /* base layer calls this method. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ typedef FT_Error (*FTDriver_initDriver)( FT_Driver driver );
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* FTDriver_doneEngine */
+ /* */
+ /* <Description> */
+ /* A driver method used to finalize a given driver object. Note that */
+ /* all faces and resources for this driver have been released before */
+ /* this call, and that this function should NOT destroy the driver */
+ /* object. */
+ /* */
+ /* <Input> */
+ /* driver :: A handle to target driver object. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ typedef FT_Error (*FTDriver_doneDriver)( FT_Driver driver );
+
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* FTDriver_getInterface */
+ /* */
+ /* <Description> */
+ /* Each driver can provide one or more extensions to the base */
+ /* FreeType API. These can be used to access format specific */
+ /* features (e.g., all TrueType/OpenType resources share a common */
+ /* file structure and common tables which can be accessed through the */
+ /* `sfnt' interface), or more simply generic ones (e.g., the */
+ /* `postscript names' interface which can be used to retrieve the */
+ /* PostScript name of a given glyph index). */
+ /* */
+ /* <Input> */
+ /* driver :: A handle to a driver object. */
+ /* interface :: A string designing the interface. Examples */
+ /* are `sfnt', `post_names', `charmaps', etc. */
+ /* */
+ /* <Return> */
+ /* A typeless pointer to the extension's interface (normally a table */
+ /* of function pointers). Returns NULL when the requested extension */
+ /* isn't available (i.e., wasn't compiled in the driver at build */
+ /* time). */
+ /* */
+ typedef void* (*FTDriver_getInterface)( FT_Driver driver,
+ const FT_String* interface );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* FTDriver_formatInterface */
+ /* */
+ /* <Description> */
+ /* A driver interface field whose value is a driver-specific */
+ /* interface method tables. This table contains entry points to */
+ /* various functions that are strictly related to the driver's */
+ /* format. */
+ /* */
+ typedef void* FT_FormatInterface;
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** F A C E S ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* FTDriver_initFace */
+ /* */
+ /* <Description> */
+ /* A driver method used to initialize a new face object. The object */
+ /* must be created by the caller. */
+ /* */
+ /* <Input> */
+ /* driver :: A handle to the source driver object. */
+ /* resource :: A handle to the source resource. */
+ /* typeface_index :: The index of face in the font resource. Used to */
+ /* access individual faces in collections. */
+ /* */
+ /* face :: A handle to the new target face. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* The `typeface_index' parameter field will be set to -1 when the */
+ /* engine only wants to test the format of the resource. This means */
+ /* that font drivers should simply check the font format, then return */
+ /* immediately with an error code of 0 (meaning success). The field */
+ /* `num_faces' should be set. */
+ /* */
+ /* done_face() will be called subsequently, whatever the result was. */
+ /* */
+ typedef FT_Error (*FTDriver_initFace)( FT_Stream stream,
+ FT_Long typeface_index,
+ FT_Face face );
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* FTDriver_doneFace */
+ /* */
+ /* <Description> */
+ /* A driver method used to finalize a given face object. This */
+ /* function does NOT destroy the object, that is the responsibility */
+ /* of the caller. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ typedef void (*FTDriver_doneFace)( FT_Face face );
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* FTDriver_getKerning */
+ /* */
+ /* <Description> */
+ /* A driver method used to return the kerning vector between two */
+ /* glyphs of the same face. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the source face object. */
+ /* */
+ /* left_glyph :: The index of the left glyph in the kern pair. */
+ /* */
+ /* right_glyph :: The index of the right glyph in the kern pair. */
+ /* */
+ /* <Output> */
+ /* kerning :: The kerning vector. This is in font units for */
+ /* scalable formats, and in pixels for fixed-sizes */
+ /* formats. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* Only horizontal layouts (left-to-right & right-to-left) are */
+ /* supported by this method. Other layouts, or more sophisticated */
+ /* kernings are out of the scope of this method (the basic driver */
+ /* interface is meant to be simple). */
+ /* */
+ /* They can be implemented through format-specific interfaces. */
+ /* */
+ typedef FT_Error (*FTDriver_getKerning)( FT_Face face,
+ FT_UInt left_glyph,
+ FT_UInt right_glyph,
+ FT_Vector* kerning );
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** S I Z E S ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* FTDriver_initSize */
+ /* */
+ /* <Description> */
+ /* A driver method used to initialize a new size object. The object */
+ /* must be created by the caller. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the parent face object. */
+ /* size :: A handle to the new size object. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* This function should return an error if the face's format isn't */
+ /* scalable. */
+ /* */
+ typedef FT_Error (*FTDriver_initSize)( FT_Size size );
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* FTDriver_setCharSizes */
+ /* */
+ /* <Description> */
+ /* A driver method used to reset a size's character sizes (horizontal */
+ /* and vertical) expressed in fractional points. */
+ /* */
+ /* <Input> */
+ /* size :: A handle to the target size object. */
+ /* char_width :: The character width expressed in 26.6 fractional */
+ /* points. */
+ /* char_height :: The character height expressed in 26.6 fractional */
+ /* points. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* This function should always FAIL if the face format isn't */
+ /* scalable! */
+ /* */
+ typedef FT_Error (*FTDriver_setCharSizes)( FT_Size size,
+ FT_F26Dot6 char_width,
+ FT_F26Dot6 char_height,
+ FT_UInt horz_resolution,
+ FT_UInt vert_resolution );
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* FTDriver_setPixelSizes */
+ /* */
+ /* <Description> */
+ /* A driver method used to reset a size's character sizes (horizontal */
+ /* and vertical) expressed in integer pixels. */
+ /* */
+ /* <Input> */
+ /* size :: A handle to the target size object. */
+ /* */
+ /* pixel_width :: The character width expressed in 26.6 fractional */
+ /* pixels. */
+ /* */
+ /* pixel_height :: The character height expressed in 26.6 fractional */
+ /* pixels. */
+ /* */
+ /* point_size :: The corresponding character size in points. This */
+ /* value is only sent to the TrueType bytecode */
+ /* interpreter, even though 99% of glyph programs */
+ /* will simply ignore it. A safe value there is the */
+ /* maximum of the pixel width and height (multiplied */
+ /* by 64 to make it a 26.6 fixed float). */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* This function should work with all kinds of `Size' objects, either */
+ /* fixed or scalable ones. The `point_size' parameter will simply be */
+ /* ignored in case of fixed formats. */
+ /* */
+ typedef FT_Error (*FTDriver_setPixelSizes)( FT_Size size,
+ FT_UInt pixel_width,
+ FT_UInt pixel_height );
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* FTDriver_doneSize */
+ /* */
+ /* <Description> */
+ /* A driver method used to finalize a given size object. This method */
+ /* does NOT destroy the object; this is the responsibility of the */
+ /* caller. */
+ /* */
+ /* <Input> */
+ /* size :: A handle to the target size object. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ typedef void (*FTDriver_doneSize)( FT_Size size );
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** G L Y P H S L O T S ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* FTDriver_initGlyphSlot */
+ /* */
+ /* <Description> */
+ /* A driver method used to initialize a new glyph slot object. The */
+ /* object must be created by the caller. The glyph slot is a */
+ /* container where a single glyph can be loaded, either in outline or */
+ /* bitmap format. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the parent face object. */
+ /* slot :: A handle to the new glyph slot object. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ typedef FT_Error (*FTDriver_initGlyphSlot)( FT_GlyphSlot slot );
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* FTDriver_doneGlyphSlot */
+ /* */
+ /* <Description> */
+ /* A driver method used to finalize a given glyph slot. The object */
+ /* is not destroyed by this function. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the parent face object. */
+ /* slot :: A handle to the new glyph slot object. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ typedef void (*FTDriver_doneGlyphSlot)( FT_GlyphSlot slot );
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* FTDriver_loadGlyph */
+ /* */
+ /* <Description> */
+ /* A driver method used to load a glyph within a given glyph slot. */
+ /* */
+ /* <Input> */
+ /* slot :: A handle to target slot object where the glyph will */
+ /* be loaded. */
+ /* */
+ /* size :: A handle to the source face size at which the glyph */
+ /* must be scaled/loaded. */
+ /* */
+ /* glyph_index :: The index of the glyph in the font file. */
+ /* */
+ /* load_flags :: A flag indicating what to load for this glyph. The */
+ /* FTLOAD_??? constants can be used to control the */
+ /* glyph loading process (e.g., whether the outline */
+ /* should be scaled, whether to load bitmaps or not, */
+ /* whether to hint the outline, etc). */
+ /* <Output> */
+ /* result :: A set of bit flags indicating the type of data that */
+ /* was loaded in the glyph slot (outline, bitmap, */
+ /* pixmap, etc). */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ typedef FT_Error (*FTDriver_loadGlyph)( FT_GlyphSlot slot,
+ FT_Size size,
+ FT_UInt glyph_index,
+ FT_Int load_flags );
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** C H A R A C T E R M A P S ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* FTDriver_getCharIndex */
+ /* */
+ /* <Description> */
+ /* Uses a charmap to return a given character code's glyph index. */
+ /* */
+ /* <Input> */
+ /* charmap :: A handle to the source charmap object. */
+ /* charcode :: The character code. */
+ /* */
+ /* <Return> */
+ /* The glyph index. 0 means `undefined character code'. */
+ /* */
+ typedef FT_UInt (*FTDriver_getCharIndex)( FT_CharMap charmap,
+ FT_Long charcode );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* FT_DriverInterface */
+ /* */
+ /* <Description> */
+ /* A structure which holds a font driver's basic interface used by */
+ /* the high-level parts of FreeType (or other applications). */
+ /* */
+ /* Most scalable drivers provide a specialized interface to access */
+ /* format specific features. It can be retrieved with a call to */
+ /* `get_format_interface()', and should be defined in each font */
+ /* driver header (e.g., ttdriver.h, t1driver.h, etc). */
+ /* */
+ /* All fields are function pointers. */
+ /* */
+ /* <Fields> */
+ /* driver_object_size :: The size in bytes of a single driver */
+ /* object. */
+ /* */
+ /* face_object_size :: The size in bytes of a single face object. */
+ /* */
+ /* size_object_size :: The size in bytes of a single size object. */
+ /* */
+ /* slot_object_size :: The size in bytes of a single glyph slot */
+ /* object. */
+ /* */
+ /* driver_name :: a string to describe the driver to the */
+ /* system. It doesn't necessarily describe */
+ /* in detail all the font formats the driver */
+ /* may support. */
+ /* */
+ /* driver_version :: driver version number. starts at 1 */
+ /* */
+ /* driver_requires :: the FreeType major version this driver is */
+ /* written for. This number should be equal */
+ /* to or greater than 2 ! */
+ /* */
+ /* format_interface :: A pointer to the driver's format-specific */
+ /* interface. */
+ /* */
+ /* init_driver :: Used to initialize a given driver object. */
+ /* */
+ /* done_driver :: Used to finalize and destroy a given */
+ /* driver object. */
+ /* */
+ /* get_extension :: Returns an interface for a given driver */
+ /* extension. */
+ /* */
+ /* init_face :: Initializes a given face object. */
+ /* */
+ /* done_face :: Discards a face object, as well as all */
+ /* child objects (sizes, charmaps, glyph */
+ /* slots). */
+ /* */
+ /* get_kerning :: Returns the kerning vector corresponding */
+ /* to a pair of glyphs, expressed in unscaled */
+ /* font units. */
+ /* */
+ /* init_size :: Initializes a given size object. */
+ /* */
+ /* done_size :: Finalizes a given size object. */
+ /* */
+ /* set_size_char_sizes :: Resets a scalable size object's character */
+ /* size. */
+ /* */
+ /* set_pixel_sizes :: Resets a face size object's pixel */
+ /* dimensions. Applies to both scalable and */
+ /* fixed faces. */
+ /* */
+ /* init_glyph_slot :: Initializes a given glyph slot object. */
+ /* */
+ /* done_glyph_slot :: Finalizes a given glyph slot. */
+ /* */
+ /* load_glyph :: Loads a given glyph into a given slot. */
+ /* */
+ typedef struct FT_DriverInterface_
+ {
+ FT_Int driver_object_size;
+ FT_Int face_object_size;
+ FT_Int size_object_size;
+ FT_Int slot_object_size;
+
+ FT_String* driver_name;
+ FT_Int driver_version;
+ FT_Int driver_requires;
+
+ void* format_interface;
+
+ FTDriver_initDriver init_driver;
+ FTDriver_doneDriver done_driver;
+ FTDriver_getInterface get_interface;
+
+ FTDriver_initFace init_face;
+ FTDriver_doneFace done_face;
+ FTDriver_getKerning get_kerning;
+
+ FTDriver_initSize init_size;
+ FTDriver_doneSize done_size;
+ FTDriver_setCharSizes set_char_sizes;
+ FTDriver_setPixelSizes set_pixel_sizes;
+
+ FTDriver_initGlyphSlot init_glyph_slot;
+ FTDriver_doneGlyphSlot done_glyph_slot;
+ FTDriver_loadGlyph load_glyph;
+
+ FTDriver_getCharIndex get_char_index;
+
+ } FT_DriverInterface;
+
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* FT_DriverChain */
+ /* */
+ /* <Description> */
+ /* A very structure used exclusively by "ftinit.c" in the function */
+ /* FT_Add_Default_Drivers. This function is in charge of loading the */
+ /* set of "default" font drivers into each new library object. */
+ /* */
+ /* The set itself is determined at _compile_ time through various */
+ /* macro definitions. */
+ /* */
+ /* <Fields> */
+ /* next :: pointer to next element in driver list chain */
+ /* interface :: pointer to the driver's interface */
+ /* */
+ typedef struct FT_DriverChain_ FT_DriverChain;
+
+ struct FT_DriverChain_
+ {
+ const FT_DriverChain* next;
+ const FT_DriverInterface* interface;
+ };
+
+
+/*************************************************************************
+ *
+ * Here is a template of the code that should appear in each
+ * font driver's _interface_ file (the one included by "ftinit.c").
+ *
+ * It is used to build, at compile time, a simple linked list of
+ * the interfaces of the drivers which have been #included in
+ * "ftinit.c". See the source code of the latter file for details
+ *
+ * (Note that this is only required when you want your driver included
+ * in the set of default drivers loaded by FT_Init_FreeType. Other
+ * drivers can still be added manually at runtime with FT_Add_Driver.
+ *
+ * {
+ * #ifdef FTINIT_DRIVER_CHAIN
+ *
+ * static
+ * const FT_DriverChain ftinit_<FORMAT>_driver_chain =
+ * {
+ * FT_INIT_LAST_DRIVER_CHAIN,
+ * &<FORMAT>_driver_interface
+ * };
+ *
+ * #undef FT_INIT_LAST_DRIVER_CHAIN
+ * #define FT_INIT_LAST_DRIVER_CHAIN &ftinit_<FORMAT>_driver_chain
+ *
+ * #endif
+ * }
+ *
+ * replace <FORMAT> with your driver's prefix
+ *
+ *************************************************************************/
+
+
+#endif /* FTDRIVER_H */
+
+
+/* END */
--- /dev/null
+++ b/src/base/ftextend.c
@@ -1,0 +1,199 @@
+/*******************************************************************
+ *
+ * ftextend.h 2.0
+ *
+ * Extensions 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.
+ *
+ * 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 "ftextend.h"
+#include "ftobjs.h"
+
+/* required by the tracing mode */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_extend
+
+
+ typedef struct FT_Extension_Registry_
+ {
+ FT_Int num_extensions;
+ FT_Long cur_offset;
+ FT_Extension_Class classes[FT_MAX_EXTENSIONS];
+
+ } FT_Extension_Registry;
+
+
+ /* Initialize the extension component */
+
+ LOCAL_FUNC
+ FT_Error FT_Init_Extensions( FT_Driver driver )
+ {
+ FT_Error error;
+ FT_Memory memory;
+ FT_Extension_Registry* registry;
+
+ memory = driver->library->memory;
+ if ( ALLOC( registry, sizeof (*registry) ) )
+ return error;
+
+ registry->num_extensions = 0;
+ registry->cur_offset = 0;
+ driver->extensions = registry;
+
+ return FT_Err_Ok;
+ }
+
+
+ /* Finalize the extension component */
+
+ LOCAL_FUNC
+ FT_Error FT_Done_Extensions( FT_Driver driver )
+ {
+ FT_Memory memory = driver->memory;
+
+ FREE( driver->extensions );
+ return FT_Err_Ok;
+ }
+
+
+ /* Register a new extension */
+
+ EXPORT_FUNC
+ FT_Error FT_Register_Extension( FT_Driver driver,
+ FT_Extension_Class* clazz )
+ {
+ FT_Extension_Registry* registry;
+
+ registry = (FT_Extension_Registry*)driver->extensions;
+ if (registry)
+ {
+ FT_Int n = registry->num_extensions;
+ FT_Extension_Class* cur = registry->classes + n;
+
+ if ( n >= FT_MAX_EXTENSIONS )
+ return FT_Err_Too_Many_Extensions;
+
+ *cur = *clazz;
+
+ cur->offset = registry->cur_offset;
+
+ registry->num_extensions++;
+ registry->cur_offset += ( cur->size + FT_ALIGNMENT-1 ) & -FT_ALIGNMENT;
+ }
+
+ return FT_Err_Ok;
+ }
+
+
+ /* Query an extension block by extension_ID */
+
+ EXPORT_FUNC
+ void* FT_Get_Extension( FT_Face face,
+ const char* extension_id,
+ void* *extension_interface )
+ {
+ FT_Extension_Registry* registry;
+
+ registry = (FT_Extension_Registry*)face->driver->extensions;
+ if (registry && face->extensions)
+ {
+ FT_Extension_Class* cur = registry->classes;
+ FT_Extension_Class* limit = cur + registry->num_extensions;
+
+ for ( ; cur < limit; cur++ )
+ if ( strcmp( cur->id, extension_id ) == 0 )
+ {
+ *extension_interface = cur->interface;
+ return (void*)((char*)face->extensions + cur->offset);
+ }
+ }
+
+ /* could not find the extension id */
+ *extension_interface = 0;
+ return 0;
+ }
+
+ /* Destroy all extensions within a face object. Called by the */
+ /* face object destructor. */
+
+ LOCAL_FUNC
+ FT_Error FT_Destroy_Extensions( FT_Face face )
+ {
+ FT_Extension_Registry* registry;
+ FT_Memory memory;
+
+ registry = (FT_Extension_Registry*)face->driver->extensions;
+ if (registry && face->extensions)
+ {
+ FT_Extension_Class* cur = registry->classes;
+ FT_Extension_Class* limit = cur + registry->num_extensions;
+
+ for ( ; cur < limit; cur++ )
+ {
+ char* ext = (char*)face->extensions + cur->offset;
+
+ if (cur->finalize)
+ cur->finalize( ext, face );
+ }
+
+ memory = face->driver->memory;
+ FREE( face->extensions );
+ }
+ return FT_Err_Ok;
+ }
+
+
+ /* Create an extension within a face object. Called by the */
+ /* face object constructor. */
+
+ LOCAL_FUNC
+ FT_Error FT_Create_Extensions( FT_Face face )
+ {
+ FT_Extension_Registry* registry;
+ FT_Memory memory;
+ FT_Error error;
+
+ face->extensions = 0;
+
+ /* load extensions registry, exit succesfully if none is there */
+ registry = (FT_Extension_Registry*)face->driver->extensions;
+ if (!registry) return FT_Err_Ok;
+
+ memory = face->driver->memory;
+ if ( ALLOC( face->extensions, registry->cur_offset ) )
+ return error;
+
+ {
+ FT_Extension_Class* cur = registry->classes;
+ FT_Extension_Class* limit = cur + registry->num_extensions;
+
+ for ( ; cur < limit; cur++ )
+ {
+ char* ext = (char*)face->extensions + cur->offset;
+
+ if (cur->init)
+ {
+ error = cur->init( ext, face );
+ if (error) break;
+ }
+ }
+ }
+ return error;
+ }
+
+
+/* END */
--- /dev/null
+++ b/src/base/ftextend.h
@@ -1,0 +1,166 @@
+/*******************************************************************
+ *
+ * ftextend.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.
+ *
+ ******************************************************************/
+
+#ifndef FTEXTEND_H
+#define FTEXTEND_H
+
+#include "ftconfig.h"
+#include "ftobjs.h"
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+ /* The extensions don't need to be integrated at compile time into */
+ /* the engine, only at link time. */
+
+
+ /*****************************************************************
+ *
+ * <FuncType>
+ * FT_Extension_Initializer
+ *
+ * <Description>
+ * Each new face object can have several extensions associated
+ * to it at creation time. This function is used to initialize
+ * a given extension data for a given face.
+ *
+ * <Input>
+ * ext :: a typeless pointer to the extension data.
+ * face :: handle to the source face object the extension is
+ * associated with
+ *
+ * <Return>
+ * Error condition. 0 means success
+ *
+ * <Note>
+ * In case of error, the initializer should not destroy the
+ * extension data, as the finalizer will get called later
+ * by the function's caller..
+ *
+ *****************************************************************/
+
+ typedef FT_Error (*FT_Extension_Initializer)( void* ext,
+ FT_Face face );
+
+ /*****************************************************************
+ *
+ * <FuncType>
+ * FT_Extension_Finalizer
+ *
+ * <Description>
+ * Each new face object can have several extensions associated
+ * to it at creation time. This function is used to finalize
+ * a given extension data for a given face. This occurs before
+ * the face object itself is finalized.
+ *
+ * <Input>
+ * ext :: a typeless pointer to the extension data.
+ * face :: handle to the source face object the extension is
+ * associated with
+ *
+ *****************************************************************/
+
+ typedef void (*FT_Extension_Finalizer)( void* ext, FT_Face face );
+
+
+ /*****************************************************************
+ *
+ * <Struct>
+ * FT_Extension_Class
+ *
+ * <Description>
+ * A simple structure used to describe a given extension to
+ * the FreeType base layer. An FT_Extension_Class is used as
+ * a parameter for FT_Register_Extension.
+ *
+ * <Fields>
+ * id :: the extension's id. This is a normal C string
+ * that is used to uniquely reference the extension's
+ * interface.
+ *
+ * size :: the size in bytes of the extension data that must
+ * be associated with each face object.
+ *
+ * init :: a pointer to the extension data's initializer
+ * finalize :: a pointer to the extension data's finalizer
+ *
+ * inteface :: this pointer can be anything, but should usually
+ * point to a table of function pointers which implement
+ * the extension's interface.
+ *
+ * offset :: this field is set and used within the base layer
+ * and should be set to 0 when registering an
+ * extension through FT_Register_Extension. It contains
+ * an offset within the face's extension block for the
+ * current extension's data.
+ *
+ *****************************************************************/
+
+ typedef struct FT_Extension_Class_
+ {
+ const char* id;
+ FT_ULong size;
+ FT_Extension_Initializer init;
+ FT_Extension_Finalizer finalize;
+ void* interface;
+
+ FT_ULong offset;
+
+ } FT_Extension_Class;
+
+
+ EXPORT_DEF
+ FT_Error FT_Register_Extension( FT_Driver driver,
+ FT_Extension_Class* clazz );
+
+
+#ifdef FT_CONFIG_OPTION_EXTEND_ENGINE
+ /* Initialize the extension component */
+ LOCAL_DEF
+ FT_Error FT_Init_Extensions( FT_Library library );
+
+ /* Finalize the extension component */
+ LOCAL_DEF
+ FT_Error FT_Done_Extensions( FT_Library library );
+
+ /* Create an extension within a face object. Called by the */
+ /* face object constructor. */
+ LOCAL_DEF
+ FT_Error FT_Create_Extensions( FT_Face face );
+
+ /* Destroy all extensions within a face object. Called by the */
+ /* face object destructor. */
+ LOCAL_DEF
+ FT_Error FT_Destroy_Extensions( FT_Face face );
+#endif
+
+ /* Returns an extension's data & inteface according to its ID */
+ EXPORT_DEF
+ void* FT_Get_Extension( FT_Face face,
+ const char* extension_id,
+ void* *extension_interface );
+#ifdef __cplusplus
+ }
+#endif
+
+
+#endif /* FTEXTEND_H */
+
+
+/* END */
--- /dev/null
+++ b/src/base/ftinit.c
@@ -1,0 +1,169 @@
+/***************************************************************************/
+/* */
+/* ftinit.c */
+/* */
+/* FreeType initialisation layer (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 purpose of this file is to implement the three following
+ * functions:
+ *
+ * FT_Default_Drivers:
+ * This function is used to add the set of default drivers
+ * to a fresh new library object. The set is computed at compile
+ * time from the Makefiles inclusions in Makefile.lib. See the
+ * document "FreeType Internals" for more info.
+ *
+ *
+ * FT_Init_FreeType:
+ * This function creates a system object for the current platform,
+ * builds a library out of it, then calls FT_Default_Drivers
+ *
+ *
+ * FT_Done_FreeType:
+ * This function simply finalise the library and the corresponding
+ * system object.
+ *
+ *
+ * Note that even if FT_Init_FreeType uses the implementation of the
+ * system object defined at build time, client applications are still
+ * able to provide their own "ftsystem.c"
+ *
+ *
+ *
+ *
+ *
+ ************************************************************************/
+
+#include <ftobjs.h>
+#include <ftdriver.h>
+#include <ftconfig.h>
+#include <ftdebug.h>
+
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_init
+
+ /*************************************************************************/
+ /* */
+ /* The macros FT_SUPPORT_xxxx are defined by Makefile.lib when this file */
+ /* is compiled. They come from a make variable called FTINIT_MACROS */
+ /* which is updated by each driver Makefile. */
+ /* */
+ /* This means that when a driver isn't part of the build, ftinit.o */
+ /* won't try to reference it. */
+ /* */
+ /*************************************************************************/
+
+#define FTINIT_DRIVER_CHAIN
+#define FT_INIT_LAST_DRIVER_CHAIN ((FT_DriverChain*) 0)
+
+ /* Include the SFNT driver interface if needed */
+
+#ifdef FT_SUPPORT_SFNT
+#include "sfdriver.h"
+#endif
+
+ /* Include the TrueType driver interface if needed */
+
+#ifdef FT_SUPPORT_TRUETYPE
+#include "ttdriver.h"
+#endif
+
+
+ /* Include the Type1 driver interface if needed */
+
+#ifdef FT_SUPPORT_TYPE1
+#include "t1driver.h"
+#endif
+
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Default_Drivers */
+ /* */
+ /* <Description> */
+ /* Adds the set of default drivers to a given library object. */
+ /* */
+ /* <Input> */
+ /* library :: A handle to a new library object. */
+ /* */
+ EXPORT_FUNC
+ void FT_Default_Drivers( FT_Library library )
+ {
+ FT_Error error;
+ const FT_DriverChain* chain = FT_INIT_LAST_DRIVER_CHAIN;
+
+ while (chain)
+ {
+ error = FT_Add_Driver( library, chain->interface );
+
+ /* notify errors, but don't stop */
+ if (error)
+ {
+ FT_ERROR(( "FT.Default_Drivers: cannot install `%s', error = %x\n",
+ chain->interface->driver_name,
+ error ));
+ }
+
+ chain = chain->next;
+ error = 0; /* clear error */
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Init_FreeType */
+ /* */
+ /* <Description> */
+ /* Initializes a new FreeType library object. The set of drivers */
+ /* that are registered by this function is determined at build time. */
+ /* */
+ /* <Output> */
+ /* library :: A handle to a new library object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_Init_FreeType( FT_Library* library )
+ {
+ FT_Error error;
+ FT_Memory memory;
+
+ /* First of all, allocate a new system object -this function is part */
+ /* of the system-specific component, i.e. ftsystem.c */
+ memory = FT_New_Memory();
+ if (!memory)
+ {
+ FT_ERROR(( "FT_Init_FreeType:" ));
+ FT_ERROR(( " cannot find memory manager" ));
+ return FT_Err_Unimplemented_Feature;
+ }
+
+ /* builds a library out of it, then fill it with the set of */
+ /* default drivers.. */
+ error = FT_New_Library( memory, library );
+ if ( !error )
+ FT_Default_Drivers(*library);
+
+ return error;
+ }
+
+
+/* END */
--- /dev/null
+++ b/src/base/ftlist.c
@@ -1,0 +1,300 @@
+/***************************************************************************/
+/* */
+/* ftlist.c */
+/* */
+/* Generic list support for FreeType (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. */
+/* */
+/***************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* This file implements functions relative to list processing. Its */
+ /* data structures are defined in freetype.h. */
+ /* */
+ /*************************************************************************/
+
+
+#include <ftlist.h>
+#include <ftdebug.h>
+#include <ftobjs.h>
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_List_Find */
+ /* */
+ /* <Description> */
+ /* Finds the list node for a given listed object. */
+ /* */
+ /* <Input> */
+ /* list :: A pointer to the parent list. */
+ /* data :: The address of the listed object. */
+ /* */
+ /* <Return> */
+ /* List node. NULL if it wasn't found. */
+ /* */
+ BASE_FUNC
+ FT_ListNode FT_List_Find( FT_List list,
+ void* data )
+ {
+ FT_ListNode cur;
+
+
+ cur = list->head;
+ while ( cur )
+ {
+ if (cur->data == data)
+ return cur;
+
+ cur = cur->next;
+ }
+
+ return (FT_ListNode)0;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_List_Add */
+ /* */
+ /* <Description> */
+ /* Appends an element at the end of a list. */
+ /* */
+ /* <InOut> */
+ /* list :: A pointer to the parent list. */
+ /* node :: The node to append. */
+ /* */
+ BASE_FUNC
+ void FT_List_Add( FT_List list,
+ FT_ListNode node )
+ {
+ FT_ListNode before = list->tail;
+
+
+ node->next = 0;
+ node->prev = before;
+
+ if ( before )
+ before->next = node;
+ else
+ list->head = node;
+
+ list->tail = node;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_List_Insert */
+ /* */
+ /* <Description> */
+ /* Inserts an element at the head of a list. */
+ /* */
+ /* <InOut> */
+ /* list :: A pointer to parent list. */
+ /* node :: The node to insert. */
+ /* */
+ BASE_FUNC
+ void FT_List_Insert( FT_List list,
+ FT_ListNode node )
+ {
+ FT_ListNode after = list->head;
+
+
+ node->next = after;
+ node->prev = 0;
+
+ if ( !after )
+ list->tail = node;
+ else
+ after->prev = node;
+
+ list->head = node;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_List_Remove */
+ /* */
+ /* <Description> */
+ /* Removes a node from a list. This function doesn't check whether */
+ /* the node is in the list! */
+ /* */
+ /* <Input> */
+ /* node :: The node to remove. */
+ /* */
+ /* <InOut> */
+ /* list :: A pointer to the parent list. */
+ /* */
+ BASE_FUNC
+ void FT_List_Remove( FT_List list,
+ FT_ListNode node )
+ {
+ FT_ListNode before, after;
+
+
+ before = node->prev;
+ after = node->next;
+
+ if ( before )
+ before->next = after;
+ else
+ list->head = after;
+
+ if ( after )
+ after->prev = before;
+ else
+ list->tail = before;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_List_Up */
+ /* */
+ /* <Description> */
+ /* Moves a node to the head/top of a list. Used to maintain LRU */
+ /* lists. */
+ /* */
+ /* <InOut> */
+ /* list :: A pointer to the parent list. */
+ /* node :: The node to move. */
+ /* */
+ BASE_FUNC
+ void FT_List_Up( FT_List list,
+ FT_ListNode node )
+ {
+ FT_ListNode before, after;
+
+
+ before = node->prev;
+ after = node->next;
+
+ /* check wether we're already on top of the list */
+ if ( !before )
+ return;
+
+ before->next = after;
+
+ if ( after )
+ after->prev = before;
+ else
+ list->tail = before;
+
+ node->prev = 0;
+ node->next = list->head;
+ list->head->prev = node;
+ list->head = node;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_List_Iterate */
+ /* */
+ /* <Description> */
+ /* Parses a list and calls a given iterator function on each element. */
+ /* Note that parsing is stopped as soon as one of the iterator calls */
+ /* returns a non-zero value. */
+ /* */
+ /* <Input> */
+ /* list :: A handle to the list. */
+ /* iterator :: An interator function, called on each node of the */
+ /* list. */
+ /* user :: A user-supplied field which is passed as the second */
+ /* argument to the iterator. */
+ /* */
+ /* <Return> */
+ /* The result of the last iterator call. */
+ /* */
+ BASE_FUNC
+ FT_Error FT_List_Iterate( FT_List list,
+ FT_List_Iterator iterator,
+ void* user )
+ {
+ FT_ListNode cur = list->head;
+ FT_Error error = FT_Err_Ok;
+
+
+ while ( cur )
+ {
+ FT_ListNode next = cur->next;
+
+
+ error = iterator( cur, user );
+ if ( error )
+ break;
+
+ cur = next;
+ }
+
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_List_Finalize */
+ /* */
+ /* <Description> */
+ /* Destroys all elements in the list as well as the list itself. */
+ /* */
+ /* <Input> */
+ /* list :: A handle to the list. */
+ /* */
+ /* destroy :: A list destructor that will be applied to each element */
+ /* of the list. */
+ /* */
+ /* memory :: The current memory object where destructions take */
+ /* place. */
+ /* */
+ /* user :: A user-supplied field which is passed as the last */
+ /* argument to the destructor. */
+ /* */
+ BASE_FUNC
+ void FT_List_Finalize( FT_List list,
+ FT_List_Destructor destroy,
+ FT_Memory memory,
+ void* user )
+ {
+ FT_ListNode cur;
+
+
+ cur = list->head;
+ while ( cur )
+ {
+ FT_ListNode next = cur->next;
+ void* data = cur->data;
+
+
+ if ( destroy )
+ destroy( memory, data, user );
+
+ FREE( cur );
+ cur = next;
+ }
+
+ list->head = 0;
+ list->tail = 0;
+ }
+
+
+/* END */
--- /dev/null
+++ b/src/base/ftlist.h
@@ -1,0 +1,228 @@
+/***************************************************************************/
+/* */
+/* ftlist.c */
+/* */
+/* Generic list support for FreeType (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 file implements functions relative to list processing. Its */
+ /* data structures are defined in freetype.h. */
+ /* */
+ /*************************************************************************/
+
+
+#ifndef FTLIST_H
+#define FTLIST_H
+
+#include <freetype.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_List_Find */
+ /* */
+ /* <Description> */
+ /* Finds the list node for a given listed object. */
+ /* */
+ /* <Input> */
+ /* list :: A pointer to the parent list. */
+ /* data :: The address of the listed object. */
+ /* */
+ /* <Return> */
+ /* List node. NULL if it wasn't found. */
+ /* */
+ EXPORT_DEF
+ FT_ListNode FT_List_Find( FT_List list,
+ void* data );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_List_Add */
+ /* */
+ /* <Description> */
+ /* Appends an element at the end of a list. */
+ /* */
+ /* <InOut> */
+ /* list :: A pointer to the parent list. */
+ /* node :: The node to append. */
+ /* */
+ EXPORT_DEF
+ void FT_List_Add( FT_List list,
+ FT_ListNode node );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_List_Insert */
+ /* */
+ /* <Description> */
+ /* Inserts an element at the head of a list. */
+ /* */
+ /* <InOut> */
+ /* list :: A pointer to parent list. */
+ /* node :: The node to insert. */
+ /* */
+ EXPORT_DEF
+ void FT_List_Insert( FT_List list,
+ FT_ListNode node );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_List_Remove */
+ /* */
+ /* <Description> */
+ /* Removes a node from a list. This function doesn't check whether */
+ /* the node is in the list! */
+ /* */
+ /* <Input> */
+ /* node :: The node to remove. */
+ /* */
+ /* <InOut> */
+ /* list :: A pointer to the parent list. */
+ /* */
+ EXPORT_DEF
+ void FT_List_Remove( FT_List list,
+ FT_ListNode node );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_List_Up */
+ /* */
+ /* <Description> */
+ /* Moves a node to the head/top of a list. Used to maintain LRU */
+ /* lists. */
+ /* */
+ /* <InOut> */
+ /* list :: A pointer to the parent list. */
+ /* node :: The node to move. */
+ /* */
+ EXPORT_DEF
+ void FT_List_Up( FT_List list,
+ FT_ListNode node );
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* FT_List_Iterator */
+ /* */
+ /* <Description> */
+ /* An FT_List iterator function which is called during a list parse */
+ /* by FT_List_Iterate(). */
+ /* */
+ /* <Input> */
+ /* node :: The current iteration list node. */
+ /* user :: A typeless pointer passed to FT_List_Iterate(). */
+ /* Can be used to point to the iteration's state. */
+ /* */
+ typedef FT_Error (*FT_List_Iterator)( FT_ListNode node,
+ void* user );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_List_Iterate */
+ /* */
+ /* <Description> */
+ /* Parses a list and calls a given iterator function on each element. */
+ /* Note that parsing is stopped as soon as one of the iterator calls */
+ /* returns a non-zero value. */
+ /* */
+ /* <Input> */
+ /* list :: A handle to the list. */
+ /* iterator :: An interator function, called on each node of the */
+ /* list. */
+ /* user :: A user-supplied field which is passed as the second */
+ /* argument to the iterator. */
+ /* */
+ /* <Return> */
+ /* The result of the last iterator call. */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_List_Iterate( FT_List list,
+ FT_List_Iterator iterator,
+ void* user );
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* FT_List_Destructor */
+ /* */
+ /* <Description> */
+ /* An FT_List iterator function which is called during a list */
+ /* finalisation by FT_List_Finalize() to destroy all elements in a */
+ /* given list. */
+ /* */
+ /* <Input> */
+ /* system :: The current system object. */
+ /* data :: The current object to destroy. */
+ /* user :: A typeless pointer passed to FT_List_Iterate(). It can */
+ /* used to point to the iteration's state. */
+ /* */
+ typedef void (*FT_List_Destructor)( FT_Memory memory,
+ void* data,
+ void* user );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_List_Finalize */
+ /* */
+ /* <Description> */
+ /* Destroys all elements in the list as well as the list itself. */
+ /* */
+ /* <Input> */
+ /* list :: A handle to the list. */
+ /* */
+ /* destroy :: A list destructor that will be applied to each element */
+ /* of the list. */
+ /* */
+ /* system :: The current system object where destructions take */
+ /* place. */
+ /* */
+ /* user :: A user-supplied field which is passed as the last */
+ /* argument to the destructor. */
+ /* */
+ EXPORT_DEF
+ void FT_List_Finalize( FT_List list,
+ FT_List_Destructor destroy,
+ FT_Memory memory,
+ void* user );
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* FTLIST_H */
+
+
+/* END */
--- /dev/null
+++ b/src/base/ftobjs.c
@@ -1,0 +1,2123 @@
+/***************************************************************************/
+/* */
+/* ftobjs.c */
+/* */
+/* The FreeType private base classes (base). */
+/* */
+/* 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 <ftobjs.h>
+#include <ftlist.h>
+#include <ftdebug.h>
+#include <ftstream.h>
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** M E M O R Y ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ /*************************************************************************/
+ /* */
+ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+ /* parameter of the PTRACE() and PERROR() macros, used to print/log */
+ /* messages during execution. */
+ /* */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_memory
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Alloc */
+ /* */
+ /* <Description> */
+ /* Allocates a new block of memory. The returned area is always */
+ /* zero-filled, this is a strong convention in many FreeType parts. */
+ /* */
+ /* <Input> */
+ /* memory :: A handle to a given `memory object' where allocation */
+ /* occurs. */
+ /* */
+ /* size :: The size in bytes of the block to allocate. */
+ /* */
+ /* <Output> */
+ /* P :: A pointer to the fresh new block. It should be set to */
+ /* NULL if `size' is 0, or in case of error. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ BASE_FUNC
+ FT_Error FT_Alloc( FT_Memory memory,
+ FT_Long size,
+ void** P )
+ {
+ FT_Assert( P != 0 );
+
+ if (size > 0)
+ {
+ *P = memory->alloc( memory, size );
+ if (!*P)
+ {
+ FT_ERROR(( "FT.Alloc:" ));
+ FT_ERROR(( " out of memory ? (%ld requested)\n",
+ size ));
+
+ return FT_Err_Out_Of_Memory;
+ }
+ MEM_Set( *P, 0, size );
+ }
+ else
+ *P = NULL;
+
+ FT_TRACE2(( "FT_Alloc:" ));
+ FT_TRACE2(( " size = %ld, block = 0x%08lx, ref = 0x%08lx\n",
+ size, (long)*P, (long)P ));
+
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Realloc */
+ /* */
+ /* <Description> */
+ /* Reallocates a block of memory pointed to by `*P' to `Size' bytes */
+ /* from the heap, possibly changing `*P'. */
+ /* */
+ /* <Input> */
+ /* memory :: A handle to a given `memory object' where allocation */
+ /* occurs. */
+ /* */
+ /* current :: current block size in bytes */
+ /* size :: the new block size in bytes */
+ /* */
+ /* <InOut> */
+ /* P :: A pointer to the fresh new block. It should be set to */
+ /* NULL if `size' is 0, or in case of error. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* All callers of FT_Realloc _must_ provide the current block size */
+ /* as well as the new one. */
+ /* */
+ /* When the memory object's flag FT_SYSTEM_FLAG_NO_REALLOC is */
+ /* set, this function will try to emulate a realloc through uses */
+ /* of FT_Alloc and FT_Free. Otherwise, it will call the system- */
+ /* specific "realloc" implementation. */
+ /* */
+ /* (Some embedded systems do not have a working realloc). */
+ /* */
+ BASE_FUNC
+ FT_Error FT_Realloc( FT_Memory memory,
+ FT_Long current,
+ FT_Long size,
+ void* *P )
+ {
+ void* Q;
+
+ FT_Assert( P != 0 );
+
+ /* if the original pointer is NULL, call FT_Alloc() */
+ if ( !*P )
+ return FT_Alloc( memory, size, P );
+
+ /* if the new block if zero-sized, clear the current one */
+ if ( size <= 0 )
+ {
+ FT_Free( memory, P );
+ return FT_Err_Ok;
+ }
+
+ Q = memory->realloc( memory, current, size, *P );
+ if ( !Q ) goto Fail;
+
+ *P = Q;
+ return FT_Err_Ok;
+
+ Fail:
+ FT_ERROR(( "FT.Realloc:" ));
+ FT_ERROR(( " failed (current %ld, requested %ld)\n",
+ current, size ));
+ return FT_Err_Out_Of_Memory;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Free */
+ /* */
+ /* <Description> */
+ /* Releases a given block of memory allocated through FT_Alloc(). */
+ /* */
+ /* <Input> */
+ /* memory :: A handle to a given `memory object' where allocation */
+ /* occured. */
+ /* */
+ /* P :: This is the _address_ of a _pointer_ which points to the */
+ /* allocated block. It is always set to NULL on exit. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* If P or *P are NULL, this function should return successfully. */
+ /* This is a strong convention within all of FreeType and its */
+ /* drivers. */
+ /* */
+ BASE_FUNC
+ void FT_Free( FT_Memory memory,
+ void* *P )
+ {
+ FT_TRACE2(( "FT_Free:" ));
+ FT_TRACE2(( " Freeing block 0x%08lx, ref 0x%08lx\n",
+ (long)P, (P ? (long)*P : -1) ));
+
+ FT_Assert( P != 0 );
+
+ if ( *P )
+ {
+ memory->free( memory, *P );
+ *P = 0;
+ }
+ }
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** O B J E C T M A N A G E M E N T ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ /* destructor for sizes list */
+ static
+ void destroy_size( FT_Memory memory,
+ FT_Size size,
+ FT_Driver driver )
+ {
+ /* finalize format-specific stuff */
+ driver->interface.done_size( size );
+ FREE( size );
+ }
+
+
+ /* destructor for faces list */
+ static
+ void destroy_face( FT_Memory memory,
+ FT_Face face,
+ FT_Driver driver )
+ {
+ /* Discard glyph slots for this face */
+ /* XXX: Beware! FT_Done_GlyphSlot() changes the field `face->slot' */
+ while ( face->glyph )
+ FT_Done_GlyphSlot( face->glyph );
+
+ /* Discard all sizes for this face */
+ FT_List_Finalize( &face->sizes_list,
+ (FT_List_Destructor)destroy_size,
+ memory,
+ driver );
+ face->size = 0;
+
+ /* finalize format-specific stuff */
+ driver->interface.done_face( face );
+
+ /* Now discard client data */
+ if ( face->generic.finalizer )
+ face->generic.finalizer( face );
+
+ /* get rid of it */
+ FREE( face );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Destroy_Driver */
+ /* */
+ /* <Description> */
+ /* Destroys a given driver object. This also destroys all child */
+ /* faces. */
+ /* */
+ /* <Input> */
+ /* driver :: A handle to the target driver object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* The driver _must_ be LOCKED! */
+ /* */
+ static
+ void Destroy_Driver( FT_Driver driver )
+ {
+ FT_Memory memory = driver->memory;
+
+ /* now, finalize all faces in the driver list */
+ FT_List_Finalize( &driver->faces_list,
+ (FT_List_Destructor)destroy_face,
+ memory,
+ driver );
+
+ /* finalize the driver object */
+ if (driver->interface.done_driver)
+ driver->interface.done_driver(driver);
+
+ /* finalize client-data */
+ if (driver->generic.finalizer)
+ driver->generic.finalizer(driver);
+
+ /* discard it */
+ FREE( driver );
+ }
+
+
+
+
+
+ BASE_FUNC
+ FT_Glyph_Format* FT_Get_Glyph_Format( FT_Library library,
+ FT_Glyph_Tag format_tag )
+ {
+ FT_Glyph_Format* cur = library->glyph_formats;
+ FT_Glyph_Format* limit = cur + FT_MAX_GLYPH_FORMATS;
+
+ for ( ; cur < limit; cur ++ )
+ {
+ if ( cur->format_tag == format_tag )
+ return cur;
+ }
+
+ return 0;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Set_Raster */
+ /* */
+ /* <Description> */
+ /* This function is used to change the raster module used to convert */
+ /* from a given memory object. It is thus possible to use libraries */
+ /* with distinct memory allocators within the same program. */
+ /* */
+ /* <Input> */
+ /* memory :: A handle to the original memory object. */
+ /* */
+ /* <Output> */
+ /* library :: A handle to a new library object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_Set_Raster( FT_Library library,
+ FT_Raster_Interface* interface,
+ FT_Raster raster )
+ {
+ FT_Memory memory = library->memory;
+ FT_Error error = FT_Err_Ok;
+ FT_Glyph_Format* format;
+
+ /* allocate the render pool if necessary */
+ if ( !library->raster_pool &&
+ ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) )
+ goto Exit;
+
+ /* find the glyph formatter for the raster's format */
+ format = FT_Get_Glyph_Format( library, interface->format_tag );
+ if (!format)
+ {
+ error = FT_Err_Invalid_Argument;
+ goto Exit;
+ }
+
+ /* free previous raster object if necessary */
+ if (format->raster_allocated)
+ {
+ FREE( format->raster );
+ format->raster_allocated = 0;
+ }
+
+ /* allocate new raster object is necessary */
+ if (!raster)
+ {
+ if ( ALLOC( raster, interface->size ) )
+ goto Exit;
+
+ format->raster_allocated = 1;
+ }
+ format->raster = raster;
+ format->raster_interface = interface;
+
+ /* initialize the raster object */
+ error = interface->init( raster,
+ (char*)library->raster_pool,
+ FT_RENDER_POOL_SIZE );
+ if (error)
+ {
+ if (format->raster_allocated)
+ {
+ FREE( format->raster );
+ format->raster_allocated = 0;
+ }
+ }
+
+ Exit:
+ return error;
+ }
+
+ EXPORT_FUNC
+ void FT_Set_Debug_Hook( FT_Library library,
+ FT_UInt hook_index,
+ FT_DebugHook_Func debug_hook )
+ {
+ if (hook_index < (sizeof(library->debug_hooks)/sizeof(void*)))
+ {
+ library->debug_hooks[hook_index] = debug_hook;
+ }
+ }
+
+
+
+ BASE_FUNC
+ FT_Error FT_Add_Glyph_Format( FT_Library library,
+ FT_Glyph_Format* format )
+ {
+ FT_Glyph_Format* new = 0;
+
+ {
+ FT_Glyph_Format* cur = library->glyph_formats;
+ FT_Glyph_Format* limit = cur + FT_MAX_GLYPH_FORMATS;
+
+ for ( ; cur < limit; cur++ )
+ {
+ /* return an error if the format is already registered */
+ if ( cur->format_tag == format->format_tag )
+ return FT_Err_Invalid_Glyph_Format;
+
+ if ( cur->format_tag == 0 && new == 0 )
+ new = cur;
+ }
+ }
+
+ /* if there is no place to hold the new format, return an error */
+ if (!new)
+ return FT_Err_Too_Many_Glyph_Formats;
+
+ *new = *format;
+
+ /* now, create a raster object if we need to */
+ return FT_Set_Raster( library,
+ format->raster_interface,
+ format->raster );
+ }
+
+
+
+ BASE_FUNC
+ FT_Error FT_Remove_Glyph_Format( FT_Library library,
+ FT_Glyph_Tag format_tag )
+ {
+ FT_Memory memory;
+ FT_Glyph_Format* cur = library->glyph_formats;
+ FT_Glyph_Format* limit = cur + FT_MAX_GLYPH_FORMATS;
+
+ memory = library->memory;
+
+ for ( ; cur < limit; cur++ )
+ {
+ if (cur->format_tag == format_tag)
+ {
+ if (cur->raster_allocated)
+ {
+ FREE( cur->raster );
+ cur->raster_allocated = 0;
+ }
+ cur->format_tag = 0;
+ return FT_Err_Ok;
+ }
+ }
+
+ return FT_Err_Invalid_Argument;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_New_Library */
+ /* */
+ /* <Description> */
+ /* This function is used to create a new FreeType library instance */
+ /* from a given memory object. It is thus possible to use libraries */
+ /* with distinct memory allocators within the same program. */
+ /* */
+ /* <Input> */
+ /* memory :: A handle to the original memory object. */
+ /* */
+ /* <Output> */
+ /* library :: A handle to a new library object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_New_Library( FT_Memory memory,
+ FT_Library* alibrary )
+ {
+ FT_Library library = 0;
+ FT_Error error;
+
+ /* First of all, allocate the library object */
+ if ( ALLOC( library, sizeof ( *library ) ) )
+ return error;
+
+ library->memory = memory;
+
+ /* now register the default raster for the `outline' glyph image format */
+ {
+ FT_Glyph_Format outline_format =
+ {
+ ft_glyph_format_outline,
+ &ft_default_raster,
+ 0,
+ 0
+ };
+
+ error = FT_Add_Glyph_Format( library, &outline_format );
+ }
+
+ /* That's ok now */
+ *alibrary = library;
+
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Done_Library */
+ /* */
+ /* <Description> */
+ /* Discards a given library object. This closes all drivers and */
+ /* discards all resource objects. */
+ /* */
+ /* <Input> */
+ /* library :: A handle to the target library */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_Done_Library( FT_Library library )
+ {
+ FT_Memory memory;
+ FT_Int n;
+
+
+ if ( !library )
+ return FT_Err_Invalid_Library_Handle;
+
+ memory = library->memory;
+
+ /* Discard client-data */
+ if( library->generic.finalizer )
+ library->generic.finalizer( library );
+
+ /* Close all drivers in the library */
+ for ( n = 0; n < library->num_drivers; n++ )
+ {
+ FT_Driver driver = library->drivers[n];
+
+ if ( driver )
+ {
+ Destroy_Driver( driver );
+ library->drivers[n] = 0;
+ }
+ }
+
+ /* Destroy raster object */
+ FREE( library->raster_pool );
+
+ {
+ FT_Glyph_Format* cur = library->glyph_formats;
+ FT_Glyph_Format* limit = cur + FT_MAX_GLYPH_FORMATS;
+
+ for ( ; cur < limit; cur++ )
+ {
+ if ( cur->raster_allocated )
+ {
+ FREE( cur->raster );
+ cur->raster_allocated = 0;
+ }
+ }
+ }
+
+ FREE( library );
+
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Set_Raster_Mode */
+ /* */
+ /* <Description> */
+ /* Set a raster-specific mode. */
+ /* */
+ /* <Input> */
+ /* library :: A handle to a target library object. */
+ /* format :: the glyph format used to select the raster */
+ /* mode :: the raster-specific mode descriptor */
+ /* args :: the mode arguments */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_Set_Raster_Mode( FT_Library library,
+ FT_Glyph_Tag format_tag,
+ const char* mode,
+ const char* args )
+ {
+ FT_Memory memory;
+ FT_Error error;
+ FT_Glyph_Format* format = 0;
+
+ {
+ FT_Glyph_Format* cur = library->glyph_formats;
+ FT_Glyph_Format* limit = cur + FT_MAX_GLYPH_FORMATS;
+
+ for (; cur < limit; cur++)
+ {
+ if (cur->format_tag == format_tag)
+ {
+ format = cur;
+ break;
+ }
+ }
+ }
+
+ if (!format)
+ return FT_Err_Invalid_Argument;
+
+ memory = library->memory;
+
+ error = FT_Err_Ok;
+ if (format->raster)
+ error = format->raster_interface->set_mode( format->raster, mode, args );
+
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Add_Driver */
+ /* */
+ /* <Description> */
+ /* Registers a new driver in a given library object. This function */
+ /* takes only a pointer to a driver interface. It uses it to create */
+ /* the new driver, then sets up some important fields. */
+ /* */
+ /* <Input> */
+ /* library :: A handle to the target library object. */
+ /* */
+ /* driver_interface :: A pointer to a driver interface table. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* This function doesn't check whether the driver is already */
+ /* installed! */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_Add_Driver( FT_Library library,
+ const FT_DriverInterface* driver_interface )
+ {
+ FT_Error error;
+ FT_Driver driver;
+ FT_Memory memory;
+
+ if ( !library || !driver_interface )
+ return FT_Err_Invalid_Library_Handle;
+
+ memory = library->memory;
+ error = FT_Err_Ok;
+
+ if ( library->num_drivers >= FT_MAX_DRIVERS )
+ error = FT_Err_Too_Many_Drivers;
+ else
+ {
+ if ( ALLOC( driver, driver_interface->driver_object_size ) )
+ goto Exit;
+
+ driver->library = library;
+ driver->memory = memory;
+ driver->interface = *driver_interface;
+
+ if (driver_interface->init_driver)
+ {
+ error = driver_interface->init_driver( driver );
+ if ( error ) goto Fail;
+ }
+
+ library->drivers[library->num_drivers++] = driver;
+ goto Exit;
+
+ Fail:
+ FREE( driver );
+ }
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Remove_Driver */
+ /* */
+ /* <Description> */
+ /* Unregister a given driver. This closes the driver, which in turn */
+ /* destroys all faces, sizes, slots, etc. associated with it. */
+ /* */
+ /* This function also DESTROYS the driver object. */
+ /* */
+ /* <Input> */
+ /* driver :: A handle to target driver object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_Remove_Driver( FT_Driver driver )
+ {
+ FT_Library library;
+ FT_Memory memory;
+ FT_Driver *cur, *last;
+ FT_Error error;
+
+
+ if ( !driver )
+ return FT_Err_Invalid_Driver_Handle;
+
+ library = driver->library;
+ memory = driver->memory;
+
+ if ( !library || !memory )
+ return FT_Err_Invalid_Driver_Handle;
+
+ /* look-up driver entry in library table */
+ error = FT_Err_Invalid_Driver_Handle;
+ cur = library->drivers;
+ last = cur + library->num_drivers - 1;
+
+ for ( ; cur <= last; cur++ )
+ {
+ if ( *cur == driver )
+ {
+ /* Destroy the driver object */
+ Destroy_Driver( driver );
+
+ /* now move the last driver in the table to the vacant slot */
+ if (cur < last)
+ {
+ *cur = *last;
+ *last = 0;
+ }
+ library->num_drivers--;
+
+ /* exit loop */
+ error = FT_Err_Ok;
+ break;
+ }
+ }
+
+ return error;
+ }
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Get_Driver */
+ /* */
+ /* <Description> */
+ /* returns the handle of the driver responsible for a given format */
+ /* (or service) according to its `name'. */
+ /* */
+ /* <Input> */
+ /* library :: handle to library object. */
+ /* driver_name :: name of driver to look-up. */
+ /* */
+ /* <Return> */
+ /* handle to driver object. 0 otherwise */
+ /* */
+ EXPORT_FUNC
+ FT_Driver FT_Get_Driver( FT_Library library,
+ char* driver_name )
+ {
+ FT_Driver *cur, *limit;
+
+ if (!library || !driver_name)
+ return 0;
+
+ cur = library->drivers;
+ limit = cur + library->num_drivers;
+ for ( ; cur < limit; cur++ )
+ {
+ if ( strcmp( (*cur)->interface.driver_name, driver_name ) == 0 )
+ return *cur;
+ }
+ return 0;
+ }
+
+
+
+ static
+ FT_Error open_face( FT_Driver driver,
+ FT_Stream stream,
+ FT_Long face_index,
+ FT_Face* aface )
+ {
+ FT_Memory memory;
+ FT_DriverInterface* interface;
+ FT_Face face = 0;
+ FT_Error error;
+
+
+ interface = &driver->interface;
+ memory = driver->memory;
+
+ /* allocate the face object, and performs basic initialisation */
+ if ( ALLOC( face, interface->face_object_size ) )
+ goto Fail;
+
+ face->driver = driver;
+ face->memory = memory;
+ face->stream = stream;
+
+ error = interface->init_face( stream, face_index, face );
+ if ( error )
+ goto Fail;
+
+ *aface = face;
+
+ Fail:
+ if ( error )
+ {
+ interface->done_face( face );
+ FREE( face );
+ *aface = 0;
+ }
+
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_New_Face */
+ /* */
+ /* <Description> */
+ /* Creates a new face object from a given resource and typeface */
+ /* index. */
+ /* */
+ /* <Input> */
+ /* resource :: A handle to a source resource. */
+ /* */
+ /* face_index :: The index of the face within the resource. The */
+ /* first face has index 0. */
+ /* <Output> */
+ /* face :: A handle to a new face object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* Unlike FreeType 1.1, this function automatically creates a glyph */
+ /* slot for the face object which can be accessed directly through */
+ /* `face->glyph'. */
+ /* */
+ /* Note that additional slots can be added to each face through the */
+ /* FT_New_GlyphSlot() API function. Slots are linked in a single */
+ /* list through their `next' field. */
+ /* */
+ /* FT_New_Face() can be used to determine and/or check the font */
+ /* format of a given font resource. If the `face_index' field is */
+ /* negative, the function will _not_ return any face handle in */
+ /* `*face'. Its return value should be 0 if the resource is */
+ /* recognized, or non-zero if not. */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_New_Face( FT_Library library,
+ const char* pathname,
+ FT_Long face_index,
+ FT_Face *aface )
+ {
+ FT_Stream stream;
+ FT_Memory memory;
+ FT_Error error;
+
+ memory = library->memory;
+ if ( ALLOC( stream, sizeof(*stream) ) )
+ goto Fail;
+
+ stream->memory = memory;
+
+ error = FT_New_Stream( pathname, stream );
+ if (error) goto Fail_Stream;
+
+ error = FT_Open_Face( library, stream, face_index, aface );
+ if (!error)
+ return error;
+
+ /* close stream in case of error */
+ stream->close( stream );
+
+ Fail_Stream:
+ FREE(stream);
+ Fail:
+ return error;
+ }
+
+ EXPORT_FUNC
+ FT_Error FT_New_Memory_Face( FT_Library library,
+ void* file_base,
+ FT_Long file_size,
+ FT_Long face_index,
+ FT_Face* face )
+ {
+ FT_Stream stream;
+ FT_Memory memory;
+ FT_Error error;
+
+ memory = library->memory;
+ if ( ALLOC( stream, sizeof(*stream) ) )
+ goto Fail;
+
+ stream->memory = memory;
+
+ FT_New_Memory_Stream( library, (void*)file_base, file_size, stream );
+
+ error = FT_Open_Face( library, stream, face_index, face );
+ if (!error)
+ return error;
+
+ FREE(stream);
+ Fail:
+ return error;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error FT_Open_Face( FT_Library library,
+ FT_Stream stream,
+ FT_Long face_index,
+ FT_Face* aface )
+ {
+ FT_Error error;
+ FT_Driver driver;
+ FT_Memory memory;
+ FT_Face face = 0;
+ FT_ListNode node = 0;
+
+ *aface = 0;
+
+ if ( !library || !stream )
+ return FT_Err_Invalid_Handle;
+
+ memory = library->memory;
+
+ {
+ /* check each font driver for an appropriate format */
+ FT_Driver* cur = library->drivers;
+ FT_Driver* limit = cur + library->num_drivers;
+
+ for ( ; cur < limit; cur++ )
+ {
+ driver = *cur;
+ if (driver->interface.face_object_size)
+ {
+ error = open_face( driver, stream, face_index, &face );
+ if ( !error )
+ goto Success;
+
+ if ( error != FT_Err_Unknown_File_Format )
+ goto Bad_Resource;
+ }
+ }
+
+ /* no driver is able to handle this format */
+ error = FT_Err_Unknown_File_Format;
+ goto Bad_Resource;
+ }
+
+ Success:
+ /****************************************************************/
+ /* if we were simply checking the font format, discard the face */
+ /* object, then return successfully. */
+ if ( face_index < 0 )
+ {
+ driver->interface.done_face( face );
+ FREE( face );
+ goto Exit;
+ }
+
+ FT_TRACE4(( "FT_New_Face: New face object, adding to list\n" ));
+
+ /****************************************************************/
+ /* Otherwise add the face object to its driver's list */
+ if ( ALLOC( node, sizeof ( *node ) ) )
+ goto Fail;
+
+ node->data = face;
+ FT_List_Add( &driver->faces_list, node );
+
+ /****************************************************************/
+ /* now allocate a glyph slot object for the face */
+ {
+ FT_GlyphSlot slot;
+
+ FT_TRACE4(( "FT_Open_Face: Creating glyph slot\n" ));
+ error = FT_New_GlyphSlot( face, &slot );
+ if ( error ) goto Fail;
+ }
+
+ /****************************************************************/
+ /* finally allocate a size object for the face */
+ {
+ FT_Size size;
+
+ FT_TRACE4(( "FT_Open_Face: Creating size object\n" ));
+ error = FT_New_Size( face, &size );
+ if ( error ) goto Fail;
+ }
+
+ *aface = face;
+ goto Exit;
+
+ Fail:
+ FT_Done_Face( face );
+
+ Bad_Resource:
+
+ Exit:
+ FT_TRACE4(( "FT_Open_Face: Return %d\n", error ));
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Done_Face */
+ /* */
+ /* <Description> */
+ /* Discards a given face object, as well as all of its child slots */
+ /* and sizes. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to a target face object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_Done_Face( FT_Face face )
+ {
+ FT_Error error;
+ FT_Driver driver;
+ FT_Memory memory;
+ FT_DriverInterface* interface;
+ FT_ListNode node;
+
+
+ if (!face || !face->driver )
+ return FT_Err_Invalid_Face_Handle;
+
+ driver = face->driver;
+ interface = &driver->interface;
+ memory = driver->memory;
+
+ /* find face in driver's list */
+ node = FT_List_Find( &driver->faces_list, face );
+ if ( node )
+ {
+ /* remove face object from the driver's list */
+ FT_List_Remove( &driver->faces_list, node );
+ FREE( node );
+
+ /* now destroy the object proper */
+ destroy_face( memory, face, driver );
+ error = FT_Err_Ok;
+ }
+ else
+ error = FT_Err_Invalid_Face_Handle;
+
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_New_Size */
+ /* */
+ /* <Description> */
+ /* Creates a new size object from a given face object. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to a parent face object. */
+ /* */
+ /* <Output> */
+ /* size :: A handle to a new size object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_New_Size( FT_Face face,
+ FT_Size* asize )
+ {
+ FT_Error error;
+ FT_Memory memory;
+ FT_Driver driver;
+ FT_DriverInterface* interface;
+
+ FT_Size size = 0;
+ FT_ListNode node = 0;
+
+
+ if ( !face || !face->driver )
+ return FT_Err_Invalid_Face_Handle;
+
+ *asize = 0;
+ driver = face->driver;
+ interface = &driver->interface;
+ memory = face->memory;
+
+ /* Allocate new size object and perform basic initialisation */
+ if ( ALLOC( size, interface->size_object_size ) ||
+ ALLOC( node, sizeof ( FT_ListNodeRec ) ) )
+ goto Exit;
+
+ size->face = face;
+
+ error = interface->init_size( size );
+
+ /* in case of success, add to the face's list */
+ if ( !error )
+ {
+ *asize = size;
+ node->data = size;
+ FT_List_Add( &face->sizes_list, node );
+
+ /* record as current size for the face */
+ face->size = size;
+ }
+
+ Exit:
+ if ( error )
+ {
+ FREE( node );
+ FREE( size );
+ }
+
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Done_Size */
+ /* */
+ /* <Description> */
+ /* Discards a given size object. */
+ /* */
+ /* <Input> */
+ /* size :: A handle to a target size object */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_Done_Size( FT_Size size )
+ {
+ FT_Error error;
+ FT_Driver driver;
+ FT_Memory memory;
+ FT_Face face;
+ FT_ListNode node;
+
+
+ if ( !size || !size->face )
+ return FT_Err_Invalid_Size_Handle;
+
+ driver = size->face->driver;
+ if ( !driver )
+ return FT_Err_Invalid_Driver_Handle;
+
+ memory = driver->memory;
+
+ error = FT_Err_Ok;
+ face = size->face;
+ node = FT_List_Find( &face->sizes_list, size );
+ if ( node )
+ {
+ FT_List_Remove( &face->sizes_list, node );
+ FREE( node );
+
+ if (face->size == size)
+ {
+ face->size = 0;
+ if (face->sizes_list.head)
+ face->size = (FT_Size)(face->sizes_list.head->data);
+ }
+
+ destroy_size( memory, size, driver );
+ }
+ else
+ error = FT_Err_Invalid_Size_Handle;
+
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Set_Char_Size */
+ /* */
+ /* <Description> */
+ /* Sets the character dimensions of a given size object. The */
+ /* `char_size' value is used for the width and height, expressed in */
+ /* 26.6 fractional points. 1 point = 1/72 inch. */
+ /* */
+ /* <Input> */
+ /* size :: A handle to a target size object. */
+ /* char_size :: The character size, in 26.6 fractional points. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* When dealing with fixed-size faces (i.e., non-scalable formats), */
+ /* use the function FT_Set_Pixel_Sizes(). */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_Set_Char_Size( FT_Face face,
+ FT_F26Dot6 char_width,
+ FT_F26Dot6 char_height,
+ FT_UInt horz_resolution,
+ FT_UInt vert_resolution )
+ {
+ FT_Error error;
+ FT_Driver driver;
+ FT_Memory memory;
+ FT_DriverInterface* interface;
+
+ if ( !face || !face->size || !face->driver)
+ return FT_Err_Invalid_Face_Handle;
+
+ if (!char_width)
+ char_width = char_height;
+
+ else if (!char_height)
+ char_height = char_width;
+
+ if (!horz_resolution)
+ horz_resolution = 72;
+
+ if (!vert_resolution)
+ vert_resolution = 72;
+
+ driver = face->driver;
+ interface = &driver->interface;
+ memory = driver->memory;
+
+ error = interface->set_char_sizes( face->size,
+ char_width,
+ char_height,
+ horz_resolution,
+ vert_resolution );
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Set_Pixel_Sizes */
+ /* */
+ /* <Description> */
+ /* Sets the character dimensions of a given size object. The width */
+ /* and height are expressed in integer pixels. */
+ /* */
+ /* <Input> */
+ /* size :: A handle to a target size object. */
+ /* pixel_width :: The character width, in integer pixels. */
+ /* pixel_height :: The character height, in integer pixels. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_Set_Pixel_Sizes( FT_Face face,
+ FT_UInt pixel_width,
+ FT_UInt pixel_height )
+ {
+ FT_Error error;
+ FT_Driver driver;
+ FT_Memory memory;
+ FT_DriverInterface* interface;
+
+ if ( !face || !face->size || !face->driver )
+ return FT_Err_Invalid_Face_Handle;
+
+ driver = face->driver;
+ interface = &driver->interface;
+ memory = driver->memory;
+
+ error = interface->set_pixel_sizes( face->size, pixel_width, pixel_height );
+
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_New_GlyphSlot */
+ /* */
+ /* <Description> */
+ /* It is sometimes useful to have more than one glyph slot for a */
+ /* given face object. This function is used to create additional */
+ /* slots. All of them are automatically discarded when the face is */
+ /* destroyed. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to a parent face object. */
+ /* */
+ /* <Output> */
+ /* aslot :: A handle to a new glyph slot object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_New_GlyphSlot( FT_Face face,
+ FT_GlyphSlot* aslot )
+ {
+ FT_Error error;
+ FT_Driver driver;
+ FT_DriverInterface* interface;
+ FT_Memory memory;
+ FT_GlyphSlot slot;
+
+
+ *aslot = 0;
+
+ if ( !face || !face->driver )
+ return FT_Err_Invalid_Face_Handle;
+
+ driver = face->driver;
+ interface = &driver->interface;
+ memory = driver->memory;
+
+ FT_TRACE4(( "FT_New_GlyphSlot: Creating new slot object\n" ));
+ if ( ALLOC( slot, interface->slot_object_size ) )
+ goto Exit;
+
+ slot->face = face;
+
+ slot->max_subglyphs = 0;
+ slot->num_subglyphs = 0;
+ slot->subglyphs = 0;
+
+ error = interface->init_glyph_slot( slot );
+ if ( !error )
+ {
+ /* in case of success, add slot to the face's list */
+ slot->next = face->glyph;
+ face->glyph = slot;
+ *aslot = slot;
+ }
+
+ if ( error )
+ FREE( slot );
+
+ Exit:
+ FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error ));
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Done_GlyphSlot */
+ /* */
+ /* <Description> */
+ /* Destroys a given glyph slot. Remember however that all slots are */
+ /* automatically destroyed with its parent. Using this function is */
+ /* not always mandatory. */
+ /* */
+ /* <Input> */
+ /* slot :: A handle to a target glyph slot. */
+ /* */
+ EXPORT_FUNC
+ void FT_Done_GlyphSlot( FT_GlyphSlot slot )
+ {
+ if (slot)
+ {
+ FT_Driver driver = slot->face->driver;
+ FT_Memory memory = driver->memory;
+ FT_GlyphSlot* parent;
+ FT_GlyphSlot cur;
+
+
+ /* Remove slot from its parent face's list */
+ parent = &slot->face->glyph;
+ cur = *parent;
+ while ( cur )
+ {
+ if ( cur == slot )
+ {
+ *parent = cur->next;
+ break;
+ }
+ cur = cur->next;
+ }
+
+ driver->interface.done_glyph_slot( slot );
+ FREE( slot );
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Load_Glyph */
+ /* */
+ /* <Description> */
+ /* A function used to load a single glyph within a given glyph slot, */
+ /* for a given size. */
+ /* */
+ /* <Input> */
+ /* slot :: A handle to a target slot object where the glyph */
+ /* will be loaded. */
+ /* */
+ /* size :: A handle to the source face size at which the glyph */
+ /* must be scaled/loaded. */
+ /* */
+ /* glyph_index :: The index of the glyph in the font file. */
+ /* */
+ /* load_flags :: A flag indicating what to load for this glyph. The */
+ /* FT_LOAD_XXX constants can be used to control the */
+ /* glyph loading process (e.g., whether the outline */
+ /* should be scaled, whether to load bitmaps or not, */
+ /* whether to hint the outline, etc). */
+ /* <Output> */
+ /* result :: A set of bit flags indicating the type of data that */
+ /* was loaded in the glyph slot (outline or bitmap, */
+ /* etc). */
+ /* */
+ /* You can set this field to 0 if you don't want this */
+ /* information. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_Load_Glyph( FT_Face face,
+ FT_UInt glyph_index,
+ FT_Int load_flags )
+ {
+ FT_Error error;
+ FT_Driver driver;
+
+ if ( !face || !face->size || !face->glyph )
+ return FT_Err_Invalid_Face_Handle;
+
+ driver = face->driver;
+
+ error = driver->interface.load_glyph( face->glyph,
+ face->size,
+ glyph_index,
+ load_flags );
+
+ return error;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error FT_Load_Char( FT_Face face,
+ FT_ULong char_code,
+ FT_Int load_flags )
+ {
+ FT_Error error;
+ FT_Driver driver;
+ FT_UInt glyph_index;
+
+ if (!face || !face->size || !face->glyph || !face->charmap )
+ return FT_Err_Invalid_Face_Handle;
+
+ driver = face->driver;
+ glyph_index = FT_Get_Char_Index( face, char_code );
+
+ if (glyph_index == 0)
+ error = FT_Err_Invalid_Character_Code;
+ else
+ error = driver->interface.load_glyph( face->glyph,
+ face->size,
+ glyph_index,
+ load_flags );
+ return error;
+ }
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Get_Kerning */
+ /* */
+ /* <Description> */
+ /* Returns the kerning vector between two glyphs of a same face. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to a source face object. */
+ /* */
+ /* left_glyph :: The index of the left glyph in the kern pair. */
+ /* */
+ /* right_glyph :: The index of the right glyph in the kern pair. */
+ /* */
+ /* <Output> */
+ /* kerning :: The kerning vector. This is in font units for */
+ /* scalable formats, and in pixels for fixed-sizes */
+ /* formats. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* Only horizontal layouts (left-to-right & right-to-left) are */
+ /* supported by this method. Other layouts, or more sophisticated */
+ /* kernings, are out of the scope of this API function -- they can be */
+ /* implemented through format-specific interfaces. */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_Get_Kerning( FT_Face face,
+ FT_UInt left_glyph,
+ FT_UInt right_glyph,
+ FT_Vector* kerning )
+ {
+ FT_Error error;
+ FT_Driver driver;
+ FT_Memory memory;
+
+
+ if ( !face )
+ {
+ error = FT_Err_Invalid_Face_Handle;
+ goto Exit;
+ }
+
+ driver = face->driver;
+ memory = driver->memory;
+
+ if ( driver->interface.get_kerning )
+ {
+ error = driver->interface.get_kerning( face, left_glyph,
+ right_glyph, kerning );
+ }
+ else
+ {
+ kerning->x = 0;
+ kerning->y = 0;
+ error = FT_Err_Ok;
+ }
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Get_Char_Index */
+ /* */
+ /* <Description> */
+ /* Returns the glyph index of a given character code. This function */
+ /* uses a charmap object to do the translation. */
+ /* */
+ /* <Input> */
+ /* charmap :: A handle to a filter charmap object. */
+ /* charcode :: The character code. */
+ /* */
+ /* <Return> */
+ /* The glyph index. 0 means `undefined character code'. */
+ /* */
+ EXPORT_DEF
+ FT_UInt FT_Get_Char_Index( FT_Face face,
+ FT_ULong charcode )
+ {
+ FT_UInt result;
+ FT_Driver driver;
+
+ result = 0;
+ if ( face && face->charmap )
+ {
+ driver = face->driver;
+ result = driver->interface.get_char_index( face->charmap, charcode );
+ }
+ return result;
+ }
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Decompose_Outline */
+ /* */
+ /* <Description> */
+ /* Walks over an outline's structure to decompose it into individual */
+ /* segments and Bezier arcs. This function is also able to emit */
+ /* `move to' and `close to' operations to indicate the start and end */
+ /* of new contours in the outline. */
+ /* */
+ /* <Input> */
+ /* outline :: A pointer to the source target. */
+ /* */
+ /* interface :: A table of `emitters', i.e,. function pointers called */
+ /* during decomposition to indicate path operations. */
+ /* */
+ /* user :: A typeless pointer which is passed to each emitter */
+ /* during the decomposition. It can be used to store */
+ /* the state during the decomposition. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means sucess. */
+ /* */
+ EXPORT_FUNC
+ int FT_Decompose_Outline( FT_Outline* outline,
+ FT_Outline_Funcs* interface,
+ void* user )
+ {
+ typedef enum _phases
+ {
+ phase_point,
+ phase_conic,
+ phase_cubic,
+ phase_cubic2
+
+ } TPhase;
+
+ FT_Vector v_first;
+ FT_Vector v_last;
+ FT_Vector v_control;
+ FT_Vector v_control2;
+ FT_Vector v_start;
+
+ FT_Vector* point;
+ char* flags;
+
+ int n; /* index of contour in outline */
+ int first; /* index of first point in contour */
+ int index; /* current point's index */
+
+ int error;
+
+ char tag; /* current point's state */
+ TPhase phase;
+
+
+ first = 0;
+
+ for ( n = 0; n < outline->n_contours; n++ )
+ {
+ int last; /* index of last point in contour */
+
+
+ last = outline->contours[n];
+
+ v_first = outline->points[first];
+ v_last = outline->points[last];
+
+ v_start = v_control = v_first;
+
+ tag = FT_CURVE_TAG( outline->flags[first] );
+ index = first;
+
+ /* A contour cannot start with a cubic control point! */
+
+ if ( tag == FT_Curve_Tag_Cubic )
+ return FT_Err_Invalid_Outline;
+
+
+ /* check first point to determine origin */
+
+ if ( tag == FT_Curve_Tag_Conic )
+ {
+ /* first point is conic control. Yes, this happens. */
+ if ( FT_CURVE_TAG( outline->flags[last] ) == FT_Curve_Tag_On )
+ {
+ /* start at last point if it is on the curve */
+ v_start = v_last;
+ }
+ else
+ {
+ /* if both first and last points are conic, */
+ /* start at their middle and record its position */
+ /* for closure */
+ v_start.x = ( v_start.x + v_last.x ) / 2;
+ v_start.y = ( v_start.y + v_last.y ) / 2;
+
+ v_last = v_start;
+ }
+ phase = phase_conic;
+ }
+ else
+ phase = phase_point;
+
+
+ /* Begin a new contour with MOVE_TO */
+
+ error = interface->move_to( &v_start, user );
+ if ( error )
+ return error;
+
+ point = outline->points + first;
+ flags = outline->flags + first;
+
+ /* now process each contour point individually */
+
+ while ( index < last )
+ {
+ index++;
+ point++;
+ flags++;
+
+ tag = FT_CURVE_TAG( flags[0] );
+
+ switch ( phase )
+ {
+ case phase_point: /* the previous point was on the curve */
+
+ switch ( tag )
+ {
+ /* two succesive on points -> emit segment */
+ case FT_Curve_Tag_On:
+ error = interface->line_to( point, user );
+ break;
+
+ /* on point + conic control -> remember control point */
+ case FT_Curve_Tag_Conic:
+ v_control = point[0];
+ phase = phase_conic;
+ break;
+
+ /* on point + cubic control -> remember first control */
+ default:
+ v_control = point[0];
+ phase = phase_cubic;
+ break;
+ }
+ break;
+
+ case phase_conic: /* the previous point was a conic control */
+
+ switch ( tag )
+ {
+ /* conic control + on point -> emit conic arc */
+ case FT_Curve_Tag_On:
+ error = interface->conic_to( &v_control, point, user );
+ phase = phase_point;
+ break;
+
+ /* two successive conics -> emit conic arc `in between' */
+ case FT_Curve_Tag_Conic:
+ {
+ FT_Vector v_middle;
+
+
+ v_middle.x = (v_control.x + point->x)/2;
+ v_middle.y = (v_control.y + point->y)/2;
+
+ error = interface->conic_to( &v_control,
+ &v_middle, user );
+ v_control = point[0];
+ }
+ break;
+
+ default:
+ error = FT_Err_Invalid_Outline;
+ }
+ break;
+
+ case phase_cubic: /* the previous point was a cubic control */
+
+ /* this point _must_ be a cubic control too */
+ if ( tag != FT_Curve_Tag_Cubic )
+ return FT_Err_Invalid_Outline;
+
+ v_control2 = point[0];
+ phase = phase_cubic2;
+ break;
+
+
+ case phase_cubic2: /* the two previous points were cubics */
+
+ /* this point _must_ be an on point */
+ if ( tag != FT_Curve_Tag_On )
+ error = FT_Err_Invalid_Outline;
+ else
+ error = interface->cubic_to( &v_control, &v_control2,
+ point, user );
+ phase = phase_point;
+ break;
+ }
+
+ /* lazy error testing */
+ if ( error )
+ return error;
+ }
+
+ /* end of contour, close curve cleanly */
+ error = 0;
+
+ tag = FT_CURVE_TAG( outline->flags[first] );
+
+ switch ( phase )
+ {
+ case phase_point:
+ if ( tag == FT_Curve_Tag_On )
+ error = interface->line_to( &v_first, user );
+ break;
+
+ case phase_conic:
+ error = interface->conic_to( &v_control, &v_start, user );
+ break;
+
+ case phase_cubic2:
+ if ( tag == FT_Curve_Tag_On )
+ error = interface->cubic_to( &v_control, &v_control2,
+ &v_first, user );
+ else
+ error = FT_Err_Invalid_Outline;
+ break;
+
+ default:
+ error = FT_Err_Invalid_Outline;
+ break;
+ }
+
+ if ( error )
+ return error;
+
+ first = last + 1;
+ }
+
+ return 0;
+ }
+
+
+ static
+ const FT_Outline null_outline = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_New_Outline */
+ /* */
+ /* <Description> */
+ /* Creates a new outline of a given size. */
+ /* */
+ /* <Input> */
+ /* library :: A handle to the library object from where the */
+ /* outline is allocated. Note however that the new */
+ /* outline will NOT necessarily be FREED when */
+ /* destroying the library, by FT_Done_FreeType(). */
+ /* */
+ /* numPoints :: The maximum number of points within the outline. */
+ /* */
+ /* numContours :: The maximum number of contours within the outline. */
+ /* */
+ /* <Output> */
+ /* outline :: A handle to the new outline. NULL in case of */
+ /* error. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <MT-Note> */
+ /* No. */
+ /* */
+ /* <Note> */
+ /* The reason why this function takes a `library' parameter is simply */
+ /* to use the library's memory allocator. You can copy the source */
+ /* code of this function, replacing allocations with `malloc()' if */
+ /* you want to control where the objects go. */
+ /* */
+ BASE_FUNC
+ FT_Error FT_New_Outline( FT_Library library,
+ FT_UInt numPoints,
+ FT_Int numContours,
+ FT_Outline* outline )
+ {
+ FT_Error error;
+ FT_Memory memory;
+
+
+ if ( !outline )
+ return FT_Err_Invalid_Argument;
+
+ *outline = null_outline;
+ memory = library->memory;
+
+ if ( ALLOC_ARRAY( outline->points, numPoints * 2L, FT_Pos ) ||
+ ALLOC_ARRAY( outline->flags, numPoints, FT_Byte ) ||
+ ALLOC_ARRAY( outline->contours, numContours, FT_UShort ) )
+ goto Fail;
+
+ outline->n_points = (FT_UShort)numPoints;
+ outline->n_contours = (FT_Short)numContours;
+ outline->owner = TRUE;
+
+ return FT_Err_Ok;
+
+ Fail:
+ outline->owner = TRUE;
+ FT_Done_Outline( library, outline );
+
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Done_Outline */
+ /* */
+ /* <Description> */
+ /* Destroys an outline created with FT_New_Outline(). */
+ /* */
+ /* <Input> */
+ /* library :: A handle of the library object used to allocate the */
+ /* outline. */
+ /* */
+ /* outline :: A pointer to the outline object to be discarded. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <MT-Note> */
+ /* No. */
+ /* */
+ /* <Note> */
+ /* If the outline's `owner' field is not set, only the outline */
+ /* descriptor will be released. */
+ /* */
+ /* The reason why this function takes an `outline' parameter is */
+ /* simply to use FT_Alloc()/FT_Free(). You can copy the source code */
+ /* of this function, replacing allocations with `malloc()' in your */
+ /* application if you want something simpler. */
+ /* */
+ BASE_FUNC
+ FT_Error FT_Done_Outline( FT_Library library,
+ FT_Outline* outline )
+ {
+ FT_Memory memory = library->memory;
+
+
+ if ( outline )
+ {
+ if ( outline->owner )
+ {
+ FREE( outline->points );
+ FREE( outline->flags );
+ FREE( outline->contours );
+ }
+ *outline = null_outline;
+
+ return FT_Err_Ok;
+ }
+ else
+ return FT_Err_Invalid_Argument;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Get_Outline_CBox */
+ /* */
+ /* <Description> */
+ /* Returns an outline's `control box'. The control box encloses all */
+ /* the outline's points, including Bezier control points. Though it */
+ /* coincides with the exact bounding box for most glyphs, it can be */
+ /* slightly larger in some situations (like when rotating an outline */
+ /* which contains Bezier outside arcs). */
+ /* */
+ /* Computing the control box is very fast, while getting the bounding */
+ /* box can take much more time as it needs to walk over all segments */
+ /* and arcs in the outline. To get the latter, you can use the */
+ /* `ftbbox' component which is dedicated to this single task. */
+ /* */
+ /* <Input> */
+ /* outline :: A pointer to the source outline descriptor. */
+ /* */
+ /* <Output> */
+ /* cbox :: The outline's control box. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <MT-Note> */
+ /* Yes. */
+ /* */
+ BASE_FUNC
+ FT_Error FT_Get_Outline_CBox( FT_Outline* outline,
+ FT_BBox* cbox )
+ {
+ if ( outline && cbox )
+ {
+ if ( outline->n_points == 0 )
+ {
+ cbox->xMin = 0;
+ cbox->yMin = 0;
+ cbox->xMax = 0;
+ cbox->yMax = 0;
+ }
+ else
+ {
+ FT_UShort k;
+ FT_Vector* vec = outline->points;
+
+
+ cbox->xMin = cbox->xMax = vec->x;
+ cbox->yMin = cbox->yMax = vec->y;
+ vec++;
+
+ for ( k = 1; k < outline->n_points; k++ )
+ {
+ FT_Pos x, y;
+
+
+ x = vec->x;
+ if ( x < cbox->xMin ) cbox->xMin = x;
+ if ( x > cbox->xMax ) cbox->xMax = x;
+
+ y = vec->y;
+ if ( y < cbox->yMin ) cbox->yMin = y;
+ if ( y > cbox->yMax ) cbox->yMax = y;
+ vec++;
+ }
+ }
+ return FT_Err_Ok;
+ }
+ else
+ return FT_Err_Invalid_Argument;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Translate_Outline */
+ /* */
+ /* <Description> */
+ /* Applies a simple translation to the points of an outline. */
+ /* */
+ /* <Input> */
+ /* outline :: A pointer to the target outline descriptor. */
+ /* xOffset :: The horizontal offset. */
+ /* yOffset :: The vertical offset. */
+ /* */
+ /* <MT-Note> */
+ /* Yes. */
+ /* */
+ BASE_FUNC
+ void FT_Translate_Outline( FT_Outline* outline,
+ FT_Pos xOffset,
+ FT_Pos yOffset )
+ {
+ FT_UShort n;
+ FT_Vector* vec = outline->points;
+
+
+ for ( n = 0; n < outline->n_points; n++ )
+ {
+ vec->x += xOffset;
+ vec->y += yOffset;
+ vec++;
+ }
+ }
+
+
+
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Done_FreeType */
+ /* */
+ /* <Description> */
+ /* Destroys a given FreeType library object and all of its childs, */
+ /* including resources, drivers, faces, sizes, etc. */
+ /* */
+ /* <Input> */
+ /* library :: A handle to the target library object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_Done_FreeType( FT_Library library )
+ {
+ /* Discard the library object */
+ FT_Done_Library( library );
+
+ return FT_Err_Ok;
+ }
+
+/* END */
--- /dev/null
+++ b/src/base/ftobjs.h
@@ -1,0 +1,710 @@
+/***************************************************************************/
+/* */
+/* ftobjs.h */
+/* */
+/* The FreeType private base classes (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 file contains the definition of all internal FreeType classes. */
+ /* */
+ /*************************************************************************/
+
+#ifndef FTOBJS_H
+#define FTOBJS_H
+
+#include <ftconfig.h>
+#include <ftsystem.h>
+#include <ftdriver.h>
+
+ /*************************************************************************/
+ /* */
+ /* Some generic definitions. */
+ /* */
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef NULL
+#define NULL (void*)0
+#endif
+
+#ifndef UNUSED
+#define UNUSED( arg ) ( (void)(arg) )
+#endif
+
+
+ /*************************************************************************/
+ /* */
+ /* The min and max functions missing in C. As usual, be careful not to */
+ /* write things like MIN( a++, b++ ) to avoid side effects. */
+ /* */
+#ifndef MIN
+#define MIN( a, b ) ( (a) < (b) ? (a) : (b) )
+#endif
+
+#ifndef MAX
+#define MAX( a, b ) ( (a) > (b) ? (a) : (b) )
+#endif
+
+#ifndef ABS
+#define ABS( a ) ( (a) < 0 ? -(a) : (a) )
+#endif
+
+
+ /*************************************************************************/
+ /* */
+ /* <Macro> */
+ /* FT_SET_ERROR */
+ /* */
+ /* <Description> */
+ /* This macro is used to set an implicit `error' variable to a given */
+ /* expression's value (usually a function call), and convert it to a */
+ /* boolean which is set whenever the value is != 0. */
+ /* */
+#undef FT_SET_ERROR
+#define FT_SET_ERROR( expression ) \
+ ( (error = (expression)) != 0 )
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** M E M O R Y ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Alloc */
+ /* */
+ /* <Description> */
+ /* Allocates a new block of memory. The returned area is always */
+ /* zero-filled, this is a strong convention in many FreeType parts. */
+ /* */
+ /* <Input> */
+ /* memory :: A handle to a given `memory object' where allocation */
+ /* occurs. */
+ /* */
+ /* size :: The size in bytes of the block to allocate. */
+ /* */
+ /* <Output> */
+ /* P :: A pointer to the fresh new block. It should be set to */
+ /* NULL if `size' is 0, or in case of error. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ BASE_DEF
+ FT_Error FT_Alloc( FT_Memory memory,
+ FT_Long size,
+ void** P );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Realloc */
+ /* */
+ /* <Description> */
+ /* Reallocates a block of memory pointed to by `*P' to `Size' bytes */
+ /* from the heap, possibly changing `*P'. */
+ /* */
+ /* <Input> */
+ /* memory :: A handle to a given `memory object' where allocation */
+ /* occurs. */
+ /* */
+ /* current :: current block size in bytes */
+ /* size :: the new block size in bytes */
+ /* */
+ /* <InOut> */
+ /* P :: A pointer to the fresh new block. It should be set to */
+ /* NULL if `size' is 0, or in case of error. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* All callers of FT_Realloc _must_ provide the current block size */
+ /* as well as the new one. */
+ /* */
+ /* When the memory object's flag FT_memory_FLAG_NO_REALLOC is */
+ /* set, this function will try to emulate a realloc through uses */
+ /* of FT_Alloc and FT_Free. Otherwise, it will call the memory- */
+ /* specific "realloc" implementation. */
+ /* */
+ /* (Some embedded memorys do not have a working realloc). */
+ /* */
+ BASE_DEF
+ FT_Error FT_Realloc( FT_Memory memory,
+ FT_Long current,
+ FT_Long size,
+ void** P );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Free */
+ /* */
+ /* <Description> */
+ /* Releases a given block of memory allocated through FT_Alloc(). */
+ /* */
+ /* <Input> */
+ /* memory :: A handle to a given `memory object' where allocation */
+ /* occured. */
+ /* */
+ /* P :: This is the _address_ of a _pointer_ which points to the */
+ /* allocated block. It is always set to NULL on exit. */
+ /* */
+ /* <Note> */
+ /* If P or *P are NULL, this function should return successfully. */
+ /* This is a strong convention within all of FreeType and its */
+ /* drivers. */
+ /* */
+ BASE_DEF
+ void FT_Free( FT_Memory memory,
+ void** P );
+
+
+
+ /* This include is needed by the MEM_xxx() macros, it should be */
+ /* available on every platform we know !! */
+#include <string.h>
+
+#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
+
+#define MEM_Move( dest, source, count ) memmove( dest, source, count )
+
+
+ /*************************************************************************/
+ /* */
+ /* We now support closures to produce completely reentrant code. This */
+ /* means the allocation functions now takes an additional argument */
+ /* (`memory'). It is a handle to a given memory object, responsible for */
+ /* all low-level operations, including memory management and */
+ /* synchronisation. */
+ /* */
+ /* In order to keep our code readable and use the same macros in the */
+ /* font drivers and the rest of the library, MEM_Alloc(), ALLOC(), and */
+ /* ALLOC_ARRAY() now use an implicit variable, `memory'. It must be */
+ /* defined at all locations where a memory operation is queried. */
+ /* */
+
+ /* */
+ /* Note that ALL memory allocation functions need an IMPLICIT argument */
+ /* called `memory' to point to the current memory object. */
+ /* */
+#define MEM_Alloc( _pointer_, _size_ ) \
+ FT_Alloc( memory, _size_, (void**)&(_pointer_) )
+
+#define MEM_Realloc( _pointer_, _current_, _size_ ) \
+ FT_Realloc( memory, _current_, _size_, (void**)&(_pointer_) )
+
+#define ALLOC( _pointer_, _size_ ) \
+ FT_SET_ERROR( MEM_Alloc( _pointer_, _size_ ) )
+
+#define REALLOC( _pointer_, _current_, _size_ ) \
+ FT_SET_ERROR( MEM_Realloc( _pointer_, _current_, _size_ ) )
+
+#define ALLOC_ARRAY( _pointer_, _count_, _type_ ) \
+ FT_SET_ERROR( MEM_Alloc( _pointer_, (_count_)*sizeof (_type_) ) )
+
+#define REALLOC_ARRAY( _pointer_, _current_, _count_, _type_ ) \
+ FT_SET_ERROR( MEM_Realloc( _pointer_, (_current_)*sizeof(_type_), \
+ (_count_)*sizeof(_type_) ) )
+
+#define FREE( _pointer_ ) FT_Free( memory, (void**)&(_pointer_) )
+
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** D R I V E R S ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* FT_DriverRec */
+ /* */
+ /* <Description> */
+ /* The root font driver class. A font driver is responsible for */
+ /* managing and loading font files of a given format. */
+ /* */
+ /* <Fields> */
+ /* library :: A handle to the driver's parent library. */
+ /* */
+ /* memory :: A handle to the driver's memory object. This is a */
+ /* duplicate of `library->memory'. */
+ /* */
+ /* interface :: A set of driver methods that implement its */
+ /* behaviour. These methods are called by the */
+ /* various FreeType functions like FT_New_Face(), */
+ /* FT_Load_Glyph(), etc. */
+ /* */
+ /* format :: A typeless pointer, used to store the address of */
+ /* the driver's format specific interface. This is a */
+ /* table of other driver methods that are specific to */
+ /* its format. Format specific interfaces are */
+ /* defined in the driver's header files (e.g., */
+ /* `freetype/drivers/ttlib/ttdriver.h'). */
+ /* */
+ /* version :: The driver's version. It can be used for */
+ /* versioning and dynamic driver update if needed. */
+ /* */
+ /* description :: An ASCII string describing the driver's supported */
+ /* format, like `truetype', `type1', etc. */
+ /* */
+ /* faces_list :: The list of faces currently opened by this driver. */
+ /* */
+ /* extensions :: a typeless pointer to the driver's extensions */
+ /* registry, when they are supported through the */
+ /* config macro FT_CONFIG_OPTION_EXTENSIONS */
+ /* */
+ typedef struct FT_DriverRec_
+ {
+ FT_Library library;
+ FT_Memory memory;
+
+ FT_Generic generic;
+
+ FT_DriverInterface interface;
+ FT_FormatInterface format;
+
+ FT_Int version; /* driver version */
+ FT_String* description; /* format description */
+
+ FT_ListRec faces_list; /* driver's faces list */
+
+ void* extensions;
+
+ } FT_DriverRec;
+
+
+#ifdef FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** G L Y P H F O R M A T S ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ /*************************************************************************
+ *
+ * <Struct>
+ * FT_Glyph_Format
+ *
+ * <Description>
+ * A structure used to model various properties of a non-standard
+ * glyph image format.
+ *
+ * <Fields>
+ * format_tag :: the glyph format tag
+ *
+ * raster_interface :: the default rasters interface for this glyph
+ * format.
+ *
+ * raster :: the default raster object for this glyph format
+ * if set to nil, a new object will be allocated
+ * automatically through the raster interface.
+ *
+ * raster_owned :: a boolean used internally by the library. If
+ * set, if indicates that the current raster object
+ * was allocated by the library.
+ *
+ *************************************************************************/
+
+ typedef struct FT_Glyph_Format_
+ {
+ FT_Glyph_Tag format_tag;
+ FT_Raster_Interface* raster_interface;
+ FT_Raster raster;
+ FT_Bool raster_allocated;
+
+ } FT_Glyph_Format;
+
+
+ /*************************************************************************
+ *
+ * <Function>
+ * FT_Add_Glyph_Format
+ *
+ * <Description>
+ * Register a new glyph format into the library
+ *
+ * <Input>
+ * library :: handle to target library object
+ * interface :: pointer to glyph format interface
+ *
+ * <Return>
+ * Error code. 0 means success
+ *
+ * <Note>
+ * This function should normally be called by those font drivers which
+ * need to use their own glyph image format.
+ *
+ *************************************************************************/
+
+ EXPORT_DEF
+ FT_Error FT_Add_Glyph_Format( FT_Library library,
+ FT_Glyph_Format* format );
+
+
+ /*************************************************************************
+ *
+ * <Function>
+ * FT_Remove_Glyph_Format
+ *
+ * <Description>
+ * Un-Register a given glyph format from the library
+ *
+ * <Input>
+ * library :: handle to target library object
+ * glyph_format :: glyph format tag
+ *
+ * <Return>
+ * Error code. 0 means success
+ *
+ * <Note>
+ * This function should normally be called by those font drivers which
+ * need to use their own glyph image format.
+ *
+ *************************************************************************/
+
+ EXPORT_DEF
+ FT_Error FT_Remove_Glyph_Format( FT_Library library,
+ FT_Glyph_Tag glyph_format );
+
+ /*************************************************************************
+ *
+ * <Function>
+ * FT_Get_Glyph_Format
+ *
+ * <Description>
+ * Return a pointer to the glyph format descriptor corresponding to
+ * a given format tag.
+ *
+ * <Input>
+ * library :: handle to source library object
+ *
+ * format_tag :: glyph format tag
+ *
+ * <Return>
+ * a pointer to the corresponding glyph format descriptor, if it was
+ * registered in the library. 0 otherwise.
+ *
+ *************************************************************************/
+
+ BASE_DEF
+ FT_Glyph_Format* FT_Get_Glyph_Format( FT_Library library,
+ FT_Glyph_Tag format_tag );
+
+
+
+#endif /* FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS */
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** L I B R A R I E S ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+#define FT_DEBUG_HOOK_TRUETYPE 0
+#define FT_DEBUG_HOOK_TYPE1 1
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* FT_LibraryRec */
+ /* */
+ /* <Description> */
+ /* The FreeType library class. This is the root of all FreeType */
+ /* data. Use FT_New_Library() to create a library object, and */
+ /* FT_Done_Library() to discard it and all child objects. */
+ /* */
+ /* <Fields> */
+ /* memory :: The library's memory object. Manages memory */
+ /* allocation */
+ /* */
+ /* generic :: Client data variable. Used to extend the */
+ /* Library class by higher levels and clients. */
+ /* */
+ /* num_drivers :: The number of drivers currently registered */
+ /* within this library. This is set to 0 for new */
+ /* libraries. New drivers are added through the */
+ /* FT_Add_Driver() API function. */
+ /* */
+ /* drivers :: A table used to store handles to the currently */
+ /* registered font drivers. Note that each driver */
+ /* contains a list of its opened faces. */
+ /* */
+ /* glyph_formats :: A table used to store glyph format descriptors */
+ /* for new image formats that may have been */
+ /* registered within the library */
+ /* */
+ /* raster_pool :: The raster object's render pool. This can */
+ /* ideally be changed dynamically at run-time. */
+ /* */
+ typedef void (*FT_DebugHook_Func)( void* arg );
+
+ typedef struct FT_LibraryRec_
+ {
+ FT_Memory memory; /* library's memory object */
+
+ FT_Generic generic;
+
+ FT_Int num_drivers;
+ FT_Driver drivers[ FT_MAX_DRIVERS ]; /* driver objects */
+
+ FT_Glyph_Format glyph_formats[FT_MAX_GLYPH_FORMATS];
+
+ void* raster_pool; /* scan-line conversion render pool */
+
+ FT_DebugHook_Func debug_hooks[4];
+
+ } FT_LibraryRec;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_New_Library */
+ /* */
+ /* <Description> */
+ /* This function is used to create a new FreeType library instance */
+ /* from a given memory object. It is thus possible to use libraries */
+ /* with distinct memory allocators within the same program. */
+ /* */
+ /* <Input> */
+ /* memory :: A handle to the original memory object. */
+ /* */
+ /* <Output> */
+ /* library :: A handle to a new library object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* This function is normally not called by client applications, */
+ /* unless they want to create a specific instance of FreeType which */
+ /* uses a specific memory allocator. */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_New_Library( FT_Memory memory,
+ FT_Library* library );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Done_Library */
+ /* */
+ /* <Description> */
+ /* Discards a given library object. This closes all drivers and */
+ /* discards all face objects. */
+ /* */
+ /* <Input> */
+ /* library :: A handle to the target library. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_Done_Library( FT_Library library );
+
+
+
+ EXPORT_DEF
+ void FT_Set_Debug_Hook( FT_Library library,
+ FT_UInt hook_index,
+ FT_DebugHook_Func debug_hook );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Add_Driver */
+ /* */
+ /* <Description> */
+ /* Registers a new driver in a given library object. This function */
+ /* takes only a pointer to a driver interface. It uses it to create */
+ /* the new driver, then sets up some important fields. */
+ /* */
+ /* <Input> */
+ /* library :: A handle to the target library object. */
+ /* */
+ /* driver_interface :: A pointer to a driver interface table. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* This function doesn't check whether the driver is already */
+ /* installed! */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_Add_Driver( FT_Library library,
+ const FT_DriverInterface* driver_interface );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Remove_Driver */
+ /* */
+ /* <Description> */
+ /* Unregister a given driver. This closes the driver, which in turn */
+ /* destroys all faces, sizes, slots, etc. associated with it. */
+ /* */
+ /* This function also DESTROYS the driver object. */
+ /* */
+ /* <Input> */
+ /* driver :: A handle to target driver object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_Remove_Driver( FT_Driver driver );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Get_Driver */
+ /* */
+ /* <Description> */
+ /* returns the handle of the driver responsible for a given format */
+ /* (or service) according to its `name'. */
+ /* */
+ /* <Input> */
+ /* library :: handle to library object. */
+ /* driver_name :: name of driver to look-up. */
+ /* */
+ /* <Return> */
+ /* handle to driver object. 0 otherwise */
+ /* */
+ EXPORT_DEF
+ FT_Driver FT_Get_Driver( FT_Library library,
+ char* driver_name );
+
+#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
+
+ /**************************************************************************
+ *
+ * <Function>
+ * FT_New_Stream
+ *
+ * <Description>
+ * Open a new stream from a given standard ASCII file path name
+ *
+ * <Input>
+ * filepathname :: an ASCII string naming the file to be opened
+ *
+ * <Output>
+ * astream :: the opened stream descriptor to be used by the library
+ *
+ * <Return>
+ * Error code. 0 means success
+ *
+ * <Note>
+ * This function must be implemented by the system-specific part
+ * of the engine, i.e. `ftsystem.c'.
+ *
+ * This function should only fill the stream descriptor. Note that
+ * the stream's `memory' field should be left to the caller.
+ *
+ **************************************************************************/
+
+ extern
+ FT_Error FT_New_Stream( const char* filepathname,
+ FT_Stream astream );
+
+
+ /**************************************************************************
+ *
+ * <Function>
+ * FT_New_Memory
+ *
+ * <Description>
+ * Returns a handle to a new memory object
+ *
+ * <Return>
+ * Handle to the memory object. 0 means failure
+ *
+ * <Note>
+ * This function must be implemented by the system-specific part
+ * of the engine, i.e. `ftsystem.c'.
+ *
+ * It is only used by `ftinit' in order to implement the function
+ * FT_Init_FreeType.
+ *
+ **************************************************************************/
+
+ extern
+ FT_Memory FT_New_Memory( void );
+
+#endif
+
+/* Define default raster's interface. The default raster is located in `src/base/ftraster.c' */
+/* */
+/* Client applications can register new rasters through the FT_Set_Raster API.. */
+/* */
+#ifndef FT_NO_DEFAULT_RASTER
+ extern
+ FT_Raster_Interface ft_default_raster;
+#endif
+
+
+#endif /* FTOBJS_H */
+
+
+/* END */
--- /dev/null
+++ b/src/base/ftoutln.c
@@ -1,0 +1,286 @@
+/***************************************************************************/
+/* */
+/* ftoutln.c */
+/* */
+/* FreeType outline management (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. */
+/* */
+/***************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* All functions are declared in freetype.h. */
+ /* */
+ /*************************************************************************/
+
+
+#include <freetype.h>
+#include <ftconfig.h>
+#include <ftobjs.h>
+#include <ftimage.h>
+#include <ftoutln.h>
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Copy_Outline */
+ /* */
+ /* <Description> */
+ /* Copies an outline into another one. Both objects must have the */
+ /* same sizes (number of points & number of contours) when this */
+ /* function is called. */
+ /* */
+ /* <Input> */
+ /* source :: A handle to the source outline. */
+ /* target :: A handle to the target outline. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ BASE_FUNC
+ FT_Error FT_Copy_Outline( FT_Outline* source,
+ FT_Outline* target )
+ {
+ if ( !source || !target ||
+ source->n_points != target->n_points ||
+ source->n_contours != target->n_contours )
+ return FT_Err_Invalid_Argument;
+
+ MEM_Copy( target->points, source->points,
+ source->n_points * 2 * sizeof ( FT_Pos ) );
+
+ MEM_Copy( target->flags, source->flags,
+ source->n_points * sizeof ( FT_Byte ) );
+
+ MEM_Copy( target->contours, source->contours,
+ source->n_contours * sizeof ( FT_Short ) );
+
+ target->high_precision = source->high_precision;
+ target->second_pass = target->second_pass;
+ target->dropout_mode = source->dropout_mode;
+
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Get_Outline_Bitmap */
+ /* */
+ /* <Description> */
+ /* Renders an outline within a bitmap. The outline's image is simply */
+ /* or-ed to the target bitmap. */
+ /* */
+ /* */
+ /* <Input> */
+ /* library :: A handle to a FreeType library object. */
+ /* outline :: A pointer to the source outline descriptor. */
+ /* map :: A pointer to the target bitmap descriptor. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <MT-Note> */
+ /* YES. Rendering is synchronized, so that concurrent calls to the */
+ /* scan-line converter will be serialized. */
+ /* */
+ /* <Note> */
+ /* This function does NOT CREATE the bitmap, it only renders an */
+ /* outline image within the one you pass to it! */
+ /* */
+ /* It will use the raster correponding to the default glyph format. */
+ /* */
+ BASE_FUNC
+ FT_Error FT_Get_Outline_Bitmap( FT_Library library,
+ FT_Outline* outline,
+ FT_Bitmap* map )
+ {
+ FT_Error error;
+ FT_Glyph_Format* format;
+
+ error = FT_Err_Invalid_Glyph_Format;
+ format = FT_Get_Glyph_Format( library, ft_glyph_format_outline );
+ if (!format) goto Exit;
+
+ error = FT_Err_Invalid_Glyph_Format;
+ if (!format->raster) goto Exit;
+
+ error = format->raster_interface->render( format->raster, outline, map );
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Transform_Outline */
+ /* */
+ /* <Description> */
+ /* Applies a simple 2x2 matrix to all of an outline's points. Useful */
+ /* for applying rotations, slanting, flipping, etc. */
+ /* */
+ /* <Input> */
+ /* outline :: A pointer to the target outline descriptor. */
+ /* matrix :: A pointer to the transformation matrix. */
+ /* */
+ /* <MT-Note> */
+ /* Yes. */
+ /* */
+ /* <Note> */
+ /* You can use FT_Translate_Outline() if you need to translate the */
+ /* outline's points. */
+ /* */
+ BASE_FUNC
+ void FT_Transform_Outline( FT_Outline* outline,
+ FT_Matrix* matrix )
+ {
+ FT_UShort n;
+ FT_Vector* vec;
+
+
+ vec = outline->points;
+ for ( n = 0; n < outline->n_points; n++ )
+ {
+ FT_Pos x, y;
+
+
+ x = FT_MulFix( vec->x, matrix->xx ) +
+ FT_MulFix( vec->y, matrix->xy );
+
+ y = FT_MulFix( vec->x, matrix->yx ) +
+ FT_MulFix( vec->y, matrix->yy );
+
+ vec->x = x;
+ vec->y = y;
+ vec++;
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Transform_Vector */
+ /* */
+ /* <Description> */
+ /* Transforms a single vector through a 2x2 matrix. */
+ /* */
+ /* <InOut> */
+ /* x :: The horizontal vector coordinate. */
+ /* y :: The vertical vector coordinate. */
+ /* */
+ /* <Input> */
+ /* matrix :: A pointer to the source 2x2 matrix. */
+ /* */
+ /* <MT-Note> */
+ /* Yes. */
+ /* */
+ BASE_FUNC
+ void FT_Transform_Vector( FT_Pos* x,
+ FT_Pos* y,
+ FT_Matrix* matrix )
+ {
+ FT_Pos xz, yz;
+
+
+ xz = FT_MulFix( *x, matrix->xx ) +
+ FT_MulFix( *y, matrix->xy );
+
+ yz = FT_MulFix( *x, matrix->yx ) +
+ FT_MulFix( *y, matrix->yy );
+
+ *x = xz;
+ *y = yz;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Matrix_Multiply */
+ /* */
+ /* <Description> */
+ /* Performs the matrix operation `b = a*b'. */
+ /* */
+ /* <Input> */
+ /* a :: A pointer to matrix `a'. */
+ /* */
+ /* <InOut> */
+ /* b :: A pointer to matrix `b'. */
+ /* */
+ /* <MT-Note> */
+ /* Yes. */
+ /* */
+ BASE_FUNC
+ void FT_Matrix_Multiply( FT_Matrix* a,
+ FT_Matrix* b )
+ {
+ FT_Fixed xx, xy, yx, yy;
+
+
+ xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx );
+ xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy );
+ yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx );
+ yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy );
+
+ b->xx = xx; b->xy = xy;
+ b->yx = yx; b->yy = yy;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Matrix_Invert */
+ /* */
+ /* <Description> */
+ /* Inverts a 2x2 matrix. Returns an error if it can't be inverted. */
+ /* */
+ /* <InOut> */
+ /* matrix :: A pointer to the target matrix. Remains untouched in */
+ /* case of error. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <MT-Note> */
+ /* Yes. */
+ /* */
+ BASE_FUNC
+ FT_Error FT_Matrix_Invert( FT_Matrix* matrix )
+ {
+ FT_Pos delta, xx, yy;
+
+
+ /* compute discriminant */
+ delta = FT_MulFix( matrix->xx, matrix->yy ) -
+ FT_MulFix( matrix->xy, matrix->yx );
+
+ if ( !delta )
+ return FT_Err_Invalid_Argument; /* matrix can't be inverted */
+
+ matrix->xy = - FT_DivFix( matrix->xy, delta );
+ matrix->yx = - FT_DivFix( matrix->yx, delta );
+
+ xx = matrix->xx;
+ yy = matrix->yy;
+
+ matrix->xx = FT_DivFix( yy, delta );
+ matrix->yy = FT_DivFix( xx, delta );
+
+ return FT_Err_Ok;
+ }
+
+
+/* END */
--- /dev/null
+++ b/src/base/ftoutln.h
@@ -1,0 +1,153 @@
+#ifndef FTOUTLN_H
+#define FTOUTLN_H
+
+#include <ftobjs.h>
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Copy_Outline */
+ /* */
+ /* <Description> */
+ /* Copies an outline into another one. Both objects must have the */
+ /* same sizes (number of points & number of contours) when this */
+ /* function is called. */
+ /* */
+ /* <Input> */
+ /* source :: A handle to the source outline. */
+ /* target :: A handle to the target outline. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_Copy_Outline( FT_Outline* source,
+ FT_Outline* target );
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Get_Outline_Bitmap */
+ /* */
+ /* <Description> */
+ /* Renders an outline within a bitmap. The outline's image is simply */
+ /* or-ed to the target bitmap. */
+ /* */
+ /* */
+ /* <Input> */
+ /* library :: A handle to a FreeType library object. */
+ /* outline :: A pointer to the source outline descriptor. */
+ /* map :: A pointer to the target bitmap descriptor. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <MT-Note> */
+ /* YES. Rendering is synchronized, so that concurrent calls to the */
+ /* scan-line converter will be serialized. */
+ /* */
+ /* <Note> */
+ /* This function does NOT CREATE the bitmap, it only renders an */
+ /* outline image within the one you pass to it! */
+ /* */
+ /* It will use the raster correponding to the default glyph format. */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_Get_Outline_Bitmap( FT_Library library,
+ FT_Outline* outline,
+ FT_Bitmap* map );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Transform_Outline */
+ /* */
+ /* <Description> */
+ /* Applies a simple 2x2 matrix to all of an outline's points. Useful */
+ /* for applying rotations, slanting, flipping, etc. */
+ /* */
+ /* <Input> */
+ /* outline :: A pointer to the target outline descriptor. */
+ /* matrix :: A pointer to the transformation matrix. */
+ /* */
+ /* <MT-Note> */
+ /* Yes. */
+ /* */
+ /* <Note> */
+ /* You can use FT_Translate_Outline() if you need to translate the */
+ /* outline's points. */
+ /* */
+ EXPORT_DEF
+ void FT_Transform_Outline( FT_Outline* outline,
+ FT_Matrix* matrix );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Transform_Vector */
+ /* */
+ /* <Description> */
+ /* Transforms a single vector through a 2x2 matrix. */
+ /* */
+ /* <InOut> */
+ /* x :: The horizontal vector coordinate. */
+ /* y :: The vertical vector coordinate. */
+ /* */
+ /* <Input> */
+ /* matrix :: A pointer to the source 2x2 matrix. */
+ /* */
+ /* <MT-Note> */
+ /* Yes. */
+ /* */
+ EXPORT_DEF
+ void FT_Transform_Vector( FT_Pos* x,
+ FT_Pos* y,
+ FT_Matrix* matrix );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Matrix_Multiply */
+ /* */
+ /* <Description> */
+ /* Performs the matrix operation `b = a*b'. */
+ /* */
+ /* <Input> */
+ /* a :: A pointer to matrix `a'. */
+ /* */
+ /* <InOut> */
+ /* b :: A pointer to matrix `b'. */
+ /* */
+ /* <MT-Note> */
+ /* Yes. */
+ /* */
+ EXPORT_DEF
+ void FT_Matrix_Multiply( FT_Matrix* a,
+ FT_Matrix* b );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Matrix_Invert */
+ /* */
+ /* <Description> */
+ /* Inverts a 2x2 matrix. Returns an error if it can't be inverted. */
+ /* */
+ /* <InOut> */
+ /* matrix :: A pointer to the target matrix. Remains untouched in */
+ /* case of error. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <MT-Note> */
+ /* Yes. */
+ /* */
+ EXPORT_DEF
+ FT_Error FT_Matrix_Invert( FT_Matrix* matrix );
+
+#endif /* FTOUTLN_H */
--- /dev/null
+++ b/src/base/ftraster.c
@@ -1,0 +1,4372 @@
+/***************************************************************************/
+/* */
+/* ftraster2.c */
+/* */
+/* 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. */
+/* */
+/***************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* The `raster' component implements FreeType's scan-line converter, the */
+ /* one used to generate bitmaps and pixmaps from vectorial outline */
+ /* descriptions. */
+ /* */
+ /* It has been rewritten entirely for FreeType 2.0, in order to become */
+ /* completely independent of the rest of the library. It should now be */
+ /* possible to include it more easily in all kinds of libraries and */
+ /* applications, which do not necessarily need the font engines and API. */
+ /* */
+ /* This version contains the following features: */
+ /* */
+ /* - Support for third-order Bezier arcs. */
+ /* */
+ /* - Improved performance of the 5-levels anti-aliasing algorithm. */
+ /* */
+ /* - 17-levels anti-aliasing for smoother curves, though the difference */
+ /* isn't always noticeable, depending on your palette. */
+ /* */
+ /* - An API to decompose a raster outline into a path (i.e., into a */
+ /* a series of segments and arcs). */
+ /* */
+ /* Planned additions: */
+ /* */
+ /* - Getting rid of the second pass for horizontal drop-out detection. */
+ /* I've got a few ideas, but I'll have to experiment in Pascal with */
+ /* them. to avoid damaging of the rendering of glyphs at small sizes. */
+ /* */
+ /* - Adding a `composition' callback, which should be invoked during */
+ /* anti-aliased rendering. In short, it will allow line-by-line */
+ /* composition (i.e., transparencies, etc.) of the output in a fairly */
+ /* portable way. Of course, a single sweep is required there. */
+ /* */
+ /*************************************************************************/
+
+
+#include <ftimage.h>
+#ifndef _STANDALONE_
+#include <ftconfig.h>
+#endif
+
+#ifndef EXPORT_FUNC
+#define EXPORT_FUNC /* nothing */
+#endif
+
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_raster
+
+#ifdef _STANDALONE_
+
+ /*************************************************************************/
+ /* */
+ /* The following defines are used when the raster is compiled as a */
+ /* stand-alone object. Each of them is commented, and you're free to */
+ /* toggle them to suit your needs. */
+ /* */
+ /*************************************************************************/
+
+ /*************************************************************************/
+ /* */
+ /* FT_RASTER_INT_IS_32 */
+ /* */
+ /* Set this configuration macro to the unsigned type which has 32 */
+ /* bits. */
+ /* */
+#define FT_RASTER_INT_IS_32
+
+
+ /*************************************************************************/
+ /* */
+ /* FT_RASTER_OPTION_ANTI_ALIAS */
+ /* */
+ /* Define this configuration macro if you want to support */
+ /* anti-aliasing. */
+ /* */
+#define FT_RASTER_OPTION_ANTI_ALIAS
+
+
+ /*************************************************************************/
+ /* */
+ /* FT_RASTER_OPTION_CONIC_BEZIERS */
+ /* */
+ /* Define this configuration macro if your source outlines contain */
+ /* second-order Bezier arcs. Typically, these are TrueType outlines. */
+ /* */
+#define FT_RASTER_CONIC_BEZIERS
+
+
+ /*************************************************************************/
+ /* */
+ /* FT_RASTER_OPTION_CUBIC_BEZIERS */
+ /* */
+ /* Define this configuration macro if your source outlines contain */
+ /* third-order Bezier arcs. Typically, these are Type1 outlines. */
+ /* */
+#define FT_RASTER_CUBIC_BEZIERS
+
+
+ /*************************************************************************/
+ /* */
+ /* FT_RASTER_ANTI_ALIAS_5 */
+ /* */
+ /* Define this configuration macro if you want to enable the 5-grays */
+ /* anti-aliasing mode. Ignored if FT_RASTER_OPTION_ANTI_ALIAS isn't */
+ /* defined. */
+ /* */
+#define FT_RASTER_ANTI_ALIAS_5
+
+
+ /*************************************************************************/
+ /* */
+ /* FT_RASTER_ANTI_ALIAS_17 */
+ /* */
+ /* Define this configuration macro if you want to enable the 17-grays */
+ /* anti-aliasing mode. Ignored if FT_RASTER_OPTION_ANTI_ALIAS isn't */
+ /* defined. */
+ /* */
+/* #define FT_RASTER_ANTI_ALIAS_17 */
+
+
+ /*************************************************************************/
+ /* */
+ /* FT_RASTER_LITTLE_ENDIAN */
+ /* FT_RASTER_BIG_ENDIAN */
+ /* */
+ /* The default anti-alias routines are processor-independent, but */
+ /* slow. Define one of these macros to suit your own system, and */
+ /* enjoy greatly improved rendering speed. */
+ /* */
+
+/* #define FT_RASTER_LITTLE_ENDIAN */
+/* #define FT_RASTER_BIG_ENDIAN */
+
+
+#else /* _STANDALONE_ */
+
+#include <freetype.h>
+#include <ftconfig.h>
+
+ /*************************************************************************/
+ /* */
+ /* The following defines are used when the raster is compiled within the */
+ /* FreeType base layer. Don't change these unless you really know what */
+ /* you're doing. */
+ /* */
+ /*************************************************************************/
+
+
+#ifdef FT_CONFIG_OPTION_ANTI_ALIAS
+#define FT_RASTER_OPTION_ANTI_ALIAS
+#endif
+
+#define FT_RASTER_CONIC_BEZIERS
+#define FT_RASTER_CUBIC_BEZIERS
+
+#define FT_RASTER_ANTI_ALIAS_5
+/* #define FT_RASTER_ANTI_ALIAS_17 */
+
+#ifdef FT_CONFIG_OPTION_LITTLE_ENDIAN
+#define FT_RASTER_LITTLE_ENDIAN
+#endif
+
+#ifdef FT_CONFIG_OPTION_BIG_ENDIAN
+#define FT_RASTER_BIG_ENDIAN
+#endif
+
+
+#endif /* _STANDALONE_ */
+
+
+/* to keep the compiler happy */
+#ifndef PTRACE2
+#define PTRACE2(x) /*void*/
+#endif
+
+ /*************************************************************************/
+ /* */
+ /* FT_RASTER_ANY_ENDIAN indicates that no endianess was defined by one */
+ /* of the configuration macros. */
+ /* */
+#if !defined( FT_RASTER_LITTLE_ENDIAN ) && !defined( FT_RASTER_BIG_ENDIAN )
+#define FT_RASTER_ANY_ENDIAN
+#endif
+
+
+ /*************************************************************************/
+ /* */
+ /* The rasterizer is a very general purpose component. Please leave the */
+ /* following redefinitions here (you never know your target */
+ /* environment). */
+ /* */
+ /*************************************************************************/
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef NULL
+#define NULL (void*)0
+#endif
+
+
+#ifndef UNUSED
+#define UNUSED( arg ) ( (void)(arg) )
+#endif
+
+
+#undef FAILURE
+#define FAILURE TRUE
+
+#undef SUCCESS
+#define SUCCESS FALSE
+
+#ifndef ABS
+#define ABS(x) ( (x) < 0 ? -(x) : (x) )
+#endif
+
+ /*************************************************************************/
+ /* */
+ /* Please don't touch the following macros. Their importance is */
+ /* historical to FreeType, but they have some nice effects, like getting */
+ /* rid of all `->' symbols when accessing the raster object (replacing */
+ /* them with a simple `.'). */
+ /* */
+ /*************************************************************************/
+
+ /* used in function signatures to define the _first_ argument */
+#define RAS_ARG_ FT_Raster raster,
+#define RAS_ARG FT_Raster raster
+
+ /* used to call a function within this component, first parameter */
+#define RAS_VAR_ raster,
+#define RAS_VAR raster
+
+ /* used to access the current raster object, with a `.' instead of a */
+ /* `->' */
+#define ras (*raster)
+
+
+ /*************************************************************************/
+ /* */
+ /* For anti-aliasing modes, we use a 2 or 4 lines intermediate bitmap */
+ /* which is filtered repeatedly to render each pixmap row. The */
+ /* following macro defines this buffer's size in bytes (which is part of */
+ /* raster objects). */
+ /* */
+#define ANTI_ALIAS_BUFFER_SIZE 2048
+
+
+ /*************************************************************************/
+ /* */
+ /* Error codes returned by the scan-line converter/raster. */
+ /* */
+#define ErrRaster_Ok 0
+#define ErrRaster_Uninitialized_Object 1
+#define ErrRaster_Overflow 2
+#define ErrRaster_Negative_Height 3
+#define ErrRaster_Invalid_Outline 4
+#define ErrRaster_Invalid_Map 5
+#define ErrRaster_AntiAlias_Unsupported 6
+#define ErrRaster_Invalid_Pool 7
+#define ErrRaster_Unimplemented 8
+#define ErrRaster_Bad_Palette_Count 9
+
+
+#define Flow_Up 1
+#define Flow_Down -1
+
+#define SET_High_Precision( p ) Set_High_Precision( RAS_VAR_ p )
+
+
+ /*************************************************************************/
+ /* */
+ /* Fast MulDiv, as `b' is always < 64. Don't use intermediate */
+ /* precision. */
+ /* */
+#define FMulDiv( a, b, c ) ( (a) * (b) / (c) )
+
+
+ /*************************************************************************/
+ /* */
+ /* 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 */
+ /* will be shown 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 */
+ /* `ftconfig.h'. */
+ /* */
+#ifdef DEBUG_RASTER
+ extern char* vio; /* A pointer to VRAM or display buffer */
+#endif
+
+
+ /*************************************************************************/
+ /* */
+ /* The maximum number of stacked Bezier curves. Setting this constant */
+ /* to more than 32 is a pure waste of space. */
+ /* */
+#define MaxBezier 32
+
+
+ /*************************************************************************/
+ /* */
+ /* The number fractional bits of *input* coordinates. We always use the */
+ /* 26.6 format (i.e, 6 bits for the fractional part), but hackers are */
+ /* free to experiment with different values. */
+ /* */
+#define Pixel_Bits 6
+
+
+ /*************************************************************************/
+ /* */
+ /* An unsigned type that is exactly 32 bits on your platform. This */
+ /* means `unsigned long' on 16-bit machines, and `unsigned int' on */
+ /* others. */
+ /* */
+#ifdef _STANDALONE_
+#if defined( FT_RASTER_INT_IS_32 )
+ typedef unsigned int FT_Word32;
+#elif defined( FT_RASTER_LONG_IS_32 )
+ typedef unsigned long FT_Word32;
+#else
+#error "no 32bit type found - please check your configuration"
+#endif
+#endif
+
+
+ /*************************************************************************/
+ /* */
+ /* A pointer to an unsigned char. */
+ /* */
+ typedef unsigned char* PByte;
+
+ typedef char TResult;
+
+ typedef unsigned char Byte;
+
+ /*************************************************************************/
+ /* */
+ /* The type of the pixel coordinates used within the render pool during */
+ /* scan-line conversion. We use longs to store either 26.6 or 22.10 */
+ /* fixed float values, depending on the `precision' we want to use */
+ /* (i.e., low resp. high precision). These are ideals in order to */
+ /* subdivise Bezier arcs in halves by simple additions and shifts. */
+ /* */
+ /* Note that this is an 8-bytes integer on 64 bits systems. */
+ /* */
+ typedef long TPos, *PPos;
+
+
+ /*************************************************************************/
+ /* */
+ /* The type of a scanline position/coordinate within a map. */
+ /* */
+ typedef int TScan, *PScan;
+
+
+ /*************************************************************************/
+ /* */
+ /* States and directions of each line, arc, and profile. */
+ /* */
+ typedef enum _TDirection
+ {
+ Unknown,
+ Ascending,
+ Descending,
+ Flat
+
+ } TDirection;
+
+
+ struct _TProfile;
+ typedef struct _TProfile TProfile;
+ typedef TProfile* PProfile;
+
+
+ /*************************************************************************/
+ /* */
+ /* The `master' structure used for decomposing outlines. */
+ /* */
+ struct _TProfile
+ {
+ TPos X; /* current coordinate during sweep */
+ PProfile link; /* link to next profile - various purpose */
+ PPos offset; /* start of profile's data in render pool */
+ int flow; /* Profile orientation: Asc/Descending */
+ TScan height; /* profile's height in scanlines */
+ TScan start; /* profile's starting scanline */
+
+ TScan 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;
+
+
+ /*************************************************************************/
+ /* */
+ /* A simple record used to implement a stack of bands, required by the */
+ /* sub-banding mechanism. */
+ /* */
+ typedef struct _TBand
+ {
+ TScan y_min; /* band's minimum */
+ TScan y_max; /* band's maximum */
+
+ } TBand;
+
+
+ /*************************************************************************/
+ /* */
+ /* The size in _TPos_ of a profile record in the render pool. */
+ /* */
+#define AlignProfileSize \
+ ( (sizeof ( TProfile ) + sizeof ( TPos ) - 1) / sizeof ( TPos ) )
+
+
+ /*************************************************************************/
+ /* */
+ /* Prototypes used for sweep function dispatch. */
+ /* */
+ typedef void (*Function_Sweep_Init)( RAS_ARG_ int* min,
+ int* max );
+
+ typedef void (*Function_Sweep_Span)( RAS_ARG_ TScan y,
+ TPos x1,
+ TPos x2 );
+
+ typedef int (*Function_Test_Pixel)( RAS_ARG_ TScan y,
+ int x );
+
+ typedef void (*Function_Set_Pixel)( RAS_ARG_ TScan y,
+ int x,
+ int color );
+
+ typedef void (*Function_Sweep_Step)( RAS_ARG );
+
+ typedef struct Raster_Render_
+ {
+ Function_Sweep_Init init;
+ Function_Sweep_Span span;
+ Function_Sweep_Step step;
+ Function_Test_Pixel test_pixel;
+ Function_Set_Pixel set_pixel;
+
+ } Raster_Render;
+
+
+ /*************************************************************************/
+ /* */
+ /* Compute lowest integer coordinate below a given value. */
+ /* */
+#define FLOOR( x ) ( (x) & ras.precision_mask )
+
+
+ /*************************************************************************/
+ /* */
+ /* Compute highest integer coordinate above a given value. */
+ /* */
+#define CEILING( x ) ( ((x) + ras.precision - 1) & ras.precision_mask )
+
+
+ /*************************************************************************/
+ /* */
+ /* Get integer coordinate of a given 26.6 or 22.10 `x' coordinate -- no */
+ /* rounding. */
+ /* */
+#define TRUNC( x ) ( (signed long)(x) >> ras.precision_bits )
+
+
+ /*************************************************************************/
+ /* */
+ /* Get the fractional part of a given coordinate. */
+ /* */
+#define FRAC( x ) ( (x) & (ras.precision - 1) )
+
+
+ /*************************************************************************/
+ /* */
+ /* Scale an `input coordinate' (as found in FT_Outline structures) into */
+ /* a `work coordinate' which depends on current resolution and render */
+ /* mode. */
+ /* */
+#define SCALED( x ) ( ((x) << ras.scale_shift) - ras.scale_delta )
+
+
+ /*************************************************************************/
+ /* */
+ /* DEBUG_PSET is used to plot a single pixel in VRam during debug mode. */
+ /* */
+#ifdef DEBUG_RASTER
+#define DEBUG_PSET Pset()
+#else
+#define DEBUG_PSET
+#endif
+
+
+ /*************************************************************************/
+ /* */
+ /* This structure defines a point in a plane. */
+ /* */
+ typedef struct _TPoint
+ {
+ TPos x, y;
+
+ } TPoint;
+
+
+ /*************************************************************************/
+ /* */
+ /* The most used variables are at the beginning of the structure. Thus, */
+ /* their offset can be coded with less opcodes which results in a */
+ /* smaller executable. */
+ /* */
+ struct FT_RasterRec_
+ {
+ PPos cursor; /* Current cursor in render pool */
+
+ PPos pool; /* The render pool base address */
+ PPos pool_size; /* The render pool's size */
+ PPos pool_limit; /* Limit of profiles zone in pool */
+
+ int bit_width; /* target bitmap width */
+ PByte bit_buffer; /* target bitmap buffer */
+ PByte pix_buffer; /* target pixmap buffer */
+
+ TPoint last;
+ long minY, maxY;
+
+ int error;
+
+ int precision_bits; /* precision related variables */
+ int precision;
+ int precision_half;
+ long precision_mask;
+ int precision_shift;
+ int precision_step;
+ int precision_jitter;
+
+ FT_Outline* outline;
+
+ int n_points; /* number of points in current glyph */
+ int n_contours; /* number of contours in current glyph */
+ int n_extrema; /* number of `extrema' scanlines */
+
+ TPoint* arc; /* current Bezier arc pointer */
+
+ int num_profs; /* current number of profiles */
+
+ char fresh; /* signals a fresh new profile which */
+ /* `start' field must be completed */
+ char joint; /* signals that the last arc ended */
+ /* exactly on a scanline. Allows */
+ /* removal of doublets */
+ PProfile cur_prof; /* current profile */
+ PProfile start_prof; /* head of linked list of profiles */
+ PProfile first_prof; /* contour's first profile in case */
+ /* of impact */
+ TDirection state; /* rendering state */
+
+ FT_Bitmap target; /* description of target bit/pixmap */
+
+ int trace_bit; /* current offset in target bitmap */
+ int trace_pix; /* current offset in target pixmap */
+ int trace_incr; /* sweep's increment in target bitmap */
+
+ int gray_min_x; /* current min x during gray rendering */
+ int gray_max_x; /* current max x during gray rendering */
+
+ /* dispatch variables */
+
+ Raster_Render render;
+
+ int scale_shift; /* == 0 for bitmaps */
+ /* == 1 for 5-levels pixmaps */
+ /* == 2 for 17-levels pixmaps */
+
+ int scale_delta; /* ras.precision_half for bitmaps */
+ /* 0 for pixmaps */
+
+ char dropout_mode; /* current drop_out control method */
+
+ char second_pass; /* indicates whether 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. */
+
+ char flipped; /* this flag is set during the rendering to */
+ /* indicate the second pass. */
+
+ TBand band_stack[16]; /* band stack used for sub-banding */
+ int band_top; /* band stack top */
+
+ TPoint arcs[2 * MaxBezier + 1]; /* The Bezier stack */
+
+#if defined( FT_RASTER_OPTION_ANTI_ALIAS )
+
+ long grays[20]; /* Palette of gray levels used for render */
+
+ int gray_width; /* length in bytes of the monochrome */
+ /* intermediate scanline of gray_lines. */
+ /* Each gray pixel takes 2 or 4 bits long */
+
+ /* The gray_lines must hold 2 lines, thus with size */
+ /* in bytes of at least `gray_width*2' */
+
+ int grays_count; /* number of entries in the palette */
+
+ char gray_lines[ANTI_ALIAS_BUFFER_SIZE];
+ /* Intermediate table used to render the */
+ /* graylevels pixmaps. */
+ /* gray_lines is a buffer holding 2 or 4 */
+ /* monochrome scanlines */
+
+ int count_table[256]; /* Look-up table used to quickly count */
+ /* set bits in several gray 2x2 cells */
+ /* at once. */
+
+#endif /* FT_RASTER_OPTION_ANTI_ALIAS */
+ };
+
+
+
+#ifdef DEBUG_RASTER
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Pset */
+ /* */
+ /* <Description> */
+ /* 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 */
+ /* from its original position). */
+ /* */
+ /* This `feature' 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. */
+ /* */
+ static
+ void Pset( RAS_ARG )
+ {
+ long o;
+ long x;
+
+
+ x = ras.cursor[-1];
+
+ switch ( ras.cur_prof->flow )
+ {
+ case FT_Flow_Up:
+ o = Vio_ScanLineWidth *
+ ( ras.cursor - ras.cur_prof->offset + ras.cur_prof->start ) +
+ ( x / (ras.precision * 8) );
+ break;
+
+ case FT_Flow_Down:
+ o = Vio_ScanLineWidth *
+ ( ras.cur_prof->start - ras.cursor + ras.cur_prof->offset ) +
+ ( x / (ras.precision * 8) );
+ break;
+ }
+
+ if ( o > 0 )
+ Vio[o] |= (unsigned)0x80 >> ( (x/ras.precision) & 7 );
+ }
+
+
+ static
+ void Clear_Band( RAS_ARG_ TScan y1,
+ TScan 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 the parameter flag. */
+ /* */
+ /* <Input> */
+ /* High :: Set to True for high precision (typically for ppem < 18), */
+ /* false otherwise. */
+ /* */
+ static
+ void Set_High_Precision( RAS_ARG_ char 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;
+ }
+
+ 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;
+ }
+
+ /*************************************************************************/
+ /* */
+ /* A simple technical note on how the raster works: */
+ /* */
+ /* Converting an outline into a bitmap is achieved in several steps */
+ /* which are: */
+ /* */
+ /* 1 - Decomposing the outline into successive `profiles'. Each */
+ /* profile is simply an array of scanline intersections on a given */
+ /* dimension. A profile's main attributes are */
+ /* */
+ /* o its scanline position boundaries, i.e. `Ymin' and `Ymax'. */
+ /* */
+ /* o an array of intersection coordinates for each scanline */
+ /* between `Ymin' and `Ymax'. */
+ /* */
+ /* o a direction, indicating wether is was built going `up' or */
+ /* `down', as this is very important for filling rules. */
+ /* */
+ /* 2 - Sweeping the target map's scanlines in order to compute segment */
+ /* `spans' which are then filled. Additionaly, this pass performs */
+ /* drop-out control. */
+ /* */
+ /* The outline data is parsed during step 1 only. The profiles are */
+ /* built from the bottom of the render pool, used as a stack. The */
+ /* following graphics shows the profile list under construction: */
+ /* */
+ /* ____________________________________________________________ _ _ */
+ /* | | | | | */
+ /* | profile | coordinates for | profile | coordinates for |--> */
+ /* | 1 | profile 1 | 2 | profile 2 |--> */
+ /* |_________|___________________|_________|_________________|__ _ _ */
+ /* */
+ /* ^ ^ */
+ /* | | */
+ /* start of render pool cursor */
+ /* */
+ /* The top of the profile stack is kept in the `cursor' variable. */
+ /* */
+ /* As you can see, a profile record is pushed on top of the render */
+ /* pool, which is then followed by its coordinates/intersections. If */
+ /* a change of direction is detected in the outline, a new profile is */
+ /* generated until the end of the outline. */
+ /* */
+ /* Note that when all profiles have been generated, the function */
+ /* Finalize_Profile_Table() is used to record, for each profile, its */
+ /* bottom-most scanline as well as the scanline above its upmost */
+ /* boundary. These positions are called `extrema' because they (sort */
+ /* of) correspond to local extrema. They are stored in a sorted list */
+ /* built from the top of the render pool as a downwards stack: */
+ /* */
+ /* _ _ _______________________________________ */
+ /* | | */
+ /* <--| sorted list of | */
+ /* <--| extrema scanlines | */
+ /* _ _ __________________|____________________| */
+ /* */
+ /* ^ ^ */
+ /* | | */
+ /* pool_limit end of render pool */
+ /* */
+ /* This list is later used during the sweep phase in order to */
+ /* optimize performance (see technical note on the sweep below). */
+ /* */
+ /* Of course, the raster detects whether the two stacks collide and */
+ /* handles the situation propertly. */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* New_Profile */
+ /* */
+ /* <Description> */
+ /* Creates a new Profile in the render pool. */
+ /* */
+ /* <Input> */
+ /* aState :: The state/orientation of the new profile. */
+ /* */
+ /* <Return> */
+ /* SUCCESS or FAILURE. */
+ /* */
+ static
+ TResult New_Profile( RAS_ARG_ TDirection direction )
+ {
+ if ( ras.start_prof == NULL )
+ {
+ ras.cur_prof = (PProfile)ras.cursor; /* current profile */
+ ras.start_prof = ras.cur_prof; /* first profile in pool */
+ ras.cursor += AlignProfileSize; /* record profile in buffer */
+ }
+
+ /* check for overflow */
+ if ( ras.cursor >= ras.pool_limit )
+ {
+ ras.error = ErrRaster_Overflow;
+ return FAILURE;
+ }
+
+ /* record profile direction */
+ switch ( direction )
+ {
+ case Ascending:
+ ras.cur_prof->flow = Flow_Up;
+ break;
+
+ case Descending:
+ ras.cur_prof->flow = Flow_Down;
+ break;
+
+ default:
+ ras.error = ErrRaster_Invalid_Map;
+ return FAILURE;
+ }
+
+ /* initialize a few fields */
+ {
+ PProfile cur = ras.cur_prof;
+
+
+ cur->start = 0; /* current start scanline */
+ cur->height = 0; /* current height */
+ cur->offset = ras.cursor; /* address of first coordinate */
+ cur->link = (PProfile)0; /* link to next profile in pool */
+ cur->next = (PProfile)0; /* link to next profile in contour */
+ }
+
+ /* record the first profile in a contour */
+ if ( ras.first_prof == NULL )
+ ras.first_prof = ras.cur_prof;
+
+ ras.state = direction;
+ ras.fresh = TRUE; /* this profile has no coordinates yet */
+ ras.joint = FALSE;
+
+ return SUCCESS;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* End_Profile */
+ /* */
+ /* <Description> */
+ /* Finalizes the current Profile and computes its height. If it is */
+ /* not 0, the profile's fields are updated and a new profile is */
+ /* pushed on top of its coordinates. Otherwise the current profile */
+ /* is kept and the recording of intersections is restarted. */
+ /* */
+ /* <Return> */
+ /* SUCCESS or FAILURE. */
+ /* */
+ static
+ TResult End_Profile( RAS_ARG )
+ {
+ int h;
+
+
+ h = ras.cursor - ras.cur_prof->offset;
+
+ if ( h < 0 )
+ {
+ /* This error should _never_ occur unless the raster is buggy */
+ ras.error = ErrRaster_Negative_Height;
+ return FAILURE;
+ }
+
+ if ( h > 0 )
+ {
+ PProfile old, new;
+
+ /* record scanline height in current profile, create a new one */
+ /* and set a link from the old one to it */
+ old = ras.cur_prof;
+ old->height = h;
+ ras.cur_prof = new = (PProfile)ras.cursor;
+
+ ras.cursor += AlignProfileSize;
+
+ new->height = 0;
+ new->offset = ras.cursor;
+ old->next = new;
+
+ ras.num_profs++;
+ }
+
+ /* check for overflow */
+ if ( ras.cursor >= ras.pool_limit )
+ {
+ ras.error = ErrRaster_Overflow;
+ return FAILURE;
+ }
+
+ ras.joint = FALSE;
+
+ return SUCCESS;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Insert_Extrema */
+ /* */
+ /* <Description> */
+ /* Records that a given scanline contains at least one local */
+ /* extremum. The table of extrema is placed at the end of the render */
+ /* pool and grows downwards. It is used during the sweep phase. */
+ /* */
+ /* <Input> */
+ /* y :: The coordinate of the scanline containing an extremum. */
+ /* */
+ static
+ TResult Insert_Extrema( RAS_ARG_ TScan y )
+ {
+ PPos extrema;
+ TScan y2;
+ int n;
+
+
+ PTRACE2(( "EXTREMA += %d", y ));
+ n = ras.n_extrema - 1;
+ extrema = ras.pool_size - ras.n_extrema;
+
+ /* look for first y extremum that is <= */
+ while ( n >= 0 && y < extrema[n] )
+ n--;
+
+ /* if it is <, simply insert it, ignore if == */
+ if ( n >= 0 && y > extrema[n] )
+ while ( n >= 0 )
+ {
+ y2 = extrema[n];
+ extrema[n] = y;
+ y = y2;
+ n--;
+ }
+
+ if ( n < 0 )
+ {
+ ras.pool_limit--;
+ ras.n_extrema++;
+ ras.pool_size[-ras.n_extrema] = y;
+
+ if ( ras.pool_limit <= ras.cursor )
+ {
+ ras.error = ErrRaster_Overflow;
+ return FAILURE;
+ }
+ }
+ return SUCCESS;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Finalize_Profile_Table */
+ /* */
+ /* <Description> */
+ /* Adjusts all links in the profiles list. Called when the outline */
+ /* parsing is done. */
+ /* */
+ /* <Return> */
+ /* SUCCESS or FAILURE. */
+ /* */
+ static
+ TResult Finalize_Profile_Table( RAS_ARG )
+ {
+ int n, bottom, top;
+ PProfile p;
+
+
+ n = ras.num_profs;
+
+ if ( n > 1 )
+ {
+ p = ras.start_prof;
+ while ( n > 0 )
+ {
+ if ( n > 1 )
+ p->link = (PProfile)( p->offset + p->height );
+ else
+ p->link = NULL;
+
+ switch ( p->flow )
+ {
+ case Flow_Down:
+ PTRACE2(( "FLOW DOWN (start = %d, height = %d)",
+ p->start, p->height ));
+ bottom = p->start - p->height+1;
+ top = p->start;
+ p->start = bottom;
+ p->offset += p->height-1;
+ break;
+
+ case Flow_Up:
+ default:
+ PTRACE2(( "FLOW UP (start = %d, height = %d)",
+ p->start, p->height ));
+ bottom = p->start;
+ top = p->start + p->height-1;
+ }
+
+ if ( Insert_Extrema( RAS_VAR_ bottom ) ||
+ Insert_Extrema( RAS_VAR_ top+1 ) )
+ return FAILURE;
+
+ p = p->link;
+ n--;
+ }
+ }
+ else
+ ras.start_prof = NULL;
+
+ return SUCCESS;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Line_Up */
+ /* */
+ /* <Description> */
+ /* Computes the scan-line intersections of an ascending line segment */
+ /* and stores them in the render pool. */
+ /* */
+ /* <Input> */
+ /* x1 :: The start x coordinate. */
+ /* y1 :: The start y coordinate. */
+ /* x2 :: The end x coordinate. */
+ /* y2 :: The end y coordinate. */
+ /* miny :: The minimum vertical grid coordinate. */
+ /* maxy :: The maximum vertical grid coordinate. */
+ /* */
+ /* <Return> */
+ /* SUCCESS or FAILURE. */
+ /* */
+ static
+ TResult Line_Up( RAS_ARG_ TPos x1, TPos y1,
+ TPos x2, TPos y2,
+ TPos miny, TPos maxy )
+ {
+ TPos Dx, Dy;
+ int e1, e2, f1, f2, size;
+ TPos Ix, Rx, Ax;
+
+ PPos top;
+
+
+ Dx = x2 - x1;
+ Dy = y2 - y1;
+
+ if ( Dy <= 0 || y2 < miny || y1 > maxy )
+ return SUCCESS;
+
+ /* clip to higher scanline when necessary */
+ if ( y2 > maxy )
+ {
+ /* x2 += FMulDiv( Dx, maxy-y2, Dy ); UNNECESSARY */
+ e2 = TRUNC( maxy );
+ f2 = 0;
+ }
+ else
+ {
+ e2 = TRUNC( y2 );
+ f2 = FRAC( y2 );
+ }
+
+ /* clip to lower scanline when necessary */
+ if ( y1 < miny )
+ {
+ TPos x, y;
+
+ /* we use a binary search to compute the lower
+ // clipping intersection. That's because we don't
+ // want to use an external function like FT_MulDiv
+ // to compute it directly.
+ */
+ if ( y2 == miny ) goto Exit;
+ do
+ {
+ x = (x1 + x2) >> 1;
+ y = (y1 + y2) >> 1;
+
+ if (y <= miny)
+ {
+ x1 = x;
+ y1 = y;
+ }
+ else
+ {
+ x2 = x;
+ y2 = y;
+ }
+ }
+ while ( y1 < miny );
+
+ e1 = TRUNC( miny );
+ f1 = 0;
+ }
+ else
+ {
+ e1 = TRUNC( y1 );
+ f1 = FRAC( y1 );
+ }
+
+ /* adjust start point so that we begin on an integer scanline position */
+ if ( f1 > 0 )
+ {
+ if ( e1 == e2 ) goto Exit;
+ else
+ {
+ x1 += FMulDiv( Dx, ras.precision - f1, Dy );
+ e1 += 1;
+ }
+ }
+ else
+ if ( ras.joint )
+ {
+ ras.cursor--;
+ ras.joint = FALSE;
+ }
+
+ ras.joint = ( f2 == 0 );
+
+ /* if this is a `fresh' profile, record its starting scanline */
+ if ( ras.fresh )
+ {
+ ras.cur_prof->start = e1;
+ ras.fresh = FALSE;
+ }
+
+ /* check for overflow */
+ size = e2 - e1 + 1;
+ if ( ras.cursor + size >= ras.pool_limit )
+ {
+ ras.error = ErrRaster_Overflow;
+ return FAILURE;
+ }
+
+ /* compute decision variables and push the intersections on top */
+ /* of the render pool */
+ Dx <<= ras.precision_bits;
+ Ix = Dx / Dy;
+ Rx = Dx % Dy;
+ if (Rx < 0)
+ {
+ Ix --;
+ Rx += Dy;
+ }
+
+ Ax = -Dy;
+ Rx <<= 1;
+ Dy <<= 1;
+
+ top = ras.cursor;
+
+ while ( size > 0 )
+ {
+ *top++ = x1;
+
+ DEBUG_PSET;
+
+ x1 += Ix;
+ Ax += Rx;
+ if ( Ax >= 0 )
+ {
+ Ax -= Dy;
+ x1 ++;
+ }
+ size--;
+ }
+
+ ras.cursor = top;
+ Exit:
+ return SUCCESS;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Line_Down */
+ /* */
+ /* <Description> */
+ /* Computes the scan-line intersections of a descending line segment */
+ /* and stores them in the render pool. */
+ /* */
+ /* <Input> */
+ /* x1 :: The start x coordinate. */
+ /* y1 :: The start y coordinate. */
+ /* x2 :: The end x coordinate. */
+ /* y2 :: The end y coordinate. */
+ /* miny :: The minimum vertical grid coordinate. */
+ /* maxy :: The maximum vertical grid coordinate. */
+ /* */
+ /* <Return> */
+ /* SUCCESS or FAILURE. */
+ /* */
+ static
+ TResult Line_Down( RAS_ARG_ TPos x1, TPos y1,
+ TPos x2, TPos y2,
+ TPos miny, TPos maxy )
+ {
+ TResult result, fresh;
+
+
+ /* simply invert the coordinates and call Line_Up */
+ fresh = ras.fresh;
+ result = Line_Up( RAS_VAR_ x1, -y1, x2, -y2, -maxy, -miny );
+
+ /* if this was a fresh profile, invert the recorded start position */
+ if ( fresh && !ras.fresh )
+ ras.cur_prof->start = -ras.cur_prof->start;
+
+ return result;
+ }
+
+
+
+
+ /* A function type describing the functions used to split bezier arcs */
+ typedef void (*TSplitter)( TPoint* base );
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Bezier_Up */
+ /* */
+ /* <Description> */
+ /* Computes the scan-line intersections of an ascending second-order */
+ /* Bezier arc and stores them in the render pool. The arc is taken */
+ /* from the top of the stack. */
+ /* */
+ /* <Input> */
+ /* miny :: The minimum vertical grid coordinate. */
+ /* maxy :: The maximum vertical grid coordinate. */
+ /* */
+ /* <Return> */
+ /* SUCCESS or FAILURE. */
+ /* */
+ static
+ TResult Bezier_Up( RAS_ARG_ int degree,
+ TSplitter splitter,
+ TPos miny,
+ TPos maxy )
+ {
+ TPos y1, y2, e, e2, e0;
+ int f1;
+
+ TPoint* arc;
+ TPoint* start_arc;
+
+ PPos top;
+
+
+ arc = ras.arc;
+ y1 = arc[degree].y;
+ y2 = arc[0].y;
+ top = ras.cursor;
+
+ if ( y2 < miny || y1 > maxy )
+ goto Fin;
+
+ e2 = FLOOR( y2 ); /* integer end y */
+
+ if ( e2 > maxy )
+ e2 = FLOOR(maxy);
+
+ e0 = CEILING(miny);
+
+ if ( y1 < miny )
+ {
+ e = e0; /* integer start y == current scanline */
+ }
+ else
+ {
+ e = CEILING( y1 ); /* integer start y == current scanline */
+ f1 = FRAC( y1 ); /* fractional shift of start y */
+ e0 = e; /* first integer scanline to be pushed */
+
+ if ( f1 == 0 ) /* do we start on an integer scanline? */
+ {
+ if ( ras.joint )
+ {
+ top--;
+ ras.joint = FALSE;
+ }
+
+ *top++ = arc[degree].x; /* write directly start position */
+
+ DEBUG_PSET;
+
+ e += ras.precision; /* go to next scanline */
+ }
+ }
+
+ /* record start position if necessary */
+ if ( ras.fresh )
+ {
+ ras.cur_prof->start = TRUNC( e0 );
+ ras.fresh = FALSE;
+ }
+
+ /* exit if the current scanline is already above the max scanline */
+ if ( e2 < e )
+ goto Fin;
+
+ /* check for overflow */
+ if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.pool_limit )
+ {
+ ras.cursor = top;
+ ras.error = ErrRaster_Overflow;
+ return FAILURE;
+ }
+
+ start_arc = arc;
+
+ /* loop while there is still an arc on the bezier stack */
+ /* and the current scan line is below y max == e2 */
+ while ( arc >= start_arc && e <= e2 )
+ {
+ ras.joint = FALSE;
+
+ y2 = arc[0].y; /* final y of the top-most arc */
+
+ if ( y2 > e ) /* the arc intercepts the current scanline */
+ {
+ y1 = arc[degree].y; /* start y of top-most arc */
+
+ if ( y2 - y1 >= ras.precision_step )
+ {
+ /* if the arc's height is too great, split it */
+ splitter( arc );
+ arc += degree;
+ }
+ else
+ {
+ /* otherwise, approximate it as a segment and compute */
+ /* its intersection with the current scanline */
+ *top++ = arc[degree].x +
+ FMulDiv( arc[0].x-arc[degree].x,
+ e - y1,
+ y2 - y1 );
+
+ DEBUG_PSET;
+
+ arc -= degree; /* pop the arc */
+ e += ras.precision; /* go to next scanline */
+ }
+ }
+ else
+ {
+ if ( y2 == e ) /* if the arc falls on the scanline */
+ { /* record its _joint_ intersection */
+ ras.joint = TRUE;
+ *top++ = arc[0].x;
+
+ DEBUG_PSET;
+
+ e += ras.precision; /* go to next scanline */
+ }
+ arc -= degree; /* pop the arc */
+ }
+ }
+
+ Fin:
+ ras.cursor = top;
+ ras.arc -= degree;
+ return SUCCESS;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Bezier_Down */
+ /* */
+ /* <Description> */
+ /* Computes the scan-line intersections of a descending second-order */
+ /* Bezier arc and stores them in the render pool. The arc is taken */
+ /* from the top of the stack. */
+ /* */
+ /* <Input> */
+ /* miny :: The minimum vertical grid coordinate. */
+ /* maxy :: The maximum vertical grid coordinate. */
+ /* */
+ /* <Return> */
+ /* SUCCESS or FAILURE. */
+ /* */
+ static
+ TResult Bezier_Down( RAS_ARG_ int degree,
+ TSplitter splitter,
+ TPos miny,
+ TPos maxy )
+ {
+ TPoint* arc = ras.arc;
+ TResult result, fresh;
+
+ arc[0].y = -arc[0].y;
+ arc[1].y = -arc[1].y;
+ arc[2].y = -arc[2].y;
+ if (degree > 2)
+ arc[3].y = -arc[3].y;
+
+ fresh = ras.fresh;
+
+ result = Bezier_Up( RAS_VAR_ degree, splitter, -maxy, -miny );
+
+ if ( fresh && !ras.fresh )
+ ras.cur_prof->start = -ras.cur_prof->start;
+
+ arc[0].y = -arc[0].y;
+ return result;
+ }
+
+
+#ifdef FT_RASTER_CONIC_BEZIERS
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Split_Conic */
+ /* */
+ /* <Description> */
+ /* Subdivides one second-order Bezier arc into two joint sub-arcs in */
+ /* the Bezier stack. */
+ /* */
+ /* <Note> */
+ /* This routine is the `beef' of the component. It is one of _the_ */
+ /* inner loops that should be optimized like hell to get the best */
+ /* performance. */
+ /* */
+ static
+ void Split_Conic( TPoint* base )
+ {
+ TPos a, b;
+
+
+ base[4].x = base[2].x;
+ b = base[1].x;
+ a = base[3].x = ( base[2].x + b )/2;
+ b = base[1].x = ( base[0].x + b )/2;
+ base[2].x = ( a + b ) / 2;
+
+ base[4].y = base[2].y;
+ b = base[1].y;
+ a = base[3].y = ( base[2].y + b )/2;
+ b = base[1].y = ( base[0].y + b )/2;
+ base[2].y = ( a + b ) / 2;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Push_Conic */
+ /* */
+ /* <Description> */
+ /* Clears the Bezier stack and pushes a new arc on top of it. */
+ /* */
+ /* <Input> */
+ /* p2 :: A pointer to the second (control) point. */
+ /* p3 :: A pointer to the third (end) point. */
+ /* */
+ /* <Note> */
+ /* The first point is taken as `raster->last', so it doesn't appear */
+ /* in the signature. */
+ /* */
+ static
+ void Push_Conic( RAS_ARG_ FT_Vector* p2,
+ FT_Vector* p3 )
+ {
+#undef STORE
+#define STORE( _arc, point ) \
+ { \
+ TPos x = SCALED( point->x ); \
+ TPos y = SCALED( point->y ); \
+ \
+ \
+ if ( ras.flipped ) \
+ { \
+ _arc.x = y; \
+ _arc.y = x; \
+ } \
+ else \
+ { \
+ _arc.x = x; \
+ _arc.y = y; \
+ } \
+ }
+
+ TPoint* arc;
+
+
+ ras.arc = arc = ras.arcs;
+
+ arc[2] = ras.last;
+ STORE( arc[1], p2 );
+ STORE( arc[0], p3 );
+#undef STORE
+ }
+
+#endif /* FT_RASTER_CONIC_BEZIERS */
+
+
+
+#ifdef FT_RASTER_CUBIC_BEZIERS
+
+ /*************************************************************************/
+ /* */
+ /* <Function> Split_Cubic */
+ /* */
+ /* <Description> */
+ /* Subdivides a third-order Bezier arc into two joint sub-arcs in */
+ /* the Bezier stack. */
+ /* */
+ /* <Note> */
+ /* This routine is the `beef' of the component. It is one of _the_ */
+ /* inner loops that should be optimized like hell to get the best */
+ /* performance. */
+ /* */
+ static
+ void Split_Cubic( TPoint* base )
+ {
+ TPos a, b, c, d;
+
+
+ base[6].x = base[3].x;
+ c = base[1].x;
+ d = base[2].x;
+ base[1].x = a = ( base[0].x + c ) / 2;
+ base[5].x = b = ( base[3].x + d ) / 2;
+ c = ( c + d ) / 2;
+ base[2].x = a = ( a + c ) / 2;
+ base[4].x = b = ( b + c ) / 2;
+ base[3].x = ( a + b ) / 2;
+
+ base[6].y = base[3].y;
+ c = base[1].y;
+ d = base[2].y;
+ base[1].y = a = ( base[0].y + c ) / 2;
+ base[5].y = b = ( base[3].y + d ) / 2;
+ c = ( c + d ) / 2;
+ base[2].y = a = ( a + c ) / 2;
+ base[4].y = b = ( b + c ) / 2;
+ base[3].y = ( a + b ) / 2;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Push_Cubic */
+ /* */
+ /* <Description> */
+ /* Clears the Bezier stack and pushes a new third-order Bezier arc on */
+ /* top of it. */
+ /* */
+ /* <Input> */
+ /* p2 :: A pointer to the second (control) point. */
+ /* p3 :: A pointer to the third (control) point. */
+ /* p4 :: A pointer to the fourth (end) point. */
+ /* */
+ /* <Note> */
+ /* The first point is taken as `raster->last', so it doesn't appear */
+ /* in the signature. */
+ /* */
+ /* This is the same as Push_Conic(), except that it deals with */
+ /* third-order Beziers. */
+ /* */
+ static
+ void Push_Cubic( RAS_ARG_ FT_Vector* p2,
+ FT_Vector* p3,
+ FT_Vector* p4 )
+ {
+#undef STORE
+#define STORE( _arc, point ) \
+ { \
+ TPos x = SCALED( point->x ); \
+ TPos y = SCALED( point->y ); \
+ \
+ \
+ if ( ras.flipped ) \
+ { \
+ _arc.x = y; \
+ _arc.y = x; \
+ } \
+ else \
+ { \
+ _arc.x = x; \
+ _arc.y = y; \
+ } \
+ }
+
+ TPoint* arc;
+ ras.arc = arc = ras.arcs;
+
+
+ arc[3] = ras.last;
+ STORE( arc[2], p2 );
+ STORE( arc[1], p3 );
+ STORE( arc[0], p4 );
+
+#undef STORE
+ }
+
+#endif /* FT_RASTER_CUBIC_BEZIERS */
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Check_Contour */
+ /* */
+ /* <Description> */
+ /* Performs some checks at contour closure. */
+ /* */
+ /* <Return> */
+ /* SUCCESS or FAILURE. */
+ /* */
+ static
+ TResult Check_Contour( RAS_ARG )
+ {
+ PProfile lastProfile;
+
+
+ /* Sometimes, the first and last profile in a contour join on */
+ /* an integer scan-line; we must then remove the last intersection */
+ /* from the last profile to get rid of doublets */
+ if ( ( FRAC( ras.last.y ) == 0 &&
+ ras.last.y >= ras.minY &&
+ ras.last.y <= ras.maxY ) )
+ {
+ if ( ras.first_prof && ras.first_prof->flow == ras.cur_prof->flow )
+ ras.cursor--;
+ }
+
+ lastProfile = ras.cur_prof;
+ if ( End_Profile( RAS_VAR ) )
+ return FAILURE;
+
+ /* close the `next profile in contour' linked list */
+ lastProfile->next = ras.first_prof;
+
+ return SUCCESS;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Move_To */
+ /* */
+ /* <Description> */
+ /* This function injects a new contour in the render pool. */
+ /* */
+ /* <Input> */
+ /* to :: A pointer to the contour's first point. */
+ /* raster :: A pointer to the current raster object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* This function is used as a `FTRasterMoveTo_Func' by the outline */
+ /* decomposer. */
+ /* */
+ static
+ int Move_To( FT_Vector* to,
+ FT_Raster raster )
+ {
+ TPos scaled_x, scaled_y;
+
+
+ /* if there was already a contour being built, perform some checks */
+ if ( ras.start_prof )
+ if ( Check_Contour( RAS_VAR ) )
+ return FAILURE;
+
+ /* set the `current last point' */
+ scaled_x = SCALED( to->x );
+ scaled_y = SCALED( to->y );
+
+ if ( ras.flipped )
+ {
+ ras.last.x = scaled_y;
+ ras.last.y = scaled_x;
+ }
+ else
+ {
+ ras.last.x = scaled_x;
+ ras.last.y = scaled_y;
+ }
+
+ ras.state = Unknown;
+ ras.first_prof = NULL;
+
+ return SUCCESS;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Line_To */
+ /* */
+ /* <Description> */
+ /* This function injects a new line segment in the render pool and */
+ /* adjusts the profiles list accordingly. */
+ /* */
+ /* <Input> */
+ /* to :: A pointer to the target position. */
+ /* raster :: A pointer to the current raster object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* This function is used as a `FTRasterLineTo_Func' by the outline */
+ /* decomposer. */
+ /* */
+ static
+ int Line_To( FT_Vector* to,
+ FT_Raster raster )
+ {
+ TPos x, scaled_x;
+ TPos y, scaled_y;
+
+
+ scaled_x = SCALED( to->x );
+ scaled_y = SCALED( to->y );
+
+ if ( ras.flipped )
+ {
+ x = scaled_y;
+ y = scaled_x;
+ }
+ else
+ {
+ x = scaled_x;
+ y = scaled_y;
+ }
+
+ /* First, detect a change of direction */
+ if ( y != ras.last.y )
+ {
+ TDirection new_state = ( (y > ras.last.y) ? Ascending : Descending );
+
+
+ if ( ras.state != new_state )
+ {
+ if ( ras.state != Unknown &&
+ End_Profile( RAS_VAR ) )
+ goto Fail;
+
+ if ( New_Profile( RAS_VAR_ new_state ) )
+ goto Fail;
+ }
+ }
+
+ /* Then compute the lines */
+ switch ( ras.state )
+ {
+ case Ascending:
+ if ( Line_Up ( RAS_VAR_ ras.last.x, ras.last.y,
+ x, y, ras.minY, ras.maxY ) )
+ goto Fail;
+ break;
+
+ case Descending:
+ if ( Line_Down( RAS_VAR_ ras.last.x, ras.last.y,
+ x, y, ras.minY, ras.maxY ) )
+ goto Fail;
+ break;
+
+ default:
+ ;
+ }
+
+ ras.last.x = x;
+ ras.last.y = y;
+
+ return SUCCESS;
+
+ Fail:
+ return FAILURE;
+ }
+
+
+#ifdef FT_RASTER_CONIC_BEZIERS
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Conic_To */
+ /* */
+ /* <Description> */
+ /* Injects a new conic Bezier arc and adjusts the profile list */
+ /* accordingly. */
+ /* */
+ /* <Input> */
+ /* control :: A pointer to an intermediate control point. */
+ /* to :: A pointer to the end point. */
+ /* raster :: A handle to the current raster object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* This function is used as a `FTRasterConicTo_Func' by the outline */
+ /* decomposer. */
+ /* */
+ static
+ int Conic_To( FT_Vector* control,
+ FT_Vector* to,
+ FT_Raster raster )
+ {
+ TPos y1, y2, y3, x3, ymin, ymax;
+ TDirection state_bez;
+
+
+ Push_Conic( RAS_VAR_ control, to );
+
+ do
+ {
+ y1 = ras.arc[2].y;
+ y2 = ras.arc[1].y;
+ y3 = ras.arc[0].y;
+ x3 = ras.arc[0].x;
+
+ /* first, categorize the Bezier arc */
+
+ if ( y1 <= y3 )
+ {
+ ymin = y1;
+ ymax = y3;
+ }
+ else
+ {
+ ymin = y3;
+ ymax = y1;
+ }
+
+ if ( y2 < ymin || y2 > ymax )
+ {
+ /* this arc has no given direction, split it !! */
+ Split_Conic( ras.arc );
+ ras.arc += 2;
+ }
+ else if ( y1 == y3 )
+ {
+ /* this arc is flat, ignore it and pop it from the bezier stack */
+ ras.arc -= 2;
+ }
+ else
+ {
+ /* the arc is y-monotonous, either ascending or descending */
+ /* detect a change of direction */
+ state_bez = y1 < y3 ? Ascending : Descending;
+ if ( ras.state != state_bez )
+ {
+ /* finalize current profile if any */
+ if ( ras.state != Unknown &&
+ End_Profile( RAS_VAR ) )
+ goto Fail;
+
+ /* create a new profile */
+ if ( New_Profile( RAS_VAR_ state_bez ) )
+ goto Fail;
+ }
+
+ /* now call the appropriate routine */
+ if ( state_bez == Ascending )
+ {
+ if ( Bezier_Up( RAS_VAR_ 2, Split_Conic, ras.minY, ras.maxY ) )
+ goto Fail;
+ }
+ else
+ if ( Bezier_Down( RAS_VAR_ 2, Split_Conic, ras.minY, ras.maxY ) )
+ goto Fail;
+ }
+
+ } while ( ras.arc >= ras.arcs );
+
+ ras.last.x = x3;
+ ras.last.y = y3;
+
+ return SUCCESS;
+
+ Fail:
+ return FAILURE;
+ }
+
+#else /* FT_RASTER_CONIC_BEZIERS */
+
+
+ static
+ int Conic_To( FT_Vector* control,
+ FT_Vector* to,
+ FT_Raster raster )
+ {
+ UNUSED( control );
+ UNUSED( to );
+ UNUSED( raster );
+
+ return ErrRaster_Invalid_Outline;
+ }
+
+
+#endif /* FT_RASTER_CONIC_BEZIERS */
+
+
+#ifdef FT_RASTER_CUBIC_BEZIERS
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Cubic_To */
+ /* */
+ /* <Description> */
+ /* Injects a new cubic Bezier arc and adjusts the profile list */
+ /* accordingly. */
+ /* */
+ /* <Input> */
+ /* control1 :: A pointer to the first control point. */
+ /* control2 :: A pointer to the second control point. */
+ /* to :: A pointer to the end point. */
+ /* raster :: A handle to the current raster object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* This function is used as a `FTRasterCubicTo_Func' by the outline */
+ /* decomposer. */
+ /* */
+ static
+ int Cubic_To( FT_Vector* control1,
+ FT_Vector* control2,
+ FT_Vector* to,
+ FT_Raster raster )
+ {
+ TPos y1, y2, y3, y4, x4, ymin1, ymax1, ymin2, ymax2;
+ TDirection state_bez;
+
+
+ Push_Cubic( RAS_VAR_ control1, control2, to );
+
+ do
+ {
+ y1 = ras.arc[3].y;
+ y2 = ras.arc[2].y;
+ y3 = ras.arc[1].y;
+ y4 = ras.arc[0].y;
+ x4 = ras.arc[0].x;
+
+ /* first, categorize the Bezier arc */
+
+ if ( y1 <= y4 )
+ {
+ ymin1 = y1;
+ ymax1 = y4;
+ }
+ else
+ {
+ ymin1 = y4;
+ ymax1 = y1;
+ }
+
+ if ( y2 <= y3 )
+ {
+ ymin2 = y2;
+ ymax2 = y3;
+ }
+ else
+ {
+ ymin2 = y3;
+ ymax2 = y2;
+ }
+
+ if ( ymin2 < ymin1 || ymax2 > ymax1 )
+ {
+ /* this arc has no given direction, split it! */
+ Split_Cubic( ras.arc );
+ ras.arc += 3;
+ }
+ else if ( y1 == y4 )
+ {
+ /* this arc is flat, ignore it and pop it from the bezier stack */
+ ras.arc -= 3;
+ }
+ else
+ {
+ state_bez = ( y1 <= y4 ) ? Ascending : Descending;
+
+ /* detect a change of direction */
+ if ( ras.state != state_bez )
+ {
+ if ( ras.state != Unknown &&
+ End_Profile( RAS_VAR ) )
+ goto Fail;
+
+ if ( New_Profile( RAS_VAR_ state_bez ) )
+ goto Fail;
+ }
+
+ /* compute intersections */
+ if ( state_bez == Ascending )
+ {
+ if ( Bezier_Up ( RAS_VAR_ 3, Split_Cubic, ras.minY, ras.maxY ) )
+ goto Fail;
+ }
+ else
+ if ( Bezier_Down ( RAS_VAR_ 3, Split_Cubic, ras.minY, ras.maxY ) )
+ goto Fail;
+ }
+
+ } while ( ras.arc >= ras.arcs );
+
+ ras.last.x = x4;
+ ras.last.y = y4;
+
+ return SUCCESS;
+
+ Fail:
+ return FAILURE;
+ }
+
+
+#else /* FT_RASTER_CUBIC_BEZIERS */
+
+
+ int Cubic_To( FT_Vector* control1,
+ FT_Vector* control2,
+ FT_Vector* to,
+ FT_Raster raster )
+ {
+ UNUSED( control1 );
+ UNUSED( control2 );
+ UNUSED( to );
+ UNUSED( raster );
+
+ return ErrRaster_Invalid_Outline;
+ }
+
+
+#endif /* FT_RASTER_CUBIC_BEZIERS */
+
+
+/********************************************************************/
+/* */
+/* The following function is compiled in the raster only when it is */
+/* compile as a stand-alone module.. */
+
+/* It can, otherwise, be found in the FreeType base layer */
+
+#ifdef _STANDALONE_
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Decompose_Outline */
+ /* */
+ /* <Description> */
+ /* Walks over an outline's structure to decompose it into individual */
+ /* segments and Bezier arcs. This function is also able to emit */
+ /* `move to' and `close to' operations to indicate the start and end */
+ /* of new contours in the outline. */
+ /* */
+ /* <Input> */
+ /* outline :: A pointer to the source target. */
+ /* */
+ /* interface :: A table of `emitters', i.e,. function pointers called */
+ /* during decomposition to indicate path operations. */
+ /* */
+ /* user :: A typeless pointer which is passed to each emitter */
+ /* during the decomposition. It can be used to store */
+ /* the state during the decomposition. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means sucess. */
+ /* */
+
+#if 0
+ typedef int (*FTRasterMoveTo_Func)( FT_Vector* to,
+ void* user );
+
+ typedef int (*FTRasterLineTo_Func)( FT_Vector* to,
+ void* user );
+
+ typedef int (*FTRasterConicTo_Func)( FT_Vector* control,
+ FT_Vector* to,
+ void* user );
+
+ typedef int (*FTRasterCubicTo_Func)( FT_Vector* control1,
+ FT_Vector* control2,
+ FT_Vector* to,
+ void* user );
+
+ typedef struct FT_Raster_Funcs_
+ {
+ FTRasterMoveTo_Func move_to;
+ FTRasterLineTo_Func line_to;
+ FTRasterConicTo_Func conic_to;
+ FTRasterCubicTo_Func cubic_to;
+
+ } FT_Raster_Funcs;
+#endif
+
+ int FT_Decompose_Outline( FT_Outline* outline,
+ FT_Raster_Funcs* interface,
+ void* user )
+ {
+ typedef enum _phases
+ {
+ phase_point,
+ phase_conic,
+ phase_cubic,
+ phase_cubic2
+
+ } TPhase;
+
+ FT_Vector v_first;
+ FT_Vector v_last;
+ FT_Vector v_control;
+ FT_Vector v_control2;
+ FT_Vector v_start;
+
+ FT_Vector* point;
+ PByte flags;
+
+ int n; /* index of contour in outline */
+ int first; /* index of first point in contour */
+ int index; /* current point's index */
+
+ int error;
+
+ char tag; /* current point's state */
+ TPhase phase;
+
+
+ first = 0;
+
+ for ( n = 0; n < outline->n_contours; n++ )
+ {
+ int last; /* index of last point in contour */
+
+
+ last = outline->contours[n];
+
+ v_first = outline->points[first];
+ v_last = outline->points[last];
+
+ v_start = v_control = v_first;
+
+ tag = FT_CURVE_TAG( outline->flags[first] );
+ index = first;
+
+ /* A contour cannot start with a cubic control point! */
+
+ if ( tag == FT_Curve_Tag_Cubic )
+ return ErrRaster_Invalid_Outline;
+
+
+ /* check first point to determine origin */
+
+ if ( tag == FT_Curve_Tag_Conic )
+ {
+ /* first point is conic control. Yes, this happens. */
+ if ( FT_CURVE_TAG( outline->flags[last] ) == FT_Curve_Tag_On )
+ {
+ /* start at last point if it is on the curve */
+ v_start = v_last;
+ }
+ else
+ {
+ /* if both first and last points are conic, */
+ /* start at their middle and record its position */
+ /* for closure */
+ v_start.x = ( v_start.x + v_last.x ) / 2;
+ v_start.y = ( v_start.y + v_last.y ) / 2;
+
+ v_last = v_start;
+ }
+ phase = phase_conic;
+ }
+ else
+ phase = phase_point;
+
+
+ /* Begin a new contour with MOVE_TO */
+
+ error = interface->move_to( &v_start, user );
+ if ( error )
+ return error;
+
+ point = outline->points + first;
+ flags = outline->flags + first;
+
+ /* now process each contour point individually */
+
+ while ( index < last )
+ {
+ index++;
+ point++;
+ flags++;
+
+ tag = FT_CURVE_TAG( flags[0] );
+
+ switch ( phase )
+ {
+ case phase_point: /* the previous point was on the curve */
+
+ switch ( tag )
+ {
+ /* two succesive on points -> emit segment */
+ case FT_Curve_Tag_On:
+ error = interface->line_to( point, user );
+ break;
+
+ /* on point + conic control -> remember control point */
+ case FT_Curve_Tag_Conic:
+ v_control = point[0];
+ phase = phase_conic;
+ break;
+
+ /* on point + cubic control -> remember first control */
+ default:
+ v_control = point[0];
+ phase = phase_cubic;
+ break;
+ }
+ break;
+
+ case phase_conic: /* the previous point was a conic control */
+
+ switch ( tag )
+ {
+ /* conic control + on point -> emit conic arc */
+ case FT_Curve_Tag_On:
+ error = interface->conic_to( &v_control, point, user );
+ phase = phase_point;
+ break;
+
+ /* two successive conics -> emit conic arc `in between' */
+ case FT_Curve_Tag_Conic:
+ {
+ FT_Vector v_middle;
+
+
+ v_middle.x = (v_control.x + point->x)/2;
+ v_middle.y = (v_control.y + point->y)/2;
+
+ error = interface->conic_to( &v_control,
+ &v_middle, user );
+ v_control = point[0];
+ }
+ break;
+
+ default:
+ error = ErrRaster_Invalid_Outline;
+ }
+ break;
+
+ case phase_cubic: /* the previous point was a cubic control */
+
+ /* this point _must_ be a cubic control too */
+ if ( tag != FT_Curve_Tag_Cubic )
+ return ErrRaster_Invalid_Outline;
+
+ v_control2 = point[0];
+ phase = phase_cubic2;
+ break;
+
+
+ case phase_cubic2: /* the two previous points were cubics */
+
+ /* this point _must_ be an on point */
+ if ( tag != FT_Curve_Tag_On )
+ error = ErrRaster_Invalid_Outline;
+ else
+ error = interface->cubic_to( &v_control, &v_control2,
+ point, user );
+ phase = phase_point;
+ break;
+ }
+
+ /* lazy error testing */
+ if ( error )
+ return error;
+ }
+
+ /* end of contour, close curve cleanly */
+ error = 0;
+
+ tag = FT_CURVE_TAG( outline->flags[first] );
+
+ switch ( phase )
+ {
+ case phase_point:
+ if ( tag == FT_Curve_Tag_On )
+ error = interface->line_to( &v_first, user );
+ break;
+
+ case phase_conic:
+ error = interface->conic_to( &v_control, &v_start, user );
+ break;
+
+ case phase_cubic2:
+ if ( tag == FT_Curve_Tag_On )
+ error = interface->cubic_to( &v_control, &v_control2,
+ &v_first, user );
+ else
+ error = ErrRaster_Invalid_Outline;
+ break;
+
+ default:
+ error = ErrRaster_Invalid_Outline;
+ break;
+ }
+
+ if ( error )
+ return error;
+
+ first = last + 1;
+ }
+
+ return SUCCESS;
+ }
+#endif
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Convert_Glyph */
+ /* */
+ /* <Description> */
+ /* Converts a glyph into a series of segments and arcs and makes a */
+ /* profiles list with them. */
+ /* */
+ /* <InOut> */
+ /* outline :: The glyph outline. */
+ /* */
+ /* <Return> */
+ /* SUCCESS or FAILURE. */
+ /* */
+ static
+ TResult Convert_Glyph( RAS_ARG_ FT_Outline* outline )
+ {
+ static FT_Outline_Funcs interface =
+ {
+ (FT_Outline_MoveTo_Func)Move_To,
+ (FT_Outline_LineTo_Func)Line_To,
+ (FT_Outline_ConicTo_Func)Conic_To,
+ (FT_Outline_CubicTo_Func)Cubic_To
+ };
+
+ /* Set up state in the raster object */
+ ras.start_prof = NULL;
+ ras.joint = FALSE;
+ ras.fresh = FALSE;
+
+ ras.pool_limit = ras.pool_size - AlignProfileSize;
+
+ ras.n_extrema = 0;
+
+ ras.cur_prof = (PProfile)ras.cursor;
+ ras.cur_prof->offset = ras.cursor;
+ ras.num_profs = 0;
+
+ /* Now decompose curve */
+ if ( FT_Decompose_Outline( outline, &interface, &ras ) )
+ return FAILURE;
+ /* XXX: the error condition is in ras.error */
+
+ /* Check the last contour if needed */
+ if ( Check_Contour( RAS_VAR ) )
+ return FAILURE;
+
+ /* Finalize profiles list */
+ return Finalize_Profile_Table( RAS_VAR );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* 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;
+ TPos 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 reach this place, unless the Profile was not */
+ /* part of the list. */
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* Update */
+ /* */
+ /* Updates 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 to implement. */
+ /* */
+ 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 Bitmap Sweep Routines ********/
+ /******** ********/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Vertical_Sweep_Init */
+ /* */
+ /* <Description> */
+ /* Initializes the vertical bitmap sweep. Called by the generic */
+ /* sweep/draw routine before its loop. */
+ /* */
+ /* <Input> */
+ /* min :: The address of the current minimum scanline. */
+ /* max :: The address of the current maximum scanline. */
+ /* */
+ static
+ void Vertical_Sweep_Init( RAS_ARG_ int* min, int* max )
+ {
+ long pitch;
+
+ UNUSED( max );
+
+ pitch = ras.target.pitch;
+
+ /* start from the bottom line, going up !! */
+ ras.trace_bit = - *min * pitch;
+ ras.trace_incr = -pitch;
+
+ if (pitch > 0)
+ ras.trace_bit += pitch*(ras.target.rows-1);
+
+ ras.gray_min_x = 0;
+ ras.gray_max_x = 0;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Vertical_Sweep_Span */
+ /* */
+ /* <Description> */
+ /* Draws a single horizontal bitmap span during the vertical bitmap */
+ /* sweep. */
+ /* */
+ /* <Input> */
+ /* y :: The current scanline. */
+ /* x1 :: The left span edge. */
+ /* x2 :: The right span edge. */
+ /* */
+ static
+ void Vertical_Sweep_Span( RAS_ARG_ TScan y,
+ TPos x1,
+ TPos x2 )
+ {
+ TPos e1, e2;
+ int c1, c2;
+ Byte f1, f2;
+ PByte target;
+
+
+ UNUSED( y );
+
+ /* Drop-out control */
+
+ e1 = TRUNC( CEILING( x1 ) );
+ if ( x2 - x1 - ras.precision <= ras.precision_jitter )
+ e2 = e1;
+ else
+ e2 = TRUNC( FLOOR( x2 ) );
+
+ if ( e1 <= e2 && e2 >= 0 && e1 < ras.bit_width )
+ {
+ if ( e1 < 0 ) e1 = 0;
+ if ( e2 >= ras.bit_width ) e2 = ras.bit_width - 1;
+
+ c1 = e1 >> 3;
+ c2 = e2 >> 3;
+
+ f1 = ((unsigned char)0xFF >> (e1 & 7));
+ f2 = ~((unsigned char)0x7F >> (e2 & 7));
+
+#ifdef FT_RASTER_ANY_ENDIAN
+ if ( ras.gray_min_x > c1 ) ras.gray_min_x = c1;
+ if ( ras.gray_max_x < c2 ) ras.gray_max_x = c2;
+#endif
+
+ target = ras.bit_buffer + ras.trace_bit + c1;
+ c2 -= c1;
+
+ if ( c2 > 0 )
+ {
+ target[0] |= f1;
+
+ /* memset() is slower than the following code on many platforms. */
+ /* This is due to the fact that, in the vast majority of cases, */
+ /* the span length in bytes is relatively small. */
+ c2--;
+ while ( c2 > 0 )
+ {
+ *(++target) = 0xFF;
+ c2--;
+ }
+ target[1] |= f2;
+ }
+ else
+ *target |= ( f1 & f2 );
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Vertical_Test_Pixel */
+ /* */
+ /* <Description> */
+ /* Tests a pixel `light' during the vertical bitmap sweep. Used */
+ /* during drop-out control only. */
+ /* */
+ /* <Input> */
+ /* y :: The current scanline. */
+ /* x :: The current x coordinate. */
+ /* */
+ static
+ int Vertical_Test_Pixel( RAS_ARG_ TScan y,
+ int x )
+ {
+ int c1 = x >> 3;
+
+
+ UNUSED( y );
+
+ return ( x >= 0 && x < ras.bit_width &&
+ ras.bit_buffer[ras.trace_bit + c1] & (0x80 >> (x & 7)) );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Vertical_Set_Pixel */
+ /* */
+ /* <Description> */
+ /* Sets a single pixel in a bitmap during the vertical sweep. Used */
+ /* during drop-out control. */
+ /* */
+ /* <Input> */
+ /* y :: The current scanline. */
+ /* x :: The current x coordinate. */
+ /* color :: Ignored by this function. */
+ /* */
+ static
+ void Vertical_Set_Pixel( RAS_ARG_ int y,
+ int x,
+ int color )
+ {
+ UNUSED( color );
+ UNUSED( y );
+
+ if ( x >= 0 && x < ras.bit_width )
+ {
+ int c1 = x >> 3;
+
+ if ( ras.gray_min_x > c1 ) ras.gray_min_x = c1;
+ if ( ras.gray_max_x < c1 ) ras.gray_max_x = c1;
+
+ ras.bit_buffer[ras.trace_bit+c1] |= (char)(0x80 >> (x & 7));
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Vertical_Sweep_Step */
+ /* */
+ /* <Description> */
+ /* Called whenever the sweep jumps to another scanline. Only updates */
+ /* the pointers in the vertical bitmap sweep. */
+ /* */
+ static
+ void Vertical_Sweep_Step( RAS_ARG )
+ {
+ ras.trace_bit += ras.trace_incr;
+ }
+
+
+ static
+ const Raster_Render vertical_render_mono =
+ {
+ &Vertical_Sweep_Init,
+ &Vertical_Sweep_Span,
+ &Vertical_Sweep_Step,
+ &Vertical_Test_Pixel,
+ &Vertical_Set_Pixel
+ };
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /******** ********/
+ /******** Horizontal Bitmap Sweep Routines ********/
+ /******** ********/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Horizontal_Sweep_Init */
+ /* */
+ /* <Description> */
+ /* Initializes the horizontal bitmap sweep. Called by the generic */
+ /* sweep/draw routine before its loop. */
+ /* */
+ /* <Input> */
+ /* min :: The address of the current minimum pixel column. */
+ /* max :: The address of the current maximum pixel column. */
+ /* */
+ static
+ void Horizontal_Sweep_Init( RAS_ARG_ int* min,
+ int* max )
+ {
+ UNUSED( ras );
+ UNUSED( min );
+ UNUSED( max );
+
+ /* nothing, really */
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Horizontal_Sweep_Span */
+ /* */
+ /* <Description> */
+ /* Draws a single vertical bitmap span during the horizontal bitmap */
+ /* sweep. Actually, this function is only used to check for weird */
+ /* drop-out cases. */
+ /* */
+ /* <Input> */
+ /* y :: The current pixel column. */
+ /* x1 :: The top span edge. */
+ /* x2 :: The bottom span edge. */
+ /* */
+ static
+ void Horizontal_Sweep_Span( RAS_ARG_ TScan y,
+ TPos x1,
+ TPos x2 )
+ {
+ TPos e1, e2;
+ PByte bits;
+ Byte f1;
+
+ UNUSED( y );
+
+ /* During the horizontal sweep, we only take care of drop-outs */
+ if ( x2 - x1 < ras.precision )
+ {
+ e1 = CEILING( x1 );
+ e2 = FLOOR( x2 );
+
+ if ( e1 == e2 )
+ {
+ bits = ras.bit_buffer + (y >> 3);
+ f1 = (Byte)(0x80 >> (y & 7));
+
+ e1 = TRUNC( e1 );
+
+ if ( e1 >= 0 && e1 < ras.target.rows )
+ {
+ long pitch = ras.target.pitch;
+ long offset = - pitch * e1;
+
+ if (pitch > 0)
+ offset += (ras.target.rows-1)*pitch;
+
+ bits[offset] |= f1;
+ }
+ }
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Horizontal_Test_Pixel */
+ /* */
+ /* <Description> */
+ /* Tests a pixel `light' during the horizontal bitmap sweep. Used */
+ /* during drop-out control only. */
+ /* */
+ /* <Input> */
+ /* y :: The current pixel column. */
+ /* x :: The current row/scanline. */
+ /* */
+ static
+ int Horizontal_Test_Pixel( RAS_ARG_ int y,
+ int x )
+ {
+ char* bits = (char*)ras.bit_buffer + (y >> 3);
+ int f1 = (Byte)(0x80 >> (y & 7));
+ long pitch = ras.target.pitch;
+ long offset = - pitch * x;
+
+ if (pitch > 0)
+ offset += (ras.target.rows-1)*pitch;
+
+ return ( x >= 0 && x < ras.target.rows && (bits[0] & f1) );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Horizontal_Set_Pixel */
+ /* */
+ /* <Description> */
+ /* Sets a single pixel in a bitmap during the horizontal sweep. Used */
+ /* during drop-out control. */
+ /* */
+ /* <Input> */
+ /* y :: The current pixel column. */
+ /* x :: The current row/scanline. */
+ /* color :: Ignored by this function. */
+ /* */
+ static
+ void Horizontal_Set_Pixel( RAS_ARG_ int y,
+ int x,
+ int color )
+ {
+ char* bits = (char*)ras.bit_buffer + (y >> 3);
+ int f1 = (Byte)(0x80 >> (y & 7));
+
+
+ UNUSED( color );
+
+ if ( x >= 0 && x < ras.target.rows )
+ {
+ long pitch = ras.target.pitch;
+ long offset = - x*pitch;
+
+ if (pitch > 0)
+ offset += (ras.target.rows-1)*pitch;
+
+ bits[offset] |= f1;
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Horizontal_Sweep_Step */
+ /* */
+ /* <Description> */
+ /* Called whenever the sweep jumps to another pixel column. */
+ /* */
+ static
+ void Horizontal_Sweep_Step( RAS_ARG )
+ {
+ UNUSED( ras.target );
+
+ /* Nothing, really */
+ }
+
+
+ static
+ const Raster_Render horizontal_render_mono =
+ {
+ &Horizontal_Sweep_Init,
+ &Horizontal_Sweep_Span,
+ &Horizontal_Sweep_Step,
+ &Horizontal_Test_Pixel,
+ &Horizontal_Set_Pixel
+ };
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /******** ********/
+ /******** Anti-Aliased Vertical Bitmap Sweep Routines ********/
+ /******** ********/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+#ifdef FT_RASTER_OPTION_ANTI_ALIAS
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Vertical_Gray_Sweep_Init */
+ /* */
+ /* <Description> */
+ /* Initializes the vertical bitmap sweep. Called by the generic */
+ /* sweep/draw routine before its loop. */
+ /* */
+ /* <Input> */
+ /* min :: The address of the current minimum scanline. */
+ /* max :: The address of the current maximum scanline. */
+ /* */
+ static
+ void Vertical_Gray_Sweep_Init( RAS_ARG_ int* min, int* max )
+ {
+ long pitch;
+
+ UNUSED( max );
+
+ pitch = ras.target.pitch;
+
+ /* start from the bottom line, going up */
+ ras.trace_incr = -pitch;
+ ras.trace_bit = - *min * pitch;
+
+ if (pitch > 0)
+ ras.trace_bit += (ras.target.rows-1)*pitch;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Vertical_Gray_Sweep_Span */
+ /* */
+ /* <Description> */
+ /* Draws a single horizontal bitmap span during the vertical bitmap */
+ /* sweep. */
+ /* */
+ /* <Input> */
+ /* y :: The current scanline. */
+ /* x1 :: The left span edge. */
+ /* x2 :: The right span edge. */
+ /* */
+ static
+ void Vertical_Gray_Sweep_Span( RAS_ARG_ TScan y,
+ TPos x1,
+ TPos x2 )
+ {
+ TPos e1, e2;
+ int shift = ras.precision_bits - 6;
+ PByte target;
+
+
+ UNUSED( y );
+
+ x1 += ras.precision_half;
+ x2 += ras.precision_half;
+
+#ifdef FT_RASTER_OPTION_CONTRAST
+ if ( x2-x1 < ras.precision )
+ {
+ x1 = ((x1+x2) >> 1) - ras.precision_half;
+ x2 = x1 + ras.precision;
+ }
+#endif
+
+ e1 = TRUNC( x1 );
+ e2 = TRUNC( x2 );
+
+ if ( e1 <= e2 && e2 >= 0 && e1 < ras.bit_width )
+ {
+ x1 = FRAC(x1) >> shift;
+ x2 = FRAC(x2) >> shift;
+
+ if ( e1 < 0 )
+ {
+ e1 = 0;
+ x1 = 0;
+ }
+
+ if ( e2 > ras.bit_width )
+ {
+ e2 = ras.bit_width-1;
+ x2 = 0;
+ }
+
+ target = ras.bit_buffer + ras.trace_bit + e1;
+ e2 -= e1;
+
+ if ( e2 > 0 )
+ {
+ target[0] += (Byte)(64-x1);
+ e2--;
+ while (e2 > 0)
+ {
+ *(++target) += 64;
+ e2--;
+ }
+ if (x2)
+ target[1] += (Byte)x2;
+ }
+ else
+ {
+ target[0] += (Byte)(x2-x1);
+ }
+ }
+ }
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Vertical_Gray_Test_Pixel */
+ /* */
+ /* <Description> */
+ /* Tests a pixel `light' during the vertical bitmap sweep. Used */
+ /* during drop-out control only. */
+ /* */
+ /* <Input> */
+ /* y :: The current scanline. */
+ /* x :: The current x coordinate. */
+ /* */
+ static
+ int Vertical_Gray_Test_Pixel( RAS_ARG_ TScan y,
+ int x )
+ {
+ UNUSED( y );
+
+#if 0
+ /* as a rule of thumb, do not add a drop-out if the current */
+ /* gray level is over 0.5 */
+
+ return ( x >= 0 && x < ras.bit_width &&
+ ras.bit_buffer[ras.trace_bit + x] >= 64 );
+#else
+ UNUSED(x);
+ return 0;
+#endif
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Vertical_Gray_Set_Pixel */
+ /* */
+ /* <Description> */
+ /* Sets a single pixel in a bitmap during the vertical sweep. Used */
+ /* during drop-out control. */
+ /* */
+ /* <Input> */
+ /* y :: The current scanline. */
+ /* x :: The current x coordinate. */
+ /* color :: Ignored by this function. */
+ /* */
+ static
+ void Vertical_Gray_Set_Pixel( RAS_ARG_ int y,
+ int x,
+ int color )
+ {
+ UNUSED( y );
+
+ if ( x >= 0 && x < ras.bit_width )
+ {
+ unsigned char* pixel;
+
+ pixel = ras.bit_buffer + ras.trace_bit + x;
+
+ /* do not add too much to the pixel gray level */
+ color += *pixel;
+ if (color < 64)
+ color = 64;
+
+ *pixel = ( color >= 128 ? 128 : (unsigned char)color );
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Vertical_Sweep_Step */
+ /* */
+ /* <Description> */
+ /* Called whenever the sweep jumps to another scanline. Only updates */
+ /* the pointers in the vertical bitmap sweep. */
+ /* */
+ static
+ void Vertical_Gray_Sweep_Step( RAS_ARG )
+ {
+ ras.trace_bit += ras.trace_incr;
+ }
+
+
+
+ static
+ const Raster_Render vertical_render_gray =
+ {
+ &Vertical_Gray_Sweep_Init,
+ &Vertical_Gray_Sweep_Span,
+ &Vertical_Gray_Sweep_Step,
+ &Vertical_Gray_Test_Pixel,
+ &Vertical_Gray_Set_Pixel
+ };
+
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /******** ********/
+ /******** Horizontal Bitmap Sweep Routines ********/
+ /******** ********/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Horizontal_Sweep_Init */
+ /* */
+ /* <Description> */
+ /* Initializes the horizontal bitmap sweep. Called by the generic */
+ /* sweep/draw routine before its loop. */
+ /* */
+ /* <Input> */
+ /* min :: The address of the current minimum pixel column. */
+ /* max :: The address of the current maximum pixel column. */
+ /* */
+ static
+ void Horizontal_Gray_Sweep_Init( RAS_ARG_ int* min,
+ int* max )
+ {
+ UNUSED( ras );
+ UNUSED( min );
+ UNUSED( max );
+
+ /* nothing, really */
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Horizontal_Gray_Sweep_Span */
+ /* */
+ /* <Description> */
+ /* Draws a single vertical bitmap span during the horizontal bitmap */
+ /* sweep. */
+ /* */
+ /* <Input> */
+ /* y :: The current scanline. */
+ /* x1 :: The left span edge. */
+ /* x2 :: The right span edge. */
+ /* */
+ static
+ void Horizontal_Gray_Sweep_Span( RAS_ARG_ TScan y,
+ TPos x1,
+ TPos x2 )
+ {
+ TPos e1, e2;
+ int shift = ras.precision_bits - 6;
+ int incr;
+ PByte bits;
+
+
+ UNUSED( y );
+
+ x1 += ras.precision_half;
+ x2 += ras.precision_half;
+
+#ifdef FT_RASTER_OPTION_CONTRAST
+ if (x2-x1 < ras.precision)
+ {
+ x1 = ((x1+x2) >> 1) - ras.precision_half;
+ x2 = x1 + ras.precision;
+ }
+#endif
+
+ e1 = TRUNC( x1 );
+ e2 = TRUNC( x2 );
+
+ if ( e1 <= e2 && e2 >= 0 && e1 < ras.bit_width )
+ {
+ x1 = FRAC(x1) >> shift;
+ x2 = FRAC(x2) >> shift;
+
+ if ( e1 < 0 )
+ {
+ e1 = 0;
+ x1 = 0;
+ }
+
+ if ( e2 >= ras.bit_width )
+ {
+ e2 = ras.bit_width;
+ x2 = 0;
+ }
+
+ incr = -ras.target.pitch;
+ bits = ras.bit_buffer + y;
+ bits += incr * e1;
+ if (incr < 0)
+ bits -= incr*(ras.target.rows-1);
+
+ e2 -= e1;
+
+ if ( e2 > 0 )
+ {
+ bits[0] += (Byte)(64-x1);
+ e2--;
+ while (e2 > 0)
+ {
+ bits += incr;
+ bits[0] += 64;
+ e2--;
+ }
+ if (x2)
+ bits[incr] += (Byte)x2;
+ }
+ else
+ {
+ bits[0] += (Byte)(x2-x1);
+ }
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Horizontal_Gray_Test_Pixel */
+ /* */
+ /* <Description> */
+ /* Tests a pixel `light' during the horizontal bitmap sweep. Used */
+ /* during drop-out control only. */
+ /* */
+ /* <Input> */
+ /* y :: The current pixel column. */
+ /* x :: The current row/scanline. */
+ /* */
+ static
+ int Horizontal_Gray_Test_Pixel( RAS_ARG_ int y,
+ int x )
+ {
+#if 0
+ unsigned char* pixel = (unsigned char*)ras.bit_buffer + y;
+
+ if ( ras.target.flow == Flow_Down )
+ pixel += (ras.target.rows-1 - x) * ras.target.cols;
+ else
+ pixel += x * ras.target.cols;
+
+ return ( x >= 0 && x < ras.target.rows &&
+ *pixel >= 64 );
+#else
+ UNUSED(y);
+ UNUSED(x);
+ return 0;
+#endif
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Horizontal_Set_Pixel */
+ /* */
+ /* <Description> */
+ /* Sets a single pixel in a bitmap during the horizontal sweep. Used */
+ /* during drop-out control. */
+ /* */
+ /* <Input> */
+ /* y :: The current pixel column. */
+ /* x :: The current row/scanline. */
+ /* color :: Ignored by this function. */
+ /* */
+ static
+ void Horizontal_Gray_Set_Pixel( RAS_ARG_ int y,
+ int x,
+ int color )
+ {
+ unsigned char* pixel = (unsigned char*)ras.bit_buffer + y;
+
+ if ( x >= 0 && x < ras.target.rows )
+ {
+ long pitch = ras.target.pitch;
+
+ pixel -= pitch*x;
+ if (pitch > 0)
+ pixel += pitch*(ras.target.rows-1);
+
+ color += *pixel;
+ if (color < 64)
+ color = 64;
+
+ *pixel = (color >= 128 ? 128 : (unsigned char)color );
+ }
+ }
+
+
+ static
+ void Gray_Ignore( void )
+ {
+ ;
+ }
+
+
+ static
+ const Raster_Render horizontal_render_gray =
+ {
+ &Horizontal_Gray_Sweep_Init,
+ &Horizontal_Gray_Sweep_Span,
+
+ (Function_Sweep_Step) &Gray_Ignore,
+ &Horizontal_Gray_Test_Pixel,
+ &Horizontal_Gray_Set_Pixel,
+ };
+
+#endif /* FT_RASTER_OPTION_ANTI_ALIAS */
+
+
+ /*************************************************************************/
+ /* */
+ /* A technical note to explain how the scanline sweep is performed: */
+ /* */
+ /* The function Draw_Sweep() is used to sweep the scanlines of the */
+ /* target bitmap or pixmap. For each scanline, it must do the */
+ /* following: */
+ /* */
+ /* - Get the set of all outline intersections for the current */
+ /* scanline. */
+ /* */
+ /* - Sort these intersections (in increasing order). */
+ /* */
+ /* - Pair intersections to create spans (horizontal pixel segments) */
+ /* that are then `drawn' by calling a `sweep_span' function. */
+ /* */
+ /* - Check for dropouts: If a span is too small to be drawn, it must */
+ /* be re-adjusted in order to make it visible again. */
+ /* */
+ /* The sweep starts from the bottom of the outline (ymin) and goes */
+ /* upwards (to ymax). Thus, the function manages the following: */
+ /* */
+ /* - A linked list of the profiles which are above the current */
+ /* scanline. It is called the `wait' list as it contains all the */
+ /* profiles waiting to be `activated' during the sweep. It contains */
+ /* all profiles initially. */
+ /* */
+ /* - A linked list of the profiles covering the current scanline, */
+ /* i.e., all the profiles that contain an intersection for the */
+ /* current scanline. It is called the `draw' list. */
+ /* */
+ /* A profile travels from the wait list to the draw list if the */
+ /* current scanline reaches its bottom border (its ymin). It is also */
+ /* removed from the draw list (and becomes unlisted) when the current */
+ /* scanline reaches the scanline above its upper border (its ymax). */
+ /* */
+ /* These positions correspond to the `extrema' table built by */
+ /* Finalize_Profile_Table(). */
+ /* */
+ /* The draw list is always sorted in increasing order of the X */
+ /* coordinates. We use a bubble sort because it is easy to implement */
+ /* on a linked list, and because in 95% cases, the list is already */
+ /* correctly sorted when going from one scanline to the other. */
+ /* */
+ /* The extrema table gives the scanline coordinates at which at least */
+ /* one profile must be removed from the `draw' list, or another one */
+ /* must be moved from the `wait' to `draw' lists. */
+ /* */
+ /* Note that when a dropout is detected, the corresponding span is not */
+ /* drawn immediately but kept on a temporary list. All dropout spans */
+ /* are drawn after the regular spans on a given scanline. This is a */
+ /* requirement of the TrueType specification to properly implement */
+ /* some drop-out control modes -- yes, it's weird! */
+ /* */
+ /* Finally, the parser contains four function pointers that are called */
+ /* by Draw_Sweep(). Each rendering mode (monochrome, anti-aliased-5, */
+ /* and anti-aliased-17) provide its own set of such functions. These */
+ /* are: */
+ /* */
+ /* sweep_init: Called only when the sweep starts. Used to set */
+ /* up some variables. */
+ /* */
+ /* sweep_span: Used to draw a horizontal span on the current */
+ /* scanline. */
+ /* */
+ /* sweep_test_pixel: Used to test a pixel's intensity, as it is */
+ /* required for drop-out control. */
+ /* */
+ /* sweep_put_pixel: Used to write a single pixel when a drop-out */
+ /* needs to be lighted/drawn. */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* Generic Sweep Drawing routine */
+ /* */
+ static
+ TResult Draw_Sweep( RAS_ARG )
+ {
+ TScan y, y_change, y_height;
+
+ PProfile P, Q, P_Left, P_Right;
+
+ TScan min_Y, max_Y, top, bottom, dropouts;
+
+ TPos x1, x2, e1, e2;
+
+ TProfileList wait;
+ TProfileList draw;
+
+
+ /* Init empty linked lists */
+ Init_Linked( &wait );
+ Init_Linked( &draw );
+
+ /* first, compute min and max Y -- and add profiles to the wait list */
+ P = ras.start_prof;
+ max_Y = TRUNC( ras.minY );
+ min_Y = 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 extrema table */
+ if ( ras.n_extrema == 0 )
+ {
+ ras.error = ErrRaster_Invalid_Outline;
+ return FAILURE;
+ }
+
+ /* Now inits the sweep */
+ PTRACE2(( "draw_sweep: initialize sweep\n" ));
+ ras.render.init( RAS_VAR_ &min_Y, &max_Y );
+ PTRACE2(( " init min_y = %d, max_y = %d\n", 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.n_extrema > 0 &&
+ ras.pool_size[-ras.n_extrema] == min_Y )
+ ras.n_extrema--;
+
+ PTRACE2(( "starting loop with n_extrema = %d", ras.n_extrema ));
+ while ( ras.n_extrema > 0 )
+ {
+ PProfile prof = wait;
+
+
+ /* look in the wait list for new activations */
+ while ( prof )
+ {
+ PProfile next = prof->link;
+
+
+ prof->countL -= y_height;
+ if ( prof->countL == 0 )
+ {
+ /* move the profile from the wait list to the draw list */
+ DelOld( &wait, prof );
+ InsNew( &draw, prof );
+ }
+ prof = next;
+ }
+
+ /* Sort the draw list */
+ Sort( &draw );
+
+ /* compute next y extremum scanline; we won't change the */
+ /* elements of the wait and draw lists until there */
+ y_change = ras.pool_size[-ras.n_extrema--];
+ y_height = y_change - y;
+
+ PTRACE2(( ">>> y = %d, y_change = %d, y_height = %d",
+ y, y_change, y_height ));
+
+ while ( y < y_change )
+ {
+ int window;
+ PProfile left;
+
+
+ /* Let's trace */
+ dropouts = 0;
+
+ /* skip to next line if there is no active profile there */
+ if ( !draw ) goto Next_Line;
+
+ left = draw;
+ window = left->flow;
+ prof = left->link;
+
+ PTRACE2(( ">>> line y = %d", y ));
+
+ while ( prof )
+ {
+ PProfile next = prof->link;
+
+
+ window += prof->flow;
+
+ if ( window == 0 )
+ {
+ x1 = left->X;
+ x2 = prof->X;
+
+ if ( x1 > x2 )
+ {
+ TPos xs = x1;
+
+
+ x1 = x2;
+ x2 = xs;
+ }
+
+ if ( x2 - x1 <= ras.precision && ras.dropout_mode )
+ {
+ e1 = CEILING( x1 );
+ e2 = FLOOR( x2 );
+
+ if ( e1 > e2 || e2 == e1 + ras.precision )
+ {
+ /* a drop out was detected */
+
+ left->X = x1;
+ prof->X = x2;
+
+ /* mark profiles for drop-out processing */
+ left->countL = 1;
+ prof->countL = 2;
+ dropouts++;
+ goto Skip_To_Next;
+ }
+ }
+
+ PTRACE2(( "drawing span ( y=%d, x1=%d, x2=%d )",
+ y, x1, x2 ));
+ ras.render.span( RAS_VAR_ y, x1, x2 );
+
+ Skip_To_Next:
+ left = next;
+ }
+ prof = next;
+ }
+
+ /* 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.render.step( RAS_VAR );
+
+ y++;
+
+ if ( y < y_change )
+ Sort( &draw );
+
+ PTRACE2(( "line sorted for next operation" ));
+ }
+
+ /* Now finalize the profiles that needs it */
+
+ PTRACE2(( "finalizing profiles..." ));
+ {
+ PProfile prof, next;
+
+
+ prof = draw;
+ while ( prof )
+ {
+ next = prof->link;
+ if (prof->height == 0)
+ DelOld( &draw, prof );
+ prof = next;
+ }
+ }
+
+ PTRACE2(( "profiles finalized for this run" ));
+ }
+
+ /* for gray-scaling, flushes the bitmap scanline cache */
+ while ( y <= max_Y )
+ {
+ ras.render.step( RAS_VAR );
+ y++;
+ }
+
+ return SUCCESS;
+
+
+Scan_DropOuts :
+ P_Left = draw;
+
+
+ while ( dropouts > 0 )
+ {
+ TPos e1, e2;
+ PProfile left, right;
+
+
+ while ( P_Left->countL != 1 )
+ P_Left = P_Left->link;
+ P_Right = P_Left->link;
+ while ( P_Right->countL != 2 )
+ P_Right = P_Right->link;
+
+ P_Left->countL = 0;
+ P_Right->countL = 0;
+
+ /* Now perform the dropout control */
+ x1 = P_Left->X;
+ x2 = P_Right->X;
+
+ left = ( ras.flipped ? P_Right : P_Left );
+ right = ( ras.flipped ? P_Left : P_Right );
+
+ PTRACE2(( "performing drop-out control ( x1= %d, x2 = %d )",
+ x1, x2 ));
+
+ e1 = CEILING( x1 );
+ e2 = FLOOR ( x2 );
+
+ if ( e1 > e2 )
+ {
+ if ( e1 == e2 + ras.precision )
+ {
+ switch ( ras.dropout_mode )
+ {
+ 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 */
+ /* */
+
+ /* upper stub test */
+ if ( ( left->next == right && left->height <= 0 ) ||
+
+ /* lower stub test */
+ ( right->next == left && left->start == y ) ||
+
+ /* check that the rightmost pixel isn't set */
+ ras.render.test_pixel( RAS_VAR_ y, TRUNC(e1)) )
+ goto Next_Dropout;
+
+ if ( ras.dropout_mode == 2 )
+ e1 = e2;
+ else
+ e1 = CEILING( (x1 + x2 + 1)/2 );
+
+ break;
+
+ default:
+ goto Next_Dropout; /* Unsupported mode */
+ }
+ }
+ else
+ goto Next_Dropout;
+ }
+
+ PTRACE2(( " -> setting pixel" ));
+ ras.render.set_pixel( RAS_VAR_ y,
+ TRUNC( e1 ),
+ (x2 - x1) >> ras.scale_shift );
+ Next_Dropout:
+
+ dropouts--;
+ }
+ goto Next_Line;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Render_Single_Pass */
+ /* */
+ /* <Description> */
+ /* Performs one sweep with sub-banding. */
+ /* */
+ /* <Input> */
+ /* flipped :: whether or not we have to flip. */
+ /* */
+ /* <Returns> */
+ /* Error code. 0 means success. */
+ /* */
+ static
+ int Render_Single_Pass( RAS_ARG_ int flipped )
+ {
+ TBand* band;
+
+
+ ras.flipped = flipped;
+
+ band = ras.band_stack;
+
+ PTRACE2(( "raster: entering render_single_pass (flipped = %d)\n",
+ flipped ));
+
+ while ( band >= ras.band_stack )
+ {
+ ras.maxY = ((long)band[0].y_max << (ras.scale_shift+6)) - 1;
+
+ ras.minY = (long)band[0].y_min << (ras.scale_shift+6);
+
+ ras.cursor = ras.pool;
+ ras.error = 0;
+
+ PTRACE2(( "raster: band = [ %d, %d ]\n",
+ band[0].y_min,
+ band[0].y_max ));
+
+ if ( Convert_Glyph( RAS_VAR_ ras.outline ) )
+ {
+ int bottom, top, half;
+
+
+ if ( ras.error != ErrRaster_Overflow )
+ return FAILURE;
+ ras.error = ErrRaster_Ok;
+
+ PTRACE2(( "conversion failure, performing sub-banding\n" ));
+
+ /* sub-banding */
+
+#ifdef DEBUG_RASTER
+ ClearBand( RAS_VAR_ TRUNC( ras.minY ), TRUNC( ras.maxY ) );
+#endif
+
+ bottom = band[0].y_min;
+ top = band[0].y_max;
+ half = ( top - bottom ) >> 1;
+
+ if ( band >= ras.band_stack + 7 || half == 0 )
+ {
+ ras.band_top = 0;
+ ras.error = ErrRaster_Invalid_Outline;
+ return ras.error;
+ }
+
+ band[1].y_min = bottom + half;
+ band[1].y_max = top;
+ band[0].y_max = bottom + half;
+
+ band ++;
+ }
+ else
+ {
+ PTRACE2(( "conversion succeeded, span drawing sweep\n" ));
+ if ( ras.start_prof )
+ if ( Draw_Sweep( RAS_VAR ) )
+ return ras.error;
+ band --;
+ }
+ }
+
+ PTRACE2(( "raster: exiting render_single_pass\n" ));
+
+ return SUCCESS; /* success */
+ }
+
+
+ static
+ int Raster_Render1( FT_Raster raster )
+ {
+ int error;
+
+
+ if ( ras.target.width > ABS(ras.target.pitch)*8 )
+ return ErrRaster_Invalid_Map;
+
+ ras.scale_shift = ras.precision_bits - 6;
+ ras.scale_delta = ras.precision_half;
+
+ /* Vertical Sweep */
+ ras.band_top = 0;
+ ras.band_stack[0].y_min = 0;
+ ras.band_stack[0].y_max = ras.target.rows;
+
+ ras.render = vertical_render_mono;
+ ras.bit_width = ras.target.width;
+ ras.bit_buffer = (unsigned char*)ras.target.buffer;
+
+ if ( (error = Render_Single_Pass( RAS_VAR_ 0 )) != 0 )
+ return error;
+
+ /* Horizontal Sweep */
+
+ if ( ras.second_pass && ras.dropout_mode != 0 )
+ {
+ ras.render = horizontal_render_mono;
+ ras.band_top = 0;
+ ras.band_stack[0].y_min = 0;
+ ras.band_stack[0].y_max = ras.target.width;
+
+ if ( (error = Render_Single_Pass( RAS_VAR_ 1 )) != 0 )
+ return error;
+ }
+
+ return ErrRaster_Ok;
+ }
+
+
+#ifdef FT_RASTER_OPTION_ANTI_ALIAS
+
+
+ static
+ int Raster_Render8( FT_Raster raster )
+ {
+ int error;
+
+ if ( ras.target.width > ABS(ras.target.pitch) )
+ return ErrRaster_Invalid_Map;
+
+ /* Vertical Sweep */
+ ras.band_top = 0;
+ ras.band_stack[0].y_min = 0;
+ ras.band_stack[0].y_max = ras.target.rows;
+
+ ras.scale_shift = (ras.precision_bits-6);
+ ras.scale_delta = ras.precision_half;
+ ras.dropout_mode = 2;
+
+ ras.render = vertical_render_gray;
+ ras.bit_width = ras.target.width;
+ ras.bit_buffer = (unsigned char*)ras.target.buffer;
+ ras.pix_buffer = (unsigned char*)ras.target.buffer;
+
+ error = Render_Single_Pass( RAS_VAR_ 0 );
+ if ( error )
+ return error;
+
+#if 1
+ /* Horizontal Sweep */
+ ras.render = horizontal_render_gray;
+ ras.band_top = 0;
+ ras.bit_width = ras.target.rows;
+ ras.band_stack[0].y_min = 0;
+ ras.band_stack[0].y_max = ras.target.width;
+
+ return Render_Single_Pass( RAS_VAR_ 1 );
+#else
+ return 0;
+#endif
+ }
+
+
+#else /* FT_RASTER_OPTION_ANTI_ALIAS */
+
+
+ static
+ int Raster_Render8( FT_Raster raster )
+ {
+ return ErrRaster_Unimplemented;
+ }
+
+
+#endif /* FT_RASTER_OPTION_ANTI_ALIAS */
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Raster_Render */
+ /* */
+ /* <Description> */
+ /* Renders an outline into a target bitmap. */
+ /* */
+ /* <Input> */
+ /* raster :: A handle to the raster object used during rendering. */
+ /* outline :: A pointer to the source outline record/object. */
+ /* bitmap :: A pointer to the target bitmap descriptor. */
+ /* */
+ /* <Return> */
+ /* Error code, interpreted as a FT_Error by FreeType. 0 means */
+ /* success. */
+ /* */
+ EXPORT_FUNC
+ int FT_Raster_Render( FT_Raster raster,
+ FT_Outline* outline,
+ FT_Bitmap* target_map )
+ {
+ if ( !raster || !raster->pool || !raster->pool_size )
+ return ErrRaster_Uninitialized_Object;
+
+ /* return immediately if the outline is empty */
+ if ( outline->n_points == 0 || outline->n_contours <= 0 )
+ return ErrRaster_Ok;
+
+ if ( !outline || !outline->contours || !outline->points )
+ return ErrRaster_Invalid_Outline;
+
+ if ( outline->n_points != outline->contours[outline->n_contours - 1] + 1 )
+ return ErrRaster_Invalid_Outline;
+
+ if ( !target_map || !target_map->buffer )
+ return ErrRaster_Invalid_Map;
+
+ ras.outline = outline;
+ ras.target = *target_map;
+
+ ras.dropout_mode = outline->dropout_mode;
+ ras.second_pass = outline->second_pass;
+ SET_High_Precision( outline->high_precision );
+
+ switch ( target_map->pixel_mode )
+ {
+ case ft_pixel_mode_mono:
+ return Raster_Render1( raster );
+ case ft_pixel_mode_grays:
+ return Raster_Render8( raster );
+
+ default:
+ return ErrRaster_Unimplemented;
+ }
+ }
+
+
+#ifdef FT_RASTER_OPTION_ANTI_ALIAS
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Reset_Palette_5 */
+ /* */
+ /* <Description> */
+ /* Resets lookup table when the 5-gray-levels palette changes. */
+ /* */
+ static
+ void Reset_Palette_5( RAS_ARG )
+ {
+
+
+#ifdef FT_RASTER_ANY_ENDIAN
+
+
+ int i, j, l, c;
+
+
+ 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;
+ }
+
+
+#else /* FT_RASTER_ANY_ENDIAN */
+
+
+ int i;
+
+
+ for ( i = 0; i < 256; i++ )
+ {
+ int cnt1, cnt2;
+
+ cnt1 = ((i & 128) >> 7) +
+ ((i & 64) >> 6) +
+ ((i & 8) >> 3) +
+ ((i & 4) >> 2);
+
+ cnt2 = ((i & 32) >> 5) +
+ ((i & 16) >> 4) +
+ ((i & 2) >> 1) +
+ (i & 1);
+
+ /* */
+ /* Note that when the endianess isn't specified through one of the */
+ /* configuration, we use the big-endian storage in `count_table' */
+ /* */
+
+#if defined( FT_RASTER_LITTLE_ENDIAN )
+ ras.count_table[i] = (ras.grays[cnt2] << 8) | ras.grays[cnt1];
+#else
+ ras.count_table[i] = (ras.grays[cnt1] << 8) | ras.grays[cnt2];
+#endif
+ }
+
+
+#endif /* FT_RASTER_ANY_ENDIAN */
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Reset_Palette_17 */
+ /* */
+ /* <Description> */
+ /* Resets lookup table when 17-gray-levels palette changes. */
+ /* */
+#ifdef FT_RASTER_ANTI_ALIAS_17
+
+
+ static
+ void Reset_Palette_17( RAS_ARG )
+ {
+ int i;
+
+
+ for ( i = 0; i < 256; i++ )
+ ras.count_table[i] = ((i & 128) >> 7) +
+ ((i & 64) >> 6) +
+ ((i & 8) >> 3) +
+ ((i & 4) >> 2) +
+ ((i & 32) >> 5) +
+ ((i & 16) >> 4) +
+ ((i & 2) >> 1) +
+ (i & 1);
+}
+
+
+#endif /* FT_RASTER_ANTI_ALIAS_17 */
+
+
+#endif /* TT_RASTER_OPTION_ANTI_ALIAS */
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Raster_ObjSize */
+ /* */
+ /* <Description> */
+ /* This function returns the size of a raster object in bytes. */
+ /* Client applications are thus able to allocate objects in their own */
+ /* heap/memory space, without revealing the internal structures of */
+ /* the scan-line converter. */
+ /* */
+ /* <Return> */
+ /* The size in bytes of a single raster object. */
+ /* */
+ EXPORT_FUNC
+ long FT_Raster_ObjSize( void )
+ {
+ return (long)sizeof( struct FT_RasterRec_ );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Raster_Init */
+ /* */
+ /* <Description> */
+ /* Initializes a fresh raster object which should have been allocated */
+ /* by client applications. This function is also used to set the */
+ /* object's render pool. It can be used repeatedly on a single */
+ /* object if one wants to change the pool's address or size. */
+ /* */
+ /* Note that the render pool has no state and is only used during a */
+ /* call to FT_Raster_Render(). It is thus theorically possible to */
+ /* share it between several non-concurrent components of your */
+ /* applications when memory is a scarce resource. */
+ /* */
+ /* <Input> */
+ /* pool_size :: The render pool's size in bytes. This must be at */
+ /* least 4 kByte. */
+ /* */
+ /* <InOut> */
+ /* raster :: A handle to the target raster object. */
+ /* */
+ /* pool_base :: The render pool's base address in memory. */
+ /* */
+ /* <Return> */
+ /* An error condition, used as a FT_Error in the FreeType library. */
+ /* 0 means success. */
+ /* */
+ EXPORT_FUNC
+ int FT_Raster_Init( FT_Raster raster,
+ const char* pool_base,
+ long pool_size )
+ {
+/* static const char default_palette[5] = { 0, 1, 2, 3, 4 }; */
+
+ /* check the object address */
+ if ( !raster )
+ return ErrRaster_Uninitialized_Object;
+
+ /* check the render pool - we won't go under 4 Kb */
+ if ( !pool_base || pool_size < 4096 )
+ return ErrRaster_Invalid_Pool;
+
+ /* save the pool */
+ raster->pool = (PPos)pool_base;
+ raster->pool_size = raster->pool + pool_size / sizeof ( TPos );
+
+#ifdef FT_RASTER_OPTION_ANTI_ALIAS
+ raster->gray_width = ANTI_ALIAS_BUFFER_SIZE/2;
+ /* clear anti-alias intermediate lines */
+ {
+ char* p = raster->gray_lines;
+ char* limit = p + ANTI_ALIAS_BUFFER_SIZE;
+
+ do *p++ = 0; while ( p < limit );
+ }
+#endif
+
+#if 0
+ /* set the default palette: 5 levels = 0, 1, 2, 3, and 4 */
+ FT_Raster_SetPalette( raster, 5, default_palette );
+#endif
+
+ return ErrRaster_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Raster_SetPalette */
+ /* */
+ /* <Description> */
+ /* Sets the pixmap rendering palette. Anti-aliasing modes are */
+ /* implemented/possible, they differ from the number of entries in */
+ /* the palette. */
+ /* */
+ /* <Input> */
+ /* count :: The number of palette entries. Valid values are 2, 5, */
+ /* and 17, which are the number of intermediate gray */
+ /* levels supported. */
+ /* */
+ /* palette :: An array of `count' chars giving the 8-bit palette of */
+ /* intermediate `gray' levels for anti-aliased rendering. */
+ /* */
+ /* In all modes, palette[0] corresponds to the background, */
+ /* while palette[count-1] to the foreground. Hence, a */
+ /* count of 2 corresponds to no anti-aliasing; a count of */
+ /* 5 uses 3 intermediate levels between the background and */
+ /* foreground, while a count of 17 uses 15 of them. */
+ /* */
+ /* <Return> */
+ /* An error code, used as a FT_Error by the FreeType library. */
+ /* */
+ /* <Note> */
+ /* By default, a new object uses mode 5, with a palette of 0, 1, 2, */
+ /* 3, and 4. You don't need to set the palette if you don't need to */
+ /* render pixmaps. */
+ /* */
+ EXPORT_FUNC
+ int FT_Raster_SetPalette( FT_Raster raster,
+ int count,
+ const char* palette )
+ {
+ switch ( count )
+ {
+#ifdef FT_RASTER_OPTION_ANTI_ALIAS
+
+
+ /******************************/
+ /* The case of 17 gray levels */
+ /******************************/
+
+ case 17:
+#ifdef FT_RASTER_ANTI_ALIAS_17
+ {
+ int n;
+
+
+ raster->grays_count = count;
+ for ( n = 0; n < count; n++ )
+ raster->grays[n] = (unsigned char)palette[n];
+ Reset_Palette_17( RAS_VAR );
+ break;
+ }
+#else
+ return ErrRaster_Unimplemented;
+#endif
+
+ /*****************************/
+ /* The case of 5 gray levels */
+ /*****************************/
+
+ case 5:
+#ifdef FT_RASTER_ANTI_ALIAS_5
+ {
+ int n;
+
+
+ raster->grays_count = count;
+ for ( n = 0; n < count; n++ )
+ raster->grays[n] = (unsigned char)palette[n];
+ Reset_Palette_5( RAS_VAR );
+ break;
+ }
+#else
+ return ErrRaster_Unimplemented;
+#endif
+
+
+#endif /* FT_RASTER_OPTION_ANTI_ALIAS */
+ default:
+ return ErrRaster_Bad_Palette_Count;
+ }
+
+ return ErrRaster_Ok;
+ }
+
+ FT_Raster_Interface ft_default_raster =
+ {
+ sizeof( struct FT_RasterRec_ ),
+ ft_glyph_format_outline,
+
+ (FT_Raster_Init_Proc) FT_Raster_Init,
+ (FT_Raster_Set_Mode_Proc) 0,
+ (FT_Raster_Render_Proc) FT_Raster_Render
+ };
+
+
+/* END */
--- /dev/null
+++ b/src/base/ftstream.c
@@ -1,0 +1,436 @@
+#include <ftstream.h>
+#include <ftdebug.h>
+
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_stream
+
+
+ BASE_FUNC
+ void FT_New_Memory_Stream( FT_Library library,
+ void* base,
+ unsigned long size,
+ FT_Stream stream )
+ {
+ stream->memory = library->memory;
+ stream->base = (char*)base;
+ stream->size = size;
+ stream->pos = 0;
+ stream->cursor = 0;
+ stream->read = 0;
+ stream->close = 0;
+ }
+
+
+ BASE_FUNC
+ FT_Error FT_Seek_Stream( FT_Stream stream,
+ FT_ULong pos )
+ {
+ FT_Error error;
+
+ stream->pos = pos;
+
+ if (stream->read)
+ {
+ if (stream->read( stream, pos, 0, 0 ))
+ {
+ error = FT_Err_Invalid_Stream_Operation;
+
+ FT_ERROR(( "FT_Seek_Stream:" ));
+ FT_ERROR(( " invalid i/o, pos = 0x%lx, size = 0x%lx\n",
+ pos, stream->size ));
+ }
+ else
+ error = FT_Err_Ok;
+ }
+ /* note that seeking to the first position after the file is valid */
+ else if (pos > stream->size)
+ {
+ error = FT_Err_Invalid_Stream_Operation;
+
+ FT_ERROR(( "FT_Seek_Stream:" ));
+ FT_ERROR(( " invalid i/o, pos = 0x%lx, size = 0x%lx\n",
+ pos, stream->size ));
+ }
+
+ else
+ error = FT_Err_Ok;
+
+ return error;
+ }
+
+
+ BASE_FUNC
+ FT_Error FT_Skip_Stream( FT_Stream stream,
+ FT_Long distance )
+ {
+ return FT_Seek_Stream( stream, (FT_ULong)(stream->pos + distance) );
+ }
+
+
+
+ BASE_FUNC
+ FT_Long FT_Stream_Pos( FT_Stream stream )
+ {
+ return stream->pos;
+ }
+
+
+ BASE_FUNC
+ FT_Error FT_Read_Stream( FT_Stream stream,
+ void* buffer,
+ FT_ULong count )
+ {
+ return FT_Read_Stream_At( stream, stream->pos, buffer, count );
+ }
+
+
+ BASE_FUNC
+ FT_Error FT_Read_Stream_At( FT_Stream stream,
+ FT_ULong pos,
+ void* buffer,
+ FT_ULong count )
+ {
+ FT_Error error = FT_Err_Ok;
+ FT_ULong read_bytes;
+
+ if (pos >= stream->size)
+ {
+ FT_ERROR(( "FT_Read_Stream_At:" ));
+ FT_ERROR(( " invalid i/o, pos = 0x%lx, size = 0x%lx\n",
+ pos, stream->size ));
+
+ return FT_Err_Invalid_Stream_Operation;
+ }
+
+ if (stream->read)
+ read_bytes = stream->read( stream, pos, buffer, count );
+ else
+ {
+ read_bytes = stream->size - pos;
+ if (read_bytes > count)
+ read_bytes = count;
+
+ MEM_Copy( buffer, stream->base + pos, read_bytes );
+ }
+
+ stream->pos = pos + read_bytes;
+
+ if (read_bytes < count)
+ {
+ FT_ERROR(( "FT_Read_Stream_At:" ));
+ FT_ERROR(( " invalid read, expected %lu bytes, got %lu",
+ count, read_bytes ));
+ error = FT_Err_Invalid_Stream_Operation;
+ }
+
+ return error;
+ }
+
+
+
+ BASE_FUNC
+ FT_Error FT_Access_Frame( FT_Stream stream,
+ FT_ULong count )
+ {
+ FT_Error error = FT_Err_Ok;
+ FT_ULong read_bytes;
+
+ /* check for nested frame access */
+ FT_Assert( stream && stream->cursor == 0 );
+
+ if (stream->read)
+ {
+ /* allocate the frame in memory */
+ FT_Memory memory = stream->memory;
+
+ if ( ALLOC( stream->base, count ) )
+ goto Exit;
+
+ /* read it */
+ read_bytes = stream->read( stream, stream->pos,
+ stream->base, count );
+ if (read_bytes < count)
+ {
+ FT_ERROR(( "FT_Access_Frame:" ));
+ FT_ERROR(( " invalid read, expected %lu bytes, got %lu",
+ count, read_bytes ));
+
+ FREE( stream->base );
+ error = FT_Err_Invalid_Stream_Operation;
+ }
+ stream->cursor = stream->base;
+ stream->limit = stream->cursor + count;
+ stream->pos += read_bytes;
+ }
+ else
+ {
+ /* check current and new position */
+ if (stream->pos >= stream->size || stream->pos + count > stream->size)
+ {
+ FT_ERROR(( "FT_Access_Frame:" ));
+ FT_ERROR(( " invalid i/o, pos = 0x%lx, count = %lu, size = 0x%lx",
+ stream->pos, count, stream->size ));
+
+ error = FT_Err_Invalid_Stream_Operation;
+ goto Exit;
+ }
+
+ /* set cursor */
+ stream->cursor = stream->base + stream->pos;
+ stream->limit = stream->cursor + count;
+ stream->pos += count;
+ }
+ Exit:
+ return error;
+ }
+
+
+ BASE_FUNC
+ void FT_Forget_Frame( FT_Stream stream )
+ {
+ FT_Assert( stream && stream->cursor != 0 );
+
+ if (stream->read)
+ {
+ FT_Memory memory = stream->memory;
+
+ FREE( stream->base );
+ }
+ stream->cursor = 0;
+ stream->limit = 0;
+ }
+
+
+ BASE_FUNC
+ FT_Char FT_Get_Char( FT_Stream stream )
+ {
+ FT_Char result;
+
+ FT_Assert( stream && stream->cursor && stream->cursor );
+
+ result = 0;
+ if (stream->cursor < stream->limit)
+ result = *stream->cursor++;
+
+ return result;
+ }
+
+
+ BASE_FUNC
+ FT_Short FT_Get_Short( FT_Stream stream )
+ {
+ char* p;
+ FT_Short result;
+
+ FT_Assert( stream && stream->cursor );
+
+ result = 0;
+ p = stream->cursor;
+ if (p+1 < stream->limit)
+ result = NEXT_Short(p);
+ stream->cursor = p;
+ return result;
+ }
+
+
+ BASE_FUNC
+ FT_Long FT_Get_Offset( FT_Stream stream )
+ {
+ char* p;
+ FT_Long result;
+
+ FT_Assert( stream && stream->cursor );
+
+ result = 0;
+ p = stream->cursor;
+ if (p+2 < stream->limit)
+ result = NEXT_Offset(p);
+ stream->cursor = p;
+ return result;
+ }
+
+
+ BASE_FUNC
+ FT_Long FT_Get_Long( FT_Stream stream )
+ {
+ char* p;
+ FT_Long result;
+
+ FT_Assert( stream && stream->cursor );
+
+ result = 0;
+ p = stream->cursor;
+ if (p+3 < stream->limit)
+ result = NEXT_Long(p);
+ stream->cursor = p;
+ return result;
+ }
+
+
+ BASE_FUNC
+ FT_Char FT_Read_Char( FT_Stream stream,
+ FT_Error* error )
+ {
+ char result = 0;
+
+ FT_Assert( stream );
+
+ *error = FT_Err_Ok;
+
+ if (stream->read)
+ {
+ if ( stream->read( stream, stream->pos, &result, 1L ) != 1L )
+ goto Fail;
+ }
+ else
+ {
+ if (stream->pos < stream->size)
+ result = stream->base[stream->pos++];
+ else
+ goto Fail;
+ }
+ return result;
+
+ Fail:
+ *error = FT_Err_Invalid_Stream_Operation;
+ FT_ERROR(( "FT_Read_Char:" ));
+ FT_ERROR(( " invalid i/o, pos = 0x%lx, size = 0x%lx",
+ stream->pos, stream->size ));
+ return 0;
+ }
+
+
+ BASE_FUNC
+ FT_Short FT_Read_Short( FT_Stream stream,
+ FT_Error* error )
+ {
+ char reads[2];
+ char* p = 0;
+ FT_Short result = 0;
+
+ FT_Assert( stream );
+
+ *error = FT_Err_Ok;
+
+ if (stream->pos+1 < stream->size)
+ {
+ if (stream->read)
+ {
+ if (stream->read( stream, stream->pos, reads, 2L ) != 2L )
+ goto Fail;
+
+ p = reads;
+ }
+ else
+ {
+ p = stream->base + stream->pos;
+ }
+
+ if (p)
+ {
+ result = NEXT_Short(p);
+ stream->pos += 2;
+ }
+ }
+ else goto Fail;
+
+ return result;
+
+ Fail:
+ *error = FT_Err_Invalid_Stream_Operation;
+ FT_ERROR(( "FT_Read_Short:" ));
+ FT_ERROR(( " invalid i/o, pos = 0x%lx, size = 0x%lx",
+ stream->pos, stream->size ));
+ return 0;
+ }
+
+
+ BASE_FUNC
+ FT_Long FT_Read_Offset( FT_Stream stream,
+ FT_Error* error )
+ {
+ char reads[3];
+ char* p = 0;
+ FT_Long result = 0;
+
+ FT_Assert( stream );
+
+ *error = FT_Err_Ok;
+
+ if (stream->pos+2 < stream->size)
+ {
+ if (stream->read)
+ {
+ if (stream->read( stream, stream->pos, reads, 3L ) != 3L )
+ goto Fail;
+
+ p = reads;
+ }
+ else
+ {
+ p = stream->base + stream->pos;
+ }
+
+ if (p)
+ {
+ result = NEXT_Offset(p);
+ stream->pos += 3;
+ }
+ }
+ else goto Fail;
+
+ return result;
+
+ Fail:
+ *error = FT_Err_Invalid_Stream_Operation;
+ FT_ERROR(( "FT_Read_Offset:" ));
+ FT_ERROR(( " invalid i/o, pos = 0x%lx, size = 0x%lx",
+ stream->pos, stream->size ));
+ return 0;
+ }
+
+
+ BASE_FUNC
+ FT_Long FT_Read_Long( FT_Stream stream,
+ FT_Error* error )
+ {
+ char reads[4];
+ char* p = 0;
+ FT_Long result = 0;
+
+ FT_Assert( stream );
+
+ *error = FT_Err_Ok;
+
+ if (stream->pos+3 < stream->size)
+ {
+ if (stream->read)
+ {
+ if (stream->read( stream, stream->pos, reads, 4L ) != 4L )
+ goto Fail;
+
+ p = reads;
+ }
+ else
+ {
+ p = stream->base + stream->pos;
+ }
+
+ if (p)
+ {
+ result = NEXT_Long(p);
+ stream->pos += 4;
+ }
+ }
+ else goto Fail;
+
+ return result;
+
+ Fail:
+ *error = FT_Err_Invalid_Stream_Operation;
+ FT_ERROR(( "FT_Read_Long:" ));
+ FT_ERROR(( " invalid i/o, pos = 0x%lx, size = 0x%lx",
+ stream->pos, stream->size ));
+ return 0;
+ }
+
--- /dev/null
+++ b/src/base/ftstream.h
@@ -1,0 +1,178 @@
+#ifndef FTSTREAM_H
+#define FTSTREAM_H
+
+#include <ftobjs.h>
+
+
+ /*************************************************************************/
+ /* */
+ /* integer extraction macros - the `buffer' parameter must ALWAYS be of */
+ /* type `char*' or equivalent (1-byte elements). */
+ /* */
+#define NEXT_Char(buffer) ((signed char)*buffer++)
+#define NEXT_Byte(buffer) ((unsigned char)*buffer++)
+
+#define NEXT_Short(buffer) ( buffer += 2, \
+ ( (short)((signed char)buffer[-2] << 8) | \
+ (unsigned char)buffer[-1] ) )
+
+#define NEXT_UShort(buffer) ((unsigned short)NEXT_Short(buffer))
+
+#define NEXT_Offset(buffer) ( buffer += 3, \
+ ( ((long)(signed char)buffer[-3] << 16) | \
+ ((long)(unsigned char)buffer[-2] << 8) | \
+ (long)(unsigned char)buffer[-1] ) )
+
+#define NEXT_UOffset(buffer) ((unsigned long)NEXT_Offset(buffer))
+
+#define NEXT_Long(buffer) ( buffer += 4, \
+ ( ((long)(signed char)buffer[-4] << 24) | \
+ ((long)(unsigned char)buffer[-3] << 16) | \
+ ((long)(unsigned char)buffer[-2] << 8) | \
+ (long)(unsigned char)buffer[-1] ) )
+
+#define NEXT_ULong(buffer) ((unsigned long)NEXT_Long(buffer))
+
+
+ /*************************************************************************/
+ /* */
+ /* Each GET_xxxx() macro uses an implicit `stream' variable. */
+ /* */
+#define FT_GET_MACRO( func, type ) ( (type)func(stream) )
+
+#define GET_Char() FT_GET_MACRO( FT_Get_Char, FT_Char )
+#define GET_Byte() FT_GET_MACRO( FT_Get_Char, FT_Byte )
+#define GET_Short() FT_GET_MACRO( FT_Get_Short, FT_Short )
+#define GET_UShort() FT_GET_MACRO( FT_Get_Short, FT_UShort )
+#define GET_Offset() FT_GET_MACRO( FT_Get_Offset, FT_Long )
+#define GET_UOffset() FT_GET_MACRO( FT_Get_Offset, FT_ULong )
+#define GET_Long() FT_GET_MACRO( FT_Get_Long, FT_Long )
+#define GET_ULong() FT_GET_MACRO( FT_Get_Long, FT_ULong )
+#define GET_Tag4() FT_GET_MACRO( FT_Get_Long, FT_ULong )
+
+
+#define FT_READ_MACRO( func, type, var ) \
+ ( var = (type)func( stream, &error ), \
+ error != FT_Err_Ok )
+
+#define READ_Byte( var ) FT_READ_MACRO( FT_Read_Char, FT_Byte, var )
+#define READ_Char( var ) FT_READ_MACRO( FT_Read_Char, FT_Char, var )
+#define READ_Short( var ) FT_READ_MACRO( FT_Read_Short, FT_Short, var )
+#define READ_UShort( var ) FT_READ_MACRO( FT_Read_Short, FT_UShort, var )
+#define READ_Offset( var ) FT_READ_MACRO( FT_Read_Offset, FT_Long, var )
+#define READ_UOffset( var ) FT_READ_MACRO( FT_Read_Offset, FT_ULong, var )
+#define READ_Long( var ) FT_READ_MACRO( FT_Read_Long, FT_Long, var )
+#define READ_ULong( var ) FT_READ_MACRO( FT_Read_Long, FT_ULong, var )
+
+
+
+ BASE_DEF
+ void FT_New_Memory_Stream( FT_Library library,
+ void* base,
+ unsigned long size,
+ FT_Stream stream );
+
+ BASE_DEF
+ FT_Error FT_Seek_Stream( FT_Stream stream,
+ FT_ULong pos );
+
+ BASE_DEF
+ FT_Error FT_Skip_Stream( FT_Stream stream,
+ FT_Long distance );
+
+ BASE_DEF
+ FT_Long FT_Stream_Pos( FT_Stream stream );
+
+
+ BASE_DEF
+ FT_Error FT_Read_Stream( FT_Stream stream,
+ void* buffer,
+ FT_ULong count );
+
+ BASE_DEF
+ FT_Error FT_Read_Stream_At( FT_Stream stream,
+ FT_ULong pos,
+ void* buffer,
+ FT_ULong count );
+
+ BASE_DEF
+ FT_Error FT_Access_Frame( FT_Stream stream,
+ FT_ULong count );
+
+ BASE_DEF
+ void FT_Forget_Frame( FT_Stream stream );
+
+
+
+ BASE_DEF
+ FT_Char FT_Get_Char( FT_Stream stream );
+
+ BASE_DEF
+ FT_Short FT_Get_Short( FT_Stream stream );
+
+ BASE_DEF
+ FT_Long FT_Get_Offset( FT_Stream stream );
+
+ BASE_DEF
+ FT_Long FT_Get_Long( FT_Stream stream );
+
+
+
+ BASE_DEF
+ FT_Char FT_Read_Char( FT_Stream stream,
+ FT_Error* error );
+
+ BASE_DEF
+ FT_Short FT_Read_Short( FT_Stream stream,
+ FT_Error* error );
+
+ BASE_DEF
+ FT_Long FT_Read_Offset( FT_Stream stream,
+ FT_Error* error );
+
+ BASE_DEF
+ FT_Long FT_Read_Long( FT_Stream stream,
+ FT_Error* error );
+
+
+#define USE_Stream( resource, stream ) \
+ FT_SET_ERROR( FT_Open_Stream( resource, stream ) )
+
+#define DONE_Stream( stream ) \
+ FT_Done_Stream( stream )
+
+
+#define ACCESS_Frame( size ) \
+ FT_SET_ERROR( FT_Access_Frame( stream, size ) )
+
+#define ACCESS_Compressed_Frame( size ) \
+ FT_SET_ERROR( FT_Access_Compressed_Frame( stream, size ) )
+
+
+#define FORGET_Frame() \
+ FT_Forget_Frame( stream )
+
+
+#define FILE_Seek( position ) \
+ FT_SET_ERROR( FT_Seek_Stream( stream, position ) )
+
+#define FILE_Skip( distance ) \
+ FT_SET_ERROR( FT_Skip_Stream( stream, distance ) )
+
+#define FILE_Pos() \
+ FT_Stream_Pos( stream )
+
+#define FILE_Read( buffer, count ) \
+ FT_SET_ERROR( FT_Read_Stream( stream, \
+ (FT_Char*)buffer, \
+ count ) )
+
+#define FILE_Read_At( position, buffer, count ) \
+ FT_SET_ERROR( FT_Read_Stream_At( stream, \
+ position, \
+ (FT_Char*)buffer, \
+ count ) )
+
+
+
+#endif /* FTIO_H */
--- /dev/null
+++ b/src/base/rules.mk
@@ -1,0 +1,136 @@
+#****************************************************************************
+#* *
+#* Base layer Makefile *
+#* *
+#* 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. *
+#* *
+#****************************************************************************
+
+
+#****************************************************************************
+#* *
+#* IMPORTANT NOTE: This Makefile is intended for GNU Make! *
+#* If you provide Makefiles for other make utilities, *
+#* please place them in `freetype/lib/arch/<system>.' *
+#* *
+#* *
+#* This file is to be included by the root FreeType sub-Makefile, usually *
+#* named `freetype/lib/Makefile.lib.' Here is the list of the variables *
+#* that must be defined to use it: *
+#* *
+#* BASE_DIR: The location of the base layer's directory. This is *
+#* usually `freetype/lib/base.' *
+#* *
+#* ARCH_DIR: The location of the architecture-dependent directory. *
+#* This is usually `freetype/lib/arch/<system>.' *
+#* *
+#* OBJ_DIR: The location where the compiled object(s) file will be *
+#* placed. *
+#* *
+#* FT_CFLAGS: A set of flags used for compilation of object files. *
+#* This contains at least the include paths of the `arch' *
+#* and `base' directories + optimization + warnings + *
+#* ANSI compliance. *
+#* *
+#* FT_IFLAGS: The flag used to specify an include path on the compiler *
+#* command line. For example, with GCC, this is `-I', while *
+#* some other compilers use `/i=' or `-J', etc. *
+#* *
+#* FT_OBJ: The suffix of an object file for the platform. Can be *
+#* `o', `obj', `coff', `tco', etc. *
+#* *
+#* FT_CC: The C compiler to use. *
+#* *
+#* *
+#* It sets the following variables, which are used by the parent Makefile *
+#* after the call: *
+#* *
+#* BASE_H: The list of base layer header files on which the rest *
+#* of the library (i.e., drivers) rely. *
+#* *
+#* BASE_OBJ_S: The single-object base layer. *
+#* BASE_OBJ_M: A list of all objects for a multiple-objects build. *
+#* BASE_EXT_OBJ: A list of base layer extensions, i.e., components *
+#* found in `freetype/lib/base' which are not compiled *
+#* within the base layer proper. *
+#* *
+#****************************************************************************
+
+INCLUDES += $(SRC_)base
+
+# Base layer sources
+#
+BASE_SRC := $(BASE_)ftstream.c \
+ $(BASE_)ftcalc.c \
+ $(BASE_)ftobjs.c \
+ $(BASE_)ftextend.c \
+ $(BASE_)ftlist.c
+
+# Base layer headers
+#
+BASE_H := $(BASE_)ftcalc.h \
+ $(BASE_)ftobjs.h \
+ $(BASE_)ftdriver.h \
+ $(BASE_)ftextend.h \
+ $(BASE_)ftlist.h
+
+
+# Base layer `extensions' sources
+#
+# An extension is added to the library file (.a or .lib) as a separate
+# object. It will then be linked to the final executable only if one of
+# its symbols is used by the application.
+#
+BASE_EXT_SRC := $(BASE_)ftbbox.c \
+ $(BASE_)ftraster.c \
+ $(BASE_)ftoutln.c
+
+
+# Base layer extensions headers
+#
+BASE_EXT_H := $(BASE_EXT_SRC:%c=%h)
+
+
+# Base layer object(s)
+#
+# BASE_OBJ_M is used during `multi' builds (each base source file
+# compiles to a single object file).
+#
+# BASE_OBJ_S is used during `single' builds (the whole base layer
+# is compiled as a single object file using ftbase.c).
+#
+BASE_OBJ_M := $(BASE_SRC:$(BASE_)%.c=$(OBJ_)%.$O)
+BASE_OBJ_S := $(OBJ_)ftbase.$O
+
+
+# Default extensions objects
+#
+BASE_EXT_OBJ := $(BASE_EXT_SRC:$(BASE_)%.c=$(OBJ_)%.$O)
+
+
+# Base layer root source file(s)
+#
+BASE_SRC_M := $(BASE_SRC)
+BASE_SRC_S := $(BASE_)ftbase.c
+
+
+# Multiple objects build + extensions
+#
+$(OBJ_)ft%.$O: $(BASE_)ft%.c $(PUBLIC_H) $(BASE_H)
+ $(FT_CC) $T$@ $<
+
+
+# Base layer - single object build
+#
+$(BASE_OBJ_S): $(PUBLIC_H) $(BASE_H) $(BASE_SRC_S) $(BASE_SRC)
+ $(FT_CC) $T$@ $(BASE_SRC_S)
+
+
+# END
--- /dev/null
+++ b/src/oldapi/Makefile
@@ -1,0 +1,29 @@
+#
+# The OldApi component had not been migrated to the new design yet
+# please wait a few days for some updates. This file should be
+# completely ignored during a BUILD !!
+#
+#
+include drivers/shared/sfnt/Makefile
+
+OLDAPI_DIR := $(TOP_DIR)/oldapi
+
+OLDAPI_INCLUDES := $(FT_IFLAG)$(SFNT_DIR) \
+ $(FT_IFLAG)$(OLDAPI_DIR) \
+ $(FT_IFLAG)$(TT_DIR)
+
+OLDAPI_CFLAGS := $(FT_CFLAGS) $(OLDAPI_INCLUDES)
+
+OLDAPI_OBJ := $(OBJ_DIR)/ttapi.$(FT_OBJ)
+
+# FreeType-1.1 compatible interface
+#
+$(OLDAPI_OBJ): $(OLDAPI_DIR)/ttapi.c $(OLDAPI_DIR)/truetype.h \
+ $(BASE_H) $(SFNT_H) $(TT_DRV_H)
+ $(FT_CC) $(OLDAPI_CFLAGS) $< -o $@
+
+# update main driver object lists
+#
+DRV_OBJS_S += $(OLDAPI_OBJ)
+DRV_OBJS_M += $(OLDAPI_OBJ)
+
--- /dev/null
+++ b/src/oldapi/readme.txt
@@ -1,0 +1,18 @@
+This directory is provided in order to compile a stand-alone
+TrueType driver which should be backwards and binary compatible
+with FreeType 1.1
+
+Reason is some important design changes were introduced in FreeType
+lately, in order to support several font formats transparently.
+
+The files are :
+
+"truetype.h" - a replacement for the old "freetype.h" file
+ that was included by client applications and
+ font servers of 1.1
+
+"ttapi.c" - a front-end for the new TrueType driver, that
+ presents exactly the same interface as the one
+ in 1.1
+
+
--- /dev/null
+++ b/src/oldapi/truetype.h
@@ -1,0 +1,1709 @@
+/*******************************************************************
+ *
+ * truetype.h
+ *
+ * Backwards-compatible high-level interface for the TrueType
+ * driver. This file is a replacement for the old "freetype.h"
+ * from 1.0 and 1.1. It can be used to compile applications
+ * and tools using the old API..
+ *
+ * Note that this (old) interface is now deprecated and won't
+ * be modified in the future. Developers will have to switch to
+ * the newer interface to get new features ( kerning, embedded
+ * bitmaps, etc.. ).
+ *
+ *
+ *
+ * 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.
+ *
+ * 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 TRUETYPE_H
+#define TRUETYPE_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
+
+
+/* The following types are also defined in "drivers/ttlib/ttobjs.h" */
+/* We use the _TRUETYPE_ macro to prevent their redefinition when */
+/* _compiling_ the backwards-compatible layer called "ttapi.c" */
+/* */
+#ifndef _TRUETYPE_
+
+ /*******************************************************************/
+ /* */
+ /* FreeType types definitions. */
+ /* */
+ /* All these begin with a 'TT_' prefix. */
+ /* */
+ /*******************************************************************/
+
+ typedef unsigned short 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 signed long TT_Long;
+ typedef unsigned long TT_ULong;
+ typedef int TT_Int;
+
+ 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 when */
+ /* 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 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;
+
+
+
+#endif /* _TRUETYPE_ */
+
+
+
+
+ /* 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 When 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 When 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's 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 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" width is the advance width for horizontal layout, */
+ /* and advance height for vertical layouts. */
+ /* */
+ /* Finally, the library (ver. 1.1) doesn't support vertical text yet */
+ /* but these changes were introduced to accomodate it, as it will */
+ /* most certainly be introduced in later releases. */
+
+ 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) */
+ };
+
+
+ /* 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 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_Glyph_Metrics_ TT_Glyph_Metrics;
+ 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 an WxH bitmap: */
+ /* */
+ /* rows = H */
+ /* cols = (W+7)/8 */
+ /* width = W */
+ /* flow = your_choice */
+ /* */
+ /* - for an 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 following tables are also defined in "drivers/ttlib/ttobjs.h" */
+/* We use the _TRUETYPE_ macro to prevent their redefinition when */
+/* _compiling_ the backwards-compatible layer called "oldapi.c" */
+/* */
+#ifndef _TRUETYPE_
+
+ /* ------- 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 caret_Offset; /* only used in vertical header */
+ TT_Short Reserved[4];
+
+ 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;
+ };
+
+
+ /*******************************************************/
+ /* 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 Reserved[4];
+
+ 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_Horizontal_Header_ TT_Horizontal_Header;
+ typedef struct TT_Vertical_Header_ TT_Vertical_Header;
+
+
+ /* ----------- OS/2 Table ----------------------------- */
+
+ 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;
+
+
+ /* ----------- 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;
+
+
+ /* ------------ horizontal device metrics "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;
+
+
+#else
+
+ typedef TT_HoriHeader TT_Horizontal_Header;
+ typedef TT_VertHeader TT_Vertical_Header;
+
+#endif /* _TRUETYPE_ */
+
+
+ /* A structure used to describe face properties. */
+ /* be aware that this is not the same structure as the one define */
+ /* in "freetype/ttlib/ttdriver.h". A suitable conversion is performed */
+ /* in "oldapi/ttapi.c" to build a binary driver that is backwards */
+ /* compatible with FreeType 1.1, in the function TT_Get_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;
+ TT_Vertical_Header* vertical; /* TT Vertical header, if present */
+ };
+
+ typedef struct TT_Face_Properties_ TT_Face_Properties;
+
+
+
+ /***********************************************************************/
+ /* */
+ /* <Type> TT_Engine */
+ /* */
+ /* <Description> */
+ /* A handle to a TrueType driver/engine instance. Engine objects */
+ /* can be created with the TT_New_Engine and TT_Build_Engine APIs */
+ /* */
+ /* TT_Done_Engine will destroy an engine, as well as all the */
+ /* objects that were created within it. */
+ /* */
+
+ typedef struct TT_EngineRec_ *TT_Engine;
+
+ /* Note : The type TT_Engine is not defined in "drivers/ttlib/ttobjs.h" */
+
+
+
+
+/* The TT_Face type is already defined in "drivers/ttlib/ttobjs.h" */
+/* We use the _TRUETYPE_ macro to prevent their redefinition when */
+/* _compiling_ the backwards-compatible layer called "oldapi.c" */
+/* */
+#ifndef _TRUETYPE_
+
+ /***********************************************************************/
+ /* */
+ /* <Type> TT_Face */
+ /* */
+ /* <Description> */
+ /* A handle to a TrueType face/font object. A TT_Face encapsulates */
+ /* the resolution and scaling independent parts of a TrueType font */
+ /* file. Instances (a.k.a. fontsizes) and glyph objects must be */
+ /* created from them before a glyph can be loaded in memory. */
+ /* */
+ /* They are created through TT_New_Face and destroyed with */
+ /* TT_Done_Face. This will destroy all instance and glyph objects */
+ /* */
+
+ typedef struct TT_FaceRec_* TT_Face;
+
+#endif /* _TRUETYPE_ */
+
+
+ /***********************************************************************/
+ /* */
+ /* <Type> TT_Instance */
+ /* */
+ /* <Description> */
+ /* A handle to a TrueType instance/fontsize object. A TT_Instance */
+ /* encapsulates all the resolution and scaling dependent part of */
+ /* a given font size, but doesn't contain any glyph. They must be */
+ /* used with glyph objects in order to load glyph objects from */
+ /* a TT file. */
+ /* */
+ /* They are created from face objects with TT_New_Instance, and */
+ /* destroyed with TT_Done_Instance */
+ /* */
+ /* A fresh new instance has a default resolution of 96x96 dpi, */
+ /* and a default point size of 10 pt. Each of these can be changed */
+ /* dynamically with various APIs defined below.. */
+ /* */
+
+ typedef struct TT_InstanceRec_* TT_Instance;
+
+ /* Note: The TT_Instance type is not defined in "drivers/ttlib/ttobjs.h" */
+
+
+ /***********************************************************************/
+ /* */
+ /* <Type> TT_Glyph */
+ /* */
+ /* <Description> */
+ /* A handle to a TrueType glyph object. A glyph object acts as a */
+ /* container for any of the glyphs of a given face object. It */
+ /* encapsulates glyph metrics as well as outline space sized large */
+ /* enough to allow the loading of any glyph without further */
+ /* allocation. A glyph object doesn't contain any bitmap or */
+ /* pixmap data/buffer. */
+ /* */
+ /* They are created from face objects with TT_New_Glyph, and */
+ /* destroyed with TT_Done_Glyph */
+ /* */
+ /* One can create several glyph objects per face, and use */
+ /* a single instance to load multiple glyphs, even concurrently */
+ /* in thread-safe and reentrant modes.. */
+ /* */
+
+ typedef struct TT_GlyphRec_* TT_Glyph;
+
+ /* Note: the TT_Glyph type is not defined in "drivers/ttlib/ttobjs.h" */
+
+
+/* The TT_CharMap type is already defined in "drivers/ttlib/ttobjs.h" */
+/* We use the _TRUETYPE_ macro to prevent their redefinition when */
+/* _compiling_ the backwards-compatible layer called "oldapi.c" */
+/* */
+#ifndef _TRUETYPE_
+
+ /***********************************************************************/
+ /* */
+ /* <Type> TT_CharMap */
+ /* */
+ /* <Description> */
+ /* A handle to a TrueType character mapping object. These objects */
+ /* are used to convert character codes in a specific locale or */
+ /* encoding into font/face glyph indexes. */
+ /* */
+ /* The list of character maps found within a face can be */
+ /* enumerated with API functions defined below. An CharMap object */
+ /* is created with TT_New_CharMap. They are destroyed automatically */
+ /* when their parent face objects are discarded. */
+ /* */
+
+ typedef struct TT_CharMapRec_* TT_CharMap;
+
+ typedef long TT_Error;
+
+#endif /* _TRUETYPE_ */
+
+
+
+ EXPORT_DEF
+ const TT_Instance TT_Null_Instance;
+
+
+ /*******************************************************************/
+ /* */
+ /* Postscript Names extension */
+ /* */
+ /*******************************************************************/
+
+#define TT_Err_Invalid_Post_Table_Format 0x0B00
+#define TT_Err_Invalid_Post_Table 0x0B01
+
+ /* Initialise the Postscript Names extension */
+ EXPORT_DEF
+ TT_Error TT_Init_Post_Extension( TT_Engine engine );
+
+ /* Load the Postscript Names table - notice that the 'post' parameter */
+ /* will be ignored in 2.0. */
+ EXPORT_DEF
+ TT_Error TT_Load_PS_Names( TT_Face face,
+ void* post );
+
+ /* Gets the postscript name of a single glyph */
+ EXPORT_DEF
+ TT_Error TT_Get_PS_Name( TT_Face face,
+ TT_UShort index,
+ TT_String** PSname );
+
+
+ /*******************************************************************/
+ /* */
+ /* Embedded Bitmaps (sbits) extension */
+ /* */
+ /*******************************************************************/
+
+#ifndef _TRUETYPE_
+ /*************************************************************/
+ /* */
+ /* <Struct> TT_SBit_Metrics */
+ /* */
+ /* <Description> */
+ /* A structure used to hold the big metrics of a given */
+ /* glyph bitmap in a TrueType or OpenType font. These */
+ /* are usually found in the "EBDT" table. */
+ /* */
+ /* <Fields> */
+ /* 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;
+
+
+
+ /*************************************************************/
+ /* */
+ /* <Struct> TT_SBit_Small_Metrics */
+ /* */
+ /* <Description> */
+ /* A structure used to hold the small metrics of a given */
+ /* glyph bitmap in a TrueType or OpenType font. These */
+ /* are usually found in the "EBDT" table. */
+ /* */
+ /* <Fields> */
+ /* 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;
+
+
+ /*************************************************************/
+ /* */
+ /* <Struct> TT_SBit_Line_Metrics */
+ /* */
+ /* <Description> */
+ /* A structure used to describe the text line metrics of */
+ /* a given bitmap strike, for either an horizontal or */
+ /* vertical layout. */
+ /* */
+ /* <Fields> */
+ /* ascender :: ascender in pixels */
+ /* descender :: descender in pixels */
+ /* max_width :: maximum glyph width in pixels */
+ /* */
+ /* caret_slope_enumerator :: ? */
+ /* caret_slope_denominator :: ? */
+ /* caret_offset :: ? */
+ /* */
+ /* min_origin_SB :: ? */
+ /* min_advance_SB :: ? */
+ /* max_before_BL :: ? */
+ /* min_after_BL :: ? */
+ /* */
+ 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;
+
+
+
+ /*************************************************************/
+ /* */
+ /* <Struct> TT_SBit_Range */
+ /* */
+ /* <Description> */
+ /* A TrueType/OpenType subIndexTable as defined in the */
+ /* "EBLC" or "bloc" tables. */
+ /* */
+ /* <Fields> */
+ /* */
+ /* 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;
+
+
+ /*************************************************************/
+ /* */
+ /* <Struct> TT_SBit_Strike */
+ /* */
+ /* <Description> */
+ /* A structure used describe a given bitmap strike in the */
+ /* "EBLC" or "bloc" tables. */
+ /* */
+ /* <Fields> */
+ /* */
+ /* 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;
+
+
+
+
+ /*************************************************************/
+ /* */
+ /* <Struct> TT_SBit_Component */
+ /* */
+ /* <Description> */
+ /* A simple structure to describe a compound sbit element */
+ /* */
+ /* <Fields> */
+ /* 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;
+
+
+
+ /*************************************************************/
+ /* */
+ /* <Struct> TT_SBit_Scale */
+ /* */
+ /* <Description> */
+ /* A structure used describe a given bitmap scaling */
+ /* table, asdefined for the "EBSC" table. */
+ /* */
+ /* <Fields> */
+ /* */
+ /* 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;
+#endif /* _TRUETYPE_ */
+
+
+ /*************************************************************/
+ /* */
+ /* <Struct> TT_SBit_Image */
+ /* */
+ /* <Description> */
+ /* A structure used to describe a given embedded bitmap */
+ /* image. */
+ /* */
+ /* <Fields> */
+ /* 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;
+
+
+
+ /*************************************************************/
+ /* */
+ /* <Struct> TT_EBLC */
+ /* */
+ /* <Description> */
+ /* A structure used to describe the "EBLC" table from */
+ /* a TrueTYpe font. */
+ /* */
+ /* <Fields> */
+ /* */
+ /* 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;
+
+
+ /*************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Init_SBit_Extension */
+ /* */
+ /* <Description> */
+ /* Initialise the embedded bitmaps extension for the */
+ /* FreeType engine. */
+ /* */
+ /* <Input> */
+ /* engine :: handle to current FreeType library instance */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_DEF
+ TT_Error TT_Init_SBit_Extension( TT_Engine engine );
+
+
+ /*************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Get_Face_Bitmaps */
+ /* */
+ /* <Description> */
+ /* Loads the "EBLC" table from a font file, if any. */
+ /* */
+ /* <Input> */
+ /* face :: handle to the source TrueType font/face */
+ /* */
+ /* <Output> */
+ /* eblc_table :: a descriptor for the EBLC table */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* This function returns TT_Err_Table_Missing when 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 );
+
+ /*************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_New_SBit_Image */
+ /* */
+ /* <Description> */
+ /* Allocates a new embedded bitmap container */
+ /* */
+ /* <Output> */
+ /* image :: sbit image */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_DEF
+ TT_Error TT_New_SBit_Image( TT_SBit_Image* *image );
+
+
+ /*************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Done_SBit_Image */
+ /* */
+ /* <Description> */
+ /* Releases an embedded bitmap container */
+ /* */
+ /* <Input> */
+ /* image :: sbit image */
+ /* */
+ EXPORT_DEF
+ void TT_Done_SBit_Image( TT_SBit_Image* image );
+
+
+ /*************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Glyph_Bitmap */
+ /* */
+ /* <Description> */
+ /* Loads a given glyph embedded bitmap */
+ /* */
+ /* <Input> */
+ /* face :: handle to the source TrueType font/face */
+ /* instance :: current size/transform instance */
+ /* glyph_index :: index of source glyph */
+ /* bitmap :: target embedded bitmap descriptor */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* 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 );
+
+
+ /*******************************************************************/
+ /* */
+ /* FreeType API */
+ /* */
+ /* All these begin with a 'TT_' prefix. */
+ /* */
+ /* Most of them are implemented in the 'ttapi.c' source file. */
+ /* */
+ /*******************************************************************/
+
+ /* 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,
+ const 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. */
+
+ 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're 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*64 )
+
+ 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_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. */
+
+ /* When 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. */
+
+ /* When 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 -- note that this function uses */
+ /* a different pixel scale, where 1.0 pixels = 128 XXXX */
+
+ 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. XXXX */
+
+ 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 );
+
+
+ /* Multiply a matrix with another -- computes "b := a*b". */
+
+ EXPORT_DEF
+ void TT_Matrix_Multiply( TT_Matrix* a,
+ TT_Matrix* b );
+
+
+ /* Invert a transformation matrix. */
+
+ EXPORT_DEF
+ TT_Error TT_Matrix_Invert( 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 mappings 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. The string is part of the face object and */
+ /* shouldn't be written to or released. */
+
+ /* Note that if for an invalid platformID a null pointer will */
+ /* be returned. */
+
+ EXPORT_DEF
+ TT_Error TT_Get_Name_String( TT_Face face,
+ TT_UShort nameIndex,
+ TT_String** stringPtr, /* pointer address */
+ TT_UShort* length ); /* string length
+ address */
+
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* TRUETYPE_H */
+
+
+/* END */
--- /dev/null
+++ b/src/oldapi/ttapi.c
@@ -1,0 +1,2267 @@
+/*******************************************************************
+ *
+ * ttapi.c
+ *
+ * High-level interface implementation
+ *
+ * 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.
+ *
+ * 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 :
+ *
+ ******************************************************************/
+
+#include <freetype.h>
+
+#include <ftdebug.h>
+#include <ftstream.h>
+#include <ftcalc.h>
+#include <ftlist.h>
+#include <ftraster.h>
+
+#include <ttdriver.h>
+#include <ttobjs.h>
+#include <ttcmap.h>
+
+#define _TRUETYPE_
+#include <truetype.h> /* backwards compatible interface */
+
+
+
+/* required by the tracing mode */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_ttapi
+
+
+#define RENDER_POOL_SIZE 64000
+
+ static
+ const FT_DriverInterface* tt_interface = &tt_driver_interface;
+
+ static
+ const TT_DriverInterface* tt_extension = &tt_format_interface;
+
+
+ /***********************************************************************/
+ /* */
+ /* <Function> TT_Init_FreeType */
+ /* */
+ /* <Description> */
+ /* Creates a new TrueType driver/engine object. */
+ /* */
+ /* <Output> */
+ /* engine :: handle to the new engine object */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success */
+ /* */
+ /* <MT-Note> */
+ /* No. */
+ /* */
+ /* <Note> */
+ /* This function is provided for stand-alone compiles of the */
+ /* TrueType driver. */
+ /* */
+
+ EXPORT_FUNC
+ TT_Error TT_Init_FreeType( TT_Engine* engine )
+ {
+ FT_Library library;
+ FT_System system;
+ TT_Error error;
+
+ *engine = 0;
+
+ error = FT_New_System( &system );
+ if (error) return error;
+
+ error = FT_New_Library( system, &library );
+ if (!error)
+ /* Now create a new TrueType driver object */
+ error = FT_Add_Driver( library,
+ (FT_DriverInterface*)&tt_driver_interface );
+ if (error)
+ FT_Done_Library(library);
+ else
+ *engine = (TT_Engine)library;
+
+ return error;
+ }
+
+
+ /***********************************************************************/
+ /* */
+ /* <Function> TT_Done_FreeType */
+ /* */
+ /* <Description> */
+ /* Destroys a given TrueType engine object created with */
+ /* TT_Init_FreeType. All associated objects, (i.e. faces, outlines */
+ /* and charmaps) will be destroyed.. */
+ /* */
+ /* <Input> */
+ /* engine :: handle to the engine object */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success */
+ /* */
+ /* <MT-Note> */
+ /* No. */
+ /* */
+ /* <Note> */
+ /* This function is provided for stand-alone compiles of the */
+ /* TrueType driver. The FreeType library uses the TT_Done_Engine */
+ /* API. */
+ /* */
+
+ EXPORT_FUNC
+ TT_Error TT_Done_FreeType( TT_Engine engine )
+ {
+ FT_Library library = (FT_Library)engine;
+
+ FT_Done_FreeType( library );
+ return FT_Err_Ok;
+ }
+
+
+ /***********************************************************************/
+ /* */
+ /* <Function> TT_Set_Raster_Gray_Palette */
+ /* */
+ /* <Description> */
+ /* Sets the raster's gray 5-levels palette. Entry 0 correspond to */
+ /* the background, Entry 4 to the foreground. Intermediate entries */
+ /* correspond to gray levels.. */
+ /* */
+ /* <Input> */
+ /* engine :: handle to the engine object */
+ /* palette :: an array of 5 bytes used to render 8-bit pixmaps */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success */
+ /* */
+ /* <MT-Note> */
+ /* No. */
+ /* */
+ /* <Note> */
+ /* This function is provided for stand-alone compiles of the */
+ /* TrueType driver. The FreeType library accesses directly the */
+ /* raster object to set the palette. */
+ /* */
+ /* This function ONLY supports 5 levels of grays. */
+ /* */
+
+ EXPORT_FUNC
+ TT_Error TT_Set_Raster_Gray_Palette( TT_Engine engine,
+ const TT_Byte* palette )
+ {
+ FT_Library library;
+
+ if (!engine)
+ return TT_Err_Invalid_Engine;
+
+ library = (FT_Library)engine;
+ return FT_Set_Raster_Palette( library, 5, (unsigned char*)palette );
+ }
+
+
+ /***********************************************************************/
+ /* */
+ /* <Function> TT_Open_Face */
+ /* */
+ /* <Description> */
+ /* Creates a new face object from a given resource. The file can */
+ /* be either a TrueType file (ttf) or a TrueType collection (ttc). */
+ /* In the latter case, only the first face is opened. The number */
+ /* of faces in a collection can be obtained in the face's */
+ /* properties field "num_Faces". Other faces can be opened with */
+ /* TT_Open_Collection (see below). */
+ /* */
+ /* <Input> */
+ /* engine :: the parent engine object where to create the face */
+ /* object. */
+ /* */
+ /* pathname :: pathname for the font file. */
+ /* */
+ /* <Output> */
+ /* face :: a handle to the fresh face object. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success.. */
+ /* */
+ /* <MT-Note> */
+ /* Yes. */
+ /* */
+ /* <Note> */
+ /* This API is provided fro backwards compatibility. Please use */
+ /* the functions TT_New_Face/TT_Done_Face now to create and */
+ /* discard face objects.. */
+ /* */
+
+
+ static
+ TT_Error open_face( FT_Library library,
+ const TT_Text* pathname,
+ TT_Int face_index,
+ TT_Face *aface )
+ {
+ TT_Error error;
+ FT_Resource resource;
+
+ *aface = 0;
+
+ error = FT_New_Resource( library, pathname, &resource );
+ if (error) return error;
+
+#if 0
+ error = FT_Add_Resource( library, resource );
+ if (error) goto Fail_Install;
+#endif
+ error = FT_New_Face( resource, face_index, (FT_Face*)aface );
+
+ /* Destroy glyph slot to comply with the 1.x API */
+ if (!error)
+ FT_Done_GlyphSlot( (*aface)->root.slot );
+
+ if (error)
+ FT_Done_Resource(resource);
+
+ return error;
+ }
+
+
+ EXPORT_DEF
+ TT_Error TT_Open_Face( TT_Engine engine,
+ const TT_Text* pathname,
+ TT_Face* aface )
+ {
+ if (!engine)
+ return TT_Err_Invalid_Driver_Handle;
+
+ return open_face( (FT_Library)engine, pathname, 0, aface );
+ }
+
+
+ /***********************************************************************/
+ /* */
+ /* <Function> TT_Open_Collection */
+ /* */
+ /* <Description> */
+ /* Loads a given face within a collection. */
+ /* */
+ /* <Input> */
+ /* engine :: TrueType engine object where to load the face */
+ /* pathname :: the collection's pathname */
+ /* fontIndex :: index of face within the collection. first is 0 */
+ /* */
+ /* <Output> */
+ /* face :: handle to the new face object. Always set to NULL */
+ /* in case of error */
+ /* <Return> */
+ /* TrueType error code. 0 means success */
+ /* */
+ /* <MT-Note> */
+ /* Yes. */
+ /* */
+ /* <Note> */
+ /* This API is provided for backwards compatibility. Please use */
+ /* the functions TT_New_Collection/TT_Done_Face now to create and */
+ /* discard face/collection objects. */
+ /* */
+
+ EXPORT_DEF
+ TT_Error TT_Open_Collection( TT_Engine engine,
+ const TT_Text* pathname,
+ TT_ULong fontIndex,
+ TT_Face* aface )
+ {
+ if (!engine)
+ return TT_Err_Invalid_Driver_Handle;
+
+ return open_face( (FT_Library)engine, pathname, fontIndex, aface );
+ }
+
+
+ /***********************************************************************/
+ /* */
+ /* <Function> TT_Close_Face */
+ /* */
+ /* <Description> */
+ /* Destroys a given face object opened through either TT_Open_Face */
+ /* of TT_Open_Collection. */
+ /* */
+ /* <Input> */
+ /* face :: handle to the target face object */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success */
+ /* */
+ /* <MT-Note> */
+ /* No. */
+ /* */
+ /* <Note> */
+ /* This API is provided for backwards compatibility. Please use */
+ /* the functions TT_New_Face/TT_Done_Face now to create and */
+ /* discard face/collection objects. */
+ /* */
+
+ EXPORT_DEF
+ TT_Error TT_Close_Face( TT_Face face )
+ {
+ FT_Resource resource;
+
+ if (!face)
+ return TT_Err_Invalid_Face_Handle;
+
+ resource = face->root.resource;
+ FT_Done_Face( (FT_Face)face );
+
+ /* uninstall corresponding resource */
+ FT_Done_Resource( resource );
+
+ return TT_Err_Ok;
+ }
+
+
+ /***********************************************************************/
+ /***********************************************************************/
+ /***********************************************************************/
+ /***********************************************************************/
+ /*********** ***********/
+ /*********** End of backwards compatible APIs.. ***********/
+ /*********** ***********/
+ /***********************************************************************/
+ /***********************************************************************/
+ /***********************************************************************/
+ /***********************************************************************/
+
+
+ /***********************************************************************/
+ /* */
+ /* <Function> TT_Get_Face_Properties */
+ /* */
+ /* <Description> */
+ /* Return a given face's properties to the caller. */
+ /* */
+ /* <Input> */
+ /* face :: handle to the source face object */
+ /* */
+ /* <Output> */
+ /* properties :: target properties structure */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <MT-Note> */
+ /* Yes. */
+ /* */
+
+ EXPORT_FUNC
+ TT_Error TT_Get_Face_Properties( TT_Face face,
+ TT_Face_Properties* props )
+ {
+ props->num_Glyphs = (TT_UShort)face->root.num_glyphs;
+ props->max_Points = (TT_UShort)face->root.max_points;
+ props->max_Contours = (TT_UShort)face->root.max_contours;
+ props->num_CharMaps = (TT_UShort)face->root.num_charmaps;
+ props->num_Faces = face->root.num_faces;
+ props->num_Names = face->num_names;
+ props->header = &face->header;
+ props->horizontal = &face->horizontal;
+
+ /* The driver supports old Mac fonts where there are no OS/2 */
+ /* tables present in the file. However, this is not true of */
+ /* FreeType 1.1. For the sake of backwards compatibility, we */
+ /* always return the address of the face's os2 table, even if */
+ /* it is empty (in which case, the 'props.os2' field is set */
+ /* to NULL.. */
+ /* */
+ /* Note however, that the 'os2->version' field is set to */
+ /* 0xFFFF to indicate a missing table though... */
+ /* */
+
+ props->os2 = &face->os2;
+
+ props->postscript = &face->postscript;
+ props->hdmx = &face->hdmx;
+ props->vertical = ( face->vertical_info ? &face->vertical : 0 );
+
+ return TT_Err_Ok;
+ }
+
+
+ /***********************************************************************/
+ /* */
+ /* <Function> TT_Set_Face_Pointer. */
+ /* */
+ /* <Description> */
+ /* Each face object contains a typeless pointer, which use is left */
+ /* to client applications (or the high-level library). This API is */
+ /* used to set this generic pointer. It is ignored by the driver. */
+ /* */
+ /* <Input> */
+ /* face :: target face object */
+ /* data :: generic pointer's value */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success */
+ /* */
+ /* <MT-Note> */
+ /* No. */
+ /* */
+ /* <Note> */
+ /* The generic pointer is used by the HLib when using the driver */
+ /* within the FreeType library. */
+ /* */
+
+ EXPORT_FUNC
+ TT_Error TT_Set_Face_Pointer( TT_Face face,
+ void* data )
+ {
+ if ( !face )
+ return TT_Err_Invalid_Face_Handle;
+ else
+ face->root.generic.data = data;
+
+ return TT_Err_Ok;
+ }
+
+
+ /***********************************************************************/
+ /* */
+ /* <Function> TT_Get_Face_Pointer */
+ /* */
+ /* <Description> */
+ /* Each face object contains a typeless pointer, which use is left */
+ /* to client applications (or the high-level library). This API is */
+ /* used to retrieve this generic pointer, which is ignored by the */
+ /* driver. */
+ /* */
+ /* <Input> */
+ /* face :: handle to source face object */
+ /* */
+ /* <Return> */
+ /* generic pointer value. NULL if the face handle is invalid.. */
+ /* */
+ /* <MT-Note> */
+ /* No. */
+ /* */
+
+ EXPORT_FUNC
+ void* TT_Get_Face_Pointer( TT_Face face )
+ {
+ return ( face ? face->root.generic.data : NULL );
+ }
+
+ /***********************************************************************/
+ /* */
+ /* <Function> TT_Get_Face_Metrics */
+ /* */
+ /* <Description> */
+ /* Get the metrics of a given array of glyphs. Returns any number */
+ /* of metrics arrays. */
+ /* */
+ /* <Input> */
+ /* face :: handle to the source face object */
+ /* firstGlyph :: index of first glyph in the array */
+ /* lastGlyph :: index of last glyph in the array */
+ /* */
+ /* <Output> */
+ /* leftBearings :: target array of shorts for the glyph left side */
+ /* bearings. Set this field to NULL if you're not */
+ /* interested in these metrics. */
+ /* */
+ /* widths :: target array of unsigned shorts for the glyph advance */
+ /* widths. Set this field to NULL if you're not */
+ /* interested in these metrics. */
+ /* */
+ /* topBearings :: target array of shorts for the glyph top side */
+ /* bearings. Set this field to NULL if you're not */
+ /* interested in these metrics. */
+ /* */
+ /* heights :: target array of unsigned shorts for the glyph advance */
+ /* heights. Set this field to NULL if you're not */
+ /* interested in these metrics. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <MT-Note> */
+ /* No. */
+ /* */
+
+ /********************************************************/
+ /* 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... */
+
+ static
+ void get_metrics( TT_HoriHeader* header,
+ TT_Int index,
+ TT_Short* bearing,
+ TT_UShort* advance )
+ {
+ TT_LongMetrics* longs_m;
+
+ TT_UShort k = header->number_Of_HMetrics;
+
+
+ if ( index < k )
+ {
+ longs_m = (TT_LongMetrics*)header->long_metrics + index;
+ *bearing = longs_m->bearing;
+ *advance = longs_m->advance;
+ }
+ else
+ {
+ *bearing = ((TT_ShortMetrics*)header->short_metrics)[index - k];
+ *advance = ((TT_LongMetrics*)header->long_metrics)[k - 1].advance;
+ }
+ }
+
+
+
+ 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 )
+ {
+ TT_UShort num;
+
+ if ( !face )
+ return TT_Err_Invalid_Face_Handle;
+
+ /* Check the glyph range */
+ if ( lastGlyph >= face->root.num_glyphs || 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 */
+ {
+ TT_UShort n;
+ TT_Short left_bearing;
+ TT_UShort advance_width;
+
+
+ for ( n = 0; n <= num; n++ )
+ {
+ get_metrics( &face->horizontal,
+ 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->vertical_info )
+ return TT_Err_No_Vertical_Data;
+
+ /* store the top side bearings */
+ {
+ TT_UShort n;
+ TT_Short top_bearing;
+ TT_UShort advance_height;
+
+ for ( n = 0; n <= num; n++ )
+ {
+ get_metrics( (TT_HoriHeader*)&face->vertical,
+ firstGlyph + n, &top_bearing, &advance_height );
+
+ if ( topBearings ) topBearings[n] = top_bearing;
+ if ( heights ) heights[n] = advance_height;
+ }
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ /***********************************************************************/
+ /* */
+ /* <Function> TT_New_Instance */
+ /* */
+ /* <Description> */
+ /* Creates a new instance object from a given face */
+ /* */
+ /* <Input> */
+ /* face :: handle to source/parent face object */
+ /* */
+ /* <Output> */
+ /* instance :: handle to fresh object. Set to NULL in case of */
+ /* error. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success */
+ /* */
+ /* <MT-Note> */
+ /* Yes. */
+ /* */
+ /* <Note> */
+ /* Any new instance uses a default resolution of 96x96 dpi, and */
+ /* a default point size of 10 pts. You can change these anytime */
+ /* with TT_Set_Instance_Resolutions/CharSize/CharSizes/PixelSizes */
+ /* (see below). */
+ /* */
+
+ EXPORT_FUNC
+ TT_Error TT_New_Instance( TT_Face face,
+ TT_Instance* instance )
+ {
+ return FT_New_Size( (FT_Face)face, (FT_Size*)instance );
+ }
+
+
+ /***********************************************************************/
+ /* */
+ /* <Function> TT_Set_Instance_Resolutions */
+ /* */
+ /* <Description> */
+ /* Sets an instance resolutions in dot-per-inches. Default values */
+ /* for "new" instances are 96x96 dpi, but these can be changed any */
+ /* time by calling this API. */
+ /* */
+ /* <Input> */
+ /* instance :: handle to target instance object */
+ /* xResolution :: horizontal device resolution in dpi. */
+ /* yResolution :: vertical device resolution in dpi. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success */
+ /* */
+ /* <MT-Note> */
+ /* You should set the charsize or pixel size immediately after */
+ /* call in multi-htreaded 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 ins,
+ TT_UShort xResolution,
+ TT_UShort yResolution )
+ {
+ return FT_Set_Resolutions( (FT_Size)ins, xResolution, yResolution );
+ }
+
+ /***********************************************************************/
+ /* */
+ /* <Function> TT_Set_Instance_CharSizes */
+ /* */
+ /* <Description> */
+ /* Same as TT_Set_Instance_CharSize, but used to specify distinct */
+ /* horizontal and vertical coordinates. */
+ /* */
+ /* <Input> */
+ /* instance :: handle to target instance object */
+ /* charWidth :: horizontal character size (26.6 points) */
+ /* charHeight :: vertical character size (26.6 points) */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success */
+ /* */
+ /* <MT-Note> */
+ /* No. */
+ /* */
+ /* <Note> */
+ /* There is no check for overflow; with other words, the product */
+ /* of glyph dimensions times the device resolution must have */
+ /* reasonable values. */
+ /* */
+
+ EXPORT_FUNC
+ TT_Error TT_Set_Instance_CharSizes( TT_Instance ins,
+ TT_F26Dot6 charWidth,
+ TT_F26Dot6 charHeight )
+ {
+ return FT_Set_Char_Sizes( (FT_Size)ins, charWidth, charHeight );
+ }
+
+
+ /***********************************************************************/
+ /* */
+ /* <Function> TT_Set_Instance_CharSize */
+ /* */
+ /* <Description> */
+ /* Sets an instance's character size. The size is in fractional */
+ /* (26.6) point units. This function sets the horizontal and */
+ /* vertical sizes to be equal. Use TT_Set_Instance_CharSizes */
+ /* for distinct X and Y char sizes. */
+ /* */
+ /* The default charsize of a new instance object is 10 pts. */
+ /* */
+ /* <Input> */
+ /* instance :: handle to target instance object */
+ /* charSize :: character size expressed in 26.6 fixed float */
+ /* points. 1 point = 1/72 dpi. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success */
+ /* */
+ /* <MT-Note> */
+ /* No. */
+ /* */
+
+ 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> */
+ /* This function is used to set an instance's pixel sizes directly */
+ /* It ignores the instance's resolutions fields, and you'll have to */
+ /* specify the corresponding pointsize in 26.6 fixed float point */
+ /* units. The latter is a requirement of the TrueType bytecode */
+ /* interpreter but can be ignored (or more safely, set to the */
+ /* maximum pixel size multiplied by 64). */
+ /* */
+ /* <Input> */
+ /* instance :: handle to target instance object */
+ /* pixelWidth :: horizontal pixel width (integer value) */
+ /* pixelHeight :: vertical pixel height (integer value) */
+ /* pointSize :: corresponding point size (26.6 points) */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <MT-Note> */
+ /* No. */
+ /* */
+
+ EXPORT_FUNC
+ TT_Error TT_Set_Instance_PixelSizes( TT_Instance ins,
+ TT_UShort pixelWidth,
+ TT_UShort pixelHeight,
+ TT_F26Dot6 pointSize )
+ {
+ /* The point size is now ignored by the driver */
+ (void)pointSize;
+
+ return FT_Set_Pixel_Sizes( (FT_Size)ins, pixelWidth, pixelHeight );
+ }
+
+ /***********************************************************************/
+ /* */
+ /* <Function> TT_Get_Instance_Metrics */
+ /* */
+ /* <Description> */
+ /* Returns an instance's metrics into caller space. */
+ /* */
+ /* <Input> */
+ /* instance :: handle to source instance object */
+ /* */
+ /* <Output> */
+ /* metrics :: target instance metrics structure */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success */
+ /* */
+ /* <MT-Note> */
+ /* No. */
+ /* */
+ /* <Note> */
+ /* The TT_Instance_Metrics structure differs slightly from the */
+ /* FT_Instance_Metrics one, which is why we re-implement this */
+ /* function, rather than call a driver method for this.. */
+ /* */
+
+ EXPORT_FUNC
+ TT_Error TT_Get_Instance_Metrics( TT_Instance ins,
+ TT_Instance_Metrics* metrics )
+ {
+ TT_Size size = (TT_Size)ins;
+
+ if (!ins)
+ return TT_Err_Invalid_Instance_Handle;
+
+ metrics->x_scale = size->root.metrics.x_scale;
+ metrics->y_scale = size->root.metrics.y_scale;
+ metrics->x_resolution = size->root.metrics.x_resolution;
+ metrics->y_resolution = size->root.metrics.y_resolution;
+ metrics->x_ppem = size->root.metrics.x_ppem;
+ metrics->y_ppem = size->root.metrics.y_ppem;
+
+ metrics->pointSize = size->root.metrics.pointSize;
+ return TT_Err_Ok;
+ }
+
+
+ /***********************************************************************/
+ /* */
+ /* <Function> TT_Set_Instance_Pointer */
+ /* */
+ /* <Description> */
+ /* Each instance object contains a typeless pointer, which use is */
+ /* left to client applications (or the high-level library). This */
+ /* API is used to set this generic pointer. It is ignored by the */
+ /* driver. */
+ /* */
+ /* <Input> */
+ /* instance :: handle to the target instance object */
+ /* data :: value of the generic pointer */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success */
+ /* */
+ /* <MT-Note> */
+ /* No. */
+ /* */
+
+ EXPORT_FUNC
+ TT_Error TT_Set_Instance_Pointer( TT_Instance ins,
+ void* data )
+ {
+ if ( !ins )
+ return TT_Err_Invalid_Instance_Handle;
+ else
+ ((FT_Size)ins)->generic.data = data;
+
+ return TT_Err_Ok;
+ }
+
+
+ /***********************************************************************/
+ /* */
+ /* <Function> TT_Get_Instance_Pointer */
+ /* */
+ /* <Description> */
+ /* Each instance object contains a typeless pointer, which use is */
+ /* left to client applications (or the high-level library). This */
+ /* API is used to retrieve this generic pointer. It is ignored by */
+ /* the driver. */
+ /* */
+ /* <Input> */
+ /* instance :: handle to source instance object */
+ /* */
+ /* <Return> */
+ /* value of generic pointer. NULL if invalid instance */
+ /* */
+ /* <MT-Note> */
+ /* No. */
+
+ EXPORT_FUNC
+ void* TT_Get_Instance_Pointer( TT_Instance instance )
+ {
+ if ( !instance )
+ return NULL;
+ else
+ return ((FT_Size)instance)->generic.data;
+ }
+
+
+ /***********************************************************************/
+ /* */
+ /* <Function> TT_Done_Instance */
+ /* */
+ /* <Description> */
+ /* Destroys a given instance object. All instances are destroyed */
+ /* automatically when their parent face object is discarded. */
+ /* However, this API can be used to save memory. */
+ /* */
+ /* <Input> */
+ /* instance :: handle to target instance object */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success */
+ /* */
+ /* <MT-Note> */
+ /* No. */
+
+ EXPORT_FUNC
+ TT_Error TT_Done_Instance( TT_Instance ins )
+ {
+ FT_Done_Size( (FT_Size)ins );
+ return TT_Err_Ok;
+ }
+
+
+ /***********************************************************************/
+ /* */
+ /* <Function> TT_Set_Instance_Transform_Flags */
+ /* */
+ /* <Description> */
+ /* Nothing. This function has been deprecated... */
+ /* */
+ /* <Input> */
+ /* instance :: handle to target instance object */
+ /* rotated :: 'rotation' flag.. */
+ /* stretched :: 'stretch' flag.. */
+ /* */
+ /* <Return> */
+ /* Always 0. */
+ /* */
+ /* <Note> */
+ /* This function has been deprecated !! Do not use it, it doesn't */
+ /* do anything now.. */
+ /* */
+
+ EXPORT_FUNC
+ TT_Error TT_Set_Instance_Transform_Flags( TT_Instance instance,
+ TT_Bool rotated,
+ TT_Bool stretched )
+ {
+ (void)instance; /* the parameters are unused, the (void) prevents */
+ (void)rotated; /* warnings from pedantic compilers.. */
+ (void)stretched;
+
+ return TT_Err_Ok;
+ }
+
+
+
+ /***********************************************************************/
+ /* */
+ /* <Function> */
+ /* */
+ /* <Description> */
+ /* */
+ /* */
+ /* <Input> */
+ /* */
+ /* */
+ /* <Output> */
+ /* */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success */
+ /* */
+ /* */
+ /* <MT-Note> */
+ /* */
+ /* */
+ /* */
+ /* <Note> */
+ /* */
+ /* */
+ /* */
+/*******************************************************************
+ *
+ * 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* aglyph )
+ {
+ return FT_New_GlyphSlot( (FT_Face)face, (FT_GlyphSlot*)aglyph );
+ }
+
+
+/*******************************************************************
+ *
+ * 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 )
+ {
+ FT_Done_GlyphSlot( (FT_GlyphSlot)glyph );
+ return TT_Err_Ok;
+ }
+
+
+/*******************************************************************
+ *
+ * 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 )
+ {
+ TT_Int result, flags;
+
+ flags = 0;
+
+ /* Convert load flags */
+ if ( (loadFlags & TTLOAD_SCALE_GLYPH) == 0 )
+ flags = FT_LOAD_NO_SCALE;
+
+ else if ( (loadFlags & TTLOAD_HINT_GLYPH) == 0 )
+ flags = FT_LOAD_NO_HINTING;
+
+ else
+ flags = FT_LOAD_DEFAULT;
+
+ flags |= FT_LOAD_NO_BITMAP | /* prevent bitmap loading for */
+ FT_LOAD_LINEAR; /* compatibility purposes.. */
+
+ return FT_Load_Glyph( (FT_GlyphSlot)glyph,
+ (FT_Size)instance,
+ glyphIndex,
+ flags,
+ &result );
+ }
+
+
+/*******************************************************************
+ *
+ * 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 )
+ {
+ FT_GlyphSlot slot = (FT_GlyphSlot)glyph;
+
+ if (!glyph)
+ return TT_Err_Invalid_Glyph_Handle;
+
+ /* the structures TT_Outline and FT_Outline are equivalent */
+ *((FT_Outline*)outline) = slot->outline;
+ 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 )
+ {
+ FT_GlyphSlot slot = (FT_GlyphSlot)glyph;
+
+ if (!glyph)
+ return TT_Err_Invalid_Glyph_Handle;
+
+ /* TT_Glyph_Metrics and FT_Glyph_Metrics are slightly different */
+ metrics->bbox.xMin = slot->metrics.horiBearingX;
+
+ metrics->bbox.xMax = slot->metrics.horiBearingX +
+ slot->metrics.width;
+
+ metrics->bbox.yMax = slot->metrics.horiBearingY;
+
+ metrics->bbox.yMin = slot->metrics.horiBearingY -
+ slot->metrics.height;
+
+ metrics->bearingX = slot->metrics.horiBearingX;
+ metrics->bearingY = slot->metrics.horiBearingY;
+ metrics->advance = slot->metrics.horiAdvance;
+
+ return TT_Err_Ok;
+ }
+
+
+/*******************************************************************
+ *
+ * Function : TT_Get_Big_Glyph_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 )
+ {
+ FT_GlyphSlot slot = (FT_GlyphSlot)glyph;
+ FT_Glyph_Metrics* met;
+ FT_Glyph_Metrics* met2;
+
+ if (!glyph)
+ return TT_Err_Invalid_Glyph_Handle;
+
+ met = &slot->metrics;
+ met2 = &slot->metrics2;
+
+ metrics->bbox.xMin = met->horiBearingX;
+ metrics->bbox.xMax = met->horiBearingX + met->width;
+ metrics->bbox.yMin = met->horiBearingY - met->height;
+ metrics->bbox.yMax = met->horiBearingY;
+
+ metrics->horiBearingX = met->horiBearingX;
+ metrics->horiBearingY = met->horiBearingY;
+ metrics->horiAdvance = met->horiAdvance;
+
+ metrics->vertBearingX = met->vertBearingX;
+ metrics->vertBearingY = met->vertBearingY;
+ metrics->vertAdvance = met->vertAdvance;
+
+ metrics->linearHoriAdvance = met2->horiAdvance;
+ metrics->linearHoriBearingX = met2->horiBearingX;
+
+ metrics->linearVertAdvance = met2->vertAdvance;
+ metrics->linearVertBearingY = met2->vertBearingY;
+
+ 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 )
+ {
+ FT_Library library;
+ TT_Error error;
+ FT_GlyphSlot slot = (FT_GlyphSlot)glyph;
+ FT_Outline outline;
+ FT_Raster_Map bitmap;
+
+ if ( !glyph )
+ return TT_Err_Invalid_Glyph_Handle;
+
+ library = slot->face->resource->library;
+ outline = slot->outline;
+
+ /* XXX : For now, use only dropout mode 2 */
+ /* outline.dropout_mode = _glyph->scan_type; */
+ outline.dropout_mode = 2;
+
+ bitmap.width = map->width;
+ bitmap.rows = map->rows;
+ bitmap.cols = map->cols;
+ bitmap.flow = map->flow;
+ bitmap.pix_bits = 1;
+ bitmap.buffer = map->bitmap;
+
+ FT_Translate_Outline( &outline, xOffset, yOffset );
+
+ error = FT_Get_Outline_Bitmap( library, &outline, &bitmap );
+
+ FT_Translate_Outline( &outline, -xOffset, -yOffset );
+
+ return error;
+ }
+
+
+/*******************************************************************
+ *
+ * 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 )
+ {
+ FT_Library library;
+ TT_Error error;
+ FT_GlyphSlot slot = (FT_GlyphSlot)glyph;
+ FT_Outline outline;
+ FT_Raster_Map bitmap;
+
+ if ( !glyph )
+ return TT_Err_Invalid_Glyph_Handle;
+
+ library = slot->face->resource->library;
+ outline = slot->outline;
+
+ /* XXX : For now, use only dropout mode 2 */
+ /* outline.dropout_mode = _glyph->scan_type; */
+ outline.dropout_mode = 2;
+
+ bitmap.width = map->width;
+ bitmap.rows = map->rows;
+ bitmap.cols = map->cols;
+ bitmap.flow = map->flow;
+ bitmap.pix_bits = 8;
+ bitmap.buffer = map->bitmap;
+
+ FT_Translate_Outline( &outline, xOffset, yOffset );
+
+ error = FT_Get_Outline_Bitmap( library, &outline, &bitmap );
+
+ FT_Translate_Outline( &outline, -xOffset, -yOffset );
+
+ return error;
+ }
+
+
+
+ /***********************************************************************/
+ /* */
+ /* <Function> TT_Get_Outline_Bitmap */
+ /* */
+ /* <Description> */
+ /* Renders an outline within a bitmap. The outline's image is */
+ /* simply or-ed to the target bitmap. */
+ /* */
+ /* <Input> */
+ /* engine :: handle to the TrueType driver object */
+ /* outline :: pointer to the source outline descriptor */
+ /* raster :: pointer to the target bitmap descriptor */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <MT-Note> */
+ /* Yes. */
+ /* */
+
+ EXPORT_FUNC
+ TT_Error TT_Get_Outline_Bitmap( TT_Engine engine,
+ TT_Outline* outline,
+ TT_Raster_Map* map )
+ {
+ FT_Library library = (FT_Library)engine;
+ FT_Raster_Map bitmap;
+
+ if ( !engine )
+ return TT_Err_Invalid_Engine;
+
+ if ( !outline || !map )
+ return TT_Err_Invalid_Argument;
+
+ bitmap.width = map->width;
+ bitmap.rows = map->rows;
+ bitmap.cols = map->cols;
+ bitmap.flow = map->flow;
+ bitmap.pix_bits = 1;
+ bitmap.buffer = map->bitmap;
+
+ return FT_Get_Outline_Bitmap( library, (FT_Outline*)outline, &bitmap );
+ }
+
+
+ /***********************************************************************/
+ /* */
+ /* <Function> TT_Get_Outline_Pixmap */
+ /* */
+ /* <Description> */
+ /* Renders an outline within a pixmap. The outline's image is */
+ /* simply or-ed to the target pixmap. */
+ /* */
+ /* <Input> */
+ /* engine :: handle to the TrueType driver object */
+ /* outline :: pointer to the source outline descriptor */
+ /* raster :: pointer to the target pixmap descriptor */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <MT-Note> */
+ /* Yes. */
+ /* */
+
+ EXPORT_FUNC
+ TT_Error TT_Get_Outline_Pixmap( TT_Engine engine,
+ TT_Outline* outline,
+ TT_Raster_Map* map )
+ {
+ FT_Library library = (FT_Library)engine;
+ FT_Raster_Map bitmap;
+
+ if ( !engine )
+ return TT_Err_Invalid_Engine;
+
+ if ( !outline || !map )
+ return TT_Err_Invalid_Argument;
+
+ bitmap.width = map->width;
+ bitmap.rows = map->rows;
+ bitmap.cols = map->cols;
+ bitmap.flow = map->flow;
+ bitmap.pix_bits = 8;
+ bitmap.buffer = map->bitmap;
+
+ return FT_Get_Outline_Bitmap( library, (FT_Outline*)outline, &bitmap );
+ }
+
+
+
+
+ /***********************************************************************/
+ /* */
+ /* <Function> TT_New_Outline */
+ /* */
+ /* <Description> */
+ /* Creates a new outline of a given size. */
+ /* */
+ /* <Input> */
+ /* numPoints :: maximum number of points within the outline */
+ /* */
+ /* numContours :: maximum number of contours within the outline */
+ /* */
+ /* <Output> */
+ /* outline :: target outline descriptor. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success */
+ /* */
+ /* <MT-Note> */
+ /* Yes. */
+ /* */
+ /* <Note> */
+ /* This function uses 'malloc' to allocate the outline's array, */
+ /* _unlike_ all other functions in the TrueType API. This means */
+ /* that the outline won't be destroyed when the TrueType engine */
+ /* is finalized.. */
+ /* */
+ /* It is provided for backwards compatibility ONLY. Use the new */
+ /* FT_New_Outline function defined in "ftoutln.h" instead if you're */
+ /* working with the FreeType 2.0 API. */
+ /* */
+
+#include <stdlib.h> /* for malloc and free */
+
+ static TT_Outline null_api_outline = { 0, 0, NULL, NULL, NULL,
+ 0, 0, 0, 0 };
+
+ EXPORT_FUNC
+ TT_Error TT_New_Outline( TT_UShort numPoints,
+ TT_Short numContours,
+ TT_Outline* outline )
+ {
+ if ( !outline )
+ return TT_Err_Invalid_Argument;
+
+ *outline = null_api_outline;
+
+ if ( numPoints > 0 && numContours > 0 )
+ {
+ outline->points = (TT_Vector*)malloc( numPoints * sizeof(TT_Vector) );
+ outline->flags = (TT_Byte*) malloc( numPoints * sizeof(TT_Char) );
+ outline->contours = (TT_UShort*)malloc( numPoints * sizeof(TT_UShort) );
+
+ if ( !outline->points || !outline->flags || !outline->contours )
+ 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 TT_Err_Out_Of_Memory;
+ }
+
+
+ /***********************************************************************/
+ /* */
+ /* <Function> TT_Done_Outline */
+ /* */
+ /* <Description> */
+ /* Destroys an outline created with FT_New_Outline */
+ /* */
+ /* <Input> */
+ /* outline :: */
+ /* pointer to the outline destructor to discard. This function */
+ /* doesn't destroy the TT_Outline sturcture, only the data it */
+ /* contains/own. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success */
+ /* */
+ /* <MT-Note> */
+ /* No. */
+ /* */
+ /* <Note> */
+ /* This function uses 'free' to discard the outline's arrays. */
+ /* You should only discard outline allocated with TT_New_Outline. */
+ /* */
+ /* It is provided for backwards compatibility ONLY. Use the new */
+ /* FT_Done_Outline function defined in "ftoutln.h" instead if you're*/
+ /* working with the FreeType 2.0 API. */
+ /* */
+
+ 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_api_outline;
+ return TT_Err_Ok;
+ }
+ else
+ return TT_Err_Invalid_Argument;
+ }
+
+
+
+ /***********************************************************************/
+ /* */
+ /* <Function> TT_Copy_Outline */
+ /* */
+ /* <Description> */
+ /* Copy an outline into another one. Both objects must have */
+ /* the same sizes ( num. points & num. contours ) when this */
+ /* function is called.. */
+ /* */
+ /* <Input> */
+ /* source :: handle to source outline */
+ /* target :: handle to target outline */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success */
+ /* */
+
+ EXPORT_FUNC
+ TT_Error TT_Copy_Outline( TT_Outline* source,
+ TT_Outline* target )
+ {
+ return FT_Copy_Outline( (FT_Outline*)source,
+ (FT_Outline*)target );
+ }
+
+
+/*******************************************************************
+ *
+ * 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 )
+ {
+ FT_Transform_Outline( (FT_Outline*)outline, (FT_Matrix*)matrix );
+ }
+
+/*******************************************************************
+ *
+ * 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 )
+ {
+ FT_Transform_Vector( x, y, (FT_Matrix*) matrix );
+ }
+
+
+/*******************************************************************
+ *
+ * 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 )
+ {
+ FT_Translate_Outline( (FT_Outline*)outline, xOffset, yOffset );
+ }
+
+
+/*******************************************************************
+ *
+ * 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 )
+ {
+ return FT_Get_Outline_CBox( (FT_Outline*)outline, (FT_BBox*)bbox );
+ }
+
+ /***********************************************************************/
+ /* */
+ /* <Function> */
+ /* */
+ /* <Description> */
+ /* */
+ /* */
+ /* <Input> */
+ /* */
+ /* */
+ /* <Output> */
+ /* */
+ /* */
+ /* <Return> */
+ /* */
+ /* */
+ /* <MT-Note> */
+ /* */
+ /* */
+ /* */
+ /* <Note> */
+ /* */
+ /* */
+ /* */
+ /* Compute A*B/C with 64 bits intermediate precision. */
+
+ EXPORT_FUNC
+ TT_Long TT_MulDiv( TT_Long A, TT_Long B, TT_Long C )
+ {
+ return FT_MulDiv( A, B, C );
+ }
+
+
+ /***********************************************************************/
+ /* */
+ /* <Function> */
+ /* */
+ /* <Description> */
+ /* */
+ /* */
+ /* <Input> */
+ /* */
+ /* */
+ /* <Output> */
+ /* */
+ /* */
+ /* <Return> */
+ /* */
+ /* */
+ /* <MT-Note> */
+ /* */
+ /* */
+ /* */
+ /* <Note> */
+ /* */
+ /* */
+ /* */
+ /* Compute A*B/0x10000 with 64 bits intermediate precision. */
+ /* Useful to multiply by a 16.16 fixed float value. */
+
+ EXPORT_FUNC
+ TT_Long TT_MulFix( TT_Long A, TT_Long B )
+ {
+ return FT_MulFix( A, B );
+ }
+
+ /* ----------------- 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 )
+ {
+ FT_Face _face = (FT_Face)face;
+
+ return ( _face ? _face->num_charmaps : -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 )
+ {
+ TT_CharMap cmap;
+
+ if ( !face )
+ return TT_Err_Invalid_Face_Handle;
+
+ if ( charmapIndex >= face->num_charmaps )
+ return TT_Err_Bad_Argument;
+
+ cmap = (TT_CharMap)face->charmaps + charmapIndex;
+
+ *platformID = cmap->root.platform_id;
+ *encodingID = cmap->root.encoding_id;
+
+ 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 )
+ {
+ if ( !face )
+ return TT_Err_Invalid_Face_Handle;
+
+ if ( charmapIndex >= face->num_charmaps )
+ return TT_Err_Bad_Argument;
+
+ *charMap = (TT_CharMap)face->charmaps + charmapIndex;
+ return TT_Err_Ok;
+ }
+
+
+/*******************************************************************
+ *
+ * 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 )
+ {
+ return tt_interface->get_char_index( (FT_CharMap)charMap, 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 )
+ {
+ if ( !face )
+ return -1;
+
+ return face->num_names;
+ }
+
+
+/*******************************************************************
+ *
+ * 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 )
+ {
+ TT_NameRec* name;
+
+ if (!face)
+ return TT_Err_Invalid_Face_Handle;
+
+ if ( nameIndex >= face->num_names )
+ return TT_Err_Bad_Argument;
+
+ name = face->name_table.names + nameIndex;
+
+ *platformID = name->platformID;
+ *encodingID = name->encodingID;
+ *languageID = name->languageID;
+ *nameID = name->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 )
+ {
+ TT_NameRec* name;
+
+ if (!face)
+ return TT_Err_Invalid_Face_Handle;
+
+ if ( nameIndex >= face->num_names )
+ return TT_Err_Bad_Argument;
+
+ name = face->name_table.names + nameIndex;
+
+ *stringPtr = (TT_String*)name->string;
+ *length = name->stringLength;
+
+ return TT_Err_Ok;
+ }
+
+
+/*******************************************************************
+ *
+ * Function : TT_Get_Font_Data
+ *
+ * Description : Loads any font table in client memory. Used by
+ * the TT_Get_Font_Data().
+ *
+ * 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 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 )
+ {
+ return tt_extension->get_font_data( face, tag, offset, buffer, length );
+ }
+
+
+
+
+
+
+
+ /*******************************************************************/
+ /* */
+ /* */
+ /* */
+ /* Postscript Names extension */
+ /* */
+ /* */
+ /* */
+ /*******************************************************************/
+
+ /* Initialise the Postscript Names extension */
+ EXPORT_FUNC
+ TT_Error TT_Init_Post_Extension( TT_Engine engine )
+ {
+ (void)engine;
+ return TT_Err_Ok;
+ }
+
+ /* Load the Postscript Names table - notice that the 'post' parameter */
+ /* will be ignored in 2.0. */
+ EXPORT_DEF
+ TT_Error TT_Load_PS_Names( TT_Face face,
+ void* post )
+ {
+ (void)post;
+ (void)face;
+
+ /* the names are now loaded on demand in 2.0 */
+ return TT_Err_Ok;
+ }
+
+
+ /* The following is directly implemented in the TrueType driver */
+#if 0
+ /* Gets the postscript name of a single glyph */
+ EXPORT_DEF
+ TT_Error TT_Get_PS_Name( TT_Face face,
+ TT_UShort index,
+ TT_String** PSname );
+#endif
+
+
+
+
+ /*******************************************************************/
+ /* */
+ /* */
+ /* */
+ /* Embedded Bitmap (sbits) extension */
+ /* */
+ /* */
+ /* */
+ /*******************************************************************/
+
+
+ /*************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Init_SBit_Extension */
+ /* */
+ /* <Description> */
+ /* Initialise the embedded bitmaps extension for the */
+ /* FreeType engine. */
+ /* */
+ /* <Input> */
+ /* engine :: handle to current FreeType library instance */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_FUNC
+ TT_Error TT_Init_SBit_Extension( TT_Engine engine )
+ {
+ (void)engine;
+ return TT_Err_Ok;
+ }
+
+
+ /*************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Get_Face_Bitmaps */
+ /* */
+ /* <Description> */
+ /* Loads the "EBLC" table from a font file, if any. */
+ /* */
+ /* <Input> */
+ /* face :: handle to the source TrueType font/face */
+ /* */
+ /* <Output> */
+ /* eblc_table :: a descriptor for the EBLC table */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* This function returns TT_Err_Table_Missing when 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 )
+ {
+ if (!face)
+ return FT_Err_Invalid_Face_Handle;
+
+ eblc_table->num_strikes = face->num_sbit_strikes;
+ eblc_table->strikes = face->sbit_strikes;
+
+ if ( face->num_sbit_strikes > 0 )
+ {
+ eblc_table->version = 0x00002000;
+ return TT_Err_Ok;
+ }
+
+ eblc_table->version = 0;
+ return TT_Err_Table_Missing;
+ }
+
+
+ /*************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_New_SBit_Image */
+ /* */
+ /* <Description> */
+ /* Allocates a new embedded bitmap container */
+ /* */
+ /* <Output> */
+ /* image :: sbit image */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_DEF
+ TT_Error TT_New_SBit_Image( TT_SBit_Image* *image )
+ {
+ *image = (TT_SBit_Image*)malloc( sizeof(**image) );
+ if ( !*image )
+ return TT_Err_Out_Of_Memory;
+
+ MEM_Set( *image, sizeof(**image), 0 );
+ return TT_Err_Ok;
+ }
+
+
+ /*************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Done_SBit_Image */
+ /* */
+ /* <Description> */
+ /* Releases an embedded bitmap container */
+ /* */
+ /* <Input> */
+ /* image :: sbit image */
+ /* */
+ EXPORT_DEF
+ void TT_Done_SBit_Image( TT_SBit_Image* image )
+ {
+ free( image->map.bitmap );
+ free( image );
+ }
+
+
+ /*************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Glyph_Bitmap */
+ /* */
+ /* <Description> */
+ /* Loads a given glyph embedded bitmap */
+ /* */
+ /* <Input> */
+ /* face :: handle to the source TrueType font/face */
+ /* instance :: current size/transform instance */
+ /* glyph_index :: index of source glyph */
+ /* bitmap :: target embedded bitmap descriptor */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* 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* bitmap )
+ {
+ FT_GlyphSlot slot;
+ TT_Error error;
+
+ error = FT_New_GlyphSlot( (FT_Face)face, &slot );
+ if (error) goto Exit;
+
+ error = FT_Load_Glyph( slot, (FT_Size)instance, glyph_index,
+ FT_LOAD_NO_OUTLINE, 0 );
+ if (!error)
+ {
+ /* copy bitmap */
+ bitmap->map.width = slot->bitmap.width;
+ bitmap->map.rows = slot->bitmap.rows;
+ bitmap->map.cols = slot->bitmap.cols;
+ bitmap->map.flow = slot->bitmap.flow;
+ bitmap->bit_depth = slot->bitmap.pix_bits;
+ bitmap->map.bitmap = slot->bitmap.buffer;
+
+ /* copy metrics */
+ bitmap->metrics.bbox.xMin = slot->metrics.horiBearingX >> 6;
+ bitmap->metrics.bbox.xMax = bitmap->metrics.bbox.xMin +
+ (slot->metrics.width >> 6);
+ bitmap->metrics.bbox.yMax = slot->metrics.horiBearingY >> 6;
+ bitmap->metrics.bbox.yMin = bitmap->metrics.bbox.yMax -
+ (slot->metrics.height >> 6);
+
+ bitmap->metrics.horiBearingX = bitmap->metrics.bbox.xMin;
+ bitmap->metrics.horiBearingY = bitmap->metrics.bbox.yMax;
+ bitmap->metrics.horiAdvance = slot->metrics.horiAdvance >> 6;
+
+ bitmap->metrics.vertBearingX = slot->metrics.vertBearingX >> 6;
+ bitmap->metrics.vertBearingY = slot->metrics.vertBearingY >> 6;
+ bitmap->metrics.vertAdvance = slot->metrics.vertAdvance >> 6;
+
+ slot->bitmap.buffer = 0;
+ }
+
+ FT_Done_GlyphSlot( slot );
+ Exit:
+ return error;
+ }
+
+/* END */
--- /dev/null
+++ b/src/sfnt/rules.mk
@@ -1,0 +1,172 @@
+#****************************************************************************
+#* *
+#* SFNT driver Makefile *
+#* *
+#* 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. *
+#* *
+#****************************************************************************
+
+
+#****************************************************************************
+#* *
+#* IMPORTANT NOTE: This Makefile is intended for GNU Make! *
+#* If you provide Makefiles for other make utilities, *
+#* please place them in `freetype/lib/arch/<system>'. *
+#* *
+#* *
+#* This file is to be included by the FreeType Makefile.lib, located in *
+#* the `freetype/lib' directory. Here is the list of the variables that *
+#* must be defined to use it: *
+#* *
+#* *
+#* BASE_DIR: The location of the base layer's directory. This is *
+#* usually `freetype/lib/base'. *
+#* *
+#* ARCH_DIR: The location of the architecture-dependent directory. *
+#* This is usually `freetype/lib/arch/<system>'. *
+#* *
+#* DRIVERS_DIR: The location of the font driver sub-dirs, usually *
+#* `freetype/lib/drivers'. *
+#* *
+#* OBJ_DIR: The location where the compiled object(s) file will be *
+#* placed. *
+#* *
+#* BASE_H: A list of pathnames to the base layer's header files on *
+#* which the driver depends. *
+#* *
+#* FT_CFLAGS: A set of flags used for compilation of object files. *
+#* This contains at least the include paths of the arch *
+#* and base directories + optimization + warnings + ANSI *
+#* compliance. *
+#* *
+#* FT_IFLAG: The flag used to specify an include path on the *
+#* compiler command line. For example, with GCC, this is *
+#* `-I', while some other compilers use `/i=' or `-J', *
+#* etc. *
+#* *
+#* FT_OBJ: The suffix of an object file for the platform; can be *
+#* `o', `obj', `coff', `tco', etc. depending on the *
+#* platform. *
+#* *
+#* *
+#* It also updates the following variables defined and used in the main *
+#* Makefile: *
+#* *
+#* DRV_OBJ_S: The list of driver object files in *
+#* single-object mode. *
+#* *
+#* DRV_OBJ_M: The list of driver object files in *
+#* multiple-objects mode. *
+#* *
+#* FTINIT_DRIVER_PATHS: The list of include paths used to compile the *
+#* `ftinit' component which registers all font *
+#* drivers in the FT_Init_FreeType() function. *
+#* *
+#* FTINIT_DRIVER_H: The list of header dependencies used to *
+#* compile the `ftinit' component. *
+#* *
+#* FTINIT_DRIVER_MACROS: The list of macros to be defined when *
+#* compiling the `ftinit' component. *
+#* *
+#* `Single-object compilation' means that each font driver is compiled *
+#* into a single object file. This is useful to get rid of all *
+#* driver-specific entries. *
+#* *
+#****************************************************************************
+
+ifndef SFNT_INCLUDE
+SFNT_INCLUDED := 1
+
+include $(SRC_)shared/rules.mk
+
+# SFNT driver directory
+#
+SFNT_DIR := $(SRC_)sfnt
+SFNT_DIR_ := $(SFNT_DIR)$(SEP)
+
+# additional include flags used when compiling the driver
+#
+SFNT_INCLUDE := $(SHARED) $(SFNT_DIR)
+
+
+# compilation flags for the driver
+#
+SFNT_CFLAGS := $(SFNT_INCLUDE:%=$I%)
+SFNT_COMPILE := $(FT_CC) $(SFNT_CFLAGS)
+
+
+# TrueType driver sources (i.e., C files)
+#
+SFNT_DRV_SRC := $(SFNT_DIR_)ttload.c \
+ $(SFNT_DIR_)ttcmap.c \
+ $(SFNT_DIR_)ttsbit.c \
+ $(SFNT_DIR_)ttpost.c \
+ $(SFNT_DIR_)sfdriver.c \
+
+
+# TrueType driver headers
+#
+SFNT_DRV_H := $(SHARED_H) \
+ $(SFNT_DIR_)sfconfig.h \
+ $(SFNT_DIR_)ttload.h \
+ $(SFNT_DIR_)ttsbit.h \
+ $(SFNT_DIR_)ttcmap.h \
+ $(SFNT_DIR_)ttpost.h
+
+
+# driver object(s)
+#
+# SFNT_DRV_OBJ_M is used during `debug' builds
+# SFNT_DRV_OBJ_S is used during `release' builds
+#
+SFNT_DRV_OBJ_M := $(SFNT_DRV_SRC:$(SFNT_DIR_)%.c=$(OBJ_)%.$O)
+SFNT_DRV_OBJ_S := $(OBJ_)sfnt.$O
+
+
+# driver root source file(s)
+#
+SFNT_DRV_SRC_M := $(SFNT_DRV_SRC)
+SFNT_DRV_SRC_S := $(SFNT_DIR_)sfnt.c
+
+
+# driver - single object
+#
+# the driver is recompiled if any of the header or source files is changed
+# as well as any of the shared source files found in `shared/sfnt'
+#
+$(SFNT_DRV_OBJ_S): $(BASE_H) $(SHARED_H) $(SFNT_DRV_H) $(SFNT_DRV_SRC) $(SFNT_DRV_SRC_S)
+ $(SFNT_COMPILE) $T$@ $(SFNT_DRV_SRC_S)
+
+
+
+# driver - multiple objects
+#
+# All objects are recompiled if any of the header files is changed
+#
+$(OBJ_)tt%.$O: $(SFNT_DIR_)tt%.c $(BASE_H) $(SHARED_H) $(SFNT_DRV_H)
+ $(SFNT_COMPILE) $T$@ $<
+
+$(OBJ_)sf%.$O: $(SFNT_DIR_)sf%.c $(BASE_H) $(SHARED_H) $(SFNT_DRV_H)
+ $(SFNT_COMPILE) $T$@ $<
+
+# update main driver object lists
+#
+DRV_OBJS_S += $(SFNT_DRV_OBJ_S)
+DRV_OBJS_M += $(SFNT_DRV_OBJ_M)
+
+
+# update `ftinit' variables
+#
+FTINIT_DRIVER_PATHS += $(SFNT_DIR) $(SHARED)
+FTINIT_DRIVER_H += $(SFNT_DRV_H)
+FTINIT_DRIVER_MACROS += FT_SUPPORT_SFNT
+
+endif
+# END
--- /dev/null
+++ b/src/sfnt/sfconfig.h
@@ -1,0 +1,51 @@
+/***************************************************************************/
+/* */
+/* sfconfig.h */
+/* */
+/* the `sfnt' driver configuration file. */
+/* */
+/* 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 is used to configure various aspects of the TrueType */
+ /* driver. */
+ /* */
+ /*************************************************************************/
+
+
+#ifndef SFCONFIG_H
+#define SFCONFIG_H
+
+
+ /*************************************************************************/
+ /* */
+ /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support */
+ /* embedded bitmaps in the TrueType/OpenType driver. */
+ /* */
+#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+
+
+ /*************************************************************************/
+ /* */
+ /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to */
+ /* load and enumerate the glyph Postscript names in a TrueType or */
+ /* OpenType file. */
+ /* */
+#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES
+
+
+#endif /* SFCONFIG_H */
+
+
+/* END */
--- /dev/null
+++ b/src/sfnt/sfdriver.c
@@ -1,0 +1,72 @@
+#include <sfdriver.h>
+#include <ttload.h>
+#include <ttsbit.h>
+#include <ttpost.h>
+#include <ttcmap.h>
+#include <sfconfig.h>
+#include <sfnt.h>
+
+ static const SFNT_Interface sfnt_interface =
+ {
+ TT_Goto_Table,
+
+ TT_Load_Any,
+ TT_Load_Directory,
+
+ TT_Load_Header,
+ TT_Load_Metrics_Header,
+ TT_Load_CMap,
+ TT_Load_MaxProfile,
+ TT_Load_OS2,
+ TT_Load_PostScript,
+
+ TT_Load_Names,
+ TT_Free_Names,
+
+ TT_Load_Hdmx,
+ TT_Free_Hdmx,
+
+ TT_Load_Kern,
+ TT_Load_Gasp,
+
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+ /* see `ttsbit.h' */
+ TT_Load_SBit_Strikes,
+ TT_Load_SBit_Image,
+ TT_Free_SBit_Strikes,
+#else
+ 0,
+ 0,
+ 0,
+#endif
+
+ /* see `ttpost.h' */
+#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
+ TT_Get_PS_Name,
+ TT_Free_Post_Names,
+#else
+ 0,
+ 0,
+#endif
+
+ /* see `ttcmap.h' */
+ TT_CharMap_Load,
+ TT_CharMap_Free,
+ };
+
+
+ EXPORT_FUNC
+ const FT_DriverInterface sfnt_driver_interface =
+ {
+ sizeof(FT_DriverRec),
+ 0,
+ 0,
+ 0,
+
+ "sfnt", /* driver name */
+ 1, /* driver version */
+ 2, /* driver requires FreeType 2 or above */
+
+ (void*)&sfnt_interface
+ };
+
--- /dev/null
+++ b/src/sfnt/sfdriver.h
@@ -1,0 +1,83 @@
+/***************************************************************************/
+/* */
+/* sfdriver.h */
+/* */
+/* High-level SFNT driver 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. */
+/* */
+/***************************************************************************/
+
+
+#ifndef SFDRIVER_H
+#define SFDRIVER_H
+
+#include <freetype.h>
+#include <ftdriver.h>
+
+ EXPORT_DEF
+ const FT_DriverInterface sfnt_driver_interface;
+
+
+
+/*************************************************************************
+ *
+ * Here is a template of the code that should appear in each
+ * font driver's _interface_ file (the one included by "ftinit.c").
+ *
+ * It is used to build, at compile time, a simple linked list of
+ * the interfaces of the drivers which have been #included in
+ * "ftinit.c". See the source code of the latter file for details
+ *
+ * (Note that this is only required when you want your driver included
+ * in the set of default drivers loaded by FT_Init_FreeType. Other
+ * drivers can still be added manually at runtime with FT_Add_Driver.
+ *
+ * {
+ * #ifdef FTINIT_DRIVER_CHAIN
+ *
+ * static
+ * const FT_DriverChain ftinit_<FORMAT>_driver_chain =
+ * {
+ * FT_INIT_LAST_DRIVER_CHAIN,
+ * &<FORMAT>_driver_interface
+ * };
+ *
+ * #undef FT_INIT_LAST_DRIVER_CHAIN
+ * #define FT_INIT_LAST_DRIVER_CHAIN &ftinit_<FORMAT>_driver_chain
+ *
+ * #endif
+ * }
+ *
+ * replace <FORMAT> with your driver's prefix
+ *
+ *************************************************************************/
+
+
+#ifdef FTINIT_DRIVER_CHAIN
+
+ static
+ const FT_DriverChain ftinit_sfnt_driver_chain =
+ {
+ FT_INIT_LAST_DRIVER_CHAIN,
+ &sfnt_driver_interface
+ };
+
+#undef FT_INIT_LAST_DRIVER_CHAIN
+#define FT_INIT_LAST_DRIVER_CHAIN &ftinit_sfnt_driver_chain
+
+#endif /* FTINIT_DRIVER_CHAIN */
+
+
+
+#endif /* SFDRIVER_H */
+
+
+/* END */
--- /dev/null
+++ b/src/sfnt/sfnt.c
@@ -1,0 +1,15 @@
+#include <sfconfig.h>
+#include <ttload.c>
+#include <ttcmap.c>
+
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+#include <ttsbit.c>
+#endif
+
+#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
+#include <ttpost.c>
+#endif
+
+#include <sfdriver.c>
+
+
--- /dev/null
+++ b/src/sfnt/ttcmap.c
@@ -1,0 +1,508 @@
+/***************************************************************************/
+/* */
+/* ttcmap.c */
+/* */
+/* TrueType character mapping table (cmap) support (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 <ftdebug.h>
+
+#include <ttload.h>
+#include <ttcmap.h>
+#include <tterrors.h>
+
+/* required by the tracing mode */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_ttcmap
+
+
+ static TT_UInt code_to_index0( TT_CMapTable* charmap, TT_ULong char_code );
+ static TT_UInt code_to_index2( TT_CMapTable* charmap, TT_ULong char_code );
+ static TT_UInt code_to_index4( TT_CMapTable* charmap, TT_ULong char_code );
+ static TT_UInt code_to_index6( TT_CMapTable* charmap, TT_ULong char_code );
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_CharMap_Load */
+ /* */
+ /* <Description> */
+ /* Loads a given TrueType character map into memory. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the parent face object. */
+ /* stream :: A handle to the current stream object. */
+ /* */
+ /* <InOut> */
+ /* table :: A pointer to a cmap object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* The function assumes that the stream is already in use (i.e., */
+ /* opened). In case of error, all partially allocated tables are */
+ /* released. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_CharMap_Load( TT_Face face,
+ TT_CMapTable* cmap,
+ FT_Stream stream )
+ {
+ TT_Error error;
+ FT_Memory memory;
+ TT_UShort num_SH, num_Seg, i;
+
+ TT_UShort u, l;
+
+ TT_CMap0* cmap0;
+ TT_CMap2* cmap2;
+ TT_CMap4* cmap4;
+ TT_CMap6* cmap6;
+
+ TT_CMap2SubHeader* cmap2sub;
+ TT_CMap4Segment* segments;
+
+
+ if ( cmap->loaded )
+ return TT_Err_Ok;
+
+ memory = stream->memory;
+
+ if ( FILE_Seek( cmap->offset ) )
+ return error;
+
+ switch ( cmap->format )
+ {
+ case 0:
+ cmap0 = &cmap->c.cmap0;
+
+ if ( ALLOC( cmap0->glyphIdArray, 256L ) ||
+ FILE_Read( (void*)cmap0->glyphIdArray, 256L ) )
+ goto Fail;
+
+ cmap->get_index = code_to_index0;
+ break;
+
+ case 2:
+ num_SH = 0;
+ cmap2 = &cmap->c.cmap2;
+
+ /* allocate subheader keys */
+
+ if ( ALLOC_ARRAY( cmap2->subHeaderKeys, 256, TT_UShort ) ||
+ ACCESS_Frame( 512L ) )
+ goto Fail;
+
+ for ( i = 0; i < 256; i++ )
+ {
+ u = GET_UShort() / 8;
+ cmap2->subHeaderKeys[i] = u;
+
+ if ( num_SH < u )
+ num_SH = u;
+ }
+
+ FORGET_Frame();
+
+ /* load subheaders */
+
+ cmap2->numGlyphId = l =
+ ( ( cmap->length - 2L*(256+3) - num_SH*8L ) & 0xffff ) / 2;
+
+ if ( ALLOC_ARRAY( cmap2->subHeaders,
+ num_SH + 1,
+ TT_CMap2SubHeader ) ||
+ ACCESS_Frame( ( num_SH + 1 ) * 8L ) )
+ goto Fail;
+
+ cmap2sub = cmap2->subHeaders;
+
+ for ( i = 0; i <= num_SH; i++ )
+ {
+ cmap2sub->firstCode = GET_UShort();
+ cmap2sub->entryCount = GET_UShort();
+ cmap2sub->idDelta = GET_Short();
+ /* we apply the location offset immediately */
+ cmap2sub->idRangeOffset = GET_UShort() - ( num_SH - i ) * 8 - 2;
+
+ cmap2sub++;
+ }
+
+ FORGET_Frame();
+
+ /* load glyph IDs */
+
+ if ( ALLOC_ARRAY( cmap2->glyphIdArray, l, TT_UShort ) ||
+ ACCESS_Frame( l * 2L ) )
+ goto Fail;
+
+ for ( i = 0; i < l; i++ )
+ cmap2->glyphIdArray[i] = GET_UShort();
+
+ FORGET_Frame();
+
+ cmap->get_index = code_to_index2;
+ break;
+
+ case 4:
+ cmap4 = &cmap->c.cmap4;
+
+ /* load header */
+
+ if ( ACCESS_Frame( 8L ) )
+ goto Fail;
+
+ cmap4->segCountX2 = GET_UShort();
+ cmap4->searchRange = GET_UShort();
+ cmap4->entrySelector = GET_UShort();
+ cmap4->rangeShift = GET_UShort();
+
+ num_Seg = cmap4->segCountX2 / 2;
+
+ FORGET_Frame();
+
+ /* load segments */
+
+ if ( ALLOC_ARRAY( cmap4->segments,
+ num_Seg,
+ TT_CMap4Segment ) ||
+ ACCESS_Frame( (num_Seg * 4 + 1) * 2L ) )
+ goto Fail;
+
+ segments = cmap4->segments;
+
+ for ( i = 0; i < num_Seg; i++ )
+ segments[i].endCount = GET_UShort();
+
+ (void)GET_UShort();
+
+ for ( i = 0; i < num_Seg; i++ )
+ segments[i].startCount = GET_UShort();
+
+ for ( i = 0; i < num_Seg; i++ )
+ segments[i].idDelta = GET_Short();
+
+ for ( i = 0; i < num_Seg; i++ )
+ segments[i].idRangeOffset = GET_UShort();
+
+ FORGET_Frame();
+
+ cmap4->numGlyphId = l =
+ ( ( cmap->length - ( 16L + 8L * num_Seg ) ) & 0xFFFF ) /2;
+
+ /* load IDs */
+
+ if ( ALLOC_ARRAY( cmap4->glyphIdArray, l, TT_UShort ) ||
+ ACCESS_Frame( l*2L ) )
+ goto Fail;
+
+ for ( i = 0; i < l; i++ )
+ cmap4->glyphIdArray[i] = GET_UShort();
+
+ FORGET_Frame();
+
+ cmap->get_index = code_to_index4;
+ 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,
+ TT_Short ) ||
+ ACCESS_Frame( l * 2L ) )
+ goto Fail;
+
+ for ( i = 0; i < l; i++ )
+ cmap6->glyphIdArray[i] = GET_UShort();
+
+ FORGET_Frame();
+ cmap->get_index = code_to_index6;
+ break;
+
+ default: /* corrupt character mapping table */
+ return TT_Err_Invalid_CharMap_Format;
+
+ }
+ return TT_Err_Ok;
+
+ Fail:
+ TT_CharMap_Free( face, cmap );
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_CharMap_Free */
+ /* */
+ /* <Description> */
+ /* Destroys a character mapping table. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the parent face object. */
+ /* cmap :: A handle to a cmap object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_CharMap_Free( TT_Face face,
+ TT_CMapTable* cmap )
+ {
+ FT_Memory memory;
+
+
+ if ( !cmap )
+ return TT_Err_Ok;
+
+ memory = face->root.driver->memory;
+
+ switch ( cmap->format )
+ {
+ case 0:
+ FREE( cmap->c.cmap0.glyphIdArray );
+ break;
+
+ case 2:
+ FREE( cmap->c.cmap2.subHeaderKeys );
+ FREE( cmap->c.cmap2.subHeaders );
+ FREE( cmap->c.cmap2.glyphIdArray );
+ break;
+
+ case 4:
+ FREE( cmap->c.cmap4.segments );
+ FREE( cmap->c.cmap4.glyphIdArray );
+ cmap->c.cmap4.segCountX2 = 0;
+ break;
+
+ case 6:
+ FREE( cmap->c.cmap6.glyphIdArray );
+ cmap->c.cmap6.entryCount = 0;
+ break;
+
+ default:
+ /* invalid table format, do nothing */
+ ;
+ }
+
+ cmap->loaded = FALSE;
+ return TT_Err_Ok;
+ }
+
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* code_to_index0 */
+ /* */
+ /* <Description> */
+ /* Converts the character code into a glyph index. Uses format 0. */
+ /* `charCode' must be in the range 0x00-0xFF (otherwise 0 is */
+ /* returned). */
+ /* */
+ /* <Input> */
+ /* charCode :: The wanted character code. */
+ /* cmap0 :: A pointer to a cmap table in format 0. */
+ /* */
+ /* <Return> */
+ /* Glyph index into the glyphs array. 0 if the glyph does not */
+ /* exist. */
+ /* */
+ static
+ TT_UInt code_to_index0( TT_CMapTable* cmap,
+ TT_ULong charCode )
+ {
+ TT_CMap0* cmap0 = &cmap->c.cmap0;
+
+ return ( charCode <= 0xFF ? cmap0->glyphIdArray[charCode] : 0 );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* code_to_index2 */
+ /* */
+ /* <Description> */
+ /* Converts the character code into a glyph index. Uses format 2. */
+ /* */
+ /* <Input> */
+ /* charCode :: The wanted character code. */
+ /* cmap2 :: A pointer to a cmap table in format 2. */
+ /* */
+ /* <Return> */
+ /* Glyph index into the glyphs array. 0 if the glyph does not */
+ /* exist. */
+ /* */
+ static
+ TT_UInt code_to_index2( TT_CMapTable* cmap,
+ TT_ULong charCode )
+ {
+ TT_UInt result, index1, offset;
+ TT_UInt char_lo;
+ TT_ULong char_hi;
+ TT_CMap2SubHeader* sh2;
+ TT_CMap2* cmap2;
+
+ cmap2 = &cmap->c.cmap2;
+ result = 0;
+ char_lo = (TT_UInt)(charCode & 0xFF);
+ char_hi = charCode >> 8;
+
+ if ( char_hi == 0 )
+ {
+ /* an 8-bit character code - we use the subHeader 0 in this case */
+ /* to test wether the character code is in the charmap */
+ if ( cmap2->subHeaderKeys[char_lo] == 0 )
+ {
+ result = cmap2->glyphIdArray[char_lo];
+ }
+ }
+ else
+ {
+ /* a 16-bit character code */
+ index1 = cmap2->subHeaderKeys[ char_hi & 0xFF ];
+ if (index1)
+ {
+ sh2 = cmap2->subHeaders + index1;
+ char_lo -= sh2->firstCode;
+
+ if (char_lo < sh2->entryCount)
+ {
+ offset = sh2->idRangeOffset/2 + char_lo;
+ if (offset < cmap2->numGlyphId)
+ {
+ result = cmap2->glyphIdArray[offset];
+ if (result)
+ result = (result + sh2->idDelta) & 0xFFFF;
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* code_to_index4 */
+ /* */
+ /* <Description> */
+ /* Converts the character code into a glyph index. Uses format 4. */
+ /* */
+ /* <Input> */
+ /* charCode :: The wanted character code. */
+ /* cmap4 :: A pointer to a cmap table in format 4. */
+ /* */
+ /* <Return> */
+ /* Glyph index into the glyphs array. 0 if the glyph does not */
+ /* exist. */
+ /* */
+ static
+ TT_UInt code_to_index4( TT_CMapTable* cmap,
+ TT_ULong charCode )
+ {
+ TT_UInt result, index1, segCount;
+ TT_CMap4* cmap4;
+ TT_CMap4Segment *seg4, *limit;
+
+ cmap4 = &cmap->c.cmap4;
+ result = 0;
+ segCount = cmap4->segCountX2 / 2;
+ seg4 = cmap4->segments;
+ limit = seg4 + segCount;
+
+ for ( ; seg4 < limit; seg4++ )
+ {
+ if ( charCode <= seg4->endCount )
+ {
+ /* the ranges are sorted in increasing order, if we're out of */
+ /* the range here, the char code isn't in the charmap, so exit */
+ if ( charCode < seg4->startCount )
+ break;
+
+ /* when the idRangeOffset is 0, we can compute the glyph index */
+ /* directly.. */
+ if ( seg4->idRangeOffset == 0 )
+ result = (charCode + seg4->idDelta) & 0xFFFF;
+ else
+ /* otherwise, we must use the glyphIdArray to do it */
+ {
+ index1 = seg4->idRangeOffset/2 + (charCode - seg4->startCount)
+ - (segCount-1);
+
+ if ( index1 < cmap4->numGlyphId &&
+ cmap4->glyphIdArray[index1] != 0 )
+ {
+ result = (cmap4->glyphIdArray[index1] + seg4->idDelta) & 0xFFFF;
+ }
+ }
+ break;
+ }
+ }
+
+ return result;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* code_to_index6 */
+ /* */
+ /* <Description> */
+ /* Converts the character code into a glyph index. Uses format 6. */
+ /* */
+ /* <Input> */
+ /* charCode :: The wanted character code. */
+ /* cmap6 :: A pointer to a cmap table in format 6. */
+ /* */
+ /* <Return> */
+ /* Glyph index into the glyphs array. 0 if the glyph does not */
+ /* exist. */
+ /* */
+ static
+ TT_UInt code_to_index6( TT_CMapTable* cmap,
+ TT_ULong charCode )
+ {
+ TT_CMap6* cmap6;
+ TT_UInt result = 0;
+
+ cmap6 = &cmap->c.cmap6;
+ result = 0;
+ charCode -= cmap6->firstCode;
+
+ if ( charCode < cmap6->entryCount )
+ result = cmap6->glyphIdArray[charCode];
+
+ return result;
+ }
+
+
+/* END */
--- /dev/null
+++ b/src/sfnt/ttcmap.h
@@ -1,0 +1,84 @@
+/***************************************************************************/
+/* */
+/* ttcmap.h */
+/* */
+/* TrueType character mapping table (cmap) support (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 TTCMAP_H
+#define TTCMAP_H
+
+#include <tttypes.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_CharMap_Load */
+ /* */
+ /* <Description> */
+ /* Loads a given TrueType character map into memory. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the parent face object. */
+ /* stream :: A handle to the current stream object. */
+ /* */
+ /* <InOut> */
+ /* cmap :: A pointer to a cmap object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* The function assumes that the stream is already in use (i.e., */
+ /* opened). In case of error, all partially allocated tables are */
+ /* released. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_CharMap_Load( TT_Face face,
+ TT_CMapTable* cmap,
+ FT_Stream input );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_CharMap_Free */
+ /* */
+ /* <Description> */
+ /* Destroys a character mapping table. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the parent face object. */
+ /* cmap :: A handle to a cmap object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_CharMap_Free( TT_Face face,
+ TT_CMapTable* cmap );
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* TTCMAP_H */
+
+
+/* END */
--- /dev/null
+++ b/src/sfnt/ttload.c
@@ -1,0 +1,1477 @@
+/***************************************************************************/
+/* */
+/* ttload.c */
+/* */
+/* TrueType tables loader (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. */
+/* */
+/* */
+/* WARNING: This file should not be compiled directly; it is meant to be */
+/* included in the source of several font drivers (i.e., the TTF */
+/* and OTF drivers). */
+/* */
+/***************************************************************************/
+
+
+#include <ftdebug.h>
+
+#include <ttload.h>
+#include <tttags.h>
+#include <ttcmap.h>
+#include <tterrors.h>
+
+/* required by the tracing mode */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_ttload
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_LookUp_Table */
+ /* */
+ /* <Description> */
+ /* Looks for a TrueType table by name. */
+ /* */
+ /* <Input> */
+ /* face :: A face object handle. */
+ /* tag :: The searched tag. */
+ /* */
+ /* <Return> */
+ /* pointer to table directory entry. 0 if not found.. */
+ /* */
+ EXPORT_FUNC
+ TT_Table* TT_LookUp_Table( TT_Face face,
+ TT_ULong tag )
+ {
+ TT_Table* entry;
+ TT_Table* limit;
+
+ FT_TRACE4(( "TT_LookUp_Table( %08lx, %c%c%c%c )\n",
+ (TT_Long)face,
+ (TT_Char)(tag >> 24),
+ (TT_Char)(tag >> 16),
+ (TT_Char)(tag >> 8),
+ (TT_Char)(tag) ));
+
+ entry = face->dir_tables;
+ limit = entry + face->num_tables;
+ for ( ; entry < limit; entry++ )
+ {
+ if ( entry->Tag == tag )
+ return entry;
+ }
+ FT_TRACE4(( " Could not find table!\n" ));
+ return 0;
+ }
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Goto_Table */
+ /* */
+ /* <Description> */
+ /* Looks for a TrueType table by name, then seek a stream to it. */
+ /* */
+ /* <Input> */
+ /* face :: a face object handle. */
+ /* tag :: the searched tag. */
+ /* stream :: the stream to seek when the table is found */
+ /* */
+ /* <Return> */
+ /* pointer to table directory entry. 0 if not found.. */
+ /* */
+ EXPORT_FUNC
+ TT_Error TT_Goto_Table( TT_Face face,
+ TT_ULong tag,
+ FT_Stream stream,
+ TT_ULong *length )
+ {
+ TT_Table* table;
+ TT_Error error;
+
+ table = TT_LookUp_Table( face, tag );
+ if (table)
+ {
+ if (length)
+ *length = table->Length;
+
+ (void)FILE_Seek( table->Offset );
+ }
+ else
+ error = TT_Err_Table_Missing;
+
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Directory */
+ /* */
+ /* <Description> */
+ /* Loads the table directory into a face object. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* faceIndex :: The index of the TrueType font, if we're opening a */
+ /* collection. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* The stream cursor must be at the font file's origin */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_Directory( TT_Face face,
+ FT_Stream stream,
+ TT_Long faceIndex )
+ {
+ TT_Error error;
+ FT_Memory memory = stream->memory;
+
+ TT_TableDir tableDir;
+ TT_ULong tag;
+
+ TT_Table *entry, *limit;
+
+
+ FT_TRACE2(( "TT_Load_Directory( %08lx, %ld )\n",
+ (TT_Long)face, faceIndex ));
+
+ face->ttc_header.Tag = 0;
+ face->ttc_header.version = 0;
+ face->ttc_header.DirCount = 0;
+
+ face->num_tables = 0;
+
+ /* first of all, read the first 4 bytes. If it's `ttcf', then the */
+ /* file is a TrueType collection, otherwise it must be a normal */
+ /* TrueType file.. */
+
+ if ( READ_ULong(tag) )
+ goto Exit;
+
+ if ( tag == TTAG_ttcf )
+ {
+ TT_Int n;
+
+ FT_TRACE4(( "TT_Load_Directory: file is a collection\n" ));
+
+ /* it's a TrueType collection, i.e. a file containing several */
+ /* font files. Read the font directory now */
+ /* */
+ if ( ACCESS_Frame( 8 ) ) goto Exit;
+
+ face->ttc_header.version = GET_Long();
+ face->ttc_header.DirCount = GET_Long();
+
+ FORGET_Frame();
+
+ /* now read the offsets of each font in the file */
+ /* */
+ if ( ALLOC_ARRAY( face->ttc_header.TableDirectory,
+ face->ttc_header.DirCount,
+ TT_ULong ) ||
+ ACCESS_Frame( face->ttc_header.DirCount * 4L ) )
+ goto Exit;
+
+ for ( n = 0; n < face->ttc_header.DirCount; n++ )
+ face->ttc_header.TableDirectory[n] = GET_ULong();
+
+ FORGET_Frame();
+
+ /* check face index */
+ if (faceIndex >= face->ttc_header.DirCount)
+ {
+ error = TT_Err_Bad_Argument;
+ goto Exit;
+ }
+
+ /* if we're checking the font format, exit immediately */
+ if (faceIndex < 0)
+ goto Exit;
+
+ /* seek to the appropriate TrueType file, then read tag */
+ if ( FILE_Skip( face->ttc_header.TableDirectory[faceIndex] - 12 ) ||
+ READ_Long( tableDir.version ) )
+ goto Exit;
+ }
+ else
+ {
+ FT_TRACE6(( "TT_Load_Directory: file is not a collection\n" ));
+ /* the file isn't a collection, exit if we're asking for a */
+ /* collected font.. */
+ if (faceIndex > 0)
+ {
+ error = TT_Err_File_Is_Not_Collection;
+ goto Exit;
+ }
+
+ tableDir.version = tag;
+ }
+
+ if ( ACCESS_Frame( 8L ) )
+ goto Exit;
+
+ tableDir.numTables = GET_UShort();
+
+ tableDir.searchRange = GET_UShort();
+ tableDir.entrySelector = GET_UShort();
+ tableDir.rangeShift = GET_UShort();
+
+ FORGET_Frame();
+
+ FT_TRACE2(( "-- Tables count : %12u\n", tableDir.numTables ));
+ FT_TRACE2(( "-- Format version : %08lx\n", tableDir.version ));
+
+ /* Check that we have a `sfnt' format there */
+ /* We must also be able to accept Mac/GX fonts, as well as OT ones */
+
+ if ( tableDir.version != 0x00010000 && /* MS fonts */
+ tableDir.version != TTAG_true && /* Mac fonts */
+ tableDir.version != TTAG_OTTO ) /* OT-Type2 fonts */
+ {
+ FT_TRACE2(( "[not a valid TTF or OTF font]" ));
+ error = TT_Err_Invalid_File_Format;
+ goto Exit;
+ }
+
+ /* if we're performing a font format check, exit immediately */
+ /* with success */
+ if ( faceIndex < 0 )
+ goto Exit;
+
+ face->num_tables = tableDir.numTables;
+
+ if ( ALLOC_ARRAY( face->dir_tables,
+ face->num_tables,
+ TT_Table ) )
+ goto Exit;
+
+ if ( ACCESS_Frame( face->num_tables * 16L ) )
+ goto Exit;
+
+ entry = face->dir_tables;
+ limit = entry + face->num_tables;
+
+ for ( ; entry < limit; entry++ )
+ { /* loop through the tables and get all entries */
+ entry->Tag = GET_Tag4();
+ entry->CheckSum = GET_ULong();
+ entry->Offset = GET_Long();
+ entry->Length = GET_Long();
+
+ FT_TRACE2(( " %c%c%c%c - %08lx - %08lx\n",
+ (TT_Char)(entry->Tag >> 24),
+ (TT_Char)(entry->Tag >> 16),
+ (TT_Char)(entry->Tag >> 8 ),
+ (TT_Char)(entry->Tag),
+ entry->Offset,
+ entry->Length ));
+ }
+
+ FORGET_Frame();
+
+ FT_TRACE2(( "Directory loaded\n\n" ));
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Any */
+ /* */
+ /* <Description> */
+ /* Loads any font table into client memory. Used by the */
+ /* TT_Get_Font_Data() API function. */
+ /* */
+ /* <Input> */
+ /* face :: The face object to look for. */
+ /* */
+ /* tag :: The tag of table to load. Use the value 0 if you want */
+ /* to access the whole font file, else set this parameter */
+ /* to a valid TrueType table tag that you can forge with */
+ /* the MAKE_TT_TAG macro. */
+ /* */
+ /* offset :: The starting offset in the table (or the file if */
+ /* tag == 0). */
+ /* */
+ /* length :: The address of the decision variable: */
+ /* */
+ /* If length == NULL: */
+ /* Loads the whole table. Returns an error if */
+ /* `offset' == 0! */
+ /* */
+ /* If *length == 0: */
+ /* Exits immediately; returning the length of the given */
+ /* table or of the font file, depending on the value of */
+ /* `tag'. */
+ /* */
+ /* If *length != 0: */
+ /* Loads the next `length' bytes of table or font, */
+ /* starting at offset `offset' (in table or font too). */
+ /* */
+ /* <Output> */
+ /* buffer :: The address of target buffer. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_Any( TT_Face face,
+ TT_ULong tag,
+ TT_Long offset,
+ void* buffer,
+ TT_Long* length )
+ {
+ TT_Error error;
+ FT_Stream stream;
+ TT_Table* table;
+ TT_ULong size;
+
+ if ( tag != 0 )
+ {
+ /* look for tag in font directory */
+ table = TT_LookUp_Table( face, tag );
+ if ( !table )
+ {
+ error = TT_Err_Table_Missing;
+ goto Exit;
+ }
+
+ offset += table->Offset;
+ size = table->Length;
+ }
+ else
+ /* tag = 0 -- the use want to access the font file directly */
+ {
+ size = face->root.stream->size;
+ }
+
+ if ( length && *length == 0 )
+ {
+ *length = size;
+ return TT_Err_Ok;
+ }
+
+ if ( length )
+ size = *length;
+
+ stream = face->root.stream;
+ (void)FILE_Read_At( offset, buffer, size );
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Header */
+ /* */
+ /* <Description> */
+ /* Loads the TrueType font header. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_Header( TT_Face face,
+ FT_Stream stream )
+ {
+ TT_Error error;
+ TT_Header* header;
+
+
+ FT_TRACE2(( "Load_TT_Header( %08lx )\n", (TT_Long)face ));
+
+ error = face->goto_table( face, TTAG_head, stream, 0 );
+ if ( error )
+ {
+ FT_TRACE0(( "Font Header is missing!\n" ));
+ goto Exit;
+ }
+
+ if ( ACCESS_Frame( 54L ) )
+ goto Exit;
+
+ header = &face->header;
+
+ 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();
+
+ FT_TRACE2(( " Units per EM : %8u\n", header->Units_Per_EM ));
+ FT_TRACE2(( " IndexToLoc : %8d\n", header->Index_To_Loc_Format ));
+ FT_TRACE2(( "Font Header Loaded.\n" ));
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_MaxProfile */
+ /* */
+ /* <Description> */
+ /* Loads the maximum profile into a face object. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_MaxProfile( TT_Face face,
+ FT_Stream stream )
+ {
+ TT_Error error;
+ TT_MaxProfile* maxProfile = &face->max_profile;
+
+
+ FT_TRACE2(( "Load_TT_MaxProfile( %08lx )\n", (TT_Long)face ));
+
+ error = face->goto_table( face, TTAG_maxp, stream, 0 );
+ if (error) goto Exit;
+
+ if ( ACCESS_Frame( 32L ) )
+ goto Exit;
+
+ /* 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 adjustment that is necessary to load certain */
+ /* broken fonts like `Keystrokes MT' :-( */
+ /* */
+ /* We allocate 64 function entries by default when */
+ /* the maxFunctionDefs field is null. */
+
+ if ( maxProfile->maxFunctionDefs == 0 )
+ maxProfile->maxFunctionDefs = 64;
+
+ face->root.num_glyphs = maxProfile->numGlyphs;
+
+ face->root.max_points = MAX( maxProfile->maxCompositePoints,
+ maxProfile->maxPoints );
+
+ face->root.max_contours = MAX( maxProfile->maxCompositeContours,
+ maxProfile->maxContours );
+
+ face->max_components = (TT_ULong)maxProfile->maxComponentElements +
+ maxProfile->maxComponentDepth;
+
+ /* XXX: some fonts have maxComponents set to 0; we will */
+ /* then use 16 of them by default. */
+ if ( face->max_components == 0 )
+ face->max_components = 16;
+
+ /* We also increase maxPoints and maxContours in order to support */
+ /* some broken fonts. */
+ face->root.max_points += 8;
+ face->root.max_contours += 4;
+
+ FT_TRACE2(( "MAXP loaded.\n" ));
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Metrics */
+ /* */
+ /* <Description> */
+ /* Loads the horizontal or vertical metrics table into a face object. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* vertical :: A boolean flag. If set, load vertical metrics. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ static
+ TT_Error TT_Load_Metrics( TT_Face face,
+ FT_Stream stream,
+ TT_Bool vertical )
+ {
+ TT_Error error;
+ FT_Memory memory = stream->memory;
+
+ TT_ULong table_len;
+ TT_Long num_shorts, num_longs, num_shorts_checked;
+
+ TT_LongMetrics** longs;
+ TT_ShortMetrics** shorts;
+
+ FT_TRACE2(( "TT_Load_%s_Metrics( %08lx )\n",
+ vertical ? "Vertical" : "Horizontal", (TT_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! */
+ /* */
+ error = face->goto_table( face, TTAG_vmtx, stream, &table_len );
+ if ( error )
+ {
+ /* Set the number_Of_VMetrics to 0! */
+ FT_TRACE2(( " no vertical header in file.\n" ));
+ face->vertical.number_Of_VMetrics = 0;
+ error = TT_Err_Ok;
+ goto Exit;
+ }
+
+ num_longs = face->vertical.number_Of_VMetrics;
+ longs = (TT_LongMetrics**)&face->vertical.long_metrics;
+ shorts = (TT_ShortMetrics**)&face->vertical.short_metrics;
+ }
+ else
+ {
+ error = face->goto_table( face, TTAG_hmtx, stream, &table_len );
+ if (error)
+ {
+ FT_ERROR(( " no horizontal metrics in file!\n" ));
+ error = TT_Err_Hmtx_Table_Missing;
+ goto Exit;
+ }
+
+ num_longs = face->horizontal.number_Of_HMetrics;
+ longs = (TT_LongMetrics**)&face->horizontal.long_metrics;
+ shorts = (TT_ShortMetrics**)&face->horizontal.short_metrics;
+ }
+
+ /* never trust derived values */
+
+ num_shorts = face->max_profile.numGlyphs - num_longs;
+ num_shorts_checked = ( table_len - num_longs*4L )/2;
+
+ if ( num_shorts < 0 )
+ {
+ FT_ERROR(( "!! more metrics than glyphs!\n" ));
+ error = ( vertical ? TT_Err_Invalid_Vert_Metrics
+ : TT_Err_Invalid_Horiz_Metrics );
+ goto Exit;
+ }
+
+ if ( ALLOC_ARRAY( *longs, num_longs, TT_LongMetrics ) ||
+ ALLOC_ARRAY( *shorts, num_shorts, TT_ShortMetrics ) )
+ goto Exit;
+
+ if ( ACCESS_Frame( table_len ) )
+ goto Exit;
+
+ {
+ TT_LongMetrics* cur = *longs;
+ TT_LongMetrics* limit = cur + num_longs;
+
+ for ( ; cur < limit; cur++ )
+ {
+ cur->advance = GET_UShort();
+ cur->bearing = GET_Short();
+ }
+ }
+
+ /* do we have an inconsistent number of metric values ? */
+ {
+ TT_ShortMetrics* cur = *shorts;
+ TT_ShortMetrics* limit = cur + MIN( num_shorts, num_shorts_checked );
+
+ for ( ; cur < limit; cur++ )
+ *cur = GET_Short();
+
+ /* we fill up the missing left side bearings with the */
+ /* last valid value. Since this will occur for buggy CJK */
+ /* fonts usually, nothing serious will happen */
+ if ( num_shorts > num_shorts_checked && num_shorts_checked > 0 )
+ {
+ TT_Short val = *(shorts)[num_shorts_checked-1];
+
+ limit = *shorts + num_shorts;
+ for ( ; cur < limit; cur++ )
+ *cur = val;
+ }
+ }
+
+ FORGET_Frame();
+
+ FT_TRACE2(( "loaded\n" ));
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Metrics_Header */
+ /* */
+ /* <Description> */
+ /* Loads the horizontal or vertical header in a face object. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* vertical :: A boolean flag. If set, load vertical metrics. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_Metrics_Header( TT_Face face,
+ FT_Stream stream,
+ TT_Bool vertical )
+ {
+ TT_Error error;
+ TT_HoriHeader* header;
+
+ FT_TRACE2(( vertical ? "Vertical header " : "Horizontal header " ));
+
+ if ( vertical )
+ {
+ face->vertical_info = 0;
+
+ /* The vertical header table is optional, so return quietly if */
+ /* we don't find it. */
+ error = face->goto_table( face, TTAG_vhea, stream, 0 );
+ if (error)
+ {
+ error = TT_Err_Ok;
+ goto Exit;
+ }
+
+ face->vertical_info = 1;
+ header = (TT_HoriHeader*)&face->vertical;
+ }
+ else
+ {
+ /* The horizontal header is mandatory, return an error if we */
+ /* don't find it. */
+ error = face->goto_table( face, TTAG_hhea, stream, 0 );
+ if (error)
+ {
+ error = TT_Err_Horiz_Header_Missing;
+ goto Exit;
+ }
+
+ header = &face->horizontal;
+ }
+
+ if ( ACCESS_Frame( 36L ) )
+ goto Exit;
+
+ 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->Reserved[0] = GET_Short(); /* this is caret_Offset for
+ vertical headers */
+ header->Reserved[1] = GET_Short();
+ header->Reserved[2] = GET_Short();
+ header->Reserved[3] = GET_Short();
+ header->Reserved[4] = GET_Short();
+
+ header->metric_Data_Format = GET_Short();
+ header->number_Of_HMetrics = GET_UShort();
+
+ FORGET_Frame();
+
+ header->long_metrics = NULL;
+ header->short_metrics = NULL;
+
+ FT_TRACE2(( "loaded\n" ));
+
+ /* Now try to load the corresponding metrics */
+
+ error = TT_Load_Metrics( face, stream, vertical );
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Names */
+ /* */
+ /* <Description> */
+ /* Loads the name records. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_Names( TT_Face face, FT_Stream stream )
+ {
+ TT_Error error;
+ FT_Memory memory = stream->memory;
+
+ TT_ULong table_pos, table_len;
+ TT_ULong storageSize;
+
+ TT_NameTable* names;
+
+
+ FT_TRACE2(( "Names " ));
+
+ error = face->goto_table( face, TTAG_name, stream, &table_len );
+ if (error)
+ {
+ /* The name table is required so indicate failure. */
+ FT_TRACE2(( "is missing!\n" ));
+ error = TT_Err_Name_Table_Missing;
+ goto Exit;
+ }
+
+ table_pos = FILE_Pos();
+
+ if ( ACCESS_Frame( 6L ) )
+ goto Exit;
+
+ names = &face->name_table;
+
+ /* 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,
+ TT_NameRec ) ||
+ ACCESS_Frame( names->numNameRecords * 12L ) )
+ goto Exit;
+
+ /* Load the name records and determine how much storage is needed */
+ /* to hold the strings themselves. */
+ {
+ TT_NameRec* cur = names->names;
+ TT_NameRec* limit = cur + names->numNameRecords;
+
+ storageSize = 0;
+
+ for ( ; cur < limit; cur ++ )
+ {
+ TT_ULong upper;
+
+ cur->platformID = GET_UShort();
+ cur->encodingID = GET_UShort();
+ cur->languageID = GET_UShort();
+ cur->nameID = GET_UShort();
+ cur->stringLength = GET_UShort();
+ cur->stringOffset = GET_UShort();
+
+ upper = (TT_ULong)(cur->stringOffset + cur->stringLength);
+ if ( upper > storageSize ) storageSize = upper;
+ }
+ }
+
+ FORGET_Frame();
+
+ if (storageSize > 0)
+ {
+ /* allocate the name storage area in memory, then read it */
+ if ( ALLOC( names->storage, storageSize ) ||
+ FILE_Read_At( table_pos + names->storageOffset,
+ (void*)names->storage, storageSize ) )
+ goto Exit;
+
+ /* Go through and assign the string pointers to the name records. */
+ {
+ TT_NameRec* cur = names->names;
+ TT_NameRec* limit = cur + names->numNameRecords;
+
+ for ( ; cur < limit; cur++ )
+ cur->string = names->storage + cur->stringOffset;
+ }
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+ /* Print Name Record Table in case of debugging */
+ {
+ TT_NameRec* cur = names->names;
+ TT_NameRec* limit = cur + names->numNameRecords;
+
+ for ( ; cur < limit; cur++ )
+ {
+ TT_UInt j;
+
+ FT_TRACE2(( "%d %d %x %d ",
+ cur->platformID,
+ cur->encodingID,
+ cur->languageID,
+ cur->nameID ));
+
+ /* I know that M$ encoded strings are Unicode, */
+ /* but this works reasonable well for debugging purposes. */
+ if ( cur->string )
+ for ( j = 0; j < cur->stringLength; j++ )
+ {
+ TT_Char c = *(cur->string + j);
+
+ if ( (TT_Byte)c < 128 )
+ FT_TRACE2(( "%c", c ));
+ }
+ }
+ }
+ FT_TRACE2(( "\n" ));
+#endif
+ }
+ FT_TRACE2(( "loaded\n" ));
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Free_Names */
+ /* */
+ /* <Description> */
+ /* Frees the name records. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* */
+ LOCAL_FUNC
+ void TT_Free_Names( TT_Face face )
+ {
+ FT_Memory memory = face->root.driver->memory;
+ TT_NameTable* names = &face->name_table;
+
+
+ /* free strings table */
+ FREE( names->names );
+
+ /* free strings storage */
+ FREE( names->storage );
+
+ names->numNameRecords = 0;
+ names->format = 0;
+ names->storageOffset = 0;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_CMap */
+ /* */
+ /* <Description> */
+ /* Loads the cmap directory in a face object. The cmaps itselves are */
+ /* loaded on demand in the `ttcmap.c' module. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: A handle to the input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_CMap( TT_Face face,
+ FT_Stream stream )
+ {
+ TT_Error error;
+ FT_Memory memory = stream->memory;
+ TT_Long off, cur_off, table_start;
+ TT_CMapDir cmap_dir;
+
+ FT_TRACE2(( "CMaps " ));
+
+ error = face->goto_table( face, TTAG_cmap, stream, 0 );
+ if (error)
+ {
+ error = TT_Err_CMap_Table_Missing;
+ goto Exit;
+ }
+
+ table_start = FILE_Pos();
+
+ if ( ACCESS_Frame( 4L ) ) /* 4 bytes cmap header */
+ goto Exit;
+
+ 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->charmaps,
+ cmap_dir.numCMaps,
+ TT_CharMapRec ) )
+ goto Exit;
+
+ face->num_charmaps = cmap_dir.numCMaps;
+ {
+ TT_CharMap charmap = face->charmaps;
+ TT_CharMap limit = charmap + face->num_charmaps;
+
+ for ( ; charmap < limit; charmap++ )
+ {
+ TT_CMapTable* cmap;
+
+ charmap->root.face = (FT_Face)face;
+ cmap = &charmap->cmap;
+
+ if ( FILE_Seek( off ) ||
+ ACCESS_Frame( 8L ) )
+ goto Exit;
+
+ cmap->loaded = FALSE;
+ cmap->platformID = GET_UShort();
+ cmap->platformEncodingID = GET_UShort();
+
+ cur_off = GET_Long();
+
+ FORGET_Frame();
+
+ off = FILE_Pos();
+
+ if ( FILE_Seek( table_start + cur_off ) ||
+ ACCESS_Frame( 6L ) )
+ goto Exit;
+
+ cmap->format = GET_UShort();
+ cmap->length = GET_UShort();
+ cmap->version = GET_UShort();
+
+ FORGET_Frame();
+
+ cmap->offset = FILE_Pos();
+ charmap++;
+ }
+ }
+
+ FT_TRACE2(( "loaded\n" ));
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_OS2 */
+ /* */
+ /* <Description> */
+ /* Loads the OS2 table. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: A handle to the input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_OS2( TT_Face face,
+ FT_Stream stream )
+ {
+ TT_Error error;
+ TT_Int j;
+ TT_OS2* os2;
+
+
+ FT_TRACE2(( "OS/2 Table " ));
+
+ /* We now support old Mac fonts where the OS/2 table doesn't */
+ /* exist. Simply put, we set the `version' field to 0xFFFF */
+ /* and test this value each time we need to access the table. */
+ error = face->goto_table( face, TTAG_OS2, stream, 0 );
+ if (error)
+ {
+ FT_TRACE2(( "is missing\n!" ));
+ face->os2.version = 0xFFFF;
+ error = TT_Err_Ok;
+ goto Exit;
+ }
+
+ if ( ACCESS_Frame( 78L ) )
+ goto Exit;
+
+ 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 ( j = 0; j < 10; j++ )
+ os2->panose[j] = GET_Byte();
+
+ os2->ulUnicodeRange1 = GET_ULong();
+ os2->ulUnicodeRange2 = GET_ULong();
+ os2->ulUnicodeRange3 = GET_ULong();
+ os2->ulUnicodeRange4 = GET_ULong();
+
+ for ( j = 0; j < 4; j++ )
+ os2->achVendID[j] = 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();
+
+ os2->ulCodePageRange1 = 0;
+ os2->ulCodePageRange2 = 0;
+
+ if ( os2->version >= 0x0001 )
+ {
+ /* only version 1 tables */
+
+ if ( ACCESS_Frame( 8L ) ) /* read into frame */
+ goto Exit;
+
+ os2->ulCodePageRange1 = GET_ULong();
+ os2->ulCodePageRange2 = GET_ULong();
+
+ FORGET_Frame();
+ }
+
+ FT_TRACE2(( "loaded\n" ));
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Postscript */
+ /* */
+ /* <Description> */
+ /* Loads the Postscript table. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: A handle to the input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_PostScript( TT_Face face,
+ FT_Stream stream )
+ {
+ TT_Error error;
+ TT_Postscript* post = &face->postscript;
+
+ FT_TRACE2(( "PostScript " ));
+
+ error = face->goto_table( face, TTAG_post, stream, 0 );
+ if (error)
+ return TT_Err_Post_Table_Missing;
+
+ if ( 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 another */
+ /* module (ttpost). */
+ FT_TRACE2(( "loaded\n" ));
+
+ return TT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Gasp */
+ /* */
+ /* <Description> */
+ /* Loads the `GASP' table into a face object. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_Gasp( TT_Face face,
+ FT_Stream stream )
+ {
+ TT_Error error;
+ FT_Memory memory = stream->memory;
+
+ TT_UInt j,num_ranges;
+ TT_GaspRange* gaspranges;
+
+
+ FT_TRACE2(( "TT_Load_Gasp( %08lx )\n", (TT_Long)face ));
+
+ /* the gasp table is optional */
+ error = face->goto_table( face, TTAG_gasp, stream, 0 );
+ if (error) return TT_Err_Ok;
+
+ if ( ACCESS_Frame( 4L ) )
+ goto Exit;
+
+ face->gasp.version = GET_UShort();
+ face->gasp.numRanges = GET_UShort();
+
+ FORGET_Frame();
+
+ num_ranges = face->gasp.numRanges;
+ FT_TRACE3(( "number of ranges = %d\n", num_ranges ));
+
+ if ( ALLOC_ARRAY( gaspranges, num_ranges, TT_GaspRange ) ||
+ ACCESS_Frame( num_ranges * 4L ) )
+ goto Exit;
+
+ face->gasp.gaspRanges = gaspranges;
+
+ for ( j = 0; j < num_ranges; j++ )
+ {
+ gaspranges[j].maxPPEM = GET_UShort();
+ gaspranges[j].gaspFlag = GET_UShort();
+
+ FT_TRACE3(( " [max:%d flag:%d]",
+ gaspranges[j].maxPPEM,
+ gaspranges[j].gaspFlag ));
+ }
+ FT_TRACE3(( "\n" ));
+
+ FORGET_Frame();
+ FT_TRACE2(( "GASP loaded\n" ));
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Kern */
+ /* */
+ /* <Description> */
+ /* Loads the first kerning table with format 0 in the font. Only */
+ /* accepts the first horizontal kerning table. Developers should use */
+ /* the `ftxkern' extension to access other kerning tables in the font */
+ /* file, if they really want to. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_Kern( TT_Face face,
+ FT_Stream stream )
+ {
+ TT_Error error;
+ FT_Memory memory = stream->memory;
+
+ TT_UInt n, num_tables, version;
+
+ /* the kern table is optional. exit silently if it's missing */
+ error = face->goto_table( face, TTAG_kern, stream, 0 );
+ if ( error ) return TT_Err_Ok;
+
+ if ( ACCESS_Frame( 4L ) ) goto Exit;
+
+ version = GET_UShort();
+ num_tables = GET_UShort();
+
+ FORGET_Frame();
+
+ for ( n = 0; n < num_tables; n++ )
+ {
+ TT_UInt coverage;
+ TT_UInt length;
+
+ if ( ACCESS_Frame( 6L ) ) goto Exit;
+
+ version = GET_UShort(); /* version */
+ length = GET_UShort() - 6; /* substract header length */
+ coverage = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( coverage == 0x0001 )
+ {
+ TT_UInt num_pairs;
+ TT_Kern_0_Pair* pair;
+ TT_Kern_0_Pair* limit;
+
+ /* found a horizontal format 0 kerning table ! */
+ if ( ACCESS_Frame(8L) )
+ goto Exit;
+
+ num_pairs = GET_UShort();
+ /* skip the rest */
+
+ FORGET_Frame();
+
+ /* allocate array of kerning pairs */
+ if ( ALLOC_ARRAY( face->kern_pairs, num_pairs, TT_Kern_0_Pair ) ||
+ ACCESS_Frame( 6L * num_pairs ) )
+ goto Exit;
+
+ pair = face->kern_pairs;
+ limit = pair + num_pairs;
+ for ( ; pair < limit; pair++ )
+ {
+ pair->left = GET_UShort();
+ pair->right = GET_UShort();
+ pair->value = GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ face->num_kern_pairs = num_pairs;
+ face->kern_table_index = n;
+ goto Exit;
+ }
+
+ if ( FILE_Skip( length ) )
+ goto Exit;
+ }
+
+ /* no kern table found -- doesn't matter */
+ face->kern_table_index = -1;
+ face->num_kern_pairs = 0;
+ face->kern_pairs = NULL;
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Hdmx */
+ /* */
+ /* <Description> */
+ /* Loads the horizontal device metrics table. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: A handle to the input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_Hdmx( TT_Face face,
+ FT_Stream stream )
+ {
+ TT_Error error;
+ FT_Memory memory = stream->memory;
+
+ TT_Hdmx* hdmx = &face->hdmx;
+ TT_Long num_glyphs;
+ TT_Long record_size;
+
+ hdmx->version = 0;
+ hdmx->num_records = 0;
+ hdmx->records = 0;
+
+ /* this table is optional */
+ error = face->goto_table( face, TTAG_hdmx, stream, 0 );
+ if (error) return TT_Err_Ok;
+
+ if ( ACCESS_Frame( 8L ) ) goto Exit;
+
+ hdmx->version = GET_UShort();
+ hdmx->num_records = GET_Short();
+ record_size = GET_Long();
+
+ FORGET_Frame();
+
+ /* Only recognize format 0 */
+ if ( hdmx->version != 0 )
+ goto Exit;
+
+ if ( ALLOC_ARRAY( hdmx->records, hdmx->num_records, TT_HdmxRec ) )
+ goto Exit;
+
+ num_glyphs = face->root.num_glyphs;
+ record_size -= num_glyphs + 2;
+
+ {
+ TT_HdmxRec* cur = hdmx->records;
+ TT_HdmxRec* limit = cur + hdmx->num_records;
+
+ for ( ; cur < limit; cur++ )
+ {
+ /* read record */
+ if ( READ_Byte( cur->ppem ) ||
+ READ_Byte( cur->max_width ) )
+ goto Exit;
+
+ if ( ALLOC( cur->widths, num_glyphs ) ||
+ FILE_Read( cur->widths, num_glyphs ) )
+ goto Exit;
+
+ /* skip padding bytes */
+ if ( record_size > 0 && FILE_Skip(record_size) )
+ goto Exit;
+ }
+ }
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Free_Hdmx */
+ /* */
+ /* <Description> */
+ /* Frees the horizontal device metrics table. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* */
+ LOCAL_FUNC
+ void TT_Free_Hdmx( TT_Face face )
+ {
+ if ( face )
+ {
+ TT_Int n;
+ FT_Memory memory = face->root.driver->memory;
+
+ for ( n = 0; n < face->hdmx.num_records; n++ )
+ FREE( face->hdmx.records[n].widths );
+
+ FREE( face->hdmx.records );
+ face->hdmx.num_records = 0;
+ }
+ }
+
+
+/* END */
--- /dev/null
+++ b/src/sfnt/ttload.h
@@ -1,0 +1,382 @@
+/***************************************************************************/
+/* */
+/* ttload.h */
+/* */
+/* Load the basic TrueType tables, i.e., tables that can be either in */
+/* TTF or OTF font (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 TTLOAD_H
+#define TTLOAD_H
+
+
+#include <ftstream.h>
+#include <tttypes.h>
+/*
+#include <ttobjs.h>
+*/
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_LookUp_Table */
+ /* */
+ /* <Description> */
+ /* Looks for a TrueType table by name. */
+ /* */
+ /* <Input> */
+ /* face :: A face object handle. */
+ /* tag :: The searched tag. */
+ /* */
+ /* <Return> */
+ /* pointer to table directory entry. 0 if not found.. */
+ /* */
+ EXPORT_DEF
+ TT_Table* TT_LookUp_Table( TT_Face face,
+ TT_ULong tag );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Goto_Table */
+ /* */
+ /* <Description> */
+ /* Looks for a TrueType table by name, then seek a stream to it. */
+ /* */
+ /* <Input> */
+ /* face :: a face object handle. */
+ /* tag :: the searched tag. */
+ /* stream :: the stream to seek when the table is found */
+ /* */
+ /* <Return> */
+ /* pointer to table directory entry. 0 if not found.. */
+ /* */
+ EXPORT_DEF
+ TT_Error TT_Goto_Table( TT_Face face,
+ TT_ULong tag,
+ FT_Stream stream,
+ TT_ULong *length );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Directory */
+ /* */
+ /* <Description> */
+ /* Loads the table directory into a face object. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* faceIndex :: The index of the TrueType font, if we're opening a */
+ /* collection. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* The stream cursor must be at the font file's origin */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_Directory( TT_Face face,
+ FT_Stream stream,
+ TT_Long faceIndex );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Any */
+ /* */
+ /* <Description> */
+ /* Loads any font table into client memory. Used by the */
+ /* TT_Get_Font_Data() API function. */
+ /* */
+ /* <Input> */
+ /* face :: The face object to look for. */
+ /* */
+ /* tag :: The tag of table to load. Use the value 0 if you want */
+ /* to access the whole font file, else set this parameter */
+ /* to a valid TrueType table tag that you can forge with */
+ /* the MAKE_TT_TAG macro. */
+ /* */
+ /* offset :: The starting offset in the table (or the file if */
+ /* tag == 0). */
+ /* */
+ /* length :: The address of the decision variable: */
+ /* */
+ /* If length == NULL: */
+ /* Loads the whole table. Returns an error if */
+ /* `offset' == 0! */
+ /* */
+ /* If *length == 0: */
+ /* Exits immediately; returning the length of the given */
+ /* table or of the font file, depending on the value of */
+ /* `tag'. */
+ /* */
+ /* If *length != 0: */
+ /* Loads the next `length' bytes of table or font, */
+ /* starting at offset `offset' (in table or font too). */
+ /* */
+ /* <Output> */
+ /* buffer :: The address of target buffer. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_Any( TT_Face face,
+ TT_ULong tag,
+ TT_Long offset,
+ void* buffer,
+ TT_Long* length );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Header */
+ /* */
+ /* <Description> */
+ /* Loads the TrueType font header. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_Header( TT_Face face,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Metrics_Header */
+ /* */
+ /* <Description> */
+ /* Loads the horizontal or vertical header in a face object. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* vertical :: A boolean flag. If set, load vertical metrics. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_Metrics_Header( TT_Face face,
+ FT_Stream stream,
+ TT_Bool vertical );
+
+
+ LOCAL_DEF
+ TT_Error TT_Load_CMap( TT_Face face,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_MaxProfile */
+ /* */
+ /* <Description> */
+ /* Loads the maximum profile into a face object. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_MaxProfile( TT_Face face,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Names */
+ /* */
+ /* <Description> */
+ /* Loads the name records. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_Names( TT_Face face,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_OS2 */
+ /* */
+ /* <Description> */
+ /* Loads the OS2 table. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: A handle to the input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_OS2( TT_Face face,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Postscript */
+ /* */
+ /* <Description> */
+ /* Loads the Postscript table. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: A handle to the input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_PostScript( TT_Face face,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Hdmx */
+ /* */
+ /* <Description> */
+ /* Loads the horizontal device metrics table. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: A handle to the input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_Hdmx( TT_Face face,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Free_Names */
+ /* */
+ /* <Description> */
+ /* Frees the name records. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ void TT_Free_Names( TT_Face face );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Free_Hdmx */
+ /* */
+ /* <Description> */
+ /* Frees the horizontal device metrics table. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ void TT_Free_Hdmx ( TT_Face face );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Kern */
+ /* */
+ /* <Description> */
+ /* Loads the first kerning table with format 0 in the font. Only */
+ /* accepts the first horizontal kerning table. Developers should use */
+ /* the `ftxkern' extension to access other kerning tables in the font */
+ /* file, if they really want to. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_Kern( TT_Face face,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Gasp */
+ /* */
+ /* <Description> */
+ /* Loads the `GASP' table into a face object. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_Gasp( TT_Face face,
+ FT_Stream stream );
+
+
+#endif /* TTLOAD_H */
+
+
+/* END */
--- /dev/null
+++ b/src/sfnt/ttpost.c
@@ -1,0 +1,700 @@
+/***************************************************************************/
+/* */
+/* ttpost.c */
+/* */
+/* Postscript names table processing (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 <ttpost.h>
+#include <ftstream.h>
+#include <tterrors.h>
+#include <ttload.h>
+#include <tttags.h>
+
+ /* the 258 default Mac PS glyph names */
+
+ const TT_String* TT_Mac_Postscript_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_Face face,
+ FT_Stream stream )
+ {
+ FT_Memory memory = stream->memory;
+ TT_Error error;
+
+ TT_Int num_glyphs;
+ TT_Int num_names;
+
+ TT_UShort* glyph_indices = 0;
+ TT_Char** name_strings = 0;
+
+
+ if ( READ_UShort( num_glyphs ) )
+ goto Exit;
+
+ /* UNDOCUMENTED! The number of glyphs in this table can be smaller */
+ /* than the value in the maxp table (cf. cyberbit.ttf). */
+
+ /* There already exist fonts which have more than 32768 glyph names */
+ /* in this table, so the test for this threshold has been dropped. */
+
+ if ( num_glyphs > face->root.num_glyphs )
+ {
+ error = TT_Err_Invalid_File_Format;
+ goto Exit;
+ }
+
+ /* load the indices */
+ {
+ TT_Int n;
+
+ if ( ALLOC_ARRAY ( glyph_indices, num_glyphs, TT_UShort ) ||
+ ACCESS_Frame( num_glyphs * 2L ) )
+ goto Fail;
+
+ for ( n = 0; n < num_glyphs; n++ )
+ glyph_indices[n] = GET_UShort();
+
+ FORGET_Frame();
+ }
+
+ /* compute number of names stored in table */
+ {
+ TT_Int n;
+
+ num_names = 0;
+
+ for ( n = 0; n < num_glyphs; n++ )
+ {
+ TT_Int index;
+
+ index = glyph_indices[n];
+ if ( index >= 258 )
+ {
+ index -= 257;
+ if ( index > num_names )
+ num_names = index;
+ }
+ }
+ }
+
+ /* now load the name strings */
+ {
+ TT_Int n;
+
+ if ( ALLOC_ARRAY( name_strings, num_names, TT_Char* ) )
+ goto Fail;
+
+ for ( n = 0; n < num_names; n++ )
+ {
+ TT_UInt len;
+
+ if ( READ_Byte ( len ) ||
+ ALLOC_ARRAY( name_strings[n], len+1, TT_Char ) ||
+ FILE_Read ( name_strings[n], len ) )
+ goto Fail1;
+
+ name_strings[n][len] = '\0';
+ }
+ }
+
+ /* all right, set table fields and exit successfuly */
+ {
+ TT_Post_20* table = &face->postscript_names.names.format_20;
+
+ table->num_glyphs = num_glyphs;
+ table->num_names = num_names;
+ table->glyph_indices = glyph_indices;
+ table->glyph_names = name_strings;
+ }
+ return TT_Err_Ok;
+
+
+ Fail1:
+ {
+ TT_Int n;
+
+ for ( n = 0; n < num_names; n++ )
+ FREE( name_strings[n] );
+ }
+
+ Fail:
+ FREE( name_strings );
+ FREE( glyph_indices );
+
+ Exit:
+ return error;
+ }
+
+
+ static
+ TT_Error Load_Format_25( TT_Face face,
+ FT_Stream stream )
+ {
+ FT_Memory memory = stream->memory;
+ TT_Error error;
+
+ TT_Int num_glyphs;
+ TT_Char* offset_table = 0;
+
+
+ /* UNDOCUMENTED! This value appears only in the Apple TT specs. */
+ if ( READ_UShort( num_glyphs ) )
+ goto Exit;
+
+ /* check the number of glyphs */
+ if ( num_glyphs > face->root.num_glyphs || num_glyphs > 258 )
+ {
+ error = TT_Err_Invalid_File_Format;
+ goto Exit;
+ }
+
+ if ( ALLOC ( offset_table, num_glyphs ) ||
+ FILE_Read( offset_table, num_glyphs ) )
+ goto Fail;
+
+ /* now check the offset table */
+ {
+ TT_Int n;
+
+
+ for ( n = 0; n < num_glyphs; n++ )
+ {
+ TT_Long index = (TT_Long)n + offset_table[n];
+
+
+ if ( index < 0 || index > num_glyphs )
+ {
+ error = TT_Err_Invalid_File_Format;
+ goto Fail;
+ }
+ }
+ }
+
+ /* OK, set table fields and exit successfuly */
+ {
+ TT_Post_25* table = &face->postscript_names.names.format_25;
+
+
+ table->num_glyphs = num_glyphs;
+ table->offsets = offset_table;
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ FREE( offset_table );
+
+ Exit:
+ return error;
+ }
+
+
+ static
+ TT_Error Load_Post_Names( TT_Face face )
+ {
+ FT_Stream stream;
+ TT_Error error;
+
+ /* get a stream for the face's resource */
+ stream = face->root.stream;
+
+ /* seek to the beginning of the PS names table */
+ error = face->goto_table( face, TTAG_post, stream, 0 );
+ if (error) goto Exit;
+
+ /* now read postscript table */
+ switch ( face->postscript.FormatType )
+ {
+ case 0x00020000:
+ error = Load_Format_20( face, stream );
+ break;
+
+ case 0x00028000:
+ error = Load_Format_25( face, stream );
+ break;
+
+ default:
+ error = TT_Err_Invalid_File_Format;
+ }
+
+ face->postscript_names.loaded = 1;
+
+ Exit:
+ return error;
+ }
+
+
+ LOCAL_FUNC
+ void TT_Free_Post_Names( TT_Face face )
+ {
+ FT_Memory memory = face->root.memory;
+ TT_Post_Names* names = &face->postscript_names;
+
+
+ if ( names->loaded )
+ {
+ switch ( face->postscript.FormatType )
+ {
+ case 0x00020000:
+ {
+ TT_Post_20* table = &names->names.format_20;
+ TT_UInt n;
+
+
+ FREE( table->glyph_indices );
+ table->num_glyphs = 0;
+
+ for ( n = 0; n < table->num_names; n++ )
+ FREE( table->glyph_names[n] );
+
+ FREE( table->glyph_names );
+ table->num_names = 0;
+ }
+ break;
+
+ case 0x00028000:
+ {
+ TT_Post_25* table = &names->names.format_25;
+
+
+ FREE( table->offsets );
+ table->num_glyphs = 0;
+ }
+ break;
+ }
+ }
+ names->loaded = 0;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Get_PS_Name */
+ /* */
+ /* <Description> */
+ /* Gets the PostScript glyph name of a glyph. */
+ /* */
+ /* <Input> */
+ /* index :: The glyph index. */
+ /* */
+ /* PSname :: The address of a string pointer. Will be NULL in case */
+ /* of error, otherwise it is a pointer to the glyph name. */
+ /* */
+ /* You must not modify the returned string! */
+ /* */
+ /* <Output> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ EXPORT_FUNC
+ TT_Error TT_Get_PS_Name( TT_Face face,
+ TT_UInt index,
+ TT_String** PSname )
+ {
+ TT_Error error;
+ TT_Post_Names* names;
+
+ if ( !face )
+ return TT_Err_Invalid_Face_Handle;
+
+ if ( index >= (TT_UInt)face->root.num_glyphs )
+ return TT_Err_Invalid_Glyph_Index;
+
+ names = &face->postscript_names;
+
+ /* `.notdef' by default */
+ *PSname = (TT_String*)TT_Mac_Postscript_Names[0];
+
+ switch ( face->postscript.FormatType )
+ {
+ case 0x00010000:
+ if ( index < 258 ) /* paranoid checking */
+ *PSname = (TT_String*)TT_Mac_Postscript_Names[index];
+ break;
+
+ case 0x00020000:
+ {
+ TT_Post_20* table = &names->names.format_20;
+
+
+ if ( !names->loaded )
+ {
+ error = Load_Post_Names( face );
+ if ( error )
+ break;
+ }
+
+ if ( index < table->num_glyphs )
+ {
+ TT_UShort name_index = table->glyph_indices[index];
+
+
+ if ( name_index < 258 )
+ *PSname = (TT_String*)TT_Mac_Postscript_Names[name_index];
+ else
+ *PSname = (TT_String*)table->glyph_names[name_index - 258];
+ }
+ }
+ break;
+
+ case 0x00028000:
+ {
+ TT_Post_25* table = &names->names.format_25;
+
+
+ if ( !names->loaded )
+ {
+ error = Load_Post_Names( face );
+ if ( error )
+ break;
+ }
+
+ if ( index < table->num_glyphs ) /* paranoid checking */
+ {
+ index += table->offsets[index];
+ *PSname = (TT_String*)TT_Mac_Postscript_Names[index];
+ }
+ }
+ break;
+
+ case 0x00030000:
+ break; /* nothing to do */
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+/* END */
--- /dev/null
+++ b/src/sfnt/ttpost.h
@@ -1,0 +1,87 @@
+/***************************************************************************/
+/* */
+/* ttpost.h */
+/* */
+/* Postcript name table processing for TrueType and OpenType fonts */
+/* (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. */
+/* */
+/***************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* 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 TTPOST_H
+#define TTPOST_H
+
+#include <ftconfig.h>
+#include <tttypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define TT_Err_Invalid_Post_Table_Format 0x0B00
+#define TT_Err_Invalid_Post_Table 0x0B01
+
+#if 0
+ /* the 258 standard Mac glyph names, used for format 1.0 and 2.5 */
+ LOCAL_DEF
+ const TT_String* TT_Mac_Postscript_Names[];
+#endif
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Get_PS_Name */
+ /* */
+ /* <Description> */
+ /* Gets the PostScript glyph name of a glyph. */
+ /* */
+ /* <Input> */
+ /* index :: The glyph index. */
+ /* */
+ /* PSname :: The address of a string pointer. Will be NULL in case */
+ /* of error, otherwise it is a pointer to the glyph name. */
+ /* */
+ /* You must not modify the returned string! */
+ /* */
+ /* <Output> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ EXPORT_DEF
+ TT_Error TT_Get_PS_Name( TT_Face face,
+ TT_UInt index,
+ TT_String** PSname );
+
+
+ LOCAL_DEF
+ void TT_Free_Post_Names( TT_Face face );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* TTPOST_H */
+
+
+/* END */
--- /dev/null
+++ b/src/sfnt/ttsbit.c
@@ -1,0 +1,1437 @@
+/***************************************************************************/
+/* */
+/* ttsbit.c */
+/* */
+/* TrueType and OpenType embedded bitmap support (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. */
+/* */
+/* */
+/* WARNING: This file should not be compiled directly, it is meant to be */
+/* included in the source of several font drivers (i.e., the TTF */
+/* and OTF drivers). */
+/* */
+/***************************************************************************/
+
+
+#include <ftdebug.h>
+
+#include <ttsbit.h>
+#include <tttags.h>
+#include <tterrors.h>
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* blit_sbit */
+ /* */
+ /* <Description> */
+ /* Blits a bitmap from an input stream into a given target. Supports */
+ /* x and y offsets as well as byte padded lines. */
+ /* */
+ /* <Input> */
+ /* target :: The target bitmap/pixmap. */
+ /* */
+ /* source :: The input packed bitmap data. */
+ /* */
+ /* line_bits :: The number of bits per line. */
+ /* */
+ /* byte_padded :: A flag which is true if lines are byte-padded. */
+ /* */
+ /* x_offset :: The horizontal offset. */
+ /* */
+ /* y_offset :: The vertical offset. */
+ /* */
+ /* <Note> */
+ /* IMPORTANT: The x and y offsets are relative to the top corner of */
+ /* the target bitmap (unlike the normal TrueType */
+ /* convention). A positive y offset indicates a downwards */
+ /* direction! */
+ /* */
+ static
+ void blit_sbit( FT_Bitmap* target,
+ char* source,
+ FT_Int line_bits,
+ FT_Bool byte_padded,
+ FT_Int x_offset,
+ FT_Int y_offset )
+ {
+ FT_Byte* line_buff;
+ FT_Int line_incr;
+ FT_Int height;
+
+ FT_UShort acc;
+ FT_Byte loaded;
+
+
+ /* first of all, compute starting write position */
+ line_incr = target->pitch;
+ line_buff = target->buffer;
+
+ if (line_incr < 0)
+ line_buff -= line_incr*(target->rows-1);
+
+ line_buff += (x_offset >> 3) + y_offset * line_incr;
+
+ /***********************************************************************/
+ /* */
+ /* We use the extra-classic `accumulator' trick to extract the bits */
+ /* from the source byte stream. */
+ /* */
+ /* Namely, the variable `acc' is a 16-bit accumulator containing the */
+ /* last `loaded' bits from the input stream. The bits are shifted to */
+ /* the upmost position in `acc'. */
+ /* */
+ /***********************************************************************/
+
+ acc = 0; /* clear accumulator */
+ loaded = 0; /* no bits were loaded */
+
+ for ( height = target->rows; height > 0; height-- )
+ {
+ FT_Byte* cur = line_buff; /* current write cursor */
+ FT_Int count = line_bits; /* # of bits to extract per line */
+ FT_Byte shift = x_offset & 7; /* current write shift */
+ FT_Byte space = 8 - shift;
+
+
+ /* first of all, read individual source bytes */
+ if ( count >= 8 )
+ {
+ count -= 8;
+ {
+ do
+ {
+ FT_Byte val;
+
+ /* ensure that there are at least 8 bits in the accumulator */
+ if ( loaded < 8 )
+ {
+ acc |= ((FT_UShort)*source++) << (8 - loaded);
+ loaded += 8;
+ }
+
+ /* now write one byte */
+ val = (FT_Byte)(acc >> 8);
+ if (shift)
+ {
+ cur[0] |= val >> shift;
+ cur[1] |= val << space;
+ }
+ else
+ cur[0] = val;
+
+ cur++;
+ acc <<= 8; /* remove bits from accumulator */
+ loaded -= 8;
+ count -= 8;
+ }
+ while ( count >= 0 );
+ }
+
+ /* restore `count' to correct value */
+ count += 8;
+ }
+
+ /* now write remaining bits (count < 8) */
+ if ( count > 0 )
+ {
+ FT_Byte val;
+
+
+ /* ensure that there are at least `count' bits in the accumulator */
+ if ( loaded < count )
+ {
+ acc |= ((FT_UShort)*source++) << (8 - loaded);
+ loaded += 8;
+ }
+
+ /* now write remaining bits */
+ val = ((FT_Byte)(acc >> 8)) & ~(0xFF >> count);
+ cur[0] |= val >> shift;
+
+ if ( count > space )
+ cur[1] |= val << space;
+
+ acc <<= count;
+ loaded -= count;
+ }
+
+ /* now, skip to next line */
+ if ( byte_padded )
+ acc = loaded = 0; /* clear accumulator on byte-padded lines */
+
+ line_buff += line_incr;
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Small_SBit_Metrics */
+ /* */
+ /* <Description> */
+ /* Loads a small bitmap metrics record. */
+ /* */
+ /* <Input> */
+ /* stream :: The input stream. */
+ /* */
+ /* <Output> */
+ /* metrics :: A small metrics structure. */
+ /* */
+ static
+ void TT_Load_Small_SBit_Metrics( TT_SBit_Small_Metrics* metrics,
+ FT_Stream stream )
+ {
+ metrics->height = GET_Byte();
+ metrics->width = GET_Byte();
+ metrics->bearingX = GET_Char();
+ metrics->bearingY = GET_Char();
+ metrics->advance = GET_Byte();
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_SBit_Metrics */
+ /* */
+ /* <Description> */
+ /* Loads a bitmap metrics record. */
+ /* */
+ /* <Input> */
+ /* stream :: The input stream. */
+ /* */
+ /* <Output> */
+ /* metrics :: A metrics structure. */
+ /* */
+ static
+ void TT_Load_SBit_Metrics( TT_SBit_Metrics* metrics,
+ FT_Stream stream )
+ {
+ 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();
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_SBit_Line_Metrics */
+ /* */
+ /* <Description> */
+ /* Loads a bitmap line metrics record. */
+ /* */
+ /* <Input> */
+ /* stream :: The input stream. */
+ /* */
+ /* <Output> */
+ /* metrics :: A line metrics structure. */
+ /* */
+ static
+ void TT_Load_SBit_Line_Metrics( TT_SBit_Line_Metrics* metrics,
+ FT_Stream stream )
+ {
+ 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();
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_SBit_Const_Metrics */
+ /* */
+ /* <Description> */
+ /* Loads the metrics for `EBLC' index tables format 2 and 5. */
+ /* */
+ /* <Input> */
+ /* range :: The target range. */
+ /* */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ static
+ TT_Error Load_SBit_Const_Metrics( TT_SBit_Range* range,
+ FT_Stream stream )
+ {
+ TT_Error error;
+
+ if ( !ACCESS_Frame( 12L ) )
+ {
+ range->image_size = GET_ULong();
+ TT_Load_SBit_Metrics( &range->metrics, stream );
+
+ FORGET_Frame();
+ }
+
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_SBit_Range_Codes */
+ /* */
+ /* <Description> */
+ /* Loads the range codes for `EBLC' index tables format 4 and 5. */
+ /* */
+ /* <Input> */
+ /* range :: The target range. */
+ /* */
+ /* stream :: The input stream. */
+ /* */
+ /* load_offsets :: A flag whether to load the glyph offset table. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ static
+ TT_Error Load_SBit_Range_Codes( TT_SBit_Range* range,
+ FT_Stream stream,
+ TT_Bool load_offsets )
+ {
+ TT_Error error;
+ TT_ULong count, n, size;
+ FT_Memory memory = stream->memory;
+
+
+ if ( READ_ULong( count ) )
+ goto Exit;
+
+ range->num_glyphs = count;
+
+ /* Allocate glyph offsets table if needed */
+ if ( load_offsets )
+ {
+ if ( ALLOC_ARRAY( range->glyph_offsets, count, TT_ULong ) )
+ goto Exit;
+
+ size = count * 4L;
+ }
+ else
+ size = count * 2L;
+
+ /* Allocate glyph codes table and access frame */
+ if ( ALLOC_ARRAY ( range->glyph_codes, count, TT_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] = (TT_ULong)range->image_offset +
+ GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_SBit_Range */
+ /* */
+ /* <Description> */
+ /* Loads a given `EBLC' index/range table. */
+ /* */
+ /* <Input> */
+ /* range :: The target range. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ static
+ TT_Error Load_SBit_Range( TT_SBit_Range* range,
+ FT_Stream stream )
+ {
+ TT_Error error;
+ FT_Memory memory = stream->memory;
+
+
+ switch( range->index_format )
+ {
+ case 1: /* variable metrics with 4-byte offsets */
+ case 3: /* variable metrics with 2-byte offsets */
+ {
+ TT_ULong num_glyphs, n;
+ TT_Int size_elem;
+ TT_Bool large = (range->index_format == 1);
+
+
+ num_glyphs = range->last_glyph - range->first_glyph + 1L;
+ range->num_glyphs = num_glyphs;
+ num_glyphs++; /* XXX : BEWARE - see spec */
+
+ size_elem = ( large ? 4 : 2 );
+
+ if ( ALLOC_ARRAY( range->glyph_offsets,
+ num_glyphs, TT_ULong ) ||
+
+ ACCESS_Frame( num_glyphs * size_elem ) )
+ goto Exit;
+
+ for ( n = 0; n < num_glyphs; n++ )
+ range->glyph_offsets[n] = (TT_ULong)( range->image_offset +
+ (large ? GET_ULong() : GET_UShort()) );
+ FORGET_Frame();
+ }
+ break;
+
+ case 2: /* all glyphs have identical metrics */
+ error = Load_SBit_Const_Metrics( range, stream );
+ break;
+
+ case 4:
+ error = Load_SBit_Range_Codes( range, stream, 1 );
+ break;
+
+ case 5:
+ error = Load_SBit_Const_Metrics( range, stream ) ||
+ Load_SBit_Range_Codes( range, stream, 0 );
+ break;
+
+ default:
+ error = TT_Err_Invalid_File_Format;
+ }
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_SBit_Strikes */
+ /* */
+ /* <Description> */
+ /* Loads the table of embedded bitmap sizes for this face. */
+ /* */
+ /* <Input> */
+ /* face :: The target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_SBit_Strikes( TT_Face face,
+ FT_Stream stream )
+ {
+ TT_Error error = 0;
+ FT_Memory memory = stream->memory;
+ TT_Fixed version;
+ TT_ULong num_strikes;
+ TT_ULong table_base;
+
+
+ /* this table is optional */
+ error = face->goto_table( face, TTAG_EBLC, stream, 0 );
+ {
+ error = 0;
+ goto Exit;
+ }
+
+ table_base = FILE_Pos();
+ if ( ACCESS_Frame( 8L ) )
+ goto Exit;
+
+ version = GET_Long();
+ num_strikes = GET_ULong();
+
+ FORGET_Frame();
+
+ /* check version number and strike count */
+ if ( version != 0x00020000 ||
+ num_strikes >= 0x10000 )
+ {
+ FT_ERROR(( "TT_Load_SBit_Strikes: invalid table version!\n" ));
+ error = TT_Err_Invalid_File_Format;
+
+ goto Exit;
+ }
+
+ /* allocate the strikes table */
+ if ( ALLOC_ARRAY( face->sbit_strikes, num_strikes, TT_SBit_Strike ) )
+ goto Exit;
+
+ face->num_sbit_strikes = num_strikes;
+
+ /* now read each strike table separately */
+ {
+ TT_SBit_Strike* strike = face->sbit_strikes;
+ TT_ULong count = num_strikes;
+
+ if ( ACCESS_Frame( 48L * num_strikes ) )
+ goto Exit;
+
+ while ( count > 0 )
+ {
+ TT_ULong indexTablesSize;
+
+
+ strike->ranges_offset = GET_ULong();
+ indexTablesSize = GET_ULong(); /* don't save */
+
+ strike->num_ranges = GET_ULong();
+ strike->color_ref = GET_ULong();
+
+ TT_Load_SBit_Line_Metrics( &strike->hori, stream );
+ TT_Load_SBit_Line_Metrics( &strike->vert, stream );
+
+ 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();
+
+ count--;
+ strike++;
+ }
+
+ FORGET_Frame();
+ }
+
+ /* allocate the index ranges for each strike table */
+ {
+ TT_SBit_Strike* strike = face->sbit_strikes;
+ TT_ULong count = num_strikes;
+
+
+ while ( count > 0 )
+ {
+ TT_SBit_Range* range;
+ TT_ULong count2 = strike->num_ranges;
+
+
+ if ( ALLOC_ARRAY( strike->sbit_ranges,
+ strike->num_ranges,
+ TT_SBit_Range ) )
+ goto Exit;
+
+ /* read each range */
+ if ( FILE_Seek( table_base + strike->ranges_offset ) ||
+ ACCESS_Frame( strike->num_ranges * 8L ) )
+ goto Exit;
+
+ range = strike->sbit_ranges;
+ while ( count2 > 0 )
+ {
+ range->first_glyph = GET_UShort();
+ range->last_glyph = GET_UShort();
+ range->table_offset = table_base + strike->ranges_offset
+ + GET_ULong();
+ count2--;
+ range++;
+ }
+
+ FORGET_Frame();
+
+ /* Now, read each index table */
+ count2 = strike->num_ranges;
+ range = strike->sbit_ranges;
+ while ( count2 > 0 )
+ {
+ /* Read the header */
+ if ( FILE_Seek( range->table_offset ) ||
+ ACCESS_Frame( 8L ) )
+ goto Exit;
+
+ range->index_format = GET_UShort();
+ range->image_format = GET_UShort();
+ range->image_offset = GET_ULong();
+
+ FORGET_Frame();
+
+ error = Load_SBit_Range( range, stream );
+ if ( error )
+ goto Exit;
+
+ count2--;
+ range++;
+ }
+
+ count--;
+ strike++;
+ }
+ }
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Free_SBit_Strikes */
+ /* */
+ /* <Description> */
+ /* Releases the embedded bitmap tables. */
+ /* */
+ /* <Input> */
+ /* face :: The target face object. */
+ /* */
+ LOCAL_FUNC
+ void TT_Free_SBit_Strikes( TT_Face face )
+ {
+ FT_Memory memory = face->root.memory;
+ TT_SBit_Strike* strike = face->sbit_strikes;
+ TT_SBit_Strike* strike_limit = strike + face->num_sbit_strikes;
+
+
+ if ( strike )
+ {
+ for ( ; strike < strike_limit; strike++ )
+ {
+ TT_SBit_Range* range = strike->sbit_ranges;
+ TT_SBit_Range* range_limit = range + strike->num_ranges;
+
+ if ( range )
+ {
+ for ( ; range < range_limit; range++ )
+ {
+ /* release the glyph offsets and codes tables */
+ /* where appropriate */
+ FREE( range->glyph_offsets );
+ FREE( range->glyph_codes );
+ }
+ }
+ FREE( strike->sbit_ranges );
+ strike->num_ranges = 0;
+ }
+ FREE( face->sbit_strikes );
+ }
+ face->num_sbit_strikes = 0;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Find_SBit_Range */
+ /* */
+ /* <Description> */
+ /* Scans a given strike's ranges and return, for a given glyph */
+ /* index, the corresponding sbit range, and `EBDT' offset. */
+ /* */
+ /* <Input> */
+ /* glyph_index :: The glyph index. */
+ /* strike :: The source/current sbit strike. */
+ /* */
+ /* <Output> */
+ /* arange :: The sbit range containing the glyph index. */
+ /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means the glyph index was found. */
+ /* */
+ static
+ TT_Error Find_SBit_Range( TT_UInt glyph_index,
+ TT_SBit_Strike* strike,
+ TT_SBit_Range** arange,
+ TT_ULong* aglyph_offset )
+ {
+ TT_SBit_Range *range, *range_limit;
+
+
+ /* check whether the glyph index is within this strike's */
+ /* glyph range */
+ if ( glyph_index < strike->start_glyph ||
+ glyph_index > strike->end_glyph )
+ goto Fail;
+
+ /* scan all ranges in strike */
+ range = strike->sbit_ranges;
+ range_limit = range + strike->num_ranges;
+ if ( !range )
+ goto Fail;
+
+ for ( ; range < range_limit; range++ )
+ {
+ if ( glyph_index >= range->first_glyph &&
+ glyph_index <= range->last_glyph )
+ {
+ TT_UShort delta = glyph_index - range->first_glyph;
+
+
+ switch ( range->index_format )
+ {
+ case 1:
+ case 3:
+ *aglyph_offset = range->glyph_offsets[delta];
+ break;
+
+ case 2:
+ *aglyph_offset = range->image_offset +
+ range->image_size * delta;
+ break;
+
+ case 4:
+ case 5:
+ {
+ TT_ULong n;
+
+
+ for ( n = 0; n < range->num_glyphs; n++ )
+ {
+ if ( range->glyph_codes[n] == glyph_index )
+ {
+ if ( range->index_format == 4 )
+ *aglyph_offset = range->glyph_offsets[n];
+ else
+ *aglyph_offset = range->image_offset +
+ n * range->image_size;
+ break;
+ }
+ }
+ }
+
+ /* fall-through */
+ default:
+ goto Fail;
+ }
+
+ /* return successfully! */
+ *arange = range;
+
+ return 0;
+ }
+ }
+
+ Fail:
+ *arange = 0;
+ *aglyph_offset = 0;
+
+ return TT_Err_Invalid_Argument;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Find_SBit_Image */
+ /* */
+ /* <Description> */
+ /* Checks whether an embedded bitmap (an `sbit') exists for a given */
+ /* glyph, at given x and y ppems. */
+ /* */
+ /* <Input> */
+ /* face :: The target face object. */
+ /* glyph_index :: The glyph index. */
+ /* x_ppem :: The horizontal resolution in points per EM. */
+ /* y_ppem :: The vertical resolution in points per EM. */
+ /* */
+ /* <Output> */
+ /* arange :: The SBit range containing the glyph index. */
+ /* astrike :: The SBit strike containing the glyph index. */
+ /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. Returns */
+ /* TT_Err_Invalid_Argument if no sbit exist for the requested glyph. */
+ /* */
+ static
+ TT_Error Find_SBit_Image( TT_Face face,
+ TT_UInt glyph_index,
+ TT_Int x_ppem,
+ TT_Int y_ppem,
+
+ TT_SBit_Range** arange,
+ TT_SBit_Strike** astrike,
+ TT_ULong* aglyph_offset )
+ {
+ TT_SBit_Strike* strike = face->sbit_strikes;
+ TT_SBit_Strike* strike_limit = strike + face->num_sbit_strikes;
+
+
+ if ( !strike)
+ goto Fail;
+
+ for ( ; strike < strike_limit; strike++ )
+ {
+ if ( strike->x_ppem == x_ppem && strike->y_ppem == y_ppem )
+ {
+ TT_Error error;
+
+
+ error = Find_SBit_Range( glyph_index, strike, arange, aglyph_offset );
+ if ( error )
+ goto Fail;
+
+ *astrike = strike;
+
+ return TT_Err_Ok;
+ }
+ }
+
+ Fail:
+ /* no embedded bitmap for this glyph in face */
+ *arange = 0;
+ *astrike = 0;
+ *aglyph_offset = 0;
+
+ return TT_Err_Invalid_Argument;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Load_SBit_Metrics */
+ /* */
+ /* <Description> */
+ /* Gets the big metrics for a given SBit. */
+ /* */
+ /* <Input> */
+ /* stream :: The input stream. */
+ /* range :: The SBit range containing the glyph. */
+ /* */
+ /* <Output> */
+ /* big_metrics :: A big SBit metrics structure for the glyph. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* The stream cursor must be positioned at the glyph's offset within */
+ /* the `EBDT' table before the call. */
+ /* */
+ /* If the image format uses variable metrics, the stream cursor is */
+ /* positioned just after the metrics header in the `EBDT' table on */
+ /* function exit. */
+ /* */
+ static
+ TT_Error Load_SBit_Metrics( FT_Stream stream,
+ TT_SBit_Range* range,
+ TT_SBit_Metrics* metrics )
+ {
+ TT_Error error = TT_Err_Ok;
+
+
+ switch ( range->index_format )
+ {
+ case 1: /* variable metrics */
+ case 3:
+ case 4:
+ {
+ switch ( range->image_format )
+ {
+ case 1: /* small metrics */
+ case 2:
+ case 8:
+ {
+ TT_SBit_Small_Metrics smetrics;
+
+
+ /* read small metrics */
+ if ( ACCESS_Frame( 5L ) )
+ goto Exit;
+ TT_Load_Small_SBit_Metrics( &smetrics, stream );
+ FORGET_Frame();
+
+ /* convert it to a big metrics */
+ metrics->height = smetrics.height;
+ metrics->width = smetrics.width;
+ metrics->horiBearingX = smetrics.bearingX;
+ metrics->horiBearingY = smetrics.bearingY;
+ metrics->horiAdvance = smetrics.advance;
+
+ /* these metrics are made up at a higher level when */
+ /* needed. */
+ metrics->vertBearingX = 0;
+ metrics->vertBearingY = 0;
+ metrics->vertAdvance = 0;
+ }
+ break;
+
+ default: /* big metrics */
+ if ( ACCESS_Frame( 8L ) )
+ goto Exit;
+ TT_Load_SBit_Metrics( metrics, stream );
+ FORGET_Frame();
+ }
+ }
+ break;
+
+ default: /* constant metrics */
+ *metrics = range->metrics;
+ }
+
+ Exit:
+ return error;
+ }
+
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Crop_Bitmap */
+ /* */
+ /* <Description> */
+ /* Crops a bitmap to its tightest bounding box, and adjusts its */
+ /* metrics. */
+ /* */
+ /* <Input> */
+ /* image :: The input glyph slot. */
+ /* */
+ /* metrics :: The corresponding metrics structure. */
+ /* */
+ static
+ void Crop_Bitmap( FT_Bitmap* map,
+ TT_SBit_Metrics* metrics )
+ {
+ /***********************************************************************/
+ /* */
+ /* In this situation, some bounding boxes of embedded bitmaps are too */
+ /* large. We need to crop it to a reasonable size. */
+ /* */
+ /* --------- */
+ /* | | ----- */
+ /* | *** | |***| */
+ /* | * | | * | */
+ /* | * | ------> | * | */
+ /* | * | | * | */
+ /* | * | | * | */
+ /* | *** | |***| */
+ /* --------- ----- */
+ /* */
+ /***********************************************************************/
+
+ TT_Int rows, count;
+ TT_Long line_len;
+ TT_Byte* line;
+
+
+ /***********************************************************************/
+ /* */
+ /* first of all, checks the top-most lines of the bitmap, and removes */
+ /* them if they're empty. */
+ /* */
+ {
+ line = (TT_Byte*)map->buffer;
+ rows = map->rows;
+ line_len = map->pitch;
+
+
+ for ( count = 0; count < rows; count++ )
+ {
+ TT_Byte* cur = line;
+ TT_Byte* limit = line + line_len;
+
+
+ for ( ; cur < limit; cur++ )
+ if ( cur[0] )
+ goto Found_Top;
+
+ /* the current line was empty - skip to next one */
+ line = limit;
+ }
+
+ Found_Top:
+ /* check that we have at least one filled line */
+ if ( count >= rows )
+ goto Empty_Bitmap;
+
+ /* now, crop the empty upper lines */
+ if ( count > 0 )
+ {
+ line = (TT_Byte*)map->buffer;
+
+ MEM_Move( line, line + count * line_len, (rows - count) * line_len );
+
+ metrics->height -= count;
+ metrics->horiBearingY -= count;
+ metrics->vertBearingY -= count;
+
+ map->rows -= count;
+ rows -= count;
+ }
+ }
+
+ /***********************************************************************/
+ /* */
+ /* second, crop the lower lines */
+ /* */
+ {
+ line = (TT_Byte*)map->buffer + (rows - 1) * line_len;
+
+ for ( count = 0; count < rows; count++ )
+ {
+ TT_Byte* cur = line;
+ TT_Byte* limit = line + line_len;
+
+
+ for ( ; cur < limit; cur++ )
+ if ( cur[0] )
+ goto Found_Bottom;
+
+ /* the current line was empty - skip to previous one */
+ line -= line_len;
+ }
+
+ Found_Bottom:
+ if ( count > 0 )
+ {
+ metrics->height -= count;
+ rows -= count;
+ map->rows -= count;
+ }
+ }
+
+ /***********************************************************************/
+ /* */
+ /* third, get rid of the space on the left side of the glyph */
+ /* */
+ do
+ {
+ TT_Byte* limit;
+
+
+ line = (TT_Byte*)map->buffer;
+ limit = line + rows * line_len;
+
+ for ( ; line < limit; line += line_len )
+ if ( line[0] & 0x80 )
+ goto Found_Left;
+
+ /* shift the whole glyph one pixel to the left */
+ line = (TT_Byte*)map->buffer;
+ limit = line + rows * line_len;
+
+ for ( ; line < limit; line += line_len )
+ {
+ TT_Int n, width = map->width;
+ TT_Byte old;
+ TT_Byte* cur = line;
+
+
+ old = cur[0] << 1;
+ for ( n = 8; n < width; n += 8 )
+ {
+ TT_Byte val;
+
+
+ val = cur[1];
+ cur[0] = old | (val >> 7);
+ old = val << 1;
+ cur++;
+ }
+ cur[0] = old;
+ }
+
+ map->width--;
+ metrics->horiBearingX++;
+ metrics->vertBearingX++;
+ metrics->width--;
+ } while ( map->width > 0 );
+
+ Found_Left:
+
+ /***********************************************************************/
+ /* */
+ /* finally, crop the bitmap width to get rid of the space on the right */
+ /* side of the glyph. */
+ /* */
+ do
+ {
+ TT_Int right = map->width-1;
+ TT_Byte* limit;
+ TT_Byte mask;
+
+
+ line = (TT_Byte*)map->buffer + (right >> 3);
+ limit = line + rows*line_len;
+ mask = 0x80 >> (right & 7);
+
+ for ( ; line < limit; line += line_len )
+ if ( line[0] & mask )
+ goto Found_Right;
+
+ /* crop the whole glyph to the right */
+ map->width--;
+ metrics->width--;
+ } while ( map->width > 0 );
+
+ Found_Right:
+ /* all right, the bitmap was cropped */
+ return;
+
+ Empty_Bitmap:
+ map->width = 0;
+ map->rows = 0;
+ map->pitch = 0;
+ map->pixel_mode = ft_pixel_mode_mono;
+ }
+
+
+ static
+ TT_Error Load_SBit_Single( FT_Bitmap* map,
+ TT_Int x_offset,
+ TT_Int y_offset,
+ TT_Int pix_bits,
+ TT_UShort image_format,
+ TT_SBit_Metrics* metrics,
+ FT_Stream stream )
+ {
+ TT_Error error;
+
+
+ /* check that the source bitmap fits into the target pixmap */
+ if ( x_offset < 0 || x_offset + metrics->width > map->width ||
+ y_offset < 0 || y_offset + metrics->height > map->rows )
+ {
+ error = TT_Err_Invalid_Argument;
+
+ goto Exit;
+ }
+
+ {
+ TT_Int glyph_width = metrics->width;
+ TT_Int glyph_height = metrics->height;
+ TT_Int glyph_size;
+ TT_Int line_bits = pix_bits * glyph_width;
+ TT_Bool pad_bytes = 0;
+
+
+ /* compute size of glyph image */
+ switch ( image_format )
+ {
+ case 1: /* byte-padded formats */
+ case 6:
+ {
+ TT_Int line_length;
+
+
+ switch ( pix_bits )
+ {
+ case 1: line_length = (glyph_width+7) >> 3; break;
+ case 2: line_length = (glyph_width+3) >> 2; break;
+ case 4: line_length = (glyph_width+1) >> 1; break;
+ default: line_length = glyph_width;
+ }
+
+ glyph_size = glyph_height * line_length;
+ pad_bytes = 1;
+ }
+ break;
+
+ case 2:
+ case 5:
+ case 7:
+ line_bits = glyph_width * pix_bits;
+ glyph_size = (glyph_height * line_bits + 7) >> 3;
+ break;
+
+ default: /* invalid format */
+ return TT_Err_Invalid_File_Format;
+ }
+
+ /* Now read data and draw glyph into target pixmap */
+ if ( ACCESS_Frame( glyph_size ) )
+ goto Exit;
+
+ /* don't forget to multiply `x_offset' by `map->pix_bits' as */
+ /* the sbit blitter doesn't make a difference between pixmap */
+ /* depths. */
+ blit_sbit( map, stream->cursor, line_bits, pad_bytes,
+ x_offset * pix_bits, y_offset );
+
+ FORGET_Frame();
+ }
+
+ Exit:
+ return error;
+ }
+
+
+ static
+ TT_Error Load_SBit_Image( TT_SBit_Strike* strike,
+ TT_SBit_Range* range,
+ TT_ULong ebdt_pos,
+ TT_ULong glyph_offset,
+ FT_Bitmap* map,
+ TT_Int x_offset,
+ TT_Int y_offset,
+ FT_Stream stream,
+ TT_SBit_Metrics* metrics )
+ {
+ FT_Memory memory = stream->memory;
+ TT_Error error;
+
+
+ /* place stream at beginning of glyph data and read metrics */
+ if ( FILE_Seek( ebdt_pos + glyph_offset ) )
+ goto Exit;
+
+ error = Load_SBit_Metrics( stream, range, metrics );
+ if ( error )
+ goto Exit;
+
+ /* this function is recursive. At the top-level call, the */
+ /* field map.buffer is NULL. We thus begin by finding the */
+ /* dimensions of the higher-level glyph to allocate the */
+ /* final pixmap buffer */
+ if ( map->buffer == 0 )
+ {
+ TT_Long size;
+
+
+ map->width = metrics->width;
+ map->rows = metrics->height;
+
+ switch ( strike->bit_depth )
+ {
+ case 1:
+ map->pixel_mode = ft_pixel_mode_mono;
+ map->pitch = (map->width+7) >> 3;
+ break;
+ case 2:
+ map->pixel_mode = ft_pixel_mode_pal2;
+ map->pitch = (map->width+3) >> 2;
+ break;
+ case 4:
+ map->pixel_mode = ft_pixel_mode_pal4;
+ map->pitch = (map->width+1) >> 1;
+ break;
+ case 8:
+ map->pixel_mode = ft_pixel_mode_grays;
+ map->pitch = map->width;
+ break;
+
+ default:
+ return TT_Err_Invalid_File_Format;
+ }
+
+ size = map->rows * map->pitch;
+
+ /* check that there is no empty image */
+ if ( size == 0 )
+ goto Exit; /* exit successfully! */
+
+ if ( ALLOC( map->buffer, size ) )
+ goto Exit;
+ }
+
+ switch ( range->image_format )
+ {
+ case 1: /* single sbit image - load it */
+ case 2:
+ case 5:
+ case 6:
+ case 7:
+ return Load_SBit_Single( map, x_offset, y_offset, strike->bit_depth,
+ range->image_format, metrics, stream );
+
+ case 8: /* compound format */
+ case 9:
+ break;
+
+ default: /* invalid image format */
+ return TT_Err_Invalid_File_Format;
+ }
+
+ /* All right, we're in a compound format. First of all, read */
+ /* the array of elements */
+ {
+ TT_SBit_Component* components;
+ TT_SBit_Component* comp;
+ TT_UShort num_components, count;
+
+
+ if ( READ_UShort( num_components ) ||
+ ALLOC_ARRAY( components, num_components, TT_SBit_Component ) )
+ goto Exit;
+
+ count = num_components;
+
+ if ( ACCESS_Frame( 4L * num_components ) )
+ goto Fail_Memory;
+
+ for ( comp = components; count > 0; count--, comp++ )
+ {
+ comp->glyph_code = GET_UShort();
+ comp->x_offset = GET_Char();
+ comp->y_offset = GET_Char();
+ }
+
+ FORGET_Frame();
+
+ /* Now recursively load each element glyph */
+ count = num_components;
+ comp = components;
+ for ( ; count > 0; count--, comp++ )
+ {
+ TT_SBit_Range* elem_range;
+ TT_SBit_Metrics elem_metrics;
+ TT_ULong elem_offset;
+
+
+ /* find the range for this element */
+ error = Find_SBit_Range( comp->glyph_code,
+ strike,
+ &elem_range,
+ &elem_offset );
+ if ( error )
+ goto Fail_Memory;
+
+ /* now load the element, recursively */
+ error = Load_SBit_Image( strike,
+ elem_range,
+ ebdt_pos,
+ elem_offset,
+ map,
+ x_offset + comp->x_offset,
+ y_offset + comp->y_offset,
+ stream,
+ &elem_metrics );
+ if ( error )
+ goto Fail_Memory;
+ }
+
+ Fail_Memory:
+ FREE( components );
+ }
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_SBit_Image */
+ /* */
+ /* <Description> */
+ /* Loads a given glyph sbit image from the font resource. This also */
+ /* returns its metrics. */
+ /* */
+ /* <Input> */
+ /* face :: The target face object. */
+ /* */
+ /* x_ppem :: The horizontal resolution in points per EM. */
+ /* */
+ /* y_ppem :: The vertical resolution in points per EM. */
+ /* */
+ /* glyph_index :: The current glyph index. */
+ /* */
+ /* stream :: The input stream. */
+ /* */
+ /* <Output> */
+ /* map :: The target pixmap. */
+ /* metrics :: A big sbit metrics structure for the glyph image. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. Returns an error if no */
+ /* glyph sbit exists for the index. */
+ /* */
+ /* <Note> */
+ /* The `map.buffer' field is always freed before the glyph is loaded. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_SBit_Image( TT_Face face,
+ TT_Int x_ppem,
+ TT_Int y_ppem,
+ TT_UInt glyph_index,
+ FT_Stream stream,
+ FT_Bitmap* map,
+ TT_SBit_Metrics* metrics )
+ {
+ TT_Error error;
+ FT_Memory memory = stream->memory;
+ TT_ULong ebdt_pos, glyph_offset;
+
+ TT_SBit_Strike* strike;
+ TT_SBit_Range* range;
+
+
+ /* Check whether there is a glyph sbit for the current index */
+ error = Find_SBit_Image( face, glyph_index, x_ppem, y_ppem,
+ &range, &strike, &glyph_offset );
+ if ( error )
+ goto Exit;
+
+ /* now, find the location of the `EBDT' table in */
+ /* the font file */
+ error = face->goto_table( face, TTAG_EBDT, stream, 0 );
+ if (error) goto Exit;
+
+ ebdt_pos = FILE_Pos();
+
+ /* clear the bitmap & load the bitmap */
+ FREE( map->buffer );
+ map->rows = map->pitch = map->width = 0;
+
+ error = Load_SBit_Image( strike, range, ebdt_pos, glyph_offset,
+ map, 0, 0, stream, metrics );
+ if ( error )
+ goto Exit;
+
+ /* setup vertical metrics if needed */
+ if ( strike->flags & 1 )
+ {
+ /* in case of a horizontal strike only */
+ FT_Int advance;
+ FT_Int top;
+
+
+ advance = strike->hori.ascender - strike->hori.descender;
+ top = advance / 10;
+
+ metrics->vertBearingX = -metrics->width / 2;
+ metrics->vertBearingY = advance / 10;
+ metrics->vertAdvance = advance * 12 / 10;
+ }
+
+ /* Crop the bitmap now */
+ Crop_Bitmap( map, metrics );
+
+ Exit:
+ return error;
+ }
+
+
+/* END */
--- /dev/null
+++ b/src/sfnt/ttsbit.h
@@ -1,0 +1,104 @@
+/***************************************************************************/
+/* */
+/* ttsbit.h */
+/* */
+/* TrueType and OpenType embedded bitmap support (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 TTSBIT_H
+#define TTSBIT_H
+
+#include <ttload.h>
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_SBit_Strikes */
+ /* */
+ /* <Description> */
+ /* Loads the table of embedded bitmap sizes for this face. */
+ /* */
+ /* <Input> */
+ /* face :: The target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_SBit_Strikes( TT_Face face,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Free_SBit_Strikes */
+ /* */
+ /* <Description> */
+ /* Releases the embedded bitmap tables. */
+ /* */
+ /* <Input> */
+ /* face :: The target face object. */
+ /* */
+ LOCAL_DEF
+ void TT_Free_SBit_Strikes( TT_Face face );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_SBit_Image */
+ /* */
+ /* <Description> */
+ /* Loads a given glyph sbit image from the font resource. This also */
+ /* returns its metrics. */
+ /* */
+ /* <Input> */
+ /* face :: The target face object. */
+ /* */
+ /* x_ppem :: The horizontal resolution in points per EM. */
+ /* */
+ /* y_ppem :: The vertical resolution in points per EM. */
+ /* */
+ /* glyph_index :: The current glyph index. */
+ /* */
+ /* stream :: The input stream. */
+ /* */
+ /* <Output> */
+ /* map :: The target pixmap. */
+ /* metrics :: A big sbit metrics structure for the glyph image. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. Returns an error if no */
+ /* glyph sbit exists for the index. */
+ /* */
+ /* <Note> */
+ /* The `map.buffer' field is always freed before the glyph is loaded. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_SBit_Image( TT_Face face,
+ TT_Int x_ppem,
+ TT_Int y_ppem,
+ TT_UInt glyph_index,
+ FT_Stream stream,
+ FT_Bitmap* map,
+ TT_SBit_Metrics* metrics );
+
+
+#endif /* TTSBIT_H */
+
+
+/* END */
--- /dev/null
+++ b/src/shared/otlayout/otlayout.h
@@ -1,0 +1,372 @@
+/***************************************************************************/
+/* */
+/* otlayout.h */
+/* */
+/* OpenType layout type definitions (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 OTLAYOUT_H
+#define OTLAYOUT_H
+
+#include <tttypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* OTL_LangSys */
+ /* */
+ /* <Description> */
+ /* An OTL LangSys record. */
+ /* */
+ /* <Fields> */
+ /* lang_tag :: The language tag. */
+ /* lang_offset :: The offset of the langsys data in the
+ /* resource. */
+ /* */
+ /* lookup_order :: Always 0 for OTL 1.0. */
+ /* req_feature_index :: The `required feature' index. */
+ /* num_feature_indices :: The number of feature indices. */
+ /* feature_indices :: An array of feature indices. */
+ /* */
+ typedef struct OTL_LangSys_
+ {
+ TT_ULong lang_tag;
+ TT_ULong lang_offset;
+
+ TT_UShort lookup_order; /* always 0 for TT Open 1.0 */
+ TT_UShort req_feature_index; /* required FeatureIndex */
+ TT_UShort num_feature_indices; /* number of Feature indices */
+ TT_UShort* feature_indices; /* array of Feature indices */
+
+ } OTL_LangSys;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* OTL_Script */
+ /* */
+ /* <Description> */
+ /* An OTL Script record. */
+ /* */
+ /* <Fields> */
+ /* script_tag :: The script tag. */
+ /* script_offset :: The offset of the script data in the resource. */
+ /* */
+ /* num_langsys :: The number of langsys records. */
+ /* langsys :: An array of langsys records. */
+ /* langsys_default :: A pointer to the default langsys table for this */
+ /* script. */
+ /* */
+ typedef struct OTL_Script_
+ {
+ TT_ULong script_tag;
+ TT_ULong script_offset;
+
+ TT_UShort num_langsys;
+ OTL_LangSys* langsys;
+ OTL_LangSys* langsys_default;
+
+ } OTL_Script;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* OTL_Script_List */
+ /* */
+ /* <Description> */
+ /* An OTL Script List record. */
+ /* */
+ /* <Fields> */
+ /* num_scripts :: The number of scripts records. */
+ /* scripts :: An array of script records. */
+ /* */
+ typedef struct OTL_Script_List_
+ {
+ TT_UShort num_scripts;
+ OTL_Script* scripts;
+
+ } OTL_Script_List;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* OTL_Feature */
+ /* */
+ /* <Description> */
+ /* An OTL Feature record. */
+ /* */
+ /* <Fields> */
+ /* feature_tag :: The feature tag. */
+ /* feature_offset :: The offset of the feature data in the resource. */
+ /* */
+ /* feature_params :: Always 0 for OpenType Layout 1.0. */
+ /* num_lookups :: The number of lookup indices. */
+ /* lookups :: An array of lookup indices. */
+ /* */
+ typedef struct OTL_Feature_
+ {
+ TT_ULong feature_tag;
+ TT_ULong feature_offset;
+
+ TT_UShort feature_params; /* always 0 for OpenType Layout 1.0 */
+ TT_UShort num_lookups;
+ TT_UShort* lookups;
+
+ } OTL_Feature;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* OTL_Feature_List */
+ /* */
+ /* <Description> */
+ /* An OTL Feature List record. */
+ /* */
+ /* <Fields> */
+ /* num_features :: The number of features. */
+ /* features :: An array of features. */
+ /* */
+ typedef struct OTL_Feature_List_
+ {
+ TT_UShort num_features;
+ OTL_Feature* features;
+
+ } OTL_Feature_List;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* OTL_Lookup */
+ /* */
+ /* <Description> */
+ /* An OTL Lookup record. */
+ /* */
+ /* <Fields> */
+ /* lookup_offset :: The offset of the lookup data in the resource. */
+ /* lookup_type :: The lookup type. */
+ /* lookup_flag :: The lookup bit flags. */
+ /* */
+ /* num_subtables :: The number of subtables. */
+ /* subtable_offsets :: An array of offsets to the subtables. */
+ /* subtables :: An array of pointers to the subtable records. */
+ /* */
+ /* <Note> */
+ /* The format of each lookup sub-table is determined by the parent */
+ /* OpenType table, and cannot be known here. */
+ /* */
+ /* The `subtable_offsets' array is filled when the lookup table is */
+ /* loaded the first time. It is up to OT table handlers to read the */
+ /* corresponding sub-table records and store them in the `subtables' */
+ /* array. */
+ /* */
+ typedef struct OTL_Lookup_
+ {
+ TT_ULong lookup_offset;
+ TT_UShort lookup_type;
+ TT_UShort lookup_flag;
+
+ TT_UShort num_subtables;
+ TT_ULong* subtable_offsets;
+ void** subtables;
+
+ } OTL_Lookup;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* OTL_Lookup_List */
+ /* */
+ /* <Description> */
+ /* An OTL Lookup List record. */
+ /* */
+ /* <Fields> */
+ /* num_lookups :: The number of lookups. */
+ /* lookups :: An array of lookups. */
+ /* */
+ typedef struct OTL_Lookup_List_
+ {
+ TT_UShort num_lookups;
+ OTL_Lookup* lookups;
+
+ } OTL_Lookup_List;
+
+
+#define OTL_LOOKUP_FLAG_RIGHT_TO_LEFT 1
+#define OTL_LOOKUP_FLAG_IGNORE_BASE_GLYPHS 2
+#define OTL_LOOKUP_FLAG_IGNORE_LIGATURES 4
+#define OTL_LOOKUP_FLAG_IGNORE_MARKS 8
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* OTL_SubTable1 */
+ /* */
+ /* <Description> */
+ /* The first generic OTL sub-table format. */
+ /* */
+ /* <Fields> */
+ /* num_indices :: The number of indices. */
+ /* indices :: An array of indices. */
+ /* data :: A generic value. */
+ /* */
+ typedef struct OTL_SubTable1_
+ {
+ TT_UShort num_indices;
+ TT_UShort* indices;
+ TT_UShort data;
+
+ } OTL_SubTable1;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* OTL_SubTable2_Rec */
+ /* */
+ /* <Description> */
+ /* A record for the second generic OTL sub-table format. */
+ /* */
+ /* <Fields> */
+ /* start :: The first element in the range. */
+ /* end :: The last element in the range. */
+ /* data :: A generic value. */
+ /* */
+ typedef struct OTL_SubTable2_Rec_
+ {
+ TT_UShort start;
+ TT_UShort end;
+ TT_UShort data;
+
+ } OTL_SubTable2_Rec;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* OTL_SubTable2 */
+ /* */
+ /* <Description> */
+ /* The second generic OTL sub-table format. */
+ /* */
+ /* <Fields> */
+ /* num_ranges :: The number of ranges. */
+ /* ranges :: An array of ranges. */
+ /* */
+ typedef struct OTL_SubTable2_
+ {
+ TT_UShort num_ranges;
+ OTL_SubTable2_Rec* ranges;
+
+ } OTL_SubTable2;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* OTL_SubTable */
+ /* */
+ /* <Description> */
+ /* A generic OTL sub-table which is a union of two possible formats */
+ /* just defined. */
+ /* */
+ /* <Fields> */
+ /* format :: The format of the sub-table. */
+ /* set :: A union of `format1' and `format2', representing */
+ /* sub-tables. */
+ /* */
+ typedef struct OTL_SubTable_
+ {
+ TT_UShort format;
+
+ union
+ {
+ OTL_SubTable1 format1;
+ OTL_SubTable2 format2;
+
+ } set;
+
+ } OTL_SubTable;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* OTL_Coverage */
+ /* */
+ /* <Description> */
+ /* An OTL Coverage sub-table. */
+ /* */
+ typedef OTL_SubTable OTL_Coverage;
+ typedef OTL_SubTable1 OTL_Coverage1;
+ typedef OTL_SubTable2 OTL_Coverage2;
+ typedef OTL_SubTable2_Rec OTL_Coverage2_Rec;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* OTL_Class_Def */
+ /* */
+ /* <Description> */
+ /* An OTL Class Definition sub-table. */
+ /* */
+ typedef OTL_SubTable OTL_Class_Def;
+ typedef OTL_SubTable1 OTL_Class_Def1;
+ typedef OTL_SubTable2 OTL_Class_Def2;
+ typedef OTL_SubTable2_Rec OTL_Class_Def2_Rec;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* OTL_Device */
+ /* */
+ /* <Description> */
+ /* An OTL Device sub-table */
+ /* */
+ /* <Fields> */
+ /* start_size :: The smallest size to correct. */
+ /* end_size :: The largest size to correct. */
+ /* delta_format :: The format of the `delta_values' array. */
+ /* delta_values :: An array of compressed delta values. */
+ typedef struct OTL_Device_
+ {
+ TT_UShort start_size;
+ TT_UShort end_size;
+ TT_UShort delta_format;
+ TT_UShort* delta_values;
+
+ } OTL_Device;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OTLAYOUT_H */
+
+
+/* END */
--- /dev/null
+++ b/src/shared/otlayout/otload.c
@@ -1,0 +1,890 @@
+/***************************************************************************/
+/* */
+/* otload.c */
+/* */
+/* OpenType Layout loader (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 <otlayout.h>
+#include <otload.h>
+
+#include <tterrors.h>
+
+
+ /***************************
+ * Script related functions
+ ***************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Free_Script_List */
+ /* */
+ /* <Description> */
+ /* Releases a given OpenType Script list. */
+ /* */
+ /* <Input> */
+ /* list :: The target script list. */
+ /* system :: The current system object. */
+ /* */
+ LOCAL_FUNC
+ void OTL_Free_Script_List( OTL_Script_List* list,
+ FT_System system )
+ {
+ if ( list )
+ {
+ if ( list->scripts )
+ {
+ OTL_Script* script = list->scripts;
+ OTL_Script* script_limit = script + list->num_scripts;
+
+
+ for ( ; script < script_limit; script++ )
+ {
+ if ( script->langsys )
+ {
+ OTL_LangSys* langsys = script->langsys;
+ OTL_LangSys* langsys_limit = langsys + script->num_langsys;
+
+
+ for ( ; langsys < langsys_limit; langsys++ )
+ {
+ FREE( langsys->feature_indices );
+ langsys->num_feature_indices = 0;
+ }
+ FREE( script->langsys );
+ }
+ script->langsys_default = NULL;
+ script->num_langsys = 0;
+ }
+ FREE( list->scripts );
+ }
+ list->num_scripts = 0;
+ }
+ }
+
+
+ static
+ TT_Error Load_OTL_LangSys_List( OTL_Script* script,
+ FT_Stream stream,
+ TT_ULong default_offset )
+ {
+ FT_System system = stream->system;
+ TT_Error error;
+
+ TT_UShort n, count;
+ OTL_LangSys* langsys;
+
+
+ /* read the langsys tags and offsets */
+ {
+ count = script->num_langsys;
+ langsys = script->langsys;
+
+ if ( ACCESS_Frame( 6L * count ) )
+ goto Exit;
+
+ for ( n = 0; n < count; n++, langsys++ )
+ {
+ TT_ULong offset;
+
+
+ langsys->lang_tag = GET_ULong();
+ offset = GET_UShort();
+
+ if ( langsys->lang_offset == default_offset )
+ script->langsys_default = langsys;
+
+ langsys->lang_offset = offset + script->script_offset;
+ }
+
+ FORGET_Frame();
+ }
+
+ /* now read each langsys record */
+ {
+ count = script->num_langsys;
+ langsys = script->langsys;
+
+ for ( n = 0; n < count; n++, langsys++ )
+ {
+ TT_UShort num_feature_indices, i;
+
+
+ if ( FILE_Seek( langsys->lang_offset ) ||
+ ACCESS_Frame( 8L ) )
+ goto Exit;
+
+ langsys->lookup_order = GET_ULong();
+ langsys->req_feature_index = GET_UShort();
+ langsys->num_feature_indices = GET_UShort();
+
+ FORGET_Frame();
+
+ num_feature_indices = langsys->num_feature_indices;
+
+ if ( ALLOC_ARRAY ( langsys->feature_indices,
+ num_feature_indices, TT_UShort ) ||
+ ACCESS_Frame( num_feature_indices * 2L ) )
+ goto Exit;
+
+ for ( i = 0; i < num_feature_indices; i++ )
+ langsys->feature_indices[i] = GET_UShort();
+
+ FORGET_Frame();
+ }
+ }
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Load_Script_List */
+ /* */
+ /* <Description> */
+ /* Loads an OpenType Script List from a font resource. */
+ /* */
+ /* <Input> */
+ /* list :: The target script list. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error OTL_Load_Script_List( OTL_Script_List* list,
+ FT_Stream stream )
+ {
+ FT_System system = stream->system;
+ TT_Error error;
+
+ TT_ULong start_pos;
+ TT_UShort num_scripts;
+ OTL_Script* scripts;
+
+
+ start_pos = FILE_Pos();
+
+ if ( READ_UShort( list->num_scripts ) )
+ goto Exit;
+
+ num_scripts = list->num_scripts;
+
+ /* Allocate the scripts table, read their tags and offsets */
+ {
+ TT_UShort n;
+
+
+ if ( ALLOC_ARRAY( list->scripts, num_scripts, OTL_Script ) ||
+ ACCESS_Frame( num_scripts * 6L ) )
+ goto Exit;
+
+ scripts = list->scripts;
+
+ for ( n = 0; n < num_scripts; n++ )
+ {
+ scripts[n].script_tag = GET_ULong();
+ scripts[n].script_offset = GET_UShort() + start_pos;
+ }
+
+ FORGET_Frame();
+ }
+
+ /* now read each script in the table */
+ {
+ TT_UShort n;
+ OTL_Script* script = scripts;
+
+
+ for ( n = num_scripts; n > 0; n--, script++ )
+ {
+ TT_ULong default_langsys_offset;
+
+
+ if ( FILE_Seek ( script->script_offset ) ||
+ READ_ULong ( default_langsys_offset ) ||
+ READ_UShort( script->num_langsys ) ||
+ ALLOC_ARRAY( script->langsys,
+ script->num_langsys, OTL_LangSys ) )
+ goto Exit;
+
+ /* read the corresponding langsys list */
+ error = Load_OTL_LangSys_List(
+ script,
+ stream,
+ default_langsys_offset + script->script_offset );
+ if ( error )
+ goto Exit;
+ }
+ }
+
+ Exit:
+ if ( error )
+ OTL_Free_Script_List( list, system );
+
+ return error;
+ }
+
+
+ /*********************************
+ * Feature List related functions
+ *********************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Free_Features_List */
+ /* */
+ /* <Description> */
+ /* Releases a given OpenType Features list. */
+ /* */
+ /* <Input> */
+ /* list :: The target feature list. */
+ /* system :: The current system object. */
+ /* */
+ LOCAL_FUNC
+ void OTL_Free_Features_List( OTL_Feature_List* list,
+ FT_System system )
+ {
+ if ( list )
+ {
+ if ( list->features )
+ {
+ OTL_Feature* feature = list->features;
+ OTL_Feature* feature_limit = feature + list->num_features;
+
+
+ for ( ; feature < feature_limit; feature++ )
+ {
+ FREE( feature->lookups );
+ feature->num_lookups = 0;
+ }
+
+ FREE( list->features );
+ }
+ list->num_features = 0;
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Load_Feature_List */
+ /* */
+ /* <Description> */
+ /* Loads an OpenType Feature List from a font resource. */
+ /* */
+ /* <Input> */
+ /* list :: The target feature list. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error OTL_Load_Feature_List( OTL_Feature_List* list,
+ FT_Stream stream )
+ {
+ FT_System system = stream->system;
+ TT_Error error;
+ TT_ULong start_pos;
+ TT_UShort num_features, n;
+
+
+ start_pos = FILE_Pos();
+
+ if ( READ_UShort( num_features ) )
+ goto Exit;
+
+ /* allocate the features array and read their tag and offset */
+ {
+ OTL_Feature* feature;
+ OTL_Feature* feature_limit;
+
+
+ if ( ALLOC_ARRAY ( list->features, num_features, OTL_Feature ) ||
+ ACCESS_Frame( num_features * 6L ) )
+ goto Exit;
+
+ list->num_features = num_features;
+ feature = list->features;
+ feature_limit = feature + num_features;
+
+ for ( ; feature < feature_limit; feature++ )
+ {
+ feature->feature_tag = GET_ULong();
+ feature->feature_offset = GET_UShort() + start_pos;
+ }
+
+ FORGET_Frame();
+ }
+
+ /* now read each feature */
+ {
+ OTL_Feature* feature;
+ OTL_Feature* feature_limit;
+
+
+ feature = list->features;
+ feature_limit = feature + num_features;
+
+ for ( ; feature < feature_limit; feature++ )
+ {
+ TT_UShort num_lookups;
+ TT_UShort* lookup;
+ TT_UShort* lookup_limit;
+
+
+ if ( FILE_Seek ( feature->feature_offset ) ||
+ READ_ULong ( feature->feature_params ) ||
+ READ_UShort ( num_lookups ) ||
+ ALLOC_ARRAY ( feature->lookups,
+ num_lookups, TT_UShort ) ||
+ ACCESS_Frame( num_lookups * 2L ) )
+ goto Exit;
+
+ feature->num_lookups = num_lookups;
+ lookup = feature->lookups;
+ lookup_limit = lookup + num_lookups;
+
+ for ( ; lookup < lookup_limit; lookup++ )
+ lookup[0] = GET_UShort();
+
+ FORGET_Frame();
+ }
+ }
+
+ Exit:
+ if ( error )
+ OTL_Free_Feature_List( list, system );
+
+ return error;
+ }
+
+
+ /********************************
+ * Lookup List related functions
+ ********************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Iterate_Lookup_List */
+ /* */
+ /* <Description> */
+ /* Scans an OpenType Lookup List. This can be used to load the */
+ /* Lookup sub-tables in a GSUB or GPOS loader. */
+ /* */
+ /* <Input> */
+ /* list :: The source list. */
+ /* iterator :: The iterator -- a function which is called on each */
+ /* element of the list. */
+ /* closure :: User-specified data which is passed to each iterator */
+ /* with the lookup element pointer. */
+ /* */
+ /* <Return> */
+ /* If one iterator call returns a non-zero `result', the list parsing */
+ /* is aborted and the value is returned to the caller. Otherwise, */
+ /* the function returns 0 when the list has been parsed completely. */
+ /* */
+ LOCAL_FUNC
+ TT_Error OTL_Iterate_Lookup_List( OTL_Lookup_List* list,
+ OTL_Lookup_Iterator iterator,
+ void* closure )
+ {
+ int result = 0;
+
+
+ if ( list->lookups )
+ {
+ OTL_Lookup* lookup = list->lookups;
+ OTL_Lookup* limit = lookup + list->num_lookups;
+
+
+ for ( ; lookup < limit; lookup++ )
+ {
+ result = iterator( lookup, closure );
+ if ( result )
+ break;
+ }
+ }
+
+ return 0;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Free_Lookup_List */
+ /* */
+ /* <Description> */
+ /* Releases a given OpenType Lookup list. Uses a destructor called */
+ /* to destroy the Lookup sub-tables. */
+ /* */
+ /* <Input> */
+ /* list :: The target lookup list. */
+ /* system :: The current system object. */
+ /* destructor :: A destructor function called on each lookup element. */
+ /* Can be used to destroy sub-tables. Ignored if NULL. */
+ /* */
+ LOCAL_FUNC
+ void OTL_Free_Lookup_List( OTL_Lookup_List* list,
+ FT_System system,
+ OTL_Lookup_Destructor destroy )
+ {
+ if ( list )
+ {
+ if ( list->lookups )
+ {
+ OTL_Lookup* lookup = list->lookups;
+ OTL_Lookup* limit = lookup + list->num_lookups;
+
+
+ for ( ; lookup < limit; lookup++ )
+ {
+ if ( destroy )
+ destroy( lookup, system );
+
+ FREE( lookup->subtable_offsets );
+ lookup->num_subtables = 0;
+ }
+
+ FREE( list->lookups );
+ }
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Load_Lookup_List */
+ /* */
+ /* <Description> */
+ /* Loads an OpenType Lookup List from a font resource. */
+ /* */
+ /* <Input> */
+ /* list :: The target lookup list. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* This function does NOT load the lookup sub-tables. Instead, it */
+ /* stores the file offsets of the particular table in each lookup */
+ /* element. It is up to the caller to load these sub-tables. This */
+ /* can be done more easily with OTL_Iterate_Lookup_List(). */
+ /* */
+ LOCAL_FUNC
+ TT_Error OTL_Load_Lookup_List( OTL_Lookup_List* list,
+ FT_Stream stream )
+ {
+ FT_System system = stream->system;
+ TT_Error error;
+
+ TT_UShort num_lookups;
+ TT_ULong start_pos;
+
+
+ start_pos = GET_ULong();
+
+ if ( READ_UShort( num_lookups ) )
+ goto Exit;
+
+ /* allocate the lookups array and read their tags and offset */
+ {
+ TT_UShort n;
+
+
+ if ( ALLOC_ARRAY ( list->lookups, num_lookups, OTL_Lookup ) ||
+ ACCESS_Frame( num_lookups * 2L ) )
+ goto Exit;
+
+ list->num_lookups = num_lookups;
+ for ( n = 0; n < num_lookups; n++ )
+ list->lookups[n].lookup_offset = start_pos + GET_UShort();
+
+ FORGET_Frame();
+ }
+
+ /* now read each lookup table */
+ /* NOTE that we don't load the sub-tables here, but simply */
+ /* store their file offsets in the `subtable_offsets' array */
+ {
+ OTL_Lookup* lookup = list->lookups;
+ OTL_Lookup* lookup_limit = lookup + num_lookups;
+
+
+ for ( ; lookup < lookup_limit; lookup++ )
+ {
+ TT_UShort n, num_subtables;
+ TT_ULong* offsets;
+
+
+ if ( FILE_Seek ( lookup->lookup_offset ) ||
+ ACCESS_Frame( 6L ) )
+ goto Exit;
+
+ lookup->lookup_type = GET_UShort();
+ lookup->lookup_flag = GET_UShort();
+ lookup->num_subtables = GET_UShort();
+
+ num_subtables = lookup->num_subtables;
+
+ FORGET_Frame();
+
+ if ( ALLOC_ARRAY ( lookup->subtable_offsets,
+ num_subtables, TT_ULong ) ||
+ ACCESS_Frame( num_subtables * 2L ) )
+ goto Exit;
+
+ offsets = lookup->subtable_offsets;
+ for ( n = 0; n < num_subtables; n++ )
+ offsets[n] = lookup->lookup_offset + GET_UShort();
+
+ FORGET_Frame();
+ }
+ }
+
+ Exit:
+ if ( error )
+ OTL_Free_Lookup_List( list, system, 0 );
+
+ return error;
+ }
+
+
+ /* generic sub-table freeing and loading */
+
+ static
+ void Free_SubTable( OTL_SubTable* subtable,
+ FT_System system )
+ {
+ if ( subtable )
+ {
+ switch ( subtable->format )
+ {
+ case 1:
+ {
+ OTL_SubTable1* st = &subtable->set.format1;
+
+
+ FREE( st->indices );
+ st->num_indices = 0;
+ FREE( st );
+ }
+ break;
+
+ case 2:
+ {
+ OTL_SubTable2* st = &subtable->set.format2;
+
+
+ FREE( st->ranges );
+ st->num_ranges = 0;
+ FREE( st );
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ FREE( subtable );
+ }
+ }
+
+
+ static
+ TT_Error Load_SubTable( OTL_SubTable* subtable,
+ FT_Stream stream )
+ {
+ FT_System system = stream->system;
+ TT_Error error;
+
+
+ if ( READ_UShort( subtable->format ) )
+ goto Exit;
+
+ switch ( subtable->format )
+ {
+ case 1:
+ {
+ OTL_SubTable1* st = &subtable->set.format1;
+ TT_UShort num_indices, n;
+
+
+ if ( READ_UShort ( num_indices ) ||
+ ALLOC_ARRAY ( st->indices, num_indices, TT_UShort ) ||
+ ACCESS_Frame( num_indices * 2L ) )
+ goto Exit;
+
+ st->num_indices = num_indices;
+ for ( n = 0; n < num_indices; n++ )
+ st->indices[n] = GET_UShort();
+
+ FORGET_Frame();
+ }
+
+ case 2:
+ {
+ OTL_SubTable2* st = &subtable->set.format2;
+ TT_UShort num_ranges, n;
+ OTL_SubTable2_Rec* range;
+
+
+ if ( READ_UShort( num_ranges ) ||
+ ALLOC_ARRAY( st->ranges, num_ranges, OTL_SubTable2_Rec ) ||
+ ACCESS_Frame( num_ranges * 6L ) )
+ goto Exit;
+
+ st->num_ranges = num_ranges;
+ range = st->ranges;
+ for ( ; num_ranges > 0; num_ranges--, range++ )
+ {
+ range->start = GET_UShort();
+ range->end = GET_UShort();
+ range->data = GET_UShort();
+ }
+
+ FORGET_Frame();
+ }
+ break;
+
+ default:
+ error = TT_Err_Invalid_File_Format;
+ }
+
+ Exit:
+ if ( error )
+ Free_SubTable( subtable, system );
+
+ return error;
+ }
+
+
+ /*****************************
+ * Coverage related functions
+ *****************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Free_Coverage */
+ /* */
+ /* <Description> */
+ /* Releases a given OpenType Coverage table. */
+ /* */
+ /* <Input> */
+ /* coverage :: The target coverage. */
+ /* system :: The current system object. */
+ /* */
+ LOCAL_FUNC
+ void OTL_Free_Coverage( OTL_Coverage* coverage,
+ FT_System system )
+ {
+ Free_SubTable( (OTL_SubTable*)coverage, system );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Load_Coverage */
+ /* */
+ /* <Description> */
+ /* Loads an OpenType Coverage table from a font resource. */
+ /* */
+ /* <Input> */
+ /* coverage :: The target coverage. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error OTL_Load_Coverage( OTL_Coverage* coverage,
+ FT_Stream stream )
+ {
+ return Load_SubTable( (OTL_SubTable*)coverage, stream );
+ }
+
+
+ /*************************************
+ * Class Definition related functions
+ *************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Free_Class_Def */
+ /* */
+ /* <Description> */
+ /* Releases a given OpenType Class Definition table. */
+ /* */
+ /* <Input> */
+ /* class_def :: The target class definition. */
+ /* system :: The current system object. */
+ /* */
+ LOCAL_FUNC
+ void OTL_Free_Class_Def( OTL_Class_Def* class_def,
+ FT_System system )
+ {
+ Free_SubTable( (OTL_SubTable*)class_def, system );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Load_Class_Def */
+ /* */
+ /* <Description> */
+ /* Loads an OpenType Class Definition table from a resource. */
+ /* */
+ /* <Input> */
+ /* class_def :: The target class definition. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error OTL_Load_Class_Def( OTL_Class_Def* class_def,
+ FT_Stream stream )
+ {
+ return OTL_Load_SubTable( (OTL_SubTable*)class_def, stream );
+ }
+
+
+ /*************************************
+ * Device related functions
+ *************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Free_Device */
+ /* */
+ /* <Description> */
+ /* Releases a given OpenType Layout Device table. */
+ /* */
+ /* <Input> */
+ /* device :: The target device table. */
+ /* system :: The current system object. */
+ /* */
+ LOCAL_FUNC
+ void OTL_Free_Device( OTL_Device* device,
+ FT_System system )
+ {
+ if ( device )
+ {
+ FREE( device->delta_values );
+ FREE( device );
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Load_Device */
+ /* */
+ /* <Description> */
+ /* Loads an OpenType Device table from a font resource. */
+ /* */
+ /* <Input> */
+ /* device :: The target device table. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error OTL_Load_Device( OTL_Device* device,
+ FT_Stream stream )
+ {
+ FT_System system = stream->system;
+ TT_Error error;
+ TT_UShort* deltas;
+ TT_UShort num_deltas, num_values;
+
+
+ if ( ACCESS_Frame( 6L ) )
+ goto Exit;
+
+ device->start_size = GET_UShort();
+ device->end_size = GET_UShort();
+ device->delta_format = GET_UShort();
+
+ FORGET_Frame();
+
+ num_deltas = device->end_size - device->start_size + 1;
+
+ switch ( device->delta_format )
+ {
+ case 1:
+ num_values = ( num_deltas + 7 ) >> 3;
+ break;
+
+ case 2:
+ num_values = ( num_deltas + 3 ) >> 2;
+ break;
+
+ case 3:
+ num_values = ( num_deltas + 1 ) >> 1;
+ break;
+
+ default:
+ error = TT_Err_Invalid_File_Format;
+ goto Exit;
+ }
+
+ if ( ALLOC_ARRAY( deltas, num_values, TT_UShort ) )
+ goto Exit;
+
+ if ( !ACCESS_Frame( num_values * 2L ) )
+ {
+ TT_UShort n;
+
+
+ for ( n = 0; n < num_values; n++ )
+ deltas[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ device->delta_values = deltas;
+ }
+ else
+ FREE( deltas );
+
+ Exit:
+ return error;
+ }
+
+
+/* END */
--- /dev/null
+++ b/src/shared/otlayout/otload.h
@@ -1,0 +1,297 @@
+/***************************************************************************/
+/* */
+/* otload.h */
+/* */
+/* OpenType layout loader functions (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 OTLOAD_H
+#define OTLOAD_H
+
+#include <otlayout.h>
+#include <ftstream.h>
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Load_Script_List */
+ /* */
+ /* <Description> */
+ /* Loads an OpenType Script List from a font resource. */
+ /* */
+ /* <Input> */
+ /* list :: The target script list. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error OTL_Load_Script_List( OTL_Script_List* list,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Load_Feature_List */
+ /* */
+ /* <Description> */
+ /* Loads an OpenType Feature List from a font resource. */
+ /* */
+ /* <Input> */
+ /* list :: The target feature list. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error OTL_Load_Feature_List( OTL_Feature_List* list,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Load_Lookup_List */
+ /* */
+ /* <Description> */
+ /* Loads an OpenType Lookup List from a font resource. */
+ /* */
+ /* <Input> */
+ /* list :: The target lookup list. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* This function does NOT load the lookup sub-tables. Instead, it */
+ /* stores the file offsets of the particular table in each lookup */
+ /* element. It is up to the caller to load these sub-tables. This */
+ /* can be done more easily with OTL_Iterate_Lookup_List(). */
+ /* */
+ LOCAL_DEF
+ TT_Error OTL_Load_Lookup_List( OTL_Lookup_List* list,
+ FT_Stream stream );
+
+
+ typedef int OTL_Lookup_Iterator( OTL_Lookup* lookup,
+ void* closure );
+
+
+ typedef void OTL_Lookup_Destructor( OTL_Lookup* lookup,
+ FT_System system );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Iterate_Lookup_List */
+ /* */
+ /* <Description> */
+ /* Scans an OpenType Lookup List. This can be used to load the */
+ /* Lookup sub-tables in a GSUB or GPOS loader. */
+ /* */
+ /* <Input> */
+ /* list :: The source list. */
+ /* iterator :: The iterator -- a function which is called on each */
+ /* element of the list. */
+ /* closure :: User-specified data which is passed to each iterator */
+ /* with the lookup element pointer. */
+ /* */
+ /* <Return> */
+ /* If one iterator call returns a non-zero `result', the list parsing */
+ /* is aborted and the value is returned to the caller. Otherwise, */
+ /* the function returns 0 when the list has been parsed completely. */
+ /* */
+ LOCAL_DEF
+ TT_Error OTL_Iterate_Lookup_List( OTL_Lookup_List* list,
+ OTL_Lookup_Iterator iterator,
+ void* closure );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Load_Coverage */
+ /* */
+ /* <Description> */
+ /* Loads an OpenType Coverage table from a font resource. */
+ /* */
+ /* <Input> */
+ /* coverage :: The target coverage. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error OTL_Load_Coverage( OTL_Coverage* coverage,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Load_Class_Def */
+ /* */
+ /* <Description> */
+ /* Loads an OpenType Class Definition table from a resource. */
+ /* */
+ /* <Input> */
+ /* class_def :: The target class definition. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error OTL_Load_Class_Def( OTL_Class_Def* class_def,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Load_Device */
+ /* */
+ /* <Description> */
+ /* Loads an OpenType Device table from a font resource. */
+ /* */
+ /* <Input> */
+ /* device :: The target device table. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error OTL_Load_Device( OTL_Device* device,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Free_Script_List */
+ /* */
+ /* <Description> */
+ /* Releases a given OpenType Script list. */
+ /* */
+ /* <Input> */
+ /* list :: The target script list. */
+ /* system :: The current system object. */
+ /* */
+ LOCAL_DEF
+ void OTL_Free_Script_List( OTL_Script_List* list,
+ FT_System system );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Free_Features_List */
+ /* */
+ /* <Description> */
+ /* Releases a given OpenType Features list. */
+ /* */
+ /* <Input> */
+ /* list :: The target feature list. */
+ /* system :: The current system object. */
+ /* */
+ LOCAL_DEF
+ void OTL_Free_Features_List( OTL_Feature_List* list,
+ FT_System system );
+
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Free_Lookup_List */
+ /* */
+ /* <Description> */
+ /* Releases a given OpenType Lookup list. Uses a destructor called */
+ /* to destroy the Lookup sub-tables. */
+ /* */
+ /* <Input> */
+ /* list :: The target lookup list. */
+ /* system :: The current system object. */
+ /* destructor :: A destructor function called on each lookup element. */
+ /* Can be used to destroy sub-tables. Ignored if NULL. */
+ /* */
+ LOCAL_DEF
+ void OTL_Free_Lookup_List( OTL_Lookup_List* list,
+ FT_System system,
+ OTL_Lookup_Destructor destroy );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Free_Coverage */
+ /* */
+ /* <Description> */
+ /* Releases a given OpenType Coverage table. */
+ /* */
+ /* <Input> */
+ /* coverage :: The target coverage. */
+ /* system :: The current system object. */
+ /* */
+ LOCAL_DEF
+ void OTL_Free_Coverage( OTL_Coverage* coverage,
+ FT_System system );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Free_Class_Def */
+ /* */
+ /* <Description> */
+ /* Releases a given OpenType Class Definition table. */
+ /* */
+ /* <Input> */
+ /* class_def :: The target class definition. */
+ /* system :: The current system object. */
+ /* */
+ LOCAL_DEF
+ void OTL_Free_Class_Def( OTL_Class_Def* class_def,
+ FT_System system );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* OTL_Free_Device */
+ /* */
+ /* <Description> */
+ /* Releases a given OpenType Layout Device table. */
+ /* */
+ /* <Input> */
+ /* device :: The target device table. */
+ /* system :: The current system object. */
+ /* */
+ LOCAL_DEF
+ void OTL_Free_Device( OTL_Device* device,
+ FT_System system );
+
+
+#endif /* OTLOAD_H */
+
+
+/* END */
--- /dev/null
+++ b/src/shared/readme.txt
@@ -1,0 +1,6 @@
+WARNING:
+
+The files in these subdirectories are shared by several font drivers.
+
+All C source files are included by at least one of the drivers, and
+thus should _never_ be compiled directly.
--- /dev/null
+++ b/src/shared/rules.mk
@@ -1,0 +1,95 @@
+#****************************************************************************
+#* *
+#* shared files Makefile *
+#* *
+#* 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. *
+#* *
+#****************************************************************************
+
+
+#****************************************************************************
+#* *
+#* IMPORTANT NOTE: This Makefile is intended for GNU Make! *
+#* If you provide Makefiles for other make utilities, *
+#* please place them in `freetype/lib/arch/<system>'. *
+#* *
+#* *
+#* This file is to be included by the FreeType Makefile.lib, located in *
+#* the `freetype/lib' directory. Here is the list of the variables that *
+#* must be defined to use it: *
+#* *
+#* *
+#* BASE_DIR: The location of the base layer's directory. This is *
+#* usually `freetype/lib/base'. *
+#* *
+#* ARCH_DIR: The location of the architecture-dependent directory. *
+#* This is usually `freetype/lib/arch/<system>'. *
+#* *
+#* DRIVERS_DIR: The location of the font driver sub-dirs, usually *
+#* `freetype/lib/drivers'. *
+#* *
+#* OBJ_DIR: The location where the compiled object(s) file will be *
+#* placed. *
+#* *
+#* BASE_H: A list of pathnames to the base layer's header files on *
+#* which the driver depends. *
+#* *
+#* FT_CFLAGS: A set of flags used for compilation of object files. *
+#* This contains at least the include paths of the arch *
+#* and base directories + optimization + warnings + ANSI *
+#* compliance. *
+#* *
+#* FT_IFLAG: The flag used to specify an include path on the *
+#* compiler command line. For example, with GCC, this is *
+#* `-I', while some other compilers use `/i=' or `-J', *
+#* etc. *
+#* *
+#* FT_OBJ: The suffix of an object file for the platform; can be *
+#* `o', `obj', `coff', `tco', etc. depending on the *
+#* platform. *
+#* *
+#* *
+#* It also updates the following variables defined and used in the main *
+#* Makefile: *
+#* *
+#* DRV_OBJ_S: The list of driver object files in *
+#* single-object mode. *
+#* *
+#* DRV_OBJ_M: The list of driver object files in *
+#* multiple-objects mode. *
+#* *
+#* FTINIT_DRIVER_PATHS: The list of include paths used to compile the *
+#* `ftinit' component which registers all font *
+#* drivers in the FT_Init_FreeType() function. *
+#* *
+#* FTINIT_DRIVER_H: The list of header dependencies used to *
+#* compile the `ftinit' component. *
+#* *
+#* FTINIT_DRIVER_MACROS: The list of macros to be defined when *
+#* compiling the `ftinit' component. *
+#* *
+#* `Single-object compilation' means that each font driver is compiled *
+#* into a single object file. This is useful to get rid of all *
+#* driver-specific entries. *
+#* *
+#****************************************************************************
+
+ifndef SHARED_RULES
+SHARED_RULES := 1
+
+SHARED := $(SRC_)shared
+SHARED_ := $(SHARED)$(SEP)
+
+SHARED_H := $(wildcard $(SHARED_)*.h)
+SHARED_SRC := $(wildcard $(SHARED_)*.c)
+
+endif
+
+# END
--- /dev/null
+++ b/src/shared/sfnt.h
@@ -1,0 +1,347 @@
+/***************************************************************************/
+/* */
+/* sfnt.h */
+/* */
+/* High-level `sfnt' driver 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. */
+/* */
+/***************************************************************************/
+
+
+#ifndef SFNT_H
+#define SFNT_H
+
+#include <freetype.h>
+#include <tttypes.h>
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* TT_Load_Directory_Func */
+ /* */
+ /* <Description> */
+ /* Loads the table directory into a face object. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* faceIndex :: The index of the TrueType font, if we're opening a */
+ /* collection. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* The stream cursor must be at the font file's origin */
+ /* */
+ typedef
+ TT_Error (*TT_Load_Directory_Func)( TT_Face face,
+ FT_Stream stream,
+ TT_Long faceIndex );
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* TT_Load_Any_Func */
+ /* */
+ /* <Description> */
+ /* Loads any font table into client memory. Used by the */
+ /* TT_Get_Font_Data() API function. */
+ /* */
+ /* <Input> */
+ /* face :: The face object to look for. */
+ /* */
+ /* tag :: The tag of table to load. Use the value 0 if you want */
+ /* to access the whole font file, else set this parameter */
+ /* to a valid TrueType table tag that you can forge with */
+ /* the MAKE_TT_TAG macro. */
+ /* */
+ /* offset :: The starting offset in the table (or the file if */
+ /* tag == 0). */
+ /* */
+ /* length :: The address of the decision variable: */
+ /* */
+ /* If length == NULL: */
+ /* Loads the whole table. Returns an error if */
+ /* `offset' == 0! */
+ /* */
+ /* If *length == 0: */
+ /* Exits immediately; returning the length of the given */
+ /* table or of the font file, depending on the value of */
+ /* `tag'. */
+ /* */
+ /* If *length != 0: */
+ /* Loads the next `length' bytes of table or font, */
+ /* starting at offset `offset' (in table or font too). */
+ /* */
+ /* <Output> */
+ /* buffer :: The address of target buffer. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ typedef
+ TT_Error (*TT_Load_Any_Func)( TT_Face face,
+ TT_ULong tag,
+ TT_Long offset,
+ void* buffer,
+ TT_Long* length );
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* TT_Load_SBit_Image_Func */
+ /* */
+ /* <Description> */
+ /* Loads a given glyph sbit image from the font resource. This also */
+ /* returns its metrics. */
+ /* */
+ /* <Input> */
+ /* face :: The target face object. */
+ /* */
+ /* x_ppem :: The horizontal resolution in points per EM. */
+ /* */
+ /* y_ppem :: The vertical resolution in points per EM. */
+ /* */
+ /* glyph_index :: The current glyph index. */
+ /* */
+ /* stream :: The input stream. */
+ /* */
+ /* <Output> */
+ /* map :: The target pixmap. */
+ /* metrics :: A big sbit metrics structure for the glyph image. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. Returns an error if no */
+ /* glyph sbit exists for the index. */
+ /* */
+ /* <Note> */
+ /* The `map.buffer' field is always freed before the glyph is loaded. */
+ /* */
+ typedef
+ TT_Error (*TT_Load_SBit_Image_Func)( TT_Face face,
+ TT_Int x_ppem,
+ TT_Int y_ppem,
+ TT_UInt glyph_index,
+ FT_Stream stream,
+ FT_Bitmap* map,
+ TT_SBit_Metrics* metrics );
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* TT_Get_PS_Name_Func */
+ /* */
+ /* <Description> */
+ /* Gets the PostScript glyph name of a glyph. */
+ /* */
+ /* <Input> */
+ /* index :: The glyph index. */
+ /* */
+ /* PSname :: The address of a string pointer. Will be NULL in case */
+ /* of error, otherwise it is a pointer to the glyph name. */
+ /* */
+ /* You must not modify the returned string! */
+ /* */
+ /* <Output> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ typedef
+ TT_Error (*TT_Get_PS_Name_Func)( TT_Face face,
+ TT_UInt index,
+ TT_String** PSname );
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* TT_Load_Metrics */
+ /* */
+ /* <Description> */
+ /* Loads the horizontal or vertical header in a face object. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* vertical :: A boolean flag. If set, load vertical metrics. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ typedef
+ TT_Error (*TT_Load_Metrics_Func)( TT_Face face,
+ FT_Stream stream,
+ TT_Bool vertical );
+
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* TT_CharMap_Load_Func */
+ /* */
+ /* <Description> */
+ /* Loads a given TrueType character map into memory. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the parent face object. */
+ /* stream :: A handle to the current stream object. */
+ /* */
+ /* <InOut> */
+ /* cmap :: A pointer to a cmap object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* The function assumes that the stream is already in use (i.e., */
+ /* opened). In case of error, all partially allocated tables are */
+ /* released. */
+ /* */
+ typedef
+ TT_Error (*TT_CharMap_Load_Func)( TT_Face face,
+ TT_CMapTable* cmap,
+ FT_Stream input );
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* TT_CharMap_Free_Func */
+ /* */
+ /* <Description> */
+ /* Destroys a character mapping table. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the parent face object. */
+ /* cmap :: A handle to a cmap object. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ typedef
+ TT_Error (*TT_CharMap_Free_Func)( TT_Face face,
+ TT_CMapTable* cmap );
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* TT_Load_Table */
+ /* */
+ /* <Description> */
+ /* Loads a given TrueType table. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* The function will use `face->goto_table' to seek the stream to */
+ /* the start of the table */
+ /* */
+ typedef
+ TT_Error (*TT_Load_Table_Func)( TT_Face face,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* TT_Load_Table */
+ /* */
+ /* <Description> */
+ /* Loads a given TrueType table. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* The function will use `face->goto_table' to seek the stream to */
+ /* the start of the table */
+ /* */
+ typedef
+ void (*TT_Free_Table_Func)( TT_Face face );
+
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* SFNT_Interface */
+ /* */
+ /* <Description> */
+ /* this structure holds pointers to the functions used to load and */
+ /* free the basic tables that are required in a `sfnt' font file. */
+ /* */
+ /* <Fields> */
+ /* */
+ /* */
+ /* */
+ /* */
+ /* */
+ /* */
+ /* */
+ /* */
+ typedef struct SFNT_Interface_
+ {
+ TT_Goto_Table_Func goto_table;
+
+ TT_Load_Any_Func load_any;
+ TT_Load_Directory_Func load_directory;
+
+ TT_Load_Table_Func load_header;
+ TT_Load_Metrics_Func load_metrics;
+ TT_Load_Table_Func load_charmaps;
+ TT_Load_Table_Func load_max_profile;
+ TT_Load_Table_Func load_os2;
+ TT_Load_Table_Func load_psnames;
+
+ TT_Load_Table_Func load_names;
+ TT_Free_Table_Func free_names;
+
+ /* optional tables */
+ TT_Load_Table_Func load_hdmx;
+ TT_Free_Table_Func free_hdmx;
+
+ TT_Load_Table_Func load_kerning;
+ TT_Load_Table_Func load_gasp;
+
+
+ /* see `ttsbit.h' */
+ TT_Load_Table_Func load_sbits;
+ TT_Load_SBit_Image_Func load_sbit_image;
+ TT_Free_Table_Func free_sbits;
+
+ /* see `ttpost.h' */
+ TT_Get_PS_Name_Func get_psname;
+ TT_Free_Table_Func free_psnames;
+
+ /* see `ttcmap.h' */
+ TT_CharMap_Load_Func load_charmap;
+ TT_CharMap_Free_Func free_charmap;
+
+ } SFNT_Interface;
+
+#endif /* SFNT_H */
+
+
+/* END */
--- /dev/null
+++ b/src/shared/sfnt/rules.mk
@@ -1,0 +1,58 @@
+#****************************************************************************
+#* *
+#* SFNT/TrueType Makefile *
+#* *
+#* 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. *
+#* *
+#****************************************************************************
+
+
+#****************************************************************************
+#* *
+#* IMPORTANT NOTE: This Makefile is intended for GNU Make! *
+#* If you provide Makefiles for other make utilities, *
+#* please place them in `freetype/lib/arch/<system>'. *
+#* *
+#* *
+#* This file is to be included by the Makefiles of each driver that uses *
+#* the shared source code in `freetype2/lib/drivers/sfnt'. This code *
+#* contains type definitions as well as interface which are common to all *
+#* `sfnt' font formats (i.e., TrueType, OpenType-TTF, and OpenType-CFF). *
+#* *
+#* *
+#* The purpose of this Makefile is to define two make variables that are *
+#* used directly by the parent Makefile. *
+#* *
+#****************************************************************************
+
+
+# SFNT_DIR is the directory to the `sfnt' sources
+#
+SFNT_DIR := $(SRC)$(SEP)shared$(SEP)sfnt
+SFNT_DIR_ := $(SFNT_DIR)$(SEP)
+
+
+# SFNT_H is the list of all header files on which the client drivers depend
+#
+SFNT_H := $(SFNT_DIR_)tttypes.h \
+ $(SFNT_DIR_)ttload.h \
+ $(SFNT_DIR_)ttsbit.h \
+ $(SFNT_DIR_)ttpost.h \
+ $(SFNT_DIR_)sfnt.h
+
+# SFNT_SRC is the list of all shared source files that are included by any
+# client driver
+#
+SFNT_SRC := $(SFNT_DIR_)ttload.c \
+ $(SFNT_DIR_)ttsbit.c \
+ $(SFNT_DIR_)ttpost.c
+
+
+# END
--- /dev/null
+++ b/src/shared/sfnt/sfnt.h
@@ -1,0 +1,50 @@
+/***************************************************************************/
+/* */
+/* sfnt.h */
+/* */
+/* Defines the function interface used to access SFNT files, i.e., */
+/* TrueType, OpenType-TT, and OpenType-T2 files (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 SFNT_H
+#define SFNT_H
+
+#include <tttypes.h>
+
+
+ typedef TT_Long (*SFNT_LookUp_Table)( TT_Face face,
+ TT_ULong tag );
+
+
+ typedef TT_Error (*SFNT_Load_Table)( TT_Face face,
+ TT_ULong tag,
+ TT_Long offset,
+ void* buffer,
+ TT_Long* length );
+
+ typedef TT_Error (*SFNT_Get_PS_Name)( TT_Face face,
+ TT_UShort index,
+ TT_String* *ps_name );
+
+ typedef struct SFNT_Interface_
+ {
+ SFNT_LookUp_Table lookup_table;
+ SFNT_Load_Table load_table;
+
+ } SFNT_Interface;
+
+
+#endif /* SFNT_H */
+
+
+/* END */
--- /dev/null
+++ b/src/shared/sfnt/ttload.c
@@ -1,0 +1,1488 @@
+/***************************************************************************/
+/* */
+/* ttload.c */
+/* */
+/* TrueType tables loader (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. */
+/* */
+/* */
+/* WARNING: This file should not be compiled directly; it is meant to be */
+/* included in the source of several font drivers (i.e., the TTF */
+/* and OTF drivers). */
+/* */
+/***************************************************************************/
+
+
+#include <ftdebug.h>
+
+#include <ttload.h>
+#include <tttags.h>
+#include <ttcmap.h>
+
+
+/* required by the tracing mode */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_ttload
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_LookUp_Table */
+ /* */
+ /* <Description> */
+ /* Looks for a TrueType table by name. */
+ /* */
+ /* <Input> */
+ /* face :: A face object handle. */
+ /* tag :: The searched tag. */
+ /* */
+ /* <Return> */
+ /* Index of table if found, -1 otherwise. */
+ /* */
+ EXPORT_FUNC
+ FT_Long TT_LookUp_Table( TT_Face face,
+ TT_ULong tag )
+ {
+ TT_Long i, found;
+
+
+ FT_TRACE4(( "TT_LookUp_Table( %08lx, %c%c%c%c )\n",
+ (TT_Long)face,
+ (TT_Char)(tag >> 24),
+ (TT_Char)(tag >> 16),
+ (TT_Char)(tag >> 8),
+ (TT_Char)(tag) ));
+
+ found = -1;
+ for ( i = 0; i < face->num_tables; i++ )
+ if ( face->dir_tables[i].Tag == tag )
+ {
+ found = i;
+ break;
+ }
+
+ if ( found == -1 )
+ {
+ FT_TRACE4(( " Could not find table!\n" ));
+ }
+
+ return found;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Collection */
+ /* */
+ /* <Description> */
+ /* Loads the TTC table directory into face table. */
+ /* */
+ /* <Input> */
+ /* face :: A face object handle. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ static
+ TT_Error TT_Load_Collection( TT_Face face,
+ FT_Stream stream )
+ {
+ TT_Long n;
+ TT_Error error;
+ FT_Memory memory = stream->memory;
+
+
+ FT_TRACE3(( "TT_Load_Collection( %08lx )\n", (TT_Long)face ));
+
+ if ( FILE_Seek ( 0L ) ||
+ ACCESS_Frame( 12L ) )
+ goto Exit;
+
+ face->ttc_header.Tag = GET_Tag4();
+ face->ttc_header.version = GET_Long();
+ face->ttc_header.DirCount = GET_Long(); /* see comment in tttypes.h */
+
+ FORGET_Frame();
+
+ if ( face->ttc_header.Tag != TTAG_ttcf )
+ {
+ face->ttc_header.Tag = 0;
+ face->ttc_header.version = 0;
+ face->ttc_header.DirCount = 0;
+
+ face->ttc_header.TableDirectory = NULL;
+
+ FT_TRACE3(( "skipped.\n" ));
+
+ error = TT_Err_File_Is_Not_Collection;
+ goto Exit;
+ }
+
+ if ( ALLOC_ARRAY( face->ttc_header.TableDirectory,
+ face->ttc_header.DirCount,
+ TT_ULong ) ||
+ ACCESS_Frame( face->ttc_header.DirCount * 4L ) )
+ goto Exit;
+
+ for ( n = 0; n < face->ttc_header.DirCount; n++ )
+ face->ttc_header.TableDirectory[n] = GET_ULong();
+
+ FORGET_Frame();
+
+ FT_TRACE3(( "collections directory loaded.\n" ));
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Directory */
+ /* */
+ /* <Description> */
+ /* Loads the table directory into a face object. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* faceIndex :: The index of the TrueType font, if we're opening a */
+ /* collection. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_Directory( TT_Face face,
+ FT_Stream stream,
+ TT_Long faceIndex )
+ {
+ TT_Error error;
+ FT_Memory memory = stream->memory;
+
+ TT_UShort n, limit;
+ TT_TableDir tableDir;
+
+ TT_TableDirEntry* entry;
+
+
+ FT_TRACE2(( "TT_Load_Directory( %08lx, %ld )\n",
+ (TT_Long)face, faceIndex ));
+
+ error = TT_Load_Collection( face, stream );
+ if ( error )
+ {
+ /* if this is a `traditional' error, exit now */
+ if ( error != TT_Err_File_Is_Not_Collection )
+ goto Exit;
+
+ /* the file isn't a collection, exit if we're asking */
+ /* for a collected font */
+
+ /* Note that we don't exit during font format checking (i.e., */
+ /* faceIndex is -1) */
+ if ( faceIndex > 0 )
+ goto Exit;
+
+ /* Now skip to the beginning of the file */
+ if ( FILE_Seek( 0 ) )
+ goto Exit;
+ }
+ else
+ {
+ /* The file is a collection. Check the font index */
+ if ( faceIndex >= face->ttc_header.DirCount )
+ {
+ error = TT_Err_Bad_Argument;
+ goto Exit;
+ }
+
+ /* if we're checking the font format, exit immediately */
+ if ( faceIndex < 0 )
+ goto Exit;
+
+ /* select a TrueType font in the ttc file */
+ if ( FILE_Seek( face->ttc_header.TableDirectory[faceIndex] ) )
+ goto Exit;
+ }
+
+ if ( ACCESS_Frame( 12L ) )
+ goto Exit;
+
+ tableDir.version = GET_Long();
+ tableDir.numTables = GET_UShort();
+
+ tableDir.searchRange = GET_UShort();
+ tableDir.entrySelector = GET_UShort();
+ tableDir.rangeShift = GET_UShort();
+
+ FORGET_Frame();
+
+ FT_TRACE2(( "-- Tables count : %12u\n", tableDir.numTables ));
+ FT_TRACE2(( "-- Format version : %08lx\n", tableDir.version ));
+
+ /* Check that we have a `sfnt' format there */
+ /* We must also be able to accept Mac/GX fonts, as well as OT ones */
+
+ if ( tableDir.version != 0x00010000 &&
+ tableDir.version != TTAG_true &&
+ tableDir.version != TTAG_OTTO )
+ {
+ FT_TRACE2(( "[not a valid TTF or OTF font]" ));
+ error = TT_Err_Invalid_File_Format;
+ goto Exit;
+ }
+
+ /* if we're performing a font format check, exit immediately */
+ /* with success */
+ if ( faceIndex < 0 )
+ goto Exit;
+
+ face->num_tables = tableDir.numTables;
+
+ if ( ALLOC_ARRAY( face->dir_tables,
+ face->num_tables,
+ TT_TableDirEntry ) )
+ goto Exit;
+
+ if ( ACCESS_Frame( face->num_tables * 16L ) )
+ goto Exit;
+
+ limit = face->num_tables;
+ entry = face->dir_tables;
+
+ 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();
+
+ FT_TRACE2(( " %c%c%c%c - %08lx - %08lx\n",
+ (TT_Char)(entry->Tag >> 24),
+ (TT_Char)(entry->Tag >> 16),
+ (TT_Char)(entry->Tag >> 8 ),
+ (TT_Char)(entry->Tag),
+ entry->Offset,
+ entry->Length ));
+ entry++;
+ }
+
+ FORGET_Frame();
+
+ FT_TRACE2(( "Directory loaded\n\n" ));
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Any */
+ /* */
+ /* <Description> */
+ /* Loads any font table into client memory. Used by the */
+ /* TT_Get_Font_Data() API function. */
+ /* */
+ /* <Input> */
+ /* face :: The face object to look for. */
+ /* */
+ /* tag :: The tag of table to load. Use the value 0 if you want */
+ /* to access the whole font file, else set this parameter */
+ /* to a valid TrueType table tag that you can forge with */
+ /* the MAKE_TT_TAG macro. */
+ /* */
+ /* offset :: The starting offset in the table (or the file if */
+ /* tag == 0). */
+ /* */
+ /* length :: The address of the decision variable: */
+ /* */
+ /* If length == NULL: */
+ /* Loads the whole table. Returns an error if */
+ /* `offset' == 0! */
+ /* */
+ /* If *length == 0: */
+ /* Exits immediately; returning the length of the given */
+ /* table or of the font file, depending on the value of */
+ /* `tag'. */
+ /* */
+ /* If *length != 0: */
+ /* Loads the next `length' bytes of table or font, */
+ /* starting at offset `offset' (in table or font too). */
+ /* */
+ /* <Output> */
+ /* buffer :: The address of target buffer. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_Any( TT_Face face,
+ TT_ULong tag,
+ TT_Long offset,
+ void* buffer,
+ TT_Long* length )
+ {
+ TT_Error error;
+ FT_Stream stream;
+ TT_Long table;
+ TT_ULong size;
+
+
+ if ( tag != 0 )
+ {
+ /* look for tag in font directory */
+ table = TT_LookUp_Table( face, tag );
+ if ( table < 0 )
+ {
+ error = TT_Err_Table_Missing;
+ goto Exit;
+ }
+
+ offset += face->dir_tables[table].Offset;
+ size = face->dir_tables[table].Length;
+ }
+ else
+ /* tag = 0 -- the use want to access the font file directly */
+ {
+ size = face->root.stream->size;
+ }
+
+ if ( length && *length == 0 )
+ {
+ *length = size;
+
+ return TT_Err_Ok;
+ }
+
+ if ( length )
+ size = *length;
+
+ stream = face->root.stream;
+ (void)FILE_Read_At( offset, buffer, size );
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Header */
+ /* */
+ /* <Description> */
+ /* Loads the TrueType font header. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_Header( TT_Face face,
+ FT_Stream stream )
+ {
+ TT_Error error;
+
+ TT_Long table;
+ TT_Header* header;
+
+
+ FT_TRACE2(( "Load_TT_Header( %08lx )\n", (TT_Long)face ));
+
+ if ( ( table = TT_LookUp_Table( face, TTAG_head ) ) < 0 )
+ {
+ FT_TRACE0(( "Font Header is missing!\n" ));
+ error = TT_Err_Header_Table_Missing;
+
+ goto Exit;
+ }
+
+ if ( FILE_Seek( face->dir_tables[table].Offset ) ||
+ ACCESS_Frame( 54L ) )
+ goto Exit;
+
+ header = &face->header;
+
+ 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();
+
+ FT_TRACE2(( " Units per EM : %8u\n", header->Units_Per_EM ));
+ FT_TRACE2(( " IndexToLoc : %8d\n", header->Index_To_Loc_Format ));
+ FT_TRACE2(( "Font Header Loaded.\n" ));
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_MaxProfile */
+ /* */
+ /* <Description> */
+ /* Loads the maximum profile into a face object. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_MaxProfile( TT_Face face,
+ FT_Stream stream )
+ {
+ TT_Error error;
+
+ TT_Long i;
+ TT_MaxProfile* maxProfile = &face->max_profile;
+
+
+ FT_TRACE2(( "Load_TT_MaxProfile( %08lx )\n", (TT_Long)face ));
+
+ if ( ( i = TT_LookUp_Table( face, TTAG_maxp ) ) < 0 )
+ {
+ error = TT_Err_Max_Profile_Missing;
+
+ goto Exit;
+ }
+
+ if ( FILE_Seek( face->dir_tables[i].Offset ) ||
+ ACCESS_Frame( 32L ) )
+ goto Exit;
+
+ /* 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 adjustment that is necessary to load certain */
+ /* broken fonts like `Keystrokes MT' :-( */
+ /* */
+ /* We allocate 64 function entries by default when */
+ /* the maxFunctionDefs field is null. */
+
+ if ( maxProfile->maxFunctionDefs == 0 )
+ maxProfile->maxFunctionDefs = 64;
+
+ face->root.num_glyphs = maxProfile->numGlyphs;
+
+ face->root.max_points = MAX( maxProfile->maxCompositePoints,
+ maxProfile->maxPoints );
+
+ face->root.max_contours = MAX( maxProfile->maxCompositeContours,
+ maxProfile->maxContours );
+
+ face->max_components = (TT_ULong)maxProfile->maxComponentElements +
+ maxProfile->maxComponentDepth;
+
+ FT_TRACE2(( "GASP loaded.\n" ));
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Metrics */
+ /* */
+ /* <Description> */
+ /* Loads the horizontal or vertical metrics table into a face object. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* vertical :: A boolean flag. If set, load vertical metrics. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ static
+ TT_Error TT_Load_Metrics( TT_Face face,
+ FT_Stream stream,
+ TT_Bool vertical )
+ {
+ TT_Error error;
+ FT_Memory memory = stream->memory;
+
+ TT_UShort n, num_shorts, num_longs;
+ TT_Long table;
+
+ TT_LongMetrics** longs;
+ TT_ShortMetrics** shorts;
+
+ TT_LongMetrics* long_metric;
+
+ FT_TRACE2(( "TT_Load_%s_Metrics( %08lx )\n",
+ vertical ? "Vertical" : "Horizontal", (TT_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! */
+ /* */
+ table = TT_LookUp_Table( face, TTAG_vmtx );
+ if ( table < 0 )
+ {
+ /* Set the number_Of_VMetrics to 0! */
+ FT_TRACE2(( " no vertical header in file.\n" ));
+ face->vertical.number_Of_VMetrics = 0;
+ error = TT_Err_Ok;
+
+ goto Exit;
+ }
+
+ num_longs = face->vertical.number_Of_VMetrics;
+ longs = (TT_LongMetrics**)&face->vertical.long_metrics;
+ shorts = (TT_ShortMetrics**)&face->vertical.short_metrics;
+ }
+ else
+ {
+ if ( ( table = TT_LookUp_Table( face, TTAG_hmtx ) ) < 0 )
+ {
+ FT_ERROR(( " no horizontal metrics in file!\n" ));
+ error = TT_Err_Hmtx_Table_Missing;
+
+ goto Exit;
+ }
+
+ num_longs = face->horizontal.number_Of_HMetrics;
+ longs = (TT_LongMetrics**)&face->horizontal.long_metrics;
+ shorts = (TT_ShortMetrics**)&face->horizontal.short_metrics;
+ }
+
+ num_shorts = face->max_profile.numGlyphs - num_longs;
+
+ if ( num_longs > face->max_profile.numGlyphs ) /* sanity check */
+ {
+ FT_ERROR(( " more metrics than glyphs!\n" ));
+ error = TT_Err_Invalid_Horiz_Metrics;
+
+ goto Exit;
+ }
+
+ if ( ALLOC_ARRAY( *longs, num_longs, TT_LongMetrics ) ||
+ ALLOC_ARRAY( *shorts, num_shorts, TT_ShortMetrics ) )
+ goto Exit;
+
+ if ( FILE_Seek( face->dir_tables[table].Offset ) ||
+ ACCESS_Frame( face->dir_tables[table].Length ) )
+ goto Exit;
+
+ long_metric = *longs;
+ for ( n = 0; n < num_longs; n++ )
+ {
+ long_metric->advance = GET_UShort();
+ long_metric->bearing = GET_Short();
+ long_metric++;
+ }
+
+ for ( n = 0; n < num_shorts; n++ )
+ (*shorts)[n] = GET_Short();
+
+ FORGET_Frame();
+
+ FT_TRACE2(( "loaded\n" ));
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Metrics_Header */
+ /* */
+ /* <Description> */
+ /* Loads the horizontal or vertical header in a face object. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* vertical :: A boolean flag. If set, load vertical metrics. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_Metrics_Header( TT_Face face,
+ FT_Stream stream,
+ TT_Bool vertical )
+ {
+ TT_Error error;
+
+ TT_Long table;
+ TT_HoriHeader* header;
+
+
+ FT_TRACE2(( vertical ? "Vertical header " : "Horizontal header " ));
+
+ if ( vertical )
+ {
+ face->vertical_info = 0;
+
+ /* The vertical header table is optional, so return quietly if */
+ /* we don't find it. */
+ if ( ( table = TT_LookUp_Table( face, TTAG_vhea ) ) < 0 )
+ {
+ error = TT_Err_Ok;
+
+ goto Exit;
+ }
+
+ face->vertical_info = 1;
+ header = (TT_HoriHeader*)&face->vertical;
+ }
+ else
+ {
+ /* The horizontal header is mandatory, return an error if we */
+ /* don't find it. */
+ if ( ( table = TT_LookUp_Table( face, TTAG_hhea ) ) < 0 )
+ {
+ error = TT_Err_Horiz_Header_Missing;
+
+ goto Exit;
+ }
+
+ header = &face->horizontal;
+ }
+
+ if ( FILE_Seek( face->dir_tables[table].Offset ) ||
+ ACCESS_Frame( 36L ) )
+ goto Exit;
+
+ 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->Reserved[0] = GET_Short();
+ header->Reserved[1] = GET_Short();
+ header->Reserved[2] = GET_Short();
+ header->Reserved[3] = GET_Short();
+ header->Reserved[4] = GET_Short();
+
+ header->metric_Data_Format = GET_Short();
+ header->number_Of_HMetrics = GET_UShort();
+
+ FORGET_Frame();
+
+ header->long_metrics = NULL;
+ header->short_metrics = NULL;
+
+ FT_TRACE2(( "loaded\n" ));
+
+ /* Now try to load the corresponding metrics */
+
+ error = TT_Load_Metrics( face, stream, vertical );
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Names */
+ /* */
+ /* <Description> */
+ /* Loads the name records. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_Names( TT_Face face, FT_Stream stream )
+ {
+ TT_Error error;
+ FT_Memory memory = stream->memory;
+
+ TT_UShort i;
+ TT_Long table;
+ TT_Long storageSize;
+
+ TT_NameTable* names;
+ TT_NameRec* namerec;
+
+
+ FT_TRACE2(( "Names " ));
+
+ if ( ( table = TT_LookUp_Table( face, TTAG_name ) ) < 0 )
+ {
+ /* The name table is required so indicate failure. */
+ FT_TRACE2(( "is missing!\n" ));
+ error = TT_Err_Name_Table_Missing;
+
+ goto Exit;
+ }
+
+ /* Seek to the beginning of the table and check the frame access. */
+ /* The names table has a 6 byte header. */
+ if ( FILE_Seek( face->dir_tables[table].Offset ) ||
+ ACCESS_Frame( 6L ) )
+ goto Exit;
+
+ names = &face->name_table;
+
+ /* 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,
+ TT_NameRec ) ||
+ ACCESS_Frame( names->numNameRecords * 12L ) )
+ goto Exit;
+
+ /* Load the name records and determine how much storage is needed */
+ /* to hold the strings themselves. */
+ namerec = names->names;
+ storageSize = 0;
+
+ for ( i = 0; i < names->numNameRecords; i++, namerec++ )
+ {
+ TT_Long upper;
+
+
+ namerec->platformID = GET_UShort();
+ namerec->encodingID = GET_UShort();
+ namerec->languageID = GET_UShort();
+ namerec->nameID = GET_UShort();
+ namerec->stringLength = GET_UShort();
+ namerec->stringOffset = GET_UShort();
+
+ upper = namerec->stringOffset + namerec->stringLength;
+ if ( upper > storageSize ) storageSize = upper;
+ }
+
+ FORGET_Frame();
+
+ if ( ALLOC( names->storage, storageSize ) ||
+ FILE_Read_At( face->dir_tables[table].Offset + names->storageOffset,
+ (void*)names->storage, storageSize ) )
+ goto Exit;
+
+ /* Go through and assign the string pointers to the name records. */
+ namerec = names->names;
+ for ( i = 0; i < names->numNameRecords; i++, namerec++ )
+ namerec->string = names->storage + namerec->stringOffset;
+
+ /* Print Name Record Table in case of debugging */
+#if 0
+ namerec = names->names;
+ for ( i = 0; i < names->numNameRecords; i++, namerec++ )
+ {
+ TT_UShort j;
+
+
+ FT_TRACE2(( "%d %d %x %d ",
+ namerec->platformID,
+ namerec->encodingID,
+ namerec->languageID,
+ namerec->nameID ));
+
+ /* I know that M$ encoded strings are Unicode, */
+ /* but this works reasonable well for debugging purposes. */
+ if ( namerec->string )
+ for ( j = 0; j < namerec->stringLength; j++ )
+ {
+ TT_Char c = *(namerec->string + j);
+
+ if ( (TT_Byte)c < 128 )
+ FT_TRACE2(( "%c", c ));
+ }
+ }
+ FT_TRACE2(( "\n" ));
+#endif
+
+ FT_TRACE2(( "loaded\n" ));
+
+ Exit:
+ return error;
+
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Free_Names */
+ /* */
+ /* <Description> */
+ /* Frees the name records. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Free_Names( TT_Face face )
+ {
+ FT_Memory memory = face->root.driver->memory;
+ TT_NameTable* names = &face->name_table;
+
+
+ /* free strings table */
+ FREE( names->names );
+
+ /* free strings storage */
+ FREE( names->storage );
+
+ names->numNameRecords = 0;
+ names->format = 0;
+ names->storageOffset = 0;
+
+ return TT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_CMap */
+ /* */
+ /* <Description> */
+ /* Loads the cmap directory in a face object. The cmaps itselves are */
+ /* loaded on demand in the `ttcmap.c' module. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: A handle to the input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_CMap( TT_Face face,
+ FT_Stream stream )
+ {
+ TT_Error error;
+ FT_Memory memory = stream->memory;
+
+ TT_Long i, off, cur_off, table_start;
+ TT_UShort n, limit;
+
+ TT_CMapDir cmap_dir;
+ TT_CharMap charmap;
+ TT_CMapTable* cmap;
+
+
+ FT_TRACE2(( "CMaps " ));
+
+ if ( ( i = TT_LookUp_Table( face, TTAG_cmap ) ) < 0 )
+ {
+ error = TT_Err_CMap_Table_Missing;
+
+ goto Exit;
+ }
+
+ table_start = face->dir_tables[i].Offset;
+
+ if ( ( FILE_Seek( table_start ) ) ||
+ ( ACCESS_Frame( 4L ) ) ) /* 4 bytes cmap header */
+ goto Exit;
+
+ 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->charmaps,
+ cmap_dir.numCMaps,
+ TT_CharMapRec ) )
+ goto Exit;
+
+ face->num_charmaps = cmap_dir.numCMaps;
+
+ limit = face->num_charmaps;
+ charmap = face->charmaps;
+
+ for ( n = 0; n < limit; n++ )
+ {
+ charmap->root.face = (FT_Face)face;
+ cmap = &charmap->cmap;
+
+ if ( FILE_Seek( off ) ||
+ ACCESS_Frame( 8L ) )
+ goto Exit;
+
+ cmap->loaded = FALSE;
+ cmap->platformID = GET_UShort();
+ cmap->platformEncodingID = GET_UShort();
+
+ cur_off = GET_Long();
+
+ FORGET_Frame();
+
+ off = FILE_Pos();
+
+ if ( FILE_Seek( table_start + cur_off ) ||
+ ACCESS_Frame( 6L ) )
+ goto Exit;
+
+ cmap->format = GET_UShort();
+ cmap->length = GET_UShort();
+ cmap->version = GET_UShort();
+
+ FORGET_Frame();
+
+ cmap->offset = FILE_Pos();
+
+ charmap++;
+ }
+
+ FT_TRACE2(( "loaded\n" ));
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_OS2 */
+ /* */
+ /* <Description> */
+ /* Loads the OS2 table. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: A handle to the input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_OS2( TT_Face face,
+ FT_Stream stream )
+ {
+ TT_Error error;
+
+ TT_Long i;
+ TT_Int j;
+ TT_OS2* os2;
+
+
+ FT_TRACE2(( "OS/2 Table " ));
+
+ /* We now support old Mac fonts where the OS/2 table doesn't */
+ /* exist. Simply put, we set the `version' field to 0xFFFF */
+ /* and test this value each time we need to access the table. */
+ if ( ( i = TT_LookUp_Table( face, TTAG_OS2 ) ) < 0 )
+ {
+ FT_TRACE2(( "is missing\n!" ));
+ face->os2.version = 0xFFFF;
+ error = TT_Err_Ok;
+
+ goto Exit;
+ }
+
+ if ( FILE_Seek( face->dir_tables[i].Offset ) ||
+ ACCESS_Frame( 78L ) )
+ goto Exit;
+
+ 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 ( j = 0; j < 10; j++ )
+ os2->panose[j] = GET_Byte();
+
+ os2->ulUnicodeRange1 = GET_ULong();
+ os2->ulUnicodeRange2 = GET_ULong();
+ os2->ulUnicodeRange3 = GET_ULong();
+ os2->ulUnicodeRange4 = GET_ULong();
+
+ for ( j = 0; j < 4; j++ )
+ os2->achVendID[j] = 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 */
+ goto Exit;
+
+ os2->ulCodePageRange1 = GET_ULong();
+ os2->ulCodePageRange2 = GET_ULong();
+
+ FORGET_Frame();
+ }
+ else
+ {
+ os2->ulCodePageRange1 = 0;
+ os2->ulCodePageRange2 = 0;
+ }
+
+ FT_TRACE2(( "loaded\n" ));
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Postscript */
+ /* */
+ /* <Description> */
+ /* Loads the Postscript table. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: A handle to the input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_PostScript( TT_Face face,
+ FT_Stream stream )
+ {
+ TT_Error error;
+ TT_Long i;
+ TT_Postscript* post = &face->postscript;
+
+
+ FT_TRACE2(( "PostScript " ));
+
+ if ( ( i = TT_LookUp_Table( face, TTAG_post ) ) < 0 )
+ return TT_Err_Post_Table_Missing;
+
+ if ( FILE_Seek( face->dir_tables[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 another */
+ /* module (ttpost). */
+
+ FT_TRACE2(( "loaded\n" ));
+
+ return TT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Gasp */
+ /* */
+ /* <Description> */
+ /* Loads the `GASP' table into a face object. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_Gasp( TT_Face face,
+ FT_Stream stream )
+ {
+ TT_Error error;
+ FT_Memory memory = stream->memory;
+
+ TT_Long table;
+ TT_UShort num_ranges;
+ TT_UShort j;
+ TT_GaspRange* gaspranges;
+
+
+ FT_TRACE2(( "TT_Load_Gasp( %08lx )\n", (TT_Long)face ));
+
+ error = TT_Err_Ok;
+
+ /* the gasp table is optional */
+ if ( ( table = TT_LookUp_Table( face, TTAG_gasp ) ) < 0 )
+ goto Exit;
+
+ if ( FILE_Seek( face->dir_tables[table].Offset ) ||
+ ACCESS_Frame( 4L ) )
+ goto Exit;
+
+ face->gasp.version = GET_UShort();
+ face->gasp.numRanges = GET_UShort();
+
+ FORGET_Frame();
+
+ num_ranges = face->gasp.numRanges;
+ FT_TRACE3(( "number of ranges = %d\n", num_ranges ));
+
+ if ( ALLOC_ARRAY( gaspranges, num_ranges, TT_GaspRange ) ||
+ ACCESS_Frame( num_ranges * 4L ) )
+ goto Exit;
+
+ face->gasp.gaspRanges = gaspranges;
+
+ for ( j = 0; j < num_ranges; j++ )
+ {
+ gaspranges[j].maxPPEM = GET_UShort();
+ gaspranges[j].gaspFlag = GET_UShort();
+
+ FT_TRACE3(( " [max:%d flag:%d]",
+ gaspranges[j].maxPPEM,
+ gaspranges[j].gaspFlag ));
+ }
+ FT_TRACE3(( "\n" ));
+
+ FORGET_Frame();
+
+ FT_TRACE2(( "GASP loaded\n" ));
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Kern */
+ /* */
+ /* <Description> */
+ /* Loads the first kerning table with format 0 in the font. Only */
+ /* accepts the first horizontal kerning table. Developers should use */
+ /* the `ftxkern' extension to access other kerning tables in the font */
+ /* file, if they really want to. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_Kern( TT_Face face,
+ FT_Stream stream )
+ {
+ TT_Error error;
+ FT_Memory memory = stream->memory;
+
+ TT_Long table;
+ TT_UShort n, num_tables, version;
+
+
+ error = TT_Err_Ok;
+ table = TT_LookUp_Table( face, TTAG_kern );
+ if ( table < 0 )
+ goto Exit;
+
+ if ( FILE_Seek( face->dir_tables[table].Offset ) ||
+ READ_UShort( version ) ||
+ READ_UShort( num_tables ) )
+ goto Exit;
+
+ for ( n = 0; n < num_tables; n++ )
+ {
+ TT_UShort coverage;
+
+
+ if ( FILE_Skip( 4L ) ||
+ READ_UShort( coverage ) )
+ goto Exit;
+
+ if ( coverage == 0x0001 )
+ {
+ TT_UShort num_pairs, m;
+ TT_Kern_0_Pair* pair;
+
+
+ /* found a horizontal format 0 kerning table ! */
+ if ( READ_UShort( num_pairs ) ||
+ FILE_Skip( 6 ) )
+ goto Exit;
+
+ /* allocate array of kerning pairs */
+ if ( ALLOC_ARRAY( face->kern_pairs, num_pairs, TT_Kern_0_Pair ) )
+ goto Exit;
+
+ /* read the kerning pairs */
+ if ( ACCESS_Frame( 6L * num_pairs ) )
+ goto Exit;
+
+ pair = face->kern_pairs;
+ for ( m = 0; m < num_pairs; m++ )
+ {
+ pair->left = GET_UShort();
+ pair->right = GET_UShort();
+ pair->value = GET_UShort();
+ pair++;
+ }
+
+ FORGET_Frame();
+
+ face->num_kern_pairs = num_pairs;
+ face->kern_table_index = n;
+ goto Exit;
+ }
+ }
+
+ /* no kern table found -- doesn't matter */
+ face->kern_table_index = -1;
+ face->num_kern_pairs = 0;
+ face->kern_pairs = NULL;
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Hdmx */
+ /* */
+ /* <Description> */
+ /* Loads the horizontal device metrics table. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: A handle to the input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_Hdmx( TT_Face face,
+ FT_Stream stream )
+ {
+ TT_Error error;
+ FT_Memory memory = stream->memory;
+
+ TT_HdmxRec* rec;
+ TT_Hdmx hdmx;
+ TT_Long table;
+ TT_UShort n;
+ TT_Long num_glyphs;
+ TT_Long record_size;
+
+ hdmx.version = 0;
+ hdmx.num_records = 0;
+ hdmx.records = 0;
+
+ face->hdmx = hdmx;
+
+ error = TT_Err_Ok;
+
+ /* ths table is optional */
+ if ( ( table = TT_LookUp_Table( face, TTAG_hdmx ) ) < 0 )
+ return error;
+
+ if ( FILE_Seek( face->dir_tables[table].Offset ) ||
+ ACCESS_Frame( 8L ) )
+ goto Exit;
+
+ hdmx.version = GET_UShort();
+ hdmx.num_records = GET_Short();
+ record_size = GET_Long();
+
+ FORGET_Frame();
+
+ /* Only recognize format 0 */
+ if ( hdmx.version != 0 )
+ goto Exit;
+
+ if ( ALLOC( hdmx.records, sizeof ( TT_HdmxRec ) * hdmx.num_records ) )
+ goto Exit;
+
+ num_glyphs = face->root.num_glyphs;
+ record_size -= num_glyphs + 2;
+ rec = hdmx.records;
+
+ for ( n = 0; n < hdmx.num_records; n++ )
+ {
+ /* read record */
+ if ( READ_Byte( rec->ppem ) ||
+ READ_Byte( rec->max_width ) )
+ goto Exit;
+
+ if ( ALLOC( rec->widths, num_glyphs ) ||
+ FILE_Read( rec->widths, num_glyphs ) )
+ goto Exit;
+
+ /* skip padding bytes */
+ if ( record_size > 0 )
+ if ( FILE_Skip( record_size ) )
+ goto Exit;
+
+ rec++;
+ }
+
+ face->hdmx = hdmx;
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Free_Hdmx */
+ /* */
+ /* <Description> */
+ /* Frees the horizontal device metrics table. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Free_Hdmx( TT_Face face )
+ {
+ if ( face )
+ {
+ TT_UShort n;
+ FT_Memory memory = face->root.driver->memory;
+
+
+ for ( n = 0; n < face->hdmx.num_records; n++ )
+ FREE( face->hdmx.records[n].widths );
+
+ FREE( face->hdmx.records );
+ face->hdmx.num_records = 0;
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+/* END */
--- /dev/null
+++ b/src/shared/sfnt/ttload.h
@@ -1,0 +1,353 @@
+/***************************************************************************/
+/* */
+/* ttload.h */
+/* */
+/* Load the basic TrueType tables, i.e., tables that can be either in */
+/* TTF or OTF font (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 TTLOAD_H
+#define TTLOAD_H
+
+
+#include <ftstream.h>
+#include <ttobjs.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_LookUp_Table */
+ /* */
+ /* <Description> */
+ /* Looks for a TrueType table by name. */
+ /* */
+ /* <Input> */
+ /* face :: A face object handle. */
+ /* tag :: The searched tag. */
+ /* */
+ /* <Return> */
+ /* Index of table if found, -1 otherwise. */
+ /* */
+ EXPORT_DEF
+ TT_Long TT_LookUp_Table( TT_Face face,
+ TT_ULong tag );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Directory */
+ /* */
+ /* <Description> */
+ /* Loads the table directory into a face object. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* faceIndex :: The index of the TrueType font, if we're opening a */
+ /* collection. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_Directory( TT_Face face,
+ FT_Stream stream,
+ TT_Long faceIndex );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Any */
+ /* */
+ /* <Description> */
+ /* Loads any font table into client memory. Used by the */
+ /* TT_Get_Font_Data() API function. */
+ /* */
+ /* <Input> */
+ /* face :: The face object to look for. */
+ /* */
+ /* tag :: The tag of table to load. Use the value 0 if you want */
+ /* to access the whole font file, else set this parameter */
+ /* to a valid TrueType table tag that you can forge with */
+ /* the MAKE_TT_TAG macro. */
+ /* */
+ /* offset :: The starting offset in the table (or the file if */
+ /* tag == 0). */
+ /* */
+ /* length :: The address of the decision variable: */
+ /* */
+ /* If length == NULL: */
+ /* Loads the whole table. Returns an error if */
+ /* `offset' == 0! */
+ /* */
+ /* If *length == 0: */
+ /* Exits immediately; returning the length of the given */
+ /* table or of the font file, depending on the value of */
+ /* `tag'. */
+ /* */
+ /* If *length != 0: */
+ /* Loads the next `length' bytes of table or font, */
+ /* starting at offset `offset' (in table or font too). */
+ /* */
+ /* <Output> */
+ /* buffer :: The address of target buffer. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_Any( TT_Face face,
+ TT_ULong tag,
+ TT_Long offset,
+ void* buffer,
+ TT_Long* length );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Header */
+ /* */
+ /* <Description> */
+ /* Loads the TrueType font header. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_Header( TT_Face face,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Metrics_Header */
+ /* */
+ /* <Description> */
+ /* Loads the horizontal or vertical header in a face object. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* vertical :: A boolean flag. If set, load vertical metrics. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_Metrics_Header( TT_Face face,
+ FT_Stream stream,
+ TT_Bool vertical );
+
+
+ LOCAL_DEF
+ TT_Error TT_Load_CMap( TT_Face face,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_MaxProfile */
+ /* */
+ /* <Description> */
+ /* Loads the maximum profile into a face object. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_MaxProfile( TT_Face face,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Names */
+ /* */
+ /* <Description> */
+ /* Loads the name records. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_Names( TT_Face face,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_OS2 */
+ /* */
+ /* <Description> */
+ /* Loads the OS2 table. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: A handle to the input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_OS2( TT_Face face,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Postscript */
+ /* */
+ /* <Description> */
+ /* Loads the Postscript table. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: A handle to the input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_PostScript( TT_Face face,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Hdmx */
+ /* */
+ /* <Description> */
+ /* Loads the horizontal device metrics table. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: A handle to the input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_Hdmx( TT_Face face,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Free_Names */
+ /* */
+ /* <Description> */
+ /* Frees the name records. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Free_Names( TT_Face face );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Free_Hdmx */
+ /* */
+ /* <Description> */
+ /* Frees the horizontal device metrics table. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Free_Hdmx ( TT_Face face );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Kern */
+ /* */
+ /* <Description> */
+ /* Loads the first kerning table with format 0 in the font. Only */
+ /* accepts the first horizontal kerning table. Developers should use */
+ /* the `ftxkern' extension to access other kerning tables in the font */
+ /* file, if they really want to. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_Kern( TT_Face face,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Gasp */
+ /* */
+ /* <Description> */
+ /* Loads the `GASP' table into a face object. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_Gasp( TT_Face face,
+ FT_Stream stream );
+
+
+#endif /* TTLOAD_H */
+
+
+/* END */
--- /dev/null
+++ b/src/shared/sfnt/ttpost.c
@@ -1,0 +1,713 @@
+/***************************************************************************/
+/* */
+/* ttpost.c */
+/* */
+/* Postscript names table processing (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 <ttpost.h>
+#include <ftstream.h>
+#include <tterrors.h>
+#include <ttload.h>
+#include <tttags.h>
+
+ /* the 258 default Mac PS glyph names */
+
+ const TT_String* TT_Mac_Postscript_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_Face face,
+ FT_Stream stream )
+ {
+ FT_Memory memory = stream->memory;
+ TT_Error error;
+
+ TT_UShort num_glyphs;
+ TT_UShort num_names;
+
+ TT_UShort* glyph_indices = 0;
+ TT_Char** name_strings = 0;
+
+
+ if ( READ_UShort( num_glyphs ) )
+ goto Exit;
+
+ /* UNDOCUMENTED! The number of glyphs in this table can be smaller */
+ /* than the value in the maxp table (cf. cyberbit.ttf). */
+
+ /* There already exist fonts which have more than 32768 glyph names */
+ /* in this table, so the test for this threshold has been dropped. */
+
+ if ( num_glyphs > face->root.num_glyphs )
+ {
+ error = TT_Err_Invalid_File_Format;
+ goto Exit;
+ }
+
+ /* load the indices */
+ {
+ TT_UShort n;
+
+
+ if ( ALLOC_ARRAY ( glyph_indices, num_glyphs, TT_UShort ) ||
+ ACCESS_Frame( num_glyphs * 2L ) )
+ goto Fail;
+
+ for ( n = 0; n < num_glyphs; n++ )
+ glyph_indices[n] = GET_UShort();
+
+ FORGET_Frame();
+ }
+
+ /* compute number of names stored in table */
+ {
+ TT_UShort n;
+
+
+ num_names = 0;
+
+ for ( n = 0; n < num_glyphs; n++ )
+ {
+ TT_UShort index;
+
+
+ index = glyph_indices[n];
+ if ( index >= 258 )
+ {
+ index -= 257;
+ if ( index > num_names )
+ num_names = index;
+ }
+ }
+ }
+
+ /* now load the name strings */
+ {
+ TT_UShort n;
+
+
+ if ( ALLOC_ARRAY( name_strings, num_names, TT_Char* ) )
+ goto Fail;
+
+ for ( n = 0; n < num_names; n++ )
+ {
+ TT_Byte len;
+
+
+ if ( READ_Byte ( len ) ||
+ ALLOC_ARRAY( name_strings[n], len+1, TT_Char ) ||
+ FILE_Read ( name_strings[n], len ) )
+ goto Fail1;
+
+ name_strings[n][len] = '\0';
+ }
+ }
+
+ /* all right, set table fields and exit successfuly */
+ {
+ TT_Post_20* table = &face->postscript_names.names.format_20;
+
+
+ table->num_glyphs = num_glyphs;
+ table->num_names = num_names;
+ table->glyph_indices = glyph_indices;
+ table->glyph_names = name_strings;
+ }
+ return TT_Err_Ok;
+
+
+ Fail1:
+ {
+ TT_UShort n;
+
+
+ for ( n = 0; n < num_names; n++ )
+ FREE( name_strings[n] );
+ }
+
+ Fail:
+ FREE( name_strings );
+ FREE( glyph_indices );
+
+ Exit:
+ return error;
+ }
+
+
+ static
+ TT_Error Load_Format_25( TT_Face face,
+ FT_Stream stream )
+ {
+ FT_Memory memory = stream->memory;
+ TT_Error error;
+
+ TT_UShort num_glyphs;
+ TT_Char* offset_table = 0;
+
+
+ /* UNDOCUMENTED! This value appears only in the Apple TT specs. */
+ if ( READ_UShort( num_glyphs ) )
+ goto Exit;
+
+ /* check the number of glyphs */
+ if ( num_glyphs > face->root.num_glyphs || num_glyphs > 258 )
+ {
+ error = TT_Err_Invalid_File_Format;
+ goto Exit;
+ }
+
+ if ( ALLOC ( offset_table, num_glyphs ) ||
+ FILE_Read( offset_table, num_glyphs ) )
+ goto Fail;
+
+ /* now check the offset table */
+ {
+ TT_UShort n;
+
+
+ for ( n = 0; n < num_glyphs; n++ )
+ {
+ TT_Long index = (TT_Long)n + offset_table[n];
+
+
+ if ( index < 0 || index > num_glyphs )
+ {
+ error = TT_Err_Invalid_File_Format;
+ goto Fail;
+ }
+ }
+ }
+
+ /* OK, set table fields and exit successfuly */
+ {
+ TT_Post_25* table = &face->postscript_names.names.format_25;
+
+
+ table->num_glyphs = num_glyphs;
+ table->offsets = offset_table;
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ FREE( offset_table );
+
+ Exit:
+ return error;
+ }
+
+
+ static
+ TT_Error Load_Post_Names( TT_Face face )
+ {
+ FT_Stream stream;
+ TT_Error error;
+
+ /* get a stream for the face's resource */
+ stream = face->root.stream;
+
+ /* seek to the beginning of the PS names table */
+ {
+ TT_Long table;
+
+
+ table = TT_LookUp_Table( face, TTAG_post );
+ if ( FILE_Seek( face->dir_tables[table].Offset + 32L ) )
+ goto Exit;
+ }
+
+ /* now read postscript table */
+ switch ( face->postscript.FormatType )
+ {
+ case 0x00020000:
+ error = Load_Format_20( face, stream );
+ break;
+
+ case 0x00028000:
+ error = Load_Format_25( face, stream );
+ break;
+
+ default:
+ error = TT_Err_Invalid_File_Format;
+ }
+
+ face->postscript_names.loaded = 1;
+
+ Exit:
+ return error;
+ }
+
+
+ LOCAL_FUNC
+ void TT_Free_Post_Names( TT_Face face )
+ {
+ FT_Memory memory = face->root.memory;
+ TT_Post_Names* names = &face->postscript_names;
+
+
+ if ( names->loaded )
+ {
+ switch ( face->postscript.FormatType )
+ {
+ case 0x00020000:
+ {
+ TT_Post_20* table = &names->names.format_20;
+ TT_UShort n;
+
+
+ FREE( table->glyph_indices );
+ table->num_glyphs = 0;
+
+ for ( n = 0; n < table->num_names; n++ )
+ FREE( table->glyph_names[n] );
+
+ FREE( table->glyph_names );
+ table->num_names = 0;
+ }
+ break;
+
+ case 0x00028000:
+ {
+ TT_Post_25* table = &names->names.format_25;
+
+
+ FREE( table->offsets );
+ table->num_glyphs = 0;
+ }
+ break;
+ }
+ }
+ names->loaded = 0;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Get_PS_Name */
+ /* */
+ /* <Description> */
+ /* Gets the PostScript glyph name of a glyph. */
+ /* */
+ /* <Input> */
+ /* index :: The glyph index. */
+ /* */
+ /* PSname :: The address of a string pointer. Will be NULL in case */
+ /* of error, otherwise it is a pointer to the glyph name. */
+ /* */
+ /* You must not modify the returned string! */
+ /* */
+ /* <Output> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ EXPORT_FUNC
+ TT_Error TT_Get_PS_Name( TT_Face face,
+ TT_UInt index,
+ TT_String** PSname )
+ {
+ TT_Error error;
+ TT_Post_Names* names;
+
+ if ( !face )
+ return TT_Err_Invalid_Face_Handle;
+
+ if ( index >= face->root.num_glyphs )
+ return TT_Err_Invalid_Glyph_Index;
+
+ names = &face->postscript_names;
+
+ /* `.notdef' by default */
+ *PSname = (TT_String*)TT_Mac_Postscript_Names[0];
+
+ switch ( face->postscript.FormatType )
+ {
+ case 0x00010000:
+ if ( index < 258 ) /* paranoid checking */
+ *PSname = (TT_String*)TT_Mac_Postscript_Names[index];
+ break;
+
+ case 0x00020000:
+ {
+ TT_Post_20* table = &names->names.format_20;
+
+
+ if ( !names->loaded )
+ {
+ error = Load_Post_Names( face );
+ if ( error )
+ break;
+ }
+
+ if ( index < table->num_glyphs )
+ {
+ TT_UShort name_index = table->glyph_indices[index];
+
+
+ if ( name_index < 258 )
+ *PSname = (TT_String*)TT_Mac_Postscript_Names[name_index];
+ else
+ *PSname = (TT_String*)table->glyph_names[name_index - 258];
+ }
+ }
+ break;
+
+ case 0x00028000:
+ {
+ TT_Post_25* table = &names->names.format_25;
+
+
+ if ( !names->loaded )
+ {
+ error = Load_Post_Names( face );
+ if ( error )
+ break;
+ }
+
+ if ( index < table->num_glyphs ) /* paranoid checking */
+ {
+ index += table->offsets[index];
+ *PSname = (TT_String*)TT_Mac_Postscript_Names[index];
+ }
+ }
+ break;
+
+ case 0x00030000:
+ break; /* nothing to do */
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+/* END */
--- /dev/null
+++ b/src/shared/sfnt/ttpost.h
@@ -1,0 +1,95 @@
+/***************************************************************************/
+/* */
+/* ttpost.h */
+/* */
+/* Postcript name table processing for TrueType and OpenType fonts */
+/* (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. */
+/* */
+/***************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* 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 TTPOST_H
+#define TTPOST_H
+
+#include <ftconfig.h>
+#include <tttypes.h>
+#include <ttconfig.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define TT_Err_Invalid_Post_Table_Format 0x0B00
+#define TT_Err_Invalid_Post_Table 0x0B01
+
+
+#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
+
+#if 0
+ /* the 258 standard Mac glyph names, used for format 1.0 and 2.5 */
+ LOCAL_DEF
+ const TT_String* TT_Mac_Postscript_Names[];
+#endif
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Get_PS_Name */
+ /* */
+ /* <Description> */
+ /* Gets the PostScript glyph name of a glyph. */
+ /* */
+ /* <Input> */
+ /* index :: The glyph index. */
+ /* */
+ /* PSname :: The address of a string pointer. Will be NULL in case */
+ /* of error, otherwise it is a pointer to the glyph name. */
+ /* */
+ /* You must not modify the returned string! */
+ /* */
+ /* <Output> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ EXPORT_DEF
+ TT_Error TT_Get_PS_Name( TT_Face face,
+ TT_UInt index,
+ TT_String** PSname );
+
+
+ LOCAL_DEF
+ void TT_Free_Post_Names( TT_Face face );
+
+
+#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* TTPOST_H */
+
+
+/* END */
--- /dev/null
+++ b/src/shared/sfnt/ttsbit.c
@@ -1,0 +1,1443 @@
+/***************************************************************************/
+/* */
+/* ttsbit.c */
+/* */
+/* TrueType and OpenType embedded bitmap support (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. */
+/* */
+/* */
+/* WARNING: This file should not be compiled directly, it is meant to be */
+/* included in the source of several font drivers (i.e., the TTF */
+/* and OTF drivers). */
+/* */
+/***************************************************************************/
+
+
+#include <ftdebug.h>
+
+#include <ttsbit.h>
+#include <tttags.h>
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* blit_sbit */
+ /* */
+ /* <Description> */
+ /* Blits a bitmap from an input stream into a given target. Supports */
+ /* x and y offsets as well as byte padded lines. */
+ /* */
+ /* <Input> */
+ /* target :: The target bitmap/pixmap. */
+ /* */
+ /* source :: The input packed bitmap data. */
+ /* */
+ /* line_bits :: The number of bits per line. */
+ /* */
+ /* byte_padded :: A flag which is true if lines are byte-padded. */
+ /* */
+ /* x_offset :: The horizontal offset. */
+ /* */
+ /* y_offset :: The vertical offset. */
+ /* */
+ /* <Note> */
+ /* IMPORTANT: The x and y offsets are relative to the top corner of */
+ /* the target bitmap (unlike the normal TrueType */
+ /* convention). A positive y offset indicates a downwards */
+ /* direction! */
+ /* */
+ static
+ void blit_sbit( FT_Bitmap* target,
+ FT_Byte* source,
+ FT_Int line_bits,
+ FT_Bool byte_padded,
+ FT_Int x_offset,
+ FT_Int y_offset )
+ {
+ FT_Byte* line_buff;
+ FT_Int line_incr;
+ FT_Int height;
+
+ FT_UShort acc;
+ FT_Byte loaded;
+
+
+ /* first of all, compute starting write position */
+ line_incr = target->pitch;
+ line_buff = target->buffer;
+
+ if (line_incr < 0)
+ line_buff -= line_incr*(target->rows-1);
+
+ line_buff += (x_offset >> 3) + y_offset * line_incr;
+
+ /***********************************************************************/
+ /* */
+ /* We use the extra-classic `accumulator' trick to extract the bits */
+ /* from the source byte stream. */
+ /* */
+ /* Namely, the variable `acc' is a 16-bit accumulator containing the */
+ /* last `loaded' bits from the input stream. The bits are shifted to */
+ /* the upmost position in `acc'. */
+ /* */
+ /***********************************************************************/
+
+ acc = 0; /* clear accumulator */
+ loaded = 0; /* no bits were loaded */
+
+ for ( height = target->rows; height > 0; height-- )
+ {
+ FT_Byte* cur = line_buff; /* current write cursor */
+ FT_Int count = line_bits; /* # of bits to extract per line */
+ FT_Byte shift = x_offset & 7; /* current write shift */
+ FT_Byte space = 8 - shift;
+
+
+ /* first of all, read individual source bytes */
+ if ( count >= 8 )
+ {
+ count -= 8;
+ {
+ do
+ {
+ FT_Byte val;
+
+ /* ensure that there are at least 8 bits in the accumulator */
+ if ( loaded < 8 )
+ {
+ acc |= ((FT_UShort)*source++) << (8 - loaded);
+ loaded += 8;
+ }
+
+ /* now write one byte */
+ val = (FT_Byte)(acc >> 8);
+ if (shift)
+ {
+ cur[0] |= val >> shift;
+ cur[1] |= val << space;
+ }
+ else
+ cur[0] = val;
+
+ cur++;
+ acc <<= 8; /* remove bits from accumulator */
+ loaded -= 8;
+ count -= 8;
+ }
+ while ( count >= 0 );
+ }
+
+ /* restore `count' to correct value */
+ count += 8;
+ }
+
+ /* now write remaining bits (count < 8) */
+ if ( count > 0 )
+ {
+ FT_Byte val;
+
+
+ /* ensure that there are at least `count' bits in the accumulator */
+ if ( loaded < count )
+ {
+ acc |= ((FT_UShort)*source++) << (8 - loaded);
+ loaded += 8;
+ }
+
+ /* now write remaining bits */
+ val = ((FT_Byte)(acc >> 8)) & ~(0xFF >> count);
+ cur[0] |= val >> shift;
+
+ if ( count > space )
+ cur[1] |= val << space;
+
+ acc <<= count;
+ loaded -= count;
+ }
+
+ /* now, skip to next line */
+ if ( byte_padded )
+ acc = loaded = 0; /* clear accumulator on byte-padded lines */
+
+ line_buff += line_incr;
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Small_SBit_Metrics */
+ /* */
+ /* <Description> */
+ /* Loads a small bitmap metrics record. */
+ /* */
+ /* <Input> */
+ /* stream :: The input stream. */
+ /* */
+ /* <Output> */
+ /* metrics :: A small metrics structure. */
+ /* */
+ static
+ void TT_Load_Small_SBit_Metrics( TT_SBit_Small_Metrics* metrics,
+ FT_Stream stream )
+ {
+ metrics->height = GET_Byte();
+ metrics->width = GET_Byte();
+ metrics->bearingX = GET_Char();
+ metrics->bearingY = GET_Char();
+ metrics->advance = GET_Byte();
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_SBit_Metrics */
+ /* */
+ /* <Description> */
+ /* Loads a bitmap metrics record. */
+ /* */
+ /* <Input> */
+ /* stream :: The input stream. */
+ /* */
+ /* <Output> */
+ /* metrics :: A metrics structure. */
+ /* */
+ static
+ void TT_Load_SBit_Metrics( TT_SBit_Metrics* metrics,
+ FT_Stream stream )
+ {
+ 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();
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_SBit_Line_Metrics */
+ /* */
+ /* <Description> */
+ /* Loads a bitmap line metrics record. */
+ /* */
+ /* <Input> */
+ /* stream :: The input stream. */
+ /* */
+ /* <Output> */
+ /* metrics :: A line metrics structure. */
+ /* */
+ static
+ void TT_Load_SBit_Line_Metrics( TT_SBit_Line_Metrics* metrics,
+ FT_Stream stream )
+ {
+ 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();
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_SBit_Const_Metrics */
+ /* */
+ /* <Description> */
+ /* Loads the metrics for `EBLC' index tables format 2 and 5. */
+ /* */
+ /* <Input> */
+ /* range :: The target range. */
+ /* */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ static
+ TT_Error Load_SBit_Const_Metrics( TT_SBit_Range* range,
+ FT_Stream stream )
+ {
+ TT_Error error;
+
+ if ( !ACCESS_Frame( 12L ) )
+ {
+ range->image_size = GET_ULong();
+ TT_Load_SBit_Metrics( &range->metrics, stream );
+
+ FORGET_Frame();
+ }
+
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_SBit_Range_Codes */
+ /* */
+ /* <Description> */
+ /* Loads the range codes for `EBLC' index tables format 4 and 5. */
+ /* */
+ /* <Input> */
+ /* range :: The target range. */
+ /* */
+ /* stream :: The input stream. */
+ /* */
+ /* load_offsets :: A flag whether to load the glyph offset table. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ static
+ TT_Error Load_SBit_Range_Codes( TT_SBit_Range* range,
+ FT_Stream stream,
+ TT_Bool load_offsets )
+ {
+ TT_Error error;
+ TT_ULong count, n, size;
+ FT_Memory memory = stream->memory;
+
+
+ if ( READ_ULong( count ) )
+ goto Exit;
+
+ range->num_glyphs = count;
+
+ /* Allocate glyph offsets table if needed */
+ if ( load_offsets )
+ {
+ if ( ALLOC_ARRAY( range->glyph_offsets, count, TT_ULong ) )
+ goto Exit;
+
+ size = count * 4L;
+ }
+ else
+ size = count * 2L;
+
+ /* Allocate glyph codes table and access frame */
+ if ( ALLOC_ARRAY ( range->glyph_codes, count, TT_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] = (TT_ULong)range->image_offset +
+ GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_SBit_Range */
+ /* */
+ /* <Description> */
+ /* Loads a given `EBLC' index/range table. */
+ /* */
+ /* <Input> */
+ /* range :: The target range. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ static
+ TT_Error Load_SBit_Range( TT_SBit_Range* range,
+ FT_Stream stream )
+ {
+ TT_Error error;
+ FT_Memory memory = stream->memory;
+
+
+ switch( range->index_format )
+ {
+ case 1: /* variable metrics with 4-byte offsets */
+ case 3: /* variable metrics with 2-byte offsets */
+ {
+ TT_ULong num_glyphs, n;
+ TT_Int size_elem;
+ TT_Bool large = (range->index_format == 1);
+
+
+ num_glyphs = range->last_glyph - range->first_glyph + 1L;
+ range->num_glyphs = num_glyphs;
+ num_glyphs++; /* XXX : BEWARE - see spec */
+
+ size_elem = ( large ? 4 : 2 );
+
+ if ( ALLOC_ARRAY( range->glyph_offsets,
+ num_glyphs, TT_ULong ) ||
+
+ ACCESS_Frame( num_glyphs * size_elem ) )
+ goto Exit;
+
+ for ( n = 0; n < num_glyphs; n++ )
+ range->glyph_offsets[n] = (TT_ULong)( range->image_offset +
+ (large ? GET_ULong() : GET_UShort()) );
+ FORGET_Frame();
+ }
+ break;
+
+ case 2: /* all glyphs have identical metrics */
+ error = Load_SBit_Const_Metrics( range, stream );
+ break;
+
+ case 4:
+ error = Load_SBit_Range_Codes( range, stream, 1 );
+ break;
+
+ case 5:
+ error = Load_SBit_Const_Metrics( range, stream ) ||
+ Load_SBit_Range_Codes( range, stream, 0 );
+ break;
+
+ default:
+ error = TT_Err_Invalid_File_Format;
+ }
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_SBit_Strikes */
+ /* */
+ /* <Description> */
+ /* Loads the table of embedded bitmap sizes for this face. */
+ /* */
+ /* <Input> */
+ /* face :: The target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_SBit_Strikes( TT_Face face,
+ FT_Stream stream )
+ {
+ TT_Error error = 0;
+ FT_Memory memory = stream->memory;
+ TT_Fixed version;
+ TT_ULong num_strikes;
+ TT_ULong table_base;
+ TT_Long table;
+
+
+ /* this table is optional */
+ if ( ( table = TT_LookUp_Table( face, TTAG_EBLC ) ) < 0 )
+ goto Exit;
+
+ table_base = face->dir_tables[table].Offset;
+ if ( FILE_Seek( table_base ) ||
+ ACCESS_Frame( 8L ) )
+ goto Exit;
+
+ version = GET_Long();
+ num_strikes = GET_ULong();
+
+ FORGET_Frame();
+
+ /* check version number and strike count */
+ if ( version != 0x00020000 ||
+ num_strikes >= 0x10000 )
+ {
+ FT_ERROR(( "TT_Load_SBit_Strikes: invalid table version!\n" ));
+ error = TT_Err_Invalid_File_Format;
+
+ goto Exit;
+ }
+
+ /* allocate the strikes table */
+ if ( ALLOC_ARRAY( face->sbit_strikes, num_strikes, TT_SBit_Strike ) )
+ goto Exit;
+
+ face->num_sbit_strikes = num_strikes;
+
+ /* now read each strike table separately */
+ {
+ TT_SBit_Strike* strike = face->sbit_strikes;
+ TT_ULong count = num_strikes;
+
+ if ( ACCESS_Frame( 48L * num_strikes ) )
+ goto Exit;
+
+ while ( count > 0 )
+ {
+ TT_ULong indexTablesSize;
+
+
+ strike->ranges_offset = GET_ULong();
+ indexTablesSize = GET_ULong(); /* don't save */
+
+ strike->num_ranges = GET_ULong();
+ strike->color_ref = GET_ULong();
+
+ TT_Load_SBit_Line_Metrics( &strike->hori, stream );
+ TT_Load_SBit_Line_Metrics( &strike->vert, stream );
+
+ 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();
+
+ count--;
+ strike++;
+ }
+
+ FORGET_Frame();
+ }
+
+ /* allocate the index ranges for each strike table */
+ {
+ TT_SBit_Strike* strike = face->sbit_strikes;
+ TT_ULong count = num_strikes;
+
+
+ while ( count > 0 )
+ {
+ TT_SBit_Range* range;
+ TT_ULong count2 = strike->num_ranges;
+
+
+ if ( ALLOC_ARRAY( strike->sbit_ranges,
+ strike->num_ranges,
+ TT_SBit_Range ) )
+ goto Exit;
+
+ /* read each range */
+ if ( FILE_Seek( table_base + strike->ranges_offset ) ||
+ ACCESS_Frame( strike->num_ranges * 8L ) )
+ goto Exit;
+
+ range = strike->sbit_ranges;
+ while ( count2 > 0 )
+ {
+ range->first_glyph = GET_UShort();
+ range->last_glyph = GET_UShort();
+ range->table_offset = table_base + strike->ranges_offset
+ + GET_ULong();
+ count2--;
+ range++;
+ }
+
+ FORGET_Frame();
+
+ /* Now, read each index table */
+ count2 = strike->num_ranges;
+ range = strike->sbit_ranges;
+ while ( count2 > 0 )
+ {
+ /* Read the header */
+ if ( FILE_Seek( range->table_offset ) ||
+ ACCESS_Frame( 8L ) )
+ goto Exit;
+
+ range->index_format = GET_UShort();
+ range->image_format = GET_UShort();
+ range->image_offset = GET_ULong();
+
+ FORGET_Frame();
+
+ error = Load_SBit_Range( range, stream );
+ if ( error )
+ goto Exit;
+
+ count2--;
+ range++;
+ }
+
+ count--;
+ strike++;
+ }
+ }
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Free_SBit_Strikes */
+ /* */
+ /* <Description> */
+ /* Releases the embedded bitmap tables. */
+ /* */
+ /* <Input> */
+ /* face :: The target face object. */
+ /* */
+ LOCAL_FUNC
+ void TT_Free_SBit_Strikes( TT_Face face )
+ {
+ FT_Memory memory = face->root.memory;
+ TT_SBit_Strike* strike = face->sbit_strikes;
+ TT_SBit_Strike* strike_limit = strike + face->num_sbit_strikes;
+
+
+ if ( strike )
+ {
+ for ( ; strike < strike_limit; strike++ )
+ {
+ TT_SBit_Range* range = strike->sbit_ranges;
+ TT_SBit_Range* range_limit = range + strike->num_ranges;
+
+ if ( range )
+ {
+ for ( ; range < range_limit; range++ )
+ {
+ /* release the glyph offsets and codes tables */
+ /* where appropriate */
+ FREE( range->glyph_offsets );
+ FREE( range->glyph_codes );
+ }
+ }
+ FREE( strike->sbit_ranges );
+ strike->num_ranges = 0;
+ }
+ FREE( face->sbit_strikes );
+ }
+ face->num_sbit_strikes = 0;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Find_SBit_Range */
+ /* */
+ /* <Description> */
+ /* Scans a given strike's ranges and return, for a given glyph */
+ /* index, the corresponding sbit range, and `EBDT' offset. */
+ /* */
+ /* <Input> */
+ /* glyph_index :: The glyph index. */
+ /* strike :: The source/current sbit strike. */
+ /* */
+ /* <Output> */
+ /* arange :: The sbit range containing the glyph index. */
+ /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means the glyph index was found. */
+ /* */
+ static
+ TT_Error Find_SBit_Range( TT_UShort glyph_index,
+ TT_SBit_Strike* strike,
+ TT_SBit_Range** arange,
+ TT_ULong* aglyph_offset )
+ {
+ TT_SBit_Range *range, *range_limit;
+
+
+ /* check whether the glyph index is within this strike's */
+ /* glyph range */
+ if ( glyph_index < strike->start_glyph ||
+ glyph_index > strike->end_glyph )
+ goto Fail;
+
+ /* scan all ranges in strike */
+ range = strike->sbit_ranges;
+ range_limit = range + strike->num_ranges;
+ if ( !range )
+ goto Fail;
+
+ for ( ; range < range_limit; range++ )
+ {
+ if ( glyph_index >= range->first_glyph &&
+ glyph_index <= range->last_glyph )
+ {
+ TT_UShort delta = glyph_index - range->first_glyph;
+
+
+ switch ( range->index_format )
+ {
+ case 1:
+ case 3:
+ *aglyph_offset = range->glyph_offsets[delta];
+ break;
+
+ case 2:
+ *aglyph_offset = range->image_offset +
+ range->image_size * delta;
+ break;
+
+ case 4:
+ case 5:
+ {
+ TT_ULong n;
+
+
+ for ( n = 0; n < range->num_glyphs; n++ )
+ {
+ if ( range->glyph_codes[n] == glyph_index )
+ {
+ if ( range->index_format == 4 )
+ *aglyph_offset = range->glyph_offsets[n];
+ else
+ *aglyph_offset = range->image_offset +
+ n * range->image_size;
+ break;
+ }
+ }
+ }
+
+ /* fall-through */
+ default:
+ goto Fail;
+ }
+
+ /* return successfully! */
+ *arange = range;
+
+ return 0;
+ }
+ }
+
+ Fail:
+ *arange = 0;
+ *aglyph_offset = 0;
+
+ return TT_Err_Invalid_Argument;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Find_SBit_Image */
+ /* */
+ /* <Description> */
+ /* Checks whether an embedded bitmap (an `sbit') exists for a given */
+ /* glyph, at given x and y ppems. */
+ /* */
+ /* <Input> */
+ /* face :: The target face object. */
+ /* glyph_index :: The glyph index. */
+ /* x_ppem :: The horizontal resolution in points per EM. */
+ /* y_ppem :: The vertical resolution in points per EM. */
+ /* */
+ /* <Output> */
+ /* arange :: The SBit range containing the glyph index. */
+ /* astrike :: The SBit strike containing the glyph index. */
+ /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. Returns */
+ /* TT_Err_Invalid_Argument if no sbit exist for the requested glyph. */
+ /* */
+ static
+ TT_Error Find_SBit_Image( TT_Face face,
+ TT_UShort glyph_index,
+ TT_Int x_ppem,
+ TT_Int y_ppem,
+
+ TT_SBit_Range** arange,
+ TT_SBit_Strike** astrike,
+ TT_ULong* aglyph_offset )
+ {
+ TT_SBit_Strike* strike = face->sbit_strikes;
+ TT_SBit_Strike* strike_limit = strike + face->num_sbit_strikes;
+
+
+ if ( !strike)
+ goto Fail;
+
+ for ( ; strike < strike_limit; strike++ )
+ {
+ if ( strike->x_ppem == x_ppem && strike->y_ppem == y_ppem )
+ {
+ TT_Error error;
+
+
+ error = Find_SBit_Range( glyph_index, strike, arange, aglyph_offset );
+ if ( error )
+ goto Fail;
+
+ *astrike = strike;
+
+ return TT_Err_Ok;
+ }
+ }
+
+ Fail:
+ /* no embedded bitmap for this glyph in face */
+ *arange = 0;
+ *astrike = 0;
+ *aglyph_offset = 0;
+
+ return TT_Err_Invalid_Argument;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Load_SBit_Metrics */
+ /* */
+ /* <Description> */
+ /* Gets the big metrics for a given SBit. */
+ /* */
+ /* <Input> */
+ /* stream :: The input stream. */
+ /* range :: The SBit range containing the glyph. */
+ /* */
+ /* <Output> */
+ /* big_metrics :: A big SBit metrics structure for the glyph. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* The stream cursor must be positioned at the glyph's offset within */
+ /* the `EBDT' table before the call. */
+ /* */
+ /* If the image format uses variable metrics, the stream cursor is */
+ /* positioned just after the metrics header in the `EBDT' table on */
+ /* function exit. */
+ /* */
+ static
+ TT_Error Load_SBit_Metrics( FT_Stream stream,
+ TT_SBit_Range* range,
+ TT_SBit_Metrics* metrics )
+ {
+ TT_Error error = TT_Err_Ok;
+
+
+ switch ( range->index_format )
+ {
+ case 1: /* variable metrics */
+ case 3:
+ case 4:
+ {
+ switch ( range->image_format )
+ {
+ case 1: /* small metrics */
+ case 2:
+ case 8:
+ {
+ TT_SBit_Small_Metrics smetrics;
+
+
+ /* read small metrics */
+ if ( ACCESS_Frame( 5L ) )
+ goto Exit;
+ TT_Load_Small_SBit_Metrics( &smetrics, stream );
+ FORGET_Frame();
+
+ /* convert it to a big metrics */
+ metrics->height = smetrics.height;
+ metrics->width = smetrics.width;
+ metrics->horiBearingX = smetrics.bearingX;
+ metrics->horiBearingY = smetrics.bearingY;
+ metrics->horiAdvance = smetrics.advance;
+
+ /* these metrics are made up at a higher level when */
+ /* needed. */
+ metrics->vertBearingX = 0;
+ metrics->vertBearingY = 0;
+ metrics->vertAdvance = 0;
+ }
+ break;
+
+ default: /* big metrics */
+ if ( ACCESS_Frame( 8L ) )
+ goto Exit;
+ TT_Load_SBit_Metrics( metrics, stream );
+ FORGET_Frame();
+ }
+ }
+ break;
+
+ default: /* constant metrics */
+ *metrics = range->metrics;
+ }
+
+ Exit:
+ return error;
+ }
+
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Crop_Bitmap */
+ /* */
+ /* <Description> */
+ /* Crops a bitmap to its tightest bounding box, and adjusts its */
+ /* metrics. */
+ /* */
+ /* <Input> */
+ /* image :: The input glyph slot. */
+ /* */
+ /* metrics :: The corresponding metrics structure. */
+ /* */
+ static
+ void Crop_Bitmap( FT_Bitmap* map,
+ TT_SBit_Metrics* metrics )
+ {
+ /***********************************************************************/
+ /* */
+ /* In this situation, some bounding boxes of embedded bitmaps are too */
+ /* large. We need to crop it to a reasonable size. */
+ /* */
+ /* --------- */
+ /* | | ----- */
+ /* | *** | |***| */
+ /* | * | | * | */
+ /* | * | ------> | * | */
+ /* | * | | * | */
+ /* | * | | * | */
+ /* | *** | |***| */
+ /* --------- ----- */
+ /* */
+ /***********************************************************************/
+
+ TT_Int rows, count;
+ TT_Long line_len;
+ TT_Byte* line;
+
+
+ /***********************************************************************/
+ /* */
+ /* first of all, checks the top-most lines of the bitmap, and removes */
+ /* them if they're empty. */
+ /* */
+ {
+ line = (TT_Byte*)map->buffer;
+ rows = map->rows;
+ line_len = map->pitch;
+
+
+ for ( count = 0; count < rows; count++ )
+ {
+ TT_Byte* cur = line;
+ TT_Byte* limit = line + line_len;
+
+
+ for ( ; cur < limit; cur++ )
+ if ( cur[0] )
+ goto Found_Top;
+
+ /* the current line was empty - skip to next one */
+ line = limit;
+ }
+
+ Found_Top:
+ /* check that we have at least one filled line */
+ if ( count >= rows )
+ goto Empty_Bitmap;
+
+ /* now, crop the empty upper lines */
+ if ( count > 0 )
+ {
+ line = (TT_Byte*)map->buffer;
+
+ MEM_Move( line, line + count * line_len, (rows - count) * line_len );
+
+ metrics->height -= count;
+ metrics->horiBearingY -= count;
+ metrics->vertBearingY -= count;
+
+ map->rows -= count;
+ rows -= count;
+ }
+ }
+
+ /***********************************************************************/
+ /* */
+ /* second, crop the lower lines */
+ /* */
+ {
+ line = (TT_Byte*)map->buffer + (rows - 1) * line_len;
+
+ for ( count = 0; count < rows; count++ )
+ {
+ TT_Byte* cur = line;
+ TT_Byte* limit = line + line_len;
+
+
+ for ( ; cur < limit; cur++ )
+ if ( cur[0] )
+ goto Found_Bottom;
+
+ /* the current line was empty - skip to previous one */
+ line -= line_len;
+ }
+
+ Found_Bottom:
+ if ( count > 0 )
+ {
+ metrics->height -= count;
+ rows -= count;
+ map->rows -= count;
+ }
+ }
+
+ /***********************************************************************/
+ /* */
+ /* third, get rid of the space on the left side of the glyph */
+ /* */
+ do
+ {
+ TT_Byte* limit;
+
+
+ line = (TT_Byte*)map->buffer;
+ limit = line + rows * line_len;
+
+ for ( ; line < limit; line += line_len )
+ if ( line[0] & 0x80 )
+ goto Found_Left;
+
+ /* shift the whole glyph one pixel to the left */
+ line = (TT_Byte*)map->buffer;
+ limit = line + rows * line_len;
+
+ for ( ; line < limit; line += line_len )
+ {
+ TT_Int n, width = map->width;
+ TT_Byte old;
+ TT_Byte* cur = line;
+
+
+ old = cur[0] << 1;
+ for ( n = 8; n < width; n += 8 )
+ {
+ TT_Byte val;
+
+
+ val = cur[1];
+ cur[0] = old | (val >> 7);
+ old = val << 1;
+ cur++;
+ }
+ cur[0] = old;
+ }
+
+ map->width--;
+ metrics->horiBearingX++;
+ metrics->vertBearingX++;
+ metrics->width--;
+ } while ( map->width > 0 );
+
+ Found_Left:
+
+ /***********************************************************************/
+ /* */
+ /* finally, crop the bitmap width to get rid of the space on the right */
+ /* side of the glyph. */
+ /* */
+ do
+ {
+ TT_Int right = map->width-1;
+ TT_Byte* limit;
+ TT_Byte mask;
+
+
+ line = (TT_Byte*)map->buffer + (right >> 3);
+ limit = line + rows*line_len;
+ mask = 0x80 >> (right & 7);
+
+ for ( ; line < limit; line += line_len )
+ if ( line[0] & mask )
+ goto Found_Right;
+
+ /* crop the whole glyph to the right */
+ map->width--;
+ metrics->width--;
+ } while ( map->width > 0 );
+
+ Found_Right:
+ /* all right, the bitmap was cropped */
+ return;
+
+ Empty_Bitmap:
+ map->width = 0;
+ map->rows = 0;
+ map->pitch = 0;
+ map->pixel_mode = ft_pixel_mode_mono;
+ }
+
+
+ static
+ TT_Error Load_SBit_Single( FT_Bitmap* map,
+ TT_Int x_offset,
+ TT_Int y_offset,
+ TT_Int pix_bits,
+ TT_UShort image_format,
+ TT_SBit_Metrics* metrics,
+ FT_Stream stream )
+ {
+ TT_Error error;
+
+
+ /* check that the source bitmap fits into the target pixmap */
+ if ( x_offset < 0 || x_offset + metrics->width > map->width ||
+ y_offset < 0 || y_offset + metrics->height > map->rows )
+ {
+ error = TT_Err_Invalid_Argument;
+
+ goto Exit;
+ }
+
+ {
+ TT_Int glyph_width = metrics->width;
+ TT_Int glyph_height = metrics->height;
+ TT_Int glyph_size;
+ TT_Int line_bits = pix_bits * glyph_width;
+ TT_Bool pad_bytes = 0;
+
+
+ /* compute size of glyph image */
+ switch ( image_format )
+ {
+ case 1: /* byte-padded formats */
+ case 6:
+ {
+ TT_Int line_length;
+
+
+ switch ( pix_bits )
+ {
+ case 1: line_length = (glyph_width+7) >> 3; break;
+ case 2: line_length = (glyph_width+3) >> 2; break;
+ case 4: line_length = (glyph_width+1) >> 1; break;
+ default: line_length = glyph_width;
+ }
+
+ glyph_size = glyph_height * line_length;
+ pad_bytes = 1;
+ }
+ break;
+
+ case 2:
+ case 5:
+ case 7:
+ line_bits = glyph_width * pix_bits;
+ glyph_size = (glyph_height * line_bits + 7) >> 3;
+ break;
+
+ default: /* invalid format */
+ return TT_Err_Invalid_File_Format;
+ }
+
+ /* Now read data and draw glyph into target pixmap */
+ if ( ACCESS_Frame( glyph_size ) )
+ goto Exit;
+
+ /* don't forget to multiply `x_offset' by `map->pix_bits' as */
+ /* the sbit blitter doesn't make a difference between pixmap */
+ /* depths. */
+ blit_sbit( map, stream->cursor, line_bits, pad_bytes,
+ x_offset * pix_bits, y_offset );
+
+ FORGET_Frame();
+ }
+
+ Exit:
+ return error;
+ }
+
+
+ static
+ TT_Error Load_SBit_Image( TT_SBit_Strike* strike,
+ TT_SBit_Range* range,
+ TT_ULong ebdt_pos,
+ TT_ULong glyph_offset,
+ FT_Bitmap* map,
+ TT_Int x_offset,
+ TT_Int y_offset,
+ FT_Stream stream,
+ TT_SBit_Metrics* metrics )
+ {
+ FT_Memory memory = stream->memory;
+ TT_Error error;
+
+
+ /* place stream at beginning of glyph data and read metrics */
+ if ( FILE_Seek( ebdt_pos + glyph_offset ) )
+ goto Exit;
+
+ error = Load_SBit_Metrics( stream, range, metrics );
+ if ( error )
+ goto Exit;
+
+ /* this function is recursive. At the top-level call, the */
+ /* field map.buffer is NULL. We thus begin by finding the */
+ /* dimensions of the higher-level glyph to allocate the */
+ /* final pixmap buffer */
+ if ( map->buffer == 0 )
+ {
+ TT_Long size;
+
+
+ map->width = metrics->width;
+ map->rows = metrics->height;
+
+ switch ( strike->bit_depth )
+ {
+ case 1:
+ map->pixel_mode = ft_pixel_mode_mono;
+ map->pitch = (map->width+7) >> 3;
+ break;
+ case 2:
+ map->pixel_mode = ft_pixel_mode_pal2;
+ map->pitch = (map->width+3) >> 2;
+ break;
+ case 4:
+ map->pixel_mode = ft_pixel_mode_pal4;
+ map->pitch = (map->width+1) >> 1;
+ break;
+ case 8:
+ map->pixel_mode = ft_pixel_mode_grays;
+ map->pitch = map->width;
+ break;
+
+ default:
+ return TT_Err_Invalid_File_Format;
+ }
+
+ size = map->rows * map->pitch;
+
+ /* check that there is no empty image */
+ if ( size == 0 )
+ goto Exit; /* exit successfully! */
+
+ if ( ALLOC( map->buffer, size ) )
+ goto Exit;
+ }
+
+ switch ( range->image_format )
+ {
+ case 1: /* single sbit image - load it */
+ case 2:
+ case 5:
+ case 6:
+ case 7:
+ return Load_SBit_Single( map, x_offset, y_offset, strike->bit_depth,
+ range->image_format, metrics, stream );
+
+ case 8: /* compound format */
+ case 9:
+ break;
+
+ default: /* invalid image format */
+ return TT_Err_Invalid_File_Format;
+ }
+
+ /* All right, we're in a compound format. First of all, read */
+ /* the array of elements */
+ {
+ TT_SBit_Component* components;
+ TT_SBit_Component* comp;
+ TT_UShort num_components, count;
+
+
+ if ( READ_UShort( num_components ) ||
+ ALLOC_ARRAY( components, num_components, TT_SBit_Component ) )
+ goto Exit;
+
+ count = num_components;
+
+ if ( ACCESS_Frame( 4L * num_components ) )
+ goto Fail_Memory;
+
+ for ( comp = components; count > 0; count--, comp++ )
+ {
+ comp->glyph_code = GET_UShort();
+ comp->x_offset = GET_Char();
+ comp->y_offset = GET_Char();
+ }
+
+ FORGET_Frame();
+
+ /* Now recursively load each element glyph */
+ count = num_components;
+ comp = components;
+ for ( ; count > 0; count--, comp++ )
+ {
+ TT_SBit_Range* elem_range;
+ TT_SBit_Metrics elem_metrics;
+ TT_ULong elem_offset;
+
+
+ /* find the range for this element */
+ error = Find_SBit_Range( comp->glyph_code,
+ strike,
+ &elem_range,
+ &elem_offset );
+ if ( error )
+ goto Fail_Memory;
+
+ /* now load the element, recursively */
+ error = Load_SBit_Image( strike,
+ elem_range,
+ ebdt_pos,
+ elem_offset,
+ map,
+ x_offset + comp->x_offset,
+ y_offset + comp->y_offset,
+ stream,
+ &elem_metrics );
+ if ( error )
+ goto Fail_Memory;
+ }
+
+ Fail_Memory:
+ FREE( components );
+ }
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_SBit_Image */
+ /* */
+ /* <Description> */
+ /* Loads a given glyph sbit image from the font resource. This also */
+ /* returns its metrics. */
+ /* */
+ /* <Input> */
+ /* face :: The target face object. */
+ /* */
+ /* x_ppem :: The horizontal resolution in points per EM. */
+ /* */
+ /* y_ppem :: The vertical resolution in points per EM. */
+ /* */
+ /* glyph_index :: The current glyph index. */
+ /* */
+ /* stream :: The input stream. */
+ /* */
+ /* <Output> */
+ /* map :: The target pixmap. */
+ /* metrics :: A big sbit metrics structure for the glyph image. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. Returns an error if no */
+ /* glyph sbit exists for the index. */
+ /* */
+ /* <Note> */
+ /* The `map.buffer' field is always freed before the glyph is loaded. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_SBit_Image( TT_Face face,
+ TT_Int x_ppem,
+ TT_Int y_ppem,
+ TT_UInt glyph_index,
+ FT_Stream stream,
+ FT_Bitmap* map,
+ TT_SBit_Metrics* metrics )
+ {
+ TT_Error error;
+ FT_Memory memory = stream->memory;
+ TT_ULong ebdt_pos, glyph_offset;
+
+ TT_SBit_Strike* strike;
+ TT_SBit_Range* range;
+
+
+ /* Check whether there is a glyph sbit for the current index */
+ error = Find_SBit_Image( face, glyph_index, x_ppem, y_ppem,
+ &range, &strike, &glyph_offset );
+ if ( error )
+ goto Exit;
+
+ /* now, find the location of the `EBDT' table in */
+ /* the font file */
+ {
+ TT_Long table = TT_LookUp_Table( face, TTAG_EBDT );
+
+
+ if ( table < 0 )
+ {
+ error = TT_Err_Invalid_File_Format;
+ goto Exit;
+ }
+
+ ebdt_pos = face->dir_tables[table].Offset;
+ }
+
+ /* clear the bitmap & load the bitmap */
+ FREE( map->buffer );
+ map->rows = map->pitch = map->width = 0;
+
+ error = Load_SBit_Image( strike, range, ebdt_pos, glyph_offset,
+ map, 0, 0, stream, metrics );
+ if ( error )
+ goto Exit;
+
+ /* setup vertical metrics if needed */
+ if ( strike->flags & 1 )
+ {
+ /* in case of a horizontal strike only */
+ FT_Int advance;
+ FT_Int top;
+
+
+ advance = strike->hori.ascender - strike->hori.descender;
+ top = advance / 10;
+
+ metrics->vertBearingX = -metrics->width / 2;
+ metrics->vertBearingY = advance / 10;
+ metrics->vertAdvance = advance * 12 / 10;
+ }
+
+ /* Crop the bitmap now */
+ Crop_Bitmap( map, metrics );
+
+ Exit:
+ return error;
+ }
+
+
+/* END */
--- /dev/null
+++ b/src/shared/sfnt/ttsbit.h
@@ -1,0 +1,104 @@
+/***************************************************************************/
+/* */
+/* ttsbit.h */
+/* */
+/* TrueType and OpenType embedded bitmap support (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 TTSBIT_H
+#define TTSBIT_H
+
+#include <ttload.h>
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_SBit_Strikes */
+ /* */
+ /* <Description> */
+ /* Loads the table of embedded bitmap sizes for this face. */
+ /* */
+ /* <Input> */
+ /* face :: The target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_SBit_Strikes( TT_Face face,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Free_SBit_Strikes */
+ /* */
+ /* <Description> */
+ /* Releases the embedded bitmap tables. */
+ /* */
+ /* <Input> */
+ /* face :: The target face object. */
+ /* */
+ LOCAL_DEF
+ void TT_Free_SBit_Strikes( TT_Face face );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_SBit_Image */
+ /* */
+ /* <Description> */
+ /* Loads a given glyph sbit image from the font resource. This also */
+ /* returns its metrics. */
+ /* */
+ /* <Input> */
+ /* face :: The target face object. */
+ /* */
+ /* x_ppem :: The horizontal resolution in points per EM. */
+ /* */
+ /* y_ppem :: The vertical resolution in points per EM. */
+ /* */
+ /* glyph_index :: The current glyph index. */
+ /* */
+ /* stream :: The input stream. */
+ /* */
+ /* <Output> */
+ /* map :: The target pixmap. */
+ /* metrics :: A big sbit metrics structure for the glyph image. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. Returns an error if no */
+ /* glyph sbit exists for the index. */
+ /* */
+ /* <Note> */
+ /* The `map.buffer' field is always freed before the glyph is loaded. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_SBit_Image( TT_Face face,
+ TT_Int x_ppem,
+ TT_Int y_ppem,
+ TT_UInt glyph_index,
+ FT_Stream stream,
+ FT_Bitmap* map,
+ TT_SBit_Metrics* metrics );
+
+
+#endif /* TTSBIT_H */
+
+
+/* END */
--- /dev/null
+++ b/src/shared/sfnt/tttypes.h
@@ -1,0 +1,1848 @@
+/***************************************************************************/
+/* */
+/* tttypes.h */
+/* */
+/* Basic SFNT/TrueType type definitions and interface (specification */
+/* only). */
+/* */
+/* This code is shared by all TrueType and OpenType drivers. */
+/* */
+/* */
+/* 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 TTTYPES_H
+#define TTTYPES_H
+
+
+#include <freetype.h>
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*** ***/
+ /*** ***/
+ /*** DEFINITIONS OF BASIC DATA TYPES ***/
+ /*** ***/
+ /*** ***/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* The REDEFINE() macro is used to convert a FreeType generic type into */
+ /* a TrueType-specific one. It simply replaces the `FT_' prefix by */
+ /* `TT_' in order to define compatible types like TT_Long, TT_Error, */
+ /* TT_Outline, etc. */
+ /* */
+#undef REDEFINE
+#define REDEFINE( type ) typedef FT_##type TT_##type
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_Bool */
+ /* */
+ /* <Description> */
+ /* A typedef of unsigned char, used for simple booleans. */
+ /* */
+ REDEFINE( Bool );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_FWord */
+ /* */
+ /* <Description> */
+ /* A signed 16-bit integer used to store a distance in original font */
+ /* units. */
+ /* */
+ REDEFINE( FWord );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_UFWord */
+ /* */
+ /* <Description> */
+ /* An unsigned 16-bit integer used to store a distance in original */
+ /* font units. */
+ /* */
+ REDEFINE( UFWord );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_Char */
+ /* */
+ /* <Description> */
+ /* A simple typedef for the _signed_ char type. */
+ /* */
+ REDEFINE( Char );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_Byte */
+ /* */
+ /* <Description> */
+ /* A simple typedef for the _unsigned_ char type. */
+ /* */
+ REDEFINE( Byte );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_String */
+ /* */
+ /* <Description> */
+ /* A simple typedef for the char type, usually used for strings. */
+ /* */
+ REDEFINE( String );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_Short */
+ /* */
+ /* <Description> */
+ /* A typedef for signed short. */
+ /* */
+ REDEFINE( Short );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_UShort */
+ /* */
+ /* <Description> */
+ /* A typedef for unsigned short. */
+ /* */
+ REDEFINE( UShort );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_Int */
+ /* */
+ /* <Description> */
+ /* A typedef for the int type. */
+ /* */
+ REDEFINE( Int );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_UInt */
+ /* */
+ /* <Description> */
+ /* A typedef for the unsigned int type. */
+ /* */
+ REDEFINE( UInt );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_Long */
+ /* */
+ /* <Description> */
+ /* A typedef for signed long. */
+ /* */
+ REDEFINE( Long );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_ULong */
+ /* */
+ /* <Description> */
+ /* A typedef for unsigned long. */
+ /* */
+ REDEFINE( ULong );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_F2Dot14 */
+ /* */
+ /* <Description> */
+ /* A signed 2.14 fixed float type used for unit vectors. */
+ /* */
+ REDEFINE( F2Dot14 );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_F26Dot6 */
+ /* */
+ /* <Description> */
+ /* A signed 26.6 fixed float type used for vectorial pixel */
+ /* coordinates. */
+ /* */
+ REDEFINE( F26Dot6 );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_Fixed */
+ /* */
+ /* <Description> */
+ /* This type is used to store 16.16 fixed float values, like scales */
+ /* or matrix coefficients. */
+ /* */
+ REDEFINE( Fixed );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_Pos */
+ /* */
+ /* <Description> */
+ /* The type FT_Pos is a 32-bit integer used to store vectorial */
+ /* coordinates. Depending on the context, these can represent */
+ /* distances in integer font units, or 26.6 fixed float pixel */
+ /* coordinates. */
+ /* */
+ REDEFINE( Pos );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_Vector */
+ /* */
+ /* <Description> */
+ /* A simple structure used to store a 2d vector; coordinates are of */
+ /* the TT_Pos type. */
+ /* */
+ /* <Fields> */
+ /* x :: The horizontal coordinate. */
+ /* y :: The vertical coordinate. */
+ /* */
+ REDEFINE( Vector );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_UnitVector */
+ /* */
+ /* <Description> */
+ /* A simple structure used to store a 2d vector unit vector. Uses */
+ /* TT_F2Dot14 types. */
+ /* */
+ /* <Fields> */
+ /* x :: Horizontal coordinate. */
+ /* y :: Vertical coordinate. */
+ /* */
+ REDEFINE( UnitVector );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_Matrix */
+ /* */
+ /* <Description> */
+ /* A simple structure used to store a 2x2 matrix. Coefficients are */
+ /* in 16.16 fixed float format. The computation performed is: */
+ /* */
+ /* { */
+ /* x' = x*xx + y*xy */
+ /* y' = x*yx + y*yy */
+ /* } */
+ /* */
+ /* <Fields> */
+ /* xx :: Matrix coefficient. */
+ /* xy :: Matrix coefficient. */
+ /* yx :: Matrix coefficient. */
+ /* yy :: Matrix coefficient. */
+ /* */
+ REDEFINE( Matrix );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_BBox */
+ /* */
+ /* <Description> */
+ /* A structure used to hold an outline's bounding box, i.e., the */
+ /* coordinates of its extrema in the horizontal and vertical */
+ /* directions. */
+ /* */
+ /* <Fields> */
+ /* xMin :: The horizontal minimum (left-most). */
+ /* yMin :: The vertical minimum (bottom-most). */
+ /* xMax :: The horizontal maximum (right-most). */
+ /* yMax :: The vertical maximum (top-most). */
+ /* */
+ REDEFINE( BBox );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_Error */
+ /* */
+ /* <Description> */
+ /* The TrueType error code type. A value of 0 is always interpreted */
+ /* as a successful operation. */
+ /* */
+ REDEFINE( Error );
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*** ***/
+ /*** ***/
+ /*** REQUIRED TRUETYPE/OPENTYPE TABLES DEFINITIONS ***/
+ /*** ***/
+ /*** ***/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TTC_Header */
+ /* */
+ /* <Description> */
+ /* TrueType collection header. This table contains the offsets of */
+ /* the font headers of each distinct TrueType face in the file. */
+ /* */
+ /* <Fields> */
+ /* tag :: Must be `ttc ' to indicate a TrueType collection. */
+ /* version :: The version number. */
+ /* count :: The number of faces in the collection. The */
+ /* specification says this should be an unsigned long, but */
+ /* we use a signed long since we need the value -1 for */
+ /* specific purposes. */
+ /* offsets :: The offsets of the font headers, one per face. */
+ /* */
+ typedef struct TTC_Header_
+ {
+ TT_ULong Tag;
+ TT_Fixed version;
+ TT_Long DirCount;
+ TT_ULong* TableDirectory;
+
+ } TTC_Header;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_TableDir */
+ /* */
+ /* <Description> */
+ /* This structure models a TrueType table directory. It is used to */
+ /* access the various tables of the font face. */
+ /* */
+ /* <Fields> */
+ /* version :: The version number; starts with 0x00010000. */
+ /* numTables :: The number of tables. */
+ /* */
+ /* searchRange :: Unused. */
+ /* entrySelector :: Unused. */
+ /* rangeShift :: Unused. */
+ /* */
+ /* <Note> */
+ /* This structure is only used during font opening. */
+ /* */
+ typedef struct TT_TableDir_
+ {
+ TT_Fixed version; /* should be 0x10000 */
+ TT_UShort numTables; /* number of tables */
+
+ TT_UShort searchRange; /* These parameters are only used */
+ TT_UShort entrySelector; /* for a dichotomy search in the */
+ TT_UShort rangeShift; /* directory. We ignore them. */
+
+ } TT_TableDir;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_TableDirEntry */
+ /* */
+ /* <Description> */
+ /* This structure describes a given table of a TrueType font. */
+ /* */
+ /* <Fields> */
+ /* Tag :: A four-bytes tag describing the table. */
+ /* CheckSum :: The table checksum. This value can be ignored. */
+ /* Offset :: The offset of the table from the start of the TrueType */
+ /* font in its resource. */
+ /* Length :: The table length (in bytes). */
+ /* */
+ typedef struct TT_TableDirEntry_
+ {
+ TT_ULong Tag; /* table type */
+ TT_ULong CheckSum; /* table checksum */
+ TT_ULong Offset; /* table file offset */
+ TT_ULong Length; /* table length */
+
+ } TT_TableDirEntry;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_Header */
+ /* */
+ /* <Description> */
+ /* A structure used to model a TrueType font header table. All */
+ /* fields follow the TrueType specification. */
+ /* */
+ typedef 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;
+
+ } TT_Header;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_HoriHeader */
+ /* */
+ /* <Description> */
+ /* A structure used to model a TrueType horizontal header, the `hhea' */
+ /* table, as well as the corresponding horizontal metrics table, */
+ /* i.e., the `hmtx' table. */
+ /* */
+ /* <Fields> */
+ /* Version :: The table version. */
+ /* */
+ /* Ascender :: The font's ascender, i.e., the distance */
+ /* from the baseline to the top-most of all */
+ /* glyph points found in the font. */
+ /* */
+ /* This value is invalid in many fonts, as */
+ /* it is usually set by the font designer, */
+ /* and often reflects only a portion of the */
+ /* glyphs found in the font (maybe ASCII). */
+ /* */
+ /* You should use the `sTypoAscender' field */
+ /* of the OS/2 table instead if you want */
+ /* the correct one. */
+ /* */
+ /* Descender :: The font's descender, i.e., the distance */
+ /* from the baseline to the bottom-most of */
+ /* all glyph points found in the font. It */
+ /* is negative. */
+ /* */
+ /* This value is invalid in many fonts, as */
+ /* it is usually set by the font designer, */
+ /* and often reflects only a portion of the */
+ /* glyphs found in the font (maybe ASCII). */
+ /* */
+ /* You should use the `sTypoDescender' */
+ /* field of the OS/2 table instead if you */
+ /* want the correct one. */
+ /* */
+ /* Line_Gap :: The font's line gap, i.e., the distance */
+ /* to add to the ascender and descender to */
+ /* get the BTB, i.e., the */
+ /* baseline-to-baseline distance for the */
+ /* font. */
+ /* */
+ /* advance_Width_Max :: This field is the maximum of all advance */
+ /* widths found in the font. It can be */
+ /* used to compute the maximum width of an */
+ /* arbitrary string of text. */
+ /* */
+ /* min_Left_Side_Bearing :: The minimum left side bearing of all */
+ /* glyphs within the font. */
+ /* */
+ /* min_Right_Side_Bearing :: The minimum right side bearing of all */
+ /* glyphs within the font. */
+ /* */
+ /* xMax_Extent :: The maximum horizontal extent (i.e., the */
+ /* `width' of a glyph's bounding box) for */
+ /* all glyphs in the font. */
+ /* */
+ /* caret_Slope_Rise :: The rise coefficient of the cursor's */
+ /* slope of the cursor (slope=rise/run). */
+ /* */
+ /* caret_Slope_Run :: The run coefficient of the cursor's */
+ /* slope. */
+ /* */
+ /* Reserved :: 10 reserved bytes. */
+ /* */
+ /* metric_Data_Format :: Always 0. */
+ /* */
+ /* number_Of_HMetrics :: Number of HMetrics entries in the `hmtx' */
+ /* table -- this value can be smaller than */
+ /* the total number of glyphs in the font. */
+ /* */
+ /* long_metrics :: A pointer into the `hmtx' table. */
+ /* */
+ /* short_metrics :: A pointer into the `hmtx' table. */
+ /* */
+ /* <Note> */
+ /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */
+ /* be identical except for the names of their fields which */
+ /* are different. */
+ /* */
+ /* This ensures that a single function in the `ttload' */
+ /* module is able to read both the horizontal and vertical */
+ /* headers. */
+ /* */
+ typedef struct TT_HoriHeader_
+ {
+ 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_FWord caret_Offset;
+
+ TT_Short Reserved[4];
+
+ 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' table. */
+
+ void* long_metrics;
+ void* short_metrics;
+
+ } TT_HoriHeader;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_VertHeader */
+ /* */
+ /* <Description> */
+ /* A structure used to model a TrueType vertical header, the `vhea' */
+ /* table, as well as the corresponding vertical metrics table, i.e., */
+ /* the `vmtx' table. */
+ /* */
+ /* <Fields> */
+ /* Version :: The table version. */
+ /* */
+ /* Ascender :: The font's ascender, i.e., the distance */
+ /* from the baseline to the top-most of */
+ /* all glyph points found in the font. */
+ /* */
+ /* This value is invalid in many fonts, as */
+ /* it is usually set by the font designer, */
+ /* and often reflects only a portion of */
+ /* the glyphs found in the font (maybe */
+ /* ASCII). */
+ /* */
+ /* You should use the `sTypoAscender' */
+ /* field of the OS/2 table instead if you */
+ /* want the correct one. */
+ /* */
+ /* Descender :: The font's descender, i.e., the */
+ /* distance from the baseline to the */
+ /* bottom-most of all glyph points found */
+ /* in the font. It is negative. */
+ /* */
+ /* This value is invalid in many fonts, as */
+ /* it is usually set by the font designer, */
+ /* and often reflects only a portion of */
+ /* the glyphs found in the font (maybe */
+ /* ASCII). */
+ /* */
+ /* You should use the `sTypoDescender' */
+ /* field of the OS/2 table instead if you */
+ /* want the correct one. */
+ /* */
+ /* Line_Gap :: The font's line gap, i.e., the distance */
+ /* to add to the ascender and descender to */
+ /* get the BTB, i.e., the */
+ /* baseline-to-baseline distance for the */
+ /* font. */
+ /* */
+ /* advance_Height_Max :: This field is the maximum of all */
+ /* advance heights found in the font. It */
+ /* can be used to compute the maximum */
+ /* height of an arbitrary string of text. */
+ /* */
+ /* min_Top_Side_Bearing :: The minimum top side bearing of all */
+ /* glyphs within the font. */
+ /* */
+ /* min_Bottom_Side_Bearing :: The minimum bottom side bearing of all */
+ /* glyphs within the font. */
+ /* */
+ /* yMax_Extent :: The maximum vertical extent (i.e., the */
+ /* `height' of a glyph's bounding box) for */
+ /* all glyphs in the font. */
+ /* */
+ /* caret_Slope_Rise :: The rise coefficient of the cursor's */
+ /* slope of the cursor (slope=rise/run). */
+ /* */
+ /* caret_Slope_Run :: The run coefficient of the cursor's */
+ /* slope. */
+ /* */
+ /* Reserved :: 10 reserved bytes. */
+ /* */
+ /* metric_Data_Format :: Always 0. */
+ /* */
+ /* number_Of_HMetrics :: Number of VMetrics entries in the */
+ /* `vmtx' table -- this value can be */
+ /* smaller than the total number of glyphs */
+ /* in the font. */
+ /* */
+ /* long_metrics :: A pointer into the `vmtx' table. */
+ /* */
+ /* short_metrics :: A pointer into the `vmtx' table. */
+ /* */
+ /* <Note> */
+ /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */
+ /* be identical except for the names of their fields which */
+ /* are different. */
+ /* */
+ /* This ensures that a single function in the `ttload' */
+ /* module is able to read both the horizontal and vertical */
+ /* headers. */
+ /* */
+ typedef struct TT_VertHeader_
+ {
+ 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 Reserved[4];
+
+ 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;
+
+ } TT_VertHeader;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_OS2 */
+ /* */
+ /* <Description> */
+ /* A structure used to model a TrueType OS/2 table. This is the long */
+ /* table version. All fields comply to the TrueType specification. */
+ /* */
+ /* Note that we now support old Mac fonts which do not include an */
+ /* OS/2 table. In this case, the `version' field is always set to */
+ /* 0xFFFF. */
+ /* */
+ typedef struct TT_OS2_
+ {
+ TT_UShort version; /* 0x0001 - more or 0xFFFF */
+ 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 */
+
+ } TT_OS2;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_Postscript */
+ /* */
+ /* <Description> */
+ /* A structure used to model a TrueType Postscript table. All fields */
+ /* comply to the TrueType table. This structure does not reference */
+ /* the Postscript glyph names, which can be nevertheless accessed */
+ /* with the `ttpost' module. */
+ /* */
+ typedef struct TT_Postscript_
+ {
+ 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 ttpost.c file. */
+
+ } TT_Postscript;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_CMapDir */
+ /* */
+ /* <Description> */
+ /* This structure describes the directory of the `cmap' table, */
+ /* containing the font's character mappings table. */
+ /* */
+ /* <Fields> */
+ /* tableVersionNumber :: The version number. */
+ /* numCMaps :: The number of charmaps in the font. */
+ /* */
+ /* <Note> */
+ /* This structure is only used during font loading. */
+ /* */
+ typedef struct TT_CMapDir_
+ {
+ TT_UShort tableVersionNumber;
+ TT_UShort numCMaps;
+
+ } TT_CMapDir;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_CMapDirEntry */
+ /* */
+ /* <Description> */
+ /* This structure describes a charmap in a TrueType font. */
+ /* */
+ /* <Fields> */
+ /* platformID :: An ID used to specify for which platform this */
+ /* charmap is defined (FreeType manages all platforms). */
+ /* */
+ /* encodingID :: A platform-specific ID used to indicate which source */
+ /* encoding is used in this charmap. */
+ /* */
+ /* offset :: The offset of the charmap relative to the start of */
+ /* the `cmap' table. */
+ /* */
+ /* <Note> */
+ /* This structure is only used during font loading. */
+ /* */
+ typedef struct TT_CMapDirEntry_
+ {
+ TT_UShort platformID;
+ TT_UShort platformEncodingID;
+ TT_Long offset;
+
+ } TT_CMapDirEntry;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_MaxProfile */
+ /* */
+ /* <Description> */
+ /* The maximum profile is a table containing many max values which */
+ /* can be used to pre-allocate arrays. This ensures that no memory */
+ /* allocation occurs during a glyph load. */
+ /* */
+ /* <Fields> */
+ /* version :: The version number. */
+ /* */
+ /* numGlyphs :: The number of glyphs in this TrueType */
+ /* font. */
+ /* */
+ /* maxPoints :: The maximum number of points in a */
+ /* non-composite TrueType glyph. See also */
+ /* the structure element */
+ /* `maxCompositePoints'. */
+ /* */
+ /* maxContours :: The maximum number of contours in a */
+ /* non-composite TrueType glyph. See also */
+ /* the structure element */
+ /* `maxCompositeContours'. */
+ /* */
+ /* maxCompositePoints :: The maximum number of points in a */
+ /* composite TrueType glyph. See also the */
+ /* structure element `maxPoints'. */
+ /* */
+ /* maxCompositeContours :: The maximum number of contours in a */
+ /* composite TrueType glyph. See also the */
+ /* structure element `maxContours'. */
+ /* */
+ /* maxZones :: The maximum number of zones used for */
+ /* glyph hinting. */
+ /* */
+ /* maxTwilightPoints :: The maximum number of points in the */
+ /* twilight zone used for glyph hinting. */
+ /* */
+ /* maxStorage :: The maximum number of elements in the */
+ /* storage area used for glyph hinting. */
+ /* */
+ /* maxFunctionDefs :: The maximum number of function */
+ /* definitions in the TrueType bytecode for */
+ /* this font. */
+ /* */
+ /* maxInstructionDefs :: The maximum number of instruction */
+ /* definitions in the TrueType bytecode for */
+ /* this font. */
+ /* */
+ /* maxStackElements :: The maximum number of stack elements used */
+ /* during bytecode interpretation. */
+ /* */
+ /* maxSizeOfInstructions :: The maximum number of TrueType opcodes */
+ /* used for glyph hinting. */
+ /* */
+ /* maxComponentElements :: An obscure value related to composite */
+ /* glyphs definitions. */
+ /* */
+ /* maxComponentDepth :: An obscure value related to composite */
+ /* glyphs definitions. Probably the maximum */
+ /* number of simple glyphs in a composite. */
+ /* */
+ /* <Note> */
+ /* This structure is only used during font loading. */
+ /* */
+ typedef struct TT_MaxProfile_
+ {
+ TT_Fixed version;
+ TT_UShort numGlyphs;
+ TT_UShort maxPoints;
+ TT_UShort maxContours;
+ TT_UShort maxCompositePoints;
+ TT_UShort maxCompositeContours;
+ TT_UShort maxZones;
+ TT_UShort maxTwilightPoints;
+ TT_UShort maxStorage;
+ TT_UShort maxFunctionDefs;
+ TT_UShort maxInstructionDefs;
+ TT_UShort maxStackElements;
+ TT_UShort maxSizeOfInstructions;
+ TT_UShort maxComponentElements;
+ TT_UShort maxComponentDepth;
+
+ } TT_MaxProfile;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_LongMetrics */
+ /* */
+ /* <Description> */
+ /* A structure modeling the long metrics of the `hmtx' and `vmtx' */
+ /* TrueType tables. The values are expressed in font units. */
+ /* */
+ /* <Fields> */
+ /* advance :: The advance width or height for the glyph. */
+ /* bearing :: The left-side or top-side bearing for the glyph. */
+ /* */
+ typedef struct TT_LongMetrics_
+ {
+ TT_UShort advance;
+ TT_Short bearing;
+
+ } TT_LongMetrics;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> TT_ShortMetrics */
+ /* */
+ /* <Description> */
+ /* A simple type to model the short metrics of the `hmtx' and `vmtx' */
+ /* tables. */
+ /* */
+ typedef TT_Short TT_ShortMetrics;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_NameRec */
+ /* */
+ /* <Description> */
+ /* A structure modeling TrueType name records. Name records are used */
+ /* to store important strings like family name, style name, */
+ /* copyright, etc. in _localized_ versions (i.e., language, encoding, */
+ /* etc). */
+ /* */
+ /* <Fields> */
+ /* platformID :: The ID of the name's encoding platform. */
+ /* */
+ /* encodingID :: The platform-specific ID for the name's encoding. */
+ /* */
+ /* languageID :: The platform-specific ID for the name's language. */
+ /* */
+ /* nameID :: The ID specifying what kind of name this is. */
+ /* */
+ /* stringLength :: The length of the string in bytes. */
+ /* */
+ /* stringOffset :: The offset to the string in the `name' table. */
+ /* */
+ /* string :: A pointer to the string's bytes. Note that these */
+ /* are usually UTF-16 encoded characters. */
+ /* */
+ typedef struct TT_NameRec_
+ {
+ TT_UShort platformID;
+ TT_UShort encodingID;
+ TT_UShort languageID;
+ TT_UShort nameID;
+ TT_UShort stringLength;
+ TT_UShort stringOffset;
+
+ /* this last field is not defined in the spec */
+ /* but used by the FreeType engine */
+
+ TT_Byte* string;
+
+ } TT_NameRec;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_NameTable */
+ /* */
+ /* <Description> */
+ /* A structure modeling the TrueType name table. */
+ /* */
+ /* <Fields> */
+ /* format :: The format of the name table. */
+ /* */
+ /* numNameRecords :: The number of names in table. */
+ /* */
+ /* storageOffset :: The offset of the name table in the `name' */
+ /* TrueType table. */
+ /* */
+ /* names :: An array of name records. */
+ /* */
+ /* storage :: The names storage area. */
+ /* */
+ typedef struct TT_NameTable_
+ {
+ TT_UShort format;
+ TT_UShort numNameRecords;
+ TT_UShort storageOffset;
+ TT_NameRec* names;
+ TT_Byte* storage;
+
+ } TT_NameTable;
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*** ***/
+ /*** ***/
+ /*** OPTIONAL TRUETYPE/OPENTYPE TABLES DEFINITIONS ***/
+ /*** ***/
+ /*** ***/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_GaspRange */
+ /* */
+ /* <Description> */
+ /* A tiny structure used to model a gasp range according to the */
+ /* TrueType specification. */
+ /* */
+ /* <Fields> */
+ /* maxPPEM :: The maximum ppem value to which `gaspFlag' applies. */
+ /* */
+ /* gaspFlag :: A flag describing the grid-fitting and anti-aliasing */
+ /* modes to be used. */
+ /* */
+ typedef struct TT_GaspRange_
+ {
+ TT_UShort maxPPEM;
+ TT_UShort gaspFlag;
+
+ } TT_GaspRange;
+
+
+#define TT_GASP_GRIDFIT 0x01
+#define TT_GASP_DOGRAY 0x02
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_Gasp */
+ /* */
+ /* <Description> */
+ /* A structure modeling the TrueType `gasp' table used to specify */
+ /* grid-fitting and anti-aliasing behaviour. */
+ /* */
+ /* <Fields> */
+ /* version :: The version number. */
+ /* numRanges :: The number of gasp ranges in table. */
+ /* gaspRanges :: An array of gasp ranges. */
+ /* */
+ typedef struct TT_Gasp_
+ {
+ TT_UShort version;
+ TT_UShort numRanges;
+ TT_GaspRange* gaspRanges;
+
+ } TT_Gasp;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_HdmxRec */
+ /* */
+ /* <Description> */
+ /* A small structure used to model the pre-computed widths of a given */
+ /* size. They're found in the `hdmx' table. */
+ /* */
+ /* <Fields> */
+ /* ppem :: The pixels per EM value at which these metrics apply. */
+ /* */
+ /* max_width :: The maximum advance width for this metric. */
+ /* */
+ /* widths :: An array of widths. Note: These are 8-bit bytes. */
+ /* */
+ typedef struct TT_HdmxRec_
+ {
+ TT_Byte ppem;
+ TT_Byte max_width;
+ TT_Byte* widths;
+
+ } TT_HdmxRec;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_HdmxRec */
+ /* */
+ /* <Description> */
+ /* A structure used to model the `hdmx' table, which contains */
+ /* pre-computed widths for a set of given sizes/dimensions. */
+ /* */
+ /* <Fields> */
+ /* version :: The version number. */
+ /* num_records :: The number of hdmx records. */
+ /* records :: An array of hdmx records. */
+ /* */
+ typedef struct TT_Hdmx_
+ {
+ TT_UShort version;
+ TT_Short num_records;
+ TT_HdmxRec* records;
+
+ } TT_Hdmx;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_Kern_0_Pair */
+ /* */
+ /* <Description> */
+ /* A structure used to model a kerning pair for the kerning table */
+ /* format 0. The engine now loads this table if it finds one in the */
+ /* font file. */
+ /* */
+ /* <Fields> */
+ /* left :: The index of the left glyph in pair. */
+ /* right :: The index of the right glyph in pair. */
+ /* value :: The kerning distance. A positive value spaces the */
+ /* glyphs, a negative one makes them closer. */
+ /* */
+ typedef struct TT_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 */
+
+ } TT_Kern_0_Pair;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_SBit_Metrics */
+ /* */
+ /* <Description> */
+ /* A structure used to hold the big metrics of a given glyph bitmap */
+ /* in a TrueType or OpenType font. These are usually found in the */
+ /* `EBDT' (Microsoft) or `bdat' (Apple) table. */
+ /* */
+ /* <Fields> */
+ /* height :: The glyph height in pixels. */
+ /* */
+ /* width :: The glyph width in pixels. */
+ /* */
+ /* horiBearingX :: The horizontal left bearing. */
+ /* */
+ /* horiBearingY :: The horizontal top bearing. */
+ /* */
+ /* horiAdvance :: The horizontal advance. */
+ /* */
+ /* vertBearingX :: The vertical left bearing. */
+ /* */
+ /* vertBearingY :: The vertical top bearing. */
+ /* */
+ /* vertAdvance :: The vertical advance. */
+ /* */
+ typedef struct TT_SBit_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;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_SBit_Small_Metrics */
+ /* */
+ /* <Description> */
+ /* A structure used to hold the small metrics of a given glyph bitmap */
+ /* in a TrueType or OpenType font. These are usually found in the */
+ /* `EBDT' (Microsoft) or the `bdat' (Apple) table. */
+ /* */
+ /* <Fields> */
+ /* height :: The glyph height in pixels. */
+ /* */
+ /* width :: The glyph width in pixels. */
+ /* */
+ /* bearingX :: The left-side bearing. */
+ /* */
+ /* bearingY :: The top-side bearing. */
+ /* */
+ /* advance :: The advance width or height. */
+ /* */
+ typedef struct TT_SBit_Small_Metrics_
+ {
+ TT_Byte height;
+ TT_Byte width;
+
+ TT_Char bearingX;
+ TT_Char bearingY;
+ TT_Byte advance;
+
+ } TT_SBit_Small_Metrics;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_SBit_Line_Metrics */
+ /* */
+ /* <Description> */
+ /* A structure used to describe the text line metrics of a given */
+ /* bitmap strike, for either a horizontal or vertical layout. */
+ /* */
+ /* <Fields> */
+ /* ascender :: The ascender in pixels. */
+ /* */
+ /* descender :: The descender in pixels. */
+ /* */
+ /* max_width :: The maximum glyph width in pixels. */
+ /* */
+ /* caret_slope_enumerator :: Rise of the caret slope, typically set */
+ /* to 1 for non-italic fonts. */
+ /* */
+ /* caret_slope_denominator :: Rise of the caret slope, typically set */
+ /* to 0 for non-italic fonts. */
+ /* */
+ /* caret_offset :: Offset in pixels to move the caret for */
+ /* proper positioning. */
+ /* */
+ /* min_origin_SB :: Minimum of horiBearingX (resp. */
+ /* vertBearingY). */
+ /* min_advance_SB :: Minimum of */
+ /* */
+ /* horizontal advance - */
+ /* ( horiBearingX + width ) */
+ /* */
+ /* resp. */
+ /* */
+ /* vertical advance - */
+ /* ( vertBearingY + height ) */
+ /* */
+ /* max_before_BL :: Maximum of horiBearingY (resp. */
+ /* vertBearingY). */
+ /* */
+ /* min_after_BL :: Minimum of */
+ /* */
+ /* horiBearingY - height */
+ /* */
+ /* resp. */
+ /* */
+ /* vertBearingX - width */
+ /* */
+ 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;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_SBit_Range */
+ /* */
+ /* <Description> */
+ /* A TrueType/OpenType subIndexTable as defined in the `EBLC' */
+ /* (Microsoft) or `bloc' (Apple) tables. */
+ /* */
+ /* <Fields> */
+ /* first_glyph :: The first glyph index in the range. */
+ /* */
+ /* last_glyph :: The last glyph index in the range. */
+ /* */
+ /* index_format :: The format of index table. Valid values are 1 */
+ /* to 5. */
+ /* */
+ /* image_format :: The format of `EBDT' image data. */
+ /* */
+ /* image_offset :: The offset to image data in `EBDT'. */
+ /* */
+ /* image_size :: For index formats 2 and 5. This is the size in */
+ /* bytes of each glyph bitmap. */
+ /* */
+ /* big_metrics :: For index formats 2 and 5. This is the big */
+ /* metrics for each glyph bitmap. */
+ /* */
+ /* num_glyphs :: For index formats 4 and 5. This is the number of */
+ /* glyphs in the code array. */
+ /* */
+ /* glyph_offsets :: For index formats 1 and 3. */
+ /* */
+ /* glyph_codes :: For index formats 4 and 5. */
+ /* */
+ /* table_offset :: The offset of the index table in the `EBLC' */
+ /* table. Only used during strike loading. */
+ /* */
+ typedef struct TT_SBit_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;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_SBit_Strike */
+ /* */
+ /* <Description> */
+ /* A structure used describe a given bitmap strike in the `EBLC' */
+ /* (Microsoft) or `bloc' (Apple) tables. */
+ /* */
+ /* <Fields> */
+ /* num_index_ranges :: The number of index ranges. */
+ /* */
+ /* index_ranges :: An array of glyph index ranges. */
+ /* */
+ /* color_ref :: Unused. A color reference? */
+ /* */
+ /* hori :: The line metrics for horizontal layouts. */
+ /* */
+ /* vert :: The line metrics for vertical layouts. */
+ /* */
+ /* start_glyph :: The lowest glyph index for this strike. */
+ /* */
+ /* end_glyph :: The highest glyph index for this strike. */
+ /* */
+ /* x_ppem :: The number of horizontal pixels per EM. */
+ /* */
+ /* y_ppem :: The number of vertical pixels per EM. */
+ /* */
+ /* bit_depth :: The bit depth. Valid values are 1, 2, 4, */
+ /* and 8. */
+ /* */
+ /* flags :: Is this a vertical or horizontal strike? */
+ /* */
+ typedef struct TT_SBit_Strike_
+ {
+ 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;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_SBit_Component */
+ /* */
+ /* <Description> */
+ /* A simple structure to describe a compound sbit element. */
+ /* */
+ /* <Fields> */
+ /* glyph_code :: The element's glyph index. */
+ /* x_offset :: The element's left bearing. */
+ /* y_offset :: The element's top bearing. */
+ /* */
+ typedef struct TT_SBit_Component_
+ {
+ TT_UShort glyph_code;
+
+ TT_Char x_offset;
+ TT_Char y_offset;
+
+ } TT_SBit_Component;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_SBit_Scale */
+ /* */
+ /* <Description> */
+ /* A structure used describe a given bitmap scaling table, as defined */
+ /* in the `EBSC' table. */
+ /* */
+ /* <Fields> */
+ /* hori :: The horizontal line metrics. */
+ /* */
+ /* vert :: The vertical line metrics. */
+ /* */
+ /* x_ppem :: The number of horizontal pixels per EM. */
+ /* */
+ /* y_ppem :: The number of vertical pixels per EM. */
+ /* */
+ /* x_ppem_substitute :: Substitution x_ppem value. */
+ /* */
+ /* y_ppem_substitute :: Substitution y_ppem value. */
+ /* */
+ typedef struct TT_SBit_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;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_Post_20 */
+ /* */
+ /* <Description> */
+ /* Postscript names sub-table, format 2.0. Stores the PS name of */
+ /* each glyph in the font face. */
+ /* */
+ /* <Fields> */
+ /* num_glyphs :: The number of named glyphs in the table. */
+ /* */
+ /* num_names :: The number of PS names stored in the table. */
+ /* */
+ /* glyph_indices :: The indices of the glyphs in the names arrays. */
+ /* */
+ /* glyph_names :: The PS names not in Mac Encoding. */
+ /* */
+ typedef struct TT_Post_20_
+ {
+ TT_UShort num_glyphs;
+ TT_UShort num_names;
+ TT_UShort* glyph_indices;
+ TT_Char** glyph_names;
+
+ } TT_Post_20;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_Post_25 */
+ /* */
+ /* <Description> */
+ /* Postscript names sub-table, format 2.5. Stores the PS name of */
+ /* each glyph in the font face. */
+ /* */
+ /* <Fields> */
+ /* num_glyphs :: The number of glyphs in the table. */
+ /* */
+ /* offsets :: An array of signed offsets in a normal Mac */
+ /* Postscript name encoding. */
+ /* */
+ typedef struct TT_Post_25_
+ {
+ TT_UShort num_glyphs;
+ TT_Char* offsets;
+
+ } TT_Post_25;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_Post_Names */
+ /* */
+ /* <Description> */
+ /* Postscript names table, either format 2.0 or 2.5. */
+ /* */
+ /* <Fields> */
+ /* loaded :: A flag to indicate whether the PS names are loaded. */
+ /* */
+ /* format_20 :: The sub-table used for format 2.0. */
+ /* */
+ /* format_25 :: The sub-table used for format 2.5. */
+ /* */
+ typedef struct TT_Post_Names_
+ {
+ TT_Bool loaded;
+
+ union
+ {
+ TT_Post_20 format_20;
+ TT_Post_25 format_25;
+
+ } names;
+
+ } TT_Post_Names;
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*** ***/
+ /*** ***/
+ /*** ORIGINAL TT_FACE CLASS DEFINITION ***/
+ /*** ***/
+ /*** ***/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* This structure/class is defined here because it is common to the */
+ /* following formats: TTF, OpenType-TT, and OpenType-CFF. */
+ /* */
+ /* Note however that the classes TT_Size, TT_GlyphSlot, and TT_CharMap */
+ /* are not shared between font drivers, and are thus defined normally in */
+ /* `drivers/truetype/ttobjs.h'. */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_Face */
+ /* */
+ /* <Description> */
+ /* A handle to a TrueType face/font object. A TT_Face encapsulates */
+ /* the resolution and scaling independent parts of a TrueType font */
+ /* resource. */
+ /* */
+ /* <Note> */
+ /* The TT_Face structure is also used as a `parent class' for the */
+ /* OpenType-CFF class (T2_Face). */
+ /* */
+ typedef struct TT_FaceRec_* TT_Face;
+
+
+ /*************************************************************************/
+ /* */
+ /* TrueType Face Type */
+ /* */
+ /* <Struct> */
+ /* TT_Face */
+ /* */
+ /* <Description> */
+ /* The TrueType face class. These objects model the resolution and */
+ /* point-size independent data found in a TrueType font file. */
+ /* */
+ /* <Fields> */
+ /* root :: The base FT_Face structure, managed by the */
+ /* base layer. */
+ /* */
+ /* ttcHeader :: The TrueType collection header, used when the */
+ /* file is a `ttc' rather than a `ttf'. For */
+ /* ordinary font files, the field */
+ /* `ttcHeader.DirCount' is set to 0. */
+ /* */
+ /* num_tables :: The number of TrueType tables in this font */
+ /* file. */
+ /* */
+ /* dir_tables :: The directory of TrueType tables for this */
+ /* font file. */
+ /* */
+ /* header :: The font's font header (`head' table). Read */
+ /* on font opening. */
+ /* */
+ /* horizontal :: The font's horizontal header (`hhea' table). */
+ /* This field also contains the associated */
+ /* horizontal metrics table (`hmtx'). */
+ /* */
+ /* max_profile :: The font's maximum profile table. Read on */
+ /* font opening. Note that some maximum values */
+ /* cannot be taken directly from this table. We */
+ /* thus define additional fields below to hold */
+ /* the computed maxima. */
+ /* */
+ /* max_components :: The maximum number of glyph components */
+ /* required to load any composite glyph from */
+ /* this font. Used to size the load stack. */
+ /* */
+ /* vertical_info :: A boolean which is set when the font file */
+ /* contains vertical metrics. If not, the value */
+ /* of the `vertical' field is undefined. */
+ /* */
+ /* vertical :: The font's vertical header (`vhea' table). */
+ /* This field also contains the associated */
+ /* vertical metrics table (`vmtx'), if found. */
+ /* IMPORTANT: The contents of this field is */
+ /* undefined if the `verticalInfo' field is */
+ /* unset. */
+ /* */
+ /* num_names :: The number of name records within this */
+ /* TrueType font. */
+ /* */
+ /* name_table :: The table of name records (`name'). */
+ /* */
+ /* os2 :: The font's OS/2 table (`OS/2'). */
+ /* */
+ /* postscript :: The font's PostScript table (`post' table). */
+ /* The PostScript glyph names are not loaded by */
+ /* the driver on face opening. See the `ttpost' */
+ /* module for more details. */
+ /* */
+ /* num_charmaps :: The number of character mappings in the font. */
+ /* */
+ /* charmaps :: The array of charmap objects for this font */
+ /* file. Note that this field is a typeless */
+ /* pointer. The Reason is that the format of */
+ /* charmaps varies with the underlying font */
+ /* format and cannot be determined here. */
+ /* */
+ /* hdmx :: The face's horizontal device metrics (`hdmx' */
+ /* table). This table is optional in */
+ /* TrueType/OpenType fonts. */
+ /* */
+ /* gasp :: The grid-fitting and scaling properties table */
+ /* (`gasp'). This table is optional in */
+ /* TrueType/OpenType fonts. */
+ /* */
+ /* num_sbit_strikes :: The number of sbit strikes, i.e., bitmap */
+ /* sizes, embedded in this font. */
+ /* */
+ /* sbit_strikes :: An array of sbit strikes embedded in this */
+ /* font. This table is optional in a */
+ /* TrueType/OpenType font. */
+ /* */
+ /* num_sbit_scales :: The number of sbit scales for this font. */
+ /* */
+ /* sbit_scales :: Array of sbit scales embedded in this font. */
+ /* This table is optional in a TrueType/OpenType */
+ /* font. */
+ /* */
+ /* postscript_names :: A table used to store the Postscript names of */
+ /* the glyphs for this font. See the file */
+ /* `ttconfig.h' for comments on the */
+ /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES option. */
+ /* */
+ /* num_locations :: The number of glyph locations in this */
+ /* TrueType file. This should be identical to */
+ /* the number of glyphs. Ignored for Type 2 */
+ /* fonts. */
+ /* */
+ /* glyph_locations :: An array of longs. These are offsets to */
+ /* glyph data within the `glyf' table. Ignored */
+ /* for Type 2 font faces. */
+ /* */
+ /* font_program_size :: Size in bytecodes of the face's font program. */
+ /* 0 if none defined. Ignored for Type 2 fonts. */
+ /* */
+ /* font_program :: The face's font program (bytecode stream) */
+ /* executed at load time, also used during glyph */
+ /* rendering. Comes from the `fpgm' table. */
+ /* Ignored for Type 2 font fonts. */
+ /* */
+ /* cvt_program_size :: Size in bytecodes of the face's cvt program. */
+ /* Ignored for Type 2 fonts. */
+ /* */
+ /* cvt_program :: The face's cvt program (bytecode stream) */
+ /* executed each time an instance/size is */
+ /* changed/reset. Comes from the `prep' table. */
+ /* Ignored for Type 2 fonts. */
+ /* */
+ /* cvt_size :: Size of the control value table (in entries). */
+ /* Ignored for Type 2 fonts. */
+ /* */
+ /* cvt :: The face's original control value table. */
+ /* Coordinates are expressed in unscaled font */
+ /* units. Comes from the `cvt ` table. Ignored */
+ /* for Type 2 fonts. */
+ /* */
+ /* num_kern_pairs :: The number of kerning pairs present in the */
+ /* font file. The engine only loads the first */
+ /* horizontal format 0 kern table it finds in */
+ /* the font file. You should use the `ttxkern' */
+ /* structures if you want to access other */
+ /* kerning tables. Ignored for Type 2 fonts. */
+ /* */
+ /* kern_table_index :: The index of the kerning table in the font */
+ /* kerning directory. Only used by the ttxkern */
+ /* extension to avoid data duplication. Ignored */
+ /* for Type 2 fonts. */
+ /* */
+ /* kern_pairs :: Array of kerning pairs, if any. Ignored for */
+ /* Type 2 fonts. */
+ /* */
+ typedef struct TT_FaceRec_
+ {
+ FT_FaceRec root;
+
+ TTC_Header ttc_header;
+
+ TT_UShort num_tables;
+ TT_TableDirEntry* dir_tables;
+
+ TT_Header header; /* TrueType header table */
+ TT_HoriHeader horizontal; /* TrueType horizontal header */
+
+ TT_MaxProfile max_profile;
+ TT_ULong max_components;
+
+ TT_Bool vertical_info;
+ TT_VertHeader vertical; /* TT Vertical header, if present */
+
+ TT_Int num_names; /* number of name records */
+ TT_NameTable name_table; /* name table */
+
+ TT_OS2 os2; /* TrueType OS/2 table */
+ TT_Postscript postscript; /* TrueType Postscript table */
+
+ TT_Int num_charmaps;
+ void* charmaps; /* array of TT_CharMapRec */
+
+ /***********************************************************************/
+ /* */
+ /* Optional TrueType/OpenType tables */
+ /* */
+ /***********************************************************************/
+
+ /* horizontal device metrics */
+ TT_Hdmx hdmx;
+
+ /* grid-fitting and scaling table */
+ TT_Gasp gasp; /* the `gasp' table */
+
+ /* embedded bitmaps support */
+ TT_Int num_sbit_strikes;
+ TT_SBit_Strike* sbit_strikes;
+
+ TT_Int num_sbit_scales;
+ TT_SBit_Scale* sbit_scales;
+
+ /* postscript names table */
+ TT_Post_Names postscript_names;
+
+ /***********************************************************************/
+ /* */
+ /* TrueType-specific fields (ignored by the OTF-Type2 driver) */
+ /* */
+ /***********************************************************************/
+
+ /* the glyph locations */
+ TT_UShort num_locations;
+ TT_Long* glyph_locations;
+
+ /* the font program, if any */
+ TT_ULong font_program_size;
+ TT_Byte* font_program;
+
+ /* the cvt program, if any */
+ TT_ULong cvt_program_size;
+ TT_Byte* cvt_program;
+
+ /* the original, unscaled, control value table */
+ TT_ULong cvt_size;
+ TT_Short* cvt;
+
+ /* the format 0 kerning table, if any */
+ TT_Int num_kern_pairs;
+ TT_Int kern_table_index;
+ TT_Kern_0_Pair* kern_pairs;
+
+ } TT_FaceRec;
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+
+#endif /* TTTYPES_H */
+
+
+/* END */
--- /dev/null
+++ b/src/shared/t1types.h
@@ -1,0 +1,485 @@
+/*******************************************************************
+ *
+ * t1types.h 1.0
+ *
+ * Basic Type1/Type2 type definitions and interface.
+ *
+ * This code is shared by the Type1 and Type2 drivers
+ *
+ *
+ * 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 T1TYPES_H
+#define T1TYPES_H
+
+#include <freetype.h>
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+/*** ***/
+/*** ***/
+/*** DEFINITIONS OF BASIC DATA TYPES ***/
+/*** ***/
+/*** ***/
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+
+
+/* The REDEFINE macro is used to convert a FreeType generic type into */
+/* a TrueType-specific one. It simply replaces the "FT_" prefix by "T1_" */
+/* in order to define compatible T1_Long, T1_Error, T1_Outline, etc.. */
+/* */
+#undef REDEFINE
+#define REDEFINE( type ) typedef FT_##type T1_##type
+
+
+ /* <Type> T1_Bool */
+ /* */
+ /* <Description> */
+ /* A simple typedef of unsigned char, used for simple booleans. */
+ /* */
+ REDEFINE( Bool );
+
+
+ /* <Type> T1_FWord */
+ /* */
+ /* <Description> */
+ /* a signed 16-bit integer used to store a distance in original */
+ /* font units. */
+ /* */
+ REDEFINE( FWord );
+
+
+ /* <Type> T1_UFWord */
+ /* */
+ /* <Description> */
+ /* an unsigned 16-bit integer used to store a distance in original */
+ /* font units. */
+ /* */
+ REDEFINE( UFWord );
+
+
+ /* <Type> T1_Char */
+ /* */
+ /* <Description> */
+ /* a simple typedef for the _signed_ char type. */
+ /* */
+ REDEFINE( Char );
+
+
+ /* <Type> T1_Byte */
+ /* */
+ /* <Description> */
+ /* a simple typedef for the _unsigned_ char type. */
+ /* */
+ REDEFINE( Byte );
+
+
+ /* <Type> T1_String */
+ /* */
+ /* <Description> */
+ /* a simple typedef for the char type, used for strings usually. */
+ /* */
+ REDEFINE( String );
+
+
+ /* <Type> T1_Short */
+ /* */
+ /* <Description> */
+ /* a typedef for signed short */
+ /* */
+ REDEFINE( Short );
+
+
+ /* <Type> T1_UShort */
+ /* */
+ /* <Description> */
+ /* a typedef for unsigned short */
+ /* */
+ REDEFINE( UShort );
+
+
+ /* <Type> FT_Int */
+ /* */
+ /* <Description> */
+ /* a typedef for the int type */
+ /* */
+ REDEFINE( Int );
+
+
+ /* <Type> FT_UInt */
+ /* */
+ /* <Description> */
+ /* a typedef for the unsigned int type */
+ /* */
+ REDEFINE( UInt );
+
+
+ /* <Type> T1_Long */
+ /* */
+ /* <Description> */
+ /* a typedef for signed long */
+ /* */
+ REDEFINE( Long );
+
+
+ /* <Type> T1_ULong */
+ /* */
+ /* <Description> */
+ /* a typedef for unsigned long */
+ /* */
+ REDEFINE( ULong );
+
+
+ /* <Type> T1_F2Dot14 */
+ /* */
+ /* <Description> */
+ /* a signed 2.14 fixed float used for unit vectors */
+ /* */
+ REDEFINE( F2Dot14 );
+
+
+ /* <Type> T1_F26Dot6 */
+ /* */
+ /* <Description> */
+ /* a signed 26.6 fixed float used for vectorial pixel coordinates */
+ /* */
+ REDEFINE( F26Dot6 );
+
+
+ /* <Type> T1_Fixed */
+ /* */
+ /* <Description> */
+ /* This type is used to store 16.16 fixed float values, like */
+ /* scales or matrix coefficients.. */
+ /* */
+ REDEFINE( Fixed );
+
+
+ /* <Type> T1_Pos */
+ /* */
+ /* <Description> */
+ /* The type T1_Pos is a 32-bits integer used to store vectorial */
+ /* coordinates. Depending on the context, these can represent */
+ /* distances in integer font units, or 26.6 fixed float pixel */
+ /* coordinates.. */
+ /* */
+ REDEFINE( Pos );
+
+
+ /* <Struct> T1_Vector */
+ /* */
+ /* <Description> */
+ /* A simple structure used to store a 2d vector, coordinates */
+ /* are of the T1_Pos type. */
+ /* */
+ /* <Fields> */
+ /* x :: horizontal coordinate */
+ /* y :: vertical coordinate */
+ /* */
+ REDEFINE( Vector );
+
+ /* <Struct> T1_UnitVector */
+ /* */
+ /* <Description> */
+ /* A simple structure used to store a 2d vector unit vector. */
+ /* uses T1_F2Dot14 types. */
+ /* */
+ /* <Fields> */
+ /* x :: horizontal coordinate */
+ /* y :: vertical coordinate */
+ /* */
+ REDEFINE( UnitVector );
+
+
+ /* <Struct> T1_Matrix */
+ /* */
+ /* <Description> */
+ /* A simple structure used to store a 2x2 matrix. Coefficients */
+ /* are in 16.16 fixed float format. The computation performed */
+ /* is : */
+ /* { */
+ /* x' = x*xx + y*xy */
+ /* y' = x*yx + y*yy */
+ /* } */
+ /* */
+ /* <Fields> */
+ /* xx :: matrix coefficient */
+ /* xy :: matrix coefficient */
+ /* yx :: matrix coefficient */
+ /* yy :: matrix coefficient */
+ /* */
+ REDEFINE( Matrix );
+
+
+ /* <Struct> T1_BBox */
+ /* */
+ /* <Description> */
+ /* A structure used to hold an outline's bounding box, i.e. */
+ /* the coordinates of its extrema in the horizontal and vertical */
+ /* directions. */
+ /* */
+ /* <Fields> */
+ /* xMin :: the horizontal minimum (left-most) */
+ /* yMin :: the vertical minimum (bottom-most) */
+ /* xMax :: the horizontal maximum (right-most) */
+ /* yMax :: the vertical maximum (top-most) */
+ /* */
+ REDEFINE( BBox );
+
+
+ /* <Type> T1_Error */
+ /* */
+ /* <Description> */
+ /* The FreeType error code type. A value of 0 is always */
+ /* interpreted as a succesful operation. */
+ /* */
+ REDEFINE( Error );
+
+
+
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+/*** ***/
+/*** ***/
+/*** REQUIRED TYPE1/TYPE2 TABLES DEFINITIONS ***/
+/*** ***/
+/*** ***/
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+
+ /***********************************************************************/
+ /* */
+ /* <Struct> T1_FontInfo */
+ /* */
+ /* <Description> */
+ /* The FontInfo dictionary structure. */
+ /* */
+ /* <Fields> */
+ /* version :: */
+ /* notice :: */
+ /* full_name :: */
+ /* family_name :: */
+ /* weight :: */
+ /* italic_angle :: */
+ /* is_fixed_pitch :: */
+ /* underline_position :: */
+ /* underline_thickness :: */
+ /* */
+ typedef struct T1_FontInfo_
+ {
+ T1_String* version;
+ T1_String* notice;
+ T1_String* full_name;
+ T1_String* family_name;
+ T1_String* weight;
+ T1_Long italic_angle;
+ T1_Bool is_fixed_pitch;
+ T1_Short underline_position;
+ T1_UShort underline_thickness;
+
+ } T1_FontInfo;
+
+
+ /***********************************************************************/
+ /* */
+ /* <Struct> T1_Private */
+ /* */
+ /* <Description> */
+ /* The Private dictionary structure. */
+ /* */
+ /* <Fields> */
+ /* unique_id :: the font's unique id */
+ /* lenIV :: length of decrypt padding */
+ /* */
+ /* num_blues :: number of blue values */
+ /* num_other_blues :: number of other blue values */
+ /* num_family_blues :: number of family blue values */
+ /* num_family_other_blues :: number of family other blue values */
+ /* */
+ /* blue_values :: array of blue values */
+ /* other_blues :: array of other blue values */
+ /* family_blues :: array of family blue values */
+ /* family_other_blues :: array of family other blue values */
+ /* */
+ /* blue_scale :: */
+ /* blue_shift :: */
+ /* blue_scale :: */
+ /* */
+ /* standard_width :: */
+ /* standard_height :: */
+ /* */
+ /* num_snap_widths :: */
+ /* num_snap_heights :: */
+ /* force_bold :: */
+ /* round_stem_up :: */
+ /* */
+ /* stem_snap_widths :: */
+ /* stem_snap_heights :: */
+ /* */
+ /* language_group :: */
+ /* password :: */
+ /* */
+ /* min_feature :: */
+ /* */
+ /* */
+ typedef struct T1_Private_
+ {
+ T1_Int unique_id;
+ T1_Int lenIV;
+
+ T1_Byte num_blues;
+ T1_Byte num_other_blues;
+ T1_Byte num_family_blues;
+ T1_Byte num_family_other_blues;
+
+ T1_Short blue_values[14];
+ T1_Short other_blues[10];
+
+ T1_Short family_blues [14];
+ T1_Short family_other_blues[10];
+
+ T1_Fixed blue_scale;
+ T1_Int blue_shift;
+ T1_Int blue_fuzz;
+
+ T1_UShort standard_width;
+ T1_UShort standard_height;
+
+ T1_Byte num_snap_widths;
+ T1_Byte num_snap_heights;
+ T1_Bool force_bold;
+ T1_Bool round_stem_up;
+
+ T1_Short stem_snap_widths [13]; /* reserve one place for the std */
+ T1_Short stem_snap_heights[13]; /* reserve one place for the std */
+
+ T1_Long language_group;
+ T1_Long password;
+
+ T1_Short min_feature[2];
+
+ } T1_Private;
+
+
+
+ /***********************************************************************/
+ /* */
+ /* <Struct> T1_Private */
+ /* */
+ /* <Description> */
+ /* The Private dictionary structure. */
+ /* */
+ /* <Fields> */
+ /* num_chars :: number of char codes in encoding. Usually 256 */
+ /* code_first :: lower char code in encoding */
+ /* code_last :: higher char code in encoding */
+ /* */
+ /* char_code :: array of character codes */
+ /* char_index :: array of correpsonding glyph indices */
+ /* char_name :: array of correpsonding glyph names */
+ /* */
+ typedef struct T1_Encoding_
+ {
+ T1_Int num_chars;
+ T1_Int code_first;
+ T1_Int code_last;
+
+ T1_Short* char_index;
+ T1_String** char_name;
+
+ } T1_Encoding;
+
+
+
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+/*** ***/
+/*** ***/
+/*** ORIGINAL TT_FACE CLASS DEFINITION ***/
+/*** ***/
+/*** ***/
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+/*** ***/
+/*** ***/
+/*** This structure/class is defined here because it is common ***/
+/*** to the following formats : TTF, OpenType-TT and OpenType-CFF ***/
+/*** ***/
+/*** Note however that the classes TT_Size, TT_GlyphSlot and ***/
+/*** TT_CharMap are not shared between font drivers, and are ***/
+/*** thus defined normally in "drivers/truetype/ttobjs.h" ***/
+/*** ***/
+/*** ***/
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+
+
+ typedef struct T1_FaceRec_* T1_Face;
+
+
+ /***************************************************/
+ /* */
+ /* T1_Face : */
+ /* */
+ /* Type1 face record.. */
+ /* */
+
+ typedef struct T1_FaceRec_
+ {
+ FT_FaceRec root;
+
+ T1_FontInfo font_info;
+ FT_String* font_name;
+
+ T1_Encoding encoding;
+
+ T1_Byte* subrs_block;
+ T1_Byte* charstrings_block;
+
+ T1_Int num_subrs;
+ T1_Byte** subrs;
+ T1_Int* subrs_len;
+
+ T1_Int num_glyphs;
+ T1_String** glyph_names; /* array of glyph names */
+ T1_Byte** charstrings; /* array of glyph charstrings */
+ T1_Int* charstrings_len;
+
+ T1_Byte paint_type;
+ T1_Byte font_type;
+ T1_Matrix font_matrix;
+ T1_BBox font_bbox;
+ T1_Long unique_id;
+ T1_Long font_id;
+
+ T1_Int stroke_width;
+ T1_Private private_dict;
+
+ } T1_FaceRec;
+
+
+#endif /* T1TYPES_H */
--- /dev/null
+++ b/src/shared/tterrors.h
@@ -1,0 +1,126 @@
+/***************************************************************************/
+/* */
+/* tterrors.h */
+/* */
+/* TrueType error ID definitions (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 TTERRORS_H
+#define TTERRORS_H
+
+
+ /*************************************************************************/
+ /* */
+ /* Error codes declaration */
+ /* */
+ /* The error codes are grouped in `classes' used to indicate the `level' */
+ /* at which the error happened. The class is given by an error code's */
+ /* high byte. */
+ /* */
+ /*************************************************************************/
+
+
+ /* Success is always 0. */
+
+#define TT_Err_Ok FT_Err_Ok
+
+ /* High level API errors. */
+
+#define TT_Err_Invalid_File_Format FT_Err_Invalid_File_Format
+#define TT_Err_Invalid_Argument FT_Err_Invalid_Argument
+#define TT_Err_Invalid_Driver_Handle FT_Err_Invalid_Driver_Handle
+#define TT_Err_Invalid_Face_Handle FT_Err_Invalid_Face_Handle
+#define TT_Err_Invalid_Instance_Handle FT_Err_Invalid_Size_Handle
+#define TT_Err_Invalid_Glyph_Handle FT_Err_Invalid_Slot_Handle
+#define TT_Err_Invalid_CharMap_Handle FT_Err_Invalid_CharMap_Handle
+#define TT_Err_Invalid_Glyph_Index FT_Err_Invalid_Glyph_Index
+
+#define TT_Err_Unimplemented_Feature FT_Err_Unimplemented_Feature
+#define TT_Err_Unavailable_Outline FT_Err_Unavailable_Outline
+#define TT_Err_Unavailable_Bitmap FT_Err_Unavailable_Bitmap
+#define TT_Err_Unavailable_Pixmap FT_Err_Unavailable_Pixmap
+#define TT_Err_File_Is_Not_Collection FT_Err_File_Is_Not_Collection
+
+#define TT_Err_Invalid_Engine FT_Err_Invalid_Driver_Handle
+
+ /* Internal errors. */
+
+#define TT_Err_Out_Of_Memory FT_Err_Out_Of_Memory
+#define TT_Err_Unlisted_Object FT_Err_Unlisted_Object
+
+ /* General glyph outline errors. */
+
+#define TT_Err_Too_Many_Points FT_Err_Too_Many_Points
+#define TT_Err_Too_Many_Contours FT_Err_Too_Many_Contours
+#define TT_Err_Too_Many_Ins FT_Err_Too_Many_Hints
+#define TT_Err_Invalid_Composite FT_Err_Invalid_Composite
+
+ /* Bytecode interpreter error codes. */
+
+ /* These error codes are produced by the TrueType */
+ /* bytecode interpreter. They usually indicate a */
+ /* broken font file, a broken glyph within a font */
+ /* file, or a bug in the interpreter! */
+
+#define TT_Err_Invalid_Opcode 0x400
+#define TT_Err_Too_Few_Arguments 0x401
+#define TT_Err_Stack_Overflow 0x402
+#define TT_Err_Code_Overflow 0x403
+#define TT_Err_Bad_Argument 0x404
+#define TT_Err_Divide_By_Zero 0x405
+#define TT_Err_Storage_Overflow 0x406
+#define TT_Err_Cvt_Overflow 0x407
+#define TT_Err_Invalid_Reference 0x408
+#define TT_Err_Invalid_Distance 0x409
+#define TT_Err_Interpolate_Twilight 0x40A
+#define TT_Err_Debug_OpCode 0x40B
+#define TT_Err_ENDF_In_Exec_Stream 0x40C
+#define TT_Err_Out_Of_CodeRanges 0x40D
+#define TT_Err_Nested_DEFS 0x40E
+#define TT_Err_Invalid_CodeRange 0x40F
+#define TT_Err_Invalid_Displacement 0x410
+#define TT_Err_Execution_Too_Long 0x411
+#define TT_Err_Too_Many_Function_Defs 0x412
+#define TT_Err_Too_Many_Instruction_Defs 0x413
+
+ /* Other TrueType specific error codes. */
+
+#define TT_Err_Table_Missing 0x420
+#define TT_Err_Too_Many_Extensions 0x421
+#define TT_Err_Extensions_Unsupported 0x422
+#define TT_Err_Invalid_Extension_Id 0x423
+
+#define TT_Err_No_Vertical_Data 0x424
+
+#define TT_Err_Max_Profile_Missing 0x430
+#define TT_Err_Header_Table_Missing 0x431
+#define TT_Err_Horiz_Header_Missing 0x432
+#define TT_Err_Locations_Missing 0x433
+#define TT_Err_Name_Table_Missing 0x434
+#define TT_Err_CMap_Table_Missing 0x435
+#define TT_Err_Hmtx_Table_Missing 0x436
+#define TT_Err_OS2_Table_Missing 0x437
+#define TT_Err_Post_Table_Missing 0x438
+
+#define TT_Err_Invalid_Horiz_Metrics 0x440
+#define TT_Err_Invalid_CharMap_Format 0x441
+#define TT_Err_Invalid_PPem 0x442
+#define TT_Err_Invalid_Vert_Metrics 0x443
+
+#define TT_Err_Could_Not_Find_Context 0x450
+
+#endif /* FTERRID_H */
+
+
+/* END */
--- /dev/null
+++ b/src/shared/ttnameid.h
@@ -1,0 +1,603 @@
+/***************************************************************************/
+/* */
+/* ttnameid.h */
+/* */
+/* TrueType name ID definitions (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 FREETYPE_H
+#error "Don't include this file! Use freetype.h instead."
+#endif
+
+
+#ifndef TTNAMEID_H
+#define TTNAMEID_H
+
+
+ /*************************************************************************/
+ /* */
+ /* Possible values for the `Platform' identifier code in the name */
+ /* records of the TTF `name' table. */
+ /* */
+#define TT_PLATFORM_APPLE_UNICODE 0
+#define TT_PLATFORM_MACINTOSH 1
+#define TT_PLATFORM_ISO 2
+#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 (1 << 0) /* U+0000-U+007F */
+/* Bit 1 C1 Controls and Latin-1 Supplement */
+#define TT_UCR_LATIN1_SUPPLEMENT (1 << 1) /* U+0080-U+00FF */
+/* Bit 2 Latin Extended-A */
+#define TT_UCR_LATIN_EXTENDED_A (1 << 2) /* U+0100-U+017F */
+/* Bit 3 Latin Extended-B */
+#define TT_UCR_LATIN_EXTENDED_B (1 << 3) /* U+0180-U+024F */
+/* Bit 4 IPA Extensions */
+#define TT_UCR_IPA_EXTENSIONS (1 << 4) /* U+0250-U+02AF */
+/* Bit 5 Spacing Modifier Letters */
+#define TT_UCR_SPACING_MODIFIER (1 << 5) /* U+02B0-U+02FF */
+/* Bit 6 Combining Diacritical Marks */
+#define TT_UCR_COMBINING_DIACRITICAL_MARKS (1 << 6) /* U+0300-U+036F */
+/* Bit 7 Greek */
+#define TT_UCR_GREEK (1 << 7) /* U+0370-U+03FF */
+/* Bit 8 is reserved (was: Greek Symbols and Coptic) */
+/* Bit 9 Cyrillic */
+#define TT_UCR_CYRILLIC (1 << 9) /* U+0400-U+04FF */
+/* Bit 10 Armenian */
+#define TT_UCR_ARMENIAN (1 << 10) /* U+0530-U+058F */
+/* Bit 11 Hebrew */
+#define TT_UCR_HEBREW (1 << 11) /* U+0590-U+05FF */
+/* Bit 12 is reserved (was: Hebrew Extended) */
+/* Bit 13 Arabic */
+#define TT_UCR_ARABIC (1 << 13) /* U+0600-U+06FF */
+/* Bit 14 is reserved (was: Arabic Extended) */
+/* Bit 15 Devanagari */
+#define TT_UCR_DEVANAGARI (1 << 15) /* U+0900-U+097F */
+/* Bit 16 Bengali */
+#define TT_UCR_BENGALI (1 << 16) /* U+0980-U+09FF */
+/* Bit 17 Gurmukhi */
+#define TT_UCR_GURMUKHI (1 << 17) /* U+0A00-U+0A7F */
+/* Bit 18 Gujarati */
+#define TT_UCR_GUJARATI (1 << 18) /* U+0A80-U+0AFF */
+/* Bit 19 Oriya */
+#define TT_UCR_ORIYA (1 << 19) /* U+0B00-U+0B7F */
+/* Bit 20 Tamil */
+#define TT_UCR_TAMIL (1 << 20) /* U+0B80-U+0BFF */
+/* Bit 21 Telugu */
+#define TT_UCR_TELUGU (1 << 21) /* U+0C00-U+0C7F */
+/* Bit 22 Kannada */
+#define TT_UCR_KANNADA (1 << 22) /* U+0C80-U+0CFF */
+/* Bit 23 Malayalam */
+#define TT_UCR_MALAYALAM (1 << 23) /* U+0D00-U+0D7F */
+/* Bit 24 Thai */
+#define TT_UCR_THAI (1 << 24) /* U+0E00-U+0E7F */
+/* Bit 25 Lao */
+#define TT_UCR_LAO (1 << 25) /* U+0E80-U+0EFF */
+/* Bit 26 Georgian */
+#define TT_UCR_GEORGIAN (1 << 26) /* U+10A0-U+10FF */
+/* Bit 27 is reserved (was Georgian Extended) */
+/* Bit 28 Hangul Jamo */
+#define TT_UCR_HANGUL_JAMO (1 << 28) /* U+1100-U+11FF */
+/* Bit 29 Latin Extended Additional */
+#define TT_UCR_LATIN_EXTENDED_ADDITIONAL (1 << 29) /* U+1E00-U+1EFF */
+/* Bit 30 Greek Extended */
+#define TT_UCR_GREEK_EXTENDED (1 << 30) /* U+1F00-U+1FFF */
+
+/* Symbols Area */
+
+/* Bit 31 General Punctuation */
+#define TT_UCR_GENERAL_PUNCTUATION (1 << 31) /* U+2000-U+206F */
+/* Bit 32 Superscripts And Subscripts */
+#define TT_UCR_SUPERSCRIPTS_SUBSCRIPTS (1 << 0) /* U+2070-U+209F */
+/* Bit 33 Currency Symbols */
+#define TT_UCR_CURRENCY_SYMBOLS (1 << 1) /* U+20A0-U+20CF */
+/* Bit 34 Combining Diacritical Marks For Symbols */
+#define TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB (1 << 2) /* U+20D0-U+20FF */
+/* Bit 35 Letterlike Symbols */
+#define TT_UCR_LETTERLIKE_SYMBOLS (1 << 3) /* U+2100-U+214F */
+/* Bit 36 Number Forms */
+#define TT_UCR_NUMBER_FORMS (1 << 4) /* U+2150-U+218F */
+/* Bit 37 Arrows */
+#define TT_UCR_ARROWS (1 << 5) /* U+2190-U+21FF */
+/* Bit 38 Mathematical Operators */
+#define TT_UCR_MATHEMATICAL_OPERATORS (1 << 6) /* U+2200-U+22FF */
+/* Bit 39 Miscellaneous Technical */
+#define TT_UCR_MISCELLANEOUS_TECHNICAL (1 << 7) /* U+2300-U+23FF */
+/* Bit 40 Control Pictures */
+#define TT_UCR_CONTROL_PICTURES (1 << 8) /* U+2400-U+243F */
+/* Bit 41 Optical Character Recognition */
+#define TT_UCR_OCR (1 << 9) /* U+2440-U+245F */
+/* Bit 42 Enclosed Alphanumerics */
+#define TT_UCR_ENCLOSED_ALPHANUMERICS (1 << 10) /* U+2460-U+24FF */
+/* Bit 43 Box Drawing */
+#define TT_UCR_BOX_DRAWING (1 << 11) /* U+2500-U+257F */
+/* Bit 44 Block Elements */
+#define TT_UCR_BLOCK_ELEMENTS (1 << 12) /* U+2580-U+259F */
+/* Bit 45 Geometric Shapes */
+#define TT_UCR_GEOMETRIC_SHAPES (1 << 13) /* U+25A0-U+25FF */
+/* Bit 46 Miscellaneous Symbols */
+#define TT_UCR_MISCELLANEOUS_SYMBOLS (1 << 14) /* U+2600-U+26FF */
+/* Bit 47 Dingbats */
+#define TT_UCR_DINGBATS (1 << 15) /* U+2700-U+27BF */
+
+/* CJK Phonetics and Symbols Area */
+
+/* Bit 48 CJK Symbols And Punctuation */
+#define TT_UCR_CJK_SYMBOLS (1 << 16) /* U+3000-U+303F */
+/* Bit 49 Hiragana */
+#define TT_UCR_HIRAGANA (1 << 17) /* U+3040-U+309F */
+/* Bit 50 Katakana */
+#define TT_UCR_KATAKANA (1 << 18) /* U+30A0-U+30FF */
+/* Bit 51 Bopomofo */
+#define TT_UCR_BOPOMOFO (1 << 19) /* U+3100-U+312F */
+/* Bit 52 Hangul Compatibility Jamo */
+#define TT_UCR_HANGUL_COMPATIBILITY_JAMO (1 << 20) /* U+3130-U+318F */
+/* Bit 53 CJK Miscellaneous */
+#define TT_UCR_CJK_MISC (1 << 21) /* U+3190-U+319F */
+/* Bit 54 Enclosed CJK Letters And Months */
+#define TT_UCR_ENCLOSED_CJK_LETTERS_MONTHS (1 << 22) /* U+3200-U+32FF */
+/* Bit 55 CJK Compatibility */
+#define TT_UCR_CJK_COMPATIBILITY (1 << 23) /* U+3300-U+33FF */
+
+/* Hangul Syllables Area */
+
+/* Bit 56 Hangul */
+#define TT_UCR_HANGUL (1 << 24) /* U+AC00-U+D7A3 */
+
+/* Surrogates Area */
+
+/* Bit 57 Surrogates */
+#define TT_UCR_SURROGATES (1 << 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 (1 << 27) /* U+4E00-U+9FFF */
+
+/* Private Use Area */
+
+/* Bit 60 Private Use */
+#define TT_UCR_PRIVATE_USE (1 << 28) /* U+E000-U+F8FF */
+
+/* Compatibility Area and Specials */
+
+/* Bit 61 CJK Compatibility Ideographs */
+#define TT_UCR_CJK_COMPATIBILITY_IDEOGRAPHS (1 << 29) /* U+F900-U+FAFF */
+/* Bit 62 Alphabetic Presentation Forms */
+#define TT_UCR_ALPHABETIC_PRESENTATION_FORMS (1 << 30) /* U+FB00-U+FB4F */
+/* Bit 63 Arabic Presentation Forms-A */
+#define TT_UCR_ARABIC_PRESENTATION_FORMS_A (1 << 31) /* U+FB50-U+FSFF */
+/* Bit 64 Combining Half Marks */
+#define TT_UCR_COMBINING_HALF_MARKS (1 << 0) /* U+FE20-U+FE2F */
+/* Bit 65 CJK Compatibility Forms */
+#define TT_UCR_CJK_COMPATIBILITY_FORMS (1 << 1) /* U+FE30-U+FE4F */
+/* Bit 66 Small Form Variants */
+#define TT_UCR_SMALL_FORM_VARIANTS (1 << 2) /* U+FE50-U+FE6F */
+/* Bit 67 Arabic Presentation Forms-B */
+#define TT_UCR_ARABIC_PRESENTATION_FORMS_B (1 << 3) /* U+FE70-U+FEFF */
+/* Bit 68 Halfwidth And Fullwidth Forms */
+#define TT_UCR_HALFWIDTH_FULLWIDTH_FORMS (1 << 4) /* U+FF00-U+FFEF */
+/* Bit 69 Specials */
+#define TT_UCR_SPECIALS (1 << 5) /* U+FEFF,
+ U+FFF0-U+FFFF */
+/* Bit 70 Tibetan */
+#define TT_UCR_TIBETAN (1 << 6) /* U+0F00-U+0FBF */
+
+
+#endif /* TTNAMEID_H */
+
+
+/* END */
--- /dev/null
+++ b/src/shared/tttags.h
@@ -1,0 +1,60 @@
+/***************************************************************************/
+/* */
+/* 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 <freetype.h> /* for MAKE_TT_TAG() */
+
+
+#define TTAG_cmap FT_MAKE_TAG( 'c', 'm', 'a', 'p' )
+#define TTAG_cvt FT_MAKE_TAG( 'c', 'v', 't', ' ' )
+#define TTAG_EBDT FT_MAKE_TAG( 'E', 'B', 'D', 'T' )
+#define TTAG_EBLC FT_MAKE_TAG( 'E', 'B', 'L', 'C' )
+#define TTAG_EBSC FT_MAKE_TAG( 'E', 'B', 'S', 'C' )
+#define TTAG_fpgm FT_MAKE_TAG( 'f', 'p', 'g', 'm' )
+#define TTAG_gasp FT_MAKE_TAG( 'g', 'a', 's', 'p' )
+#define TTAG_glyf FT_MAKE_TAG( 'g', 'l', 'y', 'f' )
+#define TTAG_GSUB FT_MAKE_TAG( 'G', 'S', 'U', 'B' )
+#define TTAG_hdmx FT_MAKE_TAG( 'h', 'd', 'm', 'x' )
+#define TTAG_head FT_MAKE_TAG( 'h', 'e', 'a', 'd' )
+#define TTAG_hhea FT_MAKE_TAG( 'h', 'h', 'e', 'a' )
+#define TTAG_hmtx FT_MAKE_TAG( 'h', 'm', 't', 'x' )
+#define TTAG_kern FT_MAKE_TAG( 'k', 'e', 'r', 'n' )
+#define TTAG_loca FT_MAKE_TAG( 'l', 'o', 'c', 'a' )
+#define TTAG_LTSH FT_MAKE_TAG( 'L', 'T', 'S', 'H' )
+#define TTAG_maxp FT_MAKE_TAG( 'm', 'a', 'x', 'p' )
+#define TTAG_name FT_MAKE_TAG( 'n', 'a', 'm', 'e' )
+#define TTAG_OS2 FT_MAKE_TAG( 'O', 'S', '/', '2' )
+#define TTAG_OTTO FT_MAKE_TAG( 'O', 'T', 'T', 'O' )
+#define TTAG_PCLT FT_MAKE_TAG( 'P', 'C', 'L', 'T' )
+#define TTAG_post FT_MAKE_TAG( 'p', 'o', 's', 't' )
+#define TTAG_prep FT_MAKE_TAG( 'p', 'r', 'e', 'p' )
+#define TTAG_true FT_MAKE_TAG( 't', 'r', 'u', 'e' )
+#define TTAG_ttc FT_MAKE_TAG( 't', 't', 'c', ' ' )
+#define TTAG_ttcf FT_MAKE_TAG( 't', 't', 'c', 'f' )
+#define TTAG_VDMX FT_MAKE_TAG( 'V', 'D', 'M', 'X' )
+#define TTAG_vhea FT_MAKE_TAG( 'v', 'h', 'e', 'a' )
+#define TTAG_vmtx FT_MAKE_TAG( 'v', 'm', 't', 'x' )
+
+
+#endif /* TTAGS_H */
+
+
+/* END */
--- /dev/null
+++ b/src/shared/tttypes.h
@@ -1,0 +1,2066 @@
+/***************************************************************************/
+/* */
+/* tttypes.h */
+/* */
+/* Basic SFNT/TrueType type definitions and interface (specification */
+/* only). */
+/* */
+/* This code is shared by all TrueType and OpenType drivers. */
+/* */
+/* */
+/* 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 TTTYPES_H
+#define TTTYPES_H
+
+
+#include <freetype.h>
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*** ***/
+ /*** ***/
+ /*** DEFINITIONS OF BASIC DATA TYPES ***/
+ /*** ***/
+ /*** ***/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* The REDEFINE() macro is used to convert a FreeType generic type into */
+ /* a TrueType-specific one. It simply replaces the `FT_' prefix by */
+ /* `TT_' in order to define compatible types like TT_Long, TT_Error, */
+ /* TT_Outline, etc. */
+ /* */
+#undef REDEFINE
+#define REDEFINE( type ) typedef FT_##type TT_##type
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_Bool */
+ /* */
+ /* <Description> */
+ /* A typedef of unsigned char, used for simple booleans. */
+ /* */
+ REDEFINE( Bool );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_FWord */
+ /* */
+ /* <Description> */
+ /* A signed 16-bit integer used to store a distance in original font */
+ /* units. */
+ /* */
+ REDEFINE( FWord );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_UFWord */
+ /* */
+ /* <Description> */
+ /* An unsigned 16-bit integer used to store a distance in original */
+ /* font units. */
+ /* */
+ REDEFINE( UFWord );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_Char */
+ /* */
+ /* <Description> */
+ /* A simple typedef for the _signed_ char type. */
+ /* */
+ REDEFINE( Char );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_Byte */
+ /* */
+ /* <Description> */
+ /* A simple typedef for the _unsigned_ char type. */
+ /* */
+ REDEFINE( Byte );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_String */
+ /* */
+ /* <Description> */
+ /* A simple typedef for the char type, usually used for strings. */
+ /* */
+ REDEFINE( String );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_Short */
+ /* */
+ /* <Description> */
+ /* A typedef for signed short. */
+ /* */
+ REDEFINE( Short );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_UShort */
+ /* */
+ /* <Description> */
+ /* A typedef for unsigned short. */
+ /* */
+ REDEFINE( UShort );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_Int */
+ /* */
+ /* <Description> */
+ /* A typedef for the int type. */
+ /* */
+ REDEFINE( Int );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_UInt */
+ /* */
+ /* <Description> */
+ /* A typedef for the unsigned int type. */
+ /* */
+ REDEFINE( UInt );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_Long */
+ /* */
+ /* <Description> */
+ /* A typedef for signed long. */
+ /* */
+ REDEFINE( Long );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_ULong */
+ /* */
+ /* <Description> */
+ /* A typedef for unsigned long. */
+ /* */
+ REDEFINE( ULong );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_F2Dot14 */
+ /* */
+ /* <Description> */
+ /* A signed 2.14 fixed float type used for unit vectors. */
+ /* */
+ REDEFINE( F2Dot14 );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_F26Dot6 */
+ /* */
+ /* <Description> */
+ /* A signed 26.6 fixed float type used for vectorial pixel */
+ /* coordinates. */
+ /* */
+ REDEFINE( F26Dot6 );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_Fixed */
+ /* */
+ /* <Description> */
+ /* This type is used to store 16.16 fixed float values, like scales */
+ /* or matrix coefficients. */
+ /* */
+ REDEFINE( Fixed );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_Pos */
+ /* */
+ /* <Description> */
+ /* The type FT_Pos is a 32-bit integer used to store vectorial */
+ /* coordinates. Depending on the context, these can represent */
+ /* distances in integer font units, or 26.6 fixed float pixel */
+ /* coordinates. */
+ /* */
+ REDEFINE( Pos );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_Vector */
+ /* */
+ /* <Description> */
+ /* A simple structure used to store a 2d vector; coordinates are of */
+ /* the TT_Pos type. */
+ /* */
+ /* <Fields> */
+ /* x :: The horizontal coordinate. */
+ /* y :: The vertical coordinate. */
+ /* */
+ REDEFINE( Vector );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_UnitVector */
+ /* */
+ /* <Description> */
+ /* A simple structure used to store a 2d vector unit vector. Uses */
+ /* TT_F2Dot14 types. */
+ /* */
+ /* <Fields> */
+ /* x :: Horizontal coordinate. */
+ /* y :: Vertical coordinate. */
+ /* */
+ REDEFINE( UnitVector );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_Matrix */
+ /* */
+ /* <Description> */
+ /* A simple structure used to store a 2x2 matrix. Coefficients are */
+ /* in 16.16 fixed float format. The computation performed is: */
+ /* */
+ /* { */
+ /* x' = x*xx + y*xy */
+ /* y' = x*yx + y*yy */
+ /* } */
+ /* */
+ /* <Fields> */
+ /* xx :: Matrix coefficient. */
+ /* xy :: Matrix coefficient. */
+ /* yx :: Matrix coefficient. */
+ /* yy :: Matrix coefficient. */
+ /* */
+ REDEFINE( Matrix );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_BBox */
+ /* */
+ /* <Description> */
+ /* A structure used to hold an outline's bounding box, i.e., the */
+ /* coordinates of its extrema in the horizontal and vertical */
+ /* directions. */
+ /* */
+ /* <Fields> */
+ /* xMin :: The horizontal minimum (left-most). */
+ /* yMin :: The vertical minimum (bottom-most). */
+ /* xMax :: The horizontal maximum (right-most). */
+ /* yMax :: The vertical maximum (top-most). */
+ /* */
+ REDEFINE( BBox );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_Error */
+ /* */
+ /* <Description> */
+ /* The TrueType error code type. A value of 0 is always interpreted */
+ /* as a successful operation. */
+ /* */
+ REDEFINE( Error );
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*** ***/
+ /*** ***/
+ /*** REQUIRED TRUETYPE/OPENTYPE TABLES DEFINITIONS ***/
+ /*** ***/
+ /*** ***/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TTC_Header */
+ /* */
+ /* <Description> */
+ /* TrueType collection header. This table contains the offsets of */
+ /* the font headers of each distinct TrueType face in the file. */
+ /* */
+ /* <Fields> */
+ /* tag :: Must be `ttc ' to indicate a TrueType collection. */
+ /* version :: The version number. */
+ /* count :: The number of faces in the collection. The */
+ /* specification says this should be an unsigned long, but */
+ /* we use a signed long since we need the value -1 for */
+ /* specific purposes. */
+ /* offsets :: The offsets of the font headers, one per face. */
+ /* */
+ typedef struct TTC_Header_
+ {
+ TT_ULong Tag;
+ TT_Fixed version;
+ TT_Long DirCount;
+ TT_ULong* TableDirectory;
+
+ } TTC_Header;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_TableDir */
+ /* */
+ /* <Description> */
+ /* This structure models a TrueType table directory. It is used to */
+ /* access the various tables of the font face. */
+ /* */
+ /* <Fields> */
+ /* version :: The version number; starts with 0x00010000. */
+ /* numTables :: The number of tables. */
+ /* */
+ /* searchRange :: Unused. */
+ /* entrySelector :: Unused. */
+ /* rangeShift :: Unused. */
+ /* */
+ /* <Note> */
+ /* This structure is only used during font opening. */
+ /* */
+ typedef struct TT_TableDir_
+ {
+ TT_Fixed version; /* should be 0x10000 */
+ TT_UShort numTables; /* number of tables */
+
+ TT_UShort searchRange; /* These parameters are only used */
+ TT_UShort entrySelector; /* for a dichotomy search in the */
+ TT_UShort rangeShift; /* directory. We ignore them. */
+
+ } TT_TableDir;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_Table */
+ /* */
+ /* <Description> */
+ /* This structure describes a given table of a TrueType font. */
+ /* */
+ /* <Fields> */
+ /* Tag :: A four-bytes tag describing the table. */
+ /* CheckSum :: The table checksum. This value can be ignored. */
+ /* Offset :: The offset of the table from the start of the TrueType */
+ /* font in its resource. */
+ /* Length :: The table length (in bytes). */
+ /* */
+ typedef struct TT_Table_
+ {
+ TT_ULong Tag; /* table type */
+ TT_ULong CheckSum; /* table checksum */
+ TT_ULong Offset; /* table file offset */
+ TT_ULong Length; /* table length */
+
+ } TT_Table;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_Header */
+ /* */
+ /* <Description> */
+ /* A structure used to model a TrueType font header table. All */
+ /* fields follow the TrueType specification. */
+ /* */
+ typedef 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;
+
+ } TT_Header;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_HoriHeader */
+ /* */
+ /* <Description> */
+ /* A structure used to model a TrueType horizontal header, the `hhea' */
+ /* table, as well as the corresponding horizontal metrics table, */
+ /* i.e., the `hmtx' table. */
+ /* */
+ /* <Fields> */
+ /* Version :: The table version. */
+ /* */
+ /* Ascender :: The font's ascender, i.e., the distance */
+ /* from the baseline to the top-most of all */
+ /* glyph points found in the font. */
+ /* */
+ /* This value is invalid in many fonts, as */
+ /* it is usually set by the font designer, */
+ /* and often reflects only a portion of the */
+ /* glyphs found in the font (maybe ASCII). */
+ /* */
+ /* You should use the `sTypoAscender' field */
+ /* of the OS/2 table instead if you want */
+ /* the correct one. */
+ /* */
+ /* Descender :: The font's descender, i.e., the distance */
+ /* from the baseline to the bottom-most of */
+ /* all glyph points found in the font. It */
+ /* is negative. */
+ /* */
+ /* This value is invalid in many fonts, as */
+ /* it is usually set by the font designer, */
+ /* and often reflects only a portion of the */
+ /* glyphs found in the font (maybe ASCII). */
+ /* */
+ /* You should use the `sTypoDescender' */
+ /* field of the OS/2 table instead if you */
+ /* want the correct one. */
+ /* */
+ /* Line_Gap :: The font's line gap, i.e., the distance */
+ /* to add to the ascender and descender to */
+ /* get the BTB, i.e., the */
+ /* baseline-to-baseline distance for the */
+ /* font. */
+ /* */
+ /* advance_Width_Max :: This field is the maximum of all advance */
+ /* widths found in the font. It can be */
+ /* used to compute the maximum width of an */
+ /* arbitrary string of text. */
+ /* */
+ /* min_Left_Side_Bearing :: The minimum left side bearing of all */
+ /* glyphs within the font. */
+ /* */
+ /* min_Right_Side_Bearing :: The minimum right side bearing of all */
+ /* glyphs within the font. */
+ /* */
+ /* xMax_Extent :: The maximum horizontal extent (i.e., the */
+ /* `width' of a glyph's bounding box) for */
+ /* all glyphs in the font. */
+ /* */
+ /* caret_Slope_Rise :: The rise coefficient of the cursor's */
+ /* slope of the cursor (slope=rise/run). */
+ /* */
+ /* caret_Slope_Run :: The run coefficient of the cursor's */
+ /* slope. */
+ /* */
+ /* Reserved :: 10 reserved bytes. */
+ /* */
+ /* metric_Data_Format :: Always 0. */
+ /* */
+ /* number_Of_HMetrics :: Number of HMetrics entries in the `hmtx' */
+ /* table -- this value can be smaller than */
+ /* the total number of glyphs in the font. */
+ /* */
+ /* long_metrics :: A pointer into the `hmtx' table. */
+ /* */
+ /* short_metrics :: A pointer into the `hmtx' table. */
+ /* */
+ /* <Note> */
+ /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */
+ /* be identical except for the names of their fields which */
+ /* are different. */
+ /* */
+ /* This ensures that a single function in the `ttload' */
+ /* module is able to read both the horizontal and vertical */
+ /* headers. */
+ /* */
+ typedef struct TT_HoriHeader_
+ {
+ 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_FWord caret_Offset;
+
+ TT_Short Reserved[4];
+
+ 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' table. */
+
+ void* long_metrics;
+ void* short_metrics;
+
+ } TT_HoriHeader;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_VertHeader */
+ /* */
+ /* <Description> */
+ /* A structure used to model a TrueType vertical header, the `vhea' */
+ /* table, as well as the corresponding vertical metrics table, i.e., */
+ /* the `vmtx' table. */
+ /* */
+ /* <Fields> */
+ /* Version :: The table version. */
+ /* */
+ /* Ascender :: The font's ascender, i.e., the distance */
+ /* from the baseline to the top-most of */
+ /* all glyph points found in the font. */
+ /* */
+ /* This value is invalid in many fonts, as */
+ /* it is usually set by the font designer, */
+ /* and often reflects only a portion of */
+ /* the glyphs found in the font (maybe */
+ /* ASCII). */
+ /* */
+ /* You should use the `sTypoAscender' */
+ /* field of the OS/2 table instead if you */
+ /* want the correct one. */
+ /* */
+ /* Descender :: The font's descender, i.e., the */
+ /* distance from the baseline to the */
+ /* bottom-most of all glyph points found */
+ /* in the font. It is negative. */
+ /* */
+ /* This value is invalid in many fonts, as */
+ /* it is usually set by the font designer, */
+ /* and often reflects only a portion of */
+ /* the glyphs found in the font (maybe */
+ /* ASCII). */
+ /* */
+ /* You should use the `sTypoDescender' */
+ /* field of the OS/2 table instead if you */
+ /* want the correct one. */
+ /* */
+ /* Line_Gap :: The font's line gap, i.e., the distance */
+ /* to add to the ascender and descender to */
+ /* get the BTB, i.e., the */
+ /* baseline-to-baseline distance for the */
+ /* font. */
+ /* */
+ /* advance_Height_Max :: This field is the maximum of all */
+ /* advance heights found in the font. It */
+ /* can be used to compute the maximum */
+ /* height of an arbitrary string of text. */
+ /* */
+ /* min_Top_Side_Bearing :: The minimum top side bearing of all */
+ /* glyphs within the font. */
+ /* */
+ /* min_Bottom_Side_Bearing :: The minimum bottom side bearing of all */
+ /* glyphs within the font. */
+ /* */
+ /* yMax_Extent :: The maximum vertical extent (i.e., the */
+ /* `height' of a glyph's bounding box) for */
+ /* all glyphs in the font. */
+ /* */
+ /* caret_Slope_Rise :: The rise coefficient of the cursor's */
+ /* slope of the cursor (slope=rise/run). */
+ /* */
+ /* caret_Slope_Run :: The run coefficient of the cursor's */
+ /* slope. */
+ /* */
+ /* Reserved :: 10 reserved bytes. */
+ /* */
+ /* metric_Data_Format :: Always 0. */
+ /* */
+ /* number_Of_HMetrics :: Number of VMetrics entries in the */
+ /* `vmtx' table -- this value can be */
+ /* smaller than the total number of glyphs */
+ /* in the font. */
+ /* */
+ /* long_metrics :: A pointer into the `vmtx' table. */
+ /* */
+ /* short_metrics :: A pointer into the `vmtx' table. */
+ /* */
+ /* <Note> */
+ /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */
+ /* be identical except for the names of their fields which */
+ /* are different. */
+ /* */
+ /* This ensures that a single function in the `ttload' */
+ /* module is able to read both the horizontal and vertical */
+ /* headers. */
+ /* */
+ typedef struct TT_VertHeader_
+ {
+ 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 Reserved[4];
+
+ 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;
+
+ } TT_VertHeader;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_OS2 */
+ /* */
+ /* <Description> */
+ /* A structure used to model a TrueType OS/2 table. This is the long */
+ /* table version. All fields comply to the TrueType specification. */
+ /* */
+ /* Note that we now support old Mac fonts which do not include an */
+ /* OS/2 table. In this case, the `version' field is always set to */
+ /* 0xFFFF. */
+ /* */
+ typedef struct TT_OS2_
+ {
+ TT_UShort version; /* 0x0001 - more or 0xFFFF */
+ 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 */
+
+ } TT_OS2;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_Postscript */
+ /* */
+ /* <Description> */
+ /* A structure used to model a TrueType Postscript table. All fields */
+ /* comply to the TrueType table. This structure does not reference */
+ /* the Postscript glyph names, which can be nevertheless accessed */
+ /* with the `ttpost' module. */
+ /* */
+ typedef struct TT_Postscript_
+ {
+ 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 ttpost.c file. */
+
+ } TT_Postscript;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_CMapDir */
+ /* */
+ /* <Description> */
+ /* This structure describes the directory of the `cmap' table, */
+ /* containing the font's character mappings table. */
+ /* */
+ /* <Fields> */
+ /* tableVersionNumber :: The version number. */
+ /* numCMaps :: The number of charmaps in the font. */
+ /* */
+ /* <Note> */
+ /* This structure is only used during font loading. */
+ /* */
+ typedef struct TT_CMapDir_
+ {
+ TT_UShort tableVersionNumber;
+ TT_UShort numCMaps;
+
+ } TT_CMapDir;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_CMapDirEntry */
+ /* */
+ /* <Description> */
+ /* This structure describes a charmap in a TrueType font. */
+ /* */
+ /* <Fields> */
+ /* platformID :: An ID used to specify for which platform this */
+ /* charmap is defined (FreeType manages all platforms). */
+ /* */
+ /* encodingID :: A platform-specific ID used to indicate which source */
+ /* encoding is used in this charmap. */
+ /* */
+ /* offset :: The offset of the charmap relative to the start of */
+ /* the `cmap' table. */
+ /* */
+ /* <Note> */
+ /* This structure is only used during font loading. */
+ /* */
+ typedef struct TT_CMapDirEntry_
+ {
+ TT_UShort platformID;
+ TT_UShort platformEncodingID;
+ TT_Long offset;
+
+ } TT_CMapDirEntry;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_MaxProfile */
+ /* */
+ /* <Description> */
+ /* The maximum profile is a table containing many max values which */
+ /* can be used to pre-allocate arrays. This ensures that no memory */
+ /* allocation occurs during a glyph load. */
+ /* */
+ /* <Fields> */
+ /* version :: The version number. */
+ /* */
+ /* numGlyphs :: The number of glyphs in this TrueType */
+ /* font. */
+ /* */
+ /* maxPoints :: The maximum number of points in a */
+ /* non-composite TrueType glyph. See also */
+ /* the structure element */
+ /* `maxCompositePoints'. */
+ /* */
+ /* maxContours :: The maximum number of contours in a */
+ /* non-composite TrueType glyph. See also */
+ /* the structure element */
+ /* `maxCompositeContours'. */
+ /* */
+ /* maxCompositePoints :: The maximum number of points in a */
+ /* composite TrueType glyph. See also the */
+ /* structure element `maxPoints'. */
+ /* */
+ /* maxCompositeContours :: The maximum number of contours in a */
+ /* composite TrueType glyph. See also the */
+ /* structure element `maxContours'. */
+ /* */
+ /* maxZones :: The maximum number of zones used for */
+ /* glyph hinting. */
+ /* */
+ /* maxTwilightPoints :: The maximum number of points in the */
+ /* twilight zone used for glyph hinting. */
+ /* */
+ /* maxStorage :: The maximum number of elements in the */
+ /* storage area used for glyph hinting. */
+ /* */
+ /* maxFunctionDefs :: The maximum number of function */
+ /* definitions in the TrueType bytecode for */
+ /* this font. */
+ /* */
+ /* maxInstructionDefs :: The maximum number of instruction */
+ /* definitions in the TrueType bytecode for */
+ /* this font. */
+ /* */
+ /* maxStackElements :: The maximum number of stack elements used */
+ /* during bytecode interpretation. */
+ /* */
+ /* maxSizeOfInstructions :: The maximum number of TrueType opcodes */
+ /* used for glyph hinting. */
+ /* */
+ /* maxComponentElements :: An obscure value related to composite */
+ /* glyphs definitions. */
+ /* */
+ /* maxComponentDepth :: An obscure value related to composite */
+ /* glyphs definitions. Probably the maximum */
+ /* number of simple glyphs in a composite. */
+ /* */
+ /* <Note> */
+ /* This structure is only used during font loading. */
+ /* */
+ typedef struct TT_MaxProfile_
+ {
+ TT_Fixed version;
+ TT_UShort numGlyphs;
+ TT_UShort maxPoints;
+ TT_UShort maxContours;
+ TT_UShort maxCompositePoints;
+ TT_UShort maxCompositeContours;
+ TT_UShort maxZones;
+ TT_UShort maxTwilightPoints;
+ TT_UShort maxStorage;
+ TT_UShort maxFunctionDefs;
+ TT_UShort maxInstructionDefs;
+ TT_UShort maxStackElements;
+ TT_UShort maxSizeOfInstructions;
+ TT_UShort maxComponentElements;
+ TT_UShort maxComponentDepth;
+
+ } TT_MaxProfile;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_LongMetrics */
+ /* */
+ /* <Description> */
+ /* A structure modeling the long metrics of the `hmtx' and `vmtx' */
+ /* TrueType tables. The values are expressed in font units. */
+ /* */
+ /* <Fields> */
+ /* advance :: The advance width or height for the glyph. */
+ /* bearing :: The left-side or top-side bearing for the glyph. */
+ /* */
+ typedef struct TT_LongMetrics_
+ {
+ TT_UShort advance;
+ TT_Short bearing;
+
+ } TT_LongMetrics;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> TT_ShortMetrics */
+ /* */
+ /* <Description> */
+ /* A simple type to model the short metrics of the `hmtx' and `vmtx' */
+ /* tables. */
+ /* */
+ typedef TT_Short TT_ShortMetrics;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_NameRec */
+ /* */
+ /* <Description> */
+ /* A structure modeling TrueType name records. Name records are used */
+ /* to store important strings like family name, style name, */
+ /* copyright, etc. in _localized_ versions (i.e., language, encoding, */
+ /* etc). */
+ /* */
+ /* <Fields> */
+ /* platformID :: The ID of the name's encoding platform. */
+ /* */
+ /* encodingID :: The platform-specific ID for the name's encoding. */
+ /* */
+ /* languageID :: The platform-specific ID for the name's language. */
+ /* */
+ /* nameID :: The ID specifying what kind of name this is. */
+ /* */
+ /* stringLength :: The length of the string in bytes. */
+ /* */
+ /* stringOffset :: The offset to the string in the `name' table. */
+ /* */
+ /* string :: A pointer to the string's bytes. Note that these */
+ /* are usually UTF-16 encoded characters. */
+ /* */
+ typedef struct TT_NameRec_
+ {
+ TT_UShort platformID;
+ TT_UShort encodingID;
+ TT_UShort languageID;
+ TT_UShort nameID;
+ TT_UShort stringLength;
+ TT_UShort stringOffset;
+
+ /* this last field is not defined in the spec */
+ /* but used by the FreeType engine */
+
+ TT_Byte* string;
+
+ } TT_NameRec;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_NameTable */
+ /* */
+ /* <Description> */
+ /* A structure modeling the TrueType name table. */
+ /* */
+ /* <Fields> */
+ /* format :: The format of the name table. */
+ /* */
+ /* numNameRecords :: The number of names in table. */
+ /* */
+ /* storageOffset :: The offset of the name table in the `name' */
+ /* TrueType table. */
+ /* */
+ /* names :: An array of name records. */
+ /* */
+ /* storage :: The names storage area. */
+ /* */
+ typedef struct TT_NameTable_
+ {
+ TT_UShort format;
+ TT_UShort numNameRecords;
+ TT_UShort storageOffset;
+ TT_NameRec* names;
+ TT_Byte* storage;
+
+ } TT_NameTable;
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*** ***/
+ /*** ***/
+ /*** OPTIONAL TRUETYPE/OPENTYPE TABLES DEFINITIONS ***/
+ /*** ***/
+ /*** ***/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_GaspRange */
+ /* */
+ /* <Description> */
+ /* A tiny structure used to model a gasp range according to the */
+ /* TrueType specification. */
+ /* */
+ /* <Fields> */
+ /* maxPPEM :: The maximum ppem value to which `gaspFlag' applies. */
+ /* */
+ /* gaspFlag :: A flag describing the grid-fitting and anti-aliasing */
+ /* modes to be used. */
+ /* */
+ typedef struct TT_GaspRange_
+ {
+ TT_UShort maxPPEM;
+ TT_UShort gaspFlag;
+
+ } TT_GaspRange;
+
+
+#define TT_GASP_GRIDFIT 0x01
+#define TT_GASP_DOGRAY 0x02
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_Gasp */
+ /* */
+ /* <Description> */
+ /* A structure modeling the TrueType `gasp' table used to specify */
+ /* grid-fitting and anti-aliasing behaviour. */
+ /* */
+ /* <Fields> */
+ /* version :: The version number. */
+ /* numRanges :: The number of gasp ranges in table. */
+ /* gaspRanges :: An array of gasp ranges. */
+ /* */
+ typedef struct TT_Gasp_
+ {
+ TT_UShort version;
+ TT_UShort numRanges;
+ TT_GaspRange* gaspRanges;
+
+ } TT_Gasp;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_HdmxRec */
+ /* */
+ /* <Description> */
+ /* A small structure used to model the pre-computed widths of a given */
+ /* size. They're found in the `hdmx' table. */
+ /* */
+ /* <Fields> */
+ /* ppem :: The pixels per EM value at which these metrics apply. */
+ /* */
+ /* max_width :: The maximum advance width for this metric. */
+ /* */
+ /* widths :: An array of widths. Note: These are 8-bit bytes. */
+ /* */
+ typedef struct TT_HdmxRec_
+ {
+ TT_Byte ppem;
+ TT_Byte max_width;
+ TT_Byte* widths;
+
+ } TT_HdmxRec;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_HdmxRec */
+ /* */
+ /* <Description> */
+ /* A structure used to model the `hdmx' table, which contains */
+ /* pre-computed widths for a set of given sizes/dimensions. */
+ /* */
+ /* <Fields> */
+ /* version :: The version number. */
+ /* num_records :: The number of hdmx records. */
+ /* records :: An array of hdmx records. */
+ /* */
+ typedef struct TT_Hdmx_
+ {
+ TT_UShort version;
+ TT_Short num_records;
+ TT_HdmxRec* records;
+
+ } TT_Hdmx;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_Kern_0_Pair */
+ /* */
+ /* <Description> */
+ /* A structure used to model a kerning pair for the kerning table */
+ /* format 0. The engine now loads this table if it finds one in the */
+ /* font file. */
+ /* */
+ /* <Fields> */
+ /* left :: The index of the left glyph in pair. */
+ /* right :: The index of the right glyph in pair. */
+ /* value :: The kerning distance. A positive value spaces the */
+ /* glyphs, a negative one makes them closer. */
+ /* */
+ typedef struct TT_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 */
+
+ } TT_Kern_0_Pair;
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*** ***/
+ /*** ***/
+ /*** EMBEDDED BITMAPS SUPPORT ***/
+ /*** ***/
+ /*** ***/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_SBit_Metrics */
+ /* */
+ /* <Description> */
+ /* A structure used to hold the big metrics of a given glyph bitmap */
+ /* in a TrueType or OpenType font. These are usually found in the */
+ /* `EBDT' (Microsoft) or `bdat' (Apple) table. */
+ /* */
+ /* <Fields> */
+ /* height :: The glyph height in pixels. */
+ /* */
+ /* width :: The glyph width in pixels. */
+ /* */
+ /* horiBearingX :: The horizontal left bearing. */
+ /* */
+ /* horiBearingY :: The horizontal top bearing. */
+ /* */
+ /* horiAdvance :: The horizontal advance. */
+ /* */
+ /* vertBearingX :: The vertical left bearing. */
+ /* */
+ /* vertBearingY :: The vertical top bearing. */
+ /* */
+ /* vertAdvance :: The vertical advance. */
+ /* */
+ typedef struct TT_SBit_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;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_SBit_Small_Metrics */
+ /* */
+ /* <Description> */
+ /* A structure used to hold the small metrics of a given glyph bitmap */
+ /* in a TrueType or OpenType font. These are usually found in the */
+ /* `EBDT' (Microsoft) or the `bdat' (Apple) table. */
+ /* */
+ /* <Fields> */
+ /* height :: The glyph height in pixels. */
+ /* */
+ /* width :: The glyph width in pixels. */
+ /* */
+ /* bearingX :: The left-side bearing. */
+ /* */
+ /* bearingY :: The top-side bearing. */
+ /* */
+ /* advance :: The advance width or height. */
+ /* */
+ typedef struct TT_SBit_Small_Metrics_
+ {
+ TT_Byte height;
+ TT_Byte width;
+
+ TT_Char bearingX;
+ TT_Char bearingY;
+ TT_Byte advance;
+
+ } TT_SBit_Small_Metrics;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_SBit_Line_Metrics */
+ /* */
+ /* <Description> */
+ /* A structure used to describe the text line metrics of a given */
+ /* bitmap strike, for either a horizontal or vertical layout. */
+ /* */
+ /* <Fields> */
+ /* ascender :: The ascender in pixels. */
+ /* */
+ /* descender :: The descender in pixels. */
+ /* */
+ /* max_width :: The maximum glyph width in pixels. */
+ /* */
+ /* caret_slope_enumerator :: Rise of the caret slope, typically set */
+ /* to 1 for non-italic fonts. */
+ /* */
+ /* caret_slope_denominator :: Rise of the caret slope, typically set */
+ /* to 0 for non-italic fonts. */
+ /* */
+ /* caret_offset :: Offset in pixels to move the caret for */
+ /* proper positioning. */
+ /* */
+ /* min_origin_SB :: Minimum of horiBearingX (resp. */
+ /* vertBearingY). */
+ /* min_advance_SB :: Minimum of */
+ /* */
+ /* horizontal advance - */
+ /* ( horiBearingX + width ) */
+ /* */
+ /* resp. */
+ /* */
+ /* vertical advance - */
+ /* ( vertBearingY + height ) */
+ /* */
+ /* max_before_BL :: Maximum of horiBearingY (resp. */
+ /* vertBearingY). */
+ /* */
+ /* min_after_BL :: Minimum of */
+ /* */
+ /* horiBearingY - height */
+ /* */
+ /* resp. */
+ /* */
+ /* vertBearingX - width */
+ /* */
+ 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;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_SBit_Range */
+ /* */
+ /* <Description> */
+ /* A TrueType/OpenType subIndexTable as defined in the `EBLC' */
+ /* (Microsoft) or `bloc' (Apple) tables. */
+ /* */
+ /* <Fields> */
+ /* first_glyph :: The first glyph index in the range. */
+ /* */
+ /* last_glyph :: The last glyph index in the range. */
+ /* */
+ /* index_format :: The format of index table. Valid values are 1 */
+ /* to 5. */
+ /* */
+ /* image_format :: The format of `EBDT' image data. */
+ /* */
+ /* image_offset :: The offset to image data in `EBDT'. */
+ /* */
+ /* image_size :: For index formats 2 and 5. This is the size in */
+ /* bytes of each glyph bitmap. */
+ /* */
+ /* big_metrics :: For index formats 2 and 5. This is the big */
+ /* metrics for each glyph bitmap. */
+ /* */
+ /* num_glyphs :: For index formats 4 and 5. This is the number of */
+ /* glyphs in the code array. */
+ /* */
+ /* glyph_offsets :: For index formats 1 and 3. */
+ /* */
+ /* glyph_codes :: For index formats 4 and 5. */
+ /* */
+ /* table_offset :: The offset of the index table in the `EBLC' */
+ /* table. Only used during strike loading. */
+ /* */
+ typedef struct TT_SBit_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;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_SBit_Strike */
+ /* */
+ /* <Description> */
+ /* A structure used describe a given bitmap strike in the `EBLC' */
+ /* (Microsoft) or `bloc' (Apple) tables. */
+ /* */
+ /* <Fields> */
+ /* num_index_ranges :: The number of index ranges. */
+ /* */
+ /* index_ranges :: An array of glyph index ranges. */
+ /* */
+ /* color_ref :: Unused. A color reference? */
+ /* */
+ /* hori :: The line metrics for horizontal layouts. */
+ /* */
+ /* vert :: The line metrics for vertical layouts. */
+ /* */
+ /* start_glyph :: The lowest glyph index for this strike. */
+ /* */
+ /* end_glyph :: The highest glyph index for this strike. */
+ /* */
+ /* x_ppem :: The number of horizontal pixels per EM. */
+ /* */
+ /* y_ppem :: The number of vertical pixels per EM. */
+ /* */
+ /* bit_depth :: The bit depth. Valid values are 1, 2, 4, */
+ /* and 8. */
+ /* */
+ /* flags :: Is this a vertical or horizontal strike? */
+ /* */
+ typedef struct TT_SBit_Strike_
+ {
+ 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;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_SBit_Component */
+ /* */
+ /* <Description> */
+ /* A simple structure to describe a compound sbit element. */
+ /* */
+ /* <Fields> */
+ /* glyph_code :: The element's glyph index. */
+ /* x_offset :: The element's left bearing. */
+ /* y_offset :: The element's top bearing. */
+ /* */
+ typedef struct TT_SBit_Component_
+ {
+ TT_UShort glyph_code;
+
+ TT_Char x_offset;
+ TT_Char y_offset;
+
+ } TT_SBit_Component;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_SBit_Scale */
+ /* */
+ /* <Description> */
+ /* A structure used describe a given bitmap scaling table, as defined */
+ /* in the `EBSC' table. */
+ /* */
+ /* <Fields> */
+ /* hori :: The horizontal line metrics. */
+ /* */
+ /* vert :: The vertical line metrics. */
+ /* */
+ /* x_ppem :: The number of horizontal pixels per EM. */
+ /* */
+ /* y_ppem :: The number of vertical pixels per EM. */
+ /* */
+ /* x_ppem_substitute :: Substitution x_ppem value. */
+ /* */
+ /* y_ppem_substitute :: Substitution y_ppem value. */
+ /* */
+ typedef struct TT_SBit_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;
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*** ***/
+ /*** ***/
+ /*** POSTSCRIPT GLYPH NAMES SUPPORT ***/
+ /*** ***/
+ /*** ***/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_Post_20 */
+ /* */
+ /* <Description> */
+ /* Postscript names sub-table, format 2.0. Stores the PS name of */
+ /* each glyph in the font face. */
+ /* */
+ /* <Fields> */
+ /* num_glyphs :: The number of named glyphs in the table. */
+ /* */
+ /* num_names :: The number of PS names stored in the table. */
+ /* */
+ /* glyph_indices :: The indices of the glyphs in the names arrays. */
+ /* */
+ /* glyph_names :: The PS names not in Mac Encoding. */
+ /* */
+ typedef struct TT_Post_20_
+ {
+ TT_UShort num_glyphs;
+ TT_UShort num_names;
+ TT_UShort* glyph_indices;
+ TT_Char** glyph_names;
+
+ } TT_Post_20;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_Post_25 */
+ /* */
+ /* <Description> */
+ /* Postscript names sub-table, format 2.5. Stores the PS name of */
+ /* each glyph in the font face. */
+ /* */
+ /* <Fields> */
+ /* num_glyphs :: The number of glyphs in the table. */
+ /* */
+ /* offsets :: An array of signed offsets in a normal Mac */
+ /* Postscript name encoding. */
+ /* */
+ typedef struct TT_Post_25_
+ {
+ TT_UShort num_glyphs;
+ TT_Char* offsets;
+
+ } TT_Post_25;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_Post_Names */
+ /* */
+ /* <Description> */
+ /* Postscript names table, either format 2.0 or 2.5. */
+ /* */
+ /* <Fields> */
+ /* loaded :: A flag to indicate whether the PS names are loaded. */
+ /* */
+ /* format_20 :: The sub-table used for format 2.0. */
+ /* */
+ /* format_25 :: The sub-table used for format 2.5. */
+ /* */
+ typedef struct TT_Post_Names_
+ {
+ TT_Bool loaded;
+
+ union
+ {
+ TT_Post_20 format_20;
+ TT_Post_25 format_25;
+
+ } names;
+
+ } TT_Post_Names;
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*** ***/
+ /*** ***/
+ /*** TRUETYPE CHARMAPS SUPPORT ***/
+ /*** ***/
+ /*** ***/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ /* format 0 */
+ typedef struct TT_CMap0_
+ {
+ TT_Byte* glyphIdArray;
+
+ } TT_CMap0;
+
+
+ /* format 2 */
+ typedef struct TT_CMap2SubHeader_
+ {
+ TT_UShort firstCode; /* first valid low byte */
+ TT_UShort entryCount; /* number of valid low bytes */
+ TT_Short idDelta; /* delta value to glyphIndex */
+ TT_UShort idRangeOffset; /* offset from here to 1st code */
+
+ } TT_CMap2SubHeader;
+
+
+ typedef struct TT_CMap2_
+ {
+ TT_UShort* subHeaderKeys;
+ /* high byte mapping table */
+ /* value = subHeader index * 8 */
+
+ TT_CMap2SubHeader* subHeaders;
+ TT_UShort* glyphIdArray;
+ TT_UShort numGlyphId; /* control value */
+
+ } TT_CMap2;
+
+
+ /* format 4 */
+ typedef struct TT_CMap4Segment_
+ {
+ TT_UShort endCount;
+ TT_UShort startCount;
+ TT_Short idDelta;
+ TT_UShort idRangeOffset;
+
+ } TT_CMap4Segment;
+
+
+ typedef struct TT_CMap4_
+ {
+ TT_UShort segCountX2; /* number of segments * 2 */
+ TT_UShort searchRange; /* these parameters can be used */
+ TT_UShort entrySelector; /* for a binary search */
+ TT_UShort rangeShift;
+
+ TT_CMap4Segment* segments;
+ TT_UShort* glyphIdArray;
+ TT_UShort numGlyphId; /* control value */
+
+ } TT_CMap4;
+
+
+ /* format 6 */
+ typedef struct TT_CMap6_
+ {
+ TT_UShort firstCode; /* first character code of subrange */
+ TT_UShort entryCount; /* number of character codes in subrange */
+
+ TT_UShort* glyphIdArray;
+
+ } TT_CMap6;
+
+ typedef struct TT_CMapTable_ TT_CMapTable;
+
+ typedef
+ TT_UInt (*TT_CharMap_Func)( TT_CMapTable* charmap,
+ TT_ULong char_code );
+
+ /* charmap table */
+ struct TT_CMapTable_
+ {
+ TT_UShort platformID;
+ TT_UShort platformEncodingID;
+ TT_UShort format;
+ TT_UShort length;
+ TT_UShort version;
+
+ TT_Bool loaded;
+ TT_ULong offset;
+
+ union
+ {
+ TT_CMap0 cmap0;
+ TT_CMap2 cmap2;
+ TT_CMap4 cmap4;
+ TT_CMap6 cmap6;
+ } c;
+
+ TT_CharMap_Func get_index;
+ };
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_CharMapRec */
+ /* */
+ /* <Description> */
+ /* The TrueType character map object type. */
+ /* */
+ /* <Fields> */
+ /* root :: The parent character map structure. */
+ /* cmap :: The used character map. */
+ /* */
+ typedef struct TT_CharMapRec_
+ {
+ FT_CharMapRec root;
+ TT_CMapTable cmap;
+
+ } TT_CharMapRec;
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*** ***/
+ /*** ***/
+ /*** ORIGINAL TT_FACE CLASS DEFINITION ***/
+ /*** ***/
+ /*** ***/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* This structure/class is defined here because it is common to the */
+ /* following formats: TTF, OpenType-TT, and OpenType-CFF. */
+ /* */
+ /* Note however that the classes TT_Size, TT_GlyphSlot, and TT_CharMap */
+ /* are not shared between font drivers, and are thus defined normally in */
+ /* `drivers/truetype/ttobjs.h'. */
+ /* */
+ /*************************************************************************/
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_Face */
+ /* */
+ /* <Description> */
+ /* A handle to a TrueType face/font object. A TT_Face encapsulates */
+ /* the resolution and scaling independent parts of a TrueType font */
+ /* resource. */
+ /* */
+ /* <Note> */
+ /* The TT_Face structure is also used as a `parent class' for the */
+ /* OpenType-CFF class (T2_Face). */
+ /* */
+ typedef struct TT_FaceRec_* TT_Face;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_CharMap */
+ /* */
+ /* <Description> */
+ /* A handle to a TrueType character mapping object. */
+ /* */
+ typedef struct TT_CharMapRec_* TT_CharMap;
+
+
+ /* a function type used for the truetype bytecode interpreter hooks */
+ typedef TT_Error (*TT_Interpreter)( void* exec_context );
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* TT_Goto_Table_Func */
+ /* */
+ /* <Description> */
+ /* Seeks a stream to the start of a given TrueType table. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* tag :: a 4-byte tag used to name the table */
+ /* stream :: The input stream. */
+ /* */
+ /* <Output> */
+ /* length :: length of table in bytes. Set to 0 when not needed */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* The stream cursor must be at the font file's origin */
+ /* */
+ typedef
+ TT_Error (*TT_Goto_Table_Func)( TT_Face face,
+ TT_ULong tag,
+ FT_Stream stream,
+ TT_ULong *length );
+
+ /*************************************************************************/
+ /* */
+ /* TrueType Face Type */
+ /* */
+ /* <Struct> */
+ /* TT_Face */
+ /* */
+ /* <Description> */
+ /* The TrueType face class. These objects model the resolution and */
+ /* point-size independent data found in a TrueType font file. */
+ /* */
+ /* <Fields> */
+ /* root :: The base FT_Face structure, managed by the */
+ /* base layer. */
+ /* */
+ /* ttcHeader :: The TrueType collection header, used when the */
+ /* file is a `ttc' rather than a `ttf'. For */
+ /* ordinary font files, the field */
+ /* `ttcHeader.DirCount' is set to 0. */
+ /* */
+ /* num_tables :: The number of TrueType tables in this font */
+ /* file. */
+ /* */
+ /* dir_tables :: The directory of TrueType tables for this */
+ /* font file. */
+ /* */
+ /* header :: The font's font header (`head' table). Read */
+ /* on font opening. */
+ /* */
+ /* horizontal :: The font's horizontal header (`hhea' table). */
+ /* This field also contains the associated */
+ /* horizontal metrics table (`hmtx'). */
+ /* */
+ /* max_profile :: The font's maximum profile table. Read on */
+ /* font opening. Note that some maximum values */
+ /* cannot be taken directly from this table. We */
+ /* thus define additional fields below to hold */
+ /* the computed maxima. */
+ /* */
+ /* max_components :: The maximum number of glyph components */
+ /* required to load any composite glyph from */
+ /* this font. Used to size the load stack. */
+ /* */
+ /* vertical_info :: A boolean which is set when the font file */
+ /* contains vertical metrics. If not, the value */
+ /* of the `vertical' field is undefined. */
+ /* */
+ /* vertical :: The font's vertical header (`vhea' table). */
+ /* This field also contains the associated */
+ /* vertical metrics table (`vmtx'), if found. */
+ /* IMPORTANT: The contents of this field is */
+ /* undefined if the `verticalInfo' field is */
+ /* unset. */
+ /* */
+ /* num_names :: The number of name records within this */
+ /* TrueType font. */
+ /* */
+ /* name_table :: The table of name records (`name'). */
+ /* */
+ /* os2 :: The font's OS/2 table (`OS/2'). */
+ /* */
+ /* postscript :: The font's PostScript table (`post' table). */
+ /* The PostScript glyph names are not loaded by */
+ /* the driver on face opening. See the `ttpost' */
+ /* module for more details. */
+ /* */
+ /* num_charmaps :: The number of character mappings in the font. */
+ /* */
+ /* charmaps :: The array of charmap objects for this font */
+ /* file. Note that this field is a typeless */
+ /* pointer. The Reason is that the format of */
+ /* charmaps varies with the underlying font */
+ /* format and cannot be determined here. */
+ /* */
+ /* goto_face :: a function called by each TrueType table */
+ /* loader to position a stream's cursor to the */
+ /* start of a given table according to its tag. */
+ /* it defaults to TT_Goto_Face but can be */
+ /* different for strange formats (e.g. Type 42) */
+ /* */
+ /* sfnt :: a pointer to the SFNT `driver' interface. */
+ /* */
+ /* hdmx :: The face's horizontal device metrics (`hdmx' */
+ /* table). This table is optional in */
+ /* TrueType/OpenType fonts. */
+ /* */
+ /* gasp :: The grid-fitting and scaling properties table */
+ /* (`gasp'). This table is optional in */
+ /* TrueType/OpenType fonts. */
+ /* */
+ /* num_sbit_strikes :: The number of sbit strikes, i.e., bitmap */
+ /* sizes, embedded in this font. */
+ /* */
+ /* sbit_strikes :: An array of sbit strikes embedded in this */
+ /* font. This table is optional in a */
+ /* TrueType/OpenType font. */
+ /* */
+ /* num_sbit_scales :: The number of sbit scales for this font. */
+ /* */
+ /* sbit_scales :: Array of sbit scales embedded in this font. */
+ /* This table is optional in a TrueType/OpenType */
+ /* font. */
+ /* */
+ /* postscript_names :: A table used to store the Postscript names of */
+ /* the glyphs for this font. See the file */
+ /* `ttconfig.h' for comments on the */
+ /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES option. */
+ /* */
+ /* num_locations :: The number of glyph locations in this */
+ /* TrueType file. This should be identical to */
+ /* the number of glyphs. Ignored for Type 2 */
+ /* fonts. */
+ /* */
+ /* glyph_locations :: An array of longs. These are offsets to */
+ /* glyph data within the `glyf' table. Ignored */
+ /* for Type 2 font faces. */
+ /* */
+ /* font_program_size :: Size in bytecodes of the face's font program. */
+ /* 0 if none defined. Ignored for Type 2 fonts. */
+ /* */
+ /* font_program :: The face's font program (bytecode stream) */
+ /* executed at load time, also used during glyph */
+ /* rendering. Comes from the `fpgm' table. */
+ /* Ignored for Type 2 font fonts. */
+ /* */
+ /* cvt_program_size :: Size in bytecodes of the face's cvt program. */
+ /* Ignored for Type 2 fonts. */
+ /* */
+ /* cvt_program :: The face's cvt program (bytecode stream) */
+ /* executed each time an instance/size is */
+ /* changed/reset. Comes from the `prep' table. */
+ /* Ignored for Type 2 fonts. */
+ /* */
+ /* cvt_size :: Size of the control value table (in entries). */
+ /* Ignored for Type 2 fonts. */
+ /* */
+ /* cvt :: The face's original control value table. */
+ /* Coordinates are expressed in unscaled font */
+ /* units. Comes from the `cvt ` table. Ignored */
+ /* for Type 2 fonts. */
+ /* */
+ /* num_kern_pairs :: The number of kerning pairs present in the */
+ /* font file. The engine only loads the first */
+ /* horizontal format 0 kern table it finds in */
+ /* the font file. You should use the `ttxkern' */
+ /* structures if you want to access other */
+ /* kerning tables. Ignored for Type 2 fonts. */
+ /* */
+ /* kern_table_index :: The index of the kerning table in the font */
+ /* kerning directory. Only used by the ttxkern */
+ /* extension to avoid data duplication. Ignored */
+ /* for Type 2 fonts. */
+ /* */
+ /* kern_pairs :: Array of kerning pairs, if any. Ignored for */
+ /* Type 2 fonts. */
+ /* */
+ /* interpreter :: Pointer to the TrueType bytecode interpreter */
+ /* this field is also used to hook the debugger */
+ /* in `ttdebug' */
+ /* */
+ typedef struct TT_FaceRec_
+ {
+ FT_FaceRec root;
+
+ TTC_Header ttc_header;
+
+ TT_UShort num_tables;
+ TT_Table* dir_tables;
+
+ TT_Header header; /* TrueType header table */
+ TT_HoriHeader horizontal; /* TrueType horizontal header */
+
+ TT_MaxProfile max_profile;
+ TT_ULong max_components;
+
+ TT_Bool vertical_info;
+ TT_VertHeader vertical; /* TT Vertical header, if present */
+
+ TT_Int num_names; /* number of name records */
+ TT_NameTable name_table; /* name table */
+
+ TT_OS2 os2; /* TrueType OS/2 table */
+ TT_Postscript postscript; /* TrueType Postscript table */
+
+ TT_Int num_charmaps;
+ TT_CharMap charmaps; /* array of TT_CharMapRec */
+
+ /* a pointer to the function used to seek a stream to the start of */
+ /* a given TrueType table. This should default to the function */
+ /* TT_Goto_Table defined in `ttload.h', but some font drivers */
+ /* might need something different, e.g. Type 42 fonts */
+ TT_Goto_Table_Func goto_table;
+
+ /* a typeless pointer to the SFNT_Interface table used to load */
+ /* the basic TrueType tables in the face object */
+ void* sfnt;
+
+ /***********************************************************************/
+ /* */
+ /* Optional TrueType/OpenType tables */
+ /* */
+ /***********************************************************************/
+
+ /* horizontal device metrics */
+ TT_Hdmx hdmx;
+
+ /* grid-fitting and scaling table */
+ TT_Gasp gasp; /* the `gasp' table */
+
+ /* embedded bitmaps support */
+ TT_Int num_sbit_strikes;
+ TT_SBit_Strike* sbit_strikes;
+
+ TT_Int num_sbit_scales;
+ TT_SBit_Scale* sbit_scales;
+
+ /* postscript names table */
+ TT_Post_Names postscript_names;
+
+ /***********************************************************************/
+ /* */
+ /* TrueType-specific fields (ignored by the OTF-Type2 driver) */
+ /* */
+ /***********************************************************************/
+
+ /* the glyph locations */
+ TT_UShort num_locations;
+ TT_Long* glyph_locations;
+
+ /* the font program, if any */
+ TT_ULong font_program_size;
+ TT_Byte* font_program;
+
+ /* the cvt program, if any */
+ TT_ULong cvt_program_size;
+ TT_Byte* cvt_program;
+
+ /* the original, unscaled, control value table */
+ TT_ULong cvt_size;
+ TT_Short* cvt;
+
+ /* the format 0 kerning table, if any */
+ TT_Int num_kern_pairs;
+ TT_Int kern_table_index;
+ TT_Kern_0_Pair* kern_pairs;
+
+ /* a pointer to the bytecode interpreter to use. This is also */
+ /* used to hook the debugger for the `ttdebug' utility.. */
+ TT_Interpreter interpreter;
+
+ } TT_FaceRec;
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+
+#endif /* TTTYPES_H */
+
+
+/* END */
--- /dev/null
+++ b/src/shared/type1/rules.mk
@@ -1,0 +1,54 @@
+#****************************************************************************
+#* *
+#* Shared/Type1 Makefile *
+#* *
+#* 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. *
+#* *
+#****************************************************************************
+
+
+#****************************************************************************
+#* *
+#* IMPORTANT NOTE: This Makefile is intended for GNU Make! *
+#* If you provide Makefiles for other make utilities, *
+#* please place them in `freetype/lib/arch/<system>'. *
+#* *
+#* *
+#* This file is to be included by the Makefiles of each driver that uses *
+#* the shared source code in `freetype2/lib/drivers/type1'. This code *
+#* contains type definitions as well as interface which are common to all *
+#* supported Postscript font formats (i.e. Type1 and Type2). *
+#* *
+#* *
+#* The purpose of this Makefile is to define make variables that are used *
+#* directly by the parent Makefile. *
+#* *
+#****************************************************************************
+
+
+# T1SHARED_DIR is the directory to the `shared/type1' sources
+#
+T1SHARED_DIR := $(SRC)/shared/type1
+T1SHARED_DIR_ := $(T1SHARED_DIR)$(SEP)
+
+
+# T1SHARED_H is the list of all header files on which the client drivers
+# depend
+#
+T1SHARED_H := $(T1SHARED_DIR_)t1types.h \
+ $(T1SHARED_DIR_)t1encode.h
+
+# T1SHARED_SRC is the list of all shared source files that are included
+# by any client driver
+#
+T1SHARED_SRC := $(T1SHARED_DIR_)t1encode.c
+
+
+# END
--- /dev/null
+++ b/src/shared/type1/t1encode.c
@@ -1,0 +1,330 @@
+/***************************************************************************/
+/* */
+/* t1encode.c */
+/* */
+/* Type 1 standard encoding tables definitions (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. */
+/* */
+/* */
+/* This file is included by both the Type1 and Type2 driver. */
+/* It should never be compiled directly. */
+/* */
+/***************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* t1_standard_strings: */
+ /* */
+ /* This array contains the Adobe Standard Glyph Names ordered by */
+ /* SID. It was taken from the CFF specification. */
+ /* */
+ LOCAL_FUNC
+ const T1_String* t1_standard_strings[] =
+ {
+ /* 0 */
+ ".notdef", "space", "exclam", "quotedbl", "numbersign",
+ "dollar", "percent", "ampersand", "quoteright", "parenleft",
+ /* 10 */
+ "parenright", "asterisk", "plus", "comma", "hyphen",
+ "period", "slash", "zero", "one", "two",
+ /* 20 */
+ "three", "four", "five", "six", "seven",
+ "height", "nine", "colon", "semicolon", "less",
+ /* 30 */
+ "equal", "greater", "question", "at", "A",
+ "B", "C", "D", "E", "F",
+ /* 40 */
+ "G", "H", "I", "J", "K",
+ "L", "M", "N", "O", "P",
+ /* 50 */
+ "Q", "R", "S", "T", "U",
+ "V", "W", "X", "Y", "Z",
+ /* 60 */
+ "bracketleft", "backslash", "bracketright", "asciicircum", "underscore",
+ "quoteleft", "a", "b", "c", "d",
+ /* 70 */
+ "e", "f", "g", "h", "i",
+ "j", "k", "l", "m", "n",
+ /* 80 */
+ "o", "p", "q", "r", "s",
+ "t", "u", "v", "w", "x",
+ /* 90 */
+ "y", "z", "braceleft", "bar", "braceright",
+ "asciitilde", "exclamdown", "cent", "sterling", "fraction",
+ /* 100 */
+ "yen", "florin", "section", "currency", "quotesingle",
+ "quotedblleft", "quillemotleft", "guilsinglleft", "guilsinglright", "fi",
+ /* 110 */
+ "fl", "endash", "dagger", "daggerdbl", "periodcenter",
+ "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright",
+ /* 120 */
+ "quillemotright", "ellipsis", "perthousand", "questiondown", "grave",
+ "acute", "circumflex", "tilde", "macron", "breve",
+ /* 130 */
+ "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut",
+ "ogonek", "caron", "emdash", "AE", "ordfeminine",
+ /* 140 */
+ "Lslash", "Oslash", "OE", "ordmasculine", "ae",
+ "dotlessi", "Islash", "oslash", "oe", "germandbls",
+ /* 150 */
+ "onesuperior", "logicalnot", "mu", "trademark", "Eth",
+ "onehalf", "plusminus", "Thorn", "onequarter", "divide",
+ /* 160 */
+ "brokenbar", "degree", "thorn", "threequarters", "twosuperior",
+ "regitered", "minus", "eth", "multiply", "threesuperior",
+ /* 170 */
+ "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave",
+ "Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex",
+ /* 180 */
+ "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis",
+ "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis",
+ /* 190 */
+ "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex",
+ "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron",
+ /* 200 */
+ "aacute", "acircumflex", "adieresis", "agrave", "aring",
+ "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis",
+ /* 210 */
+ "egrave", "iacute", "icircumflex", "idieresis", "igrave",
+ "ntilde", "oacute", "ocircumflex", "odieresis", "ograve",
+ /* 220 */
+ "otilde", "scaron", "uacute", "ucircumflex", "udieresis",
+ "ugrave", "yacute", "ydieresis", "zcaron", "exclamsmall",
+ /* 230 */
+ "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall",
+ "Acutesmall",
+ "parenleftsuperior", "parenrightsuperior", "twodotenleader",
+ "onedotenleader", "zerooldstyle",
+ /* 240 */
+ "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle",
+ "fiveoldstyle",
+ "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle",
+ "commasuperior",
+ /* 250 */
+ "threequartersemdash", "periodsuperior", "questionsmall", "asuperior",
+ "bsuperior",
+ "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior",
+ /* 260 */
+ "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior",
+ "tsuperior", "ff", "ffi", "ffl", "parenleftinferior",
+ /* 270 */
+ "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall",
+ "Asmall",
+ "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall",
+ /* 280 */
+ "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall",
+ "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall",
+ /* 290 */
+ "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall",
+ "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall",
+ /* 300 */
+ "colonmonetary", "onefitted", "rupiah", "Tildesmall", "exclamdownsmall",
+ "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall",
+ "Dieresissmall",
+ /* 310 */
+ "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash",
+ "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall",
+ "questiondownsmall",
+ /* 320 */
+ "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird",
+ "twothirds", "zerosuperior", "foursuperior", "fivesuperior",
+ "sixsuperior",
+ /* 330 */
+ "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior",
+ "oneinferior",
+ "twoinferior", "threeinferior", "fourinferior", "fiveinferior",
+ "sixinferior",
+ /* 340 */
+ "seveninferior", "eightinferior", "nineinferior", "centinferior",
+ "dollarinferior",
+ "periodinferior", "commainferior", "Agravesmall", "Aacutesmall",
+ "Acircumflexsmall",
+ /* 350 */
+ "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall",
+ "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall",
+ "Igravesmall",
+ /* 360 */
+ "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall",
+ "Ntildesmall",
+ "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall",
+ "Odieresissmall",
+ /* 370 */
+ "OEsmall", "Oslashsmall", "Ugravesmall", "Uacautesmall",
+ "Ucircumflexsmall",
+ "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall",
+ "001.000",
+ /* 380 */
+ "001.001", "001.002", "001.003", "Black", "Bold",
+ "Book", "Light", "Medium", "Regular", "Roman",
+ /* 390 */
+ "Semibold"
+ };
+
+
+ /*************************************************************************/
+ /* */
+ /* t1_standard_encoding: */
+ /* */
+ /* A simple table used to encode the Adobe StandardEncoding. The */
+ /* table values are the SID of the standard glyphs; the table index */
+ /* is the character code for the encoding. */
+ /* */
+ /* Example: */
+ /* */
+ /* t1_standard_encoding[33] == 2 */
+ /* */
+ /* which means that the glyph name for character code 32 is */
+ /* */
+ /* t1_standard_strings[2] == "exclam" */
+ /* */
+ /* (this correspond to the exclamation mark `!'). */
+ /* */
+ LOCAL_FUNC
+ T1_Short t1_standard_encoding[256] =
+ {
+ /* 0 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ /* 50 */
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
+ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ /* 100 */
+ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
+ 89, 90, 91, 92, 93, 94, 95, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 150 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 0, 111, 112, 113,
+ 114, 0, 115, 116, 117, 118, 119, 120, 121, 122,
+ 0, 123, 0, 124, 125, 126, 127, 128, 129, 130,
+ /* 200 */
+ 131, 0, 132, 133, 0, 134, 135, 136, 137, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 138, 0, 139, 0, 0,
+ 0, 0, 140, 141, 142, 143, 0, 0, 0, 0,
+ 0, 144, 0, 0, 0, 145, 0, 0, 146, 147,
+ /* 250 */
+ 148, 149, 0, 0, 0, 0
+ };
+
+
+ /*************************************************************************/
+ /* */
+ /* t1_expert_encoding: */
+ /* */
+ /* A simple table used to encode the Adobe ExpertEncoding. The */
+ /* table values are the SID of the standard glyphs; the table index */
+ /* is the character code for the encoding. */
+ /* */
+ /* Example: */
+ /* */
+ /* t1_expert_encoding[33] == 229 */
+ /* */
+ /* which means that the glyph name for character code 32 is */
+ /* */
+ /* t1_standard_strings[229] == "exclamsmall" */
+ /* */
+ LOCAL_FUNC
+ T1_Short t1_expert_encoding[256] =
+ {
+ /* 0 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 229, 230, 0, 231, 232, 233, 234,
+ 235, 236, 237, 238, 13, 14, 15, 99, 239, 240,
+ /* 50 */
+ 241, 242, 243, 244, 245, 246, 247, 248, 27, 28,
+ 249, 250, 251, 252, 0, 253, 254, 255, 256, 257,
+ 0, 0, 0, 258, 0, 0, 259, 260, 261, 262,
+ 0, 0, 263, 264, 265, 0, 266, 109, 110, 267,
+ 268, 269, 0, 270, 271, 272, 273, 274, 275, 276,
+ /* 100 */
+ 277, 278, 279, 280, 281, 282, 283, 284, 285, 286,
+ 287, 288, 289, 290, 291, 292, 293, 294, 295, 296,
+ 297, 298, 299, 300, 301, 302, 303, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 150 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 304, 305, 306, 0, 0, 307, 308, 309, 310,
+ 311, 0, 312, 0, 0, 312, 0, 0, 314, 315,
+ 0, 0, 316, 317, 318, 0, 0, 0, 158, 155,
+ 163, 319, 320, 321, 322, 323, 324, 325, 0, 0,
+ /* 200 */
+ 326, 150, 164, 169, 327, 328, 329, 330, 331, 332,
+ 333, 334, 335, 336, 337, 338, 339, 340, 341, 342,
+ 343, 344, 345, 346, 347, 348, 349, 350, 351, 352,
+ 353, 354, 355, 356, 357, 358, 359, 360, 361, 362,
+ 363, 364, 365, 366, 367, 368, 369, 370, 371, 372,
+ /* 250 */
+ 373, 374, 375, 376, 377, 378
+ };
+
+
+ /*************************************************************************/
+ /* */
+ /* t1_expert_subset_encoding: */
+ /* */
+ /* A simple table used to encode the Adobe ExpertEncoding subset */
+ /* defined in the CFF specification. It will probably evolve into */
+ /* another form sooner or later, as we deal with charsets */
+ /* differently than with encodings. */
+ /* */
+ LOCAL_FUNC
+ FT_Short t1_expert_subset_encoding[256] =
+ {
+ /* 0 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 231, 232, 0, 0,
+ 235, 236, 237, 238, 13, 14, 15, 99, 239, 240,
+ /* 50 */
+ 241, 242, 243, 244, 245, 246, 247, 248, 27, 28,
+ 249, 250, 251, 252, 0, 253, 254, 255, 256, 257,
+ 0, 0, 0, 258, 0, 0, 259, 260, 261, 262,
+ 0, 0, 263, 264, 265, 0, 266, 109, 110, 267,
+ 268, 269, 0, 270, 0, 272, 0, 0, 0, 0,
+ /* 100 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 300, 301, 302, 303, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 150 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 304, 305, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 314, 315,
+ 0, 0, 0, 0, 0, 0, 0, 0, 158, 155,
+ 163, 0, 320, 321, 322, 323, 324, 325, 0, 0,
+ /* 200 */
+ 326, 150, 164, 169, 327, 328, 329, 330, 331, 332,
+ 333, 334, 335, 336, 337, 338, 339, 340, 341, 342,
+ 343, 344, 345, 346, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 250 */
+ 0, 0, 0, 0, 0, 0
+ };
+
+
+/* END */
--- /dev/null
+++ b/src/shared/type1/t1encode.h
@@ -1,0 +1,98 @@
+/***************************************************************************/
+/* */
+/* t1encode.h */
+/* */
+/* Type 1 standard encoding tables definitions (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 file is included by both the Type1 and Type2 driver. */
+/* It should never be compiled directly. */
+/* */
+/***************************************************************************/
+
+
+#ifndef T1ENCODE_H
+#define T1ENCODE_H
+
+#include <t1types.h>
+
+
+ /*************************************************************************/
+ /* */
+ /* t1_standard_strings: */
+ /* */
+ /* This array contains the Adobe Standard Glyph Names ordered by */
+ /* SID. It was taken from the CFF specification. */
+ /* */
+ LOCAL_DEF
+ const T1_String* t1_standard_strings[];
+
+
+ /*************************************************************************/
+ /* */
+ /* t1_standard_encoding: */
+ /* */
+ /* A simple table used to encode the Adobe StandardEncoding. The */
+ /* table values are the SID of the standard glyphs; the table index */
+ /* is the character code for the encoding. */
+ /* */
+ /* Example: */
+ /* */
+ /* t1_standard_encoding[33] == 2 */
+ /* */
+ /* which means that the glyph name for character code 32 is */
+ /* */
+ /* t1_standard_strings[2] == "exclam" */
+ /* */
+ /* (this correspond to the exclamation mark `!'). */
+ /* */
+ LOCAL_DEF
+ T1_Short t1_standard_encoding[256];
+
+
+ /*************************************************************************/
+ /* */
+ /* t1_expert_encoding: */
+ /* */
+ /* A simple table used to encode the Adobe ExpertEncoding. The */
+ /* table values are the SID of the standard glyphs; the table index */
+ /* is the character code for the encoding. */
+ /* */
+ /* Example: */
+ /* */
+ /* t1_expert_encoding[33] == 229 */
+ /* */
+ /* which means that the glyph name for character code 32 is */
+ /* */
+ /* t1_standard_strings[229] == "exclamsmall" */
+ /* */
+ LOCAL_DEF
+ T1_Short t1_expert_encoding[256];
+
+
+ /*************************************************************************/
+ /* */
+ /* t1_expert_subset_encoding: */
+ /* */
+ /* A simple table used to encode the Adobe ExpertEncoding subset */
+ /* defined in the CFF specification. It will probably evolve into */
+ /* another form sooner or later, as we deal with charsets */
+ /* differently than with encodings. */
+ /* */
+ LOCAL_DEF
+ T1_Short t1_expert_subset_encoding[256];
+
+
+#endif /* T1ENCODE_H */
+
+
+/* END */
--- /dev/null
+++ b/src/shared/type1/t1types.h
@@ -1,0 +1,485 @@
+/*******************************************************************
+ *
+ * t1types.h 1.0
+ *
+ * Basic Type1/Type2 type definitions and interface.
+ *
+ * This code is shared by the Type1 and Type2 drivers
+ *
+ *
+ * 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 T1TYPES_H
+#define T1TYPES_H
+
+#include <freetype.h>
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+/*** ***/
+/*** ***/
+/*** DEFINITIONS OF BASIC DATA TYPES ***/
+/*** ***/
+/*** ***/
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+
+
+/* The REDEFINE macro is used to convert a FreeType generic type into */
+/* a TrueType-specific one. It simply replaces the "FT_" prefix by "T1_" */
+/* in order to define compatible T1_Long, T1_Error, T1_Outline, etc.. */
+/* */
+#undef REDEFINE
+#define REDEFINE( type ) typedef FT_##type T1_##type
+
+
+ /* <Type> T1_Bool */
+ /* */
+ /* <Description> */
+ /* A simple typedef of unsigned char, used for simple booleans. */
+ /* */
+ REDEFINE( Bool );
+
+
+ /* <Type> T1_FWord */
+ /* */
+ /* <Description> */
+ /* a signed 16-bit integer used to store a distance in original */
+ /* font units. */
+ /* */
+ REDEFINE( FWord );
+
+
+ /* <Type> T1_UFWord */
+ /* */
+ /* <Description> */
+ /* an unsigned 16-bit integer used to store a distance in original */
+ /* font units. */
+ /* */
+ REDEFINE( UFWord );
+
+
+ /* <Type> T1_Char */
+ /* */
+ /* <Description> */
+ /* a simple typedef for the _signed_ char type. */
+ /* */
+ REDEFINE( Char );
+
+
+ /* <Type> T1_Byte */
+ /* */
+ /* <Description> */
+ /* a simple typedef for the _unsigned_ char type. */
+ /* */
+ REDEFINE( Byte );
+
+
+ /* <Type> T1_String */
+ /* */
+ /* <Description> */
+ /* a simple typedef for the char type, used for strings usually. */
+ /* */
+ REDEFINE( String );
+
+
+ /* <Type> T1_Short */
+ /* */
+ /* <Description> */
+ /* a typedef for signed short */
+ /* */
+ REDEFINE( Short );
+
+
+ /* <Type> T1_UShort */
+ /* */
+ /* <Description> */
+ /* a typedef for unsigned short */
+ /* */
+ REDEFINE( UShort );
+
+
+ /* <Type> FT_Int */
+ /* */
+ /* <Description> */
+ /* a typedef for the int type */
+ /* */
+ REDEFINE( Int );
+
+
+ /* <Type> FT_UInt */
+ /* */
+ /* <Description> */
+ /* a typedef for the unsigned int type */
+ /* */
+ REDEFINE( UInt );
+
+
+ /* <Type> T1_Long */
+ /* */
+ /* <Description> */
+ /* a typedef for signed long */
+ /* */
+ REDEFINE( Long );
+
+
+ /* <Type> T1_ULong */
+ /* */
+ /* <Description> */
+ /* a typedef for unsigned long */
+ /* */
+ REDEFINE( ULong );
+
+
+ /* <Type> T1_F2Dot14 */
+ /* */
+ /* <Description> */
+ /* a signed 2.14 fixed float used for unit vectors */
+ /* */
+ REDEFINE( F2Dot14 );
+
+
+ /* <Type> T1_F26Dot6 */
+ /* */
+ /* <Description> */
+ /* a signed 26.6 fixed float used for vectorial pixel coordinates */
+ /* */
+ REDEFINE( F26Dot6 );
+
+
+ /* <Type> T1_Fixed */
+ /* */
+ /* <Description> */
+ /* This type is used to store 16.16 fixed float values, like */
+ /* scales or matrix coefficients.. */
+ /* */
+ REDEFINE( Fixed );
+
+
+ /* <Type> T1_Pos */
+ /* */
+ /* <Description> */
+ /* The type T1_Pos is a 32-bits integer used to store vectorial */
+ /* coordinates. Depending on the context, these can represent */
+ /* distances in integer font units, or 26.6 fixed float pixel */
+ /* coordinates.. */
+ /* */
+ REDEFINE( Pos );
+
+
+ /* <Struct> T1_Vector */
+ /* */
+ /* <Description> */
+ /* A simple structure used to store a 2d vector, coordinates */
+ /* are of the T1_Pos type. */
+ /* */
+ /* <Fields> */
+ /* x :: horizontal coordinate */
+ /* y :: vertical coordinate */
+ /* */
+ REDEFINE( Vector );
+
+ /* <Struct> T1_UnitVector */
+ /* */
+ /* <Description> */
+ /* A simple structure used to store a 2d vector unit vector. */
+ /* uses T1_F2Dot14 types. */
+ /* */
+ /* <Fields> */
+ /* x :: horizontal coordinate */
+ /* y :: vertical coordinate */
+ /* */
+ REDEFINE( UnitVector );
+
+
+ /* <Struct> T1_Matrix */
+ /* */
+ /* <Description> */
+ /* A simple structure used to store a 2x2 matrix. Coefficients */
+ /* are in 16.16 fixed float format. The computation performed */
+ /* is : */
+ /* { */
+ /* x' = x*xx + y*xy */
+ /* y' = x*yx + y*yy */
+ /* } */
+ /* */
+ /* <Fields> */
+ /* xx :: matrix coefficient */
+ /* xy :: matrix coefficient */
+ /* yx :: matrix coefficient */
+ /* yy :: matrix coefficient */
+ /* */
+ REDEFINE( Matrix );
+
+
+ /* <Struct> T1_BBox */
+ /* */
+ /* <Description> */
+ /* A structure used to hold an outline's bounding box, i.e. */
+ /* the coordinates of its extrema in the horizontal and vertical */
+ /* directions. */
+ /* */
+ /* <Fields> */
+ /* xMin :: the horizontal minimum (left-most) */
+ /* yMin :: the vertical minimum (bottom-most) */
+ /* xMax :: the horizontal maximum (right-most) */
+ /* yMax :: the vertical maximum (top-most) */
+ /* */
+ REDEFINE( BBox );
+
+
+ /* <Type> T1_Error */
+ /* */
+ /* <Description> */
+ /* The FreeType error code type. A value of 0 is always */
+ /* interpreted as a succesful operation. */
+ /* */
+ REDEFINE( Error );
+
+
+
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+/*** ***/
+/*** ***/
+/*** REQUIRED TYPE1/TYPE2 TABLES DEFINITIONS ***/
+/*** ***/
+/*** ***/
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+
+ /***********************************************************************/
+ /* */
+ /* <Struct> T1_FontInfo */
+ /* */
+ /* <Description> */
+ /* The FontInfo dictionary structure. */
+ /* */
+ /* <Fields> */
+ /* version :: */
+ /* notice :: */
+ /* full_name :: */
+ /* family_name :: */
+ /* weight :: */
+ /* italic_angle :: */
+ /* is_fixed_pitch :: */
+ /* underline_position :: */
+ /* underline_thickness :: */
+ /* */
+ typedef struct T1_FontInfo_
+ {
+ T1_String* version;
+ T1_String* notice;
+ T1_String* full_name;
+ T1_String* family_name;
+ T1_String* weight;
+ T1_Long italic_angle;
+ T1_Bool is_fixed_pitch;
+ T1_Short underline_position;
+ T1_UShort underline_thickness;
+
+ } T1_FontInfo;
+
+
+ /***********************************************************************/
+ /* */
+ /* <Struct> T1_Private */
+ /* */
+ /* <Description> */
+ /* The Private dictionary structure. */
+ /* */
+ /* <Fields> */
+ /* unique_id :: the font's unique id */
+ /* lenIV :: length of decrypt padding */
+ /* */
+ /* num_blues :: number of blue values */
+ /* num_other_blues :: number of other blue values */
+ /* num_family_blues :: number of family blue values */
+ /* num_family_other_blues :: number of family other blue values */
+ /* */
+ /* blue_values :: array of blue values */
+ /* other_blues :: array of other blue values */
+ /* family_blues :: array of family blue values */
+ /* family_other_blues :: array of family other blue values */
+ /* */
+ /* blue_scale :: */
+ /* blue_shift :: */
+ /* blue_scale :: */
+ /* */
+ /* standard_width :: */
+ /* standard_height :: */
+ /* */
+ /* num_snap_widths :: */
+ /* num_snap_heights :: */
+ /* force_bold :: */
+ /* round_stem_up :: */
+ /* */
+ /* stem_snap_widths :: */
+ /* stem_snap_heights :: */
+ /* */
+ /* language_group :: */
+ /* password :: */
+ /* */
+ /* min_feature :: */
+ /* */
+ /* */
+ typedef struct T1_Private_
+ {
+ T1_Int unique_id;
+ T1_Int lenIV;
+
+ T1_Byte num_blues;
+ T1_Byte num_other_blues;
+ T1_Byte num_family_blues;
+ T1_Byte num_family_other_blues;
+
+ T1_Short blue_values[14];
+ T1_Short other_blues[10];
+
+ T1_Short family_blues [14];
+ T1_Short family_other_blues[10];
+
+ T1_Fixed blue_scale;
+ T1_Int blue_shift;
+ T1_Int blue_fuzz;
+
+ T1_UShort standard_width;
+ T1_UShort standard_height;
+
+ T1_Byte num_snap_widths;
+ T1_Byte num_snap_heights;
+ T1_Bool force_bold;
+ T1_Bool round_stem_up;
+
+ T1_Short stem_snap_widths [13]; /* reserve one place for the std */
+ T1_Short stem_snap_heights[13]; /* reserve one place for the std */
+
+ T1_Long language_group;
+ T1_Long password;
+
+ T1_Short min_feature[2];
+
+ } T1_Private;
+
+
+
+ /***********************************************************************/
+ /* */
+ /* <Struct> T1_Private */
+ /* */
+ /* <Description> */
+ /* The Private dictionary structure. */
+ /* */
+ /* <Fields> */
+ /* num_chars :: number of char codes in encoding. Usually 256 */
+ /* code_first :: lower char code in encoding */
+ /* code_last :: higher char code in encoding */
+ /* */
+ /* char_code :: array of character codes */
+ /* char_index :: array of correpsonding glyph indices */
+ /* char_name :: array of correpsonding glyph names */
+ /* */
+ typedef struct T1_Encoding_
+ {
+ T1_Int num_chars;
+ T1_Int code_first;
+ T1_Int code_last;
+
+ T1_Short* char_index;
+ T1_String** char_name;
+
+ } T1_Encoding;
+
+
+
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+/*** ***/
+/*** ***/
+/*** ORIGINAL TT_FACE CLASS DEFINITION ***/
+/*** ***/
+/*** ***/
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+/*** ***/
+/*** ***/
+/*** This structure/class is defined here because it is common ***/
+/*** to the following formats : TTF, OpenType-TT and OpenType-CFF ***/
+/*** ***/
+/*** Note however that the classes TT_Size, TT_GlyphSlot and ***/
+/*** TT_CharMap are not shared between font drivers, and are ***/
+/*** thus defined normally in "drivers/truetype/ttobjs.h" ***/
+/*** ***/
+/*** ***/
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+
+
+ typedef struct T1_FaceRec_* T1_Face;
+
+
+ /***************************************************/
+ /* */
+ /* T1_Face : */
+ /* */
+ /* Type1 face record.. */
+ /* */
+
+ typedef struct T1_FaceRec_
+ {
+ FT_FaceRec root;
+
+ T1_FontInfo font_info;
+ FT_String* font_name;
+
+ T1_Encoding encoding;
+
+ T1_Byte* subrs_block;
+ T1_Byte* charstrings_block;
+
+ T1_Int num_subrs;
+ T1_Byte** subrs;
+ T1_Int* subrs_len;
+
+ T1_Int num_glyphs;
+ T1_String** glyph_names; /* array of glyph names */
+ T1_Byte** charstrings; /* array of glyph charstrings */
+ T1_Int* charstrings_len;
+
+ T1_Byte paint_type;
+ T1_Byte font_type;
+ T1_Matrix font_matrix;
+ T1_BBox font_bbox;
+ T1_Long unique_id;
+ T1_Long font_id;
+
+ T1_Int stroke_width;
+ T1_Private private_dict;
+
+ } T1_FaceRec;
+
+
+#endif /* T1TYPES_H */
--- /dev/null
+++ b/src/truetype/rules.mk
@@ -1,0 +1,205 @@
+#****************************************************************************
+#* *
+#* TrueType driver Makefile *
+#* *
+#* 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. *
+#* *
+#****************************************************************************
+
+
+#****************************************************************************
+#* *
+#* IMPORTANT NOTE: This Makefile is intended for GNU Make! *
+#* If you provide Makefiles for other make utilities, *
+#* please place them in `freetype/lib/arch/<system>'. *
+#* *
+#* *
+#* This file is to be included by the FreeType Makefile.lib, located in *
+#* the `freetype/lib' directory. Here is the list of the variables that *
+#* must be defined to use it: *
+#* *
+#* *
+#* BASE_DIR: The location of the base layer's directory. This is *
+#* usually `freetype/lib/base'. *
+#* *
+#* ARCH_DIR: The location of the architecture-dependent directory. *
+#* This is usually `freetype/lib/arch/<system>'. *
+#* *
+#* DRIVERS_DIR: The location of the font driver sub-dirs, usually *
+#* `freetype/lib/drivers'. *
+#* *
+#* OBJ_DIR: The location where the compiled object(s) file will be *
+#* placed. *
+#* *
+#* BASE_H: A list of pathnames to the base layer's header files on *
+#* which the driver depends. *
+#* *
+#* FT_CFLAGS: A set of flags used for compilation of object files. *
+#* This contains at least the include paths of the arch *
+#* and base directories + optimization + warnings + ANSI *
+#* compliance. *
+#* *
+#* FT_IFLAG: The flag used to specify an include path on the *
+#* compiler command line. For example, with GCC, this is *
+#* `-I', while some other compilers use `/i=' or `-J', *
+#* etc. *
+#* *
+#* FT_OBJ: The suffix of an object file for the platform; can be *
+#* `o', `obj', `coff', `tco', etc. depending on the *
+#* platform. *
+#* *
+#* *
+#* It also updates the following variables defined and used in the main *
+#* Makefile: *
+#* *
+#* DRV_OBJ_S: The list of driver object files in *
+#* single-object mode. *
+#* *
+#* DRV_OBJ_M: The list of driver object files in *
+#* multiple-objects mode. *
+#* *
+#* FTINIT_DRIVER_PATHS: The list of include paths used to compile the *
+#* `ftinit' component which registers all font *
+#* drivers in the FT_Init_FreeType() function. *
+#* *
+#* FTINIT_DRIVER_H: The list of header dependencies used to *
+#* compile the `ftinit' component. *
+#* *
+#* FTINIT_DRIVER_MACROS: The list of macros to be defined when *
+#* compiling the `ftinit' component. *
+#* *
+#* `Single-object compilation' means that each font driver is compiled *
+#* into a single object file. This is useful to get rid of all *
+#* driver-specific entries. *
+#* *
+#****************************************************************************
+
+# include the rules defined for the SFNT driver, which is heavily used
+# by the TrueType one..
+#
+include $(SRC_)sfnt/rules.mk
+
+
+# TrueType driver directory
+#
+TT_DIR := $(SRC_)truetype
+TT_DIR_ := $(TT_DIR)$(SEP)
+
+
+# location of all extensions to the driver, if any
+#
+TT_EXT_DIR := $(TT_DIR_)extend
+TT_EXT_DIR_ := $(TT_EXT_DIR)$(SEP)
+
+# additional include flags used when compiling the driver
+#
+TT_INCLUDE := $(SFNT_INCLUDE) $(TT_DIR) $(TT_EXT_DIR)
+
+
+# compilation flags for the driver
+#
+TT_CFLAGS := $(TT_INCLUDE:%=$I%)
+TT_COMPILE := $(FT_CC) $(TT_CFLAGS)
+
+
+# TrueType driver sources (i.e., C files)
+#
+TT_DRV_SRC := $(TT_DIR_)ttobjs.c \
+ $(TT_DIR_)ttpload.c \
+ $(TT_DIR_)ttgload.c \
+ $(TT_DIR_)ttinterp.c \
+ $(TT_DIR_)ttdriver.c
+
+
+# TrueType driver headers
+#
+TT_DRV_H := $(SFNT_H) \
+ $(TT_DIR_)ttconfig.h \
+ $(TT_DRV_SRC:%.c=%.h)
+
+
+# default TrueType extensions sources
+#
+TT_EXT_SRC := $(TT_EXT_DIR_)ttxkern.c \
+ $(TT_EXT_DIR_)ttxgasp.c \
+ $(TT_EXT_DIR_)ttxpost.c \
+ $(TT_EXT_DIR_)ttxcmap.c \
+ $(TT_EXT_DIR_)ttxwidth.c
+
+
+# default TrueType extensions headers
+#
+TT_EXT_H := $(TT_EXT_SRC:.c=.h)
+
+
+# driver object(s)
+#
+# TT_DRV_OBJ_M is used during `debug' builds
+# TT_DRV_OBJ_S is used during `release' builds
+#
+TT_DRV_OBJ_M := $(TT_DRV_SRC:$(TT_DIR_)%.c=$(OBJ_)%.$O)
+TT_DRV_OBJ_S := $(OBJ_)truetype.$O
+
+
+# default extensions objects
+#
+TT_EXT_OBJ := $(TT_EXT_SRC:$(TT_EXT_DIR_)%.c=$(OBJ_)%.$O)
+
+
+
+# driver root source file(s)
+#
+TT_DRV_SRC_M := $(TT_DRV_SRC) $(SFNT_SRC)
+TT_DRV_SRC_S := $(TT_DIR_)truetype.c
+
+
+# driver - single object
+#
+# the driver is recompiled if any of the header or source files is changed
+# as well as any of the shared source files found in `shared/sfnt'
+#
+$(TT_DRV_OBJ_S): $(BASE_H) $(TT_DRV_H) $(TT_DRV_SRC) $(TT_DRV_SRC_S)
+ $(TT_COMPILE) $T$@ $(TT_DRV_SRC_S)
+
+
+
+# driver - multiple objects
+#
+# All objects are recompiled if any of the header files is changed
+#
+$(OBJ_)tt%.$O: $(TT_DIR_)tt%.c $(BASE_H) $(TT_DRV_H)
+ $(TT_COMPILE) $T$@ $<
+
+$(OBJ_)ttx%.$O: $(TT_EXT_DIR_)ttx%.c $(BASE_H) $(SFNT_H) $(TT_EXT_H)
+ $(TT_COMPILE) $T$@ $<
+
+$(OBJ_)tt%.$O: $(SFNT_DIR_)tt%.c $(BASE_H) $(SFNT_H)
+ $(TT_COMPILE) $T$@ $<
+
+
+# treat `ttpload' as a special case, as it includes C files
+#
+$(OBJ_)ttpload.$O: $(TT_DIR_)ttpload.c $(BASE_H) $(SFNT_SRC) $(TT_DRV_H)
+ $(TT_COMPILE) $T$@ $<
+
+
+# update main driver object lists
+#
+DRV_OBJS_S += $(TT_DRV_OBJ_S)
+DRV_OBJS_M += $(TT_DRV_OBJ_M)
+
+
+# update `ftinit' variables
+#
+FTINIT_DRIVER_PATHS += $(SFNT_DIR) $(TT_DIR) $(TT_EXT_DIR)
+FTINIT_DRIVER_H += $(SFNT_H) $(TT_DRV_H)
+FTINIT_DRIVER_MACROS += FT_SUPPORT_TRUETYPE
+
+# END
--- /dev/null
+++ b/src/truetype/truetype.c
@@ -1,0 +1,50 @@
+/***************************************************************************/
+/* */
+/* truetype.c */
+/* */
+/* FreeType TrueType driver component (body 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. */
+/* */
+/***************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* This file is used to compile the FreeType TrueType font driver. It */
+ /* relies on all components included in the `base' layer (see the file */
+ /* `ftbase.c'). The source code is located in `freetype/ttlib' and */
+ /* contains: */
+ /* */
+ /* - a driver interface */
+ /* - an object manager */
+ /* - a table loader */
+ /* - a glyph loader */
+ /* - a glyph hinter/bytecode interpreter */
+ /* - a charmap processor */
+ /* - an extension manager (only used for some tools) */
+ /* */
+ /* Note that the engine extensions found in `freetype/ttlib/extend' are */
+ /* reserved to specific tools and/or font servers; they're not part of */
+ /* the `core' TrueType driver, even though they are separately linkable */
+ /* to it. */
+ /* */
+ /*************************************************************************/
+
+
+#define FT_MAKE_OPTION_SINGLE_OBJECT
+
+#include <ttdriver.c> /* driver interface */
+#include <ttpload.c> /* tables loader */
+#include <ttgload.c> /* glyph loader */
+#include <ttinterp.c> /* bytecode interpreter */
+#include <ttobjs.c> /* object manager */
+
+/* END */
--- /dev/null
+++ b/src/truetype/ttconfig.h
@@ -1,0 +1,66 @@
+/***************************************************************************/
+/* */
+/* ttconfig.h */
+/* */
+/* TrueType configuration file (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. */
+/* */
+/***************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* This file is used to configure various aspects of the TrueType */
+ /* driver. */
+ /* */
+ /*************************************************************************/
+
+
+#ifndef TTCONFIG_H
+#define TTCONFIG_H
+
+
+ /*************************************************************************/
+ /* */
+ /* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType */
+ /* bytecode interpreter with a huge switch statement, rather than a */
+ /* call table. This results in smaller and faster code for a number of */
+ /* architectures. */
+ /* */
+ /* Note however that on some compiler/processor combinations, undefining */
+ /* this macro will generate a faster, though larger, code. */
+ /* */
+#define TT_CONFIG_OPTION_INTERPRETER_SWITCH
+
+
+ /*************************************************************************/
+ /* */
+ /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support */
+ /* embedded bitmaps in the TrueType/OpenType driver. */
+ /* */
+#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+
+
+ /*************************************************************************/
+ /* */
+ /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to */
+ /* load and enumerate the glyph Postscript names in a TrueType or */
+ /* OpenType file. */
+ /* */
+#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES
+
+
+#define TT_USE_FIXED
+
+#endif /* TTCONFIG_H */
+
+
+/* END */
--- /dev/null
+++ b/src/truetype/ttdriver.c
@@ -1,0 +1,783 @@
+/***************************************************************************/
+/* */
+/* ttdriver.c */
+/* */
+/* TrueType font driver implementation (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 <ftdebug.h>
+#include <ftstream.h>
+#include <ttnameid.h>
+#include <sfnt.h>
+
+#include <ttdriver.h>
+#include <ttgload.h>
+
+
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_ttdriver
+
+
+ static
+ TT_Bool string_compare( const TT_String* s1,
+ const TT_String* s2 )
+ {
+ int tries;
+
+
+ for ( tries = 128; tries > 0; tries-- )
+ {
+ if ( !*s1 )
+ return !*s2;
+
+ if ( *s1 != *s2 )
+ return 0;
+
+ s1++;
+ s2++;
+ }
+
+ return 0;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Get_Interface */
+ /* */
+ /* <Description> */
+ /* Some drivers can be compiled with extensions, special code used */
+ /* only for specific purposes (usually for system-specific uses). */
+ /* Each extension is registered through a simple name (e.g. `sfnt', */
+ /* `post_names', etc). */
+ /* */
+ /* This function is used to return an extension's interface (i.e., */
+ /* a table of pointers) when it is present in the driver. */
+ /* */
+ /* If the driver wasn't compiled with the requested extension, it */
+ /* should return NULL. */
+ /* */
+ /* <Input> */
+ /* driver :: A handle to the driver object. */
+ /* */
+ /* interface :: The interface's name string. */
+ /* */
+ /* <Return> */
+ /* A typeless pointer to the extension's interface (normally a table */
+ /* of function pointers). Returns NULL when the requested extension */
+ /* isn't available (i.e., wasn't compiled in the driver at build */
+ /* time). */
+ /* */
+ /* <Note> */
+ /* Note that unlike format-specific methods returned by */
+ /* getFormatInterface(), extensions can be format-independent. */
+ /* */
+ static
+ void* Get_Interface( TT_Driver driver,
+ const TT_String* interface )
+ {
+ /* `sfnt' returns a vtable of functions used to access the tables */
+ /* of a TrueType or OpenType font resource. */
+ if ( string_compare( interface, "sfnt" ) )
+ return (void*)NULL;
+
+ /* XXXX : For now, there is no extension support there */
+ UNUSED( driver );
+ UNUSED( interface );
+
+ return NULL;
+ }
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** F A C E S ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /******************************************************************
+ *
+ * <Function>
+ * find_encoding
+ *
+ * <Description>
+ * return the FT_Encoding corresponding to a given
+ * (platform_id,encoding_id) pair, as found in TrueType charmaps
+ *
+ * <Input>
+ * platform_id ::
+ * encoding_id ::
+ *
+ * <Return>
+ * the corresponding FT_Encoding tag. ft_encoding_none by default
+ *
+ *****************************************************************/
+
+ static
+ FT_Encoding find_encoding( int platform_id,
+ int encoding_id )
+ {
+ typedef struct TEncoding
+ {
+ int platform_id;
+ int encoding_id;
+ FT_Encoding encoding;
+
+ } TEncoding;
+
+ static
+ const TEncoding tt_encodings[] =
+ {
+ { TT_PLATFORM_ISO, -1, ft_encoding_unicode },
+
+ { TT_PLATFORM_APPLE_UNICODE, -1, ft_encoding_unicode },
+
+ { TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN, ft_encoding_apple_roman },
+
+ { TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, ft_encoding_unicode },
+ { TT_PLATFORM_MICROSOFT, TT_MS_ID_SJIS, ft_encoding_sjis },
+ { TT_PLATFORM_MICROSOFT, TT_MS_ID_BIG_5, ft_encoding_big5 }
+ };
+
+ const TEncoding *cur, *limit;
+
+ cur = tt_encodings;
+ limit = cur + sizeof(tt_encodings)/sizeof(tt_encodings[0]);
+
+ for ( ; cur < limit; cur++ )
+ {
+ if (cur->platform_id == platform_id)
+ {
+ if (cur->encoding_id == encoding_id ||
+ cur->encoding_id == -1 )
+ return cur->encoding;
+ }
+ }
+ return ft_encoding_none;
+ }
+
+
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Init_Face */
+ /* */
+ /* <Description> */
+ /* A driver method used to initialize a new TrueType face object. */
+ /* */
+ /* <Input> */
+ /* resource :: A handle to the source resource. */
+ /* */
+ /* typeface_index :: An index of the face in the font resource. Used */
+ /* to access individual faces in font collections. */
+ /* */
+ /* <InOut> */
+ /* face :: A handle to the face object. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* The `typeface_index' parameter field will be set to -1 if the */
+ /* engine only wants to test the format of the resource. This means */
+ /* that font drivers should simply check the font format, then return */
+ /* immediately with an error code of 0 (meaning success). The field */
+ /* `num_faces' should be set. */
+ /* */
+ /* Done_Face() will be called subsequently, whatever the result was. */
+ /* */
+ static
+ TT_Error Init_Face( FT_Stream stream,
+ TT_Long typeface_index,
+ TT_Face face )
+ {
+ TT_Error error;
+
+ /* initialize the TrueType face object */
+ error = TT_Init_Face( stream, typeface_index, face );
+
+ /* now set up root fields */
+ if ( !error && typeface_index >= 0 )
+ {
+ FT_Face root = &face->root;
+ FT_Int flags;
+ TT_CharMap charmap;
+ TT_Int n;
+ FT_Memory memory;
+
+ memory = root->memory;
+
+ /*****************************************************************/
+ /* */
+ /* Compute face flags. */
+ /* */
+ flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */
+ FT_FACE_FLAG_SFNT | /* SFNT file format */
+ FT_FACE_FLAG_HORIZONTAL; /* horizontal data */
+
+ /* fixed width font ? */
+ if ( face->postscript.isFixedPitch )
+ flags |= FT_FACE_FLAG_FIXED_WIDTH;
+
+ /* vertical information ? */
+ if ( face->vertical_info )
+ flags |= FT_FACE_FLAG_VERTICAL;
+
+ /* kerning available ? */
+ if ( face->kern_pairs )
+ flags |= FT_FACE_FLAG_KERNING;
+
+ root->face_flags = flags;
+
+ /*****************************************************************/
+ /* */
+ /* Compute style flags. */
+ /* */
+ flags = 0;
+
+ if ( face->os2.version != 0xFFFF )
+ {
+ /* We have an OS/2 table, use the `fsSelection' field */
+ if ( face->os2.fsSelection & 1 )
+ flags |= FT_STYLE_FLAG_ITALIC;
+
+ if ( face->os2.fsSelection & 32 )
+ flags |= FT_STYLE_FLAG_BOLD;
+ }
+ else
+ {
+ /* This is an old Mac font, use the header field */
+ if ( face->header.Mac_Style & 1 )
+ flags |= FT_STYLE_FLAG_BOLD;
+
+ if ( face->header.Mac_Style & 2 )
+ flags |= FT_STYLE_FLAG_ITALIC;
+ }
+
+ face->root.style_flags = flags;
+
+ /*****************************************************************/
+ /* */
+ /* Polish the charmaps. */
+ /* */
+ /* Try to set the charmap encoding according to the platform & */
+ /* encoding ID of each charmap. */
+ /* */
+ charmap = face->charmaps;
+ root->num_charmaps = face->num_charmaps;
+
+ /* allocate table of pointers */
+ if ( ALLOC_ARRAY( root->charmaps, root->num_charmaps, FT_CharMap ) )
+ return error;
+
+ for ( n = 0; n < root->num_charmaps; n++, charmap++ )
+ {
+ FT_Int platform = charmap->cmap.platformID;
+ FT_Int encoding = charmap->cmap.platformEncodingID;
+
+ charmap->root.face = (FT_Face)face;
+ charmap->root.platform_id = platform;
+ charmap->root.encoding_id = encoding;
+ charmap->root.encoding = find_encoding(platform,encoding);
+
+ /* now, set root->charmap with a unicode charmap wherever available */
+ if (!root->charmap && charmap->root.encoding == ft_encoding_unicode)
+ root->charmap = (FT_CharMap)charmap;
+
+ root->charmaps[n] = (FT_CharMap)charmap;
+ }
+
+ root->num_fixed_sizes = 0;
+ root->available_sizes = 0;
+
+ /*****************************************************************/
+ /* */
+ /* Set up metrics. */
+ /* */
+ root->bbox.xMin = face->header.xMin;
+ root->bbox.yMin = face->header.yMin;
+ root->bbox.xMax = face->header.xMax;
+ root->bbox.yMax = face->header.yMax;
+ root->units_per_EM = face->header.Units_Per_EM;
+
+ /* The ascender/descender/height are computed from the OS/2 table */
+ /* when found. Otherwise, they're taken from the horizontal header */
+ if ( face->os2.version != 0xFFFF )
+ {
+ root->ascender = face->os2.sTypoAscender;
+ root->descender = -face->os2.sTypoDescender;
+ root->height = root->ascender + root->descender +
+ face->os2.sTypoLineGap;
+ }
+ else
+ {
+ root->ascender = face->horizontal.Ascender;
+ root->descender = face->horizontal.Descender;
+ root->height = root->ascender + root->descender +
+ face->horizontal.Line_Gap;
+ }
+
+ root->max_advance_width = face->horizontal.advance_Width_Max;
+
+ root->max_advance_height = root->height;
+ if ( face->vertical_info )
+ root->max_advance_height = face->vertical.advance_Height_Max;
+
+ root->underline_position = face->postscript.underlinePosition;
+ root->underline_thickness = face->postscript.underlineThickness;
+
+ /* root->max_points - already set up */
+ /* root->max_contours - already set up */
+
+ }
+ return error;
+ }
+
+
+#undef PAIR_TAG
+#define PAIR_TAG( left, right ) ( ((TT_ULong)left << 16) | (TT_ULong)right )
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Get_Kerning */
+ /* */
+ /* <Description> */
+ /* A driver method used to return the kerning vector between two */
+ /* glyphs of the same face. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the source face object. */
+ /* */
+ /* left_glyph :: The index of the left glyph in the kern pair. */
+ /* */
+ /* right_glyph :: The index of the right glyph in the kern pair. */
+ /* */
+ /* <Output> */
+ /* kerning :: The kerning vector. This is in font units for */
+ /* scalable formats, and in pixels for fixed-sizes */
+ /* formats. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* Only horizontal layouts (left-to-right & right-to-left) are */
+ /* supported by this function. Other layouts, or more sophisticated */
+ /* kernings are out of scope of this method (the basic driver */
+ /* interface is meant to be simple). */
+ /* */
+ /* They can be implemented by format-specific interfaces. */
+ /* */
+ static
+ TT_Error Get_Kerning( TT_Face face,
+ TT_UShort left_glyph,
+ TT_UShort right_glyph,
+ TT_Vector* kerning )
+ {
+ TT_Kern_0_Pair* pair;
+
+
+ if ( !face )
+ return TT_Err_Invalid_Face_Handle;
+
+ kerning->x = 0;
+ kerning->y = 0;
+
+ if ( face->kern_pairs )
+ {
+ /* there are some kerning pairs in this font file! */
+ TT_ULong search_tag = PAIR_TAG( left_glyph, right_glyph );
+ TT_Long left, right;
+
+
+ left = 0;
+ right = face->num_kern_pairs - 1;
+
+ while ( left + 1 < right )
+ {
+ TT_Int middle = (left + right) >> 1;
+ TT_ULong cur_pair;
+
+
+ pair = face->kern_pairs + middle;
+ cur_pair = PAIR_TAG( pair->left, pair->right );
+
+ if ( cur_pair == search_tag )
+ goto Found;
+
+ if ( cur_pair < search_tag )
+ left = middle;
+ else
+ right = middle;
+ }
+
+ pair = face->kern_pairs + left;
+ if ( PAIR_TAG( pair->left, pair->right ) == search_tag )
+ goto Found;
+
+ pair = face->kern_pairs + right;
+ if ( PAIR_TAG( pair->left, pair->right ) == search_tag )
+ goto Found;
+ }
+
+ Exit:
+ return TT_Err_Ok;
+
+ Found:
+ kerning->x = pair->value;
+ goto Exit;
+ }
+
+
+#undef PAIR_TAG
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** S I Z E S ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Set_Char_Sizes */
+ /* */
+ /* <Description> */
+ /* A driver method used to reset a size's character sizes (horizontal */
+ /* and vertical) expressed in fractional points. */
+ /* */
+ /* <Input> */
+ /* char_width :: The character width expressed in 26.6 fractional */
+ /* points. */
+ /* char_height :: The character height expressed in 26.6 fractional */
+ /* points. */
+ /* */
+ /* <InOut> */
+ /* size :: A handle to the target size object. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ static
+ TT_Error Set_Char_Sizes( TT_Size size,
+ TT_F26Dot6 char_width,
+ TT_F26Dot6 char_height,
+ TT_UInt horz_resolution,
+ TT_UInt vert_resolution )
+ {
+ FT_Size_Metrics* metrics = &size->root.metrics;
+ TT_Face face = (TT_Face)size->root.face;
+ TT_Long dim_x, dim_y;
+
+
+ if ( char_width < 1*64 ) char_width = 1*64;
+ if ( char_height < 1*64 ) char_height = 1*64;
+
+ /* Compute pixel sizes in 26.6 units */
+ dim_x = (char_width * horz_resolution) / 72;
+ dim_y = (char_height * vert_resolution) / 72;
+
+ /* Truncate to integer pixels if required by font - nearly all */
+ /* TrueType fonts have this bit set, as hinting can really work */
+ /* with integer pixel sizes. */
+ if ( face->header.Flags & 8 )
+ {
+ dim_x = (dim_x + 32) & -64;
+ dim_y = (dim_y + 32) & -64;
+ }
+
+ metrics->x_scale = FT_MulDiv( dim_x,
+ 0x10000L,
+ face->root.units_per_EM );
+
+ metrics->y_scale = FT_MulDiv( dim_y,
+ 0x10000L,
+ face->root.units_per_EM );
+
+ metrics->x_ppem = (TT_UShort)(dim_x >> 6);
+ metrics->y_ppem = (TT_UShort)(dim_y >> 6);
+
+ size->ttmetrics.valid = FALSE;
+
+ return TT_Reset_Size( size );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Set_Pixel_Sizes */
+ /* */
+ /* <Description> */
+ /* A driver method used to reset a size's character sizes (horizontal */
+ /* and vertical) expressed in integer pixels. */
+ /* */
+ /* <Input> */
+ /* pixel_width :: The character width expressed in integer pixels. */
+ /* */
+ /* pixel_height :: The character height expressed in integer pixels. */
+ /* */
+ /* <InOut> */
+ /* size :: A handle to the target size object. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success */
+ /* */
+ static
+ TT_Error Set_Pixel_Sizes( TT_Size size,
+ TT_UInt pixel_width,
+ TT_UInt pixel_height )
+ {
+ FT_Size_Metrics* metrics = &size->root.metrics;
+ TT_Face face = (TT_Face)size->root.face;
+
+
+ if ( pixel_width < 1 ) pixel_width = 1;
+ if ( pixel_height < 1 ) pixel_height = 1;
+
+ metrics->x_ppem = pixel_width;
+ metrics->y_ppem = pixel_height;
+
+ metrics->x_scale = FT_MulDiv( metrics->x_ppem << 6,
+ 0x10000L,
+ face->root.units_per_EM );
+
+ metrics->y_scale = FT_MulDiv( metrics->y_ppem << 6,
+ 0x10000L,
+ face->root.units_per_EM );
+
+ size->ttmetrics.valid = FALSE;
+
+ return TT_Reset_Size( size );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Load_Glyph */
+ /* */
+ /* <Description> */
+ /* A driver method used to load a glyph within a given glyph slot. */
+ /* */
+ /* <Input> */
+ /* slot :: A handle to the target slot object where the glyph */
+ /* will be loaded. */
+ /* */
+ /* size :: A handle to the source face size at which the glyph */
+ /* must be scaled/loaded/etc. */
+ /* */
+ /* glyph_index :: The index of the glyph in the font file. */
+ /* */
+ /* load_flags :: A flag indicating what to load for this glyph. The */
+ /* FTLOAD_??? constants can be used to control the */
+ /* glyph loading process (e.g., whether the outline */
+ /* should be scaled, whether to load bitmaps or not, */
+ /* whether to hint the outline, etc). */
+ /* <Output> */
+ /* result :: A set of bit flags indicating the type of data that */
+ /* was loaded in the glyph slot (outline, bitmap, */
+ /* pixmap, etc). */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ static
+ TT_Error Load_Glyph( TT_GlyphSlot slot,
+ TT_Size size,
+ TT_UShort glyph_index,
+ TT_UInt load_flags )
+ {
+ TT_Error error;
+
+
+ if ( !slot )
+ return TT_Err_Invalid_Glyph_Handle;
+
+ /* check that we want a scaled outline or bitmap */
+ if ( !size )
+ load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
+
+ if ( load_flags & FT_LOAD_NO_SCALE )
+ size = NULL;
+
+ /* reset the size object if necessary */
+ if ( size )
+ {
+ /* these two object must have the same parent */
+ if ( size->root.face != slot->face )
+ return TT_Err_Invalid_Face_Handle;
+
+ if ( !size->ttmetrics.valid )
+ {
+ if ( FT_SET_ERROR( TT_Reset_Size( size ) ) )
+ return error;
+ }
+ }
+
+ /* now load the glyph outline if necessary */
+ error = TT_Load_Glyph( size, slot, glyph_index, load_flags );
+
+ /* force drop-out mode to 2 */
+ slot->outline.dropout_mode = 2;
+
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** ****/
+ /**** C H A R A C T E R M A P P I N G S ****/
+ /**** ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Get_Char_Index */
+ /* */
+ /* <Description> */
+ /* Uses a charmap to return a given character code's glyph index. */
+ /* */
+ /* <Input> */
+ /* charmap :: A handle to the source charmap object. */
+ /* charcode :: The character code. */
+ /* */
+ /* <Return> */
+ /* Glyph index. 0 means `undefined character code'. */
+ /* */
+ static
+ FT_UInt Get_Char_Index( TT_CharMap charmap,
+ TT_Long charcode )
+ {
+ TT_Error error;
+ TT_Face face;
+ TT_CMapTable* cmap;
+
+ cmap = &charmap->cmap;
+ face = (TT_Face)charmap->root.face;
+
+ /* Load table if needed */
+ if ( !cmap->loaded )
+ {
+ SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt;
+
+ error = sfnt->load_charmap( face, cmap, face->root.stream );
+ if (error)
+ return error;
+
+ cmap->loaded = TRUE;
+ }
+
+ if ( cmap->get_index )
+ return cmap->get_index( cmap, charcode );
+ else
+ return 0;
+ }
+
+
+ /* The FT_DriverInterface structure is defined in ftdriver.h. */
+
+ const FT_DriverInterface tt_driver_interface =
+ {
+ sizeof ( TT_DriverRec ),
+ sizeof ( TT_FaceRec ),
+ sizeof ( TT_SizeRec ),
+ sizeof ( FT_GlyphSlotRec ),
+
+ "truetype", /* driver name */
+ 1, /* driver version */
+ 2, /* driver requires FreeType 2 or above */
+
+ (void*)0,
+
+ (FTDriver_initDriver) TT_Init_Driver,
+ (FTDriver_doneDriver) TT_Done_Driver,
+ (FTDriver_getInterface) Get_Interface,
+
+ (FTDriver_initFace) Init_Face,
+ (FTDriver_doneFace) TT_Done_Face,
+ (FTDriver_getKerning) Get_Kerning,
+
+ (FTDriver_initSize) TT_Init_Size,
+ (FTDriver_doneSize) TT_Done_Size,
+ (FTDriver_setCharSizes) Set_Char_Sizes,
+ (FTDriver_setPixelSizes) Set_Pixel_Sizes,
+
+ (FTDriver_initGlyphSlot) TT_Init_GlyphSlot,
+ (FTDriver_doneGlyphSlot) TT_Done_GlyphSlot,
+ (FTDriver_loadGlyph) Load_Glyph,
+
+ (FTDriver_getCharIndex) Get_Char_Index,
+ };
+
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* getDriverInterface */
+ /* */
+ /* <Description> */
+ /* This function is used when compiling the TrueType driver as a */
+ /* shared library (`.DLL' or `.so'). It will be used by the */
+ /* high-level library of FreeType to retrieve the address of the */
+ /* driver's generic interface. */
+ /* */
+ /* It shouldn't be implemented in a static build, as each driver must */
+ /* have the same function as an exported entry point. */
+ /* */
+ /* <Return> */
+ /* The address of the TrueType's driver generic interface. The */
+ /* format-specific interface can then be retrieved through the method */
+ /* interface->get_format_interface. */
+ /* */
+#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS
+
+ EXPORT_FUNC
+ FT_DriverInterface* getDriverInterface( void )
+ {
+ return &truetype_driver_interface;
+ }
+
+#endif /* CONFIG_OPTION_DYNAMIC_DRIVERS */
+
+
+/* END */
--- /dev/null
+++ b/src/truetype/ttdriver.h
@@ -1,0 +1,193 @@
+/***************************************************************************/
+/* */
+/* ttdriver.h */
+/* */
+/* High-level TrueType driver 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. */
+/* */
+/***************************************************************************/
+
+
+#ifndef TTDRIVER_H
+#define TTDRIVER_H
+
+#include <freetype.h>
+#include <ftdriver.h>
+#include <ttobjs.h>
+#include <tterrors.h>
+#include <ttnameid.h>
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* TTDriver_getFontData */
+ /* */
+ /* <Description> */
+ /* Returns either a single font table or the whole font file into */
+ /* caller's memory. This function mimics the GetFontData() API */
+ /* function found in Windows. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the source TrueType face object. */
+ /* */
+ /* tag :: A 32-bit integer used to name the table you want to */
+ /* read. Use the macro MAKE_TT_TAG (defined in freetype.h) */
+ /* to create one. Use the value 0 if you want to access */
+ /* the whole file instead. */
+ /* */
+ /* offset :: The offset from the start of the table or file from */
+ /* which you want to read bytes. */
+ /* */
+ /* buffer :: The address of the target/read buffer where data will be */
+ /* copied. */
+ /* */
+ /* <InOut> */
+ /* length :: The length in bytes of the data to read. If it is set */
+ /* to 0 when this function is called, it will return */
+ /* immediately, setting the value of `length' to the */
+ /* requested table's size (or the whole font file if the */
+ /* tag is 0). It is thus possible to allocate and read an */
+ /* arbitrary table in two successive calls. */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ typedef TT_Error (*TTDriver_getFontData)( TT_Face face,
+ TT_ULong tag,
+ TT_ULong offset,
+ void* buffer,
+ TT_Long* length );
+
+
+ /*************************************************************************/
+ /* */
+ /* <FuncType> */
+ /* TTDriver_getFaceWidths */
+ /* */
+ /* <Description> */
+ /* Returns the widths and/or heights of a given range of glyph from */
+ /* a face. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the source FreeType face object. */
+ /* */
+ /* first_glyph :: The first glyph in the range. */
+ /* */
+ /* last_glyph :: The last glyph in the range. */
+ /* */
+ /* <Output> */
+ /* widths :: The address of the table receiving the widths */
+ /* expressed in font units (UShorts). Set this */
+ /* parameter to NULL if you're not interested in these */
+ /* values. */
+ /* */
+ /* heights :: The address of the table receiving the heights */
+ /* expressed in font units (UShorts). Set this */
+ /* parameter to NULL if you're not interested in these */
+ /* values. */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ typedef TT_Error (*TTDriver_getFaceWidths)( TT_Face face,
+ TT_UShort first_glyph,
+ TT_UShort last_glyph,
+ TT_UShort* widths,
+ TT_UShort* heights );
+
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_DriverInterface */
+ /* */
+ /* <Description> */
+ /* The TrueType-specific interface of this driver. Note that some of */
+ /* the methods defined here are optional, as they're only used for */
+ /* for specific tasks of the driver. */
+ /* */
+ /* <Fields> */
+ /* get_font_data :: See the declaration of TTDriver_getFontData(). */
+ /* get_face_widths :: See the declaration of */
+ /* TTDriver_getFaceWidths(). */
+ /* */
+ typedef struct TT_DriverInterface_
+ {
+ TTDriver_getFontData get_font_data;
+ TTDriver_getFaceWidths get_face_widths;
+
+ } TT_DriverInterface;
+
+
+ EXPORT_DEF
+ const FT_DriverInterface tt_driver_interface;
+
+
+ EXPORT_DEF
+ const TT_DriverInterface tt_format_interface;
+
+
+
+/*************************************************************************
+ *
+ * Here is a template of the code that should appear in each
+ * font driver's _interface_ file (the one included by "ftinit.c").
+ *
+ * It is used to build, at compile time, a simple linked list of
+ * the interfaces of the drivers which have been #included in
+ * "ftinit.c". See the source code of the latter file for details
+ *
+ * (Note that this is only required when you want your driver included
+ * in the set of default drivers loaded by FT_Init_FreeType. Other
+ * drivers can still be added manually at runtime with FT_Add_Driver.
+ *
+ * {
+ * #ifdef FTINIT_DRIVER_CHAIN
+ *
+ * static
+ * const FT_DriverChain ftinit_<FORMAT>_driver_chain =
+ * {
+ * FT_INIT_LAST_DRIVER_CHAIN,
+ * &<FORMAT>_driver_interface
+ * };
+ *
+ * #undef FT_INIT_LAST_DRIVER_CHAIN
+ * #define FT_INIT_LAST_DRIVER_CHAIN &ftinit_<FORMAT>_driver_chain
+ *
+ * #endif
+ * }
+ *
+ * replace <FORMAT> with your driver's prefix
+ *
+ *************************************************************************/
+
+
+#ifdef FTINIT_DRIVER_CHAIN
+
+ static
+ const FT_DriverChain ftinit_tt_driver_chain =
+ {
+ FT_INIT_LAST_DRIVER_CHAIN,
+ &tt_driver_interface
+ };
+
+#undef FT_INIT_LAST_DRIVER_CHAIN
+#define FT_INIT_LAST_DRIVER_CHAIN &ftinit_tt_driver_chain
+
+#endif /* FTINIT_DRIVER_CHAIN */
+
+
+
+#endif /* TTDRIVER_H */
+
+
+/* END */
--- /dev/null
+++ b/src/truetype/tterrors.h
@@ -1,0 +1,124 @@
+/***************************************************************************/
+/* */
+/* tterrors.h */
+/* */
+/* TrueType error ID definitions (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 TTERRORS_H
+#define TTERRORS_H
+
+
+ /*************************************************************************/
+ /* */
+ /* Error codes declaration */
+ /* */
+ /* The error codes are grouped in `classes' used to indicate the `level' */
+ /* at which the error happened. The class is given by an error code's */
+ /* high byte. */
+ /* */
+ /*************************************************************************/
+
+
+ /* Success is always 0. */
+
+#define TT_Err_Ok FT_Err_Ok
+
+ /* High level API errors. */
+
+#define TT_Err_Invalid_File_Format FT_Err_Invalid_File_Format
+#define TT_Err_Invalid_Argument FT_Err_Invalid_Argument
+#define TT_Err_Invalid_Driver_Handle FT_Err_Invalid_Driver_Handle
+#define TT_Err_Invalid_Face_Handle FT_Err_Invalid_Face_Handle
+#define TT_Err_Invalid_Instance_Handle FT_Err_Invalid_Size_Handle
+#define TT_Err_Invalid_Glyph_Handle FT_Err_Invalid_Slot_Handle
+#define TT_Err_Invalid_CharMap_Handle FT_Err_Invalid_CharMap_Handle
+#define TT_Err_Invalid_Glyph_Index FT_Err_Invalid_Glyph_Index
+
+#define TT_Err_Unimplemented_Feature FT_Err_Unimplemented_Feature
+#define TT_Err_Unavailable_Outline FT_Err_Unavailable_Outline
+#define TT_Err_Unavailable_Bitmap FT_Err_Unavailable_Bitmap
+#define TT_Err_Unavailable_Pixmap FT_Err_Unavailable_Pixmap
+#define TT_Err_File_Is_Not_Collection FT_Err_File_Is_Not_Collection
+
+#define TT_Err_Invalid_Engine FT_Err_Invalid_Driver_Handle
+
+ /* Internal errors. */
+
+#define TT_Err_Out_Of_Memory FT_Err_Out_Of_Memory
+#define TT_Err_Unlisted_Object FT_Err_Unlisted_Object
+
+ /* General glyph outline errors. */
+
+#define TT_Err_Too_Many_Points FT_Err_Too_Many_Points
+#define TT_Err_Too_Many_Contours FT_Err_Too_Many_Contours
+#define TT_Err_Too_Many_Ins FT_Err_Too_Many_Hints
+#define TT_Err_Invalid_Composite FT_Err_Invalid_Composite
+
+ /* Bytecode interpreter error codes. */
+
+ /* These error codes are produced by the TrueType */
+ /* bytecode interpreter. They usually indicate a */
+ /* broken font file, a broken glyph within a font */
+ /* file, or a bug in the interpreter! */
+
+#define TT_Err_Invalid_Opcode 0x400
+#define TT_Err_Too_Few_Arguments 0x401
+#define TT_Err_Stack_Overflow 0x402
+#define TT_Err_Code_Overflow 0x403
+#define TT_Err_Bad_Argument 0x404
+#define TT_Err_Divide_By_Zero 0x405
+#define TT_Err_Storage_Overflow 0x406
+#define TT_Err_Cvt_Overflow 0x407
+#define TT_Err_Invalid_Reference 0x408
+#define TT_Err_Invalid_Distance 0x409
+#define TT_Err_Interpolate_Twilight 0x40A
+#define TT_Err_Debug_OpCode 0x40B
+#define TT_Err_ENDF_In_Exec_Stream 0x40C
+#define TT_Err_Out_Of_CodeRanges 0x40D
+#define TT_Err_Nested_DEFS 0x40E
+#define TT_Err_Invalid_CodeRange 0x40F
+#define TT_Err_Invalid_Displacement 0x410
+#define TT_Err_Execution_Too_Long 0x411
+
+ /* Other TrueType specific error codes. */
+
+#define TT_Err_Table_Missing 0x420
+#define TT_Err_Too_Many_Extensions 0x421
+#define TT_Err_Extensions_Unsupported 0x422
+#define TT_Err_Invalid_Extension_Id 0x423
+
+#define TT_Err_No_Vertical_Data 0x424
+
+#define TT_Err_Max_Profile_Missing 0x430
+#define TT_Err_Header_Table_Missing 0x431
+#define TT_Err_Horiz_Header_Missing 0x432
+#define TT_Err_Locations_Missing 0x433
+#define TT_Err_Name_Table_Missing 0x434
+#define TT_Err_CMap_Table_Missing 0x435
+#define TT_Err_Hmtx_Table_Missing 0x436
+#define TT_Err_OS2_Table_Missing 0x437
+#define TT_Err_Post_Table_Missing 0x438
+
+#define TT_Err_Invalid_Horiz_Metrics 0x440
+#define TT_Err_Invalid_CharMap_Format 0x441
+#define TT_Err_Invalid_PPem 0x442
+#define TT_Err_Invalid_Vert_Metrics 0x443
+
+#define TT_Err_Could_Not_Find_Context 0x450
+
+#endif /* FTERRID_H */
+
+
+/* END */
--- /dev/null
+++ b/src/truetype/ttgload.c
@@ -1,0 +1,1492 @@
+/***************************************************************************/
+/* */
+/* ttgload.c */
+/* */
+/* TrueType Glyph Loader (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 <freetype.h>
+#include <ftdebug.h>
+#include <ftcalc.h>
+#include <ftstream.h>
+
+#include <sfnt.h>
+#include <ttgload.h>
+
+#include <tttags.h>
+#include <ttinterp.h>
+
+
+ /* required for the tracing mode */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_ttgload
+
+
+ /*************************************************************************/
+ /* */
+ /* Composite font flags. */
+ /* */
+#define ARGS_ARE_WORDS 0x001
+#define ARGS_ARE_XY_VALUES 0x002
+#define ROUND_XY_TO_GRID 0x004
+#define WE_HAVE_A_SCALE 0x008
+/* reserved 0x010 */
+#define MORE_COMPONENTS 0x020
+#define WE_HAVE_AN_XY_SCALE 0x040
+#define WE_HAVE_A_2X2 0x080
+#define WE_HAVE_INSTR 0x100
+#define USE_MY_METRICS 0x200
+
+
+#undef SCALE_X
+#define SCALE_X( distance ) FT_MulFix( distance, exec->metrics.x_scale )
+
+#undef SCALE_Y
+#define SCALE_Y( distance ) FT_MulFix( distance, exec->metrics.y_scale )
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Get_Metrics */
+ /* */
+ /* <Description> */
+ /* Returns the horizontal or vertical metrics in font units for a */
+ /* given glyph. The metrics are the left side bearing (resp. top */
+ /* side bearing) and advance width (resp. advance height). */
+ /* */
+ /* <Input> */
+ /* header :: A pointer to either the horizontal or vertical metrics */
+ /* structure. */
+ /* */
+ /* index :: The glyph index. */
+ /* */
+ /* <Output> */
+ /* bearing :: The bearing, either left side or top side. */
+ /* */
+ /* advance :: The advance width resp. advance height. */
+ /* */
+ /* <Note> */
+ /* This function will much probably move to another component in the */
+ /* near future, but I haven't decided which yet. */
+ /* */
+ LOCAL_FUNC
+ void TT_Get_Metrics( TT_HoriHeader* header,
+ TT_UShort index,
+ TT_Short* bearing,
+ TT_UShort* advance )
+ {
+ TT_LongMetrics* longs_m;
+ TT_UShort k = header->number_Of_HMetrics;
+
+
+ if ( index < k )
+ {
+ longs_m = (TT_LongMetrics*)header->long_metrics + index;
+ *bearing = longs_m->bearing;
+ *advance = longs_m->advance;
+ }
+ else
+ {
+ *bearing = ((TT_ShortMetrics*)header->short_metrics)[index - k];
+ *advance = ((TT_LongMetrics*)header->long_metrics)[k - 1].advance;
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Get_HMetrics */
+ /* */
+ /* <Description> */
+ /* Returns the horizontal metrics in font units for a given glyph. */
+ /* If `check' is true, take care of monospaced fonts by returning the */
+ /* advance width maximum. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target source face. */
+ /* */
+ /* index :: The glyph index. */
+ /* */
+ /* check :: If set, handle monospaced fonts. */
+ /* */
+ /* <Output> */
+ /* lsb :: The left side bearing. */
+ /* */
+ /* aw :: The advance width. */
+ /* */
+ static
+ void Get_HMetrics( TT_Face face,
+ TT_UShort index,
+ TT_Bool check,
+ TT_Short* lsb,
+ TT_UShort* aw )
+ {
+ TT_Get_Metrics( &face->horizontal, index, lsb, aw );
+
+ if ( check && face->postscript.isFixedPitch )
+ *aw = face->horizontal.advance_Width_Max;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Get_Advance_Widths */
+ /* */
+ /* <Description> */
+ /* Returns the advance width table for a given pixel size if it is */
+ /* found in the font's `hdmx' table (if any). */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target source face. */
+ /* */
+ /* ppem :: The pixel size. */
+ /* */
+ /* <Return> */
+ /* A pointer to the advance with table. NULL if it doesn't exist. */
+ /* */
+ static
+ TT_Byte* Get_Advance_Widths( TT_Face face,
+ TT_UShort ppem )
+ {
+ TT_UShort n;
+
+
+ for ( n = 0; n < face->hdmx.num_records; n++ )
+ if ( face->hdmx.records[n].ppem == ppem )
+ return face->hdmx.records[n].widths;
+
+ return NULL;
+ }
+
+
+#define cur_to_org( n, zone ) \
+ MEM_Copy( (zone)->org, (zone)->cur, n * sizeof ( TT_Vector ) )
+
+#define org_to_cur( n, zone ) \
+ MEM_Copy( (zone)->cur, (zone)->org, n * sizeof ( TT_Vector ) )
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* translate_array */
+ /* */
+ /* <Description> */
+ /* Translates an array of coordinates. */
+ /* */
+ /* <Input> */
+ /* n :: The number of points to translate. */
+ /* */
+ /* delta_x :: The horizontal coordinate of the shift vector. */
+ /* */
+ /* delta_y :: The vertical coordinate of the shift vector. */
+ /* */
+ /* <InOut> */
+ /* coords :: The vector array to translate. */
+ /* */
+ static
+ void translate_array( TT_UShort n,
+ TT_Vector* coords,
+ TT_Pos delta_x,
+ TT_Pos delta_y )
+ {
+ TT_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;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* mount_zone */
+ /* */
+ /* <Description> */
+ /* Mounts one glyph zone on top of another. This is needed to */
+ /* assemble composite glyphs. */
+ /* */
+ /* <Input> */
+ /* source :: The source glyph zone. */
+ /* */
+ /* <Output> */
+ /* target :: The target glyph zone. */
+ /* */
+ static
+ void mount_zone( TT_GlyphZone* source,
+ TT_GlyphZone* target )
+ {
+ TT_UShort np;
+ TT_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 */
+ /* */
+ /* <Description> */
+ /* Loads a simple (i.e, non-composite) glyph. This function is used */
+ /* for the `Load_Simple' state of TT_Load_Glyph(). All composite */
+ /* glyphs elements will be loaded with routine. */
+ /* */
+ static
+ TT_Error Load_Simple_Glyph( TT_ExecContext exec,
+ FT_Stream stream,
+ TT_ULong byte_count,
+ TT_Short n_contours,
+ TT_Short left_contours,
+ TT_UShort left_points,
+ TT_UInt load_flags,
+ TT_SubGlyphRec* subg,
+ TT_Bool debug )
+ {
+ TT_Error error;
+ TT_GlyphZone* pts;
+ TT_Short k;
+ TT_UShort j;
+ TT_UShort n_points, n_ins;
+ TT_Face face;
+ TT_Byte* flag;
+ TT_Vector* vec;
+ TT_F26Dot6 x, y;
+
+ TT_Vector *pp1, *pp2;
+
+
+ face = exec->face;
+
+ /*********************************************************************/
+ /* simple check */
+
+ if ( n_contours > left_contours )
+ {
+ FT_TRACE0(( "ERROR: Glyph index %ld has %d contours > left %d\n",
+ subglyph.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( byte_count ) )
+ return error;
+
+ for ( k = 0; k < n_contours; k++ )
+ exec->pts.contours[k] = GET_UShort();
+
+ n_points = 0;
+ if ( n_contours > 0 )
+ n_points = exec->pts.contours[n_contours - 1] + 1;
+
+
+ /*********************************************************************/
+ /* reading the bytecode instructions */
+
+ n_ins = GET_UShort();
+
+ if ( n_points > left_points )
+ {
+ FT_TRACE0(( "ERROR: Too many points in glyph %ld\n", subg->index ));
+ error = TT_Err_Too_Many_Points;
+ goto Fail;
+ }
+
+ FT_TRACE4(( "Instructions size : %d\n", n_ins ));
+
+ if ( n_ins > face->max_profile.maxSizeOfInstructions )
+ {
+ FT_TRACE0(( "ERROR: Too many instructions!\n" ));
+ error = TT_Err_Too_Many_Ins;
+ goto Fail;
+ }
+
+ if (stream->cursor + n_ins > stream->limit)
+ {
+ FT_TRACE0(( "ERROR: Instruction count mismatch!\n" ));
+ error = TT_Err_Too_Many_Ins;
+ goto Fail;
+ }
+ MEM_Copy( exec->glyphIns, stream->cursor, n_ins );
+ stream->cursor += n_ins;
+
+ error = TT_Set_CodeRange( exec, tt_coderange_glyph,
+ exec->glyphIns, n_ins );
+ if (error) goto Fail;
+
+
+ /*********************************************************************/
+ /* reading the point flags */
+
+ j = 0;
+ flag = exec->pts.touch;
+
+ while ( j < n_points )
+ {
+ TT_Byte c, cnt;
+
+ flag[j] = c = GET_Byte();
+ j++;
+
+ if ( c & 8 )
+ {
+ cnt = GET_Byte();
+
+ while( cnt > 0 )
+ {
+ flag[j++] = c;
+ cnt--;
+ }
+ }
+ }
+
+ /*********************************************************************/
+ /* reading the X coordinates */
+
+ 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;
+ }
+
+
+ /*********************************************************************/
+ /* reading the YX coordinates */
+
+ 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();
+
+ /*********************************************************************/
+ /* Add shadow points */
+
+ /* Now add the two shadow points at n and n + 1. */
+ /* We need the left side bearing and advance width. */
+
+ /* pp1 = xMin - lsb */
+ pp1 = vec + n_points;
+ pp1->x = subg->bbox.xMin - subg->left_bearing;
+ pp1->y = 0;
+
+ /* pp2 = pp1 + aw */
+ pp2 = pp1 + 1;
+ pp2->x = pp1->x + subg->advance;
+ pp2->y = 0;
+
+ /* clear the touch flags */
+ for ( j = 0; j < n_points; j++ )
+ exec->pts.touch[j] &= FT_Curve_Tag_On;
+
+ 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 & FT_LOAD_NO_SCALE)
+ {
+ /* 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( pts->org[j].x );
+ pts->org[j].y = SCALE_Y( 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 & FT_LOAD_PEDANTIC;
+
+ error = TT_Run_Context( exec, debug );
+ 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;
+
+ Fail:
+ FORGET_Frame();
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Load_Composite_End */
+ /* */
+ /* <Description> */
+ /* Finalizes the loading process of a composite glyph element. This */
+ /* function is used for the `Load_End' state of TT_Load_Glyph(). */
+ /* */
+ static
+ TT_Error Load_Composite_End( TT_UShort n_points,
+ TT_Short n_contours,
+ TT_ExecContext exec,
+ TT_SubGlyphRec* subg,
+ FT_Stream stream,
+ TT_UInt load_flags,
+ TT_Bool debug )
+ {
+ TT_Error error;
+
+ TT_UShort k, n_ins;
+ TT_GlyphZone* pts;
+
+ if ( subg->is_hinted &&
+ subg->element_flag & WE_HAVE_INSTR )
+ {
+ if ( READ_UShort( n_ins ) ) /* read size of instructions */
+ return error;
+
+ FT_TRACE4(( "Instructions size = %d\n", n_ins ));
+
+ if ( n_ins > exec->face->max_profile.maxSizeOfInstructions )
+ {
+ FT_TRACE0(( "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 = TT_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] &= FT_Curve_Tag_On;
+
+ 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 & FT_LOAD_PEDANTIC;
+
+ error = TT_Run_Context( exec, debug );
+ 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 */
+ /* */
+ /* <Description> */
+ /* Initializes a glyph component for further processing. */
+ /* */
+ static
+ void Init_Glyph_Component( TT_SubGlyphRec* element,
+ TT_SubGlyphRec* original,
+ TT_ExecContext 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 = 1 << 16;
+ element->transform.xy = 0;
+ element->transform.yx = 0;
+ element->transform.yy = 1 << 16;
+
+ element->transform.ox = 0;
+ element->transform.oy = 0;
+
+ element->left_bearing = 0;
+ element->advance = 0;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Glyph */
+ /* */
+ /* <Description> */
+ /* A function used to load a single glyph within a given glyph slot, */
+ /* for a given size. */
+ /* */
+ /* <Input> */
+ /* glyph :: A handle to a target slot object where the glyph */
+ /* will be loaded. */
+ /* */
+ /* size :: A handle to the source face size at which the glyph */
+ /* must be scaled/loaded. */
+ /* */
+ /* glyph_index :: The index of the glyph in the font file. */
+ /* */
+ /* load_flags :: A flag indicating what to load for this glyph. The */
+ /* FT_LOAD_XXX constants can be used to control the */
+ /* glyph loading process (e.g., whether the outline */
+ /* should be scaled, whether to load bitmaps or not, */
+ /* whether to hint the outline, etc). */
+ /* <Output> */
+ /* result :: A set of bit flags indicating the type of data that */
+ /* was loaded in the glyph slot (outline or bitmap, */
+ /* etc). */
+ /* */
+ /* You can set this field to 0 if you don't want this */
+ /* information. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_Glyph( TT_Size size,
+ TT_GlyphSlot glyph,
+ TT_UShort glyph_index,
+ TT_UInt load_flags )
+ {
+ typedef enum TPhases_
+ {
+ Load_Exit,
+ Load_Glyph,
+ Load_Header,
+ Load_Simple,
+ Load_Composite,
+ Load_End
+
+ } TPhases;
+
+ TT_Error error = 0;
+ FT_Stream stream;
+
+ TT_Face face;
+
+ TT_UShort num_points;
+ TT_Short num_contours;
+ TT_UShort left_points;
+ TT_Short left_contours;
+
+ TT_ULong load_top;
+ TT_Long k, l;
+ TT_Int new_flags;
+ TT_UShort index;
+ TT_UShort u;
+ TT_Long count;
+
+ TT_Long glyph_offset, offset;
+
+ TT_F26Dot6 x, y, nx, ny;
+
+ TT_Fixed xx, xy, yx, yy;
+ TT_BBox bbox;
+
+ TT_ExecContext exec;
+
+ TT_SubGlyphRec *subglyph, *subglyph2;
+
+ TT_GlyphZone base_pts;
+
+ TPhases phase;
+ TT_Byte* widths;
+
+ SFNT_Interface* sfnt;
+
+ /* first of all, check arguments */
+ if ( !glyph )
+ return TT_Err_Invalid_Glyph_Handle;
+
+ face = (TT_Face)glyph->face;
+ if ( !face )
+ return TT_Err_Invalid_Glyph_Handle;
+
+ sfnt = (SFNT_Interface*)face->sfnt;
+ stream = face->root.stream;
+ count = 0;
+
+ if ( glyph_index >= face->root.num_glyphs )
+ return TT_Err_Invalid_Glyph_Index;
+
+ if ( !size || (load_flags & FT_LOAD_NO_SCALE) )
+ {
+ size = NULL;
+ load_flags |= FT_LOAD_NO_SCALE |
+ FT_LOAD_NO_HINTING |
+ FT_LOAD_NO_BITMAP;
+ }
+
+ /* Try to load embedded bitmap if any */
+ if ( size && (load_flags & FT_LOAD_NO_BITMAP) == 0 && sfnt->load_sbits )
+ {
+ TT_SBit_Metrics metrics;
+
+ error = sfnt->load_sbit_image( face,
+ size->root.metrics.x_ppem,
+ size->root.metrics.y_ppem,
+ glyph_index,
+ stream,
+ &glyph->bitmap,
+ &metrics );
+ if ( !error )
+ {
+ glyph->outline.n_points = 0;
+ glyph->outline.n_contours = 0;
+
+ glyph->metrics.width = (TT_Pos)metrics.width << 6;
+ glyph->metrics.height = (TT_Pos)metrics.height << 6;
+
+ glyph->metrics.horiBearingX = (TT_Pos)metrics.horiBearingX << 6;
+ glyph->metrics.horiBearingY = (TT_Pos)metrics.horiBearingY << 6;
+ glyph->metrics.horiAdvance = (TT_Pos)metrics.horiAdvance << 6;
+
+ glyph->metrics.vertBearingX = (TT_Pos)metrics.vertBearingX << 6;
+ glyph->metrics.vertBearingY = (TT_Pos)metrics.vertBearingY << 6;
+ glyph->metrics.vertAdvance = (TT_Pos)metrics.vertAdvance << 6;
+
+ glyph->format = ft_glyph_format_bitmap;
+ return error;
+ }
+ }
+
+ if ( load_flags & FT_LOAD_NO_OUTLINE )
+ return ( error ? error : TT_Err_Unavailable_Bitmap );
+
+ error = face->goto_table( face, TTAG_glyf, stream, 0 );
+ if (error)
+ {
+ FT_ERROR(( "TT.GLoad: could not access glyph table\n" ));
+ return error;
+ }
+
+ glyph_offset = FILE_Pos();
+
+ /* query new execution context */
+
+ if ( size && size->debug )
+ exec = size->context;
+ else
+ exec = TT_New_Context( face );
+
+ if ( !exec )
+ return TT_Err_Could_Not_Find_Context;
+
+ TT_Load_Context( exec, face, size );
+
+ if ( size )
+ {
+ /* load default graphics state - if needed */
+ if ( size->GS.instruct_control & 2 )
+ exec->GS = tt_default_graphics_state;
+
+ glyph->outline.high_precision = ( size->root.metrics.y_ppem < 24 );
+ }
+
+ /* save its critical pointers, as they'll be modified during load */
+ base_pts = exec->pts;
+
+ /* init variables */
+ left_points = face->root.max_points; /* remove phantom points */
+ left_contours = face->root.max_contours;
+
+ 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 & FT_LOAD_NO_HINTING);
+
+ /* when the cvt program has disabled hinting, the argument */
+ /* is ignored. */
+ if ( size && (size->GS.instruct_control & 1) )
+ subglyph->is_hinted = FALSE;
+
+ /* 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 data, checking whether the */
+ /* glyph is cached already (not implemented yet) */
+ /* */
+ /* exit states: Load_Header and Load_End */
+ /* */
+ case Load_Glyph:
+ /* check glyph index and table */
+
+ index = (TT_UInt)subglyph->index;
+ if ( index >= face->root.num_glyphs )
+ {
+ error = TT_Err_Invalid_Glyph_Index;
+ goto Fail;
+ }
+
+ /* get horizontal metrics */
+ {
+ TT_Short left_bearing;
+ TT_UShort advance_width;
+
+
+ Get_HMetrics( face, index, TRUE,
+ &left_bearing,
+ &advance_width );
+
+ subglyph->left_bearing = left_bearing;
+ subglyph->advance = advance_width;
+ }
+
+ phase = Load_Header;
+ break;
+
+ /************************************************************/
+ /* */
+ /* Load_Header state */
+ /* */
+ /* reading a glyph's generic header to determine whether */
+ /* it is a simple or composite glyph */
+ /* */
+ /* exit states: Load_Simple and Load_Composite */
+ /* */
+ case Load_Header:
+ /* load glyph */
+
+ offset = face->glyph_locations[index];
+ count = 0;
+ if (index < face->num_locations-1)
+ count = face->glyph_locations[index+1] - offset;
+
+ if ( index < ( face->num_locations - 1 ) && count == 0 )
+ {
+ /* as described by Frederic Loyer, these are spaces, and */
+ /* not the unknown glyph. */
+
+ num_contours = 0;
+ num_points = 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->advance;
+
+ if ( !(load_flags & FT_LOAD_NO_SCALE) )
+ subglyph->pp2.x = SCALE_X( subglyph->pp2.x );
+
+ exec->glyphSize = 0;
+ phase = Load_End;
+ break;
+ }
+
+ offset = glyph_offset + offset;
+
+ /* read first glyph header */
+ if ( FILE_Seek( offset ) ||
+ ACCESS_Frame( 10L ) )
+ 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();
+
+ FORGET_Frame();
+
+ FT_TRACE6(( "Glyph %ld\n", index ));
+ FT_TRACE6(( " # of contours : %d\n", num_contours ));
+ FT_TRACE6(( " xMin: %4d xMax: %4d\n",
+ subglyph->bbox.xMin,
+ subglyph->bbox.xMax ));
+ FT_TRACE6(( " yMin: %4d yMax: %4d\n",
+ subglyph->bbox.yMin,
+ subglyph->bbox.yMax ));
+ FT_TRACE6(( "-" ));
+
+ count -= 10;
+
+ if ( num_contours > left_contours )
+ {
+ FT_TRACE0(( "ERROR: Too many contours for glyph %ld\n", index ));
+ error = TT_Err_Too_Many_Contours;
+ goto Fail;
+ }
+
+ subglyph->pp1.x = subglyph->bbox.xMin - subglyph->left_bearing;
+ subglyph->pp1.y = 0;
+ subglyph->pp2.x = subglyph->pp1.x + subglyph->advance;
+ if (!(load_flags & FT_LOAD_NO_SCALE))
+ {
+ subglyph->pp1.x = SCALE_X( subglyph->pp1.x );
+ subglyph->pp2.x = SCALE_X( 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 state: Load_End */
+ /* */
+ case Load_Simple:
+ new_flags = load_flags;
+
+ /* disable hinting when scaling */
+ if ( !subglyph->is_hinted )
+ new_flags |= FT_LOAD_NO_HINTING;
+
+ error = Load_Simple_Glyph( exec,
+ stream,
+ count,
+ num_contours,
+ left_contours,
+ left_points,
+ new_flags,
+ subglyph,
+ (TT_Bool)(size && size->debug &&
+ load_top == 0) );
+ 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 and pushing a new */
+ /* load element on the stack. */
+ /* */
+ /* exit state: Load_Glyph */
+ /* */
+ case Load_Composite:
+
+ /* create a new element on the stack */
+ load_top++;
+
+ if ( load_top > face->max_components )
+ {
+ 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 = 1 << 16;
+ xy = 0;
+ yx = 0;
+ yy = 1 << 16;
+
+ if ( new_flags & WE_HAVE_A_SCALE )
+ {
+ xx = (TT_Fixed)GET_Short() << 2;
+ yy = xx;
+ subglyph2->is_scaled = TRUE;
+ }
+ else if ( new_flags & WE_HAVE_AN_XY_SCALE )
+ {
+ xx = (TT_Fixed)GET_Short() << 2;
+ yy = (TT_Fixed)GET_Short() << 2;
+ subglyph2->is_scaled = TRUE;
+ }
+ else if ( new_flags & WE_HAVE_A_2X2 )
+ {
+ xx = (TT_Fixed)GET_Short() << 2;
+ xy = (TT_Fixed)GET_Short() << 2;
+ yx = (TT_Fixed)GET_Short() << 2;
+ yy = (TT_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 = FT_MulFix( xx, yy ) - FT_MulFix( xy, yx );
+
+ /* disable hinting in case of scaling/slanting */
+ if ( ABS( k ) != (1 << 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, pop 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->left_bearing = subglyph2->left_bearing;
+ subglyph->advance = subglyph2->advance;
+
+ 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 = FT_MulFix( cur->x, subglyph->transform.xx ) +
+ FT_MulFix( cur->y, subglyph->transform.yx );
+
+ ny = FT_MulFix( cur->x, subglyph->transform.xy ) +
+ FT_MulFix( cur->y, subglyph->transform.yy );
+
+ cur->x = nx;
+ cur->y = ny;
+
+ nx = FT_MulFix( org->x, subglyph->transform.xx ) +
+ FT_MulFix( org->y, subglyph->transform.yx );
+
+ ny = FT_MulFix( org->x, subglyph->transform.xy ) +
+ FT_MulFix( org->y, subglyph->transform.yy );
+
+ org->x = nx;
+ org->y = ny;
+
+ cur++;
+ org++;
+ }
+ }
+
+ /* adjust counts */
+
+ for ( k = 0; k < num_contours; k++ )
+ subglyph2->zone.contours[k] += subglyph->zone.n_points;
+
+ subglyph->zone.n_points += num_points;
+ subglyph->zone.n_contours += num_contours;
+
+ left_points -= num_points;
+ left_contours -= num_contours;
+
+ /* apply offset */
+
+ if ( !(subglyph->element_flag & ARGS_ARE_XY_VALUES) )
+ {
+ k = subglyph->arg1;
+ l = subglyph->arg2;
+
+ if ( k >= subglyph->zone.n_points ||
+ l >= num_points )
+ {
+ error = TT_Err_Invalid_Composite;
+ goto Fail;
+ }
+
+ l += subglyph->zone.n_points;
+
+ x = subglyph->zone.cur[k].x - subglyph->zone.cur[l].x;
+ y = subglyph->zone.cur[k].y - subglyph->zone.cur[l].y;
+ }
+ else
+ {
+ x = subglyph->transform.ox;
+ y = subglyph->transform.oy;
+
+ if (!(load_flags & FT_LOAD_NO_SCALE))
+ {
+ x = SCALE_X( x );
+ y = SCALE_Y( 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,
+ stream,
+ load_flags,
+ (TT_Bool)(size && size->debug &&
+ load_top == 0) );
+ 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; 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, glyph->outline.points,
+ -subglyph->pp1.x, 0 );
+
+ FT_Get_Outline_CBox( &glyph->outline, &bbox );
+
+ if ( subglyph->is_hinted )
+ {
+ /* grid-fit the bounding box */
+ bbox.xMin &= -64;
+ bbox.yMin &= -64;
+ bbox.xMax = (bbox.xMax + 63) & -64;
+ bbox.yMax = (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->left_bearing;
+ advance = subglyph->advance;
+
+ if ( face->postscript.isFixedPitch )
+ advance = face->horizontal.advance_Width_Max;
+
+ if ( !(load_flags & FT_LOAD_NO_SCALE) )
+ {
+ left_bearing = SCALE_X( left_bearing );
+ advance = SCALE_X( advance );
+ }
+
+ glyph->metrics2.horiBearingX = left_bearing;
+ glyph->metrics2.horiAdvance = advance;
+ }
+
+ glyph->metrics.horiBearingX = bbox.xMin;
+ glyph->metrics.horiBearingY = 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'... */
+
+ {
+ TT_Short top_bearing; /* vertical top side bearing (EM units) */
+ TT_UShort advance_height; /* vertical advance height (EM units) */
+
+ TT_Pos left; /* scaled vertical left side bearing */
+ TT_Pos top; /* scaled vertical top side bearing */
+ TT_Pos advance; /* scaled vertical advance height */
+
+
+ /* Get the unscaled `tsb' and `ah' */
+ if ( face->vertical_info &&
+ face->vertical.number_Of_VMetrics > 0 )
+ {
+ /* Don't assume that both the vertical header and vertical */
+ /* metrics are present in the same font :-) */
+
+ TT_Get_Metrics( (TT_HoriHeader*)&face->vertical,
+ glyph_index,
+ &top_bearing,
+ &advance_height );
+ }
+ else
+ {
+ /* Make up the distances from the horizontal header.. */
+
+ /* NOTE: The OS/2 values are the only `portable' ones, */
+ /* which is why we use them, when there is an */
+ /* OS/2 table in the font. Otherwise, we use the */
+ /* values defined in the horizontal header.. */
+ /* */
+ /* NOTE2: The sTypoDescender is negative, which is why */
+ /* we compute the baseline-to-baseline distance */
+ /* here with: */
+ /* ascender - descender + linegap */
+ /* */
+ if ( face->os2.version != 0xFFFF )
+ {
+ top_bearing = face->os2.sTypoLineGap / 2;
+ advance_height = (TT_UShort)(face->os2.sTypoAscender -
+ face->os2.sTypoDescender +
+ face->os2.sTypoLineGap);
+ }
+ else
+ {
+ top_bearing = face->horizontal.Line_Gap / 2;
+ advance_height = (TT_UShort)(face->horizontal.Ascender +
+ face->horizontal.Descender +
+ face->horizontal.Line_Gap);
+ }
+ }
+
+ /* scale the metrics */
+ if ( !(load_flags & FT_LOAD_NO_SCALE) )
+ {
+ top = SCALE_Y( top_bearing );
+ advance = SCALE_X( advance_height );
+ }
+ else
+ {
+ top = top_bearing;
+ advance = advance_height;
+ }
+
+ glyph->metrics2.vertBearingY = top;
+ glyph->metrics2.vertAdvance = advance;
+
+ /* XXX: for now, we have no better algorithm for the lsb, but it */
+ /* should work fine. */
+ /* */
+ left = ( bbox.xMin - bbox.xMax ) / 2;
+
+ /* grid-fit them if necessary */
+ if ( 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 && size &&
+ subglyph->is_hinted )
+ {
+ widths = Get_Advance_Widths( exec->face,
+ exec->size->root.metrics.x_ppem );
+ if ( widths )
+ glyph->metrics.horiAdvance = widths[glyph_index] << 6;
+ }
+
+ glyph->outline.dropout_mode = (TT_Char)exec->GS.scan_type;
+
+ /* set glyph dimensions */
+ glyph->metrics.width = bbox.xMax - bbox.xMin;
+ glyph->metrics.height = bbox.yMax - bbox.yMin;
+
+ glyph->format = ft_glyph_format_outline;
+
+ error = TT_Err_Ok;
+
+ Fail_File:
+ Fail:
+
+ /* reset the execution context */
+ exec->pts = base_pts;
+
+ if ( !size || !size->debug )
+ TT_Done_Context( exec );
+
+ return error;
+ }
+
+
+/* END */
--- /dev/null
+++ b/src/truetype/ttgload.h
@@ -1,0 +1,109 @@
+/***************************************************************************/
+/* */
+/* ttgload.h */
+/* */
+/* TrueType Glyph Loader (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 TTGLOAD_H
+#define TTGLOAD_H
+
+#include <ttobjs.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Get_Metrics */
+ /* */
+ /* <Description> */
+ /* Returns the horizontal or vertical metrics in font units for a */
+ /* given glyph. The metrics are the left side bearing (resp. top */
+ /* side bearing) and advance width (resp. advance height). */
+ /* */
+ /* <Input> */
+ /* header :: A pointer to either the horizontal or vertical metrics */
+ /* structure. */
+ /* */
+ /* index :: The glyph index. */
+ /* */
+ /* <Output> */
+ /* bearing :: The bearing, either left side or top side. */
+ /* */
+ /* advance :: The advance width resp. advance height. */
+ /* */
+ /* <Note> */
+ /* This function will much probably move to another component in the */
+ /* near future, but I haven't decided which yet. */
+ /* */
+ LOCAL_DEF
+ void TT_Get_Metrics( TT_HoriHeader* header,
+ TT_UShort index,
+ TT_Short* bearing,
+ TT_UShort* advance );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Glyph */
+ /* */
+ /* <Description> */
+ /* A function used to load a single glyph within a given glyph slot, */
+ /* for a given size. */
+ /* */
+ /* <Input> */
+ /* glyph :: A handle to a target slot object where the glyph */
+ /* will be loaded. */
+ /* */
+ /* size :: A handle to the source face size at which the glyph */
+ /* must be scaled/loaded. */
+ /* */
+ /* glyph_index :: The index of the glyph in the font file. */
+ /* */
+ /* load_flags :: A flag indicating what to load for this glyph. The */
+ /* FT_LOAD_XXX constants can be used to control the */
+ /* glyph loading process (e.g., whether the outline */
+ /* should be scaled, whether to load bitmaps or not, */
+ /* whether to hint the outline, etc). */
+ /* <Output> */
+ /* result :: A set of bit flags indicating the type of data that */
+ /* was loaded in the glyph slot (outline or bitmap, */
+ /* etc). */
+ /* */
+ /* You can set this field to 0 if you don't want this */
+ /* information. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_Glyph( TT_Size size,
+ TT_GlyphSlot glyph,
+ TT_UShort glyph_index,
+ TT_UInt load_flags );
+
+#ifdef __cplusplus
+ }
+#endif
+
+
+#endif /* TTGLOAD_H */
+
+
+/* END */
--- /dev/null
+++ b/src/truetype/ttinterp.c
@@ -1,0 +1,7954 @@
+/***************************************************************************/
+/* */
+/* ttinterp.c */
+/* */
+/* TrueType bytecode intepreter (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 <ftdebug.h>
+#include <ftsystem.h>
+#include <ftcalc.h>
+
+#include <ttinterp.h>
+
+#define TT_MULFIX FT_MulFix
+#define TT_MULDIV FT_MulDiv
+
+#define TT_INT64 FT_Int64
+
+/* required by the tracing mode */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_ttinterp
+
+
+ /*************************************************************************/
+ /* */
+ /* In order to detect infinite loops in the code, we set-up a counter */
+ /* within the run loop. a single stroke of interpretation is now limited */
+ /* to a maximum number of opcodes defined below. */
+ /* */
+#define MAX_RUNNABLE_OPCODES 1000000
+
+
+ /*************************************************************************/
+ /* */
+ /* There are two kinds of implementations: */
+ /* */
+ /* a. static implementation: */
+ /* */
+ /* The current execution context is a static variable, which fields */
+ /* are accessed directly by the interpreter during execution. The */
+ /* context is named `cur'. */
+ /* */
+ /* This version is non-reentrant, of course. */
+ /* */
+ /* b. indirect implementation: */
+ /* */
+ /* The current execution context is passed to _each_ function as its */
+ /* first argument, and each field is thus accessed indirectly. */
+ /* */
+ /* This version is fully re-entrant. */
+ /* */
+ /* The idea is that an indirect implementation may be slower to execute */
+ /* on low-end processors that are used in some systems (like 386s or */
+ /* even 486s). */
+ /* */
+ /* As a consequence, the indirect implementation is now the default, as */
+ /* its performance costs can be considered negligible in our context. */
+ /* Note, however, that we kept the same source with macros because: */
+ /* */
+ /* - The code is kept very close in design to the Pascal code used for */
+ /* development. */
+ /* */
+ /* - It's much more readable that way! */
+ /* */
+ /* - It's still open to experimentation and tuning. */
+ /* */
+ /*************************************************************************/
+
+
+#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER /* indirect implementation */
+
+#define CUR (*exc) /* see ttobjs.h */
+
+#else /* static implementation */
+
+#define CUR cur
+
+ static
+ TT_ExecContextRec cur; /* static exec. context variable */
+
+ /* apparently, we have a _lot_ of direct indexing when accessing */
+ /* the static `cur', which makes the code bigger (due to all the */
+ /* four bytes addresses). */
+
+#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */
+
+
+ /*************************************************************************/
+ /* */
+ /* Most of FreeType builds don't use engine compensations. We thus */
+ /* introduce a macro, FT_CONFIG_OPTION_INTERPRETER_QUICK, which controls */
+ /* the use of these values. */
+ /* */
+#define INS_ARG EXEC_OP_ TT_Long* args /* see ttobjs.h for EXEC_OP_ */
+
+
+ /*************************************************************************/
+ /* */
+ /* This macro is used whenever `exec' is unused in a function, to avoid */
+ /* stupid warnings from pedantic compilers. */
+ /* */
+#define UNUSED_EXEC (void)CUR
+
+
+ /*************************************************************************/
+ /* */
+ /* This macro is used whenever `args' is unused in a function, to avoid */
+ /* stupid warnings from pedantic compilers. */
+ /* */
+#define UNUSED_ARG UNUSED_EXEC; (void)args;
+
+
+ /*************************************************************************/
+ /* */
+ /* The following macros hide the use of EXEC_ARG and EXEC_ARG_ to */
+ /* increase readabiltyof the code. */
+ /* */
+ /*************************************************************************/
+
+
+#define SKIP_Code() \
+ SkipCode( EXEC_ARG )
+
+#define GET_ShortIns() \
+ GetShortIns( EXEC_ARG )
+
+#define NORMalize( x, y, v ) \
+ Normalize( EXEC_ARG_ x, y, v )
+
+#define SET_SuperRound( scale, flags ) \
+ SetSuperRound( EXEC_ARG_ scale, flags )
+
+#define ROUND_None( d, c ) \
+ Round_None( EXEC_ARG_ d, c )
+
+#define INS_Goto_CodeRange( range, ip ) \
+ Ins_Goto_CodeRange( EXEC_ARG_ range, ip )
+
+#define CUR_Func_project( x, y ) \
+ CUR.func_project( EXEC_ARG_ x, y )
+
+#define CUR_Func_move( z, p, d ) \
+ CUR.func_move( EXEC_ARG_ z, p, d )
+
+#define CUR_Func_dualproj( x, y ) \
+ CUR.func_dualproj( EXEC_ARG_ x, y )
+
+#define CUR_Func_freeProj( x, y ) \
+ CUR.func_freeProj( EXEC_ARG_ x, y )
+
+#define CUR_Func_round( d, c ) \
+ CUR.func_round( EXEC_ARG_ d, c )
+
+#define CUR_Func_read_cvt( index ) \
+ CUR.func_read_cvt( EXEC_ARG_ index )
+
+#define CUR_Func_write_cvt( index, val ) \
+ CUR.func_write_cvt( EXEC_ARG_ index, val )
+
+#define CUR_Func_move_cvt( index, val ) \
+ CUR.func_move_cvt( EXEC_ARG_ index, val )
+
+#define CURRENT_Ratio() \
+ Current_Ratio( EXEC_ARG )
+
+#define CURRENT_Ppem() \
+ Current_Ppem( EXEC_ARG )
+
+#define CUR_Ppem() \
+ Cur_PPEM( EXEC_ARG )
+
+#define CALC_Length() \
+ Calc_Length( EXEC_ARG )
+
+#define INS_SxVTL( a, b, c, d ) \
+ Ins_SxVTL( EXEC_ARG_ a, b, c, d )
+
+#define COMPUTE_Funcs() \
+ Compute_Funcs( EXEC_ARG )
+
+#define COMPUTE_Round( a ) \
+ Compute_Round( EXEC_ARG_ a )
+
+#define COMPUTE_Point_Displacement( a, b, c, d ) \
+ Compute_Point_Displacement( EXEC_ARG_ a, b, c, d )
+
+#define MOVE_Zp2_Point( a, b, c, t ) \
+ Move_Zp2_Point( EXEC_ARG_ a, b, c, t )
+
+
+
+ /*************************************************************************/
+ /* */
+ /* Instruction dispatch function, as used by the interpreter. */
+ /* */
+ typedef void (*TInstruction_Function)( INS_ARG );
+
+
+ /*************************************************************************/
+ /* */
+ /* A simple bounds-checking macro. */
+ /* */
+#define BOUNDS( x, n ) ((TT_UInt)(x) >= (TT_UInt)(n))
+
+
+#undef SUCCESS
+#define SUCCESS 0
+
+#undef FAILURE
+#define FAILURE 1
+
+
+ /*************************************************************************/
+ /* */
+ /* CODERANGE FUNCTIONS */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Goto_CodeRange */
+ /* */
+ /* <Description> */
+ /* Switches to a new code range (updates the code related elements in */
+ /* `exec', and `IP'). */
+ /* */
+ /* <Input> */
+ /* range :: The new execution code range. */
+ /* IP :: The new IP in the new code range. */
+ /* */
+ /* <InOut> */
+ /* exec :: The target execution context. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ EXPORT_FUNC
+ TT_Error TT_Goto_CodeRange( TT_ExecContext exec,
+ TT_Int range,
+ TT_Long IP )
+ {
+ TT_CodeRange* coderange;
+
+
+ FT_Assert( range >= 1 && range <= 3 );
+
+ coderange = &exec->codeRangeTable[range - 1];
+
+ FT_Assert( coderange->base != NULL );
+
+ /* NOTE: Because the last instruction of a program may be a CALL */
+ /* which will return to the first byte *after* the code */
+ /* range, we test for IP <= Size, instead of IP < Size. */
+ /* */
+ FT_Assert( (TT_ULong)IP <= coderange->size );
+
+ exec->code = coderange->base;
+ exec->codeSize = coderange->size;
+ exec->IP = IP;
+ exec->curRange = range;
+
+ return TT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Set_CodeRange */
+ /* */
+ /* <Description> */
+ /* Sets a code range. */
+ /* */
+ /* <Input> */
+ /* range :: The code range index. */
+ /* base :: The new code base. */
+ /* length :: The range size in bytes. */
+ /* */
+ /* <InOut> */
+ /* exec :: The target execution context. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ EXPORT_FUNC
+ TT_Error TT_Set_CodeRange( TT_ExecContext exec,
+ TT_Int range,
+ void* base,
+ TT_Long length )
+ {
+ FT_Assert( range >= 1 && range <= 3 );
+
+ exec->codeRangeTable[range - 1].base = (TT_Byte*)base;
+ exec->codeRangeTable[range - 1].size = length;
+
+ return TT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Clear_CodeRange */
+ /* */
+ /* <Description> */
+ /* Clears a code range. */
+ /* */
+ /* <Input> */
+ /* range :: The code range index. */
+ /* */
+ /* <InOut> */
+ /* exec :: The target execution context. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* Does not set the Error variable. */
+ /* */
+ EXPORT_FUNC
+ TT_Error TT_Clear_CodeRange( TT_ExecContext exec,
+ TT_Int range )
+ {
+ FT_Assert( range >= 1 && range <= 3 );
+
+ exec->codeRangeTable[range - 1].base = NULL;
+ exec->codeRangeTable[range - 1].size = 0;
+
+ return TT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* EXECUTION CONTEXT ROUTINES */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Destroy_Context */
+ /* */
+ /* <Description> */
+ /* Destroys a given context. */
+ /* */
+ /* <Input> */
+ /* exec :: A handle to the target execution context. */
+ /* system :: A handle to the parent system object. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* Only the glyph loader and debugger should call this function. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Destroy_Context( TT_ExecContext exec,
+ FT_Memory memory )
+ {
+ /* free composite load stack */
+ FREE( exec->loadStack );
+ exec->loadSize = 0;
+
+ /* points zone */
+ TT_Done_GlyphZone( exec->memory, &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->size = NULL;
+ exec->face = NULL;
+
+ FREE( exec );
+ return TT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Init_Context */
+ /* */
+ /* <Description> */
+ /* Initializes a context object. */
+ /* */
+ /* <Input> */
+ /* memory :: A handle to the parent memory object. */
+ /* */
+ /* face :: A handle to the source TrueType face object. */
+ /* */
+ /* <InOut> */
+ /* exec :: A handle to the target execution context. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ static
+ TT_Error Init_Context( TT_ExecContext exec,
+ TT_Face face,
+ FT_Memory memory )
+ {
+ TT_Error error;
+
+
+ FT_TRACE1(( "TT.Create_Create: new object at 0x%08lx, parent = 0x%08lx\n",
+ (long)exec, (long)face ));
+
+ /* XXX: We don't reserve arrays anymore, this is done automatically */
+ /* during a call to Context_Load(). */
+
+ exec->memory = memory;
+ exec->callSize = 32;
+
+ if ( ALLOC_ARRAY( exec->callStack, exec->callSize, TT_CallRec ) )
+ goto Fail_Memory;
+
+ /* all values in the context are set to 0 already, but this is */
+ /* here as a remainder */
+ exec->maxPoints = 0;
+ exec->maxContours = 0;
+
+ exec->stackSize = 0;
+ exec->loadSize = 0;
+ exec->glyphSize = 0;
+
+ exec->stack = NULL;
+ exec->loadStack = NULL;
+ exec->glyphIns = NULL;
+
+ exec->face = face;
+ exec->size = NULL;
+
+ return TT_Err_Ok;
+
+ Fail_Memory:
+ FT_ERROR(( "TT.Context_Create: not enough memory for 0x%08lx\n",
+ (long)exec ));
+ TT_Destroy_Context( exec, memory );
+
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Update_Max */
+ /* */
+ /* <Description> */
+ /* Checks the size of a buffer and reallocates it if necessary. */
+ /* */
+ /* <Input> */
+ /* multiplier :: The size in bytes of each element in the buffer. */
+ /* */
+ /* new_max :: The new capacity (size) of the buffer. */
+ /* */
+ /* <InOut> */
+ /* size :: The address of the buffer's current size expressed */
+ /* in elements. */
+ /* */
+ /* buff :: The address of the buffer base pointer. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ static
+ TT_Error Update_Max( FT_Memory memory,
+ TT_ULong* size,
+ TT_Long multiplier,
+ void** buff,
+ TT_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;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Update_Zone */
+ /* */
+ /* <Description> */
+ /* Checks the size of a zone and reallocates it if necessary. */
+ /* */
+ /* <Input> */
+ /* newPoints :: The new capacity for points. We add two slots for */
+ /* phantom points. */
+ /* */
+ /* newContours :: The new capacity for contours. */
+ /* */
+ /* <InOut> */
+ /* zone :: The address of the target zone. */
+ /* */
+ /* maxPoints :: The address of the zone's current capacity for */
+ /* points. */
+ /* */
+ /* maxContours :: The address of the zone's current capacity for */
+ /* contours. */
+ /* */
+ static
+ TT_Error Update_Zone( FT_Memory memory,
+ TT_GlyphZone* zone,
+ TT_UShort* maxPoints,
+ TT_Short* maxContours,
+ TT_UShort newPoints,
+ TT_Short newContours )
+ {
+ newPoints += 2;
+
+ if ( *maxPoints < newPoints || *maxContours < newContours )
+ {
+ TT_Error error;
+
+
+ TT_Done_GlyphZone( memory, zone );
+
+ error = TT_New_GlyphZone( memory, zone, newPoints, newContours );
+ if ( error )
+ return error;
+
+ *maxPoints = newPoints;
+ *maxContours = newContours;
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Context */
+ /* */
+ /* <Description> */
+ /* Prepare an execution context for glyph hinting. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the source face object. */
+ /* size :: A handle to the source size object. */
+ /* */
+ /* <InOut> */
+ /* exec :: A handle to the target execution context. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* Only the glyph loader and debugger should call this function. */
+ /* */
+ EXPORT_FUNC
+ TT_Error TT_Load_Context( TT_ExecContext exec,
+ TT_Face face,
+ TT_Size size )
+ {
+ TT_Int i;
+ TT_ULong tmp;
+ TT_MaxProfile* maxp;
+ TT_Error error;
+
+
+ exec->face = face;
+ maxp = &face->max_profile;
+ exec->size = size;
+
+ if ( size )
+ {
+ exec->numFDefs = size->num_function_defs;
+ exec->maxFDefs = size->max_function_defs;
+ exec->numIDefs = size->num_instruction_defs;
+ exec->maxIDefs = size->max_instruction_defs;
+ exec->FDefs = size->function_defs;
+ exec->IDefs = size->instruction_defs;
+ exec->tt_metrics = size->ttmetrics;
+ exec->metrics = size->root.metrics;
+
+ exec->maxFunc = size->max_func;
+ exec->maxIns = size->max_ins;
+
+ for ( i = 0; i < TT_MAX_CODE_RANGES; i++ )
+ exec->codeRangeTable[i] = size->codeRangeTable[i];
+
+ /* set graphics state */
+ exec->GS = size->GS;
+
+ exec->cvtSize = size->cvt_size;
+ exec->cvt = size->cvt;
+
+ exec->storeSize = size->storage_size;
+ exec->storage = size->storage;
+
+ exec->twilight = size->twilight;
+ }
+
+ error = Update_Max( exec->memory,
+ &exec->loadSize,
+ sizeof ( TT_SubGlyphRec ),
+ (void**)&exec->loadStack,
+ exec->face->max_components + 1 );
+ if ( error )
+ return error;
+
+ /* XXX: We reserve a little more elements on the stack to deal safely */
+ /* with broken fonts like arialbs, courbs, timesbs, etc. */
+ tmp = exec->stackSize;
+ error = Update_Max( exec->memory,
+ &tmp,
+ sizeof ( TT_F26Dot6 ),
+ (void**)&exec->stack,
+ maxp->maxStackElements + 32 );
+ exec->stackSize = (TT_UInt)tmp;
+ if ( error )
+ return error;
+
+ tmp = exec->glyphSize;
+ error = Update_Max( exec->memory,
+ &tmp,
+ sizeof ( TT_Byte ),
+ (void**)&exec->glyphIns,
+ maxp->maxSizeOfInstructions );
+ exec->glyphSize = (TT_UShort)tmp;
+ if ( error )
+ return error;
+
+ /* XXX: Update_Zone() reserves two positions for the phantom points! */
+ error = Update_Zone( exec->memory,
+ &exec->pts,
+ &exec->maxPoints,
+ &exec->maxContours,
+ exec->face->root.max_points,
+ exec->face->root.max_contours );
+ if ( error )
+ return error;
+
+ exec->pts.n_points = 0;
+ exec->pts.n_contours = 0;
+
+ exec->instruction_trap = FALSE;
+
+ return TT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Save_Context */
+ /* */
+ /* <Description> */
+ /* Saves the code ranges in a `size' object. */
+ /* */
+ /* <Input> */
+ /* exec :: A handle to the source execution context. */
+ /* */
+ /* <Output> */
+ /* ins :: A handle to the target size object. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* Only the glyph loader and debugger should call this function. */
+ /* */
+ EXPORT_FUNC
+ TT_Error TT_Save_Context( TT_ExecContext exec,
+ TT_Size size )
+ {
+ TT_Int i;
+
+ /* XXXX: Will probably disappear soon with all the code range */
+ /* management, which is now rather obsolete. */
+ /* */
+ size->num_function_defs = exec->numFDefs;
+ size->num_instruction_defs = exec->numIDefs;
+
+ size->max_func = exec->maxFunc;
+ size->max_ins = exec->maxIns;
+
+ for ( i = 0; i < TT_MAX_CODE_RANGES; i++ )
+ size->codeRangeTable[i] = exec->codeRangeTable[i];
+
+ return TT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Run_Context */
+ /* */
+ /* <Description> */
+ /* Executes one or more instructions in the execution context. */
+ /* */
+ /* <Input> */
+ /* debug :: A Boolean flag. If set, the function sets some internal */
+ /* variables and returns immediately, otherwise TT_RunIns() */
+ /* is called. */
+ /* */
+ /* <Input> */
+ /* exec :: A handle to the target execution context. */
+ /* */
+ /* <Return> */
+ /* TrueTyoe error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* Only the glyph loader and debugger should call this function. */
+ /* */
+ EXPORT_FUNC
+ TT_Error TT_Run_Context( TT_ExecContext exec,
+ TT_Bool debug )
+ {
+ TT_Error error;
+
+ if ( (error = TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 ))
+ != TT_Err_Ok )
+ return error;
+
+ exec->zp0 = exec->pts;
+ exec->zp1 = exec->pts;
+ exec->zp2 = exec->pts;
+
+ exec->GS.gep0 = 1;
+ exec->GS.gep1 = 1;
+ exec->GS.gep2 = 1;
+
+ exec->GS.projVector.x = 0x4000;
+ exec->GS.projVector.y = 0x0000;
+
+ exec->GS.freeVector = exec->GS.projVector;
+ exec->GS.dualVector = exec->GS.projVector;
+
+ exec->GS.round_state = 1;
+ exec->GS.loop = 1;
+
+ /* some glyphs leave something on the stack. so we clean it */
+ /* before a new execution. */
+ exec->top = 0;
+ exec->callTop = 0;
+
+#if 1
+ return exec->face->interpreter( exec );
+#else
+ if ( !debug )
+ return TT_RunIns( exec );
+ else
+ return TT_Err_Ok;
+#endif
+ }
+
+
+ LOCAL_FUNC
+ const TT_GraphicsState tt_default_graphics_state =
+ {
+ 0, 0, 0,
+ { 0x4000, 0 },
+ { 0x4000, 0 },
+ { 0x4000, 0 },
+ 1, 64, 1,
+ TRUE, 68, 0, 0, 9, 3,
+ 0, FALSE, 2, 1, 1, 1
+ };
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_New_Context */
+ /* */
+ /* <Description> */
+ /* Queries the face context for a given font. Note that there is */
+ /* now a _single_ execution context in the TrueType driver which is */
+ /* shared among faces. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the source face object. */
+ /* */
+ /* <Return> */
+ /* A handle to the execution context. Initialized for `face'. */
+ /* */
+ /* <Note> */
+ /* Only the glyph loader and debugger should call this function. */
+ /* */
+ EXPORT_FUNC
+ TT_ExecContext TT_New_Context( TT_Face face )
+ {
+ TT_Driver driver = (TT_Driver)face->root.driver;
+ TT_ExecContext exec;
+ FT_Memory memory = driver->root.memory;
+
+
+ exec = driver->context;
+
+ if ( !driver->context )
+ {
+ TT_Error error;
+
+
+ /* allocate object */
+ if ( ALLOC( exec, sizeof ( *exec ) ) )
+ goto Exit;
+
+ /* initialize it */
+ error = Init_Context( exec, face, memory );
+ if ( error )
+ goto Fail;
+
+ /* store it into the driver */
+ driver->context = exec;
+ }
+
+ Exit:
+ return driver->context;
+
+ Fail:
+ FREE( exec );
+
+ return 0;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Done_Context */
+ /* */
+ /* <Description> */
+ /* Discards an execution context. */
+ /* */
+ /* <Input> */
+ /* exec :: A handle to the target execution context. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* Only the glyph loader and debugger should call this function. */
+ /* */
+ EXPORT_FUNC
+ TT_Error TT_Done_Context( TT_ExecContext exec )
+ {
+ /* Nothing at all for now */
+ UNUSED( exec );
+
+ return TT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* Before an opcode is executed, the interpreter verifies that there are */
+ /* enough arguments on the stack, with the help of the Pop_Push_Count */
+ /* table. */
+ /* */
+ /* For each opcode, the first column gives the number of arguments that */
+ /* are popped from the stack; the second one gives the number of those */
+ /* that are pushed in result. */
+ /* */
+ /* Note that for opcodes with a varying number of parameters, either 0 */
+ /* or 1 arg is verified before execution, depending on the nature of the */
+ /* instruction: */
+ /* */
+ /* - if the number of arguments is given by the bytecode stream or the */
+ /* loop variable, 0 is chosen. */
+ /* */
+ /* - if the first argument is a count n that is followed by arguments */
+ /* a1 .. an, then 1 is chosen. */
+ /* */
+ /*************************************************************************/
+
+
+#undef PACK
+#define PACK( x, y ) ((x << 4) | y)
+
+
+ static
+ const TT_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_Char opcode_length[256] =
+ {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ -1,-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 3, 4, 5, 6, 7, 8, 9, 3, 5, 7, 9, 11,13,15,17,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+ };
+
+ static
+ const TT_Vector Null_Vector = {0,0};
+
+
+#undef PACK
+
+
+#undef NULL_Vector
+#define NULL_Vector (TT_Vector*)&Null_Vector
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Current_Ratio */
+ /* */
+ /* <Description> */
+ /* Returns the current aspect ratio scaling factor depending on the */
+ /* projection vector's state and device resolutions. */
+ /* */
+ /* <Return> */
+ /* The aspect ratio in 16.16 format, always <= 1.0 . */
+ /* */
+ static
+ TT_Long Current_Ratio( EXEC_OP )
+ {
+ if ( CUR.tt_metrics.ratio )
+ return CUR.tt_metrics.ratio;
+
+ if ( CUR.GS.projVector.y == 0 )
+ CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio;
+
+ else if ( CUR.GS.projVector.x == 0 )
+ CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio;
+
+ else
+ {
+ TT_Long x, y;
+#if 0
+ x = TT_MULDIV( CUR.GS.projVector.x, CUR.tt_metrics.x_ratio, 0x4000 );
+ y = TT_MULDIV( CUR.GS.projVector.y, CUR.tt_metrics.y_ratio, 0x4000 );
+ CUR.tt_metrics.ratio = Norm( x, y );
+#else
+ x = TT_MULDIV( CUR.GS.projVector.x, CUR.tt_metrics.x_ratio, 0x8000 );
+ y = TT_MULDIV( CUR.GS.projVector.y, CUR.tt_metrics.y_ratio, 0x8000 );
+ CUR.tt_metrics.ratio = FT_Sqrt32( x*x+y*y ) << 1;
+#endif
+ }
+
+ return CUR.tt_metrics.ratio;
+ }
+
+
+ static
+ TT_Long Current_Ppem( EXEC_OP )
+ {
+ return TT_MULFIX( CUR.tt_metrics.ppem, CURRENT_Ratio() );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* Functions related to the control value table (CVT). */
+ /* */
+ /*************************************************************************/
+
+
+ static
+ TT_F26Dot6 Read_CVT( EXEC_OP_ TT_ULong index )
+ {
+ return CUR.cvt[index];
+ }
+
+
+ static
+ TT_F26Dot6 Read_CVT_Stretched( EXEC_OP_ TT_ULong index )
+ {
+ return TT_MULFIX( CUR.cvt[index], CURRENT_Ratio() );
+ }
+
+
+ static
+ void Write_CVT( EXEC_OP_ TT_ULong index,
+ TT_F26Dot6 value )
+ {
+ CUR.cvt[index] = value;
+ }
+
+ static
+ void Write_CVT_Stretched( EXEC_OP_ TT_ULong index,
+ TT_F26Dot6 value )
+ {
+ CUR.cvt[index] = FT_DivFix( value, CURRENT_Ratio() );
+ }
+
+
+ static
+ void Move_CVT( EXEC_OP_ TT_ULong index,
+ TT_F26Dot6 value )
+ {
+ CUR.cvt[index] += value;
+ }
+
+
+ static
+ void Move_CVT_Stretched( EXEC_OP_ TT_ULong index,
+ TT_F26Dot6 value )
+ {
+ CUR.cvt[index] += FT_DivFix( value, CURRENT_Ratio() );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* GetShortIns */
+ /* */
+ /* <Description> */
+ /* Returns a short integer taken from the instruction stream at */
+ /* address IP. */
+ /* */
+ /* <Return> */
+ /* Short read at code[IP]. */
+ /* */
+ /* <Note> */
+ /* This one could become a macro. */
+ /* */
+ static TT_Short GetShortIns( EXEC_OP )
+ {
+ /* Reading a byte stream so there is no endianess (DaveP) */
+ CUR.IP += 2;
+ return (TT_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 :: The index of the code range. */
+ /* */
+ /* aIP :: The new IP address in the code range. */
+ /* */
+ /* <Return> */
+ /* SUCCESS or FAILURE. */
+ /* */
+ static
+ TT_Bool Ins_Goto_CodeRange( EXEC_OP_ TT_Int aRange,
+ TT_ULong aIP )
+ {
+ TT_CodeRange* range;
+
+
+ if ( aRange < 1 || aRange > 3 )
+ {
+ CUR.error = TT_Err_Bad_Argument;
+ return FAILURE;
+ }
+
+ range = &CUR.codeRangeTable[aRange - 1];
+
+ if ( range->base == NULL ) /* invalid coderange */
+ {
+ CUR.error = TT_Err_Invalid_CodeRange;
+ return FAILURE;
+ }
+
+ /* NOTE: Because the last instruction of a program may be a CALL */
+ /* which will return to the first byte *after* the code */
+ /* range, we test for AIP <= Size, instead of AIP < Size. */
+
+ if ( aIP > range->size )
+ {
+ CUR.error = TT_Err_Code_Overflow;
+ return FAILURE;
+ }
+
+ CUR.code = range->base;
+ CUR.codeSize = range->size;
+ CUR.IP = aIP;
+ CUR.curRange = aRange;
+
+ return SUCCESS;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Direct_Move */
+ /* */
+ /* <Description> */
+ /* Moves a point by a given distance along the freedom vector. The */
+ /* point will be `touched'. */
+ /* */
+ /* <Input> */
+ /* point :: The index of the point to move. */
+ /* distance :: The distance to apply. */
+ /* */
+ /* <InOut> */
+ /* zone :: The affected glyph zone. */
+ /* */
+ static
+ void Direct_Move( EXEC_OP_ TT_GlyphZone* zone,
+ TT_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] |= FT_Curve_Tag_Touch_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] |= FT_Curve_Tag_Touch_Y;
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* Special versions of Direct_Move() */
+ /* */
+ /* The following versions are used whenever both vectors are both */
+ /* along one of the coordinate unit vectors, i.e. in 90% cases. */
+ /* */
+ /*************************************************************************/
+
+ static
+ void Direct_Move_X( EXEC_OP_ TT_GlyphZone* zone,
+ TT_UShort point,
+ TT_F26Dot6 distance )
+ {
+ UNUSED_EXEC;
+
+ zone->cur[point].x += distance;
+ zone->touch[point] |= FT_Curve_Tag_Touch_X;
+ }
+
+
+ static
+ void Direct_Move_Y( EXEC_OP_ TT_GlyphZone* zone,
+ TT_UShort point,
+ TT_F26Dot6 distance )
+ {
+ UNUSED_EXEC;
+
+ zone->cur[point].y += distance;
+ zone->touch[point] |= FT_Curve_Tag_Touch_Y;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Round_None */
+ /* */
+ /* <Description> */
+ /* Does not round, but adds engine compensation. */
+ /* */
+ /* <Input> */
+ /* distance :: The distance (not) to round. */
+ /* compensation :: The engine compensation. */
+ /* */
+ /* <Return> */
+ /* The compensated distance. */
+ /* */
+ /* <Note> */
+ /* The TrueType specification says very few about the relationship */
+ /* between rounding and engine compensation. However, it seems from */
+ /* the description of super round that we should add the compensation */
+ /* before rounding. */
+ /* */
+ static
+ TT_F26Dot6 Round_None( EXEC_OP_ TT_F26Dot6 distance,
+ TT_F26Dot6 compensation )
+ {
+ TT_F26Dot6 val;
+
+
+ UNUSED_EXEC;
+
+ 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 :: The distance to round. */
+ /* compensation :: The engine compensation. */
+ /* */
+ /* <Return> */
+ /* Rounded distance. */
+ /* */
+ static
+ TT_F26Dot6 Round_To_Grid( EXEC_OP_ TT_F26Dot6 distance,
+ TT_F26Dot6 compensation )
+ {
+ TT_F26Dot6 val;
+
+
+ UNUSED_EXEC;
+
+ if ( distance >= 0 )
+ {
+ val = distance + compensation + 32;
+ if ( val > 0 )
+ val &= ~63;
+ else
+ val = 0;
+ }
+ else
+ {
+ val = -( (compensation - distance + 32) & (-64) );
+ if ( val > 0 )
+ val = 0;
+ }
+ return val;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Round_To_Half_Grid */
+ /* */
+ /* <Description> */
+ /* Rounds value to half grid after adding engine compensation. */
+ /* */
+ /* <Input> */
+ /* distance :: The distance to round. */
+ /* compensation :: The engine compensation. */
+ /* */
+ /* <Return> */
+ /* Rounded distance. */
+ /* */
+ static
+ TT_F26Dot6 Round_To_Half_Grid( EXEC_OP_ TT_F26Dot6 distance,
+ TT_F26Dot6 compensation )
+ {
+ TT_F26Dot6 val;
+
+
+ UNUSED_EXEC;
+
+ if ( distance >= 0 )
+ {
+ val = ((distance + compensation) & (-64)) + 32;
+ if ( val < 0 )
+ val = 0;
+ }
+ else
+ {
+ val = -( ((compensation - distance) & (-64)) + 32 );
+ if ( val > 0 )
+ val = 0;
+ }
+ return val;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Round_Down_To_Grid */
+ /* */
+ /* <Description> */
+ /* Rounds value down to grid after adding engine compensation. */
+ /* */
+ /* <Input> */
+ /* distance :: The distance to round. */
+ /* compensation :: The engine compensation. */
+ /* */
+ /* <Return> */
+ /* Rounded distance. */
+ /* */
+ static
+ TT_F26Dot6 Round_Down_To_Grid( EXEC_OP_ TT_F26Dot6 distance,
+ TT_F26Dot6 compensation )
+ {
+ TT_F26Dot6 val;
+
+
+ UNUSED_EXEC;
+
+ if ( distance >= 0 )
+ {
+ val = distance + compensation;
+ if ( val > 0 )
+ val &= ~63;
+ else
+ val = 0;
+ }
+ else
+ {
+ val = -( (compensation - distance) & (-64) );
+ if ( val > 0 )
+ val = 0;
+ }
+ return val;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Round_Up_To_Grid */
+ /* */
+ /* <Description> */
+ /* Rounds value up to grid after adding engine compensation. */
+ /* */
+ /* <Input> */
+ /* distance :: The distance to round. */
+ /* compensation :: The engine compensation. */
+ /* */
+ /* <Return> */
+ /* Rounded distance. */
+ /* */
+ static
+ TT_F26Dot6 Round_Up_To_Grid( EXEC_OP_ TT_F26Dot6 distance,
+ TT_F26Dot6 compensation )
+ {
+ TT_F26Dot6 val;
+
+
+ UNUSED_EXEC;
+
+ if ( distance >= 0 )
+ {
+ val = distance + compensation + 63;
+ if ( val > 0 )
+ val &= ~63;
+ else
+ val = 0;
+ }
+ else
+ {
+ val = -( (compensation - distance + 63) & (-64) );
+ if ( val > 0 )
+ val = 0;
+ }
+ return val;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Round_To_Double_Grid */
+ /* */
+ /* <Description> */
+ /* Rounds value to double grid after adding engine compensation. */
+ /* */
+ /* <Input> */
+ /* distance :: The distance to round. */
+ /* compensation :: The engine compensation. */
+ /* */
+ /* <Return> */
+ /* Rounded distance. */
+ /* */
+ static
+ TT_F26Dot6 Round_To_Double_Grid( EXEC_OP_ TT_F26Dot6 distance,
+ TT_F26Dot6 compensation )
+ {
+ TT_F26Dot6 val;
+
+ UNUSED_EXEC;
+
+ if ( distance >= 0 )
+ {
+ val = distance + compensation + 16;
+ if ( val > 0 )
+ val &= ~31;
+ else
+ val = 0;
+ }
+ else
+ {
+ val = -( (compensation - distance + 16) & (-32) );
+ if ( val > 0 )
+ val = 0;
+ }
+ return val;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Round_Super */
+ /* */
+ /* <Description> */
+ /* Super-rounds value to grid after adding engine compensation. */
+ /* */
+ /* <Input> */
+ /* distance :: The distance to round. */
+ /* compensation :: The engine compensation. */
+ /* */
+ /* <Return> */
+ /* Rounded distance. */
+ /* */
+ /* <Note> */
+ /* The TrueType specification says very few about the relationship */
+ /* between rounding and engine compensation. However, it seems from */
+ /* the description of super round that we should add the compensation */
+ /* before rounding. */
+ /* */
+ static
+ TT_F26Dot6 Round_Super( EXEC_OP_ 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 :: The distance to round. */
+ /* compensation :: The engine compensation. */
+ /* */
+ /* <Return> */
+ /* Rounded distance. */
+ /* */
+ /* <Note> */
+ /* There is a separate function for Round_Super_45() as we may need */
+ /* greater precision. */
+ /* */
+ static
+ TT_F26Dot6 Round_Super_45( EXEC_OP_ 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;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Compute_Round */
+ /* */
+ /* <Description> */
+ /* Sets the rounding mode. */
+ /* */
+ /* <Input> */
+ /* round_mode :: The rounding mode to be used. */
+ /* */
+ static
+ void Compute_Round( EXEC_OP_ TT_Byte round_mode )
+ {
+ switch ( round_mode )
+ {
+ case TT_Round_Off:
+ CUR.func_round = (TT_Round_Func)Round_None;
+ break;
+
+ case TT_Round_To_Grid:
+ CUR.func_round = (TT_Round_Func)Round_To_Grid;
+ break;
+
+ case TT_Round_Up_To_Grid:
+ CUR.func_round = (TT_Round_Func)Round_Up_To_Grid;
+ break;
+
+ case TT_Round_Down_To_Grid:
+ CUR.func_round = (TT_Round_Func)Round_Down_To_Grid;
+ break;
+
+ case TT_Round_To_Half_Grid:
+ CUR.func_round = (TT_Round_Func)Round_To_Half_Grid;
+ break;
+
+ case TT_Round_To_Double_Grid:
+ CUR.func_round = (TT_Round_Func)Round_To_Double_Grid;
+ break;
+
+ case TT_Round_Super:
+ CUR.func_round = (TT_Round_Func)Round_Super;
+ break;
+
+ case TT_Round_Super_45:
+ CUR.func_round = (TT_Round_Func)Round_Super_45;
+ break;
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* SetSuperRound */
+ /* */
+ /* <Description> */
+ /* Sets Super Round parameters. */
+ /* */
+ /* <Input> */
+ /* GridPeriod :: Grid period */
+ /* selector :: SROUND opcode */
+ /* */
+ static
+ void SetSuperRound( EXEC_OP_ TT_F26Dot6 GridPeriod,
+ TT_Long selector )
+ {
+ switch ( (TT_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 ( (TT_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 = ( (TT_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 :: First input vector. */
+ /* v2 :: Second input vector. */
+ /* */
+ /* <Return> */
+ /* The distance in F26dot6 format. */
+ /* */
+ static
+ TT_F26Dot6 Project( EXEC_OP_ TT_Vector* v1,
+ TT_Vector* v2 )
+ {
+ return TT_MULDIV( v1->x - v2->x, CUR.GS.projVector.x, 0x4000 ) +
+ TT_MULDIV( v1->y - v2->y, CUR.GS.projVector.y, 0x4000 );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Dual_Project */
+ /* */
+ /* <Description> */
+ /* Computes the projection of the vector given by (v2-v1) along the */
+ /* current dual vector. */
+ /* */
+ /* <Input> */
+ /* v1 :: First input vector. */
+ /* v2 :: Second input vector. */
+ /* */
+ /* <Return> */
+ /* The distance in F26dot6 format. */
+ /* */
+ static
+ TT_F26Dot6 Dual_Project( EXEC_OP_ TT_Vector* v1,
+ TT_Vector* v2 )
+ {
+ return TT_MULDIV( v1->x - v2->x, CUR.GS.dualVector.x, 0x4000 ) +
+ TT_MULDIV( v1->y - v2->y, CUR.GS.dualVector.y, 0x4000 );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Free_Project */
+ /* */
+ /* <Description> */
+ /* Computes the projection of the vector given by (v2-v1) along the */
+ /* current freedom vector. */
+ /* */
+ /* <Input> */
+ /* v1 :: First input vector. */
+ /* v2 :: Second input vector. */
+ /* */
+ /* <Return> */
+ /* The distance in F26dot6 format. */
+ /* */
+ static
+ TT_F26Dot6 Free_Project( EXEC_OP_ TT_Vector* v1,
+ TT_Vector* v2 )
+ {
+ return TT_MULDIV( v1->x - v2->x, CUR.GS.freeVector.x, 0x4000 ) +
+ TT_MULDIV( v1->y - v2->y, CUR.GS.freeVector.y, 0x4000 );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Project_x */
+ /* */
+ /* <Description> */
+ /* Computes the projection of the vector given by (v2-v1) along the */
+ /* horizontal axis. */
+ /* */
+ /* <Input> */
+ /* v1 :: First input vector. */
+ /* v2 :: Second input vector. */
+ /* */
+ /* <Return> */
+ /* The distance in F26dot6 format. */
+ /* */
+ static
+ TT_F26Dot6 Project_x( EXEC_OP_ TT_Vector* v1,
+ TT_Vector* v2 )
+ {
+ UNUSED_EXEC;
+
+ return (v1->x - v2->x);
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Project_y */
+ /* */
+ /* <Description> */
+ /* Computes the projection of the vector given by (v2-v1) along the */
+ /* vertical axis. */
+ /* */
+ /* <Input> */
+ /* v1 :: First input vector. */
+ /* v2 :: Second input vector. */
+ /* */
+ /* <Return> */
+ /* The distance in F26dot6 format. */
+ /* */
+ static
+ TT_F26Dot6 Project_y( EXEC_OP_ TT_Vector* v1,
+ TT_Vector* v2 )
+ {
+ UNUSED_EXEC;
+
+ return (v1->y - v2->y);
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Compute_Funcs */
+ /* */
+ /* <Description> */
+ /* Computes the projection and movement function pointers according */
+ /* to the current graphics state. */
+ /* */
+ static
+ void Compute_Funcs( EXEC_OP )
+ {
+ if ( CUR.GS.freeVector.x == 0x4000 )
+ {
+ CUR.func_freeProj = (TT_Project_Func)Project_x;
+ CUR.F_dot_P = CUR.GS.projVector.x * 0x10000L;
+ }
+ else
+ {
+ if ( CUR.GS.freeVector.y == 0x4000 )
+ {
+ CUR.func_freeProj = (TT_Project_Func)Project_y;
+ CUR.F_dot_P = CUR.GS.projVector.y * 0x10000L;
+ }
+ else
+ {
+ CUR.func_freeProj = (TT_Project_Func)Free_Project;
+ CUR.F_dot_P = (TT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x * 4 +
+ (TT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y * 4;
+ }
+ }
+
+ if ( CUR.GS.projVector.x == 0x4000 )
+ CUR.func_project = (TT_Project_Func)Project_x;
+ else
+ {
+ if ( CUR.GS.projVector.y == 0x4000 )
+ CUR.func_project = (TT_Project_Func)Project_y;
+ else
+ CUR.func_project = (TT_Project_Func)Project;
+ }
+
+ if ( CUR.GS.dualVector.x == 0x4000 )
+ CUR.func_dualproj = (TT_Project_Func)Project_x;
+ else
+ {
+ if ( CUR.GS.dualVector.y == 0x4000 )
+ CUR.func_dualproj = (TT_Project_Func)Project_y;
+ else
+ CUR.func_dualproj = (TT_Project_Func)Dual_Project;
+ }
+
+ CUR.func_move = (TT_Move_Func)Direct_Move;
+
+ if ( CUR.F_dot_P == 0x40000000L )
+ {
+ if ( CUR.GS.freeVector.x == 0x4000 )
+ CUR.func_move = (TT_Move_Func)Direct_Move_X;
+ else
+ {
+ if ( CUR.GS.freeVector.y == 0x4000 )
+ CUR.func_move = (TT_Move_Func)Direct_Move_Y;
+ }
+ }
+
+ /* at small sizes, F_dot_P can become too small, resulting */
+ /* in overflows and `spikes' in a number of glyphs like `w'. */
+
+ if ( ABS( CUR.F_dot_P ) < 0x4000000L )
+ CUR.F_dot_P = 0x40000000L;
+
+ /* Disable cached aspect ratio */
+ CUR.tt_metrics.ratio = 0;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Normalize */
+ /* */
+ /* <Description> */
+ /* Norms a vector. */
+ /* */
+ /* <Input> */
+ /* Vx :: The horizontal input vector coordinate. */
+ /* Vy :: The vertical input vector coordinate. */
+ /* */
+ /* <Output> */
+ /* R :: The normed unit vector. */
+ /* */
+ /* <Return> */
+ /* Returns FAILURE if a vector parameter is zero. */
+ /* */
+ /* <Note> */
+ /* In case Vx and Vy are both zero, Normalize() returns SUCCESS, and */
+ /* R is undefined. */
+ /* */
+ static
+ TT_Bool Normalize( EXEC_OP_ TT_F26Dot6 Vx,
+ TT_F26Dot6 Vy,
+ TT_UnitVector* R )
+ {
+ TT_F26Dot6 u, v, d;
+ TT_Int shift;
+ TT_ULong H, L, L2, hi, lo, med;
+
+ u = ABS(Vx);
+ v = ABS(Vy);
+
+ if (u < v)
+ {
+ d = u;
+ u = v;
+ v = d;
+ }
+
+ R->x = 0;
+ R->y = 0;
+
+ /* check that we're not trying to normalise zero !! */
+ if (u==0) return SUCCESS;
+
+ /* compute (u*u+v*v) on 64 bits with two 32-bit registers [H:L] */
+ hi = (TT_ULong)u >> 16;
+ lo = (TT_ULong)u & 0xFFFF;
+ med = hi*lo;
+
+ H = hi*hi + (med >> 15);
+ med <<= 17;
+ L = lo*lo + med;
+ if (L < med) H++;
+
+ hi = (TT_ULong)v >> 16;
+ lo = (TT_ULong)v & 0xFFFF;
+ med = hi*lo;
+
+ H += hi*hi + (med >> 15);
+ med <<= 17;
+ L2 = lo*lo + med;
+ if (L2 < med) H++;
+
+ L += L2;
+ if (L < L2) H++;
+
+ /* if the value is smaller than 32-bits */
+ if (H == 0)
+ {
+ shift = 0;
+ while ((L & 0xC0000000) == 0)
+ {
+ L <<= 2;
+ shift++;
+ }
+
+ d = FT_Sqrt32(L);
+ R->x = (TT_F2Dot14)TT_MULDIV( Vx << shift, 0x4000, d );
+ R->y = (TT_F2Dot14)TT_MULDIV( Vy << shift, 0x4000, d );
+ }
+ /* if the value is greater than 64-bits */
+ else
+ {
+ shift = 0;
+ while (H)
+ {
+ L = (L >> 2) | (H << 30);
+ H >>= 2;
+ shift++;
+ }
+
+ d = FT_Sqrt32(L);
+ R->x = (TT_F2Dot14)TT_MULDIV( Vx >> shift, 0x4000, d );
+ R->y = (TT_F2Dot14)TT_MULDIV( Vy >> shift, 0x4000, d );
+ }
+
+ return SUCCESS;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* Here we start with the implementation of the various opcodes. */
+ /* */
+ /*************************************************************************/
+
+
+ static
+ TT_Bool Ins_SxVTL( EXEC_OP_ TT_UShort aIdx1,
+ TT_UShort aIdx2,
+ TT_Int aOpc,
+ TT_UnitVector* Vec )
+ {
+ TT_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 \
+ { \
+ TT_Short A, B; \
+ \
+ \
+ A = (TT_Short)(CUR.opcode & 1) << 14; \
+ B = A ^ (TT_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 \
+ { \
+ TT_Short A, B; \
+ \
+ \
+ A = (TT_Short)(CUR.opcode & 1) << 14; \
+ B = A ^ (TT_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 \
+ { \
+ TT_Short A, B; \
+ \
+ \
+ A = (TT_Short)(CUR.opcode & 1) << 14; \
+ B = A ^ (TT_Short)0x4000; \
+ \
+ CUR.GS.freeVector.x = A; \
+ CUR.GS.freeVector.y = B; \
+ \
+ COMPUTE_Funcs(); \
+ }
+
+
+#define DO_SPVTL \
+ if ( INS_SxVTL( (TT_UShort)args[1], \
+ (TT_UShort)args[0], \
+ CUR.opcode, \
+ &CUR.GS.projVector) == SUCCESS ) \
+ { \
+ CUR.GS.dualVector = CUR.GS.projVector; \
+ COMPUTE_Funcs(); \
+ }
+
+
+#define DO_SFVTL \
+ if ( INS_SxVTL( (TT_UShort)(args[1]), \
+ (TT_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 \
+ { \
+ TT_Short S; \
+ TT_Long X, Y; \
+ \
+ \
+ /* Only use low 16bits, then sign extend */ \
+ S = (TT_Short)args[1]; \
+ Y = (TT_Long)S; \
+ S = (TT_Short)args[0]; \
+ X = (TT_Long)S; \
+ \
+ NORMalize( X, Y, &CUR.GS.projVector ); \
+ \
+ CUR.GS.dualVector = CUR.GS.projVector; \
+ COMPUTE_Funcs(); \
+ }
+
+
+#define DO_SFVFS \
+ { \
+ TT_Short S; \
+ TT_Long X, Y; \
+ \
+ \
+ /* Only use low 16bits, then sign extend */ \
+ S = (TT_Short)args[1]; \
+ Y = (TT_Long)S; \
+ S = (TT_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 = (TT_UShort)(args[0]);
+
+
+#define DO_SRP1 \
+ CUR.GS.rp1 = (TT_UShort)(args[0]);
+
+
+#define DO_SRP2 \
+ CUR.GS.rp2 = (TT_UShort)(args[0]);
+
+
+#define DO_RTHG \
+ CUR.GS.round_state = TT_Round_To_Half_Grid; \
+ CUR.func_round = (TT_Round_Func)Round_To_Half_Grid;
+
+
+#define DO_RTG \
+ CUR.GS.round_state = TT_Round_To_Grid; \
+ CUR.func_round = (TT_Round_Func)Round_To_Grid;
+
+
+#define DO_RTDG \
+ CUR.GS.round_state = TT_Round_To_Double_Grid; \
+ CUR.func_round = (TT_Round_Func)Round_To_Double_Grid;
+
+
+#define DO_RUTG \
+ CUR.GS.round_state = TT_Round_Up_To_Grid; \
+ CUR.func_round = (TT_Round_Func)Round_Up_To_Grid;
+
+
+#define DO_RDTG \
+ CUR.GS.round_state = TT_Round_Down_To_Grid; \
+ CUR.func_round = (TT_Round_Func)Round_Down_To_Grid;
+
+
+#define DO_ROFF \
+ CUR.GS.round_state = TT_Round_Off; \
+ CUR.func_round = (TT_Round_Func)Round_None;
+
+
+#define DO_SROUND \
+ SET_SuperRound( 0x4000, args[0] ); \
+ CUR.GS.round_state = TT_Round_Super; \
+ CUR.func_round = (TT_Round_Func)Round_Super;
+
+
+#define DO_S45ROUND \
+ SET_SuperRound( 0x2D41, args[0] ); \
+ CUR.GS.round_state = TT_Round_Super_45; \
+ CUR.func_round = (TT_Round_Func)Round_Super_45;
+
+
+#define DO_SLOOP \
+ if ( args[0] < 0 ) \
+ CUR.error = TT_Err_Bad_Argument; \
+ else \
+ CUR.GS.loop = args[0];
+
+
+#define DO_SMD \
+ CUR.GS.minimum_distance = args[0];
+
+
+#define DO_SCVTCI \
+ CUR.GS.control_value_cutin = (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 = (TT_Short)args[0];
+
+
+#define DO_SDS \
+ CUR.GS.delta_shift = (TT_Short)args[0];
+
+
+#define DO_MD /* nothing */
+
+
+#define DO_MPPEM \
+ args[0] = CURRENT_Ppem();
+
+
+/* Note: the pointSize should be irrelevant in a given font program */
+/* we thus decide to return only the ppem */
+#if 0
+#define DO_MPS \
+ args[0] = CUR.metrics.pointSize;
+#else
+#define DO_MPS \
+ args[0] = CURRENT_Ppem();
+#endif
+
+#define DO_DUP \
+ args[1] = args[0];
+
+
+#define DO_CLEAR \
+ CUR.new_top = 0;
+
+
+#define DO_SWAP \
+ { \
+ TT_Long L; \
+ \
+ L = args[0]; \
+ args[0] = args[1]; \
+ args[1] = L; \
+ }
+
+
+#define DO_DEPTH \
+ args[0] = CUR.top;
+
+
+#define DO_CINDEX \
+ { \
+ TT_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 \
+ { \
+ TT_ULong I = (TT_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 \
+ { \
+ TT_ULong I = (TT_ULong)args[0]; \
+ \
+ \
+ if ( BOUNDS( I, CUR.storeSize ) ) \
+ { \
+ if ( CUR.pedantic_hinting ) \
+ { \
+ ARRAY_BOUND_ERROR; \
+ } \
+ } \
+ else \
+ CUR.storage[I] = args[1]; \
+ }
+
+
+#define DO_RCVT \
+ { \
+ TT_ULong I = (TT_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 \
+ { \
+ TT_ULong I = (TT_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 \
+ { \
+ TT_ULong I = (TT_ULong)args[0]; \
+ \
+ \
+ if ( BOUNDS( I, CUR.cvtSize ) ) \
+ { \
+ if ( CUR.pedantic_hinting ) \
+ { \
+ ARRAY_BOUND_ERROR; \
+ } \
+ } \
+ else \
+ CUR.cvt[I] = TT_MULFIX( args[1], CUR.tt_metrics.scale ); \
+ }
+
+
+#define DO_DEBUG \
+ CUR.error = TT_Err_Debug_OpCode;
+
+
+#define DO_ROUND \
+ args[0] = CUR_Func_round( \
+ args[0], \
+ CUR.tt_metrics.compensations[CUR.opcode - 0x68] );
+
+
+#define DO_NROUND \
+ args[0] = ROUND_None( args[0], \
+ CUR.tt_metrics.compensations[CUR.opcode - 0x6C] );
+
+
+#define DO_MAX \
+ if ( args[1] > args[0] ) \
+ args[0] = args[1];
+
+
+#define DO_MIN \
+ if ( args[1] < args[0] ) \
+ args[0] = args[1];
+
+
+#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH
+
+
+#undef ARRAY_BOUND_ERROR
+#define ARRAY_BOUND_ERROR \
+ { \
+ CUR.error = TT_Err_Invalid_Reference; \
+ return; \
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SVTCA[a]: Set (F and P) Vectors to Coordinate Axis */
+ /* Opcode range: 0x00-0x01 */
+ /* Stack: --> */
+ /* */
+ static
+ void Ins_SVTCA( INS_ARG )
+ {
+ DO_SVTCA
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SPVTCA[a]: Set PVector to Coordinate Axis */
+ /* Opcode range: 0x02-0x03 */
+ /* Stack: --> */
+ /* */
+ static
+ void Ins_SPVTCA( INS_ARG )
+ {
+ DO_SPVTCA
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SFVTCA[a]: Set FVector to Coordinate Axis */
+ /* Opcode range: 0x04-0x05 */
+ /* Stack: --> */
+ /* */
+ static
+ void Ins_SFVTCA( INS_ARG )
+ {
+ DO_SFVTCA
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SPVTL[a]: Set PVector To Line */
+ /* Opcode range: 0x06-0x07 */
+ /* Stack: uint32 uint32 --> */
+ /* */
+ static
+ void Ins_SPVTL( INS_ARG )
+ {
+ DO_SPVTL
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SFVTL[a]: Set FVector To Line */
+ /* Opcode range: 0x08-0x09 */
+ /* Stack: uint32 uint32 --> */
+ /* */
+ static
+ void Ins_SFVTL( INS_ARG )
+ {
+ DO_SFVTL
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SFVTPV[]: Set FVector To PVector */
+ /* Opcode range: 0x0E */
+ /* Stack: --> */
+ /* */
+ static
+ void Ins_SFVTPV( INS_ARG )
+ {
+ DO_SFVTPV
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SPVFS[]: Set PVector From Stack */
+ /* Opcode range: 0x0A */
+ /* Stack: f2.14 f2.14 --> */
+ /* */
+ static
+ void Ins_SPVFS( INS_ARG )
+ {
+ DO_SPVFS
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SFVFS[]: Set FVector From Stack */
+ /* Opcode range: 0x0B */
+ /* Stack: f2.14 f2.14 --> */
+ /* */
+ static
+ void Ins_SFVFS( INS_ARG )
+ {
+ DO_SFVFS
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* GPV[]: Get Projection Vector */
+ /* Opcode range: 0x0C */
+ /* Stack: ef2.14 --> ef2.14 */
+ /* */
+ static
+ void Ins_GPV( INS_ARG )
+ {
+ DO_GPV
+ }
+
+
+ /*************************************************************************/
+ /* GFV[]: Get Freedom Vector */
+ /* Opcode range: 0x0D */
+ /* Stack: ef2.14 --> ef2.14 */
+ /* */
+ static
+ void Ins_GFV( INS_ARG )
+ {
+ DO_GFV
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SRP0[]: Set Reference Point 0 */
+ /* Opcode range: 0x10 */
+ /* Stack: uint32 --> */
+ /* */
+ static
+ void Ins_SRP0( INS_ARG )
+ {
+ DO_SRP0
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SRP1[]: Set Reference Point 1 */
+ /* Opcode range: 0x11 */
+ /* Stack: uint32 --> */
+ /* */
+ static
+ void Ins_SRP1( INS_ARG )
+ {
+ DO_SRP1
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SRP2[]: Set Reference Point 2 */
+ /* Opcode range: 0x12 */
+ /* Stack: uint32 --> */
+ /* */
+ static
+ void Ins_SRP2( INS_ARG )
+ {
+ DO_SRP2
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* RTHG[]: Round To Half Grid */
+ /* Opcode range: 0x19 */
+ /* Stack: --> */
+ /* */
+ static
+ void Ins_RTHG( INS_ARG )
+ {
+ DO_RTHG
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* RTG[]: Round To Grid */
+ /* Opcode range: 0x18 */
+ /* Stack: --> */
+ /* */
+ static
+ void Ins_RTG( INS_ARG )
+ {
+ DO_RTG
+ }
+
+
+ /*************************************************************************/
+ /* RTDG[]: Round To Double Grid */
+ /* Opcode range: 0x3D */
+ /* Stack: --> */
+ /* */
+ static
+ void Ins_RTDG( INS_ARG )
+ {
+ DO_RTDG
+ }
+
+
+ /*************************************************************************/
+ /* RUTG[]: Round Up To Grid */
+ /* Opcode range: 0x7C */
+ /* Stack: --> */
+ /* */
+ static
+ void Ins_RUTG( INS_ARG )
+ {
+ DO_RUTG
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* RDTG[]: Round Down To Grid */
+ /* Opcode range: 0x7D */
+ /* Stack: --> */
+ /* */
+ static
+ void Ins_RDTG( INS_ARG )
+ {
+ DO_RDTG
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* ROFF[]: Round OFF */
+ /* Opcode range: 0x7A */
+ /* Stack: --> */
+ /* */
+ static
+ void Ins_ROFF( INS_ARG )
+ {
+ DO_ROFF
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SROUND[]: Super ROUND */
+ /* Opcode range: 0x76 */
+ /* Stack: Eint8 --> */
+ /* */
+ static
+ void Ins_SROUND( INS_ARG )
+ {
+ DO_SROUND
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* S45ROUND[]: Super ROUND 45 degrees */
+ /* Opcode range: 0x77 */
+ /* Stack: uint32 --> */
+ /* */
+ static
+ void Ins_S45ROUND( INS_ARG )
+ {
+ DO_S45ROUND
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SLOOP[]: Set LOOP variable */
+ /* Opcode range: 0x17 */
+ /* Stack: int32? --> */
+ /* */
+ static
+ void Ins_SLOOP( INS_ARG )
+ {
+ DO_SLOOP
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SMD[]: Set Minimum Distance */
+ /* Opcode range: 0x1A */
+ /* Stack: f26.6 --> */
+ /* */
+ static
+ void Ins_SMD( INS_ARG )
+ {
+ DO_SMD
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SCVTCI[]: Set Control Value Table Cut In */
+ /* Opcode range: 0x1D */
+ /* Stack: f26.6 --> */
+ /* */
+ static
+ void Ins_SCVTCI( INS_ARG )
+ {
+ DO_SCVTCI
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SSWCI[]: Set Single Width Cut In */
+ /* Opcode range: 0x1E */
+ /* Stack: f26.6 --> */
+ /* */
+ static
+ void Ins_SSWCI( INS_ARG )
+ {
+ DO_SSWCI
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SSW[]: Set Single Width */
+ /* Opcode range: 0x1F */
+ /* Stack: int32? --> */
+ /* */
+ static
+ void Ins_SSW( INS_ARG )
+ {
+ DO_SSW
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* FLIPON[]: Set auto-FLIP to ON */
+ /* Opcode range: 0x4D */
+ /* Stack: --> */
+ /* */
+ static
+ void Ins_FLIPON( INS_ARG )
+ {
+ DO_FLIPON
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* FLIPOFF[]: Set auto-FLIP to OFF */
+ /* Opcode range: 0x4E */
+ /* Stack: --> */
+ /* */
+ static
+ void Ins_FLIPOFF( INS_ARG )
+ {
+ DO_FLIPOFF
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SANGW[]: Set ANGle Weight */
+ /* Opcode range: 0x7E */
+ /* Stack: uint32 --> */
+ /* */
+ static
+ void Ins_SANGW( INS_ARG )
+ {
+ /* instruction not supported anymore */
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SDB[]: Set Delta Base */
+ /* Opcode range: 0x5E */
+ /* Stack: uint32 --> */
+ /* */
+ static
+ void Ins_SDB( INS_ARG )
+ {
+ DO_SDB
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SDS[]: Set Delta Shift */
+ /* Opcode range: 0x5F */
+ /* Stack: uint32 --> */
+ /* */
+ static
+ void Ins_SDS( INS_ARG )
+ {
+ DO_SDS
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* MPPEM[]: Measure Pixel Per EM */
+ /* Opcode range: 0x4B */
+ /* Stack: --> Euint16 */
+ /* */
+ static
+ void Ins_MPPEM( INS_ARG )
+ {
+ DO_MPPEM
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* MPS[]: Measure Point Size */
+ /* Opcode range: 0x4C */
+ /* Stack: --> Euint16 */
+ /* */
+ static
+ void Ins_MPS( INS_ARG )
+ {
+ DO_MPS
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* DUP[]: DUPlicate top stack element */
+ /* Opcode range: 0x20 */
+ /* Stack: StkElt --> StkElt StkElt */
+ /* */
+ static
+ void Ins_DUP( INS_ARG )
+ {
+ DO_DUP
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* POP[]: POP the stack's top elt */
+ /* Opcode range: 0x21 */
+ /* Stack: StkElt --> */
+ /* */
+ static
+ void Ins_POP( INS_ARG )
+ {
+ /* nothing to do */
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* CLEAR[]: CLEAR the entire stack */
+ /* Opcode range: 0x22 */
+ /* Stack: StkElt... --> */
+ /* */
+ static
+ void Ins_CLEAR( INS_ARG )
+ {
+ DO_CLEAR
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SWAP[]: SWAP the top two elements */
+ /* Opcode range: 0x23 */
+ /* Stack: 2 * StkElt --> 2 * StkElt */
+ /* */
+ static
+ void Ins_SWAP( INS_ARG )
+ {
+ DO_SWAP
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* DEPTH[]: return the stack DEPTH */
+ /* Opcode range: 0x24 */
+ /* Stack: --> uint32 */
+ /* */
+ static
+ void Ins_DEPTH( INS_ARG )
+ {
+ DO_DEPTH
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* CINDEX[]: Copy INDEXed element */
+ /* Opcode range: 0x25 */
+ /* Stack: int32 --> StkElt */
+ /* */
+ static
+ void Ins_CINDEX( INS_ARG )
+ {
+ DO_CINDEX
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* EIF[]: End IF */
+ /* Opcode range: 0x59 */
+ /* Stack: --> */
+ /* */
+ static
+ void Ins_EIF( INS_ARG )
+ {
+ /* nothing to do */
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* JROT[]: Jump Relative On True */
+ /* Opcode range: 0x78 */
+ /* Stack: StkElt int32 --> */
+ /* */
+ static
+ void Ins_JROT( INS_ARG )
+ {
+ DO_JROT
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* JMPR[]: JuMP Relative */
+ /* Opcode range: 0x1C */
+ /* Stack: int32 --> */
+ /* */
+ static
+ void Ins_JMPR( INS_ARG )
+ {
+ DO_JMPR
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* JROF[]: Jump Relative On False */
+ /* Opcode range: 0x79 */
+ /* Stack: StkElt int32 --> */
+ /* */
+ static
+ void Ins_JROF( INS_ARG )
+ {
+ DO_JROF
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* LT[]: Less Than */
+ /* Opcode range: 0x50 */
+ /* Stack: int32? int32? --> bool */
+ /* */
+ static
+ void Ins_LT( INS_ARG )
+ {
+ DO_LT
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* LTEQ[]: Less Than or EQual */
+ /* Opcode range: 0x51 */
+ /* Stack: int32? int32? --> bool */
+ /* */
+ static
+ void Ins_LTEQ( INS_ARG )
+ {
+ DO_LTEQ
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* GT[]: Greater Than */
+ /* Opcode range: 0x52 */
+ /* Stack: int32? int32? --> bool */
+ /* */
+ static
+ void Ins_GT( INS_ARG )
+ {
+ DO_GT
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* GTEQ[]: Greater Than or EQual */
+ /* Opcode range: 0x53 */
+ /* Stack: int32? int32? --> bool */
+ /* */
+ static
+ void Ins_GTEQ( INS_ARG )
+ {
+ DO_GTEQ
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* EQ[]: EQual */
+ /* Opcode range: 0x54 */
+ /* Stack: StkElt StkElt --> bool */
+ /* */
+ static
+ void Ins_EQ( INS_ARG )
+ {
+ DO_EQ
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* NEQ[]: Not EQual */
+ /* Opcode range: 0x55 */
+ /* Stack: StkElt StkElt --> bool */
+ /* */
+ static
+ void Ins_NEQ( INS_ARG )
+ {
+ DO_NEQ
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* ODD[]: Is ODD */
+ /* Opcode range: 0x56 */
+ /* Stack: f26.6 --> bool */
+ /* */
+ static
+ void Ins_ODD( INS_ARG )
+ {
+ DO_ODD
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* EVEN[]: Is EVEN */
+ /* Opcode range: 0x57 */
+ /* Stack: f26.6 --> bool */
+ /* */
+ static
+ void Ins_EVEN( INS_ARG )
+ {
+ DO_EVEN
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* AND[]: logical AND */
+ /* Opcode range: 0x5A */
+ /* Stack: uint32 uint32 --> uint32 */
+ /* */
+ static
+ void Ins_AND( INS_ARG )
+ {
+ DO_AND
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* OR[]: logical OR */
+ /* Opcode range: 0x5B */
+ /* Stack: uint32 uint32 --> uint32 */
+ /* */
+ static
+ void Ins_OR( INS_ARG )
+ {
+ DO_OR
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* NOT[]: logical NOT */
+ /* Opcode range: 0x5C */
+ /* Stack: StkElt --> uint32 */
+ /* */
+ static
+ void Ins_NOT( INS_ARG )
+ {
+ DO_NOT
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* ADD[]: ADD */
+ /* Opcode range: 0x60 */
+ /* Stack: f26.6 f26.6 --> f26.6 */
+ /* */
+ static
+ void Ins_ADD( INS_ARG )
+ {
+ DO_ADD
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SUB[]: SUBtract */
+ /* Opcode range: 0x61 */
+ /* Stack: f26.6 f26.6 --> f26.6 */
+ /* */
+ static
+ void Ins_SUB( INS_ARG )
+ {
+ DO_SUB
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* DIV[]: DIVide */
+ /* Opcode range: 0x62 */
+ /* Stack: f26.6 f26.6 --> f26.6 */
+ /* */
+ static
+ void Ins_DIV( INS_ARG )
+ {
+ DO_DIV
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* MUL[]: MULtiply */
+ /* Opcode range: 0x63 */
+ /* Stack: f26.6 f26.6 --> f26.6 */
+ /* */
+ static
+ void Ins_MUL( INS_ARG )
+ {
+ DO_MUL
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* ABS[]: ABSolute value */
+ /* Opcode range: 0x64 */
+ /* Stack: f26.6 --> f26.6 */
+ /* */
+ static
+ void Ins_ABS( INS_ARG )
+ {
+ DO_ABS
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* NEG[]: NEGate */
+ /* Opcode range: 0x65 */
+ /* Stack: f26.6 --> f26.6 */
+ /* */
+ static
+ void Ins_NEG( INS_ARG )
+ {
+ DO_NEG
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* FLOOR[]: FLOOR */
+ /* Opcode range: 0x66 */
+ /* Stack: f26.6 --> f26.6 */
+ /* */
+ static
+ void Ins_FLOOR( INS_ARG )
+ {
+ DO_FLOOR
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* CEILING[]: CEILING */
+ /* Opcode range: 0x67 */
+ /* Stack: f26.6 --> f26.6 */
+ /* */
+ static
+ void Ins_CEILING( INS_ARG )
+ {
+ DO_CEILING
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* RS[]: Read Store */
+ /* Opcode range: 0x43 */
+ /* Stack: uint32 --> uint32 */
+ /* */
+ static
+ void Ins_RS( INS_ARG )
+ {
+ DO_RS
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* WS[]: Write Store */
+ /* Opcode range: 0x42 */
+ /* Stack: uint32 uint32 --> */
+ /* */
+ static
+ void Ins_WS( INS_ARG )
+ {
+ DO_WS
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* WCVTP[]: Write CVT in Pixel units */
+ /* Opcode range: 0x44 */
+ /* Stack: f26.6 uint32 --> */
+ /* */
+ static
+ void Ins_WCVTP( INS_ARG )
+ {
+ DO_WCVTP
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* WCVTF[]: Write CVT in Funits */
+ /* Opcode range: 0x70 */
+ /* Stack: uint32 uint32 --> */
+ /* */
+ static
+ void Ins_WCVTF( INS_ARG )
+ {
+ DO_WCVTF
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* RCVT[]: Read CVT */
+ /* Opcode range: 0x45 */
+ /* Stack: uint32 --> f26.6 */
+ /* */
+ static
+ void Ins_RCVT( INS_ARG )
+ {
+ DO_RCVT
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* AA[]: Adjust Angle */
+ /* Opcode range: 0x7F */
+ /* Stack: uint32 --> */
+ /* */
+ static
+ void Ins_AA( INS_ARG )
+ {
+ /* Intentional - no longer supported */
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* DEBUG[]: DEBUG. Unsupported */
+ /* Opcode range: 0x4F */
+ /* Stack: uint32 --> */
+ /* */
+ /* Note: The original instruction pops a value from the stack */
+ /* */
+ static
+ void Ins_DEBUG( INS_ARG )
+ {
+ DO_DEBUG
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* ROUND[ab]: ROUND value */
+ /* Opcode range: 0x68-0x6B */
+ /* Stack: f26.6 --> f26.6 */
+ /* */
+ static
+ void Ins_ROUND( INS_ARG )
+ {
+ DO_ROUND
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* NROUND[ab]: No ROUNDing of value */
+ /* Opcode range: 0x6C-0x6F */
+ /* Stack: f26.6 --> f26.6 */
+ /* */
+ static
+ void Ins_NROUND( INS_ARG )
+ {
+ DO_NROUND
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* MAX[]: MAXimum */
+ /* Opcode range: 0x68 */
+ /* Stack: int32? int32? --> int32 */
+ /* */
+ static
+ void Ins_MAX( INS_ARG )
+ {
+ DO_MAX
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* MIN[]: MINimum */
+ /* Opcode range: 0x69 */
+ /* Stack: int32? int32? --> int32 */
+ /* */
+ static
+ void Ins_MIN( INS_ARG )
+ {
+ DO_MIN
+ }
+
+
+#endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */
+
+
+ /*************************************************************************/
+ /* */
+ /* The following functions are called as is within the switch statement. */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* MINDEX[]: Move INDEXed element */
+ /* Opcode range: 0x26 */
+ /* Stack: int32? --> StkElt */
+ /* */
+ static
+ void Ins_MINDEX( INS_ARG )
+ {
+ TT_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 ( TT_Long ) );
+
+ CUR.stack[CUR.args - 1] = K;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* ROLL[]: ROLL top three elements */
+ /* Opcode range: 0x8A */
+ /* Stack: 3 * StkElt --> 3 * StkElt */
+ /* */
+ static
+ void Ins_ROLL( INS_ARG )
+ {
+ TT_Long A, B, C;
+
+
+ UNUSED_EXEC;
+
+ A = args[2];
+ B = args[1];
+ C = args[0];
+
+ args[2] = C;
+ args[1] = A;
+ args[0] = B;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* MANAGING THE FLOW OF CONTROL */
+ /* */
+ /* Instructions appear in the specs' order. */
+ /* */
+ /*************************************************************************/
+
+
+ static
+ TT_Bool SkipCode( EXEC_OP )
+ {
+ CUR.IP += CUR.length;
+
+ if ( CUR.IP < CUR.codeSize )
+ {
+ CUR.opcode = CUR.code[CUR.IP];
+
+ CUR.length = opcode_length[CUR.opcode];
+ if ( CUR.length < 0 )
+ {
+ if ( CUR.IP + 1 > CUR.codeSize )
+ goto Fail_Overflow;
+ CUR.length = CUR.code[CUR.IP + 1] + 2;
+ }
+
+ if ( CUR.IP + CUR.length <= CUR.codeSize )
+ return SUCCESS;
+ }
+
+ Fail_Overflow:
+ CUR.error = TT_Err_Code_Overflow;
+ return FAILURE;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* IF[]: IF test */
+ /* Opcode range: 0x58 */
+ /* Stack: StkElt --> */
+ /* */
+ static
+ void Ins_IF( INS_ARG )
+ {
+ TT_Int nIfs;
+ TT_Bool Out;
+
+
+ if ( args[0] != 0 )
+ return;
+
+ nIfs = 1;
+ Out = 0;
+
+ do
+ {
+ if ( SKIP_Code() == FAILURE )
+ return;
+
+ switch ( CUR.opcode )
+ {
+ case 0x58: /* IF */
+ nIfs++;
+ break;
+
+ case 0x1B: /* ELSE */
+ Out = (nIfs == 1);
+ break;
+
+ case 0x59: /* EIF */
+ nIfs--;
+ Out = (nIfs == 0);
+ break;
+ }
+ } while ( Out == 0 );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* ELSE[]: ELSE */
+ /* Opcode range: 0x1B */
+ /* Stack: --> */
+ /* */
+ static
+ void Ins_ELSE( INS_ARG )
+ {
+ TT_Int nIfs;
+
+
+ UNUSED_ARG;
+
+ nIfs = 1;
+
+ do
+ {
+ if ( SKIP_Code() == FAILURE )
+ return;
+
+ switch ( CUR.opcode )
+ {
+ case 0x58: /* IF */
+ nIfs++;
+ break;
+
+ case 0x59: /* EIF */
+ nIfs--;
+ break;
+ }
+ } while ( nIfs != 0 );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS */
+ /* */
+ /* Instructions appear in the specs' order. */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* FDEF[]: Function DEFinition */
+ /* Opcode range: 0x2C */
+ /* Stack: uint32 --> */
+ /* */
+ static
+ void Ins_FDEF( INS_ARG )
+ {
+ TT_ULong n;
+ TT_DefRecord* rec;
+ TT_DefRecord* limit;
+
+ /* some font programs are broken enough to redefine functions! */
+ /* We will then parse the current table.. */
+ rec = CUR.FDefs;
+ limit = rec + CUR.numFDefs;
+ n = args[0];
+
+ for ( ; rec < limit; rec++ )
+ {
+ if (rec->opc == n)
+ break;
+ }
+
+ if ( rec == limit )
+ {
+ /* check that there is enough room for new functions */
+ if ( CUR.numFDefs >= CUR.maxFDefs )
+ {
+ CUR.error = TT_Err_Too_Many_Function_Defs;
+ return;
+ }
+ CUR.numFDefs++;
+ }
+
+ rec->range = CUR.curRange;
+ rec->opc = n;
+ rec->start = CUR.IP+1;
+ rec->active = TRUE;
+
+ if ( n > CUR.maxFunc )
+ CUR.maxFunc = n;
+
+ /* Now skip the whole function definition. */
+ /* We don't allow nested IDEFS & FDEFs. */
+
+ while ( SKIP_Code() == SUCCESS )
+ {
+ switch ( CUR.opcode )
+ {
+ case 0x89: /* IDEF */
+ case 0x2C: /* FDEF */
+ CUR.error = TT_Err_Nested_DEFS;
+ return;
+
+ case 0x2D: /* ENDF */
+ return;
+ }
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* ENDF[]: END Function definition */
+ /* Opcode range: 0x2D */
+ /* Stack: --> */
+ /* */
+ static
+ void Ins_ENDF( INS_ARG )
+ {
+ TT_CallRec* pRec;
+
+
+ UNUSED_ARG;
+
+ if ( CUR.callTop <= 0 ) /* We encountered an ENDF without a call */
+ {
+ CUR.error = TT_Err_ENDF_In_Exec_Stream;
+ return;
+ }
+
+ CUR.callTop--;
+
+ pRec = &CUR.callStack[CUR.callTop];
+
+ pRec->Cur_Count--;
+
+ CUR.step_ins = FALSE;
+
+ if ( pRec->Cur_Count > 0 )
+ {
+ CUR.callTop++;
+ CUR.IP = pRec->Cur_Restart;
+ }
+ else
+ /* Loop through the current function */
+ INS_Goto_CodeRange( pRec->Caller_Range,
+ pRec->Caller_IP );
+
+ /* Exit the current call frame. */
+
+ /* NOTE: 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 */
+ /* Opcode range: 0x2B */
+ /* Stack: uint32? --> */
+ /* */
+ static
+ void Ins_CALL( INS_ARG )
+ {
+ TT_ULong F;
+ TT_CallRec* pCrec;
+ TT_DefRecord* def;
+
+ /* first of all, check the index */
+ F = args[0];
+ if ( BOUNDS( F, CUR.maxFunc+1 ) ) goto Fail;
+
+ /* Except for some old Apple fonts, all functions in a TrueType */
+ /* font are defined in increasing order, starting from 0. This */
+ /* means that we normally have */
+ /* */
+ /* CUR.maxFunc+1 == CUR.numFDefs */
+ /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */
+ /* */
+ /* If this isn't true, we need to look up the function table. */
+
+ def = CUR.FDefs + F;
+ if ( CUR.maxFunc+1 != CUR.numFDefs || def->opc != F )
+ {
+ /* look up the FDefs table */
+ TT_DefRecord* limit;
+
+ def = CUR.FDefs;
+ limit = def + CUR.numFDefs;
+
+ while (def < limit && def->opc != F)
+ def++;
+
+ if (def == limit) goto Fail;
+ }
+
+ /* check that the function is active */
+ if (!def->active)
+ goto Fail;
+
+ /* check the call stack */
+ if ( CUR.callTop >= CUR.callSize )
+ {
+ CUR.error = TT_Err_Stack_Overflow;
+ return;
+ }
+
+ pCrec = CUR.callStack + CUR.callTop;
+
+ pCrec->Caller_Range = CUR.curRange;
+ pCrec->Caller_IP = CUR.IP + 1;
+ pCrec->Cur_Count = 1;
+ pCrec->Cur_Restart = def->start;
+
+ CUR.callTop++;
+
+ INS_Goto_CodeRange( def->range,
+ def->start );
+
+ CUR.step_ins = FALSE;
+ return;
+
+ Fail:
+ CUR.error = TT_Err_Invalid_Reference;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* LOOPCALL[]: LOOP and CALL function */
+ /* Opcode range: 0x2A */
+ /* Stack: uint32? Eint16? --> */
+ /* */
+ static
+ void Ins_LOOPCALL( INS_ARG )
+ {
+ TT_ULong F;
+ TT_CallRec* pCrec;
+ TT_DefRecord* def;
+
+ /* first of all, check the index */
+ F = args[1];
+ if ( BOUNDS( F, CUR.maxFunc+1 ) ) goto Fail;
+
+ /* Except for some old Apple fonts, all functions in a TrueType */
+ /* font are defined in increasing order, starting from 0. This */
+ /* means that we normally have */
+ /* */
+ /* CUR.maxFunc+1 == CUR.numFDefs */
+ /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */
+ /* */
+ /* If this isn't true, we need to look up the function table. */
+
+ def = CUR.FDefs + F;
+ if ( CUR.maxFunc+1 != CUR.numFDefs || def->opc != F )
+ {
+ /* look up the FDefs table */
+ TT_DefRecord* limit;
+
+ def = CUR.FDefs;
+ limit = def + CUR.numFDefs;
+
+ while (def < limit && def->opc != F)
+ def++;
+
+ if (def == limit) goto Fail;
+ }
+
+ /* check that the function is active */
+ if (!def->active)
+ goto Fail;
+
+ /* check stack */
+ if ( CUR.callTop >= CUR.callSize )
+ {
+ CUR.error = TT_Err_Stack_Overflow;
+ return;
+ }
+
+ if ( args[0] > 0 )
+ {
+ pCrec = CUR.callStack + CUR.callTop;
+
+ pCrec->Caller_Range = CUR.curRange;
+ pCrec->Caller_IP = CUR.IP + 1;
+ pCrec->Cur_Count = (TT_Int)(args[0]);
+ pCrec->Cur_Restart = def->start;
+
+ CUR.callTop++;
+
+ INS_Goto_CodeRange( def->range, def->start );
+
+ CUR.step_ins = FALSE;
+ }
+ return;
+
+ Fail:
+ CUR.error = TT_Err_Invalid_Reference;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* IDEF[]: Instruction DEFinition */
+ /* Opcode range: 0x89 */
+ /* Stack: Eint8 --> */
+ /* */
+ static
+ void Ins_IDEF( INS_ARG )
+ {
+ TT_DefRecord* def;
+ TT_DefRecord* limit;
+
+ /* First of all, look for the same function in our table */
+ def = CUR.IDefs;
+ limit = def + CUR.numIDefs;
+ for ( ; def < limit; def++ )
+ if (def->opc == (TT_ULong)args[0] )
+ break;
+
+ if ( def == limit )
+ {
+ /* check that there is enough room for a new instruction */
+ if ( CUR.numIDefs >= CUR.maxIDefs )
+ {
+ CUR.error = TT_Err_Too_Many_Instruction_Defs;
+ return;
+ }
+ CUR.numIDefs++;
+ }
+
+ def->opc = args[0];
+ def->start = CUR.IP+1;
+ def->range = CUR.curRange;
+ def->active = TRUE;
+
+ if ( (TT_ULong)args[0] > CUR.maxIns )
+ CUR.maxIns = args[0];
+
+ /* Now skip the whole function definition. */
+ /* We don't allow nested IDEFs & FDEFs. */
+
+ while ( SKIP_Code() == SUCCESS )
+ {
+ switch ( CUR.opcode )
+ {
+ case 0x89: /* IDEF */
+ case 0x2C: /* FDEF */
+ CUR.error = TT_Err_Nested_DEFS;
+ return;
+ case 0x2D: /* ENDF */
+ return;
+ }
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* PUSHING DATA ONTO THE INTERPRETER STACK */
+ /* */
+ /* Instructions appear in the specs' order. */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* NPUSHB[]: PUSH N Bytes */
+ /* Opcode range: 0x40 */
+ /* Stack: --> uint32... */
+ /* */
+ static
+ void Ins_NPUSHB( INS_ARG )
+ {
+ TT_UShort L, K;
+
+
+ L = (TT_UShort)CUR.code[CUR.IP + 1];
+
+ if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
+ {
+ CUR.error = TT_Err_Stack_Overflow;
+ return;
+ }
+
+ for ( K = 1; K <= L; K++ )
+ args[K - 1] = CUR.code[CUR.IP + K + 1];
+
+ CUR.new_top += L;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* NPUSHW[]: PUSH N Words */
+ /* Opcode range: 0x41 */
+ /* Stack: --> int32... */
+ /* */
+ static
+ void Ins_NPUSHW( INS_ARG )
+ {
+ TT_UShort L, K;
+
+
+ L = (TT_UShort)CUR.code[CUR.IP + 1];
+
+ if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
+ {
+ CUR.error = TT_Err_Stack_Overflow;
+ return;
+ }
+
+ CUR.IP += 2;
+
+ for ( K = 0; K < L; K++ )
+ args[K] = GET_ShortIns();
+
+ CUR.step_ins = FALSE;
+ CUR.new_top += L;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* PUSHB[abc]: PUSH Bytes */
+ /* Opcode range: 0xB0-0xB7 */
+ /* Stack: --> uint32... */
+ /* */
+ static
+ void Ins_PUSHB( INS_ARG )
+ {
+ TT_UShort L, K;
+
+
+ L = (TT_UShort)CUR.opcode - 0xB0 + 1;
+
+ if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
+ {
+ CUR.error = TT_Err_Stack_Overflow;
+ return;
+ }
+
+ for ( K = 1; K <= L; K++ )
+ args[K - 1] = CUR.code[CUR.IP + K];
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* PUSHW[abc]: PUSH Words */
+ /* Opcode range: 0xB8-0xBF */
+ /* Stack: --> int32... */
+ /* */
+ static
+ void Ins_PUSHW( INS_ARG )
+ {
+ TT_UShort L, K;
+
+
+ L = (TT_UShort)CUR.opcode - 0xB8 + 1;
+
+ if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
+ {
+ CUR.error = TT_Err_Stack_Overflow;
+ return;
+ }
+
+ CUR.IP++;
+
+ for ( K = 0; K < L; K++ )
+ args[K] = GET_ShortIns();
+
+ CUR.step_ins = FALSE;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* MANAGING THE GRAPHICS STATE */
+ /* */
+ /* Instructions appear in the specs' order. */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* GC[a]: Get Coordinate projected onto */
+ /* Opcode range: 0x46-0x47 */
+ /* Stack: uint32 --> f26.6 */
+ /* */
+ /* BULLSHIT: Measures from the original glyph must be taken along the */
+ /* dual projection vector! */
+ /* */
+ static void Ins_GC( INS_ARG )
+ {
+ TT_ULong L;
+ TT_F26Dot6 R;
+
+
+ L = (TT_ULong)args[0];
+
+ if ( BOUNDS( L, CUR.zp2.n_points ) )
+ {
+ if ( CUR.pedantic_hinting )
+ {
+ CUR.error = TT_Err_Invalid_Reference;
+ return;
+ }
+ else
+ R = 0;
+ }
+ else
+ {
+ if ( CUR.opcode & 1 )
+ R = CUR_Func_dualproj( CUR.zp2.org + L, NULL_Vector );
+ else
+ R = CUR_Func_project( CUR.zp2.cur + L, NULL_Vector );
+ }
+
+ args[0] = R;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SCFS[]: Set Coordinate From Stack */
+ /* Opcode range: 0x48 */
+ /* Stack: f26.6 uint32 --> */
+ /* */
+ /* Formula: */
+ /* */
+ /* OA := OA + ( value - OA.p )/( f.p ) * f */
+ /* */
+ static
+ void Ins_SCFS( INS_ARG )
+ {
+ TT_Long K;
+ TT_UShort L;
+
+
+ L = (TT_UShort)args[0];
+
+ if ( BOUNDS( L, CUR.zp2.n_points ) )
+ {
+ if ( CUR.pedantic_hinting )
+ CUR.error = TT_Err_Invalid_Reference;
+ return;
+ }
+
+ K = CUR_Func_project( CUR.zp2.cur + L, NULL_Vector );
+
+ CUR_Func_move( &CUR.zp2, L, args[1] - K );
+
+ /* not part of the specs, but here for safety */
+
+ if ( CUR.GS.gep2 == 0 )
+ CUR.zp2.org[L] = CUR.zp2.cur[L];
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* MD[a]: Measure Distance */
+ /* Opcode range: 0x49-0x4A */
+ /* Stack: uint32 uint32 --> f26.6 */
+ /* */
+ /* BULLSHIT: Measure taken in the original glyph must be along the dual */
+ /* projection vector. */
+ /* */
+ /* Second BULLSHIT: Flag attributes are inverted! */
+ /* 0 => measure distance in original outline */
+ /* 1 => measure distance in grid-fitted outline */
+ /* */
+ /* Third one: `zp0 - zp1', and not `zp2 - zp1! */
+ /* */
+ static
+ void Ins_MD( INS_ARG )
+ {
+ TT_UShort K, L;
+ TT_F26Dot6 D;
+
+
+ K = (TT_UShort)args[1];
+ L = (TT_UShort)args[0];
+
+ if( BOUNDS( L, CUR.zp0.n_points ) ||
+ BOUNDS( K, CUR.zp1.n_points ) )
+ {
+ if ( CUR.pedantic_hinting )
+ {
+ CUR.error = TT_Err_Invalid_Reference;
+ return;
+ }
+ D = 0;
+ }
+ else
+ {
+ if ( CUR.opcode & 1 )
+ D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K );
+ else
+ D = CUR_Func_dualproj( CUR.zp0.org + L, CUR.zp1.org + K );
+ }
+
+ args[0] = D;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SDPVTL[a]: Set Dual PVector to Line */
+ /* Opcode range: 0x86-0x87 */
+ /* Stack: uint32 uint32 --> */
+ /* */
+ static
+ void Ins_SDPVTL( INS_ARG )
+ {
+ TT_Long A, B, C;
+ TT_UShort p1, p2; /* was TT_Int in pas type ERROR */
+
+
+ p1 = (TT_UShort)args[1];
+ p2 = (TT_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 */
+ /* Opcode range: 0x13 */
+ /* Stack: uint32 --> */
+ /* */
+ static
+ void Ins_SZP0( INS_ARG )
+ {
+ switch ( (TT_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 = (TT_UShort)(args[0]);
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SZP1[]: Set Zone Pointer 1 */
+ /* Opcode range: 0x14 */
+ /* Stack: uint32 --> */
+ /* */
+ static
+ void Ins_SZP1( INS_ARG )
+ {
+ switch ( (TT_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 = (TT_UShort)(args[0]);
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SZP2[]: Set Zone Pointer 2 */
+ /* Opcode range: 0x15 */
+ /* Stack: uint32 --> */
+ /* */
+ static
+ void Ins_SZP2( INS_ARG )
+ {
+ switch ( (TT_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 = (TT_UShort)(args[0]);
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SZPS[]: Set Zone PointerS */
+ /* Opcode range: 0x16 */
+ /* Stack: uint32 --> */
+ /* */
+ static
+ void Ins_SZPS( INS_ARG )
+ {
+ switch ( (TT_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 = (TT_UShort)(args[0]);
+ CUR.GS.gep1 = (TT_UShort)(args[0]);
+ CUR.GS.gep2 = (TT_UShort)(args[0]);
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* INSTCTRL[]: INSTruction ConTRoL */
+ /* Opcode range: 0x8e */
+ /* Stack: int32 int32 --> */
+ /* */
+ static
+ void Ins_INSTCTRL( INS_ARG )
+ {
+ TT_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 =
+ (TT_Byte)( CUR.GS.instruct_control & ~(TT_Byte)K ) | (TT_Byte)L;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SCANCTRL[]: SCAN ConTRoL */
+ /* Opcode range: 0x85 */
+ /* Stack: uint32? --> */
+ /* */
+ static
+ void Ins_SCANCTRL( INS_ARG )
+ {
+ TT_Int A;
+
+
+ /* Get Threshold */
+ A = (TT_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.tt_metrics.rotated )
+ CUR.GS.scan_control = TRUE;
+
+ if ( (args[0] & 0x400) != 0 && CUR.tt_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.tt_metrics.rotated )
+ CUR.GS.scan_control = FALSE;
+
+ if ( (args[0] & 0x2000) != 0 && CUR.tt_metrics.stretched )
+ CUR.GS.scan_control = FALSE;
+}
+
+
+ /*************************************************************************/
+ /* */
+ /* SCANTYPE[]: SCAN TYPE */
+ /* Opcode range: 0x8D */
+ /* Stack: uint32? --> */
+ /* */
+ static
+ void Ins_SCANTYPE( INS_ARG )
+ {
+ /* For compatibility with future enhancements, */
+ /* we must ignore new modes */
+
+ if ( args[0] >= 0 && args[0] <= 5 )
+ {
+ if ( args[0] == 3 )
+ args[0] = 2;
+
+ CUR.GS.scan_type = (TT_Int)args[0];
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* MANAGING OUTLINES */
+ /* */
+ /* Instructions appear in the specs' order. */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* FLIPPT[]: FLIP PoinT */
+ /* Opcode range: 0x80 */
+ /* Stack: uint32... --> */
+ /* */
+ static
+ void Ins_FLIPPT( INS_ARG )
+ {
+ TT_UShort point;
+
+
+ UNUSED_ARG;
+
+ if ( CUR.top < CUR.GS.loop )
+ {
+ CUR.error = TT_Err_Too_Few_Arguments;
+ return;
+ }
+
+ while ( CUR.GS.loop > 0 )
+ {
+ CUR.args--;
+
+ point = (TT_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] ^= FT_Curve_Tag_On;
+
+ CUR.GS.loop--;
+ }
+
+ CUR.GS.loop = 1;
+ CUR.new_top = CUR.args;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* FLIPRGON[]: FLIP RanGe ON */
+ /* Opcode range: 0x81 */
+ /* Stack: uint32 uint32 --> */
+ /* */
+ static
+ void Ins_FLIPRGON( INS_ARG )
+ {
+ TT_UShort I, K, L;
+
+
+ K = (TT_UShort)args[1];
+ L = (TT_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] |= FT_Curve_Tag_On;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* FLIPRGOFF: FLIP RanGe OFF */
+ /* Opcode range: 0x82 */
+ /* Stack: uint32 uint32 --> */
+ /* */
+ static
+ void Ins_FLIPRGOFF( INS_ARG )
+ {
+ TT_UShort I, K, L;
+
+
+ K = (TT_UShort)args[1];
+ L = (TT_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] &= ~FT_Curve_Tag_On;
+ }
+
+
+ static
+ TT_Bool Compute_Point_Displacement( EXEC_OP_ TT_F26Dot6* x,
+ TT_F26Dot6* y,
+ TT_GlyphZone* zone,
+ TT_UShort* refp )
+ {
+ TT_GlyphZone zp;
+ TT_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_Reference;
+ return FAILURE;
+ }
+
+ *zone = zp;
+ *refp = p;
+
+ d = CUR_Func_project( zp.cur + p, zp.org + p );
+
+ *x = TT_MULDIV( d,
+ (TT_Long)CUR.GS.freeVector.x * 0x10000L,
+ CUR.F_dot_P );
+ *y = TT_MULDIV( d,
+ (TT_Long)CUR.GS.freeVector.y * 0x10000L,
+ CUR.F_dot_P );
+
+ return SUCCESS;
+ }
+
+
+ static
+ void Move_Zp2_Point( EXEC_OP_ TT_UShort point,
+ TT_F26Dot6 dx,
+ TT_F26Dot6 dy,
+ TT_Bool touch )
+ {
+ if ( CUR.GS.freeVector.x != 0 )
+ {
+ CUR.zp2.cur[point].x += dx;
+ if ( touch )
+ CUR.zp2.touch[point] |= FT_Curve_Tag_Touch_X;
+ }
+
+ if ( CUR.GS.freeVector.y != 0 )
+ {
+ CUR.zp2.cur[point].y += dy;
+ if ( touch )
+ CUR.zp2.touch[point] |= FT_Curve_Tag_Touch_Y;
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SHP[a]: SHift Point by the last point */
+ /* Opcode range: 0x32-0x33 */
+ /* Stack: uint32... --> */
+ /* */
+ static
+ void Ins_SHP( INS_ARG )
+ {
+ TT_GlyphZone zp;
+ TT_UShort refp;
+
+ TT_F26Dot6 dx,
+ dy;
+ TT_UShort point;
+
+
+ UNUSED_ARG;
+
+ if ( CUR.top < CUR.GS.loop )
+ {
+ CUR.error = TT_Err_Invalid_Reference;
+ return;
+ }
+
+ if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )
+ return;
+
+ while ( CUR.GS.loop > 0 )
+ {
+ CUR.args--;
+ point = (TT_UShort)CUR.stack[CUR.args];
+
+ if ( BOUNDS( point, CUR.zp2.n_points ) )
+ {
+ if ( CUR.pedantic_hinting )
+ {
+ CUR.error = TT_Err_Invalid_Reference;
+ return;
+ }
+ }
+ else
+ /* XXX: UNDOCUMENTED! SHP touches the points */
+ MOVE_Zp2_Point( point, dx, dy, TRUE );
+
+ CUR.GS.loop--;
+ }
+
+ CUR.GS.loop = 1;
+ CUR.new_top = CUR.args;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SHC[a]: SHift Contour */
+ /* Opcode range: 0x34-35 */
+ /* Stack: uint32 --> */
+ /* */
+ static
+ void Ins_SHC( INS_ARG )
+ {
+ TT_GlyphZone zp;
+ TT_UShort refp;
+ TT_F26Dot6 dx,
+ dy;
+
+ TT_Short contour;
+ TT_UShort first_point, last_point, i;
+
+
+ contour = (TT_UShort)args[0];
+
+ if ( BOUNDS( contour, CUR.pts.n_contours ) )
+ {
+ if ( CUR.pedantic_hinting )
+ CUR.error = TT_Err_Invalid_Reference;
+ return;
+ }
+
+ if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )
+ return;
+
+ if ( contour == 0 )
+ first_point = 0;
+ else
+ first_point = CUR.pts.contours[contour - 1] + 1;
+
+ last_point = CUR.pts.contours[contour];
+
+ /* XXX: this is probably wrong... at least it prevents memory */
+ /* corruption when zp2 is the twilight zone */
+ if ( last_point > CUR.zp2.n_points )
+ {
+ if ( CUR.zp2.n_points > 0 )
+ last_point = CUR.zp2.n_points - 1;
+ else
+ last_point = 0;
+ }
+
+ /* XXX: UNDOCUMENTED! SHC doesn't touch the points */
+ for ( i = first_point; i <= last_point; i++ )
+ {
+ if ( zp.cur != CUR.zp2.cur || refp != i )
+ MOVE_Zp2_Point( i, dx, dy, FALSE );
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SHZ[a]: SHift Zone */
+ /* Opcode range: 0x36-37 */
+ /* Stack: uint32 --> */
+ /* */
+ static
+ void Ins_SHZ( INS_ARG )
+ {
+ TT_GlyphZone zp;
+ TT_UShort refp;
+ TT_F26Dot6 dx,
+ dy;
+
+ TT_UShort last_point, i;
+
+
+ if ( BOUNDS( args[0], 2 ) )
+ {
+ if ( CUR.pedantic_hinting )
+ CUR.error = TT_Err_Invalid_Reference;
+ return;
+ }
+
+ if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )
+ return;
+
+ if ( CUR.zp2.n_points > 0 )
+ last_point = CUR.zp2.n_points - 1;
+ else
+ last_point = 0;
+
+ /* XXX: UNDOCUMENTED! SHZ doesn't touch the points */
+ for ( i = 0; i <= last_point; i++ )
+ {
+ if ( zp.cur != CUR.zp2.cur || refp != i )
+ MOVE_Zp2_Point( i, dx, dy, FALSE );
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SHPIX[]: SHift points by a PIXel amount */
+ /* Opcode range: 0x38 */
+ /* Stack: f26.6 uint32... --> */
+ /* */
+ static
+ void Ins_SHPIX( INS_ARG )
+ {
+ TT_F26Dot6 dx, dy;
+ TT_UShort point;
+
+
+ if ( CUR.top < CUR.GS.loop + 1 )
+ {
+ CUR.error = TT_Err_Invalid_Reference;
+ return;
+ }
+
+ dx = TT_MULDIV( args[0],
+ (TT_Long)CUR.GS.freeVector.x,
+ 0x4000 );
+ dy = TT_MULDIV( args[0],
+ (TT_Long)CUR.GS.freeVector.y,
+ 0x4000 );
+
+ while ( CUR.GS.loop > 0 )
+ {
+ CUR.args--;
+
+ point = (TT_UShort)CUR.stack[CUR.args];
+
+ if ( BOUNDS( point, CUR.zp2.n_points ) )
+ {
+ if ( CUR.pedantic_hinting )
+ {
+ CUR.error = TT_Err_Invalid_Reference;
+ return;
+ }
+ }
+ else
+ MOVE_Zp2_Point( point, dx, dy, TRUE );
+
+ CUR.GS.loop--;
+ }
+
+ CUR.GS.loop = 1;
+ CUR.new_top = CUR.args;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* MSIRP[a]: Move Stack Indirect Relative Position */
+ /* Opcode range: 0x3A-0x3B */
+ /* Stack: f26.6 uint32 --> */
+ /* */
+ static
+ void Ins_MSIRP( INS_ARG )
+ {
+ TT_UShort point;
+ TT_F26Dot6 distance;
+
+
+ point = (TT_UShort)args[0];
+
+ if ( BOUNDS( point, CUR.zp1.n_points ) ||
+ BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
+ {
+ if ( CUR.pedantic_hinting )
+ CUR.error = TT_Err_Invalid_Reference;
+ return;
+ }
+
+ /* XXX: UNDOCUMENTED! behaviour */
+ if ( CUR.GS.gep0 == 0 ) /* if in twilight zone */
+ {
+ CUR.zp1.org[point] = CUR.zp0.org[CUR.GS.rp0];
+ CUR.zp1.cur[point] = CUR.zp1.org[point];
+ }
+
+ distance = CUR_Func_project( CUR.zp1.cur + point,
+ CUR.zp0.cur + CUR.GS.rp0 );
+
+ CUR_Func_move( &CUR.zp1, point, args[1] - distance );
+
+ CUR.GS.rp1 = CUR.GS.rp0;
+ CUR.GS.rp2 = point;
+
+ if ( (CUR.opcode & 1) != 0 )
+ CUR.GS.rp0 = point;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* MDAP[a]: Move Direct Absolute Point */
+ /* Opcode range: 0x2E-0x2F */
+ /* Stack: uint32 --> */
+ /* */
+ static
+ void Ins_MDAP( INS_ARG )
+ {
+ TT_UShort point;
+ TT_F26Dot6 cur_dist,
+ distance;
+
+
+ point = (TT_UShort)args[0];
+
+ if ( BOUNDS( point, CUR.zp0.n_points ) )
+ {
+ if ( CUR.pedantic_hinting )
+ CUR.error = TT_Err_Invalid_Reference;
+ return;
+ }
+
+ /* XXX: Is there some undocumented feature while in the */
+ /* twilight zone? ? */
+ if ( (CUR.opcode & 1) != 0 )
+ {
+ cur_dist = CUR_Func_project( CUR.zp0.cur + point, NULL_Vector );
+ distance = CUR_Func_round( cur_dist,
+ CUR.tt_metrics.compensations[0] ) - cur_dist;
+ }
+ else
+ distance = 0;
+
+ CUR_Func_move( &CUR.zp0, point, distance );
+
+ CUR.GS.rp0 = point;
+ CUR.GS.rp1 = point;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* MIAP[a]: Move Indirect Absolute Point */
+ /* Opcode range: 0x3E-0x3F */
+ /* Stack: uint32 uint32 --> */
+ /* */
+ static
+ void Ins_MIAP( INS_ARG )
+ {
+ TT_ULong cvtEntry;
+ TT_UShort point;
+ TT_F26Dot6 distance,
+ org_dist;
+
+
+ cvtEntry = (TT_ULong)args[1];
+ point = (TT_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, 0x4000 );
+ CUR.zp0.org[point].y = TT_MULDIV( CUR.GS.freeVector.y,
+ distance, 0x4000 );
+ CUR.zp0.cur[point] = CUR.zp0.org[point];
+ }
+
+ org_dist = CUR_Func_project( CUR.zp0.cur + point, NULL_Vector );
+
+ if ( (CUR.opcode & 1) != 0 ) /* rounding and control cutin flag */
+ {
+ if ( ABS( distance - org_dist ) > CUR.GS.control_value_cutin )
+ distance = org_dist;
+
+ distance = CUR_Func_round( distance, CUR.tt_metrics.compensations[0] );
+ }
+
+ CUR_Func_move( &CUR.zp0, point, distance - org_dist );
+
+ CUR.GS.rp0 = point;
+ CUR.GS.rp1 = point;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* MDRP[abcde]: Move Direct Relative Point */
+ /* Opcode range: 0xC0-0xDF */
+ /* Stack: uint32 --> */
+ /* */
+ static
+ void Ins_MDRP( INS_ARG )
+ {
+ TT_UShort point;
+ TT_F26Dot6 org_dist, distance;
+
+
+ point = (TT_UShort)args[0];
+
+ if ( BOUNDS( point, CUR.zp1.n_points ) ||
+ BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
+ {
+ if ( CUR.pedantic_hinting )
+ CUR.error = TT_Err_Invalid_Reference;
+ return;
+ }
+
+ /* XXX: Is there some undocumented feature while in the */
+ /* twilight zone? */
+
+ org_dist = CUR_Func_dualproj( CUR.zp1.org + point,
+ CUR.zp0.org + CUR.GS.rp0 );
+
+ /* single width cutin test */
+
+ if ( ABS( org_dist ) < CUR.GS.single_width_cutin )
+ {
+ if ( org_dist >= 0 )
+ org_dist = CUR.GS.single_width_value;
+ else
+ org_dist = -CUR.GS.single_width_value;
+ }
+
+ /* round flag */
+
+ if ( (CUR.opcode & 4) != 0 )
+ distance = CUR_Func_round( org_dist,
+ CUR.tt_metrics.compensations[CUR.opcode & 3] );
+ else
+ distance = ROUND_None( org_dist,
+ CUR.tt_metrics.compensations[CUR.opcode & 3] );
+
+ /* minimum distance flag */
+
+ if ( (CUR.opcode & 8) != 0 )
+ {
+ if ( org_dist >= 0 )
+ {
+ if ( distance < CUR.GS.minimum_distance )
+ distance = CUR.GS.minimum_distance;
+ }
+ else
+ {
+ if ( distance > -CUR.GS.minimum_distance )
+ distance = -CUR.GS.minimum_distance;
+ }
+ }
+
+ /* now move the point */
+
+ org_dist = CUR_Func_project( CUR.zp1.cur + point,
+ CUR.zp0.cur + CUR.GS.rp0 );
+
+ CUR_Func_move( &CUR.zp1, point, distance - org_dist );
+
+ CUR.GS.rp1 = CUR.GS.rp0;
+ CUR.GS.rp2 = point;
+
+ if ( (CUR.opcode & 16) != 0 )
+ CUR.GS.rp0 = point;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* MIRP[abcde]: Move Indirect Relative Point */
+ /* Opcode range: 0xE0-0xFF */
+ /* Stack: int32? uint32 --> */
+ /* */
+ static
+ void Ins_MIRP( INS_ARG )
+ {
+ TT_UShort point;
+ TT_ULong cvtEntry;
+
+ TT_F26Dot6 cvt_dist,
+ distance,
+ cur_dist,
+ org_dist;
+
+
+ point = (TT_UShort)args[0];
+ cvtEntry = (TT_ULong)(args[1] + 1);
+
+ /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */
+
+ if ( BOUNDS( point, CUR.zp1.n_points ) ||
+ BOUNDS( cvtEntry, CUR.cvtSize + 1 ) ||
+ BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
+ {
+ if ( CUR.pedantic_hinting )
+ CUR.error = TT_Err_Invalid_Reference;
+ return;
+ }
+
+ if ( !cvtEntry )
+ cvt_dist = 0;
+ else
+ cvt_dist = CUR_Func_read_cvt( cvtEntry - 1 );
+
+ /* single width test */
+
+ if ( ABS( cvt_dist ) < CUR.GS.single_width_cutin )
+ {
+ if ( cvt_dist >= 0 )
+ cvt_dist = CUR.GS.single_width_value;
+ else
+ cvt_dist = -CUR.GS.single_width_value;
+ }
+
+ /* XXX: UNDOCUMENTED! -- twilight zone */
+
+ if ( CUR.GS.gep1 == 0 )
+ {
+ CUR.zp1.org[point].x = CUR.zp0.org[CUR.GS.rp0].x +
+ TT_MULDIV( cvt_dist,
+ CUR.GS.freeVector.x,
+ 0x4000 );
+
+ CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y +
+ TT_MULDIV( cvt_dist,
+ CUR.GS.freeVector.y,
+ 0x4000 );
+
+ CUR.zp1.cur[point] = CUR.zp1.org[point];
+ }
+
+ org_dist = CUR_Func_dualproj( CUR.zp1.org + point,
+ CUR.zp0.org + CUR.GS.rp0 );
+
+ cur_dist = CUR_Func_project( CUR.zp1.cur + point,
+ CUR.zp0.cur + CUR.GS.rp0 );
+
+ /* auto-flip test */
+
+ if ( CUR.GS.auto_flip )
+ {
+ if ( (org_dist ^ cvt_dist) < 0 )
+ cvt_dist = -cvt_dist;
+ }
+
+ /* control value cutin and round */
+
+ if ( (CUR.opcode & 4) != 0 )
+ {
+ /* XXX: UNDOCUMENTED! Only perform cut-in test when both points */
+ /* refer to the same zone. */
+
+ if ( CUR.GS.gep0 == CUR.GS.gep1 )
+ if ( ABS( cvt_dist - org_dist ) >= CUR.GS.control_value_cutin )
+ cvt_dist = org_dist;
+
+ distance = CUR_Func_round( cvt_dist,
+ CUR.tt_metrics.compensations[CUR.opcode & 3] );
+ }
+ else
+ distance = ROUND_None( cvt_dist,
+ CUR.tt_metrics.compensations[CUR.opcode & 3] );
+
+ /* minimum distance test */
+
+ if ( (CUR.opcode & 8) != 0 )
+ {
+ if ( org_dist >= 0 )
+ {
+ if ( distance < CUR.GS.minimum_distance )
+ distance = CUR.GS.minimum_distance;
+ }
+ else
+ {
+ if ( distance > -CUR.GS.minimum_distance )
+ distance = -CUR.GS.minimum_distance;
+ }
+ }
+
+ CUR_Func_move( &CUR.zp1, point, distance - cur_dist );
+
+ CUR.GS.rp1 = CUR.GS.rp0;
+
+ if ( (CUR.opcode & 16) != 0 )
+ CUR.GS.rp0 = point;
+
+ /* XXX: UNDOCUMENTED! */
+
+ CUR.GS.rp2 = point;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* ALIGNRP[]: ALIGN Relative Point */
+ /* Opcode range: 0x3C */
+ /* Stack: uint32 uint32... --> */
+ /* */
+ static
+ void Ins_ALIGNRP( INS_ARG )
+ {
+ TT_UShort point;
+ TT_F26Dot6 distance;
+
+
+ UNUSED_ARG;
+
+ if ( CUR.top < CUR.GS.loop ||
+ BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
+ {
+ if ( CUR.pedantic_hinting )
+ CUR.error = TT_Err_Invalid_Reference;
+ return;
+ }
+
+ while ( CUR.GS.loop > 0 )
+ {
+ CUR.args--;
+
+ point = (TT_UShort)CUR.stack[CUR.args];
+
+ if ( BOUNDS( point, CUR.zp1.n_points ) )
+ {
+ if ( CUR.pedantic_hinting )
+ {
+ CUR.error = TT_Err_Invalid_Reference;
+ return;
+ }
+ }
+ else
+ {
+ distance = CUR_Func_project( CUR.zp1.cur + point,
+ CUR.zp0.cur + CUR.GS.rp0 );
+
+ CUR_Func_move( &CUR.zp1, point, -distance );
+ }
+
+ CUR.GS.loop--;
+ }
+
+ CUR.GS.loop = 1;
+ CUR.new_top = CUR.args;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* ISECT[]: moves point to InterSECTion */
+ /* Opcode range: 0x0F */
+ /* Stack: 5 * uint32 --> */
+ /* */
+ static
+ void Ins_ISECT( INS_ARG )
+ {
+ TT_UShort point,
+ a0, a1,
+ b0, b1;
+
+ TT_F26Dot6 discriminant;
+
+ TT_F26Dot6 dx, dy,
+ dax, day,
+ dbx, dby;
+
+ TT_F26Dot6 val;
+
+ TT_Vector R;
+
+
+ point = (TT_UShort)args[0];
+
+ a0 = (TT_UShort)args[1];
+ a1 = (TT_UShort)args[2];
+ b0 = (TT_UShort)args[3];
+ b1 = (TT_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] |= FT_Curve_Tag_Touch_Both;
+
+ discriminant = TT_MULDIV( dax, -dby, 0x40 ) +
+ TT_MULDIV( day, dbx, 0x40 );
+
+ if ( ABS( discriminant ) >= 0x40 )
+ {
+ val = TT_MULDIV( dx, -dby, 0x40 ) + TT_MULDIV( dy, dbx, 0x40 );
+
+ R.x = TT_MULDIV( val, dax, discriminant );
+ R.y = TT_MULDIV( val, day, discriminant );
+
+ CUR.zp2.cur[point].x = CUR.zp1.cur[a0].x + R.x;
+ CUR.zp2.cur[point].y = CUR.zp1.cur[a0].y + R.y;
+ }
+ else
+ {
+ /* else, take the middle of the middles of A and B */
+
+ CUR.zp2.cur[point].x = ( CUR.zp1.cur[a0].x +
+ CUR.zp1.cur[a1].x +
+ CUR.zp0.cur[b0].x +
+ CUR.zp0.cur[b1].x ) / 4;
+ CUR.zp2.cur[point].y = ( CUR.zp1.cur[a0].y +
+ CUR.zp1.cur[a1].y +
+ CUR.zp0.cur[b0].y +
+ CUR.zp0.cur[b1].y ) / 4;
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* ALIGNPTS[]: ALIGN PoinTS */
+ /* Opcode range: 0x27 */
+ /* Stack: uint32 uint32 --> */
+ /* */
+ static
+ void Ins_ALIGNPTS( INS_ARG )
+ {
+ TT_UShort p1, p2;
+ TT_F26Dot6 distance;
+
+
+ p1 = (TT_UShort)args[0];
+ p2 = (TT_UShort)args[1];
+
+ if ( BOUNDS( args[0], CUR.zp1.n_points ) ||
+ BOUNDS( args[1], CUR.zp0.n_points ) )
+ {
+ if ( CUR.pedantic_hinting )
+ CUR.error = TT_Err_Invalid_Reference;
+ return;
+ }
+
+ distance = CUR_Func_project( CUR.zp0.cur + p2,
+ CUR.zp1.cur + p1 ) / 2;
+
+ CUR_Func_move( &CUR.zp1, p1, distance );
+ CUR_Func_move( &CUR.zp0, p2, -distance );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* IP[]: Interpolate Point */
+ /* Opcode range: 0x39 */
+ /* Stack: uint32... --> */
+ /* */
+ static
+ void Ins_IP( INS_ARG )
+ {
+ TT_F26Dot6 org_a, org_b, org_x,
+ cur_a, cur_b, cur_x,
+ distance;
+ TT_UShort point;
+
+
+ UNUSED_ARG;
+
+ if ( CUR.top < CUR.GS.loop )
+ {
+ CUR.error = TT_Err_Invalid_Reference;
+ return;
+ }
+
+ /* XXX: there are some glyphs in some braindead but popular */
+ /* fonts out there (e.g. [aeu]grave in monotype.ttf) */
+ /* calling IP[] with bad values of rp[12]. */
+ /* Do something sane when this odd thing happens. */
+
+ if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) ||
+ BOUNDS( CUR.GS.rp2, CUR.zp1.n_points ) )
+ {
+ org_a = cur_a = 0;
+ org_b = cur_b = 0;
+ }
+ else
+ {
+ org_a = CUR_Func_dualproj( CUR.zp0.org + CUR.GS.rp1, NULL_Vector );
+ org_b = CUR_Func_dualproj( CUR.zp1.org + CUR.GS.rp2, NULL_Vector );
+
+ cur_a = CUR_Func_project( CUR.zp0.cur + CUR.GS.rp1, NULL_Vector );
+ cur_b = CUR_Func_project( CUR.zp1.cur + CUR.GS.rp2, NULL_Vector );
+ }
+
+ while ( CUR.GS.loop > 0 )
+ {
+ CUR.args--;
+
+ point = (TT_UShort)CUR.stack[CUR.args];
+ if ( BOUNDS( point, CUR.zp2.n_points ) )
+ {
+ if ( CUR.pedantic_hinting )
+ {
+ CUR.error = TT_Err_Invalid_Reference;
+ return;
+ }
+ }
+ else
+ {
+ org_x = CUR_Func_dualproj( CUR.zp2.org + point, NULL_Vector );
+ cur_x = CUR_Func_project ( CUR.zp2.cur + point, NULL_Vector );
+
+ if ( ( org_a <= org_b && org_x <= org_a ) ||
+ ( org_a > org_b && org_x >= org_a ) )
+
+ distance = ( cur_a - org_a ) + ( org_x - cur_x );
+
+ else if ( ( org_a <= org_b && org_x >= org_b ) ||
+ ( org_a > org_b && org_x < org_b ) )
+
+ distance = ( cur_b - org_b ) + ( org_x - cur_x );
+
+ else
+ /* note: it seems that rounding this value isn't a good */
+ /* idea (cf. width of capital `S' in Times) */
+
+ distance = TT_MULDIV( cur_b - cur_a,
+ org_x - org_a,
+ org_b - org_a ) + ( cur_a - cur_x );
+
+ CUR_Func_move( &CUR.zp2, point, distance );
+ }
+
+ CUR.GS.loop--;
+ }
+
+ CUR.GS.loop = 1;
+ CUR.new_top = CUR.args;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* UTP[a]: UnTouch Point */
+ /* Opcode range: 0x29 */
+ /* Stack: uint32 --> */
+ /* */
+ static
+ void Ins_UTP( INS_ARG )
+ {
+ TT_UShort point;
+ TT_Byte mask;
+
+
+ point = (TT_UShort)args[0];
+
+ if ( BOUNDS( point, CUR.zp0.n_points ) )
+ {
+ if ( CUR.pedantic_hinting )
+ CUR.error = TT_Err_Invalid_Reference;
+ return;
+ }
+
+ mask = 0xFF;
+
+ if ( CUR.GS.freeVector.x != 0 )
+ mask &= ~FT_Curve_Tag_Touch_X;
+
+ if ( CUR.GS.freeVector.y != 0 )
+ mask &= ~FT_Curve_Tag_Touch_Y;
+
+ CUR.zp0.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( TT_UInt p1,
+ TT_UInt p2,
+ TT_UInt p,
+ struct LOC_Ins_IUP* LINK )
+ {
+ TT_UInt 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( TT_UInt p1,
+ TT_UInt p2,
+ TT_UInt ref1,
+ TT_UInt ref2,
+ struct LOC_Ins_IUP* LINK )
+ {
+ TT_UInt 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 */
+ /* Opcode range: 0x30-0x31 */
+ /* Stack: --> */
+ /* */
+ static
+ void Ins_IUP( INS_ARG )
+ {
+ struct LOC_Ins_IUP V;
+ TT_Byte mask;
+
+ TT_UInt first_point; /* first point of contour */
+ TT_UInt end_point; /* end point (last+1) of contour */
+
+ TT_UInt first_touched; /* first touched point in contour */
+ TT_UInt cur_touched; /* current touched point in contour */
+
+ TT_UInt point; /* current point */
+ TT_Short contour; /* current contour */
+
+
+ UNUSED_ARG;
+
+ if ( CUR.opcode & 1 )
+ {
+ mask = FT_Curve_Tag_Touch_X;
+ V.orgs = CUR.pts.org;
+ V.curs = CUR.pts.cur;
+ }
+ else
+ {
+ mask = FT_Curve_Tag_Touch_Y;
+ V.orgs = (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( (TT_UShort)(cur_touched + 1),
+ end_point,
+ cur_touched,
+ first_touched,
+ &V );
+
+ if ( first_touched > 0 )
+ Interp( first_point,
+ first_touched - 1,
+ cur_touched,
+ first_touched,
+ &V );
+ }
+ }
+ contour++;
+ } while ( contour < CUR.pts.n_contours );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* DELTAPn[]: DELTA exceptions P1, P2, P3 */
+ /* Opcode range: 0x5D,0x71,0x72 */
+ /* Stack: uint32 (2 * uint32)... --> */
+ /* */
+ static
+ void Ins_DELTAP( INS_ARG )
+ {
+ TT_ULong k, nump;
+ TT_UShort A;
+ TT_ULong C;
+ TT_Long B;
+
+
+ nump = (TT_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 = (TT_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 = ((TT_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() == (TT_Long)C )
+ {
+ B = ((TT_ULong)B & 0xF) - 8;
+ if ( B >= 0 )
+ B++;
+ B = B * 64 / (1L << CUR.GS.delta_shift);
+
+ CUR_Func_move( &CUR.zp0, A, B );
+ }
+ }
+ else
+ if ( CUR.pedantic_hinting )
+ CUR.error = TT_Err_Invalid_Reference;
+ }
+
+ CUR.new_top = CUR.args;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* DELTACn[]: DELTA exceptions C1, C2, C3 */
+ /* Opcode range: 0x73,0x74,0x75 */
+ /* Stack: uint32 (2 * uint32)... --> */
+ /* */
+ static
+ void Ins_DELTAC( INS_ARG )
+ {
+ TT_ULong nump, k;
+ TT_ULong A, C;
+ TT_Long B;
+
+
+ nump = (TT_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 = (TT_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 = ((TT_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() == (TT_Long)C )
+ {
+ B = ((TT_ULong)B & 0xF) - 8;
+ if ( B >= 0 )
+ B++;
+ B = B * 64 / (1L << CUR.GS.delta_shift);
+
+ CUR_Func_move_cvt( A, B );
+ }
+ }
+ }
+
+ CUR.new_top = CUR.args;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* MISC. INSTRUCTIONS */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* GETINFO[]: GET INFOrmation */
+ /* Opcode range: 0x88 */
+ /* Stack: uint32 --> uint32 */
+ /* */
+ /* XXX: According to Apple specs, bits 1 & 2 of the argument ought to be */
+ /* consulted before rotated/stretched info is returned. */
+ static
+ void Ins_GETINFO( INS_ARG )
+ {
+ TT_Long K;
+
+
+ K = 0;
+
+ /* We return then Windows 3.1 version number */
+ /* for the font scaler */
+ if ( (args[0] & 1) != 0 )
+ K = 3;
+
+ /* Has the glyph been rotated ? */
+ if ( CUR.tt_metrics.rotated )
+ K |= 0x80;
+
+ /* Has the glyph been stretched ? */
+ if ( CUR.tt_metrics.stretched )
+ K |= 0x100;
+
+ args[0] = K;
+ }
+
+
+ static
+ void Ins_UNKNOWN( INS_ARG )
+ {
+ TT_DefRecord* def = CUR.IDefs;
+ TT_DefRecord* limit = def + CUR.numIDefs;
+
+ UNUSED_ARG;
+
+ for ( ; def < limit; def++ )
+ {
+ if (def->opc == CUR.opcode && def->active )
+ {
+ TT_CallRec* call;
+
+ if ( CUR.callTop >= CUR.callSize )
+ {
+ CUR.error = TT_Err_Stack_Overflow;
+ return;
+ }
+
+ call = CUR.callStack + CUR.callTop++;
+
+ call->Caller_Range = CUR.curRange;
+ call->Caller_IP = CUR.IP+1;
+ call->Cur_Count = 1;
+ call->Cur_Restart = def->start;
+
+ INS_Goto_CodeRange( def->range, def->start );
+
+ CUR.step_ins = FALSE;
+ return;
+ }
+ }
+
+ CUR.error = TT_Err_Invalid_Opcode;
+ }
+
+
+#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH
+ static
+ TInstruction_Function Instruct_Dispatch[256] =
+ {
+ /* Opcodes are gathered in groups of 16. */
+ /* Please keep the spaces as they are. */
+
+ /* SVTCA y */ Ins_SVTCA,
+ /* SVTCA x */ Ins_SVTCA,
+ /* SPvTCA y */ Ins_SPVTCA,
+ /* SPvTCA x */ Ins_SPVTCA,
+ /* SFvTCA y */ Ins_SFVTCA,
+ /* SFvTCA x */ Ins_SFVTCA,
+ /* SPvTL // */ Ins_SPVTL,
+ /* SPvTL + */ Ins_SPVTL,
+ /* SFvTL // */ Ins_SFVTL,
+ /* SFvTL + */ Ins_SFVTL,
+ /* SPvFS */ Ins_SPVFS,
+ /* SFvFS */ Ins_SFVFS,
+ /* GPV */ Ins_GPV,
+ /* GFV */ Ins_GFV,
+ /* SFvTPv */ Ins_SFVTPV,
+ /* ISECT */ Ins_ISECT,
+
+ /* SRP0 */ Ins_SRP0,
+ /* SRP1 */ Ins_SRP1,
+ /* SRP2 */ Ins_SRP2,
+ /* SZP0 */ Ins_SZP0,
+ /* SZP1 */ Ins_SZP1,
+ /* SZP2 */ Ins_SZP2,
+ /* SZPS */ Ins_SZPS,
+ /* SLOOP */ Ins_SLOOP,
+ /* RTG */ Ins_RTG,
+ /* RTHG */ Ins_RTHG,
+ /* SMD */ Ins_SMD,
+ /* ELSE */ Ins_ELSE,
+ /* JMPR */ Ins_JMPR,
+ /* SCvTCi */ Ins_SCVTCI,
+ /* SSwCi */ Ins_SSWCI,
+ /* SSW */ Ins_SSW,
+
+ /* DUP */ Ins_DUP,
+ /* POP */ Ins_POP,
+ /* CLEAR */ Ins_CLEAR,
+ /* SWAP */ Ins_SWAP,
+ /* DEPTH */ Ins_DEPTH,
+ /* CINDEX */ Ins_CINDEX,
+ /* MINDEX */ Ins_MINDEX,
+ /* AlignPTS */ Ins_ALIGNPTS,
+ /* INS_0x28 */ Ins_UNKNOWN,
+ /* UTP */ Ins_UTP,
+ /* LOOPCALL */ Ins_LOOPCALL,
+ /* CALL */ Ins_CALL,
+ /* FDEF */ Ins_FDEF,
+ /* ENDF */ Ins_ENDF,
+ /* MDAP[0] */ Ins_MDAP,
+ /* MDAP[1] */ Ins_MDAP,
+
+ /* IUP[0] */ Ins_IUP,
+ /* IUP[1] */ Ins_IUP,
+ /* SHP[0] */ Ins_SHP,
+ /* SHP[1] */ Ins_SHP,
+ /* SHC[0] */ Ins_SHC,
+ /* SHC[1] */ Ins_SHC,
+ /* SHZ[0] */ Ins_SHZ,
+ /* SHZ[1] */ Ins_SHZ,
+ /* SHPIX */ Ins_SHPIX,
+ /* IP */ Ins_IP,
+ /* MSIRP[0] */ Ins_MSIRP,
+ /* MSIRP[1] */ Ins_MSIRP,
+ /* AlignRP */ Ins_ALIGNRP,
+ /* RTDG */ Ins_RTDG,
+ /* MIAP[0] */ Ins_MIAP,
+ /* MIAP[1] */ Ins_MIAP,
+
+ /* NPushB */ Ins_NPUSHB,
+ /* NPushW */ Ins_NPUSHW,
+ /* WS */ Ins_WS,
+ /* RS */ Ins_RS,
+ /* WCvtP */ Ins_WCVTP,
+ /* RCvt */ Ins_RCVT,
+ /* GC[0] */ Ins_GC,
+ /* GC[1] */ Ins_GC,
+ /* SCFS */ Ins_SCFS,
+ /* MD[0] */ Ins_MD,
+ /* MD[1] */ Ins_MD,
+ /* MPPEM */ Ins_MPPEM,
+ /* MPS */ Ins_MPS,
+ /* FlipON */ Ins_FLIPON,
+ /* FlipOFF */ Ins_FLIPOFF,
+ /* DEBUG */ Ins_DEBUG,
+
+ /* LT */ Ins_LT,
+ /* LTEQ */ Ins_LTEQ,
+ /* GT */ Ins_GT,
+ /* GTEQ */ Ins_GTEQ,
+ /* EQ */ Ins_EQ,
+ /* NEQ */ Ins_NEQ,
+ /* ODD */ Ins_ODD,
+ /* EVEN */ Ins_EVEN,
+ /* IF */ Ins_IF,
+ /* EIF */ Ins_EIF,
+ /* AND */ Ins_AND,
+ /* OR */ Ins_OR,
+ /* NOT */ Ins_NOT,
+ /* DeltaP1 */ Ins_DELTAP,
+ /* SDB */ Ins_SDB,
+ /* SDS */ Ins_SDS,
+
+ /* ADD */ Ins_ADD,
+ /* SUB */ Ins_SUB,
+ /* DIV */ Ins_DIV,
+ /* MUL */ Ins_MUL,
+ /* ABS */ Ins_ABS,
+ /* NEG */ Ins_NEG,
+ /* FLOOR */ Ins_FLOOR,
+ /* CEILING */ Ins_CEILING,
+ /* ROUND[0] */ Ins_ROUND,
+ /* ROUND[1] */ Ins_ROUND,
+ /* ROUND[2] */ Ins_ROUND,
+ /* ROUND[3] */ Ins_ROUND,
+ /* NROUND[0] */ Ins_NROUND,
+ /* NROUND[1] */ Ins_NROUND,
+ /* NROUND[2] */ Ins_NROUND,
+ /* NROUND[3] */ Ins_NROUND,
+
+ /* WCvtF */ Ins_WCVTF,
+ /* DeltaP2 */ Ins_DELTAP,
+ /* DeltaP3 */ Ins_DELTAP,
+ /* DeltaCn[0] */ Ins_DELTAC,
+ /* DeltaCn[1] */ Ins_DELTAC,
+ /* DeltaCn[2] */ Ins_DELTAC,
+ /* SROUND */ Ins_SROUND,
+ /* S45Round */ Ins_S45ROUND,
+ /* JROT */ Ins_JROT,
+ /* JROF */ Ins_JROF,
+ /* ROFF */ Ins_ROFF,
+ /* INS_0x7B */ Ins_UNKNOWN,
+ /* RUTG */ Ins_RUTG,
+ /* RDTG */ Ins_RDTG,
+ /* SANGW */ Ins_SANGW,
+ /* AA */ Ins_AA,
+
+ /* FlipPT */ Ins_FLIPPT,
+ /* FlipRgON */ Ins_FLIPRGON,
+ /* FlipRgOFF */ Ins_FLIPRGOFF,
+ /* INS_0x83 */ Ins_UNKNOWN,
+ /* INS_0x84 */ Ins_UNKNOWN,
+ /* ScanCTRL */ Ins_SCANCTRL,
+ /* SDPVTL[0] */ Ins_SDPVTL,
+ /* SDPVTL[1] */ Ins_SDPVTL,
+ /* GetINFO */ Ins_GETINFO,
+ /* IDEF */ Ins_IDEF,
+ /* ROLL */ Ins_ROLL,
+ /* MAX */ Ins_MAX,
+ /* MIN */ Ins_MIN,
+ /* ScanTYPE */ Ins_SCANTYPE,
+ /* InstCTRL */ Ins_INSTCTRL,
+ /* INS_0x8F */ Ins_UNKNOWN,
+
+ /* INS_0x90 */ Ins_UNKNOWN,
+ /* INS_0x91 */ Ins_UNKNOWN,
+ /* INS_0x92 */ Ins_UNKNOWN,
+ /* INS_0x93 */ Ins_UNKNOWN,
+ /* INS_0x94 */ Ins_UNKNOWN,
+ /* INS_0x95 */ Ins_UNKNOWN,
+ /* INS_0x96 */ Ins_UNKNOWN,
+ /* INS_0x97 */ Ins_UNKNOWN,
+ /* INS_0x98 */ Ins_UNKNOWN,
+ /* INS_0x99 */ Ins_UNKNOWN,
+ /* INS_0x9A */ Ins_UNKNOWN,
+ /* INS_0x9B */ Ins_UNKNOWN,
+ /* INS_0x9C */ Ins_UNKNOWN,
+ /* INS_0x9D */ Ins_UNKNOWN,
+ /* INS_0x9E */ Ins_UNKNOWN,
+ /* INS_0x9F */ Ins_UNKNOWN,
+
+ /* INS_0xA0 */ Ins_UNKNOWN,
+ /* INS_0xA1 */ Ins_UNKNOWN,
+ /* INS_0xA2 */ Ins_UNKNOWN,
+ /* INS_0xA3 */ Ins_UNKNOWN,
+ /* INS_0xA4 */ Ins_UNKNOWN,
+ /* INS_0xA5 */ Ins_UNKNOWN,
+ /* INS_0xA6 */ Ins_UNKNOWN,
+ /* INS_0xA7 */ Ins_UNKNOWN,
+ /* INS_0xA8 */ Ins_UNKNOWN,
+ /* INS_0xA9 */ Ins_UNKNOWN,
+ /* INS_0xAA */ Ins_UNKNOWN,
+ /* INS_0xAB */ Ins_UNKNOWN,
+ /* INS_0xAC */ Ins_UNKNOWN,
+ /* INS_0xAD */ Ins_UNKNOWN,
+ /* INS_0xAE */ Ins_UNKNOWN,
+ /* INS_0xAF */ Ins_UNKNOWN,
+
+ /* PushB[0] */ Ins_PUSHB,
+ /* PushB[1] */ Ins_PUSHB,
+ /* PushB[2] */ Ins_PUSHB,
+ /* PushB[3] */ Ins_PUSHB,
+ /* PushB[4] */ Ins_PUSHB,
+ /* PushB[5] */ Ins_PUSHB,
+ /* PushB[6] */ Ins_PUSHB,
+ /* PushB[7] */ Ins_PUSHB,
+ /* PushW[0] */ Ins_PUSHW,
+ /* PushW[1] */ Ins_PUSHW,
+ /* PushW[2] */ Ins_PUSHW,
+ /* PushW[3] */ Ins_PUSHW,
+ /* PushW[4] */ Ins_PUSHW,
+ /* PushW[5] */ Ins_PUSHW,
+ /* PushW[6] */ Ins_PUSHW,
+ /* PushW[7] */ Ins_PUSHW,
+
+ /* MDRP[00] */ Ins_MDRP,
+ /* MDRP[01] */ Ins_MDRP,
+ /* MDRP[02] */ Ins_MDRP,
+ /* MDRP[03] */ Ins_MDRP,
+ /* MDRP[04] */ Ins_MDRP,
+ /* MDRP[05] */ Ins_MDRP,
+ /* MDRP[06] */ Ins_MDRP,
+ /* MDRP[07] */ Ins_MDRP,
+ /* MDRP[08] */ Ins_MDRP,
+ /* MDRP[09] */ Ins_MDRP,
+ /* MDRP[10] */ Ins_MDRP,
+ /* MDRP[11] */ Ins_MDRP,
+ /* MDRP[12] */ Ins_MDRP,
+ /* MDRP[13] */ Ins_MDRP,
+ /* MDRP[14] */ Ins_MDRP,
+ /* MDRP[15] */ Ins_MDRP,
+
+ /* MDRP[16] */ Ins_MDRP,
+ /* MDRP[17] */ Ins_MDRP,
+ /* MDRP[18] */ Ins_MDRP,
+ /* MDRP[19] */ Ins_MDRP,
+ /* MDRP[20] */ Ins_MDRP,
+ /* MDRP[21] */ Ins_MDRP,
+ /* MDRP[22] */ Ins_MDRP,
+ /* MDRP[23] */ Ins_MDRP,
+ /* MDRP[24] */ Ins_MDRP,
+ /* MDRP[25] */ Ins_MDRP,
+ /* MDRP[26] */ Ins_MDRP,
+ /* MDRP[27] */ Ins_MDRP,
+ /* MDRP[28] */ Ins_MDRP,
+ /* MDRP[29] */ Ins_MDRP,
+ /* MDRP[30] */ Ins_MDRP,
+ /* MDRP[31] */ Ins_MDRP,
+
+ /* MIRP[00] */ Ins_MIRP,
+ /* MIRP[01] */ Ins_MIRP,
+ /* MIRP[02] */ Ins_MIRP,
+ /* MIRP[03] */ Ins_MIRP,
+ /* MIRP[04] */ Ins_MIRP,
+ /* MIRP[05] */ Ins_MIRP,
+ /* MIRP[06] */ Ins_MIRP,
+ /* MIRP[07] */ Ins_MIRP,
+ /* MIRP[08] */ Ins_MIRP,
+ /* MIRP[09] */ Ins_MIRP,
+ /* MIRP[10] */ Ins_MIRP,
+ /* MIRP[11] */ Ins_MIRP,
+ /* MIRP[12] */ Ins_MIRP,
+ /* MIRP[13] */ Ins_MIRP,
+ /* MIRP[14] */ Ins_MIRP,
+ /* MIRP[15] */ Ins_MIRP,
+
+ /* MIRP[16] */ Ins_MIRP,
+ /* MIRP[17] */ Ins_MIRP,
+ /* MIRP[18] */ Ins_MIRP,
+ /* MIRP[19] */ Ins_MIRP,
+ /* MIRP[20] */ Ins_MIRP,
+ /* MIRP[21] */ Ins_MIRP,
+ /* MIRP[22] */ Ins_MIRP,
+ /* MIRP[23] */ Ins_MIRP,
+ /* MIRP[24] */ Ins_MIRP,
+ /* MIRP[25] */ Ins_MIRP,
+ /* MIRP[26] */ Ins_MIRP,
+ /* MIRP[27] */ Ins_MIRP,
+ /* MIRP[28] */ Ins_MIRP,
+ /* MIRP[29] */ Ins_MIRP,
+ /* MIRP[30] */ Ins_MIRP,
+ /* MIRP[31] */ Ins_MIRP
+ };
+#endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */
+
+
+ /*************************************************************************/
+ /* */
+ /* RUN */
+ /* */
+ /* This function executes a run of opcodes. It will exit in the */
+ /* following cases: */
+ /* */
+ /* - Errors (in which case it returns FALSE). */
+ /* */
+ /* - Reaching the end of the main code range (returns TRUE). */
+ /* Reaching the end of a code range within a function call is an */
+ /* error. */
+ /* */
+ /* - After executing one single opcode, if the flag `Instruction_Trap' */
+ /* is set to TRUE (returns TRUE). */
+ /* */
+ /* On exit whith TRUE, test IP < CodeSize to know wether it comes from */
+ /* an instruction trap or a normal termination. */
+ /* */
+ /* */
+ /* Note: The documented DEBUG opcode pops a value from the stack. This */
+ /* behaviour is unsupported, here a DEBUG opcode is always an */
+ /* error. */
+ /* */
+ /* */
+ /* THIS IS THE INTERPRETER'S MAIN LOOP. */
+ /* */
+ /* Instructions appear in the specs' order. */
+ /* */
+ /*************************************************************************/
+
+
+ EXPORT_FUNC
+#ifndef DEBUG_INTERPRETER
+ TT_Error TT_RunIns( TT_ExecContext exc )
+#else
+ TT_Error TT_RunIns2( TT_ExecContext exc )
+#endif
+ {
+ TT_Long ins_counter = 0; /* executed instructions counter */
+
+#ifdef TT_CONFIG_OPTION_STATIC_RASTER
+ cur = *exc;
+#endif
+
+ /* set CVT functions */
+ CUR.tt_metrics.ratio = 0;
+ if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem )
+ {
+ /* non-square pixels, use the stretched routines */
+ CUR.func_read_cvt = Read_CVT_Stretched;
+ CUR.func_write_cvt = Write_CVT_Stretched;
+ CUR.func_move_cvt = Move_CVT_Stretched;
+ }
+ else
+ {
+ /* square pixels, use normal routines */
+ CUR.func_read_cvt = Read_CVT;
+ CUR.func_write_cvt = Write_CVT;
+ CUR.func_move_cvt = Move_CVT;
+ }
+
+ COMPUTE_Funcs();
+ COMPUTE_Round( (TT_Byte)exc->GS.round_state );
+
+ do
+ {
+ CUR.opcode = CUR.code[CUR.IP];
+
+ if ( ( CUR.length = opcode_length[CUR.opcode] ) < 0 )
+ {
+ if ( CUR.IP + 1 > CUR.codeSize )
+ goto LErrorCodeOverflow_;
+
+ CUR.length = CUR.code[CUR.IP + 1] + 2;
+ }
+
+ if ( CUR.IP + CUR.length > CUR.codeSize )
+ goto LErrorCodeOverflow_;
+
+ /* First, let's check for empty stack and overflow */
+ CUR.args = CUR.top - (Pop_Push_Count[CUR.opcode] >> 4);
+
+ /* `args' is the top of the stack once arguments have been popped. */
+ /* One can also interpret it as the index of the last argument. */
+ if ( CUR.args < 0 )
+ {
+ CUR.error = TT_Err_Too_Few_Arguments;
+ goto LErrorLabel_;
+ }
+
+ CUR.new_top = CUR.args + (Pop_Push_Count[CUR.opcode] & 15);
+
+ /* `new_top' is the new top of the stack, after the instruction's */
+ /* execution. `top' will be set to `new_top' after the `switch' */
+ /* statement. */
+ if ( CUR.new_top > CUR.stackSize )
+ {
+ CUR.error = TT_Err_Stack_Overflow;
+ goto LErrorLabel_;
+ }
+
+ CUR.step_ins = TRUE;
+ CUR.error = TT_Err_Ok;
+
+#ifdef TT_CONFIG_OPTION_INTERPRETER_SWITCH
+ {
+ TT_Long* args = CUR.stack + CUR.args;
+ TT_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 */
+ {
+ TT_Short AA, BB;
+
+
+ AA = (TT_Short)(opcode & 1) << 14;
+ BB = AA ^ (TT_Short)0x4000;
+
+ if ( opcode < 4 )
+ {
+ CUR.GS.projVector.x = AA;
+ CUR.GS.projVector.y = BB;
+
+ CUR.GS.dualVector.x = AA;
+ CUR.GS.dualVector.y = BB;
+ }
+
+ if ( (opcode & 2) == 0 )
+ {
+ CUR.GS.freeVector.x = AA;
+ CUR.GS.freeVector.y = BB;
+ }
+
+ COMPUTE_Funcs();
+ }
+ break;
+
+ case 0x06: /* SPvTL // */
+ case 0x07: /* SPvTL + */
+ DO_SPVTL
+ break;
+
+ case 0x08: /* SFvTL // */
+ case 0x09: /* SFvTL + */
+ DO_SFVTL
+ break;
+
+ case 0x0A: /* SPvFS */
+ DO_SPVFS
+ break;
+
+ case 0x0B: /* SFvFS */
+ DO_SFVFS
+ break;
+
+ case 0x0C: /* GPV */
+ DO_GPV
+ break;
+
+ case 0x0D: /* GFV */
+ DO_GFV
+ break;
+
+ case 0x0E: /* SFvTPv */
+ DO_SFVTPV
+ break;
+
+ case 0x0F: /* ISECT */
+ Ins_ISECT( EXEC_ARG_ args );
+ break;
+
+ case 0x10: /* SRP0 */
+ DO_SRP0
+ break;
+
+ case 0x11: /* SRP1 */
+ DO_SRP1
+ break;
+
+ case 0x12: /* SRP2 */
+ DO_SRP2
+ break;
+
+ case 0x13: /* SZP0 */
+ Ins_SZP0( EXEC_ARG_ args );
+ break;
+
+ case 0x14: /* SZP1 */
+ Ins_SZP1( EXEC_ARG_ args );
+ break;
+
+ case 0x15: /* SZP2 */
+ Ins_SZP2( EXEC_ARG_ args );
+ break;
+
+ case 0x16: /* SZPS */
+ Ins_SZPS( EXEC_ARG_ args );
+ break;
+
+ case 0x17: /* SLOOP */
+ DO_SLOOP
+ break;
+
+ case 0x18: /* RTG */
+ DO_RTG
+ break;
+
+ case 0x19: /* RTHG */
+ DO_RTHG
+ break;
+
+ case 0x1A: /* SMD */
+ DO_SMD
+ break;
+
+ case 0x1B: /* ELSE */
+ Ins_ELSE( EXEC_ARG_ args );
+ break;
+
+ case 0x1C: /* JMPR */
+ DO_JMPR
+ break;
+
+ case 0x1D: /* SCVTCI */
+ DO_SCVTCI
+ break;
+
+ case 0x1E: /* SSWCI */
+ DO_SSWCI
+ break;
+
+ case 0x1F: /* SSW */
+ DO_SSW
+ break;
+
+ case 0x20: /* DUP */
+ DO_DUP
+ break;
+
+ case 0x21: /* POP */
+ /* nothing :-) ! */
+ break;
+
+ case 0x22: /* CLEAR */
+ DO_CLEAR
+ break;
+
+ case 0x23: /* SWAP */
+ DO_SWAP
+ break;
+
+ case 0x24: /* DEPTH */
+ DO_DEPTH
+ break;
+
+ case 0x25: /* CINDEX */
+ DO_CINDEX
+ break;
+
+ case 0x26: /* MINDEX */
+ Ins_MINDEX( EXEC_ARG_ args );
+ break;
+
+ case 0x27: /* ALIGNPTS */
+ Ins_ALIGNPTS( EXEC_ARG_ args );
+ break;
+
+ case 0x28: /* ???? */
+ Ins_UNKNOWN( EXEC_ARG_ args );
+ break;
+
+ case 0x29: /* UTP */
+ Ins_UTP( EXEC_ARG_ args );
+ break;
+
+ case 0x2A: /* LOOPCALL */
+ Ins_LOOPCALL( EXEC_ARG_ args );
+ break;
+
+ case 0x2B: /* CALL */
+ Ins_CALL( EXEC_ARG_ args );
+ break;
+
+ case 0x2C: /* FDEF */
+ Ins_FDEF( EXEC_ARG_ args );
+ break;
+
+ case 0x2D: /* ENDF */
+ Ins_ENDF( EXEC_ARG_ args );
+ break;
+
+ case 0x2E: /* MDAP */
+ case 0x2F: /* MDAP */
+ Ins_MDAP( EXEC_ARG_ args );
+ break;
+
+
+ case 0x30: /* IUP */
+ case 0x31: /* IUP */
+ Ins_IUP( EXEC_ARG_ args );
+ break;
+
+ case 0x32: /* SHP */
+ case 0x33: /* SHP */
+ Ins_SHP( EXEC_ARG_ args );
+ break;
+
+ case 0x34: /* SHC */
+ case 0x35: /* SHC */
+ Ins_SHC( EXEC_ARG_ args );
+ break;
+
+ case 0x36: /* SHZ */
+ case 0x37: /* SHZ */
+ Ins_SHZ( EXEC_ARG_ args );
+ break;
+
+ case 0x38: /* SHPIX */
+ Ins_SHPIX( EXEC_ARG_ args );
+ break;
+
+ case 0x39: /* IP */
+ Ins_IP( EXEC_ARG_ args );
+ break;
+
+ case 0x3A: /* MSIRP */
+ case 0x3B: /* MSIRP */
+ Ins_MSIRP( EXEC_ARG_ args );
+ break;
+
+ case 0x3C: /* AlignRP */
+ Ins_ALIGNRP( EXEC_ARG_ args );
+ break;
+
+ case 0x3D: /* RTDG */
+ DO_RTDG
+ break;
+
+ case 0x3E: /* MIAP */
+ case 0x3F: /* MIAP */
+ Ins_MIAP( EXEC_ARG_ args );
+ break;
+
+ case 0x40: /* NPUSHB */
+ Ins_NPUSHB( EXEC_ARG_ args );
+ break;
+
+ case 0x41: /* NPUSHW */
+ Ins_NPUSHW( EXEC_ARG_ args );
+ break;
+
+ case 0x42: /* WS */
+ DO_WS
+ break;
+
+ Set_Invalid_Ref:
+ CUR.error = TT_Err_Invalid_Reference;
+ break;
+
+ case 0x43: /* RS */
+ DO_RS
+ break;
+
+ case 0x44: /* WCVTP */
+ DO_WCVTP
+ break;
+
+ case 0x45: /* RCVT */
+ DO_RCVT
+ break;
+
+ case 0x46: /* GC */
+ case 0x47: /* GC */
+ Ins_GC( EXEC_ARG_ args );
+ break;
+
+ case 0x48: /* SCFS */
+ Ins_SCFS( EXEC_ARG_ args );
+ break;
+
+ case 0x49: /* MD */
+ case 0x4A: /* MD */
+ Ins_MD( EXEC_ARG_ args );
+ break;
+
+ case 0x4B: /* MPPEM */
+ DO_MPPEM
+ break;
+
+ case 0x4C: /* MPS */
+ DO_MPS
+ break;
+
+ case 0x4D: /* FLIPON */
+ DO_FLIPON
+ break;
+
+ case 0x4E: /* FLIPOFF */
+ DO_FLIPOFF
+ break;
+
+ case 0x4F: /* DEBUG */
+ DO_DEBUG
+ break;
+
+ case 0x50: /* LT */
+ DO_LT
+ break;
+
+ case 0x51: /* LTEQ */
+ DO_LTEQ
+ break;
+
+ case 0x52: /* GT */
+ DO_GT
+ break;
+
+ case 0x53: /* GTEQ */
+ DO_GTEQ
+ break;
+
+ case 0x54: /* EQ */
+ DO_EQ
+ break;
+
+ case 0x55: /* NEQ */
+ DO_NEQ
+ break;
+
+ case 0x56: /* ODD */
+ DO_ODD
+ break;
+
+ case 0x57: /* EVEN */
+ DO_EVEN
+ break;
+
+ case 0x58: /* IF */
+ Ins_IF( EXEC_ARG_ args );
+ break;
+
+ case 0x59: /* EIF */
+ /* do nothing */
+ break;
+
+ case 0x5A: /* AND */
+ DO_AND
+ break;
+
+ case 0x5B: /* OR */
+ DO_OR
+ break;
+
+ case 0x5C: /* NOT */
+ DO_NOT
+ break;
+
+ case 0x5D: /* DELTAP1 */
+ Ins_DELTAP( EXEC_ARG_ args );
+ break;
+
+ case 0x5E: /* SDB */
+ DO_SDB
+ break;
+
+ case 0x5F: /* SDS */
+ DO_SDS
+ break;
+
+ case 0x60: /* ADD */
+ DO_ADD
+ break;
+
+ case 0x61: /* SUB */
+ DO_SUB
+ break;
+
+ case 0x62: /* DIV */
+ DO_DIV
+ break;
+
+ case 0x63: /* MUL */
+ DO_MUL
+ break;
+
+ case 0x64: /* ABS */
+ DO_ABS
+ break;
+
+ case 0x65: /* NEG */
+ DO_NEG
+ break;
+
+ case 0x66: /* FLOOR */
+ DO_FLOOR
+ break;
+
+ case 0x67: /* CEILING */
+ DO_CEILING
+ break;
+
+ case 0x68: /* ROUND */
+ case 0x69: /* ROUND */
+ case 0x6A: /* ROUND */
+ case 0x6B: /* ROUND */
+ DO_ROUND
+ break;
+
+ case 0x6C: /* NROUND */
+ case 0x6D: /* NROUND */
+ case 0x6E: /* NRRUND */
+ case 0x6F: /* NROUND */
+ DO_NROUND
+ break;
+
+ case 0x70: /* WCVTF */
+ DO_WCVTF
+ break;
+
+ case 0x71: /* DELTAP2 */
+ case 0x72: /* DELTAP3 */
+ Ins_DELTAP( EXEC_ARG_ args );
+ break;
+
+ case 0x73: /* DELTAC0 */
+ case 0x74: /* DELTAC1 */
+ case 0x75: /* DELTAC2 */
+ Ins_DELTAC( EXEC_ARG_ args );
+ break;
+
+ case 0x76: /* SROUND */
+ DO_SROUND
+ break;
+
+ case 0x77: /* S45Round */
+ DO_S45ROUND
+ break;
+
+ case 0x78: /* JROT */
+ DO_JROT
+ break;
+
+ case 0x79: /* JROF */
+ DO_JROF
+ break;
+
+ case 0x7A: /* ROFF */
+ DO_ROFF
+ break;
+
+ case 0x7B: /* ???? */
+ Ins_UNKNOWN( EXEC_ARG_ args );
+ break;
+
+ case 0x7C: /* RUTG */
+ DO_RUTG
+ break;
+
+ case 0x7D: /* RDTG */
+ DO_RDTG
+ break;
+
+ case 0x7E: /* SANGW */
+ case 0x7F: /* AA */
+ /* nothing - obsolete */
+ break;
+
+ case 0x80: /* FLIPPT */
+ Ins_FLIPPT( EXEC_ARG_ args );
+ break;
+
+ case 0x81: /* FLIPRGON */
+ Ins_FLIPRGON( EXEC_ARG_ args );
+ break;
+
+ case 0x82: /* FLIPRGOFF */
+ Ins_FLIPRGOFF( EXEC_ARG_ args );
+ break;
+
+ case 0x83: /* UNKNOWN */
+ case 0x84: /* UNKNOWN */
+ Ins_UNKNOWN( EXEC_ARG_ args );
+ break;
+
+ case 0x85: /* SCANCTRL */
+ Ins_SCANCTRL( EXEC_ARG_ args );
+ break;
+
+ case 0x86: /* SDPVTL */
+ case 0x87: /* SDPVTL */
+ Ins_SDPVTL( EXEC_ARG_ args );
+ break;
+
+ case 0x88: /* GETINFO */
+ Ins_GETINFO( EXEC_ARG_ args );
+ break;
+
+ case 0x89: /* IDEF */
+ Ins_IDEF( EXEC_ARG_ args );
+ break;
+
+ case 0x8A: /* ROLL */
+ Ins_ROLL( EXEC_ARG_ args );
+ break;
+
+ case 0x8B: /* MAX */
+ DO_MAX
+ break;
+
+ case 0x8C: /* MIN */
+ DO_MIN
+ break;
+
+ case 0x8D: /* SCANTYPE */
+ Ins_SCANTYPE( EXEC_ARG_ args );
+ break;
+
+ case 0x8E: /* INSTCTRL */
+ Ins_INSTCTRL( EXEC_ARG_ args );
+ break;
+
+ case 0x8F:
+ Ins_UNKNOWN( EXEC_ARG_ args );
+ break;
+
+ default:
+ if ( opcode >= 0xE0 )
+ Ins_MIRP( EXEC_ARG_ args );
+ else if ( opcode >= 0xC0 )
+ Ins_MDRP( EXEC_ARG_ args );
+ else if ( opcode >= 0xB8 )
+ Ins_PUSHW( EXEC_ARG_ args );
+ else if ( opcode >= 0xB0 )
+ Ins_PUSHB( EXEC_ARG_ args );
+ else
+ Ins_UNKNOWN( EXEC_ARG_ args );
+ }
+
+ }
+#else
+ Instruct_Dispatch[CUR.opcode]( EXEC_ARG_ &CUR.stack[CUR.args] );
+#endif
+ if ( CUR.error != TT_Err_Ok )
+ {
+ switch ( CUR.error )
+ {
+ case TT_Err_Invalid_Opcode: /* looking for redefined instructions */
+ {
+ TT_DefRecord* def = CUR.IDefs;
+ TT_DefRecord* limit = def + CUR.numIDefs;
+
+ for ( ; def < limit; def++ )
+ {
+ if ( def->active && CUR.opcode == def->opc )
+ {
+ TT_CallRec* callrec;
+
+ if ( CUR.callTop >= CUR.callSize )
+ {
+ CUR.error = TT_Err_Invalid_Reference;
+ goto LErrorLabel_;
+ }
+
+ callrec = &CUR.callStack[CUR.callTop];
+
+ callrec->Caller_Range = CUR.curRange;
+ callrec->Caller_IP = CUR.IP + 1;
+ callrec->Cur_Count = 1;
+ callrec->Cur_Restart = def->start;
+
+ if ( INS_Goto_CodeRange( def->range, def->start ) == FAILURE )
+ goto LErrorLabel_;
+
+ goto LSuiteLabel_;
+ }
+ }
+ }
+
+ CUR.error = TT_Err_Invalid_Opcode;
+ goto LErrorLabel_;
+/* 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 )
+ return TT_Err_Execution_Too_Long;
+
+ LSuiteLabel_:
+ if ( CUR.IP >= CUR.codeSize )
+ {
+ if ( CUR.callTop > 0 )
+ {
+ CUR.error = TT_Err_Code_Overflow;
+ goto LErrorLabel_;
+ }
+ else
+ goto LNo_Error_;
+ }
+ } while ( !CUR.instruction_trap );
+
+ LNo_Error_:
+#ifdef TT_CONFIG_OPTION_STATIC_RASTER
+ *exc = cur;
+#endif
+ return TT_Err_Ok;
+
+ LErrorCodeOverflow_:
+ CUR.error = TT_Err_Code_Overflow;
+
+ LErrorLabel_:
+#ifdef TT_CONFIG_OPTION_STATIC_RASTER
+ *exc = cur;
+#endif
+ return CUR.error;
+ }
+
+
+#if 0
+
+ /* 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;
+
+ static char tempStr[128];
+
+ static const char* 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 char* Cur_U_Line( TT_ExecContext exec )
+ {
+ char s[32];
+
+ int op, i, n;
+
+ 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 (char*)tempStr;
+ }
+
+
+ EXPORT_FUNC
+ TT_Error TT_RunIns( TT_ExecContext exc )
+ {
+ TT_Int A, diff;
+ TT_ULong next_IP;
+ TT_Char ch, oldch;
+ char *temp;
+ int key;
+ FT_Memory memory;
+
+ TT_Error error = 0;
+
+ TT_GlyphZone save;
+ TT_GlyphZone 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 char* 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 TT_RunIns2( exc );
+
+ pts = exc->pts;
+
+ memory = exc->face->root.memory;
+
+ 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 ( TT_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
+ if ( ( CUR.length = opcode_length[CUR.opcode] ) < 0 )
+ {
+ if ( CUR.IP + 1 > CUR.codeSize )
+ goto LErrorCodeOverflow_;
+
+ CUR.length = CUR.code[CUR.IP + 1] + 2;
+ }
+
+ 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';
+ FT_TRACE0(( temp ));
+ }
+
+ /* First, check for empty stack and overflow */
+ if ( CUR.args < 0 )
+ {
+ FT_TRACE0(( "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 )
+ {
+ FT_TRACE0(( "ERROR : Stack overflow\n" ));
+ exc->error = TT_Err_Stack_Overflow;
+ goto LErrorLabel_;
+ }
+ }
+ else
+ FT_TRACE0(( "End of program reached.\n" ));
+
+ key = 0;
+ do
+ {
+ /* read keyboard */
+
+ ch = getch();
+
+ switch ( ch )
+ {
+ /* Help - show keybindings */
+ case '?':
+ FT_TRACE0(( "FDebug Help\n\n" ));
+ FT_TRACE0(( "? Show this page\n" ));
+ FT_TRACE0(( "q Quit debugger\n" ));
+ FT_TRACE0(( "n Skip to next instruction\n" ));
+ FT_TRACE0(( "s Step into\n" ));
+ FT_TRACE0(( "v Show vector info\n" ));
+ FT_TRACE0(( "g Show graphics state\n" ));
+ FT_TRACE0(( "p Show points zone\n\n" ));
+ break;
+
+ /* Show vectors */
+ case 'v':
+ FT_TRACE0(( "freedom (%04hx,%04hx)\n", exc->GS.freeVector.x,
+ exc->GS.freeVector.y ));
+ FT_TRACE0(( "projection (%04hx,%04hx)\n", exc->GS.projVector.x,
+ exc->GS.projVector.y ));
+ FT_TRACE0(( "dual (%04hx,%04hx)\n\n", exc->GS.dualVector.x,
+ exc->GS.dualVector.y ));
+ break;
+
+ /* Show graphics state */
+ case 'g':
+ FT_TRACE0(( "rounding %s\n", round_str[exc->GS.round_state] ));
+ FT_TRACE0(( "min dist %04lx\n", exc->GS.minimum_distance ));
+ FT_TRACE0(( "cvt_cutin %04lx\n", exc->GS.control_value_cutin ));
+ break;
+
+ /* Show points table */
+ case 'p':
+ for ( A = 0; A < exc->pts.n_points; A++ )
+ {
+ FT_TRACE0(( "%02hx ", A ));
+ FT_TRACE0(( "%08lx,%08lx - ", pts.org[A].x, pts.org[A].y ));
+ FT_TRACE0(( "%08lx,%08lx\n", pts.cur[A].x, pts.cur[A].y ));
+ }
+ FT_TRACE0(( "\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 = TT_RunIns2( exc ) ) )
+ goto LErrorLabel_;
+ }
+ }
+ oldch = ch;
+ break;
+
+ /* Step into */
+ case 's':
+ if ( exc->IP < exc->codeSize )
+
+ Step_into:
+ if ( ( error = TT_RunIns2( exc ) ) )
+ goto LErrorLabel_;
+ oldch = ch;
+ break;
+
+ default:
+ FT_TRACE0(( "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 )
+ {
+ FT_TRACE0(( "%02hx ", A ));
+
+ if ( diff & 16 ) temp = "(%01hx)"; else temp = " %01hx ";
+ FT_TRACE0(( temp, save.touch[A] & 7 ));
+
+ if ( diff & 1 ) temp = "(%08lx)"; else temp = " %08lx ";
+ FT_TRACE0(( temp, save.org[A].x ));
+
+ if ( diff & 2 ) temp = "(%08lx)"; else temp = " %08lx ";
+ FT_TRACE0(( temp, save.org[A].y ));
+
+ if ( diff & 4 ) temp = "(%08lx)"; else temp = " %08lx ";
+ FT_TRACE0(( temp, save.cur[A].x ));
+
+ if ( diff & 8 ) temp = "(%08lx)"; else temp = " %08lx ";
+ FT_TRACE0(( temp, save.cur[A].y ));
+
+ FT_TRACE0(( "\n" ));
+
+ FT_TRACE0(( "%02hx ", A ));
+
+ if ( diff & 16 ) temp = "[%01hx]"; else temp = " %01hx ";
+ FT_TRACE0(( temp, pts.touch[A] & 7 ));
+
+ if ( diff & 1 ) temp = "[%08lx]"; else temp = " %08lx ";
+ FT_TRACE0(( temp, pts.org[A].x ));
+
+ if ( diff & 2 ) temp = "[%08lx]"; else temp = " %08lx ";
+ FT_TRACE0(( temp, pts.org[A].y ));
+
+ if ( diff & 4 ) temp = "[%08lx]"; else temp = " %08lx ";
+ FT_TRACE0(( temp, pts.cur[A].x ));
+
+ if ( diff & 8 ) temp = "[%08lx]"; else temp = " %08lx ";
+ FT_TRACE0(( temp, pts.cur[A].y ));
+
+ FT_TRACE0(( "\n\n" ));
+ }
+ }
+ } while ( TRUE );
+
+ LErrorLabel_:
+
+ return error;
+
+ LErrorCodeOverflow_:
+ error = TT_Err_Code_Overflow;
+ return error;
+ }
+
+#endif /* DEBUG_INTERPRETER */
+
+
+/* END */
--- /dev/null
+++ b/src/truetype/ttinterp.h
@@ -1,0 +1,470 @@
+/***************************************************************************/
+/* */
+/* ttinterp.h */
+/* */
+/* TrueType bytecode intepreter (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 TTINTERP_H
+#define TTINTERP_H
+
+#include <ttobjs.h>
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+#ifndef TT_STATIC_INTEPRETER /* indirect implementation */
+
+#define EXEC_OP_ TT_ExecContext exc,
+#define EXEC_OP TT_ExecContext exc
+#define EXEC_ARG_ exc,
+#define EXEC_ARG exc
+
+#else /* static implementation */
+
+#define EXEC_OP_ /* void */
+#define EXEC_OP /* void */
+#define EXEC_ARG_ /* void */
+#define EXEC_ARG /* void */
+
+#endif /* TT_STATIC_INTERPRETER */
+
+
+ /*************************************************************************/
+ /* */
+ /* Rounding mode constants. */
+ /* */
+#define TT_Round_Off 5
+#define TT_Round_To_Half_Grid 0
+#define TT_Round_To_Grid 1
+#define TT_Round_To_Double_Grid 2
+#define TT_Round_Up_To_Grid 4
+#define TT_Round_Down_To_Grid 3
+#define TT_Round_Super 6
+#define TT_Round_Super_45 7
+
+
+ /*************************************************************************/
+ /* */
+ /* Function types used by the interpreter, depending on various modes */
+ /* (e.g. the rounding mode, whether to render a vertical or horizontal */
+ /* line etc). */
+ /* */
+ /*************************************************************************/
+
+ /* Rounding function */
+ typedef TT_F26Dot6 (*TT_Round_Func)( EXEC_OP_ TT_F26Dot6 distance,
+ TT_F26Dot6 compensation );
+
+ /* Point displacement along the freedom vector routine */
+ typedef void (*TT_Move_Func)( EXEC_OP_ TT_GlyphZone* zone,
+ TT_UInt point,
+ TT_F26Dot6 distance );
+
+ /* Distance projection along one of the projection vectors */
+ typedef TT_F26Dot6 (*TT_Project_Func)( EXEC_OP_ TT_Vector* v1,
+ TT_Vector* v2 );
+
+ /* reading a cvt value. Take care of non-square pixels if necessary */
+ typedef TT_F26Dot6 (*TT_Get_CVT_Func)( EXEC_OP_ TT_ULong index );
+
+ /* setting or moving a cvt value. Take care of non-square pixels */
+ /* if necessary */
+ typedef void (*TT_Set_CVT_Func)( EXEC_OP_ TT_ULong index,
+ TT_F26Dot6 value );
+
+
+ /*************************************************************************/
+ /* */
+ /* This structure defines a call record, used to manage function calls. */
+ /* */
+ typedef struct TT_CallRec_
+ {
+ TT_Int Caller_Range;
+ TT_Long Caller_IP;
+ TT_Long Cur_Count;
+ TT_Long Cur_Restart;
+
+ } TT_CallRec, *TT_CallStack;
+
+
+ /*************************************************************************/
+ /* */
+ /* The main structure for the interpreter which collects all necessary */
+ /* variables and states. */
+ /* */
+ typedef struct TT_ExecContextRec_
+ {
+ TT_Face face;
+ TT_Size size;
+ FT_Memory memory;
+
+ /* instructions state */
+
+ TT_Error error; /* last execution error */
+
+ TT_Long top; /* top of exec. stack */
+
+ TT_UInt stackSize; /* size of exec. stack */
+ TT_Long* stack; /* current exec. stack */
+
+ TT_Long args;
+ TT_UInt new_top; /* new top after exec. */
+
+ TT_GlyphZone zp0, /* zone records */
+ zp1,
+ zp2,
+ pts,
+ twilight;
+
+ FT_Size_Metrics metrics;
+ TT_Size_Metrics tt_metrics; /* size metrics */
+
+ TT_GraphicsState GS; /* current graphics state */
+
+ TT_Int curRange; /* current code range number */
+ TT_Byte* code; /* current code range */
+ TT_Long IP; /* current instruction pointer */
+ TT_Long codeSize; /* size of current range */
+
+ TT_Byte opcode; /* current opcode */
+ TT_Int length; /* length of current opcode */
+
+ TT_Bool step_ins; /* true if the interpreter must */
+ /* increment IP after ins. exec */
+ TT_Long cvtSize;
+ TT_Long* cvt;
+
+ TT_UInt glyphSize; /* glyph instructions buffer size */
+ TT_Byte* glyphIns; /* glyph instructions buffer */
+
+ TT_UInt numFDefs; /* number of function defs */
+ TT_UInt maxFDefs; /* maximum number of function defs */
+ TT_DefArray FDefs; /* table of FDefs entries */
+
+ TT_UInt numIDefs; /* number of instruction defs */
+ TT_UInt maxIDefs; /* maximum number of ins defs */
+ TT_DefArray IDefs; /* table of IDefs entries */
+
+ TT_UInt maxFunc; /* maximum function index */
+ TT_UInt maxIns; /* maximum instruction index */
+
+ TT_Int callTop, /* top of call stack during execution */
+ callSize; /* size of call stack */
+ TT_CallStack callStack; /* call stack */
+
+ TT_UShort maxPoints; /* capacity of this context's `pts' */
+ TT_Short maxContours; /* record, expressed in points and */
+ /* contours. */
+
+ TT_CodeRangeTable codeRangeTable; /* table of valid code ranges */
+ /* useful for the debugger */
+
+ TT_UShort storeSize; /* size of current storage */
+ TT_Long* storage; /* storage area */
+
+ TT_F26Dot6 period; /* values used for the */
+ TT_F26Dot6 phase; /* `SuperRounding' */
+ TT_F26Dot6 threshold;
+
+ /* this seems to be unused */
+#if 0
+ TT_Int cur_ppem; /* ppem along the current proj vector */
+#endif
+ TT_Bool instruction_trap; /* If `True', the interpreter will */
+ /* exit after each instruction */
+
+ TT_GraphicsState default_GS; /* graphics state resulting from */
+ /* the prep program */
+ TT_Bool is_composite; /* true if the glyph is composite */
+ TT_Bool pedantic_hinting; /* true for pedantic interpretation */
+
+ /* latest interpreter additions */
+
+ TT_Long F_dot_P; /* dot product of freedom and projection */
+ /* vectors */
+ TT_Round_Func func_round; /* current rounding function */
+
+ TT_Project_Func func_project, /* current projection function */
+ func_dualproj, /* current dual proj. function */
+ func_freeProj; /* current freedom proj. func */
+
+ TT_Move_Func func_move; /* current point move function */
+
+ TT_Get_CVT_Func func_read_cvt; /* read a cvt entry */
+ TT_Set_CVT_Func func_write_cvt; /* write a cvt entry (in pixels) */
+ TT_Set_CVT_Func func_move_cvt; /* incr a cvt entry (in pixels) */
+
+ TT_ULong loadSize;
+ TT_SubGlyph_Stack loadStack; /* loading subglyph stack */
+
+ } TT_ExecContextRec;
+
+
+
+ LOCAL_DEF
+ const TT_GraphicsState tt_default_graphics_state;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Goto_CodeRange */
+ /* */
+ /* <Description> */
+ /* Switches to a new code range (updates the code related elements in */
+ /* `exec', and `IP'). */
+ /* */
+ /* <Input> */
+ /* range :: The new execution code range. */
+ /* IP :: The new IP in the new code range. */
+ /* */
+ /* <InOut> */
+ /* exec :: The target execution context. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Goto_CodeRange( TT_ExecContext exec,
+ TT_Int range,
+ TT_Long IP );
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Set_CodeRange */
+ /* */
+ /* <Description> */
+ /* Sets a code range. */
+ /* */
+ /* <Input> */
+ /* range :: The code range index. */
+ /* base :: The new code base. */
+ /* length :: The range size in bytes. */
+ /* */
+ /* <InOut> */
+ /* exec :: The target execution context. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Set_CodeRange( TT_ExecContext exec,
+ TT_Int range,
+ void* base,
+ TT_Long length );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Clear_CodeRange */
+ /* */
+ /* <Description> */
+ /* Clears a code range. */
+ /* */
+ /* <Input> */
+ /* range :: The code range index. */
+ /* */
+ /* <InOut> */
+ /* exec :: The target execution context. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* Does not set the Error variable. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Clear_CodeRange( TT_ExecContext exec,
+ TT_Int range );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_New_Context */
+ /* */
+ /* <Description> */
+ /* Queries the face context for a given font. Note that there is */
+ /* now a _single_ execution context in the TrueType driver which is */
+ /* shared among faces. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the source face object. */
+ /* */
+ /* <Return> */
+ /* A handle to the execution context. Initialized for `face'. */
+ /* */
+ /* <Note> */
+ /* Only the glyph loader and debugger should call this function. */
+ /* */
+ EXPORT_DEF
+ TT_ExecContext TT_New_Context( TT_Face face );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Done_Context */
+ /* */
+ /* <Description> */
+ /* Discards an execution context. */
+ /* */
+ /* <Input> */
+ /* exec :: A handle to the target execution context. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* Only the glyph loader and debugger should call this function. */
+ /* */
+ EXPORT_DEF
+ TT_Error TT_Done_Context( TT_ExecContext exec );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Destroy_Context */
+ /* */
+ /* <Description> */
+ /* Destroys a given context. */
+ /* */
+ /* <Input> */
+ /* exec :: A handle to the target execution context. */
+ /* memory :: A handle to the parent memory object. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* Only the glyph loader and debugger should call this function. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Destroy_Context( TT_ExecContext exec,
+ FT_Memory memory );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Context */
+ /* */
+ /* <Description> */
+ /* Prepare an execution context for glyph hinting. */
+ /* */
+ /* <Input> */
+ /* exec :: A handle to the target execution context. */
+ /* face :: A handle to the source face object. */
+ /* size :: A handle to the source size object. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* Only the glyph loader and debugger should call this function. */
+ /* */
+ EXPORT_DEF
+ TT_Error TT_Load_Context( TT_ExecContext exec,
+ TT_Face face,
+ TT_Size size );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Save_Context */
+ /* */
+ /* <Description> */
+ /* Saves the code ranges in a `size' object. */
+ /* */
+ /* <Input> */
+ /* exec :: A handle to the source execution context. */
+ /* */
+ /* <Output> */
+ /* ins :: A handle to the target size object. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* Only the glyph loader and debugger should call this function. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Save_Context( TT_ExecContext exec,
+ TT_Size ins );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Run_Context */
+ /* */
+ /* <Description> */
+ /* Executes one or more instructions in the execution context. */
+ /* */
+ /* <Input> */
+ /* exec :: A handle to the target execution context. */
+ /* */
+ /* debug :: A Boolean flag. If set, the function sets some internal */
+ /* variables and returns immediately, otherwise TT_RunIns() */
+ /* is called. */
+ /* */
+ /* <Return> */
+ /* TrueTyoe error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* Only the glyph loader and debugger should call this function. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Run_Context( TT_ExecContext exec,
+ TT_Bool debug );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_RunIns */
+ /* */
+ /* <Description> */
+ /* Executes one or more instruction in the execution context. This */
+ /* is the main function of the TrueType opcode interpreter. */
+ /* */
+ /* <Input> */
+ /* exec :: A handle to the target execution context. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* Only object manager and debugger should call this function. */
+ /* */
+ EXPORT_DEF
+ TT_Error TT_RunIns( TT_ExecContext exec );
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* TTINTERP_H */
+
+
+/* END */
--- /dev/null
+++ b/src/truetype/ttnameid.h
@@ -1,0 +1,603 @@
+/***************************************************************************/
+/* */
+/* ttnameid.h */
+/* */
+/* TrueType name ID definitions (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 FREETYPE_H
+#error "Don't include this file! Use freetype.h instead."
+#endif
+
+
+#ifndef TTNAMEID_H
+#define TTNAMEID_H
+
+
+ /*************************************************************************/
+ /* */
+ /* Possible values for the `Platform' identifier code in the name */
+ /* records of the TTF `name' table. */
+ /* */
+#define TT_PLATFORM_APPLE_UNICODE 0
+#define TT_PLATFORM_MACINTOSH 1
+#define TT_PLATFORM_ISO 2
+#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 (1 << 0) /* U+0000-U+007F */
+/* Bit 1 C1 Controls and Latin-1 Supplement */
+#define TT_UCR_LATIN1_SUPPLEMENT (1 << 1) /* U+0080-U+00FF */
+/* Bit 2 Latin Extended-A */
+#define TT_UCR_LATIN_EXTENDED_A (1 << 2) /* U+0100-U+017F */
+/* Bit 3 Latin Extended-B */
+#define TT_UCR_LATIN_EXTENDED_B (1 << 3) /* U+0180-U+024F */
+/* Bit 4 IPA Extensions */
+#define TT_UCR_IPA_EXTENSIONS (1 << 4) /* U+0250-U+02AF */
+/* Bit 5 Spacing Modifier Letters */
+#define TT_UCR_SPACING_MODIFIER (1 << 5) /* U+02B0-U+02FF */
+/* Bit 6 Combining Diacritical Marks */
+#define TT_UCR_COMBINING_DIACRITICAL_MARKS (1 << 6) /* U+0300-U+036F */
+/* Bit 7 Greek */
+#define TT_UCR_GREEK (1 << 7) /* U+0370-U+03FF */
+/* Bit 8 is reserved (was: Greek Symbols and Coptic) */
+/* Bit 9 Cyrillic */
+#define TT_UCR_CYRILLIC (1 << 9) /* U+0400-U+04FF */
+/* Bit 10 Armenian */
+#define TT_UCR_ARMENIAN (1 << 10) /* U+0530-U+058F */
+/* Bit 11 Hebrew */
+#define TT_UCR_HEBREW (1 << 11) /* U+0590-U+05FF */
+/* Bit 12 is reserved (was: Hebrew Extended) */
+/* Bit 13 Arabic */
+#define TT_UCR_ARABIC (1 << 13) /* U+0600-U+06FF */
+/* Bit 14 is reserved (was: Arabic Extended) */
+/* Bit 15 Devanagari */
+#define TT_UCR_DEVANAGARI (1 << 15) /* U+0900-U+097F */
+/* Bit 16 Bengali */
+#define TT_UCR_BENGALI (1 << 16) /* U+0980-U+09FF */
+/* Bit 17 Gurmukhi */
+#define TT_UCR_GURMUKHI (1 << 17) /* U+0A00-U+0A7F */
+/* Bit 18 Gujarati */
+#define TT_UCR_GUJARATI (1 << 18) /* U+0A80-U+0AFF */
+/* Bit 19 Oriya */
+#define TT_UCR_ORIYA (1 << 19) /* U+0B00-U+0B7F */
+/* Bit 20 Tamil */
+#define TT_UCR_TAMIL (1 << 20) /* U+0B80-U+0BFF */
+/* Bit 21 Telugu */
+#define TT_UCR_TELUGU (1 << 21) /* U+0C00-U+0C7F */
+/* Bit 22 Kannada */
+#define TT_UCR_KANNADA (1 << 22) /* U+0C80-U+0CFF */
+/* Bit 23 Malayalam */
+#define TT_UCR_MALAYALAM (1 << 23) /* U+0D00-U+0D7F */
+/* Bit 24 Thai */
+#define TT_UCR_THAI (1 << 24) /* U+0E00-U+0E7F */
+/* Bit 25 Lao */
+#define TT_UCR_LAO (1 << 25) /* U+0E80-U+0EFF */
+/* Bit 26 Georgian */
+#define TT_UCR_GEORGIAN (1 << 26) /* U+10A0-U+10FF */
+/* Bit 27 is reserved (was Georgian Extended) */
+/* Bit 28 Hangul Jamo */
+#define TT_UCR_HANGUL_JAMO (1 << 28) /* U+1100-U+11FF */
+/* Bit 29 Latin Extended Additional */
+#define TT_UCR_LATIN_EXTENDED_ADDITIONAL (1 << 29) /* U+1E00-U+1EFF */
+/* Bit 30 Greek Extended */
+#define TT_UCR_GREEK_EXTENDED (1 << 30) /* U+1F00-U+1FFF */
+
+/* Symbols Area */
+
+/* Bit 31 General Punctuation */
+#define TT_UCR_GENERAL_PUNCTUATION (1 << 31) /* U+2000-U+206F */
+/* Bit 32 Superscripts And Subscripts */
+#define TT_UCR_SUPERSCRIPTS_SUBSCRIPTS (1 << 0) /* U+2070-U+209F */
+/* Bit 33 Currency Symbols */
+#define TT_UCR_CURRENCY_SYMBOLS (1 << 1) /* U+20A0-U+20CF */
+/* Bit 34 Combining Diacritical Marks For Symbols */
+#define TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB (1 << 2) /* U+20D0-U+20FF */
+/* Bit 35 Letterlike Symbols */
+#define TT_UCR_LETTERLIKE_SYMBOLS (1 << 3) /* U+2100-U+214F */
+/* Bit 36 Number Forms */
+#define TT_UCR_NUMBER_FORMS (1 << 4) /* U+2150-U+218F */
+/* Bit 37 Arrows */
+#define TT_UCR_ARROWS (1 << 5) /* U+2190-U+21FF */
+/* Bit 38 Mathematical Operators */
+#define TT_UCR_MATHEMATICAL_OPERATORS (1 << 6) /* U+2200-U+22FF */
+/* Bit 39 Miscellaneous Technical */
+#define TT_UCR_MISCELLANEOUS_TECHNICAL (1 << 7) /* U+2300-U+23FF */
+/* Bit 40 Control Pictures */
+#define TT_UCR_CONTROL_PICTURES (1 << 8) /* U+2400-U+243F */
+/* Bit 41 Optical Character Recognition */
+#define TT_UCR_OCR (1 << 9) /* U+2440-U+245F */
+/* Bit 42 Enclosed Alphanumerics */
+#define TT_UCR_ENCLOSED_ALPHANUMERICS (1 << 10) /* U+2460-U+24FF */
+/* Bit 43 Box Drawing */
+#define TT_UCR_BOX_DRAWING (1 << 11) /* U+2500-U+257F */
+/* Bit 44 Block Elements */
+#define TT_UCR_BLOCK_ELEMENTS (1 << 12) /* U+2580-U+259F */
+/* Bit 45 Geometric Shapes */
+#define TT_UCR_GEOMETRIC_SHAPES (1 << 13) /* U+25A0-U+25FF */
+/* Bit 46 Miscellaneous Symbols */
+#define TT_UCR_MISCELLANEOUS_SYMBOLS (1 << 14) /* U+2600-U+26FF */
+/* Bit 47 Dingbats */
+#define TT_UCR_DINGBATS (1 << 15) /* U+2700-U+27BF */
+
+/* CJK Phonetics and Symbols Area */
+
+/* Bit 48 CJK Symbols And Punctuation */
+#define TT_UCR_CJK_SYMBOLS (1 << 16) /* U+3000-U+303F */
+/* Bit 49 Hiragana */
+#define TT_UCR_HIRAGANA (1 << 17) /* U+3040-U+309F */
+/* Bit 50 Katakana */
+#define TT_UCR_KATAKANA (1 << 18) /* U+30A0-U+30FF */
+/* Bit 51 Bopomofo */
+#define TT_UCR_BOPOMOFO (1 << 19) /* U+3100-U+312F */
+/* Bit 52 Hangul Compatibility Jamo */
+#define TT_UCR_HANGUL_COMPATIBILITY_JAMO (1 << 20) /* U+3130-U+318F */
+/* Bit 53 CJK Miscellaneous */
+#define TT_UCR_CJK_MISC (1 << 21) /* U+3190-U+319F */
+/* Bit 54 Enclosed CJK Letters And Months */
+#define TT_UCR_ENCLOSED_CJK_LETTERS_MONTHS (1 << 22) /* U+3200-U+32FF */
+/* Bit 55 CJK Compatibility */
+#define TT_UCR_CJK_COMPATIBILITY (1 << 23) /* U+3300-U+33FF */
+
+/* Hangul Syllables Area */
+
+/* Bit 56 Hangul */
+#define TT_UCR_HANGUL (1 << 24) /* U+AC00-U+D7A3 */
+
+/* Surrogates Area */
+
+/* Bit 57 Surrogates */
+#define TT_UCR_SURROGATES (1 << 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 (1 << 27) /* U+4E00-U+9FFF */
+
+/* Private Use Area */
+
+/* Bit 60 Private Use */
+#define TT_UCR_PRIVATE_USE (1 << 28) /* U+E000-U+F8FF */
+
+/* Compatibility Area and Specials */
+
+/* Bit 61 CJK Compatibility Ideographs */
+#define TT_UCR_CJK_COMPATIBILITY_IDEOGRAPHS (1 << 29) /* U+F900-U+FAFF */
+/* Bit 62 Alphabetic Presentation Forms */
+#define TT_UCR_ALPHABETIC_PRESENTATION_FORMS (1 << 30) /* U+FB00-U+FB4F */
+/* Bit 63 Arabic Presentation Forms-A */
+#define TT_UCR_ARABIC_PRESENTATION_FORMS_A (1 << 31) /* U+FB50-U+FSFF */
+/* Bit 64 Combining Half Marks */
+#define TT_UCR_COMBINING_HALF_MARKS (1 << 0) /* U+FE20-U+FE2F */
+/* Bit 65 CJK Compatibility Forms */
+#define TT_UCR_CJK_COMPATIBILITY_FORMS (1 << 1) /* U+FE30-U+FE4F */
+/* Bit 66 Small Form Variants */
+#define TT_UCR_SMALL_FORM_VARIANTS (1 << 2) /* U+FE50-U+FE6F */
+/* Bit 67 Arabic Presentation Forms-B */
+#define TT_UCR_ARABIC_PRESENTATION_FORMS_B (1 << 3) /* U+FE70-U+FEFF */
+/* Bit 68 Halfwidth And Fullwidth Forms */
+#define TT_UCR_HALFWIDTH_FULLWIDTH_FORMS (1 << 4) /* U+FF00-U+FFEF */
+/* Bit 69 Specials */
+#define TT_UCR_SPECIALS (1 << 5) /* U+FEFF,
+ U+FFF0-U+FFFF */
+/* Bit 70 Tibetan */
+#define TT_UCR_TIBETAN (1 << 6) /* U+0F00-U+0FBF */
+
+
+#endif /* TTNAMEID_H */
+
+
+/* END */
--- /dev/null
+++ b/src/truetype/ttobjs.c
@@ -1,0 +1,888 @@
+/***************************************************************************/
+/* */
+/* ttobjs.c */
+/* */
+/* Objects manager (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 <freetype.h>
+#include <ftdebug.h>
+#include <ftcalc.h>
+#include <ftstream.h>
+#include <ttnameid.h>
+
+#include <sfnt.h>
+
+#include <ttpload.h>
+#include <ttinterp.h>
+#include <tterrors.h>
+
+/* required by tracing mode */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_ttobjs
+
+
+ /*************************************************************************/
+ /* */
+ /* GLYPH ZONE FUNCTIONS */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_New_GlyphZone */
+ /* */
+ /* <Description> */
+ /* Allocates a new glyph zone. */
+ /* */
+ /* <Input> */
+ /* memory :: A handle to the current memory object. */
+ /* */
+ /* maxPoints :: The capacity of glyph zone in points. */
+ /* */
+ /* maxContours :: The capacity of glyph zone in contours. */
+ /* */
+ /* <InOut> */
+ /* pts :: A pointer to the target glyph zone record. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_New_GlyphZone( FT_Memory memory,
+ TT_GlyphZone* pts,
+ TT_UShort maxPoints,
+ TT_Short 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 ( TT_Byte ) ) ||
+ ALLOC( pts->contours, maxContours * sizeof ( TT_UShort ) ) )
+ return error;
+
+ return TT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Done_GlyphZone */
+ /* */
+ /* <Description> */
+ /* Deallocates a glyph zone. */
+ /* */
+ /* <Input> */
+ /* memory :: A handle to the current memory object. */
+ /* */
+ /* pts :: A pointer to the target glyph zone record. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Done_GlyphZone( FT_Memory memory,
+ TT_GlyphZone* pts )
+ {
+ FREE( pts->contours );
+ FREE( pts->touch );
+ FREE( pts->cur );
+ FREE( pts->org );
+
+ return TT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* Get_Name */
+ /* */
+ /* <Description> */
+ /* Returns a given ENGLISH name record in ASCII. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the source face object. */
+ /* */
+ /* nameid :: The name id of the name record to return. */
+ /* */
+ /* <Return> */
+ /* Char string. NULL if no name is present. */
+ /* */
+ static
+ FT_String* Get_Name( TT_Face face,
+ TT_UShort nameid )
+ {
+ FT_Memory memory = face->root.memory;
+ TT_UShort n;
+ TT_NameRec* rec;
+ TT_Bool wide_chars = 1;
+
+ /* first pass, look for a given name record */
+
+ rec = face->name_table.names;
+ for ( n = 0; n < face->name_table.numNameRecords; n++, rec++ )
+ {
+ if ( rec->nameID == nameid )
+ {
+ /* found the name - now create an ASCII string from it */
+ TT_Bool found = 0;
+
+
+ /* Test for Microsoft English language */
+ if ( rec->platformID == TT_PLATFORM_MICROSOFT &&
+ rec->encodingID < TT_MS_ID_UNICODE_CS &&
+ (rec->languageID & 0x3FF) == 0x009 )
+ found = 1;
+
+ /* Test for Apple Unicode encoding */
+ else if ( rec->platformID == TT_PLATFORM_APPLE_UNICODE )
+ found = 1;
+
+ /* Test for Apple Roman */
+ else if ( rec->platformID == TT_PLATFORM_MACINTOSH &&
+ rec->languageID == TT_MAC_ID_ROMAN )
+ {
+ found = 1;
+ wide_chars = 0;
+ }
+
+ /* Found a Unicode Name */
+ if ( found )
+ {
+ TT_String* string;
+ TT_UInt len;
+
+ if ( wide_chars )
+ {
+ TT_UInt m;
+
+ len = (TT_UInt)rec->stringLength / 2;
+ if ( MEM_Alloc( string, len + 1 ) )
+ return NULL;
+
+ for ( m = 0; m < len; m ++ )
+ string[m] = rec->string[2*m + 1];
+ }
+ else
+ {
+ len = rec->stringLength;
+ if ( MEM_Alloc( string, len + 1 ) )
+ return NULL;
+
+ MEM_Copy( string, rec->string, len );
+ }
+
+ string[len] = '\0';
+ return string;
+ }
+ }
+ }
+ return NULL;
+ }
+
+
+#undef LOAD_
+#define LOAD_(x) ( (error = sfnt->load_##x( face, stream )) != TT_Err_Ok )
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Init_Face */
+ /* */
+ /* <Description> */
+ /* Initializes a given TrueType face object. */
+ /* */
+ /* <Input> */
+ /* resource :: The source font resource. */
+ /* face_index :: The index of the font face in the resource. */
+ /* face :: The newly built face object. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Init_Face( FT_Stream stream,
+ TT_Long face_index,
+ TT_Face face )
+ {
+ TT_Error error;
+ SFNT_Interface* sfnt;
+
+ sfnt = (SFNT_Interface*)face->sfnt;
+ if (!sfnt)
+ {
+ /* look-up the SFNT driver */
+ FT_Driver sfnt_driver;
+
+ sfnt_driver = FT_Get_Driver( face->root.driver->library, "sfnt" );
+ if (!sfnt_driver)
+ return FT_Err_Invalid_File_Format;
+
+ sfnt = (SFNT_Interface*)(sfnt_driver->interface.format_interface);
+ if (!sfnt)
+ return FT_Err_Invalid_File_Format;
+
+ face->sfnt = sfnt;
+ face->goto_table = sfnt->goto_table;
+ }
+
+ /* create input stream from resource */
+ if ( FILE_Seek(0) )
+ goto Exit;
+
+ /* Load collection directory if present, then font directory */
+ error = sfnt->load_directory( face, stream, face_index );
+ if ( error ) goto Exit;
+
+ face->root.num_faces = face->ttc_header.DirCount;
+ if ( face->root.num_faces < 1 )
+ face->root.num_faces = 1;
+
+ /* If we're performing a simple font format check, exit immediately */
+ if ( face_index < 0 )
+ return TT_Err_Ok;
+
+ /* Load tables */
+
+ if ( LOAD_( header ) ||
+ LOAD_( max_profile ) ||
+
+ (error = sfnt->load_metrics( face, stream, 0 )) != TT_Err_Ok ||
+ /* load the `hhea' & `hmtx' tables at once */
+
+ (error = sfnt->load_metrics( face, stream, 1 )) != TT_Err_Ok ||
+ /* try to load the `vhea' & `vmtx' at once if present */
+
+ LOAD_( charmaps ) ||
+ LOAD_( names ) ||
+ LOAD_( os2 ) ||
+ LOAD_( psnames ) ||
+
+ /* the optional tables */
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+ LOAD_( sbits ) ||
+#endif
+ LOAD_( hdmx ) ||
+ LOAD_( gasp ) ||
+ LOAD_( kerning ) ||
+
+ (error = TT_Load_Locations( face, stream )) != TT_Err_Ok ||
+ (error = TT_Load_CVT ( face, stream )) != TT_Err_Ok ||
+ (error = TT_Load_Programs ( face, stream )) != TT_Err_Ok )
+
+ goto Exit;
+
+#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
+ if ( ( error = TT_Extension_Create( face ) ) != TT_Err_Ok )
+ goto Exit;
+#endif
+
+ face->root.family_name = Get_Name( face, TT_NAME_ID_FONT_FAMILY );
+ face->root.style_name = Get_Name( face, TT_NAME_ID_FONT_SUBFAMILY );
+
+ Exit:
+ return error;
+ }
+
+
+#undef LOAD_
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Done_Face */
+ /* */
+ /* <Description> */
+ /* Finalizes a given face object. */
+ /* */
+ /* <Input> */
+ /* face :: A pointer to the face object to destroy. */
+ /* */
+ LOCAL_DEF
+ void TT_Done_Face( TT_Face face )
+ {
+ TT_UShort n;
+ FT_Memory memory = face->root.memory;
+
+ SFNT_Interface* sfnt = face->sfnt;
+
+ if (sfnt)
+ {
+ /* destroy the postscript names table if it is supported */
+ if (sfnt->load_psnames)
+ sfnt->free_psnames( face );
+
+ /* destroy the embedded bitmaps table if it is supported */
+ if (sfnt->load_sbits)
+ sfnt->free_sbits( face );
+ }
+
+ /* freeing the kerning table */
+ FREE( face->kern_pairs );
+ face->num_kern_pairs = 0;
+
+ /* freeing the collection table */
+ FREE( face->ttc_header.TableDirectory );
+ face->ttc_header.DirCount = 0;
+
+ /* freeing table directory */
+ FREE( face->dir_tables );
+ face->num_tables = 0;
+
+ /* freeing the locations table */
+ FREE( face->glyph_locations );
+ face->num_locations = 0;
+
+ /* freeing the character mapping tables */
+ if (sfnt && sfnt->load_charmaps )
+ {
+ for ( n = 0; n < face->num_charmaps; n++ )
+ sfnt->free_charmap( face, &face->charmaps[n].cmap );
+ }
+
+ FREE( face->charmaps );
+ face->num_charmaps = 0;
+
+ FREE( face->root.charmaps );
+ face->root.num_charmaps = 0;
+ face->root.charmap = 0;
+
+ /* freeing the CVT */
+ FREE( face->cvt );
+ face->cvt_size = 0;
+
+ /* freeing the horizontal metrics */
+ FREE( face->horizontal.long_metrics );
+ FREE( face->horizontal.short_metrics );
+
+ /* freeing the vertical ones, if any */
+ if ( face->vertical_info )
+ {
+ FREE( face->vertical.long_metrics );
+ FREE( face->vertical.short_metrics );
+ face->vertical_info = 0;
+ }
+
+ /* freeing the programs */
+ FREE( face->font_program );
+ FREE( face->cvt_program );
+ face->font_program_size = 0;
+ face->cvt_program_size = 0;
+
+ /* freeing the gasp table */
+ FREE( face->gasp.gaspRanges );
+ face->gasp.numRanges = 0;
+
+ /* freeing the name table */
+ sfnt->free_names( face );
+
+ /* freeing the hdmx table */
+ sfnt->free_hdmx( face );
+
+ /* freeing family and style name */
+ FREE( face->root.family_name );
+ FREE( face->root.style_name );
+
+ face->sfnt = 0;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* SIZE FUNCTIONS */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Init_Size */
+ /* */
+ /* <Description> */
+ /* Initializes a new TrueType size object. */
+ /* */
+ /* <InOut> */
+ /* size :: A handle to the size object. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Init_Size( TT_Size size )
+ {
+ TT_Face face = (TT_Face)size->root.face;
+ FT_Memory memory = face->root.memory;
+ TT_Error error;
+ TT_Int i;
+ TT_UShort n_twilight;
+
+ TT_MaxProfile* maxp = &face->max_profile;
+ TT_ExecContext exec;
+
+ size->ttmetrics.valid = FALSE;
+
+ size->max_function_defs = maxp->maxFunctionDefs;
+ size->max_instruction_defs = maxp->maxInstructionDefs;
+
+ size->num_function_defs = 0;
+ size->num_instruction_defs = 0;
+
+ size->max_func = 0;
+ size->max_ins = 0;
+
+ size->cvt_size = face->cvt_size;
+ size->storage_size = maxp->maxStorage;
+
+ /* Set default metrics */
+ {
+ FT_Size_Metrics* metrics = &size->root.metrics;
+ TT_Size_Metrics* metrics2 = &size->ttmetrics;
+
+ metrics->x_ppem = 0;
+ metrics->y_ppem = 0;
+
+ metrics2->rotated = FALSE;
+ metrics2->stretched = FALSE;
+
+ /* set default compensation (all 0) */
+ for ( i = 0; i < 4; i++ )
+ metrics2->compensations[i] = 0;
+ }
+
+ /* allocate function defs, instruction defs, cvt and storage area */
+ if ( ALLOC_ARRAY( size->function_defs,
+ size->max_function_defs,
+ TT_DefRecord ) ||
+
+ ALLOC_ARRAY( size->instruction_defs,
+ size->max_instruction_defs,
+ TT_DefRecord ) ||
+
+ ALLOC_ARRAY( size->cvt,
+ size->cvt_size, TT_Long ) ||
+
+ ALLOC_ARRAY( size->storage,
+ size->storage_size, TT_Long ) )
+
+ goto Fail_Memory;
+
+ /* reserve twilight zone */
+ n_twilight = maxp->maxTwilightPoints;
+ error = TT_New_GlyphZone( memory, &size->twilight, n_twilight, 0 );
+ if ( error )
+ goto Fail_Memory;
+
+ size->twilight.n_points = n_twilight;
+
+ /* set `face->interpreter' according to the debug hook present */
+ {
+ FT_Library library = face->root.driver->library;
+
+ face->interpreter = (TT_Interpreter)
+ library->debug_hooks[ FT_DEBUG_HOOK_TRUETYPE ];
+ if (!face->interpreter)
+ face->interpreter = (TT_Interpreter)TT_RunIns;
+ }
+
+ /* Fine, now execute the font program! */
+ exec = size->context;
+ if (!size->debug)
+ exec = TT_New_Context( face );
+ /* size objects used during debugging have their own context */
+
+ if ( !exec )
+ {
+ error = TT_Err_Could_Not_Find_Context;
+ goto Fail_Memory;
+ }
+
+ size->GS = tt_default_graphics_state;
+ TT_Load_Context( exec, face, size );
+
+ exec->callTop = 0;
+ exec->top = 0;
+
+ exec->period = 64;
+ exec->phase = 0;
+ exec->threshold = 0;
+
+ {
+ FT_Size_Metrics* metrics = &exec->metrics;
+ TT_Size_Metrics* tt_metrics = &exec->tt_metrics;
+
+
+ metrics->x_ppem = 0;
+ metrics->y_ppem = 0;
+ metrics->x_scale = 0;
+ metrics->y_scale = 0;
+
+ tt_metrics->ppem = 0;
+ tt_metrics->scale = 0;
+ tt_metrics->ratio = 0x10000;
+ }
+
+ exec->instruction_trap = FALSE;
+
+ exec->cvtSize = size->cvt_size;
+ exec->cvt = size->cvt;
+
+ exec->F_dot_P = 0x10000L;
+
+ /* allow font program execution */
+ TT_Set_CodeRange( exec,
+ tt_coderange_font,
+ face->font_program,
+ face->font_program_size );
+
+ /* disable CVT and glyph programs coderange */
+ TT_Clear_CodeRange( exec, tt_coderange_cvt );
+ TT_Clear_CodeRange( exec, tt_coderange_glyph );
+
+ if ( face->font_program_size > 0 )
+ {
+ error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 );
+ if ( !error )
+ error = face->interpreter( exec );
+
+ if ( error )
+ goto Fail_Exec;
+ }
+ else
+ error = TT_Err_Ok;
+
+ TT_Save_Context( exec, size );
+
+ if ( !size->debug )
+ TT_Done_Context( exec );
+
+ size->ttmetrics.valid = FALSE;
+ return error;
+
+ Fail_Exec:
+ if ( !size->debug )
+ TT_Done_Context( exec );
+
+ Fail_Memory:
+ TT_Done_Size( size );
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Done_Size */
+ /* */
+ /* <Description> */
+ /* The TrueType size object finalizer. */
+ /* */
+ /* <Input> */
+ /* size :: A handle to the target size object. */
+ /* */
+ LOCAL_FUNC
+ void TT_Done_Size( TT_Size size )
+ {
+ FT_Memory memory = size->root.face->memory;
+
+
+ if ( size->debug )
+ {
+ /* the debug context must be deleted by the debugger itself */
+ size->context = NULL;
+ size->debug = FALSE;
+ }
+
+ FREE( size->cvt );
+ size->cvt_size = 0;
+
+ /* free storage area */
+ FREE( size->storage );
+ size->storage_size = 0;
+
+ /* twilight zone */
+ TT_Done_GlyphZone( memory, &size->twilight );
+
+ FREE( size->function_defs );
+ FREE( size->instruction_defs );
+ size->num_function_defs = 0;
+ size->max_function_defs = 0;
+ size->num_instruction_defs = 0;
+ size->max_instruction_defs = 0;
+
+ size->max_func = 0;
+ size->max_ins = 0;
+
+ size->ttmetrics.valid = FALSE;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Reset_Size */
+ /* */
+ /* <Description> */
+ /* Resets a TrueType size when resolutions and character dimensions */
+ /* have been changed. */
+ /* */
+ /* <Input> */
+ /* size :: A handle to the target size object. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Reset_Size( TT_Size size )
+ {
+ TT_ExecContext exec;
+ TT_Error error;
+ TT_UShort i, j;
+ TT_Face face;
+
+ FT_Size_Metrics* metrics;
+
+ if ( size->ttmetrics.valid )
+ return TT_Err_Ok;
+
+ face = (TT_Face)size->root.face;
+
+ metrics = &size->root.metrics;
+
+ if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 )
+ return TT_Err_Invalid_PPem;
+
+ /* compute new transformation */
+ if ( metrics->x_ppem >= metrics->y_ppem )
+ {
+ size->ttmetrics.scale = metrics->x_scale;
+ size->ttmetrics.ppem = metrics->x_ppem;
+ size->ttmetrics.x_ratio = 0x10000;
+ size->ttmetrics.y_ratio = FT_MulDiv( metrics->y_ppem,
+ 0x10000L,
+ metrics->x_ppem );
+ }
+ else
+ {
+ size->ttmetrics.scale = metrics->y_scale;
+ size->ttmetrics.ppem = metrics->y_ppem;
+ size->ttmetrics.x_ratio = FT_MulDiv( metrics->x_ppem,
+ 0x10000L,
+ metrics->y_ppem );
+ size->ttmetrics.y_ratio = 0x10000;
+ }
+
+ /* Compute root ascender, descender, test height, and max_advance */
+ metrics->ascender = ( FT_MulFix( face->root.ascender,
+ metrics->y_scale ) + 32 ) & -64;
+
+ metrics->descender = ( FT_MulFix( face->root.descender,
+ metrics->y_scale ) + 32 ) & -64;
+
+ metrics->height = ( FT_MulFix( face->root.height,
+ metrics->y_scale ) + 32 ) & -64;
+
+ metrics->max_advance = ( FT_MulFix( face->root.max_advance_width,
+ metrics->x_scale ) + 32 ) & -64;
+
+ /* Scale the cvt values to the new ppem. */
+ /* We use by default the y ppem to scale the CVT. */
+
+ for ( i = 0; i < size->cvt_size; i++ )
+ size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
+
+ /* All twilight points are originally zero */
+ for ( j = 0; j < size->twilight.n_points; j++ )
+ {
+ size->twilight.org[j].x = 0;
+ size->twilight.org[j].y = 0;
+ size->twilight.cur[j].x = 0;
+ size->twilight.cur[j].y = 0;
+ }
+
+ /* clear storage area */
+ for ( i = 0; i < size->storage_size; i++ )
+ size->storage[i] = 0;
+
+ size->GS = tt_default_graphics_state;
+
+ /* get execution context and run prep program */
+ if ( size->debug )
+ exec = size->context;
+ else
+ exec = TT_New_Context( face );
+ /* debugging instances have their own context */
+
+ if ( !exec )
+ return TT_Err_Could_Not_Find_Context;
+
+ TT_Load_Context( exec, face, size );
+
+ TT_Set_CodeRange( exec,
+ tt_coderange_cvt,
+ face->cvt_program,
+ face->cvt_program_size );
+
+ TT_Clear_CodeRange( exec, tt_coderange_glyph );
+
+ exec->instruction_trap = FALSE;
+
+ exec->top = 0;
+ exec->callTop = 0;
+
+ if ( face->cvt_program_size > 0 )
+ {
+ error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
+ if ( error )
+ goto Fin;
+
+ if ( !size->debug )
+ error = face->interpreter( exec );
+ }
+ else
+ error = TT_Err_Ok;
+
+ size->GS = exec->GS;
+ /* save default graphics state */
+
+ Fin:
+ TT_Save_Context( exec, size );
+
+ if ( !size->debug )
+ TT_Done_Context( exec );
+ /* debugging instances keep their context */
+
+ if ( !error )
+ size->ttmetrics.valid = TRUE;
+
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Init_GlyphSlot */
+ /* */
+ /* <Description> */
+ /* The TrueType glyph slot initializer. */
+ /* */
+ /* <Input> */
+ /* slot :: The glyph record to build. */
+ /* */
+ /* <Output> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Init_GlyphSlot( TT_GlyphSlot slot )
+ {
+ /* allocate the outline space */
+ FT_Face face = slot->face;
+ FT_Library library = face->driver->library;
+
+
+ FT_TRACE4(( "TT.Init_GlyphSlot: Creating outline maxp = %d, maxc = %d\n",
+ face->max_points, face->max_contours ));
+
+ return FT_New_Outline( library,
+ face->max_points + 2,
+ face->max_contours,
+ &slot->outline );
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Done_GlyphSlot */
+ /* */
+ /* <Description> */
+ /* The TrueType glyph slot finalizer. */
+ /* */
+ /* <Input> */
+ /* slot :: A handle to the glyph slot object. */
+ /* */
+ LOCAL_FUNC
+ void TT_Done_GlyphSlot( TT_GlyphSlot slot )
+ {
+ FT_Library library = slot->face->driver->library;
+
+
+ FT_Done_Outline( library, &slot->outline );
+ return;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Init_Driver */
+ /* */
+ /* <Description> */
+ /* Initializes a given TrueType driver object. */
+ /* */
+ /* <Input> */
+ /* driver :: A handle to the target driver object. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Init_Driver( TT_Driver driver )
+ {
+ /* init extension registry if needed */
+#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
+ return TT_Init_Extensions( driver );
+#else
+ UNUSED( driver );
+
+ return TT_Err_Ok;
+#endif
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Done_Driver */
+ /* */
+ /* <Description> */
+ /* Finalizes a given TrueType driver. */
+ /* */
+ /* <Input> */
+ /* driver :: A handle to the target TrueType driver. */
+ /* */
+ LOCAL_FUNC
+ void TT_Done_Driver( TT_Driver driver )
+ {
+ /* destroy extensions registry if needed */
+#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
+ TT_Done_Extensions( driver );
+#endif
+
+ /* destroy the execution context */
+ if ( driver->context )
+ {
+ TT_Destroy_Context( driver->context, driver->root.memory );
+ driver->context = NULL;
+ }
+ }
+
+
+/* END */
--- /dev/null
+++ b/src/truetype/ttobjs.h
@@ -1,0 +1,594 @@
+/***************************************************************************/
+/* */
+/* ttobjs.h */
+/* */
+/* Objects manager (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 TTOBJS_H
+#define TTOBJS_H
+
+
+#include <ftobjs.h>
+#include <tttypes.h>
+#include <ttconfig.h>
+#include <tterrors.h>
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_Driver */
+ /* */
+ /* <Description> */
+ /* A handle to a TrueType driver object. */
+ /* */
+ typedef struct TT_DriverRec_* TT_Driver;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_Instance */
+ /* */
+ /* <Description> */
+ /* A handle to a TrueType size object. */
+ /* */
+ typedef struct TT_SizeRec_* TT_Size;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> */
+ /* TT_GlyphSlot */
+ /* */
+ /* <Description> */
+ /* A handle to a TrueType glyph slot object. */
+ /* */
+ /* <Note> */
+ /* This is a direct typedef of FT_GlyphSlot, as there is nothing */
+ /* specific about the TrueType glyph slot. */
+ /* */
+ typedef FT_GlyphSlot TT_GlyphSlot;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* TT_GraphicsState */
+ /* */
+ /* <Description> */
+ /* The TrueType graphics state used during bytecode interpretation. */
+ /* */
+ typedef struct TT_GraphicsState_
+ {
+ TT_UShort rp0;
+ TT_UShort rp1;
+ TT_UShort rp2;
+
+ TT_UnitVector dualVector;
+ TT_UnitVector projVector;
+ TT_UnitVector freeVector;
+
+ TT_Long loop;
+ TT_F26Dot6 minimum_distance;
+ TT_Int round_state;
+
+ TT_Bool auto_flip;
+ TT_F26Dot6 control_value_cutin;
+ TT_F26Dot6 single_width_cutin;
+ TT_F26Dot6 single_width_value;
+ TT_Short delta_base;
+ TT_Short delta_shift;
+
+ TT_Byte instruct_control;
+ TT_Bool scan_control;
+ TT_Int scan_type;
+
+ TT_UShort gep0;
+ TT_UShort gep1;
+ TT_UShort gep2;
+
+ } TT_GraphicsState;
+
+
+ /*************************************************************************/
+ /* */
+ /* EXECUTION SUBTABLES */
+ /* */
+ /* These sub-tables relate to instruction execution. */
+ /* */
+ /*************************************************************************/
+
+
+#define TT_MAX_CODE_RANGES 3
+
+
+ /*************************************************************************/
+ /* */
+ /* There can only be 3 active code ranges at once: */
+ /* - the Font Program */
+ /* - the CVT Program */
+ /* - a glyph's instructions set */
+ /* */
+ typedef enum TT_CodeRange_Tag_
+ {
+ tt_coderange_none = 0,
+ tt_coderange_font,
+ tt_coderange_cvt,
+ tt_coderange_glyph
+
+ } TT_CodeRange_Tag;
+
+
+ typedef struct TT_CodeRange_
+ {
+ TT_Byte* base;
+ TT_ULong size;
+
+ } TT_CodeRange;
+
+ typedef TT_CodeRange TT_CodeRangeTable[TT_MAX_CODE_RANGES];
+
+
+ /*************************************************************************/
+ /* */
+ /* Defines a function/instruction definition record. */
+ /* */
+ typedef struct TT_DefRecord_
+ {
+ TT_Int range; /* in which code range is it located? */
+ TT_Long start; /* where does it start? */
+ TT_UInt opc; /* function #, or instruction code */
+ TT_Bool active; /* is it active? */
+
+ } TT_DefRecord, *TT_DefArray;
+
+
+ /*************************************************************************/
+ /* */
+ /* This type defining a set of glyph points will be used to represent */
+ /* each zone (regular and twilight) during instructions decoding. */
+ /* */
+ typedef struct TT_GlyphZone_
+ {
+ TT_UShort n_points; /* number of points in zone */
+ TT_Short n_contours; /* number of contours */
+
+ TT_Vector* org; /* original point coordinates */
+ TT_Vector* cur; /* current point coordinates */
+
+ TT_Byte* touch; /* current touch flags */
+ TT_UShort* contours; /* contour end points */
+
+ } TT_GlyphZone;
+
+
+ /*************************************************************************/
+ /* */
+ /* Subglyph transformation record. */
+ /* */
+ typedef struct TT_Transform_
+ {
+ TT_Fixed xx, xy; /* transformation matrix coefficients */
+ TT_Fixed yx, yy;
+ TT_F26Dot6 ox, oy; /* offsets */
+
+ } TT_Transform;
+
+
+ /*************************************************************************/
+ /* */
+ /* Subglyph loading record. Used to load composite components. */
+ /* */
+ typedef struct TT_SubglyphRec_
+ {
+ TT_Long index; /* subglyph index; initialized with -1 */
+ TT_Bool is_scaled; /* is the subglyph scaled? */
+ TT_Bool is_hinted; /* should it be hinted? */
+ TT_Bool preserve_pps; /* preserve phantom points? */
+
+ TT_Long file_offset;
+
+ TT_BBox bbox;
+ TT_Pos left_bearing;
+ TT_Pos advance;
+
+ TT_GlyphZone zone;
+
+ TT_Long arg1; /* first argument */
+ TT_Long arg2; /* second argument */
+
+ TT_UShort element_flag; /* current load element flag */
+
+ TT_Transform transform; /* transformation matrix */
+
+ TT_Vector pp1, pp2; /* phantom points */
+
+ } TT_SubGlyphRec, *TT_SubGlyph_Stack;
+
+
+ /*************************************************************************/
+ /* */
+ /* A note regarding non-squared pixels: */
+ /* */
+ /* (This text will probably go into some docs at some time, for now, it */
+ /* is kept here to explain some definitions in the TIns_Metrics */
+ /* record). */
+ /* */
+ /* The CVT is a one-dimensional array containing values that control */
+ /* certain important characteristics in a font, like the height of all */
+ /* capitals, all lowercase letter, default spacing or stem width/height. */
+ /* */
+ /* These values are found in FUnits in the font file, and must be scaled */
+ /* to pixel coordinates before being used by the CVT and glyph programs. */
+ /* Unfortunately, when using distinct x and y resolutions (or distinct x */
+ /* and y pointsizes), there are two possible scalings. */
+ /* */
+ /* A first try was to implement a `lazy' scheme where all values were */
+ /* scaled when first used. However, while some values are always used */
+ /* in the same direction, some others are used under many different */
+ /* circumstances and orientations. */
+ /* */
+ /* I have found a simpler way to do the same, and it even seems to work */
+ /* in most of the cases: */
+ /* */
+ /* - All CVT values are scaled to the maximum ppem size. */
+ /* */
+ /* - When performing a read or write in the CVT, a ratio factor is used */
+ /* to perform adequate scaling. Example: */
+ /* */
+ /* x_ppem = 14 */
+ /* y_ppem = 10 */
+ /* */
+ /* We choose ppem = x_ppem = 14 as the CVT scaling size. All cvt */
+ /* entries are scaled to it. */
+ /* */
+ /* x_ratio = 1.0 */
+ /* y_ratio = y_ppem/ppem (< 1.0) */
+ /* */
+ /* We compute the current ratio like: */
+ /* */
+ /* - If projVector is horizontal, */
+ /* ratio = x_ratio = 1.0 */
+ /* */
+ /* - if projVector is vertical, */
+ /* ratio = y_ratio */
+ /* */
+ /* - else, */
+ /* ratio = sqrt( (proj.x * x_ratio) ^ 2 + (proj.y * y_ratio) ^ 2 ) */
+ /* */
+ /* Reading a cvt value returns */
+ /* ratio * cvt[index] */
+ /* */
+ /* Writing a cvt value in pixels: */
+ /* cvt[index] / ratio */
+ /* */
+ /* The current ppem is simply */
+ /* ratio * ppem */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* Metrics used by the TrueType size and context objects. */
+ /* */
+ typedef struct TT_Size_Metrics_
+ {
+ /* for non-square pixels */
+ TT_Long x_ratio;
+ TT_Long y_ratio;
+
+ TT_UShort ppem; /* maximum ppem size */
+ TT_Long ratio; /* current ratio */
+ TT_Fixed scale;
+
+ TT_F26Dot6 compensations[4]; /* device-specific compensations */
+
+ TT_Bool valid;
+
+ TT_Bool rotated; /* `is the glyph rotated?'-flag */
+ TT_Bool stretched; /* `is the glyph stretched?'-flag */
+
+ } TT_Size_Metrics;
+
+
+ /*************************************************************************/
+ /* */
+ /* FreeType execution context type. */
+ /* */
+ /* This is a forward declaration; the full specification is in the file */
+ /* `ttinterp.h'. */
+ /* */
+ typedef struct TT_ExecContextRec_* TT_ExecContext;
+
+
+ /***********************************************************************/
+ /* */
+ /* TrueType size class. */
+ /* */
+ typedef struct TT_SizeRec_
+ {
+ FT_SizeRec root;
+
+ TT_Size_Metrics ttmetrics;
+
+ TT_UInt num_function_defs; /* number of function definitions */
+ TT_UInt max_function_defs;
+ TT_DefArray function_defs; /* table of function definitions */
+
+ TT_UInt num_instruction_defs; /* number of ins. definitions */
+ TT_UInt max_instruction_defs;
+ TT_DefArray instruction_defs; /* table of ins. definitions */
+
+ TT_UInt max_func;
+ TT_UInt max_ins;
+
+ TT_CodeRangeTable codeRangeTable;
+
+ TT_GraphicsState GS;
+
+ TT_ULong cvt_size; /* the scaled control value table */
+ TT_Long* cvt;
+
+ TT_UShort storage_size; /* The storage area is now part of */
+ TT_Long* storage; /* the instance */
+
+ TT_GlyphZone twilight; /* The instance's twilight zone */
+
+ /* debugging variables */
+
+ /* When using the debugger, we must keep the */
+ /* execution context tied to the instance */
+ /* object rather than asking it on demand. */
+
+ TT_Bool debug;
+ TT_ExecContext context;
+
+ } TT_SizeRec;
+
+
+ /***********************************************************************/
+ /* */
+ /* TrueType driver class. */
+ /* */
+ typedef struct TT_DriverRec_
+ {
+ FT_DriverRec root;
+ TT_ExecContext context; /* execution context */
+
+ void* extension_component;
+
+ } TT_DriverRec;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_New_GlyphZone */
+ /* */
+ /* <Description> */
+ /* Allocates a new glyph zone. */
+ /* */
+ /* <Input> */
+ /* memory :: A handle to the current memory object. */
+ /* */
+ /* maxPoints :: The capacity of glyph zone in points. */
+ /* */
+ /* maxContours :: The capacity of glyph zone in contours. */
+ /* */
+ /* <InOut> */
+ /* pts :: A pointer to the target glyph zone record. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_New_GlyphZone( FT_Memory memory,
+ TT_GlyphZone* pts,
+ TT_UShort maxPoints,
+ TT_Short maxContours );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Done_GlyphZone */
+ /* */
+ /* <Description> */
+ /* Deallocates a glyph zone. */
+ /* */
+ /* <Input> */
+ /* memory :: A handle to the current memory object. */
+ /* */
+ /* pts :: A pointer to the target glyph zone record. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Done_GlyphZone( FT_Memory memory,
+ TT_GlyphZone* pts );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Init_Face */
+ /* */
+ /* <Description> */
+ /* Initializes a given TrueType face object. */
+ /* */
+ /* <Input> */
+ /* resource :: The source font resource. */
+ /* face_index :: The index of the font face in the resource. */
+ /* face :: The newly built face object. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Init_Face( FT_Stream stream,
+ TT_Long face_index,
+ TT_Face face );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Done_Face */
+ /* */
+ /* <Description> */
+ /* Finalizes a given face object. */
+ /* */
+ /* <Input> */
+ /* face :: The target face object to finalize. */
+ /* */
+ LOCAL_DEF
+ void TT_Done_Face( TT_Face face );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Init_Size */
+ /* */
+ /* <Description> */
+ /* Initializes a new TrueType size object. */
+ /* */
+ /* <Input> */
+ /* size :: A handle to the size object. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Init_Size( TT_Size size );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Done_Size */
+ /* */
+ /* <Description> */
+ /* The TrueType size object finalizer. */
+ /* */
+ /* <Input> */
+ /* size :: A handle to the target size object. */
+ /* */
+ LOCAL_DEF
+ void TT_Done_Size( TT_Size size );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Reset_Size */
+ /* */
+ /* <Description> */
+ /* Resets a TrueType size when resolutions and character dimensions */
+ /* have been changed. */
+ /* */
+ /* <Input> */
+ /* size :: A handle to the target size object. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Reset_Size( TT_Size size );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Init_GlyphSlot */
+ /* */
+ /* <Description> */
+ /* The TrueType glyph slot initializer. */
+ /* */
+ /* <Input> */
+ /* glyph :: The glyph record to build. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Init_GlyphSlot( TT_GlyphSlot slot );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Done_GlyphSlot */
+ /* */
+ /* <Description> */
+ /* The TrueType glyph slot finalizer. */
+ /* */
+ /* <Input> */
+ /* glyph :: A handle to the glyph slot object. */
+ /* */
+ LOCAL_DEF
+ void TT_Done_GlyphSlot( TT_GlyphSlot slot );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Init_Driver */
+ /* */
+ /* <Description> */
+ /* Initializes a given TrueType driver object. */
+ /* */
+ /* <Input> */
+ /* driver :: A handle to the target driver object. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Init_Driver( TT_Driver driver );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Done_Driver */
+ /* */
+ /* <Description> */
+ /* Finalizes a given TrueType driver. */
+ /* */
+ /* <Input> */
+ /* driver :: A handle to the target TrueType driver. */
+ /* */
+ LOCAL_DEF
+ void TT_Done_Driver( TT_Driver driver );
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+
+#endif /* TTOBJS_H */
+
+
+/* END */
--- /dev/null
+++ b/src/truetype/ttpload.c
@@ -1,0 +1,260 @@
+/***************************************************************************/
+/* */
+/* ttpload.h */
+/* */
+/* TrueType glyph data/program tables loader (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 <ftdebug.h>
+#include <ftobjs.h>
+#include <ftstream.h>
+
+#include <ttpload.h>
+#include <tttags.h>
+#include <tterrors.h>
+
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_ttload
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Locations */
+ /* */
+ /* <Description> */
+ /* Loads the locations table. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_Locations( TT_Face face,
+ FT_Stream stream )
+ {
+ TT_Error error;
+ FT_Memory memory = stream->memory;
+ TT_Short LongOffsets;
+ TT_ULong table_len;
+
+ FT_TRACE2(( "Locations " ));
+ LongOffsets = face->header.Index_To_Loc_Format;
+
+ error = face->goto_table( face, TTAG_loca, stream, &table_len );
+ if (error)
+ {
+ error = TT_Err_Locations_Missing;
+ goto Exit;
+ }
+
+ if ( LongOffsets != 0 )
+ {
+ face->num_locations = (TT_UShort)(table_len >> 2);
+
+ FT_TRACE2(( "(32 bits offsets): %12d ", face->num_locations ));
+
+ if ( ALLOC_ARRAY( face->glyph_locations,
+ face->num_locations,
+ TT_Long ) )
+ goto Exit;
+
+ if ( ACCESS_Frame( face->num_locations * 4L ) )
+ goto Exit;
+
+ {
+ TT_Long* loc = face->glyph_locations;
+ TT_Long* limit = loc + face->num_locations;
+
+ for ( ; loc < limit; loc++ )
+ *loc = GET_Long();
+ }
+
+ FORGET_Frame();
+ }
+ else
+ {
+ face->num_locations = (TT_UShort)(table_len >> 1);
+
+ FT_TRACE2(( "(16 bits offsets): %12d ",
+ face->num_locations ));
+
+ if ( ALLOC_ARRAY( face->glyph_locations,
+ face->num_locations,
+ TT_Long ) )
+ goto Exit;
+
+ if ( ACCESS_Frame( face->num_locations * 2L ) )
+ goto Exit;
+ {
+ TT_Long* loc = face->glyph_locations;
+ TT_Long* limit = loc + face->num_locations;
+
+ for ( ; loc < limit; loc++ )
+ *loc = (TT_Long)((TT_ULong)GET_UShort() * 2);
+ }
+ FORGET_Frame();
+ }
+
+ FT_TRACE2(( "loaded\n" ));
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_CVT */
+ /* */
+ /* <Description> */
+ /* Loads the control value table into a face object. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: A handle to the input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_CVT( TT_Face face,
+ FT_Stream stream )
+ {
+ TT_Error error;
+ FT_Memory memory = stream->memory;
+ TT_ULong table_len;
+
+ FT_TRACE2(( "CVT " ));
+
+ error = face->goto_table( face, TTAG_cvt, stream, &table_len );
+ if (error)
+ {
+ FT_TRACE2(( "is missing!\n" ));
+
+ face->cvt_size = 0;
+ face->cvt = NULL;
+ error = TT_Err_Ok;
+
+ goto Exit;
+ }
+
+ face->cvt_size = table_len / 2;
+
+ if ( ALLOC_ARRAY( face->cvt,
+ face->cvt_size,
+ TT_Short ) )
+ goto Exit;
+
+ if ( ACCESS_Frame( face->cvt_size * 2L ) )
+ goto Exit;
+
+ {
+ TT_Short* cur = face->cvt;
+ TT_Short* limit = cur + face->cvt_size;
+
+ for ( ; cur < limit; cur++ )
+ *cur = GET_Short();
+ }
+
+ FORGET_Frame();
+ FT_TRACE2(( "loaded\n" ));
+
+ Exit:
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Progams */
+ /* */
+ /* <Description> */
+ /* Loads the font program and the cvt program. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: A handle to the input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_FUNC
+ TT_Error TT_Load_Programs( TT_Face face,
+ FT_Stream stream )
+ {
+ TT_Error error;
+ FT_Memory memory = stream->memory;
+ TT_ULong table_len;
+
+ FT_TRACE2(( "Font program " ));
+
+ error = TT_Err_Ok;
+
+ /* The font program is optional */
+ error = face->goto_table( face, TTAG_fpgm, stream, &table_len );
+ if (error)
+ {
+ face->font_program = NULL;
+ face->font_program_size = 0;
+ FT_TRACE2(( "is missing!\n" ));
+ }
+ else
+ {
+ face->font_program_size = table_len;
+
+ if ( ALLOC( face->font_program,
+ face->font_program_size ) ||
+
+ FILE_Read( (void*)face->font_program,
+ face->font_program_size ) )
+ goto Exit;
+
+ FT_TRACE2(( "loaded, %12d bytes\n", face->font_program_size ));
+ }
+
+ FT_TRACE2(( "Prep program " ));
+
+ error = face->goto_table( face, TTAG_prep, stream, &table_len );
+ if (error)
+ {
+ face->cvt_program = NULL;
+ face->cvt_program_size = 0;
+
+ FT_TRACE2(( "is missing!\n" ));
+ }
+ else
+ {
+ face->cvt_program_size = table_len;
+
+ if ( ALLOC( face->cvt_program,
+ face->cvt_program_size ) ||
+
+ FILE_Read( (void*)face->cvt_program,
+ face->cvt_program_size ) )
+ return error;
+
+ FT_TRACE2(( "loaded, %12d bytes\n", face->cvt_program_size ));
+ }
+
+ Exit:
+ return error;
+ }
+
+
+/* END */
--- /dev/null
+++ b/src/truetype/ttpload.h
@@ -1,0 +1,92 @@
+/***************************************************************************/
+/* */
+/* ttpload.h */
+/* */
+/* TrueType glyph data/program tables loader (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 TTPLOAD_H
+#define TTPLOAD_H
+
+#include <tttypes.h>
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Locations */
+ /* */
+ /* <Description> */
+ /* Loads the locations table. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: The input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_Locations( TT_Face face,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_CVT */
+ /* */
+ /* <Description> */
+ /* Loads the control value table into a face object. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: A handle to the input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_CVT( TT_Face face,
+ FT_Stream stream );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Load_Progams */
+ /* */
+ /* <Description> */
+ /* Loads the font program and the cvt program. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the target face object. */
+ /* stream :: A handle to the input stream. */
+ /* */
+ /* <Return> */
+ /* TrueType error code. 0 means success. */
+ /* */
+ LOCAL_DEF
+ TT_Error TT_Load_Programs( TT_Face face,
+ FT_Stream stream );
+
+#endif /* TTPLOAD_H */
+
+
+/* END */
--- /dev/null
+++ b/src/truetype/tttags.h
@@ -1,0 +1,60 @@
+/***************************************************************************/
+/* */
+/* 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 <freetype.h> /* for MAKE_TT_TAG() */
+
+
+#define TTAG_cmap FT_MAKE_TAG( 'c', 'm', 'a', 'p' )
+#define TTAG_cvt FT_MAKE_TAG( 'c', 'v', 't', ' ' )
+#define TTAG_EBDT FT_MAKE_TAG( 'E', 'B', 'D', 'T' )
+#define TTAG_EBLC FT_MAKE_TAG( 'E', 'B', 'L', 'C' )
+#define TTAG_EBSC FT_MAKE_TAG( 'E', 'B', 'S', 'C' )
+#define TTAG_fpgm FT_MAKE_TAG( 'f', 'p', 'g', 'm' )
+#define TTAG_gasp FT_MAKE_TAG( 'g', 'a', 's', 'p' )
+#define TTAG_glyf FT_MAKE_TAG( 'g', 'l', 'y', 'f' )
+#define TTAG_GSUB FT_MAKE_TAG( 'G', 'S', 'U', 'B' )
+#define TTAG_hdmx FT_MAKE_TAG( 'h', 'd', 'm', 'x' )
+#define TTAG_head FT_MAKE_TAG( 'h', 'e', 'a', 'd' )
+#define TTAG_hhea FT_MAKE_TAG( 'h', 'h', 'e', 'a' )
+#define TTAG_hmtx FT_MAKE_TAG( 'h', 'm', 't', 'x' )
+#define TTAG_kern FT_MAKE_TAG( 'k', 'e', 'r', 'n' )
+#define TTAG_loca FT_MAKE_TAG( 'l', 'o', 'c', 'a' )
+#define TTAG_LTSH FT_MAKE_TAG( 'L', 'T', 'S', 'H' )
+#define TTAG_maxp FT_MAKE_TAG( 'm', 'a', 'x', 'p' )
+#define TTAG_name FT_MAKE_TAG( 'n', 'a', 'm', 'e' )
+#define TTAG_OS2 FT_MAKE_TAG( 'O', 'S', '/', '2' )
+#define TTAG_OTTO FT_MAKE_TAG( 'O', 'T', 'T', 'O' )
+#define TTAG_PCLT FT_MAKE_TAG( 'P', 'C', 'L', 'T' )
+#define TTAG_post FT_MAKE_TAG( 'p', 'o', 's', 't' )
+#define TTAG_prep FT_MAKE_TAG( 'p', 'r', 'e', 'p' )
+#define TTAG_true FT_MAKE_TAG( 't', 'r', 'u', 'e' )
+#define TTAG_ttc FT_MAKE_TAG( 't', 't', 'c', ' ' )
+#define TTAG_ttcf FT_MAKE_TAG( 't', 't', 'c', 'f' )
+#define TTAG_VDMX FT_MAKE_TAG( 'V', 'D', 'M', 'X' )
+#define TTAG_vhea FT_MAKE_TAG( 'v', 'h', 'e', 'a' )
+#define TTAG_vmtx FT_MAKE_TAG( 'v', 'm', 't', 'x' )
+
+
+#endif /* TTAGS_H */
+
+
+/* END */
--- /dev/null
+++ b/src/type1/rules.mk
@@ -1,0 +1,167 @@
+#****************************************************************************
+#* *
+#* Type1 driver Makefile *
+#* *
+#* 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. *
+#* *
+#****************************************************************************
+
+
+#****************************************************************************
+#* *
+#* IMPORTANT NOTE: This Makefile is intended for GNU Make! *
+#* If you provide Makefiles for other make utilities, *
+#* please place them in `freetype/lib/arch/<system>'. *
+#* *
+#* *
+#* This file is to be included by the FreeType Makefile.lib, located in *
+#* the `freetype/lib' directory. Here is the list of the variables that *
+#* must be defined to use it: *
+#* *
+#* *
+#* BASE_DIR: The location of the base layer's directory. This is *
+#* usually `freetype/lib/base'. *
+#* *
+#* ARCH_DIR: The location of the architecture-dependent directory. *
+#* This is usually `freetype/lib/arch/<system>'. *
+#* *
+#* DRIVERS_DIR: The location of the font driver sub-dirs, usually *
+#* `freetype/lib/drivers'. *
+#* *
+#* OBJ_DIR: The location where the compiled object(s) file will be *
+#* placed. *
+#* *
+#* BASE_H: A list of pathnames to the base layer's header files on *
+#* which the driver depends. *
+#* *
+#* FT_CFLAGS: A set of flags used for compilation of object files. *
+#* This contains at least the include paths of the arch *
+#* and base directories + optimization + warnings + ANSI *
+#* compliance. *
+#* *
+#* FT_IFLAG: The flag used to specify an include path on the *
+#* compiler command line. For example, with GCC, this is *
+#* `-I', while some other compilers use `/i=' or `-J', *
+#* etc. *
+#* *
+#* FT_OBJ: The suffix of an object file for the platform; can be *
+#* `o', `obj', `coff', `tco', etc. depending on the *
+#* platform. *
+#* *
+#* *
+#* It also updates the following variables defined and used in the main *
+#* Makefile: *
+#* *
+#* DRV_OBJ_S: The list of driver object files in *
+#* single-object mode. *
+#* *
+#* DRV_OBJ_M: The list of driver object files in *
+#* multiple-objects mode. *
+#* *
+#* FTINIT_DRIVER_PATHS: The list of include paths used to compile the *
+#* `ftinit' component which registers all font *
+#* drivers in the FT_Init_FreeType() function. *
+#* *
+#* FTINIT_DRIVER_H: The list of header dependencies used to *
+#* compile the `ftinit' component. *
+#* *
+#* FTINIT_DRIVER_MACROS: The list of macros to be defined when *
+#* compiling the `ftinit' component. *
+#* *
+#* `Single-object compilation' means that each font driver is compiled *
+#* into a single object file. This is useful to get rid of all *
+#* driver-specific entries. *
+#* *
+#****************************************************************************
+
+
+# Type1 driver directory
+#
+T1_DIR := $(SRC_)type1
+T1_DIR_ := $(T1_DIR)$(SEP)
+
+
+# additional include flags used when compiling the driver
+#
+T1_INCLUDE := $(SHARED) $(T1_DIR)
+T1_COMPILE := $(FT_CC) $(T1_INCLUDE:%=$I%)
+
+
+# Type1 driver sources (i.e., C files)
+#
+T1_DRV_SRC := $(T1_DIR_)t1objs.c \
+ $(T1_DIR_)t1load.c \
+ $(T1_DIR_)t1parse.c \
+ $(T1_DIR_)t1tokens.c \
+ $(T1_DIR_)t1driver.c \
+ $(T1_DIR_)t1encode.c \
+ $(T1_DIR_)t1hinter.c \
+ $(T1_DIR_)t1gload.c
+
+
+# Type1 driver headers
+#
+T1_DRV_H := $(T1_DIR_)t1errors.h \
+ $(T1_DIR_)t1config.h \
+ $(T1SHARED_H) \
+ $(T1_DRV_SRC:%.c=%.h)
+
+
+# driver object(s)
+#
+# T1_DRV_OBJ_M is used during `debug' builds
+# T1_DRV_OBJ_S is used during `release' builds
+#
+T1_DRV_OBJ_M := $(T1_DRV_SRC:$(T1_DIR_)%.c=$(OBJ_)%.$O) \
+ $(T1SHARED:$(T1SHARED_DIR_)%.c=$(OBJ_)%.$O)
+T1_DRV_OBJ_S := $(OBJ_)type1.$O
+
+
+
+# driver root source file(s)
+#
+T1_DRV_SRC_M := $(T1_DRV_SRC) $(T1SHARED_SRC)
+T1_DRV_SRC_S := $(T1_DIR_)type1.c
+
+
+# driver - single object
+#
+# the driver is recompiled if any of the header or source files is changed
+#
+$(T1_DRV_OBJ_S): $(BASE_H) $(T1_DRV_H) $(T1_DRV_SRC) $(T1_DRV_SRC_S)
+ $(T1_COMPILE) $T$@ $(T1_DRV_SRC_S)
+
+
+
+# driver - multiple objects
+#
+# All objects are recompiled if any of the header files is changed
+#
+$(OBJ_)t1%.$O: $(T1_DIR_)t1%.c $(BASE_H) $(T1_DRV_H)
+ $(T1_COMPILE) $T$@ $<
+
+$(OBJ_)t1%.$O: $(T1SHARED_DIR_)t1%.c $(BASE_H) $(T1SHARED_H)
+ $(T1_COMPILE) $T$@ $<
+
+
+# update main driver object lists
+#
+DRV_OBJS_S += $(T1_DRV_OBJ_S)
+DRV_OBJS_M += $(T1_DRV_OBJ_M)
+
+
+# update 'ftinit' variables
+#
+FTINIT_DRIVER_PATHS += $(T1_DIR) $(T1SHARED_DIR)
+FTINIT_DRIVER_H += $(T1_DRV_H)
+FTINIT_DRIVER_MACROS += FT_SUPPORT_TYPE1
+
+
+# END
--- /dev/null
+++ b/src/type1/t1config.h
@@ -1,0 +1,45 @@
+/*******************************************************************
+ *
+ * t1config.h
+ *
+ * Type 1 driver configuration file
+ *
+ * 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.
+ *
+ ******************************************************************/
+
+#ifndef T1CONFIG_H
+#define T1CONFIG_H
+
+/* T1_MAX_STACK_DEPTH is the maximal depth of the token stack used */
+/* by the Type 1 parser (see t1load.c). A minimum of 16 is required */
+/* */
+#define T1_MAX_STACK_DEPTH 16
+
+/* T1_MAX_DICT_DEPTH is the maximal depth of nest dictionaries and */
+/* arrays in the Type 1 stream (see t1load.c). A minimum of 4 is */
+/* required */
+#define T1_MAX_DICT_DEPTH 5
+
+/* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */
+/* calls during glyph loading */
+#define T1_MAX_SUBRS_CALLS 8
+
+
+/* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity */
+#define T1_MAX_CHARSTRINGS_OPERANDS 32
+
+
+/* Define T1_CONFIG_OPTION_DISABLE_HINTER if you want to generate */
+/* a driver with no hinter. This can be useful to debug the parser */
+/* */
+#undef T1_CONFIG_OPTION_DISABLE_HINTER
+
+#endif /* T1CONFIG_H */
--- /dev/null
+++ b/src/type1/t1driver.c
@@ -1,0 +1,279 @@
+/*******************************************************************
+ *
+ * t1driver.c
+ *
+ * High-level Type1 driver interface for FreeType 2.0
+ *
+ * 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.
+ *
+ ******************************************************************/
+
+#include <t1driver.h>
+#include <t1gload.h>
+
+#include <ftdebug.h>
+#include <ftstream.h>
+
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_t1driver
+
+ /******************************************************************/
+ /* */
+ /* <Function> Set_Char_Sizes */
+ /* */
+ /* <Description> */
+ /* A driver method used to reset a size's character sizes */
+ /* (horizontal and vertical) expressed in fractional points. */
+ /* */
+ /* <Input> */
+ /* size :: handle to target size object */
+ /* char_width :: character width expressed in 26.6 points */
+ /* char_height :: character height expressed in 26.6 points */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success */
+ /* */
+ static
+ T1_Error Set_Char_Sizes( T1_Size size,
+ T1_F26Dot6 char_width,
+ T1_F26Dot6 char_height,
+ T1_UInt horz_resolution,
+ T1_UInt vert_resolution )
+ {
+ FT_Size_Metrics* metrics;
+ T1_Face face;
+
+ if (!size)
+ return T1_Err_Invalid_Size_Handle;
+
+ if ( char_width < 1*64 ) char_width = 1*64;
+ if ( char_height < 1*64 ) char_height = 1*64;
+
+ metrics = &size->root.metrics;
+ face = (T1_Face)size->root.face;
+
+ metrics->x_ppem = ( char_width * horz_resolution + 36 )/72;
+ metrics->y_ppem = ( char_height * vert_resolution + 36 )/72;
+
+ metrics->x_ppem = ( metrics->x_ppem + 32 ) & -64;
+ metrics->y_ppem = ( metrics->y_ppem + 32 ) & -64;
+
+ metrics->x_scale = FT_MulDiv( metrics->x_ppem, 0x10000,
+ face->root.units_per_EM );
+
+ metrics->y_scale = FT_MulDiv( metrics->y_ppem, 0x10000,
+ face->root.units_per_EM );
+
+ metrics->x_ppem >>= 6;
+ metrics->y_ppem >>= 6;
+
+ size->valid = FALSE;
+
+ return T1_Reset_Size( size );
+ }
+
+
+ /******************************************************************/
+ /* */
+ /* <Function> Set_Pixel_Sizes */
+ /* */
+ /* <Description> */
+ /* A driver method used to reset a size's character sizes */
+ /* (horizontal and vertical) expressed in integer pixels. */
+ /* */
+ /* <Input> */
+ /* size :: handle to target size object */
+ /* */
+ /* pixel_width :: character width expressed in 26.6 points */
+ /* */
+ /* pixel_height :: character height expressed in 26.6 points */
+ /* */
+ /* char_size :: the corresponding character size in points */
+ /* This value is only sent to the TrueType */
+ /* bytecode interpreter, even though 99% of */
+ /* glyph programs will simply ignore it. A */
+ /* safe value there is the maximum of the */
+ /* pixel width and height (multiplied by */
+ /* 64 to make it a 26.6 fixed float !) */
+ /* <Return> */
+ /* FreeType error code. 0 means success */
+ /* */
+ static
+ T1_Error Set_Pixel_Sizes( T1_Size size,
+ T1_Int pixel_width,
+ T1_Int pixel_height )
+ {
+ FT_Size_Metrics* metrics;
+ T1_Face face;
+
+ if (!size)
+ return T1_Err_Invalid_Size_Handle;
+
+ if ( pixel_width < 1 ) pixel_width = 1;
+ if ( pixel_height < 1 ) pixel_height = 1;
+
+ metrics = &size->root.metrics;
+ face = (T1_Face)size->root.face;
+
+ metrics->x_ppem = pixel_width;
+ metrics->y_ppem = pixel_height;
+
+ metrics->x_scale = FT_MulDiv( metrics->x_ppem * 64,
+ 0x10000, face->root.units_per_EM );
+
+ metrics->y_scale = FT_MulDiv( metrics->y_ppem * 64,
+ 0x10000, face->root.units_per_EM );
+
+ size->valid = 0;
+
+ return T1_Reset_Size(size);
+ }
+
+
+ /******************************************************************/
+ /* */
+ /* <Struct> FT_DriverInterface */
+ /* */
+ /* <Description> */
+ /* A structure used to hold a font driver's basic interface */
+ /* used by the high-level parts of FreeType (or other apps) */
+ /* */
+ /* Most scalable drivers provide a specialized interface to */
+ /* access format-specific features. It can be retrieved with */
+ /* a call to the "get_format_interface", and should be defined */
+ /* in each font driver header (e.g. ttdriver.h, t1driver.h,..) */
+ /* */
+ /* All fields are function pointers .. */
+ /* */
+ /* */
+ /* <Fields> */
+ /* */
+ /* new_engine :: */
+ /* used to create and initialise a new driver object */
+ /* */
+ /* done_engine :: */
+ /* used to finalise and destroy a given driver object */
+ /* */
+ /* get_format_interface :: */
+ /* return a typeless pointer to the format-specific */
+ /* driver interface. */
+ /* */
+ /* new_face :: */
+ /* create a new face object from a resource */
+ /* */
+ /* done_face :: */
+ /* discards a face object, as well as all child objects */
+ /* ( sizes, charmaps, glyph slots ) */
+ /* */
+ /* get_face_properties :: */
+ /* return generic face properties */
+ /* */
+ /* get_kerning :: */
+ /* return the kerning vector corresponding to a pair */
+ /* of glyphs, expressed in unscaled font units. */
+ /* */
+ /* new_size :: */
+ /* create and initialise a new scalable size object. */
+ /* */
+ /* new_fixed_size :: */
+ /* create and initialise a new fixed-size object. */
+ /* */
+ /* done_size :: */
+ /* finalize a given face size object. */
+ /* */
+ /* set_size_resolutions :: */
+ /* reset a scalable size object's output resolutions */
+ /* */
+ /* set_size_char_sizes :: */
+ /* reset a scalable size object's character size */
+ /* */
+ /* set_pixel_sizes :: */
+ /* reset a face size object's pixel dimensions. Applies */
+ /* to both scalable and fixed faces. */
+ /* */
+ /* new_glyph_slot :: */
+ /* create and initialise a new glyph slot */
+ /* */
+ /* done_glyph_slot :: */
+ /* discard a given glyph slot */
+ /* */
+ /* load_glyph :: */
+ /* load a given glyph into a given slot */
+ /* */
+ /* get_glyph_metrics :: */
+ /* return a loaded glyph's metrics. */
+ /* */
+
+ EXPORT_FUNC
+ const FT_DriverInterface t1_driver_interface =
+ {
+ sizeof( FT_DriverRec ),
+ sizeof( T1_FaceRec ),
+ sizeof( T1_SizeRec ),
+ sizeof( T1_GlyphSlotRec ),
+
+ "type1",
+ 1,
+ 2,
+
+ 0, /* format interface */
+
+ (FTDriver_initDriver) T1_Init_Driver,
+ (FTDriver_doneDriver) T1_Done_Driver,
+ (FTDriver_getInterface) 0,
+
+ (FTDriver_initFace) T1_Init_Face,
+ (FTDriver_doneFace) T1_Done_Face,
+ (FTDriver_getKerning) 0,
+
+ (FTDriver_initSize) T1_Init_Size,
+ (FTDriver_doneSize) T1_Done_Size,
+ (FTDriver_setCharSizes) Set_Char_Sizes,
+ (FTDriver_setPixelSizes) Set_Pixel_Sizes,
+
+ (FTDriver_initGlyphSlot) T1_Init_GlyphSlot,
+ (FTDriver_doneGlyphSlot) T1_Done_GlyphSlot,
+ (FTDriver_loadGlyph) T1_Load_Glyph,
+
+ (FTDriver_getCharIndex) 0,
+ };
+
+
+ /******************************************************************/
+ /* */
+ /* <Function> Get_FreeType_Driver_Interface */
+ /* */
+ /* <Description> */
+ /* This function is used when compiling the TrueType driver */
+ /* as a shared library (.DLL or .so). It will be used by the */
+ /* high-level library of FreeType to retrieve the address of */
+ /* the driver's generic interface. */
+ /* */
+ /* It shouldn't be implemented in a static build, as each */
+ /* driver must have the same function as an exported entry */
+ /* point. */
+ /* */
+ /* <Return> */
+ /* address of TrueType's driver generic interface. The */
+ /* forma-specific interface can then be retrieved through */
+ /* the method interface->get_format_interface.. */
+ /* */
+
+#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS
+
+ EXPORT_FUNC
+ FT_DriverInterface* getDriverInterface( void )
+ {
+ return &t1_driver_interface;
+ }
+
+#endif /* FT_CONFIG_OPTION_DYNAMIC_DRIVERS */
+
+
--- /dev/null
+++ b/src/type1/t1driver.h
@@ -1,0 +1,77 @@
+/*******************************************************************
+ *
+ * t1driver.h
+ *
+ * High-level Type1 driver interface for FreeType 2.0
+ *
+ * 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.
+ *
+ ******************************************************************/
+
+#ifndef T1DRIVER_H
+#define T1DRIVER_H
+
+#include <t1objs.h>
+#include <t1errors.h>
+
+ EXPORT_DEF
+ const FT_DriverInterface t1_driver_interface;
+
+
+/*************************************************************************
+ *
+ * Here is a template of the code that should appear in each
+ * font driver's _interface_ file (the one included by "ftinit.c").
+ *
+ * It is used to build, at compile time, a simple linked list of
+ * the interfaces of the drivers which have been #included in
+ * "ftinit.c". See the source code of the latter file for details
+ *
+ * (Note that this is only required when you want your driver included
+ * in the set of default drivers loaded by FT_Init_FreeType. Other
+ * drivers can still be added manually at runtime with FT_Add_Driver.
+ *
+ * {
+ * #ifdef FTINIT_DRIVER_CHAIN
+ *
+ * static
+ * const FT_DriverChain ftinit_<FORMAT>_driver_chain =
+ * {
+ * FT_INIT_LAST_DRIVER_CHAIN,
+ * &<FORMAT>_driver_interface
+ * };
+ *
+ * #undef FT_INIT_LAST_DRIVER_CHAIN
+ * #define FT_INIT_LAST_DRIVER_CHAIN &ftinit_<FORMAT>_driver_chain
+ *
+ * #endif
+ * }
+ *
+ * replace <FORMAT> with your driver's prefix
+ *
+ *************************************************************************/
+
+#ifdef FTINIT_DRIVER_CHAIN
+
+ static
+ const FT_DriverChain ftinit_t1_driver_chain =
+ {
+ FT_INIT_LAST_DRIVER_CHAIN,
+ &t1_driver_interface
+ };
+
+#undef FT_INIT_LAST_DRIVER_CHAIN
+#define FT_INIT_LAST_DRIVER_CHAIN &ftinit_t1_driver_chain
+
+#endif /* FTINIT_DRIVER_CHAIN */
+
+
+#endif /* T1DRIVER_H */
+
--- /dev/null
+++ b/src/type1/t1encode.c
@@ -1,0 +1,332 @@
+/***************************************************************************/
+/* */
+/* t1encode.c */
+/* */
+/* Type 1 standard encoding tables definitions (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. */
+/* */
+/* */
+/* This file is included by both the Type1 and Type2 driver. */
+/* It should never be compiled directly. */
+/* */
+/***************************************************************************/
+
+#include <ftobjs.h>
+#include <t1types.h>
+
+ /*************************************************************************/
+ /* */
+ /* t1_standard_strings: */
+ /* */
+ /* This array contains the Adobe Standard Glyph Names ordered by */
+ /* SID. It was taken from the CFF specification. */
+ /* */
+ LOCAL_FUNC
+ const T1_String* t1_standard_strings[] =
+ {
+ /* 0 */
+ ".notdef", "space", "exclam", "quotedbl", "numbersign",
+ "dollar", "percent", "ampersand", "quoteright", "parenleft",
+ /* 10 */
+ "parenright", "asterisk", "plus", "comma", "hyphen",
+ "period", "slash", "zero", "one", "two",
+ /* 20 */
+ "three", "four", "five", "six", "seven",
+ "height", "nine", "colon", "semicolon", "less",
+ /* 30 */
+ "equal", "greater", "question", "at", "A",
+ "B", "C", "D", "E", "F",
+ /* 40 */
+ "G", "H", "I", "J", "K",
+ "L", "M", "N", "O", "P",
+ /* 50 */
+ "Q", "R", "S", "T", "U",
+ "V", "W", "X", "Y", "Z",
+ /* 60 */
+ "bracketleft", "backslash", "bracketright", "asciicircum", "underscore",
+ "quoteleft", "a", "b", "c", "d",
+ /* 70 */
+ "e", "f", "g", "h", "i",
+ "j", "k", "l", "m", "n",
+ /* 80 */
+ "o", "p", "q", "r", "s",
+ "t", "u", "v", "w", "x",
+ /* 90 */
+ "y", "z", "braceleft", "bar", "braceright",
+ "asciitilde", "exclamdown", "cent", "sterling", "fraction",
+ /* 100 */
+ "yen", "florin", "section", "currency", "quotesingle",
+ "quotedblleft", "quillemotleft", "guilsinglleft", "guilsinglright", "fi",
+ /* 110 */
+ "fl", "endash", "dagger", "daggerdbl", "periodcenter",
+ "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright",
+ /* 120 */
+ "quillemotright", "ellipsis", "perthousand", "questiondown", "grave",
+ "acute", "circumflex", "tilde", "macron", "breve",
+ /* 130 */
+ "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut",
+ "ogonek", "caron", "emdash", "AE", "ordfeminine",
+ /* 140 */
+ "Lslash", "Oslash", "OE", "ordmasculine", "ae",
+ "dotlessi", "Islash", "oslash", "oe", "germandbls",
+ /* 150 */
+ "onesuperior", "logicalnot", "mu", "trademark", "Eth",
+ "onehalf", "plusminus", "Thorn", "onequarter", "divide",
+ /* 160 */
+ "brokenbar", "degree", "thorn", "threequarters", "twosuperior",
+ "regitered", "minus", "eth", "multiply", "threesuperior",
+ /* 170 */
+ "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave",
+ "Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex",
+ /* 180 */
+ "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis",
+ "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis",
+ /* 190 */
+ "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex",
+ "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron",
+ /* 200 */
+ "aacute", "acircumflex", "adieresis", "agrave", "aring",
+ "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis",
+ /* 210 */
+ "egrave", "iacute", "icircumflex", "idieresis", "igrave",
+ "ntilde", "oacute", "ocircumflex", "odieresis", "ograve",
+ /* 220 */
+ "otilde", "scaron", "uacute", "ucircumflex", "udieresis",
+ "ugrave", "yacute", "ydieresis", "zcaron", "exclamsmall",
+ /* 230 */
+ "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall",
+ "Acutesmall",
+ "parenleftsuperior", "parenrightsuperior", "twodotenleader",
+ "onedotenleader", "zerooldstyle",
+ /* 240 */
+ "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle",
+ "fiveoldstyle",
+ "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle",
+ "commasuperior",
+ /* 250 */
+ "threequartersemdash", "periodsuperior", "questionsmall", "asuperior",
+ "bsuperior",
+ "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior",
+ /* 260 */
+ "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior",
+ "tsuperior", "ff", "ffi", "ffl", "parenleftinferior",
+ /* 270 */
+ "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall",
+ "Asmall",
+ "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall",
+ /* 280 */
+ "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall",
+ "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall",
+ /* 290 */
+ "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall",
+ "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall",
+ /* 300 */
+ "colonmonetary", "onefitted", "rupiah", "Tildesmall", "exclamdownsmall",
+ "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall",
+ "Dieresissmall",
+ /* 310 */
+ "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash",
+ "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall",
+ "questiondownsmall",
+ /* 320 */
+ "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird",
+ "twothirds", "zerosuperior", "foursuperior", "fivesuperior",
+ "sixsuperior",
+ /* 330 */
+ "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior",
+ "oneinferior",
+ "twoinferior", "threeinferior", "fourinferior", "fiveinferior",
+ "sixinferior",
+ /* 340 */
+ "seveninferior", "eightinferior", "nineinferior", "centinferior",
+ "dollarinferior",
+ "periodinferior", "commainferior", "Agravesmall", "Aacutesmall",
+ "Acircumflexsmall",
+ /* 350 */
+ "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall",
+ "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall",
+ "Igravesmall",
+ /* 360 */
+ "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall",
+ "Ntildesmall",
+ "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall",
+ "Odieresissmall",
+ /* 370 */
+ "OEsmall", "Oslashsmall", "Ugravesmall", "Uacautesmall",
+ "Ucircumflexsmall",
+ "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall",
+ "001.000",
+ /* 380 */
+ "001.001", "001.002", "001.003", "Black", "Bold",
+ "Book", "Light", "Medium", "Regular", "Roman",
+ /* 390 */
+ "Semibold"
+ };
+
+
+ /*************************************************************************/
+ /* */
+ /* t1_standard_encoding: */
+ /* */
+ /* A simple table used to encode the Adobe StandardEncoding. The */
+ /* table values are the SID of the standard glyphs; the table index */
+ /* is the character code for the encoding. */
+ /* */
+ /* Example: */
+ /* */
+ /* t1_standard_encoding[33] == 2 */
+ /* */
+ /* which means that the glyph name for character code 32 is */
+ /* */
+ /* t1_standard_strings[2] == "exclam" */
+ /* */
+ /* (this correspond to the exclamation mark `!'). */
+ /* */
+ LOCAL_FUNC
+ T1_Short t1_standard_encoding[256] =
+ {
+ /* 0 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ /* 50 */
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
+ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ /* 100 */
+ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
+ 89, 90, 91, 92, 93, 94, 95, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 150 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 0, 111, 112, 113,
+ 114, 0, 115, 116, 117, 118, 119, 120, 121, 122,
+ 0, 123, 0, 124, 125, 126, 127, 128, 129, 130,
+ /* 200 */
+ 131, 0, 132, 133, 0, 134, 135, 136, 137, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 138, 0, 139, 0, 0,
+ 0, 0, 140, 141, 142, 143, 0, 0, 0, 0,
+ 0, 144, 0, 0, 0, 145, 0, 0, 146, 147,
+ /* 250 */
+ 148, 149, 0, 0, 0, 0
+ };
+
+
+ /*************************************************************************/
+ /* */
+ /* t1_expert_encoding: */
+ /* */
+ /* A simple table used to encode the Adobe ExpertEncoding. The */
+ /* table values are the SID of the standard glyphs; the table index */
+ /* is the character code for the encoding. */
+ /* */
+ /* Example: */
+ /* */
+ /* t1_expert_encoding[33] == 229 */
+ /* */
+ /* which means that the glyph name for character code 32 is */
+ /* */
+ /* t1_standard_strings[229] == "exclamsmall" */
+ /* */
+ LOCAL_FUNC
+ T1_Short t1_expert_encoding[256] =
+ {
+ /* 0 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 229, 230, 0, 231, 232, 233, 234,
+ 235, 236, 237, 238, 13, 14, 15, 99, 239, 240,
+ /* 50 */
+ 241, 242, 243, 244, 245, 246, 247, 248, 27, 28,
+ 249, 250, 251, 252, 0, 253, 254, 255, 256, 257,
+ 0, 0, 0, 258, 0, 0, 259, 260, 261, 262,
+ 0, 0, 263, 264, 265, 0, 266, 109, 110, 267,
+ 268, 269, 0, 270, 271, 272, 273, 274, 275, 276,
+ /* 100 */
+ 277, 278, 279, 280, 281, 282, 283, 284, 285, 286,
+ 287, 288, 289, 290, 291, 292, 293, 294, 295, 296,
+ 297, 298, 299, 300, 301, 302, 303, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 150 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 304, 305, 306, 0, 0, 307, 308, 309, 310,
+ 311, 0, 312, 0, 0, 312, 0, 0, 314, 315,
+ 0, 0, 316, 317, 318, 0, 0, 0, 158, 155,
+ 163, 319, 320, 321, 322, 323, 324, 325, 0, 0,
+ /* 200 */
+ 326, 150, 164, 169, 327, 328, 329, 330, 331, 332,
+ 333, 334, 335, 336, 337, 338, 339, 340, 341, 342,
+ 343, 344, 345, 346, 347, 348, 349, 350, 351, 352,
+ 353, 354, 355, 356, 357, 358, 359, 360, 361, 362,
+ 363, 364, 365, 366, 367, 368, 369, 370, 371, 372,
+ /* 250 */
+ 373, 374, 375, 376, 377, 378
+ };
+
+
+ /*************************************************************************/
+ /* */
+ /* t1_expert_subset_encoding: */
+ /* */
+ /* A simple table used to encode the Adobe ExpertEncoding subset */
+ /* defined in the CFF specification. It will probably evolve into */
+ /* another form sooner or later, as we deal with charsets */
+ /* differently than with encodings. */
+ /* */
+ LOCAL_FUNC
+ FT_Short t1_expert_subset_encoding[256] =
+ {
+ /* 0 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 231, 232, 0, 0,
+ 235, 236, 237, 238, 13, 14, 15, 99, 239, 240,
+ /* 50 */
+ 241, 242, 243, 244, 245, 246, 247, 248, 27, 28,
+ 249, 250, 251, 252, 0, 253, 254, 255, 256, 257,
+ 0, 0, 0, 258, 0, 0, 259, 260, 261, 262,
+ 0, 0, 263, 264, 265, 0, 266, 109, 110, 267,
+ 268, 269, 0, 270, 0, 272, 0, 0, 0, 0,
+ /* 100 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 300, 301, 302, 303, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 150 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 304, 305, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 314, 315,
+ 0, 0, 0, 0, 0, 0, 0, 0, 158, 155,
+ 163, 0, 320, 321, 322, 323, 324, 325, 0, 0,
+ /* 200 */
+ 326, 150, 164, 169, 327, 328, 329, 330, 331, 332,
+ 333, 334, 335, 336, 337, 338, 339, 340, 341, 342,
+ 343, 344, 345, 346, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 250 */
+ 0, 0, 0, 0, 0, 0
+ };
+
+
+/* END */
--- /dev/null
+++ b/src/type1/t1encode.h
@@ -1,0 +1,98 @@
+/***************************************************************************/
+/* */
+/* t1encode.h */
+/* */
+/* Type 1 standard encoding tables definitions (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 file is included by both the Type1 and Type2 driver. */
+/* It should never be compiled directly. */
+/* */
+/***************************************************************************/
+
+
+#ifndef T1ENCODE_H
+#define T1ENCODE_H
+
+#include <t1types.h>
+
+
+ /*************************************************************************/
+ /* */
+ /* t1_standard_strings: */
+ /* */
+ /* This array contains the Adobe Standard Glyph Names ordered by */
+ /* SID. It was taken from the CFF specification. */
+ /* */
+ LOCAL_DEF
+ const T1_String* t1_standard_strings[];
+
+
+ /*************************************************************************/
+ /* */
+ /* t1_standard_encoding: */
+ /* */
+ /* A simple table used to encode the Adobe StandardEncoding. The */
+ /* table values are the SID of the standard glyphs; the table index */
+ /* is the character code for the encoding. */
+ /* */
+ /* Example: */
+ /* */
+ /* t1_standard_encoding[33] == 2 */
+ /* */
+ /* which means that the glyph name for character code 32 is */
+ /* */
+ /* t1_standard_strings[2] == "exclam" */
+ /* */
+ /* (this correspond to the exclamation mark `!'). */
+ /* */
+ LOCAL_DEF
+ T1_Short t1_standard_encoding[256];
+
+
+ /*************************************************************************/
+ /* */
+ /* t1_expert_encoding: */
+ /* */
+ /* A simple table used to encode the Adobe ExpertEncoding. The */
+ /* table values are the SID of the standard glyphs; the table index */
+ /* is the character code for the encoding. */
+ /* */
+ /* Example: */
+ /* */
+ /* t1_expert_encoding[33] == 229 */
+ /* */
+ /* which means that the glyph name for character code 32 is */
+ /* */
+ /* t1_standard_strings[229] == "exclamsmall" */
+ /* */
+ LOCAL_DEF
+ T1_Short t1_expert_encoding[256];
+
+
+ /*************************************************************************/
+ /* */
+ /* t1_expert_subset_encoding: */
+ /* */
+ /* A simple table used to encode the Adobe ExpertEncoding subset */
+ /* defined in the CFF specification. It will probably evolve into */
+ /* another form sooner or later, as we deal with charsets */
+ /* differently than with encodings. */
+ /* */
+ LOCAL_DEF
+ T1_Short t1_expert_subset_encoding[256];
+
+
+#endif /* T1ENCODE_H */
+
+
+/* END */
--- /dev/null
+++ b/src/type1/t1errors.h
@@ -1,0 +1,77 @@
+/*******************************************************************
+ *
+ * t1errors.h
+ *
+ * Type1 Error ID definitions
+ *
+ * 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.
+ *
+ ******************************************************************/
+
+#ifndef FREETYPE_H
+#error "Don't include this file! Use t1driver.h instead."
+#endif
+
+#ifndef T1ERRORS_H
+#define T1ERRORS_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 T1_Err_Ok FT_Err_Ok
+
+/* ----------- high level API errors -------- */
+
+#define T1_Err_Invalid_File_Format FT_Err_Invalid_File_Format
+#define T1_Err_Invalid_Argument FT_Err_Invalid_Argument
+#define T1_Err_Invalid_Driver_Handle FT_Err_Invalid_Driver_Handle
+#define T1_Err_Invalid_Face_Handle FT_Err_Invalid_Face_Handle
+#define T1_Err_Invalid_Size_Handle FT_Err_Invalid_Size_Handle
+#define T1_Err_Invalid_Glyph_Handle FT_Err_Invalid_Slot_Handle
+#define T1_Err_Invalid_CharMap_Handle FT_Err_Invalid_CharMap_Handle
+#define T1_Err_Invalid_Glyph_Index FT_Err_Invalid_Glyph_Index
+
+#define T1_Err_Unimplemented_Feature FT_Err_Unimplemented_Feature
+#define T1_Err_Unavailable_Outline FT_Err_Unavailable_Outline
+#define T1_Err_Unavailable_Bitmap FT_Err_Unavailable_Bitmap
+#define T1_Err_Unavailable_Pixmap FT_Err_Unavailable_Pixmap
+#define T1_Err_File_Is_Not_Collection FT_Err_File_Is_Not_Collection
+
+#define T1_Err_Invalid_Engine FT_Err_Invalid_Driver_Handle
+
+/* ------------- internal errors ------------ */
+
+#define T1_Err_Out_Of_Memory FT_Err_Out_Of_Memory
+#define T1_Err_Unlisted_Object FT_Err_Unlisted_Object
+
+/* ------------ general glyph outline errors ------ */
+
+#define T1_Err_Too_Many_Points FT_Err_Too_Many_Points
+#define T1_Err_Too_Many_Contours FT_Err_Too_Many_Contours
+#define T1_Err_Too_Many_Hints FT_Err_Too_Many_Hints
+#define T1_Err_Invalid_Composite FT_Err_Invalid_Composite
+#define T1_Err_Too_Many_Edges FT_Err_Too_Many_Edges
+#define T1_Err_Too_Many_Strokes FT_Err_Too_Many_Strokes
+
+
+#define T1_Err_Syntax_Error FT_Err_Invalid_File_Format
+#define T1_Err_Stack_Underflow FT_Err_Invalid_File_Format
+#define T1_Err_Stack_Overflow FT_Err_Invalid_File_Format
+
+#endif /* TDERRORS_H */
+
+
+/* END */
--- /dev/null
+++ b/src/type1/t1gload.c
@@ -1,0 +1,1579 @@
+/*******************************************************************
+ *
+ * t1gload.c 1.0
+ *
+ * Type1 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 <t1gload.h>
+#include <ftdebug.h>
+#include <t1encode.h>
+#include <ftstream.h>
+
+#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
+#include <t1hinter.h>
+#endif
+
+ /**********************************************************************/
+ /**********************************************************************/
+ /**********************************************************************/
+ /********** *********/
+ /********** *********/
+ /********** GENERIC CHARSTRINGS PARSING *********/
+ /********** *********/
+ /********** *********/
+ /**********************************************************************/
+ /**********************************************************************/
+ /**********************************************************************/
+
+/*********************************************************************
+ *
+ * <Function>
+ * T1_Init_Builder
+ *
+ * <Description>
+ * Initialise a given glyph builder.
+ *
+ * <Input>
+ * builder :: glyph builder to initialise
+ * face :: current face object
+ * size :: current size object
+ * glyph :: current glyph object
+ * funcs :: glyph builder functions (or "methods").
+ *
+ *********************************************************************/
+
+ EXPORT_FUNC
+ void T1_Init_Builder( T1_Builder* builder,
+ T1_Face face,
+ T1_Size size,
+ T1_GlyphSlot glyph,
+ const T1_Builder_Funcs* funcs )
+ {
+ builder->funcs = *funcs;
+ builder->path_begun = 0;
+ builder->load_points = 1;
+
+ builder->face = face;
+ builder->size = size;
+ builder->glyph = glyph;
+ builder->memory = face->root.memory;
+
+ if (glyph)
+ {
+ builder->base = glyph->root.outline;
+ builder->max_points = glyph->max_points;
+ builder->max_contours = glyph->max_contours;
+ }
+
+ if (size)
+ {
+ builder->scale_x = size->root.metrics.x_scale;
+ builder->scale_y = size->root.metrics.y_scale;
+ }
+
+ builder->pos_x = 0;
+ builder->pos_y = 0;
+
+ builder->left_bearing.x = 0;
+ builder->left_bearing.y = 0;
+ builder->advance.x = 0;
+ builder->advance.y = 0;
+
+ builder->base.n_points = 0;
+ builder->base.n_contours = 0;
+ builder->current = builder->base;
+
+ builder->pass = 0;
+ builder->hint_point = 0;
+ }
+
+
+/*********************************************************************
+ *
+ * <Function>
+ * T1_Done_Builder
+ *
+ * <Description>
+ * Finalise a given glyph builder. Its content can still be
+ * used after the call, but the function saves important information
+ * within the corresponding glyph slot.
+ *
+ * <Input>
+ * builder :: glyph builder to initialise
+ *
+ *********************************************************************/
+
+ EXPORT_FUNC
+ void T1_Done_Builder( T1_Builder* builder )
+ {
+ T1_GlyphSlot glyph = builder->glyph;
+
+ if (glyph)
+ {
+ glyph->root.outline = builder->base;
+ glyph->max_points = builder->max_points;
+ glyph->max_contours = builder->max_contours;
+ }
+ }
+
+
+
+/*********************************************************************
+ *
+ * <Function>
+ * T1_Init_Decoder
+ *
+ * <Description>
+ * Initialise a given Type 1 decoder for parsing
+ *
+ * <Input>
+ * decoder :: Type 1 decoder to initialise
+ * funcs :: hinter functions interface
+ *
+ *********************************************************************/
+
+ EXPORT_FUNC
+ void T1_Init_Decoder( T1_Decoder* decoder,
+ const T1_Hinter_Funcs* funcs )
+ {
+ decoder->hinter = *funcs; /* copy hinter interface */
+ decoder->top = 0;
+ decoder->zone = 0;
+
+ decoder->flex_state = 0;
+ decoder->num_flex_vectors = 0;
+
+ /* Clear loader */
+ MEM_Set( &decoder->builder, 0, sizeof(decoder->builder) );
+ }
+
+
+/*********************************************************************
+ *
+ * <Function>
+ * lookup_glyph_by_stdcharcode
+ *
+ * <Description>
+ * Lookup a given glyph by its StandardEncoding charcode. Used
+ * to implement the SEAC Type 1 operator.
+ *
+ * <Input>
+ * face :: current face object
+ * charcode :: charcode to look for
+ *
+ * <Return>
+ * glyph index in font face. Returns -1 if the corresponding
+ * glyph wasn't found.
+ *
+ *********************************************************************/
+
+ static
+ T1_Int lookup_glyph_by_stdcharcode( T1_Face face,
+ T1_Int charcode )
+ {
+ T1_Int n;
+ const T1_String* glyph_name;
+
+ /* check range of standard char code */
+ if (charcode < 0 || charcode > 255)
+ return -1;
+
+ glyph_name = t1_standard_strings[t1_standard_encoding[charcode]];
+
+ for ( n = 0; n < face->num_glyphs; n++ )
+ {
+ T1_String* name = (T1_String*)face->glyph_names[n];
+
+ if ( name && strcmp(name,glyph_name) == 0 )
+ return n;
+ }
+
+ return -1;
+ }
+
+
+/*********************************************************************
+ *
+ * <Function>
+ * t1operator_seac
+ *
+ * <Description>
+ * Implements the "seac" Type 1 operator for a Type 1 decoder
+ *
+ * <Input>
+ * decoder :: current Type 1 decoder
+ * asb :: accent's side bearing
+ * adx :: horizontal position of accent
+ * ady :: vertical position of accent
+ * bchar :: base character's StandardEncoding charcode
+ * achar :: accent character's StandardEncoding charcode
+ *
+ * <Return>
+ * Error code. 0 means success.
+ *
+ *********************************************************************/
+
+ static
+ T1_Error t1operator_seac( T1_Decoder* decoder,
+ T1_Pos asb,
+ T1_Pos adx,
+ T1_Pos ady,
+ T1_Int bchar,
+ T1_Int achar )
+ {
+ T1_Error error;
+ T1_Face face = decoder->builder.face;
+ T1_Int bchar_index, achar_index, n_base_points;
+ FT_Outline* cur = &decoder->builder.current;
+ FT_Outline* base = &decoder->builder.base;
+ T1_Vector left_bearing, advance;
+
+ bchar_index = lookup_glyph_by_stdcharcode( face, bchar );
+ achar_index = lookup_glyph_by_stdcharcode( face, achar );
+
+ if (bchar_index < 0 || achar_index < 0)
+ {
+ FT_ERROR(( "T1.Parse_Seac : invalid seac character code arguments\n" ));
+ return T1_Err_Syntax_Error;
+ }
+
+ /* First load "bchar" in builder */
+ /* now load the unscaled outline */
+ cur->n_points = 0;
+ cur->n_contours = 0;
+ cur->points = base->points + base->n_points;
+ cur->flags = base->flags + base->n_points;
+ cur->contours = base->contours + base->n_contours;
+
+ error = T1_Parse_CharStrings( decoder,
+ face->charstrings [bchar_index],
+ face->charstrings_len[bchar_index],
+ face->num_subrs,
+ face->subrs,
+ face->subrs_len );
+ if (error) return error;
+
+ n_base_points = cur->n_points;
+
+ /* save the left bearing and width of the base character */
+ /* as they will be erase by the next load.. */
+ left_bearing = decoder->builder.left_bearing;
+ advance = decoder->builder.advance;
+
+ decoder->builder.left_bearing.x = 0;
+ decoder->builder.left_bearing.y = 0;
+
+ /* Now load "achar" on top of */
+ /* the base outline */
+ /* */
+ cur->n_points = 0;
+ cur->n_contours = 0;
+ cur->points = base->points + base->n_points;
+ cur->flags = base->flags + base->n_points;
+ cur->contours = base->contours + base->n_contours;
+
+ error = T1_Parse_CharStrings( decoder,
+ face->charstrings [achar_index],
+ face->charstrings_len[achar_index],
+ face->num_subrs,
+ face->subrs,
+ face->subrs_len );
+ if (error) return error;
+
+ /* adjust contours in accented character outline */
+ {
+ T1_Int n;
+
+ for ( n = 0; n < cur->n_contours; n++ )
+ cur->contours[n] += n_base_points;
+ }
+
+ /* restore the left side bearing and */
+ /* advance width of the base character */
+ decoder->builder.left_bearing = left_bearing;
+ decoder->builder.advance = advance;
+
+ /* Finally, move the accent */
+ FT_Translate_Outline( cur, adx - asb, ady );
+
+ (void)asb; /* ignore this parameter */
+ return T1_Err_Ok;
+ }
+
+/*********************************************************************
+ *
+ * <Function>
+ * t1operator_flex
+ *
+ * <Description>
+ * Implements the "flex" Type 1 operator for a Type 1 decoder
+ *
+ * <Input>
+ * decoder :: current Type 1 decoder
+ * threshold :: threshold
+ * end_x :: position of final flex point
+ * end_y :: position of final flex point
+ *
+ * <Return>
+ * Error code. 0 means success.
+ *
+ *********************************************************************/
+
+ static
+ T1_Error t1operator_flex( T1_Decoder* decoder,
+ T1_Pos threshold,
+ T1_Pos end_x,
+ T1_Pos end_y )
+ {
+ T1_Vector vec;
+ T1_Vector* flex = decoder->flex_vectors;
+ T1_Int n;
+
+ /* we don't even try to test the threshold in the non-hinting */
+ /* builder, even if the flex operator is said to be a path */
+ /* construction statement in the specification. This is better */
+ /* left to the hinter.. */
+
+ flex = decoder->flex_vectors;
+ vec = *flex++;
+
+ for ( n = 0; n < 6; n++ )
+ {
+ flex->x += vec.x;
+ flex->y += vec.y;
+
+ vec = *flex++;
+ }
+
+
+ (void)threshold;
+ (void)end_x;
+ (void)end_y;
+
+ flex = decoder->flex_vectors;
+
+ return decoder->builder.funcs.rcurve_to( &decoder->builder,
+ flex[0].x, flex[0].y,
+ flex[1].x, flex[1].y,
+ flex[2].x, flex[2].y ) ||
+
+ decoder->builder.funcs.rcurve_to( &decoder->builder,
+ flex[3].x, flex[3].y,
+ flex[4].x, flex[4].y,
+ flex[5].x, flex[5].y );
+ }
+
+
+/*********************************************************************
+ *
+ * <Function>
+ * T1_Parse_CharStrings
+ *
+ * <Description>
+ * Parses a given Type 1 charstrings program
+ *
+ * <Input>
+ * decoder :: current Type 1 decoder
+ * charstring_base :: base of the charstring stream
+ * charstring_len :: length in bytes of the charstring stream
+ * num_subrs :: number of sub-routines
+ * subrs_base :: array of sub-routines addresses
+ * subrs_len :: array of sub-routines lengths
+ *
+ * <Return>
+ * Error code. 0 means success.
+ *
+ *********************************************************************/
+
+ EXPORT_FUNC
+ T1_Error T1_Parse_CharStrings( T1_Decoder* decoder,
+ T1_Byte* charstring_base,
+ T1_Int charstring_len,
+ T1_Int num_subrs,
+ T1_Byte** subrs_base,
+ T1_Int* subrs_len )
+ {
+ T1_Error error;
+ T1_Decoder_Zone* zone;
+ T1_Byte* ip;
+ T1_Byte* limit;
+ T1_Builder* builder = &decoder->builder;
+ T1_Builder_Funcs* builds = &builder->funcs;
+ T1_Hinter_Funcs* hints = &decoder->hinter;
+
+ static const T1_Int args_count[ op_max ] =
+ {
+ 0, /* none */
+ 0, /* endchar */
+ 2, /* hsbw */
+ 5, /* seac */
+ 4, /* sbw */
+ 0, /* closepath */
+ 1, /* hlineto */
+ 1, /* hmoveto */
+ 4, /* hvcurveto */
+ 2, /* rlineto */
+ 2, /* rmoveto */
+ 6, /* rrcurveto */
+ 4, /* vhcurveto */
+ 1, /* vlineto */
+ 1, /* vmoveto */
+ 0, /* dotsection */
+ 2, /* hstem */
+ 6, /* hstem3 */
+ 2, /* vstem */
+ 6, /* vstem3 */
+ 2, /* div */
+ -1, /* callothersubr */
+ 1, /* callsubr */
+ 0, /* pop */
+ 0, /* return */
+ 2 /* setcurrentpoint */
+ };
+
+ /* First of all, initialise the decoder */
+ decoder->top = decoder->stack;
+ decoder->zone = decoder->zones;
+ zone = decoder->zones;
+
+ builder->path_begun = 0;
+
+ zone->base = charstring_base;
+ limit = zone->limit = charstring_base + charstring_len;
+ ip = zone->cursor = zone->base;
+
+ error = T1_Err_Ok;
+
+ /* now, execute loop */
+ while ( ip < limit )
+ {
+ T1_Int* top = decoder->top;
+ T1_Operator op = op_none;
+ T1_Long value = 0;
+
+ /* First of all, decompress operator or value */
+ switch (*ip++)
+ {
+ case 1: op = op_hstem; break;
+
+ case 3: op = op_vstem; break;
+ case 4: op = op_vmoveto; break;
+ case 5: op = op_rlineto; break;
+ case 6: op = op_hlineto; break;
+ case 7: op = op_vlineto; break;
+ case 8: op = op_rrcurveto; break;
+ case 9: op = op_closepath; break;
+ case 10: op = op_callsubr; break;
+ case 11: op = op_return; break;
+
+ case 13: op = op_hsbw; break;
+ case 14: op = op_endchar; break;
+
+ case 21: op = op_rmoveto; break;
+ case 22: op = op_hmoveto; break;
+
+ case 30: op = op_vhcurveto; break;
+ case 31: op = op_hvcurveto; break;
+
+ case 12:
+ {
+ if (ip > limit)
+ {
+ FT_ERROR(( "T1.Parse_CharStrings : invalid escape (12+EOF)\n" ));
+ goto Syntax_Error;
+ }
+
+ switch (*ip++)
+ {
+ case 0: op = op_dotsection; break;
+ case 1: op = op_vstem3; break;
+ case 2: op = op_hstem3; break;
+ case 6: op = op_seac; break;
+ case 7: op = op_sbw; break;
+ case 12: op = op_div; break;
+ case 16: op = op_callothersubr; break;
+ case 17: op = op_pop; break;
+ case 33: op = op_setcurrentpoint; break;
+
+ default:
+ FT_ERROR(( "T1.Parse_CharStrings : invalid escape (12+%d)\n",
+ ip[-1] ));
+ goto Syntax_Error;
+ }
+ }
+ break;
+
+ case 255: /* four bytes integer */
+ {
+ if (ip+4 > limit)
+ {
+ FT_ERROR(( "T1.Parse_CharStrings : unexpected EOF in integer\n" ));
+ goto Syntax_Error;
+ }
+
+ value = ((long)ip[0] << 24) |
+ ((long)ip[1] << 16) |
+ ((long)ip[2] << 8) |
+ ip[3];
+ ip += 4;
+ }
+ break;
+
+ default:
+ if (ip[-1] >= 32)
+ {
+ if (ip[-1] < 247)
+ value = (long)ip[-1] - 139;
+ else
+ {
+ if (++ip > limit)
+ {
+ FT_ERROR(( "T1.Parse_CharStrings : unexpected EOF in integer\n" ));
+ goto Syntax_Error;
+ }
+
+ if (ip[-2] < 251)
+ value = ((long)(ip[-2]-247) << 8) + ip[-1] + 108;
+ else
+ value = -((((long)ip[-2]-251) << 8) + ip[-1] + 108 );
+ }
+ }
+ else
+ {
+ FT_ERROR(( "T1.Parse_CharStrings : invalid byte (%d)\n",
+ ip[-1] ));
+ goto Syntax_Error;
+ }
+ }
+
+ /* push value if needed */
+ if ( op == op_none )
+ {
+ if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS )
+ {
+ FT_ERROR(( "T1.Parse_CharStrings : Stack overflow !!\n" ));
+ goto Syntax_Error;
+ }
+
+ *top++ = value;
+ decoder->top = top;
+ }
+
+ else if ( op == op_callothersubr ) /* check arguments differently */
+ {
+ if ( top - decoder->stack < 2)
+ goto Stack_Underflow;
+
+ top -= 2;
+
+ switch (top[1])
+ {
+ case 1: /* start flex feature ----------------------------- */
+ {
+ if (top[0] != 0) goto Unexpected_OtherSubr;
+
+ decoder->flex_state = 1;
+ decoder->num_flex_vectors = 0;
+ decoder->flex_vectors[0].x = 0;
+ decoder->flex_vectors[0].y = 0;
+ }
+ break;
+
+
+ case 2: /* add flex vector ------------------------------- */
+ {
+ T1_Int index;
+ T1_Vector* flex;
+
+ if (top[0] != 0) goto Unexpected_OtherSubr;
+
+ top -= 2;
+ if (top < decoder->stack) goto Stack_Underflow;
+
+ index = decoder->num_flex_vectors++;
+ if (index >= 7)
+ {
+ FT_ERROR(( "T1.Parse_CharStrings: too many flex vectors !\n" ));
+ goto Syntax_Error;
+ }
+
+ flex = decoder->flex_vectors + index;
+ flex->x += top[0];
+ flex->y += top[1];
+
+ }
+ break;
+
+
+ case 0: /* end flex feature ------------------------------ */
+ {
+ if ( decoder->flex_state == 0 ||
+ decoder->num_flex_vectors != 7 )
+ {
+ FT_ERROR(( "T1.Parse_CharStrings: unexpected flex end\n" ));
+ goto Syntax_Error;
+ }
+
+ if (top[0] != 3) goto Unexpected_OtherSubr;
+
+ top -= 3;
+ if (top < decoder->stack) goto Stack_Underflow;
+
+ /* now consume the remaining "pop pop setcurrentpoint" */
+ if ( ip+6 > limit ||
+ ip[0] != 12 || ip[1] != 17 || /* pop */
+ ip[2] != 12 || ip[3] != 17 || /* pop */
+ ip[4] != 12 || ip[5] != 33 ) /* setcurrentpoint */
+ {
+ FT_ERROR(( "T1.Parse_CharStrings: invalid flex charstring\n" ));
+ goto Syntax_Error;
+ }
+
+ decoder->flex_state = 0;
+ decoder->top = top;
+
+ error = t1operator_flex( decoder, top[0], top[1], top[2] );
+ }
+ break;
+
+
+ case 3: /* change hints ------------------------------------ */
+ {
+ if (top[0] != 1) goto Unexpected_OtherSubr;
+
+ /* eat the following "pop" */
+ if (ip+2 > limit)
+ {
+ FT_ERROR(( "T1.Parse_CharStrings: invalid escape (12+%d)\n",
+ ip[-1] ));
+ goto Syntax_Error;
+ }
+
+ if (ip[0] != 12 || ip[1] != 17)
+ {
+ FT_ERROR(( "T1.Parse_CharStrings: 'pop' expected, found (%d %d)\n",
+ ip[0], ip[1] ));
+ goto Syntax_Error;
+ }
+
+ ip += 2;
+ error = hints->change_hints(builder);
+ }
+ break;
+
+
+ default:
+ /* invalid OtherSubrs call */
+ Unexpected_OtherSubr:
+ FT_ERROR(( "T1.Parse_CharStrings: unexpected OtherSubrs [%d %d]\n",
+ top[0], top[1] ));
+ goto Syntax_Error;
+ }
+ decoder->top = top;
+ }
+ else
+ {
+ T1_Int num_args = args_count[op];
+
+ if ( top - decoder->stack < num_args )
+ goto Stack_Underflow;
+
+ top -= num_args;
+
+ switch (op)
+ {
+ case op_endchar:
+ error = builds->end_char( builder );
+ break;
+
+ case op_hsbw:
+ error = builds->set_bearing_point( builder, top[0], 0,
+ top[1], 0 );
+ break;
+
+ case op_seac:
+ /* return immediately after the processing */
+ return t1operator_seac( decoder, top[0], top[1],
+ top[2], top[3], top[4] );
+
+ case op_sbw:
+ error = builds->set_bearing_point( builder, top[0], top[1],
+ top[2], top[3] );
+ break;
+
+ case op_closepath:
+ error = builds->close_path( builder );
+ break;
+
+ case op_hlineto:
+ error = builds->rline_to( builder, top[0], 0 );
+ break;
+
+ case op_hmoveto:
+ error = builds->rmove_to( builder, top[0], 0 );
+ break;
+
+ case op_hvcurveto:
+ error = builds->rcurve_to( builder, top[0], 0,
+ top[1], top[2],
+ 0, top[3] );
+ break;
+
+ case op_rlineto:
+ error = builds->rline_to( builder, top[0], top[1] );
+ break;
+
+ case op_rmoveto:
+ /* ignore operator when in flex mode */
+ if (decoder->flex_state == 0)
+ error = builds->rmove_to( builder, top[0], top[1] );
+ else
+ top += 2;
+ break;
+
+ case op_rrcurveto:
+ {
+ error = builds->rcurve_to( builder, top[0], top[1],
+ top[2], top[3],
+ top[4], top[5] );
+ }
+ break;
+
+ case op_vhcurveto:
+ error = builds->rcurve_to( builder, 0, top[0],
+ top[1], top[2],
+ top[3], 0 );
+ break;
+
+ case op_vlineto:
+ error = builds->rline_to( builder, 0, top[0] );
+ break;
+
+ case op_vmoveto:
+ error = builds->rmove_to( builder, 0, top[0] );
+ break;
+
+ case op_dotsection:
+ error = hints->dot_section( builder );
+ break;
+
+ case op_hstem:
+ error = hints->stem( builder, top[0], top[1], 0 );
+ break;
+
+ case op_hstem3:
+ error = hints->stem3( builder, top[0], top[1], top[2],
+ top[3], top[4], top[5], 0 );
+ break;
+
+ case op_vstem:
+ error = hints->stem( builder, top[0], top[1], 1 );
+ break;
+
+ case op_vstem3:
+ error = hints->stem3( builder, top[0], top[1], top[2],
+ top[3], top[4], top[5], 1 );
+ break;
+
+ case op_div:
+ if (top[1])
+ *top++ = top[0] / top[1];
+ else
+ {
+ FT_ERROR(( "T1.Parse_CHarStrings : division by 0\n" ));
+ goto Syntax_Error;
+ }
+ break;
+
+ case op_callsubr:
+ {
+ T1_Int index = top[0];
+
+ if ( index < 0 || index >= num_subrs )
+ {
+ FT_ERROR(( "T1.Parse_CharStrings : invalid subrs index\n" ));
+ goto Syntax_Error;
+ }
+
+ if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS )
+ {
+ FT_ERROR(( "T1.Parse_CharStrings : too many nested subrs\n" ));
+ goto Syntax_Error;
+ }
+
+ zone->cursor = ip; /* save current instruction pointer */
+
+ zone++;
+ zone->base = subrs_base[index];
+ zone->limit = zone->base + subrs_len[index];
+ zone->cursor = zone->base;
+
+ if (!zone->base)
+ {
+ FT_ERROR(( "T1.Parse_CharStrings : invoking empty subrs !!\n" ));
+ goto Syntax_Error;
+ }
+
+ decoder->zone = zone;
+ ip = zone->base;
+ limit = zone->limit;
+ }
+ break;
+
+ case op_pop:
+ FT_ERROR(( "T1.Parse_CharStrings : unexpected POP\n" ));
+ goto Syntax_Error;
+
+
+ case op_return:
+ if ( zone <= decoder->zones )
+ {
+ FT_ERROR(( "T1.Parse_CharStrings : unexpected return\n" ));
+ goto Syntax_Error;
+ }
+
+ zone--;
+ ip = zone->cursor;
+ limit = zone->limit;
+ decoder->zone = zone;
+ break;
+
+ case op_setcurrentpoint:
+ FT_ERROR(( "T1.Parse_CharStrings : unexpected SETCURRENTPOINT\n" ));
+ goto Syntax_Error;
+ break;
+
+ default:
+ FT_ERROR(( "T1.Parse_CharStrings : unhandled opcode %d\n", op ));
+ goto Syntax_Error;
+ }
+
+ decoder->top = top;
+ }
+ }
+
+ return error;
+
+ Syntax_Error:
+ return T1_Err_Syntax_Error;
+
+ Stack_Underflow:
+ return T1_Err_Stack_Underflow;
+ }
+
+
+
+/*************************************************************************/
+/* */
+/* <Function> T1_Add_Points */
+/* */
+/* <Description> */
+/* Checks that there is enough room in the current load glyph outline */
+/* to accept "num_points" additional outline points. If not, this */
+/* function grows the load outline's arrays accordingly.. */
+/* */
+/* <Input> */
+/* builder :: pointer to glyph builder object */
+/* num_points :: number of points that will be added later */
+/* */
+/* <Return> */
+/* Type1 error code. 0 means success */
+/* */
+/* <Note> */
+/* This function does NOT update the points count in the glyph builder*/
+/* This must be done by the caller itself, after this function is */
+/* invoked.. */
+/* */
+ LOCAL_FUNC
+ T1_Error T1_Add_Points( T1_Builder* builder,
+ T1_Int num_points )
+ {
+ T1_Int new_points;
+
+ new_points = builder->base.n_points +
+ builder->current.n_points +
+ num_points;
+
+ if ( new_points > builder->max_points )
+ {
+ FT_Memory memory = builder->memory;
+ T1_Error error;
+ T1_Int increment = builder->current.points - builder->base.points;
+ T1_Int current = builder->max_points;
+
+ while ( builder->max_points < new_points )
+ builder->max_points += 16;
+
+ if ( REALLOC_ARRAY( builder->base.points,
+ current, builder->max_points, T1_Vector ) ||
+
+ REALLOC_ARRAY( builder->base.flags,
+ current, builder->max_points, T1_Byte ) )
+ return error;
+
+ builder->current.points = builder->base.points + increment;
+ builder->current.flags = builder->base.flags + increment;
+ }
+
+ return T1_Err_Ok;
+ }
+
+/*************************************************************************/
+/* */
+/* <Function> T1_Add_Contours */
+/* */
+/* <Description> */
+/* Checks that there is enough room in the current load glyph outline */
+/* to accept "num_contours" additional contours. If not, this func */
+/* the load outline's arrays accordingly.. */
+/* */
+/* <Input> */
+/* builder :: pointer to glyph builder object */
+/* num_contours :: number of contours that will be added later */
+/* */
+/* <Return> */
+/* Type1 error code. 0 means success */
+/* */
+/* <Note> */
+/* This function does NOT update the contours count in the load glyph */
+/* This must be done by the caller itself, after this function is */
+/* invoked.. */
+/* */
+ LOCAL_FUNC
+ T1_Error T1_Add_Contours( T1_Builder* builder,
+ T1_Int num_contours )
+ {
+ T1_Int new_contours;
+
+ new_contours = builder->base.n_contours +
+ builder->current.n_contours +
+ num_contours;
+
+ if ( new_contours > builder->max_contours && builder->load_points )
+ {
+ T1_Error error;
+ FT_Memory memory = builder->memory;
+ T1_Int increment = builder->current.contours - builder->base.contours;
+ T1_Int current = builder->max_contours;
+
+ while ( builder->max_contours < new_contours )
+ builder->max_contours += 4;
+
+ if ( REALLOC_ARRAY( builder->base.contours,
+ current, builder->max_contours, T1_Short ) )
+ return error;
+
+ builder->current.contours = builder->base.contours + increment;
+ }
+
+ return T1_Err_Ok;
+ }
+
+
+ /**********************************************************************/
+ /**********************************************************************/
+ /**********************************************************************/
+ /********** *********/
+ /********** *********/
+ /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/
+ /********** *********/
+ /********** The following code is in charge of computing *********/
+ /********** the maximum advance width of the font. It *********/
+ /********** quickly process each glyph charstring to *********/
+ /********** extract the value from either a "sbw" or "seac" *********/
+ /********** operator. *********/
+ /********** *********/
+ /**********************************************************************/
+ /**********************************************************************/
+ /**********************************************************************/
+
+
+
+ static
+ T1_Error maxadv_sbw( T1_Decoder* decoder,
+ T1_Pos sbx,
+ T1_Pos sby,
+ T1_Pos wx,
+ T1_Pos wy )
+ {
+ if (wx > decoder->builder.advance.x)
+ decoder->builder.advance.x = wx;
+
+ (void)sbx;
+ (void)sby;
+ (void)wy;
+ return -1; /* return an error code to exit the Type 1 parser */
+ /* immediately. */
+ }
+
+
+ static
+ T1_Int maxadv_error( void )
+ {
+ /* we should never reach this code, unless with a buggy font */
+ return -2;
+ }
+
+ /* the maxadv_gbuilder_interface is used when computing the maximum */
+ /* advance width of all glyphs in a given font. We only process the */
+ /* 'sbw' operator here, and return an error for all others.. */
+
+ /* Note that "seac" is processed by the T1_Decoder */
+ static
+ const T1_Builder_Funcs maxadv_builder_interface =
+ {
+ (T1_Builder_EndChar) maxadv_error,
+ (T1_Builder_Sbw) maxadv_sbw,
+ (T1_Builder_ClosePath) maxadv_error,
+ (T1_Builder_RLineTo) maxadv_error,
+ (T1_Builder_RMoveTo) maxadv_error,
+ (T1_Builder_RCurveTo) maxadv_error
+ };
+
+
+ /* the maxadv_interface is used when computing the maximum advance */
+ /* with of the set of glyphs in a given font file. We only process */
+ /* the "seac" operator and return immediately.. */
+ static
+ const T1_Hinter_Funcs maxadv_hinter_interface =
+ {
+ (T1_Hinter_DotSection) maxadv_error,
+ (T1_Hinter_ChangeHints) maxadv_error,
+ (T1_Hinter_Stem) maxadv_error,
+ (T1_Hinter_Stem3) maxadv_error,
+ };
+
+
+
+ LOCAL_FUNC
+ T1_Error T1_Compute_Max_Advance( T1_Face face,
+ T1_Int *max_advance )
+ {
+ T1_Error error;
+ T1_Decoder decoder;
+ T1_Int glyph_index;
+
+ *max_advance = 0;
+
+ /* Initialise load decoder */
+ T1_Init_Decoder( &decoder, &maxadv_hinter_interface );
+
+ T1_Init_Builder( &decoder.builder, face, 0, 0,
+ &maxadv_builder_interface );
+
+ /* For each glyph, parse the glyph charstring and extract */
+ /* the advance width.. */
+ for ( glyph_index = 0; glyph_index < face->num_glyphs; glyph_index++ )
+ {
+ /* now get load the unscaled outline */
+ error = T1_Parse_CharStrings( &decoder,
+ face->charstrings [glyph_index],
+ face->charstrings_len[glyph_index],
+ face->num_subrs,
+ face->subrs,
+ face->subrs_len );
+ /* ignore the error if one occured - skip to next glyph */
+ (void)error;
+ }
+
+ *max_advance = decoder.builder.advance.x;
+ return T1_Err_Ok;
+ }
+
+
+ /**********************************************************************/
+ /**********************************************************************/
+ /**********************************************************************/
+ /********** *********/
+ /********** *********/
+ /********** UNHINTED GLYPH LOADER *********/
+ /********** *********/
+ /********** The following code is in charge of loading a *********/
+ /********** single outline. It completely ignores hinting *********/
+ /********** and is used when FT_LOAD_NO_HINTING is set. *********/
+ /********** *********/
+ /********** The Type 1 hinter is located in "t1hint.c" *********/
+ /********** *********/
+ /**********************************************************************/
+ /**********************************************************************/
+ /**********************************************************************/
+
+
+
+ static
+ T1_Error close_open_path( T1_Builder* builder )
+ {
+ T1_Error error;
+ FT_Outline* cur = &builder->current;
+ T1_Int num_points;
+ T1_Int first_point;
+
+ /* Some fonts, like Hershey, are made of "open paths" which are */
+ /* now managed directly by FreeType. In this case, it is necessary */
+ /* to close the path by duplicating its points in reverse order, */
+ /* which is precisely the purpose of this function */
+
+ /* first compute the number of points to duplicate.. */
+ if (cur->n_contours > 1)
+ first_point = cur->contours[ cur->n_contours-2 ]+1;
+ else
+ first_point = 0;
+
+ num_points = cur->n_points - first_point - 2;
+ if ( num_points > 0 )
+ {
+ T1_Vector* source_point;
+ char* source_flags;
+ T1_Vector* point;
+ char* flags;
+
+ error = T1_Add_Points( builder, num_points );
+ if (error) return error;
+
+ point = cur->points + cur->n_points;
+ flags = cur->flags + cur->n_points;
+
+ source_point = point - 2;
+ source_flags = flags - 2;
+
+ cur->n_points += num_points;
+
+ if ( builder->load_points )
+ do
+ {
+ *point++ = *source_point--;
+ *flags++ = *source_flags--;
+ num_points--;
+ }
+ while (num_points > 0);
+ }
+
+ builder->path_begun = 0;
+ return T1_Err_Ok;
+ }
+
+
+ static
+ T1_Error gload_closepath( T1_Builder* builder )
+ {
+ FT_Outline* cur = &builder->current;
+
+ /* save current contour, if any */
+ if ( cur->n_contours > 0 )
+ cur->contours[cur->n_contours-1] = cur->n_points-1;
+
+#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
+ /* hint latest points if needed - this is not strictly required */
+ /* there, but it helps for debugging, and doesn't affect performance */
+ if ( builder->pass == 1 )
+ T1_Hint_Points( builder );
+#endif
+
+ builder->path_begun = 0;
+ return T1_Err_Ok;
+ }
+
+
+
+ static
+ T1_Error gload_endchar( T1_Builder* builder )
+ {
+ FT_Outline* cur = &builder->current;
+ T1_Error error;
+
+ /* close path if needed */
+ if (builder->path_begun)
+ {
+ error = close_open_path( builder );
+ if (error) return error;
+ }
+
+ error = gload_closepath( builder );
+
+ builder->base.n_points += cur->n_points;
+ builder->base.n_contours += cur->n_contours;
+
+ return error;
+ }
+
+
+
+ static
+ T1_Error gload_sbw( T1_Builder* builder,
+ T1_Pos sbx,
+ T1_Pos sby,
+ T1_Pos wx,
+ T1_Pos wy )
+ {
+ builder->left_bearing.x += sbx;
+ builder->left_bearing.y += sby;
+ builder->advance.x = wx;
+ builder->advance.y = wy;
+
+ builder->last.x = sbx;
+ builder->last.y = sby;
+ return 0;
+ }
+
+
+
+
+ static
+ T1_Error gload_rlineto( T1_Builder* builder,
+ T1_Pos dx,
+ T1_Pos dy )
+ {
+ T1_Error error;
+ FT_Outline* cur = &builder->current;
+ T1_Vector vec;
+
+ /* grow buffer if necessary */
+ error = T1_Add_Points ( builder, 1 );
+ if (error) return error;
+
+ if ( builder->load_points )
+ {
+ /* save point */
+ vec.x = builder->last.x + dx;
+ vec.y = builder->last.y + dy;
+
+ cur->points[cur->n_points] = vec;
+ cur->flags [cur->n_points] = FT_Curve_Tag_On;
+
+ builder->last = vec;
+ }
+ cur->n_points++;
+
+ builder->path_begun = 1;
+ return T1_Err_Ok;
+ }
+
+
+ static
+ T1_Error gload_rmoveto( T1_Builder* builder,
+ T1_Pos dx,
+ T1_Pos dy )
+ {
+ T1_Error error;
+ FT_Outline* cur = &builder->current;
+ T1_Vector vec;
+
+ /* in the case where "path_begun" is set, we have a rmoveto */
+ /* after some normal path definition. When the face's paint */
+ /* type is set to 1, this means that we have an "open path", */
+ /* also called a 'stroke'. The FreeType raster doesn't support */
+ /* opened path, so we'll close it explicitely there.. */
+ if ( builder->path_begun && builder->face->paint_type == 1 )
+ {
+ if ( builder->face->paint_type == 1 )
+ {
+ error = close_open_path( builder );
+ if (error) return error;
+ }
+ }
+
+ /* grow buffer if necessary */
+ error = T1_Add_Contours( builder, 1 ) ||
+ T1_Add_Points ( builder, 1 );
+ if (error) return error;
+
+ /* save current contour, if any */
+ if ( cur->n_contours > 0 )
+ cur->contours[cur->n_contours-1] = cur->n_points-1;
+
+ if ( builder->load_points )
+ {
+ /* save point */
+ vec.x = builder->last.x + dx;
+ vec.y = builder->last.y + dy;
+ cur->points[cur->n_points] = vec;
+ cur->flags [cur->n_points] = FT_Curve_Tag_On;
+
+ builder->last = vec;
+ }
+
+ cur->n_contours++;
+ cur->n_points++;
+
+ return T1_Err_Ok;
+ }
+
+
+ static
+ T1_Error gload_rrcurveto( T1_Builder* builder,
+ T1_Pos dx1,
+ T1_Pos dy1,
+ T1_Pos dx2,
+ T1_Pos dy2,
+ T1_Pos dx3,
+ T1_Pos dy3 )
+ {
+ T1_Error error;
+ FT_Outline* cur = &builder->current;
+ T1_Vector vec;
+ T1_Vector* points;
+ char* flags;
+
+ /* grow buffer if necessary */
+ error = T1_Add_Points ( builder, 3 );
+ if (error) return error;
+
+ if ( builder->load_points )
+ {
+ /* save point */
+ points = cur->points + cur->n_points;
+ flags = cur->flags + cur->n_points;
+
+ vec.x = builder->last.x + dx1;
+ vec.y = builder->last.y + dy1;
+ points[0] = vec; flags[0] = FT_Curve_Tag_Cubic;
+
+ vec.x += dx2;
+ vec.y += dy2;
+ points[1] = vec; flags[1] = FT_Curve_Tag_Cubic;
+
+ vec.x += dx3;
+ vec.y += dy3;
+ points[2] = vec; flags[2] = FT_Curve_Tag_On;
+
+ builder->last = vec;
+ }
+
+ cur->n_points += 3;
+ builder->path_begun = 1;
+ return T1_Err_Ok;
+ }
+
+
+
+
+ static
+ T1_Error gload_ignore( void )
+ {
+ return 0;
+ }
+
+
+ static
+ const T1_Builder_Funcs gload_builder_interface =
+ {
+ gload_endchar,
+ gload_sbw,
+ gload_closepath,
+ gload_rlineto,
+ gload_rmoveto,
+ gload_rrcurveto
+ };
+
+
+ static
+ const T1_Builder_Funcs gload_builder_interface_null =
+ {
+ (T1_Builder_EndChar) gload_ignore,
+ (T1_Builder_Sbw) gload_sbw, /* record left bearing */
+ (T1_Builder_ClosePath) gload_ignore,
+ (T1_Builder_RLineTo) gload_ignore,
+ (T1_Builder_RMoveTo) gload_ignore,
+ (T1_Builder_RCurveTo) gload_ignore
+ };
+
+
+ static
+ const T1_Hinter_Funcs gload_hinter_interface =
+ {
+ (T1_Hinter_DotSection) gload_ignore, /* dotsection */
+ (T1_Hinter_ChangeHints) gload_ignore, /* changehints */
+ (T1_Hinter_Stem) gload_ignore, /* hstem & vstem */
+ (T1_Hinter_Stem3) gload_ignore, /* hstem3 & vestem3 */
+ };
+
+
+
+
+ LOCAL_FUNC
+ T1_Error T1_Load_Glyph( T1_GlyphSlot glyph,
+ T1_Size size,
+ T1_Int glyph_index,
+ T1_Int load_flags )
+ {
+ T1_Error error;
+ T1_Decoder decoder;
+ T1_Face face = (T1_Face)glyph->root.face;
+ T1_Bool hinting;
+
+ glyph->x_scale = size->root.metrics.x_scale;
+ glyph->y_scale = size->root.metrics.y_scale;
+
+ glyph->root.outline.n_points = 0;
+ glyph->root.outline.n_contours = 0;
+
+ hinting = ( load_flags & FT_LOAD_NO_SCALE ) == 0 &&
+ ( load_flags & FT_LOAD_NO_HINTING ) == 0;
+
+ glyph->root.format = ft_glyph_format_none;
+
+#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
+ /*****************************************************************/
+ /* */
+ /* Hinter overview : */
+ /* */
+ /* This is a two-pass hinter. On the first pass, the hints */
+ /* are all recorded by the hinter, and no point is loaded */
+ /* in the outline. */
+ /* */
+ /* When the first pass is finished, all stems hints are */
+ /* grid-fitted at once. */
+ /* */
+ /* Then, a second pass is performed to load the outline */
+ /* points as well as hint/scale them correctly. */
+ /* */
+
+ if ( hinting )
+ {
+ /* Pass 1 - don't record points, simply stem hints */
+ T1_Init_Decoder( &decoder, &t1_hinter_funcs );
+ T1_Init_Builder( &decoder.builder, face, size, glyph,
+ &gload_builder_interface_null );
+
+ glyph->hints->hori_stems.num_stems = 0;
+ glyph->hints->vert_stems.num_stems = 0;
+
+ error = T1_Parse_CharStrings( &decoder,
+ face->charstrings [glyph_index],
+ face->charstrings_len[glyph_index],
+ face->num_subrs,
+ face->subrs,
+ face->subrs_len );
+
+ /* All right, pass 1 is finished, now grid-fit all stem hints */
+ T1_Hint_Stems( &decoder.builder );
+
+ /* Pass 2 - record and scale/hint the points */
+ T1_Init_Decoder( &decoder, &t1_hinter_funcs );
+ T1_Init_Builder( &decoder.builder, face, size, glyph,
+ &gload_builder_interface );
+
+ decoder.builder.pass = 1;
+
+ error = T1_Parse_CharStrings( &decoder,
+ face->charstrings [glyph_index],
+ face->charstrings_len[glyph_index],
+ face->num_subrs,
+ face->subrs,
+ face->subrs_len );
+
+ /* save new glyph tables */
+ T1_Done_Builder( &decoder.builder );
+ }
+ else
+#endif
+ {
+ T1_Init_Decoder( &decoder, &gload_hinter_interface );
+
+ T1_Init_Builder( &decoder.builder, face, size, glyph,
+ &gload_builder_interface );
+
+ /* now load the unscaled outline */
+ error = T1_Parse_CharStrings( &decoder,
+ face->charstrings [glyph_index],
+ face->charstrings_len[glyph_index],
+ face->num_subrs,
+ face->subrs,
+ face->subrs_len );
+
+ /* save new glyph tables */
+ T1_Done_Builder( &decoder.builder );
+ }
+
+
+ /* Now, set the metrics.. - this is rather simple, as : */
+ /* the left side bearing is the xMin, and the top side */
+ /* bearing the yMax.. */
+ if (!error)
+ {
+ FT_BBox cbox;
+ FT_Glyph_Metrics* metrics = &glyph->root.metrics;
+
+ FT_Get_Outline_CBox( &glyph->root.outline, &cbox );
+
+ /* grid fit the bounding box if necessary */
+ if (hinting)
+ {
+ cbox.xMin &= -64;
+ cbox.yMin &= -64;
+ cbox.xMax = ( cbox.xMax+63 ) & -64;
+ cbox.yMax = ( cbox.yMax+63 ) & -64;
+ }
+
+ metrics->width = cbox.xMax - cbox.xMin;
+ metrics->height = cbox.yMax - cbox.yMin;
+
+ metrics->horiBearingX = cbox.xMin;
+ metrics->horiBearingY = cbox.yMax;
+
+ /* copy the _unscaled_ advance width */
+ metrics->horiAdvance = decoder.builder.advance.x;
+
+ /* make up vertical metrics */
+ metrics->vertBearingX = 0;
+ metrics->vertBearingY = 0;
+ metrics->vertAdvance = 0;
+
+ glyph->root.format = ft_glyph_format_outline;
+
+ glyph->root.outline.second_pass = TRUE;
+ glyph->root.outline.high_precision = ( size->root.metrics.y_ppem < 24 );
+ glyph->root.outline.dropout_mode = 2;
+
+ if ( hinting )
+ {
+ /* adjust the advance width */
+ /* XXX : TODO : consider stem hints grid-fit */
+ metrics->horiAdvance = FT_MulFix( metrics->horiAdvance,
+ glyph->x_scale );
+ }
+ else if ( (load_flags & FT_LOAD_NO_SCALE) == 0 )
+ {
+ /* scale the outline and the metrics */
+ T1_Int n;
+ FT_Outline* cur = &decoder.builder.base;
+ T1_Vector* vec = cur->points;
+ T1_Fixed x_scale = glyph->x_scale;
+ T1_Fixed y_scale = glyph->y_scale;
+
+ /* First of all, scale the points */
+ for ( n = cur->n_points; n > 0; n--, vec++ )
+ {
+ vec->x = FT_MulFix( vec->x, x_scale );
+ vec->y = FT_MulFix( vec->y, y_scale );
+ }
+
+ /* Then scale the metrics */
+ metrics->width = FT_MulFix( metrics->width, x_scale );
+ metrics->height = FT_MulFix( metrics->height, y_scale );
+
+ metrics->horiBearingX = FT_MulFix( metrics->horiBearingX, x_scale );
+ metrics->horiBearingY = FT_MulFix( metrics->horiBearingY, y_scale );
+ metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
+
+ metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale );
+ metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale );
+ metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, x_scale );
+
+ }
+ }
+
+ return error;
+ }
+
--- /dev/null
+++ b/src/type1/t1gload.h
@@ -1,0 +1,436 @@
+/*******************************************************************
+ *
+ * t1gload.h 1.0
+ *
+ * Type1 Glyph Loader.
+ *
+ * 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.
+ *
+ *
+ * The Type 1 glyph loader uses three distinct objects to build
+ * scaled and hinted outlines from a charstrings program. These are :
+ *
+ * - a glyph builder, T1_Builder, used to store the built outline
+ *
+ * - a glyph hinter, T1_Hinter, used to record and apply the stem
+ * hints
+ *
+ * - a charstrings interpreter, T1_Decoder, used to parse the
+ * Type 1 charstrings stream, manage a stack and call the builder
+ * and/or hinter depending on the opcodes.
+ *
+ * Ideally, a Type 2 glyph loader would only need to have its own
+ * T2_Decoder object (assuming the hinter is able to manage all
+ * kinds of hints).
+ *
+ ******************************************************************/
+
+#ifndef T1GLOAD_H
+#define T1GLOAD_H
+
+#include <t1objs.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/*************************************************************************/
+/* */
+/* <Structure> T1_Builder_Funcs */
+/* */
+/* <Description> */
+/* a structure used to store the address of various functions */
+/* used by a glyph builder to implement the outline's "path */
+/* construction". */
+/* */
+/* */
+ typedef struct T1_Builder_ T1_Builder;
+
+ typedef T1_Error (*T1_Builder_EndChar)( T1_Builder* loader );
+
+ typedef T1_Error (*T1_Builder_Sbw) ( T1_Builder* loader,
+ T1_Pos sbx,
+ T1_Pos sby,
+ T1_Pos wx,
+ T1_Pos wy );
+
+ typedef T1_Error (*T1_Builder_ClosePath)( T1_Builder* loader );
+
+ typedef T1_Error (*T1_Builder_RLineTo)( T1_Builder* loader,
+ T1_Pos dx,
+ T1_Pos dy );
+
+ typedef T1_Error (*T1_Builder_RMoveTo)( T1_Builder* loader,
+ T1_Pos dx,
+ T1_Pos dy );
+
+ typedef T1_Error (*T1_Builder_RCurveTo)( T1_Builder* loader,
+ T1_Pos dx1,
+ T1_Pos dy1,
+ T1_Pos dx2,
+ T1_Pos dy2,
+ T1_Pos dx3,
+ T1_Pos dy3 );
+
+ typedef struct T1_Builder_Funcs_
+ {
+ T1_Builder_EndChar end_char;
+ T1_Builder_Sbw set_bearing_point;
+ T1_Builder_ClosePath close_path;
+ T1_Builder_RLineTo rline_to;
+ T1_Builder_RMoveTo rmove_to;
+ T1_Builder_RCurveTo rcurve_to;
+
+ } T1_Builder_Funcs;
+
+
+
+/*************************************************************************/
+/* */
+/* <Structure> T1_Builder */
+/* */
+/* <Description> */
+/* a structure used during glyph loading to store its outline. */
+/* */
+/* <Fields> */
+/* system :: current system object */
+/* face :: current face object */
+/* size :: current size object */
+/* glyph :: current glyph slot */
+/* */
+/* current :: current glyph outline */
+/* base :: base glyph outline */
+/* */
+/* max_points :: maximum points in builder outline */
+/* max_contours :: maximum contours in builder outline */
+/* */
+/* last :: last point position */
+/* */
+/* scale_x :: horizontal scale ( FUnits to sub-pixels ) */
+/* scale_y :: vertical scale ( FUnits to sub-pixels ) */
+/* pos_x :: horizontal translation (composite glyphs) */
+/* pos_y :: vertical translation (composite glyph) */
+/* */
+/* left_bearing :: left side bearing point */
+/* advance :: horizontal advance vector */
+/* */
+/* path_begun :: flag, indicates that a new path has begun */
+/* load_points :: flag, if not set, no points are loaded */
+/* */
+/* pass :: pass number for multi-pass hinters */
+/* */
+/* funcs :: table of builder functions used to perform */
+/* the outline's path construction */
+/* */
+/* hint_point :: index of next point to hint.. */
+/* */
+/* */
+/* */
+/* */
+
+ struct T1_Builder_
+ {
+ FT_Memory memory;
+ T1_Face face;
+ T1_Size size;
+ T1_GlyphSlot glyph;
+
+ FT_Outline current; /* the current glyph outline */
+ FT_Outline base; /* the composite glyph outline */
+
+ T1_Int max_points; /* capacity of base outline in points */
+ T1_Int max_contours; /* capacity of base outline in contours */
+
+ T1_Vector last;
+
+ T1_Fixed scale_x;
+ T1_Fixed scale_y;
+
+ T1_Pos pos_x;
+ T1_Pos pos_y;
+
+ T1_Vector left_bearing;
+ T1_Vector advance;
+
+ T1_BBox bbox; /* bounding box */
+ T1_Bool path_begun;
+ T1_Bool load_points;
+
+ T1_Int pass;
+ T1_Int hint_point;
+
+ /* path construction function interface */
+ T1_Builder_Funcs funcs;
+ };
+
+
+/*************************************************************************/
+/* */
+/* <Structure> T1_Hinter_Funcs */
+/* */
+/* <Description> */
+/* a structure used to store the address of various functions */
+/* used by a Type 1 hinter to perform outline hinting. */
+/* */
+
+ typedef T1_Error (*T1_Hinter_ChangeHints)( T1_Builder* builder );
+
+ typedef T1_Error (*T1_Hinter_DotSection)( T1_Builder* builder );
+
+ typedef T1_Error (*T1_Hinter_Stem)( T1_Builder* builder,
+ T1_Pos pos,
+ T1_Pos width,
+ T1_Bool vertical );
+
+
+ typedef T1_Error (*T1_Hinter_Stem3)( T1_Builder* builder,
+ T1_Pos pos0,
+ T1_Pos width0,
+ T1_Pos pos1,
+ T1_Pos width1,
+ T1_Pos pos2,
+ T1_Pos width2,
+ T1_Bool vertical );
+
+ typedef struct T1_Hinter_Func_
+ {
+ T1_Hinter_ChangeHints change_hints;
+ T1_Hinter_DotSection dot_section;
+ T1_Hinter_Stem stem;
+ T1_Hinter_Stem3 stem3;
+
+ } T1_Hinter_Funcs;
+
+
+
+ typedef enum T1_Operator_
+ {
+ op_none = 0,
+ op_endchar,
+ op_hsbw,
+ op_seac,
+ op_sbw,
+ op_closepath,
+ op_hlineto,
+ op_hmoveto,
+ op_hvcurveto,
+ op_rlineto,
+ op_rmoveto,
+ op_rrcurveto,
+ op_vhcurveto,
+ op_vlineto,
+ op_vmoveto,
+ op_dotsection,
+ op_hstem,
+ op_hstem3,
+ op_vstem,
+ op_vstem3,
+ op_div,
+ op_callothersubr,
+ op_callsubr,
+ op_pop,
+ op_return,
+ op_setcurrentpoint,
+
+ op_max /* never remove this one */
+
+ } T1_Operator;
+
+
+
+
+ /* execution context charstring zone */
+ typedef struct T1_Decoder_Zone_
+ {
+ T1_Byte* base;
+ T1_Byte* limit;
+ T1_Byte* cursor;
+
+ } T1_Decoder_Zone;
+
+
+ typedef struct T1_Decoder_
+ {
+ T1_Builder builder;
+ T1_Hinter_Funcs hinter;
+
+ T1_Int stack[ T1_MAX_CHARSTRINGS_OPERANDS ];
+ T1_Int* top;
+
+ T1_Decoder_Zone zones[ T1_MAX_SUBRS_CALLS+1 ];
+ T1_Decoder_Zone* zone;
+
+ T1_Int flex_state;
+ T1_Int num_flex_vectors;
+ T1_Vector flex_vectors[7];
+
+ } T1_Decoder;
+
+
+
+/*********************************************************************
+ *
+ * <Function>
+ * T1_Init_Builder
+ *
+ * <Description>
+ * Initialise a given glyph builder.
+ *
+ * <Input>
+ * builder :: glyph builder to initialise
+ * face :: current face object
+ * size :: current size object
+ * glyph :: current glyph object
+ * funcs :: glyph builder functions (or "methods").
+ *
+ * <Note>
+ * This function is exported for now because it is used by the
+ * "t1dump" utility. Later, it will be accessed through a
+ * format-specific extension
+ *
+ *********************************************************************/
+
+ EXPORT_DEF
+ void T1_Init_Builder( T1_Builder* builder,
+ T1_Face face,
+ T1_Size size,
+ T1_GlyphSlot glyph,
+ const T1_Builder_Funcs* funcs );
+
+/*********************************************************************
+ *
+ * <Function>
+ * T1_Done_Builder
+ *
+ * <Description>
+ * Finalise a given glyph builder. Its content can still be
+ * used after the call, but the function saves important information
+ * within the corresponding glyph slot.
+ *
+ * <Input>
+ * builder :: glyph builder to initialise
+ *
+ * <Note>
+ * This function is exported for now because it is used by the
+ * "t1dump" utility. Later, it will be accessed through a
+ * format-specific extension
+ *
+ *********************************************************************/
+
+ EXPORT_DEF
+ void T1_Done_Builder( T1_Builder* builder );
+
+
+/*********************************************************************
+ *
+ * <Function>
+ * T1_Init_Decoder
+ *
+ * <Description>
+ * Initialise a given Type 1 decoder for parsing
+ *
+ * <Input>
+ * decoder :: Type 1 decoder to initialise
+ * funcs :: hinter functions interface
+ *
+ * <Note>
+ * This function is exported for now because it is used by the
+ * "t1dump" utility. Later, it will be accessed through a
+ * format-specific extension
+ *
+ *********************************************************************/
+
+ EXPORT_DEF
+ void T1_Init_Decoder( T1_Decoder* decoder,
+ const T1_Hinter_Funcs* funcs );
+
+
+
+ /* Compute the maximum advance width of a font through quick parsing */
+ LOCAL_DEF
+ T1_Error T1_Compute_Max_Advance( T1_Face face,
+ T1_Int *max_advance );
+
+
+ /* This function is exported, because it is used by the T1Dump utility */
+ EXPORT_DEF
+ T1_Error T1_Parse_CharStrings( T1_Decoder* decoder,
+ T1_Byte* charstring_base,
+ T1_Int charstring_len,
+ T1_Int num_subrs,
+ T1_Byte** subrs_base,
+ T1_Int* subrs_len );
+
+
+
+/*************************************************************************/
+/* */
+/* <Function> T1_Add_Points */
+/* */
+/* <Description> */
+/* Checks that there is enough room in the current load glyph outline */
+/* to accept "num_points" additional outline points. If not, this */
+/* function grows the load outline's arrays accordingly.. */
+/* */
+/* <Input> */
+/* builder :: pointer to glyph builder object */
+/* num_points :: number of points that will be added later */
+/* */
+/* <Return> */
+/* Type1 error code. 0 means success */
+/* */
+/* <Note> */
+/* This function does NOT update the points count in the glyph loader */
+/* This must be done by the caller itself, after this function is */
+/* invoked.. */
+/* */
+ LOCAL_DEF
+ T1_Error T1_Add_Points( T1_Builder* builder,
+ T1_Int num_points );
+
+/*************************************************************************/
+/* */
+/* <Function> T1_Add_Contours */
+/* */
+/* <Description> */
+/* Checks that there is enough room in the current load glyph outline */
+/* to accept "num_contours" additional contours. If not, this func */
+/* the load outline's arrays accordingly.. */
+/* */
+/* <Input> */
+/* builder :: pointer to glyph builder object */
+/* num_contours :: number of contours that will be added later */
+/* */
+/* <Return> */
+/* Type1 error code. 0 means success */
+/* */
+/* <Note> */
+/* This function does NOT update the contours count in the load glyph */
+/* This must be done by the caller itself, after this function is */
+/* invoked.. */
+/* */
+ LOCAL_DEF
+ T1_Error T1_Add_Contours( T1_Builder* builder,
+ T1_Int num_contours );
+
+
+ LOCAL_DEF
+ T1_Error T1_Load_Glyph( T1_GlyphSlot glyph,
+ T1_Size size,
+ T1_Int glyph_index,
+ T1_Int load_flags );
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* T1GLOAD_H */
--- /dev/null
+++ b/src/type1/t1hinter.c
@@ -1,0 +1,1269 @@
+/*******************************************************************
+ *
+ * t1hinter.c 1.2
+ *
+ * Type1 hinter.
+ *
+ * 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 Hinter is in charge of fitting th scaled outline to the
+ * pixel grid in order to considerably improve the quality of
+ * the Type 1 font driver's output..
+ *
+ ******************************************************************/
+
+#include <ftdebug.h>
+#include <t1objs.h>
+#include <t1hinter.h>
+
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_t1hint /* for debugging/tracing */
+
+
+#undef ONE_PIXEL
+#define ONE_PIXEL 64
+
+#undef ROUND
+#define ROUND(x) (( x + ONE_PIXEL/2 ) & -ONE_PIXEL)
+
+#undef SCALE
+#define SCALE(val) FT_MulFix( val, scale )
+
+/* various constants used to describe the alignment of a horizontal */
+/* stem with regards to the blue zones */
+#define T1_ALIGN_NONE 0
+#define T1_ALIGN_BOTTOM 1
+#define T1_ALIGN_TOP 2
+#define T1_ALIGN_BOTH 3
+
+
+/************************************************************************
+ *
+ * <Function>
+ * t1_set_blue_zones
+ *
+ * <Description>
+ * Set a size object's blue zones during reset. This will compute
+ * the "snap" zone corresponding to each blue zone.
+ *
+ * <Input>
+ * size :: handle to target size object
+ *
+ * <Return>
+ * Error code. 0 means success
+ *
+ * <Note>
+ * This functions does the following :
+ *
+ * 1. It extracts the bottom and top blue zones from the
+ * face object.
+ *
+ * 2. Each zone is then grown by BlueFuzz, overlapping
+ * is eliminated by adjusting the zone edges appropriately
+ *
+ * 3. For each zone, we keep its original font units position, its
+ * original scaled position, as well as its grown/adjusted
+ * edges.
+ *
+ ************************************************************************/
+
+ /* ultra simple bubble sort (not a lot of elements, mostly */
+ /* pre-sorted, no need for quicksort) */
+ static
+ void t1_sort_blues( T1_Int* blues,
+ T1_Int count )
+ {
+ T1_Int i, swap;
+ T1_Int* cur;
+
+ for ( i = 2; i < count; i += 2 )
+ {
+ cur = blues + i;
+ do
+ {
+ if ( cur[-1] < cur[0] )
+ break;
+
+ swap = cur[-2]; cur[-2] = cur[0]; cur[0] = swap;
+ swap = cur[-1]; cur[-1] = cur[1]; cur[1] = swap;
+ cur -= 2;
+ }
+ while ( cur > blues );
+ }
+ }
+
+
+ static
+ T1_Error t1_set_blue_zones( T1_Size size )
+ {
+ T1_Face face = (T1_Face)size->root.face;
+ T1_Private* priv = &face->private_dict;
+ T1_Int n;
+ T1_Int blues[24];
+ T1_Int num_bottom;
+ T1_Int num_top;
+ T1_Int num_blues;
+ T1_Size_Hints* hints = size->hints;
+ T1_Snap_Zone* zone;
+ T1_Pos pix, orus;
+ T1_Pos min, max, threshold;
+ T1_Fixed scale;
+ T1_Bool is_bottom;
+
+ /**********************************************************************/
+ /* */
+ /* COPY BOTTOM AND TOP BLUE ZONES IN LOCAL ARRAYS */
+ /* */
+ /* */
+
+ /* First of all, check the sizes of the /BlueValues and /OtherBlues */
+ /* tables. They all must contain an even number of arguments */
+ if ( priv->num_other_blues & 1 ||
+ priv->num_blues & 1 )
+ {
+ FT_ERROR(( "T1.Copy_Blues : odd number of blue values\n" ));
+ return T1_Err_Syntax_Error;
+ }
+
+ /* copy the bottom blue zones from /OtherBlues */
+ num_top = 0;
+ num_bottom = priv->num_other_blues;
+
+ for ( n = 0; n < num_bottom; n ++ )
+ blues[n] = priv->other_blues[n];
+
+ /* Add the first blue zone in /BlueValues to the table */
+ num_top = priv->num_blues - 2;
+ if ( num_top >= 0 )
+ {
+ blues[ num_bottom ] = priv->blue_values[0];
+ blues[num_bottom+1] = priv->blue_values[1];
+
+ num_bottom += 2;
+ }
+
+ /* sort the bottom blue zones */
+ t1_sort_blues( blues, num_bottom );
+
+ hints->num_bottom_zones = num_bottom >> 1;
+
+ /* now copy the /BlueValues to the top of the blues array */
+ if ( num_top > 0 )
+ {
+ for ( n = 0; n < num_top; n++ )
+ blues[ num_bottom+n ] = priv->blue_values[n+2];
+
+ /* sort the top blue zones */
+ t1_sort_blues( blues + num_bottom, num_top );
+ }
+ else
+ num_top = 0;
+
+ num_blues = num_top + num_bottom;
+ hints->num_blue_zones = ( num_blues ) >> 1;
+
+ /**********************************************************************/
+ /* */
+ /* BUILD BLUE SNAP ZONES FROM THE LOCAL BLUES ARRAYS */
+ /* */
+ /* */
+
+ scale = size->root.metrics.y_scale;
+ zone = hints->blue_zones;
+ threshold = ONE_PIXEL/4; /* 0.25 pixels */
+
+ for ( n = 0; n < num_blues; n += 2, zone ++ )
+ {
+ is_bottom = ( n < num_bottom ? 1 : 0 );
+
+ orus = blues[n+is_bottom]; /* get alignement coordinate */
+ pix = SCALE( orus ); /* scale it */
+
+ min = SCALE( blues[ n ] - priv->blue_fuzz );
+ max = SCALE( blues[n+1] + priv->blue_fuzz );
+
+ if ( min > pix - threshold ) min = pix - threshold;
+ if ( max < pix + threshold ) max = pix + threshold;
+
+ zone->orus = orus;
+ zone->pix = pix;
+ zone->min = min;
+ zone->max = max;
+ }
+
+ /* adjust edges in case of overlap */
+ zone = hints->blue_zones;
+ for ( n = 0; n < num_blues-2; n += 2, zone ++ )
+ {
+ if ( n != num_bottom-2 &&
+ zone[0].max > zone[1].min )
+ {
+ zone[0].max = zone[1].min = (zone[0].pix+zone[1].pix)/2;
+ }
+ }
+
+
+ /* Compare the current pixel size with the BlueScale value */
+ /* to know wether to supress overshoots.. */
+
+ hints->supress_overshoots =
+ ( size->root.metrics.y_ppem < FT_MulFix(1000,priv->blue_scale) );
+
+ /* Now print the new blue values in tracing mode */
+#ifdef FT_DEBUG_LEVEL_TRACE
+
+ FT_TRACE2(( "Blue Zones for size object at $%08lx :\n", (long)size ));
+ FT_TRACE2(( " orus pix min max\n" ));
+ FT_TRACE2(( "-------------------------------\n" ));
+
+ zone = hints->blue_zones;
+ for ( n = 0; n < hints->num_blue_zones; n++ )
+ {
+ FT_TRACE2(( " %3d %.2f %.2f %.2f\n",
+ zone->orus,
+ zone->pix/64.0,
+ zone->min/64.0,
+ zone->max/64.0 ));
+ zone++;
+ }
+ FT_TRACE2(( "\nOver shoots are %s\n\n",
+ hints->supress_overshoots ? "supressed" : "active" ));
+
+#endif /* DEBUG_LEVEL_TRACE */
+
+ return T1_Err_Ok;
+ }
+
+
+
+/************************************************************************
+ *
+ * <Function>
+ * t1_set_snap_zones
+ *
+ * <Description>
+ * This function set a size object's stem snap zones.
+ *
+ * <Input>
+ * size :: handle to target size object
+ *
+ * <Return>
+ * Error code. 0 means success
+ *
+ * <Note>
+ * This function performs the following :
+ *
+ * 1. It reads and scales the stem snap widths from the parent face
+ *
+ * 2. A "snap zone" is computed for each snap width, by "growing"
+ * it with a threshold of a 1/2 pixel. Overlapping is avoided
+ * through proper edge adjustment.
+ *
+ * 3. Each width whose zone contain the scaled standard set width
+ * is removed from the table
+ *
+ * 4. Finally, the standard set width is scaled, and its correponding
+ * "snap zone" is inserted into the sorted snap zones table
+ *
+ ************************************************************************/
+
+ static
+ T1_Error t1_set_snap_zones( T1_Size size )
+ {
+ T1_Int n, direction, n_zones, num_zones;
+ T1_Snap_Zone* zone;
+ T1_Snap_Zone* base_zone;
+ T1_Short* orgs;
+ T1_Pos standard_width;
+ T1_Fixed scale;
+
+ T1_Face face = (T1_Face)size->root.face;
+ T1_Private* priv = &face->private_dict;
+ T1_Size_Hints* hints = size->hints;
+
+ /* start with horizontal snap zones */
+ direction = 0;
+ standard_width = priv->standard_width;
+ n_zones = priv->num_snap_widths;
+ base_zone = hints->snap_widths;
+ orgs = priv->stem_snap_widths;
+ scale = size->root.metrics.x_scale;
+
+ while (direction < 2)
+ {
+ /*****************************************************************/
+ /* */
+ /* Read and scale stem snap widths table from the physical */
+ /* font record. */
+ /* */
+ T1_Pos prev, orus, pix, min, max, threshold;
+
+ threshold = ONE_PIXEL/4;
+ zone = base_zone;
+
+ if ( n_zones > 0 )
+ {
+ orus = *orgs++;
+ pix = SCALE( orus );
+ min = pix-threshold;
+ max = pix+threshold;
+
+ zone->orus = orus;
+ zone->pix = pix;
+ zone->min = min;
+ prev = pix;
+
+ for ( n = 1; n < n_zones; n++ )
+ {
+ orus = *orgs++;
+ pix = SCALE( orus );
+
+ if ( pix-prev < 2*threshold )
+ {
+ min = max = (pix+prev)/2;
+ }
+ else
+ min = pix-threshold;
+
+ zone->max = max;
+ zone++;
+ zone->orus = orus;
+ zone->pix = pix;
+ zone->min = min;
+
+ max = pix+threshold;
+ prev = pix;
+ }
+ zone->max = max;
+ }
+
+ /* print the scaled stem snap values in tracing modes */
+#ifdef FT_DEBUG_LEVEL_TRACE
+
+ FT_TRACE2(( "Set_Snap_Zones : first %s pass\n",
+ direction ? "vertical" : "horizontal" ));
+
+ FT_TRACE2(( "Scaled original stem snap zones :\n" ));
+ FT_TRACE2(( " orus pix min max\n" ));
+ FT_TRACE2(( "-----------------------------\n" ));
+
+ zone = base_zone;
+ for ( n = 0; n < n_zones; n++, zone++ )
+ FT_TRACE2(( " %3d %.2f %.2f %.2f\n",
+ zone->orus,
+ zone->pix/64.0,
+ zone->min/64.0,
+ zone->max/64.0 ));
+ FT_TRACE2(( "\n" ));
+
+ FT_TRACE2(( "Standard width = %d\n", standard_width ));
+#endif
+
+ /*****************************************************************/
+ /* */
+ /* Now, each snap width which is in the range of the standard */
+ /* set width will be removed from the list.. */
+ /* */
+
+ if ( standard_width > 0 )
+ {
+ T1_Snap_Zone* parent;
+ T1_Pos std_pix, std_min, std_max;
+
+ std_pix = SCALE( standard_width );
+
+ std_min = std_pix-threshold;
+ std_max = std_pix+threshold;
+
+ num_zones = 0;
+ zone = base_zone;
+ parent = base_zone;
+
+ for ( n = 0; n < n_zones; n++ )
+ {
+ if ( zone->pix >= std_min && zone->pix <= std_max )
+ {
+ /* this zone must be removed from the list */
+ if ( std_min > zone->min ) std_min = zone->min;
+ if ( std_max < zone->max ) std_max = zone->max;
+ }
+ else
+ {
+ *parent++ = *zone;
+ num_zones++;
+ }
+ zone++;
+ }
+
+ /**********************************************/
+ /* Now, insert the standard width zone */
+
+ zone = base_zone+num_zones;
+ while ( zone > base_zone && zone[-1].pix > std_max )
+ {
+ zone[0] = zone[-1];
+ zone --;
+ }
+
+ /* check border zones */
+ if ( zone > base_zone && zone[-1].max > std_min )
+ zone[-1].max = std_min;
+
+ if ( zone < base_zone+num_zones && zone[1].min < std_max )
+ zone[1].min = std_max;
+
+ zone->orus = standard_width;
+ zone->pix = std_pix;
+ zone->min = std_min;
+ zone->max = std_max;
+
+ num_zones++;
+ }
+ else
+ num_zones = n_zones;
+
+ /* save total number of stem snaps now */
+ if (direction) hints->num_snap_heights = num_zones;
+ else hints->num_snap_widths = num_zones;
+
+ /* print the scaled stem snap values in tracing modes */
+#ifdef FT_DEBUG_LEVEL_TRACE
+
+ FT_TRACE2(( "Set_Snap_Zones : second %s pass\n",
+ direction ? "vertical" : "horizontal" ));
+
+ FT_TRACE2(( "Scaled clipped stem snap zones :\n" ));
+ FT_TRACE2(( " orus pix min max\n" ));
+ FT_TRACE2(( "-----------------------------\n" ));
+
+ zone = base_zone;
+ for ( n = 0; n < num_zones; n++, zone++ )
+ FT_TRACE2(( " %3d %.2f %.2f %.2f\n",
+ zone->orus,
+ zone->pix/64.0,
+ zone->min/64.0,
+ zone->max/64.0 ));
+ FT_TRACE2(( "\n" ));
+
+ FT_TRACE2(( "Standard width = %d\n", standard_width ));
+#endif
+
+ /* continue with vertical snap zone */
+ direction++;
+ standard_width = priv->standard_height;
+ n_zones = priv->num_snap_heights;
+ base_zone = hints->snap_heights;
+ orgs = priv->stem_snap_heights;
+ scale = size->root.metrics.y_scale;
+ }
+
+ return T1_Err_Ok;
+ }
+
+
+/************************************************************************
+ *
+ * <Function>
+ * T1_New_Size_Hinter
+ *
+ * <Description>
+ * Allocates a new hinter structure for a given size object
+ *
+ * <Input>
+ * size :: handle to target size object
+ *
+ * <Return>
+ * Error code. 0 means success
+ *
+ ************************************************************************/
+
+ LOCAL_FUNC
+ T1_Error T1_New_Size_Hinter( T1_Size size )
+ {
+ FT_Memory memory = size->root.face->memory;
+
+ return MEM_Alloc( size->hints, sizeof(*size->hints) );
+ }
+
+
+/************************************************************************
+ *
+ * <Function>
+ * T1_Done_Size_Hinter
+ *
+ * <Description>
+ * Releases a given size object's hinter structure
+ *
+ * <Input>
+ * size :: handle to target size object
+ *
+ ************************************************************************/
+
+ LOCAL_FUNC
+ void T1_Done_Size_Hinter( T1_Size size )
+ {
+ FT_Memory memory = size->root.face->memory;
+
+ FREE( size->hints );
+ }
+
+
+
+/************************************************************************
+ *
+ * <Function>
+ * T1_Reset_Size_Hinter
+ *
+ * <Description>
+ * Recomputes hinting information when a given size object has
+ * changed its resolutions/char sizes/pixel sizes
+ *
+ * <Input>
+ * size :: handle to size object
+ *
+ * <Return>
+ * Error code. 0 means success
+ *
+ ************************************************************************/
+
+ LOCAL_FUNC
+ T1_Error T1_Reset_Size_Hinter( T1_Size size )
+ {
+ return t1_set_blue_zones(size) || t1_set_snap_zones(size);
+ }
+
+
+
+/************************************************************************
+ *
+ * <Function>
+ * T1_New_Glyph_Hinter
+ *
+ * <Description>
+ * Allocates a new hinter structure for a given glyph slot
+ *
+ * <Input>
+ * glyph :: handle to target glyph slot
+ *
+ * <Return>
+ * Error code. 0 means success
+ *
+ ************************************************************************/
+
+ LOCAL_FUNC
+ T1_Error T1_New_Glyph_Hinter( T1_GlyphSlot glyph )
+ {
+ FT_Memory memory = glyph->root.face->memory;
+
+ return MEM_Alloc( glyph->hints, sizeof(*glyph->hints) );
+ }
+
+
+/************************************************************************
+ *
+ * <Function>
+ * T1_Done_Glyph_Hinter
+ *
+ * <Description>
+ * Releases a given glyph slot's hinter structure
+ *
+ * <Input>
+ * glyph :: handle to glyph slot
+ *
+ ************************************************************************/
+
+ LOCAL_FUNC
+ void T1_Done_Glyph_Hinter( T1_GlyphSlot glyph )
+ {
+ FT_Memory memory = glyph->root.face->memory;
+
+ FREE( glyph->hints );
+ }
+
+
+
+ /**********************************************************************/
+ /**********************************************************************/
+ /**********************************************************************/
+ /********** *********/
+ /********** *********/
+ /********** HINTED GLYPH LOADER *********/
+ /********** *********/
+ /********** The following code is in charge of the first *********/
+ /********** and second pass when loading a single outline *********/
+ /********** *********/
+ /**********************************************************************/
+ /**********************************************************************/
+ /**********************************************************************/
+
+ static
+ T1_Error t1_hinter_ignore( void )
+ {
+ /* do nothing, used for "dotsection" which is unsupported for now */
+ return 0;
+ }
+
+ static
+ T1_Error t1_hinter_stem( T1_Builder* builder,
+ T1_Pos pos,
+ T1_Int width,
+ T1_Bool vertical )
+ {
+ T1_Stem_Table* stem_table;
+ T1_Stem_Hint* stems;
+ T1_Stem_Hint* cur_stem;
+ T1_Int min, max, n, num_stems;
+ T1_Bool new_stem;
+ T1_Glyph_Hints* hinter = builder->glyph->hints;
+
+ /* select the appropriate stem array */
+ stem_table = vertical ? &hinter->vert_stems : &hinter->hori_stems;
+ stems = stem_table->stems;
+ num_stems = stem_table->num_stems;
+
+ /* Compute minimum and maximum orus for the stem */
+ min = pos + ( vertical
+ ? builder->left_bearing.x
+ : builder->left_bearing.y );
+
+ if ( width >= 0 )
+ max = min + width;
+ else
+ {
+ /* a negative width indicates a ghost stem */
+ if ( width == -21 )
+ min += width;
+
+ max = min;
+ }
+
+ /* now scan the array. If we find a stem with the same borders */
+ /* simply activate it.. */
+ cur_stem = stems;
+ new_stem = 1;
+
+ for ( n = 0; n < num_stems; n++, cur_stem++ )
+ {
+ if ( cur_stem->min_edge.orus == min &&
+ cur_stem->max_edge.orus == max )
+ {
+ /* This stem is already in the table, simply activate it */
+ if ( (cur_stem->hint_flags & T1_HINT_FLAG_ACTIVE) == 0)
+ {
+ cur_stem->hint_flags |= T1_HINT_FLAG_ACTIVE;
+ stem_table->num_active ++;
+ }
+ new_stem = 0;
+ break;
+ }
+ }
+
+ /* add a new stem to the array when necessary */
+ if (new_stem)
+ {
+ if (cur_stem >= stems + T1_HINTER_MAX_EDGES)
+ {
+ FT_ERROR(( "T1.Hinter : too many stems in glyph charstring\n" ));
+ return T1_Err_Syntax_Error;
+ }
+
+ /* on the first pass, we record the stem, otherwise, this is */
+ /* a bug in the glyph loader !! */
+ if ( builder->pass == 0 )
+ {
+ cur_stem->min_edge.orus = min;
+ cur_stem->max_edge.orus = max;
+ cur_stem->hint_flags = T1_HINT_FLAG_ACTIVE;
+
+ stem_table->num_stems++;
+ stem_table->num_active++;
+ }
+ else
+ {
+ FT_ERROR(( "T1.Hinter : fatal glyph loader bug - pass2-stem\n" ));
+ return T1_Err_Syntax_Error;
+ }
+ }
+
+ return T1_Err_Ok;
+ }
+
+
+ static
+ T1_Error t1_hinter_stem3( T1_Builder* builder,
+ T1_Pos pos0,
+ T1_Int width0,
+ T1_Pos pos1,
+ T1_Int width1,
+ T1_Pos pos2,
+ T1_Int width2,
+ T1_Bool vertical )
+ {
+ /* For now, don't be elitist and simply call "stem" 3 times */
+ return t1_hinter_stem( builder, pos0, width0, vertical ) ||
+ t1_hinter_stem( builder, pos1, width1, vertical ) ||
+ t1_hinter_stem( builder, pos2, width2, vertical );
+ }
+
+
+ static
+ T1_Error t1_hinter_changehints( T1_Builder* builder )
+ {
+ T1_Int dimension;
+ T1_Stem_Table* stem_table;
+ T1_Glyph_Hints* hinter = builder->glyph->hints;
+
+ /* if we're in the second pass of glyph hinting, we must */
+ /* call the function T1_Hint_Points on the builder in order */
+ /* to force the fit the latest points to the pixel grid */
+ if ( builder->pass == 1 )
+ T1_Hint_Points( builder );
+
+ /* Simply de-activate all hints in all arrays */
+ stem_table = &hinter->hori_stems;
+
+ for ( dimension = 2; dimension > 0; dimension-- )
+ {
+ T1_Stem_Hint* cur = stem_table->stems;
+ T1_Stem_Hint* limit = cur + stem_table->num_stems;
+
+ for ( ; cur < limit; cur++ )
+ cur->hint_flags &= ~T1_HINT_FLAG_ACTIVE;
+
+ stem_table->num_active = 0;
+ stem_table = &hinter->vert_stems;
+ }
+
+ return T1_Err_Ok;
+ }
+
+
+ LOCAL_FUNC
+ const T1_Hinter_Funcs t1_hinter_funcs =
+ {
+ (T1_Hinter_ChangeHints) t1_hinter_changehints,
+ (T1_Hinter_DotSection) t1_hinter_ignore,
+ (T1_Hinter_Stem) t1_hinter_stem,
+ (T1_Hinter_Stem3) t1_hinter_stem3
+ };
+
+
+ /**********************************************************************/
+ /**********************************************************************/
+ /**********************************************************************/
+ /********** *********/
+ /********** *********/
+ /********** STEM HINTS MANAGEMENT *********/
+ /********** *********/
+ /********** The following code is in charge of computing *********/
+ /********** the placement of each scaled stem hint.. *********/
+ /********** *********/
+ /**********************************************************************/
+ /**********************************************************************/
+ /**********************************************************************/
+
+/************************************************************************
+ *
+ * <Function>
+ * t1_sort_hints
+ *
+ * <Description>
+ * Sort the list of active stems in increasing order, through
+ * the "sort" indexing table
+ *
+ * <Input>
+ * table :: a stem hints table
+ *
+ ************************************************************************/
+
+ static
+ void t1_sort_hints( T1_Stem_Table* table )
+ {
+ T1_Int num_stems = table->num_stems;
+ T1_Int num_active = 0;
+ T1_Int* sort = table->sort;
+ T1_Stem_Hint* stems = table->stems;
+ T1_Int n;
+
+ /* record active stems in sort table */
+ for ( n = 0; n < num_stems; n++ )
+ {
+ if ( stems[n].hint_flags & T1_HINT_FLAG_ACTIVE )
+ sort[num_active++] = n;
+ }
+
+ /* now sort the indices. There are usually very few stems, */
+ /* and they are pre-sorted in 90% cases, so we choose a */
+ /* simple bubble sort (quicksort would be slower).. */
+ for ( n = 1; n < num_active; n++ )
+ {
+ T1_Int p = n-1;
+ T1_Stem_Hint* cur = stems + sort[n];
+
+ do
+ {
+ T1_Int swap;
+ T1_Stem_Hint* prev = stems + sort[p];
+
+ /* note that by definition, the active stems cannot overlap */
+ /* so we simply compare their "min" to sort them.. */
+ /* (we could compare their max, this wouldn't change anything) */
+ if ( prev->min_edge.orus <= cur->min_edge.orus )
+ break;
+
+ /* swap elements */
+ swap = sort[ p ];
+ sort[ p ] = sort[p+1];
+ sort[p+1] = swap;
+ p--;
+ }
+ while ( p >= 0 );
+ }
+
+ table->num_active = num_active;
+ }
+
+
+/************************************************************************
+ *
+ * <Function>
+ * t1_hint_horizontal_stems
+ *
+ * <Description>
+ * Compute the location of each scaled horizontal stem hint.
+ * This takes care of the blue zones and the horizontal stem
+ * snap table
+ *
+ * <Input>
+ * table :: the horizontal stem hints table
+ * hints :: the current size's hint structure
+ * blueShift :: the value of the /BlueShift as taken from the
+ * face object.
+ * scale :: the 16.16 scale used to convert outline
+ * units to 26.6 pixels
+ *
+ * <Note>
+ * For now, all stems are hinted independently from each other.
+ * It might be necessary, for better performance, to introduce
+ * the notion of "controlled" hints describing things like
+ * counter-stems, stem3 as well as overlapping stems control.
+ *
+ ************************************************************************/
+
+ static
+ void t1_hint_horizontal_stems( T1_Stem_Table* table,
+ T1_Size_Hints* hints,
+ T1_Pos blueShift,
+ T1_Fixed scale )
+ {
+ T1_Stem_Hint* stem = table->stems;
+ T1_Stem_Hint* limit = stem + table->num_stems;
+
+ /* first of all, scale the blueShift */
+ blueShift = SCALE(blueShift);
+
+ /* then scan the horizontal stem table */
+ for ( ; stem < limit; stem++ )
+ {
+ T1_Pos bottom_orus = stem->min_edge.orus;
+ T1_Pos top_orus = stem->max_edge.orus;
+
+ T1_Pos top_pix = SCALE( top_orus );
+ T1_Pos bottom_pix = SCALE( bottom_orus );
+ T1_Pos width_pix = top_pix - bottom_pix;
+
+ T1_Pos bottom = bottom_pix;
+ T1_Pos top = top_pix;
+ T1_Int align = T1_ALIGN_NONE;
+
+ /******************************************************************/
+ /* Snap pixel width if in stem snap range */
+ {
+ T1_Snap_Zone* zone = hints->snap_heights;
+ T1_Snap_Zone* zone_limit = zone + hints->num_snap_heights;
+
+ for ( ; zone < zone_limit; zone++ )
+ {
+ if ( width_pix < zone->min )
+ break;
+
+ if ( width_pix <= zone->max )
+ {
+ width_pix = zone->pix;
+ break;
+ }
+ }
+ }
+
+ /******************************************************************/
+ /* round width - minimum 1 pixel if this isn't a ghost stem */
+ if ( width_pix > 0 )
+ width_pix = ( width_pix < ONE_PIXEL ? ONE_PIXEL : ROUND(width_pix) );
+
+
+ /******************************************************************/
+ /* Now check for bottom blue zones alignement */
+ {
+ T1_Int num_blues = hints->num_bottom_zones;
+ T1_Snap_Zone* blue = hints->blue_zones;
+ T1_Snap_Zone* blue_limit = blue + num_blues;
+
+ for ( ; blue < blue_limit; blue++ )
+ {
+ if ( bottom_pix < blue->min )
+ break;
+
+ if ( bottom_pix <= blue->max )
+ {
+ align = T1_ALIGN_BOTTOM;
+ bottom = ROUND( blue->pix );
+
+ /* implements blue shift */
+ if (!hints->supress_overshoots)
+ {
+ T1_Pos delta = blue->pix - bottom_pix;
+
+ delta = ( delta < blueShift ? 0 : ROUND( delta ) );
+ bottom -= delta;
+ }
+ }
+ }
+ }
+
+
+ /******************************************************************/
+ /* Check for top blue zones alignement */
+ {
+ T1_Int num_blues = hints->num_blue_zones -
+ hints->num_bottom_zones;
+
+ T1_Snap_Zone* blue = hints->blue_zones +
+ hints->num_bottom_zones;
+
+ T1_Snap_Zone* blue_limit = blue + num_blues;
+
+ for ( ; blue < blue_limit; blue++ )
+ {
+ if ( top_pix < blue->min )
+ break;
+
+ if ( top_pix <= blue->max )
+ {
+ align |= T1_ALIGN_TOP;
+ top = ROUND( blue->pix );
+
+ /* implements blue shift */
+ if (!hints->supress_overshoots)
+ {
+ T1_Pos delta = top - blue->pix;
+
+ delta = ( delta < blueShift ? 0 : ROUND( delta ) );
+ top += delta;
+ }
+ }
+ }
+ }
+
+
+ /******************************************************************/
+ /* compute the hinted stem position, according to its alignment */
+ switch (align)
+ {
+ case T1_ALIGN_BOTTOM: /* bottom zone alignement */
+ bottom_pix = bottom;
+ top_pix = bottom + width_pix;
+ break;
+
+ case T1_ALIGN_TOP: /* top zone alignement */
+ top_pix = top;
+ bottom_pix = top - width_pix;
+
+ break;
+
+ case T1_ALIGN_BOTH: /* bottom+top zone alignement */
+ bottom_pix = bottom;
+ top_pix = top;
+ break;
+
+ default: /* no alignement */
+
+ /* XXXX : TODO : Add management of controlled stems */
+ bottom = ( SCALE(bottom_orus+top_orus) - width_pix )/2;
+
+ bottom_pix = ROUND(bottom);
+ top_pix = bottom_pix + width_pix;
+ }
+
+ stem->min_edge.pix = bottom_pix;
+ stem->max_edge.pix = top_pix;
+ }
+ }
+
+
+
+
+/************************************************************************
+ *
+ * <Function>
+ * t1_hint_vertical_stems
+ *
+ * <Description>
+ * Compute the location of each scaled vertical stem hint.
+ * This takes care of the vertical stem snap table
+ *
+ * <Input>
+ * table :: the vertical stem hints table
+ * hints :: the current size's hint structure
+ * scale :: the 16.16 scale used to convert outline
+ * units to 26.6 pixels
+ *
+ * <Note>
+ * For now, all stems are hinted independently from each other.
+ * It might be necessary, for better performance, to introduce
+ * the notion of "controlled" hints describing things like
+ * counter-stems, stem3 as well as overlapping stems control.
+ *
+ ************************************************************************/
+
+ /* compute the location of each scaled vertical stem hint. */
+ /* Take care of blue zones and stem snap table */
+ static
+ void t1_hint_vertical_stems( T1_Stem_Table* table,
+ T1_Size_Hints* hints,
+ T1_Fixed scale )
+ {
+ T1_Stem_Hint* stem = table->stems;
+ T1_Stem_Hint* limit = stem + table->num_stems;
+
+ for ( ; stem < limit; stem++ )
+ {
+ T1_Pos stem_left = stem->min_edge.orus;
+ T1_Pos stem_right = stem->max_edge.orus;
+ T1_Pos width_pix, left;
+
+ width_pix = SCALE( stem_right - stem_left );
+
+ /* Snap pixel width if in stem snap range */
+ {
+ T1_Snap_Zone* zone = hints->snap_widths;
+ T1_Snap_Zone* zone_limit = zone + hints->num_snap_widths;
+
+ for ( ; zone < zone_limit; zone++ )
+ {
+ if ( width_pix < zone->min )
+ break;
+
+ if ( width_pix <= zone->max )
+ {
+ width_pix = zone->pix;
+ break;
+ }
+ }
+ }
+
+ /* round width - minimum 1 pixel if this isn't a ghost stem */
+ if ( width_pix > 0 )
+ width_pix = ( width_pix < ONE_PIXEL ? ONE_PIXEL :
+ ROUND( width_pix ) );
+
+ /* now place the snapped and rounded stem */
+
+ /* XXXX : TODO : implement controlled stems for the overlapping */
+ /* cases.. */
+
+ left = ( SCALE(stem_left+stem_right) - width_pix )/2;
+
+ stem->min_edge.pix = ROUND(left);
+ stem->max_edge.pix = stem->min_edge.pix + width_pix;
+ }
+ }
+
+
+
+
+/************************************************************************
+ *
+ * <Function>
+ * t1_hint_point
+ *
+ * <Description>
+ * Grid-fit a coordinate with regards to a given stem hints table
+ *
+ * <Input>
+ * table :: the source stem hints table
+ * coord :: original coordinate, expressed in font units
+ * scale :: the 16.16 scale used to convert font units into
+ * 26.6 pixels
+ *
+ * <Return>
+ * the hinted/scaled value in 26.6 pixels
+ *
+ * <Note>
+ * For now, all stems are hinted independently from each other.
+ * It might be necessary, for better performance, to introduce
+ * the notion of "controlled" hints describing things like
+ * counter-stems, stem3 as well as overlapping stems control.
+ *
+ ************************************************************************/
+
+ static
+ T1_Pos t1_hint_point( T1_Stem_Table* table,
+ T1_Pos coord,
+ T1_Fixed scale )
+ {
+ T1_Int num_active = table->num_active;
+ T1_Int n;
+ T1_Stem_Hint* prev = 0;
+ T1_Stem_Hint* cur = 0;
+ T1_Edge* min;
+ T1_Edge* max;
+ T1_Pos delta;
+
+ /* only hint when there is at least one stem defined */
+ if (num_active <= 0)
+ return SCALE(coord);
+
+ /* scan the stem table to determine placement of coordinate */
+ /* relative to the list of sorted and stems */
+ for ( n = 0; n < num_active; n++, prev = cur )
+ {
+ cur = table->stems + table->sort[n];
+
+ /* is it on the left of the current edge ? */
+ delta = cur->min_edge.orus - coord;
+ if ( delta == 0 ) return cur->min_edge.pix;
+
+ if (delta > 0)
+ {
+ /* if this is the left of the first edge, simply shift */
+ if (!prev) return cur->min_edge.pix - SCALE(delta);
+
+ /* otherwise, interpolate between the maximum of the */
+ /* previous stem, and the minimum of the current one */
+ min = &prev->max_edge;
+ max = &cur->min_edge;
+ goto Interpolate;
+ }
+
+ /* is it within the current edge ? */
+ delta = cur->max_edge.orus - coord;
+ if ( delta == 0 ) return cur->max_edge.pix;
+
+ if (delta > 0)
+ {
+ /* interpolate within the stem */
+ min = &cur->min_edge;
+ max = &cur->max_edge;
+ goto Interpolate;
+ }
+ }
+
+ /* apparently, this coordinate is on the right of the last stem */
+ delta = coord - cur->max_edge.orus;
+ return cur->max_edge.pix + SCALE(delta);
+
+ Interpolate:
+ return min->pix +
+ FT_MulDiv( coord - min->orus,
+ max->pix - min->pix,
+ max->orus - min->orus );
+ }
+
+
+
+
+
+
+#if 1
+
+/************************************************************************
+ *
+ * <Function>
+ * T1_Hint_Points
+ *
+ * <Description>
+ * this function grid-fits several points in a given Type 1 builder
+ * at once.
+ *
+ * <Input>
+ * builder :: handle to target Type 1 builder
+ * first :: first point to hint in builder's current outline
+ * last :: last point to hint in builder's current outline
+ *
+ ************************************************************************/
+
+ LOCAL_FUNC
+ void T1_Hint_Points( T1_Builder* builder )
+ {
+ T1_Int first = builder->hint_point;
+ T1_Int last = builder->current.n_points-1;
+
+ T1_Size size = builder->size;
+ T1_Fixed scale_x = size->root.metrics.x_scale;
+ T1_Fixed scale_y = size->root.metrics.y_scale;
+
+ T1_Glyph_Hints* hints = builder->glyph->hints;
+ T1_Stem_Table* hori_stems = &hints->hori_stems;
+ T1_Stem_Table* vert_stems = &hints->vert_stems;
+
+ T1_Vector* cur = builder->current.points + first;
+ T1_Vector* limit = cur + last - first + 1;
+
+ /* first of all, sort the active stem hints */
+ t1_sort_hints( hori_stems );
+ t1_sort_hints( vert_stems );
+
+ for ( ; cur < limit; cur++ )
+ {
+ cur->x = t1_hint_point( vert_stems, cur->x, scale_x );
+ cur->y = t1_hint_point( hori_stems, cur->y, scale_y );
+ }
+
+ builder->hint_point = builder->current.n_points;
+ }
+
+
+/************************************************************************
+ *
+ * <Function>
+ * T1_Hint_Stems
+ *
+ * <Description>
+ * This function is used to compute the location of each stem hint
+ * between the first and second passes of the glyph loader on the
+ * charstring.
+ *
+ * <Input>
+ * builder :: handle to target builder
+ *
+ ************************************************************************/
+
+ LOCAL_FUNC
+ void T1_Hint_Stems( T1_Builder* builder )
+ {
+ T1_Glyph_Hints* hints = builder->glyph->hints;
+ T1_Private* priv = &builder->face->private_dict;
+
+ T1_Size size = builder->size;
+ T1_Fixed scale_x = size->root.metrics.x_scale;
+ T1_Fixed scale_y = size->root.metrics.y_scale;
+
+ t1_hint_horizontal_stems( &hints->hori_stems,
+ builder->size->hints,
+ priv->blue_shift,
+ scale_y );
+
+ t1_hint_vertical_stems( &hints->vert_stems,
+ builder->size->hints,
+ scale_x );
+ }
+
+#endif
--- /dev/null
+++ b/src/type1/t1hinter.h
@@ -1,0 +1,380 @@
+/*******************************************************************
+ *
+ * t1hinter.h 1.2
+ *
+ * Type1 hinter.
+ *
+ * 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 Hinter is in charge of fitting th scaled outline to the
+ * pixel grid in order to considerably improve the quality of
+ * the Type 1 font driver's output..
+ *
+ ******************************************************************/
+
+#ifndef T1HINTER_H
+#define T1HINTER_H
+
+#include <t1objs.h>
+#include <t1gload.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/************************************************************************
+ *
+ * <Struct>
+ * T1_Snap_Zone
+ *
+ * <Description>
+ * A "snap zone" is used to model either a blue zone or a stem width
+ * at a given character size. It is made of a minimum and maximum
+ * edge, defined in 26.6 pixels, as well as one "original" and
+ * "scaled" position.
+ *
+ * the position corresponds to the stem width (for stem snap zones)
+ * or to the blue position (for blue zones)
+ *
+ * <Fields>
+ * orus :: original position in font units
+ * pix :: current position in sub-pixel units
+ * min :: minimum boundary in sub-pixel units
+ * max :: maximim boundary in sub-pixel units
+ *
+ ************************************************************************/
+
+ typedef struct T1_Snap_Zone_
+ {
+ T1_Pos orus;
+ T1_Pos pix;
+ T1_Pos min;
+ T1_Pos max;
+
+ } T1_Snap_Zone;
+
+
+/************************************************************************
+ *
+ * <Struct>
+ * T1_Edge
+ *
+ * <Description>
+ * A very simply structure used to model an stem edge
+ *
+ * <Fields>
+ * orus :: original edge position in font units
+ * pix :: scaled edge position in sub-pixel units
+ *
+ ************************************************************************/
+
+ typedef struct T1_Edge_
+ {
+ T1_Pos orus;
+ T1_Pos pix;
+
+ } T1_Edge;
+
+
+/************************************************************************
+ *
+ * <Struct>
+ * T1_Stem_Hint
+ *
+ * <Description>
+ * A simple structure used to model a stem hint
+ *
+ * <Fields>
+ * min_edge :: the hint's minimum edge
+ * max_edge :: the hint's maximum edge
+ * hint_flags :: some flags describing the stem properties
+ *
+ * <Note>
+ * the min and max edges of a ghost stem have the same position,
+ * even if they're coded in a weird way in the charstrings
+ *
+ ************************************************************************/
+
+ typedef struct T1_Stem_Hint_
+ {
+ T1_Edge min_edge;
+ T1_Edge max_edge;
+ T1_Int hint_flags;
+
+ } T1_Stem_Hint;
+
+
+#define T1_HINT_FLAG_ACTIVE 1 /* indicates an active stem */
+#define T1_HINT_FLAG_MIN_BORDER 2 /* unused for now.. */
+#define T1_HINT_FLAG_MAX_BORDER 4 /* unused for now.. */
+
+
+/* hinter's configuration constants */
+#define T1_HINTER_MAX_BLUES 24 /* maximum number of blue zones */
+#define T1_HINTER_MAX_SNAPS 16 /* maximum number of stem snap zones */
+#define T1_HINTER_MAX_EDGES 64 /* maximum number of stem hints */
+
+
+/************************************************************************
+ *
+ * <Struct>
+ * T1_Size_Hints
+ *
+ * <Description>
+ * A structure used to model the hinting information related to
+ * a size object
+ *
+ * <Fields>
+ * supress_overshoots :: a boolean flag to tell when overshoot
+ * supression should occur.
+ *
+ * num_blue_zones :: the total number of blue zones (top+bottom)
+ * num_bottom_zones :: the number of bottom zones
+ *
+ * blue_zones :: the blue zones table. bottom zones are
+ * stored first in the table, followed by
+ * all top zones
+ *
+ * num_stem_snapH :: number of horizontal stem snap zones
+ * stem_snapH :: horizontal stem snap zones
+ *
+ * num_stem_snapV :: number of vertical stem snap zones
+ * stem_snapV :: vertical stem snap zones
+ *
+ ************************************************************************/
+
+ struct T1_Size_Hints_
+ {
+ T1_Bool supress_overshoots;
+
+ T1_Int num_blue_zones;
+ T1_Int num_bottom_zones;
+ T1_Snap_Zone blue_zones[ T1_HINTER_MAX_BLUES ];
+
+ T1_Int num_snap_widths;
+ T1_Snap_Zone snap_widths[ T1_HINTER_MAX_SNAPS ];
+
+ T1_Int num_snap_heights;
+ T1_Snap_Zone snap_heights[ T1_HINTER_MAX_SNAPS ];
+ };
+
+
+
+/************************************************************************
+ *
+ * <Struct>
+ * T1_Stem_Table
+ *
+ * <Description>
+ * A simple structure used to model a set of stem hints in a
+ * single direction during the loading of a given glyph outline.
+ * Not all stem hints are active at a time. Moreover, stems must
+ * be sorted regularly
+ *
+ * <Fields>
+ * num_stems :: total number of stems in table
+ * num_active :: number of active stems in table
+ *
+ * stems :: the table of all stems
+ * sort :: a table of indices into the stems table, used
+ * to keep a sorted list of the active stems
+ *
+ ************************************************************************/
+
+ typedef struct T1_Stem_Table_
+ {
+ T1_Int num_stems;
+ T1_Int num_active;
+
+ T1_Stem_Hint stems[ T1_HINTER_MAX_EDGES ];
+ T1_Int sort [ T1_HINTER_MAX_EDGES ];
+
+ } T1_Stem_Table;
+
+
+
+/************************************************************************
+ *
+ * <Struct>
+ * T1_Glyph_Hints
+ *
+ * <Description>
+ * A structure used to model the stem hints of a given glyph outline
+ * during glyph loading.
+ *
+ * <Fields>
+ * hori_stems :: horizontal stem hints table
+ * vert_stems :: vertical stem hints table
+ *
+ ************************************************************************/
+
+ struct T1_Glyph_Hints_
+ {
+ T1_Stem_Table hori_stems;
+ T1_Stem_Table vert_stems;
+ };
+
+
+
+/************************************************************************
+ *
+ * <Data>
+ * t1_hinter_funcs
+ *
+ * <Description>
+ * A table containing the address of various functions used during
+ * the loading of an hinted scaled outline
+ *
+ ************************************************************************/
+
+ LOCAL_DEF
+ const T1_Hinter_Funcs t1_hinter_funcs;
+
+
+/************************************************************************
+ *
+ * <Function>
+ * T1_New_Size_Hinter
+ *
+ * <Description>
+ * Allocates a new hinter structure for a given size object
+ *
+ * <Input>
+ * size :: handle to target size object
+ *
+ * <Return>
+ * Error code. 0 means success
+ *
+ ************************************************************************/
+
+ LOCAL_DEF
+ T1_Error T1_New_Size_Hinter( T1_Size size );
+
+
+/************************************************************************
+ *
+ * <Function>
+ * T1_Done_Size_Hinter
+ *
+ * <Description>
+ * Releases a given size object's hinter structure
+ *
+ * <Input>
+ * size :: handle to target size object
+ *
+ ************************************************************************/
+
+ LOCAL_DEF
+ void T1_Done_Size_Hinter( T1_Size size );
+
+
+/************************************************************************
+ *
+ * <Function>
+ * T1_Reset_Size_Hinter
+ *
+ * <Description>
+ * Recomputes hinting information when a given size object has
+ * changed its resolutions/char sizes/pixel sizes
+ *
+ * <Input>
+ * size :: handle to size object
+ *
+ * <Return>
+ * Error code. 0 means success
+ *
+ ************************************************************************/
+
+ LOCAL_DEF
+ T1_Error T1_Reset_Size_Hinter( T1_Size size );
+
+
+/************************************************************************
+ *
+ * <Function>
+ * T1_New_Glyph_Hinter
+ *
+ * <Description>
+ * Allocates a new hinter structure for a given glyph slot
+ *
+ * <Input>
+ * glyph :: handle to target glyph slot
+ *
+ * <Return>
+ * Error code. 0 means success
+ *
+ ************************************************************************/
+
+ LOCAL_DEF
+ T1_Error T1_New_Glyph_Hinter( T1_GlyphSlot glyph );
+
+
+/************************************************************************
+ *
+ * <Function>
+ * T1_Done_Glyph_Hinter
+ *
+ * <Description>
+ * Releases a given glyph slot's hinter structure
+ *
+ * <Input>
+ * glyph :: handle to glyph slot
+ *
+ ************************************************************************/
+
+ LOCAL_DEF
+ void T1_Done_Glyph_Hinter( T1_GlyphSlot glyph );
+
+
+
+
+/************************************************************************
+ *
+ * <Function>
+ * T1_Hint_Points
+ *
+ * <Description>
+ * this function grid-fits several points in a given Type 1 builder
+ * at once.
+ *
+ * <Input>
+ * builder :: handle to target Type 1 builder
+ *
+ ************************************************************************/
+
+ LOCAL_DEF
+ void T1_Hint_Points( T1_Builder* builder );
+
+
+/************************************************************************
+ *
+ * <Function>
+ * T1_Hint_Stems
+ *
+ * <Description>
+ * This function is used to compute the location of each stem hint
+ * between the first and second passes of the glyph loader on the
+ * charstring.
+ *
+ * <Input>
+ * builder :: handle to target builder
+ *
+ ************************************************************************/
+
+ LOCAL_DEF
+ void T1_Hint_Stems( T1_Builder* builder );
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* T1HINTER_H */
--- /dev/null
+++ b/src/type1/t1load.c
@@ -1,0 +1,1458 @@
+#include <ftdebug.h>
+
+#include <t1types.h>
+#include <t1encode.h>
+#include <t1tokens.h>
+#include <t1config.h>
+#include <t1parse.h>
+
+#include <stdio.h>
+
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_t1load
+
+ typedef T1_Error (*T1_Parse_Func)( T1_Parser* parser );
+
+
+/*************************************************************************/
+/* */
+/* <Function> Init_T1_Parser */
+/* */
+/* <Description> */
+/* Initialise a given parser object to build a given T1_Face */
+/* */
+/* <Input> */
+/* parser :: handle to the newly built parser object */
+/* face :: handle to target T1 face object */
+/* */
+ LOCAL_FUNC
+ void Init_T1_Parser( T1_Parser* parser,
+ T1_Face face,
+ T1_Tokenizer tokenizer )
+ {
+ parser->error = 0;
+ parser->face = face;
+ parser->tokenizer = tokenizer;
+ parser->top = parser->stack;
+ parser->limit = parser->stack + T1_MAX_STACK_DEPTH;
+
+ parser->state_index = 0;
+ parser->state_stack[0] = dict_none;
+
+ parser->encoding_type = encoding_none;
+ parser->encoding_names = 0;
+ parser->encoding_offsets = 0;
+ parser->encoding_lengths = 0;
+
+ parser->dump_tokens = 0;
+ face->private_dict.lenIV = 4; /* XXX : is it sure ?? */
+ }
+
+
+
+/*************************************************************************/
+/* */
+/* <Function> Next_T1_Token */
+/* */
+/* <Description> */
+/* grabs the next significant token from a parser's input stream. */
+/* this function ignores a number of tokens, and translates */
+/* alternate forms into their common ones.. */
+/* */
+/* <Input> */
+/* parser :: handle to source parser */
+/* */
+/* <Output> */
+/* token :: the extracted token descriptor */
+/* */
+/* <Return> */
+/* Error code. 0 means success */
+/* */
+ LOCAL_FUNC
+ T1_Error Next_T1_Token( T1_Parser* parser,
+ T1_Token* token )
+ {
+ T1_Error error;
+ T1_Tokenizer tokzer = parser->tokenizer;
+
+ L1:
+ error = Read_Token( tokzer );
+ if (error) return error;
+
+ /* We now must ignore a number of tokens like "dup", "executeonly", */
+ /* "readonly", etc... */
+ *token = tokzer->token;
+ if ( token->kind == tok_keyword )
+ switch( token->kind2 )
+ {
+ case key_dup:
+ case key_execonly:
+ case key_readonly:
+ case key_noaccess:
+ case key_userdict:
+ /* do nothing - loop */
+ goto L1;
+
+ /* We also translate some other keywords from their alternative */
+ /* to their "normal" form.. */
+
+ case key_NP_alternate:
+ token->kind2 = key_NP;
+ break;
+
+ case key_RD_alternate:
+ token->kind2 = key_RD;
+ break;
+
+ case key_ND_alternate:
+ token->kind2 = key_ND;
+ break;
+
+ default:
+ ;
+ }
+
+ /* Dump the token when requested. This feature is only available */
+ /* in the 'error' and 'trace' debug levels.. */
+#if defined( FT_DEBUG_LEVEL_ERROR ) || defined( FT_DEBUG_LEVEL_TRACE )
+ if ( parser->dump_tokens )
+ {
+ T1_String temp_string[128];
+ T1_Int len;
+
+ len = token->len;
+ if ( len > 127 ) len = 127;
+ strncpy( temp_string,
+ (T1_String*)tokzer->base + token->start,
+ len );
+ temp_string[len] = '\0';
+ FT_ERROR(( "%s\n", temp_string ));
+ }
+#endif
+
+ return T1_Err_Ok;
+ }
+
+
+
+ static
+ T1_Error Expect_Keyword( T1_Parser* parser,
+ T1_TokenType keyword )
+ {
+ T1_Token token;
+ T1_Error error;
+
+ error = Next_T1_Token( parser, &token );
+ if (error) goto Exit;
+
+ if ( token.kind != tok_keyword ||
+ token.kind2 != keyword )
+ {
+ error = T1_Err_Syntax_Error;
+ FT_ERROR(( "T1.Parse: keyword '%s' expected.\n",
+ t1_keywords[ keyword - key_first_ ] ));
+ }
+
+ Exit:
+ return error;
+ }
+
+
+
+ static
+ T1_Error Expect_Keyword2( T1_Parser* parser,
+ T1_TokenType keyword1,
+ T1_TokenType keyword2 )
+ {
+ T1_Token token;
+ T1_Error error;
+
+ error = Next_T1_Token( parser, &token );
+ if (error) goto Exit;
+
+ if ( token.kind != tok_keyword ||
+ ( token.kind2 != keyword1 &&
+ token.kind2 != keyword2 ) )
+ {
+ error = T1_Err_Syntax_Error;
+ FT_ERROR(( "T1.Parse: keyword '%s' or '%s' expected.\n",
+ t1_keywords[ keyword1 - key_first_ ],
+ t1_keywords[ keyword2 - key_first_ ] ));
+ }
+
+ Exit:
+ return error;
+ }
+
+
+
+ static
+ void Parse_Encoding( T1_Parser* parser )
+ {
+ T1_Token* token = parser->top+1;
+ FT_Memory memory = parser->face->root.memory;
+ T1_Encoding* encode = &parser->face->encoding;
+ T1_Error error = 0;
+
+ if (token->kind == tok_keyword &&
+ (token->kind2 == key_StandardEncoding ||
+ token->kind2 == key_ExpertEncoding ) )
+ {
+ encode->num_chars = 256;
+ encode->code_first = 32;
+ encode->code_last = 255;
+
+ if ( ALLOC_ARRAY( encode->char_index, 256, T1_Short ) )
+ goto Exit;
+
+ encode->char_name = 0; /* no need to store glyph names */
+
+ /* Now copy the encoding */
+ switch (token->kind2)
+ {
+ case key_ExpertEncoding : parser->encoding_type = encoding_expert;
+ default : parser->encoding_type = encoding_standard; break;
+ }
+ }
+ else
+ {
+ FT_ERROR(( "T1.Parse_Encoding: invalid encoding type\n" ));
+ error = T1_Err_Syntax_Error;
+ }
+
+ Exit:
+ parser->error = error;
+ }
+
+
+
+
+
+
+
+ /**********************************************************************/
+ /* */
+ /* */
+ /* IMPLEMENTATION OF THE "DEF" KEYWORD DEPENDING ON */
+ /* CURRENT DICTIONARY STATE */
+ /* */
+ /* */
+ /**********************************************************************/
+
+
+/**************************************************************************/
+/* */
+/* <Function> Do_Def_Font */
+/* */
+/* <Description> */
+/* This function performs a 'def' when in the Font dictionary */
+/* Its purpose is to build the T1_Face attributes directly from */
+/* the stream.. */
+/* */
+/* <Input> */
+/* parser :: handle to current parser. */
+/* */
+/* <Return> */
+/* Error code. 0 means success */
+/* */
+ static
+ T1_Error Do_Def_Font( T1_Parser* parser )
+ {
+ T1_Token* top = parser->top;
+ T1_Face face = parser->face;
+
+ switch ( top[0].kind2 )
+ {
+ case imm_FontName:
+ /* in some cases, the /FontName is an immediate like */
+ /* /TimesNewRoman. In this case, we simply copy the */
+ /* token string (without the /).. */
+ if (top[1].kind == tok_immediate)
+ {
+ FT_Memory memory = parser->tokenizer->memory;
+ T1_Error error;
+ T1_Int len = top[1].len;
+
+ if ( ALLOC( face->font_name, len+1 ) )
+ {
+ parser->error = error;
+ return error;
+ }
+
+ MEM_Copy( face->font_name,
+ parser->tokenizer->base + top[1].start,
+ len );
+ face->font_name[len] = '\0';
+ }
+ else
+ face->font_name = CopyString( parser );
+ break;
+
+ case imm_Encoding:
+ Parse_Encoding( parser );
+ break;
+
+ case imm_PaintType:
+ face->paint_type = (T1_Byte)CopyInteger( parser );
+ break;
+
+ case imm_FontType:
+ face->font_type = (T1_Byte)CopyInteger( parser );
+ break;
+
+ case imm_FontMatrix:
+ CopyMatrix( parser, &face->font_matrix );
+ break;
+
+ case imm_FontBBox:
+ CopyBBox( parser, &face->font_bbox );
+ break;
+
+ case imm_UniqueID:
+ face->unique_id = CopyInteger( parser );
+ break;
+
+ case imm_StrokeWidth:
+ face->stroke_width = CopyInteger( parser );
+ break;
+
+ case imm_FontID:
+ face->font_id = CopyInteger( parser );
+ break;
+
+ default:
+ /* ignore all other things */
+ parser->error = T1_Err_Ok;
+ }
+ return parser->error;
+ }
+
+
+
+/**************************************************************************/
+/* */
+/* <Function> Do_Def_FontInfo */
+/* */
+/* <Description> */
+/* This function performs a 'def' when in the FontInfo dictionary */
+/* Its purpose is to build the T1_FontInfo structure directly from */
+/* the stream.. */
+/* */
+/* <Input> */
+/* parser :: handle to current parser. */
+/* */
+/* <Return> */
+/* Error code. 0 means success */
+/* */
+ static
+ T1_Error Do_Def_FontInfo( T1_Parser* parser )
+ {
+ T1_Token* top = parser->top;
+ T1_FontInfo* info = &parser->face->font_info;
+
+ switch ( top[0].kind2 )
+ {
+ case imm_version:
+ info->version = CopyString( parser );
+ break;
+
+ case imm_Notice:
+ info->notice = CopyString( parser );
+ break;
+
+ case imm_FullName:
+ info->full_name = CopyString( parser );
+ break;
+
+ case imm_FamilyName:
+ info->family_name = CopyString( parser );
+ break;
+
+ case imm_Weight:
+ info->weight = CopyString( parser );
+ break;
+
+ case imm_ItalicAngle:
+ info->italic_angle = CopyInteger( parser );
+ break;
+
+ case imm_isFixedPitch:
+ info->is_fixed_pitch = CopyBoolean( parser );
+ break;
+
+ case imm_UnderlinePosition:
+ info->underline_position = (T1_Short)CopyInteger( parser );
+ break;
+
+ case imm_UnderlineThickness:
+ info->underline_thickness = (T1_Short)CopyInteger( parser );
+ break;
+
+ default:
+ /* ignore all other things */
+ parser->error = T1_Err_Ok;
+ }
+ return parser->error;
+ }
+
+
+
+/**************************************************************************/
+/* */
+/* <Function> Do_Def_Private */
+/* */
+/* <Description> */
+/* This function performs a 'def' when in the Private dictionary */
+/* Its purpose is to build the T1_Private structure directly from */
+/* the stream.. */
+/* */
+/* <Input> */
+/* parser :: handle to current parser. */
+/* */
+/* <Return> */
+/* Error code. 0 means success */
+/* */
+ static
+ T1_Error Do_Def_Private( T1_Parser* parser )
+ {
+ T1_Token* top = parser->top;
+ T1_Private* priv = &parser->face->private_dict;
+
+ switch ( top[0].kind2 )
+ {
+ case imm_RD: case imm_RD_alternate: /* Ignore the definitions */
+ case imm_ND: case imm_ND_alternate: /* of RD, NP, ND and their */
+ case imm_NP: case imm_NP_alternate: /* alternate forms ... */
+ parser->error = T1_Err_Ok;
+ break;
+
+
+ case imm_BlueValues:
+ CopyArray( parser, &priv->num_blues,
+ priv->blue_values, 14 );
+ break;
+
+
+ case imm_OtherBlues:
+ CopyArray( parser, &priv->num_other_blues,
+ priv->other_blues, 10 );
+ break;
+
+
+ case imm_FamilyBlues:
+ CopyArray( parser, &priv->num_family_blues,
+ priv->family_blues, 14 );
+ break;
+
+
+ case imm_FamilyOtherBlues:
+ CopyArray( parser, &priv->num_family_other_blues,
+ priv->family_other_blues, 10 );
+ break;
+
+
+ case imm_BlueScale:
+ priv->blue_scale = CopyFloat( parser, 0x10000 );
+ break;
+
+
+ case imm_BlueShift:
+ priv->blue_shift = CopyInteger( parser );
+ break;
+
+
+ case imm_BlueFuzz:
+ priv->blue_fuzz = CopyInteger( parser );
+ break;
+
+
+ case imm_StdHW:
+ CopyArray( parser, 0, (T1_Short*)&priv->standard_width, 1 );
+ break;
+
+
+ case imm_StdVW:
+ CopyArray( parser, 0, (T1_Short*)&priv->standard_height, 1 );
+ break;
+
+
+ case imm_StemSnapH:
+ CopyArray( parser, &priv->num_snap_widths,
+ priv->stem_snap_widths, 12 );
+ break;
+
+
+ case imm_StemSnapV:
+ CopyArray( parser, &priv->num_snap_heights,
+ priv->stem_snap_heights, 12 );
+ break;
+
+
+ case imm_ForceBold:
+ priv->force_bold = CopyBoolean( parser );
+ break;
+
+
+ case imm_LanguageGroup:
+ priv->language_group = CopyInteger( parser );
+ break;
+
+
+ case imm_password:
+ priv->password = CopyInteger( parser );
+ break;
+
+
+ case imm_UniqueID:
+ priv->unique_id = CopyInteger( parser );
+ break;
+
+
+ case imm_lenIV:
+ priv->lenIV = CopyInteger( parser );
+ break;
+
+
+ case imm_MinFeature:
+ CopyArray( parser, 0, priv->min_feature, 2 );
+ break;
+
+
+ default:
+ /* ignore all other things */
+ parser->error = T1_Err_Ok;
+ }
+ return parser->error;
+ }
+
+
+
+/**************************************************************************/
+/* */
+/* <Function> Do_Def_Error */
+/* */
+/* <Description> */
+/* This function returns a simple syntax error when invoked. It is */
+/* ued for the "def" keyword when in the "encoding", "subrs", */
+/* "othersubrs" and "charstrings" dictionary states.. */
+/* */
+/* <Input> */
+/* parser :: handle to current parser. */
+/* */
+/* <Return> */
+/* Error code. 0 means success */
+/* */
+ static
+ T1_Error Do_Def_Error( T1_Parser* parser )
+ {
+ FT_ERROR(( "T1.Load : 'def' keyword encountered in bad dictionary/array\n" ));
+ parser->error = T1_Err_Syntax_Error;
+ return parser->error;
+ }
+
+
+ static
+ T1_Error Do_Def_Ignore( T1_Parser* parser )
+ {
+ (void)parser;
+ return T1_Err_Ok;
+ }
+
+ static
+ T1_Parse_Func def_funcs[ dict_max ] =
+ {
+ Do_Def_Error,
+ Do_Def_Font,
+ Do_Def_FontInfo,
+ Do_Def_Ignore,
+ Do_Def_Private,
+ Do_Def_Ignore,
+ Do_Def_Ignore,
+ Do_Def_Ignore,
+ Do_Def_Ignore,
+ Do_Def_Ignore,
+ Do_Def_Ignore,
+ };
+
+
+ /**********************************************************************/
+ /* */
+ /* */
+ /* IMPLEMENTATION OF THE "PUT" KEYWORD DEPENDING ON */
+ /* CURRENT DICTIONARY STATE */
+ /* */
+ /* */
+ /**********************************************************************/
+
+/**************************************************************************/
+/* */
+/* <Function> Do_Put_Encoding */
+/* */
+/* <Description> */
+/* This function performs a 'put' when in the Encoding array */
+/* The glyph name is copied into the T1 recorder, and the charcode */
+/* and glyph name pointer are written into the face object encoding */
+/* */
+/* <Input> */
+/* parser :: handle to current parser. */
+/* */
+/* <Return> */
+/* Error code. 0 means success */
+/* */
+ static
+ T1_Error Do_Put_Encoding( T1_Parser* parser )
+ {
+ T1_Error error = T1_Err_Ok;
+ T1_Face face = parser->face;
+ T1_Token* top = parser->top;
+ T1_Encoding* encode = &face->encoding;
+ T1_Int index;
+
+ /* record and check the character code */
+ if ( top[0].kind != tok_number )
+ {
+ FT_TRACE4(( "T1.Parse.put: number expected\n" ));
+ goto Syntax_Error;
+ }
+ index = (T1_Int)CopyInteger( parser );
+ if (parser->error) return parser->error;
+
+ if ( index < 0 || index >= encode->num_chars )
+ {
+ FT_TRACE4(( "T1.Parse.put: invalid character code\n" ));
+ goto Syntax_Error;
+ }
+
+ /* record the immediate name */
+ if ( top[1].kind != tok_immediate )
+ {
+ FT_TRACE4(( "T1.Parse.put: immediate name expected\n" ));
+ goto Syntax_Error;
+ }
+
+ /* if the glyph name is '.notdef', store a NULL char name */
+ /* otherwise, record the glyph name.. */
+ if ( top[1].kind == imm_notdef )
+ {
+ parser->table.elements[ index ] = 0;
+ parser->table.lengths [ index ] = 0;
+ }
+ else
+ {
+ T1_String temp_name[128];
+ T1_Token* token = top+1;
+ T1_Int len = token->len-1;
+
+ /* copy immediate name */
+ if (len > 127) len = 127;
+ MEM_Copy( temp_name, parser->tokenizer->base + token->start+1, len );
+ temp_name[len] = '\0';
+
+ error = T1_Add_Table( &parser->table, index, (T1_Byte*)temp_name, len+1 );
+
+ /* adjust code_first and code_last */
+ if ( index < encode->code_first ) encode->code_first = index;
+ if ( index > encode->code_last ) encode->code_last = index;
+ }
+ return error;
+
+ Syntax_Error:
+ /* ignore the error, and simply clear the stack */
+ FT_TRACE4(( "T1.Put.Encoding: invalid syntax encountered\n" ));
+ parser->top = parser->stack;
+ return T1_Err_Ok;
+ }
+
+ /**********************************************************************/
+ /* */
+ /* */
+ /* IMPLEMENTATION OF THE "RD" KEYWORD DEPENDING ON */
+ /* CURRENT DICTIONARY STATE */
+ /* */
+ /* */
+ /**********************************************************************/
+
+/**************************************************************************/
+/* */
+/* <Function> Do_RD_Subrs */
+/* */
+/* <Description> */
+/* This function performs a 'RD' when in the Subrs dictionary */
+/* It simply records the array of bytecodes/charstrings corresponding */
+/* to the sub-routine.. */
+/* */
+/* <Input> */
+/* parser :: handle to current parser. */
+/* */
+/* <Return> */
+/* Error code. 0 means success */
+/* */
+ static
+ T1_Error Do_RD_Subrs( T1_Parser* parser )
+ {
+ T1_Error error = T1_Err_Ok;
+ T1_Face face = parser->face;
+ T1_Token* top = parser->top;
+ T1_Tokenizer tokzer = parser->tokenizer;
+ T1_Int index, count;
+
+ /* record and check the character code */
+ if ( top[0].kind != tok_number ||
+ top[1].kind != tok_number )
+ {
+ FT_ERROR(( "T1.Parse.put: number expected\n" ));
+ goto Syntax_Error;
+ }
+ index = (T1_Int)CopyInteger( parser );
+ error = parser->error; if (error) goto Exit;
+
+ count = (T1_Int)CopyInteger( parser );
+ error = parser->error; if (error) goto Exit;
+
+ if ( index < 0 || index >= face->num_subrs )
+ {
+ FT_ERROR(( "T1.Parse.put: invalid character code\n" ));
+ goto Syntax_Error;
+ }
+
+ /* decrypt charstring and skip them */
+ {
+ T1_Byte* base = tokzer->base + tokzer->cursor;
+
+ t1_decrypt( base, count, 4330 );
+ tokzer->cursor += count;
+
+ base += face->private_dict.lenIV;
+ count -= face->private_dict.lenIV;
+
+ error = T1_Add_Table( &parser->table, index, base, count );
+ }
+
+ /* consume the closing NP or 'put' */
+ error = Expect_Keyword2( parser, key_NP, key_put );
+
+ Exit:
+ return error;
+
+ Syntax_Error:
+ return T1_Err_Syntax_Error;
+ }
+
+
+/**************************************************************************/
+/* */
+/* <Function> Do_RD_CharStrings */
+/* */
+/* <Description> */
+/* This function performs a 'RD' when in the CharStrings dictionary */
+/* It simply records the array of bytecodes/charstrings corresponding */
+/* to the glyph program string. */
+/* */
+/* <Input> */
+/* parser :: handle to current parser. */
+/* */
+/* <Return> */
+/* Error code. 0 means success */
+/* */
+ static
+ T1_Error Do_RD_Charstrings( T1_Parser* parser )
+ {
+ T1_Error error = T1_Err_Ok;
+ T1_Face face = parser->face;
+ T1_Token* top = parser->top;
+ T1_Tokenizer tokzer = parser->tokenizer;
+ T1_Int index, count;
+
+ /* check the character name argument */
+ if ( top[0].kind != tok_immediate )
+ {
+ FT_ERROR(( "T1.Parse.RD: immediate character name expected\n" ));
+ goto Syntax_Error;
+ }
+
+ /* check the count argument */
+ if ( top[1].kind != tok_number )
+ {
+ FT_ERROR(( "T1.Parse.put: number expected\n" ));
+ goto Syntax_Error;
+ }
+ parser->args++;
+ count = (T1_Int)CopyInteger( parser );
+ error = parser->error; if (error) goto Exit;
+
+ /* record the glyph name and get the corresponding glyph index */
+ if ( top[0].kind2 == imm_notdef )
+ index = 0;
+ else
+ {
+ T1_String temp_name[128];
+ T1_Token* token = top;
+ T1_Int len = token->len-1;
+
+ /* copy immediate name */
+ if (len > 127) len = 127;
+ MEM_Copy( temp_name, parser->tokenizer->base + token->start+1, len );
+ temp_name[len] = '\0';
+
+ index = parser->cur_name++;
+ error = T1_Add_Table( &parser->table, index*2, (T1_Byte*)temp_name, len+1 );
+ if (error) goto Exit;
+ }
+
+ /* decrypt and record charstring, then skip them */
+ {
+ T1_Byte* base = tokzer->base + tokzer->cursor;
+
+ t1_decrypt( base, count, 4330 );
+ tokzer->cursor += count; /* skip */
+
+ base += face->private_dict.lenIV;
+ count -= face->private_dict.lenIV;
+
+ error = T1_Add_Table( &parser->table, index*2+1, base, count );
+ }
+
+ /* consume the closing ND */
+ if (!error)
+ error = Expect_Keyword( parser, key_ND );
+
+ Exit:
+ return error;
+
+ Syntax_Error:
+ return T1_Err_Syntax_Error;
+ }
+
+
+
+
+
+
+ static
+ T1_Error Expect_Dict_Arguments( T1_Parser* parser,
+ T1_Int num_args,
+ T1_TokenType immediate,
+ T1_DictState new_state,
+ T1_Int *count )
+ {
+ /* check that we have enough arguments in the stack, including */
+ /* the 'dict' keyword.. */
+ if ( parser->top - parser->stack < num_args )
+ {
+ FT_ERROR(( "T1.Parse.Dict : expecting at least %d arguments",
+ num_args ));
+ goto Syntax_Error;
+ }
+
+ /* check that we have the correct immediate, if needed */
+ if ( num_args == 2 )
+ {
+ if ( parser->top[-2].kind != tok_immediate ||
+ parser->top[-2].kind2 != immediate )
+ {
+ FT_ERROR(( "T1.Parse.Dict : expecting '/%s' dictionary\n",
+ t1_immediates[ immediate - imm_first_ ] ));
+ goto Syntax_Error;
+ }
+ }
+
+ parser->args = parser->top-1;
+
+ /* check that the count argument is a number */
+ if ( parser->args->kind != tok_number )
+ {
+ FT_ERROR(( "T1.Parse.Dict : expecting numerical count argument for 'dict'\n" ));
+ goto Syntax_Error;
+ }
+ if (count)
+ {
+ *count = CopyInteger( parser );
+ if (parser->error) return parser->error;
+ }
+
+ /* save the dictionary state */
+ parser->state_stack[ ++parser->state_index ] = new_state;
+
+ /* consume the 'begin' keyword, and clear the stack */
+ parser->top -= num_args;
+ return Expect_Keyword( parser, key_begin );
+
+ Syntax_Error:
+ return T1_Err_Syntax_Error;
+ }
+
+
+
+
+
+ static
+ T1_Error Expect_Array_Arguments( T1_Parser* parser )
+ {
+ T1_Token* top = parser->top;
+ T1_Error error = T1_Err_Ok;
+ T1_DictState new_state;
+ T1_Int count;
+ T1_Face face = parser->face;
+ FT_Memory memory = face->root.memory;
+
+ /* Check arguments format */
+ if ( top - parser->stack < 2 )
+ {
+ FT_ERROR(( "T1.Parse.array: two arguments expected\n" ));
+ error = T1_Err_Stack_Underflow;
+ goto Exit;
+ }
+
+ parser->top -= 2;
+ top -= 2;
+ parser->args = top + 1;
+
+ if ( top[0].kind != tok_immediate )
+ {
+ FT_ERROR(( "T1.Parse.array: first argument must be an immediate name\n" ));
+ goto Syntax_Error;
+ }
+
+ if ( top[1].kind != tok_number )
+ {
+ FT_ERROR(( "T1.Parse.array: second argument must be a number\n" ));
+ goto Syntax_Error;
+ }
+ count = (T1_Int)CopyInteger( parser );
+
+ /* Is this an array we know about ?? */
+ switch ( top[0].kind2 )
+ {
+ case imm_Encoding:
+ {
+ T1_Encoding* encode = &face->encoding;
+
+ new_state = dict_encoding;
+
+ encode->code_first = count;
+ encode->code_last = 0;
+ encode->num_chars = count;
+
+ /* allocate the table of character indexes. The table of */
+ /* character names is allocated through init_t1_recorder */
+ if ( ALLOC_ARRAY( encode->char_index, count, T1_Short ) )
+ return error;
+
+ error = T1_New_Table( &parser->table, count, memory );
+ if (error) goto Exit;
+
+ parser->encoding_type = encoding_array;
+ }
+ break;
+
+
+ case imm_Subrs:
+ {
+ new_state = dict_subrs;
+ face->num_subrs = count;
+
+ error = T1_New_Table( &parser->table, count, memory );
+ if (error) goto Exit;
+ }
+ break;
+
+
+ case imm_CharStrings:
+ new_state = dict_charstrings;
+ break;
+
+
+ default:
+ new_state = dict_unknown_array;
+ }
+ parser->state_stack[ ++parser->state_index ] = new_state;
+
+ Exit:
+ return error;
+
+ Syntax_Error:
+ return T1_Err_Syntax_Error;
+ }
+
+
+
+
+ static
+ T1_Error Finalise_Parsing( T1_Parser* parser )
+ {
+ T1_Face face = parser->face;
+ FT_Memory memory = face->root.memory;
+ T1_Table* strings = &parser->table;
+ T1_Int num_glyphs;
+ T1_Int n;
+ T1_Error error;
+
+ num_glyphs = face->num_glyphs = parser->cur_name;
+
+ /* allocate glyph names and charstrings arrays */
+ if ( ALLOC_ARRAY( face->glyph_names , num_glyphs, T1_String* ) ||
+ ALLOC_ARRAY( face->charstrings , num_glyphs, T1_Byte* ) ||
+ ALLOC_ARRAY( face->charstrings_len, num_glyphs, T1_Int* ) )
+ return error;
+
+ /* copy glyph names and charstrings offsets and lengths */
+ face->charstrings_block = strings->block;
+ for ( n = 0; n < num_glyphs; n++ )
+ {
+ face->glyph_names[n] = (T1_String*)strings->elements[2*n];
+ face->charstrings[n] = strings->elements[2*n+1];
+ face->charstrings_len[n] = strings->lengths [2*n+1];
+ }
+
+ /* now free the old tables */
+ FREE( strings->elements );
+ FREE( strings->lengths );
+
+ /* Compute encoding if required. */
+ if (parser->encoding_type == encoding_none)
+ {
+ FT_ERROR(( "T1.Parse.Finalise : no encoding specified in font file\n" ));
+ return T1_Err_Syntax_Error;
+ }
+
+ {
+ T1_Int n;
+ T1_Encoding* encode = &face->encoding;
+
+ encode->code_first = encode->num_chars-1;
+ encode->code_last = 0;
+
+ for ( n = 0; n < encode->num_chars; n++ )
+ {
+ T1_String** names;
+ T1_Int index;
+ T1_Int m;
+
+ switch (parser->encoding_type)
+ {
+ case encoding_standard:
+ index = t1_standard_encoding[n];
+ names = (T1_String**)t1_standard_strings;
+ break;
+
+ case encoding_expert:
+ index = t1_expert_encoding[n];
+ names = (T1_String**)t1_standard_strings;
+ break;
+
+ default:
+ index = n;
+ names = (T1_String**)parser->encoding_offsets;
+ }
+ encode->char_index[n] = 0;
+ if (index)
+ {
+ T1_String* name = names[index];
+
+ if ( name )
+ {
+ T1_Int len = strlen(name);
+
+ /* lookup glyph index from name */
+ for ( m = 0; m < num_glyphs; m++ )
+ {
+ if ( strncmp( face->glyph_names[m], name, len ) == 0 )
+ {
+ encode->char_index[n] = m;
+ break;
+ }
+ }
+
+ if ( n < encode->code_first ) encode->code_first = n;
+ if ( n > encode->code_last ) encode->code_last = n;
+ }
+ }
+ }
+
+ parser->encoding_type = encoding_none;
+ FREE( parser->encoding_names );
+ FREE( parser->encoding_lengths );
+ FREE( parser->encoding_offsets );
+ }
+
+ return T1_Err_Ok;
+ }
+
+
+
+
+
+ LOCAL_FUNC
+ T1_Error Parse_T1_FontProgram( T1_Parser* parser )
+ {
+ T1_Error error;
+
+ for (;;)
+ {
+ T1_Token token;
+ T1_Token* top;
+ T1_DictState dict_state;
+ T1_Int dict_index;
+
+ error = Next_T1_Token( parser, &token );
+ top = parser->top;
+ dict_index = parser->state_index;
+ dict_state = parser->state_stack[ dict_index ];
+
+ switch ( token.kind )
+ {
+ /* A keyword was detected */
+ case tok_keyword:
+ switch (token.kind2)
+ {
+ case key_dict:
+
+ switch (dict_state)
+ {
+ case dict_none:
+ /* All right, we're beggining the font dictionary */
+ /* check that we only have one number argument, then */
+ /* consume the 'begin' and change to 'dict_font' */
+ /* state.. */
+ error = Expect_Dict_Arguments( parser, 1, tok_error,
+ dict_font, 0 );
+ if (error) goto Exit;
+
+ /* clear stack from all the previous content. This */
+ /* could be some stupid Postscript code ... */
+ parser->top = parser->stack;
+ break;
+
+
+ case dict_font:
+ /* This must be the /FontInfo dictionary, so check */
+ /* That we have at least two arguments, that they */
+ /* are "/FontInfo" and a number, then change the */
+ /* dictionary state.. */
+ error = Expect_Dict_Arguments( parser, 2, imm_FontInfo,
+ dict_fontinfo, 0 );
+ if (error) goto Exit;
+ break;
+
+
+ case dict_none2:
+ error = Expect_Dict_Arguments( parser, 2, imm_Private,
+ dict_private, 0 );
+ if (error) goto Exit;
+ break;
+
+
+ case dict_private:
+ {
+ T1_Face face = parser->face;
+ T1_Int count;
+
+ error = Expect_Dict_Arguments( parser, 2, imm_CharStrings,
+ dict_charstrings, &count );
+ if (error) goto Exit;
+
+ face->num_glyphs = count;
+ error = T1_New_Table( &parser->table, count*2, face->root.memory );
+ if (error) goto Exit;
+
+ /* record '.notdef' as the first glyph in the font */
+ error = T1_Add_Table( &parser->table, 0, (T1_Byte*)".notdef", 8 );
+ parser->cur_name = 1;
+ /* XXXXX : DO SOMETHING HERE */
+ }
+ break;
+
+ default:
+ /* All other uses are invalid */
+ FT_ERROR(( "T1.Parse: invalid use of the 'dict' keyword\n" ));
+ goto Syntax_Error;
+ }
+ break;
+
+
+ case key_array:
+ /* Are we in an array yet ? Is so, raise an error */
+ switch (dict_state)
+ {
+ case dict_encoding: case dict_subrs:
+ case dict_othersubrs: case dict_charstrings:
+ case dict_unknown_array:
+ FT_ERROR(( "T1.Parse.array: nested array definitions\n" ));
+ goto Syntax_Error;
+
+ default:
+ ;
+ }
+ error = Expect_Array_Arguments( parser );
+ if (error) goto Exit;
+ break;
+
+
+ case key_ND:
+ case key_NP:
+ case key_def:
+ /* Are we in an array ? If so, finalise it.. */
+ switch ( dict_state )
+ {
+ case dict_encoding: /* finish encoding array */
+ {
+ /* copy table names to the face object */
+ T1_Done_Table( &parser->table );
+
+ parser->encoding_names = parser->table.block;
+ parser->encoding_lengths = parser->table.lengths;
+ parser->encoding_offsets = parser->table.elements;
+
+ parser->state_index--;
+ }
+ break;
+
+
+ case dict_subrs:
+ {
+ T1_Face face = parser->face;
+
+ /* copy recorder sub-routines */
+ T1_Done_Table( &parser->table );
+
+ parser->subrs = parser->table.block;
+ face->subrs = parser->table.elements;
+ face->subrs_len = parser->table.lengths;
+
+ parser->state_index--;
+ }
+ break;
+
+ case dict_charstrings:
+ case dict_othersubrs:
+ case dict_unknown_array:
+ FT_ERROR(( "T1.Parser.def: unsupported array\n" ));
+ goto Syntax_Error;
+ break;
+
+ default: /* normal 'def' processing */
+ {
+ /* Check that we have sufficient operands in the stack */
+ if ( top >= parser->stack+2 )
+ {
+ /* Now check that the first operand is an immediate */
+ /* If so, call the appropriate "def" routine based */
+ /* on the current parser state.. */
+ if ( top[-2].kind == tok_immediate )
+ {
+ parser->top -= 2;
+ parser->args = parser->top + 1;
+ error = def_funcs[dict_state](parser);
+ }
+ else
+ {
+ /* This is an error, but some fonts contain some */
+ /* stupid Postscript code. We simply ignore */
+ /* an invalid 'def' by clearing the stack */
+#if 0
+ FT_ERROR(( "T1.Parse.def: immediate expected\n" ));
+ goto Syntax_Error;
+#else
+ parser->top = parser->stack;
+#endif
+ }
+ }
+ else
+ {
+ FT_ERROR(( "T1.Parse.def: not enough arguments\n" ));
+ goto Stack_Underflow;
+ }
+ }
+ }
+ break;
+
+
+
+ case key_index:
+ if ( top <= parser->stack )
+ {
+ FT_ERROR(( "T1.Parse.index: not enough arguments\n" ));
+ goto Stack_Underflow;
+ }
+
+ /* simply ignore ?? */
+ parser->top --;
+ break;
+
+
+ case key_put:
+ /* Check that we have sufficient operands in stack */
+ if ( top < parser->stack+2 )
+ {
+ FT_ERROR(( "T1.Parse.put: not enough arguments\n" ));
+ goto Stack_Underflow;
+ }
+
+ parser->top -= 2;
+ parser->args = parser->top;
+ switch (dict_state)
+ {
+ case dict_encoding:
+ error = Do_Put_Encoding( parser );
+ if (error) goto Exit;
+ break;
+
+ case dict_unknown_array: /* ignore the put */
+ break;
+
+ default:
+#if 0
+ FT_ERROR(( "T1.Parse.put: invalid context\n" ));
+ goto Syntax_Error;
+#else
+ /* invalid context, simply ignore the put and */
+ /* clear the stack (stupid Postscript code..) */
+ FT_TRACE4(( "T1.Parse.put: invalid context. ignored.\n" ));
+ parser->top = parser->stack;
+#endif
+ }
+ break;
+
+
+
+ case key_RD:
+ /* Check that we have sufficient operands in stack */
+ if ( top < parser->stack+2 )
+ {
+ FT_ERROR(( "T1.Parse.RD: not enough arguments\n" ));
+ goto Stack_Underflow;
+ }
+
+ parser->top -= 2;
+ parser->args = parser->top;
+ switch (dict_state)
+ {
+ case dict_subrs:
+ error = Do_RD_Subrs( parser );
+ if (error) goto Exit;
+ break;
+
+ case dict_charstrings:
+ error = Do_RD_Charstrings( parser );
+ if (error) goto Exit;
+ break;
+
+ default:
+ FT_ERROR(( "T1.Parse.RD: invalid context\n" ));
+ goto Syntax_Error;
+ }
+ break;
+
+
+
+ case key_end:
+ /* Were we in a dictionary or in an array ? */
+ if ( dict_index <= 0 )
+ {
+ FT_ERROR(( "T1.Parse.end: no dictionary defined\n" ));
+ goto Syntax_Error;
+ }
+
+ switch (dict_state)
+ {
+ /* Jump to the private dictionary if we're closing the */
+ /* /Font dictionary.. */
+ case dict_font:
+ goto Open_Private;
+
+ /* Exit the parser when closing the CharStrings dictionary */
+ case dict_charstrings:
+ return Finalise_Parsing( parser );
+
+ default:
+ /* Pop the current dictionary state and return to previous */
+ /* one. Consume the "def".. */
+
+ /* Because some buggy fonts (BitStream) have incorrect */
+ /* syntax, we never escape from the private dictionary */
+ if (dict_state != dict_private)
+ parser->state_index--;
+
+ error = Expect_Keyword2( parser, key_def, key_put );
+ if (error) goto Exit;
+ }
+ break;
+
+
+
+ case key_for:
+ /* check that we have four arguments, and simply */
+ /* ignore them.. */
+ if ( top - parser->stack < 4 )
+ {
+ FT_ERROR(( "T1.Parse.for: not enough arguments\n" ));
+ goto Stack_Underflow;
+ }
+
+ parser->top -= 4;
+ break;
+
+
+
+ case key_currentdict:
+
+ Open_Private:
+ parser->state_index = 0;
+ parser->state_stack[0] = dict_none2;
+ error = Open_PrivateDict( parser->tokenizer );
+ if (error) goto Exit;
+ break;
+
+
+ case key_true:
+ case key_false:
+ case key_StandardEncoding:
+ case key_ExpertEncoding:
+ goto Push_Element;
+
+
+ default:
+ FT_ERROR(( "T1.Parser: invalid keyword in context\n" ));
+ error = T1_Err_Syntax_Error;
+ }
+ break;
+
+ /* A number was detected */
+ case tok_string:
+ case tok_program:
+ case tok_immediate:
+ case tok_array:
+ case tok_hexarray:
+ case tok_any:
+ case tok_number: /* push number on stack */
+
+ Push_Element:
+ if ( top >= parser->limit )
+ {
+ error = T1_Err_Stack_Overflow;
+ goto Exit;
+ }
+ else
+ *parser->top++ = token;
+ break;
+
+ /* anything else is an error per se the spec, but we */
+ /* frequently encountre stupid postscript code in fonts, */
+ /* so just ignore them.. */
+ default:
+ error = T1_Err_Ok; /* ignore token */
+ }
+
+ if (error)
+ return error;
+ }
+ Exit:
+ return error;
+
+ Syntax_Error:
+ return T1_Err_Syntax_Error;
+
+ Stack_Underflow:
+ return T1_Err_Stack_Underflow;
+ }
+
--- /dev/null
+++ b/src/type1/t1load.h
@@ -1,0 +1,72 @@
+/*******************************************************************
+ *
+ * t1load.h 1.0
+ *
+ * Type1 Loader.
+ *
+ * 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.
+ *
+ ******************************************************************/
+
+#ifndef T1LOAD_H
+#define T1LOAD_H
+
+#include <ftstream.h>
+#include <t1parse.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+ /*************************************************************************/
+ /* */
+ /* <Function> Init_T1_Parser */
+ /* */
+ /* <Description> */
+ /* Initialise a given parser object to build a given T1_Face */
+ /* */
+ /* <Input> */
+ /* parser :: handle to the newly built parser object */
+ /* face :: handle to target T1 face object */
+ /* */
+ LOCAL_DEF
+ void Init_T1_Parser( T1_Parser* parser,
+ T1_Face face,
+ T1_Tokenizer tokenizer );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> Parse_T1_FontProgram */
+ /* */
+ /* <Description> */
+ /* Parses a given Type 1 font file and builds its face object */
+ /* */
+ /* <Input> */
+ /* parser :: handle to target parser object */
+ /* */
+ /* <Return> */
+ /* Error code. 0 means success.. */
+ /* */
+ /* <Note> */
+ /* The parser contains a handle to the target face object. */
+ /* */
+ LOCAL_DEF
+ T1_Error Parse_T1_FontProgram( T1_Parser* parser );
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* T1LOAD_H */
+
+
+/* END */
--- /dev/null
+++ b/src/type1/t1objs.c
@@ -1,0 +1,414 @@
+/*******************************************************************
+ *
+ * t1objs.c 1.0
+ *
+ * Type1 Objects manager.
+ *
+ * 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.
+ *
+ ******************************************************************/
+
+#include <ftdebug.h>
+#include <ftstream.h>
+
+#include <t1gload.h>
+#include <t1load.h>
+
+#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
+#include <t1hinter.h>
+#endif
+
+/* Required by tracing mode */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_t1objs
+
+/*******************************************************************
+ * *
+ * SIZE FUNCTIONS *
+ * *
+ * *
+ *******************************************************************/
+
+/*******************************************************************
+ *
+ * <Function> T1_Done_Size
+ *
+ * <Description>
+ * The TrueDoc instance object destructor. Used to discard
+ * a given instance object..
+ *
+ * <Input>
+ * instance :: handle to the target instance object
+ *
+ * <Return>
+ * TrueDoc error code. 0 means success
+ *
+ ******************************************************************/
+
+ LOCAL_FUNC
+ void T1_Done_Size( T1_Size size )
+ {
+ if (size)
+ {
+#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
+ T1_Done_Size_Hinter( size );
+#endif
+ size->valid = 0;
+ }
+ }
+
+
+/*******************************************************************
+ *
+ * <Function> T1_Init_Size
+ *
+ * <Description>
+ * The instance object constructor
+ *
+ * <Input>
+ * instance : handle to new instance object
+ * face : pointer to parent face object
+ *
+ * <Return>
+ * TrueDoc error code. 0 means success.
+ *
+ ******************************************************************/
+
+ LOCAL_DEF
+ T1_Error T1_Init_Size( T1_Size size )
+ {
+ T1_Error error;
+
+ size->valid = 0;
+
+#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
+ error = T1_New_Size_Hinter( size );
+ return error;
+#else
+ (void)error;
+ return T1_Err_Ok;
+#endif
+ }
+
+
+/*******************************************************************
+ *
+ * <Function> T1_Reset_Size
+ *
+ * <Description>
+ * Resets an instance to a new pointsize/transform.
+ * This function is in charge of resetting the blue zones,
+ * As well as the stem snap tables for a given size..
+ *
+ * <Input>
+ * instance the instance object to destroy
+ *
+ * <Output>
+ * Error code.
+ *
+ ******************************************************************/
+
+ LOCAL_FUNC
+ T1_Error T1_Reset_Size( T1_Size size )
+ {
+#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
+ return T1_Reset_Size_Hinter( size );
+#else
+ (void)size;
+ return 0;
+#endif
+ }
+
+
+/*******************************************************************
+ * *
+ * FACE FUNCTIONS *
+ * *
+ * *
+ *******************************************************************/
+
+/*******************************************************************
+ *
+ * <Function> T1_Done_Face
+ *
+ * <Description>
+ * The face object destructor.
+ *
+ * <Input>
+ * face :: typeless pointer to the face object to destroy
+ *
+ * <Return>
+ * Error code.
+ *
+ ******************************************************************/
+
+ LOCAL_FUNC
+ void T1_Done_Face( T1_Face face )
+ {
+ FT_Memory memory;
+
+ if (face)
+ {
+ memory = face->root.memory;
+ /* XXXX : TO DO */
+ }
+ }
+
+/*******************************************************************
+ *
+ * <Function> T1_Init_Face
+ *
+ * <Description>
+ * The face object constructor.
+ *
+ * <Input>
+ * face :: face record to build
+ * Input :: input stream where to load font data
+ *
+ * <Return>
+ * Error code.
+ *
+ ******************************************************************/
+
+ LOCAL_FUNC
+ T1_Error T1_Init_Face( FT_Stream stream,
+ FT_Int face_index,
+ T1_Face face )
+ {
+ T1_Tokenizer tokenizer;
+ T1_Error error;
+
+ (void)face_index;
+ (void)face;
+
+ face->root.num_faces = 1;
+
+ /* open the tokenizer, this will also check the font format */
+ error = New_Tokenizer( stream, &tokenizer );
+ if (error) goto Fail;
+
+ /* if we just wanted to check the format, leave successfully now */
+ if (face_index < 0)
+ goto Leave;
+
+ /* check the face index */
+ if ( face_index != 0 )
+ {
+ FT_ERROR(( "T1.Init_Face : invalid face index\n" ));
+ error = T1_Err_Invalid_Argument;
+ goto Leave;
+ }
+
+ /* Now, load the font program into the face object */
+ {
+ T1_Parser parser;
+
+ Init_T1_Parser( &parser, face, tokenizer );
+ error = Parse_T1_FontProgram( &parser );
+ if (error) goto Leave;
+
+ /* Init the face object fields */
+ /* Now set up root face fields */
+ {
+ FT_Face root = (FT_Face)&face->root;
+
+ root->num_glyphs = face->num_glyphs;
+ root->num_charmaps = 1;
+
+ root->face_index = face_index;
+ root->face_flags = FT_FACE_FLAG_SCALABLE;
+
+ root->face_flags |= FT_FACE_FLAG_HORIZONTAL;
+
+ if ( face->font_info.is_fixed_pitch )
+ root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
+
+ /* XXX : TO DO - add kerning with .afm support */
+
+ /* get style name - be careful, some broken fonts only */
+ /* have a /FontName dictionary entry .. !! */
+ root->family_name = face->font_info.family_name;
+ if (root->family_name)
+ {
+ char* full = face->font_info.full_name;
+ char* family = root->family_name;
+
+ while ( *family && *full == *family )
+ {
+ family++;
+ full++;
+ }
+
+ root->style_name = ( *full == ' ' ? full+1 : "Regular" );
+ }
+ else
+ {
+ /* do we have a /FontName ?? */
+ if (face->font_name)
+ {
+ root->family_name = face->font_name;
+ root->style_name = "Regular";
+ }
+ }
+
+ /* no embedded bitmap support */
+ root->num_fixed_sizes = 0;
+ root->available_sizes = 0;
+
+ root->bbox = face->font_bbox;
+ root->units_per_EM = 1000;
+ root->ascender = (T1_Short)face->font_bbox.yMax;
+ root->descender = -(T1_Short)face->font_bbox.yMin;
+ root->height = ((root->ascender + root->descender)*12)/10;
+
+ /* now compute the maximum advance width */
+
+ root->max_advance_width = face->private_dict.standard_width;
+
+ /* compute max advance width for proportional fonts */
+ if (!face->font_info.is_fixed_pitch)
+ {
+ T1_Int max_advance;
+
+ error = T1_Compute_Max_Advance( face, &max_advance );
+
+ /* in case of error, keep the standard width */
+ if (!error)
+ root->max_advance_width = max_advance;
+ else
+ error = 0; /* clear error */
+ }
+
+ root->max_advance_height = root->height;
+
+ root->underline_position = face->font_info.underline_position;
+ root->underline_thickness = face->font_info.underline_thickness;
+
+ root->max_points = 0;
+ root->max_contours = 0;
+ }
+ }
+
+ Leave:
+ Done_Tokenizer( tokenizer );
+
+ Fail:
+ return error;
+ }
+
+
+/*******************************************************************
+ *
+ * Function : Glyph_Destroy
+ *
+ * Description : The glyph object destructor.
+ *
+ * Input : _glyph typeless pointer to the glyph record to destroy
+ *
+ * Output : Error code.
+ *
+ ******************************************************************/
+
+ LOCAL_FUNC
+ void T1_Done_GlyphSlot( T1_GlyphSlot glyph )
+ {
+ FT_Memory memory = glyph->root.face->memory;
+ FT_Library library = glyph->root.face->driver->library;
+
+#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
+ T1_Done_Glyph_Hinter( glyph );
+#endif
+ /* the bitmaps are created on demand */
+ FREE( glyph->root.bitmap.buffer );
+ FT_Done_Outline( library, &glyph->root.outline );
+ return;
+ }
+
+
+/*******************************************************************
+ *
+ * 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
+ T1_Error T1_Init_GlyphSlot( T1_GlyphSlot glyph )
+ {
+ FT_Library library = glyph->root.face->driver->library;
+ T1_Error error;
+
+ glyph->max_points = 0;
+ glyph->max_contours = 0;
+ glyph->root.bitmap.buffer = 0;
+
+ error = FT_New_Outline( library, 0, 0, &glyph->root.outline );
+ if (error) return error;
+
+#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
+ error = T1_New_Glyph_Hinter( glyph );
+ if (error)
+ FT_Done_Outline( library, &glyph->root.outline );
+#endif
+
+ return error;
+ }
+
+
+/*******************************************************************
+ *
+ * <Function> T1_Init_Driver
+ *
+ * <Description>
+ * Initialise a given Type 1 driver object
+ *
+ * <Input>
+ * driver :: handle to target driver object
+ *
+ * <Return>
+ * Error code.
+ *
+ ******************************************************************/
+
+ LOCAL_FUNC
+ T1_Error T1_Init_Driver( T1_Driver driver )
+ {
+ (void)driver;
+ return T1_Err_Ok;
+ }
+
+
+
+/*******************************************************************
+ *
+ * <Function> T1_Done_Driver
+ *
+ * <Description>
+ * finalise a given Type 1 driver
+ *
+ * <Input>
+ * driver :: handle to target Type 1 driver
+ *
+ ******************************************************************/
+
+ LOCAL_DEF
+ void T1_Done_Driver( T1_Driver driver )
+ {
+ (void)driver;
+ }
+
+
+/* END */
--- /dev/null
+++ b/src/type1/t1objs.h
@@ -1,0 +1,302 @@
+/*******************************************************************
+ *
+ * t1objs.h 1.0
+ *
+ * Type1 objects 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.
+ *
+ ******************************************************************/
+
+#ifndef T1OBJS_H
+#define T1OBJS_H
+
+#include <ftobjs.h>
+#include <t1config.h>
+#include <t1errors.h>
+#include <t1types.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+ /* The following structures must be defined by the hinter */
+ typedef struct T1_Size_Hints_ T1_Size_Hints;
+ typedef struct T1_Glyph_Hints_ T1_Glyph_Hints;
+
+ /***********************************************************************/
+ /* */
+ /* <Type> T1_Driver */
+ /* */
+ /* <Description> */
+ /* A handle to a Type 1 driver object. */
+ /* */
+ typedef struct T1_DriverRec_ *T1_Driver;
+
+
+ /***********************************************************************/
+ /* */
+ /* <Type> T1_Size */
+ /* */
+ /* <Description> */
+ /* A handle to a Type 1 size object. */
+ /* */
+ typedef struct T1_SizeRec_* T1_Size;
+
+
+ /***********************************************************************/
+ /* */
+ /* <Type> T1_GlyphSlot */
+ /* */
+ /* <Description> */
+ /* A handle to a Type 1 glyph slot object. */
+ /* */
+ typedef struct T1_GlyphSlotRec_* T1_GlyphSlot;
+
+
+ /***********************************************************************/
+ /* */
+ /* <Type> T1_CharMap */
+ /* */
+ /* <Description> */
+ /* A handle to a Type 1 character mapping object. */
+ /* */
+ /* <Note> */
+ /* The Type 1 format doesn't use a charmap but an encoding table. */
+ /* The driver is responsible for making up charmap objects */
+ /* corresponding to these tables.. */
+ /* */
+ typedef struct T1_CharMapRec_* T1_CharMap;
+
+
+
+ /**************************************************************************/
+ /* */
+ /* NOW BEGINS THE TYPE1 SPECIFIC STUFF .............................. */
+ /* */
+ /**************************************************************************/
+
+
+ /***************************************************/
+ /* */
+ /* T1_Size : */
+ /* */
+ /* Type 1 size record.. */
+ /* */
+
+ typedef struct T1_SizeRec_
+ {
+ FT_SizeRec root;
+ T1_Bool valid;
+ T1_Size_Hints* hints; /* defined in the hinter. This allows */
+ /* us to experiment with different */
+ /* hinting schemes without having to */
+ /* change 't1objs' each time.. */
+ } T1_SizeRec;
+
+
+
+ /***************************************************/
+ /* */
+ /* T1_GlyphSlot : */
+ /* */
+ /* TrueDoc glyph record.. */
+ /* */
+
+ typedef struct T1_GlyphSlotRec_
+ {
+ FT_GlyphSlotRec root;
+
+ T1_Bool hint;
+ T1_Bool scaled;
+
+ T1_Int max_points;
+ T1_Int max_contours;
+
+ FT_Fixed x_scale;
+ FT_Fixed y_scale;
+
+ T1_Glyph_Hints* hints; /* defined in the hinter */
+
+ } T1_GlyphSlotRec;
+
+
+/*******************************************************************
+ *
+ * <Function> T1_Init_Face
+ *
+ * <Description>
+ * Initialise a given Type 1 face object
+ *
+ * <Input>
+ * face_index :: index of font face in resource
+ * resource :: source font resource
+ * face :: face record to build
+ *
+ * <Return>
+ * Error code.
+ *
+ ******************************************************************/
+
+ LOCAL_DEF
+ T1_Error T1_Init_Face( FT_Stream stream,
+ FT_Int face_index,
+ T1_Face face );
+
+
+
+/*******************************************************************
+ *
+ * <Function> T1_Done_Face
+ *
+ * <Description>
+ * Finalise a given face object
+ *
+ * <Input>
+ * face :: handle to the face object to destroy
+ *
+ ******************************************************************/
+
+ LOCAL_DEF
+ void T1_Done_Face( T1_Face face );
+
+
+
+/*******************************************************************
+ *
+ * <Function> T1_Init_Size
+ *
+ * <Description>
+ * Initialise a new Type 1 size object
+ *
+ * <Input>
+ * size :: handle to size object
+ *
+ * <Return>
+ * Type 1 error code. 0 means success.
+ *
+ ******************************************************************/
+
+ LOCAL_DEF
+ T1_Error T1_Init_Size( T1_Size size );
+
+
+
+/*******************************************************************
+ *
+ * <Function> T1_Done_Size
+ *
+ * <Description>
+ * The Type 1 size object finaliser.
+ *
+ * <Input>
+ * size :: handle to the target size object.
+ *
+ ******************************************************************/
+
+ LOCAL_DEF
+ void T1_Done_Size( T1_Size size );
+
+
+/*******************************************************************
+ *
+ * <Function> T1_Reset_Size
+ *
+ * <Description>
+ * Reset a Type 1 size when resolutions and character dimensions
+ * have been changed..
+ *
+ * <Input>
+ * size :: handle to the target size object.
+ *
+ ******************************************************************/
+
+ LOCAL_DEF
+ T1_Error T1_Reset_Size( T1_Size size );
+
+
+
+/*******************************************************************
+ *
+ * <Function> T1_Init_GlyphSlot
+ *
+ * <Description> The TrueType glyph slot initialiser
+ *
+ * <Input> glyph :: glyph record to build.
+ *
+ * <Output> Error code.
+ *
+ ******************************************************************/
+
+ LOCAL_DEF
+ T1_Error T1_Init_GlyphSlot( T1_GlyphSlot slot );
+
+
+
+/*******************************************************************
+ *
+ * <Function> T1_Done_GlyphSlot
+ *
+ * <Description> The Type 1 glyph slot finaliser
+ *
+ * <Input> glyph :: handle to glyph slot object
+ *
+ * <Output> Error code.
+ *
+ ******************************************************************/
+
+ LOCAL_DEF
+ void T1_Done_GlyphSlot( T1_GlyphSlot slot );
+
+
+
+/*******************************************************************
+ *
+ * <Function> T1_Init_Driver
+ *
+ * <Description>
+ * Initialise a given Type 1 driver object
+ *
+ * <Input>
+ * driver :: handle to target driver object
+ *
+ * <Return>
+ * Error code.
+ *
+ ******************************************************************/
+
+ LOCAL_DEF
+ T1_Error T1_Init_Driver( T1_Driver driver );
+
+
+
+/*******************************************************************
+ *
+ * <Function> T1_Done_Driver
+ *
+ * <Description>
+ * finalise a given Type 1 driver
+ *
+ * <Input>
+ * driver :: handle to target Type 1 driver
+ *
+ ******************************************************************/
+
+ LOCAL_DEF
+ void T1_Done_Driver( T1_Driver driver );
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* T1OBJS_H */
+
+
+/* END */
--- /dev/null
+++ b/src/type1/t1parse.c
@@ -1,0 +1,665 @@
+#include <ftdebug.h>
+#include <t1types.h>
+#include <t1parse.h>
+
+#include <stdio.h> /* for sscanf */
+
+/*************************************************************************/
+/* */
+/* <Function> T1_New_Table */
+/* */
+/* <Description> */
+/* Initialise a T1_Table. */
+/* */
+/* <Input> */
+/* table :: address of target table */
+/* count :: table size = maximum number of elements */
+/* memory :: memory object to use for all subsequent reallocations */
+/* */
+/* <Return> */
+/* Error code. 0 means success */
+/* */
+
+ LOCAL_FUNC
+ T1_Error T1_New_Table( T1_Table* table,
+ T1_Int count,
+ FT_Memory memory )
+ {
+ T1_Error error;
+
+ table->memory = memory;
+ if ( ALLOC_ARRAY( table->elements, count, T1_Byte* ) )
+ return error;
+
+ if ( ALLOC_ARRAY( table->lengths, count, T1_Byte* ) )
+ {
+ FREE( table->elements );
+ return error;
+ }
+
+ table->max_elems = count;
+ table->num_elems = 0;
+
+ table->block = 0;
+ table->capacity = 0;
+ table->cursor = 0;
+
+ return error;
+ }
+
+
+
+/*************************************************************************/
+/* */
+/* <Function> T1_Add_Table */
+/* */
+/* <Description> */
+/* Adds an object to a T1_Table, possibly growing its memory block */
+/* */
+/* <Input> */
+/* table :: target table */
+/* index :: index of object in table */
+/* object :: address of object to copy in memory */
+/* length :: length in bytes of source object */
+/* */
+/* <Return> */
+/* Error code. 0 means success. An error is returned when a */
+/* realloc failed.. */
+/* */
+
+ static
+ T1_Error reallocate_t1_table( T1_Table* table,
+ T1_Int new_size )
+ {
+ FT_Memory memory = table->memory;
+ T1_Byte* old_base = table->block;
+ T1_Error error;
+
+ /* realloc the base block */
+ if ( REALLOC( table->block, table->capacity, new_size ) )
+ return error;
+ table->capacity = new_size;
+
+ /* shift all offsets when needed */
+ if (old_base)
+ {
+ T1_Long delta = table->block - old_base;
+ T1_Byte** offset = table->elements;
+ T1_Byte** limit = offset + table->max_elems;
+
+ if (delta)
+ for ( ; offset < limit; offset ++ )
+ if (offset[0])
+ offset[0] += delta;
+ }
+
+ return T1_Err_Ok;
+ }
+
+
+ LOCAL_FUNC
+ T1_Error T1_Add_Table( T1_Table* table,
+ T1_Int index,
+ void* object,
+ T1_Int length )
+ {
+ if (index < 0 || index > table->max_elems)
+ {
+ FT_ERROR(( "T1.Add_Table: invalid index\n" ));
+ return T1_Err_Syntax_Error;
+ }
+
+ /* grow the base block if needed */
+ if ( table->cursor + length > table->capacity )
+ {
+ T1_Error error;
+ T1_Int new_size = table->capacity;
+
+ while ( new_size < table->cursor+length )
+ new_size += 1024;
+
+ error = reallocate_t1_table( table, new_size );
+ if (error) return error;
+ }
+
+ /* add the object to the base block and adjust offset */
+ table->elements[ index ] = table->block + table->cursor;
+ table->lengths [ index ] = length;
+ MEM_Copy( table->block + table->cursor, object, length );
+
+ table->cursor += length;
+ return T1_Err_Ok;
+ }
+
+
+/*************************************************************************/
+/* */
+/* <Function> T1_Done_Table */
+/* */
+/* <Description> */
+/* Finalise a T1_Table. (realloc it to its current cursor). */
+/* */
+/* <Input> */
+/* table :: target table */
+/* */
+/* <Note> */
+/* This function does NOT release the heap's memory block. It is up */
+/* to the caller to clean it, or reference it in its own structures. */
+/* */
+ LOCAL_FUNC
+ void T1_Done_Table( T1_Table* table )
+ {
+ FT_Memory memory = table->memory;
+ T1_Error error;
+ T1_Byte* old_base;
+
+ /* should never fail, as rec.cursor <= rec.size */
+ old_base = table->block;
+ if (!old_base)
+ return;
+
+ (void)REALLOC( table->block, table->capacity, table->cursor );
+ table->capacity = table->cursor;
+
+ if (old_base != table->block)
+ {
+ T1_Long delta = table->block - old_base;
+ T1_Byte** element = table->elements;
+ T1_Byte** limit = element + table->max_elems;
+
+ for ( ; element < limit; element++ )
+ if (element[0])
+ element[0] += delta;
+ }
+ }
+
+
+ LOCAL_FUNC
+ T1_String* CopyString( T1_Parser* parser )
+ {
+ T1_String* string = NULL;
+ T1_Token* token = parser->args++;
+ FT_Memory memory = parser->tokenizer->memory;
+ T1_Error error;
+
+ if ( token->kind == tok_string )
+ {
+ int len = token->len-2;
+
+ if ( ALLOC( string, len+1 ) )
+ {
+ parser->error = error;
+ return 0;
+ }
+
+ MEM_Copy( string, parser->tokenizer->base + token->start+1, len );
+ string[len] = '\0';
+
+ parser->error = T1_Err_Ok;
+ }
+ else
+ {
+ FT_ERROR(( "T1.CopyString : syntax error, string token expected !\n" ));
+ parser->error = T1_Err_Syntax_Error;
+ }
+ return string;
+ }
+
+
+
+ static
+ T1_Error parse_int( T1_Byte* base,
+ T1_Byte* limit,
+ T1_Long* result )
+ {
+ T1_Bool sign = 0;
+ T1_Long sum = 0;
+
+ if (base >= limit)
+ goto Fail;
+
+ /* check sign */
+ if ( *base == '+' )
+ base++;
+
+ else if ( *base == '-' )
+ {
+ sign++;
+ base++;
+ }
+
+ /* parse digits */
+ if ( base >= limit )
+ goto Fail;
+
+ do
+ {
+ sum = ( 10*sum + (*base++ - '0') );
+
+ } while (base < limit);
+
+ if (sign)
+ sum = -sum;
+
+ *result = sum;
+ return T1_Err_Ok;
+
+ Fail:
+ FT_ERROR(( "T1.parse_integer : integer expected\n" ));
+ *result = 0;
+ return T1_Err_Syntax_Error;
+ }
+
+
+
+
+ static
+ T1_Error parse_float( T1_Byte* base,
+ T1_Byte* limit,
+ T1_Int scale,
+ T1_Long* result )
+ {
+#if 1
+ /* XXX : We're simply much too lazy to code this function */
+ /* properly for now.. We'll do that when the rest of */
+ /* the driver works properly.. */
+ char temp[32];
+ int len = limit-base;
+ double value;
+
+ if (len > 31) goto Fail;
+
+ strncpy( temp, (char*)base, len );
+ temp[len] = '\0';
+ if ( sscanf( temp, "%lf", &value ) != 1 )
+ goto Fail;
+
+ *result = (T1_Long)(scale*value);
+ return 0;
+
+#else
+ T1_Byte* cur;
+ T1_Bool sign = 0; /* sign */
+ T1_Long number_int = 0; /* integer part */
+ T1_Long number_frac = 0; /* fractional part */
+ T1_Long exponent = 0; /* exponent value */
+ T1_Int num_frac = 0; /* number of fractional digits */
+
+ /* check sign */
+ if (*base == '+')
+ base++;
+
+ else if (*base == '-')
+ {
+ sign++;
+ base++;
+ }
+
+ /* find integer part */
+ cur = base;
+ while ( cur < limit )
+ {
+ T1_Byte c = *cur;
+ if ( c == '.' || c == 'e' || c == 'E' )
+ break;
+
+ cur++;
+ }
+
+ if ( cur > base )
+ {
+ error = parse_integer( base, cur, &number_int );
+ if (error) goto Fail;
+ }
+
+ /* read fractional part, if any */
+ if ( *cur == '.' )
+ {
+ cur++;
+ base = cur;
+ while ( cur < limit )
+ {
+ T1_Byte c = *cur;
+ if ( c == 'e' || c == 'E' )
+ break;
+ cur++;
+ }
+
+ num_frac = cur - base;
+
+ if ( cur > base )
+ {
+ error = parse_integer( base, cur, &number_frac );
+ if (error) goto Fail;
+ base = cur;
+ }
+ }
+
+ /* read exponent, if any */
+ if ( *cur == 'e' || *cur == 'E' )
+ {
+ cur++;
+ base = cur;
+ error = parse_integer( base, limit, &exponent );
+ if (error) goto Fail;
+
+ /* now check that exponent is within 'correct bounds' */
+ /* i.e. between -6 and 6 */
+ if ( exponent < -6 || exponent > 6 )
+ goto Fail;
+ }
+
+ /* now adjust integer value and exponent for fractional part */
+ while ( num_frac > 0 )
+ {
+ number_int *= 10;
+ exponent --;
+ num_frac--;
+ }
+
+ number_int += num_frac;
+
+ /* skip point if any, read fractional part */
+ if ( cur+1 < limit )
+ {
+ if (*cur
+ }
+
+ /* now compute scaled float value */
+ /* XXXXX : incomplete !!! */
+#endif
+
+ Fail:
+ FT_ERROR(( "T1.parse_float : syntax error !\n" ));
+ return T1_Err_Syntax_Error;
+ }
+
+
+
+ static
+ T1_Error parse_integer( T1_Byte* base,
+ T1_Byte* limit,
+ T1_Long* result )
+ {
+ T1_Byte* cur;
+
+ /* the lexical analyser accepts floats as well as integers */
+ /* now, check that we really have an int in this token */
+ cur = base;
+ while ( cur < limit )
+ {
+ T1_Byte c = *cur++;
+
+ if ( c == '.' || c == 'e' || c == 'E' )
+ goto Float_Number;
+ }
+
+ /* now read the number's value */
+ return parse_int( base, limit, result );
+
+ Float_Number:
+ /* We really have a float there, simply call parse_float in this */
+ /* case with a scale of '10' to perform round.. */
+ {
+ T1_Error error;
+
+ error = parse_float( base, limit, 10, result );
+ if (!error)
+ {
+ if (*result >= 0) *result = (*result+5)/10; /* round value */
+ else *result = -((5-*result)/10);
+ }
+ return error;
+ }
+ }
+
+
+ LOCAL_FUNC
+ T1_Long CopyInteger( T1_Parser* parser )
+ {
+ T1_Long sum = 0;
+ T1_Token* token = parser->args++;
+
+ if ( token->kind == tok_number )
+ {
+ T1_Byte* base = parser->tokenizer->base + token->start;
+ T1_Byte* limit = base + token->len;
+
+ /* now read the number's value */
+ parser->error = parse_integer( base, limit, &sum );
+ return sum;
+ }
+
+ FT_ERROR(( "T1.CopyInteger : number expected\n" ));
+ parser->args--;
+ parser->error = T1_Err_Syntax_Error;
+ return 0;
+ }
+
+
+
+ LOCAL_FUNC
+ T1_Bool CopyBoolean( T1_Parser* parser )
+ {
+ T1_Error error = T1_Err_Ok;
+ T1_Bool result = 0;
+ T1_Token* token = parser->args++;
+
+ if ( token->kind == tok_keyword )
+ {
+ if ( token->kind2 == key_false )
+ result = 0;
+
+ else if ( token->kind2 == key_true )
+ result = !0;
+
+ else
+ goto Fail;
+ }
+ else
+ {
+ Fail:
+ FT_ERROR(( "T1.CopyBoolean : syntax error, 'false' or 'true' expected\n" ));
+ error = T1_Err_Syntax_Error;
+ }
+ parser->error = error;
+ return result;
+ }
+
+
+
+
+ LOCAL_FUNC
+ T1_Long CopyFloat( T1_Parser* parser,
+ T1_Int scale )
+ {
+ T1_Error error;
+ T1_Long sum = 0;
+ T1_Token* token = parser->args++;
+
+ if ( token->kind == tok_number )
+ {
+ T1_Byte* base = parser->tokenizer->base + token->start;
+ T1_Byte* limit = base + token->len;
+
+ error = parser->error = parse_float( base, limit, scale, &sum );
+ if (error) goto Fail;
+
+ return sum;
+ }
+
+ Fail:
+ FT_ERROR(( "T1.CopyFloat : syntax error !\n" ));
+ parser->error = T1_Err_Syntax_Error;
+ return 0;
+ }
+
+
+
+
+
+
+ LOCAL_FUNC
+ void CopyBBox( T1_Parser* parser,
+ T1_BBox* bbox )
+ {
+ T1_Token* token = parser->args++;
+ T1_Int n;
+ T1_Error error;
+
+ if ( token->kind == tok_program ||
+ token->kind == tok_array )
+ {
+ /* get rid of '['/']', or '{'/'}' */
+ T1_Byte* base = parser->tokenizer->base + token->start + 1;
+ T1_Byte* limit = base + token->len - 1;
+ T1_Byte* cur;
+ T1_Byte* start;
+
+ /* read each parameter independently */
+ cur = base;
+ for ( n = 0; n < 4; n++ )
+ {
+ T1_Long* result;
+
+ /* skip whitespace */
+ while (cur < limit && *cur == ' ') cur++;
+
+ /* skip numbers */
+ start = cur;
+ while (cur < limit && *cur != ' ') cur++;
+
+ /* compute result address */
+ switch (n)
+ {
+ case 0 : result = &bbox->xMin; break;
+ case 1 : result = &bbox->yMin; break;
+ case 2 : result = &bbox->xMax; break;
+ default: result = &bbox->yMax;
+ }
+
+ error = parse_integer( start, cur, result );
+ if (error) goto Fail;
+ }
+ parser->error = 0;
+ return;
+ }
+
+ Fail:
+ FT_ERROR(( "T1.CopyBBox : syntax error !\n" ));
+ parser->error = T1_Err_Syntax_Error;
+ }
+
+
+
+
+ LOCAL_FUNC
+ void CopyMatrix( T1_Parser* parser,
+ T1_Matrix* matrix )
+ {
+ T1_Token* token = parser->args++;
+ T1_Error error;
+
+ if ( token->kind == tok_array )
+ {
+ /* get rid of '[' and ']' */
+ T1_Byte* base = parser->tokenizer->base + token->start + 1;
+ T1_Byte* limit = base + token->len - 1;
+ T1_Byte* cur;
+ T1_Byte* start;
+ T1_Int n;
+
+ /* read each parameter independently */
+ cur = base;
+ for ( n = 0; n < 4; n++ )
+ {
+ T1_Long* result;
+
+ /* skip whitespace */
+ while (cur < limit && *cur == ' ') cur++;
+
+ /* skip numbers */
+ start = cur;
+ while (cur < limit && *cur != ' ') cur++;
+
+ /* compute result address */
+ switch (n)
+ {
+ case 0 : result = &matrix->xx; break;
+ case 1 : result = &matrix->xy; break;
+ case 2 : result = &matrix->yx; break;
+ default: result = &matrix->yy;
+ }
+
+ error = parse_float( start, cur, 65536000, result );
+ if (error) goto Fail;
+ }
+ parser->error = 0;
+ return;
+ }
+
+ Fail:
+ FT_ERROR(( "T1.CopyMatrix : syntax error !\n" ));
+ parser->error = T1_Err_Syntax_Error;
+ }
+
+
+
+ LOCAL_FUNC
+ void CopyArray( T1_Parser* parser,
+ T1_Byte* num_elements,
+ T1_Short* elements,
+ T1_Int max_elements )
+ {
+ T1_Token* token = parser->args++;
+ T1_Error error;
+
+ if ( token->kind == tok_array ||
+ token->kind == tok_program ) /* in the case of MinFeature */
+ {
+ /* get rid of '['/']', or '{'/'}' */
+ T1_Byte* base = parser->tokenizer->base + token->start + 1;
+ T1_Byte* limit = base + token->len - 2;
+ T1_Byte* cur;
+ T1_Byte* start;
+ T1_Int n;
+
+ /* read each parameter independently */
+ cur = base;
+ for ( n = 0; n < max_elements; n++ )
+ {
+ T1_Long result;
+
+ /* test end of string */
+ if (cur >= limit)
+ break;
+
+ /* skip whitespace */
+ while (cur < limit && *cur == ' ') cur++;
+
+ /* end of list ? */
+ if (cur >= limit)
+ break;
+
+ /* skip numbers */
+ start = cur;
+ while (cur < limit && *cur != ' ') cur++;
+
+ error = parse_integer( start, cur, &result );
+ if (error) goto Fail;
+
+ *elements ++ = (T1_Short)result;
+ }
+
+ if (num_elements)
+ *num_elements = (T1_Byte)n;
+
+ parser->error = 0;
+ return;
+ }
+
+ Fail:
+ FT_ERROR(( "T1.CopyArray : syntax error !\n" ));
+ parser->error = T1_Err_Syntax_Error;
+ }
+
--- /dev/null
+++ b/src/type1/t1parse.h
@@ -1,0 +1,296 @@
+/*******************************************************************
+ *
+ * t1parse.h 1.0
+ *
+ * Type1 parser.
+ *
+ * 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.
+ *
+ *
+ * The Type1 parser component is in charge of simply parsing
+ * the font input stream and convert simple tokens and elements
+ * into integers, floats, matrices, strings, etc..
+ *
+ * It is used by the Type1 loader..
+ *
+ ******************************************************************/
+
+#ifndef T1PARSE_H
+#define T1PARSE_H
+
+#include <ftstream.h>
+#include <t1tokens.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/*************************************************************************
+ *
+ * <Enum> T1_DictState
+ *
+ * <Description>
+ * An enumeration used to describe the Type 1 parser's state, i.e.
+ * which dictionary (or array) it is scanning and processing at the
+ * current moment..
+ *
+ */
+ typedef enum T1_DictState_
+ {
+ dict_none = 0,
+ dict_font, /* parsing the font dictionary */
+ dict_fontinfo, /* parsing the font info dictionary */
+ dict_none2, /* beginning to parse the encrypted section */
+ dict_private, /* parsing the private dictionary */
+ dict_encoding, /* parsing the encoding array */
+ dict_subrs, /* parsing the subrs array */
+ dict_othersubrs, /* parsing the othersubrs array (?) */
+ dict_charstrings, /* parsing the charstrings dictionary */
+ dict_unknown_array, /* parsing/ignoring an unknown array */
+ dict_unknown_dict, /* parsing/ignoring an unknown dictionary */
+
+ dict_max /* do not remove from list */
+
+ } T1_DictState;
+
+
+ typedef enum T1_EncodingType_
+ {
+ encoding_none = 0,
+ encoding_array,
+ encoding_standard,
+ encoding_expert
+
+ } T1_EncodingType;
+/*************************************************************************
+ *
+ * <Struct> T1_Table
+ *
+ * <Description>
+ * A T1_Table is a simple object used to store an array of objects
+ * in a single memory block.
+ *
+ * <Fields>
+ * block :: address in memory of the growheap's block. This
+ * can change between two object adds, due to the use
+ * of 'realloc'.
+ *
+ * cursor :: current top of the grow heap within its block
+ *
+ * capacity :: current size of the heap block. Increments by 1 Kb
+ *
+ * max_elems :: maximum number of elements in table
+ * num_elems :: current number of elements in table
+ *
+ * elements :: table of element addresses within the block
+ * lengths :: table of element sizes within the block
+ *
+ * system :: system object used for memory operations (alloc/realloc)
+ */
+
+ typedef struct T1_Table_
+ {
+ T1_Byte* block; /* current memory block */
+ T1_Int cursor; /* current cursor in memory block */
+ T1_Int capacity; /* current size of memory block */
+
+ T1_Int max_elems;
+ T1_Int num_elems;
+ T1_Byte** elements; /* addresses of table elements */
+ T1_Int* lengths; /* lengths of table elements */
+
+ FT_Memory memory;
+
+ } T1_Table;
+
+
+
+
+/*************************************************************************/
+/* */
+/* <Struct> T1_Parser */
+/* */
+/* <Description> */
+/* A Type 1 parser. This object is in charge of parsing Type 1 */
+/* ASCII streams and builds dictionaries for a T1_Face object. */
+/* */
+/* <Fields> */
+/* error :: */
+/* current error code. 0 means success */
+/* */
+/* face :: */
+/* the target T1_Face object being built */
+/* */
+/* tokenizer :: */
+/* the tokenizer (lexical analyser) used for processing the */
+/* input stream. */
+/* */
+/* stack :: */
+/* the current token stack. Note that we don't use intermediate */
+/* Postscript objects here ! */
+/* */
+/* top :: */
+/* current top of token stack */
+/* */
+/* limit :: */
+/* current upper bound of the token stack. Used for overflow */
+/* checks.. */
+/* */
+/* args :: */
+/* arguments of a given operator. used and increased by the */
+/* Copy.... functions.. */
+/* */
+/* state_index :: */
+/* index of top of the dictionary state stack */
+/* */
+/* state_stack :: */
+/* dictionary states stack */
+/* */
+/* table :: */
+/* a T1_Table object used to record various kinds of */
+/* dictionaries or arrays (like /Encoding, /Subrs, /CharStrings) */
+/* */
+/* */
+ typedef struct T1_Parser_
+ {
+ T1_Error error;
+ T1_Face face;
+
+ T1_Tokenizer tokenizer;
+ T1_Bool dump_tokens;
+
+ T1_Token stack[ T1_MAX_STACK_DEPTH ];
+ T1_Token* top;
+ T1_Token* limit;
+ T1_Token* args;
+
+ T1_Int state_index;
+ T1_DictState state_stack[ T1_MAX_DICT_DEPTH ];
+
+ T1_Table table;
+
+ T1_Int cur_name;
+
+ T1_EncodingType encoding_type;
+ T1_Byte* encoding_names;
+ T1_Int* encoding_lengths;
+ T1_Byte** encoding_offsets;
+
+ T1_Byte* subrs;
+ T1_Byte* charstrings;
+
+ } T1_Parser;
+
+
+
+/*************************************************************************/
+/* */
+/* <Function> T1_New_Table */
+/* */
+/* <Description> */
+/* Initialise a T1_Table. */
+/* */
+/* <Input> */
+/* table :: address of target table */
+/* count :: table size = maximum number of elements */
+/* system :: system object to use for all subsequent reallocations */
+/* */
+/* <Return> */
+/* Error code. 0 means success */
+/* */
+ LOCAL_DEF
+ T1_Error T1_New_Table( T1_Table* table,
+ T1_Int count,
+ FT_Memory memory );
+
+
+/*************************************************************************/
+/* */
+/* <Function> T1_Add_Table */
+/* */
+/* <Description> */
+/* Adds an object to a T1_Table, possibly growing its memory block */
+/* */
+/* <Input> */
+/* table :: target table */
+/* index :: index of object in table */
+/* object :: address of object to copy in memory */
+/* length :: length in bytes of source object */
+/* */
+/* <Return> */
+/* Error code. 0 means success. An error is returned when a */
+/* realloc failed.. */
+/* */
+ LOCAL_DEF
+ T1_Error T1_Add_Table( T1_Table* table,
+ T1_Int index,
+ void* object,
+ T1_Int length );
+
+
+/*************************************************************************/
+/* */
+/* <Function> T1_Done_Table */
+/* */
+/* <Description> */
+/* Finalise a T1_Table. (realloc it to its current cursor). */
+/* */
+/* <Input> */
+/* table :: target table */
+/* */
+/* <Note> */
+/* This function does NOT release the heap's memory block. It is up */
+/* to the caller to clean it, or reference it in its own structures. */
+/* */
+ LOCAL_DEF
+ void T1_Done_Table( T1_Table* table );
+
+
+
+
+ LOCAL_DEF
+ T1_String* CopyString( T1_Parser* parser );
+
+
+ LOCAL_DEF
+ T1_Long CopyInteger( T1_Parser* parser );
+
+
+ LOCAL_DEF
+ T1_Bool CopyBoolean( T1_Parser* parser );
+
+
+ LOCAL_DEF
+ T1_Long CopyFloat( T1_Parser* parser,
+ T1_Int scale );
+
+ LOCAL_DEF
+ void CopyBBox( T1_Parser* parser,
+ T1_BBox* bbox );
+
+ LOCAL_DEF
+ void CopyMatrix( T1_Parser* parser,
+ T1_Matrix* matrix );
+
+ LOCAL_DEF
+ void CopyArray( T1_Parser* parser,
+ T1_Byte* num_elements,
+ T1_Short* elements,
+ T1_Int max_elements );
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* T1PARSE_H */
+
+
+/* END */
+
--- /dev/null
+++ b/src/type1/t1tokens.c
@@ -1,0 +1,994 @@
+/*******************************************************************
+ *
+ * t1tokens.c
+ *
+ * Type 1 tokenizer
+ *
+ * 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.
+ *
+ *
+ * The tokenizer is in charge of loading and reading a Type1 font
+ * file (either in PFB or PFA format), and extract successive tokens
+ * and keywords from its two streams (i.e. the font program, and the
+ * private dictionary).
+ *
+ * Eexec decryption is performed automatically when entering the
+ * private dictionary, or when retrieving char strings..
+ *
+ ******************************************************************/
+
+#include <ftstream.h>
+#include <ftdebug.h>
+
+#include <t1tokens.h>
+#include <t1load.h>
+
+#undef READ_BUFFER_INCREMENT
+#define READ_BUFFER_INCREMENT 0x400
+
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_t1load
+
+ /* array of Type1 keywords supported by this engine. This table places */
+ /* the keyword in lexicographical order. It should always correspond */
+ /* to the enums key_XXXX !! */
+ /* */
+ const char* t1_keywords[ key_max - key_first_ ] =
+ {
+ "-|", "ExpertEncoding", "ND", "NP", "RD", "StandardEncoding", "array",
+ "begin", "closefile", "currentdict", "currentfile", "def", "dict", "dup",
+ "eexec", "end", "executeonly", "false", "for", "index", "noaccess",
+ "put", "readonly", "true", "userdict", "|", "|-"
+ };
+
+
+
+ const char* t1_immediates[ imm_max - imm_first_ ] =
+ {
+ "-|", ".notdef", "BlueFuzz", "BlueScale", "BlueShift", "BlueValues",
+ "CharStrings", "Encoding", "FamilyBlues", "FamilyName", "FamilyOtherBlues",
+ "FID", "FontBBox", "FontID", "FontInfo", "FontMatrix", "FontName",
+ "FontType", "ForceBold", "FullName", "ItalicAngle", "LanguageGroup",
+ "Metrics", "MinFeature", "ND", "NP", "Notice", "OtherBlues", "OtherSubrs",
+ "PaintType", "Private", "RD", "RndStemUp", "StdHW", "StdVW", "StemSnapH",
+ "StemSnapV", "StrokeWidth", "Subrs", "UnderlinePosition",
+ "UnderlineThickness", "UniqueID", "Weight", "isFixedPitch", "lenIV",
+ "password", "version", "|", "|-"
+ };
+
+
+ /* lexicographic comparison of two strings */
+ static
+ int lexico_strcmp( const char* str1,
+ int str1_len,
+ const char* str2 )
+ {
+ int c2 = 0;
+
+ for ( ; str1_len > 0; str1_len-- )
+ {
+ int c1, diff;
+
+ c1 = *str1++;
+ c2 = *str2++;
+
+ diff = c1 - c2;
+ if (diff) return diff;
+ };
+ return -*str2;
+ }
+
+
+ /* Find a given token/name, perform binary search */
+ static
+ int Find_Name( char* base, int length,
+ const char** table, int table_len )
+ {
+ /* performs a binary search */
+
+ T1_Int left, right;
+
+ left = 0;
+ right = table_len-1;
+
+ while ( right-left > 1 )
+ {
+ T1_Int middle = left + (( right-left ) >> 1);
+ T1_Int cmp;
+
+ cmp = lexico_strcmp( base, length, table[middle] );
+ if (!cmp) return middle;
+
+ if ( cmp < 0 )
+ right = middle;
+ else
+ left = middle;
+ }
+
+ if ( !lexico_strcmp( base, length, table[left ] ) ) return left;
+ if ( !lexico_strcmp( base, length, table[right] ) ) return right;
+
+ return -1;
+ }
+
+
+ /* read the small PFB section header */
+ static
+ T1_Error Read_PFB_Tag( FT_Stream stream,
+ T1_UShort* atag,
+ T1_ULong* asize )
+ {
+ T1_UShort tag;
+ T1_ULong size;
+ T1_Error error;
+
+ FT_TRACE2(( "Read_PFB_Tag : reading\n" ));
+
+ if ( ACCESS_Frame( 6L ) ) return error;
+
+ tag = GET_UShort();
+ size = GET_ULong();
+
+ FORGET_Frame();
+
+ *atag = tag;
+ *asize = ( (size & 0xFF) << 24 ) |
+ ( ((size >> 8) & 0xFF) << 16 ) |
+ ( ((size >> 16) & 0xFF) << 8 ) |
+ ( ((size >> 24) & 0xFF) );
+
+ FT_TRACE2(( " tag = %04x\n", tag ));
+ FT_TRACE4(( " asze = %08x\n", size ));
+ FT_TRACE2(( " size = %08x\n", *asize ));
+
+ return T1_Err_Ok;
+ }
+
+
+
+ static
+ T1_Error grow( T1_Tokenizer tokzer )
+ {
+ T1_Error error;
+ T1_Long left_bytes;
+ FT_Memory memory = tokzer->memory;
+
+ left_bytes = tokzer->max - tokzer->limit;
+
+ if ( left_bytes > 0 )
+ {
+ FT_Stream stream = tokzer->stream;
+
+ if ( left_bytes > READ_BUFFER_INCREMENT )
+ left_bytes = READ_BUFFER_INCREMENT;
+
+ FT_TRACE2(( "Growing tokenizer buffer by %d bytes\n", left_bytes ));
+
+ (void)stream; /* unused in non reentrant mode */
+
+ if ( !REALLOC( tokzer->base, tokzer->limit,
+ tokzer->limit + left_bytes ) &&
+ !FILE_Read( tokzer->base + tokzer->limit, left_bytes ) )
+ tokzer->limit += left_bytes;
+ }
+ else
+ {
+ FT_ERROR(( "Unexpected end of Type1 fragment !!\n" ));
+ error = T1_Err_Invalid_File_Format;
+ }
+
+ tokzer->error = error;
+ return error;
+ }
+
+
+
+
+ LOCAL_FUNC
+ void t1_decrypt( T1_Byte* buffer,
+ T1_Int length,
+ T1_UShort seed )
+ {
+ while ( length > 0 )
+ {
+ T1_Byte plain;
+
+ plain = (*buffer ^ (seed >> 8));
+ seed = (*buffer+seed)*52845+22719;
+ *buffer++ = plain;
+ length--;
+ }
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> New_Tokenizer */
+ /* */
+ /* <Description> */
+ /* Creates a new tokenizer from a given input stream. This function */
+ /* automatically recognizes "pfa" or "pfb" files. The function */
+ /* "Read_Token" can then be used to extract successive tokens from */
+ /* the stream.. */
+ /* */
+ /* <Input> */
+ /* stream :: input stream */
+ /* */
+ /* <Output> */
+ /* tokenizer :: handle to new tokenizer object.. */
+ /* */
+ /* <Return> */
+ /* Type1 error code. 0 means success.. */
+ /* */
+ /* <Note> */
+ /* This function copies the stream handle within the object. Callers */
+ /* should not discard "stream". This is done by the Done_Tokenizer */
+ /* function.. */
+ /* */
+
+ LOCAL_FUNC
+ T1_Error New_Tokenizer( FT_Stream stream,
+ T1_Tokenizer* tokenizer )
+ {
+ FT_Memory memory = stream->memory;
+ T1_Tokenizer tokzer;
+ T1_Error error;
+ T1_UShort tag;
+ T1_ULong size;
+
+ T1_Byte* tok_base;
+ T1_ULong tok_limit;
+ T1_ULong tok_max;
+
+ *tokenizer = 0;
+
+ /* allocate object */
+ if ( FILE_Seek( 0L ) ||
+ ALLOC( tokzer, sizeof(*tokzer) ) )
+ return error;
+
+ tokzer->stream = stream;
+ tokzer->memory = stream->memory;
+
+ tokzer->in_pfb = 0;
+ tokzer->in_private = 0;
+
+ tok_base = 0;
+ tok_limit = 0;
+ tok_max = stream->size;
+
+ error = Read_PFB_Tag( stream, &tag, &size );
+ if (error) goto Fail;
+
+ if ( tag != 0x8001 )
+ {
+ /* assume that it is a PFA file - an error will be produced later */
+ /* if a character with value > 127 is encountered.. */
+
+ /* rewind to start of file */
+ if ( FILE_Seek(0L) ) goto Fail;
+
+ size = stream->size;
+ }
+ else
+ tokzer->in_pfb = 1;
+
+ /* if it's a memory-based resource, set up pointer */
+ if ( !stream->read )
+ {
+ tok_base = (T1_Byte*)stream->base + stream->pos;
+ tok_limit = size;
+ tok_max = size;
+
+ /* check that the "size" field is valid */
+ if ( FILE_Skip(size) ) goto Fail;
+ }
+ else if ( tag == 0x8001 )
+ {
+ /* read segment in memory */
+ if ( ALLOC( tok_base, size ) )
+ goto Fail;
+
+ if ( FILE_Read( tok_base, size ) )
+ {
+ FREE( tok_base );
+ goto Fail;
+ }
+
+ tok_limit = size;
+ tok_max = size;
+ }
+
+ tokzer->base = tok_base;
+ tokzer->limit = tok_limit;
+ tokzer->max = tok_max;
+ tokzer->cursor = 0;
+
+ *tokenizer = tokzer;
+
+ /* Now check font format, we must see a '%!PS-AdobeFont-1' */
+ /* or a '%!FontType' */
+ {
+ if ( 16 > tokzer->limit )
+ grow( tokzer );
+
+ if ( tokzer->limit <= 16 ||
+ ( strncmp( (const char*)tokzer->base, "%!PS-AdobeFont-1", 16 ) &&
+ strncmp( (const char*)tokzer->base, "%!FontType", 10 ) ) )
+ {
+ FT_TRACE2(( "Not a Type1 font\n" ));
+ error = T1_Err_Invalid_File_Format;
+ goto Fail;
+ }
+ }
+ return T1_Err_Ok;
+
+ Fail:
+ FREE( tokzer );
+ return error;
+ }
+
+
+
+ /* return the value of an hexadecimal digit */
+ static
+ int hexa_value( char c )
+ {
+ unsigned int d;
+
+ d = (unsigned int)(c-'0');
+ if ( d <= 9 ) return (int)d;
+
+ d = (unsigned int)(c-'a');
+ if ( d <= 5 ) return (int)(d+10);
+
+ d = (unsigned int)(c-'A');
+ if ( d <= 5 ) return (int)(d+10);
+
+ return -1;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> Done_Tokenizer */
+ /* */
+ /* <Description> */
+ /* Closes a given tokenizer. This function will also close the */
+ /* stream embedded in the object.. */
+ /* */
+ /* <Input> */
+ /* tokenizer :: target tokenizer object */
+ /* */
+ /* <Return> */
+ /* Type1 error code. 0 means success.. */
+ /* */
+
+ LOCAL_FUNC
+ T1_Error Done_Tokenizer( T1_Tokenizer tokenizer )
+ {
+ FT_Memory memory = tokenizer->memory;
+
+ /* clear read buffer if needed (disk-based resources) */
+ if ( tokenizer->in_private || !tokenizer->stream->base )
+ FREE( tokenizer->base );
+
+ FREE( tokenizer );
+ return T1_Err_Ok;
+ }
+
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> Open_PrivateDict */
+ /* */
+ /* <Description> */
+ /* This function must be called to set the tokenizer to the private */
+ /* section of the Type1 file. It recognizes automatically the */
+ /* the kind of eexec encryption used (ascii or binary).. */
+ /* */
+ /* <Input> */
+ /* tokenizer :: target tokenizer object */
+ /* lenIV :: value of the "lenIV" variable.. */
+ /* */
+ /* <Return> */
+ /* Type1 error code. 0 means success.. */
+ /* */
+
+ LOCAL_FUNC
+ T1_Error Open_PrivateDict( T1_Tokenizer tokenizer )
+ {
+ T1_Tokenizer tokzer = tokenizer;
+ FT_Stream stream = tokzer->stream;
+ FT_Memory memory = tokzer->memory;
+ T1_Error error = 0;
+
+ T1_UShort tag;
+ T1_ULong size;
+
+ T1_Byte* private;
+
+ /* are we already in the private dictionary ? */
+ if ( tokzer->in_private )
+ return 0;
+
+ if ( tokzer->in_pfb )
+ {
+ /* in the case of the PFB format, the private dictionary can be */
+ /* made of several segments. We thus first read the number of */
+ /* segments to compute the total size of the private dictionary */
+ /* then re-read them into memory.. */
+ T1_Long start_pos = FILE_Pos();
+ T1_ULong private_size = 0;
+
+ do
+ {
+ error = Read_PFB_Tag( stream, &tag, &size );
+ if (error || tag != 0x8002) break;
+
+ private_size += size;
+
+ if ( FILE_Skip(size) )
+ goto Fail;
+ }
+ while (1);
+
+ /* Check that we have a private dictionary there */
+ /* and allocate private dictionary buffer */
+ if ( private_size == 0 )
+ {
+ FT_ERROR(( "T1.Open_Private: invalid private dictionary section\n" ));
+ error = T1_Err_Invalid_File_Format;
+ goto Fail;
+ }
+
+ if ( ALLOC( private, private_size ) )
+ goto Fail;
+
+ /* read all sections into buffer */
+ if ( FILE_Seek( start_pos ) )
+ goto Fail_Private;
+
+ private_size = 0;
+ do
+ {
+ error = Read_PFB_Tag( stream, &tag, &size );
+ if (error || tag != 0x8002) { error = 0; break; }
+
+ if ( FILE_Read( private + private_size, size ) )
+ goto Fail_Private;
+
+ private_size += size;
+ }
+ while (1);
+
+ tokzer->base = private;
+ tokzer->cursor = 0;
+ tokzer->limit = private_size;
+ tokzer->max = private_size;
+ }
+ else
+ {
+ char* base;
+
+ /* we're in a PFA file, read each token until we find "eexec" */
+ while ( tokzer->token.kind2 != key_eexec )
+ {
+ error = Read_Token( tokzer );
+ if (error) goto Fail;
+ }
+
+ /* now determine wether the private dictionary is encoded in binary */
+ /* or hexadecimal ASCII format.. */
+
+ /* we need to access the next 4 bytes (after the final \r following */
+ /* the 'eexec' keyword..) if they all are hexadecimal digits, then */
+ /*we have a case of ASCII storage.. */
+ while ( tokzer->cursor+5 > tokzer->limit )
+ {
+ error = grow( tokzer );
+ if (error) goto Fail;
+ }
+
+ /* skip whitespace/line feed after "eexec" */
+ base = (char*)tokzer->base + tokzer->cursor + 1;
+ if ( ( hexa_value( base[0] ) | hexa_value( base[1] ) |
+ hexa_value( base[2] ) | hexa_value( base[3] ) ) < 0 )
+ {
+ /* binary encoding - "simply" read the stream */
+
+ /* if it's a memory-based resource, we need to allocate a new */
+ /* storage buffer for the private dictionary, as it needs to */
+ /* be decrypted later.. */
+ if ( stream->base )
+ {
+ size = stream->size - tokzer->cursor-1; /* remaining bytes */
+
+ if ( ALLOC( private, size ) ) /* allocate private dict buffer */
+ goto Fail;
+
+ /* copy eexec-encrypted bytes */
+ MEM_Copy( private, tokzer->base + tokzer->cursor+1, size );
+
+ /* reset pointers - forget about file mapping */
+ tokzer->base = private;
+ tokzer->limit = size;
+ tokzer->max = size;
+ tokzer->cursor = 0;
+ }
+ /* on the opposite, for disk based resources, we simply grow */
+ /* the current buffer until its completion, and decrypt the */
+ /* bytes within it. In all cases, the "base" buffer will be */
+ /* discarded on DoneTokenizer if we're in the private dict.. */
+ else
+ {
+ /* grow the read buffer to the full file.. */
+ while ( tokzer->limit < tokzer->max )
+ {
+ error = grow( tokenizer );
+ if (error) goto Fail;
+ }
+
+ /* set up cursor to first encrypted byte */
+ tokzer->cursor++;
+ }
+ }
+ else
+ {
+ /* ASCII hexadecimal encoding.. This sucks.. */
+ T1_Byte* write;
+ T1_Byte* cur;
+ T1_Byte* limit;
+ T1_Int count;
+
+ /* Allocate a buffer, read each one byte at a time .. */
+ count = ( stream->size - tokzer->cursor );
+ size = count/2;
+
+ if ( ALLOC( private, size ) ) /* allocate private dict buffer */
+ goto Fail;
+
+ write = private;
+ cur = tokzer->base + tokzer->cursor;
+ limit = tokzer->base + tokzer->limit;
+
+ /* read each bytes */
+ while ( count > 0 )
+ {
+ /* ensure that we can read the next 2 bytes !! */
+ while ( cur+2 > limit )
+ {
+ int cursor = cur - tokzer->base;
+ error = grow( tokzer );
+ if (error) goto Fail_Private;
+ cur = tokzer->base + cursor;
+ limit = tokzer->base + tokzer->limit;
+ }
+
+ /* check for new line */
+ if ( cur[0] == '\r' || cur[0] == '\n' )
+ {
+ cur++;
+ count--;
+ }
+ else
+ {
+ int hex1 = hexa_value(cur[0]);
+
+ /* exit if we have a non hexa-decimal digit which isn't */
+ /* a new-line character.. */
+ if (hex1 < 0)
+ break;
+
+ /* otherwise, store byte */
+ *write++ = ( hex1 << 4 ) | hexa_value( cur[1] );
+ cur += 2;
+ count -= 2;
+ }
+ }
+
+ /* get rid of old buffer in the case of disk-based resources */
+ if ( !stream->base )
+ FREE( tokzer->base );
+
+ /* set up pointers */
+ tokzer->base = private;
+ tokzer->limit = size;
+ tokzer->max = size;
+ tokzer->cursor = 0;
+ }
+ }
+
+ /* finally, decrypt the private dictionary - and skip the lenIV bytes */
+ t1_decrypt( tokzer->base, tokzer->limit, 55665 );
+ tokzer->cursor += 4;
+
+ Fail:
+ return error;
+
+ Fail_Private:
+ FREE( private );
+ goto Fail;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> Read_Token */
+ /* */
+ /* <Description> */
+ /* Read a new token from the current input stream. This function */
+ /* extracts a token from the font program until "Open_PrivateDict" */
+ /* has been called. After this, it returns tokens from the */
+ /* (eexec-encrypted) private dictionnary.. */
+ /* */
+ /* <Input> */
+ /* tokenizer :: target tokenizer object */
+ /* */
+ /* <Return> */
+ /* Type1 error code. 0 means success.. */
+ /* */
+ /* <Note> */
+ /* One should use the function Read_CharStrings to read the binary */
+ /* charstrings from the private dict.. */
+ /* */
+ LOCAL_FUNC
+ T1_Error Read_Token( T1_Tokenizer tokenizer )
+ {
+ T1_Tokenizer tok = tokenizer;
+ T1_Long cur, limit;
+ T1_Byte* base;
+ char c, starter, ender;
+ T1_Bool token_started;
+
+ T1_TokenType kind;
+
+ tok->error = T1_Err_Ok;
+ tok->token.kind = tok_any;
+
+ base = tok->base;
+ limit = tok->limit;
+ cur = tok->cursor;
+
+ token_started = 0;
+
+ for (;;)
+ {
+ if ( cur >= limit )
+ {
+ if ( grow( tok ) ) goto Exit;
+ base = tok->base;
+ limit = tok->limit;
+ }
+
+ c = (char)base[cur++];
+
+ /* check that we have an ASCII character */
+ if ( (T1_Byte)c > 127 )
+ {
+ FT_ERROR(( "Unexpected binary data in Type1 fragment !!\n" ));
+ tok->error = T1_Err_Invalid_File_Format;
+ goto Exit;
+ }
+
+ switch (c)
+ {
+ case '\r' :
+ case '\n' :
+ case ' ' :
+ case '\t' : /* skip initial whitespace => skip to next */
+ if (token_started)
+ {
+ /* possibly a name, keyword, wathever */
+ tok->token.kind = tok_any;
+ tok->token.len = cur-tok->token.start-1;
+ goto Exit;
+ }
+ /* otherwise, skip everything */
+ break;
+
+
+ case '%' : /* this is a comment - skip everything */
+ for (;;)
+ {
+ T1_Int left = limit - cur;
+
+ while (left > 0)
+ {
+ c = (char)base[cur++];
+ if ( c == '\r' || c == '\n' )
+ goto Next;
+ left--;
+ }
+ if ( grow( tokenizer ) ) goto Exit;
+ base = tok->base;
+ limit = tok->limit;
+ }
+
+
+ case '(' : /* a Postscript string */
+ kind = tok_string;
+ ender = ')';
+
+ L1:
+ if (!token_started)
+ {
+ token_started = 1;
+ tok->token.start = cur-1;
+ }
+
+ {
+ T1_Int nest_level = 1;
+
+ starter = c;
+ for (;;)
+ {
+ T1_Int left = limit-cur;
+ while (left > 0)
+ {
+ c = (char)base[cur++];
+
+ if ( c == starter )
+ nest_level++;
+
+ else if ( c == ender )
+ {
+ nest_level--;
+ if (nest_level <= 0)
+ {
+ tok->token.kind = kind;
+ tok->token.len = cur - tok->token.start;
+ goto Exit;
+ }
+ }
+ left--;
+ }
+
+ if ( grow( tok ) ) goto Exit;
+ base = tok->base;
+ limit = tok->limit;
+ }
+ }
+
+
+ case '[' : /* a Postscript array */
+ if (token_started)
+ goto Any_Token;
+
+ kind = tok_array;
+ ender = ']';
+ goto L1;
+ break;
+
+
+ case '{' : /* a Postscript program */
+ if (token_started)
+ goto Any_Token;
+
+ kind = tok_program;
+ ender = '}';
+ goto L1;
+ break;
+
+
+ case '<' : /* a Postscript hex byte array ?? */
+ if (token_started)
+ goto Any_Token;
+
+ kind = tok_hexarray;
+ ender = '>';
+ goto L1;
+ break;
+
+
+ case '0': /* any number */
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (token_started)
+ goto Next;
+
+ tok->token.kind = tok_number;
+ token_started = 1;
+ tok->token.start = cur-1;
+ L2:
+ for (;;)
+ {
+ T1_Int left = limit-cur;
+ while (left > 0)
+ {
+ c = (char)base[cur++];
+
+ switch (c)
+ {
+ case '[':
+ case '{':
+ case '(':
+ case '<':
+ case '/':
+ goto Any_Token;
+
+ case ' ':
+ case '\r':
+ case '\t':
+ case '\n':
+ tok->token.len = cur - tok->token.start - 1;
+ goto Exit;
+
+ default:
+ ;
+ }
+ left--;
+ }
+ if (grow( tok )) goto Exit;
+ base = tok->base;
+ limit = tok->limit;
+ }
+
+
+ case '.': /* maybe a number */
+ case '-':
+ case '+':
+ if (token_started)
+ goto Next;
+
+ token_started = 1;
+ tok->token.start = cur-1;
+ for (;;)
+ {
+ T1_Int left = limit-cur;
+ if ( left > 0 )
+ {
+ /* test for any following digit, interpreted as number */
+ c = (char)base[cur];
+ tok->token.kind = ( c >= '0' && c <= '9' ? tok_number : tok_any );
+ goto L2;
+ }
+ if (grow( tok )) goto Exit;
+ base = tok->base;
+ limit = tok->limit;
+ }
+
+ case '/': /* maybe an immediate name */
+ if (!token_started)
+ {
+ token_started = 1;
+ tok->token.start = cur-1;
+
+ for (;;)
+ {
+ T1_Int left = limit-cur;
+ if ( left > 0 )
+ {
+ /* test for single '/', interpreted as garbage */
+ c = (char)base[cur];
+ tok->token.kind = ( c == ' ' || c == '\t' ||
+ c == '\r' || c == '\n' ?
+ tok_any : tok_immediate );
+ goto L2;
+ }
+ if (grow( tok )) goto Exit;
+ base = tok->base;
+ limit = tok->limit;
+ }
+ }
+ else
+ {
+ Any_Token: /* possibly a name or wathever */
+ cur--;
+ tok->token.len = cur - tok->token.start;
+ goto Exit;
+ }
+
+ default:
+ if (!token_started)
+ {
+ token_started = 1;
+ tok->token.start = cur-1;
+ }
+ }
+
+ Next:
+ ;
+ }
+
+ Exit:
+ tok->cursor = cur;
+
+ if (!tok->error)
+ {
+ /* now, tries to match keywords and immediate names */
+ T1_Int index;
+
+ switch ( tok->token.kind )
+ {
+ case tok_immediate : /* immediate name */
+ index = Find_Name( (char*)(tok->base + tok->token.start+1),
+ tok->token.len-1,
+ t1_immediates,
+ imm_max - imm_first_ );
+ tok->token.kind2 = ( index >= 0 ? imm_first_ + index : 0 );
+ break;
+
+
+ case tok_any : /* test for keyword */
+ index = Find_Name( (char*)(tok->base + tok->token.start),
+ tok->token.len,
+ t1_keywords,
+ key_max - key_first_ );
+ if ( index >= 0 )
+ {
+ tok->token.kind = tok_keyword;
+ tok->token.kind2 = key_first_ + index;
+ }
+ else
+ tok->token.kind2 = 0;
+ break;
+
+ default:
+ tok->token.kind2 = 0;
+ }
+ }
+ return tokenizer->error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> Read_CharStrings */
+ /* */
+ /* <Description> */
+ /* Read a charstrings from the current input stream. These are */
+ /* binary bytes that encode each individual glyph outline. */
+ /* */
+ /* The caller is responsible for skipping the "lenIV" bytes at */
+ /* the start of the record.. */
+ /* */
+ /* <Input> */
+ /* tokenizer :: target tokenizer object */
+ /* num_chars :: number of binary bytes to read */
+ /* */
+ /* <Output> */
+ /* buffer :: target array of bytes. These are eexec-decrypted.. */
+ /* */
+ /* <Return> */
+ /* Type1 error code. 0 means success.. */
+ /* */
+ /* <Note> */
+ /* One should use the function Read_CharStrings to read the binary */
+ /* charstrings from the private dict.. */
+ /* */
+ LOCAL_FUNC
+ T1_Error Read_CharStrings( T1_Tokenizer tokenizer,
+ T1_Int num_chars,
+ T1_Byte* buffer )
+ {
+ for (;;)
+ {
+ T1_Int left = tokenizer->limit - tokenizer->cursor;
+
+ if ( left >= num_chars )
+ {
+ MEM_Copy( buffer, tokenizer->base + tokenizer->cursor, num_chars );
+ t1_decrypt( buffer, num_chars, 4330 );
+ tokenizer->cursor += num_chars;
+ return T1_Err_Ok;
+ }
+
+ if ( grow(tokenizer) ) return tokenizer->error;
+ }
+ }
+
--- /dev/null
+++ b/src/type1/t1tokens.h
@@ -1,0 +1,352 @@
+/*******************************************************************
+ *
+ * t1tokens.h
+ *
+ * Type 1 tokenizer
+ *
+ * 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.
+ *
+ * The tokenizer is in charge of loading and reading a Type1 font
+ * file (either in PFB or PFA format), and extract successive tokens
+ * and keywords from its two streams (i.e. the font program, and the
+ * private dictionary).
+ *
+ * Eexec decryption is performed automatically when entering the
+ * private dictionary, or when retrieving char strings..
+ *
+ ******************************************************************/
+
+#ifndef T1TOKENS_H
+#define T1TOKENS_H
+
+#include <t1objs.h>
+
+/* enum value of first keyword */
+#define key_first_ 100
+
+/* enum value of first immediate name */
+#define imm_first_ 200
+
+ typedef enum T1_TokenType_
+ {
+ tok_error = 0,
+
+ tok_eof, /* end of file */
+
+ /* simple token types */
+
+ tok_keyword, /* keyword */
+ tok_number, /* number (integer or real) */
+ tok_string, /* postscript string */
+ tok_program, /* postscript program */
+ tok_immediate, /* any immediate name */
+ tok_array, /* matrix, array, etc.. */
+ tok_hexarray, /* array of hexadecimal nibbles */
+ tok_any, /* anything else */
+
+ /* Postscript keywords - placed in lexicographical order */
+
+ key_RD_alternate = key_first_, /* "-|" = alternate form of RD */
+ key_ExpertEncoding,
+ key_ND,
+ key_NP,
+ key_RD,
+ key_StandardEncoding,
+ key_array,
+ key_begin,
+ key_closefile,
+ key_currentdict,
+ key_currentfile,
+ key_def,
+ key_dict,
+ key_dup,
+ key_eexec,
+ key_end,
+ key_execonly,
+ key_false,
+ key_for,
+ key_index,
+ key_noaccess,
+ key_put,
+ key_readonly,
+ key_true,
+ key_userdict,
+ key_NP_alternate, /* "|" = alternate form of NP */
+ key_ND_alternate, /* "|-" = alternate form of ND */
+
+ key_max, /* always keep this value there */
+
+ /* Postscript immediate names - other names will be ignored, except */
+ /* in charstrings.. */
+
+ imm_RD_alternate = imm_first_, /* "-|" = alternate form of RD */
+ imm_notdef, /* "/.notdef" immediate */
+ imm_BlueFuzz,
+ imm_BlueScale,
+ imm_BlueShift,
+ imm_BlueValues,
+ imm_CharStrings,
+ imm_Encoding,
+ imm_FamilyBlues,
+ imm_FamilyName,
+ imm_FamilyOtherBlues,
+ imm_FID,
+ imm_FontBBox,
+ imm_FontID,
+ imm_FontInfo,
+ imm_FontMatrix,
+ imm_FontName,
+ imm_FontType,
+ imm_ForceBold,
+ imm_FullName,
+ imm_ItalicAngle,
+ imm_LanguageGroup,
+ imm_Metrics,
+ imm_MinFeature,
+ imm_ND,
+ imm_NP,
+ imm_Notice,
+ imm_OtherBlues,
+ imm_OtherSubrs,
+ imm_PaintType,
+ imm_Private,
+ imm_RD,
+ imm_RndStemUp,
+ imm_StdHW,
+ imm_StdVW,
+ imm_StemSnapH,
+ imm_StemSnapV,
+ imm_StrokeWidth,
+ imm_Subrs,
+ imm_UnderlinePosition,
+ imm_UnderlineThickness,
+ imm_UniqueID,
+ imm_Weight,
+
+ imm_isFixedPitch,
+ imm_lenIV,
+ imm_password,
+ imm_version,
+
+ imm_NP_alternate, /* "|" = alternate form of NP */
+ imm_ND_alternate, /* "|-" = alternate form of ND */
+
+ imm_max /* always keep this value here */
+
+ } T1_TokenType;
+
+
+ /* these arrays are visible for debugging purposes.. */
+ extern const char* t1_keywords[];
+ extern const char* t1_immediates[];
+
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> T1_Token */
+ /* */
+ /* <Description> */
+ /* A structure used to describe a token in the current input */
+ /* stream. Note that the Type1 driver doesn't try to interpret */
+ /* tokens until it really needs to.. */
+ /* */
+ /* <Fields> */
+ /* kind :: token type. Describes the token to the loader */
+ /* kind2 :: detailed token type. */
+ /* */
+ /* start :: index of first character of token in input stream */
+ /* */
+ /* len :: length of token in characters. */
+ /* */
+ typedef struct T1_Token_
+ {
+ T1_TokenType kind; /* simple type */
+ T1_TokenType kind2; /* detailed type */
+ T1_Int start; /* index of first token character */
+ T1_Int len; /* length of token in chars */
+
+ } T1_Token;
+
+
+
+
+ typedef struct T1_TokenParser_
+ {
+ FT_Memory memory;
+ FT_Stream stream;
+
+ T1_Bool in_pfb; /* true if PFB file, PFA otherwise */
+ T1_Bool in_private; /* true if in private dictionary */
+
+ T1_Byte* base; /* base address of current read buffer */
+ T1_Long cursor; /* current position in read buffer */
+ T1_Long limit; /* limit of current read buffer */
+ T1_Long max; /* maximum size of read buffer */
+
+ T1_Error error; /* last error */
+ T1_Token token; /* last token read */
+
+ } T1_TokenParser;
+
+
+
+ /*************************************************************************/
+ /* */
+ /* <Type> T1_Tokenizer */
+ /* */
+ /* <Description> */
+ /* A handle to an object used to extract tokens from the input. */
+ /* The object is able to perform PFA/PFB recognition, eexec */
+ /* decryption of the private dictionary, as well as eexec decryption */
+ /* of the charstrings.. */
+ /* */
+ typedef T1_TokenParser* T1_Tokenizer;
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> New_Tokenizer */
+ /* */
+ /* <Description> */
+ /* Creates a new tokenizer from a given input stream. This function */
+ /* automatically recognizes "pfa" or "pfb" files. The function */
+ /* "Read_Token" can then be used to extract successive tokens from */
+ /* the stream.. */
+ /* */
+ /* <Input> */
+ /* stream :: input stream */
+ /* */
+ /* <Output> */
+ /* tokenizer :: handle to new tokenizer object.. */
+ /* */
+ /* <Return> */
+ /* Type1 error code. 0 means success.. */
+ /* */
+ /* <Note> */
+ /* This function copies the stream handle within the object. Callers */
+ /* should not discard "stream". This is done by the Done_Tokenizer */
+ /* function.. */
+ /* */
+ LOCAL_DEF
+ T1_Error New_Tokenizer( FT_Stream stream,
+ T1_Tokenizer* tokenizer );
+
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> Done_Tokenizer */
+ /* */
+ /* <Description> */
+ /* Closes a given tokenizer. This function will also close the */
+ /* stream embedded in the object.. */
+ /* */
+ /* <Input> */
+ /* tokenizer :: target tokenizer object */
+ /* */
+ /* <Return> */
+ /* Type1 error code. 0 means success.. */
+ /* */
+ LOCAL_DEF
+ T1_Error Done_Tokenizer( T1_Tokenizer tokenizer );
+
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> Open_PrivateDict */
+ /* */
+ /* <Description> */
+ /* This function must be called to set the tokenizer to the private */
+ /* section of the Type1 file. It recognizes automatically the */
+ /* the kind of eexec encryption used (ascii or binary).. */
+ /* */
+ /* <Input> */
+ /* tokenizer :: target tokenizer object */
+ /* lenIV :: value of the "lenIV" variable.. */
+ /* */
+ /* <Return> */
+ /* Type1 error code. 0 means success.. */
+ /* */
+ LOCAL_DEF
+ T1_Error Open_PrivateDict( T1_Tokenizer tokenizer );
+
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> Read_Token */
+ /* */
+ /* <Description> */
+ /* Read a new token from the current input stream. This function */
+ /* extracts a token from the font program until "Open_PrivateDict" */
+ /* has been called. After this, it returns tokens from the */
+ /* (eexec-encrypted) private dictionnary.. */
+ /* */
+ /* <Input> */
+ /* tokenizer :: target tokenizer object */
+ /* */
+ /* <Return> */
+ /* Type1 error code. 0 means success.. */
+ /* */
+ /* <Note> */
+ /* One should use the function Read_CharStrings to read the binary */
+ /* charstrings from the private dict.. */
+ /* */
+ LOCAL_DEF
+ T1_Error Read_Token( T1_Tokenizer tokenizer );
+
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> Read_CharStrings */
+ /* */
+ /* <Description> */
+ /* Read a charstrings from the current input stream. These are */
+ /* binary bytes that encode each individual glyph outline. */
+ /* */
+ /* <Input> */
+ /* tokenizer :: target tokenizer object */
+ /* num_chars :: number of binary bytes to read */
+ /* */
+ /* <Output> */
+ /* buffer :: target array of bytes. These are eexec-decrypted.. */
+ /* */
+ /* <Return> */
+ /* Type1 error code. 0 means success.. */
+ /* */
+ /* <Note> */
+ /* One should use the function Read_CharStrings to read the binary */
+ /* charstrings from the private dict.. */
+ /* */
+ LOCAL_DEF
+ T1_Error Read_CharStrings( T1_Tokenizer tokenizer,
+ T1_Int num_chars,
+ T1_Byte* buffer );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> t1_decrypt */
+ /* */
+ /* <Description> */
+ /* Performs the Type 1 charstring decryption process.. */
+ /* */
+ /* <Input> */
+ /* buffer :: base address of data to decrypt */
+ /* length :: number of bytes to decrypt from base address */
+ /* seed :: ecnryption seed (4330 for charstrings). */
+ /* */
+ LOCAL_DEF
+ void t1_decrypt( T1_Byte* buffer,
+ T1_Int length,
+ T1_UShort seed );
+
+#endif /* T1TOKENS_H */
--- /dev/null
+++ b/src/type1/type1.c
@@ -1,0 +1,50 @@
+/***************************************************************************/
+/* */
+/* type1.c */
+/* */
+/* FreeType Type 1 driver component */
+/* */
+/* 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 compile the FreeType Type 1 font driver. */
+/* It relies on all components included in the "base" layer (see */
+/* the file "ftbase.c"). Source code is located in "freetype/ttlib" */
+/* and contains : */
+/* */
+/* - a driver interface */
+/* - an object manager */
+/* - a table loader */
+/* - a glyph loader */
+/* - a glyph hinter */
+/* */
+/***************************************************************************/
+
+
+
+#if 0
+#define FT_MAKE_OPTION_SINGLE_OBJECT
+#include <t1driver.c> /* driver interface */
+#include <t1objs.c> /* object manager */
+#include <t1load.c> /* table loader */
+#include <t1hint.c> /* hinter */
+#include <t1gload.c> /* glyph loader */
+#endif
+
+#include <t1driver.c>
+#include <t1objs.c>
+#include <t1load.c> /* table loader */
+#include <t1gload.c>
+
+#include <t1tokens.c>
+#include <t1parse.c>
+#include <t1encode.c>
+#include <t1hinter.c>
+