fixed divide by zero bug
added CFF/OpenType driver source (not working for now)
This commit is contained in:
parent
a519b3b7a3
commit
4f99c3c423
9
CHANGES
9
CHANGES
@ -1,5 +1,14 @@
|
||||
LATEST_CHANGES
|
||||
|
||||
- fixed potential "divide by zero" bugs in ftcalc.c.. my god..
|
||||
|
||||
- added source code for the OpenType/CFF driver (still incomplete though..)
|
||||
|
||||
- modified the SFNT driver slightly to perform more robust header
|
||||
checks in TT_Load_SFNT_Header. This prevents certain font files
|
||||
(e.g. some Type 1 Multiple Masters) from being incorrectly "recognized"
|
||||
as TrueType font files..
|
||||
|
||||
- moved a lot of stuff from the TrueType driver to the SFNT module,
|
||||
this allows greater code re-use between font drivers (e.g. TrueType,
|
||||
OpenType, Compact-TrueType, etc..)
|
||||
|
@ -132,13 +132,13 @@
|
||||
{
|
||||
FT_Int s;
|
||||
|
||||
|
||||
s = 1;
|
||||
if ( a < 0 ) { a = -a; s = -s; }
|
||||
if ( b < 0 ) { b = -b; s = -s; }
|
||||
if ( c < 0 ) { c = -c; s = -s; }
|
||||
|
||||
return s * ( ( (FT_Int64)a * b + ( c >> 1 ) ) / c );
|
||||
return s * ( c > 0 ? ( ( (FT_Int64)a * b + ( c >> 1 ) ) / c )
|
||||
: 0x7FFFFFFF );
|
||||
}
|
||||
|
||||
|
||||
@ -344,21 +344,22 @@
|
||||
s ^= b; b = ABS( b );
|
||||
s ^= c; c = ABS( c );
|
||||
|
||||
if ( a <= 46340 && b <= 46340 && c <= 176095L )
|
||||
if ( a <= 46340 && b <= 46340 && c <= 176095L && c > 0)
|
||||
{
|
||||
a = ( a*b + (c >> 1) ) / c;
|
||||
a = a*b + (c >> 1) ) / c;
|
||||
}
|
||||
else
|
||||
else if (c > 0)
|
||||
{
|
||||
FT_Int64 temp, temp2;
|
||||
|
||||
|
||||
FT_MulTo64( a, b, &temp );
|
||||
temp2.hi = (FT_Int32)(c >> 31);
|
||||
temp2.lo = (FT_Word32)(c / 2);
|
||||
FT_Add64( &temp, &temp2, &temp );
|
||||
a = FT_Div64by32( &temp, c );
|
||||
}
|
||||
else
|
||||
a = 0x7FFFFFFF;
|
||||
|
||||
return ( s < 0 ) ? -a : a;
|
||||
}
|
||||
@ -614,7 +615,6 @@
|
||||
FT_Int32 s;
|
||||
FT_Word32 q, r, i, lo;
|
||||
|
||||
|
||||
s = x->hi;
|
||||
if ( s < 0 )
|
||||
{
|
||||
@ -626,7 +626,9 @@
|
||||
/* Shortcut */
|
||||
if ( x->hi == 0 )
|
||||
{
|
||||
q = x->lo / y;
|
||||
if (y > 0) q = x->lo / y;
|
||||
else q = 0x7FFFFFFF;
|
||||
|
||||
return ( s < 0 ) ? -(FT_Int32)q : (FT_Int32)q;
|
||||
}
|
||||
|
||||
|
49
src/cff/cff.c
Normal file
49
src/cff/cff.c
Normal file
@ -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 */
|
7
src/cff/module.mk
Normal file
7
src/cff/module.mk
Normal file
@ -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
|
112
src/cff/rules.mk
Normal file
112
src/cff/rules.mk
Normal file
@ -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
|
444
src/cff/t2driver.c
Normal file
444
src/cff/t2driver.c
Normal file
@ -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 */
|
34
src/cff/t2driver.h
Normal file
34
src/cff/t2driver.h
Normal file
@ -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 */
|
126
src/cff/t2errors.h
Normal file
126
src/cff/t2errors.h
Normal file
@ -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 */
|
1177
src/cff/t2gload.c
Normal file
1177
src/cff/t2gload.c
Normal file
File diff suppressed because it is too large
Load Diff
140
src/cff/t2gload.h
Normal file
140
src/cff/t2gload.h
Normal file
@ -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 */
|
292
src/cff/t2load.c
Normal file
292
src/cff/t2load.c
Normal file
@ -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 */
|
36
src/cff/t2load.h
Normal file
36
src/cff/t2load.h
Normal file
@ -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 */
|
333
src/cff/t2objs.c
Normal file
333
src/cff/t2objs.c
Normal file
@ -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 */
|
141
src/cff/t2objs.h
Normal file
141
src/cff/t2objs.h
Normal file
@ -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 */
|
514
src/cff/t2parse.c
Normal file
514
src/cff/t2parse.c
Normal file
@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
33
src/cff/t2parse.h
Normal file
33
src/cff/t2parse.h
Normal file
@ -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 */
|
76
src/cff/t2tokens.h
Normal file
76
src/cff/t2tokens.h
Normal file
@ -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
Block a user