added a new experimental Type 1 driver. This version sports several

improvements compared to "src/type1". Briefly :

  - the postscript-like interpreter is now gone. We now perform
    pattern-matching to load our font content. The resultant code
    is much faster, smaller, and easier to maintain.

    For a more detailed description, see the comments at the start
    of "src/type1z/t1objs.c"

  - the glyph loader will be greatly simplified really soon, and the
    clumsy hinter will be ditched in favor of a more general auto-hinting
    module (when we get one).

    The goal is to strip down the Type1 driver to about 15-20 Kb.

This is still an experimental version. It is added to the repository
for archiving. You should not try to use it for now (it won't work
because some crucial parts are _knowingly_ ignored for now !).

Note that the "old" type1 driver will probably move to the "demos/src"
directory, in order to show how one can replace one given font driver
at runtime (and to provide the functionality of the "t1dump" program).
This commit is contained in:
David Turner 2000-01-27 14:02:04 +00:00
parent d42c68e855
commit 2dfb5aca28
20 changed files with 7414 additions and 0 deletions

6
src/type1z/module.mk Normal file
View File

@ -0,0 +1,6 @@
make_module_list: add_type1z_driver
add_type1z_driver:
$(OPEN_DRIVER)t1z_driver_interface$(CLOSE_DRIVER)
$(ECHO_DRIVER)type1z $(ECHO_DRIVER_DESC) Postscript font files with extension *.pfa or *.pfb $(ECHO_DRIVER_DONE)

168
src/type1z/rules.mk Normal file
View File

@ -0,0 +1,168 @@
#****************************************************************************
#* *
#* Type1z 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. *
#* *
#* The "Type1z" driver is an experimental replacement for the current *
#* Type 1 driver. It features a very different loading mechanism that *
#* is much faster than the one used by the "normal" driver, and also *
#* deals nicely with nearly broken Type 1 font files.. It is also *
#* much smaller.. *
#* *
#* Note that it may become a permanent replacement of the current *
#* "src/type1" driver in the future.. *
#* *
#****************************************************************************
#****************************************************************************
#* *
#* 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. *
#* *
#****************************************************************************
# Type1z driver directory
#
T1Z_DIR := $(SRC_)type1z
T1Z_DIR_ := $(T1Z_DIR)$(SEP)
# additional include flags used when compiling the driver
#
T1Z_INCLUDE := $(SHARED) $(T1Z_DIR)
T1Z_COMPILE := $(FT_COMPILE) $(T1Z_INCLUDE:%=$I%)
# Type1 driver sources (i.e., C files)
#
T1Z_DRV_SRC := $(T1Z_DIR_)t1parse.c \
$(T1Z_DIR_)t1load.c
# $(T1Z_DIR_)t1parse.c \
# $(T1Z_DIR_)t1tokens.c \
# $(T1Z_DIR_)t1driver.c \
# $(T1Z_DIR_)t1encode.c \
# $(T1Z_DIR_)t1hinter.c \
# $(T1Z_DIR_)t1gload.c
# Type1 driver headers
#
T1Z_DRV_H := $(T1Z_DIR_)t1errors.h \
$(T1Z_DIR_)t1config.h \
$(T1SHARED_H) \
$(T1Z_DRV_SRC:%.c=%.h)
# driver object(s)
#
# T1Z_DRV_OBJ_M is used during `debug' builds
# T1Z_DRV_OBJ_S is used during `release' builds
#
T1Z_DRV_OBJ_M := $(T1Z_DRV_SRC:$(T1Z_DIR_)%.c=$(OBJ_)%.$O) \
$(T1SHARED:$(T1SHARED_DIR_)%.c=$(OBJ_)%.$O)
T1Z_DRV_OBJ_S := $(OBJ_)type1z.$O
# driver root source file(s)
#
T1Z_DRV_SRC_M := $(T1Z_DRV_SRC) $(T1SHARED_SRC)
T1Z_DRV_SRC_S := $(T1Z_DIR_)type1z.c
# driver - single object
#
# the driver is recompiled if any of the header or source files is changed
#
$(T1Z_DRV_OBJ_S): $(BASE_H) $(T1Z_DRV_H) $(T1Z_DRV_SRC) $(T1Z_DRV_SRC_S)
$(T1Z_COMPILE) $T$@ $(T1Z_DRV_SRC_S)
# driver - multiple objects
#
# All objects are recompiled if any of the header files is changed
#
$(OBJ_)t1%.$O: $(T1Z_DIR_)t1%.c $(BASE_H) $(T1Z_DRV_H)
$(T1Z_COMPILE) $T$@ $<
$(OBJ_)t1%.$O: $(T1SHARED_DIR_)t1%.c $(BASE_H) $(T1SHARED_H)
$(T1Z_COMPILE) $T$@ $<
# update main driver object lists
#
DRV_OBJS_S += $(T1Z_DRV_OBJ_S)
DRV_OBJS_M += $(T1Z_DRV_OBJ_M)
# END

45
src/type1z/t1config.h Normal file
View File

@ -0,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 */

271
src/type1z/t1driver.c Normal file
View File

@ -0,0 +1,271 @@
/*******************************************************************
*
* 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> */
/* Get_Interface */
/* */
/* <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). */
/* */
/* <InOut> */
/* driver :: A handle to a driver object. */
/* */
/* <Input> */
/* 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 if the requested extension */
/* isn't available (i.e., wasn't compiled in the driver at build */
/* time). */
/* */
static
void* Get_Interface( FT_Driver* driver,
const FT_String* interface )
{
UNUSED(driver);
UNUSED(interface);
return 0;
}
/******************************************************************/
/* */
/* <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 )
{
UNUSED(char_width);
UNUSED(horz_resolution);
UNUSED(vert_resolution);
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 )
{
UNUSED(pixel_width);
UNUSED(pixel_height);
size->valid = FALSE;
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",
100, /* driver version == 1.0 */
200, /* requires FreeType 2.0 or above */
0, /* format interface */
(FTDriver_initDriver) T1_Init_Driver,
(FTDriver_doneDriver) T1_Done_Driver,
(FTDriver_getInterface) Get_Interface,
(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> */
/* getDriverInterface */
/* */
/* <Description> */
/* This function is used when compiling the font 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 &t1_driver_interface;
}
#endif /* CONFIG_OPTION_DYNAMIC_DRIVERS */

28
src/type1z/t1driver.h Normal file
View File

@ -0,0 +1,28 @@
/*******************************************************************
*
* 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;
#endif /* T1DRIVER_H */

332
src/type1z/t1encode.c Normal file
View File

@ -0,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 */

98
src/type1z/t1encode.h Normal file
View File

@ -0,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 33 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 33 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 */

75
src/type1z/t1errors.h Normal file
View File

@ -0,0 +1,75 @@
/*******************************************************************
*
* 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 T1ERRORS_H
#define T1ERRORS_H
#include <fterrors.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 */

1582
src/type1z/t1gload.c Normal file

File diff suppressed because it is too large Load Diff

436
src/type1z/t1gload.h Normal file
View File

@ -0,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 */

1269
src/type1z/t1hinter.c Normal file

File diff suppressed because it is too large Load Diff

380
src/type1z/t1hinter.h Normal file
View File

@ -0,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 */

741
src/type1z/t1load.c Normal file
View File

@ -0,0 +1,741 @@
/*******************************************************************
*
* t1load.h 2.0
*
* Type1 Loader.
*
* Copyright 1996-2000 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used
* modified and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*
* This is the new and improved Type 1 data loader for FreeType 2.
* The old loader has several problems: it is slow, complex, difficult
* to maintain, and contains incredible hacks to make it accept some
* ill-formed Type 1 fonts without hiccup-ing. Moreover, about 5%
* of the Type 1 fonts on my machine still aren't loaded correctly
* by it.
*
* This version is much simpler, much faster and also easier to
* read and maintain by a great order of magnitude. The idea behind
* it is to _not_ try to read the Type 1 token stream with a state
* machine (i.e. a Postscript-like interpreter) but rather to perform
* simple pattern-matching.
*
* Indeed, nearly all data definitions follow a simple pattern
* like :
*
* ..... /Field <data> ....
*
* where <data> can be a number, a boolean, a string, or an
* array of numbers. There are a few exceptions, namely the
* encoding, font name, charstrings and subrs and they are
* handled with a special pattern-matching routine.
*
* All other common cases are handled very simply. The matching
* rules are defined in the file "t1tokens.h" through the use
* of several macros calls PARSE_XXXX
*
* This file is included twice here, the first time to generate
* parsing callback functions, the second to generate a table
* of keywords (with pointers to the associated callback).
*
* The function "parse_dict" simply scans *linearly* a given
* dictionary (either the top-level or private one) and calls
* the appropriate callback when it encounters an immediate
* keyword.
*
* This is by far the fastest way one can find to parse and read
* all data :-)
*
* This led to tremendous code size reduction. Note that later,
* the glyph loader will also be _greatly_ simplified, and the
* automatic hinter will replace the clumsy "t1hinter"..
*
******************************************************************/
#include <ftdebug.h>
#include <t1types.h>
#include <t1errors.h>
#include <t1encode.h>
#include <t1config.h>
#include <t1load.h>
#include <stdio.h>
#undef FT_COMPONENT
#define FT_COMPONENT trace_t1load
typedef void (*T1_Parse_Func)( T1_Face face, T1_Loader* loader );
typedef struct T1_KeyWord_
{
const char* name;
T1_Parse_Func parsing;
} T1_KeyWord;
/* some handy macros used to easily define parsing callback functions */
/* each callback is in charge of loading a value and storing it in a */
/* given field of the Type 1 face.. */
#define PARSE_(x) static void parse_##x##( T1_Face face, T1_Loader* loader )
#define PARSE_STRING(s,x) PARSE_(x) \
{ \
FACE.##x = T1_ToString(&loader->parser); \
FT_TRACE2(( "type1.parse_##x##: \"%s\"\n", FACE.##x )); \
}
#define PARSE_INT(s,x) PARSE_(x) \
{ \
FACE.##x = T1_ToInt(&loader->parser); \
FT_TRACE2(( "type1.parse_##x##: \"%d\"\n", FACE.##x )); \
}
#define PARSE_BOOL(s,x) PARSE_(x) \
{ \
FACE.##x = T1_ToBool(&loader->parser); \
FT_TRACE2(( "type1.parse_##x##: \"%s\"\n", \
FACE.##x ? "true" : "false" )); \
}
#define PARSE_FIXED(s,x) PARSE_(x) \
{ \
FACE.##x = T1_ToFixed(&loader->parser,3); \
FT_TRACE2(( "type1.parse_##x##: \"%f\"\n", FACE.##x/65536.0 )); \
}
#define PARSE_COORDS(s,c,m,x) PARSE_(x) \
{ \
FACE.##c = T1_ToCoordArray(&loader->parser, m, (T1_Short*)FACE.##x ); \
FT_TRACE2(( "type1.parse_##x##\n" )); \
}
#define PARSE_FIXEDS(s,c,m,x) PARSE_(x) \
{ \
FACE.##c = T1_ToFixedArray(&loader->parser, m, (T1_Fixed*)FACE.##x, 3 ); \
FT_TRACE2(( "type1.parse_##x##\n" )); \
}
#define PARSE_COORDS2(s,m,x) PARSE_(x) \
{ \
(void)T1_ToCoordArray( &loader->parser, m, (T1_Short*)&FACE.##x ); \
FT_TRACE2(( "type1.parse_##x##\n" )); \
}
#define PARSE_FIXEDS2(s,m,x) PARSE_(x) \
{ \
(void)T1_ToFixedArray(&loader->parser, m, (T1_Fixed*)&FACE.##x, 3 ); \
FT_TRACE2(( "type1.parse_##x##\n" )); \
}
/* define all parsing callbacks */
#include <t1tokens.h>
static
int is_space( char c )
{
return ( c == ' ' || c == '\t' || c == '\r' || c == '\n' );
}
static
int is_alpha( char c )
{
return ( (c >= 'A' && c <= 'Z') ||
(c >= 'a' && c <= 'z') ||
(c >= '0' && c <= '9') ||
(c == '.') ||
(c == '_') );
}
static
void skip_whitespace( T1_Parser* parser )
{
T1_Byte* cur = parser->cursor;
while ( cur < parser->limit && is_space(*cur) )
cur++;
parser->cursor = cur;
}
static
void skip_blackspace( T1_Parser* parser )
{
T1_Byte* cur = parser->cursor;
while ( cur < parser->limit && !is_space(*cur) )
cur++;
parser->cursor = cur;
}
static
int read_binary_data( T1_Parser* parser, T1_Int *size, T1_Byte* *base )
{
T1_Byte* cur;
T1_Byte* limit = parser->limit;
/* the binary data has the following format */
/* */
/* "size" [white*] RD white ....... ND */
/* */
skip_whitespace(parser);
cur = parser->cursor;
if ( cur < limit && (T1_Byte)(*cur-'0') < 10 )
{
*size = T1_ToInt(parser);
skip_whitespace(parser);
skip_blackspace(parser); /* "RD" or "-|" or something else */
/* there is only one whitespace char after the */
/* "RD" or "-|" token */
*base = parser->cursor + 1;
parser->cursor += *size+1;
return 1;
}
FT_ERROR(( "type1.read_binary_data: invalid size field\n" ));
parser->error = FT_Err_Invalid_File_Format;
return 0;
}
/* we will now define the routines used to handle */
/* the /Encoding, /Subrs and /CharStrings */
/* dictionaries.. */
static
void parse_font_name( T1_Face face, T1_Loader* loader )
{
T1_Parser* parser = &loader->parser;
FT_Error error;
FT_Memory memory = parser->memory;
T1_Int len;
T1_Byte* cur;
T1_Byte* cur2;
T1_Byte* limit;
skip_whitespace(parser);
cur = parser->cursor;
limit = parser->limit;
if ( cur >= limit-1 || *cur != '/' ) return;
cur++;
cur2 = cur;
while (cur2 < limit && is_alpha(*cur2)) cur2++;
len = cur2-cur;
if (len > 0)
{
if ( ALLOC( face->type1.font_name, len+1 ) )
{
parser->error = error;
return;
}
MEM_Copy( face->type1.font_name, cur, len );
face->type1.font_name[len] = '\0';
}
parser->cursor = cur2;
}
static
void parse_font_bbox( T1_Face face, T1_Loader* loader )
{
T1_Parser* parser = &loader->parser;
T1_Short temp[4];
T1_BBox* bbox = &face->type1.font_bbox;
(void)T1_ToCoordArray( parser, 4, temp );
bbox->xMin = temp[0];
bbox->yMin = temp[1];
bbox->xMax = temp[2];
bbox->yMax = temp[3];
}
static
void parse_encoding( T1_Face face, T1_Loader* loader )
{
T1_Parser* parser = &loader->parser;
T1_Byte* cur = parser->cursor;
T1_Byte* limit = parser->limit;
/* skip whitespace */
while (is_space(*cur))
{
cur++;
if (cur >= limit)
{
FT_ERROR(( "type1.parse_encoding: out of bounds !!\n" ));
parser->error = FT_Err_Invalid_File_Format;
return;
}
}
/* if we have a number, then the encoding is an array, */
/* and we must load it now */
if ((T1_Byte)(*cur - '0') < 10)
{
T1_Encoding* encode = &face->type1.encoding;
T1_Int count, n;
T1_Table* char_table = &loader->encoding_table;
FT_Memory memory = parser->memory;
FT_Error error;
/* read the number of entries in the encoding, should be 256 */
count = T1_ToInt( parser );
if (parser->error) return;
/* we use a T1_Table to store our charnames */
encode->num_chars = count;
if ( ALLOC_ARRAY( encode->char_index, count, T1_Short ) ||
ALLOC_ARRAY( encode->char_name, count, T1_String* ) ||
(error = T1_New_Table( char_table, count, memory )) != 0 )
{
parser->error = error;
return;
}
/* now, we will need to read a record of the form */
/* ... charcode /charname ... for each entry in our table */
/* */
/* we simply look for a number followed by an immediate */
/* name. Note that this ignores correctly the sequence */
/* that is often seen in type1 fonts : */
/* */
/* 0 1 255 { 1 index exch /.notdef put } for dup */
/* */
/* used to clean the encoding array before anything else */
/* */
/* we stop when we encounter a "def" */
/* */
cur = parser->cursor;
limit = parser->limit;
n = 0;
for ( ; cur < limit; )
{
T1_Byte c;
c = *cur;
/* we stop when we encounter a 'def' */
if ( c == 'd' && cur+3 < limit )
{
if ( cur[1] == 'e' &&
cur[2] == 'f' &&
is_space(cur[3]) )
break;
}
/* otherwise, we must find a number before anything else */
if ( (T1_Byte)(c-'0') < 10 )
{
T1_Int charcode;
parser->cursor = cur;
charcode = T1_ToInt(parser);
cur = parser->cursor;
/* skip whitespace */
while (cur < limit && is_space(*cur)) cur++;
if (cur < limit && *cur == '/')
{
/* bingo, we have an immediate name - it must be a */
/* character name */
FT_Byte* cur2 = cur+1;
T1_Int len;
while (cur2 < limit && is_alpha(*cur2)) cur2++;
len = cur2-cur-1;
parser->error = T1_Add_Table( char_table, charcode, cur+1, len+1 );
char_table->elements[charcode][len] = '\0';
if (parser->error) return;
cur = cur2;
}
}
else
cur++;
}
face->type1.encoding_type = t1_encoding_array;
}
/* Otherwise, we should have either "StandardEncoding" or */
/* "ExpertEncoding" */
else
{
if ( cur+17 < limit && strncmp( cur, "StandardEncoding", 16 ) == 0 )
face->type1.encoding_type = t1_encoding_standard;
else if (cur+15 < limit && strncmp( cur, "ExpertEncoding", 14 ) == 0 )
face->type1.encoding_type = t1_encoding_expert;
else
{
FT_ERROR(( "type1.parse_encoding: invalid token !!\n" ));
parser->error = FT_Err_Invalid_File_Format;
}
}
}
static
void parse_subrs( T1_Face face, T1_Loader* loader )
{
T1_Parser* parser = &loader->parser;
T1_Table* table = &loader->subrs;
FT_Memory memory = parser->memory;
FT_Error error;
T1_Int n;
loader->num_subrs = T1_ToInt( parser );
if (parser->error) return;
/* initialise subrs array */
error = T1_New_Table( table, loader->num_subrs, memory );
if (error) goto Fail;
/* the format is simple : */
/* */
/* "index" + binary data */
/* */
for ( n = 0; n < loader->num_subrs; n++ )
{
T1_Int index, size;
T1_Byte* base;
index = T1_ToInt(parser);
if (!read_binary_data(parser,&size,&base)) return;
error = T1_Add_Table( table, index, base, size );
if (error) goto Fail;
}
return;
Fail:
parser->error = error;
}
static
void parse_charstrings( T1_Face face, T1_Loader* loader )
{
T1_Parser* parser = &loader->parser;
T1_Table* code_table = &loader->charstrings;
T1_Table* name_table = &loader->glyph_names;
FT_Memory memory = parser->memory;
FT_Error error;
T1_Byte* cur;
T1_Byte* limit = parser->limit;
T1_Int n;
loader->num_glyphs = T1_ToInt( parser );
if (parser->error) return;
/* initialise tables */
error = T1_New_Table( code_table, loader->num_glyphs, memory ) ||
T1_New_Table( name_table, loader->num_glyphs, memory );
if (error) goto Fail;
n = 0;
for ( ;; )
{
T1_Int size;
T1_Byte* base;
/* the format is simple : */
/* "/glyphname" + binary data */
/* */
/* note that we stop when we find a "def" */
/* */
skip_whitespace(parser);
cur = parser->cursor;
if (cur >= limit) break;
/* we stop when we find a "def" */
if (*cur == 'd' &&
cur+3 < limit &&
cur[1] == 'e' &&
cur[2] == 'f' )
break;
if (*cur != '/')
skip_blackspace(parser);
else
{
T1_Byte* cur2 = cur+1;
T1_Int len;
while (cur2 < limit && is_alpha(*cur2)) cur2++;
len = cur2-cur-1;
error = T1_Add_Table( name_table, n, cur+1, len+1 );
if (error) goto Fail;
/* add a trailing zero to the name table */
name_table->elements[n][len] = '\0';
parser->cursor = cur2;
if (!read_binary_data(parser,&size,&base)) return;
error = T1_Add_Table( code_table, n, base, size );
if (error) goto Fail;
n++;
if (n >= loader->num_glyphs)
break;
}
}
return;
Fail:
parser->error = error;
}
#undef PARSE_STRING
#undef PARSE_INT
#undef PARSE_BOOL
#undef PARSE_FIXED
#undef PARSE_COORDS
#undef PARSE_FIXEDS
#undef PARSE_COORDS2
#undef PARSE_FIXEDS2
#undef PARSE_
#define PARSE_(s,x) { s, parse_##x },
#define PARSE_STRING(s,x) PARSE_(s,x)
#define PARSE_INT(s,x) PARSE_(s,x)
#define PARSE_BOOL(s,x) PARSE_(s,x)
#define PARSE_FIXED(s,x) PARSE_(s,x)
#define PARSE_COORDS(s,c,m,x) PARSE_(s,x)
#define PARSE_FIXEDS(s,c,m,x) PARSE_(s,x)
#define PARSE_COORDS2(s,m,x) PARSE_(s,x)
#define PARSE_FIXEDS2(s,m,x) PARSE_(s,x)
static
const T1_KeyWord t1_keywords[] =
{
#include <t1tokens.h>
/* now add the special functions... */
{ "FontName", parse_font_name },
{ "FontBBox", parse_font_bbox },
{ "Encoding", parse_encoding },
{ "Subrs", parse_subrs },
{ "CharStrings", parse_charstrings },
{ 0, 0 }
};
static
T1_Error parse_dict( T1_Face face,
T1_Loader* loader,
T1_Byte* base,
T1_Int size )
{
T1_Parser* parser = &loader->parser;
parser->cursor = base;
parser->limit = base + size;
parser->error = 0;
{
T1_Byte* cur = base;
T1_Byte* limit = cur + size;
for ( ;cur < limit; cur++ )
{
/* look for immediates */
if (*cur == '/' && cur+2 < limit)
{
T1_Byte* cur2;
T1_Int len;
cur ++;
cur2 = cur;
while (cur2 < limit && is_alpha(*cur2)) cur2++;
len = cur2-cur;
if (len > 0)
{
/* now, compare the immediate name to the keyword table */
T1_KeyWord* keyword = (T1_KeyWord*)t1_keywords;
for (;;)
{
T1_Byte* name;
name = (T1_Byte*)keyword->name;
if (!name) break;
if (cur[0] == name[0] && len == strlen(name) )
{
T1_Int n;
for ( n = 1; n < len; n++ )
if (cur[n] != name[n])
break;
if (n >= len)
{
/* we found it - run the parsing callback !! */
parser->cursor = cur2;
skip_whitespace( parser );
keyword->parsing( face, loader );
if (parser->error)
return parser->error;
cur = parser->cursor;
}
}
keyword++;
}
}
}
}
}
return parser->error;
}
static
void t1_init_loader( T1_Loader* loader, T1_Face face )
{
loader->num_glyphs = 0;
loader->num_chars = 0;
loader->encoding_table.init = 0;
loader->charstrings.init = 0;
loader->glyph_names.init = 0;
loader->subrs.init = 0;
}
static
void t1_done_loader( T1_Loader* loader )
{
T1_Parser* parser = &loader->parser;
/* finalize tables */
T1_Release_Table( &loader->encoding_table );
T1_Release_Table( &loader->charstrings );
T1_Release_Table( &loader->glyph_names );
T1_Release_Table( &loader->subrs );
/* finalize parser */
T1_Done_Parser( parser );
}
LOCAL_FUNC
T1_Error T1_Open_Face( T1_Face face )
{
T1_Loader loader;
T1_Parser* parser;
T1_Font* type1 = &face->type1;
FT_Error error;
t1_init_loader( &loader, face );
/* default lenIV */
type1->lenIV = 4;
parser = &loader.parser;
error = T1_New_Parser( parser, face->root.stream, face->root.memory );
if (error) goto Exit;
error = parse_dict( face, &loader, parser->base_dict, parser->base_len );
if (error) goto Exit;
error = T1_Get_Private_Dict( parser );
if (error) goto Exit;
error = parse_dict( face, &loader, parser->private_dict, parser->private_len );
if (error) goto Exit;
/* now, propagate the subrs, charstrings and glyphnames tables */
/* to the Type1 data */
type1->num_glyphs = loader.num_glyphs;
loader.subrs.init = 0;
type1->num_subrs = loader.num_subrs;
type1->subrs_block = loader.subrs.block;
type1->subrs = loader.subrs.elements;
type1->subrs_len = loader.subrs.lengths;
loader.charstrings.init = 0;
type1->charstrings_block = loader.charstrings.block;
type1->charstrings = loader.charstrings.elements;
type1->charstrings_len = loader.charstrings.lengths;
/* we copy the glyph names "block" and "elements" fields */
/* but the "lengths" field must be released later.. */
type1->glyph_names_block = loader.glyph_names.block;
type1->glyph_names = (T1_String**)loader.glyph_names.elements;
loader.glyph_names.block = 0;
loader.glyph_names.elements = 0;
/* we must now build type1.encoding when we have a custom */
/* array.. */
if ( type1->encoding_type == t1_encoding_array )
{
T1_Int charcode, index, min_char, max_char;
T1_Byte* char_name;
T1_Byte* glyph_name;
/* OK, we do the following : for each element in the encoding */
/* table, lookup the index of the glyph having the same name */
/* the index is then stored in type1.encoding.char_index, and */
/* a the name to type1.encoding.char_name */
min_char = +32000;
max_char = -32000;
charcode = 0;
for ( ; charcode < loader.encoding_table.num_elems; charcode++ )
{
type1->encoding.char_index[charcode] = 0;
type1->encoding.char_name [charcode] = ".notdef";
char_name = loader.encoding_table.elements[charcode];
if (char_name)
for ( index = 0; index < type1->num_glyphs; index++ )
{
glyph_name = type1->glyph_names[index];
if ( strcmp( char_name, glyph_name ) == 0 )
{
type1->encoding.char_index[charcode] = index;
type1->encoding.char_name [charcode] = glyph_name;
if (charcode < min_char) min_char = charcode;
if (charcode > max_char) max_char = charcode;
break;
}
}
}
type1->encoding.code_first = min_char;
type1->encoding.code_last = max_char;
type1->encoding.num_chars = loader.num_chars;
}
Exit:
t1_done_loader( &loader );
return error;
}

56
src/type1z/t1load.h Normal file
View File

@ -0,0 +1,56 @@
/*******************************************************************
*
* t1load.h 2.0
*
* Type1 Loader.
*
* Copyright 1996-2000 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used
* modified and distributed under the terms of the FreeType project
* license, LICENSE.TXT. 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
typedef struct T1_Loader_
{
T1_Parser parser; /* parser used to read the stream */
T1_Int num_chars; /* number of characters in encoding */
T1_Table encoding_table; /* T1_Table used to store the */
/* encoding character names */
T1_Int num_glyphs;
T1_Table glyph_names;
T1_Table charstrings;
T1_Int num_subrs;
T1_Table subrs;
} T1_Loader;
LOCAL_DEF
T1_Error T1_Open_Face( T1_Face face );
#ifdef __cplusplus
}
#endif
#endif /* T1LOAD_H */
/* END */

404
src/type1z/t1objs.c Normal file
View File

@ -0,0 +1,404 @@
/*******************************************************************
*
* 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_Error error;
(void)face_index;
(void)face;
face->root.num_faces = 1;
/* open the tokenizer, this will also check the font format */
error = T1_Open_Face( face );
if (error) goto Exit;
/* if we just wanted to check the format, leave successfully now */
if (face_index < 0)
goto Exit;
/* check the face index */
if ( face_index != 0 )
{
FT_ERROR(( "T1.Init_Face : invalid face index\n" ));
error = T1_Err_Invalid_Argument;
goto Exit;
}
/* Now, load the font program into the face object */
{
/* Init the face object fields */
/* Now set up root face fields */
{
FT_Face root = (FT_Face)&face->root;
root->num_glyphs = face->type1.num_glyphs;
root->num_charmaps = 1;
root->face_index = face_index;
root->face_flags = FT_FACE_FLAG_SCALABLE;
root->face_flags |= FT_FACE_FLAG_HORIZONTAL;
if ( face->type1.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->type1.family_name;
if (root->family_name)
{
char* full = face->type1.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->type1.font_name)
{
root->family_name = face->type1.font_name;
root->style_name = "Regular";
}
}
/* no embedded bitmap support */
root->num_fixed_sizes = 0;
root->available_sizes = 0;
root->bbox = face->type1.font_bbox;
root->units_per_EM = 1000;
root->ascender = (T1_Short)face->type1.font_bbox.yMax;
root->descender = -(T1_Short)face->type1.font_bbox.yMin;
root->height = ((root->ascender + root->descender)*12)/10;
/* now compute the maximum advance width */
root->max_advance_width = face->type1.standard_width;
/* compute max advance width for proportional fonts */
if (!face->type1.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->type1.underline_position;
root->underline_thickness = face->type1.underline_thickness;
root->max_points = 0;
root->max_contours = 0;
}
}
Exit:
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 */

302
src/type1z/t1objs.h Normal file
View File

@ -0,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 */

901
src/type1z/t1parse.c Normal file
View File

@ -0,0 +1,901 @@
/*******************************************************************
*
* t1parse.c 2.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 Type 1 parser is in charge of the following:
*
* - provide an implementation of a growing sequence of
* objects called a T1_Table (used to build various tables
* needed by the loader).
*
* - opening .pfb and .pfa files to extract their top-level
* and private dictionaries
*
* - read numbers, arrays & strings from any dictionary
*
* See "t1load.c" to see how data is loaded from the font file
*
******************************************************************/
#include <ftdebug.h>
#include <ftcalc.h>
#include <ftobjs.h>
#include <ftstream.h>
#include <t1errors.h>
#include <t1parse.h>
#undef FT_COMPONENT
#define FT_COMPONENT trace_t1load
/*************************************************************************/
/* */
/* <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* ) ||
ALLOC_ARRAY( table->lengths, count, T1_Byte* ) )
goto Exit;
table->max_elems = count;
table->init = 0xdeadbeef;
table->num_elems = 0;
table->block = 0;
table->capacity = 0;
table->cursor = 0;
Exit:
if (error) FREE(table->elements);
return error;
}
/*************************************************************************/
/* */
/* <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 void shift_elements( T1_Table* table, T1_Byte* 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;
}
}
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)
shift_elements( table, old_base );
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)
shift_elements( table, old_base );
}
LOCAL_FUNC
void T1_Release_Table( T1_Table* table )
{
FT_Memory memory = table->memory;
if (table->init == 0xdeadbeef)
{
FREE( table->block );
FREE( table->elements );
FREE( table->lengths );
table->init = 0;
}
}
static
T1_Long t1_toint( T1_Byte* *cursor,
T1_Byte* limit )
{
T1_Long result = 0;
T1_Byte* cur = *cursor;
T1_Byte c, d;
for (; cur < limit; cur++)
{
c = *cur;
d = (T1_Byte)(c - '0');
if (d < 10) break;
if ( c=='-' )
{
cur++;
break;
}
}
if (cur < limit)
{
do
{
d = (T1_Byte)(cur[0] - '0');
if (d >= 10)
break;
result = result*10 + d;
cur++;
} while (cur < limit);
if (c == '-')
result = -result;
}
*cursor = cur;
return result;
}
static
T1_Long t1_tofixed( T1_Byte* *cursor,
T1_Byte* limit,
T1_Long power_ten )
{
T1_Byte* cur = *cursor;
T1_Long num, divider, result;
T1_Int sign = 0;
T1_Byte d;
if (cur >= limit) return 0;
/* first of all, read the integer part */
result = t1_toint( &cur, limit ) << 16;
num = 0;
divider = 1;
if (result < 0)
{
sign = 1;
result = -result;
}
if (cur >= limit) goto Exit;
/* read decimal part, if any */
if (*cur == '.' && cur+1 < limit)
{
cur++;
for (;;)
{
d = (T1_Byte)(*cur - '0');
if (d >= 10) break;
if (divider < 10000000L)
{
num = num*10 + d;
divider *= 10;
}
cur++;
if (cur >= limit) break;
}
}
/* read exponent, if any */
if ( cur+1 < limit && (*cur == 'e' || *cur == 'E'))
{
cur++;
power_ten += t1_toint( &cur, limit );
}
Exit:
/* raise to power of ten if needed */
while (power_ten > 0)
{
result = result*10;
num = num*10;
power_ten--;
}
while (power_ten < 0)
{
result = result/10;
divider = divider*10;
power_ten++;
}
if (num)
result += FT_DivFix( num, divider );
if (sign)
result = -result;
*cursor = cur;
return result;
}
static
T1_Int t1_tocoordarray( T1_Byte* *cursor,
T1_Byte* limit,
T1_Int max_coords,
T1_Short* coords )
{
T1_Byte* cur = *cursor;
T1_Int count = 0;
T1_Byte c, ender;
if (cur >= limit) goto Exit;
/* check for the beginning of an array. If not, only one number will be read */
c = *cur;
ender = 0;
if (c == '[')
ender = ']';
if (c == '{')
ender = '}';
if (ender)
cur++;
/* now, read the coordinates */
for ( ; cur < limit; cur++ )
{
c = *cur;
if (count >= max_coords || c == ender)
break;
coords[count] = (T1_Short)(t1_tofixed(&cur,limit,0) >> 16);
count++;
if (!ender)
break;
}
Exit:
*cursor = cur;
return count;
}
static
T1_Int t1_tofixedarray( T1_Byte* *cursor,
T1_Byte* limit,
T1_Int max_values,
T1_Fixed* values,
T1_Int power_ten )
{
T1_Byte* cur = *cursor;
T1_Int count = 0;
T1_Byte c, ender;
if (cur >= limit) goto Exit;
/* check for the beginning of an array. If not, only one number will be read */
c = *cur;
ender = 0;
if (c == '[')
ender = ']';
if (c == '{')
ender = '}';
if (ender)
cur++;
/* now, read the values */
for ( ; cur < limit; cur++ )
{
c = *cur;
if (count >= max_values || c == ender)
break;
values[count] = t1_tofixed(&cur,limit,power_ten);
count++;
if (!ender)
break;
}
Exit:
*cursor = cur;
return count;
}
static
T1_String* t1_tostring( T1_Byte* *cursor, T1_Byte* limit, FT_Memory memory )
{
T1_Byte* cur = *cursor;
T1_Int len = 0;
T1_Int count;
T1_String* result;
FT_Error error;
/* first of all, skip everything until we encounter a string */
while ( cur < limit && *cur != '(' ) cur++;
cur++;
if (cur >= limit) return 0;
*cursor = cur;
count = 0;
/* then, count its length */
for ( ; cur < limit; cur++ )
{
if (*cur == '(')
count++;
else if (*cur == ')')
{
count--;
if (count < 0)
break;
}
}
len = cur - *cursor;
if (cur >= limit || ALLOC(result,len+1)) return 0;
/* now copy the string */
MEM_Copy( result, *cursor, len );
result[len] = '\0';
return result;
}
static
int t1_tobool( T1_Byte* *cursor, T1_Byte* limit )
{
T1_Byte* cur = *cursor;
T1_Bool result = 0;
/* return 1 if we find a "true", 0 otherwise */
if ( cur+3 < limit &&
cur[0] == 't' &&
cur[1] == 'r' &&
cur[2] == 'u' &&
cur[3] == 'e' )
{
result = 1;
cur += 5;
}
else if ( cur+4 < limit &&
cur[0] == 'f' &&
cur[1] == 'a' &&
cur[2] == 'l' &&
cur[3] == 's' &&
cur[4] == 'e' )
{
result = 0;
cur += 6;
}
*cursor = cur;
return result;
}
LOCAL_FUNC
T1_Long T1_ToInt ( T1_Parser* parser )
{
return t1_toint( &parser->cursor, parser->limit );
}
LOCAL_FUNC
T1_Long T1_ToFixed( T1_Parser* parser, T1_Int power_ten )
{
return t1_tofixed( &parser->cursor, parser->limit, power_ten );
}
LOCAL_FUNC
T1_Int T1_ToCoordArray( T1_Parser* parser,
T1_Int max_coords,
T1_Short* coords )
{
return t1_tocoordarray( &parser->cursor, parser->limit, max_coords, coords );
}
LOCAL_FUNC
T1_Int T1_ToFixedArray( T1_Parser* parser,
T1_Int max_values,
T1_Fixed* values,
T1_Int power_ten )
{
return t1_tofixedarray( &parser->cursor, parser->limit, max_values, values, power_ten );
}
LOCAL_FUNC
T1_String* T1_ToString( T1_Parser* parser )
{
return t1_tostring( &parser->cursor, parser->limit, parser->memory );
}
LOCAL_FUNC
T1_Bool T1_ToBool( T1_Parser* parser )
{
return t1_tobool( &parser->cursor, parser->limit );
}
static
FT_Error read_pfb_tag( FT_Stream stream, T1_UShort *tag, T1_Long* size )
{
FT_Error error;
if (READ_UShort(*tag)) goto Exit;
if (*tag == 0x8001 || *tag == 0x8002)
{
FT_Long asize;
if (READ_ULong(asize)) goto Exit;
/* swap between big and little endianness */
*size = ((asize & 0xFF000000) >> 24) |
((asize & 0x00FF0000) >> 8 ) |
((asize & 0x0000FF00) << 8 ) |
((asize & 0x000000FF) << 24);
}
Exit:
return error;
}
LOCAL_FUNC
T1_Error T1_New_Parser( T1_Parser* parser,
FT_Stream stream,
FT_Memory memory )
{
FT_Error error;
T1_UShort tag;
T1_Long size;
parser->stream = stream;
parser->memory = memory;
parser->base_len = 0;
parser->base_dict = 0;
parser->private_len = 0;
parser->private_dict = 0;
parser->in_pfb = 0;
parser->in_memory = 0;
parser->single_block = 0;
parser->cursor = 0;
parser->limit = 0;
/******************************************************************/
/* */
/* Here's a short summary of what is going on : */
/* */
/* When creating a new Type 1 parser, we try to locate and */
/* load the base dictionary when this is possible (i.e. for */
/* .pfb files). Otherwise, we load the whole font in memory. */
/* */
/* When "loading" the base dictionary, we only setup pointers */
/* in the case of a memory-based stream. Otherwise, we allocate */
/* and load the base dict in it. */
/* */
/* parser->in_pfb is set when we are in a binary (".pfb") font */
/* parser->in_memory is set when we have a memory stream. */
/* */
/* try to compute the size of the base dictionary */
/* look for a Postscript binary file tag, i.e 0x8001 */
if ( FILE_Seek(0L) )
goto Exit;
error = read_pfb_tag( stream, &tag, &size );
if (error) goto Exit;
if (tag != 0x8001)
{
/* assume that this is a PFA file for now, an error will */
/* be produced later when more things are checked */
(void)FILE_Seek(0L);
size = stream->size;
}
else
parser->in_pfb = 1;
/* now, try to load the "size" bytes of the "base" dictionary we */
/* found previously */
/* if it's a memory-based resource, set up pointers */
if ( !stream->read )
{
parser->base_dict = (T1_Byte*)stream->base + stream->pos;
parser->base_len = size;
parser->in_memory = 1;
/* check that the "size" field is valid */
if ( FILE_Skip(size) ) goto Exit;
}
else
{
/* read segment in memory */
if ( ALLOC( parser->base_dict, size ) ||
FILE_Read( parser->base_dict, size ) )
goto Exit;
}
/* Now check font format, we must see a '%!PS-AdobeFont-1' */
/* or a '%!FontType' */
{
if ( size <= 16 ||
( strncmp( (const char*)parser->base_dict, "%!PS-AdobeFont-1", 16 ) &&
strncmp( (const char*)parser->base_dict, "%!FontType", 10 ) ) )
{
FT_TRACE2(( "Not a Type1 font\n" ));
error = T1_Err_Invalid_File_Format;
}
else
{
parser->cursor = parser->base_dict;
parser->limit = parser->cursor + parser->base_len;
}
}
Exit:
if (error && !parser->in_memory)
FREE( parser->base_dict );
return error;
}
LOCAL_FUNC
void T1_Done_Parser( T1_Parser* parser )
{
FT_Memory memory = parser->memory;
/* always free the private dictionary */
FREE( parser->private_dict );
/* free the base dictionary only when we have a disk stream */
if (!parser->in_memory)
FREE( parser->base_dict );
}
/* return the value of an hexadecimal digit */
static
int hexa_value( char c )
{
unsigned int d;
d = (unsigned int)(c-'0');
if ( d <= 9 ) return (int)d;
d = (unsigned int)(c-'a');
if ( d <= 5 ) return (int)(d+10);
d = (unsigned int)(c-'A');
if ( d <= 5 ) return (int)(d+10);
return -1;
}
LOCAL_FUNC
void 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--;
}
}
LOCAL_FUNC
T1_Error T1_Get_Private_Dict( T1_Parser* parser )
{
FT_Stream stream = parser->stream;
FT_Memory memory = parser->memory;
FT_Error error = 0;
T1_Long size;
if (parser->in_pfb)
{
/* in the case of the PFB format, the private dictionary can be */
/* made of several segments. We thus first read the number of */
/* segments to compute the total size of the private dictionary */
/* then re-read them into memory.. */
T1_Long start_pos = FILE_Pos();
T1_UShort tag;
T1_Long size;
parser->private_len = 0;
for (;;)
{
error = read_pfb_tag(stream, &tag, &size);
if (error) goto Fail;
if (tag != 0x8002)
break;
parser->private_len += size;
if ( FILE_Skip(size) )
goto Fail;
}
/* Check that we have a private dictionary there */
/* and allocate private dictionary buffer */
if ( parser->private_len == 0 )
{
FT_ERROR(( "T1.Open_Private: invalid private dictionary section\n" ));
error = T1_Err_Invalid_File_Format;
goto Fail;
}
if ( FILE_Seek( start_pos ) ||
ALLOC( parser->private_dict, parser->private_len ) )
goto Fail;
parser->private_len = 0;
for (;;)
{
error = read_pfb_tag( stream, &tag, &size );
if (error || tag != 0x8002) { error = 0; break; }
if ( FILE_Read( parser->private_dict + parser->private_len, size ) )
goto Fail;
parser->private_len += size;
}
}
else
{
/* we have already "loaded" the whole PFA font file in memory */
/* if this is a memory resource, allocate a new block to hold */
/* the private dict. Otherwise, simply overwrite into the */
/* base dict block in the heap.. */
/* first of all, look at the "eexec" keyword */
FT_Byte* cur = parser->base_dict;
FT_Byte* limit = cur + parser->base_len;
FT_Byte c;
for (;;)
{
c = cur[0];
if (c == 'e' && cur+9 < limit) /* 9 = 5 letters for 'eexec' + newline + 4 chars */
{
if ( cur[1] == 'e' && cur[2] == 'x' &&
cur[3] == 'e' && cur[4] == 'c' )
{
cur += 6; /* we skip the newling after the "eexec" */
break;
}
}
cur++;
if (cur >= limit)
{
FT_ERROR(("T1.Open_Private: could not find 'eexec' keyword\n"));
error = FT_Err_Invalid_File_Format;
goto Exit;
}
}
/* now determine wether where to write the _encrypted_ binary private */
/* dictionary. We overwrite the base dictionary for disk-based resources */
/* and allocate a new block otherwise */
size = parser->base_len - (cur-parser->base_dict);
if ( parser->in_memory )
{
/* note that we allocate one more byte to put a terminating '0' */
if (ALLOC( parser->private_dict, size+1 )) goto Fail;
parser->private_len = size;
}
else
{
parser->single_block = 1;
parser->private_dict = parser->base_dict;
parser->private_len = size;
parser->base_dict = 0;
parser->base_len = 0;
}
/* now determine wether the private dictionary is encoded in binary */
/* or hexadecimal ASCII format.. */
/* and decode it accordingly */
/* we need to access the next 4 bytes (after the final \r following */
/* the 'eexec' keyword..) if they all are hexadecimal digits, then */
/*we have a case of ASCII storage.. */
if ( ( hexa_value( cur[0] ) | hexa_value( cur[1] ) |
hexa_value( cur[2] ) | hexa_value( cur[3] ) ) < 0 )
{
/* binary encoding - "simply" copy the private dict */
MEM_Copy( parser->private_dict, cur, size );
}
else
{
/* ASCII hexadecimal encoding.. This blows goats !!.. */
T1_Byte* write;
T1_Int count;
write = parser->private_dict;
count = 0;
for ( ;cur < limit; cur++)
{
int hex1;
/* check for newline */
if (cur[0] == '\r' || cur[0] == '\n')
continue;
/* exit if we have a non-hexadecimal digit that isn't a newline */
hex1 = hexa_value(cur[0]);
if (hex1 < 0 || cur+1 >= limit)
break;
/* otherwise, store byte */
*write++ = (hex1 << 4) | hexa_value(cur[1]);
count++;
cur++;
}
/* put a safeguard */
parser->private_len = write - parser->private_dict;
*write++ = 0;
}
}
/* we now decrypt the encoded binary private dictionary */
T1_Decrypt( parser->private_dict, parser->private_len, 55665 );
parser->cursor = parser->private_dict;
parser->limit = parser->cursor + parser->private_len;
Fail:
Exit:
return error;
}

206
src/type1z/t1parse.h Normal file
View File

@ -0,0 +1,206 @@
/*******************************************************************
*
* t1parse.h 2.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 Type 1 parser is in charge of the following:
*
* - provide an implementation of a growing sequence of
* objects called a T1_Table (used to build various tables
* needed by the loader).
*
* - opening .pfb and .pfa files to extract their top-level
* and private dictionaries
*
* - read numbers, arrays & strings from any dictionary
*
* See "t1load.c" to see how data is loaded from the font file
*
******************************************************************/
#ifndef T1PARSE_H
#define T1PARSE_H
#include <t1types.h>
#ifdef __cplusplus
extern "C" {
#endif
/*************************************************************************
*
* <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
*
* init :: boolean. set when the table has been initialized
* (the table user should set this field)
*
* 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
*
* memory :: memory 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_Long init;
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 T1_Parser is an object used to parse a Type 1 fonts very
* quickly.
*
* <Fields>
* stream :: current input stream
* memory :: current memory object
*
* base_dict :: pointer to top-level dictionary
* base_len :: length in bytes of top dict
*
* private_dict :: pointer to private dictionary
* private_len :: length in bytes of private dict
*
* in_pfb :: boolean. Indicates that we're in a .pfb file
* in_memory :: boolean. Indicates a memory-based stream
* single_block :: boolean. Indicates that the private dict
* is stored in lieu of the base dict
*
* cursor :: current parser cursor
* limit :: current parser limit (first byte after current
* dictionary).
*
* error :: current parsing error
*/
typedef struct T1_Parser_
{
FT_Stream stream;
FT_Memory memory;
T1_Byte* base_dict;
T1_Int base_len;
T1_Byte* private_dict;
T1_Int private_len;
T1_Byte in_pfb;
T1_Byte in_memory;
T1_Byte single_block;
T1_Byte* cursor;
T1_Byte* limit;
T1_Error error;
} T1_Parser;
LOCAL_DEF
T1_Error T1_New_Table( T1_Table* table,
T1_Int count,
FT_Memory memory );
LOCAL_DEF
T1_Error T1_Add_Table( T1_Table* table,
T1_Int index,
void* object,
T1_Int length );
LOCAL_DEF
void T1_Done_Table( T1_Table* table );
LOCAL_DEF
void T1_Release_Table( T1_Table* table );
LOCAL_DEF
T1_Long T1_ToInt ( T1_Parser* parser );
LOCAL_DEF
T1_Long T1_ToFixed( T1_Parser* parser, T1_Int power_ten );
LOCAL_DEF
T1_Int T1_ToCoordArray( T1_Parser* parser,
T1_Int max_coords,
T1_Short* coords );
LOCAL_DEF
T1_Int T1_ToFixedArray( T1_Parser* parser,
T1_Int max_values,
T1_Fixed* values,
T1_Int power_ten );
LOCAL_DEF
T1_String* T1_ToString( T1_Parser* parser );
LOCAL_DEF
T1_Bool T1_ToBool( T1_Parser* parser );
LOCAL_DEF
T1_Int T1_ToImmediate( T1_Parser* parser );
LOCAL_DEF
T1_Error T1_New_Parser( T1_Parser* parser,
FT_Stream stream,
FT_Memory memory );
LOCAL_DEF
T1_Error T1_Get_Private_Dict( T1_Parser* parser );
LOCAL_DEF
void T1_Decrypt( T1_Byte* buffer,
T1_Int length,
T1_UShort seed );
#ifdef __cplusplus
}
#endif
#endif /* T1PARSE_H */
/* END */

73
src/type1z/t1tokens.h Normal file
View File

@ -0,0 +1,73 @@
/*******************************************************************
*
* t1tokens.h
*
* Type 1 tokens definition
*
* Copyright 2000 David Turner, Robert Wilhelm and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used
* modified and distributed under the terms of the FreeType project
* license, LICENSE.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 only contains macros that are expanded when compiling
* the "t1load.c" source file.
*
******************************************************************/
#undef FACE
#define FACE (face->type1)
/* define the font info dictionary parsing callbacks */
PARSE_STRING("version",version)
PARSE_STRING("Notice",notice)
PARSE_STRING("FullName",full_name)
PARSE_STRING("FamilyName",family_name)
PARSE_STRING("Weight",weight)
PARSE_INT("ItalicAngle",italic_angle)
PARSE_BOOL("isFixedPitch",is_fixed_pitch)
PARSE_INT("UnderlinePosition",underline_position)
PARSE_INT("UnderlineThickness",underline_thickness)
/* define the private dict parsing callbacks */
PARSE_INT("UniqueID",unique_id)
PARSE_INT("lenIV",lenIV)
PARSE_COORDS( "BlueValues", num_blues, 14, blue_values)
PARSE_COORDS( "OtherBlues", num_other_blues, 10, other_blues)
PARSE_COORDS( "FamilyBlues", num_family_blues, 14, family_blues)
PARSE_COORDS( "FamilyOtherBlues", num_family_other_blues, 10, family_other_blues)
PARSE_FIXED( "BlueScale", blue_scale)
PARSE_INT( "BlueShift", blue_shift)
PARSE_INT( "BlueFuzz", blue_fuzz)
PARSE_COORDS2( "StdHW", 1, standard_width )
PARSE_COORDS2( "StdVW", 1, standard_height )
PARSE_COORDS( "StemSnapH", num_snap_widths, 12, stem_snap_widths )
PARSE_COORDS( "StemSnapV", num_snap_heights, 12, stem_snap_heights )
PARSE_INT( "LanguageGroup", language_group )
PARSE_INT( "password", password )
PARSE_COORDS2( "MinFeature", 2, min_feature )
/* define the top-level dictionary parsing callbacks */
/* PARSE_STRING( "FontName", font_name ) -- handled by special routine */
PARSE_INT( "PaintType", paint_type )
PARSE_INT( "FontType", font_type )
PARSE_FIXEDS2( "FontMatrix", 4, font_matrix )
/* PARSE_COORDS2( "FontBBox", 4, font_bbox ) -- handled by special func */
PARSE_INT( "StrokeWidth", stroke_width )
#undef FACE

41
src/type1z/type1z.c Normal file
View File

@ -0,0 +1,41 @@
/***************************************************************************/
/* */
/* 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 */
/* */
/***************************************************************************/
#include <t1parse.c>
#include <t1load.c>
#include <t1objs.c>
#include <t1driver.c>
/*
#include <t1hinter.c>
#include <t1gload.c>
#include <t1encode.c>
*/