parent
a519b3b7a3
commit
4f99c3c423
17 changed files with 3533 additions and 8 deletions
@ -0,0 +1,49 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* cff.c */ |
||||
/* */ |
||||
/* FreeType OpenType driver component (body only). */ |
||||
/* */ |
||||
/* Copyright 1996-1999 by */ |
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
||||
/* */ |
||||
/* This file is part of the FreeType project, and may only be used */ |
||||
/* modified and distributed under the terms of the FreeType project */ |
||||
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
||||
/* this file you indicate that you have read the license and */ |
||||
/* understand and accept it fully. */ |
||||
/* */ |
||||
/***************************************************************************/ |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* This file is used to compile the FreeType TrueType font driver. It */ |
||||
/* relies on all components included in the `base' layer (see the file */ |
||||
/* `ftbase.c'). The source code is located in `freetype/ttlib' and */ |
||||
/* contains: */ |
||||
/* */ |
||||
/* - a driver interface */ |
||||
/* - an object manager */ |
||||
/* - a table loader */ |
||||
/* - a glyph loader */ |
||||
/* - a glyph hinter/bytecode interpreter */ |
||||
/* - a charmap processor */ |
||||
/* - an extension manager (only used for some tools) */ |
||||
/* */ |
||||
/* Note that the engine extensions found in `freetype/ttlib/extend' are */ |
||||
/* reserved to specific tools and/or font servers; they're not part of */ |
||||
/* the `core' TrueType driver, even though they are separately linkable */ |
||||
/* to it. */ |
||||
/* */ |
||||
/*************************************************************************/ |
||||
|
||||
|
||||
#define FT_MAKE_OPTION_SINGLE_OBJECT |
||||
|
||||
#include <t2driver.c> /* driver interface */ |
||||
#include <t2parse.c> /* token parser */ |
||||
#include <t2load.c> /* tables loader */ |
||||
#include <t2objs.c> /* object management */ |
||||
|
||||
/* END */ |
@ -0,0 +1,7 @@ |
||||
make_module_list: add_cff_driver |
||||
|
||||
add_cff_driver: |
||||
$(OPEN_DRIVER)cff_driver_interface$(CLOSE_DRIVER)
|
||||
$(ECHO_DRIVER)cff $(ECHO_DRIVER_DESC)OpenType fonts with extension *.otf$(ECHO_DRIVER_DONE)
|
||||
|
||||
# EOF
|
@ -0,0 +1,112 @@ |
||||
#
|
||||
# FreeType 2 OpenType/CFF driver configuration rules
|
||||
#
|
||||
|
||||
|
||||
# Copyright 1996-2000 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used modified
|
||||
# and distributed under the terms of the FreeType project license,
|
||||
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
|
||||
# indicate that you have read the license and understand and accept it
|
||||
# fully.
|
||||
|
||||
|
||||
# Include the rules defined for the SFNT driver, which is heavily used
|
||||
# by the TrueType one.
|
||||
#
|
||||
include $(SRC_)sfnt/rules.mk |
||||
|
||||
|
||||
# OpenType driver directory
|
||||
#
|
||||
T2_DIR := $(SRC_)cff
|
||||
T2_DIR_ := $(T2_DIR)$(SEP)
|
||||
|
||||
|
||||
# location of all extensions to the driver, if any
|
||||
#
|
||||
T2_EXT_DIR := $(T2_DIR_)extend
|
||||
T2_EXT_DIR_ := $(T2_EXT_DIR)$(SEP)
|
||||
|
||||
# additional include flags used when compiling the driver
|
||||
#
|
||||
T2_INCLUDE := $(SFNT_INCLUDE) $(T2_DIR) $(T2_EXT_DIR)
|
||||
|
||||
|
||||
# compilation flags for the driver
|
||||
#
|
||||
T2_CFLAGS := $(T2_INCLUDE:%=$I%)
|
||||
T2_COMPILE := $(FT_COMPILE) $(T2_CFLAGS)
|
||||
|
||||
|
||||
# driver sources (i.e., C files)
|
||||
#
|
||||
T2_DRV_SRC := $(T2_DIR_)t2objs.c \
|
||||
$(T2_DIR_)t2load.c \
|
||||
$(T2_DIR_)t2gload.c \
|
||||
$(T2_DIR_)t2parse.c \
|
||||
$(T2_DIR_)t2driver.c
|
||||
|
||||
# driver headers
|
||||
#
|
||||
T2_DRV_H := $(SFNT_H) \
|
||||
$(T2_DRV_SRC:%.c=%.h)
|
||||
|
||||
|
||||
# default extensions headers
|
||||
#
|
||||
T2_EXT_H := $(T2_EXT_SRC:.c=.h)
|
||||
|
||||
|
||||
# driver object(s)
|
||||
#
|
||||
# T2_DRV_OBJ_M is used during `debug' builds
|
||||
# T2_DRV_OBJ_S is used during `release' builds
|
||||
#
|
||||
T2_DRV_OBJ_M := $(T2_DRV_SRC:$(T2_DIR_)%.c=$(OBJ_)%.$O)
|
||||
T2_DRV_OBJ_S := $(OBJ_)cff.$O
|
||||
|
||||
|
||||
# default extensions objects
|
||||
#
|
||||
T2_EXT_OBJ := $(T2_EXT_SRC:$(T2_EXT_DIR_)%.c=$(OBJ_)%.$O)
|
||||
|
||||
|
||||
# driver source file(s)
|
||||
#
|
||||
T2_DRV_SRC_M := $(T2_DRV_SRC) $(SFNT_SRC)
|
||||
T2_DRV_SRC_S := $(T2_DIR_)cff.c
|
||||
|
||||
|
||||
# driver - single object
|
||||
#
|
||||
# the driver is recompiled if any of the header or source files is changed
|
||||
# as well as any of the shared source files found in `shared/sfnt'
|
||||
#
|
||||
$(T2_DRV_OBJ_S): $(BASE_H) $(T2_DRV_H) $(T2_DRV_SRC) $(T2_DRV_SRC_S) |
||||
$(T2_COMPILE) $T$@ $(T2_DRV_SRC_S)
|
||||
|
||||
|
||||
|
||||
# driver - multiple objects
|
||||
#
|
||||
# All objects are recompiled if any of the header files is changed
|
||||
#
|
||||
$(OBJ_)t2%.$O: $(T2_DIR_)t2%.c $(BASE_H) $(T2_DRV_H) |
||||
$(T2_COMPILE) $T$@ $<
|
||||
|
||||
$(OBJ_)t2x%.$O: $(T2_EXT_DIR_)t2x%.c $(BASE_H) $(SFNT_H) $(T2_EXT_H) |
||||
$(T2_COMPILE) $T$@ $<
|
||||
|
||||
$(OBJ_)t2%.$O: $(SFNT_DIR_)t2%.c $(BASE_H) $(SFNT_H) |
||||
$(T2_COMPILE) $T$@ $<
|
||||
|
||||
|
||||
# update main driver object lists
|
||||
#
|
||||
DRV_OBJS_S += $(T2_DRV_OBJ_S)
|
||||
DRV_OBJS_M += $(T2_DRV_OBJ_M)
|
||||
|
||||
# EOF
|
@ -0,0 +1,444 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* t2driver.c */ |
||||
/* */ |
||||
/* OpenType font driver implementation (body). */ |
||||
/* */ |
||||
/* Copyright 1996-1999 by */ |
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
||||
/* */ |
||||
/* This file is part of the FreeType project, and may only be used, */ |
||||
/* modified, and distributed under the terms of the FreeType project */ |
||||
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
||||
/* this file you indicate that you have read the license and */ |
||||
/* understand and accept it fully. */ |
||||
/* */ |
||||
/***************************************************************************/ |
||||
|
||||
|
||||
#include <freetype/internal/ftdebug.h> |
||||
#include <freetype/internal/ftstream.h> |
||||
#include <freetype/internal/sfnt.h> |
||||
#include <freetype/ttnameid.h> |
||||
|
||||
#include <t2driver.h> |
||||
#include <t2gload.h> |
||||
|
||||
|
||||
#undef FT_COMPONENT |
||||
#define FT_COMPONENT trace_ttdriver |
||||
|
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/**** ****/ |
||||
/**** ****/ |
||||
/**** F A C E S ****/ |
||||
/**** ****/ |
||||
/**** ****/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
|
||||
#undef PAIR_TAG |
||||
#define PAIR_TAG( left, right ) ( ((TT_ULong)left << 16) | (TT_ULong)right ) |
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Function> */ |
||||
/* Get_Kerning */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* A driver method used to return the kerning vector between two */ |
||||
/* glyphs of the same face. */ |
||||
/* */ |
||||
/* <Input> */ |
||||
/* face :: A handle to the source face object. */ |
||||
/* */ |
||||
/* left_glyph :: The index of the left glyph in the kern pair. */ |
||||
/* */ |
||||
/* right_glyph :: The index of the right glyph in the kern pair. */ |
||||
/* */ |
||||
/* <Output> */ |
||||
/* kerning :: The kerning vector. This is in font units for */ |
||||
/* scalable formats, and in pixels for fixed-sizes */ |
||||
/* formats. */ |
||||
/* */ |
||||
/* <Return> */ |
||||
/* FreeType error code. 0 means success. */ |
||||
/* */ |
||||
/* <Note> */ |
||||
/* Only horizontal layouts (left-to-right & right-to-left) are */ |
||||
/* supported by this function. Other layouts, or more sophisticated */ |
||||
/* kernings are out of scope of this method (the basic driver */ |
||||
/* interface is meant to be simple). */ |
||||
/* */ |
||||
/* They can be implemented by format-specific interfaces. */ |
||||
/* */ |
||||
static |
||||
TT_Error Get_Kerning( TT_Face face, |
||||
TT_UInt left_glyph, |
||||
TT_UInt right_glyph, |
||||
TT_Vector* kerning ) |
||||
{ |
||||
TT_Kern_0_Pair* pair; |
||||
|
||||
|
||||
if ( !face ) |
||||
return FT_Err_Invalid_Face_Handle; |
||||
|
||||
kerning->x = 0; |
||||
kerning->y = 0; |
||||
|
||||
if ( face->kern_pairs ) |
||||
{ |
||||
/* there are some kerning pairs in this font file! */ |
||||
TT_ULong search_tag = PAIR_TAG( left_glyph, right_glyph ); |
||||
TT_Long left, right; |
||||
|
||||
|
||||
left = 0; |
||||
right = face->num_kern_pairs - 1; |
||||
|
||||
while ( left <= right ) |
||||
{ |
||||
TT_Int middle = left + ((right-left) >> 1); |
||||
TT_ULong cur_pair; |
||||
|
||||
|
||||
pair = face->kern_pairs + middle; |
||||
cur_pair = PAIR_TAG( pair->left, pair->right ); |
||||
|
||||
if ( cur_pair == search_tag ) |
||||
goto Found; |
||||
|
||||
if ( cur_pair < search_tag ) |
||||
left = middle+1; |
||||
else |
||||
right = middle-1; |
||||
} |
||||
} |
||||
|
||||
Exit: |
||||
return FT_Err_Ok; |
||||
|
||||
Found: |
||||
kerning->x = pair->value; |
||||
goto Exit; |
||||
} |
||||
|
||||
|
||||
#undef PAIR_TAG |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/**** ****/ |
||||
/**** ****/ |
||||
/**** S I Z E S ****/ |
||||
/**** ****/ |
||||
/**** ****/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Function> */ |
||||
/* Set_Char_Sizes */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* A driver method used to reset a size's character sizes (horizontal */ |
||||
/* and vertical) expressed in fractional points. */ |
||||
/* */ |
||||
/* <Input> */ |
||||
/* char_width :: The character width expressed in 26.6 fractional */ |
||||
/* points. */ |
||||
/* char_height :: The character height expressed in 26.6 fractional */ |
||||
/* points. */ |
||||
/* */ |
||||
/* <InOut> */ |
||||
/* size :: A handle to the target size object. */ |
||||
/* */ |
||||
/* <Return> */ |
||||
/* FreeType error code. 0 means success. */ |
||||
/* */ |
||||
static |
||||
TT_Error Set_Char_Sizes( T2_Size size, |
||||
FT_F26Dot6 char_width, |
||||
FT_F26Dot6 char_height, |
||||
FT_UInt horz_resolution, |
||||
FT_UInt vert_resolution ) |
||||
{ |
||||
FT_Size_Metrics* metrics = &size->metrics; |
||||
T2_Face face = (T2_Face)size->face; |
||||
FT_Long dim_x, dim_y; |
||||
|
||||
/* This bit flag, when set, indicates that the pixel size must be */ |
||||
/* truncated to an integer. Nearly all TrueType fonts have this */ |
||||
/* bit set, as hinting won't work really well otherwise. */ |
||||
/* */ |
||||
/* However, for those rare fonts who do not set it, we override */ |
||||
/* the default computations performed by the base layer. I really */ |
||||
/* don't know if this is useful, but hey, that's the spec :-) */ |
||||
/* */ |
||||
if ( (face->header.Flags & 8) == 0 ) |
||||
{ |
||||
/* Compute pixel sizes in 26.6 units */ |
||||
dim_x = (char_width * horz_resolution) / 72; |
||||
dim_y = (char_height * vert_resolution) / 72; |
||||
|
||||
metrics->x_scale = FT_DivFix( dim_x, face->root.units_per_EM ); |
||||
metrics->y_scale = FT_DivFix( dim_y, face->root.units_per_EM ); |
||||
|
||||
metrics->x_ppem = (TT_UShort)(dim_x >> 6); |
||||
metrics->y_ppem = (TT_UShort)(dim_y >> 6); |
||||
} |
||||
|
||||
return T2_Reset_Size( size ); |
||||
} |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Function> */ |
||||
/* Set_Pixel_Sizes */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* A driver method used to reset a size's character sizes (horizontal */ |
||||
/* and vertical) expressed in integer pixels. */ |
||||
/* */ |
||||
/* <Input> */ |
||||
/* pixel_width :: The character width expressed in integer pixels. */ |
||||
/* */ |
||||
/* pixel_height :: The character height expressed in integer pixels. */ |
||||
/* */ |
||||
/* <InOut> */ |
||||
/* size :: A handle to the target size object. */ |
||||
/* */ |
||||
/* <Return> */ |
||||
/* FreeType error code. 0 means success */ |
||||
/* */ |
||||
static |
||||
FT_Error Set_Pixel_Sizes( T2_Size size, |
||||
FT_UInt pixel_width, |
||||
FT_UInt pixel_height ) |
||||
{ |
||||
UNUSED(pixel_width); |
||||
UNUSED(pixel_height); |
||||
|
||||
return T2_Reset_Size( size ); |
||||
} |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Function> */ |
||||
/* Load_Glyph */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* A driver method used to load a glyph within a given glyph slot. */ |
||||
/* */ |
||||
/* <Input> */ |
||||
/* slot :: A handle to the target slot object where the glyph */ |
||||
/* will be loaded. */ |
||||
/* */ |
||||
/* size :: A handle to the source face size at which the glyph */ |
||||
/* must be scaled/loaded/etc. */ |
||||
/* */ |
||||
/* glyph_index :: The index of the glyph in the font file. */ |
||||
/* */ |
||||
/* load_flags :: A flag indicating what to load for this glyph. The */ |
||||
/* FTLOAD_??? constants can be used to control the */ |
||||
/* glyph loading process (e.g., whether the outline */ |
||||
/* should be scaled, whether to load bitmaps or not, */ |
||||
/* whether to hint the outline, etc). */ |
||||
/* <Output> */ |
||||
/* result :: A set of bit flags indicating the type of data that */ |
||||
/* was loaded in the glyph slot (outline, bitmap, */ |
||||
/* pixmap, etc). */ |
||||
/* */ |
||||
/* <Return> */ |
||||
/* FreeType error code. 0 means success. */ |
||||
/* */ |
||||
static |
||||
FT_Error Load_Glyph( T2_GlyphSlot slot, |
||||
T2_Size size, |
||||
FT_UShort glyph_index, |
||||
FT_UInt load_flags ) |
||||
{ |
||||
FT_Error error; |
||||
|
||||
|
||||
if ( !slot ) |
||||
return FT_Err_Invalid_Handle; |
||||
|
||||
/* check that we want a scaled outline or bitmap */ |
||||
if ( !size ) |
||||
load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; |
||||
|
||||
if ( load_flags & FT_LOAD_NO_SCALE ) |
||||
size = NULL; |
||||
|
||||
/* reset the size object if necessary */ |
||||
if ( size ) |
||||
{ |
||||
/* these two object must have the same parent */ |
||||
if ( size->face != slot->face ) |
||||
return FT_Err_Invalid_Face_Handle; |
||||
} |
||||
|
||||
/* now load the glyph outline if necessary */ |
||||
#if 1 /* XXXX: TODO */ |
||||
error = FT_Err_Unimplemented_Feature; |
||||
#else |
||||
error = T2_Load_Glyph( size, slot, glyph_index, load_flags ); |
||||
#endif |
||||
/* force drop-out mode to 2 - irrelevant now */ |
||||
/* slot->outline.dropout_mode = 2; */ |
||||
|
||||
return error; |
||||
} |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/**** ****/ |
||||
/**** ****/ |
||||
/**** C H A R A C T E R M A P P I N G S ****/ |
||||
/**** ****/ |
||||
/**** ****/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Function> */ |
||||
/* Get_Char_Index */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* Uses a charmap to return a given character code's glyph index. */ |
||||
/* */ |
||||
/* <Input> */ |
||||
/* charmap :: A handle to the source charmap object. */ |
||||
/* charcode :: The character code. */ |
||||
/* */ |
||||
/* <Return> */ |
||||
/* Glyph index. 0 means `undefined character code'. */ |
||||
/* */ |
||||
static |
||||
FT_UInt Get_Char_Index( TT_CharMap charmap, |
||||
FT_Long charcode ) |
||||
{ |
||||
FT_Error error; |
||||
T2_Face face; |
||||
TT_CMapTable* cmap; |
||||
|
||||
cmap = &charmap->cmap; |
||||
face = (T2_Face)charmap->root.face; |
||||
|
||||
/* Load table if needed */ |
||||
if ( !cmap->loaded ) |
||||
{ |
||||
SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt; |
||||
|
||||
error = sfnt->load_charmap( face, cmap, face->root.stream ); |
||||
if (error) return error; |
||||
|
||||
cmap->loaded = TRUE; |
||||
} |
||||
|
||||
return (cmap->get_index ? cmap->get_index( cmap, charcode ) : 0 ); |
||||
} |
||||
|
||||
|
||||
static |
||||
FTDriver_Interface t2_get_interface( T2_Driver driver, const char* interface ) |
||||
{ |
||||
FT_Driver sfntd = FT_Get_Driver( driver->root.library, "sfnt" ); |
||||
SFNT_Interface* sfnt; |
||||
|
||||
/* only return the default interface from the SFNT module */ |
||||
if (sfntd) |
||||
{ |
||||
sfnt = (SFNT_Interface*)(sfntd->interface.format_interface); |
||||
if (sfnt) |
||||
return sfnt->get_interface( (FT_Driver)driver, interface ); |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
|
||||
/* The FT_DriverInterface structure is defined in ftdriver.h. */ |
||||
|
||||
const FT_DriverInterface cff_driver_interface = |
||||
{ |
||||
sizeof ( T2_DriverRec ), |
||||
sizeof ( TT_FaceRec ), |
||||
sizeof ( FT_SizeRec ), |
||||
sizeof ( FT_GlyphSlotRec ), |
||||
|
||||
"cff", /* driver name */ |
||||
100, /* driver version == 1.0 */ |
||||
200, /* driver requires FreeType 2.0 or above */ |
||||
|
||||
(void*)0, |
||||
|
||||
(FTDriver_initDriver) T2_Init_Driver, |
||||
(FTDriver_doneDriver) T2_Done_Driver, |
||||
(FTDriver_getInterface) t2_get_interface, |
||||
|
||||
(FTDriver_initFace) T2_Init_Face, |
||||
(FTDriver_doneFace) T2_Done_Face, |
||||
(FTDriver_getKerning) Get_Kerning, |
||||
|
||||
(FTDriver_initSize) T2_Init_Size, |
||||
(FTDriver_doneSize) T2_Done_Size, |
||||
(FTDriver_setCharSizes) Set_Char_Sizes, |
||||
(FTDriver_setPixelSizes) Set_Pixel_Sizes, |
||||
|
||||
(FTDriver_initGlyphSlot) T2_Init_GlyphSlot, |
||||
(FTDriver_doneGlyphSlot) T2_Done_GlyphSlot, |
||||
(FTDriver_loadGlyph) Load_Glyph, |
||||
|
||||
(FTDriver_getCharIndex) Get_Char_Index, |
||||
}; |
||||
|
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Function> */ |
||||
/* getDriverInterface */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* This function is used when compiling the TrueType driver as a */ |
||||
/* shared library (`.DLL' or `.so'). It will be used by the */ |
||||
/* high-level library of FreeType to retrieve the address of the */ |
||||
/* driver's generic interface. */ |
||||
/* */ |
||||
/* It shouldn't be implemented in a static build, as each driver must */ |
||||
/* have the same function as an exported entry point. */ |
||||
/* */ |
||||
/* <Return> */ |
||||
/* The address of the TrueType's driver generic interface. The */ |
||||
/* format-specific interface can then be retrieved through the method */ |
||||
/* interface->get_format_interface. */ |
||||
/* */ |
||||
#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS |
||||
|
||||
EXPORT_FUNC(FT_DriverInterface*) getDriverInterface( void ) |
||||
{ |
||||
return &cff_driver_interface; |
||||
} |
||||
|
||||
#endif /* CONFIG_OPTION_DYNAMIC_DRIVERS */ |
||||
|
||||
|
||||
/* END */ |
@ -0,0 +1,34 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* t2driver.h */ |
||||
/* */ |
||||
/* High-level OpenType driver interface (specification). */ |
||||
/* */ |
||||
/* Copyright 1996-1999 by */ |
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
||||
/* */ |
||||
/* This file is part of the FreeType project, and may only be used, */ |
||||
/* modified, and distributed under the terms of the FreeType project */ |
||||
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
||||
/* this file you indicate that you have read the license and */ |
||||
/* understand and accept it fully. */ |
||||
/* */ |
||||
/***************************************************************************/ |
||||
|
||||
|
||||
#ifndef T2DRIVER_H |
||||
#define T2DRIVER_H |
||||
|
||||
#include <freetype/internal/ftdriver.h> |
||||
#include <freetype/ttnameid.h> |
||||
#include <t2objs.h> |
||||
#include <t2errors.h> |
||||
|
||||
|
||||
FT_EXPORT_VAR(const FT_DriverInterface) cff_driver_interface; |
||||
|
||||
|
||||
#endif /* T2DRIVER_H */ |
||||
|
||||
|
||||
/* END */ |
@ -0,0 +1,126 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* t2errors.h */ |
||||
/* */ |
||||
/* OpenType error ID definitions (specification only). */ |
||||
/* */ |
||||
/* Copyright 1996-1999 by */ |
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
||||
/* */ |
||||
/* This file is part of the FreeType project, and may only be used */ |
||||
/* modified and distributed under the terms of the FreeType project */ |
||||
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
||||
/* this file you indicate that you have read the license and */ |
||||
/* understand and accept it fully. */ |
||||
/* */ |
||||
/***************************************************************************/ |
||||
|
||||
|
||||
#ifndef T2ERRORS_H |
||||
#define T2ERRORS_H |
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* Error codes declaration */ |
||||
/* */ |
||||
/* The error codes are grouped in `classes' used to indicate the `level' */ |
||||
/* at which the error happened. The class is given by an error code's */ |
||||
/* high byte. */ |
||||
/* */ |
||||
/*************************************************************************/ |
||||
|
||||
|
||||
/* Success is always 0. */ |
||||
|
||||
#define T2_Err_Ok FT_Err_Ok |
||||
|
||||
/* High level API errors. */ |
||||
|
||||
#define T2_Err_Invalid_File_Format FT_Err_Invalid_File_Format |
||||
#define T2_Err_Invalid_Argument FT_Err_Invalid_Argument |
||||
#define T2_Err_Invalid_Driver_Handle FT_Err_Invalid_Driver_Handle |
||||
#define T2_Err_Invalid_Face_Handle FT_Err_Invalid_Face_Handle |
||||
#define T2_Err_Invalid_Instance_Handle FT_Err_Invalid_Size_Handle |
||||
#define T2_Err_Invalid_Glyph_Handle FT_Err_Invalid_Slot_Handle |
||||
#define T2_Err_Invalid_CharMap_Handle FT_Err_Invalid_CharMap_Handle |
||||
#define T2_Err_Invalid_Glyph_Index FT_Err_Invalid_Glyph_Index |
||||
|
||||
#define T2_Err_Unimplemented_Feature FT_Err_Unimplemented_Feature |
||||
#define T2_Err_Unavailable_Outline FT_Err_Unavailable_Outline |
||||
#define T2_Err_Unavailable_Bitmap FT_Err_Unavailable_Bitmap |
||||
#define T2_Err_Unavailable_Pixmap FT_Err_Unavailable_Pixmap |
||||
#define T2_Err_File_Is_Not_Collection FT_Err_File_Is_Not_Collection |
||||
|
||||
#define T2_Err_Invalid_Engine FT_Err_Invalid_Driver_Handle |
||||
|
||||
/* Internal errors. */ |
||||
|
||||
#define T2_Err_Out_Of_Memory FT_Err_Out_Of_Memory |
||||
#define T2_Err_Unlisted_Object FT_Err_Unlisted_Object |
||||
|
||||
/* General glyph outline errors. */ |
||||
|
||||
#define T2_Err_Too_Many_Points FT_Err_Too_Many_Points |
||||
#define T2_Err_Too_Many_Contours FT_Err_Too_Many_Contours |
||||
#define T2_Err_Too_Many_Ins FT_Err_Too_Many_Hints |
||||
#define T2_Err_Invalid_Composite FT_Err_Invalid_Composite |
||||
|
||||
/* Bytecode interpreter error codes. */ |
||||
|
||||
/* These error codes are produced by the TrueType */ |
||||
/* bytecode interpreter. They usually indicate a */ |
||||
/* broken font file, a broken glyph within a font */ |
||||
/* file, or a bug in the interpreter! */ |
||||
|
||||
#define T2_Err_Invalid_Opcode 0x400 |
||||
#define T2_Err_Too_Few_Arguments 0x401 |
||||
#define T2_Err_Stack_Overflow 0x402 |
||||
#define T2_Err_Code_Overflow 0x403 |
||||
#define T2_Err_Bad_Argument 0x404 |
||||
#define T2_Err_Divide_By_Zero 0x405 |
||||
#define T2_Err_Storage_Overflow 0x406 |
||||
#define T2_Err_Cvt_Overflow 0x407 |
||||
#define T2_Err_Invalid_Reference 0x408 |
||||
#define T2_Err_Invalid_Distance 0x409 |
||||
#define T2_Err_Interpolate_Twilight 0x40A |
||||
#define T2_Err_Debug_OpCode 0x40B |
||||
#define T2_Err_ENDF_In_Exec_Stream 0x40C |
||||
#define T2_Err_Out_Of_CodeRanges 0x40D |
||||
#define T2_Err_Nested_DEFS 0x40E |
||||
#define T2_Err_Invalid_CodeRange 0x40F |
||||
#define T2_Err_Invalid_Displacement 0x410 |
||||
#define T2_Err_Execution_Too_Long 0x411 |
||||
|
||||
#define T2_Err_Too_Many_Instruction_Defs 0x412 |
||||
#define T2_Err_Too_Many_Function_Defs 0x412 |
||||
|
||||
/* Other TrueType specific error codes. */ |
||||
|
||||
#define T2_Err_Table_Missing 0x420 |
||||
#define T2_Err_Too_Many_Extensions 0x421 |
||||
#define T2_Err_Extensions_Unsupported 0x422 |
||||
#define T2_Err_Invalid_Extension_Id 0x423 |
||||
|
||||
#define T2_Err_No_Vertical_Data 0x424 |
||||
|
||||
#define T2_Err_Max_Profile_Missing 0x430 |
||||
#define T2_Err_Header_Table_Missing 0x431 |
||||
#define T2_Err_Horiz_Header_Missing 0x432 |
||||
#define T2_Err_Locations_Missing 0x433 |
||||
#define T2_Err_Name_Table_Missing 0x434 |
||||
#define T2_Err_CMap_Table_Missing 0x435 |
||||
#define T2_Err_Hmtx_Table_Missing 0x436 |
||||
#define T2_Err_OS2_Table_Missing 0x437 |
||||
#define T2_Err_Post_Table_Missing 0x438 |
||||
|
||||
#define T2_Err_Invalid_Horiz_Metrics 0x440 |
||||
#define T2_Err_Invalid_CharMap_Format 0x441 |
||||
#define T2_Err_Invalid_PPem 0x442 |
||||
#define T2_Err_Invalid_Vert_Metrics 0x443 |
||||
|
||||
#define T2_Err_Could_Not_Find_Context 0x450 |
||||
|
||||
#endif /* FTERRID_H */ |
||||
|
||||
|
||||
/* END */ |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,140 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* t2gload.h */ |
||||
/* */ |
||||
/* OpenType Glyph Loader (specification). */ |
||||
/* */ |
||||
/* Copyright 1996-1999 by */ |
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
||||
/* */ |
||||
/* This file is part of the FreeType project, and may only be used */ |
||||
/* modified and distributed under the terms of the FreeType project */ |
||||
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
||||
/* this file you indicate that you have read the license and */ |
||||
/* understand and accept it fully. */ |
||||
/* */ |
||||
/***************************************************************************/ |
||||
|
||||
|
||||
#ifndef T2GLOAD_H |
||||
#define T2GLOAD_H |
||||
|
||||
#include <t2objs.h> |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
typedef struct T2_Loader_ |
||||
{ |
||||
T2_Face face; |
||||
T2_Size size; |
||||
T2_GlyphSlot glyph; |
||||
|
||||
FT_ULong load_flags; |
||||
FT_UInt glyph_index; |
||||
|
||||
FT_Stream stream; |
||||
FT_Int byte_len; |
||||
FT_Int left_points; |
||||
FT_Int left_contours; |
||||
|
||||
FT_BBox bbox; |
||||
FT_Int left_bearing; |
||||
FT_Int advance; |
||||
FT_Bool preserve_pps; |
||||
FT_Vector pp1; |
||||
FT_Vector pp2; |
||||
|
||||
FT_ULong glyf_offset; |
||||
|
||||
/* the zone where we load our glyphs */ |
||||
FT_GlyphZone base; |
||||
FT_GlyphZone zone; |
||||
|
||||
} T2_Loader; |
||||
|
||||
|
||||
#if 0 |
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Function> */ |
||||
/* T2_Get_Metrics */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* Returns the horizontal or vertical metrics in font units for a */ |
||||
/* given glyph. The metrics are the left side bearing (resp. top */ |
||||
/* side bearing) and advance width (resp. advance height). */ |
||||
/* */ |
||||
/* <Input> */ |
||||
/* header :: A pointer to either the horizontal or vertical metrics */ |
||||
/* structure. */ |
||||
/* */ |
||||
/* index :: The glyph index. */ |
||||
/* */ |
||||
/* <Output> */ |
||||
/* bearing :: The bearing, either left side or top side. */ |
||||
/* */ |
||||
/* advance :: The advance width resp. advance height. */ |
||||
/* */ |
||||
/* <Note> */ |
||||
/* This function will much probably move to another component in the */ |
||||
/* near future, but I haven't decided which yet. */ |
||||
/* */ |
||||
LOCAL_DEF |
||||
void T2_Get_Metrics( TT_HoriHeader* header, |
||||
FT_UInt index, |
||||
FT_Short* bearing, |
||||
FT_UShort* advance ); |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Function> */ |
||||
/* T2_Load_Glyph */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* A function used to load a single glyph within a given glyph slot, */ |
||||
/* for a given size. */ |
||||
/* */ |
||||
/* <Input> */ |
||||
/* glyph :: A handle to a target slot object where the glyph */ |
||||
/* will be loaded. */ |
||||
/* */ |
||||
/* size :: A handle to the source face size at which the glyph */ |
||||
/* must be scaled/loaded. */ |
||||
/* */ |
||||
/* glyph_index :: The index of the glyph in the font file. */ |
||||
/* */ |
||||
/* load_flags :: A flag indicating what to load for this glyph. The */ |
||||
/* FT_LOAD_XXX constants can be used to control the */ |
||||
/* glyph loading process (e.g., whether the outline */ |
||||
/* should be scaled, whether to load bitmaps or not, */ |
||||
/* whether to hint the outline, etc). */ |
||||
/* <Output> */ |
||||
/* result :: A set of bit flags indicating the type of data that */ |
||||
/* was loaded in the glyph slot (outline or bitmap, */ |
||||
/* etc). */ |
||||
/* */ |
||||
/* You can set this field to 0 if you don't want this */ |
||||
/* information. */ |
||||
/* */ |
||||
/* <Return> */ |
||||
/* FreeType error code. 0 means success. */ |
||||
/* */ |
||||
LOCAL_DEF |
||||
FT_Error T2_Load_Glyph( T2_Size size, |
||||
T2_GlyphSlot glyph, |
||||
FT_UShort glyph_index, |
||||
FT_UInt load_flags ); |
||||
#endif |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
|
||||
#endif /* T2GLOAD_H */ |
||||
|
||||
|
||||
/* END */ |
@ -0,0 +1,292 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* t2load.h */ |
||||
/* */ |
||||
/* TrueType glyph data/program tables loader (body). */ |
||||
/* */ |
||||
/* Copyright 1996-1999 by */ |
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
||||
/* */ |
||||
/* This file is part of the FreeType project, and may only be used */ |
||||
/* modified and distributed under the terms of the FreeType project */ |
||||
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
||||
/* this file you indicate that you have read the license and */ |
||||
/* understand and accept it fully. */ |
||||
/* */ |
||||
/***************************************************************************/ |
||||
|
||||
|
||||
#include <freetype/internal/ftdebug.h> |
||||
#include <freetype/internal/ftobjs.h> |
||||
#include <freetype/internal/ftstream.h> |
||||
|
||||
#include <freetype/fterrors.h> |
||||
#include <freetype/tttags.h> |
||||
#include <t2load.h> |
||||
#include <t2parse.h> |
||||
#include <t2errors.h> |
||||
|
||||
#undef FT_COMPONENT |
||||
#define FT_COMPONENT trace_ttload |
||||
|
||||
/* read a CFF offset from memory */ |
||||
LOCAL_FUNC |
||||
FT_ULong T2_Get_Offset( FT_Byte* p, |
||||
FT_Byte off_size ) |
||||
{ |
||||
FT_ULong result; |
||||
for ( result = 0; off_size > 0; off_size-- ) |
||||
result = (result <<= 8) | *p++; |
||||
return result; |
||||
} |
||||
|
||||
|
||||
#if 0 |
||||
/* read a CFF offset from a stream */ |
||||
LOCAL_FUNC |
||||
FT_ULong T2_Read_Offset( FT_Byte off_size, |
||||
FT_Stream stream ) |
||||
{ |
||||
FT_Byte bytes[4]; |
||||
FT_Byte* p; |
||||
FT_ULong result; |
||||
|
||||
if (off_size > 4) |
||||
off_size = 4; |
||||
|
||||
/* first of all, read or access the bytes - this should really go */ |
||||
/* in "src/base/ftstream.c", but there are great chances that it will */ |
||||
/* never be used elsewhere, so.. */ |
||||
if (stream->read) |
||||
{ |
||||
p = bytes; |
||||
if ( stream->read( stream, stream->pos, (char*)bytes, off_size ) != off_size ) |
||||
goto Fail; |
||||
} |
||||
else |
||||
{ |
||||
p = (FT_Byte*)stream->base + stream->pos; |
||||
if (p+off_size-1 >= (FT_Byte*)stream->limit) |
||||
goto Fail; |
||||
} |
||||
|
||||
result = 0; |
||||
while (off_size > 0) |
||||
{ |
||||
result = (result <<= 8) | *p++; |
||||
off_size--; |
||||
} |
||||
stream->pos += off_size; |
||||
return result; |
||||
|
||||
Fail: |
||||
FT_ERROR(( "T2_Read_Offset:" )); |
||||
FT_ERROR(( " invalid i/o, pos = 0x%lx, size = 0x%lx", |
||||
stream->pos, stream->size )); |
||||
return 0; |
||||
} |
||||
#endif |
||||
|
||||
/* return the memory address of a CFF index's element, when the index */ |
||||
/* is already loaded in memory.. */ |
||||
|
||||
LOCAL_FUNC |
||||
FT_Error T2_Access_Element( CFF_Index* cff_index, |
||||
FT_UInt element, |
||||
FT_Byte* *pbytes, |
||||
FT_ULong *pbyte_len ) |
||||
{ |
||||
FT_Error error; |
||||
|
||||
if (cff_index && cff_index->bytes && element < (FT_UInt)cff_index->count) |
||||
{ |
||||
FT_ULong off1, off2; |
||||
FT_Byte offsize = cff_index->off_size; |
||||
FT_Byte* p = cff_index->bytes + 3 + element*offsize; |
||||
FT_Byte* limit = cff_index->bytes + cff_index->data_offset; |
||||
|
||||
/* read element offset */ |
||||
off1 = T2_Get_Offset(p,offsize); |
||||
|
||||
/* a value of 0 indicates no object !! */ |
||||
if (off1) |
||||
{ |
||||
/* compute offset of next element - skip empty elements */ |
||||
do |
||||
{ |
||||
p += offsize; |
||||
off2 = T2_Get_Offset(p,offsize); |
||||
} |
||||
while (off2 == 0 && p < limit); |
||||
|
||||
if (p >= limit) |
||||
off1 = 0; |
||||
} |
||||
|
||||
*pbytes = 0; |
||||
*pbyte_len = 0; |
||||
if (off1) |
||||
{ |
||||
*pbytes = cff_index->bytes + cff_index->data_offset + off1 - 1; |
||||
*pbyte_len = off2 - off1; |
||||
} |
||||
error = 0; |
||||
} |
||||
else |
||||
error = FT_Err_Invalid_Argument; |
||||
|
||||
return error; |
||||
} |
||||
|
||||
|
||||
LOCAL_FUNC |
||||
|
||||
LOCAL_FUNC |
||||
FT_Error T2_Read_CFF_Index( CFF_Index* index, |
||||
FT_Stream stream ) |
||||
{ |
||||
FT_Error error; |
||||
FT_ULong data_size; |
||||
|
||||
MEM_Set( index, 0, sizeof(*index) ); |
||||
index->file_offset = FILE_Pos(); |
||||
if ( !READ_UShort( index->count ) && |
||||
index->count > 0 ) |
||||
{ |
||||
FT_Byte* p; |
||||
FT_Byte offsize; |
||||
|
||||
/* there is at least one element, read the offset size */ |
||||
/* then access the offset table to compute the index's total size */ |
||||
if ( READ_Byte( offsize ) ) |
||||
goto Exit; |
||||
|
||||
index->off_size = offsize; |
||||
index->data_offset = ((FT_Long)index->count + 1)*offsize; |
||||
|
||||
if (ACCESS_Frame( index->data_offset )) |
||||
goto Exit; |
||||
|
||||
/* now read element offset limit */ |
||||
p = (FT_Byte*)stream->cursor + index->data_offset - offsize; |
||||
data_size = T2_Get_Offset( p, offsize ); |
||||
|
||||
FORGET_Frame(); |
||||
|
||||
index->data_offset += 3; |
||||
index->total_size = index->data_offset + data_size; |
||||
|
||||
/* skip the data */ |
||||
(void)FILE_Skip( data_size ); |
||||
} |
||||
Exit: |
||||
return error; |
||||
} |
||||
|
||||
|
||||
LOCAL_FUNC |
||||
FT_Error T2_Load_CFF_Index( CFF_Index* index, |
||||
FT_Stream stream ) |
||||
{ |
||||
FT_Error error; |
||||
|
||||
/* we begin by reading the index's data */ |
||||
error = T2_Read_CFF_Index( index, stream ); |
||||
if (!error && index->total_size > 0) |
||||
{ |
||||
/* OK, read it from the file */ |
||||
if ( FILE_Seek( index->file_offset ) || |
||||
EXTRACT_Frame( index->total_size, index->bytes ) ) |
||||
goto Exit; |
||||
|
||||
/* done !! */ |
||||
} |
||||
Exit: |
||||
return error; |
||||
} |
||||
|
||||
|
||||
LOCAL_FUNC |
||||
void T2_Done_CFF_Index( CFF_Index* index, |
||||
FT_Stream stream ) |
||||
{ |
||||
if (index->bytes) |
||||
RELEASE_Frame( index->bytes ); |
||||
|
||||
MEM_Set( index, 0, sizeof(*index) ); |
||||
} |
||||
|
||||
|
||||
LOCAL_FUNC |
||||
FT_Error T2_Load_CFF_Font( FT_Stream stream, |
||||
CFF_Font* font ) |
||||
{ |
||||
static const FT_Frame_Field cff_header_fields[] = { |
||||
FT_FRAME_START(4), |
||||
FT_FRAME_BYTE( CFF_Font, version_major ), |
||||
FT_FRAME_BYTE( CFF_Font, version_minor ), |
||||
FT_FRAME_BYTE( CFF_Font, header_size ), |
||||
FT_FRAME_BYTE( CFF_Font, absolute_offsize ), |
||||
FT_FRAME_END }; |
||||
|
||||
FT_Error error; |
||||
|
||||
MEM_Set( font, 0, sizeof(*font) ); |
||||
font->stream = stream; |
||||
font->memory = stream->memory; |
||||
|
||||
/* read CFF font header */ |
||||
if ( READ_Fields( cff_header_fields, font ) ) |
||||
goto Exit; |
||||
|
||||
/* check format */ |
||||
if ( font->version_major != 1 || |
||||
font->header_size < 4 || |
||||
font->absolute_offsize > 4 ) |
||||
{ |
||||
FT_ERROR(( "incorrect CFF font header !!\n" )); |
||||
error = FT_Err_Unknown_File_Format; |
||||
goto Exit; |
||||
} |
||||
|
||||
/* skip the rest of the header */ |
||||
(void)FILE_Skip( font->header_size - 4 ); |
||||
|
||||
/* read the name, top dict, strong and global subrs index */ |
||||
error = T2_Load_CFF_Index( &font->name_index, stream ) || |
||||
T2_Load_CFF_Index( &font->top_dict_index, stream ) || |
||||
T2_Read_CFF_Index( &font->string_index, stream ) || |
||||
T2_Load_CFF_Index( &font->global_subrs_index, stream ); |
||||
if (error) goto Exit; |
||||
|
||||
/* well, we don't really forget the "disable" fonts.. */ |
||||
font->num_faces = font->name_index.count; |
||||
|
||||
Exit: |
||||
return error; |
||||
} |
||||
|
||||
LOCAL_FUNC |
||||
void T2_Done_CFF_Font( CFF_Font* font ) |
||||
{ |
||||
FT_Stream stream = font->stream; |
||||
|
||||
T2_Done_CFF_Index( &font->global_subrs_index, stream ); |
||||
T2_Done_CFF_Index( &font->string_index, stream ); |
||||
T2_Done_CFF_Index( &font->top_dict_index, stream ); |
||||
T2_Done_CFF_Index( &font->name_index, stream ); |
||||
} |
||||
|
||||
|
||||
|
||||
/***********************************************************************/ |
||||
/***********************************************************************/ |
||||
/***********************************************************************/ |
||||
/***** *****/ |
||||
/***** TYPE 2 TABLES DECODING.. *****/ |
||||
/***** *****/ |
||||
/***********************************************************************/ |
||||
/***********************************************************************/ |
||||
/***********************************************************************/ |
||||
|
||||
/* END */ |
@ -0,0 +1,36 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* t2load.h */ |
||||
/* */ |
||||
/* OpenType glyph data/program tables loader (specification). */ |
||||
/* */ |
||||
/* Copyright 1996-1999 by */ |
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
||||
/* */ |
||||
/* This file is part of the FreeType project, and may only be used */ |
||||
/* modified and distributed under the terms of the FreeType project */ |
||||
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
||||
/* this file you indicate that you have read the license and */ |
||||
/* understand and accept it fully. */ |
||||
/* */ |
||||
/***************************************************************************/ |
||||
|
||||
|
||||
#ifndef T2LOAD_H |
||||
#define T2LOAD_H |
||||
|
||||
#include <freetype/internal/t2types.h> |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
|
||||
#endif /* T2LOAD_H */ |
||||
|
||||
|
||||
/* END */ |
@ -0,0 +1,333 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* ttobjs.c */ |
||||
/* */ |
||||
/* Objects manager (body). */ |
||||
/* */ |
||||
/* Copyright 1996-1999 by */ |
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
||||
/* */ |
||||
/* This file is part of the FreeType project, and may only be used */ |
||||
/* modified and distributed under the terms of the FreeType project */ |
||||
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
||||
/* this file you indicate that you have read the license and */ |
||||
/* understand and accept it fully. */ |
||||
/* */ |
||||
/***************************************************************************/ |
||||
|
||||
|
||||
#include <freetype/internal/ftdebug.h> |
||||
#include <freetype/internal/ftcalc.h> |
||||
#include <freetype/internal/ftstream.h> |
||||
#include <freetype/ttnameid.h> |
||||
#include <freetype/tttags.h> |
||||
|
||||
#include <freetype/internal/sfnt.h> |
||||
#include <freetype/internal/psnames.h> |
||||
#include <t2objs.h> |
||||
|
||||
#include <t2load.h> |
||||
#include <t2errors.h> |
||||
|
||||
/* required by tracing mode */ |
||||
#undef FT_COMPONENT |
||||
#define FT_COMPONENT trace_ttobjs |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* GLYPH ZONE FUNCTIONS */ |
||||
/* */ |
||||
/*************************************************************************/ |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Function> */ |
||||
/* T2_Init_Face */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* Initializes a given TrueType face object. */ |
||||
/* */ |
||||
/* <Input> */ |
||||
/* resource :: The source font resource. */ |
||||
/* face_index :: The index of the font face in the resource. */ |
||||
/* face :: The newly built face object. */ |
||||
/* */ |
||||
/* <Return> */ |
||||
/* TrueType error code. 0 means success. */ |
||||
/* */ |
||||
LOCAL_DEF |
||||
FT_Error T2_Init_Face( FT_Stream stream, |
||||
T2_Face face, |
||||
FT_Int face_index, |
||||
FT_Int num_params, |
||||
FT_Parameter* params ) |
||||
{ |
||||
TT_Error error; |
||||
FT_Driver sfnt_driver; |
||||
SFNT_Interface* sfnt; |
||||
|
||||
sfnt_driver = FT_Get_Driver( face->root.driver->library, "sfnt" ); |
||||
if (!sfnt_driver) goto Bad_Format; |
||||
|
||||
sfnt = (SFNT_Interface*)(sfnt_driver->interface.format_interface); |
||||
if (!sfnt) goto Bad_Format; |
||||
|
||||
/* create input stream from resource */ |
||||
if ( FILE_Seek(0) ) |
||||
goto Exit; |
||||
|
||||
/* check that we have a valid TrueType file */ |
||||
error = sfnt->init_face( stream, face, face_index, num_params, params ); |
||||
if (error) goto Exit; |
||||
|
||||
/* We must also be able to accept Mac/GX fonts, as well as OT ones */ |
||||
if ( face->format_tag != 0x4f54544f ) /* OpenType/CFF font */ |
||||
{ |
||||
FT_TRACE2(( "[not a valid OpenType/CFF font]" )); |
||||
goto Bad_Format; |
||||
} |
||||
|
||||
/* If we're performing a simple font format check, exit immediately */ |
||||
if ( face_index < 0 ) |
||||
return FT_Err_Ok; |
||||
|
||||
/* Load font directory */ |
||||
error = sfnt->load_face( stream, face, face_index, num_params, params ); |
||||
if ( error ) goto Exit; |
||||
|
||||
Exit: |
||||
return error; |
||||
Bad_Format:
|
||||
error = FT_Err_Unknown_File_Format; |
||||
goto Exit; |
||||
} |
||||
|
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Function> */ |
||||
/* T2_Done_Face */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* Finalizes a given face object. */ |
||||
/* */ |
||||
/* <Input> */ |
||||
/* face :: A pointer to the face object to destroy. */ |
||||
/* */ |
||||
LOCAL_DEF |
||||
void T2_Done_Face( T2_Face face ) |
||||
{ |
||||
#if 0
|
||||
FT_Memory memory = face->root.memory; |
||||
FT_Stream stream = face->root.stream; |
||||
#endif |
||||
SFNT_Interface* sfnt = face->sfnt; |
||||
|
||||
if (sfnt) |
||||
sfnt->done_face(face); |
||||
|
||||
/* XXXXX: TO DO */ |
||||
} |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* SIZE FUNCTIONS */ |
||||
/* */ |
||||
/*************************************************************************/ |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Function> */ |
||||
/* T2_Init_Size */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* Initializes a new OpenType size object. */ |
||||
/* */ |
||||
/* <InOut> */ |
||||
/* size :: A handle to the size object. */ |
||||
/* */ |
||||
/* <Return> */ |
||||
/* TrueType error code. 0 means success. */ |
||||
/* */ |
||||
LOCAL_DEF |
||||
FT_Error T2_Init_Size( T2_Size size ) |
||||
{ |
||||
UNUSED(size); |
||||
return 0; |
||||
} |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Function> */ |
||||
/* T2_Done_Size */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* The OpenType size object finalizer. */ |
||||
/* */ |
||||
/* <Input> */ |
||||
/* size :: A handle to the target size object. */ |
||||
/* */ |
||||
LOCAL_FUNC |
||||
void T2_Done_Size( T2_Size size ) |
||||
{ |
||||
UNUSED(size); |
||||
} |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Function> */ |
||||
/* T2_Reset_Size */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* Resets a OpenType size when resolutions and character dimensions */ |
||||
/* have been changed. */ |
||||
/* */ |
||||
/* <Input> */ |
||||
/* size :: A handle to the target size object. */ |
||||
/* */ |
||||
LOCAL_DEF |
||||
FT_Error T2_Reset_Size( T2_Size size ) |
||||
{ |
||||
T2_Face face = (T2_Face)size->face; |
||||
FT_Size_Metrics* metrics = &size->metrics; |
||||
FT_Error error = FT_Err_Ok; |
||||
|
||||
if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 ) |
||||
return FT_Err_Invalid_Argument; |
||||
|
||||
/* Compute root ascender, descender, test height, and max_advance */ |
||||
metrics->ascender = ( FT_MulFix( face->root.ascender, |
||||
metrics->y_scale ) + 32 ) & -64; |
||||
|
||||
metrics->descender = ( FT_MulFix( face->root.descender, |
||||
metrics->y_scale ) + 32 ) & -64; |
||||
|
||||
metrics->height = ( FT_MulFix( face->root.height, |
||||
metrics->y_scale ) + 32 ) & -64; |
||||
|
||||
metrics->max_advance = ( FT_MulFix( face->root.max_advance_width, |
||||
metrics->x_scale ) + 32 ) & -64; |
||||
return error; |
||||
} |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Function> */ |
||||
/* T2_Init_GlyphSlot */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* The OpenType glyph slot initializer. */ |
||||
/* */ |
||||
/* <Input> */ |
||||
/* slot :: The glyph record to build. */ |
||||
/* */ |
||||
/* <Output> */ |
||||
/* TrueType error code. 0 means success. */ |
||||
/* */ |
||||
LOCAL_FUNC |
||||
FT_Error T2_Init_GlyphSlot( T2_GlyphSlot slot ) |
||||
{ |
||||
/* allocate the outline space */ |
||||
FT_Face face = slot->face; |
||||
FT_Library library = face->driver->library; |
||||
|
||||
FT_TRACE4(( "TT.Init_GlyphSlot: Creating outline maxp = %d, maxc = %d\n", |
||||
face->max_points, face->max_contours )); |
||||
|
||||
return FT_Outline_New( library, |
||||
face->max_points + 2, |
||||
face->max_contours, |
||||
&slot->outline ); |
||||
} |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Function> */ |
||||
/* TT_Done_GlyphSlot */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* The OpenType glyph slot finalizer. */ |
||||
/* */ |
||||
/* <Input> */ |
||||
/* slot :: A handle to the glyph slot object. */ |
||||
/* */ |
||||
LOCAL_FUNC |
||||
void T2_Done_GlyphSlot( T2_GlyphSlot slot ) |
||||
{ |
||||
FT_Library library = slot->face->driver->library; |
||||
FT_Memory memory = library->memory; |
||||
|
||||
if (slot->flags & ft_glyph_own_bitmap) |
||||
FREE( slot->bitmap.buffer ); |
||||
|
||||
FT_Outline_Done( library, &slot->outline ); |
||||
return; |
||||
} |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Function> */ |
||||
/* T2_Init_Driver */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* Initializes a given OpenType driver object. */ |
||||
/* */ |
||||
/* <Input> */ |
||||
/* driver :: A handle to the target driver object. */ |
||||
/* */ |
||||
/* <Return> */ |
||||
/* TrueType error code. 0 means success. */ |
||||
/* */ |
||||
LOCAL_FUNC |
||||
FT_Error T2_Init_Driver( T2_Driver driver ) |
||||
{ |
||||
FT_Memory memory = driver->root.memory; |
||||
FT_Error error; |
||||
|
||||
error = FT_New_GlyphZone( memory, 0, 0, &driver->zone ); |
||||
if (error) return error; |
||||
|
||||
/* init extension registry if needed */ |
||||
#ifdef T2_CONFIG_OPTION_EXTEND_ENGINE |
||||
return TT_Init_Extensions( driver ); |
||||
#else |
||||
return FT_Err_Ok; |
||||
#endif |
||||
} |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Function> */ |
||||
/* TT_Done_Driver */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* Finalizes a given TrueType driver. */ |
||||
/* */ |
||||
/* <Input> */ |
||||
/* driver :: A handle to the target TrueType driver. */ |
||||
/* */ |
||||
LOCAL_FUNC |
||||
void T2_Done_Driver( T2_Driver driver ) |
||||
{ |
||||
/* destroy extensions registry if needed */ |
||||
#ifdef T2_CONFIG_OPTION_EXTEND_ENGINE |
||||
TT_Done_Extensions( driver ); |
||||
#endif |
||||
|
||||
/* remove the loading glyph zone */ |
||||
FT_Done_GlyphZone( &driver->zone ); |
||||
} |
||||
|
||||
|
||||
/* END */ |
@ -0,0 +1,141 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* t2objs.h */ |
||||
/* */ |
||||
/* Objects manager (specification). */ |
||||
/* */ |
||||
/* Copyright 1996-1999 by */ |
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
||||
/* */ |
||||
/* This file is part of the FreeType project, and may only be used */ |
||||
/* modified and distributed under the terms of the FreeType project */ |
||||
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
||||
/* this file you indicate that you have read the license and */ |
||||
/* understand and accept it fully. */ |
||||
/* */ |
||||
/***************************************************************************/ |
||||
|
||||
|
||||
#ifndef T2OBJS_H |
||||
#define T2OBJS_H |
||||
|
||||
|
||||
#include <freetype/internal/ftobjs.h> |
||||
#include <freetype/internal/t2types.h> |
||||
#include <t2errors.h> |
||||
|
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Type> */ |
||||
/* T2_Driver */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* A handle to an OpenType driver object. */ |
||||
/* */ |
||||
typedef struct T2_DriverRec_* T2_Driver; |
||||
|
||||
typedef TT_Face T2_Face; |
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Type> */ |
||||
/* T2_Size */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* A handle to an OpenType size object. */ |
||||
/* */ |
||||
typedef FT_Size T2_Size; |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Type> */ |
||||
/* T2_GlyphSlot */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* A handle to an OpenType glyph slot object. */ |
||||
/* */ |
||||
/* <Note> */ |
||||
/* This is a direct typedef of FT_GlyphSlot, as there is nothing */ |
||||
/* specific about the OpenType glyph slot. */ |
||||
/* */ |
||||
typedef FT_GlyphSlot T2_GlyphSlot; |
||||
|
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* Subglyph transformation record. */ |
||||
/* */ |
||||
typedef struct T2_Transform_ |
||||
{ |
||||
FT_Fixed xx, xy; /* transformation matrix coefficients */ |
||||
FT_Fixed yx, yy; |
||||
FT_F26Dot6 ox, oy; /* offsets */ |
||||
|
||||
} T2_Transform; |
||||
|
||||
|
||||
/***********************************************************************/ |
||||
/* */ |
||||
/* TrueType driver class. */ |
||||
/* */ |
||||
typedef struct T2_DriverRec_ |
||||
{ |
||||
FT_DriverRec root; |
||||
FT_GlyphZone zone; /* glyph loader points zone */ |
||||
|
||||
void* extension_component; |
||||
|
||||
} T2_DriverRec; |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* Face Funcs */ |
||||
|
||||
LOCAL_DEF FT_Error T2_Init_Face( FT_Stream stream, |
||||
T2_Face face, |
||||
TT_Int face_index, |
||||
TT_Int num_params, |
||||
FT_Parameter* params ); |
||||
|
||||
LOCAL_DEF void T2_Done_Face( T2_Face face ); |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* Size funcs */ |
||||
|
||||
LOCAL_DEF FT_Error T2_Init_Size ( T2_Size size ); |
||||
LOCAL_DEF void T2_Done_Size ( T2_Size size ); |
||||
LOCAL_DEF FT_Error T2_Reset_Size( T2_Size size ); |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* GlyphSlot funcs */ |
||||
|
||||
LOCAL_DEF FT_Error T2_Init_GlyphSlot( T2_GlyphSlot slot ); |
||||
LOCAL_DEF void T2_Done_GlyphSlot( T2_GlyphSlot slot ); |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* Driver funcs */ |
||||
|
||||
LOCAL_DEF FT_Error T2_Init_Driver( T2_Driver driver ); |
||||
LOCAL_DEF void T2_Done_Driver( T2_Driver driver ); |
||||
|
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
|
||||
#endif /* T2OBJS_H */ |
||||
|
||||
|
||||
/* END */ |
@ -0,0 +1,514 @@ |
||||
#include <t2parse.h> |
||||
#include <freetype/fterrors.h> |
||||
|
||||
#define T2_Err_Stack_Underflow FT_Err_Invalid_Argument |
||||
#define T2_Err_Syntax_Error FT_Err_Invalid_Argument |
||||
|
||||
enum |
||||
{ |
||||
t2_kind_none = 0, |
||||
t2_kind_num, |
||||
t2_kind_fixed, |
||||
t2_kind_string, |
||||
t2_kind_bool, |
||||
t2_kind_delta, |
||||
t2_kind_callback, |
||||
|
||||
t2_kind_max /* do not remove */ |
||||
}; |
||||
|
||||
|
||||
/* now generate handlers for the most simple fields */ |
||||
typedef FT_Error (*T2_Field_Reader)( T2_Parser* parser ); |
||||
|
||||
typedef struct T2_Field_Handler_ |
||||
{ |
||||
int kind; |
||||
int code; |
||||
FT_UInt offset; |
||||
FT_Byte size; |
||||
T2_Field_Reader reader; |
||||
FT_UInt array_max; |
||||
FT_UInt count_offset; |
||||
|
||||
} T2_Field_Handler; |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LOCAL_FUNC |
||||
void T2_Parser_Init( T2_Parser* parser, FT_UInt code, void* object ) |
||||
{ |
||||
MEM_Set(parser,0,sizeof(*parser)); |
||||
parser->top = parser->stack; |
||||
parser->object_code = code; |
||||
parser->object = object; |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* reads an integer */ |
||||
static |
||||
FT_Long parse_t2_integer( FT_Byte* start, |
||||
FT_Byte* limit ) |
||||
{ |
||||
FT_Byte* p = start; |
||||
FT_Int v = *p++; |
||||
FT_Long val = 0; |
||||
|
||||
if (v == 28) |
||||
{ |
||||
if ( p+2 > limit ) goto Bad; |
||||
val = ((FT_Long)p[0] << 8) | p[1]; |
||||
p += 2; |
||||
} |
||||
else if (v == 29) |
||||
{ |
||||
if ( p+4 > limit ) goto Bad; |
||||
val = ((FT_Long)p[0] << 24) | |
||||
((FT_Long)p[1] << 16) | |
||||
((FT_Long)p[2] << 8) | p[3]; |
||||
p += 4; |
||||
} |
||||
else if (v < 247) |
||||
{ |
||||
val = v - 139; |
||||
} |
||||
else if (v < 251) |
||||
{ |
||||
if (p+1 > limit) goto Bad; |
||||
val = (v-247)*256 + p[0]+108; |
||||
p ++; |
||||
} |
||||
else |
||||
{ |
||||
if (p+1 > limit) goto Bad; |
||||
val = -(v-251)*256 - p[0]-108; |
||||
p ++; |
||||
} |
||||
|
||||
Exit: |
||||
return val; |
||||
|
||||
Bad: |
||||
val = 0; |
||||
goto Exit; |
||||
} |
||||
|
||||
|
||||
/* reads a real */ |
||||
static |
||||
FT_Fixed parse_t2_real( FT_Byte* start, |
||||
FT_Byte* limit, |
||||
FT_Int power_ten ) |
||||
{ |
||||
FT_Byte* p = start; |
||||
FT_Long num, divider, result, exp; |
||||
FT_Int sign = 0, exp_sign = 0; |
||||
FT_Byte nib; |
||||
FT_Byte phase; |
||||
|
||||
result = 0; |
||||
num = 0; |
||||
divider = 1; |
||||
|
||||
/* first of all, read the integer part */ |
||||
phase = 4; |
||||
p--; |
||||
for (;;) |
||||
{ |
||||
/* read one nibble at a time */ |
||||
if (phase && ++p >= limit) goto Bad; |
||||
nib = (p[0] >> phase) & 0xF; |
||||
phase = 4-phase; |
||||
|
||||
if (nib == 0xE) |
||||
sign = 1; |
||||
else if (nib > 9) |
||||
break; |
||||
else |
||||
result = result*10 + nib; |
||||
} |
||||
|
||||
/* read decimal part, if any */ |
||||
if (nib == 0xa) |
||||
for (;;) |
||||
{ |
||||
/* read one nibble at a time */ |
||||
if (!phase && ++p >= limit) goto Bad; |
||||
phase = 4-phase; |
||||
nib = (p[0] >> phase) & 0xF; |
||||
|
||||
if (nib >= 10) |
||||
break; |
||||
|
||||
if (divider < 10000000L) |
||||
{ |
||||
num = num*10 + nib; |
||||
divider *= 10; |
||||
} |
||||
} |
||||
|
||||
/* read exponent, if any */ |
||||
if (nib == 12) |
||||
{ |
||||
exp_sign = 1; |
||||
nib = 11; |
||||
} |
||||
if (nib == 11) |
||||
{ |
||||
exp = 0; |
||||
for (;;) |
||||
{ |
||||
/* read one nibble at a time */ |
||||
if (!phase && ++p >= limit) goto Bad; |
||||
phase = 4-phase; |
||||
nib = (p[0] >> phase) & 0xF; |
||||
|
||||
if (nib >= 10) |
||||
break; |
||||
|
||||
exp = exp*10 + nib; |
||||
} |
||||
if (exp_sign) |
||||
exp = -exp; |
||||
|
||||
power_ten += exp; |
||||
} |
||||
|
||||
/* raise to power of ten if needed */ |
||||
while (power_ten > 0) |
||||
{ |
||||
result = result*10; |
||||
num = num*10; |
||||
power_ten--; |
||||
} |
||||
|
||||
while (power_ten < 0) |
||||
{ |
||||
result = result/10; |
||||
divider = divider*10; |
||||
power_ten++; |
||||
} |
||||
|
||||
if (num) |
||||
result += FT_DivFix( num, divider ); |
||||
|
||||
if (sign) |
||||
result = -result; |
||||
|
||||
Exit: |
||||
return result; |
||||
|
||||
Bad: |
||||
result = 0; |
||||
goto Exit; |
||||
} |
||||
|
||||
|
||||
/* reads a number, either integer or real */ |
||||
static |
||||
FT_Long t2_parse_num( FT_Byte** d ) |
||||
{ |
||||
return ( **d == 30 ? (parse_t2_real ( d[0], d[1], 0 ) >> 16): |
||||
parse_t2_integer( d[0], d[1] ) ); |
||||
} |
||||
|
||||
/* reads a floating point number, either integer or real */ |
||||
static |
||||
FT_Fixed t2_parse_fixed( FT_Byte** d ) |
||||
{ |
||||
return ( **d == 30 ? parse_t2_real( d[0], d[1], 0 ) : |
||||
parse_t2_integer( d[0], d[1] ) << 16 ); |
||||
} |
||||
|
||||
|
||||
|
||||
static |
||||
FT_Error parse_font_matrix( T2_Parser* parser ) |
||||
{ |
||||
CFF_Top_Dict* dict = (CFF_Top_Dict*)parser->object; |
||||
FT_Matrix* matrix = &dict->font_matrix; |
||||
FT_Byte** data = parser->stack; |
||||
FT_Error error; |
||||
|
||||
error = T2_Err_Stack_Underflow; |
||||
if (parser->top >= parser->stack + 4) |
||||
{ |
||||
matrix->xx = t2_parse_fixed( data++ ); |
||||
matrix->yx = t2_parse_fixed( data++ ); |
||||
matrix->xy = t2_parse_fixed( data++ ); |
||||
matrix->yy = t2_parse_fixed( data ); |
||||
error = 0; |
||||
} |
||||
return error; |
||||
} |
||||
|
||||
|
||||
static |
||||
FT_Error parse_font_bbox( T2_Parser* parser ) |
||||
{ |
||||
CFF_Top_Dict* dict = (CFF_Top_Dict*)parser->object; |
||||
FT_BBox* bbox = &dict->font_bbox; |
||||
FT_Byte** data = parser->stack; |
||||
FT_Error error; |
||||
|
||||
error = T2_Err_Stack_Underflow; |
||||
if (parser->top >= parser->stack + 4) |
||||
{ |
||||
bbox->xMin = t2_parse_fixed( data++ ); |
||||
bbox->yMin = t2_parse_fixed( data++ ); |
||||
bbox->xMax = t2_parse_fixed( data++ ); |
||||
bbox->yMax = t2_parse_fixed( data ); |
||||
error = 0; |
||||
} |
||||
return error; |
||||
} |
||||
|
||||
|
||||
static |
||||
FT_Error parse_private_dict( T2_Parser* parser ) |
||||
{ |
||||
CFF_Top_Dict* dict = (CFF_Top_Dict*)parser->object; |
||||
FT_Byte** data = parser->stack; |
||||
FT_Error error; |
||||
|
||||
error = T2_Err_Stack_Underflow; |
||||
if (parser->top >= parser->stack + 2) |
||||
{ |
||||
dict->private_offset = t2_parse_num( data++ ); |
||||
dict->private_size = t2_parse_num( data ); |
||||
error = 0; |
||||
} |
||||
return error; |
||||
} |
||||
|
||||
|
||||
static |
||||
FT_Error parse_cid_ros( T2_Parser* parser ) |
||||
{ |
||||
CFF_Top_Dict* dict = (CFF_Top_Dict*)parser->object; |
||||
FT_Byte** data = parser->stack; |
||||
FT_Error error; |
||||
|
||||
error = T2_Err_Stack_Underflow; |
||||
if (parser->top >= parser->stack + 3) |
||||
{ |
||||
dict->cid_registry = (FT_UInt)t2_parse_num( data++ ); |
||||
dict->cid_ordering = (FT_UInt)t2_parse_num( data++ ); |
||||
dict->cid_supplement = (FT_ULong)t2_parse_num( data ); |
||||
error = 0; |
||||
} |
||||
return error; |
||||
} |
||||
|
||||
|
||||
|
||||
#define T2_FIELD_NUM(code,name) T2_FIELD( code, name, t2_kind_num ) |
||||
#define T2_FIELD_FIXED(code,name) T2_FIELD( code, name, t2_kind_fixed ) |
||||
#define T2_FIELD_STRING(code,name) T2_FIELD( code, name, t2_kind_string ) |
||||
#define T2_FIELD_BOOL(code,name) T2_FIELD( code, name, t2_kind_bool ) |
||||
#define T2_FIELD_DELTA(code,name,max) T2_FIELD( code, name, t2_kind_delta ) |
||||
|
||||
|
||||
#define T2_REF(s,f) (((s*)0)->f) |
||||
|
||||
#define T2_FIELD_CALLBACK( code, name ) \ |
||||
{ t2_kind_callback, code, 0, 0, parse_ ## name, 0, 0 }, |
||||
|
||||
#undef T2_FIELD |
||||
#define T2_FIELD( code, name, kind ) \ |
||||
{ kind, code | T2CODE, \
|
||||
(FT_UInt)(char*)&T2_REF( T2TYPE, name ), \
|
||||
sizeof( T2_REF( T2TYPE, name ) ), \
|
||||
0 }, |
||||
|
||||
#undef T2_FIELD_DELTA |
||||
#define T2_FIELD_DELTA( code, name, max ) \ |
||||
{ t2_kind_delta, code | T2CODE, \
|
||||
(FT_UInt)(char*)&T2_REF( T2TYPE, name ), \
|
||||
sizeof( T2_REF( T2TYPE, name ) ), \
|
||||
0, \
|
||||
max, (FT_UInt)(char*)&T2_REF( T2TYPE, num_ ## name ) }, |
||||
|
||||
|
||||
#define T2CODE_TOPDICT 0x1000 |
||||
#define T2CODE_PRIVATE 0x2000 |
||||
|
||||
static const T2_Field_Handler t2_field_handlers[] = |
||||
{ |
||||
#include <t2tokens.h> |
||||
{ 0, 0, 0, 0, 0, 0, 0 } |
||||
}; |
||||
|
||||
|
||||
LOCAL_FUNC |
||||
FT_Error T2_Parser_Run( T2_Parser* parser, |
||||
FT_Byte* start, |
||||
FT_Byte* limit ) |
||||
{ |
||||
FT_Byte* p; |
||||
FT_Error error = 0; |
||||
|
||||
parser->top = parser->stack; |
||||
parser->start = start; |
||||
parser->limit = limit; |
||||
parser->cursor = start; |
||||
|
||||
while (p < limit) |
||||
{ |
||||
FT_Byte v = *p; |
||||
if ( v >= 27 || v != 31 ) |
||||
{ |
||||
/* its a number, we'll push its position on the stack */ |
||||
if (parser->top - parser->stack >= T2_MAX_STACK_DEPTH) |
||||
goto Stack_Overflow; |
||||
|
||||
*parser->top ++ = p; |
||||
|
||||
/* now, skip it */ |
||||
if (v == 30) |
||||
{ |
||||
/* skip real number */ |
||||
for (;;) |
||||
{ |
||||
if (p >= limit) goto Syntax_Error; |
||||
v = p[0] >> 4; |
||||
if (v == 15) break; |
||||
v = p[0] & 0xF; |
||||
if (v == 15) break; |
||||
p++; |
||||
} |
||||
p++; |
||||
} |
||||
else if (v == 28)
|
||||
p += 2; |
||||
else if (v == 29) |
||||
p += 4; |
||||
else if (v > 246) |
||||
p += 1; |
||||
} |
||||
else |
||||
{ |
||||
/* this is not a number, hence it's an operator. Compute its code */ |
||||
/* and look for it in our current list.. */ |
||||
FT_UInt code; |
||||
FT_Int num_args = parser->top - parser->stack; |
||||
const T2_Field_Handler* field; |
||||
|
||||
/* first of all, a trivial check */ |
||||
if ( num_args < 1 ) goto Stack_Underflow; |
||||
|
||||
code = v; |
||||
if (v == 12) |
||||
{ |
||||
/* two byte operator */ |
||||
p++; |
||||
code = 0x100 | p[0]; |
||||
} |
||||
code = code | parser->object_code; |
||||
|
||||
for ( field = t2_field_handlers; field->kind; field++ ) |
||||
{ |
||||
if (field->code == code) |
||||
{ |
||||
/* we found our field's handler, read it.. */ |
||||
FT_Long val; |
||||
FT_Byte* q = (FT_Byte*)parser->object + field->offset; |
||||
|
||||
switch (field->kind) |
||||
{ |
||||
case t2_kind_bool: |
||||
case t2_kind_string: |
||||
case t2_kind_num: |
||||
val = t2_parse_num( parser->stack ); |
||||
goto Store_Number; |
||||
|
||||
case t2_kind_fixed: |
||||
val = t2_parse_fixed( parser->stack ); |
||||
|
||||
Store_Number:
|
||||
switch (field->size) |
||||
{ |
||||
case 1: *(FT_Byte*) q = (FT_Byte)val; break; |
||||
case 2: *(FT_Short*)q = (FT_Short)val; break; |
||||
default: *(FT_Long*)q = val; |
||||
} |
||||
break; |
||||
|
||||
|
||||
case t2_kind_delta: |
||||
{ |
||||
FT_Byte* qcount = (FT_Byte*)parser->object + |
||||
field->count_offset; |
||||
|
||||
FT_Long val; |
||||
FT_Byte** data = parser->stack; |
||||
|
||||
if (num_args > field->array_max) |
||||
num_args = field->array_max; |
||||
|
||||
/* store count */ |
||||
*qcount = (FT_Byte)num_args; |
||||
|
||||
val = 0; |
||||
while (num_args > 0) |
||||
{ |
||||
val += t2_parse_num( data++ ); |
||||
switch (field->size) |
||||
{ |
||||
case 1: *(FT_Byte*) q = (FT_Byte)val; break; |
||||
case 2: *(FT_Short*)q = (FT_Short)val; break; |
||||
default: *(FT_Long*)q = val;
|
||||
} |
||||
q += field->size; |
||||
num_args--; |
||||
} |
||||
} |
||||
break; |
||||
|
||||
default: /* callback */ |
||||
error = field->reader( parser ); |
||||
if (error) goto Exit; |
||||
} |
||||
/* clear stack */ |
||||
parser->top = parser->stack; |
||||
} |
||||
goto Found; /* exit loop */ |
||||
} |
||||
|
||||
/* this is an unknown operator, or it is unsupported, we will ignore */ |
||||
/* it for now... */ |
||||
|
||||
Found: |
||||
/* clear stack */ |
||||
parser->top = parser->stack; |
||||
} |
||||
p++; |
||||
} |
||||
Exit: |
||||
return error; |
||||
|
||||
Stack_Overflow: |
||||
error = FT_Err_Invalid_Argument; |
||||
goto Exit; |
||||
|
||||
Stack_Underflow: |
||||
error = FT_Err_Invalid_Argument; |
||||
goto Exit; |
||||
|
||||
Syntax_Error: |
||||
error = FT_Err_Invalid_Argument; |
||||
goto Exit; |
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,33 @@ |
||||
#ifndef T2PARSE_H |
||||
#define T2PARSE_H |
||||
|
||||
#include <freetype/internal/t2types.h> |
||||
#include <freetype/internal/ftobjs.h> |
||||
|
||||
#define T2_MAX_STACK_DEPTH 96 |
||||
|
||||
typedef struct T2_Parser_ |
||||
{ |
||||
FT_Byte* start; |
||||
FT_Byte* limit; |
||||
FT_Byte* cursor; |
||||
|
||||
FT_Byte* stack[ T2_MAX_STACK_DEPTH+1 ]; |
||||
FT_Byte** top; |
||||
|
||||
FT_UInt object_code; |
||||
void* object; |
||||
|
||||
} T2_Parser; |
||||
|
||||
|
||||
LOCAL_DEF |
||||
void T2_Parser_Init( T2_Parser* parser, FT_UInt code, void* object ); |
||||
|
||||
|
||||
LOCAL_DEF |
||||
FT_Error T2_Parser_Run( T2_Parser* parser, |
||||
FT_Byte* start, |
||||
FT_Byte* limit ); |
||||
|
||||
#endif /* T2PARSE_H */ |
@ -0,0 +1,76 @@ |
||||
|
||||
#undef T2TYPE |
||||
#undef T2CODE |
||||
#define T2TYPE CFF_Top_Dict |
||||
#define T2CODE T2CODE_TOPDICT |
||||
|
||||
T2_FIELD_STRING ( 0, version ) |
||||
T2_FIELD_STRING ( 1, notice ) |
||||
T2_FIELD_STRING ( 0x100, copyright ) |
||||
T2_FIELD_STRING ( 2, full_name ) |
||||
T2_FIELD_STRING ( 3, family_name ) |
||||
T2_FIELD_STRING ( 4, weight ) |
||||
T2_FIELD_BOOL ( 0x101, is_fixed_pitch ) |
||||
T2_FIELD_FIXED ( 0x102, italic_angle ) |
||||
T2_FIELD_NUM ( 0x103, underline_position ) |
||||
T2_FIELD_NUM ( 0x104, underline_thickness ) |
||||
T2_FIELD_NUM ( 0x105, paint_type ) |
||||
T2_FIELD_NUM ( 0x106, charstring_type ) |
||||
T2_FIELD_CALLBACK( 0x107, font_matrix ) |
||||
T2_FIELD_NUM ( 13, unique_id ) |
||||
T2_FIELD_CALLBACK( 5, font_bbox ) |
||||
T2_FIELD_NUM ( 0x108, stroke_width ) |
||||
T2_FIELD_NUM ( 15, charset_offset ) |
||||
T2_FIELD_NUM ( 16, encoding_offset ) |
||||
T2_FIELD_NUM ( 17, charstrings_offset ) |
||||
T2_FIELD_CALLBACK( 18, private_dict ) |
||||
T2_FIELD_NUM ( 0x114, synthetic_base ) |
||||
T2_FIELD_STRING ( 0x115, postscript ) |
||||
T2_FIELD_STRING ( 0x116, base_font_name ) |
||||
|
||||
#if 0
|
||||
T2_FIELD_DELTA ( 0x117, base_font_blend, 16 ) |
||||
T2_FIELD_CALLBACK( 0x118, multiple_master ) |
||||
T2_FIELD_CALLBACK( 0x119, blend_axit_types ) |
||||
#endif |
||||
|
||||
T2_FIELD_CALLBACK( 0x11E, cid_ros ) |
||||
T2_FIELD_NUM ( 0x11F, cid_font_version ) |
||||
T2_FIELD_NUM ( 0x120, cid_font_revision ) |
||||
T2_FIELD_NUM ( 0x121, cid_font_type ) |
||||
T2_FIELD_NUM ( 0x122, cid_count ) |
||||
T2_FIELD_NUM ( 0x123, cid_uid_base ) |
||||
T2_FIELD_NUM ( 0x124, cid_fd_array_offset ) |
||||
T2_FIELD_NUM ( 0x125, cid_fd_select_offset ) |
||||
T2_FIELD_STRING ( 0x126, cid_font_name ) |
||||
|
||||
#if 0 |
||||
T2_FIELD_NUM ( 0x127, chameleon ) |
||||
#endif |
||||
|
||||
#undef T2TYPE |
||||
#undef T2CODE |
||||
#define T2TYPE CFF_Private |
||||
#define T2CODE T2CODE_PRIVATE |
||||
|
||||
T2_FIELD_DELTA( 6, blue_values, 14 ) |
||||
T2_FIELD_DELTA( 7, other_blues, 10 ) |
||||
T2_FIELD_DELTA( 8, family_blues, 14 ) |
||||
T2_FIELD_DELTA( 9, family_other_blues, 10 ) |
||||
T2_FIELD_FIXED( 0x109, blue_scale ) |
||||
T2_FIELD_NUM ( 0x10A, blue_shift ) |
||||
T2_FIELD_NUM ( 0x10B, blue_fuzz ) |
||||
T2_FIELD_NUM ( 10, standard_width ) |
||||
T2_FIELD_NUM ( 11, standard_height ) |
||||
T2_FIELD_DELTA( 0x10C, snap_widths, 13 ) |
||||
T2_FIELD_DELTA( 0x10D, snap_heights, 13 ) |
||||
T2_FIELD_BOOL ( 0x10E, force_bold ) |
||||
T2_FIELD_FIXED( 0x10F, force_bold_threshold ) |
||||
T2_FIELD_NUM ( 0x110, lenIV ) |
||||
T2_FIELD_NUM ( 0x111, language_group ) |
||||
T2_FIELD_FIXED( 0x112, expansion_factor ) |
||||
T2_FIELD_NUM ( 0x113, initial_random_seed ) |
||||
T2_FIELD_NUM ( 19, local_subrs_offset ) |
||||
T2_FIELD_NUM ( 20, default_width ) |
||||
T2_FIELD_NUM ( 21, nominal_width ) |
||||
|
Loading…
Reference in new issue