From f0df85ba2a573c6c5c602667e9f91ef3b00c1d20 Mon Sep 17 00:00:00 2001 From: David Turner Date: Thu, 22 Jun 2000 00:17:42 +0000 Subject: [PATCH] - MAJOR INTERNAL REDESIGN: A lot of internal modifications have been performed lately on the source in order to provide the following enhancements: - more generic module support: The FT_Module type is now defined to represent a handle to a given module. The file contains the FT_Module_Class definition, as well as the module-loading public API The FT_Driver type is still defined, and still represents a pointer to a font driver. Note that FT_Add_Driver is replaced by FT_Add_Module, FT_Get_Driver by FT_Get_Module, etc.. - support for generic glyph image types: The FT_Renderer type is a pointer to a module used to perform various operations on glyph image. Each renderer is capable of handling images in a single format (e.g. ft_glyph_format_outline). Its functions are used to: - transform an glyph image - render a glyph image into a bitmap - return the control box (dimensions) of a given glyph image The scan converters "ftraster.c" and "ftgrays.c" have been moved to the new directory "src/renderer", and are used to provide two default renderer modules. One corresponds to the "standard" scan-converter, the other to the "smooth" one. The current renderer can be set through the new function FT_Set_Renderer. The old raster-related function FT_Set_Raster, FT_Get_Raster and FT_Set_Raster_Mode have now disappeared, in favor of the new: FT_Get_Renderer FT_Set_Renderer see the file for more details.. These changes were necessary to properly support different scalable formats in the future, like bi-color glyphs, etc.. - glyph loader object: A new internal object, called a 'glyph loader' has been introduced in the base layer. It is used by all scalable format font drivers to load glyphs and composites. This object has been created to reduce the code size of each driver, as each one of them basically re-implemented its functionality. See and the FT_GlyphLoader type for more information.. - FT_GlyphSlot had new fields: In order to support extended features (see below), the FT_GlyphSlot structure has a few new fields: linearHoriAdvance: this field gives the linearly scaled (i.e. scaled but unhinted) advance width for the glyph, expressed as a 16.16 fixed pixel value. This is useful to perform WYSIWYG text. linearVertAdvance: this field gives the linearly scaled advance height for the glyph (relevant in vertical glyph layouts only). This is useful to perform WYSIWYG text. Note that the two above field replace the removed "metrics2" field in the glyph slot. advance: this field is a vector that gives the transformed advance for the glyph. By default, it corresponds to the advance width, unless FT_LOAD_VERTICAL_LAYOUT was specified when calling FT_Load_Glyph or FT_Load_Char bitmap_left: this field gives the distance in integer pixels from the current pen position to the left-most pixel of a glyph image WHEN IT IS A BITMAP. It is only valid when the "format" field is set to "ft_glyph_format_bitmap", for example, after calling the new function FT_Render_Glyph. bitmap_top: this field gives the distance in integer pixels from the current pen position (located on the baseline) to the top-most pixel of the glyph image WHEN IT IS A BITMAP. Positive values correspond to upwards Y. loader: this is a new private field for the glyph slot. Client applications should not touch it.. - support for transforms and direct rendering in FT_Load_Glyph: Most of the functionality found in has been moved to the core library. Hence, the following: - a transform can be specified for a face through FT_Set_Transform. this transform is applied by FT_Load_Glyph to scalable glyph images (i.e. NOT TO BITMAPS) before the function returns, unless the bit flag FT_LOAD_IGNORE_TRANSFORM was set in the load flags.. - once a glyph image has been loaded, it can be directly converted to a bitmap by using the new FT_Render_Glyph function. Note that this function takes the glyph image from the glyph slot, and converts it to a bitmap whose properties are returned in "face.glyph.bitmap", "face.glyph.bitmap_left" and "face.glyph.bitmap_top". The original native image might be lost after the conversion. - when using the new bit flag FT_LOAD_RENDER, the FT_Load_Glyph and FT_Load_Char functions will call FT_Render_Glyph automatically when needed. --- CHANGES | 130 ++ config/modules.mk | 6 +- demos/src/ftmulti.c | 19 +- demos/src/ftstring.c | 22 +- demos/src/fttimer.c | 9 +- demos/src/ftview.c | 19 +- demos/src/memtest.c | 2 +- demos/src/ttdebug.c | 2 +- include/freetype/config/ftmodule.h | 16 +- include/freetype/config/ftoption.h | 12 +- include/freetype/freetype.h | 397 +++- include/freetype/fterrors.h | 2 + include/freetype/ftimage.h | 53 +- include/freetype/internal/ftdriver.h | 620 +----- include/freetype/internal/ftobjs.h | 300 ++- include/freetype/internal/sfnt.h | 4 +- src/base/ftextend.c | 15 +- src/base/ftglyph.c | 90 +- src/base/ftinit.c | 39 +- src/base/ftmm.c | 12 +- src/base/ftobjs.c | 2627 ++++++++++++++++---------- src/base/ftoutln.c | 250 ++- src/base/rules.mk | 6 +- src/cff/module.mk | 2 +- src/cff/t2driver.c | 191 +- src/cff/t2driver.h | 5 +- src/cff/t2gload.c | 117 +- src/cff/t2gload.h | 41 +- src/cff/t2objs.c | 164 +- src/cff/t2objs.h | 28 - src/cid/cidgload.c | 202 +- src/cid/cidgload.h | 41 +- src/cid/cidobjs.c | 161 +- src/cid/cidobjs.h | 28 +- src/cid/cidparse.c | 6 +- src/cid/cidriver.c | 255 +-- src/cid/cidriver.h | 2 +- src/cid/module.mk | 2 +- src/psnames/module.mk | 6 +- src/psnames/psdriver.h | 14 +- src/psnames/psnames.c | 23 +- src/psnames/rules.mk | 4 +- src/{base => renderer}/ftgrays.c | 2 +- src/renderer/ftgrays.h | 49 + src/{base => renderer}/ftraster.c | 4 +- src/renderer/ftraster.h | 48 + src/renderer/ftrender.c | 161 ++ src/renderer/module.mk | 11 + src/renderer/renderer.c | 219 +++ src/renderer/renderer.h | 14 + src/renderer/rules.mk | 75 + src/sfnt/module.mk | 8 +- src/sfnt/sfdriver.c | 37 +- src/sfnt/sfdriver.h | 5 +- src/sfnt/sfobjs.c | 29 +- src/sfnt/ttcmap.c | 6 +- src/sfnt/ttload.c | 36 +- src/sfnt/ttpost.c | 2 +- src/sfnt/ttsbit.c | 16 +- src/truetype/module.mk | 2 +- src/truetype/ttdriver.c | 65 +- src/truetype/ttdriver.h | 2 +- src/truetype/ttgload.c | 502 ++--- src/truetype/ttgload.h | 3 +- src/truetype/ttinterp.c | 24 +- src/truetype/ttobjs.c | 157 +- src/truetype/ttobjs.h | 15 - src/type1/module.mk | 2 +- src/type1/t1afm.h | 76 +- src/type1/t1driver.c | 447 ++--- src/type1/t1driver.h | 40 +- src/type1/t1gload.c | 1725 ++++++++--------- src/type1/t1gload.h | 420 ++-- src/type1/t1hinter.c | 1184 ++++++------ src/type1/t1objs.c | 78 +- src/type1/t1objs.h | 34 - src/type1z/module.mk | 2 +- src/type1z/t1driver.c | 214 +-- src/type1z/t1driver.h | 5 +- src/type1z/t1gload.c | 211 +-- src/type1z/t1gload.h | 40 +- src/type1z/t1objs.c | 159 +- src/type1z/t1objs.h | 89 - 83 files changed, 5800 insertions(+), 6362 deletions(-) rename src/{base => renderer}/ftgrays.c (99%) create mode 100644 src/renderer/ftgrays.h rename src/{base => renderer}/ftraster.c (99%) create mode 100644 src/renderer/ftraster.h create mode 100644 src/renderer/ftrender.c create mode 100644 src/renderer/module.mk create mode 100644 src/renderer/renderer.c create mode 100644 src/renderer/renderer.h create mode 100644 src/renderer/rules.mk diff --git a/CHANGES b/CHANGES index 7e056e7f8..d19b854cb 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,135 @@ LATEST CHANGES + - MAJOR INTERNAL REDESIGN: + + A lot of internal modifications have been performed lately on the + source in order to provide the following enhancements: + + - more generic module support: + + The FT_Module type is now defined to represent a handle to a given + module. The file contains the FT_Module_Class + definition, as well as the module-loading public API + + The FT_Driver type is still defined, and still represents a pointer + to a font driver. Note that FT_Add_Driver is replaced by FT_Add_Module, + FT_Get_Driver by FT_Get_Module, etc.. + + + - support for generic glyph image types: + + The FT_Renderer type is a pointer to a module used to perform various + operations on glyph image. + + Each renderer is capable of handling images in a single format + (e.g. ft_glyph_format_outline). Its functions are used to: + + - transform an glyph image + - render a glyph image into a bitmap + - return the control box (dimensions) of a given glyph image + + + The scan converters "ftraster.c" and "ftgrays.c" have been moved + to the new directory "src/renderer", and are used to provide two + default renderer modules. + + One corresponds to the "standard" scan-converter, the other to the + "smooth" one. + + The current renderer can be set through the new function + FT_Set_Renderer. + + The old raster-related function FT_Set_Raster, FT_Get_Raster and + FT_Set_Raster_Mode have now disappeared, in favor of the new: + + FT_Get_Renderer + FT_Set_Renderer + + see the file for more details.. + + These changes were necessary to properly support different scalable + formats in the future, like bi-color glyphs, etc.. + + + - glyph loader object: + + A new internal object, called a 'glyph loader' has been introduced + in the base layer. It is used by all scalable format font drivers + to load glyphs and composites. + + This object has been created to reduce the code size of each driver, + as each one of them basically re-implemented its functionality. + + See and the FT_GlyphLoader type for + more information.. + + + + - FT_GlyphSlot had new fields: + + In order to support extended features (see below), the FT_GlyphSlot + structure has a few new fields: + + linearHoriAdvance: this field gives the linearly scaled (i.e. + scaled but unhinted) advance width for the glyph, + expressed as a 16.16 fixed pixel value. This + is useful to perform WYSIWYG text. + + linearVertAdvance: this field gives the linearly scaled advance + height for the glyph (relevant in vertical glyph + layouts only). This is useful to perform + WYSIWYG text. + + Note that the two above field replace the removed "metrics2" field + in the glyph slot. + + advance: this field is a vector that gives the transformed + advance for the glyph. By default, it corresponds + to the advance width, unless FT_LOAD_VERTICAL_LAYOUT + was specified when calling FT_Load_Glyph or FT_Load_Char + + bitmap_left: this field gives the distance in integer pixels from + the current pen position to the left-most pixel of + a glyph image WHEN IT IS A BITMAP. It is only valid + when the "format" field is set to + "ft_glyph_format_bitmap", for example, after calling + the new function FT_Render_Glyph. + + bitmap_top: this field gives the distance in integer pixels from + the current pen position (located on the baseline) to + the top-most pixel of the glyph image WHEN IT IS A + BITMAP. Positive values correspond to upwards Y. + + loader: this is a new private field for the glyph slot. Client + applications should not touch it.. + + + - support for transforms and direct rendering in FT_Load_Glyph: + + Most of the functionality found in has been + moved to the core library. Hence, the following: + + - a transform can be specified for a face through FT_Set_Transform. + this transform is applied by FT_Load_Glyph to scalable glyph images + (i.e. NOT TO BITMAPS) before the function returns, unless the + bit flag FT_LOAD_IGNORE_TRANSFORM was set in the load flags.. + + + - once a glyph image has been loaded, it can be directly converted to + a bitmap by using the new FT_Render_Glyph function. Note that this + function takes the glyph image from the glyph slot, and converts + it to a bitmap whose properties are returned in "face.glyph.bitmap", + "face.glyph.bitmap_left" and "face.glyph.bitmap_top". The original + native image might be lost after the conversion. + + + - when using the new bit flag FT_LOAD_RENDER, the FT_Load_Glyph + and FT_Load_Char functions will call FT_Render_Glyph automatically + when needed. + + + + - reformated all modules source code in order to get rid of the basic data types redifinitions (i.e. "TT_Int" instead of "FT_Int", "T1_Fixed" instead of "FT_Fixed"). Hence the format-specific prefixes like "TT_", diff --git a/config/modules.mk b/config/modules.mk index 97f691de4..350d7ad5b 100644 --- a/config/modules.mk +++ b/config/modules.mk @@ -40,7 +40,7 @@ endif # clean_module_list: @-$(DELETE) $(subst $(SEP),$(HOSTSEP),$(FT_MODULE_LIST)) - @-echo Regenerating the font drivers list in $(FT_MODULE_LIST)... + @-echo Regenerating the modules list in $(FT_MODULE_LIST)... make_module_list: clean_module_list @echo done. @@ -60,10 +60,10 @@ endif # $(OPEN_DRIVER) & $(CLOSE_DRIVER) are used to specify a given font driver # in the `module.mk' rules file. # -OPEN_DRIVER := $(OPEN_MODULE)FT_DRIVER( +OPEN_DRIVER := $(OPEN_MODULE)FT_USE_MODULE( CLOSE_DRIVER := )$(CLOSE_MODULE) -ECHO_DRIVER := @echo "* driver: # +ECHO_DRIVER := @echo "* module: # ECHO_DRIVER_DESC := ( ECHO_DRIVER_DONE := )" diff --git a/demos/src/ftmulti.c b/demos/src/ftmulti.c index 75689db82..5a5b20e6e 100644 --- a/demos/src/ftmulti.c +++ b/demos/src/ftmulti.c @@ -13,8 +13,7 @@ /****************************************************************************/ #include -#include -#include +#include #include #include "common.h" @@ -76,7 +75,8 @@ int use_grays = 1; /* the standard raster's interface */ - FT_Raster_Funcs std_raster; + FT_Renderer std_renderer; + FT_Renderer smooth_renderer; FT_Multi_Master multimaster; FT_Long design_pos[T1_MAX_MM_AXIS]; @@ -460,10 +460,10 @@ static void reset_raster( void ) { - if ( antialias && use_grays ) - FT_Set_Raster( library, &ft_grays_raster ); + if ( antialias && use_grays && smooth_renderer ) + FT_Set_Renderer( library, smooth_renderer, 0, 0 ); else - FT_Set_Raster( library, &std_raster ); + FT_Set_Renderer( library, std_renderer, 0, 0 ); } @@ -715,8 +715,11 @@ PanicZ( "Could not initialize FreeType library" ); /* retrieve the standard raster's interface */ - (void)FT_Get_Raster( library, ft_glyph_format_outline, &std_raster ); - reset_raster(); + std_renderer = (FT_Renderer)FT_Get_Module( library, "standard renderer" ); + if (!std_renderer) + PanicZ( "Could not retrieve standard renderer" ); + + smooth_renderer = (FT_Renderer)FT_Get_Module( library, "smooth renderer" ); NewFile: ptsize = orig_ptsize; diff --git a/demos/src/ftstring.c b/demos/src/ftstring.c index 1a2d46a3e..726324d28 100644 --- a/demos/src/ftstring.c +++ b/demos/src/ftstring.c @@ -11,6 +11,7 @@ /****************************************************************************/ #include +#include #include #include "common.h" @@ -64,7 +65,8 @@ static int use_grays = 1; /* the standard raster's interface */ - static FT_Raster_Funcs std_raster; + FT_Renderer std_renderer; + FT_Renderer smooth_renderer; static FT_Matrix trans_matrix; static int transform = 0; @@ -470,14 +472,10 @@ static void reset_raster( void ) { - FT_Error error; - - error = 1; - if ( use_grays && antialias ) - error = FT_Set_Raster( library, &ft_grays_raster ); - - if (error) - (void)FT_Set_Raster( library, &std_raster ); + if ( antialias && use_grays && smooth_renderer ) + FT_Set_Renderer( library, smooth_renderer, 0, 0 ); + else + FT_Set_Renderer( library, std_renderer, 0, 0 ); } @@ -673,7 +671,11 @@ if (error) PanicZ( "Could not initialise FreeType library" ); /* retrieve the standard raster's interface */ - (void)FT_Get_Raster( library, ft_glyph_format_outline, &std_raster ); + std_renderer = (FT_Renderer)FT_Get_Module( library, "standard renderer" ); + if (!std_renderer) + PanicZ( "Could not retrieve standard renderer" ); + + smooth_renderer = (FT_Renderer)FT_Get_Module( library, "smooth renderer" ); NewFile: ptsize = orig_ptsize; diff --git a/demos/src/fttimer.c b/demos/src/fttimer.c index 5e057db65..4042f5f78 100644 --- a/demos/src/fttimer.c +++ b/demos/src/fttimer.c @@ -20,6 +20,7 @@ /****************************************************************************/ #include +#include #include #include @@ -331,8 +332,12 @@ /* set-up smooth anti-aliaser */ if (use_grays) { - error = FT_Set_Raster( library, &ft_grays_raster ); - if (error) Panic( "Could not initialize smooth anti-aliasing renderer" ); + FT_Renderer smooth; + + smooth = (FT_Renderer)FT_Get_Module( library, "smooth renderer" ); + if (!smooth) Panic( "Could not initialize smooth anti-aliasing renderer" ); + + FT_Set_Renderer( library, smooth, 0, 0 ); } /* Load face */ diff --git a/demos/src/ftview.c b/demos/src/ftview.c index bf1d45b65..43f4dfe89 100644 --- a/demos/src/ftview.c +++ b/demos/src/ftview.c @@ -17,8 +17,7 @@ #include -#include -#include +#include /* the following header shouldn't be used in normal programs */ #include @@ -84,7 +83,9 @@ int trace_level = 0; /* the standard raster's interface */ - FT_Raster_Funcs std_raster; + FT_Renderer std_renderer; + FT_Renderer smooth_renderer; + #define RASTER_BUFF_SIZE 32768 char raster_buff[RASTER_BUFF_SIZE]; @@ -458,10 +459,10 @@ static void reset_raster( void ) { - if ( antialias && use_grays ) - FT_Set_Raster( library, &ft_grays_raster ); + if ( antialias && use_grays && smooth_renderer ) + FT_Set_Renderer( library, smooth_renderer, 0, 0 ); else - FT_Set_Raster( library, &std_raster ); + FT_Set_Renderer( library, std_renderer, 0, 0 ); } @@ -672,8 +673,12 @@ PanicZ( "Could not initialize FreeType library" ); /* retrieve the standard raster's interface */ - (void)FT_Get_Raster( library, ft_glyph_format_outline, &std_raster ); + std_renderer = (FT_Renderer)FT_Get_Module( library, "standard renderer" ); + if (!std_renderer) + PanicZ( "Could not retrieve standard renderer" ); + smooth_renderer = (FT_Renderer)FT_Get_Module( library, "smooth renderer" ); + NewFile: ptsize = orig_ptsize; hinted = 1; diff --git a/demos/src/memtest.c b/demos/src/memtest.c index b510ef31d..574c7028f 100644 --- a/demos/src/memtest.c +++ b/demos/src/memtest.c @@ -224,7 +224,7 @@ int main( int argc, char** argv ) /* the new library has no drivers in it, add the default ones */ /* (implemented in ftinit.c).. */ - FT_Default_Drivers(library); + FT_Add_Default_Modules(library); /* Now check all files */ diff --git a/demos/src/ttdebug.c b/demos/src/ttdebug.c index 138db6e54..3a4216d85 100644 --- a/demos/src/ttdebug.c +++ b/demos/src/ttdebug.c @@ -1203,7 +1203,7 @@ int glyph_size; if (error) Panic( "could not initialise FreeType library" ); memory = library->memory; - driver = FT_Get_Driver( library, "truetype" ); + driver = (FT_Driver)FT_Get_Module( library, "truetype" ); if (!driver) Panic( "could not find the TrueType driver in FreeType 2\n" ); FT_Set_Debug_Hook( library, diff --git a/include/freetype/config/ftmodule.h b/include/freetype/config/ftmodule.h index 910866330..1fb091a9b 100644 --- a/include/freetype/config/ftmodule.h +++ b/include/freetype/config/ftmodule.h @@ -1,7 +1,9 @@ -FT_DRIVER(cff_driver_interface) -FT_DRIVER(t1cid_driver_interface) -FT_DRIVER(psnames_driver_interface) -FT_DRIVER(sfnt_driver_interface) -FT_DRIVER(tt_driver_interface) -FT_DRIVER(t1_driver_interface) -FT_DRIVER(t1z_driver_interface) +FT_USE_MODULE(cff_driver_class) +FT_USE_MODULE(t1cid_driver_class) +FT_USE_MODULE(psnames_module_class) +FT_USE_MODULE(ft_standard_renderer_class) +FT_USE_MODULE(ft_smooth_renderer_class) +FT_USE_MODULE(sfnt_module_class) +FT_USE_MODULE(tt_driver_class) +FT_USE_MODULE(t1_driver_class) +FT_USE_MODULE(t1z_driver_class) diff --git a/include/freetype/config/ftoption.h b/include/freetype/config/ftoption.h index 570a598fb..209881618 100644 --- a/include/freetype/config/ftoption.h +++ b/include/freetype/config/ftoption.h @@ -251,16 +251,12 @@ /*************************************************************************/ /* */ - /* FT_MAX_DRIVERS */ + /* FT_MAX_MODULES */ /* */ - /* The maximum number of font drivers that can be registered in a */ - /* single FreeType library object. 8 seems to be a good choice due */ - /* to the relative low actual number of drivers ;-) */ + /* The maximum number ofmodules that can be registered in a single */ + /* FreeType library object. 16 seems to be a good choice for now :-) */ /* */ - /* If you don't intend to register new drivers at runtime, you */ - /* certainly do not need to change this value.. */ - /* */ -#define FT_MAX_DRIVERS 8 +#define FT_MAX_MODULES 16 /*************************************************************************/ diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h index 37aea0586..66e3841c8 100644 --- a/include/freetype/freetype.h +++ b/include/freetype/freetype.h @@ -209,6 +209,19 @@ typedef struct FT_LibraryRec_ *FT_Library; + /*************************************************************************/ + /* */ + /* */ + /* FT_Module */ + /* */ + /* */ + /* A handle to a given FreeType module object. Each module can be */ + /* a font driver, a renderer, or anything else that provides services */ + /* to the formers.. */ + /* */ + typedef struct FT_ModuleRec_* FT_Module; + + /*************************************************************************/ /* */ /* */ @@ -225,6 +238,22 @@ typedef struct FT_DriverRec_* FT_Driver; + + /*************************************************************************/ + /* */ + /* */ + /* FT_Renderer */ + /* */ + /* */ + /* A handle to a given FreeType renderer. A renderer is in charge */ + /* of converting a glyph image to a bitmap, when necessary. Each */ + /* supports a given glyph image format, and one or more target */ + /* surface depths.. */ + /* */ + typedef struct FT_RendererRec_* FT_Renderer; + + + /*************************************************************************/ /* */ /* */ @@ -607,7 +636,7 @@ /************************************************************/ /* The following fields should be considered private and */ - /* rarely, if ever, used by client applications.. */ + /* rarely, if ever, used driectly by client applications.. */ FT_Driver driver; FT_Memory memory; @@ -750,6 +779,19 @@ #define FT_FACE_FLAG_MULTIPLE_MASTERS 0x100 + /*************************************************************************/ + /* */ + /* */ + /* FT_FACE_FLAG_EXTERNAL_STREAM */ + /* */ + /* */ + /* This bit field is used internally by FreeType to indicate that */ + /* a face's stream was provided by the client application and should */ + /* not be destroyed by FT_Done_Face */ + /* */ +#define FT_FACE_FLAG_EXTERNAL_STREAM 0x4000 + + #define FT_HAS_HORIZONTAL(face) (face->face_flags & FT_FACE_FLAG_HORIZONTAL) #define FT_HAS_VERTICAL(face) (face->face_flags & FT_FACE_FLAG_VERTICAL) #define FT_HAS_KERNING(face) (face->face_flags & FT_FACE_FLAG_KERNING) @@ -921,6 +963,25 @@ #define FT_SUBGLYPH_FLAG_USE_MY_METRICS 0x200 + /********************************************************************** + * + * + * FT_Glyph_Loader + * + * + * The glyph loader is an internal object used to load several + * glyphs together (for example, in the case of composites) + * + * + * the glyph loader implementation is not part of the high-level + * API, hence the forward structure declaration; + * + * + *********************************************************************/ + + typedef struct FT_GlyphLoader_ FT_GlyphLoader; + + /*************************************************************************/ /* */ /* FreeType Glyph Slot base class */ @@ -941,35 +1002,104 @@ /* rare, the glyph slots are listed through a direct, */ /* single-linked list using its `next' field. */ /* */ - /* metrics :: The metrics of the last loaded glyph in the slot. The */ - /* returned values depend on the last load flags (see the */ - /* FT_Load_Glyph() API function) and can be expressed */ - /* either in 26.6 fractional pixels or font units. */ - /* */ - /* metrics2 :: This field is used to return alternate glyph metrics */ - /* for scalable formats. Only four fields in it are */ - /* valid: horiBearingX, horiAdvance, vertBearingY and */ - /* vertAdvance. All other fields should be ignored. */ - /* By default, it contains the glyph metrics expressed */ - /* in font units. However, when FT_Load_Glyph() is called */ - /* with FT_LOAD_LINEAR set, the metrics are expressed */ - /* in 16.16 unhinted pixel values.. This can be useful */ - /* to perform WYSIWYG glyph layout.. */ - /* */ /* generic :: A typeless pointer which is unused by the FreeType */ /* library or any of its drivers. It can be used by */ /* client applications to link their own data to each */ /* size object. */ /* */ - /* outline :: The outline descriptor for the current glyph, if it */ - /* is a vectorial one. The nature of the last loaded */ - /* glyph can be retrieved through the result value */ - /* returned by FT_Load_Glyph(). */ + /* metrics :: The metrics of the last loaded glyph in the slot. The */ + /* returned values depend on the last load flags (see the */ + /* FT_Load_Glyph() API function) and can be expressed */ + /* either in 26.6 fractional pixels or font units. */ + /* */ + /* Note that even when the glyph image is transformed, */ + /* the metrics aren't.. */ + /* */ + /* linearHoriAdvance :: For scalable formats only, this field holds */ + /* the linearly scaled horizontal advance width */ + /* for the glyph (i.e. the scaled and unhinted */ + /* value of the hori advance). This can be */ + /* important to perform correct WYSIWYG layout */ + /* */ + /* Note that this value is expressed by default */ + /* in 16.16 pixels. However, when the glyph is */ + /* loaded with the FT_LOAD_UNSCALED_LINEAR flag, */ + /* this field contains simply the value of the */ + /* advance in original font units. */ + /* */ + /* linearVertAdvance :: For scalable formats only, this field holds */ + /* the linearly scaled vertical advance height */ + /* for the glyph. See linearHoriAdvance for */ + /* comments. */ + /* */ + /* advance :: this is the transformed advance width for the glyph */ + /* */ + /* format :: this field indicates the format of the image */ + /* contained in the glyph slot. Typically */ + /* ft_glyph_format_bitmap, ft_glyph_format_outline */ + /* & ft_glyph_format_composite, but others are possible */ + /* */ + /* bitmap :: this field is used as a bitmap descriptor when the */ + /* slot format is ft_glyph_format_bitmap. Note that */ + /* the address and content of the bitmap buffer can */ + /* change between calls of FT_Load_Glyph and a few */ + /* other functions. */ + /* */ + /* bitmap_left :: this is the bitmap's left bearing expressed in */ + /* integer pixels. Of course, this is only valid */ + /* when the format is ft_glyph_format_bitmap */ + /* */ + /* bitmap_top :: this is the bitmap's top bearing expressed in */ + /* integer pixels. Remember that this is the */ + /* distance from the baseline to the top-most */ + /* glyph scanline, upwards y coordinates being */ + /* *positive* */ + /* */ + /* outline :: The outline descriptor for the current glyph image */ + /* when it's format is ft_glyph_bitmap_outline. */ + /* */ + /* num_subglyphs :: the number of subglyphs in a composite glyph. */ + /* this format is only valid for the composite */ + /* glyph format, that should normally only be */ + /* loaded with the FT_LOAD_NO_RECURSE flag.. */ + /* */ + /* subglyphs :: an array of subglyph descriptors for composite */ + /* glyphs. There are 'num_subglyphs' elements in */ + /* in there.. */ + /* */ + /* control_data :: certain font drivers can also return the control */ + /* data for a given glyph image (e.g. TrueType */ + /* bytecode, Type 1 charstrings, etc..). This field */ + /* is a pointer to such data.. */ + /* */ + /* control_len :: this is the length in bytes of the control data */ + /* */ + /* other :: really wicked format can use this pointer to */ + /* present their own glyph image to client apps. */ + /* Note that the app will need to know about the */ + /* image format, */ + /* */ + /* loader :: this is a private object for the glyph slot. Do */ + /* not touch this.. */ + /* */ + /* */ + /* When FT_Load_Glyph is called with default flags (FT_LOAD_DEFAULT), */ + /* the glyph image is loaded in the glyph slot in its native format */ + /* (e.g. a vectorial outline for TrueType and Type 1 formats) */ + /* */ + /* This image can later be converted into a bitmap by calling */ + /* FT_Render_Glyph. This function finds the current renderer for the */ + /* native image's format then invokes it. */ + /* */ + /* The renderer is in charge of transforming the native image through */ + /* the slot's face transformation fields, then convert it into a */ + /* bitmap that is returned in "slot->bitmap". */ + /* */ + /* Note that "slot->bitmap_left" and "slot->bitmap_top" are also */ + /* used to specify the position of the bitmap relative to the current */ + /* pen position (e.g. coordinates [0,0] on the baseline). Of course, */ + /* "slot->format" is also changed to "ft_glyph_format_bitmap".. */ /* */ - /* bitmap :: The bitmap/graymap descriptor for the current glyph, */ - /* if it is a fixed-width one. The nature of the last */ - /* loaded glyph can be retrieved through the result value */ - /* returned by FT_Load_Glyph(). */ /* */ enum @@ -977,21 +1107,29 @@ ft_glyph_own_bitmap = 1 }; + + typedef struct FT_GlyphSlotRec_ { FT_Face face; FT_GlyphSlot next; FT_UInt flags; + FT_Generic generic; FT_Glyph_Metrics metrics; - FT_Glyph_Metrics metrics2; + FT_Fixed linearHoriAdvance; + FT_Fixed linearVertAdvance; + FT_Vector advance; FT_Glyph_Format format; + FT_Bitmap bitmap; + FT_Int bitmap_left; + FT_Int bitmap_top; + FT_Outline outline; - FT_Int num_subglyphs; - FT_Int max_subglyphs; + FT_UInt num_subglyphs; FT_SubGlyph* subglyphs; void* control_data; @@ -999,6 +1137,9 @@ void* other; + /* private fields */ + FT_GlyphLoader* loader; + } FT_GlyphSlotRec; @@ -1149,7 +1290,7 @@ FT_Long memory_size; FT_String* pathname; FT_Stream stream; - FT_Driver driver; + FT_Module driver; FT_Int num_params; FT_Parameter* params; @@ -1438,6 +1579,15 @@ /* */ /* FreeType error code. 0 means success. */ /* */ + /* */ + /* If the glyph image is not a bitmap, and if the bit flag */ + /* FT_LOAD_IGNORE_TRANSFORM is unset, the glyph image will be */ + /* transformed with the information passed to a previous call to */ + /* FT_Set_Transform. */ + /* */ + /* Note that this also transforms the "face.glyph.advance" field, */ + /* but **NOT** the values in "face.glyph.metrics".. */ + /* */ FT_EXPORT_DEF(FT_Error) FT_Load_Glyph( FT_Face face, FT_UInt glyph_index, FT_Int load_flags ); @@ -1472,6 +1622,14 @@ /* is not defined in the charmap, this function will return an */ /* error.. */ /* */ + /* If the glyph image is not a bitmap, and if the bit flag */ + /* FT_LOAD_IGNORE_TRANSFORM is unset, the glyph image will be */ + /* transformed with the information passed to a previous call to */ + /* FT_Set_Transform. */ + /* */ + /* Note that this also transforms the "face.glyph.advance" field, */ + /* but **NOT** the values in "face.glyph.metrics".. */ + /* */ FT_EXPORT_DEF(FT_Error) FT_Load_Char( FT_Face face, FT_ULong char_code, FT_Int load_flags ); @@ -1507,15 +1665,17 @@ /*************************************************************************/ /* */ /* */ - /* FT_LOAD_NO_OUTLINE */ + /* FT_LOAD_RENDER */ /* */ /* */ /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the function should not load the vector outline of a given glyph. */ - /* If an embedded bitmap exists for the glyph in the font, it will be */ - /* loaded, otherwise nothing is returned and an error is produced. */ + /* the function should load the glyph and immediately convert it */ + /* into a bitmap, when necessary, by calling FT_Render_Glyph. */ /* */ -#define FT_LOAD_NO_OUTLINE 4 + /* Note that by default, FT_Load_Glyph loads the glyph image in its */ + /* native format.. */ + /* */ +#define FT_LOAD_RENDER 4 /*************************************************************************/ @@ -1526,8 +1686,9 @@ /* */ /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ /* the function should not load the bitmap or pixmap of a given */ - /* glyph. If an outline exists for the glyph in the font, it is */ - /* loaded, otherwise nothing is returned and an error is produced. */ + /* glyph. This is useful when you do not want to load the embedded */ + /* bitmaps of scalable formats, as the native glyph image will be */ + /* loaded, and can then be renderer through FT_Render_Glyph */ /* */ #define FT_LOAD_NO_BITMAP 8 @@ -1535,15 +1696,18 @@ /*************************************************************************/ /* */ /* */ - /* FT_LOAD_LINEAR */ + /* FT_LOAD_VERTICAL_LAYOUT */ /* */ /* */ /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the function should return the linearly scaled metrics for the */ - /* glyph in `slot->metrics2' (these metrics are not grid-fitted). */ - /* Otherwise, `metrics2' gives the original font units values. */ + /* the glyph image should be prepared for vertical layout. This */ + /* basically means that "face.glyph.advance" will correspond to the */ + /* vertical advance height (instead of the default horizontal */ + /* advance width), and that the glyph image will translated to */ + /* match the vertical bearings positions.. */ /* */ -#define FT_LOAD_LINEAR 16 +#define FT_LOAD_VERTICAL_LAYOUT 16 + /*************************************************************************/ /* */ @@ -1557,6 +1721,7 @@ /* */ #define FT_LOAD_FORCE_AUTOHINT 32 + /*************************************************************************/ /* */ /* */ @@ -1571,6 +1736,7 @@ /* */ #define FT_LOAD_CROP_BITMAP 64 + /*************************************************************************/ /* */ /* */ @@ -1601,6 +1767,7 @@ /* */ #define FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH 512 + /*************************************************************************/ /* */ /* */ @@ -1621,6 +1788,49 @@ /* */ #define FT_LOAD_NO_RECURSE 1024 + + /*************************************************************************/ + /* */ + /* */ + /* FT_LOAD_IGNORE_TRANSFORM */ + /* */ + /* */ + /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ + /* the glyph loader should not try to transform the loaded glyph */ + /* image. */ + /* */ +#define FT_LOAD_IGNORE_TRANSFORM 2048 + + + /*************************************************************************/ + /* */ + /* */ + /* FT_LOAD_ANTI_ALIAS */ + /* */ + /* */ + /* Only used with FT_LOAD_RENDER set, indicates that the returned */ + /* glyph image should be anti-aliased. This basically tells the */ + /* glyph loader to use 'ft_render_mode_antialias' when calling */ + /* FT_Render_Glyph. */ + /* */ + /* */ +#define FT_LOAD_LINEAR_ANTI_ALIAS 4096 + + + /*************************************************************************/ + /* */ + /* */ + /* FT_LOAD_LINEAR_DESIGN */ + /* */ + /* */ + /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ + /* the function should return the linearly scaled metrics expressed */ + /* in original font units, instead of the default 16.16 pixel values. */ + /* */ +#define FT_LOAD_LINEAR_DESIGN 8192 + + + /*************************************************************************/ /* */ /* */ @@ -1635,6 +1845,69 @@ #define FT_LOAD_DEFAULT 0 + /*************************************************************************/ + /* */ + /* */ + /* FT_Set_Transform */ + /* */ + /* */ + /* A function used to set the transformation that is applied to glyph */ + /* images just before they're converted to bitmaps in a glyph slot */ + /* when FT_Render_Glyph is called.. */ + /* */ + /* */ + /* face :: A handle to the source face object. */ + /* */ + /* */ + /* matrix :: A pointer to the transformation's 2x2 matrix. Use 0 for */ + /* the identity matrix. */ + /* delta :: A pointer to the translation vector. Use 0 for the null */ + /* vector. */ + /* */ + /* */ + /* The transformation is only applied to scalable image formats. */ + /* */ + FT_EXPORT_DEF( void ) FT_Set_Transform( FT_Face face, + FT_Matrix* matrix, + FT_Vector* delta ); + + + /************************************************************************* + * + * + * FT_Render_Glyph + * + * + * Converts a given glyph image to a bitmap. It does so by inspecting + * the glyph image format, find the relevant renderer, and invoke it + * + * + * slot :: handle to the glyph slot containing the image to + * convert + * + * render_mode :: a set of bit flags indicating which kind of bitmap + * to render. For now, only 'ft_render_mode_anti_alias' + * is supported by the available renderers, but others + * could appear later (e.g. LCD or TV optimised) + * + * + * Error code. 0 means success. + * + * + * in case of success, the renderer will be used to convert glyph + * images in the renderer's known format into bitmaps. + * + * This doesn't change the current renderer for other formats.. + * + * The slot's native image should be considered lost after the + * conversion.. + * + *************************************************************************/ + + FT_EXPORT_DEF(FT_Error) FT_Render_Glyph( FT_GlyphSlot slot, + FT_UInt render_mode ); + + /*************************************************************************/ /* */ /* */ @@ -1826,6 +2099,27 @@ FT_Long b ); + /*************************************************************************/ + /* */ + /* */ + /* FT_Vector_Transform */ + /* */ + /* */ + /* Transforms a single vector through a 2x2 matrix. */ + /* */ + /* */ + /* vector :: The target vector to transform */ + /* */ + /* */ + /* matrix :: A pointer to the source 2x2 matrix. */ + /* */ + /* */ + /* Yes. */ + /* */ + FT_EXPORT_DEF(void) FT_Vector_Transform( FT_Vector* vector, + FT_Matrix* matrix ); + + /*************************************************************************/ /* */ /* */ @@ -1893,6 +2187,7 @@ FT_Outline* outline, FT_Raster_Params* params ); + /*************************************************************************/ /* */ /* */ @@ -2045,6 +2340,7 @@ FT_Pos yOffset ); +#if 0 /*************************************************************************/ /* */ /* */ @@ -2146,7 +2442,7 @@ FT_Glyph_Format format, unsigned long mode, void* args ); - +#endif /***************************************************************************/ /***************************************************************************/ @@ -2231,25 +2527,6 @@ FT_EXPORT_DEF(void) FT_Outline_Reverse( FT_Outline* outline ); - /*************************************************************************/ - /* */ - /* */ - /* FT_Vector_Transform */ - /* */ - /* */ - /* Transforms a single vector through a 2x2 matrix. */ - /* */ - /* */ - /* vector :: The target vector to transform */ - /* */ - /* */ - /* matrix :: A pointer to the source 2x2 matrix. */ - /* */ - /* */ - /* Yes. */ - /* */ - FT_EXPORT_DEF(void) FT_Vector_Transform( FT_Vector* vector, - FT_Matrix* matrix ); /*************************************************************************/ diff --git a/include/freetype/fterrors.h b/include/freetype/fterrors.h index e918f167c..de3f94571 100644 --- a/include/freetype/fterrors.h +++ b/include/freetype/fterrors.h @@ -64,6 +64,8 @@ FT_ERROR_START_LIST FT_ERRORDEF( FT_Err_Invalid_CharMap_Handle, 0x0035, "invalid charmap handle" ) FT_ERRORDEF( FT_Err_Invalid_Outline, 0x0036, "invalid outline" ) FT_ERRORDEF( FT_Err_Invalid_Dimensions, 0x0037, "invalid dimensions" ) + FT_ERRORDEF( FT_Err_Invalid_Version, 0x0038, "invalid FreeType version" ) + FT_ERRORDEF( FT_Err_Lower_Module_Version, 0x0039, "module version is too low" ) FT_ERRORDEF( FT_Err_Unavailable_Outline, 0x0040, "unavailable outline" ) FT_ERRORDEF( FT_Err_Unavailable_Bitmap, 0x0041, "unavailable bitmap" ) diff --git a/include/freetype/ftimage.h b/include/freetype/ftimage.h index 77bb3688d..de9328f23 100644 --- a/include/freetype/ftimage.h +++ b/include/freetype/ftimage.h @@ -5,6 +5,9 @@ /* This file defines the glyph image formats recognized by FreeType, as */ /* well as the default raster interface. */ /* */ +/* Note: a "raster" is simply a scan-line converter, used to render */ +/* FT_Outlines into FT_Bitmaps */ +/* */ /* Copyright 1996-2000 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg */ /* */ @@ -187,6 +190,10 @@ * for paletted pixel modes. * * + * For now, the only pixel mode supported by FreeType are mono and grays. + * However, drivers might be added in the future to support more "colorful" + * options.. + * * When using pixel modes pal2, pal4 and pal8 with a void `palette' * field, a gray pixmap with respectively 4, 16 and 256 levels of gray * is assumed. This, in order to be compatible with some embedded bitmap @@ -195,7 +202,6 @@ * Note that no font was found presenting such embedded bitmaps, so this * is currently completely unhandled by the library. * - * *************************************************************************/ typedef struct FT_Bitmap_ @@ -220,8 +226,7 @@ /* */ /* */ /* This structure is used to describe an outline to the scan-line */ - /* converter. It's a copy of the TT_Outline type that was defined */ - /* in FreeType 1.x. */ + /* converter. */ /* */ /* */ /* n_contours :: The number of contours in the outline. */ @@ -268,6 +273,7 @@ } FT_Outline; + /*************************************************************************/ /* */ /* */ @@ -286,7 +292,7 @@ /* ft_outline_even_odd_fill :: */ /* by default, outlines are filled using the non-zero winding */ /* rule. When set to 1, the outline will be filled using the */ - /* even-odd fill rule.. (XXX: unimplemented) */ + /* even-odd fill rule.. (only works with the smooth raster) */ /* */ /* ft_outline_reverse_fill :: */ /* By default, outside contours of an outline are oriented in */ @@ -460,6 +466,23 @@ /* conic_to :: The second-order Bezier arc emitter. */ /* cubic_to :: The third-order Bezier arc emitter. */ /* */ + /* shift :: the shift that is applied to coordinates before */ + /* they're sent to the emmiter */ + /* */ + /* delta :: the delta that is applied to coordinates before */ + /* they're sent to the emitter, but after the shift */ + /* */ + /* */ + /* The point coordinates sent to the emitters are the transformed */ + /* version of the original coordinates (this is important for high */ + /* accuracy during scan-conversion). The transform is simply: */ + /* */ + /* x' = (x << shift) - delta */ + /* y' = (x << shift) - delta */ + /* */ + /* Set the value of 'shift' and 'delta' to 0 to get the original */ + /* point coordinates.. */ + /* */ typedef struct FT_Outline_Funcs_ { FT_Outline_MoveTo_Func move_to; @@ -479,13 +502,12 @@ /* FT_IMAGE_TAG */ /* */ /* */ - /* This macro converts four letter tags which are used to label */ - /* TrueType tables into an unsigned long to be used within FreeType. */ + /* This macro converts four letter tags into unsigned longs.. */ /* */ #define FT_IMAGE_TAG( _x1, _x2, _x3, _x4 ) \ - (((unsigned long)_x1 << 24) | \ - ((unsigned long)_x2 << 16) | \ - ((unsigned long)_x3 << 8) | \ + (((unsigned long)_x1 << 24) | \ + ((unsigned long)_x2 << 16) | \ + ((unsigned long)_x3 << 8) | \ (unsigned long)_x4) @@ -495,7 +517,7 @@ * FT_Glyph_Format * * - * An enumeration type used to describethe format of a given glyph + * An enumeration type used to describe the format of a given glyph * image. Note that this version of FreeType only supports two image * formats, even though future font drivers will be able to register * their own format. @@ -541,12 +563,12 @@ /************************************************************************** * + * A raster is a scan converter, in charge of rendering an outline into a + * a bitmap. This section contains the public API for rasters. * - * - * - * - * - * + * Note that in FreeType 2, all rasters are now encapsulated within + * specific modules called "renderers". See + * for more details on renderers.. * **************************************************************************/ @@ -935,4 +957,3 @@ #endif /* FTIMAGE_H */ - diff --git a/include/freetype/internal/ftdriver.h b/include/freetype/internal/ftdriver.h index b89afef07..f2d435e99 100644 --- a/include/freetype/internal/ftdriver.h +++ b/include/freetype/internal/ftdriver.h @@ -2,7 +2,7 @@ /* */ /* ftdriver.h */ /* */ -/* FreeType driver interface (specification). */ +/* FreeType font driver interface (specification). */ /* */ /* Copyright 1996-2000 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ @@ -18,174 +18,9 @@ #ifndef FTDRIVER_H #define FTDRIVER_H -#include +#include +#include - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** D R I V E R S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* FTDriver_initDriver */ - /* */ - /* */ - /* A driver method used to create a new driver object for a given */ - /* format. */ - /* */ - /* */ - /* driver :: A handle to the `new' driver object. The fields */ - /* `library', `system', and `lock' are already set when the */ - /* base layer calls this method. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - typedef FT_Error (*FTDriver_initDriver)( FT_Driver driver ); - - - /*************************************************************************/ - /* */ - /* */ - /* FTDriver_doneDriver */ - /* */ - /* */ - /* A driver method used to finalize a given driver object. Note that */ - /* all faces and resources for this driver have been released before */ - /* this call, and that this function should NOT destroy the driver */ - /* object. */ - /* */ - /* */ - /* driver :: A handle to target driver object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - typedef FT_Error (*FTDriver_doneDriver)( FT_Driver driver ); - - - typedef void (*FTDriver_Interface)( void ); - - /*************************************************************************/ - /* */ - /* */ - /* FTDriver_getInterface */ - /* */ - /* */ - /* Each driver can provide one or more extensions to the base */ - /* FreeType API. These can be used to access format specific */ - /* features (e.g., all TrueType/OpenType resources share a common */ - /* file structure and common tables which can be accessed through the */ - /* `sfnt' interface), or more simply generic ones (e.g., the */ - /* `postscript names' interface which can be used to retrieve the */ - /* PostScript name of a given glyph index). */ - /* */ - /* */ - /* driver :: A handle to a driver object. */ - /* */ - /* */ - /* interface :: A string designing the interface. Examples are */ - /* `sfnt', `post_names', `charmaps', etc. */ - /* */ - /* */ - /* A typeless pointer to the extension's interface (normally a table */ - /* of function pointers). Returns NULL if the requested extension */ - /* isn't available (i.e., wasn't compiled in the driver at build */ - /* time). */ - /* */ - typedef FTDriver_Interface (*FTDriver_getInterface) - ( FT_Driver driver, - const FT_String* interface ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_FormatInterface */ - /* */ - /* */ - /* A driver interface field whose value is a driver-specific */ - /* interface method table. This table contains entry points to */ - /* various functions that are strictly related to the driver's */ - /* format. */ - /* */ - typedef void* FT_FormatInterface; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Attach_Reader */ - /* */ - /* */ - /* This function is associated to the `attach_file' driver-specific */ - /* interface. It is used to read additional data for a given face */ - /* from another input stream/file. For example, it is used to */ - /* attach a Type 1 AFM file to a given Type 1 face. */ - /* */ - typedef FT_Error (*FT_Attach_Reader)( FT_Face face, FT_Stream stream ); - - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** F A C E S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* FTDriver_initFace */ - /* */ - /* */ - /* A driver method used to initialize a new face object. The object */ - /* must be created by the caller. */ - /* */ - /* */ - /* stream :: The input stream. */ - /* face :: A handle to the new target face. */ - /* */ - /* */ - /* typeface_index :: The face index in the font resource. Used to */ - /* access individual faces in collections. */ - /* */ - /* num_params :: number of optional generic parameters */ - /* parameters :: table of generic parameters */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The `typeface_index' parameter field will be set to -1 if the */ - /* engine only wants to test the format of the resource. This means */ - /* that font drivers should simply check the font format, then return */ - /* immediately with an error code of 0 (meaning success). The field */ - /* `num_faces' should be set. */ - /* */ - /* The generic parameters are a way to pass additional data to a */ - /* given font driver when creating a new face object. In most cases */ - /* they will be simply ignored.. */ - /* */ - /* FTDriver_doneFace() will be called subsequently, whatever the */ - /* result was. */ - /* */ typedef FT_Error (*FTDriver_initFace)( FT_Stream stream, FT_Face face, FT_Int typeface_index, @@ -193,400 +28,147 @@ FT_Parameter* parameters ); - /*************************************************************************/ - /* */ - /* */ - /* FTDriver_doneFace */ - /* */ - /* */ - /* A driver method used to finalize a given face object. This */ - /* function does NOT destroy the object, that is the responsibility */ - /* of the caller. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ typedef void (*FTDriver_doneFace)( FT_Face face ); - /*************************************************************************/ - /* */ - /* */ - /* FTDriver_getKerning */ - /* */ - /* */ - /* A driver method used to return the kerning vector between two */ - /* glyphs of the same face. */ - /* */ - /* */ - /* 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. */ - /* */ - /* */ - /* kerning :: A pointer to the kerning vector. This is in font */ - /* units for scalable formats, and in pixels for */ - /* fixed-sizes formats. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Only horizontal layouts (left-to-right & right-to-left) are */ - /* supported by this method. Other layouts, or more sophisticated */ - /* kernings are out of the scope of this method (the basic driver */ - /* interface is meant to be simple). */ - /* */ - /* They can be implemented by format-specific interfaces. */ - /* */ - typedef FT_Error (*FTDriver_getKerning)( FT_Face face, - FT_UInt left_glyph, - FT_UInt right_glyph, - FT_Vector* kerning ); - - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** S I Z E S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* FTDriver_initSize */ - /* */ - /* */ - /* A driver method used to initialize a new size object. The object */ - /* must be created by the caller. */ - /* */ - /* */ - /* size :: A handle to the new size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function should return an error if the face's format isn't */ - /* scalable. */ - /* */ typedef FT_Error (*FTDriver_initSize)( FT_Size size ); - /*************************************************************************/ - /* */ - /* */ - /* FTDriver_setCharSizes */ - /* */ - /* */ - /* A driver method used to reset a size's character sizes (horizontal */ - /* and vertical) expressed in fractional points. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* char_width :: The character width expressed in 26.6 */ - /* fractional points. */ - /* char_height :: The character height expressed in 26.6 */ - /* fractional points. */ - /* horz_resolution :: The horizontal resolution. */ - /* vert_resolution :: The vertical resolution. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function should always FAIL if the face format isn't */ - /* scalable! */ - /* */ + typedef void (*FTDriver_doneSize)( FT_Size size ); + + + typedef FT_Error (*FTDriver_initGlyphSlot)( FT_GlyphSlot slot ); + + + typedef void (*FTDriver_doneGlyphSlot)( FT_GlyphSlot slot ); + + typedef FT_Error (*FTDriver_setCharSizes)( FT_Size size, FT_F26Dot6 char_width, FT_F26Dot6 char_height, FT_UInt horz_resolution, FT_UInt vert_resolution ); - - /*************************************************************************/ - /* */ - /* */ - /* FTDriver_setPixelSizes */ - /* */ - /* */ - /* A driver method used to reset a size's character sizes (horizontal */ - /* and vertical) expressed in integer pixels. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* pixel_width :: The character width expressed in 26.6 fractional */ - /* pixels. */ - /* pixel_height :: The character height expressed in 26.6 fractional */ - /* pixels. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function should work with all kinds of `size' objects, either */ - /* fixed or scalable ones. */ - /* */ typedef FT_Error (*FTDriver_setPixelSizes)( FT_Size size, FT_UInt pixel_width, FT_UInt pixel_height ); - - /*************************************************************************/ - /* */ - /* */ - /* FTDriver_doneSize */ - /* */ - /* */ - /* A driver method used to finalize a given size object. This method */ - /* does NOT destroy the object; this is the responsibility of the */ - /* caller. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - typedef void (*FTDriver_doneSize)( FT_Size size ); - - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** G L Y P H S L O T S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* FTDriver_initGlyphSlot */ - /* */ - /* */ - /* A driver method used to initialize a new glyph slot object. The */ - /* object must be created by the caller. The glyph slot is a */ - /* container where a single glyph can be loaded, either in outline or */ - /* bitmap format. */ - /* */ - /* */ - /* slot :: A handle to the new glyph slot object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - typedef FT_Error (*FTDriver_initGlyphSlot)( FT_GlyphSlot slot ); - - - /*************************************************************************/ - /* */ - /* */ - /* FTDriver_doneGlyphSlot */ - /* */ - /* */ - /* A driver method used to finalize a given glyph slot. The object */ - /* is not destroyed by this function. */ - /* */ - /* */ - /* slot :: A handle to the new glyph slot object. */ - /* */ - typedef void (*FTDriver_doneGlyphSlot)( FT_GlyphSlot slot ); - - - /*************************************************************************/ - /* */ - /* */ - /* FTDriver_loadGlyph */ - /* */ - /* */ - /* A driver method used to load a glyph within a given glyph slot. */ - /* */ - /* */ - /* slot :: A handle to target slot object where the glyph will */ - /* be loaded. */ - /* size :: A handle to the source face size at which the glyph */ - /* must be scaled/loaded. */ - /* */ - /* */ - /* glyph_index :: The index of the glyph in the font file. */ - /* load_flags :: A flag indicating what to load for this glyph. The */ - /* FTLOAD_??? constants can be used to control the */ - /* glyph loading process (e.g., whether the outline */ - /* should be scaled, whether to load bitmaps or not, */ - /* whether to hint the outline, etc). */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ typedef FT_Error (*FTDriver_loadGlyph)( FT_GlyphSlot slot, FT_Size size, FT_UInt glyph_index, FT_Int load_flags ); - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** C H A R A C T E R M A P S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* */ - /* FTDriver_getCharIndex */ - /* */ - /* */ - /* Uses a charmap to return a given character code's glyph index. */ - /* */ - /* */ - /* charmap :: A handle to the source charmap object. */ - /* charcode :: The character code. */ - /* */ - /* */ - /* The glyph index. 0 means `undefined character code'. */ - /* */ typedef FT_UInt (*FTDriver_getCharIndex)( FT_CharMap charmap, FT_Long charcode ); + typedef FT_Error (*FTDriver_getKerning)( FT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_Vector* kerning ); - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** I N T E R F A C E ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ + typedef FT_Error (*FTDriver_attachFile)( FT_Face face, FT_Stream stream ); - /*************************************************************************/ - /* */ - /* */ - /* FT_DriverInterface */ - /* */ - /* */ - /* A structure which holds a font driver's basic interface used by */ - /* the high-level parts of FreeType (or other applications). */ - /* */ - /* Most scalable drivers provide a specialized interface to access */ - /* format specific features. It can be retrieved with a call to */ - /* `get_format_interface()', and should be defined in each font */ - /* driver header (e.g., ttdriver.h, t1driver.h, etc). */ - /* */ - /* All fields are function pointers. */ - /* */ - /* */ - /* driver_object_size :: The size in bytes of a single driver */ - /* object. */ - /* face_object_size :: The size in bytes of a single face object. */ - /* size_object_size :: The size in bytes of a single size object. */ - /* slot_object_size :: The size in bytes of a single glyph slot */ - /* object. */ - /* */ - /* driver_name :: A string to describe the driver to the */ - /* system. It doesn't necessarily describe */ - /* in detail all the font formats the driver */ - /* may support. */ - /* driver_version :: The driver version number. Starts at 1. */ - /* driver_requires :: The FreeType major version this driver is */ - /* written for. This number should be equal */ - /* to or greater than 2! */ - /* */ - /* format_interface :: A pointer to the driver's format-specific */ - /* interface. */ - /* */ - /* init_driver :: Used to initialize a given driver object. */ - /* done_driver :: Used to finalize and destroy a given */ - /* driver object. */ - /* get_interface :: Returns an interface for a given driver */ - /* extension. */ - /* */ - /* init_face :: Initializes a given face object. */ - /* done_face :: Discards a face object, as well as all */ - /* child objects (sizes, charmaps, glyph */ - /* slots). */ - /* get_kerning :: Returns the kerning vector corresponding */ - /* to a pair of glyphs, expressed in unscaled */ - /* font units. */ - /* */ - /* init_size :: Initializes a given size object. */ - /* done_size :: Finalizes a given size object. */ - /* set_size_char_sizes :: Resets a scalable size object's character */ - /* size. */ - /* set_pixel_sizes :: Resets a face size object's pixel */ - /* dimensions. Applies to both scalable and */ - /* fixed faces. */ - /* */ - /* init_glyph_slot :: Initializes a given glyph slot object. */ - /* done_glyph_slot :: Finalizes a given glyph slot. */ - /* load_glyph :: Loads a given glyph into a given slot. */ - /* */ - /* get_char_index :: Returns the glyph index for a given */ - /* charmap. */ - /* */ - typedef struct FT_DriverInterface_ + + typedef FT_Error (*FTDriver_getAdvances)( FT_Face face, + FT_UInt first, + FT_UInt count, + FT_Bool vertical, + FT_UShort* advances ); + + + /************************************************************************* + * + * + * FT_Driver_Class + * + * + * The font driver class. This structure mostly contains pointers to + * driver methods. + * + * + * face_object_size :: size of a face object in bytes + * size_object_size :: size of a size object in bytes + * slot_object_size :: size of a glyph object in bytes + * + * init_face :: format-specific face constructor + * done_face :: format-specific face destructor + * + * init_size :: format-specific size constructor + * done_size :: format-specific size destructor + * + * init_slot :: format-specific slot constructor + * done_slot :: format-specific slot destructor + * + * set_char_sizes :: handle to a function used to set the new character + * size in points + resolution. can be set to 0 to + * indicate default behaviour + * + * set_pixel_sizes :: handme to function used to set the new character + * size in pixels. can be set to 0 to indicate + * default behaviour + * + * load_glyph :: load a given glyph image in a slot. This field + * is mandatory ! + * + * get_char_index :: return the glyph index of a given character + * for a given charmap. This field is mandatory ! + * + * get_kerning :: return the unscaled kerning for a given pair + * of glyphs. can be set to 0 if the format doesn't + * support kerning. + * + * attach_file :: reads additional data for a face from another + * file/stream. For example, this can be used + * to add data from AFM or PFM files on a Type 1 + * face, or a CIDMap on a CID-keyed face.. + * + * get_advances :: a function used to return the advances of 'count' + * glyphs, starting at 'index'. the "vertical" flags + * must be set when vertical advances are queried. + * the advances buffer is caller-allocated + * + * get_bboxes :: a function used to return the bounding box of + * 'count' glyphs, starting at 'index'. the bbox + * buffer is caller-allocated + * + * + * Most function pointers, with the exception of "load_glyph" and + * "get_char_index" can be set to 0 to indicate a the default behaviour + * + * + *************************************************************************/ + + typedef struct FT_Driver_Class_ { - FT_Int driver_object_size; + FT_Module_Class root; + FT_Int face_object_size; FT_Int size_object_size; FT_Int slot_object_size; - FT_String* driver_name; - FT_Int driver_version; - FT_Int driver_requires; - - void* format_interface; - - FTDriver_initDriver init_driver; - FTDriver_doneDriver done_driver; - FTDriver_getInterface get_interface; - FTDriver_initFace init_face; FTDriver_doneFace done_face; - FTDriver_getKerning get_kerning; - + FTDriver_initSize init_size; FTDriver_doneSize done_size; + + FTDriver_initGlyphSlot init_slot; + FTDriver_doneGlyphSlot done_slot; + FTDriver_setCharSizes set_char_sizes; FTDriver_setPixelSizes set_pixel_sizes; - FTDriver_initGlyphSlot init_glyph_slot; - FTDriver_doneGlyphSlot done_glyph_slot; FTDriver_loadGlyph load_glyph; - FTDriver_getCharIndex get_char_index; - } FT_DriverInterface; + FTDriver_getKerning get_kerning; + FTDriver_attachFile attach_file; + + FTDriver_getAdvances get_advances; + + } FT_Driver_Class; #endif /* FTDRIVER_H */ diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h index 17f852073..5c4e82430 100644 --- a/include/freetype/internal/ftobjs.h +++ b/include/freetype/internal/ftobjs.h @@ -26,6 +26,7 @@ #define FTOBJS_H #include +#include #include /*************************************************************************/ @@ -67,12 +68,103 @@ #endif + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** M O D U L E S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /************************************************************************ + * + * + * FT_ModuleRec + * + * + * A module object instance. + * + * + * clazz :: pointer to module's class + * library :: handle to parent library object + * memory :: handle to memory manager + * generic :: generic structure for user-level extensibility (?) + * + ************************************************************************/ + + typedef struct FT_ModuleRec_ + { + FT_Module_Class* clazz; + FT_Library library; + FT_Memory memory; + FT_Generic generic; + + } FT_ModuleRec; + + /* typecast an object to a FT_Module */ + #define FT_MODULE(x) ((FT_Module)(x)) + #define FT_MODULE_CLASS(x) FT_MODULE(x)->clazz + #define FT_MODULE_LIBRARY(x) FT_MODULE(x)->library + #define FT_MODULE_MEMORY(x) FT_MODULE(x)->memory + + #define FT_MODULE_IS_DRIVER(x) (FT_MODULE_CLASS(x)->module_flags & \ + ft_module_font_driver ) + + #define FT_MODULE_IS_DRIVER(x) (FT_MODULE_CLASS(x)->module_flags & \ + ft_module_font_driver ) + + #define FT_MODULE_IS_RENDERER(x) (FT_MODULE_CLASS(x)->module_flags & \ + ft_module_renderer ) + + #define FT_DRIVER_IS_SCALABLE(x) (FT_MODULE_CLASS(x)->module_flags & \ + ft_module_driver_scalable ) + + #define FT_DRIVER_USES_OUTLINES(x) !(FT_MODULE_CLASS(x)->module_flags & \ + ft_module_driver_no_outlines ) + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** FACE, SIZE & GLYPH SLOT OBJECTS ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* a few macros used to perform easy typecasts with minimal brain damage */ + + #define FT_FACE(x) ((FT_Face)x) + #define FT_SIZE(x) ((FT_Size)x) + #define FT_SLOT(x) ((FT_GlyphSlot)x) + + #define FT_FACE_DRIVER(x) FT_FACE(x)->driver + #define FT_FACE_LIBRARY(x) FT_FACE_DRIVER(x)->root.library + #define FT_FACE_MEMORY(x) FT_FACE(x)->memory + + #define FT_SIZE_FACE(x) FT_SIZE(x)->face + #define FT_SLOT_FACE(x) FT_SLOT(x)->face + + #define FT_FACE_SLOT(x) FT_FACE(x)->glyph + #define FT_FACE_SIZE(x) FT_FACE(x)->size + + + /* this must be kept exported - this will be used later in our own */ + /* high-level caching font manager called SemTex (way after the */ + /* 2.0 release though.. */ FT_EXPORT_DEF(FT_Error) FT_New_Size( FT_Face face, FT_Size* size ); FT_EXPORT_DEF(FT_Error) FT_Done_Size( FT_Size size ); + FT_EXPORT_DEF(FT_Error) FT_New_GlyphSlot( FT_Face face, FT_GlyphSlot* aslot ); @@ -80,19 +172,114 @@ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** G L Y P H L O A D E R ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct FT_GlyphLoad_ + { + FT_Outline outline; /* outline */ + FT_UInt num_subglyphs; /* number of subglyphs */ + FT_SubGlyph* subglyphs; /* subglyphs */ + FT_Vector* extra_points; /* extra points table.. */ + + } FT_GlyphLoad; + + + struct FT_GlyphLoader_ + { + FT_Memory memory; + FT_UInt max_points; + FT_UInt max_contours; + FT_UInt max_subglyphs; + FT_Bool use_extra; + + FT_GlyphLoad base; + FT_GlyphLoad current; + + void* other; /* for possible future extension ? */ + + }; + + + BASE_DEF(FT_Error) FT_GlyphLoader_New( FT_Memory memory, + FT_GlyphLoader* *aloader ); + + BASE_DEF(FT_Error) FT_GlyphLoader_Create_Extra( FT_GlyphLoader* loader ); + + BASE_DEF(void) FT_GlyphLoader_Done( FT_GlyphLoader* loader ); + + BASE_DEF(void) FT_GlyphLoader_Reset( FT_GlyphLoader* loader ); + + BASE_DEF(void) FT_GlyphLoader_Rewind( FT_GlyphLoader* loader ); + + BASE_DEF(FT_Error) FT_GlyphLoader_Check_Points( FT_GlyphLoader* loader, + FT_UInt n_points, + FT_UInt n_contours ); + + BASE_DEF(FT_Error) FT_GlyphLoader_Check_Subglyphs( FT_GlyphLoader* loader, + FT_UInt n_subs ); + + BASE_DEF(void) FT_GlyphLoader_Prepare( FT_GlyphLoader* loader ); + + + BASE_DEF(void) FT_GlyphLoader_Add( FT_GlyphLoader* loader ); + + BASE_DEF(FT_Error) FT_GlyphLoader_Copy_Points( FT_GlyphLoader* target, + FT_GlyphLoader* source ); /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** ****/ - /**** D R I V E R S ****/ + /**** R E N D E R E R S ****/ /**** ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ + #define FT_RENDERER(x) ((FT_Renderer)(x)) + + typedef struct FT_RendererRec_ + { + FT_ModuleRec root; + FT_Renderer_Class* clazz; + FT_Glyph_Format glyph_format; + + FT_Raster raster; + FT_Raster_Render_Func raster_render; + FTRenderer_render render; + + } FT_RendererRec; + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** F O N T D R I V E R S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* typecast a module into a driver easily */ + #define FT_DRIVER(x) ((FT_Driver)(x)) + + /* typecast a module as a driver, and get its driver class */ + #define FT_DRIVER_CLASS(x) FT_DRIVER(x)->clazz + /*************************************************************************/ /* */ /* */ @@ -103,28 +290,11 @@ /* managing and loading font files of a given format. */ /* */ /* */ - /* library :: A handle to the driver's parent library. */ + /* root :: contains the fields of the root module class */ /* */ - /* memory :: A handle to the driver's memory object. This is a */ - /* duplicate of `library->memory'. */ - /* */ - /* interface :: A set of driver methods that implement its */ - /* behaviour. These methods are called by the */ - /* various FreeType functions like FT_New_Face(), */ - /* FT_Load_Glyph(), etc. */ - /* */ - /* format :: A typeless pointer, used to store the address of */ - /* the driver's format specific interface. This is a */ - /* table of other driver methods that are specific to */ - /* its format. Format specific interfaces are */ - /* defined in the driver's header files (e.g., */ - /* `freetype/drivers/ttlib/ttdriver.h'). */ - /* */ - /* version :: The driver's version. It can be used for */ - /* versioning and dynamic driver update if needed. */ - /* */ - /* description :: An ASCII string describing the driver's supported */ - /* format, like `truetype', `type1', etc. */ + /* clazz :: a pointer to the font driver's class. Note that */ + /* this is NOT root.clazz. 'class' wasn't used */ + /* as it's a reserved word in C++ */ /* */ /* faces_list :: The list of faces currently opened by this driver. */ /* */ @@ -132,39 +302,22 @@ /* registry, when they are supported through the */ /* config macro FT_CONFIG_OPTION_EXTENSIONS */ /* */ + /* glyph_loader :: glyph loader for all faces managed by this driver */ + /* this object isn't defined for unscalable formats */ + /* */ typedef struct FT_DriverRec_ { - FT_Library library; - FT_Memory memory; - - FT_Generic generic; - - FT_DriverInterface interface; - FT_FormatInterface format; - - FT_Int version; /* driver version */ - FT_String* description; /* format description */ - - FT_ListRec faces_list; /* driver's faces list */ - - void* extensions; + FT_ModuleRec root; + FT_Driver_Class* clazz; + + FT_ListRec faces_list; + void* extensions; + + FT_GlyphLoader* glyph_loader; } FT_DriverRec; - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** G L Y P H Z O N E S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ @@ -197,31 +350,45 @@ /* generic :: Client data variable. Used to extend the */ /* Library class by higher levels and clients. */ /* */ - /* num_drivers :: The number of drivers currently registered */ + /* num_modules :: The number of modules currently registered */ /* within this library. This is set to 0 for new */ - /* libraries. New drivers are added through the */ - /* FT_Add_Driver() API function. */ + /* libraries. New modules are added through the */ + /* FT_Add_Module() API function. */ /* */ - /* drivers :: A table used to store handles to the currently */ - /* registered font drivers. Note that each driver */ + /* modules :: A table used to store handles to the currently */ + /* registered modules. Note that each font driver */ /* contains a list of its opened faces. */ /* */ + /* renderers :: the list of renderers currently registered */ + /* within the library. */ + /* */ + /* cur_renderer :: current outline renderer. This is a short cut */ + /* used to avoid parsing the list on each call to */ + /* FT_Outline_Render. It is a handle to the current */ + /* renderer for the ft_glyph_format_outline format. */ + /* */ /* raster_pool :: The raster object's render pool. This can */ /* ideally be changed dynamically at run-time. */ /* */ + /* raster_pool_size :: size of the render pool in bytes */ + /* */ + /* */ + /* */ + /* */ typedef void (*FT_DebugHook_Func)( void* arg ); + typedef struct FT_LibraryRec_ { - FT_Memory memory; /* library's memory object */ + FT_Memory memory; /* library's memory manager */ FT_Generic generic; - FT_Int num_drivers; - FT_Driver drivers[ FT_MAX_DRIVERS ]; /* driver objects */ + FT_Int num_modules; + FT_Module modules[ FT_MAX_MODULES ]; /* module objects */ - FT_Raster_Funcs raster_funcs[ FT_MAX_GLYPH_FORMATS ]; - FT_Raster rasters [ FT_MAX_GLYPH_FORMATS ]; + FT_ListRec renderers; /* list of renderers */ + FT_Renderer cur_renderer; /* current outline renderer */ void* raster_pool; /* scan-line conversion render pool */ long raster_pool_size; /* size of render pool in bytes */ @@ -239,21 +406,13 @@ - FT_EXPORT_DEF(void) FT_Set_Debug_Hook( FT_Library library, - FT_UInt hook_index, - FT_DebugHook_Func debug_hook ); + FT_EXPORT_DEF(void) FT_Set_Debug_Hook( FT_Library library, + FT_UInt hook_index, + FT_DebugHook_Func debug_hook ); - FT_EXPORT_DEF(FT_Error) FT_Add_Driver( FT_Library library, - const FT_DriverInterface* driver_interface ); - FT_EXPORT_DEF(FT_Error) FT_Remove_Driver( FT_Driver driver ); - - - FT_EXPORT_DEF(FT_Driver) FT_Get_Driver( FT_Library library, - char* driver_name ); - #ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM FT_EXPORT_DEF(FT_Error) FT_New_Stream( const char* filepathname, @@ -265,6 +424,7 @@ #endif + /* Define default raster's interface. The default raster is located in `src/base/ftraster.c' */ /* */ /* Client applications can register new rasters through the FT_Set_Raster API.. */ diff --git a/include/freetype/internal/sfnt.h b/include/freetype/internal/sfnt.h index 3f5f02bab..5e524bae1 100644 --- a/include/freetype/internal/sfnt.h +++ b/include/freetype/internal/sfnt.h @@ -110,8 +110,8 @@ typedef - FTDriver_Interface (*SFNT_Get_Interface_Func)( FT_Driver driver, - const char* interface ); + FT_Module_Interface (*SFNT_Get_Interface_Func)( FT_Module module, + const char* interface ); /*************************************************************************/ diff --git a/src/base/ftextend.c b/src/base/ftextend.c index f7ca3987b..7b4f22283 100644 --- a/src/base/ftextend.c +++ b/src/base/ftextend.c @@ -70,7 +70,7 @@ FT_Extension_Registry* registry; - memory = driver->library->memory; + memory = driver->root.library->memory; if ( ALLOC( registry, sizeof ( *registry ) ) ) return error; @@ -101,7 +101,7 @@ LOCAL_FUNC FT_Error FT_Done_Extensions( FT_Driver driver ) { - FT_Memory memory = driver->memory; + FT_Memory memory = driver->root.memory; FREE( driver->extensions ); @@ -126,7 +126,7 @@ /* */ FT_EXPORT_FUNC( FT_Error ) FT_Register_Extension( FT_Driver driver, - FT_Extension_Class* class ) + FT_Extension_Class* clazz ) { FT_Extension_Registry* registry; @@ -134,7 +134,7 @@ if ( !driver ) return FT_Err_Invalid_Driver_Handle; - if ( !class ) + if ( !clazz ) return FT_Err_Invalid_Argument; registry = (FT_Extension_Registry*)driver->extensions; @@ -143,11 +143,10 @@ FT_Int n = registry->num_extensions; FT_Extension_Class* cur = registry->classes + n; - if ( n >= FT_MAX_EXTENSIONS ) return FT_Err_Too_Many_Extensions; - *cur = *class; + *cur = *clazz; cur->offset = registry->cur_offset; @@ -260,7 +259,7 @@ cur->finalize( ext, face ); } - memory = face->driver->memory; + memory = face->driver->root.memory; FREE( face->extensions ); } @@ -302,7 +301,7 @@ if ( !registry ) return FT_Err_Ok; - memory = face->driver->memory; + memory = face->driver->root.memory; if ( ALLOC( face->extensions, registry->cur_offset ) ) return error; diff --git a/src/base/ftglyph.c b/src/base/ftglyph.c index d576b1012..33f09b502 100644 --- a/src/base/ftglyph.c +++ b/src/base/ftglyph.c @@ -209,11 +209,9 @@ /* transform the outline -- note that the original metrics are NOT */ /* transformed by this, only the outline points themselves... */ - FT_Outline_Transform( &face->glyph->outline, - &face->transform_matrix ); FT_Outline_Translate( &face->glyph->outline, - face->transform_delta.x + origin_x, - face->transform_delta.y + origin_y ); + origin_x, + origin_y ); /* compute the size in pixels of the outline */ FT_Outline_Get_CBox( &face->glyph->outline, &cbox ); @@ -257,7 +255,7 @@ FT_Outline_Translate( &face->glyph->outline, -cbox.xMin, -cbox.yMin ); - error = FT_Outline_Get_Bitmap( face->driver->library, + error = FT_Outline_Get_Bitmap( face->driver->root.library, &face->glyph->outline, &bitglyph->bitmap ); if ( error ) @@ -327,8 +325,8 @@ *vecglyph = 0; - /* check that NO_OUTLINE and NO_RECURSE are not set */ - if ( load_flags & ( FT_LOAD_NO_OUTLINE | FT_LOAD_NO_RECURSE ) ) + /* check that RENDER and NO_RECURSE are not set */ + if ( load_flags & ( FT_LOAD_RENDER | FT_LOAD_NO_RECURSE ) ) { error = FT_Err_Invalid_Argument; goto Exit; @@ -348,16 +346,6 @@ goto Exit; } - /* transform the outline -- note that the original metrics are NOT */ - /* transformed by this, only the outline points themselves... */ - if ( face->transform_flags ) - { - FT_Outline_Transform( &face->glyph->outline, &face->transform_matrix ); - FT_Outline_Translate( &face->glyph->outline, - face->transform_delta.x, - face->transform_delta.y ); - } - /* now, create a new outline glyph and copy everything */ memory = face->memory; if ( ALLOC( glyph, sizeof ( *glyph ) ) ) @@ -366,7 +354,7 @@ ft_prepare_glyph( (FT_Glyph)glyph, face, 0 ); glyph->metrics.glyph_type = ft_glyph_type_outline; - error = FT_Outline_New( face->driver->library, + error = FT_Outline_New( face->driver->root.library, face->glyph->outline.n_points, face->glyph->outline.n_contours, &glyph->outline ); @@ -386,72 +374,6 @@ } - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_Transform */ - /* */ - /* */ - /* A function used to set the transformation that is applied to glyph */ - /* images just after they are loaded in the face's glyph slot, and */ - /* before they are returned by either FT_Get_Glyph_Bitmap() or */ - /* FT_Get_Glyph_Outline(). */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* */ - /* matrix :: A pointer to the transformation's 2x2 matrix. Use 0 for */ - /* the identity matrix. */ - /* delta :: A pointer to the translation vector. Use 0 for the null */ - /* vector. */ - /* */ - /* */ - /* The transformation is only applied to glyph outlines if they are */ - /* found in a font face. It is unable to transform embedded glyph */ - /* bitmaps. */ - /* */ - FT_EXPORT_FUNC( void ) FT_Set_Transform( FT_Face face, - FT_Matrix* matrix, - FT_Vector* delta ) - { - if ( !face ) - return; - - face->transform_flags = 0; - - if ( !matrix ) - { - face->transform_matrix.xx = 0x10000L; - face->transform_matrix.xy = 0L; - face->transform_matrix.yx = 0L; - face->transform_matrix.yy = 0x10000L; - matrix = &face->transform_matrix; - } - else - face->transform_matrix = *matrix; - - /* set transform_flags bit flag 0 if `matrix' isn't the identity */ - if ( ( matrix->xy | matrix->yx ) || - matrix->xx != 0x10000L || - matrix->yy != 0x10000L ) - face->transform_flags |= 1; - - if ( !delta ) - { - face->transform_delta.x = 0; - face->transform_delta.y = 0; - delta = &face->transform_delta; - } - else - face->transform_delta = *delta; - - /* set transform_flags bit flag 1 if `delta' isn't the null vector */ - if ( delta->x | delta->y ) - face->transform_flags |= 2; - } - - /*************************************************************************/ /* */ /* */ diff --git a/src/base/ftinit.c b/src/base/ftinit.c index 6035486ea..1a6e44022 100644 --- a/src/base/ftinit.c +++ b/src/base/ftinit.c @@ -20,8 +20,8 @@ /* The purpose of this file is to implement the following two */ /* functions: */ /* */ - /* FT_Default_Drivers(): */ - /* This function is used to add the set of default drivers to a */ + /* FT_Add_Default_Modules(): */ + /* This function is used to add the set of default modules to a */ /* fresh new library object. The set is taken from the header file */ /* `freetype/config/ftmodule.h'. See the document `FreeType 2.0 */ /* Build System' for more information. */ @@ -40,7 +40,7 @@ #include #include #include -#include +#include /*************************************************************************/ @@ -52,16 +52,16 @@ #undef FT_COMPONENT #define FT_COMPONENT trace_init -#undef FT_DRIVER -#define FT_DRIVER( x ) extern FT_DriverInterface x; +#undef FT_USE_MODULE +#define FT_USE_MODULE( x ) extern const FT_Module_Class* x; #include -#undef FT_DRIVER -#define FT_DRIVER( x ) &x, +#undef FT_USE_MODULE +#define FT_USE_MODULE( x ) (const FT_Module_Class*)&x, static -const FT_DriverInterface* ft_default_drivers[] = +const FT_Module_Class* ft_default_modules[] = { #include 0 @@ -71,7 +71,7 @@ const FT_DriverInterface* ft_default_drivers[] = /*************************************************************************/ /* */ /* */ - /* FT_Default_Drivers */ + /* FT_Add_Default_Modules */ /* */ /* */ /* Adds the set of default drivers to a given library object. */ @@ -79,23 +79,22 @@ const FT_DriverInterface* ft_default_drivers[] = /* */ /* library :: A handle to a new library object. */ /* */ - FT_EXPORT_FUNC( void ) FT_Default_Drivers( FT_Library library ) + FT_EXPORT_FUNC( void ) FT_Add_Default_Modules( FT_Library library ) { - FT_Error error; - const FT_DriverInterface** cur; + FT_Error error; + const FT_Module_Class** cur; + /* test for valid library delayed to FT_Add_Module() */ - /* test for valid library delayed to FT_Add_Driver() */ - - cur = ft_default_drivers; + cur = ft_default_modules; while ( *cur ) { - error = FT_Add_Driver( library, *cur ); + error = FT_Add_Module( library, *cur ); /* notify errors, but don't stop */ if ( error ) { - FT_ERROR(( "FT_Default_Drivers: Cannot install `%s', error = %x\n", - (*cur)->driver_name, error )); + FT_ERROR(( "FT_Add_Default_Module: Cannot install `%s', error = %x\n", + (*cur)->module_name, error )); } cur++; } @@ -115,7 +114,7 @@ const FT_DriverInterface* ft_default_drivers[] = /* library :: A handle to a new library object. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeTyoe error code. 0 means success. */ /* */ FT_EXPORT_FUNC( FT_Error ) FT_Init_FreeType( FT_Library* library ) { @@ -139,7 +138,7 @@ const FT_DriverInterface* ft_default_drivers[] = error = FT_New_Library( memory, library ); if ( !error ) - FT_Default_Drivers( *library ); + FT_Add_Default_Modules( *library ); return error; } diff --git a/src/base/ftmm.c b/src/base/ftmm.c index 09bc88ea9..4f6457261 100644 --- a/src/base/ftmm.c +++ b/src/base/ftmm.c @@ -47,8 +47,8 @@ FT_Get_MM_Func func; - func = (FT_Get_MM_Func)driver->interface.get_interface( - driver, "get_mm" ); + func = (FT_Get_MM_Func)driver->root.clazz->get_interface( + FT_MODULE(driver), "get_mm" ); if ( func ) error = func( face, master ); } @@ -76,8 +76,8 @@ FT_Set_MM_Design_Func func; - func = (FT_Set_MM_Design_Func)driver->interface.get_interface( - driver, "set_mm_design" ); + func = (FT_Set_MM_Design_Func)driver->root.clazz->get_interface( + FT_MODULE(driver), "set_mm_design" ); if ( func ) error = func( face, num_coords, coords ); } @@ -105,8 +105,8 @@ FT_Set_MM_Blend_Func func; - func = (FT_Set_MM_Blend_Func)driver->interface.get_interface( - driver, "set_mm_blend" ); + func = (FT_Set_MM_Blend_Func)driver->root.clazz->get_interface( + FT_MODULE(driver), "set_mm_blend" ); if ( func ) error = func( face, num_coords, coords ); } diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index ad540fe8c..308b84d91 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -199,6 +199,18 @@ } } + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** S T R E A M ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ /* */ @@ -298,22 +310,698 @@ } - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** O B J E C T M A N A G E M E N T ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - #undef FT_COMPONENT #define FT_COMPONENT trace_objs + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** G L Y P H L O A D E R ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /************************************************************************** + * + * The glyph loader is a simple object which is used to load a set of + * glyphs easily. It is critical for the correct loading of composites. + * + * Ideally, one can see it as a stack of abstract "glyph" objects. + * + * loader.base is really the bottom of the stack. It describes a + * single glyph image made of the juxtaposition of several + * glyphs (those 'in the stack') + * + * loader.current describes the top of the stack, on which a new + * glyph can be loaded. + * + * Rewind clears the stack + * Prepare means set up "loader.current" for addition of a new glyph image + * Add means add the 'current' glyph image to the 'base' one, and + * prepare for another one.. + * + * the glyph loader is now a base object. Each driver used to re-implement + * it in one way or the other, which wasted code and energy.. + * + *************************************************************************/ + + /* create a new glyph loader */ + BASE_FUNC(FT_Error) FT_GlyphLoader_New( FT_Memory memory, + FT_GlyphLoader* *aloader ) + { + FT_GlyphLoader* loader; + FT_Error error; + + if (!ALLOC(loader, sizeof(*loader))) + { + loader->memory = memory; + *aloader = loader; + } + return error; + } + + + /* rewind the glyph loader - reset counters to 0 */ + BASE_FUNC(void) FT_GlyphLoader_Rewind( FT_GlyphLoader* loader ) + { + FT_GlyphLoad* base = &loader->base; + FT_GlyphLoad* current = &loader->current; + + base->outline.n_points = 0; + base->outline.n_contours = 0; + base->num_subglyphs = 0; + + *current = *base; + } + + + /* reset the glyph loader, frees all allocated tables and starts from zero */ + BASE_FUNC(void) FT_GlyphLoader_Reset( FT_GlyphLoader* loader ) + { + FT_Memory memory = loader->memory; + + FREE( loader->base.outline.points ); + FREE( loader->base.outline.tags ); + FREE( loader->base.outline.contours ); + FREE( loader->base.extra_points ); + FREE( loader->base.subglyphs ); + + loader->max_points = 0; + loader->max_contours = 0; + loader->max_subglyphs = 0; + + FT_GlyphLoader_Rewind( loader ); + } + + + /* delete a glyph loader */ + BASE_FUNC(void) FT_GlyphLoader_Done( FT_GlyphLoader* loader ) + { + if (loader) + { + FT_Memory memory = loader->memory; + + FT_GlyphLoader_Reset(loader); + FREE( loader ); + } + } + + + /* re-adjust the 'current' outline fields */ + static void FT_GlyphLoader_Adjust_Points( FT_GlyphLoader* loader ) + { + FT_Outline* base = &loader->base.outline; + FT_Outline* current = &loader->current.outline; + + current->points = base->points + base->n_points; + current->tags = base->tags + base->n_points; + current->contours = base->contours + base->n_contours; + + /* handle extra points table - if any */ + if (loader->use_extra) + loader->current.extra_points = loader->base.extra_points + base->n_points; + } + + + + BASE_FUNC(FT_Error) FT_GlyphLoader_Create_Extra( FT_GlyphLoader* loader ) + { + FT_Error error; + FT_Memory memory = loader->memory; + + if ( !ALLOC_ARRAY( loader->base.extra_points, + loader->max_points, FT_Vector ) ) + { + loader->use_extra = 1; + FT_GlyphLoader_Adjust_Points(loader); + } + return error; + } + + + + + /* re-adjust the 'current' subglyphs field */ + static void FT_GlyphLoader_Adjust_Subglyphs( FT_GlyphLoader* loader ) + { + FT_GlyphLoad* base = &loader->base; + FT_GlyphLoad* current = &loader->current; + + current->subglyphs = base->subglyphs + base->num_subglyphs; + } + + + /* ensure that we can add n_points and n_contours to our glyph. this */ + /* function reallocates its outline tables if necessary. Note that */ + /* it DOESN'T change the number of points within the loader !! */ + BASE_FUNC(FT_Error) FT_GlyphLoader_Check_Points( FT_GlyphLoader* loader, + FT_UInt n_points, + FT_UInt n_contours ) + { + FT_Memory memory = loader->memory; + FT_Error error = FT_Err_Ok; + FT_Outline* base = &loader->base.outline; + FT_Outline* current = &loader->current.outline; + FT_Bool adjust = 1; + + FT_UInt new_max; + + /* check points & tags */ + new_max = base->n_points + current->n_points + n_points; + if (new_max > loader->max_points) + { + new_max = (new_max+7) & -8; + if ( REALLOC_ARRAY( base->points, base->n_points, new_max, FT_Vector ) || + REALLOC_ARRAY( base->tags, base->n_points, new_max, FT_Byte ) ) + goto Exit; + + if ( loader->use_extra && + REALLOC_ARRAY( loader->base.extra_points, base->n_points, new_max, + FT_Vector ) ) + goto Exit; + + adjust = 1; + loader->max_points = new_max; + } + + /* check contours */ + new_max = base->n_contours + current->n_contours + + n_contours; + if (new_max > loader->max_contours) + { + new_max = (new_max+3) & -4; + if (REALLOC_ARRAY( base->contours, base->n_contours, new_max, FT_Short )) + goto Exit; + + adjust = 1; + loader->max_contours = new_max; + } + + if (adjust) + FT_GlyphLoader_Adjust_Points( loader ); + + Exit: + return error; + } + + + /* ensure that we can add n_subglyphs to our glyph. this function */ + /* reallocates its subglyphs table if necessary. Note that it DOES */ + /* NOT change the number of subglyphs within the loader !! */ + BASE_FUNC(FT_Error) FT_GlyphLoader_Check_Subglyphs( FT_GlyphLoader* loader, + FT_UInt n_subs ) + { + FT_Memory memory = loader->memory; + FT_Error error = FT_Err_Ok; + FT_UInt new_max; + + FT_GlyphLoad* base = &loader->base; + FT_GlyphLoad* current = &loader->current; + + new_max = base->num_subglyphs + current->num_subglyphs + n_subs; + if (new_max > loader->max_subglyphs) + { + new_max = (new_max+1) & -2; + if (REALLOC_ARRAY( base->subglyphs, base->num_subglyphs, + new_max, FT_SubGlyph )) + goto Exit; + + loader->max_subglyphs = new_max; + + FT_GlyphLoader_Adjust_Subglyphs( loader ); + } + + Exit: + return error; + } + + + /* prepare loader for the addition of a new glyph on top of the base one */ + BASE_FUNC(void) FT_GlyphLoader_Prepare( FT_GlyphLoader* loader ) + { + FT_GlyphLoad* current = &loader->current; + + current->outline.n_points = 0; + current->outline.n_contours = 0; + current->num_subglyphs = 0; + + FT_GlyphLoader_Adjust_Points ( loader ); + FT_GlyphLoader_Adjust_Subglyphs( loader ); + } + + + /* add current glyph to the base image - and prepare for another */ + BASE_FUNC(void) FT_GlyphLoader_Add( FT_GlyphLoader* loader ) + { + FT_GlyphLoad* base = &loader->base; + FT_GlyphLoad* current = &loader->current; + + FT_UInt n_curr_contours = current->outline.n_contours; + FT_UInt n_base_points = base->outline.n_points; + FT_UInt n; + + base->outline.n_points += current->outline.n_points; + base->outline.n_contours += current->outline.n_contours; + base->num_subglyphs += current->num_subglyphs; + + /* adjust contours count in newest outline */ + for ( n = 0; n < n_curr_contours; n++ ) + current->outline.contours[n] += n_base_points; + + /* prepare for another new glyph image */ + FT_GlyphLoader_Prepare( loader ); + } + + + BASE_FUNC(FT_Error) FT_GlyphLoader_Copy_Points( FT_GlyphLoader* target, + FT_GlyphLoader* source ) + { + FT_Error error; + FT_UInt num_points = source->base.outline.n_points; + FT_UInt num_contours = source->base.outline.n_contours; + + error = FT_GlyphLoader_Check_Points( target, num_points, num_contours ); + if (!error) + { + FT_Outline* out = &target->base.outline; + FT_Outline* in = &source->base.outline; + + MEM_Copy( out->points, in->points, num_points * sizeof(FT_Vector) ); + MEM_Copy( out->tags, in->tags, num_points * sizeof(char) ); + MEM_Copy( out->contours, in->contours, num_contours * sizeof(short) ); + + /* do we need to copy the extra points ? */ + if (target->use_extra && source->use_extra) + MEM_Copy( target->base.extra_points, source->base.extra_points, + num_points * sizeof(FT_Vector) ); + + out->n_points = num_points; + out->n_contours = num_contours; + + FT_GlyphLoader_Adjust_Points( target ); + } + return error; + } + + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** FACE, SIZE & GLYPH SLOT OBJECTS ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + static FT_Error ft_glyphslot_init( FT_GlyphSlot slot ) + { + FT_Driver driver = slot->face->driver; + FT_Driver_Class* clazz = driver->clazz; + FT_Memory memory = driver->root.memory; + FT_Error error = FT_Err_Ok; + + if (FT_DRIVER_USES_OUTLINES(driver)) + error = FT_GlyphLoader_New( memory, &slot->loader ); + + if (!error && clazz->init_slot) + error = clazz->init_slot( slot ); + + return error; + } + + + static void ft_glyphslot_clear( FT_GlyphSlot slot ) + { + /* clear all public fields in the glyph slot */ + MEM_Set( &slot->metrics, 0, sizeof(slot->metrics) ); + MEM_Set( &slot->outline, 0, sizeof(slot->outline) ); + MEM_Set( &slot->bitmap, 0, sizeof(slot->bitmap) ); + + slot->bitmap_left = 0; + slot->bitmap_top = 0; + slot->num_subglyphs = 0; + slot->subglyphs = 0; + slot->control_data = 0; + slot->control_len = 0; + slot->other = 0; + slot->format = 0; + + slot->linearHoriAdvance = 0; + slot->linearVertAdvance = 0; + } + + + static void ft_glyphslot_done( FT_GlyphSlot slot ) + { + FT_Driver driver = slot->face->driver; + FT_Driver_Class* clazz = driver->clazz; + FT_Memory memory = driver->root.memory; + + /* free bitmap buffer if needed */ + if ( slot->flags & ft_glyph_own_bitmap ) + FREE( slot->bitmap.buffer ); + + /* free glyph loader */ + if (FT_DRIVER_USES_OUTLINES(driver)) + { + FT_GlyphLoader_Done( slot->loader ); + slot->loader = 0; + } + + if (clazz->done_slot) + clazz->done_slot( slot ); + } + + + + + /*************************************************************************/ + /* */ + /* */ + /* FT_New_GlyphSlot */ + /* */ + /* */ + /* It is sometimes useful to have more than one glyph slot for a */ + /* given face object. This function is used to create additional */ + /* slots. All of them are automatically discarded when the face is */ + /* destroyed. */ + /* */ + /* */ + /* face :: A handle to a parent face object. */ + /* */ + /* */ + /* aslot :: A handle to a new glyph slot object. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + + FT_EXPORT_FUNC( FT_Error ) FT_New_GlyphSlot( FT_Face face, + FT_GlyphSlot* aslot ) + { + FT_Error error; + FT_Driver driver; + FT_Driver_Class* clazz; + FT_Memory memory; + FT_GlyphSlot slot; + + *aslot = 0; + + if ( !face || !aslot || !face->driver ) + return FT_Err_Invalid_Argument; + + driver = face->driver; + clazz = driver->clazz; + memory = driver->root.memory; + + FT_TRACE4(( "FT_New_GlyphSlot: Creating new slot object\n" )); + if ( !ALLOC( slot, clazz->slot_object_size ) ) + { + slot->face = face; + + error = ft_glyphslot_init( slot ); + if (error) + { + ft_glyphslot_done( slot ); + FREE( slot ); + goto Exit; + } + + *aslot = slot; + } + + Exit: + FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error )); + return error; + } + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Done_GlyphSlot */ + /* */ + /* */ + /* Destroys a given glyph slot. Remember however that all slots are */ + /* automatically destroyed with its parent. Using this function is */ + /* not always mandatory. */ + /* */ + /* */ + /* slot :: A handle to a target glyph slot. */ + /* */ + FT_EXPORT_FUNC( void ) FT_Done_GlyphSlot( FT_GlyphSlot slot ) + { + if ( slot ) + { + FT_Driver driver = slot->face->driver; + FT_Memory memory = driver->root.memory; + FT_GlyphSlot* parent; + FT_GlyphSlot cur; + + /* Remove slot from its parent face's list */ + parent = &slot->face->glyph; + cur = *parent; + while ( cur ) + { + if ( cur == slot ) + { + *parent = cur->next; + ft_glyphslot_done(slot); + FREE( slot ); + break; + } + cur = cur->next; + } + } + } + + + + /* forward declaration */ + static FT_Renderer ft_lookup_glyph_renderer( FT_GlyphSlot slot ); + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Set_Transform */ + /* */ + /* */ + /* A function used to set the transformation that is applied to glyph */ + /* images just before they're converted to bitmaps in a glyph slot */ + /* when FT_Render_Glyph is called.. */ + /* */ + /* */ + /* face :: A handle to the source face object. */ + /* */ + /* */ + /* matrix :: A pointer to the transformation's 2x2 matrix. Use 0 for */ + /* the identity matrix. */ + /* delta :: A pointer to the translation vector. Use 0 for the null */ + /* vector. */ + /* */ + /* */ + /* The transformation is only applied to scalable image formats. */ + /* */ + FT_EXPORT_FUNC( void ) FT_Set_Transform( FT_Face face, + FT_Matrix* matrix, + FT_Vector* delta ) + { + if ( !face ) + return; + + face->transform_flags = 0; + + if ( !matrix ) + { + face->transform_matrix.xx = 0x10000L; + face->transform_matrix.xy = 0L; + face->transform_matrix.yx = 0L; + face->transform_matrix.yy = 0x10000L; + matrix = &face->transform_matrix; + } + else + face->transform_matrix = *matrix; + + /* set transform_flags bit flag 0 if `matrix' isn't the identity */ + if ( ( matrix->xy | matrix->yx ) || + matrix->xx != 0x10000L || + matrix->yy != 0x10000L ) + face->transform_flags |= 1; + + if ( !delta ) + { + face->transform_delta.x = 0; + face->transform_delta.y = 0; + delta = &face->transform_delta; + } + else + face->transform_delta = *delta; + + /* set transform_flags bit flag 1 if `delta' isn't the null vector */ + if ( delta->x | delta->y ) + face->transform_flags |= 2; + } + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Load_Glyph */ + /* */ + /* */ + /* A function used to load a single glyph within a given glyph slot, */ + /* for a given size. */ + /* */ + /* */ + /* face :: A handle to the target face object where the glyph */ + /* will be loaded. */ + /* */ + /* glyph_index :: The index of the glyph in the font file. */ + /* */ + /* load_flags :: A flag indicating what to load for this glyph. The */ + /* FT_LOAD_XXX constants can be used to control the */ + /* glyph loading process (e.g., whether the outline */ + /* should be scaled, whether to load bitmaps or not, */ + /* whether to hint the outline, etc). */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + /* */ + /* If the glyph image is not a bitmap, and if the bit flag */ + /* FT_LOAD_IGNORE_TRANSFORM is unset, the glyph image will be */ + /* transformed with the information passed to a previous call to */ + /* FT_Set_Transform. */ + /* */ + /* Note that this also transforms the "face.glyph.advance" field, */ + /* but **NOT** the values in "face.glyph.metrics".. */ + /* */ + + FT_EXPORT_FUNC( FT_Error ) FT_Load_Glyph( FT_Face face, + FT_UInt glyph_index, + FT_Int load_flags ) + { + FT_Error error; + FT_Driver driver; + FT_GlyphSlot slot; + + if ( !face || !face->size || !face->glyph ) + return FT_Err_Invalid_Face_Handle; + + if ( glyph_index >= face->num_glyphs ) + return FT_Err_Invalid_Argument; + + slot = face->glyph; + ft_glyphslot_clear( slot ); + + driver = face->driver; + + /* when the flag NO_RECURSE is set, we disable hinting and scaling */ + if ( load_flags & FT_LOAD_NO_RECURSE ) + load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; + + error = driver->clazz->load_glyph( slot, + face->size, + glyph_index, + load_flags ); + if (error) goto Exit; + + /* compute the advance */ + if (load_flags & FT_LOAD_VERTICAL_LAYOUT) + { + slot->advance.x = 0; + slot->advance.y = slot->metrics.vertAdvance; + } + else + { + slot->advance.x = slot->metrics.horiAdvance; + slot->advance.y = 0; + } + + /* now, transform the glyph image when needed */ + if (face->transform_flags) + { + /* get renderer */ + FT_Renderer renderer = ft_lookup_glyph_renderer( slot ); + + if (renderer) + error = renderer->clazz->transform_glyph( renderer, slot, + &face->transform_matrix, + &face->transform_delta ); + /* transform advance */ + FT_Vector_Transform( &slot->advance, &face->transform_matrix ); + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Load_Char */ + /* */ + /* */ + /* A function used to load a single glyph within a given glyph slot, */ + /* for a given size, according to its character code ! */ + /* */ + /* */ + /* face :: A handle to a target face object where the glyph */ + /* will be loaded. */ + /* */ + /* char_code :: The glyph's character code, according to the */ + /* current charmap used in the face. */ + /* */ + /* load_flags :: A flag indicating what to load for this glyph. The */ + /* FT_LOAD_XXX constants can be used to control the */ + /* glyph loading process (e.g., whether the outline */ + /* should be scaled, whether to load bitmaps or not, */ + /* whether to hint the outline, etc). */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + /* */ + /* If the face has no current charmap, or if the character code */ + /* is not defined in the charmap, this function will return an */ + /* error.. */ + /* */ + /* If the glyph image is not a bitmap, and if the bit flag */ + /* FT_LOAD_IGNORE_TRANSFORM is unset, the glyph image will be */ + /* transformed with the information passed to a previous call to */ + /* FT_Set_Transform. */ + /* */ + /* Note that this also transforms the "face.glyph.advance" field, */ + /* but **NOT** the values in "face.glyph.metrics".. */ + /* */ + FT_EXPORT_FUNC( FT_Error ) FT_Load_Char( FT_Face face, + FT_ULong char_code, + FT_Int load_flags ) + { + FT_UInt glyph_index; + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + glyph_index = (FT_UInt)char_code; + if (face->charmap) + glyph_index = FT_Get_Char_Index( face, char_code ); + + return glyph_index ? FT_Load_Glyph( face, glyph_index, load_flags ) + : FT_Err_Invalid_Character_Code; + } + + + /* destructor for sizes list */ static @@ -321,8 +1009,14 @@ FT_Size size, FT_Driver driver ) { + /* finalize client-specific data */ + if (size->generic.finalizer) + size->generic.finalizer( size ); + /* finalize format-specific stuff */ - driver->interface.done_size( size ); + if (driver->clazz->done_size) + driver->clazz->done_size( size ); + FREE( size ); } @@ -333,8 +1027,10 @@ FT_Face face, FT_Driver driver ) { - /* Discard glyph slots for this face */ - /* XXX: Beware! FT_Done_GlyphSlot() changes the field `face->slot' */ + FT_Driver_Class* clazz = driver->clazz; + + /* Discard glyph slots for this face */ + /* Beware! FT_Done_GlyphSlot() changes the field `face->slot' */ while ( face->glyph ) FT_Done_GlyphSlot( face->glyph ); @@ -345,633 +1041,38 @@ driver ); face->size = 0; - /* finalize format-specific stuff */ - driver->interface.done_face( face ); - /* Now discard client data */ if ( face->generic.finalizer ) face->generic.finalizer( face ); - /* close the stream for this face */ - ft_done_stream( &face->stream ); + /* finalize format-specific stuff */ + if (clazz->done_face) + clazz->done_face(face); + + /* close the stream for this face if needed */ + if ( (face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM) == 0 ) + ft_done_stream( &face->stream ); /* get rid of it */ FREE( face ); } - /*************************************************************************/ - /* */ - /* */ - /* Destroy_Driver */ - /* */ - /* */ - /* Destroys a given driver object. This also destroys all child */ - /* faces. */ - /* */ - /* */ - /* driver :: A handle to the target driver object. */ - /* */ - /* */ - /* The driver _must_ be LOCKED! */ - /* */ - static - void Destroy_Driver( FT_Driver driver ) + static void Destroy_Driver( FT_Driver driver ) { - FT_Memory memory = driver->memory; - - - /* now, finalize all faces in the driver list */ FT_List_Finalize( &driver->faces_list, (FT_List_Destructor)destroy_face, - memory, + driver->root.memory, driver ); - /* finalize the driver object */ - if ( driver->interface.done_driver ) - driver->interface.done_driver( driver ); - - /* finalize client-data */ - if ( driver->generic.finalizer ) - driver->generic.finalizer( driver ); - - /* discard it */ - FREE( driver ); + /* see if we need to drop the driver's glyph loader */ + if (FT_DRIVER_USES_OUTLINES(driver)) + FT_GlyphLoader_Done( driver->glyph_loader ); + + } - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Raster */ - /* */ - /* */ - /* Returns the raster interface corresponding to a given glyph format */ - /* tag. */ - /* */ - /* */ - /* library :: A handle to the source library object. */ - /* */ - /* glyph_format :: The glyph format tag. */ - /* */ - /* */ - /* raster_funcs :: If this field is not 0, the raster's interface */ - /* functions are returned. */ - /* */ - /* */ - /* A pointer to the corresponding raster object. */ - /* */ - FT_EXPORT_FUNC( FT_Raster ) FT_Get_Raster( - FT_Library library, - FT_Glyph_Format glyph_format, - FT_Raster_Funcs* raster_funcs ) - { - FT_Int n; - - - if ( !library ) - return 0; - - for ( n = 0; n < FT_MAX_GLYPH_FORMATS; n++ ) - { - FT_Raster_Funcs* funcs = &library->raster_funcs[n]; - - - if ( funcs->glyph_format == glyph_format ) - { - if ( raster_funcs ) - *raster_funcs = *funcs; - return library->rasters[n]; - } - } - return 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_Raster */ - /* */ - /* */ - /* Registers a given raster to the library. */ - /* */ - /* */ - /* library :: A handle to a target library object. */ - /* */ - /* raster_funcs :: A pointer to the raster's interface functions. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function will do the following: */ - /* */ - /* - A new raster object is created through `raster_func.raster_new'. */ - /* If this fails, the function returns. */ - /* */ - /* - If a raster is already registered for the glyph format */ - /* specified in raster_funcs, it will be destroyed. */ - /* */ - /* - The new raster is registered for the glyph format. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Set_Raster( FT_Library library, - FT_Raster_Funcs* raster_funcs ) - { - FT_Glyph_Format glyph_format; - FT_Raster_Funcs* funcs; - FT_Raster raster; - FT_Error error; - FT_Int n, index; - - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - if ( !raster_funcs ) - return FT_Err_Invalid_Argument; - - glyph_format = raster_funcs->glyph_format; - - if ( glyph_format == ft_glyph_format_none ) - return FT_Err_Invalid_Argument; - - /* create a new raster object */ - error = raster_funcs->raster_new( library->memory, &raster ); - if ( error ) - goto Exit; - - raster_funcs->raster_reset( raster, - library->raster_pool, - library->raster_pool_size ); - - index = -1; - for ( n = 0; n < FT_MAX_GLYPH_FORMATS; n++ ) - { - FT_Raster_Funcs* funcs = library->raster_funcs + n; - - - /* record the first vacant entry in `index' */ - if ( index < 0 && funcs->glyph_format == ft_glyph_format_none ) - index = n; - - /* compare this entry's glyph format with the one we need */ - if ( funcs->glyph_format == glyph_format ) - { - /* A raster already exists for this glyph format. We will */ - /* destroy it before updating its entry in the table. */ - funcs->raster_done( library->rasters[n] ); - index = n; - break; - } - } - - if ( index < 0 ) - { - /* the table is full and has no vacant entries */ - error = FT_Err_Too_Many_Glyph_Formats; - goto Fail; - } - - funcs = library->raster_funcs + index; - *funcs = *raster_funcs; - library->rasters[index] = raster; - - Exit: - return error; - - Fail: - raster_funcs->raster_done( raster ); - goto Exit; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Unset_Raster */ - /* */ - /* */ - /* Removes a given raster from the library. */ - /* */ - /* */ - /* library :: A handle to a target library object. */ - /* */ - /* raster_funcs :: A pointer to the raster's interface functions. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Unset_Raster( - FT_Library library, - FT_Raster_Funcs* raster_funcs ) - { - FT_Glyph_Format glyph_format; - FT_Error error; - FT_Int n; - - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - error = FT_Err_Invalid_Argument; - - if ( !raster_funcs ) - goto Exit; - - glyph_format = raster_funcs->glyph_format; - - if ( glyph_format == ft_glyph_format_none ) - goto Exit; - - for ( n = 0; n < FT_MAX_GLYPH_FORMATS; n++ ) - { - FT_Raster_Funcs* funcs = library->raster_funcs + n; - - - if ( funcs->glyph_format == glyph_format ) - { - funcs->raster_done( library->rasters[n] ); - library->rasters[n] = 0; - library->raster_funcs[n].glyph_format = ft_glyph_format_none; - error = FT_Err_Ok; - break; - } - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_Raster_Mode */ - /* */ - /* */ - /* Sets a raster-specific mode. */ - /* */ - /* */ - /* library :: A handle to a target library object. */ - /* */ - /* */ - /* format :: The glyph format used to select the raster. */ - /* */ - /* mode :: The raster-specific mode descriptor. */ - /* */ - /* args :: The mode arguments. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Set_Raster_Mode( FT_Library library, - FT_Glyph_Format format, - unsigned long mode, - void* args ) - { - FT_Raster_Funcs funcs; - FT_Raster raster; - - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - raster = FT_Get_Raster( library, format, &funcs ); - if ( raster && args && funcs.raster_set_mode ) - return funcs.raster_set_mode( raster, mode, args ); - else - return FT_Err_Invalid_Argument; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_Debug_Hook */ - /* */ - /* */ - /* Sets a debug hook function for debugging the interpreter of a */ - /* font format. */ - /* */ - /* */ - /* library :: A handle to the library object. */ - /* */ - /* hook_index :: The index of the debug hook. You should use the */ - /* values defined in ftobjs.h, e.g. */ - /* FT_DEBUG_HOOK_TRUETYPE */ - /* */ - /* debug_hook :: The function used to debug the interpreter. */ - /* */ - /* */ - /* Currently, four debug hook slots are available, but only two (for */ - /* the TrueType and the Type 1 interpreter) are defined. */ - /* */ - FT_EXPORT_FUNC( void ) FT_Set_Debug_Hook( FT_Library library, - FT_UInt hook_index, - FT_DebugHook_Func debug_hook ) - { - if ( library && debug_hook && - hook_index < - ( sizeof ( library->debug_hooks ) / sizeof ( void* ) ) ) - library->debug_hooks[hook_index] = debug_hook; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_New_Library */ - /* */ - /* */ - /* This function is used to create a new FreeType library instance */ - /* from a given memory object. It is thus possible to use libraries */ - /* with distinct memory allocators within the same program. */ - /* */ - /* */ - /* memory :: A handle to the original memory object. */ - /* */ - /* */ - /* alibrary :: A pointer to handle of a new library object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_New_Library( FT_Memory memory, - FT_Library* alibrary ) - { - FT_Library library = 0; - FT_Error error; - - - if ( !memory ) - return FT_Err_Invalid_Argument; - - /* first of all, allocate the library object */ - if ( ALLOC( library, sizeof ( *library ) ) ) - return error; - - library->memory = memory; - - /* allocate the render pool */ - library->raster_pool_size = FT_RENDER_POOL_SIZE; - if ( ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) ) - goto Fail; - - /* now register the default raster for the `outline' glyph image */ - /* format for now, ignore the error... */ - error = FT_Set_Raster( library, &ft_default_raster ); - - /* That's ok now */ - *alibrary = library; - - return FT_Err_Ok; - - Fail: - FREE( library ); - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Done_Library */ - /* */ - /* */ - /* Discards a given library object. This closes all drivers and */ - /* discards all resource objects. */ - /* */ - /* */ - /* library :: A handle to the target library. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Done_Library( FT_Library library ) - { - FT_Memory memory; - FT_Int n; - - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - memory = library->memory; - - /* Discard client-data */ - if ( library->generic.finalizer ) - library->generic.finalizer( library ); - - /* Close all drivers in the library */ - for ( n = 0; n < library->num_drivers; n++ ) - { - FT_Driver driver = library->drivers[n]; - - - if ( driver ) - { - Destroy_Driver( driver ); - library->drivers[n] = 0; - } - } - - /* Destroy raster objects */ - FREE( library->raster_pool ); - library->raster_pool_size = 0; - - { - FT_Raster_Funcs* cur = library->raster_funcs; - FT_Raster_Funcs* limit = cur + FT_MAX_GLYPH_FORMATS; - FT_Raster* raster = library->rasters; - - for ( ; cur < limit; cur++, raster++ ) - { - if ( cur->glyph_format != ft_glyph_format_none ) - { - cur->raster_done( *raster ); - *raster = 0; - cur->glyph_format = ft_glyph_format_none; - } - } - } - - FREE( library ); - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Add_Driver */ - /* */ - /* */ - /* Registers a new driver in a given library object. This function */ - /* takes only a pointer to a driver interface; it uses it to create */ - /* the new driver, then sets up some important fields. */ - /* */ - /* */ - /* library :: A handle to the target library object. */ - /* */ - /* */ - /* driver_interface :: A pointer to a driver interface table. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function doesn't check whether the driver is already */ - /* installed! */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Add_Driver( - FT_Library library, - const FT_DriverInterface* driver_interface ) - { - FT_Error error; - FT_Driver driver; - FT_Memory memory; - - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - if ( !driver_interface ) - return FT_Err_Invalid_Argument; - - memory = library->memory; - error = FT_Err_Ok; - - if ( library->num_drivers >= FT_MAX_DRIVERS ) - error = FT_Err_Too_Many_Drivers; - else - { - if ( ALLOC( driver, driver_interface->driver_object_size ) ) - goto Exit; - - driver->library = library; - driver->memory = memory; - driver->interface = *driver_interface; - - if ( driver_interface->init_driver ) - { - error = driver_interface->init_driver( driver ); - if ( error ) - goto Fail; - } - - library->drivers[library->num_drivers++] = driver; - goto Exit; - - Fail: - FREE( driver ); - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Remove_Driver */ - /* */ - /* */ - /* Unregisters a given driver. This closes the driver, which in turn */ - /* destroys all faces, sizes, slots, etc. associated with it. */ - /* */ - /* This function also DESTROYS the driver object. */ - /* */ - /* */ - /* driver :: A handle to target driver object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Remove_Driver( FT_Driver driver ) - { - FT_Library library; - FT_Memory memory; - FT_Driver *cur, *last; - FT_Error error; - - - if ( !driver ) - return FT_Err_Invalid_Driver_Handle; - - library = driver->library; - memory = driver->memory; - - if ( !library || !memory ) - return FT_Err_Invalid_Driver_Handle; - - /* look-up driver entry in library table */ - error = FT_Err_Invalid_Driver_Handle; - cur = library->drivers; - last = cur + library->num_drivers - 1; - - for ( ; cur <= last; cur++ ) - { - if ( *cur == driver ) - { - /* destroy the driver object */ - Destroy_Driver( driver ); - - /* now move the last driver in the table to the vacant slot */ - if ( cur < last ) - { - *cur = *last; - *last = 0; - } - library->num_drivers--; - - /* exit loop */ - error = FT_Err_Ok; - break; - } - } - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Driver */ - /* */ - /* */ - /* Returns the handle of the driver responsible for a given format */ - /* (or service) according to its `name'. */ - /* */ - /* */ - /* library :: A handle to the library object. */ - /* driver_name :: The name of the driver to look up. */ - /* */ - /* */ - /* A handle to the driver object, 0 otherwise. */ - /* */ - FT_EXPORT_FUNC( FT_Driver ) FT_Get_Driver( FT_Library library, - char* driver_name ) - { - FT_Driver *cur, *limit; - - - if ( !library || !driver_name ) - return 0; - - cur = library->drivers; - limit = cur + library->num_drivers; - for ( ; cur < limit; cur++ ) - { - if ( strcmp( (*cur)->interface.driver_name, driver_name ) == 0 ) - return *cur; - } - return 0; - } - /*************************************************************************/ /* */ @@ -989,28 +1090,27 @@ FT_Parameter* params, FT_Face* aface ) { - FT_Memory memory; - FT_DriverInterface* interface; - FT_Face face = 0; - FT_Error error; + FT_Memory memory; + FT_Driver_Class* clazz; + FT_Face face = 0; + FT_Error error; - - interface = &driver->interface; - memory = driver->memory; + clazz = driver->clazz; + memory = driver->root.memory; /* allocate the face object, and perform basic initialization */ - if ( ALLOC( face, interface->face_object_size ) ) + if ( ALLOC( face, clazz->face_object_size ) ) goto Fail; face->driver = driver; face->memory = memory; face->stream = stream; - error = interface->init_face( stream, - face, - face_index, - num_params, - params ); + error = clazz->init_face( stream, + face, + face_index, + num_params, + params ); if ( error ) goto Fail; @@ -1019,7 +1119,7 @@ Fail: if ( error ) { - interface->done_face( face ); + clazz->done_face( face ); FREE( face ); *aface = 0; } @@ -1073,9 +1173,7 @@ { FT_Open_Args args; - /* test for valid `library' and `aface' delayed to FT_Open_Face() */ - if ( !pathname ) return FT_Err_Invalid_Argument; @@ -1134,9 +1232,7 @@ { FT_Open_Args args; - /* test for valid `library' and `face' delayed to FT_Open_Face() */ - if ( !file_base ) return FT_Err_Invalid_Argument; @@ -1211,8 +1307,7 @@ /* create input stream */ error = ft_new_input_stream( library, args, &stream ); - if ( error ) - goto Exit; + if ( error ) goto Exit; memory = library->memory; @@ -1220,14 +1315,14 @@ /* it. Otherwise, we'll scan the list of registered drivers. */ if ( args->flags & ft_open_driver && args->driver ) { - driver = args->driver; - /* not all drivers directly support face objects, so check... */ - if ( driver->interface.face_object_size ) + driver = FT_DRIVER(args->driver); + + /* not all modules are drivers, so check... */ + if ( FT_MODULE_IS_DRIVER(driver) ) { FT_Int num_params = 0; FT_Parameter* params = 0; - if ( args->flags & ft_open_params ) { num_params = args->num_params; @@ -1247,18 +1342,18 @@ else { /* check each font driver for an appropriate format */ - FT_Driver* cur = library->drivers; - FT_Driver* limit = cur + library->num_drivers; + FT_Module* cur = library->modules; + FT_Module* limit = cur + library->num_modules; for ( ; cur < limit; cur++ ) { - driver = *cur; - /* not all drivers directly support face objects, so check... */ - if ( driver->interface.face_object_size ) + /* not all modules are font drivers, so check... */ + if ( FT_MODULE_IS_DRIVER(cur[0]) ) { FT_Int num_params = 0; FT_Parameter* params = 0; + driver = FT_DRIVER(cur[0]); if ( args->flags & ft_open_params ) { @@ -1284,6 +1379,10 @@ Success: FT_TRACE4(( "FT_New_Face: New face object, adding to list\n" )); + /* set the EXTERNAL_STREAM bit for FT_Done_Face */ + if ( args->flags & ft_open_stream && args->stream ) + face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM; + /* add the face object to its driver's list */ if ( ALLOC( node, sizeof ( *node ) ) ) goto Fail; @@ -1300,8 +1399,9 @@ FT_TRACE4(( "FT_Open_Face: Creating glyph slot\n" )); error = FT_New_GlyphSlot( face, &slot ); - if ( error ) - goto Fail; + if ( error ) goto Fail; + + face->glyph = slot; } /* finally, allocate a size object for the face */ @@ -1311,8 +1411,9 @@ FT_TRACE4(( "FT_Open_Face: Creating size object\n" )); error = FT_New_Size( face, &size ); - if ( error ) - goto Fail; + if ( error ) goto Fail; + + face->size = size; } /* initialize transformation for convenience functions */ @@ -1419,8 +1520,7 @@ FT_Error error; FT_Driver driver; - FTDriver_getInterface get_interface; - + FT_Driver_Class* clazz; /* test for valid `parameters' delayed to ft_new_input_stream() */ @@ -1431,7 +1531,7 @@ if ( !driver ) return FT_Err_Invalid_Driver_Handle; - error = ft_new_input_stream( driver->library, parameters, &stream ); + error = ft_new_input_stream( driver->root.library, parameters, &stream ); if ( error ) goto Exit; @@ -1439,20 +1539,13 @@ /* `attach_file' interface */ error = FT_Err_Unimplemented_Feature; - - get_interface = driver->interface.get_interface; - if ( get_interface ) - { - FT_Attach_Reader reader; - - - reader = (FT_Attach_Reader)(get_interface( driver, "attach_file" )); - if ( reader ) - error = reader( face, stream ); - } + clazz = driver->clazz; + if (clazz->attach_file) + error = clazz->attach_file( face, stream ); /* close the attached stream */ - ft_done_stream( &stream ); + if ( !parameters->stream || (parameters->flags & ft_open_stream) ) + ft_done_stream( &stream ); Exit: return error; @@ -1476,38 +1569,30 @@ /* */ FT_EXPORT_FUNC( FT_Error ) FT_Done_Face( FT_Face face ) { - FT_Error error; - FT_Driver driver; - FT_Memory memory; - FT_DriverInterface* interface; - FT_ListNode node; + FT_Error error; + FT_Driver driver; + FT_Memory memory; + FT_ListNode node; - - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - driver = face->driver; - if ( !driver ) - return FT_Err_Invalid_Driver_Handle; - - interface = &driver->interface; - memory = driver->memory; - - /* find face in driver's list */ - node = FT_List_Find( &driver->faces_list, face ); - if ( node ) + error = FT_Err_Invalid_Face_Handle; + if ( face && face->driver ) { - /* remove face object from the driver's list */ - FT_List_Remove( &driver->faces_list, node ); - FREE( node ); - - /* now destroy the object proper */ - destroy_face( memory, face, driver ); - error = FT_Err_Ok; + driver = face->driver; + memory = driver->root.memory; + + /* find face in driver's list */ + node = FT_List_Find( &driver->faces_list, face ); + if ( node ) + { + /* remove face object from the driver's list */ + FT_List_Remove( &driver->faces_list, node ); + FREE( node ); + + /* now destroy the object proper */ + destroy_face( memory, face, driver ); + error = FT_Err_Ok; + } } - else - error = FT_Err_Invalid_Face_Handle; - return error; } @@ -1532,38 +1617,32 @@ FT_EXPORT_FUNC( FT_Error ) FT_New_Size( FT_Face face, FT_Size* asize ) { - FT_Error error; - FT_Memory memory; - FT_Driver driver; - FT_DriverInterface* interface; + FT_Error error; + FT_Memory memory; + FT_Driver driver; + FT_Driver_Class* clazz; - FT_Size size = 0; - FT_ListNode node = 0; - - - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - if ( !asize ) - return FT_Err_Invalid_Argument; + FT_Size size = 0; + FT_ListNode node = 0; *asize = 0; - driver = face->driver; - if ( !driver ) - return FT_Err_Invalid_Driver_Handle; + if ( !face || !asize || !face->driver ) + return FT_Err_Invalid_Handle; - interface = &driver->interface; - memory = face->memory; + driver = face->driver; + clazz = driver->clazz; + memory = face->memory; /* Allocate new size object and perform basic initialisation */ - if ( ALLOC( size, interface->size_object_size ) || - ALLOC( node, sizeof ( FT_ListNodeRec ) ) ) + if ( ALLOC( size, clazz->size_object_size ) || + ALLOC( node, sizeof ( FT_ListNodeRec ) ) ) goto Exit; size->face = face; - error = interface->init_size( size ); + if (clazz->init_size) + error = clazz->init_size( size ); /* in case of success, add to the face's list */ if ( !error ) @@ -1571,9 +1650,6 @@ *asize = size; node->data = size; FT_List_Add( &face->sizes_list, node ); - - /* record as current size for the face */ - face->size = size; } Exit: @@ -1621,7 +1697,7 @@ if ( !driver ) return FT_Err_Invalid_Driver_Handle; - memory = driver->memory; + memory = driver->root.memory; error = FT_Err_Ok; node = FT_List_Find( &face->sizes_list, size ); @@ -1680,45 +1756,62 @@ /* When dealing with fixed-size faces (i.e., non-scalable formats), */ /* use the function FT_Set_Pixel_Sizes(). */ /* */ + + static void ft_recompute_scaled_metrics( FT_Face face, + FT_Size_Metrics* metrics ) + { + /* Compute root ascender, descender, test height, and max_advance */ + metrics->ascender = ( FT_MulFix( face->ascender, + metrics->y_scale ) + 32 ) & -64; + + metrics->descender = ( FT_MulFix( face->descender, + metrics->y_scale ) + 32 ) & -64; + + metrics->height = ( FT_MulFix( face->height, + metrics->y_scale ) + 32 ) & -64; + + metrics->max_advance = ( FT_MulFix( face->max_advance_width, + metrics->x_scale ) + 32 ) & -64; + } + + + + FT_EXPORT_FUNC( FT_Error ) FT_Set_Char_Size( FT_Face face, FT_F26Dot6 char_width, FT_F26Dot6 char_height, FT_UInt horz_resolution, FT_UInt vert_resolution ) { - FT_Error error; - FT_Driver driver; - FT_Memory memory; - FT_DriverInterface* interface; - FT_Size_Metrics* metrics; - FT_Long dim_x, dim_y; + FT_Error error = FT_Err_Ok; + FT_Driver driver; + FT_Memory memory; + FT_Driver_Class* clazz; + FT_Size_Metrics* metrics; + FT_Long dim_x, dim_y; - if ( !face ) + if ( !face || !face->size || !face->driver ) return FT_Err_Invalid_Face_Handle; - if ( !face->size ) - return FT_Err_Invalid_Size_Handle; - - driver = face->driver; - if ( !driver ) - return FT_Err_Invalid_Driver_Handle; - + driver = face->driver; metrics = &face->size->metrics; if ( !char_width ) char_width = char_height; + else if ( !char_height ) char_height = char_width; if ( !horz_resolution ) horz_resolution = 72; + if ( !vert_resolution ) vert_resolution = 72; - driver = face->driver; - interface = &driver->interface; - memory = driver->memory; + driver = face->driver; + clazz = driver->clazz; + memory = driver->root.memory; /* default processing -- this can be overridden by the driver */ if ( char_width < 1 * 64 ) char_width = 1 * 64; @@ -1740,11 +1833,14 @@ metrics->y_scale = FT_DivFix( dim_y, face->units_per_EM ); } - error = interface->set_char_sizes( face->size, - char_width, - char_height, - horz_resolution, - vert_resolution ); + ft_recompute_scaled_metrics( face, metrics ); + + if (clazz->set_char_sizes) + error = clazz->set_char_sizes( face->size, + char_width, + char_height, + horz_resolution, + vert_resolution ); return error; } @@ -1776,29 +1872,24 @@ FT_UInt pixel_width, FT_UInt pixel_height ) { - FT_Error error; - FT_Driver driver; - FT_Memory memory; - FT_DriverInterface* interface; - FT_Size_Metrics* metrics = &face->size->metrics; + FT_Error error = FT_Err_Ok; + FT_Driver driver; + FT_Memory memory; + FT_Driver_Class* clazz; + FT_Size_Metrics* metrics = &face->size->metrics; - if ( !face ) + if ( !face || !face->size || !face->driver ) return FT_Err_Invalid_Face_Handle; - if ( !face->size ) - return FT_Err_Invalid_Size_Handle; - driver = face->driver; - if ( !driver ) - return FT_Err_Invalid_Driver_Handle; - - interface = &driver->interface; - memory = driver->memory; + clazz = driver->clazz; + memory = driver->root.memory; /* default processing -- this can be overridden by the driver */ if ( pixel_width == 0 ) pixel_width = pixel_height; + else if ( pixel_height == 0 ) pixel_height = pixel_width; @@ -1817,242 +1908,12 @@ face->units_per_EM ); } - error = interface->set_pixel_sizes( face->size, - pixel_width, - pixel_height ); - return error; - } + ft_recompute_scaled_metrics( face, metrics ); - - /*************************************************************************/ - /* */ - /* */ - /* FT_New_GlyphSlot */ - /* */ - /* */ - /* It is sometimes useful to have more than one glyph slot for a */ - /* given face object. This function is used to create additional */ - /* slots. All of them are automatically discarded when the face is */ - /* destroyed. */ - /* */ - /* */ - /* face :: A handle to a parent face object. */ - /* */ - /* */ - /* aslot :: A handle to a new glyph slot object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_New_GlyphSlot( FT_Face face, - FT_GlyphSlot* aslot ) - { - FT_Error error; - FT_Driver driver; - FT_DriverInterface* interface; - FT_Memory memory; - FT_GlyphSlot slot; - - - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - if ( !aslot ) - return FT_Err_Invalid_Argument; - - *aslot = 0; - - driver = face->driver; - if ( !driver ) - return FT_Err_Invalid_Driver_Handle; - - interface = &driver->interface; - memory = driver->memory; - - FT_TRACE4(( "FT_New_GlyphSlot: Creating new slot object\n" )); - if ( ALLOC( slot, interface->slot_object_size ) ) - goto Exit; - - slot->face = face; - - slot->max_subglyphs = 0; - slot->num_subglyphs = 0; - slot->subglyphs = 0; - - error = interface->init_glyph_slot( slot ); - if ( !error ) - { - /* in case of success, add slot to the face's list */ - slot->next = face->glyph; - face->glyph = slot; - *aslot = slot; - } - - if ( error ) - FREE( slot ); - - Exit: - FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error )); - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Done_GlyphSlot */ - /* */ - /* */ - /* Destroys a given glyph slot. Remember however that all slots are */ - /* automatically destroyed with its parent. Using this function is */ - /* not always mandatory. */ - /* */ - /* */ - /* slot :: A handle to a target glyph slot. */ - /* */ - FT_EXPORT_FUNC( void ) FT_Done_GlyphSlot( FT_GlyphSlot slot ) - { - if ( slot ) - { - FT_Driver driver = slot->face->driver; - FT_Memory memory = driver->memory; - FT_GlyphSlot* parent; - FT_GlyphSlot cur; - - - /* Remove slot from its parent face's list */ - parent = &slot->face->glyph; - cur = *parent; - while ( cur ) - { - if ( cur == slot ) - { - *parent = cur->next; - break; - } - cur = cur->next; - } - - driver->interface.done_glyph_slot( slot ); - FREE( slot ); - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Load_Glyph */ - /* */ - /* */ - /* A function used to load a single glyph within a given face. */ - /* */ - /* */ - /* face :: A handle to a target face object where the glyph */ - /* will be loaded. */ - /* */ - /* glyph_index :: The index of the glyph in the font file. */ - /* */ - /* load_flags :: A flag indicating what to load for this glyph. The */ - /* FT_LOAD_XXX constants can be used to control the */ - /* glyph loading process (e.g., whether the outline */ - /* should be scaled, whether to load bitmaps or not, */ - /* whether to hint the outline, etc). */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Load_Glyph( FT_Face face, - FT_UInt glyph_index, - FT_Int load_flags ) - { - FT_Error error; - FT_Driver driver; - - - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - if ( !face->size ) - return FT_Err_Invalid_Size_Handle; - - if ( !face->glyph ) - return FT_Err_Invalid_Slot_Handle; - - if ( glyph_index >= face->num_glyphs ) - return FT_Err_Invalid_Argument; - - driver = face->driver; - - /* when the flag NO_RECURSE is set, we disable hinting and scaling */ - if ( load_flags & FT_LOAD_NO_RECURSE ) - load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; - - error = driver->interface.load_glyph( face->glyph, - face->size, - glyph_index, - load_flags ); - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Load_Char */ - /* */ - /* */ - /* A function used to load a single character within a given face */ - /* and the selected charmap (to be done with the FT_Select_Charmap() */ - /* function). */ - /* */ - /* */ - /* face :: A handle to a target face object where the */ - /* character will be loaded. */ - /* */ - /* char_code :: The character code 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). */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Load_Char( FT_Face face, - FT_ULong char_code, - FT_Int load_flags ) - { - FT_Error error; - FT_Driver driver; - FT_UInt glyph_index; - - - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - if ( !face->size ) - return FT_Err_Invalid_Size_Handle; - - if ( !face->glyph ) - return FT_Err_Invalid_Slot_Handle; - - if ( !face->charmap ) - return FT_Err_Invalid_CharMap_Handle; - - driver = face->driver; - glyph_index = FT_Get_Char_Index( face, char_code ); - - if ( glyph_index == 0 ) - error = FT_Err_Invalid_Character_Code; - else - error = driver->interface.load_glyph( face->glyph, - face->size, - glyph_index, - load_flags ); + if (clazz->set_pixel_sizes) + error = clazz->set_pixel_sizes( face->size, + pixel_width, + pixel_height ); return error; } @@ -2103,11 +1964,11 @@ return FT_Err_Invalid_Argument; driver = face->driver; - memory = driver->memory; + memory = driver->root.memory; - if ( driver->interface.get_kerning ) + if ( driver->clazz->get_kerning ) { - error = driver->interface.get_kerning( face, + error = driver->clazz->get_kerning( face, left_glyph, right_glyph, kerning ); @@ -2247,7 +2108,7 @@ if ( face && face->charmap ) { driver = face->driver; - result = driver->interface.get_char_index( face->charmap, charcode ); + result = driver->clazz->get_char_index( face->charmap, charcode ); } return result; } @@ -2291,8 +2152,8 @@ goto Exit; driver = face->driver; - func = (FT_Get_Sfnt_Table_Func)driver->interface.get_interface( - driver, "get_sfnt" ); + func = (FT_Get_Sfnt_Table_Func)driver->root.clazz->get_interface( + FT_MODULE(driver), "get_sfnt" ); if ( func ) table = func( face, tag ); @@ -2301,6 +2162,764 @@ } + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** R E N D E R E R S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* lookup a renderer by glyph format in the library's list */ + static FT_Renderer ft_lookup_renderer( FT_Library library, + FT_Glyph_Format format, + FT_ListNode *node ) + { + FT_ListNode cur = library->renderers.head; + FT_Renderer result = 0; + + if (node) + *node = 0; + + while (cur) + { + FT_Renderer renderer = FT_RENDERER(cur->data); + + if (renderer->glyph_format == format) + { + if (node) + *node = cur; + + result = renderer; + break; + } + + } + return result; + } + + + static FT_Renderer ft_lookup_glyph_renderer( FT_GlyphSlot slot ) + { + FT_Face face = slot->face; + FT_Library library = FT_FACE_LIBRARY(face); + FT_Renderer result = library->cur_renderer; + + if (!result || result->glyph_format != slot->format) + result = ft_lookup_renderer( library, slot->format, 0 ); + + return result; + } + + + static void ft_set_current_renderer( FT_Library library ) + { + FT_Renderer renderer; + + renderer = ft_lookup_renderer( library, ft_glyph_format_outline, 0 ); + library->cur_renderer = renderer; + } + + + static FT_Error ft_add_renderer( FT_Module module ) + { + FT_Library library = module->library; + FT_Memory memory = library->memory; + FT_Error error; + FT_ListNode node; + + if (ALLOC(node,sizeof(*node))) + goto Exit; + + { + FT_Renderer render = FT_RENDERER(module); + FT_Renderer_Class* clazz = (FT_Renderer_Class*)module->clazz; + + render->clazz = clazz; + render->glyph_format = clazz->glyph_format; + + /* allocate raster object if needed */ + if ( clazz->glyph_format == ft_glyph_format_outline && + clazz->raster_class->raster_new ) + { + error = clazz->raster_class->raster_new( memory, &render->raster ); + if (error) goto Fail; + + render->raster_render = clazz->raster_class->raster_render; + render->render = clazz->render_glyph; + } + + /* add to list */ + node->data = module; + FT_List_Add( &library->renderers, node ); + + ft_set_current_renderer( library ); + } + + Fail: + if (error) + FREE(node); + + Exit: + return error; + } + + + static void ft_remove_renderer( FT_Module module ) + { + FT_Library library = module->library; + FT_Memory memory = library->memory; + FT_ListNode node; + + node = FT_List_Find( &library->renderers, module ); + if (node) + { + FT_Renderer render = FT_RENDERER(module); + + /* release raster object, if any */ + if (render->raster) + render->clazz->raster_class->raster_done( render->raster ); + + /* remove from list */ + FT_List_Remove( &library->renderers, node ); + FREE( node ); + + ft_set_current_renderer( library ); + } + } + + + + /************************************************************************* + * + * + * FT_Get_Renderer + * + * + * retrieves the current renderer for a given glyph format. + * + * + * library :: handle to library object + * format :: glyph format + * + * + * renderer handle. 0 if none found. + * + * + * An error will be returned if a module already exists by that + * name, or if the module requires a version of freetype that is + * too great + * + * To add a new renderer, simply use FT_Add_Module. To retrieve + * a renderer by its name, use FT_Get_Module + * + *************************************************************************/ + + FT_EXPORT_FUNC(FT_Renderer) FT_Get_Renderer( FT_Library library, + FT_Glyph_Format format ) + { + return ft_lookup_renderer( library, format, 0 ); + } + + + /************************************************************************* + * + * + * FT_Set_Renderer + * + * + * Sets the current renderer to use, and set additional mode + * + * + * library :: handle to library object + * renderer :: handle to renderer object + * num_params :: number of additional parameters + * params :: additional parameters + * + * + * Error code. 0 means success. + * + * + * in case of success, the renderer will be used to convert glyph + * images in the renderer's known format into bitmaps. + * + * This doesn't change the current renderer for other formats.. + * + *************************************************************************/ + + FT_EXPORT_DEF(FT_Error) FT_Set_Renderer( FT_Library library, + FT_Renderer renderer, + FT_UInt num_params, + FT_Parameter* parameters ) + { + FT_ListNode node; + FT_Error error = FT_Err_Ok; + + node = FT_List_Find( &library->renderers, renderer ); + if (!node) + { + error = FT_Err_Invalid_Argument; + goto Exit; + } + + FT_List_Up( &library->renderers, node ); + + if (renderer->glyph_format == ft_glyph_format_outline ) + library->cur_renderer = renderer; + + if (num_params > 0) + { + FTRenderer_setMode set_mode = renderer->clazz->set_mode; + + for ( ; num_params > 0; num_params-- ) + { + error = set_mode( renderer, parameters->tag, parameters->data ); + if (error) + break; + } + } + + Exit: + return error; + } + + + + /************************************************************************* + * + * + * FT_Render_Glyph + * + * + * Converts a given glyph image to a bitmap. It does so by inspecting + * the glyph image format, find the relevant renderer, and invoke it + * + * + * slot :: handle to the glyph slot containing the image to + * convert + * + * render_mode :: a set of bit flags indicating which kind of bitmap + * to render. For now, only 'ft_render_mode_anti_alias' + * is supported by the available renderers, but others + * could appear later (e.g. LCD or TV optimised) + * + * + * Error code. 0 means success. + * + * + * in case of success, the renderer will be used to convert glyph + * images in the renderer's known format into bitmaps. + * + * This doesn't change the current renderer for other formats.. + * + * The slot's native image should be considered lost after the + * conversion.. + * + *************************************************************************/ + + FT_EXPORT_FUNC(FT_Error) FT_Render_Glyph( FT_GlyphSlot slot, + FT_UInt render_mode ) + { + FT_Error error = FT_Err_Ok; + FT_Renderer renderer; + + if (slot) + { + FT_Face face = slot->face; + FT_Library library = FT_FACE_LIBRARY(face); + + /* if it's already a bitmap, no need to do anything */ + switch (slot->format) + { + case ft_glyph_format_bitmap: /* already a bitmap, don't do anything */ + break; + + default: + { + /* small shortcut for the very common case */ + if (slot->format == ft_glyph_format_outline) + renderer = library->cur_renderer; + else + renderer = ft_lookup_renderer( library, slot->format, 0 ); + + error = FT_Err_Unimplemented_Feature; + if (renderer) + error = renderer->render( renderer, slot, render_mode ); + } + } + } + else + error = FT_Err_Invalid_Argument; + + return error; + } + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** M O D U L E S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* */ + /* Destroy_Module */ + /* */ + /* */ + /* Destroys a given module object. For drivers, this also destroys */ + /* all child faces.. */ + /* */ + /* */ + /* module :: A handle to the target driver object. */ + /* */ + /* */ + /* The driver _must_ be LOCKED! */ + /* */ + static + void Destroy_Module( FT_Module module ) + { + FT_Memory memory = module->memory; + FT_Module_Class* clazz = module->clazz; + + /* finalize client-data - before anything else */ + if ( module->generic.finalizer ) + module->generic.finalizer( module ); + + /* if the module is a renderer */ + if (FT_MODULE_IS_RENDERER(module)) + ft_remove_renderer(module); + + /* if the module is a font driver, add some steps */ + if (FT_MODULE_IS_DRIVER(module)) + Destroy_Driver( FT_DRIVER(module) ); + + /* finalize the module object */ + if (clazz->module_done) + clazz->module_done(module); + + /* discard it */ + FREE( module ); + } + + /************************************************************************* + * + * + * FT_Add_Module + * + * + * Add a new module to a given library instance. + * + * + * library :: handle to library object + * clazz :: pointer to class descriptor for the module + * + * + * Error code. 0 means success + * + * + * An error will be returned if a module already exists by that + * name, or if the module requires a version of freetype that is + * too great + * + *************************************************************************/ + + FT_EXPORT_FUNC(FT_Error) FT_Add_Module( FT_Library library, + const FT_Module_Class* clazz ) + { + FT_Error error; + FT_Memory memory; + FT_Module module; + FT_UInt nn; + + #define FREETYPE_VER_FIXED (((FT_Long)FREETYPE_MAJOR << 16) | FREETYPE_MINOR) + + if (!library || !clazz) + return FT_Err_Invalid_Argument; + + /* check freetype version */ + if ( clazz->module_requires > FREETYPE_VER_FIXED ) + return FT_Err_Invalid_Version; + + /* look for a module with the same name in the library's table */ + for ( nn = 0; nn < library->num_modules; nn++ ) + { + module = library->modules[nn]; + if ( strcmp( module->clazz->module_name, clazz->module_name ) == 0 ) + { + /* this installed module has the same name, compare their versions */ + if ( clazz->module_version <= module->clazz->module_version ) + return FT_Err_Lower_Module_Version; + + /* remove the module from our list, then exit the loop to replace */ + /* it by our new version.. */ + FT_Remove_Module( library, module ); + break; + } + } + + memory = library->memory; + error = FT_Err_Ok; + + if ( library->num_modules >= FT_MAX_MODULES ) + { + error = FT_Err_Too_Many_Drivers; + goto Exit; + } + + /* allocate module object */ + if (ALLOC(module,clazz->module_size)) + goto Exit; + + /* base initialisation */ + module->library = library; + module->memory = memory; + module->clazz = (FT_Module_Class*)clazz; + + /* if the module is a renderer - this must be performed before */ + /* the normal module initialisation.. */ + if (FT_MODULE_IS_RENDERER(module)) + { + /* add to the renderers list */ + error = ft_add_renderer(module); + if (error) goto Fail; + } + + /* if the module is a font driver */ + if (FT_MODULE_IS_DRIVER(module)) + { + /* allocate glyph loader if needed */ + FT_Driver driver = FT_DRIVER(module); + + driver->clazz = (FT_Driver_Class*)module->clazz; + if (FT_DRIVER_USES_OUTLINES(driver)) + { + error = FT_GlyphLoader_New( memory, &driver->glyph_loader ); + if (error) goto Fail; + } + } + + if (clazz->module_init) + { + error = clazz->module_init(module); + if (error) goto Fail; + } + + /* add module to the library's table */ + library->modules[ library->num_modules++ ] = module; + + + Exit: + return error; + + Fail: + if (FT_MODULE_IS_DRIVER(module)) + { + FT_Driver driver = FT_DRIVER(module); + + if (FT_DRIVER_USES_OUTLINES(driver)) + FT_GlyphLoader_Done( driver->glyph_loader ); + } + + if (FT_MODULE_IS_RENDERER(module)) + { + FT_Renderer renderer = FT_RENDERER(module); + if (renderer->raster) + renderer->clazz->raster_class->raster_done( renderer->raster ); + } + FREE(module); + goto Exit; + } + + /************************************************************************* + * + * + * FT_Get_Module + * + * + * Find a module by its name. + * + * + * library :: handle to library object + * module_name :: the module's ASCII name. + * + * + * Module handle, 0 if none was found. + * + * + * You'd better be familiar with FreeType internals to know which + * module to look for :-) + * + *************************************************************************/ + + FT_EXPORT_FUNC(FT_Module) FT_Get_Module( FT_Library library, + const char* module_name ) + { + FT_Module result = 0; + FT_Module* cur = library->modules; + FT_Module* limit = cur + library->num_modules; + + for ( ; cur < limit; cur++ ) + if ( strcmp( cur[0]->clazz->module_name, module_name ) == 0 ) + { + result = cur[0]; + break; + } + + return result; + } + + /************************************************************************* + * + * + * FT_Get_Module_Interface + * + * + * Find a module and returns it's specific interface as a void* + * + * + * library :: handle to library object + * module_name :: the module's ASCII name. + * + * + * Module specific interface, if any + * + * + * You'd better be familiar with FreeType internals to know which + * module to look for, and what it's interface is :-) + * + *************************************************************************/ + + FT_EXPORT_FUNC(const void*) FT_Get_Module_Interface( FT_Library library, + const char* mod_name ) + { + FT_Module module; + + module = FT_Get_Module( library, mod_name ); + return module ? module->clazz->module_interface : 0; + } + + + /************************************************************************* + * + * + * FT_Remove_Module + * + * + * Removes a given module from a library instance. + * + * + * library :: handle to library object + * module :: handle to module object + * + * + * Error code (module not listed) + * + * + * The module object is destroyed by the function in case of success + * + *************************************************************************/ + + FT_EXPORT_FUNC(FT_Error) FT_Remove_Module( FT_Library library, + FT_Module module ) + { + /* try to find the module from the table, then remove it from there */ + if (library && module) + { + FT_Module* cur = library->modules; + FT_Module* limit = cur + library->num_modules; + + for ( ; cur < limit; cur++ ) + { + if (cur[0] == module) + { + /* remove it from the table */ + library->num_modules--; + limit--; + while (cur < limit) + { + cur[0] = cur[1]; + cur++; + } + limit[0] = 0; + + /* destroy the module */ + Destroy_Module(module); + + return FT_Err_Ok; + } + } + } + return FT_Err_Invalid_Handle; + } + + + + + + + + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** L I B R A R Y ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* */ + /* FT_New_Library */ + /* */ + /* */ + /* This function is used to create a new FreeType library instance */ + /* from a given memory object. It is thus possible to use libraries */ + /* with distinct memory allocators within the same program. */ + /* */ + /* */ + /* memory :: A handle to the original memory object. */ + /* */ + /* */ + /* alibrary :: A pointer to handle of a new library object. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT_FUNC( FT_Error ) FT_New_Library( FT_Memory memory, + FT_Library* alibrary ) + { + FT_Library library = 0; + FT_Error error; + + + if ( !memory ) + return FT_Err_Invalid_Argument; + + /* first of all, allocate the library object */ + if ( ALLOC( library, sizeof ( *library ) ) ) + return error; + + library->memory = memory; + + /* allocate the render pool */ + library->raster_pool_size = FT_RENDER_POOL_SIZE; + if ( ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) ) + goto Fail; + + /* That's ok now */ + *alibrary = library; + + return FT_Err_Ok; + + Fail: + FREE( library ); + return error; + } + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Done_Library */ + /* */ + /* */ + /* Discards a given library object. This closes all drivers and */ + /* discards all resource objects. */ + /* */ + /* */ + /* library :: A handle to the target library. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT_FUNC( FT_Error ) FT_Done_Library( FT_Library library ) + { + FT_Memory memory; + FT_Int n; + + + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + memory = library->memory; + + /* Discard client-data */ + if ( library->generic.finalizer ) + library->generic.finalizer( library ); + + /* Close all modules in the library */ + for ( n = 0; n < library->num_modules; n++ ) + { + FT_Module module = library->modules[n]; + + if ( module ) + { + Destroy_Module( module ); + library->modules[n] = 0; + } + } + + /* Destroy raster objects */ + FREE( library->raster_pool ); + library->raster_pool_size = 0; + + FREE( library ); + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Set_Debug_Hook */ + /* */ + /* */ + /* Sets a debug hook function for debugging the interpreter of a */ + /* font format. */ + /* */ + /* */ + /* library :: A handle to the library object. */ + /* */ + /* hook_index :: The index of the debug hook. You should use the */ + /* values defined in ftobjs.h, e.g. */ + /* FT_DEBUG_HOOK_TRUETYPE */ + /* */ + /* debug_hook :: The function used to debug the interpreter. */ + /* */ + /* */ + /* Currently, four debug hook slots are available, but only two (for */ + /* the TrueType and the Type 1 interpreter) are defined. */ + /* */ + FT_EXPORT_FUNC( void ) FT_Set_Debug_Hook( FT_Library library, + FT_UInt hook_index, + FT_DebugHook_Func debug_hook ) + { + if ( library && debug_hook && + hook_index < + ( sizeof ( library->debug_hooks ) / sizeof ( void* ) ) ) + library->debug_hooks[hook_index] = debug_hook; + } + + + + + /*************************************************************************/ /* */ /* */ diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c index fb84cb7d9..8c6afc06e 100644 --- a/src/base/ftoutln.c +++ b/src/base/ftoutln.c @@ -566,70 +566,6 @@ } - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Get_Bitmap */ - /* */ - /* */ - /* Renders an outline within a bitmap. The outline's image is simply */ - /* OR-ed to the target bitmap. */ - /* */ - /* */ - /* library :: A handle to a FreeType library object. */ - /* */ - /* outline :: A pointer to the source outline descriptor. */ - /* */ - /* map :: A pointer to the target bitmap descriptor. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* YES. Rendering is synchronized, so that concurrent calls to the */ - /* scan-line converter will be serialized. */ - /* */ - /* */ - /* This function does NOT CREATE the bitmap, it only renders an */ - /* outline image within the one you pass to it! */ - /* */ - /* It will use the raster correponding to the default glyph format. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Outline_Get_Bitmap( FT_Library library, - FT_Outline* outline, - FT_Bitmap* bitmap ) - { - FT_Error error; - FT_Raster raster; - FT_Raster_Funcs funcs; - FT_Raster_Params params; - - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - if ( !outline || !bitmap ) - return FT_Err_Invalid_Argument; - - error = FT_Err_Invalid_Glyph_Format; - raster = FT_Get_Raster( library, ft_glyph_format_outline, &funcs ); - if ( !raster ) - goto Exit; - - params.target = bitmap; - params.source = outline; - params.flags = 0; - - if ( bitmap->pixel_mode == ft_pixel_mode_grays ) - params.flags |= ft_raster_flag_aa; - - error = funcs.raster_render( raster, ¶ms ); - - Exit: - return error; - } - - /*************************************************************************/ /* */ /* */ @@ -667,30 +603,129 @@ FT_Outline* outline, FT_Raster_Params* params ) { - FT_Error error; - FT_Raster raster; - FT_Raster_Funcs funcs; - + FT_Error error; + FT_Renderer renderer; if ( !library ) - return FT_Err_Invalid_Library_Handle; + { + error = FT_Err_Invalid_Library_Handle; + goto Exit; + } if ( !outline || !params ) - return FT_Err_Invalid_Argument; - - error = FT_Err_Invalid_Glyph_Format; - raster = FT_Get_Raster( library, ft_glyph_format_outline, &funcs ); - if ( !raster ) + { + error = FT_Err_Invalid_Argument; goto Exit; + } + + /* retrieve the current outline renderer */ + renderer = library->cur_renderer; + if (!renderer) + { + /* XXXX: should use another error code */ + error = FT_Err_Invalid_Argument; + goto Exit; + } params->source = (void*)outline; - error = funcs.raster_render( raster, params ); + + error = renderer->raster_render( renderer->raster, params ); Exit: return error; } + /*************************************************************************/ + /* */ + /* */ + /* FT_Outline_Get_Bitmap */ + /* */ + /* */ + /* Renders an outline within a bitmap. The outline's image is simply */ + /* OR-ed to the target bitmap. */ + /* */ + /* */ + /* library :: A handle to a FreeType library object. */ + /* */ + /* outline :: A pointer to the source outline descriptor. */ + /* */ + /* map :: A pointer to the target bitmap descriptor. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + /* */ + /* YES. Rendering is synchronized, so that concurrent calls to the */ + /* scan-line converter will be serialized. */ + /* */ + /* */ + /* This function does NOT CREATE the bitmap, it only renders an */ + /* outline image within the one you pass to it! */ + /* */ + /* It will use the raster correponding to the default glyph format. */ + /* */ + FT_EXPORT_FUNC( FT_Error ) FT_Outline_Get_Bitmap( FT_Library library, + FT_Outline* outline, + FT_Bitmap* bitmap ) + { + FT_Raster_Params params; + + if (!bitmap) + return FT_Err_Invalid_Argument; + + /* other checks are delayed to FT_Outline_Render */ + + params.target = bitmap; + params.flags = 0; + + if ( bitmap->pixel_mode == ft_pixel_mode_grays ) + params.flags |= ft_raster_flag_aa; + + return FT_Outline_Render( library, outline, ¶ms ); + } + + + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Vector_Transform */ + /* */ + /* */ + /* Transforms a single vector through a 2x2 matrix. */ + /* */ + /* */ + /* vector :: The target vector to transform. */ + /* */ + /* */ + /* matrix :: A pointer to the source 2x2 matrix. */ + /* */ + /* */ + /* Yes. */ + /* */ + /* */ + /* The result is undefined if either `vector' or `matrix' is invalid. */ + /* */ + FT_EXPORT_FUNC( void ) FT_Vector_Transform( FT_Vector* vector, + FT_Matrix* matrix ) + { + FT_Pos xz, yz; + + xz = FT_MulFix( vector->x, matrix->xx ) + + FT_MulFix( vector->y, matrix->xy ); + + yz = FT_MulFix( vector->x, matrix->yx ) + + FT_MulFix( vector->y, matrix->yy ); + + vector->x = xz; + vector->y = yz; + } + + + + /*************************************************************************/ /* */ /* */ @@ -715,26 +750,11 @@ BASE_FUNC( void ) FT_Outline_Transform( FT_Outline* outline, FT_Matrix* matrix ) { - FT_UShort n; - FT_Vector* vec; - - - vec = outline->points; - for ( n = 0; n < outline->n_points; n++ ) - { - FT_Pos x, y; - - - x = FT_MulFix( vec->x, matrix->xx ) + - FT_MulFix( vec->y, matrix->xy ); - - y = FT_MulFix( vec->x, matrix->yx ) + - FT_MulFix( vec->y, matrix->yy ); - - vec->x = x; - vec->y = y; - vec++; - } + FT_Vector* vec = outline->points; + FT_Vector* limit = vec + outline->n_points; + + for ( ; vec < limit; vec++ ) + FT_Vector_Transform( vec, matrix ); } @@ -807,46 +827,6 @@ } - /*************************************************************************/ - /* */ - /* */ - /* FT_Vector_Transform */ - /* */ - /* */ - /* Transforms a single vector through a 2x2 matrix. */ - /* */ - /* */ - /* vector :: The target vector to transform. */ - /* */ - /* */ - /* matrix :: A pointer to the source 2x2 matrix. */ - /* */ - /* */ - /* Yes. */ - /* */ - /* */ - /* The result is undefined if either `vector' or `matrix' is invalid. */ - /* */ - FT_EXPORT_FUNC( void ) FT_Vector_Transform( FT_Vector* vector, - FT_Matrix* matrix ) - { - FT_Pos xz, yz; - - - if ( !vector || !matrix ) - return; - - xz = FT_MulFix( vector->x, matrix->xx ) + - FT_MulFix( vector->y, matrix->xy ); - - yz = FT_MulFix( vector->x, matrix->yx ) + - FT_MulFix( vector->y, matrix->yy ); - - vector->x = xz; - vector->y = yz; - } - - /*************************************************************************/ /* */ /* */ diff --git a/src/base/rules.mk b/src/base/rules.mk index a8846a9e5..1763a0981 100644 --- a/src/base/rules.mk +++ b/src/base/rules.mk @@ -45,10 +45,8 @@ BASE_SRC := $(BASE_)ftcalc.c \ # object. It will then be linked to the final executable only if one of its # symbols is used by the application. # -BASE_EXT_SRC := $(BASE_)ftraster.c \ - $(BASE_)ftglyph.c \ - $(BASE_)ftmm.c \ - $(BASE_)ftgrays.c +BASE_EXT_SRC := $(BASE_)ftglyph.c \ + $(BASE_)ftmm.c # Default extensions objects # diff --git a/src/cff/module.mk b/src/cff/module.mk index 1e8b92539..9bc5c8f72 100644 --- a/src/cff/module.mk +++ b/src/cff/module.mk @@ -1,7 +1,7 @@ make_module_list: add_cff_driver add_cff_driver: - $(OPEN_DRIVER)cff_driver_interface$(CLOSE_DRIVER) + $(OPEN_DRIVER)cff_driver_class$(CLOSE_DRIVER) $(ECHO_DRIVER)cff $(ECHO_DRIVER_DESC)OpenType fonts with extension *.otf$(ECHO_DRIVER_DONE) # EOF diff --git a/src/cff/t2driver.c b/src/cff/t2driver.c index a2f051729..2a599751f 100644 --- a/src/cff/t2driver.c +++ b/src/cff/t2driver.c @@ -78,7 +78,7 @@ /* formats. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ /* */ /* Only horizontal layouts (left-to-right & right-to-left) are */ @@ -144,114 +144,6 @@ #undef PAIR_TAG - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** S I Z E S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* Set_Char_Sizes */ - /* */ - /* */ - /* A driver method used to reset a size's character sizes (horizontal */ - /* and vertical) expressed in fractional points. */ - /* */ - /* */ - /* char_width :: The character width expressed in 26.6 */ - /* fractional points. */ - /* */ - /* char_height :: The character height expressed in 26.6 */ - /* fractional points. */ - /* */ - /* horz_resolution :: The horizontal resolution of the output device. */ - /* */ - /* vert_resolution :: The vertical resolution of the output device. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_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 whether 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 = (FT_UShort)( dim_x >> 6 ); - metrics->y_ppem = (FT_UShort)( dim_y >> 6 ); - } - - return T2_Reset_Size( size ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* Set_Pixel_Sizes */ - /* */ - /* */ - /* A driver method used to reset a size's character sizes (horizontal */ - /* and vertical) expressed in integer pixels. */ - /* */ - /* */ - /* pixel_width :: The character width expressed in integer pixels. */ - /* */ - /* pixel_height :: The character height expressed in integer pixels. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* 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 ); - } - /*************************************************************************/ /* */ @@ -277,7 +169,7 @@ /* whether to hint the outline, etc). */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ static FT_Error Load_Glyph( T2_GlyphSlot slot, @@ -385,58 +277,57 @@ static - FTDriver_Interface t2_get_interface( T2_Driver driver, - const char* interface ) + FT_Module_Interface t2_get_interface( T2_Driver driver, + const char* interface ) { - FT_Driver sfntd = FT_Get_Driver( driver->root.library, "sfnt" ); - SFNT_Interface* sfnt; + FT_Module 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; + /* we simply pass our request to the "sfnt" module */ + sfnt = FT_Get_Module( driver->root.root.library, "sfnt" ); + return sfnt ? sfnt->clazz->get_interface( sfnt, interface ) : 0; } /* The FT_DriverInterface structure is defined in ftdriver.h. */ - const FT_DriverInterface cff_driver_interface = + const FT_Driver_Class cff_driver_class = { - sizeof ( T2_DriverRec ), - sizeof ( TT_FaceRec ), - sizeof ( FT_SizeRec ), - sizeof ( T2_GlyphSlotRec ), + /* begin with the FT_Module_Class fields */ + { + ft_module_font_driver | ft_module_driver_scalable, + sizeof( T2_DriverRec ), + "cff", + 0x10000, + 0x20000, - "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, + 0, /* module-specific interface */ + + (FT_Module_Constructor) T2_Init_Driver, + (FT_Module_Destructor) T2_Done_Driver, + (FT_Module_Requester) t2_get_interface, + }, + + /* now the specific driver fields */ + sizeof( TT_FaceRec ), + sizeof( FT_SizeRec ), + sizeof( T2_GlyphSlotRec ), (FTDriver_initFace) T2_Init_Face, (FTDriver_doneFace) T2_Done_Face, - (FTDriver_getKerning) Get_Kerning, + (FTDriver_initSize) 0, + (FTDriver_doneSize) 0, + (FTDriver_initGlyphSlot) 0, + (FTDriver_doneGlyphSlot) 0, - (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_setCharSizes) 0, + (FTDriver_setPixelSizes) 0, + (FTDriver_loadGlyph) Load_Glyph, - (FTDriver_getCharIndex) Get_Char_Index, + + (FTDriver_getKerning) Get_Kerning, + (FTDriver_attachFile) 0, + (FTDriver_getAdvances) 0 }; @@ -446,7 +337,7 @@ /*************************************************************************/ /* */ /* */ - /* getDriverInterface */ + /* getDriverClass */ /* */ /* */ /* This function is used when compiling the TrueType driver as a */ @@ -462,9 +353,9 @@ /* format-specific interface can then be retrieved through the method */ /* interface->get_format_interface. */ /* */ - EXPORT_FUNC( FT_DriverInterface* ) getDriverInterface( void ) + EXPORT_FUNC( FT_Driver_Class* ) getDriverClass( void ) { - return &cff_driver_interface; + return &cff_driver_class; } diff --git a/src/cff/t2driver.h b/src/cff/t2driver.h index 225c5ad37..e0b0afd3a 100644 --- a/src/cff/t2driver.h +++ b/src/cff/t2driver.h @@ -19,12 +19,9 @@ #ifndef T2DRIVER_H #define T2DRIVER_H -#include #include -#include - - FT_EXPORT_VAR( const FT_DriverInterface ) cff_driver_interface; + FT_EXPORT_VAR( const FT_Driver_Class ) cff_driver_class; #endif /* T2DRIVER_H */ diff --git a/src/cff/t2gload.c b/src/cff/t2gload.c index 4114925bf..31b7c93e8 100644 --- a/src/cff/t2gload.c +++ b/src/cff/t2gload.c @@ -231,9 +231,12 @@ if ( glyph ) { - builder->base = glyph->root.outline; - builder->max_points = glyph->max_points; - builder->max_contours = glyph->max_contours; + FT_GlyphLoader* loader = glyph->root.loader; + + builder->loader = loader; + builder->base = &loader->base.outline; + builder->current = &loader->current.outline; + FT_GlyphLoader_Rewind( loader ); } if ( size ) @@ -249,10 +252,6 @@ builder->left_bearing.y = 0; builder->advance.x = 0; builder->advance.y = 0; - - builder->base.n_points = 0; - builder->base.n_contours = 0; - builder->current = builder->base; } @@ -274,13 +273,8 @@ { T2_GlyphSlot glyph = builder->glyph; - if ( glyph ) - { - glyph->root.outline = builder->base; - glyph->max_points = builder->max_points; - glyph->max_contours = builder->max_contours; - } + glyph->root.outline = *builder->base; } @@ -366,43 +360,9 @@ FT_Error check_points( T2_Builder* builder, FT_Int count ) { - FT_Outline* base = &builder->base; - FT_Outline* outline = &builder->current; - - - if ( !builder->load_points ) - return T2_Err_Ok; - - count += base->n_points + outline->n_points; - - /* realloc points table if necessary */ - if ( count >= builder->max_points ) - { - FT_Error error; - FT_Memory memory = builder->memory; - FT_Int increment = outline->points - base->points; - FT_Int current = builder->max_points; - - - while ( builder->max_points < count ) - builder->max_points += 8; - - if ( REALLOC_ARRAY( base->points, current, - builder->max_points, FT_Vector ) || - - REALLOC_ARRAY( base->tags, current, - builder->max_points, FT_Byte ) ) - { - builder->error = error; - return error; - } - - outline->points = base->points + increment; - outline->tags = base->tags + increment; - } - - return T2_Err_Ok; - } + return FT_GlyphLoader_Check_Points( builder->loader, + count, 0 ); + } /* add a new point, do not check space */ @@ -412,22 +372,19 @@ FT_Pos y, FT_Byte flag ) { - FT_Outline* outline = &builder->current; - + FT_Outline* outline = builder->current; if ( builder->load_points ) { FT_Vector* point = outline->points + outline->n_points; FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; - point->x = x >> 16; point->y = y >> 16; *control = flag ? FT_Curve_Tag_On : FT_Curve_Tag_Cubic; builder->last = *point; } - outline->n_points++; } @@ -440,7 +397,6 @@ { FT_Error error; - error = check_points( builder, 1 ); if ( !error ) add_point( builder, x, y, 1 ); @@ -453,9 +409,8 @@ static FT_Error add_contour( T2_Builder* builder ) { - FT_Outline* base = &builder->base; - FT_Outline* outline = &builder->current; - + FT_Outline* outline = builder->current; + FT_Error error; if ( !builder->load_points ) { @@ -463,34 +418,15 @@ return T2_Err_Ok; } - /* realloc contours array if necessary */ - if ( base->n_contours + outline->n_contours >= builder->max_contours && - builder->load_points ) + error = FT_GlyphLoader_Check_Points( builder->loader, 0, 1 ); + if (!error) { - FT_Error error; - FT_Memory memory = builder->memory; - FT_Int increment = outline->contours - base->contours; - FT_Int current = builder->max_contours; - - - builder->max_contours += 4; - - if ( REALLOC_ARRAY( base->contours, - current, builder->max_contours, FT_Short ) ) - { - builder->error = error; - return error; - } - - outline->contours = base->contours + increment; + if ( outline->n_contours > 0 ) + outline->contours[outline->n_contours - 1] = outline->n_points - 1; + + outline->n_contours++; } - - if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = outline->n_points - 1; - - outline->n_contours++; - - return T2_Err_Ok; + return error; } @@ -505,7 +441,6 @@ { FT_Error error; - builder->path_begun = 1; error = add_contour( builder ); if ( error ) @@ -520,8 +455,7 @@ static void close_contour( T2_Builder* builder ) { - FT_Outline* outline = &builder->current; - + FT_Outline* outline = builder->current; if ( outline->n_contours > 0 ) outline->contours[outline->n_contours - 1] = outline->n_points - 1; @@ -550,7 +484,7 @@ /* charstring_len :: The length in bytes of the charstring stream. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error T2_Parse_CharStrings( T2_Decoder* decoder, @@ -593,7 +527,7 @@ ip = zone->cursor = zone->base; error = T2_Err_Ok; - outline = &builder->current; + outline = builder->current; x = builder->pos_x; y = builder->pos_y; @@ -1182,8 +1116,7 @@ close_contour( builder ); /* add current outline to the glyph slot */ - builder->base.n_points += builder->current.n_points; - builder->base.n_contours += builder->current.n_contours; + FT_GlyphLoader_Add( builder->loader ); /* return now! */ FT_TRACE4(( "\n\n" )); @@ -1769,7 +1702,7 @@ { /* scale the outline and the metrics */ FT_Int n; - FT_Outline* cur = &decoder.builder.base; + FT_Outline* cur = &glyph->root.outline; FT_Vector* vec = cur->points; FT_Fixed x_scale = glyph->x_scale; FT_Fixed y_scale = glyph->y_scale; diff --git a/src/cff/t2gload.h b/src/cff/t2gload.h index fb6a48833..ef615765d 100644 --- a/src/cff/t2gload.h +++ b/src/cff/t2gload.h @@ -85,34 +85,31 @@ /* */ typedef struct T2_Builder_ { - FT_Memory memory; - TT_Face face; - T2_GlyphSlot glyph; + FT_Memory memory; + TT_Face face; + T2_GlyphSlot glyph; + FT_GlyphLoader* loader; + FT_Outline* base; + FT_Outline* current; - FT_Outline current; /* the current glyph outline */ - FT_Outline base; /* the composite glyph outline */ + FT_Vector last; - FT_Int max_points; /* capacity of base outline in points */ - FT_Int max_contours; /* capacity of base outline in contours */ + FT_Fixed scale_x; + FT_Fixed scale_y; - FT_Vector last; + FT_Pos pos_x; + FT_Pos pos_y; - FT_Fixed scale_x; - FT_Fixed scale_y; + FT_Vector left_bearing; + FT_Vector advance; - FT_Pos pos_x; - FT_Pos pos_y; + FT_BBox bbox; /* bounding box */ + FT_Bool path_begun; + FT_Bool load_points; + FT_Bool no_recurse; - FT_Vector left_bearing; - FT_Vector advance; - - FT_BBox bbox; /* bounding box */ - FT_Bool path_begun; - FT_Bool load_points; - FT_Bool no_recurse; - - FT_Error error; /* only used for memory errors */ - FT_Bool metrics_only; + FT_Error error; /* only used for memory errors */ + FT_Bool metrics_only; } T2_Builder; diff --git a/src/cff/t2objs.c b/src/cff/t2objs.c index cf57ed802..e59952d60 100644 --- a/src/cff/t2objs.c +++ b/src/cff/t2objs.c @@ -68,7 +68,7 @@ /* face :: The newly built face object. */ /* */ /* */ - /* FreeTrue error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ LOCAL_DEF FT_Error T2_Init_Face( FT_Stream stream, @@ -78,17 +78,11 @@ FT_Parameter* params ) { FT_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; + sfnt = (SFNT_Interface*) + FT_Get_Module_Interface( face->root.driver->root.library,"sfnt" ); + if ( !sfnt ) goto Bad_Format; /* create input stream from resource */ if ( FILE_Seek( 0 ) ) @@ -163,13 +157,9 @@ void T2_Done_Face( T2_Face face ) { FT_Memory memory = face->root.memory; -#if 0 - FT_Stream stream = face->root.stream; -#endif SFNT_Interface* sfnt = face->sfnt; - if ( sfnt ) sfnt->done_face( face ); @@ -186,150 +176,6 @@ } - /*************************************************************************/ - /* */ - /* SIZE FUNCTIONS */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* T2_Init_Size */ - /* */ - /* */ - /* Initializes a new OpenType size object. */ - /* */ - /* */ - /* size :: A handle to the size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_DEF - FT_Error T2_Init_Size( T2_Size size ) - { - UNUSED( size ); - - return 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* T2_Done_Size */ - /* */ - /* */ - /* The OpenType size object finalizer. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - LOCAL_FUNC - void T2_Done_Size( T2_Size size ) - { - UNUSED( size ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* T2_Reset_Size */ - /* */ - /* */ - /* Resets a OpenType size when resolutions and character dimensions */ - /* have been changed. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_DEF - FT_Error T2_Reset_Size( T2_Size size ) - { - T2_Face face = (T2_Face)size->face; - FT_Size_Metrics* metrics = &size->metrics; - - - if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 ) - return T2_Err_Invalid_PPem; - - /* 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 T2_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* T2_Init_GlyphSlot */ - /* */ - /* */ - /* The OpenType glyph slot initializer. */ - /* */ - /* */ - /* slot :: The glyph record to build. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error T2_Init_GlyphSlot( T2_GlyphSlot slot ) - { - FT_Library library = slot->root.face->driver->library; - - - slot->max_points = 0; - slot->max_contours = 0; - slot->root.bitmap.buffer = 0; - - return FT_Outline_New( library, 0, 0, &slot->root.outline ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* T2_Done_GlyphSlot */ - /* */ - /* */ - /* The OpenType glyph slot finalizer. */ - /* */ - /* */ - /* slot :: A handle to the glyph slot object. */ - /* */ - LOCAL_FUNC - void T2_Done_GlyphSlot( T2_GlyphSlot slot ) - { - FT_Library library = slot->root.face->driver->library; - FT_Memory memory = library->memory; - - - if ( slot->root.flags & ft_glyph_own_bitmap ) - FREE( slot->root.bitmap.buffer ); - - FT_Outline_Done( library, &slot->root.outline ); - return; - } - - /*************************************************************************/ /* */ /* */ @@ -342,7 +188,7 @@ /* driver :: A handle to the target driver object. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error T2_Init_Driver( T2_Driver driver ) diff --git a/src/cff/t2objs.h b/src/cff/t2objs.h index 23e13a43f..2e30b4ea5 100644 --- a/src/cff/t2objs.h +++ b/src/cff/t2objs.h @@ -69,9 +69,6 @@ FT_Bool hint; FT_Bool scaled; - FT_Int max_points; - FT_Int max_contours; - FT_Fixed x_scale; FT_Fixed y_scale; @@ -120,31 +117,6 @@ void T2_Done_Face( T2_Face face ); - /*************************************************************************/ - /* */ - /* Size functions */ - /* */ - 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 functions */ - /* */ - LOCAL_DEF - FT_Error T2_Init_GlyphSlot( T2_GlyphSlot slot ); - - LOCAL_DEF - void T2_Done_GlyphSlot( T2_GlyphSlot slot ); - - /*************************************************************************/ /* */ /* Driver functions */ diff --git a/src/cid/cidgload.c b/src/cid/cidgload.c index 8fe3fb058..68c1de627 100644 --- a/src/cid/cidgload.c +++ b/src/cid/cidgload.c @@ -157,9 +157,13 @@ if ( glyph ) { - builder->base = glyph->root.outline; - builder->max_points = glyph->max_points; - builder->max_contours = glyph->max_contours; + FT_GlyphLoader* loader = glyph->root.loader; + + builder->loader = loader; + builder->base = &loader->base.outline; + builder->current = &loader->current.outline; + + FT_GlyphLoader_Rewind(loader); } if ( size ) @@ -176,9 +180,6 @@ builder->advance.x = 0; builder->advance.y = 0; - builder->base.n_points = 0; - builder->base.n_contours = 0; - builder->current = builder->base; } @@ -200,13 +201,8 @@ { T1_GlyphSlot glyph = builder->glyph; - if ( glyph ) - { - glyph->root.outline = builder->base; - glyph->max_points = builder->max_points; - glyph->max_contours = builder->max_contours; - } + glyph->root.outline = *builder->base; } @@ -236,42 +232,7 @@ FT_Error check_points( CID_Builder* builder, FT_Int count ) { - FT_Outline* base = &builder->base; - FT_Outline* outline = &builder->current; - - - if ( !builder->load_points ) - return T1_Err_Ok; - - count += base->n_points + outline->n_points; - - /* realloc points table if necessary */ - if ( count >= builder->max_points ) - { - FT_Error error; - FT_Memory memory = builder->memory; - FT_Int increment = outline->points - base->points; - FT_Int current = builder->max_points; - - - while ( builder->max_points < count ) - builder->max_points += 8; - - if ( REALLOC_ARRAY( base->points, current, - builder->max_points, FT_Vector ) || - - REALLOC_ARRAY( base->tags, current, - builder->max_points, FT_Byte ) ) - { - builder->error = error; - return error; - } - - outline->points = base->points + increment; - outline->tags = base->tags + increment; - } - - return T1_Err_Ok; + return FT_GlyphLoader_Check_Points( builder->loader, count, 0 ); } @@ -282,8 +243,7 @@ FT_Pos y, FT_Byte flag ) { - FT_Outline* outline = &builder->current; - + FT_Outline* outline = builder->current; if ( builder->load_points ) { @@ -310,7 +270,6 @@ { FT_Error error; - error = check_points( builder, 1 ); if ( !error ) add_point( builder, x, y, 1 ); @@ -323,9 +282,8 @@ static FT_Error add_contour( CID_Builder* builder ) { - FT_Outline* base = &builder->base; - FT_Outline* outline = &builder->current; - + FT_Outline* outline = builder->current; + FT_Error error; if ( !builder->load_points ) { @@ -333,34 +291,15 @@ return T1_Err_Ok; } - /* realloc contours array if necessary */ - if ( base->n_contours + outline->n_contours >= builder->max_contours && - builder->load_points ) + error = FT_GlyphLoader_Check_Points( builder->loader, 0, 1 ); + if (!error) { - FT_Error error; - FT_Memory memory = builder->memory; - FT_Int increment = outline->contours - base->contours; - FT_Int current = builder->max_contours; - - - builder->max_contours += 4; - - if ( REALLOC_ARRAY( base->contours, - current, builder->max_contours, FT_Short ) ) - { - builder->error = error; - return error; - } - - outline->contours = base->contours + increment; + if ( outline->n_contours > 0 ) + outline->contours[outline->n_contours - 1] = outline->n_points - 1; + + outline->n_contours++; } - - if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = outline->n_points - 1; - - outline->n_contours++; - - return T1_Err_Ok; + return error; } @@ -375,7 +314,6 @@ { FT_Error error; - builder->path_begun = 1; error = add_contour( builder ); if ( error ) @@ -390,8 +328,7 @@ static void close_contour( CID_Builder* builder ) { - FT_Outline* outline = &builder->current; - + FT_Outline* outline = builder->current; if ( outline->n_contours > 0 ) outline->contours[outline->n_contours - 1] = outline->n_points - 1; @@ -473,7 +410,7 @@ /* achar :: The accent character's StandardEncoding charcode. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* Type 1 error code. 0 means success. */ /* */ static FT_Error t1operator_seac( CID_Decoder* decoder, @@ -485,11 +422,10 @@ { FT_Error error; FT_Int bchar_index, achar_index, n_base_points; - FT_Outline* cur = &decoder->builder.current; - FT_Outline* base = &decoder->builder.base; + FT_Outline* cur = decoder->builder.current; + FT_Outline* base = decoder->builder.base; FT_Vector left_bearing, advance; - bchar_index = bchar; achar_index = achar; @@ -499,43 +435,21 @@ return T1_Err_Syntax_Error; } - /* First load `bchar' in builder */ - /* now load the unscaled outline */ - cur->n_points = 0; - cur->n_contours = 0; - cur->points = base->points + base->n_points; - cur->tags = base->tags + base->n_points; - cur->contours = base->contours + base->n_contours; - - error = cid_load_glyph( decoder, bchar_index ); - if ( error ) - return error; - - n_base_points = cur->n_points; + /* if we are trying to load a composite glyph, do not load the */ + /* accent character and return the array of subglyphs. */ if ( decoder->builder.no_recurse ) { - /* if we are trying to load a composite glyph, do not load the */ - /* accent character and return the array of subglyphs. */ - - FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph; - FT_SubGlyph* subg; + FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph; + FT_GlyphLoader* loader = glyph->loader; + FT_SubGlyph* subg; /* reallocate subglyph array if necessary */ - if ( glyph->max_subglyphs < 2 ) - { - FT_Memory memory = decoder->builder.face->root.memory; - - - if ( REALLOC_ARRAY( glyph->subglyphs, glyph->max_subglyphs, - 2, FT_SubGlyph ) ) - return error; - - glyph->max_subglyphs = 2; - } - - subg = glyph->subglyphs; + error = FT_GlyphLoader_Check_Subglyphs( loader, 2 ); + if (error) goto Exit; + + subg = loader->current.subglyphs; /* subglyph 0 = base character */ subg->index = bchar_index; @@ -554,8 +468,20 @@ /* set up remaining glyph fields */ glyph->num_subglyphs = 2; glyph->format = ft_glyph_format_composite; + + loader->current.num_subglyphs = 2; } - else + + /* First load `bchar' in builder */ + /* now load the unscaled outline */ + if (decoder->builder.loader) + FT_GlyphLoader_Prepare( decoder->builder.loader ); /* prepare loader */ + + error = cid_load_glyph( decoder, bchar_index ); /* load one glyph */ + if ( error ) goto Exit; + + n_base_points = cur->n_points; + { /* save the left bearing and width of the base character */ /* as they will be erased by the next load. */ @@ -568,27 +494,10 @@ /* Now load `achar' on top of */ /* the base outline */ - - cur->n_points = 0; - cur->n_contours = 0; - cur->points = base->points + base->n_points; - cur->tags = base->tags + base->n_points; - cur->contours = base->contours + base->n_contours; - error = cid_load_glyph( decoder, achar_index ); if ( error ) return error; - /* adjust contours in accented character outline */ - if ( decoder->builder.load_points ) - { - FT_Int n; - - - for ( n = 0; n < cur->n_contours; n++ ) - cur->contours[n] += n_base_points; - } - /* restore the left side bearing and */ /* advance width of the base character */ @@ -597,10 +506,16 @@ /* Finally, move the accent */ if ( decoder->builder.load_points ) - FT_Outline_Translate( cur, adx - asb, ady ); + { + FT_Outline dummy; + + dummy.n_points = base->n_points - n_base_points; + dummy.points = base->points + n_base_points; + FT_Outline_Translate( &dummy, adx - asb, ady ); + } } - - return T1_Err_Ok; + Exit: + return error; } @@ -626,7 +541,7 @@ /* charstring_len :: The length in bytes of the charstring stream. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* Type1 error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error CID_Parse_CharStrings( CID_Decoder* decoder, @@ -654,7 +569,7 @@ ip = zone->cursor = zone->base; error = T1_Err_Ok; - outline = &builder->current; + outline = builder->current; x = builder->pos_x; y = builder->pos_y; @@ -1011,8 +926,7 @@ close_contour( builder ); /* add current outline to the glyph slot */ - builder->base.n_points += builder->current.n_points; - builder->base.n_contours += builder->current.n_contours; + FT_GlyphLoader_Add( builder->loader ); /* return now! */ FT_TRACE4(( "\n\n" )); @@ -1535,7 +1449,7 @@ { /* scale the outline and the metrics */ FT_Int n; - FT_Outline* cur = &decoder.builder.base; + FT_Outline* cur = &glyph->root.outline; FT_Vector* vec = cur->points; FT_Fixed x_scale = glyph->x_scale; FT_Fixed y_scale = glyph->y_scale; diff --git a/src/cid/cidgload.h b/src/cid/cidgload.h index 408908928..2aa3b0e08 100644 --- a/src/cid/cidgload.h +++ b/src/cid/cidgload.h @@ -80,34 +80,31 @@ /* */ typedef struct CID_Builder_ { - FT_Memory memory; - CID_Face face; - T1_GlyphSlot glyph; + FT_Memory memory; + CID_Face face; + T1_GlyphSlot glyph; + FT_GlyphLoader* loader; + FT_Outline* base; + FT_Outline* current; - FT_Outline current; /* the current glyph outline */ - FT_Outline base; /* the composite glyph outline */ + FT_Vector last; - FT_Int max_points; /* capacity of base outline in points */ - FT_Int max_contours; /* capacity of base outline in contours */ + FT_Fixed scale_x; + FT_Fixed scale_y; - FT_Vector last; + FT_Pos pos_x; + FT_Pos pos_y; - FT_Fixed scale_x; - FT_Fixed scale_y; + FT_Vector left_bearing; + FT_Vector advance; - FT_Pos pos_x; - FT_Pos pos_y; + FT_BBox bbox; /* bounding box */ + FT_Bool path_begun; + FT_Bool load_points; + FT_Bool no_recurse; - FT_Vector left_bearing; - FT_Vector advance; - - FT_BBox bbox; /* bounding box */ - FT_Bool path_begun; - FT_Bool load_points; - FT_Bool no_recurse; - - FT_Error error; /* only used for memory errors */ - FT_Bool metrics_only; + FT_Error error; /* only used for memory errors */ + FT_Bool metrics_only; } CID_Builder; diff --git a/src/cid/cidobjs.c b/src/cid/cidobjs.c index 4c63beea2..aea6b3209 100644 --- a/src/cid/cidobjs.c +++ b/src/cid/cidobjs.c @@ -35,97 +35,6 @@ #define FT_COMPONENT trace_cidobjs - /*************************************************************************/ - /* */ - /* SIZE FUNCTIONS */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* CID_Done_Size */ - /* */ - /* */ - /* The CID size object finalizer. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - LOCAL_FUNC - void CID_Done_Size( T1_Size size ) - { - UNUSED( size ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* CID_Init_Size */ - /* */ - /* */ - /* Initializes a new CID size object. */ - /* */ - /* */ - /* size :: A handle to the size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_DEF - FT_Error CID_Init_Size( T1_Size size ) - { - size->valid = 0; - - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* CID_Reset_Size */ - /* */ - /* */ - /* Resets a OpenType size when resolutions and character dimensions */ - /* have been changed. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error CID_Reset_Size( T1_Size size ) - { - /* recompute ascender, descender, etc. */ - CID_Face face = (CID_Face)size->root.face; - FT_Size_Metrics* metrics = &size->root.metrics; - - - if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 ) - return T1_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 T1_Err_Ok; - } - - /*************************************************************************/ /* */ /* FACE FUNCTIONS */ @@ -201,7 +110,7 @@ /* face :: The newly built face object. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* Type1 error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error CID_Init_Face( FT_Stream stream, @@ -225,13 +134,13 @@ if ( !psnames ) { /* look-up the PSNames driver */ - FT_Driver psnames_driver; + FT_Module psnames_module; - - psnames_driver = FT_Get_Driver( face->root.driver->library, "psnames" ); - if ( psnames_driver ) + psnames_module = FT_Get_Module( face->root.driver->root.library, + "psnames" ); + if (psnames_module) face->psnames = (PSNames_Interface*) - (psnames_driver->interface.format_interface); + (psnames_module->clazz->module_interface); } /* open the tokenizer; this will also check the font format */ @@ -420,60 +329,6 @@ } - /*************************************************************************/ - /* */ - /* */ - /* CID_Done_GlyphSlot */ - /* */ - /* */ - /* The CID glyph slot finalizer. */ - /* */ - /* */ - /* slot :: A handle to the glyph slot object. */ - /* */ - LOCAL_FUNC - void CID_Done_GlyphSlot( T1_GlyphSlot glyph ) - { - FT_Memory memory = glyph->root.face->memory; - FT_Library library = glyph->root.face->driver->library; - - - /* the bitmaps are created on demand */ - FREE( glyph->root.bitmap.buffer ); - FT_Outline_Done( library, &glyph->root.outline ); - - return; - } - - - /*************************************************************************/ - /* */ - /* */ - /* CID_Init_GlyphSlot */ - /* */ - /* */ - /* The CID glyph slot initializer. */ - /* */ - /* */ - /* slot :: The glyph record to build. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error CID_Init_GlyphSlot( T1_GlyphSlot glyph ) - { - FT_Library library = glyph->root.face->driver->library; - - - glyph->max_points = 0; - glyph->max_contours = 0; - glyph->root.bitmap.buffer = 0; - - return FT_Outline_New( library, 0, 0, &glyph->root.outline ); - } - - /*************************************************************************/ /* */ /* */ @@ -486,14 +341,14 @@ /* driver :: A handle to the target driver object. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* Type1 error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error CID_Init_Driver( T1_Driver driver ) { UNUSED( driver ); - return T1_Err_Ok; + return FT_Err_Ok; } diff --git a/src/cid/cidobjs.h b/src/cid/cidobjs.h index 3db7558d5..6ef3d4c99 100644 --- a/src/cid/cidobjs.h +++ b/src/cid/cidobjs.h @@ -95,12 +95,8 @@ { FT_SizeRec root; FT_Bool valid; - T1_Size_Hints* hints; /* defined in the hinter. This allows */ - /* us to experiment with different */ - /* hinting schemes without having to */ - /* change `cidobjs' each time. */ - } T1_SizeRec; + } T1_SizeRec; typedef struct T1_GlyphSlotRec_ @@ -110,14 +106,9 @@ FT_Bool hint; FT_Bool scaled; - FT_Int max_points; - FT_Int max_contours; - FT_Fixed x_scale; FT_Fixed y_scale; - T1_Glyph_Hints* hints; /* defined in the hinter */ - } T1_GlyphSlotRec; @@ -132,23 +123,6 @@ void CID_Done_Face( CID_Face face ); - LOCAL_DEF - FT_Error CID_Init_Size( T1_Size size ); - - LOCAL_DEF - void CID_Done_Size( T1_Size size ); - - LOCAL_DEF - FT_Error CID_Reset_Size( T1_Size size ); - - - LOCAL_DEF - FT_Error CID_Init_GlyphSlot( T1_GlyphSlot slot ); - - LOCAL_DEF - void CID_Done_GlyphSlot( T1_GlyphSlot slot ); - - LOCAL_DEF FT_Error CID_Init_Driver( T1_Driver driver ); diff --git a/src/cid/cidparse.c b/src/cid/cidparse.c index 263022043..31acb29e6 100644 --- a/src/cid/cidparse.c +++ b/src/cid/cidparse.c @@ -67,7 +67,7 @@ /* reallocations. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* Type1 error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error T1_New_Table( T1_Table* table, @@ -157,7 +157,7 @@ /* length :: The length in bytes of the source object. */ /* */ /* */ - /* FreeType error code. 0 means success. An error is returned if */ + /* Type1 error code. 0 means success. An error is returned if */ /* reallocation fails. */ /* */ LOCAL_FUNC @@ -934,7 +934,7 @@ if ( strncmp( stream->cursor, "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) ) { - FT_ERROR(( "[not a valid CID-keyed font]\n" )); + FT_TRACE2(( "[not a valid CID-keyed font]\n" )); error = FT_Err_Unknown_File_Format; } diff --git a/src/cid/cidriver.c b/src/cid/cidriver.c index a3d06c379..292bc37d2 100644 --- a/src/cid/cidriver.c +++ b/src/cid/cidriver.c @@ -37,36 +37,9 @@ #define FT_COMPONENT trace_ciddriver - /*************************************************************************/ - /* */ - /* */ - /* Get_Interface */ - /* */ - /* */ - /* Each driver can provide one or more extensions to the base */ - /* FreeType API. These can be used to access format specific */ - /* features (e.g., all TrueType/OpenType resources share a common */ - /* file structure and common tables which can be accessed through the */ - /* `sfnt' interface), or more simply generic ones (e.g., the */ - /* `postscript names' interface which can be used to retrieve the */ - /* PostScript name of a given glyph index). */ - /* */ - /* */ - /* driver :: A handle to a driver object. */ - /* */ - /* */ - /* interface :: A string designing the interface. Examples are */ - /* `sfnt', `post_names', `charmaps', etc. */ - /* */ - /* */ - /* A typeless pointer to the extension's interface (normally a table */ - /* of function pointers). Returns NULL if the requested extension */ - /* isn't available (i.e., wasn't compiled in the driver at build */ - /* time). */ - /* */ static - FTDriver_Interface Get_Interface( FT_Driver driver, - const FT_String* interface ) + FT_Module_Interface CID_Get_Interface( FT_Driver driver, + const FT_String* interface ) { UNUSED( driver ); UNUSED( interface ); @@ -75,152 +48,37 @@ } -#ifndef T1_CONFIG_OPTION_NO_AFM +#ifdef xxxT1_CONFIG_OPTION_NO_AFM - /*************************************************************************/ - /* */ - /* */ - /* Get_Kerning */ - /* */ - /* */ - /* A driver method used to return the kerning vector between two */ - /* glyphs of the same face. */ - /* */ - /* */ - /* 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. */ - /* */ - /* */ - /* kerning :: The kerning vector. This is in font units for */ - /* scalable formats, and in pixels for fixed-sizes */ - /* formats. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* 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 - FT_Error Get_Kerning( T1_Face face, - FT_UInt left_glyph, - FT_UInt right_glyph, - FT_Vector* kerning ) + FT_Error cid_Get_Kerning( T1_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_Vector* kerning ) { -#if 0 - T1_AFM* afm; -#endif - kerning->x = 0; kerning->y = 0; -#if 0 - afm = (T1_AFM*)face->afm_data; if ( afm ) CID_Get_Kerning( afm, left_glyph, right_glyph, kerning ); -#endif /* 0 */ - return T1_Err_Ok; } -#endif /* !T1_CONFIG_OPTION_NO_AFM */ +#endif /* xxxT1_CONFIG_OPTION_NO_AFM */ + /*************************************************************************/ /* */ /* */ - /* Set_Char_Sizes */ - /* */ - /* */ - /* A driver method used to reset a size's character sizes (horizontal */ - /* and vertical) expressed in fractional points. */ - /* */ - /* */ - /* char_width :: The character width expressed in 26.6 */ - /* fractional points. */ - /* */ - /* char_height :: The character height expressed in 26.6 */ - /* fractional points. */ - /* */ - /* horz_resolution :: The horizontal resolution of the output device. */ - /* */ - /* vert_resolution :: The vertical resolution of the output device. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Set_Char_Sizes( T1_Size size, - FT_F26Dot6 char_width, - FT_F26Dot6 char_height, - FT_UInt horz_resolution, - FT_UInt vert_resolution ) - { - UNUSED( char_width ); - UNUSED( char_height ); - UNUSED( horz_resolution ); - UNUSED( vert_resolution ); - - size->valid = FALSE; - return CID_Reset_Size( size ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* Set_Pixel_Sizes */ - /* */ - /* */ - /* A driver method used to reset a size's character sizes (horizontal */ - /* and vertical) expressed in integer pixels. */ - /* */ - /* */ - /* pixel_width :: The character width expressed in integer pixels. */ - /* */ - /* pixel_height :: The character height expressed in integer pixels. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Set_Pixel_Sizes( T1_Size size, - FT_Int pixel_width, - FT_Int pixel_height ) - { - UNUSED( pixel_width ); - UNUSED( pixel_height ); - - size->valid = FALSE; - return CID_Reset_Size( size ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* Get_Char_Index */ + /* cid_get_char_index */ /* */ /* */ /* Uses a charmap to return a given character code's glyph index. */ @@ -233,14 +91,13 @@ /* Glyph index. 0 means `undefined character code'. */ /* */ static - FT_UInt Get_Char_Index( FT_CharMap charmap, - FT_Long charcode ) + FT_UInt CID_Get_Char_Index( FT_CharMap charmap, + FT_Long charcode ) { T1_Face face; FT_UInt result = 0; PSNames_Interface* psnames; - face = (T1_Face)charmap->face; psnames = (PSNames_Interface*)face->psnames; if ( psnames ) @@ -316,75 +173,55 @@ } - const FT_DriverInterface t1cid_driver_interface = + + const FT_Driver_Class t1cid_driver_class = { - sizeof( FT_DriverRec ), + /* firs of all, the FT_Module_Class fields */ + { + ft_module_font_driver | ft_module_driver_scalable, + sizeof( FT_DriverRec ), + "t1cid", /* module name */ + 0x10000, /* version 1.0 of driver */ + 0x20000, /* requires FreeType 2.0 */ + + 0, + + (FT_Module_Constructor) CID_Init_Driver, + (FT_Module_Destructor) CID_Done_Driver, + (FT_Module_Requester) CID_Get_Interface + }, + + /* then the other font drivers fields */ sizeof( CID_FaceRec ), sizeof( T1_SizeRec ), sizeof( T1_GlyphSlotRec ), - "t1cid", - 100, - 200, + (FTDriver_initFace) CID_Init_Face, + (FTDriver_doneFace) CID_Done_Face, - 0, /* format interface */ + (FTDriver_initSize) 0, + (FTDriver_doneSize) 0, + (FTDriver_initGlyphSlot) 0, + (FTDriver_doneGlyphSlot) 0, - (FTDriver_initDriver) CID_Init_Driver, - (FTDriver_doneDriver) CID_Done_Driver, + (FTDriver_setCharSizes) 0, + (FTDriver_setPixelSizes) 0, - (FTDriver_getInterface) Get_Interface, + (FTDriver_loadGlyph) CID_Load_Glyph, + (FTDriver_getCharIndex) CID_Get_Char_Index, - (FTDriver_initFace) CID_Init_Face, - (FTDriver_doneFace) CID_Done_Face, - -#ifdef T1_CONFIG_OPTION_NO_AFM - (FTDriver_getKerning) 0, +#ifndef xxxxT1_CONFIG_OPTION_NO_AFM + (FTDriver_getKerning) 0, + (FTDriver_attachFile) 0, #else - (FTDriver_getKerning) Get_Kerning, + (FTDriver_getKerning) cid_Get_Kerning, + (FTDriver_attachFile) CID_Read_AFM, #endif - (FTDriver_initSize) CID_Init_Size, - (FTDriver_doneSize) CID_Done_Size, - (FTDriver_setCharSizes) Set_Char_Sizes, - (FTDriver_setPixelSizes)Set_Pixel_Sizes, - - (FTDriver_initGlyphSlot)CID_Init_GlyphSlot, - (FTDriver_doneGlyphSlot)CID_Done_GlyphSlot, - (FTDriver_loadGlyph) CID_Load_Glyph, - - (FTDriver_getCharIndex) Get_Char_Index, + (FTDriver_getAdvances) 0 }; -#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS - - - /*************************************************************************/ - /* */ - /* */ - /* getDriverInterface */ - /* */ - /* */ - /* This function is used when compiling the CID 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. */ - /* */ - /* */ - /* The address of the CID's driver generic interface. The */ - /* format-specific interface can then be retrieved through the method */ - /* interface->get_format_interface. */ - /* */ - EXPORT_FUNC( FT_DriverInterface* ) getDriverInterface( void ) - { - return &t1cid_driver_interface; - } - - -#endif /* FT_CONFIG_OPTION_DYNAMIC_DRIVERS */ /* END */ diff --git a/src/cid/cidriver.h b/src/cid/cidriver.h index 75c87301a..eb1a71be0 100644 --- a/src/cid/cidriver.h +++ b/src/cid/cidriver.h @@ -22,7 +22,7 @@ #include #include - FT_EXPORT_VAR( const FT_DriverInterface ) t1cid_driver_interface; + FT_EXPORT_VAR( const FT_Driver_Class ) t1cid_driver_class; #endif /* CIDRIVER_H */ diff --git a/src/cid/module.mk b/src/cid/module.mk index ce6551417..3d13c9ca1 100644 --- a/src/cid/module.mk +++ b/src/cid/module.mk @@ -1,6 +1,6 @@ make_module_list: add_type1cid_driver add_type1cid_driver: - $(OPEN_DRIVER)t1cid_driver_interface$(CLOSE_DRIVER) + $(OPEN_DRIVER)t1cid_driver_class$(CLOSE_DRIVER) $(ECHO_DRIVER)cid $(ECHO_DRIVER_DESC)Postscript CID-keyed fonts, no known extension$(ECHO_DRIVER_DONE) # EOF diff --git a/src/psnames/module.mk b/src/psnames/module.mk index cb23e8e76..3d33c120d 100644 --- a/src/psnames/module.mk +++ b/src/psnames/module.mk @@ -1,7 +1,7 @@ -make_module_list: add_psnames_driver +make_module_list: add_psnames_module -add_psnames_driver: - $(OPEN_DRIVER)psnames_driver_interface$(CLOSE_DRIVER) +add_psnames_module: + $(OPEN_DRIVER)psnames_module_class$(CLOSE_DRIVER) $(ECHO_DRIVER)psnames $(ECHO_DRIVER_DESC)Postscript & Unicode Glyph name handling$(ECHO_DRIVER_DONE) # EOF diff --git a/src/psnames/psdriver.h b/src/psnames/psdriver.h index 19d415b80..5fa89d5b5 100644 --- a/src/psnames/psdriver.h +++ b/src/psnames/psdriver.h @@ -1,10 +1,10 @@ /***************************************************************************/ /* */ -/* psdriver.h */ +/* psmodule.h */ /* */ -/* High-level PSNames driver interface (specification). */ +/* High-level PSNames module interface (specification). */ /* */ -/* Copyright 1996-2000 by */ +/* Copyright 1996-1999 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,13 +19,11 @@ #ifndef PSDRIVER_H #define PSDRIVER_H +#include -#include + FT_EXPORT_VAR(const FT_Module_Class) psnames_module_class; - FT_EXPORT_VAR( const FT_DriverInterface ) psnames_driver_interface; - - -#endif /* PSDRIVER_H */ +#endif /* PSMODULE_H */ /* END */ diff --git a/src/psnames/psnames.c b/src/psnames/psnames.c index c0238f48b..3b2b16c23 100644 --- a/src/psnames/psnames.c +++ b/src/psnames/psnames.c @@ -1,23 +1,2 @@ -/***************************************************************************/ -/* */ -/* psnames.c */ -/* */ -/* FreeType PSNames driver component (body only). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - #define FT_MAKE_OPTION_SINGLE_OBJECT -#include - - -/* END */ +#include diff --git a/src/psnames/rules.mk b/src/psnames/rules.mk index 47580e79c..0ee337348 100644 --- a/src/psnames/rules.mk +++ b/src/psnames/rules.mk @@ -31,7 +31,7 @@ PSNAMES_COMPILE := $(FT_COMPILE) $(PSNAMES_CFLAGS) # PSNames driver sources (i.e., C files) # -PSNAMES_DRV_SRC := $(PSNAMES_DIR_)psdriver.c +PSNAMES_DRV_SRC := $(PSNAMES_DIR_)psmodule.c # PSNames driver headers @@ -50,7 +50,7 @@ PSNAMES_DRV_OBJ_S := $(OBJ_)psnames.$O # PSNames driver source file for single build # -PSNAMES_DRV_SRC_S := $(PSNAMES_DIR_)psdriver.c +PSNAMES_DRV_SRC_S := $(PSNAMES_DIR_)psmodule.c # PSNames driver - single object diff --git a/src/base/ftgrays.c b/src/renderer/ftgrays.c similarity index 99% rename from src/base/ftgrays.c rename to src/renderer/ftgrays.c index f6cad8951..d7ef21032 100644 --- a/src/base/ftgrays.c +++ b/src/renderer/ftgrays.c @@ -123,7 +123,7 @@ #else /* _STANDALONE_ */ -#include +#include "ftgrays.h" #include /* for UNUSED() */ #include /* for FT_TRACE() and FT_ERROR() */ #include /* for FT_Outline_Decompose() */ diff --git a/src/renderer/ftgrays.h b/src/renderer/ftgrays.h new file mode 100644 index 000000000..feb74843b --- /dev/null +++ b/src/renderer/ftgrays.h @@ -0,0 +1,49 @@ +/***************************************************************************/ +/* */ +/* ftgrays.h */ +/* */ +/* FreeType smooth renderer declaration */ +/* */ +/* Copyright 1996-2000 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used */ +/* modified and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#ifndef FTGRAYS_H +#define FTGRAYS_H + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef _STANDALONE_ +#include "ftimage.h" +#else +#include +#endif + + /*************************************************************************/ + /* */ + /* To make ftgrays.h independent from configuration files we check */ + /* whether FT_EXPORT_DEF has been defined already. */ + /* */ + /* On some systems and compilers (Win32 mostly), an extra keyword is */ + /* necessary to compile the library as a DLL. */ + /* */ +#ifndef FT_EXPORT_VAR +#define FT_EXPORT_VAR(x) extern x +#endif + + FT_EXPORT_VAR(FT_Raster_Funcs) ft_grays_raster; + + #ifdef __cplusplus + } + #endif + +#endif diff --git a/src/base/ftraster.c b/src/renderer/ftraster.c similarity index 99% rename from src/base/ftraster.c rename to src/renderer/ftraster.c index 9687366da..4b2baae6f 100644 --- a/src/base/ftraster.c +++ b/src/renderer/ftraster.c @@ -22,7 +22,7 @@ /*************************************************************************/ -#include +#include "ftraster.h" #include /* for FT_MulDiv() only */ @@ -3248,7 +3248,7 @@ } - FT_Raster_Funcs ft_default_raster = + FT_Raster_Funcs ft_standard_raster = { ft_glyph_format_outline, (FT_Raster_New_Func) ft_black_new, diff --git a/src/renderer/ftraster.h b/src/renderer/ftraster.h new file mode 100644 index 000000000..371ed2783 --- /dev/null +++ b/src/renderer/ftraster.h @@ -0,0 +1,48 @@ +/***************************************************************************/ +/* */ +/* ftraster.h */ +/* */ +/* The FreeType glyph rasterizer (specification). */ +/* */ +/* Copyright 1996-2000 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used */ +/* modified and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef FTRASTER_H +#define FTRASTER_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include + + /*************************************************************************/ + /* */ + /* Uncomment the following line if you are using ftraster.c as a */ + /* standalone module, fully independent of FreeType. */ + /* */ +/* #define _STANDALONE_ */ + +#ifndef FT_EXPORT_VAR +#define FT_EXPORT_VAR(x) extern x +#endif + + FT_EXPORT_VAR(FT_Raster_Funcs) ft_standard_raster; + +#ifdef __cplusplus + } +#endif + +#endif /* FTRASTER_H */ + + +/* END */ diff --git a/src/renderer/ftrender.c b/src/renderer/ftrender.c new file mode 100644 index 000000000..a376d50f4 --- /dev/null +++ b/src/renderer/ftrender.c @@ -0,0 +1,161 @@ +#include + + /* sets render-specific mode */ + static FT_Error ft_renderer_set_mode( FT_Renderer render, + FT_ULong mode_tag, + FT_Pointer data ) + { + /* we simply pass it to the raster */ + return render->clazz->raster_class->raster_set_mode( + render->raster, mode_tag, data ); + } + + + /* convert a slot's glyph image into a bitmap */ + static FT_Error ft_renderer_render( FT_Renderer render, + FT_GlyphSlot slot, + FT_UInt mode ) + { + FT_Error error; + FT_Outline* outline; + FT_BBox cbox; + FT_UInt width, height, pitch; + FT_Bitmap* bitmap; + FT_Memory memory; + + FT_Raster_Params params; + + /* first of all, transform the outline */ + if (slot->format != ft_glyph_format_outline) + { + error = FT_Err_Invalid_Argument; + goto Exit; + } + + outline = &slot->outline; + + FT_Outline_Transform( outline, &slot->transform_matrix ); + FT_Outline_Translate( outline, slot->transform_delta.x, + slot->transform_delta.y ); + + /* compute the control box, and grid fit it */ + FT_Outline_Get_CBox( outline, &cbox ); + + cbox.xMin &= -64; + cbox.yMin &= -64; + cbox.xMax = (cbox.xMax+63) & -64; + cbox.yMax = (cbox.yMax+63) & -64; + + width = (cbox.xMax - cbox.xMin) >> 6; + height = (cbox.yMax - cbox.yMin) >> 6; + bitmap = &slot->bitmap; + memory = slot->face->memory; + + /* release old bitmap buffer */ + if ((slot->flags & ft_glyph_own_bitmap)) + FREE(bitmap->buffer); + + /* allocate new one, depends on pixel format */ + if ( mode & ft_render_mode_antialias ) + { + pitch = width; + bitmap->pixel_mode = ft_pixel_mode_grays; + bitmap->num_grays = 256; + } + else + { + pitch = (width+7) >> 3; + bitmap->pixel_mode = ft_pixel_mode_mono; + } + + bitmap->width = width; + bitmap->rows = height; + bitmap->pitch = pitch; + + if (ALLOC( bitmap->buffer, (FT_ULong)pitch * height )) + goto Exit; + + /* translate outline to render it into the bitmap */ + FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin ); + + /* set up parameters */ + params.target = bitmap; + params.source = outline; + params.flags = 0; + + if ( bitmap->pixel_mode == ft_pixel_mode_grays ) + params.flags |= ft_raster_flag_aa; + + /* render outline into the bitmap */ + error = render->render( render->raster, ¶ms ); + if (error) goto Exit; + + slot->format = ft_glyph_format_bitmap; + slot->bitmap_left = cbox.xMin >> 6; + slot->bitmap_top = cbox.yMax >> 6; + + Exit: + return error; + } + +#ifndef FT_CONFIG_OPTION_NO_STD_RASTER + +#include + + const FT_Renderer_Class ft_standard_renderer_class = + { + { + ft_module_renderer, + sizeof( FT_RendererRec ), + + "standard renderer", + 0x10000, + 0x20000, + + 0, /* module specific interface */ + + (FT_Module_Constructor) 0, + (FT_Module_Destructor) 0, + (FT_Module_Requester) 0 + }, + + ft_glyph_format_outline, + + (FTRenderer_render) ft_renderer_render, + (FTRenderer_setMode) ft_renderer_set_mode, + + (FT_Raster_Funcs*) &ft_standard_raster + }; + +#endif /* !FT_CONFIG_OPTION_NO_STD_RASTER */ + +#ifndef FT_CONFIG_OPTION_NO_SMOOTH_RASTER + +#include + + const FT_Renderer_Class ft_smooth_renderer_class = + { + { + ft_module_renderer, + sizeof( FT_RendererRec ), + + "smooth renderer", + 0x10000, + 0x20000, + + 0, /* module specific interface */ + + (FT_Module_Constructor) 0, + (FT_Module_Destructor) 0, + (FT_Module_Requester) 0 + }, + + ft_glyph_format_outline, + + (FTRenderer_render) ft_renderer_render, + (FTRenderer_setMode) ft_renderer_set_mode, + + (FT_Raster_Funcs*) &ft_grays_raster + }; + +#endif /* !FT_CONFIG_OPTION_NO_SMOOTH_RASTER */ diff --git a/src/renderer/module.mk b/src/renderer/module.mk new file mode 100644 index 000000000..be7d80dba --- /dev/null +++ b/src/renderer/module.mk @@ -0,0 +1,11 @@ +make_module_list: add_renderer_module + +# XXX: important, the standard renderer *MUST* be first on this list.. +# +add_renderer_module: + $(OPEN_DRIVER)ft_standard_renderer_class$(CLOSE_DRIVER) + $(ECHO_DRIVER)standard $(ECHO_DRIVER_DESC)standard outline renderer module$(ECHO_DRIVER_DONE) + $(OPEN_DRIVER)ft_smooth_renderer_class$(CLOSE_DRIVER) + $(ECHO_DRIVER)smooth $(ECHO_DRIVER_DESC)smooth outline renderer module$(ECHO_DRIVER_DONE) + +# EOF diff --git a/src/renderer/renderer.c b/src/renderer/renderer.c new file mode 100644 index 000000000..f3251c5f8 --- /dev/null +++ b/src/renderer/renderer.c @@ -0,0 +1,219 @@ +#include + + /* initialise renderer - init its raster */ + static FT_Error ft_renderer_init( FT_Renderer render ) + { + FT_Library library = FT_MODULE_LIBRARY(render); + + render->clazz->raster_class->raster_reset( render->raster, + library->raster_pool, library->raster_pool_size ); + + return 0; + } + + + + /* sets render-specific mode */ + static FT_Error ft_renderer_set_mode( FT_Renderer render, + FT_ULong mode_tag, + FT_Pointer data ) + { + /* we simply pass it to the raster */ + return render->clazz->raster_class->raster_set_mode( + render->raster, mode_tag, data ); + } + + /* transform a given glyph image */ + static FT_Error ft_renderer_transform( FT_Renderer render, + FT_GlyphSlot slot, + FT_Matrix* matrix, + FT_Vector* delta ) + { + FT_Error error = FT_Err_Ok; + + if (slot->format != render->glyph_format) + { + error = FT_Err_Invalid_Argument; + goto Exit; + } + + if (matrix) + FT_Outline_Transform( &slot->outline, matrix ); + + if (delta) + FT_Outline_Translate( &slot->outline, delta->x, delta->y ); + + Exit: + return error; + } + + /* return the glyph's control box */ + static void ft_renderer_get_cbox( FT_Renderer render, + FT_GlyphSlot slot, + FT_BBox *cbox ) + { + MEM_Set( cbox, 0, sizeof(*cbox) ); + + if (slot->format == render->glyph_format) + FT_Outline_Get_CBox( &slot->outline, cbox ); + } + + + /* convert a slot's glyph image into a bitmap */ + static FT_Error ft_renderer_render( FT_Renderer render, + FT_GlyphSlot slot, + FT_UInt mode, + FT_Vector* origin ) + { + FT_Error error; + FT_Outline* outline; + FT_BBox cbox; + FT_UInt width, height, pitch; + FT_Bitmap* bitmap; + FT_Memory memory; + + FT_Raster_Params params; + + /* check glyph image format */ + if (slot->format != render->glyph_format) + { + error = FT_Err_Invalid_Argument; + goto Exit; + } + + outline = &slot->outline; + + /* translate the outline to the new origin if needed */ + if (origin) + FT_Outline_Translate( outline, origin->x, origin->y ); + + /* compute the control box, and grid fit it */ + FT_Outline_Get_CBox( outline, &cbox ); + + cbox.xMin &= -64; + cbox.yMin &= -64; + cbox.xMax = (cbox.xMax+63) & -64; + cbox.yMax = (cbox.yMax+63) & -64; + + width = (cbox.xMax - cbox.xMin) >> 6; + height = (cbox.yMax - cbox.yMin) >> 6; + bitmap = &slot->bitmap; + memory = slot->face->memory; + + /* release old bitmap buffer */ + if ((slot->flags & ft_glyph_own_bitmap)) + { + FREE(bitmap->buffer); + slot->flags &= ~ft_glyph_own_bitmap; + } + + /* allocate new one, depends on pixel format */ + if ( mode & ft_render_mode_antialias ) + { + pitch = width; + bitmap->pixel_mode = ft_pixel_mode_grays; + bitmap->num_grays = 256; + } + else + { + pitch = (width+7) >> 3; + bitmap->pixel_mode = ft_pixel_mode_mono; + } + + bitmap->width = width; + bitmap->rows = height; + bitmap->pitch = pitch; + + if (ALLOC( bitmap->buffer, (FT_ULong)pitch * height )) + goto Exit; + + slot->flags |= ft_glyph_own_bitmap; + + /* translate outline to render it into the bitmap */ + FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin ); + + /* set up parameters */ + params.target = bitmap; + params.source = outline; + params.flags = 0; + + if ( bitmap->pixel_mode == ft_pixel_mode_grays ) + params.flags |= ft_raster_flag_aa; + + /* render outline into the bitmap */ + error = render->raster_render( render->raster, ¶ms ); + if (error) goto Exit; + + slot->format = ft_glyph_format_bitmap; + slot->bitmap_left = cbox.xMin >> 6; + slot->bitmap_top = cbox.yMax >> 6; + + Exit: + return error; + } + +#ifndef FT_CONFIG_OPTION_NO_STD_RASTER + +#include + + const FT_Renderer_Class ft_standard_renderer_class = + { + { + ft_module_renderer, + sizeof( FT_RendererRec ), + + "standard renderer", + 0x10000, + 0x20000, + + 0, /* module specific interface */ + + (FT_Module_Constructor) ft_renderer_init, + (FT_Module_Destructor) 0, + (FT_Module_Requester) 0 + }, + + ft_glyph_format_outline, + + (FTRenderer_render) ft_renderer_render, + (FTRenderer_transform) ft_renderer_transform, + (FTRenderer_getCBox) ft_renderer_get_cbox, + (FTRenderer_setMode) ft_renderer_set_mode, + + (FT_Raster_Funcs*) &ft_standard_raster + }; + +#endif /* !FT_CONFIG_OPTION_NO_STD_RASTER */ + +#ifndef FT_CONFIG_OPTION_NO_SMOOTH_RASTER + +#include + + const FT_Renderer_Class ft_smooth_renderer_class = + { + { + ft_module_renderer, + sizeof( FT_RendererRec ), + + "smooth renderer", + 0x10000, + 0x20000, + + 0, /* module specific interface */ + + (FT_Module_Constructor) ft_renderer_init, + (FT_Module_Destructor) 0, + (FT_Module_Requester) 0 + }, + + ft_glyph_format_outline, + + (FTRenderer_render) ft_renderer_render, + (FTRenderer_transform) ft_renderer_transform, + (FTRenderer_getCBox) ft_renderer_get_cbox, + (FTRenderer_setMode) ft_renderer_set_mode, + + (FT_Raster_Funcs*) &ft_grays_raster + }; + +#endif /* !FT_CONFIG_OPTION_NO_SMOOTH_RASTER */ diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h new file mode 100644 index 000000000..091d1ec5a --- /dev/null +++ b/src/renderer/renderer.h @@ -0,0 +1,14 @@ +#ifndef RENDERER_H +#define RENDERER_H + +#include + +#ifndef FT_CONFIG_OPTION_NO_STD_RASTER + FT_EXPORT_VAR(const FT_Renderer_Class) ft_std_renderer_class; +#endif + +#ifndef FT_CONFIG_OPTION_NO_SMOOTH_RASTER + FT_EXPORT_VAR(const FT_Renderer_Class) ft_smooth_renderer_class; +#endif + +#endif /* RENDERER_H */ diff --git a/src/renderer/rules.mk b/src/renderer/rules.mk new file mode 100644 index 000000000..5cdfd144c --- /dev/null +++ b/src/renderer/rules.mk @@ -0,0 +1,75 @@ +# +# FreeType 2 renderer module build 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. + + +# renderer driver directory +# +REND_DIR := $(SRC_)renderer +REND_DIR_ := $(REND_DIR)$(SEP) + + +# additional include flags used when compiling the driver +# +REND_INCLUDE := $(REND_DIR) + +# compilation flags for the driver +# +REND_CFLAGS := $(REND_INCLUDE:%=$I%) +REND_COMPILE := $(FT_COMPILE) $(REND_CFLAGS) + + +# REND driver sources (i.e., C files) +# +REND_DRV_SRC := $(REND_DIR_)ftraster.c \ + $(REND_DIR_)ftgrays.c \ + $(REND_DIR_)renderer.c + +# REND driver headers +# +REND_DRV_H := $(REND_DRV_SRC:%c=%h) + + +# REND driver object(s) +# +# REND_DRV_OBJ_M is used during `multi' builds. +# REND_DRV_OBJ_S is used during `single' builds. +# +REND_DRV_OBJ_M := $(REND_DRV_SRC:$(REND_DIR_)%.c=$(OBJ_)%.$O) +REND_DRV_OBJ_S := $(REND_DRV_OBJ_M) + +# REND driver source file for single build +# +#REND_DRV_SRC_S := $(REND_DIR_)renderer.c + + +# REND driver - single object +# +#$(REND_DRV_OBJ_S): $(REND_DRV_SRC_S) $(REND_DRV_SRC) \ +# $(FREETYPE_H) $(REND_DRV_H) +# $(REND_COMPILE) $T$@ $(REND_DRV_SRC_S) + + +# REND driver - multiple objects +# +$(OBJ_)%.$O: $(REND_DIR_)%.c $(FREETYPE_H) $(REND_DRV_H) + $(REND_COMPILE) $T$@ $< + + +# update main driver object lists +# +DRV_OBJS_S += $(REND_DRV_OBJ_M) +DRV_OBJS_M += $(REND_DRV_OBJ_M) + + +# EOF diff --git a/src/sfnt/module.mk b/src/sfnt/module.mk index f98860e30..48b494f4d 100644 --- a/src/sfnt/module.mk +++ b/src/sfnt/module.mk @@ -1,7 +1,7 @@ -make_module_list: add_sfnt_driver +make_module_list: add_sfnt_module -add_sfnt_driver: - $(OPEN_DRIVER)sfnt_driver_interface$(CLOSE_DRIVER) - $(ECHO_DRIVER)sfnt $(ECHO_DRIVER_DESC)pseudo-driver for TrueType & OpenType formats$(ECHO_DRIVER_DONE) +add_sfnt_module: + $(OPEN_DRIVER)sfnt_module_class$(CLOSE_DRIVER) + $(ECHO_DRIVER)sfnt $(ECHO_DRIVER_DESC)helper module for TrueType & OpenType formats$(ECHO_DRIVER_DONE) # EOF diff --git a/src/sfnt/sfdriver.c b/src/sfnt/sfdriver.c index 81bdb02c9..61b726a08 100644 --- a/src/sfnt/sfdriver.c +++ b/src/sfnt/sfdriver.c @@ -25,7 +25,6 @@ #include #include - static void* get_sfnt_table( TT_Face face, FT_Sfnt_Tag tag ) @@ -72,13 +71,13 @@ static - FTDriver_Interface SFNT_Get_Interface( FT_Driver driver, - const char* interface ) + FT_Module_Interface SFNT_Get_Interface( FT_Module module, + const char* interface ) { - UNUSED( driver ); + UNUSED( module ); if ( strcmp( interface, "get_sfnt" ) == 0 ) - return (FTDriver_Interface)get_sfnt_table; + return (FT_Module_Interface)get_sfnt_table; return 0; } @@ -140,22 +139,22 @@ }; - const FT_DriverInterface sfnt_driver_interface = + const FT_Module_Class sfnt_module_class = { - sizeof ( FT_DriverRec ), 0, 0, 0, - - "sfnt", /* driver name */ - 1, /* driver version */ - 2, /* driver requires FreeType 2 or higher */ - - (void*)&sfnt_interface, - - 0, 0, 0, - 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, - 0, + 0, /* not a font driver or renderer */ + sizeof( FT_ModuleRec ), + + "sfnt", /* driver name */ + 0x10000, /* driver version 1.0 */ + 0x20000, /* driver requires FreeType 2.0 or higher */ + + (const void*)&sfnt_interface, /* module specific interface */ + + (FT_Module_Constructor) 0, + (FT_Module_Destructor) 0, + (FT_Module_Requester) SFNT_Get_Interface }; + /* END */ diff --git a/src/sfnt/sfdriver.h b/src/sfnt/sfdriver.h index 44d5a5579..cfd1a2a3a 100644 --- a/src/sfnt/sfdriver.h +++ b/src/sfnt/sfdriver.h @@ -19,10 +19,9 @@ #ifndef SFDRIVER_H #define SFDRIVER_H -#include -#include +#include - FT_EXPORT_VAR(const FT_DriverInterface) sfnt_driver_interface; + FT_EXPORT_VAR(const FT_Module_Class) sfnt_module_class; #endif /* SFDRIVER_H */ diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c index 3b0f654b7..4b38c2c3c 100644 --- a/src/sfnt/sfobjs.c +++ b/src/sfnt/sfobjs.c @@ -180,30 +180,18 @@ FT_Parameter* params ) { FT_Error error; + FT_Library library = face->root.driver->root.library; SFNT_Interface* sfnt; - PSNames_Interface* psnames; SFNT_Header sfnt_header; /* for now, parameters are unused */ UNUSED( num_params ); UNUSED( params ); - sfnt = (SFNT_Interface*)face->sfnt; if ( !sfnt ) { - /* look-up the SFNT driver */ - FT_Driver sfnt_driver; - - - sfnt_driver = FT_Get_Driver( face->root.driver->library, "sfnt" ); - if ( !sfnt_driver ) - { - error = FT_Err_Invalid_File_Format; - goto Exit; - } - - sfnt = (SFNT_Interface*)( sfnt_driver->interface.format_interface ); + sfnt = (SFNT_Interface*)FT_Get_Module_Interface( library, "sfnt" ); if ( !sfnt ) { error = FT_Err_Invalid_File_Format; @@ -214,17 +202,10 @@ face->goto_table = sfnt->goto_table; } - psnames = (PSNames_Interface*)face->psnames; - if ( !psnames ) + if ( !face->psnames ) { - /* look-up the PSNames driver */ - FT_Driver psnames_driver; - - - psnames_driver = FT_Get_Driver( face->root.driver->library, "psnames" ); - if ( psnames_driver ) - face->psnames = (PSNames_Interface*) - ( psnames_driver->interface.format_interface ); + face->psnames = (PSNames_Interface*) + FT_Get_Module_Interface( library, "psnames" ); } /* check that we have a valid TrueType file */ diff --git a/src/sfnt/ttcmap.c b/src/sfnt/ttcmap.c index 1a5cbba3d..d10ca084c 100644 --- a/src/sfnt/ttcmap.c +++ b/src/sfnt/ttcmap.c @@ -59,7 +59,7 @@ /* table :: A pointer to a cmap object. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ /* */ /* The function assumes that the stream is already in use (i.e., */ @@ -281,7 +281,7 @@ /* cmap :: A handle to a cmap object. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error TT_CharMap_Free( TT_Face face, @@ -293,7 +293,7 @@ if ( !cmap ) return TT_Err_Ok; - memory = face->root.driver->memory; + memory = face->root.driver->root.memory; switch ( cmap->format ) { diff --git a/src/sfnt/ttload.c b/src/sfnt/ttload.c index 94e4171f3..c954ec461 100644 --- a/src/sfnt/ttload.c +++ b/src/sfnt/ttload.c @@ -96,7 +96,7 @@ /* length :: The length of the table if found, undefined otherwise. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error TT_Goto_Table( TT_Face face, @@ -141,7 +141,7 @@ /* sfnt :: The SFNT header. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ /* */ /* The stream cursor must be at the font file's origin. */ @@ -275,7 +275,7 @@ /* sfnt :: The SFNT directory header. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ /* */ /* The stream cursor must be at the font file's origin. */ @@ -373,7 +373,7 @@ /* buffer :: The address of target buffer. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error TT_Load_Any( TT_Face face, @@ -436,7 +436,7 @@ /* stream :: The input stream. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error TT_Load_Header( TT_Face face, @@ -507,7 +507,7 @@ /* stream :: The input stream. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error TT_Load_MaxProfile( TT_Face face, @@ -597,7 +597,7 @@ /* vertical :: A boolean flag. If set, load vertical metrics. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ static FT_Error TT_Load_Metrics( TT_Face face, @@ -733,7 +733,7 @@ /* vertical :: A boolean flag. If set, load vertical metrics. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error TT_Load_Metrics_Header( TT_Face face, @@ -829,7 +829,7 @@ /* stream :: The input stream. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error TT_Load_Names( TT_Face face, @@ -990,7 +990,7 @@ LOCAL_FUNC void TT_Free_Names( TT_Face face ) { - FT_Memory memory = face->root.driver->memory; + FT_Memory memory = face->root.driver->root.memory; TT_NameTable* names = &face->name_table; @@ -1020,7 +1020,7 @@ /* stream :: A handle to the input stream. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error TT_Load_CMap( TT_Face face, @@ -1129,7 +1129,7 @@ /* stream :: A handle to the input stream. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error TT_Load_OS2( TT_Face face, @@ -1263,7 +1263,7 @@ /* stream :: A handle to the input stream. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error TT_Load_PostScript( TT_Face face, @@ -1318,7 +1318,7 @@ /* stream :: A handle to the input stream. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error TT_Load_PCLT( TT_Face face, @@ -1389,7 +1389,7 @@ /* stream :: The input stream. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error TT_Load_Gasp( TT_Face face, @@ -1461,7 +1461,7 @@ /* stream :: The input stream. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error TT_Load_Kern( TT_Face face, @@ -1566,7 +1566,7 @@ /* stream :: A handle to the input stream. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error TT_Load_Hdmx( TT_Face face, @@ -1652,7 +1652,7 @@ if ( face ) { FT_Int n; - FT_Memory memory = face->root.driver->memory; + FT_Memory memory = face->root.driver->root.memory; for ( n = 0; n < face->hdmx.num_records; n++ ) diff --git a/src/sfnt/ttpost.c b/src/sfnt/ttpost.c index 8fad70562..513078295 100644 --- a/src/sfnt/ttpost.c +++ b/src/sfnt/ttpost.c @@ -427,7 +427,7 @@ /* You must not modify the returned string! */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error TT_Get_PS_Name( TT_Face face, diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c index 9768e63be..ecfb88e69 100644 --- a/src/sfnt/ttsbit.c +++ b/src/sfnt/ttsbit.c @@ -211,7 +211,7 @@ /* stream :: The input stream. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ static FT_Error Load_SBit_Const_Metrics( TT_SBit_Range* range, @@ -243,7 +243,7 @@ /* load_offsets :: A flag whether to load the glyph offset table. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ static FT_Error Load_SBit_Range_Codes( TT_SBit_Range* range, @@ -306,7 +306,7 @@ /* stream :: The input stream. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ static FT_Error Load_SBit_Range( TT_SBit_Range* range, @@ -381,7 +381,7 @@ /* stream :: The input stream. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error TT_Load_SBit_Strikes( TT_Face face, @@ -631,7 +631,7 @@ /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */ /* */ /* */ - /* FreeType error code. 0 means the glyph index was found. */ + /* TrueType error code. 0 means the glyph index was found. */ /* */ static FT_Error Find_SBit_Range( FT_UInt glyph_index, @@ -735,7 +735,7 @@ /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */ /* */ /* */ - /* FreeType error code. 0 means success. Returns */ + /* TrueType error code. 0 means success. Returns */ /* TT_Err_Invalid_Argument if no sbit exists for the requested glyph. */ /* */ static @@ -800,7 +800,7 @@ /* big_metrics :: A big SBit metrics structure for the glyph. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ /* */ /* The stream cursor must be positioned at the glyph's offset within */ @@ -1349,7 +1349,7 @@ /* metrics :: A big sbit metrics structure for the glyph image. */ /* */ /* */ - /* FreeType error code. 0 means success. Returns an error if no */ + /* TrueType error code. 0 means success. Returns an error if no */ /* glyph sbit exists for the index. */ /* */ /* */ diff --git a/src/truetype/module.mk b/src/truetype/module.mk index 0a2d6b1ca..79072bb54 100644 --- a/src/truetype/module.mk +++ b/src/truetype/module.mk @@ -1,7 +1,7 @@ make_module_list: add_truetype_driver add_truetype_driver: - $(OPEN_DRIVER)tt_driver_interface$(CLOSE_DRIVER) + $(OPEN_DRIVER)tt_driver_class$(CLOSE_DRIVER) $(ECHO_DRIVER)truetype $(ECHO_DRIVER_DESC)Windows/Mac font files with extension *.ttf or *.ttc$(ECHO_DRIVER_DONE) # EOF diff --git a/src/truetype/ttdriver.c b/src/truetype/ttdriver.c index 635521ee2..e118997a0 100644 --- a/src/truetype/ttdriver.c +++ b/src/truetype/ttdriver.c @@ -75,7 +75,7 @@ /* formats. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ /* */ /* Only horizontal layouts (left-to-right & right-to-left) are */ @@ -178,7 +178,7 @@ /* size :: A handle to the target size object. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ static FT_Error Set_Char_Sizes( TT_Size size, @@ -238,7 +238,7 @@ /* size :: A handle to the target size object. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ static FT_Error Set_Pixel_Sizes( TT_Size size, @@ -280,7 +280,7 @@ /* whether to hint the outline, etc). */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ static FT_Error Load_Glyph( TT_GlyphSlot slot, @@ -398,19 +398,18 @@ static - FTDriver_Interface tt_get_interface( TT_Driver driver, - const char* interface ) + FT_Module_Interface tt_get_interface( TT_Driver driver, + const char* interface ) { - FT_Driver sfntd = FT_Get_Driver( driver->root.library, "sfnt" ); + FT_Module sfntd = FT_Get_Module( driver->root.root.library, "sfnt" ); SFNT_Interface* sfnt; - /* only return the default interface from the SFNT module */ if ( sfntd ) { - sfnt = (SFNT_Interface*)(sfntd->interface.format_interface); + sfnt = (SFNT_Interface*)(sfntd->clazz->module_interface); if ( sfnt ) - return sfnt->get_interface( (FT_Driver)driver, interface ); + return sfnt->get_interface( FT_MODULE(driver), interface ); } return 0; @@ -419,37 +418,45 @@ /* The FT_DriverInterface structure is defined in ftdriver.h. */ - const FT_DriverInterface tt_driver_interface = + const FT_Driver_Class tt_driver_class = { - sizeof ( TT_DriverRec ), + { + ft_module_font_driver | ft_module_driver_scalable, + sizeof ( TT_DriverRec ), + + "truetype", /* driver name */ + 0x10000, /* driver version == 1.0 */ + 0x20000, /* driver requires FreeType 2.0 or above */ + + (void*)0, /* driver specific interface */ + + (FT_Module_Constructor) TT_Init_Driver, + (FT_Module_Destructor) TT_Done_Driver, + (FT_Module_Requester) tt_get_interface, + }, + sizeof ( TT_FaceRec ), sizeof ( TT_SizeRec ), sizeof ( FT_GlyphSlotRec ), - "truetype", /* driver name */ - 100, /* driver version == 1.0 */ - 200, /* driver requires FreeType 2.0 or above */ - - (void*)0, - - (FTDriver_initDriver) TT_Init_Driver, - (FTDriver_doneDriver) TT_Done_Driver, - (FTDriver_getInterface) tt_get_interface, (FTDriver_initFace) TT_Init_Face, (FTDriver_doneFace) TT_Done_Face, - (FTDriver_getKerning) Get_Kerning, - (FTDriver_initSize) TT_Init_Size, (FTDriver_doneSize) TT_Done_Size, + (FTDriver_initGlyphSlot) 0, + (FTDriver_doneGlyphSlot) 0, + (FTDriver_setCharSizes) Set_Char_Sizes, (FTDriver_setPixelSizes) Set_Pixel_Sizes, - - (FTDriver_initGlyphSlot) TT_Init_GlyphSlot, - (FTDriver_doneGlyphSlot) TT_Done_GlyphSlot, (FTDriver_loadGlyph) Load_Glyph, - (FTDriver_getCharIndex) Get_Char_Index, + + (FTDriver_getKerning) Get_Kerning, + (FTDriver_attachFile) 0, + (FTDriver_getAdvances) 0 + + }; @@ -475,9 +482,9 @@ /* format-specific interface can then be retrieved through the method */ /* interface->get_format_interface. */ /* */ - EXPORT_FUNC( FT_DriverInterface* ) getDriverInterface( void ) + EXPORT_FUNC( const FT_Driver_Class* ) getDriverClass( void ) { - return &tt_driver_interface; + return &tt_driver_class; } diff --git a/src/truetype/ttdriver.h b/src/truetype/ttdriver.h index 5d9481765..145d42064 100644 --- a/src/truetype/ttdriver.h +++ b/src/truetype/ttdriver.h @@ -25,7 +25,7 @@ #include - FT_EXPORT_VAR( const FT_DriverInterface ) tt_driver_interface; + FT_EXPORT_VAR( const FT_Driver_Class ) tt_driver_class; #endif /* TTDRIVER_H */ diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c index 181a5a1be..1d455ccbd 100644 --- a/src/truetype/ttgload.c +++ b/src/truetype/ttgload.c @@ -174,30 +174,18 @@ } - /*************************************************************************/ - /* */ - /* Mounts one glyph zone on top of another. This is needed to */ - /* assemble composite glyphs. */ - /* */ - static - void mount_zone( TT_GlyphZone* source, - TT_GlyphZone* target ) + static void tt_prepare_zone( TT_GlyphZone* zone, + FT_GlyphLoad* load, + FT_UInt start_point, + FT_UInt start_contour ) { - FT_UInt np; - FT_Int nc; - - np = source->n_points; - nc = source->n_contours; - - target->org = source->org + np; - target->cur = source->cur + np; - target->tags = source->tags + np; - - target->contours = source->contours + nc; - - target->n_points = 0; - target->n_contours = 0; - } + zone->n_points = load->outline.n_points - start_point; + zone->n_contours = load->outline.n_contours - start_contour; + zone->org = load->extra_points + start_point; + zone->cur = load->outline.points + start_point; + zone->tags = (FT_Byte*)load->outline.tags + start_point; + zone->contours = (FT_UShort*)load->outline.contours + start_contour; + } #undef IS_HINTED @@ -220,54 +208,43 @@ FT_Int n_contours, FT_Bool debug ) { - FT_Error error; - FT_Stream stream = load->stream; - TT_GlyphZone* zone = &load->zone; - TT_Face face = load->face; + FT_Error error; + FT_Stream stream = load->stream; + FT_GlyphLoader* gloader = load->gloader; + FT_Outline* outline; + TT_GlyphZone* zone = &load->zone; + TT_Face face = load->face; - FT_UShort n_ins; - FT_Int n, n_points; + FT_UShort n_ins; + FT_Int n, n_points; - /* simple check */ - - if ( n_contours > load->left_contours ) - { - FT_TRACE0(( "ERROR: Glyph index %ld has %d contours > left %d\n", - load->glyph_index, - n_contours, - load->left_contours )); - return TT_Err_Too_Many_Contours; - } - - /* preparing the execution context */ - mount_zone( &load->base, zone ); - - /* reading the contours endpoints */ - if ( ACCESS_Frame( byte_count ) ) return error; - for ( n = 0; n < n_contours; n++ ) - zone->contours[n] = GET_UShort(); + /* reading the contours endpoints & number of points */ + { + short* cur = gloader->current.outline.contours; + short* limit = cur + n_contours; + + for ( ; cur < limit; cur++ ) + cur[0] = GET_UShort(); + + n_points = 0; + if (n_contours > 0) + n_points = cur[-1]+1; + + error = FT_GlyphLoader_Check_Points( gloader, n_points+2, 0 ); + if (error) goto Fail; + + outline = &gloader->current.outline; + } - n_points = 0; - if ( n_contours > 0 ) - n_points = zone->contours[n_contours - 1] + 1; /* reading the bytecode instructions */ - n_ins = GET_UShort(); load->face->root.glyph->control_len = n_ins; - if ( n_points > load->left_points ) - { - FT_TRACE0(( "ERROR: Too many points in glyph %ld\n", - load->glyph_index )); - error = TT_Err_Too_Many_Points; - goto Fail; - } - FT_TRACE5(( " Instructions size: %d\n", n_ins )); if ( n_ins > face->max_profile.maxSizeOfInstructions ) @@ -302,11 +279,10 @@ /* reading the point tags */ { - FT_Byte* flag = load->zone.tags; + FT_Byte* flag = (FT_Byte*)outline->tags; FT_Byte* limit = flag + n_points; FT_Byte c, count; - for ( ; flag < limit; flag++ ) { *flag = c = GET_Byte(); @@ -321,9 +297,9 @@ /* reading the X coordinates */ { - FT_Vector* vec = zone->org; + FT_Vector* vec = outline->points; FT_Vector* limit = vec + n_points; - FT_Byte* flag = zone->tags; + FT_Byte* flag = (FT_Byte*)outline->tags; FT_Pos x = 0; @@ -349,9 +325,9 @@ /* reading the Y coordinates */ { - FT_Vector* vec = zone->org; + FT_Vector* vec = gloader->current.outline.points; FT_Vector* limit = vec + n_points; - FT_Byte* flag = zone->tags; + FT_Byte* flag = (FT_Byte*)outline->tags; FT_Pos x = 0; @@ -387,7 +363,7 @@ /* pp1 = xMin - lsb */ - pp1 = zone->org + n_points; + pp1 = outline->points + n_points; pp1->x = load->bbox.xMin - load->left_bearing; pp1->y = 0; @@ -398,74 +374,67 @@ /* clear the touch tags */ for ( n = 0; n < n_points; n++ ) - zone->tags[n] &= FT_Curve_Tag_On; + outline->tags[n] &= FT_Curve_Tag_On; - zone->tags[n_points ] = 0; - zone->tags[n_points + 1] = 0; + outline->tags[n_points ] = 0; + outline->tags[n_points + 1] = 0; } /* Note that we return two more points that are not */ /* part of the glyph outline. */ - zone->n_points = n_points; - zone->n_contours = n_contours; - n_points += 2; + outline->n_points = n_points; + outline->n_contours = n_contours; + n_points += 2; - /* now eventually scale and hint the glyph */ + /* set up zone for hinting */ + tt_prepare_zone( zone, &gloader->current, 0, 0 ); - if ( load->load_flags & FT_LOAD_NO_SCALE ) + /* eventually scale the glyph */ + if (!(load->load_flags & FT_LOAD_NO_SCALE)) { - /* no scaling, just copy the orig arrays into the cur ones */ - org_to_cur( n_points, zone ); - } - else - { - FT_Vector* vec = zone->org; - FT_Vector* limit = vec + n_points; + FT_Vector* vec = zone->cur; + FT_Vector* limit = vec + n_points; FT_Fixed x_scale = load->size->root.metrics.x_scale; FT_Fixed y_scale = load->size->root.metrics.y_scale; - /* first scale the glyph points */ for ( ; vec < limit; vec++ ) { vec->x = FT_MulFix( vec->x, x_scale ); vec->y = FT_MulFix( vec->y, y_scale ); } + } - /* if hinting, round pp1, and shift the glyph accordingly */ - if ( !IS_HINTED( load->load_flags ) ) - { - org_to_cur( n_points, zone ); - } - else - { - FT_Pos x = zone->org[n_points-2].x; + cur_to_org( n_points, zone ); + /* eventually hint the glyph */ + if ( IS_HINTED(load->load_flags) ) + { + FT_Pos x = zone->org[n_points-2].x; - x = ( ( x + 32 ) & -64 ) - x; - translate_array( n_points, zone->org, x, 0 ); + x = ( ( x + 32 ) & -64 ) - x; + translate_array( n_points, zone->org, x, 0 ); - org_to_cur( n_points, zone ); + org_to_cur( n_points, zone ); - zone->cur[n_points - 1].x = ( zone->cur[n_points - 1].x + 32 ) & -64; + zone->cur[n_points - 1].x = ( zone->cur[n_points - 1].x + 32 ) & -64; #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - /* now consider hinting */ - if ( n_ins > 0 ) - { - load->exec->is_composite = FALSE; - load->exec->pedantic_hinting = (FT_Bool)(load->load_flags & - FT_LOAD_PEDANTIC); - load->exec->pts = *zone; - load->exec->pts.n_points += 2; + /* now consider hinting */ + if ( n_ins > 0 ) + { + load->exec->is_composite = FALSE; + load->exec->pedantic_hinting = (FT_Bool)(load->load_flags & + FT_LOAD_PEDANTIC); + load->exec->pts = *zone; + load->exec->pts.n_points += 2; - error = TT_Run_Context( load->exec, debug ); - if ( error && load->exec->pedantic_hinting ) - return error; - } -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + error = TT_Run_Context( load->exec, debug ); + if ( error && load->exec->pedantic_hinting ) + return error; } +#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ } /* save glyph phantom points */ @@ -475,7 +444,7 @@ load->pp2 = zone->cur[n_points - 1]; } - return TT_Err_Ok; + return FT_Err_Ok; Fail: FORGET_Frame(); @@ -496,14 +465,15 @@ FT_Error load_truetype_glyph( TT_Loader* loader, FT_UInt glyph_index ) { - FT_Stream stream = loader->stream; - FT_Error error; - TT_Face face = loader->face; - FT_ULong offset; - FT_Int num_subglyphs = 0, contours_count; - FT_UInt index, num_points, num_contours, count; - FT_Fixed x_scale, y_scale; - FT_ULong ins_offset; + FT_Stream stream = loader->stream; + FT_Error error; + TT_Face face = loader->face; + FT_ULong offset; + FT_Int num_subglyphs = 0, contours_count; + FT_UInt index, num_points, num_contours, count; + FT_Fixed x_scale, y_scale; + FT_ULong ins_offset; + FT_GlyphLoader* gloader = loader->gloader; /* check glyph index */ @@ -596,13 +566,6 @@ count -= 10; - if ( contours_count > loader->left_contours ) - { - FT_TRACE0(( "ERROR: Too many contours for glyph %ld\n", index )); - error = TT_Err_Too_Many_Contours; - goto Fail; - } - loader->pp1.x = loader->bbox.xMin - loader->left_bearing; loader->pp1.y = 0; loader->pp2.x = loader->pp1.x + loader->advance; @@ -622,8 +585,9 @@ if ( contours_count >= 0 ) { - FT_UInt num_base_points; - + /* check that we can add the contours to the glyph */ + error = FT_GlyphLoader_Check_Points( gloader, 0, contours_count ); + if (error) goto Fail; #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER error = Load_Simple( loader, @@ -634,31 +598,12 @@ #else error = Load_Simple( loader, count, contours_count, 0 ); #endif - if ( error ) - goto Fail; + if ( error ) goto Fail; + + FT_GlyphLoader_Add( gloader ); /* Note: We could have put the simple loader source there */ /* but the code is fat enough already :-) */ - num_points = loader->zone.n_points; - num_contours = loader->zone.n_contours; - - num_base_points = loader->base.n_points; - { - FT_UInt k; - - - for ( k = 0; k < num_contours; k++ ) - loader->zone.contours[k] += num_base_points; - } - - loader->base.n_points += num_points; - loader->base.n_contours += num_contours; - - loader->zone.n_points = 0; - loader->zone.n_contours = 0; - - loader->left_points -= num_points; - loader->left_contours -= num_contours; } /***********************************************************************/ @@ -669,9 +614,14 @@ else { /* for each subglyph, read composite header */ - TT_GlyphSlot glyph = loader->glyph; - FT_SubGlyph* subglyph = glyph->subglyphs + glyph->num_subglyphs; + TT_GlyphSlot glyph = loader->glyph; + FT_SubGlyph* subglyph; + FT_UInt num_base_subgs; + FT_UInt start_point, start_contour; + start_point = gloader->base.outline.n_points; + start_contour = gloader->base.outline.n_contours; + if ( ACCESS_Frame( count ) ) goto Fail; @@ -679,28 +629,12 @@ do { FT_Fixed xx, xy, yy, yx; - FT_UInt total_subglyphs; - - /* grow the `glyph->subglyphs' table if necessary */ - total_subglyphs = glyph->num_subglyphs + num_subglyphs; - - if ( total_subglyphs >= glyph->max_subglyphs ) - { - FT_UInt new_max = glyph->max_subglyphs; - FT_Memory memory = loader->face->root.memory; - - - while ( new_max <= total_subglyphs ) - new_max += 4; - - if ( REALLOC_ARRAY( glyph->subglyphs, glyph->max_subglyphs, - new_max, FT_SubGlyph ) ) - goto Fail; - - glyph->max_subglyphs = new_max; - subglyph = glyph->subglyphs + glyph->num_subglyphs + num_subglyphs; - } + /* check that we can load a new subglyph */ + error = FT_GlyphLoader_Check_Subglyphs( gloader, num_subglyphs+1 ); + if (error) goto Fail; + + subglyph = gloader->current.subglyphs + num_subglyphs; subglyph->arg1 = subglyph->arg2 = 0; @@ -746,11 +680,12 @@ subglyph->transform.yx = yx; subglyph->transform.yy = yy; - subglyph++; num_subglyphs++; } - while (subglyph[-1].flags & MORE_COMPONENTS); + while (subglyph->flags & MORE_COMPONENTS); + gloader->current.num_subglyphs = num_subglyphs; + #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER { /* we must undo the ACCESS_Frame in order to point to the */ @@ -769,8 +704,12 @@ if ( loader->load_flags & FT_LOAD_NO_RECURSE ) { /* set up remaining glyph fields */ - glyph->num_subglyphs += num_subglyphs; + FT_GlyphLoader_Add( gloader ); + + glyph->num_subglyphs = gloader->base.num_subglyphs; glyph->format = ft_glyph_format_composite; + glyph->subglyphs = gloader->base.subglyphs; + goto Load_End; } @@ -784,25 +723,32 @@ { FT_Int n, num_base_points, num_new_points; - subglyph = glyph->subglyphs + glyph->num_subglyphs; - glyph->num_subglyphs += num_subglyphs; - - - for ( n = 0; n < num_subglyphs; n++, subglyph++ ) + num_base_subgs = gloader->base.num_subglyphs; + + FT_GlyphLoader_Add( gloader ); + + for ( n = 0; n < num_subglyphs; n++ ) { FT_Vector pp1, pp2; FT_Pos x, y; + /* each time we call load_truetype_glyph in this loop, the */ + /* value of 'gloader.base.subglyphs' can change due to table */ + /* reallocations. We thus need to recompute the subglyph */ + /* pointer on each iteration.. */ + subglyph = gloader->base.subglyphs + num_base_subgs + n; pp1 = loader->pp1; pp2 = loader->pp2; - num_base_points = loader->base.n_points; + num_base_points = gloader->base.outline.n_points; error = load_truetype_glyph( loader, subglyph->index ); if ( error ) goto Fail; + subglyph = gloader->base.subglyphs + num_base_subgs + n; + if ( subglyph->flags & USE_MY_METRICS ) { pp1 = loader->pp1; @@ -814,8 +760,7 @@ loader->pp2 = pp2; } - num_points = loader->base.n_points; - num_contours = loader->base.n_contours; + num_points = gloader->base.outline.n_points; num_new_points = num_points - num_base_points; @@ -825,33 +770,14 @@ WE_HAVE_AN_XY_SCALE | WE_HAVE_A_2X2 ) ) { - FT_Vector* cur = loader->zone.cur; - FT_Vector* org = loader->zone.org; + FT_Vector* cur = gloader->base.outline.points + num_base_points; + FT_Vector* org = gloader->base.extra_points + num_base_points; FT_Vector* limit = cur + num_new_points; - for ( ; cur < limit; cur++, org++ ) { - FT_Pos nx, ny; - - - nx = FT_MulFix( cur->x, subglyph->transform.xx ) + - FT_MulFix( cur->y, subglyph->transform.yx ); - - ny = FT_MulFix( cur->x, subglyph->transform.xy ) + - FT_MulFix( cur->y, subglyph->transform.yy ); - - cur->x = nx; - cur->y = ny; - - nx = FT_MulFix( org->x, subglyph->transform.xx ) + - FT_MulFix( org->y, subglyph->transform.yx ); - - ny = FT_MulFix( org->x, subglyph->transform.xy ) + - FT_MulFix( org->y, subglyph->transform.yy ); - - org->x = nx; - org->y = ny; + FT_Vector_Transform( cur, &subglyph->transform ); + FT_Vector_Transform( org, &subglyph->transform ); } } @@ -859,12 +785,13 @@ if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) ) { - FT_Int k = subglyph->arg1; - FT_UInt l = subglyph->arg2; + FT_Int k = subglyph->arg1; + FT_UInt l = subglyph->arg2; + FT_Vector* p1; + FT_Vector* p2; - - if ( k >= num_base_points || - l >= (FT_UInt)num_new_points ) + if ( start_point + k >= num_base_points || + l >= (FT_UInt)num_new_points ) { error = TT_Err_Invalid_Composite; goto Fail; @@ -872,8 +799,11 @@ l += num_base_points; - x = loader->base.cur[k].x - loader->base.cur[l].x; - y = loader->base.cur[k].y - loader->base.cur[l].y; + p1 = gloader->base.outline.points + start_point + k; + p2 = gloader->base.outline.points + start_point + l; + + x = p1->x - p2->x; + y = p1->y - p2->y; } else { @@ -906,7 +836,6 @@ #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - subglyph--; if ( num_subglyphs > 0 && loader->exec && subglyph->flags & WE_HAVE_INSTR ) @@ -949,8 +878,8 @@ goto Fail; /* prepare the execution context */ - exec->pts = loader->base; - pts = &exec->pts; + tt_prepare_zone( &exec->pts, &gloader->base, start_point, start_contour ); + pts = &exec->pts; pts->n_points = num_points + 2; pts->n_contours = num_contours; @@ -1007,7 +936,7 @@ /***********************************************************************/ Load_End: - error = TT_Err_Ok; + error = FT_Err_Ok; Fail: return error; @@ -1018,24 +947,12 @@ void compute_glyph_metrics( TT_Loader* loader, FT_UInt glyph_index ) { - FT_UInt num_points = loader->base.n_points; - FT_UInt num_contours = loader->base.n_contours; FT_BBox bbox; TT_Face face = loader->face; FT_Fixed x_scale, y_scale; TT_GlyphSlot glyph = loader->glyph; TT_Size size = loader->size; - - /* when a simple glyph was loaded, the value of */ - /* `base.n_points' and `base.n_contours' is 0, we will */ - /* take those in the `zone' instead. */ - if ( num_points == 0 && num_contours == 0 ) - { - num_points = loader->zone.n_points; - num_contours = loader->zone.n_contours; - } - x_scale = 0x10000L; y_scale = 0x10000L; if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) @@ -1046,27 +963,14 @@ if ( glyph->format != ft_glyph_format_composite ) { - FT_UInt u; - - - for ( u = 0; u < num_points + 2; u++ ) - { - glyph->outline.points[u] = loader->base.cur[u]; - glyph->outline.tags [u] = loader->base.tags[u]; - } - - for ( u = 0; u < num_contours; u++ ) - glyph->outline.contours[u] = loader->base.contours[u]; - - glyph->outline.flags &= ~ft_outline_single_pass; - glyph->outline.n_points = num_points; - glyph->outline.n_contours = num_contours; + glyph->outline.flags &= ~ft_outline_single_pass; + /* copy outline to our glyph slot */ + FT_GlyphLoader_Copy_Points( glyph->loader, loader->gloader ); + glyph->outline = glyph->loader->base.outline; + /* translate array so that (0,0) is the glyph's origin */ - translate_array( (FT_UShort)( num_points + 2 ), - glyph->outline.points, - -loader->pp1.x, - 0 ); + FT_Outline_Translate( &glyph->outline, -loader->pp1.x, 0 ); FT_Outline_Get_CBox( &glyph->outline, &bbox ); @@ -1082,17 +986,10 @@ else bbox = loader->bbox; - /* get the device-independent scaled horizontal metrics; */ - /* take care of fixed-pitch fonts... */ + /* get the device-independent horizontal advance. It is scaled later */ + /* by the base layer.. */ { - FT_Pos left_bearing; - FT_Pos advance; - - FT_Pos lsb2, adv2; - - - left_bearing = loader->left_bearing; - advance = loader->advance; + FT_Pos advance = loader->advance; /* the flag FT_LOAD_NO_ADVANCE_CHECK was introduced to */ /* correctly support DynaLab fonts, which have an incorrect */ @@ -1103,23 +1000,9 @@ ( loader->load_flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ) == 0 ) advance = face->horizontal.advance_Width_Max; - lsb2 = left_bearing; - adv2 = advance; - - /* if necessary, scale the horizontal left bearing and advance */ - /* to get their values in 16.16 format.. */ - if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) && - loader->load_flags & FT_LOAD_LINEAR ) - { - FT_Pos em_size = face->root.units_per_EM; - FT_Pos pixel_size = (FT_Pos)face->root.size->metrics.x_ppem << 16; - - - lsb2 = FT_MulDiv( lsb2, pixel_size, em_size ); - adv2 = FT_MulDiv( adv2, pixel_size, em_size ); - } - glyph->metrics2.horiBearingX = lsb2; - glyph->metrics2.horiAdvance = adv2; + /* we need to return the advance in font units in linearHoriAdvance, */ + /* it will be scaled later by the base layer.. */ + glyph->linearHoriAdvance = advance; } glyph->metrics.horiBearingX = bbox.xMin; @@ -1184,7 +1067,7 @@ /* We must adjust the top_bearing value from the bounding box given */ /* in the glyph header to te bounding box calculated with */ - /* TT_Get_Outline_BBox(). */ + /* FT_Get_Outline_CBox(). */ /* scale the metrics */ if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) ) @@ -1201,27 +1084,9 @@ advance = advance_height; } - /* compute metrics2 fields */ - { - FT_Pos vtb2 = top_bearing; - FT_Pos adv2 = advance_height; - - - /* scale to 16.16 format if required */ - if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) && - loader->load_flags & FT_LOAD_LINEAR ) - { - FT_Pos em_size = face->root.units_per_EM; - FT_Pos pixel_size = face->root.size->metrics.y_ppem; - - - vtb2 = FT_MulDiv( vtb2, pixel_size, em_size ); - adv2 = FT_MulDiv( adv2, pixel_size, em_size ); - } - - glyph->metrics2.vertBearingY = vtb2; - glyph->metrics2.vertAdvance = adv2; - } + /* set the advance height in design units. It is scaled later by the */ + /* base layer.. */ + glyph->linearVertAdvance = advance_height; /* XXX: for now, we have no better algorithm for the lsb, but it */ /* should work fine. */ @@ -1251,16 +1116,6 @@ glyph->metrics.horiAdvance = widths[glyph_index] << 6; } -/* drop-out mode is irrelevant, we always use mode 2 */ -#if 0 -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - if ( loader->exec ) - glyph->outline.dropout_mode = (FT_Char)loader->exec->GS.scan_type; -#else - glyph->outline.dropout_mode = 2; -#endif -#endif - /* set glyph dimensions */ glyph->metrics.width = bbox.xMax - bbox.xMin; glyph->metrics.height = bbox.yMax - bbox.yMin; @@ -1293,7 +1148,7 @@ /* whether to hint the outline, etc). */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error TT_Load_Glyph( TT_Size size, @@ -1307,7 +1162,6 @@ FT_Memory memory; FT_Error error; TT_Loader loader; - TT_GlyphZone* zone; face = (TT_Face)glyph->face; @@ -1362,15 +1216,22 @@ glyph->metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6; glyph->format = ft_glyph_format_bitmap; + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + { + glyph->bitmap_left = metrics.horiBearingX; + glyph->bitmap_top = metrics.horiBearingY; + } + else + { + glyph->bitmap_left = metrics.vertBearingX; + glyph->bitmap_top = metrics.vertBearingY; + } return error; } } #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - if ( load_flags & FT_LOAD_NO_OUTLINE ) - return ( error ? error : TT_Err_Unavailable_Bitmap ); - /* seek to the beginning of the glyph table. For Type 43 fonts */ /* the table might be accessed from a Postscript stream or something */ /* else... */ @@ -1385,19 +1246,16 @@ MEM_Set( &loader, 0, sizeof ( loader ) ); /* update the glyph zone bounds */ - zone = &((TT_Driver)face->root.driver)->zone; - error = TT_Update_GlyphZone( zone, - face->root.max_points, - face->root.max_contours ); - if ( error ) { - FT_ERROR(( "TT_Load_Glyph: Could not update loader glyph zone\n" )); - goto Exit; + FT_GlyphLoader* gloader = FT_FACE_DRIVER(face)->glyph_loader; + + loader.gloader = gloader; + + FT_GlyphLoader_Rewind( gloader ); + + tt_prepare_zone( &loader.zone, &gloader->base, 0, 0 ); + tt_prepare_zone( &loader.base, &gloader->base, 0, 0 ); } - loader.base = *zone; - - loader.zone.n_points = 0; - loader.zone.n_contours = 0; #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER @@ -1425,8 +1283,6 @@ /* let's initialize the rest of our loader now */ - loader.left_points = face->root.max_points; - loader.left_contours = face->root.max_contours; loader.load_flags = load_flags; loader.face = face; diff --git a/src/truetype/ttgload.h b/src/truetype/ttgload.h index 9d5432c98..c20b4c6f2 100644 --- a/src/truetype/ttgload.h +++ b/src/truetype/ttgload.h @@ -34,14 +34,13 @@ TT_Face face; TT_Size size; TT_GlyphSlot glyph; + FT_GlyphLoader* gloader; 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; diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c index cefb1af8b..d84509771 100644 --- a/src/truetype/ttinterp.c +++ b/src/truetype/ttinterp.c @@ -257,7 +257,7 @@ /* exec :: The target execution context. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error TT_Goto_CodeRange( TT_ExecContext exec, @@ -307,7 +307,7 @@ /* exec :: The target execution context. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error TT_Set_CodeRange( TT_ExecContext exec, @@ -339,7 +339,7 @@ /* exec :: The target execution context. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ /* */ /* Does not set the Error variable. */ @@ -378,7 +378,7 @@ /* memory :: A handle to the parent memory object. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ /* */ /* Only the glyph loader and debugger should call this function. */ @@ -433,7 +433,7 @@ /* exec :: A handle to the target execution context. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ static FT_Error Init_Context( TT_ExecContext exec, @@ -504,7 +504,7 @@ /* buff :: The address of the buffer base pointer. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ static FT_Error Update_Max( FT_Memory memory, @@ -546,7 +546,7 @@ /* exec :: A handle to the target execution context. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ /* */ /* Only the glyph loader and debugger should call this function. */ @@ -649,7 +649,7 @@ /* size :: A handle to the target size object. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ /* */ /* Only the glyph loader and debugger should call this function. */ @@ -696,7 +696,7 @@ /* exec :: A handle to the target execution context. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueTyoe error code. 0 means success. */ /* */ /* */ /* Only the glyph loader and debugger should call this function. */ @@ -791,7 +791,7 @@ driver = (TT_Driver)face->root.driver; - memory = driver->root.memory; + memory = driver->root.root.memory; exec = driver->context; if ( !driver->context ) @@ -834,7 +834,7 @@ /* exec :: A handle to the target execution context. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ /* */ /* Only the glyph loader and debugger should call this function. */ @@ -6781,7 +6781,7 @@ /* exec :: A handle to the target execution context. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ /* */ /* Only the object manager and debugger should call this function. */ diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c index 2ac0d2a61..a9f900e38 100644 --- a/src/truetype/ttobjs.c +++ b/src/truetype/ttobjs.c @@ -121,65 +121,6 @@ } - /*************************************************************************/ - /* */ - /* */ - /* TT_Update_GlyphZone */ - /* */ - /* */ - /* Checks the size of a zone and reallocates it if necessary. */ - /* */ - /* */ - /* newPoints :: The new capacity for points. We add two slots for */ - /* phantom points. */ - /* */ - /* newContours :: The new capacity for contours. */ - /* */ - /* */ - /* zone :: The address of the target zone. */ - /* */ - LOCAL_FUNC FT_Error TT_Update_GlyphZone( TT_GlyphZone* zone, - FT_UShort newPoints, - FT_Short newContours ) - { - FT_Error error = FT_Err_Ok; - FT_Memory memory = zone->memory; - - - newPoints += 2; - - if ( zone->max_points < newPoints ) - { - /* reallocate the points arrays */ - if ( REALLOC_ARRAY( zone->org, zone->max_points * 2, - newPoints * 2, FT_F26Dot6 ) || - REALLOC_ARRAY( zone->cur, zone->max_points * 2, - newPoints * 2, FT_F26Dot6 ) || - REALLOC_ARRAY( zone->tags, zone->max_points * 2, - newPoints, FT_Byte ) ) - goto Exit; - - zone->max_points = newPoints; - } - - if ( zone->max_contours < newContours ) - { - /* reallocate the contours array */ - if ( REALLOC_ARRAY( zone->contours, zone->max_contours, - newContours, FT_UShort ) ) - goto Exit; - - zone->max_contours = newContours; - } - - Exit: - return error; - } - - - - - /*************************************************************************/ /* */ /* */ @@ -201,7 +142,7 @@ /* face :: The newly built face object. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ LOCAL_DEF FT_Error TT_Init_Face( FT_Stream stream, @@ -211,17 +152,12 @@ FT_Parameter* params ) { FT_Error error; - FT_Driver sfnt_driver; + FT_Library library; 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; + library = face->root.driver->root.library; + sfnt = (SFNT_Interface*)FT_Get_Module_Interface( library, "sfnt" ); + if (!sfnt) goto Bad_Format; /* create input stream from resource */ if ( FILE_Seek( 0 ) ) @@ -320,7 +256,7 @@ /* size :: A handle to the size object. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ LOCAL_DEF FT_Error TT_Init_Size( TT_Size size ) @@ -396,7 +332,7 @@ /* set `face->interpreter' according to the debug hook present */ { - FT_Library library = face->root.driver->library; + FT_Library library = face->root.driver->root.library; face->interpreter = (TT_Interpreter) @@ -697,63 +633,6 @@ } - /*************************************************************************/ - /* */ - /* */ - /* TT_Init_GlyphSlot */ - /* */ - /* */ - /* The TrueType glyph slot initializer. */ - /* */ - /* */ - /* slot :: The glyph record to build. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Init_GlyphSlot( TT_GlyphSlot slot ) - { - /* allocate the outline space */ - FT_Face face = slot->face; - FT_Library library = face->driver->library; - - - FT_TRACE4(( "TT_Init_GlyphSlot: Creating outline maxp = %d, maxc = %d\n", - face->max_points, face->max_contours )); - - return FT_Outline_New( library, - face->max_points + 2, - face->max_contours, - &slot->outline ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Done_GlyphSlot */ - /* */ - /* */ - /* The TrueType glyph slot finalizer. */ - /* */ - /* */ - /* slot :: A handle to the glyph slot object. */ - /* */ - LOCAL_FUNC - void TT_Done_GlyphSlot( TT_GlyphSlot slot ) - { - FT_Library library = slot->face->driver->library; - FT_Memory memory = library->memory; - - - if ( slot->flags & ft_glyph_own_bitmap ) - FREE( slot->bitmap.buffer ); - - FT_Outline_Done( library, &slot->outline ); - return; - } - /*************************************************************************/ /* */ @@ -767,25 +646,24 @@ /* driver :: A handle to the target driver object. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ LOCAL_FUNC FT_Error TT_Init_Driver( TT_Driver driver ) { - FT_Memory memory = driver->root.memory; FT_Error error; - error = TT_New_GlyphZone( memory, 0, 0, &driver->zone ); - if ( error ) - return error; - + /* set 'extra' in glyph loader */ + error = FT_GlyphLoader_Create_Extra( FT_DRIVER(driver)->glyph_loader ); + /* init extension registry if needed */ #ifdef TT_CONFIG_OPTION_EXTEND_ENGINE - return TT_Init_Extensions( driver ); -#else - return TT_Err_Ok; + if (!error) + return TT_Init_Extensions( driver ); #endif + + return error; } @@ -809,15 +687,12 @@ TT_Done_Extensions( driver ); #endif - /* remove the loading glyph zone */ - TT_Done_GlyphZone( &driver->zone ); - #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER /* destroy the execution context */ if ( driver->context ) { - TT_Destroy_Context( driver->context, driver->root.memory ); + TT_Destroy_Context( driver->context, driver->root.root.memory ); driver->context = NULL; } diff --git a/src/truetype/ttobjs.h b/src/truetype/ttobjs.h index 698e9d794..947be8c07 100644 --- a/src/truetype/ttobjs.h +++ b/src/truetype/ttobjs.h @@ -151,10 +151,6 @@ FT_Short maxContours, TT_GlyphZone* zone ); - LOCAL_DEF FT_Error TT_Update_GlyphZone( TT_GlyphZone* zone, - FT_UShort newPoints, - FT_Short newContours ); - /*************************************************************************/ /* */ /* EXECUTION SUBTABLES */ @@ -442,17 +438,6 @@ FT_Error TT_Reset_Size( TT_Size size ); - /*************************************************************************/ - /* */ - /* GlyphSlot functions */ - /* */ - LOCAL_DEF - FT_Error TT_Init_GlyphSlot( TT_GlyphSlot slot ); - - LOCAL_DEF - void TT_Done_GlyphSlot( TT_GlyphSlot slot ); - - /*************************************************************************/ /* */ /* Driver functions */ diff --git a/src/type1/module.mk b/src/type1/module.mk index 5b057b7ed..af99eae25 100644 --- a/src/type1/module.mk +++ b/src/type1/module.mk @@ -1,6 +1,6 @@ make_module_list: add_type1_driver add_type1_driver: - $(OPEN_DRIVER)t1_driver_interface$(CLOSE_DRIVER) + $(OPEN_DRIVER)t1_driver_class$(CLOSE_DRIVER) $(ECHO_DRIVER)type1 $(ECHO_DRIVER_DESC)Postscript font files with extension *.pfa or *.pfb$(ECHO_DRIVER_DONE) diff --git a/src/type1/t1afm.h b/src/type1/t1afm.h index 1e9bba0c0..984ae945c 100644 --- a/src/type1/t1afm.h +++ b/src/type1/t1afm.h @@ -1,59 +1,47 @@ -/***************************************************************************/ -/* */ -/* t1afm.h */ -/* */ -/* AFM support for Type 1 fonts (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - +/*************************************************************************** + * + * t1afm.h - support for reading Type 1 AFM files + * + * + ***************************************************************************/ #ifndef T1AFM_H #define T1AFM_H #include +/* In this version, we only read the kerning table from the */ +/* AFM file. We may add support for ligatures a bit later.. */ - typedef struct T1_Kern_Pair_ - { - FT_UInt glyph1; - FT_UInt glyph2; - FT_Vector kerning; +typedef struct T1_Kern_Pair_ +{ + FT_UInt glyph1; + FT_UInt glyph2; + FT_Vector kerning; - } T1_Kern_Pair; - - typedef struct T1_AFM_ - { - FT_Int num_pairs; - T1_Kern_Pair* kern_pairs; - - } T1_AFM; +} T1_Kern_Pair; - LOCAL_DEF - FT_Error T1_Read_AFM( FT_Face face, - FT_Stream stream ); +typedef struct T1_AFM_ +{ + FT_Int num_pairs; + T1_Kern_Pair* kern_pairs; - LOCAL_DEF - void T1_Done_AFM( FT_Memory memory, - T1_AFM* afm ); +} T1_AFM; - LOCAL_DEF - void T1_Get_Kerning( T1_AFM* afm, - FT_UInt glyph1, - FT_UInt glyph2, - FT_Vector* kerning ); +LOCAL_DEF +FT_Error T1_Read_AFM( FT_Face face, + FT_Stream stream ); + +LOCAL_DEF +void T1_Done_AFM( FT_Memory memory, + T1_AFM* afm ); + +LOCAL_DEF +void T1_Get_Kerning( T1_AFM* afm, + FT_UInt glyph1, + FT_UInt glyph2, + FT_Vector* kerning ); #endif /* T1AFM_H */ - - -/* END */ diff --git a/src/type1/t1driver.c b/src/type1/t1driver.c index 504f87c05..85b580d35 100644 --- a/src/type1/t1driver.c +++ b/src/type1/t1driver.c @@ -1,20 +1,19 @@ -/***************************************************************************/ -/* */ -/* t1driver.c */ -/* */ -/* Type 1 driver interface (body). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - +/******************************************************************* + * + * t1driver.c + * + * High-level Type1 driver interface for FreeType 2.0 + * + * Copyright 1996-1998 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ #include #include @@ -24,61 +23,11 @@ #include #include - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ #undef FT_COMPONENT #define FT_COMPONENT trace_t1driver - #ifndef T1_CONFIG_OPTION_NO_AFM - - /*************************************************************************/ - /* */ - /* */ - /* Get_Interface */ - /* */ - /* */ - /* Each driver can provide one or more extensions to the base */ - /* FreeType API. These can be used to access format specific */ - /* features (e.g., all TrueType/OpenType resources share a common */ - /* file structure and common tables which can be accessed through the */ - /* `sfnt' interface), or more simply generic ones (e.g., the */ - /* `postscript names' interface which can be used to retrieve the */ - /* PostScript name of a given glyph index). */ - /* */ - /* */ - /* driver :: A handle to a driver object. */ - /* */ - /* */ - /* interface :: A string designing the interface. Examples are */ - /* `sfnt', `post_names', `charmaps', etc. */ - /* */ - /* */ - /* A typeless pointer to the extension's interface (normally a table */ - /* of function pointers). Returns NULL if the requested extension */ - /* isn't available (i.e., wasn't compiled in the driver at build */ - /* time). */ - /* */ - static - FTDriver_Interface Get_Interface( FT_Driver driver, - const FT_String* interface ) - { - UNUSED( driver ); - - if ( strcmp( (const char*)interface, "attach_file" ) == 0 ) - return (FTDriver_Interface)T1_Read_AFM; - - return 0; - } - - - /*************************************************************************/ /* */ /* */ @@ -119,97 +68,87 @@ { T1_AFM* afm; - kerning->x = 0; kerning->y = 0; afm = (T1_AFM*)face->afm_data; - if ( afm ) + if (afm) T1_Get_Kerning( afm, left_glyph, right_glyph, kerning ); return T1_Err_Ok; } +#endif - -#endif /* !T1_CONFIG_OPTION_NO_AFM */ - - - /*************************************************************************/ - /* */ - /* */ - /* Set_Char_Sizes */ - /* */ - /* */ - /* A driver method used to reset a size's character sizes (horizontal */ - /* and vertical) expressed in fractional points. */ - /* */ - /* */ - /* char_width :: The character width expressed in 26.6 */ - /* fractional points. */ - /* */ - /* char_height :: The character height expressed in 26.6 */ - /* fractional points. */ - /* */ - /* horz_resolution :: The horizontal resolution of the output device. */ - /* */ - /* vert_resolution :: The vertical resolution of the output device. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /******************************************************************/ + /* */ + /* Set_Char_Sizes */ + /* */ + /* */ + /* A driver method used to reset a size's character sizes */ + /* (horizontal and vertical) expressed in fractional points. */ + /* */ + /* */ + /* size :: handle to target size object */ + /* char_width :: character width expressed in 26.6 points */ + /* char_height :: character height expressed in 26.6 points */ + /* */ + /* */ + /* FreeType error code. 0 means success */ + /* */ static - FT_Error Set_Char_Sizes( T1_Size size, - FT_F26Dot6 char_width, - FT_F26Dot6 char_height, - FT_UInt horz_resolution, - FT_UInt vert_resolution ) + FT_Error Set_Char_Sizes( T1_Size size, + FT_F26Dot6 char_width, + FT_F26Dot6 char_height, + FT_UInt horz_resolution, + FT_UInt vert_resolution ) { - UNUSED( char_width ); - UNUSED( char_height ); - UNUSED( horz_resolution ); - UNUSED( vert_resolution ); + UNUSED(char_width); + UNUSED(char_height); + UNUSED(horz_resolution); + UNUSED(vert_resolution); size->valid = FALSE; return T1_Reset_Size( size ); } - /*************************************************************************/ - /* */ - /* */ - /* Set_Pixel_Sizes */ - /* */ - /* */ - /* A driver method used to reset a size's character sizes (horizontal */ - /* and vertical) expressed in integer pixels. */ - /* */ - /* */ - /* pixel_width :: The character width expressed in integer pixels. */ - /* */ - /* pixel_height :: The character height expressed in integer pixels. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /******************************************************************/ + /* */ + /* Set_Pixel_Sizes */ + /* */ + /* */ + /* A driver method used to reset a size's character sizes */ + /* (horizontal and vertical) expressed in integer pixels. */ + /* */ + /* */ + /* size :: handle to target size object */ + /* */ + /* pixel_width :: character width expressed in 26.6 points */ + /* */ + /* pixel_height :: character height expressed in 26.6 points */ + /* */ + /* char_size :: the corresponding character size in points */ + /* This value is only sent to the TrueType */ + /* bytecode interpreter, even though 99% of */ + /* glyph programs will simply ignore it. A */ + /* safe value there is the maximum of the */ + /* pixel width and height (multiplied by */ + /* 64 to make it a 26.6 fixed float !) */ + /* */ + /* FreeType error code. 0 means success */ + /* */ static - FT_Error Set_Pixel_Sizes( T1_Size size, - FT_Int pixel_width, - FT_Int pixel_height ) + FT_Error Set_Pixel_Sizes( T1_Size size, + FT_Int pixel_width, + FT_Int pixel_height ) { - UNUSED( pixel_width ); - UNUSED( pixel_height ); + UNUSED(pixel_width); + UNUSED(pixel_height); size->valid = FALSE; - return T1_Reset_Size( size ); + return T1_Reset_Size(size); } - /*************************************************************************/ /* */ /* */ @@ -233,155 +172,155 @@ FT_UInt result = 0; PSNames_Interface* psnames; - face = (T1_Face)charmap->face; psnames = (PSNames_Interface*)face->psnames; - if ( psnames ) - switch ( charmap->encoding ) + if (psnames) + switch (charmap->encoding) { - /*******************************************************************/ - /* */ - /* Unicode encoding support */ - /* */ - case ft_encoding_unicode: - /* use the `PSNames' module to synthetize the Unicode charmap */ - result = psnames->lookup_unicode( &face->unicode_map, - (FT_ULong)charcode ); - - /* the function returns 0xFFFF if the Unicode charcode has */ - /* no corresponding glyph. */ - if ( result == 0xFFFF ) - result = 0; - goto Exit; - - /*******************************************************************/ - /* */ - /* Custom Type 1 encoding */ - /* */ - case ft_encoding_adobe_custom: - { - T1_Encoding* encoding = &face->type1.encoding; - - - if ( charcode >= encoding->code_first && - charcode <= encoding->code_last ) - result = encoding->char_index[charcode]; - goto Exit; - } - - /*******************************************************************/ - /* */ - /* Adobe Standard & Expert encoding support */ - /* */ - default: - if ( charcode < 256 ) - { - FT_UInt code; - FT_Int n; - const char* glyph_name; - - - code = psnames->adobe_std_encoding[charcode]; - if ( charmap->encoding == ft_encoding_adobe_expert ) - code = psnames->adobe_expert_encoding[charcode]; - - glyph_name = psnames->adobe_std_strings( code ); - if ( !glyph_name ) - break; - - for ( n = 0; n < face->type1.num_glyphs; n++ ) + /********************************************************************/ + /* */ + /* Unicode encoding support */ + /* */ + case ft_encoding_unicode: { - const char* gname = face->type1.glyph_names[n]; + /* use the "psnames" module to synthetize the Unicode charmap */ + result = psnames->lookup_unicode( &face->unicode_map, + (FT_ULong)charcode ); - - if ( gname && gname[0] == glyph_name[0] && - strcmp( gname, glyph_name ) == 0 ) - { - result = n; - break; - } + /* the function returns 0xFFFF when the Unicode charcode has */ + /* no corresponding glyph.. */ + if (result == 0xFFFF) + result = 0; + goto Exit; } - } - } + /********************************************************************/ + /* */ + /* Custom Type 1 encoding */ + /* */ + case ft_encoding_adobe_custom: + { + T1_Encoding* encoding = &face->type1.encoding; + if (charcode >= encoding->code_first && + charcode <= encoding->code_last) + { + result = encoding->char_index[charcode]; + } + goto Exit; + } + + /********************************************************************/ + /* */ + /* Adobe Standard & Expert encoding support */ + /* */ + default: + if (charcode < 256) + { + FT_UInt code; + FT_Int n; + const char* glyph_name; + + code = psnames->adobe_std_encoding[charcode]; + if (charmap->encoding == ft_encoding_adobe_expert) + code = psnames->adobe_expert_encoding[charcode]; + + glyph_name = psnames->adobe_std_strings(code); + if (!glyph_name) break; + + for ( n = 0; n < face->type1.num_glyphs; n++ ) + { + const char* gname = face->type1.glyph_names[n]; + + if ( gname && gname[0] == glyph_name[0] && + strcmp( gname, glyph_name ) == 0 ) + { + result = n; + break; + } + } + } + } Exit: return result; } - const FT_DriverInterface t1_driver_interface = + + + const FT_Driver_Class t1_driver_class = { - sizeof( FT_DriverRec ), + { + ft_module_font_driver | ft_module_driver_scalable, + sizeof( FT_DriverRec ), + + "type1", /* driver name */ + 0x10000, /* driver version 1.0 */ + 0x20000, /* driver requires FreeType 2.0 or above */ + + 0, /* module specific interface */ + + (FT_Module_Constructor) 0, + (FT_Module_Destructor) 0, +#ifdef T1_CONFIG_OPTION_NO_AFM + (FT_Module_Requester) Get_Interface +#else + (FT_Module_Requester) 0 +#endif + }, + sizeof( T1_FaceRec ), sizeof( T1_SizeRec ), sizeof( T1_GlyphSlotRec ), - "type1", - 100, - 200, + (FTDriver_initFace) T1_Init_Face, + (FTDriver_doneFace) T1_Done_Face, + (FTDriver_initSize) T1_Init_Size, + (FTDriver_doneSize) T1_Done_Size, + (FTDriver_initGlyphSlot) T1_Init_GlyphSlot, + (FTDriver_doneGlyphSlot) T1_Done_GlyphSlot, - 0, /* format interface */ - - (FTDriver_initDriver) T1_Init_Driver, - (FTDriver_doneDriver) T1_Done_Driver, + (FTDriver_setCharSizes) Set_Char_Sizes, + (FTDriver_setPixelSizes) Set_Pixel_Sizes, + (FTDriver_loadGlyph) T1_Load_Glyph, + (FTDriver_getCharIndex) Get_Char_Index, #ifdef T1_CONFIG_OPTION_NO_AFM - (FTDriver_getInterface) 0, + (FTDriver_getKerning) 0, + (FTDriver_getAdvances) 0 #else - (FTDriver_getInterface) Get_Interface, + (FTDriver_getKerning) Get_Kerning, + (FTDriver_attachFile) T1_Read_AFM #endif - - (FTDriver_initFace) T1_Init_Face, - (FTDriver_doneFace) T1_Done_Face, - -#ifdef T1_CONFIG_OPTION_NO_AFM - (FTDriver_getKerning) 0, -#else - (FTDriver_getKerning) Get_Kerning, -#endif - - (FTDriver_initSize) T1_Init_Size, - (FTDriver_doneSize) T1_Done_Size, - (FTDriver_setCharSizes) Set_Char_Sizes, - (FTDriver_setPixelSizes)Set_Pixel_Sizes, - - (FTDriver_initGlyphSlot)T1_Init_GlyphSlot, - (FTDriver_doneGlyphSlot)T1_Done_GlyphSlot, - (FTDriver_loadGlyph) T1_Load_Glyph, - - (FTDriver_getCharIndex) Get_Char_Index, }; + /******************************************************************/ + /* */ + /* Get_FreeType_Driver_Interface */ + /* */ + /* */ + /* 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. */ + /* */ + /* */ + /* address of TrueType's driver generic interface. The */ + /* forma-specific interface can then be retrieved through */ + /* the method interface->get_format_interface.. */ + /* */ + #ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS - - /*************************************************************************/ - /* */ - /* */ - /* getDriverInterface */ - /* */ - /* */ - /* This function is used when compiling the CID 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. */ - /* */ - /* */ - /* The address of the CID's driver generic interface. The */ - /* format-specific interface can then be retrieved through the method */ - /* interface->get_format_interface. */ - /* */ - EXPORT_FUNC( FT_DriverInterface* ) getDriverInterface( void ) + EXPORT_FUNC(const FT_Driver_Class*) getDriverClass( void ) { - return &t1_driver_interface; + return &t1_driver_class; } - #endif /* FT_CONFIG_OPTION_DYNAMIC_DRIVERS */ -/* END */ diff --git a/src/type1/t1driver.h b/src/type1/t1driver.h index e42dfe616..c770480ca 100644 --- a/src/type1/t1driver.h +++ b/src/type1/t1driver.h @@ -1,30 +1,26 @@ -/***************************************************************************/ -/* */ -/* t1driver.h */ -/* */ -/* High-level Type 1 driver interface (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - +/******************************************************************* + * + * t1driver.h + * + * High-level Type1 driver interface for FreeType 2.0 + * + * Copyright 1996-1998 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ #ifndef T1DRIVER_H #define T1DRIVER_H -#include -#include +#include - FT_EXPORT_VAR( const FT_DriverInterface ) t1_driver_interface; + FT_EXPORT_VAR(const FT_Driver_Class) t1_driver_class; #endif /* T1DRIVER_H */ - -/* END */ diff --git a/src/type1/t1gload.c b/src/type1/t1gload.c index 76d0fec04..6035757dc 100644 --- a/src/type1/t1gload.c +++ b/src/type1/t1gload.c @@ -1,20 +1,19 @@ -/***************************************************************************/ -/* */ -/* t1gload.c */ -/* */ -/* Type 1 Glyph Loader (body). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - +/******************************************************************* + * + * t1gload.c 1.0 + * + * Type1 Glyph Loader. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ #include #include @@ -24,33 +23,37 @@ #include #endif + /**********************************************************************/ + /**********************************************************************/ + /**********************************************************************/ + /********** *********/ + /********** *********/ + /********** GENERIC CHARSTRINGS PARSING *********/ + /********** *********/ + /********** *********/ + /**********************************************************************/ + /**********************************************************************/ + /**********************************************************************/ - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_t1gload - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** *********/ - /********** GENERIC CHARSTRING PARSING *********/ - /********** *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - +/********************************************************************* + * + * + * T1_Init_Builder + * + * + * Initialise a given glyph builder. + * + * + * builder :: glyph builder to initialise + * face :: current face object + * size :: current size object + * glyph :: current glyph object + * funcs :: glyph builder functions (or "methods"). + * + *********************************************************************/ static - void T1_Reset_Builder( T1_Builder* builder, - FT_Bool reset_base ) + void T1_Reset_Builder( T1_Builder* builder, FT_Bool reset_base ) { builder->pos_x = 0; builder->pos_y = 0; @@ -63,52 +66,22 @@ builder->pass = 0; builder->hint_point = 0; - if ( reset_base ) + if (builder->loader) { - builder->base.n_points = 0; - builder->base.n_contours = 0; - } + if (reset_base) + FT_GlyphLoader_Rewind( builder->loader ); - { - FT_Outline* base = &builder->base; - FT_Outline* cur = &builder->current; - - - cur->n_points = 0; - cur->n_contours = 0; - cur->points = base->points + base->n_points; - cur->tags = base->tags + base->n_points; - cur->contours = base->contours + base->n_contours; + FT_GlyphLoader_Prepare( builder->loader ); } } - /*************************************************************************/ - /* */ - /* */ - /* T1_Init_Builder */ - /* */ - /* */ - /* Initializes a given glyph builder. */ - /* */ - /* */ - /* builder :: A pointer to the glyph builder to initialize. */ - /* */ - /* */ - /* face :: The current face object. */ - /* */ - /* size :: The current size object. */ - /* */ - /* glyph :: The current glyph object. */ - /* */ - /* funcs :: Glyph builder functions (or `methods'). */ - /* */ LOCAL_FUNC - void T1_Init_Builder( T1_Builder* builder, - T1_Face face, - T1_Size size, - T1_GlyphSlot glyph, - const T1_Builder_Funcs* funcs ) + void T1_Init_Builder( T1_Builder* builder, + T1_Face face, + T1_Size size, + T1_GlyphSlot glyph, + const T1_Builder_Funcs* funcs ) { builder->funcs = *funcs; builder->path_begun = 0; @@ -119,14 +92,16 @@ builder->glyph = glyph; builder->memory = face->root.memory; - if ( glyph ) + if (glyph) { - builder->base = glyph->root.outline; - builder->max_points = glyph->max_points; - builder->max_contours = glyph->max_contours; + FT_GlyphLoader* loader = FT_SLOT(glyph)->loader; + + builder->loader = loader; + builder->base = &loader->base.outline; + builder->current = &loader->current.outline; } - if ( size ) + if (size) { builder->scale_x = size->root.metrics.x_scale; builder->scale_y = size->root.metrics.y_scale; @@ -136,47 +111,47 @@ } - /*************************************************************************/ - /* */ - /* */ - /* T1_Done_Builder */ - /* */ - /* */ - /* Finalizes a given glyph builder. Its contents can still be used */ - /* after the call, but the function saves important information */ - /* within the corresponding glyph slot. */ - /* */ - /* */ - /* builder :: A pointer to the glyph builder to finalize. */ - /* */ +/********************************************************************* + * + * + * T1_Done_Builder + * + * + * Finalise a given glyph builder. Its content can still be + * used after the call, but the function saves important information + * within the corresponding glyph slot. + * + * + * builder :: glyph builder to initialise + * + *********************************************************************/ + LOCAL_FUNC - void T1_Done_Builder( T1_Builder* builder ) + void T1_Done_Builder( T1_Builder* builder ) { T1_GlyphSlot glyph = builder->glyph; - - if ( glyph ) - { - glyph->root.outline = builder->base; - glyph->max_points = builder->max_points; - glyph->max_contours = builder->max_contours; - } + if (glyph) + glyph->root.outline = *builder->base; } - /*************************************************************************/ - /* */ - /* */ - /* T1_Init_Decoder */ - /* */ - /* */ - /* Initializes a given glyph decoder. */ - /* */ - /* */ - /* decoder :: A pointer to the glyph builder to initialize. */ - /* */ - /* */ - /* funcs :: The hinting functions interface. */ + +/********************************************************************* + * + * + * T1_Init_Decoder + * + * + * Initialise a given Type 1 decoder for parsing + * + * + * decoder :: Type 1 decoder to initialise + * funcs :: hinter functions interface + * + *********************************************************************/ + + LOCAL_FUNC void T1_Init_Decoder( T1_Decoder* decoder, const T1_Hinter_Funcs* funcs ) @@ -189,50 +164,49 @@ decoder->num_flex_vectors = 0; /* Clear loader */ - MEM_Set( &decoder->builder, 0, sizeof ( decoder->builder ) ); + MEM_Set( &decoder->builder, 0, sizeof(decoder->builder) ); } - /*************************************************************************/ - /* */ - /* */ - /* lookup_glyph_by_stdcharcode */ - /* */ - /* */ - /* Looks up a given glyph by its StandardEncoding charcode. Used */ - /* to implement the SEAC Type 1 operator. */ - /* */ - /* */ - /* face :: The current face object. */ - /* */ - /* charcode :: The character code to look for. */ - /* */ - /* */ - /* A glyph index in the font face. Returns -1 if the corresponding */ - /* glyph wasn't found. */ - /* */ +/********************************************************************* + * + * + * lookup_glyph_by_stdcharcode + * + * + * Lookup a given glyph by its StandardEncoding charcode. Used + * to implement the SEAC Type 1 operator. + * + * + * face :: current face object + * charcode :: charcode to look for + * + * + * glyph index in font face. Returns -1 if the corresponding + * glyph wasn't found. + * + *********************************************************************/ + static - FT_Int lookup_glyph_by_stdcharcode( T1_Face face, - FT_Int charcode ) + FT_Int lookup_glyph_by_stdcharcode( T1_Face face, + FT_Int charcode ) { FT_Int n; const FT_String* glyph_name; PSNames_Interface* psnames = (PSNames_Interface*)face->psnames; - /* check range of standard char code */ - if ( charcode < 0 || charcode > 255 ) + if (charcode < 0 || charcode > 255) return -1; glyph_name = psnames->adobe_std_strings( - psnames->adobe_std_encoding[charcode]); + psnames->adobe_std_encoding[charcode]); for ( n = 0; n < face->type1.num_glyphs; n++ ) { FT_String* name = (FT_String*)face->type1.glyph_names[n]; - - if ( name && strcmp( name, glyph_name ) == 0 ) + if ( name && strcmp(name,glyph_name) == 0 ) return n; } @@ -240,30 +214,27 @@ } - /*************************************************************************/ - /* */ - /* */ - /* t1operator_seac */ - /* */ - /* */ - /* Implements the `seac' Type 1 operator for a Type 1 decoder. */ - /* */ - /* */ - /* decoder :: The current CID decoder. */ - /* */ - /* asb :: The accent's side bearing. */ - /* */ - /* adx :: The horizontal offset of the accent. */ - /* */ - /* ady :: The vertical offset of the accent. */ - /* */ - /* bchar :: The base character's StandardEncoding charcode. */ - /* */ - /* achar :: The accent character's StandardEncoding charcode. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ +/********************************************************************* + * + * + * t1operator_seac + * + * + * Implements the "seac" Type 1 operator for a Type 1 decoder + * + * + * decoder :: current Type 1 decoder + * asb :: accent's side bearing + * adx :: horizontal position of accent + * ady :: vertical position of accent + * bchar :: base character's StandardEncoding charcode + * achar :: accent character's StandardEncoding charcode + * + * + * Error code. 0 means success. + * + *********************************************************************/ + static FT_Error t1operator_seac( T1_Decoder* decoder, FT_Pos asb, @@ -273,14 +244,13 @@ FT_Int achar ) { FT_Error error; - T1_Face face = decoder->builder.face; FT_Int bchar_index, achar_index, n_base_points; - FT_Outline* cur = &decoder->builder.current; - FT_Outline* base = &decoder->builder.base; + FT_Outline* cur = decoder->builder.current; + FT_Outline* base = decoder->builder.base; FT_Vector left_bearing, advance; + T1_Face face = decoder->builder.face; T1_Font* type1 = &face->type1; - bchar_index = lookup_glyph_by_stdcharcode( face, bchar ); achar_index = lookup_glyph_by_stdcharcode( face, achar ); @@ -290,29 +260,20 @@ return T1_Err_Syntax_Error; } + /* if we are trying to load a composite glyph, do not load the */ + /* accent character and return the array of subglyphs. */ if ( decoder->builder.no_recurse ) { - /* if we are trying to load a composite glyph, do not load the */ - /* accent character and return the array of subglyphs. */ - - FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph; - FT_SubGlyph* subg; + FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph; + FT_GlyphLoader* loader = glyph->loader; + FT_SubGlyph* subg; /* reallocate subglyph array if necessary */ - if ( glyph->max_subglyphs < 2 ) - { - FT_Memory memory = decoder->builder.face->root.memory; - - - if ( REALLOC_ARRAY( glyph->subglyphs, glyph->max_subglyphs, - 2, FT_SubGlyph ) ) - return error; - - glyph->max_subglyphs = 2; - } - - subg = glyph->subglyphs; + error = FT_GlyphLoader_Check_Subglyphs( loader, 2 ); + if (error) goto Exit; + + subg = loader->current.subglyphs; /* subglyph 0 = base character */ subg->index = bchar_index; @@ -331,29 +292,27 @@ /* set up remaining glyph fields */ glyph->num_subglyphs = 2; glyph->format = ft_glyph_format_composite; + + loader->current.num_subglyphs = 2; } - else + + /* First load `bchar' in builder */ + /* now load the unscaled outline */ + + if (decoder->builder.loader) + FT_GlyphLoader_Prepare( decoder->builder.loader ); /* prepare loader */ + + error = T1_Parse_CharStrings( decoder, + type1->charstrings [bchar_index], + type1->charstrings_len[bchar_index], + type1->num_subrs, + type1->subrs, + type1->subrs_len ); + if ( error ) goto Exit; + + n_base_points = cur->n_points; + { - /* First load `bchar' in builder */ - /* now load the unscaled outline */ - - cur->n_points = 0; - cur->n_contours = 0; - cur->points = base->points + base->n_points; - cur->tags = base->tags + base->n_points; - cur->contours = base->contours + base->n_contours; - - error = T1_Parse_CharStrings( decoder, - type1->charstrings [bchar_index], - type1->charstrings_len[bchar_index], - type1->num_subrs, - type1->subrs, - type1->subrs_len ); - if ( error ) - return error; - - n_base_points = cur->n_points; - /* save the left bearing and width of the base character */ /* as they will be erased by the next load. */ @@ -365,29 +324,13 @@ /* Now load `achar' on top of */ /* the base outline */ - - cur->n_points = 0; - cur->n_contours = 0; - cur->points = base->points + base->n_points; - cur->tags = base->tags + base->n_points; - cur->contours = base->contours + base->n_contours; - error = T1_Parse_CharStrings( decoder, type1->charstrings [achar_index], type1->charstrings_len[achar_index], type1->num_subrs, type1->subrs, type1->subrs_len ); - if ( error ) - return error; - - /* adjust contours in accented character outline */ - { - FT_Int n; - - for ( n = 0; n < cur->n_contours; n++ ) - cur->contours[n] += n_base_points; - } + if ( error ) return error; /* restore the left side bearing and */ /* advance width of the base character */ @@ -396,30 +339,38 @@ decoder->builder.advance = advance; /* Finally, move the accent */ - FT_Outline_Translate( cur, adx - asb, ady ); + if ( decoder->builder.load_points ) + { + FT_Outline dummy; + + dummy.n_points = base->n_points - n_base_points; + dummy.points = base->points + n_base_points; + FT_Outline_Translate( &dummy, adx - asb, ady ); + } } - - return T1_Err_Ok; + Exit: + return error; } +/********************************************************************* + * + * + * t1operator_flex + * + * + * Implements the "flex" Type 1 operator for a Type 1 decoder + * + * + * decoder :: current Type 1 decoder + * threshold :: threshold + * end_x :: position of final flex point + * end_y :: position of final flex point + * + * + * Error code. 0 means success. + * + *********************************************************************/ - /*************************************************************************/ - /* */ - /* */ - /* t1operator_flex */ - /* */ - /* */ - /* Implements the `flex' Type 1 operator for a Type 1 decoder. */ - /* */ - /* */ - /* decoder :: The current Type 1 decoder. */ - /* threshold :: The threshold. */ - /* end_x :: The horizontal position of the final flex point. */ - /* end_y :: The vertical position of the final flex point. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ static FT_Error t1operator_flex( T1_Decoder* decoder, FT_Pos threshold, @@ -430,15 +381,10 @@ FT_Vector* flex = decoder->flex_vectors; FT_Int n; - UNUSED( threshold ); - UNUSED( end_x ); - UNUSED( end_y ); - - - /* we don't even try to test the threshold in the non-hinting */ + /* we don't even try to test the threshold in the non-hinting */ /* builder, even if the flex operator is said to be a path */ - /* construction statement in the specification. This is better */ - /* left to the hinter. */ + /* construction statement in the specification. This is better */ + /* left to the hinter.. */ flex = decoder->flex_vectors; vec = *flex++; @@ -451,6 +397,11 @@ vec = *flex++; } + + UNUSED(threshold); + UNUSED(end_x); + UNUSED(end_y); + flex = decoder->flex_vectors; return decoder->builder.funcs.rcurve_to( &decoder->builder, @@ -465,37 +416,34 @@ } - /*************************************************************************/ - /* */ - /* */ - /* T1_Parse_CharStrings */ - /* */ - /* */ - /* Parses a given Type 1 charstrings program. */ - /* */ - /* */ - /* decoder :: The current Type 1 decoder. */ - /* */ - /* charstring_base :: The base address of the charstring stream. */ - /* */ - /* charstring_len :: The length in bytes of the charstring stream. */ - /* */ - /* num_subrs :: The number of sub-routines. */ - /* */ - /* subrs_base :: An array of sub-routines addresses. */ - /* */ - /* subrs_len :: An array of sub-routines lengths. */ - /* */ - /* */ - /* Free error code. 0 means success. */ - /* */ +/********************************************************************* + * + * + * T1_Parse_CharStrings + * + * + * Parses a given Type 1 charstrings program + * + * + * decoder :: current Type 1 decoder + * charstring_base :: base of the charstring stream + * charstring_len :: length in bytes of the charstring stream + * num_subrs :: number of sub-routines + * subrs_base :: array of sub-routines addresses + * subrs_len :: array of sub-routines lengths + * + * + * Error code. 0 means success. + * + *********************************************************************/ + LOCAL_FUNC - FT_Error T1_Parse_CharStrings( T1_Decoder* decoder, - FT_Byte* charstring_base, - FT_Int charstring_len, - FT_Int num_subrs, - FT_Byte** subrs_base, - FT_Int* subrs_len ) + FT_Error T1_Parse_CharStrings( T1_Decoder* decoder, + FT_Byte* charstring_base, + FT_Int charstring_len, + FT_Int num_subrs, + FT_Byte** subrs_base, + FT_Int* subrs_len ) { FT_Error error; T1_Decoder_Zone* zone; @@ -505,7 +453,7 @@ T1_Builder_Funcs* builds = &builder->funcs; T1_Hinter_Funcs* hints = &decoder->hinter; - static const FT_Int args_count[op_max] = + static const FT_Int args_count[ op_max ] = { 0, /* none */ 0, /* endchar */ @@ -535,8 +483,7 @@ 2 /* setcurrentpoint */ }; - - /* First of all, initialize the decoder */ + /* First of all, initialise the decoder */ decoder->top = decoder->stack; decoder->zone = decoder->zones; zone = decoder->zones; @@ -556,146 +503,99 @@ T1_Operator op = op_none; FT_Long value = 0; - - /* Start with the decompression of operator or value */ - switch ( *ip++ ) + /* First of all, decompress operator or value */ + switch (*ip++) { - case 1: - op = op_hstem; - break; + case 1: op = op_hstem; break; - case 3: - op = op_vstem; - break; - case 4: - op = op_vmoveto; - break; - case 5: - op = op_rlineto; - break; - case 6: - op = op_hlineto; - break; - case 7: - op = op_vlineto; - break; - case 8: - op = op_rrcurveto; - break; - case 9: - op = op_closepath; - break; - case 10: - op = op_callsubr; - break; - case 11: - op = op_return; - break; + case 3: op = op_vstem; break; + case 4: op = op_vmoveto; break; + case 5: op = op_rlineto; break; + case 6: op = op_hlineto; break; + case 7: op = op_vlineto; break; + case 8: op = op_rrcurveto; break; + case 9: op = op_closepath; break; + case 10: op = op_callsubr; break; + case 11: op = op_return; break; - case 13: - op = op_hsbw; - break; - case 14: - op = op_endchar; - break; + case 13: op = op_hsbw; break; + case 14: op = op_endchar; break; - case 21: - op = op_rmoveto; - break; - case 22: - op = op_hmoveto; - break; + case 21: op = op_rmoveto; break; + case 22: op = op_hmoveto; break; - case 30: - op = op_vhcurveto; - break; - case 31: - op = op_hvcurveto; - break; + case 30: op = op_vhcurveto; break; + case 31: op = op_hvcurveto; break; - case 12: - if ( ip > limit ) - { - FT_ERROR(( "T1_Parse_CharStrings: invalid escape (12+EOF)\n" )); - goto Syntax_Error; - } - - switch ( *ip++ ) - { - case 0: - op = op_dotsection; - break; - case 1: - op = op_vstem3; - break; - case 2: - op = op_hstem3; - break; - case 6: - op = op_seac; - break; - case 7: - op = op_sbw; - break; case 12: - op = op_div; - break; - case 16: - op = op_callothersubr; - break; - case 17: - op = op_pop; - break; - case 33: - op = op_setcurrentpoint; - break; - - default: - FT_ERROR(( "T1_Parse_CharStrings: invalid escape (12+%d)\n", - ip[-1] )); - goto Syntax_Error; - } - break; - - case 255: /* four bytes integer */ - if ( ip + 4 > limit ) - { - FT_ERROR(( "T1_Parse_CharStrings: unexpected EOF in integer\n" )); - goto Syntax_Error; - } - - value = ( (FT_Long)ip[0] << 24 ) | - ( (FT_Long)ip[1] << 16 ) | - ( (FT_Long)ip[2] << 8 ) | - ip[3]; - ip += 4; - break; - - default: - if ( ip[-1] >= 32 ) - { - if ( ip[-1] < 247 ) - value = (FT_Long)ip[-1] - 139; - else { - if ( ++ip > limit ) + if (ip > limit) { - FT_ERROR(( "T1_Parse_CharStrings: unexpected EOF in integer\n" )); + FT_ERROR(( "T1.Parse_CharStrings : invalid escape (12+EOF)\n" )); goto Syntax_Error; } - if ( ip[-2] < 251 ) - value = ( (FT_Long)( ip[-2] - 247 ) << 8 ) + ip[-1] + 108; - else - value = -( ( ( (FT_Long)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 ); + switch (*ip++) + { + case 0: op = op_dotsection; break; + case 1: op = op_vstem3; break; + case 2: op = op_hstem3; break; + case 6: op = op_seac; break; + case 7: op = op_sbw; break; + case 12: op = op_div; break; + case 16: op = op_callothersubr; break; + case 17: op = op_pop; break; + case 33: op = op_setcurrentpoint; break; + + default: + FT_ERROR(( "T1.Parse_CharStrings : invalid escape (12+%d)\n", + ip[-1] )); + goto Syntax_Error; + } } - } - else - { - FT_ERROR(( "T1_Parse_CharStrings: invalid byte (%d)\n", + break; + + case 255: /* four bytes integer */ + { + if (ip+4 > limit) + { + FT_ERROR(( "T1.Parse_CharStrings : unexpected EOF in integer\n" )); + goto Syntax_Error; + } + + value = ((long)ip[0] << 24) | + ((long)ip[1] << 16) | + ((long)ip[2] << 8) | + ip[3]; + ip += 4; + } + break; + + default: + if (ip[-1] >= 32) + { + if (ip[-1] < 247) + value = (long)ip[-1] - 139; + else + { + if (++ip > limit) + { + FT_ERROR(( "T1.Parse_CharStrings : unexpected EOF in integer\n" )); + goto Syntax_Error; + } + + if (ip[-2] < 251) + value = ((long)(ip[-2]-247) << 8) + ip[-1] + 108; + else + value = -((((long)ip[-2]-251) << 8) + ip[-1] + 108 ); + } + } + else + { + FT_ERROR(( "T1.Parse_CharStrings : invalid byte (%d)\n", ip[-1] )); - goto Syntax_Error; - } + goto Syntax_Error; + } } /* push value if needed */ @@ -703,120 +603,123 @@ { if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS ) { - FT_ERROR(( "T1_Parse_CharStrings: Stack overflow!\n" )); + FT_ERROR(( "T1.Parse_CharStrings : Stack overflow !!\n" )); goto Syntax_Error; } *top++ = value; decoder->top = top; } + else if ( op == op_callothersubr ) /* check arguments differently */ { - if ( top - decoder->stack < 2 ) + if ( top - decoder->stack < 2) goto Stack_Underflow; top -= 2; - switch ( top[1] ) + switch (top[1]) { - case 1: /* start flex feature ----------------------------- */ - if ( top[0] != 0 ) - goto Unexpected_OtherSubr; - - decoder->flex_state = 1; - decoder->num_flex_vectors = 0; - decoder->flex_vectors[0].x = 0; - decoder->flex_vectors[0].y = 0; - break; - - - case 2: /* add flex vector ------------------------------- */ - { - FT_Int index; - FT_Vector* flex; - - - if ( top[0] != 0 ) - goto Unexpected_OtherSubr; - - top -= 2; - if ( top < decoder->stack ) - goto Stack_Underflow; - - index = decoder->num_flex_vectors++; - if ( index >= 7 ) + case 1: /* start flex feature ----------------------------- */ { - FT_ERROR(( "T1_Parse_CharStrings: too many flex vectors!\n" )); - goto Syntax_Error; + if (top[0] != 0) goto Unexpected_OtherSubr; + + decoder->flex_state = 1; + decoder->num_flex_vectors = 0; + decoder->flex_vectors[0].x = 0; + decoder->flex_vectors[0].y = 0; } + break; - flex = decoder->flex_vectors + index; - flex->x += top[0]; - flex->y += top[1]; - } - break; - case 0: /* end flex feature ------------------------------ */ - if ( decoder->flex_state == 0 || - decoder->num_flex_vectors != 7 ) - { - FT_ERROR(( "T1_Parse_CharStrings: unexpected flex end\n" )); - goto Syntax_Error; - } + case 2: /* add flex vector ------------------------------- */ + { + FT_Int index; + FT_Vector* flex; - if ( top[0] != 3 ) - goto Unexpected_OtherSubr; + if (top[0] != 0) goto Unexpected_OtherSubr; - top -= 3; - if ( top < decoder->stack ) - goto Stack_Underflow; + top -= 2; + if (top < decoder->stack) goto Stack_Underflow; - /* now consume the remaining `pop pop setcurrentpoint' */ - if ( ip + 6 > limit || - ip[0] != 12 || ip[1] != 17 || /* pop */ - ip[2] != 12 || ip[3] != 17 || /* pop */ - ip[4] != 12 || ip[5] != 33 ) /* setcurrentpoint */ - { - FT_ERROR(( "T1_Parse_CharStrings: invalid flex charstring\n" )); - goto Syntax_Error; - } + index = decoder->num_flex_vectors++; + if (index >= 7) + { + FT_ERROR(( "T1.Parse_CharStrings: too many flex vectors !\n" )); + goto Syntax_Error; + } - decoder->flex_state = 0; - decoder->top = top; + flex = decoder->flex_vectors + index; + flex->x += top[0]; + flex->y += top[1]; - error = t1operator_flex( decoder, top[0], top[1], top[2] ); - break; + } + break; - case 3: /* change hints ------------------------------------ */ - if ( top[0] != 1 ) - goto Unexpected_OtherSubr; - /* eat the following `pop' */ - if ( ip + 2 > limit ) - { - FT_ERROR(( "T1_Parse_CharStrings: invalid escape (12+%d)\n", - ip[-1] )); - goto Syntax_Error; - } + case 0: /* end flex feature ------------------------------ */ + { + if ( decoder->flex_state == 0 || + decoder->num_flex_vectors != 7 ) + { + FT_ERROR(( "T1.Parse_CharStrings: unexpected flex end\n" )); + goto Syntax_Error; + } - if (ip[0] != 12 || ip[1] != 17) - { - FT_ERROR(( "T1_Parse_CharStrings: `pop' expected, found (%d %d)\n", - ip[0], ip[1] )); - goto Syntax_Error; - } + if (top[0] != 3) goto Unexpected_OtherSubr; - ip += 2; + top -= 3; + if (top < decoder->stack) goto Stack_Underflow; - error = hints->change_hints( builder ); - break; + /* now consume the remaining "pop pop setcurrentpoint" */ + if ( ip+6 > limit || + ip[0] != 12 || ip[1] != 17 || /* pop */ + ip[2] != 12 || ip[3] != 17 || /* pop */ + ip[4] != 12 || ip[5] != 33 ) /* setcurrentpoint */ + { + FT_ERROR(( "T1.Parse_CharStrings: invalid flex charstring\n" )); + goto Syntax_Error; + } - default: - /* invalid OtherSubrs call */ - Unexpected_OtherSubr: - FT_ERROR(( "T1_Parse_CharStrings: unexpected OtherSubrs [%d %d]\n", + decoder->flex_state = 0; + decoder->top = top; + + error = t1operator_flex( decoder, top[0], top[1], top[2] ); + } + break; + + + case 3: /* change hints ------------------------------------ */ + { + if (top[0] != 1) goto Unexpected_OtherSubr; + + /* eat the following "pop" */ + if (ip+2 > limit) + { + FT_ERROR(( "T1.Parse_CharStrings: invalid escape (12+%d)\n", + ip[-1] )); + goto Syntax_Error; + } + + if (ip[0] != 12 || ip[1] != 17) + { + FT_ERROR(( "T1.Parse_CharStrings: 'pop' expected, found (%d %d)\n", + ip[0], ip[1] )); + goto Syntax_Error; + } + + ip += 2; + error = hints->change_hints(builder); + } + break; + + + default: + /* invalid OtherSubrs call */ + Unexpected_OtherSubr: + FT_ERROR(( "T1.Parse_CharStrings: unexpected OtherSubrs [%d %d]\n", top[0], top[1] )); - goto Syntax_Error; + goto Syntax_Error; } decoder->top = top; } @@ -824,176 +727,177 @@ { FT_Int num_args = args_count[op]; - if ( top - decoder->stack < num_args ) goto Stack_Underflow; top -= num_args; - switch ( op ) + switch (op) { - case op_endchar: - error = builds->end_char( builder ); - break; + case op_endchar: + error = builds->end_char( builder ); + break; - case op_hsbw: - error = builds->set_bearing_point( builder, top[0], 0, - top[1], 0 ); - break; + case op_hsbw: + error = builds->set_bearing_point( builder, top[0], 0, + top[1], 0 ); + break; - case op_seac: - /* return immediately after the processing */ - return t1operator_seac( decoder, top[0], top[1], - top[2], top[3], top[4] ); + case op_seac: + /* return immediately after the processing */ + return t1operator_seac( decoder, top[0], top[1], + top[2], top[3], top[4] ); - case op_sbw: - error = builds->set_bearing_point( builder, top[0], top[1], - top[2], top[3] ); - break; + case op_sbw: + error = builds->set_bearing_point( builder, top[0], top[1], + top[2], top[3] ); + break; - case op_closepath: - error = builds->close_path( builder ); - break; + case op_closepath: + error = builds->close_path( builder ); + break; - case op_hlineto: - error = builds->rline_to( builder, top[0], 0 ); - break; + case op_hlineto: + error = builds->rline_to( builder, top[0], 0 ); + break; - case op_hmoveto: - error = builds->rmove_to( builder, top[0], 0 ); - break; + case op_hmoveto: + error = builds->rmove_to( builder, top[0], 0 ); + break; - case op_hvcurveto: - error = builds->rcurve_to( builder, top[0], 0, - top[1], top[2], - 0, top[3] ); - break; + case op_hvcurveto: + error = builds->rcurve_to( builder, top[0], 0, + top[1], top[2], + 0, top[3] ); + break; - case op_rlineto: - error = builds->rline_to( builder, top[0], top[1] ); - break; + case op_rlineto: + error = builds->rline_to( builder, top[0], top[1] ); + break; - case op_rmoveto: - /* ignore operator when in flex mode */ - if ( decoder->flex_state == 0 ) - error = builds->rmove_to( builder, top[0], top[1] ); - else - top += 2; - break; + case op_rmoveto: + /* ignore operator when in flex mode */ + if (decoder->flex_state == 0) + error = builds->rmove_to( builder, top[0], top[1] ); + else + top += 2; + break; - case op_rrcurveto: - error = builds->rcurve_to( builder, top[0], top[1], - top[2], top[3], - top[4], top[5] ); - break; + case op_rrcurveto: + { + error = builds->rcurve_to( builder, top[0], top[1], + top[2], top[3], + top[4], top[5] ); + } + break; - case op_vhcurveto: - error = builds->rcurve_to( builder, 0, top[0], - top[1], top[2], - top[3], 0 ); - break; + case op_vhcurveto: + error = builds->rcurve_to( builder, 0, top[0], + top[1], top[2], + top[3], 0 ); + break; - case op_vlineto: - error = builds->rline_to( builder, 0, top[0] ); - break; + case op_vlineto: + error = builds->rline_to( builder, 0, top[0] ); + break; - case op_vmoveto: - error = builds->rmove_to( builder, 0, top[0] ); - break; + case op_vmoveto: + error = builds->rmove_to( builder, 0, top[0] ); + break; - case op_dotsection: - error = hints->dot_section( builder ); - break; + case op_dotsection: + error = hints->dot_section( builder ); + break; - case op_hstem: - error = hints->stem( builder, top[0], top[1], 0 ); - break; + case op_hstem: + error = hints->stem( builder, top[0], top[1], 0 ); + break; - case op_hstem3: - error = hints->stem3( builder, top[0], top[1], top[2], - top[3], top[4], top[5], 0 ); - break; + case op_hstem3: + error = hints->stem3( builder, top[0], top[1], top[2], + top[3], top[4], top[5], 0 ); + break; - case op_vstem: - error = hints->stem( builder, top[0], top[1], 1 ); - break; + case op_vstem: + error = hints->stem( builder, top[0], top[1], 1 ); + break; - case op_vstem3: - error = hints->stem3( builder, top[0], top[1], top[2], - top[3], top[4], top[5], 1 ); - break; + case op_vstem3: + error = hints->stem3( builder, top[0], top[1], top[2], + top[3], top[4], top[5], 1 ); + break; - case op_div: - if ( top[1] ) - *top++ = top[0] / top[1]; - else - { - FT_ERROR(( "T1_Parse_CHarStrings: division by 0\n" )); + case op_div: + if (top[1]) + *top++ = top[0] / top[1]; + else + { + FT_ERROR(( "T1.Parse_CHarStrings : division by 0\n" )); + goto Syntax_Error; + } + break; + + case op_callsubr: + { + FT_Int index = top[0]; + + if ( index < 0 || index >= num_subrs ) + { + FT_ERROR(( "T1.Parse_CharStrings : invalid subrs index\n" )); + goto Syntax_Error; + } + + if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS ) + { + FT_ERROR(( "T1.Parse_CharStrings : too many nested subrs\n" )); + goto Syntax_Error; + } + + zone->cursor = ip; /* save current instruction pointer */ + + zone++; + zone->base = subrs_base[index]; + zone->limit = zone->base + subrs_len[index]; + zone->cursor = zone->base; + + if (!zone->base) + { + FT_ERROR(( "T1.Parse_CharStrings : invoking empty subrs !!\n" )); + goto Syntax_Error; + } + + decoder->zone = zone; + ip = zone->base; + limit = zone->limit; + } + break; + + case op_pop: + FT_ERROR(( "T1.Parse_CharStrings : unexpected POP\n" )); goto Syntax_Error; - } - break; - - case op_callsubr: - { - FT_Int index = top[0]; - if ( index < 0 || index >= num_subrs ) + case op_return: + if ( zone <= decoder->zones ) { - FT_ERROR(( "T1_Parse_CharStrings: invalid subrs index\n" )); + FT_ERROR(( "T1.Parse_CharStrings : unexpected return\n" )); goto Syntax_Error; } - if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS ) - { - FT_ERROR(( "T1_Parse_CharStrings: too many nested subrs\n" )); - goto Syntax_Error; - } - - zone->cursor = ip; /* save current instruction pointer */ - - zone++; - zone->base = subrs_base[index]; - zone->limit = zone->base + subrs_len[index]; - zone->cursor = zone->base; - - if ( !zone->base ) - { - FT_ERROR(( "T1_Parse_CharStrings: invoking empty subrs!\n" )); - goto Syntax_Error; - } - - decoder->zone = zone; - ip = zone->base; + zone--; + ip = zone->cursor; limit = zone->limit; - } - break; + decoder->zone = zone; + break; - case op_pop: - FT_ERROR(( "T1_Parse_CharStrings: unexpected POP\n" )); - goto Syntax_Error; - - case op_return: - if ( zone <= decoder->zones ) - { - FT_ERROR(( "T1_Parse_CharStrings: unexpected return\n" )); + case op_setcurrentpoint: + FT_ERROR(( "T1.Parse_CharStrings : unexpected SETCURRENTPOINT\n" )); goto Syntax_Error; - } + break; - zone--; - ip = zone->cursor; - limit = zone->limit; - decoder->zone = zone; - break; - - case op_setcurrentpoint: - FT_ERROR(( "T1_Parse_CharStrings: unexpected `setcurrentpoint'\n" )); - goto Syntax_Error; - break; - - default: - FT_ERROR(( "T1_Parse_CharStrings : unhandled opcode %d\n", op )); - goto Syntax_Error; + default: + FT_ERROR(( "T1.Parse_CharStrings : unhandled opcode %d\n", op )); + goto Syntax_Error; } decoder->top = top; @@ -1010,138 +914,81 @@ } - /*************************************************************************/ - /* */ - /* */ - /* T1_Add_Points */ - /* */ - /* */ - /* Checks that there is enough room in the current load glyph outline */ - /* to accept `num_points' additional outline points. If not, this */ - /* function grows the load outline's arrays accordingly. */ - /* */ - /* */ - /* builder :: A pointer to the glyph builder object. */ - /* */ - /* num_points :: The number of points that will be added later. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function does NOT update the points count in the glyph */ - /* builder. This must be done by the caller itself, after this */ - /* function has been invoked. */ - /* */ + +/*************************************************************************/ +/* */ +/* T1_Add_Points */ +/* */ +/* */ +/* Checks that there is enough room in the current load glyph outline */ +/* to accept "num_points" additional outline points. If not, this */ +/* function grows the load outline's arrays accordingly.. */ +/* */ +/* */ +/* builder :: pointer to glyph builder object */ +/* num_points :: number of points that will be added later */ +/* */ +/* */ +/* Type1 error code. 0 means success */ +/* */ +/* */ +/* This function does NOT update the points count in the glyph builder*/ +/* This must be done by the caller itself, after this function is */ +/* invoked.. */ +/* */ LOCAL_FUNC FT_Error T1_Add_Points( T1_Builder* builder, FT_Int num_points ) { - FT_Int new_points; - - - new_points = builder->base.n_points + - builder->current.n_points + - num_points; - - if ( new_points > builder->max_points ) - { - FT_Memory memory = builder->memory; - FT_Error error; - FT_Int increment = builder->current.points - builder->base.points; - FT_Int current = builder->max_points; - - - while ( builder->max_points < new_points ) - builder->max_points += 16; - - if ( REALLOC_ARRAY( builder->base.points, - current, builder->max_points, FT_Vector ) || - - REALLOC_ARRAY( builder->base.tags, - current, builder->max_points, FT_Byte ) ) - return error; - - builder->current.points = builder->base.points + increment; - builder->current.tags = builder->base.tags + increment; - } - - return T1_Err_Ok; + return FT_GlyphLoader_Check_Points( builder->loader, num_points, 0 ); } - - /*************************************************************************/ - /* */ - /* */ - /* T1_Add_Contours */ - /* */ - /* */ - /* Checks that there is enough room in the current load glyph outline */ - /* to accept `num_contours' additional contours. If not, this */ - /* function grows the load outline's arrays accordingly. */ - /* */ - /* */ - /* builder :: A pointer to the glyph builder object. */ - /* */ - /* num_contours :: The number of contours that will be added later. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function does NOT update the contours count in the load glyph */ - /* This must be done by the caller itself, after this function is */ - /* invoked. */ - /* */ +/*************************************************************************/ +/* */ +/* T1_Add_Contours */ +/* */ +/* */ +/* Checks that there is enough room in the current load glyph outline */ +/* to accept "num_contours" additional contours. If not, this func */ +/* the load outline's arrays accordingly.. */ +/* */ +/* */ +/* builder :: pointer to glyph builder object */ +/* num_contours :: number of contours that will be added later */ +/* */ +/* */ +/* Type1 error code. 0 means success */ +/* */ +/* */ +/* This function does NOT update the contours count in the load glyph */ +/* This must be done by the caller itself, after this function is */ +/* invoked.. */ +/* */ LOCAL_FUNC FT_Error T1_Add_Contours( T1_Builder* builder, FT_Int num_contours ) { - FT_Int new_contours; - - - new_contours = builder->base.n_contours + - builder->current.n_contours + - num_contours; - - if ( new_contours > builder->max_contours && builder->load_points ) - { - FT_Error error; - FT_Memory memory = builder->memory; - FT_Int increment = builder->current.contours - - builder->base.contours; - FT_Int current = builder->max_contours; - - - while ( builder->max_contours < new_contours ) - builder->max_contours += 4; - - if ( REALLOC_ARRAY( builder->base.contours, - current, builder->max_contours, FT_Short ) ) - return error; - - builder->current.contours = builder->base.contours + increment; - } - - return T1_Err_Ok; + return FT_GlyphLoader_Check_Points( builder->loader, 0, num_contours ); } - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ - /********** *********/ - /********** The following code is in charge of computing *********/ - /********** the maximum advance width of the font. It *********/ - /********** quickly processes each glyph charstring to *********/ - /********** extract the value from either a `sbw' or `seac' *********/ - /********** operator. *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ + /**********************************************************************/ + /**********************************************************************/ + /**********************************************************************/ + /********** *********/ + /********** *********/ + /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ + /********** *********/ + /********** The following code is in charge of computing *********/ + /********** the maximum advance width of the font. It *********/ + /********** quickly process each glyph charstring to *********/ + /********** extract the value from either a "sbw" or "seac" *********/ + /********** operator. *********/ + /********** *********/ + /**********************************************************************/ + /**********************************************************************/ + /**********************************************************************/ + static @@ -1151,13 +998,12 @@ FT_Pos wx, FT_Pos wy ) { - UNUSED( sbx ); - UNUSED( sby ); - UNUSED( wy ); - - if ( wx > decoder->builder.advance.x ) + if (wx > decoder->builder.advance.x) decoder->builder.advance.x = wx; + UNUSED(sbx); + UNUSED(sby); + UNUSED(wy); return -1; /* return an error code to exit the Type 1 parser */ /* immediately. */ } @@ -1170,57 +1016,56 @@ return -2; } - /* the maxadv_gbuilder_interface is used when computing the maximum */ - /* advance width of all glyphs in a given font. We only process the */ - /* `sbw' operator here, and return an error for all others. */ + /* advance width of all glyphs in a given font. We only process the */ + /* 'sbw' operator here, and return an error for all others.. */ - /* Note that `seac' is processed by the T1_Decoder. */ + /* Note that "seac" is processed by the T1_Decoder */ static const T1_Builder_Funcs maxadv_builder_interface = { - (T1_Builder_EndChar) maxadv_error, - (T1_Builder_Sbw) maxadv_sbw, - (T1_Builder_ClosePath)maxadv_error, - (T1_Builder_RLineTo) maxadv_error, - (T1_Builder_RMoveTo) maxadv_error, - (T1_Builder_RCurveTo) maxadv_error + (T1_Builder_EndChar) maxadv_error, + (T1_Builder_Sbw) maxadv_sbw, + (T1_Builder_ClosePath) maxadv_error, + (T1_Builder_RLineTo) maxadv_error, + (T1_Builder_RMoveTo) maxadv_error, + (T1_Builder_RCurveTo) maxadv_error }; - /* the maxadv_hinter_interface always return an error. */ - + /* the maxadv_interface is used when computing the maximum advance */ + /* with of the set of glyphs in a given font file. We only process */ + /* the "seac" operator and return immediately.. */ static const T1_Hinter_Funcs maxadv_hinter_interface = { - (T1_Hinter_DotSection) maxadv_error, - (T1_Hinter_ChangeHints)maxadv_error, - (T1_Hinter_Stem) maxadv_error, - (T1_Hinter_Stem3) maxadv_error, + (T1_Hinter_DotSection) maxadv_error, + (T1_Hinter_ChangeHints) maxadv_error, + (T1_Hinter_Stem) maxadv_error, + (T1_Hinter_Stem3) maxadv_error, }; + LOCAL_FUNC FT_Error T1_Compute_Max_Advance( T1_Face face, - FT_Int* max_advance ) + FT_Int *max_advance ) { FT_Error error; T1_Decoder decoder; FT_Int glyph_index; T1_Font* type1 = &face->type1; - *max_advance = 0; - /* Initialize load decoder */ + /* Initialise load decoder */ T1_Init_Decoder( &decoder, &maxadv_hinter_interface ); T1_Init_Builder( &decoder.builder, face, 0, 0, &maxadv_builder_interface ); /* For each glyph, parse the glyph charstring and extract */ - /* the advance width. */ - + /* the advance width.. */ for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ ) { /* now get load the unscaled outline */ @@ -1230,49 +1075,49 @@ type1->num_subrs, type1->subrs, type1->subrs_len ); - /* ignore error if one occured - skip to next glyph */ + /* ignore the error if one occured - skip to next glyph */ } *max_advance = decoder.builder.advance.x; - return T1_Err_Ok; } - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** UNHINTED GLYPH LOADER *********/ - /********** *********/ - /********** The following code is in charge of loading a *********/ - /********** single outline. It completely ignores hinting *********/ - /********** and is used when FT_LOAD_NO_HINTING is set. *********/ - /********** *********/ - /********** The Type 1 hinter is located in `t1hint.c' *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ + /**********************************************************************/ + /**********************************************************************/ + /**********************************************************************/ + /********** *********/ + /********** *********/ + /********** UNHINTED GLYPH LOADER *********/ + /********** *********/ + /********** The following code is in charge of loading a *********/ + /********** single outline. It completely ignores hinting *********/ + /********** and is used when FT_LOAD_NO_HINTING is set. *********/ + /********** *********/ + /********** The Type 1 hinter is located in "t1hint.c" *********/ + /********** *********/ + /**********************************************************************/ + /**********************************************************************/ + /**********************************************************************/ + static FT_Error close_open_path( T1_Builder* builder ) { FT_Error error; - FT_Outline* cur = &builder->current; + FT_Outline* cur = builder->current; FT_Int num_points; FT_Int first_point; + /* Some fonts, like Hershey, are made of "open paths" which are */ + /* now managed directly by FreeType. In this case, it is necessary */ + /* to close the path by duplicating its points in reverse order, */ + /* which is precisely the purpose of this function */ - /* Some fonts, like Hershey, are made of `open paths' which are */ - /* now managed directly by FreeType. In this case, it is necessary */ - /* to close the path by duplicating its points in reverse order, */ - /* which is precisely the purpose of this function. */ - - /* first compute the number of points to duplicate. */ - if ( cur->n_contours > 1 ) - first_point = cur->contours[cur->n_contours - 2] + 1; + /* first compute the number of points to duplicate.. */ + if (cur->n_contours > 1) + first_point = cur->contours[ cur->n_contours-2 ]+1; else first_point = 0; @@ -1284,16 +1129,14 @@ FT_Vector* point; char* tags; - error = T1_Add_Points( builder, num_points ); - if ( error ) - return error; + if (error) return error; point = cur->points + cur->n_points; - tags = cur->tags + cur->n_points; + tags = cur->tags + cur->n_points; - source_point = point - 2; - source_tags = tags - 2; + source_point = point - 2; + source_tags = tags - 2; cur->n_points += num_points; @@ -1301,14 +1144,13 @@ do { *point++ = *source_point--; - *tags++ = *source_tags--; + *tags++ = *source_tags--; num_points--; } - while ( num_points > 0 ); + while (num_points > 0); } builder->path_begun = 0; - return T1_Err_Ok; } @@ -1316,52 +1158,46 @@ static FT_Error gload_closepath( T1_Builder* builder ) { - FT_Outline* cur = &builder->current; - + FT_Outline* cur = builder->current; /* save current contour, if any */ if ( cur->n_contours > 0 ) - cur->contours[cur->n_contours - 1] = cur->n_points - 1; + cur->contours[cur->n_contours-1] = cur->n_points-1; #ifndef T1_CONFIG_OPTION_DISABLE_HINTER - /* hint latest points if needed - this is not strictly required */ /* there, but it helps for debugging, and doesn't affect performance */ if ( builder->pass == 1 ) T1_Hint_Points( builder ); - -#endif /* T1_CONFIG_OPTION_DISABLE_HINTER */ +#endif builder->path_begun = 0; - return T1_Err_Ok; } + static FT_Error gload_endchar( T1_Builder* builder ) { - FT_Outline* cur = &builder->current; FT_Error error; - /* close path if needed */ - if ( builder->path_begun ) + if (builder->path_begun) { error = close_open_path( builder ); - if ( error ) - return error; + if (error) return error; } error = gload_closepath( builder ); - builder->base.n_points += cur->n_points; - builder->base.n_contours += cur->n_contours; + FT_GlyphLoader_Add( builder->loader ); return error; } + static FT_Error gload_sbw( T1_Builder* builder, FT_Pos sbx, @@ -1376,25 +1212,24 @@ builder->last.x = sbx; builder->last.y = sby; - return 0; } + + static FT_Error gload_rlineto( T1_Builder* builder, FT_Pos dx, FT_Pos dy ) { FT_Error error; - FT_Outline* cur = &builder->current; + FT_Outline* cur = builder->current; FT_Vector vec; - /* grow buffer if necessary */ - error = T1_Add_Points( builder, 1 ); - if ( error ) - return error; + error = T1_Add_Points ( builder, 1 ); + if (error) return error; if ( builder->load_points ) { @@ -1403,14 +1238,13 @@ vec.y = builder->last.y + dy; cur->points[cur->n_points] = vec; - cur->tags [cur->n_points] = FT_Curve_Tag_On; + cur->tags [cur->n_points] = FT_Curve_Tag_On; builder->last = vec; } cur->n_points++; - builder->path_begun = 1; - + builder->path_begun = 1; return T1_Err_Ok; } @@ -1421,35 +1255,31 @@ FT_Pos dy ) { FT_Error error; - FT_Outline* cur = &builder->current; + FT_Outline* cur = builder->current; FT_Vector vec; - - /* in the case where `path_begun' is set, we have an `rmoveto' */ - /* after some normal path definition. If the face's paint type */ - /* is set to 1, this means that we have an `open path', also */ - /* called a `stroke'. The FreeType raster doesn't support */ - /* opened paths, so we'll close it explicitely there. */ - + /* in the case where "path_begun" is set, we have a rmoveto */ + /* after some normal path definition. When the face's paint */ + /* type is set to 1, this means that we have an "open path", */ + /* also called a 'stroke'. The FreeType raster doesn't support */ + /* opened path, so we'll close it explicitely there.. */ if ( builder->path_begun && builder->face->type1.paint_type == 1 ) { if ( builder->face->type1.paint_type == 1 ) { error = close_open_path( builder ); - if ( error ) - return error; + if (error) return error; } } /* grow buffer if necessary */ error = T1_Add_Contours( builder, 1 ) || T1_Add_Points ( builder, 1 ); - if ( error ) - return error; + if (error) return error; /* save current contour, if any */ if ( cur->n_contours > 0 ) - cur->contours[cur->n_contours - 1] = cur->n_points - 1; + cur->contours[cur->n_contours-1] = cur->n_points-1; if ( builder->load_points ) { @@ -1457,7 +1287,7 @@ vec.x = builder->last.x + dx; vec.y = builder->last.y + dy; cur->points[cur->n_points] = vec; - cur->tags [cur->n_points] = FT_Curve_Tag_On; + cur->tags [cur->n_points] = FT_Curve_Tag_On; builder->last = vec; } @@ -1479,36 +1309,32 @@ FT_Pos dy3 ) { FT_Error error; - FT_Outline* cur = &builder->current; + FT_Outline* cur = builder->current; FT_Vector vec; FT_Vector* points; char* tags; /* grow buffer if necessary */ - error = T1_Add_Points( builder, 3 ); - if ( error ) - return error; + error = T1_Add_Points ( builder, 3 ); + if (error) return error; if ( builder->load_points ) { /* save point */ points = cur->points + cur->n_points; - tags = cur->tags + cur->n_points; + tags = cur->tags + cur->n_points; vec.x = builder->last.x + dx1; vec.y = builder->last.y + dy1; - points[0] = vec; - tags[0] = FT_Curve_Tag_Cubic; + points[0] = vec; tags[0] = FT_Curve_Tag_Cubic; vec.x += dx2; vec.y += dy2; - points[1] = vec; - tags[1] = FT_Curve_Tag_Cubic; + points[1] = vec; tags[1] = FT_Curve_Tag_Cubic; vec.x += dx3; vec.y += dy3; - points[2] = vec; - tags[2] = FT_Curve_Tag_On; + points[2] = vec; tags[2] = FT_Curve_Tag_On; builder->last = vec; } @@ -1519,6 +1345,8 @@ } + + static FT_Error gload_ignore( void ) { @@ -1541,30 +1369,31 @@ static const T1_Builder_Funcs gload_builder_interface_null = { - (T1_Builder_EndChar) gload_ignore, - (T1_Builder_Sbw) gload_sbw, /* record left bearing */ - (T1_Builder_ClosePath)gload_ignore, - (T1_Builder_RLineTo) gload_ignore, - (T1_Builder_RMoveTo) gload_ignore, - (T1_Builder_RCurveTo) gload_ignore + (T1_Builder_EndChar) gload_ignore, + (T1_Builder_Sbw) gload_sbw, /* record left bearing */ + (T1_Builder_ClosePath) gload_ignore, + (T1_Builder_RLineTo) gload_ignore, + (T1_Builder_RMoveTo) gload_ignore, + (T1_Builder_RCurveTo) gload_ignore }; static const T1_Hinter_Funcs gload_hinter_interface = { - (T1_Hinter_DotSection) gload_ignore, /* dotsection */ - (T1_Hinter_ChangeHints)gload_ignore, /* changehints */ - (T1_Hinter_Stem) gload_ignore, /* hstem & vstem */ - (T1_Hinter_Stem3) gload_ignore, /* hstem3 & vestem3 */ + (T1_Hinter_DotSection) gload_ignore, /* dotsection */ + (T1_Hinter_ChangeHints) gload_ignore, /* changehints */ + (T1_Hinter_Stem) gload_ignore, /* hstem & vstem */ + (T1_Hinter_Stem3) gload_ignore, /* hstem3 & vestem3 */ }; + /*****************************************************************/ /* */ /* Hinter overview : */ /* */ - /* This is a two-pass hinter. On the first pass, the hints */ + /* This is a two-pass hinter. On the first pass, the hints */ /* are all recorded by the hinter, and no point is loaded */ /* in the outline. */ /* */ @@ -1582,15 +1411,19 @@ FT_UInt glyph_index, FT_Bool recurse ) { - T1_Builder* builder = &decoder->builder; - T1_GlyphSlot glyph = builder->glyph; - T1_Font* type1 = &builder->face->type1; - FT_Outline old_base; - FT_Error error; + T1_Builder* builder = &decoder->builder; + T1_GlyphSlot glyph = builder->glyph; + T1_Font* type1 = &builder->face->type1; + FT_UInt old_points, old_contours; + FT_GlyphLoader* loader = decoder->builder.loader; + FT_Error error; - /* Pass 1 - try to load first glyph, simply recording points */ - old_base = builder->base; + old_points = loader->base.outline.n_points; + old_contours = loader->base.outline.n_contours; + + FT_GlyphLoader_Prepare( decoder->builder.loader ); + T1_Reset_Builder( builder, 0 ); builder->no_recurse = recurse; @@ -1604,61 +1437,51 @@ type1->num_subrs, type1->subrs, type1->subrs_len ); - if ( error ) - goto Exit; + if (error) goto Exit; - /* check for composite (i.e. `seac' operator) */ + /* check for composite (i.e. "seac" operator) */ if ( glyph->root.format == ft_glyph_format_composite ) { /* this is a composite glyph, we must then load the first one, */ /* then load the second one on top of it and translate it by a */ - /* fixed amount. */ - - FT_Outline* cur = &builder->current; - FT_UInt n_base_points; - FT_SubGlyph* subglyph = glyph->root.subglyphs; - T1_Size size = builder->size; - FT_Pos dx, dy; - FT_Vector left_bearing, advance; - + /* fixed amount.. */ + FT_UInt n_base_points; + FT_SubGlyph* subglyph = loader->base.subglyphs; + T1_Size size = builder->size; + FT_Pos dx, dy; + FT_Vector left_bearing, advance; /* clean glyph format */ glyph->root.format = ft_glyph_format_none; - /* First load `bchar' in builder */ + /* First load "bchar" in builder */ builder->no_recurse = 0; error = t1_load_hinted_glyph( decoder, subglyph->index, 0 ); - if ( error ) - goto Exit; + if (error) goto Exit; /* save the left bearing and width of the base character */ - /* as they will be erased by the next load. */ + /* as they will be erased by the next load.. */ left_bearing = builder->left_bearing; advance = builder->advance; - /* Then load `achar' in builder */ - n_base_points = builder->base.n_points; + /* Then load "achar" in builder */ + n_base_points = builder->base->n_points; subglyph++; - error = t1_load_hinted_glyph( decoder, subglyph->index, 0 ); - if ( error ) - goto Exit; + if (error) goto Exit; - /* adjust contours in accented character outline */ - { - FT_Int n; - - - for ( n = 0; n < cur->n_contours; n++ ) - cur->contours[n] += n_base_points; - } - /* Finally, move the accent */ dx = FT_MulFix( subglyph->arg1, size->root.metrics.x_scale ); dy = FT_MulFix( subglyph->arg2, size->root.metrics.y_scale ); - dx = ( dx + 32 ) & -64; - dy = ( dy + 32 ) & -64; - FT_Outline_Translate( cur, dx, dy ); + dx = (dx+32) & -64; + dy = (dy+32) & -64; + { + FT_Outline dummy; + + dummy.n_points = loader->base.outline.n_points - n_base_points; + dummy.points = loader->base.outline.points + n_base_points; + FT_Outline_Translate( &dummy, dx, dy ); + } /* restore the left side bearing and */ /* advance width of the base character */ @@ -1671,11 +1494,11 @@ T1_Hint_Stems( &decoder->builder ); /* undo the end-char */ - builder->base.n_points -= builder->current.n_points; - builder->base.n_contours -= builder->current.n_contours; + builder->base->n_points = old_points; + builder->base->n_contours = old_contours; /* Pass 2 - record and scale/hint the points */ - T1_Reset_Builder( &decoder->builder, 0 ); + T1_Reset_Builder( builder, 0 ); builder->pass = 1; builder->no_recurse = 0; @@ -1689,31 +1512,29 @@ } /* save new glyph tables */ - if ( recurse ) + if (recurse) T1_Done_Builder( builder ); Exit: return error; } - - -#endif /* T1_CONFIG_OPTION_DISABLE_HINTER */ +#endif + LOCAL_FUNC FT_Error T1_Load_Glyph( T1_GlyphSlot glyph, T1_Size size, FT_Int glyph_index, FT_Int load_flags ) { - FT_Error error; - T1_Decoder decoder; - T1_Face face = (T1_Face)glyph->root.face; - FT_Bool hinting; - T1_Font* type1 = &face->type1; + FT_Error error; + T1_Decoder decoder; + T1_Face face = (T1_Face)glyph->root.face; + FT_Bool hinting; + T1_Font* type1 = &face->type1; - - if ( load_flags & FT_LOAD_NO_RECURSE ) + if (load_flags & FT_LOAD_NO_RECURSE) load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; glyph->x_scale = size->root.metrics.x_scale; @@ -1728,7 +1549,7 @@ #ifndef T1_CONFIG_OPTION_DISABLE_HINTER - hinting = ( load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) ) == 0; + hinting = (load_flags & (FT_LOAD_NO_SCALE|FT_LOAD_NO_HINTING)) == 0; if ( hinting ) { @@ -1739,8 +1560,7 @@ error = t1_load_hinted_glyph( &decoder, glyph_index, 1 ); } else - -#endif /* T1_CONFIG_OPTION_DISABLE_HINTER */ +#endif { T1_Init_Decoder( &decoder, &gload_hinter_interface ); @@ -1748,7 +1568,7 @@ T1_Init_Builder( &decoder.builder, face, size, glyph, &gload_builder_interface ); - decoder.builder.no_recurse = ( load_flags & FT_LOAD_NO_RECURSE ) != 0; + decoder.builder.no_recurse = !!(load_flags & FT_LOAD_NO_RECURSE); /* now load the unscaled outline */ error = T1_Parse_CharStrings( &decoder, @@ -1762,13 +1582,14 @@ T1_Done_Builder( &decoder.builder ); } - /* Now, set the metrics - this is rather simple, as */ - /* the left side bearing is the xMin, and the top side */ - /* bearing the yMax. */ - if ( !error ) + + /* Now, set the metrics.. - this is rather simple, as : */ + /* the left side bearing is the xMin, and the top side */ + /* bearing the yMax.. */ + if (!error) { /* for composite glyphs, return only the left side bearing and the */ - /* advance width. */ + /* advance width.. */ if ( load_flags & FT_LOAD_NO_RECURSE ) { glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x; @@ -1779,20 +1600,18 @@ FT_BBox cbox; FT_Glyph_Metrics* metrics = &glyph->root.metrics; - /* apply the font matrix */ - FT_Outline_Transform( &glyph->root.outline, - &face->type1.font_matrix ); + FT_Outline_Transform( &glyph->root.outline, &face->type1.font_matrix ); FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); /* grid fit the bounding box if necessary */ - if ( hinting ) + if (hinting) { cbox.xMin &= -64; cbox.yMin &= -64; - cbox.xMax = ( cbox.xMax + 63 ) & -64; - cbox.yMax = ( cbox.yMax + 63 ) & -64; + cbox.xMax = ( cbox.xMax+63 ) & -64; + cbox.yMax = ( cbox.yMax+63 ) & -64; } metrics->width = cbox.xMax - cbox.xMin; @@ -1802,7 +1621,7 @@ metrics->horiBearingY = cbox.yMax; /* copy the _unscaled_ advance width */ - metrics->horiAdvance = decoder.builder.advance.x; + metrics->horiAdvance = decoder.builder.advance.x; /* make up vertical metrics */ metrics->vertBearingX = 0; @@ -1818,29 +1637,28 @@ glyph->root.outline.flags |= ft_outline_reverse_fill; -#if 0 + /* glyph->root.outline.second_pass = TRUE; - glyph->root.outline.high_precision = size->root.metrics.y_ppem < 24; + glyph->root.outline.high_precision = ( size->root.metrics.y_ppem < 24 ); glyph->root.outline.dropout_mode = 2; -#endif + */ if ( hinting ) { - /* adjust the advance width */ - /* XXX TODO: consider stem hints grid-fit */ + /* adjust the advance width */ + /* XXX : TODO : consider stem hints grid-fit */ metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, glyph->x_scale ); } - else if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) + else if ( (load_flags & FT_LOAD_NO_SCALE) == 0 ) { /* scale the outline and the metrics */ FT_Int n; - FT_Outline* cur = &decoder.builder.base; + FT_Outline* cur = decoder.builder.base; FT_Vector* vec = cur->points; FT_Fixed x_scale = glyph->x_scale; FT_Fixed y_scale = glyph->y_scale; - /* First of all, scale the points */ for ( n = cur->n_points; n > 0; n--, vec++ ) { @@ -1859,6 +1677,7 @@ metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale ); metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, x_scale ); + } } } @@ -1866,5 +1685,3 @@ return error; } - -/* END */ diff --git a/src/type1/t1gload.h b/src/type1/t1gload.h index 5d21f2e0d..e491f4366 100644 --- a/src/type1/t1gload.h +++ b/src/type1/t1gload.h @@ -1,20 +1,36 @@ -/***************************************************************************/ -/* */ -/* t1gload.h */ -/* */ -/* Type 1 Glyph Loader (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - +/******************************************************************* + * + * t1gload.h 1.0 + * + * Type1 Glyph Loader. + * + * Copyright 1996-1998 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * The Type 1 glyph loader uses three distinct objects to build + * scaled and hinted outlines from a charstrings program. These are : + * + * - a glyph builder, T1_Builder, used to store the built outline + * + * - a glyph hinter, T1_Hinter, used to record and apply the stem + * hints + * + * - a charstrings interpreter, T1_Decoder, used to parse the + * Type 1 charstrings stream, manage a stack and call the builder + * and/or hinter depending on the opcodes. + * + * Ideally, a Type 2 glyph loader would only need to have its own + * T2_Decoder object (assuming the hinter is able to manage all + * kinds of hints). + * + ******************************************************************/ #ifndef T1GLOAD_H #define T1GLOAD_H @@ -26,15 +42,25 @@ #endif +/*************************************************************************/ +/* */ +/* T1_Builder_Funcs */ +/* */ +/* */ +/* a structure used to store the address of various functions */ +/* used by a glyph builder to implement the outline's "path */ +/* construction". */ +/* */ +/* */ typedef struct T1_Builder_ T1_Builder; typedef FT_Error (*T1_Builder_EndChar)( T1_Builder* loader ); - typedef FT_Error (*T1_Builder_Sbw)( T1_Builder* loader, - FT_Pos sbx, - FT_Pos sby, - FT_Pos wx, - FT_Pos wy ); + typedef FT_Error (*T1_Builder_Sbw) ( T1_Builder* loader, + FT_Pos sbx, + FT_Pos sby, + FT_Pos wx, + FT_Pos wy ); typedef FT_Error (*T1_Builder_ClosePath)( T1_Builder* loader ); @@ -54,17 +80,7 @@ FT_Pos dx3, FT_Pos dy3 ); - - /*************************************************************************/ - /* */ - /* */ - /* T1_Builder_Funcs */ - /* */ - /* */ - /* A structure to store the address of various functions used by a */ - /* glyph builder to implement the outline's `path construction'. */ - /* */ - typedef struct T1_Builder_Funcs_ + typedef struct T1_Builder_Funcs_ { T1_Builder_EndChar end_char; T1_Builder_Sbw set_bearing_point; @@ -76,98 +92,94 @@ } T1_Builder_Funcs; - /*************************************************************************/ - /* */ - /* */ - /* T1_Builder */ - /* */ - /* */ - /* A structure used during glyph loading to store its outline. */ - /* */ - /* */ - /* memory :: The current memory object. */ - /* */ - /* face :: The current face object. */ - /* */ - /* size :: The current size object. */ - /* */ - /* glyph :: The current glyph slot. */ - /* */ - /* current :: The current glyph outline. */ - /* */ - /* base :: The base glyph outline. */ - /* */ - /* max_points :: The maximum number of points in builder outline. */ - /* */ - /* max_contours :: The maximum number of contours in builder outline. */ - /* */ - /* last :: The last point position. */ - /* */ - /* scale_x :: The horizontal scale (FUnits to sub-pixels). */ - /* */ - /* scale_y :: The vertical scale (FUnits to sub-pixels). */ - /* */ - /* pos_x :: The horizontal translation (for composite glyphs). */ - /* */ - /* pos_y :: The vertical translation (for composite glyphs). */ - /* */ - /* left_bearing :: The left side bearing point. */ - /* */ - /* advance :: The horizontal advance vector. */ - /* */ - /* no_recurse :: */ - /* */ - /* bbox :: The glyph's bounding box. */ - /* */ - /* path_begun :: A flag which indicates that a new path has begun. */ - /* */ - /* load_points :: A flag which indicates, if not set, that no points */ - /* are loaded. */ - /* */ - /* pass :: The pass number for multi-pass hinters. */ - /* */ - /* hint_point :: The index of the next point to hint. */ - /* */ - /* funcs :: A table of builder functions used to perform the */ - /* outline's path construction. */ - /* */ - struct T1_Builder_ + +/*************************************************************************/ +/* */ +/* T1_Builder */ +/* */ +/* */ +/* a structure used during glyph loading to store its outline. */ +/* */ +/* */ +/* system :: current system object */ +/* face :: current face object */ +/* size :: current size object */ +/* glyph :: current glyph slot */ +/* */ +/* current :: current glyph outline */ +/* base :: base glyph outline */ +/* */ +/* max_points :: maximum points in builder outline */ +/* max_contours :: maximum contours in builder outline */ +/* */ +/* last :: last point position */ +/* */ +/* scale_x :: horizontal scale ( FUnits to sub-pixels ) */ +/* scale_y :: vertical scale ( FUnits to sub-pixels ) */ +/* pos_x :: horizontal translation (composite glyphs) */ +/* pos_y :: vertical translation (composite glyph) */ +/* */ +/* left_bearing :: left side bearing point */ +/* advance :: horizontal advance vector */ +/* */ +/* path_begun :: flag, indicates that a new path has begun */ +/* load_points :: flag, if not set, no points are loaded */ +/* */ +/* pass :: pass number for multi-pass hinters */ +/* */ +/* funcs :: table of builder functions used to perform */ +/* the outline's path construction */ +/* */ +/* hint_point :: index of next point to hint.. */ +/* */ +/* */ +/* */ +/* */ + + struct T1_Builder_ { - FT_Memory memory; - T1_Face face; - T1_Size size; - T1_GlyphSlot glyph; + FT_Memory memory; + T1_Face face; + T1_Size size; + T1_GlyphSlot glyph; + FT_GlyphLoader* loader; - FT_Outline current; /* the current glyph outline */ - FT_Outline base; /* the composite glyph outline */ + FT_Outline* current; /* the current glyph outline */ + FT_Outline* base; /* the composite glyph outline */ - FT_Int max_points; /* capacity of base outline in points */ - FT_Int max_contours; /* capacity of base outline in contours */ + FT_Vector last; - FT_Vector last; + FT_Fixed scale_x; + FT_Fixed scale_y; - FT_Fixed scale_x; - FT_Fixed scale_y; + FT_Pos pos_x; + FT_Pos pos_y; - FT_Pos pos_x; - FT_Pos pos_y; + FT_Vector left_bearing; + FT_Vector advance; + FT_Bool no_recurse; - FT_Vector left_bearing; - FT_Vector advance; - FT_Bool no_recurse; + FT_BBox bbox; /* bounding box */ + FT_Bool path_begun; + FT_Bool load_points; - FT_BBox bbox; /* bounding box */ - FT_Bool path_begun; - FT_Bool load_points; - - FT_Int pass; - FT_Int hint_point; + FT_Int pass; + FT_Int hint_point; /* path construction function interface */ T1_Builder_Funcs funcs; }; +/*************************************************************************/ +/* */ +/* T1_Hinter_Funcs */ +/* */ +/* */ +/* a structure used to store the address of various functions */ +/* used by a Type 1 hinter to perform outline hinting. */ +/* */ + typedef FT_Error (*T1_Hinter_ChangeHints)( T1_Builder* builder ); typedef FT_Error (*T1_Hinter_DotSection)( T1_Builder* builder ); @@ -177,6 +189,7 @@ FT_Pos width, FT_Bool vertical ); + typedef FT_Error (*T1_Hinter_Stem3)( T1_Builder* builder, FT_Pos pos0, FT_Pos width0, @@ -186,27 +199,18 @@ FT_Pos width2, FT_Bool vertical ); - - /*************************************************************************/ - /* */ - /* */ - /* T1_Hinter_Funcs */ - /* */ - /* */ - /* A structure to store the address of various functions used by a */ - /* Type 1 hinter to perform outline hinting. */ - /* */ typedef struct T1_Hinter_Func_ { - T1_Hinter_ChangeHints change_hints; - T1_Hinter_DotSection dot_section; - T1_Hinter_Stem stem; - T1_Hinter_Stem3 stem3; + T1_Hinter_ChangeHints change_hints; + T1_Hinter_DotSection dot_section; + T1_Hinter_Stem stem; + T1_Hinter_Stem3 stem3; } T1_Hinter_Funcs; - typedef enum T1_Operator_ + + typedef enum T1_Operator_ { op_none = 0, op_endchar, @@ -240,8 +244,10 @@ } T1_Operator; + + /* execution context charstring zone */ - typedef struct T1_Decoder_Zone_ + typedef struct T1_Decoder_Zone_ { FT_Byte* base; FT_Byte* limit; @@ -250,54 +256,166 @@ } T1_Decoder_Zone; - typedef struct T1_Decoder_ + typedef struct T1_Decoder_ { - T1_Builder builder; - T1_Hinter_Funcs hinter; + T1_Builder builder; + T1_Hinter_Funcs hinter; - FT_Int stack[T1_MAX_CHARSTRINGS_OPERANDS]; - FT_Int* top; + FT_Int stack[ T1_MAX_CHARSTRINGS_OPERANDS ]; + FT_Int* top; - T1_Decoder_Zone zones[T1_MAX_SUBRS_CALLS + 1]; - T1_Decoder_Zone* zone; + T1_Decoder_Zone zones[ T1_MAX_SUBRS_CALLS+1 ]; + T1_Decoder_Zone* zone; - FT_Int flex_state; - FT_Int num_flex_vectors; - FT_Vector flex_vectors[7]; + FT_Int flex_state; + FT_Int num_flex_vectors; + FT_Vector flex_vectors[7]; } T1_Decoder; + +/********************************************************************* + * + * + * T1_Init_Builder + * + * + * Initialise a given glyph builder. + * + * + * builder :: glyph builder to initialise + * face :: current face object + * size :: current size object + * glyph :: current glyph object + * funcs :: glyph builder functions (or "methods"). + * + * + * This function is exported for now because it is used by the + * "t1dump" utility. Later, it will be accessed through a + * format-specific extension + * + *********************************************************************/ + LOCAL_DEF - void T1_Init_Builder( T1_Builder* builder, - T1_Face face, - T1_Size size, - T1_GlyphSlot glyph, - const T1_Builder_Funcs* funcs ); + void T1_Init_Builder( T1_Builder* builder, + T1_Face face, + T1_Size size, + T1_GlyphSlot glyph, + const T1_Builder_Funcs* funcs ); + +/********************************************************************* + * + * + * T1_Done_Builder + * + * + * Finalise a given glyph builder. Its content can still be + * used after the call, but the function saves important information + * within the corresponding glyph slot. + * + * + * builder :: glyph builder to initialise + * + * + * This function is exported for now because it is used by the + * "t1dump" utility. Later, it will be accessed through a + * format-specific extension + * + *********************************************************************/ LOCAL_DEF void T1_Done_Builder( T1_Builder* builder ); + +/********************************************************************* + * + * + * T1_Init_Decoder + * + * + * Initialise a given Type 1 decoder for parsing + * + * + * decoder :: Type 1 decoder to initialise + * funcs :: hinter functions interface + * + * + * This function is exported for now because it is used by the + * "t1dump" utility. Later, it will be accessed through a + * format-specific extension + * + *********************************************************************/ + LOCAL_DEF void T1_Init_Decoder( T1_Decoder* decoder, const T1_Hinter_Funcs* funcs ); + + + /* Compute the maximum advance width of a font through quick parsing */ LOCAL_DEF FT_Error T1_Compute_Max_Advance( T1_Face face, - FT_Int* max_advance ); + FT_Int *max_advance ); + + /* This function is exported, because it is used by the T1Dump utility */ LOCAL_DEF - FT_Error T1_Parse_CharStrings( T1_Decoder* decoder, - FT_Byte* charstring_base, - FT_Int charstring_len, - FT_Int num_subrs, - FT_Byte** subrs_base, - FT_Int* subrs_len ); + FT_Error T1_Parse_CharStrings( T1_Decoder* decoder, + FT_Byte* charstring_base, + FT_Int charstring_len, + FT_Int num_subrs, + FT_Byte** subrs_base, + FT_Int* subrs_len ); + + +/*************************************************************************/ +/* */ +/* T1_Add_Points */ +/* */ +/* */ +/* Checks that there is enough room in the current load glyph outline */ +/* to accept "num_points" additional outline points. If not, this */ +/* function grows the load outline's arrays accordingly.. */ +/* */ +/* */ +/* builder :: pointer to glyph builder object */ +/* num_points :: number of points that will be added later */ +/* */ +/* */ +/* Type1 error code. 0 means success */ +/* */ +/* */ +/* This function does NOT update the points count in the glyph loader */ +/* This must be done by the caller itself, after this function is */ +/* invoked.. */ +/* */ LOCAL_DEF FT_Error T1_Add_Points( T1_Builder* builder, FT_Int num_points ); +/*************************************************************************/ +/* */ +/* T1_Add_Contours */ +/* */ +/* */ +/* Checks that there is enough room in the current load glyph outline */ +/* to accept "num_contours" additional contours. If not, this func */ +/* the load outline's arrays accordingly.. */ +/* */ +/* */ +/* builder :: pointer to glyph builder object */ +/* num_contours :: number of contours that will be added later */ +/* */ +/* */ +/* Type1 error code. 0 means success */ +/* */ +/* */ +/* This function does NOT update the contours count in the load glyph */ +/* This must be done by the caller itself, after this function is */ +/* invoked.. */ +/* */ LOCAL_DEF FT_Error T1_Add_Contours( T1_Builder* builder, FT_Int num_contours ); @@ -314,8 +432,4 @@ } #endif - #endif /* T1GLOAD_H */ - - -/* END */ diff --git a/src/type1/t1hinter.c b/src/type1/t1hinter.c index a0081f965..aac08387c 100644 --- a/src/type1/t1hinter.c +++ b/src/type1/t1hinter.c @@ -1,160 +1,151 @@ -/***************************************************************************/ -/* */ -/* t1hinter.c */ -/* */ -/* Type 1 hinter (body). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* The Hinter is in charge of fitting th scaled outline to the pixel */ - /* grid in order to considerably improve the quality of the Type 1 font */ - /* driver's output. */ - /* */ - /*************************************************************************/ - +/******************************************************************* + * + * t1hinter.c 1.2 + * + * Type1 hinter. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * The Hinter is in charge of fitting th scaled outline to the + * pixel grid in order to considerably improve the quality of + * the Type 1 font driver's output.. + * + ******************************************************************/ #include #include #include - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ #undef FT_COMPONENT -#define FT_COMPONENT trace_t1hint +#define FT_COMPONENT trace_t1hint /* for debugging/tracing */ #undef ONE_PIXEL #define ONE_PIXEL 64 #undef ROUND -#define ROUND( x ) ( ( x + ONE_PIXEL / 2 ) & -ONE_PIXEL ) +#define ROUND(x) (( x + ONE_PIXEL/2 ) & -ONE_PIXEL) #undef SCALE -#define SCALE( val ) FT_MulFix( val, scale ) +#define SCALE(val) FT_MulFix( val, scale ) /* various constants used to describe the alignment of a horizontal */ /* stem with regards to the blue zones */ - #define T1_ALIGN_NONE 0 #define T1_ALIGN_BOTTOM 1 #define T1_ALIGN_TOP 2 #define T1_ALIGN_BOTH 3 - /* very simple bubble sort (not a lot of elements, mostly */ - /* pre-sorted, no need for quicksort) */ +/************************************************************************ + * + * + * t1_set_blue_zones + * + * + * Set a size object's blue zones during reset. This will compute + * the "snap" zone corresponding to each blue zone. + * + * + * size :: handle to target size object + * + * + * Error code. 0 means success + * + * + * This functions does the following : + * + * 1. It extracts the bottom and top blue zones from the + * face object. + * + * 2. Each zone is then grown by BlueFuzz, overlapping + * is eliminated by adjusting the zone edges appropriately + * + * 3. For each zone, we keep its original font units position, its + * original scaled position, as well as its grown/adjusted + * edges. + * + ************************************************************************/ - static - void t1_sort_blues( FT_Int* blues, - FT_Int count ) - { - FT_Int i, swap; - FT_Int* cur; - - - for ( i = 2; i < count; i += 2 ) - { - cur = blues + i; - do + /* ultra simple bubble sort (not a lot of elements, mostly */ + /* pre-sorted, no need for quicksort) */ + static + void t1_sort_blues( FT_Int* blues, + FT_Int count ) { - if ( cur[-1] < cur[0] ) - break; + FT_Int i, swap; + FT_Int* cur; - swap = cur[-2]; cur[-2] = cur[0]; cur[0] = swap; - swap = cur[-1]; cur[-1] = cur[1]; cur[1] = swap; - cur -= 2; - } while ( cur > blues ); - } - } + for ( i = 2; i < count; i += 2 ) + { + cur = blues + i; + do + { + if ( cur[-1] < cur[0] ) + break; + + swap = cur[-2]; cur[-2] = cur[0]; cur[0] = swap; + swap = cur[-1]; cur[-1] = cur[1]; cur[1] = swap; + cur -= 2; + } + while ( cur > blues ); + } + } - /*************************************************************************/ - /* */ - /* */ - /* t1_set_blue_zones */ - /* */ - /* */ - /* Sets a size object's blue zones during reset. This will compute */ - /* the `snap' zone corresponding to each blue zone. */ - /* */ - /* */ - /* size :: A handle to target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This functions does the following: */ - /* */ - /* 1. It extracts the bottom and top blue zones from the face object. */ - /* */ - /* 2. Each zone is then grown by `BlueFuzz', overlapping is */ - /* eliminated by adjusting the zone edges appropriately. */ - /* */ - /* 3. For each zone, we keep its original font units position, its */ - /* original scaled position, as well as its grown/adjusted edges. */ - /* */ static FT_Error t1_set_blue_zones( T1_Size size ) { - T1_Face face = (T1_Face)size->root.face; - T1_Private* priv = &face->type1.private_dict; - FT_Int n; - FT_Int blues[24]; - FT_Int num_bottom; - FT_Int num_top; - FT_Int num_blues; - T1_Size_Hints* hints = size->hints; - T1_Snap_Zone* zone; - FT_Pos pix, orus; - FT_Pos min, max, threshold; - FT_Fixed scale; - FT_Bool is_bottom; + T1_Face face = (T1_Face)size->root.face; + T1_Private* priv = &face->type1.private_dict; + FT_Int n; + FT_Int blues[24]; + FT_Int num_bottom; + FT_Int num_top; + FT_Int num_blues; + T1_Size_Hints* hints = size->hints; + T1_Snap_Zone* zone; + FT_Pos pix, orus; + FT_Pos min, max, threshold; + FT_Fixed scale; + FT_Bool is_bottom; - - /***********************************************************************/ - /* */ - /* copy bottom and top blue zones in local arrays */ - /* */ + /**********************************************************************/ + /* */ + /* COPY BOTTOM AND TOP BLUE ZONES IN LOCAL ARRAYS */ + /* */ + /* */ /* First of all, check the sizes of the /BlueValues and /OtherBlues */ - /* tables. They all must contain an even number of arguments. */ + /* tables. They all must contain an even number of arguments */ if ( priv->num_other_blues & 1 || priv->num_blue_values & 1 ) { - FT_ERROR(( "t1_set_blue_zones: odd number of blue values\n" )); + FT_ERROR(( "T1.Copy_Blues : odd number of blue values\n" )); return T1_Err_Syntax_Error; } - /* copy the bottom blue zones from /OtherBlues */ + /* copy the bottom blue zones from /OtherBlues */ num_top = 0; num_bottom = priv->num_other_blues; for ( n = 0; n < num_bottom; n ++ ) blues[n] = priv->other_blues[n]; - /* add the first blue zone in /BlueValues to the table */ + /* Add the first blue zone in /BlueValues to the table */ num_top = priv->num_blue_values - 2; if ( num_top >= 0 ) { - blues[num_bottom ] = priv->blue_values[0]; - blues[num_bottom + 1] = priv->blue_values[1]; + blues[ num_bottom ] = priv->blue_values[0]; + blues[num_bottom+1] = priv->blue_values[1]; num_bottom += 2; } @@ -168,7 +159,7 @@ if ( num_top > 0 ) { for ( n = 0; n < num_top; n++ ) - blues[num_bottom + n] = priv->blue_values[n + 2]; + blues[ num_bottom+n ] = priv->blue_values[n+2]; /* sort the top blue zones */ t1_sort_blues( blues + num_bottom, num_top ); @@ -179,29 +170,28 @@ num_blues = num_top + num_bottom; hints->num_blue_zones = ( num_blues ) >> 1; - /***********************************************************************/ - /* */ - /* build blue snap zones from the local blues arrays */ - /* */ + /**********************************************************************/ + /* */ + /* BUILD BLUE SNAP ZONES FROM THE LOCAL BLUES ARRAYS */ + /* */ + /* */ scale = size->root.metrics.y_scale; zone = hints->blue_zones; - threshold = ONE_PIXEL / 4; /* 0.25 pixels */ + threshold = ONE_PIXEL/4; /* 0.25 pixels */ for ( n = 0; n < num_blues; n += 2, zone ++ ) { - is_bottom = n < num_bottom ? 1 : 0; + is_bottom = ( n < num_bottom ? 1 : 0 ); - orus = blues[n + is_bottom]; /* get alignement coordinate */ - pix = SCALE( orus ); /* scale it */ + orus = blues[n+is_bottom]; /* get alignement coordinate */ + pix = SCALE( orus ); /* scale it */ - min = SCALE( blues[n ] - priv->blue_fuzz ); - max = SCALE( blues[n + 1] + priv->blue_fuzz ); + min = SCALE( blues[ n ] - priv->blue_fuzz ); + max = SCALE( blues[n+1] + priv->blue_fuzz ); - if ( min > pix - threshold ) - min = pix - threshold; - if ( max < pix + threshold ) - max = pix + threshold; + if ( min > pix - threshold ) min = pix - threshold; + if ( max < pix + threshold ) max = pix + threshold; zone->orus = orus; zone->pix = pix; @@ -213,22 +203,24 @@ zone = hints->blue_zones; for ( n = 0; n < num_blues-2; n += 2, zone ++ ) { - if ( n != num_bottom - 2 && + if ( n != num_bottom-2 && zone[0].max > zone[1].min ) - zone[0].max = zone[1].min = ( zone[0].pix + zone[1].pix ) / 2; + { + zone[0].max = zone[1].min = (zone[0].pix+zone[1].pix)/2; + } } + /* Compare the current pixel size with the BlueScale value */ - /* to know whether to supress overshoots. */ + /* to know wether to supress overshoots.. */ hints->supress_overshoots = - size->root.metrics.y_ppem < FT_MulFix( 1000, priv->blue_scale ); - -#ifdef FT_DEBUG_LEVEL_TRACE + ( size->root.metrics.y_ppem < FT_MulFix(1000,priv->blue_scale) ); /* Now print the new blue values in tracing mode */ +#ifdef FT_DEBUG_LEVEL_TRACE - FT_TRACE2(( "Blue Zones for size object at $%08lx:\n", (long)size )); + FT_TRACE2(( "Blue Zones for size object at $%08lx :\n", (long)size )); FT_TRACE2(( " orus pix min max\n" )); FT_TRACE2(( "-------------------------------\n" )); @@ -236,14 +228,14 @@ for ( n = 0; n < hints->num_blue_zones; n++ ) { FT_TRACE2(( " %3d %.2f %.2f %.2f\n", - zone->orus, - zone->pix / 64.0, - zone->min / 64.0, - zone->max / 64.0 )); + zone->orus, + zone->pix/64.0, + zone->min/64.0, + zone->max/64.0 )); zone++; } - FT_TRACE2(( "\nOvershoots are %s\n\n", - hints->supress_overshoots ? "supressed" : "active" )); + FT_TRACE2(( "\nOver shoots are %s\n\n", + hints->supress_overshoots ? "supressed" : "active" )); #endif /* DEBUG_LEVEL_TRACE */ @@ -251,35 +243,38 @@ } - /*************************************************************************/ - /* */ - /* */ - /* t1_set_snap_zones */ - /* */ - /* */ - /* This function set a size object's stem snap zones. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function performs the following: */ - /* */ - /* 1. It reads and scales the stem snap widths from the parent face. */ - /* */ - /* 2. A `snap zone' is computed for each snap width, by `growing' it */ - /* with a threshold of 1/2 pixel. Overlapping is avoided through */ - /* proper edge adjustment. */ - /* */ - /* 3. Each width whose zone contain the scaled standard set width is */ - /* removed from the table. */ - /* */ - /* 4. Finally, the standard set width is scaled, and its correponding */ - /* `snap zone' is inserted into the sorted snap zones table. */ - /* */ + +/************************************************************************ + * + * + * t1_set_snap_zones + * + * + * This function set a size object's stem snap zones. + * + * + * size :: handle to target size object + * + * + * Error code. 0 means success + * + * + * This function performs the following : + * + * 1. It reads and scales the stem snap widths from the parent face + * + * 2. A "snap zone" is computed for each snap width, by "growing" + * it with a threshold of a 1/2 pixel. Overlapping is avoided + * through proper edge adjustment. + * + * 3. Each width whose zone contain the scaled standard set width + * is removed from the table + * + * 4. Finally, the standard set width is scaled, and its correponding + * "snap zone" is inserted into the sorted snap zones table + * + ************************************************************************/ + static FT_Error t1_set_snap_zones( T1_Size size ) { @@ -290,11 +285,10 @@ FT_Pos standard_width; FT_Fixed scale; - T1_Face face = (T1_Face)size->root.face; - T1_Private* priv = &face->type1.private_dict; + T1_Face face = (T1_Face)size->root.face; + T1_Private* priv = &face->type1.private_dict; T1_Size_Hints* hints = size->hints; - /* start with horizontal snap zones */ direction = 0; standard_width = priv->standard_width[0]; @@ -303,26 +297,24 @@ orgs = priv->snap_widths; scale = size->root.metrics.x_scale; - while ( direction < 2 ) + while (direction < 2) { - /*********************************************************************/ - /* */ - /* Read and scale stem snap widths table from the physical font */ - /* record. */ - /* */ - + /*****************************************************************/ + /* */ + /* Read and scale stem snap widths table from the physical */ + /* font record. */ + /* */ FT_Pos prev, orus, pix, min, max, threshold; - - threshold = ONE_PIXEL / 4; + threshold = ONE_PIXEL/4; zone = base_zone; if ( n_zones > 0 ) { orus = *orgs++; pix = SCALE( orus ); - min = pix - threshold; - max = pix + threshold; + min = pix-threshold; + max = pix+threshold; zone->orus = orus; zone->pix = pix; @@ -334,12 +326,12 @@ orus = *orgs++; pix = SCALE( orus ); - if ( pix - prev < 2 * threshold ) + if ( pix-prev < 2*threshold ) { - min = max = ( pix + prev ) / 2; + min = max = (pix+prev)/2; } else - min = pix - threshold; + min = pix-threshold; zone->max = max; zone++; @@ -347,52 +339,49 @@ zone->pix = pix; zone->min = min; - max = pix + threshold; + max = pix+threshold; prev = pix; } zone->max = max; } + /* print the scaled stem snap values in tracing modes */ #ifdef FT_DEBUG_LEVEL_TRACE - /* print the scaled stem snap values in tracing mode */ + FT_TRACE2(( "Set_Snap_Zones : first %s pass\n", + direction ? "vertical" : "horizontal" )); - FT_TRACE2(( "Set_Snap_Zones: first %s pass\n", - direction ? "vertical" : "horizontal" )); - - FT_TRACE2(( "Scaled original stem snap zones:\n" )); + FT_TRACE2(( "Scaled original stem snap zones :\n" )); FT_TRACE2(( " orus pix min max\n" )); FT_TRACE2(( "-----------------------------\n" )); zone = base_zone; for ( n = 0; n < n_zones; n++, zone++ ) FT_TRACE2(( " %3d %.2f %.2f %.2f\n", - zone->orus, - zone->pix / 64.0, - zone->min / 64.0, - zone->max / 64.0 )); - FT_TRACE2(( "\n" )); + zone->orus, + zone->pix/64.0, + zone->min/64.0, + zone->max/64.0 )); + FT_TRACE2(( "\n" )); - FT_TRACE2(( "Standard width = %d\n", standard_width )); + FT_TRACE2(( "Standard width = %d\n", standard_width )); +#endif -#endif /* FT_DEBUG_LEVEL_TRACE */ - - /*********************************************************************/ - /* */ - /* Now, each snap width which is in the range of the standard set */ - /* width will be removed from the list. */ - /* */ + /*****************************************************************/ + /* */ + /* Now, each snap width which is in the range of the standard */ + /* set width will be removed from the list.. */ + /* */ if ( standard_width > 0 ) { T1_Snap_Zone* parent; FT_Pos std_pix, std_min, std_max; - std_pix = SCALE( standard_width ); - std_min = std_pix - threshold; - std_max = std_pix + threshold; + std_min = std_pix-threshold; + std_max = std_pix+threshold; num_zones = 0; zone = base_zone; @@ -403,10 +392,8 @@ if ( zone->pix >= std_min && zone->pix <= std_max ) { /* this zone must be removed from the list */ - if ( std_min > zone->min ) - std_min = zone->min; - if ( std_max < zone->max ) - std_max = zone->max; + if ( std_min > zone->min ) std_min = zone->min; + if ( std_max < zone->max ) std_max = zone->max; } else { @@ -416,23 +403,21 @@ zone++; } - /*******************************************************************/ - /* */ - /* Now, insert the standard width zone */ - /* */ + /**********************************************/ + /* Now, insert the standard width zone */ - zone = base_zone + num_zones; + zone = base_zone+num_zones; while ( zone > base_zone && zone[-1].pix > std_max ) { zone[0] = zone[-1]; - zone--; + zone --; } /* check border zones */ if ( zone > base_zone && zone[-1].max > std_min ) zone[-1].max = std_min; - if ( zone < base_zone + num_zones && zone[1].min < std_max ) + if ( zone < base_zone+num_zones && zone[1].min < std_max ) zone[1].min = std_max; zone->orus = standard_width; @@ -446,34 +431,30 @@ num_zones = n_zones; /* save total number of stem snaps now */ - if ( direction ) - hints->num_snap_heights = num_zones; - else - hints->num_snap_widths = num_zones; + if (direction) hints->num_snap_heights = num_zones; + else hints->num_snap_widths = num_zones; + /* print the scaled stem snap values in tracing modes */ #ifdef FT_DEBUG_LEVEL_TRACE - /* print the scaled stem snap values in tracing mode */ + FT_TRACE2(( "Set_Snap_Zones : second %s pass\n", + direction ? "vertical" : "horizontal" )); - FT_TRACE2(( "Set_Snap_Zones: second %s pass\n", - direction ? "vertical" : "horizontal" )); - - FT_TRACE2(( "Scaled clipped stem snap zones:\n" )); + FT_TRACE2(( "Scaled clipped stem snap zones :\n" )); FT_TRACE2(( " orus pix min max\n" )); FT_TRACE2(( "-----------------------------\n" )); zone = base_zone; for ( n = 0; n < num_zones; n++, zone++ ) FT_TRACE2(( " %3d %.2f %.2f %.2f\n", - zone->orus, - zone->pix / 64.0, - zone->min / 64.0, - zone->max / 64.0 )); + zone->orus, + zone->pix/64.0, + zone->min/64.0, + zone->max/64.0 )); FT_TRACE2(( "\n" )); FT_TRACE2(( "Standard width = %d\n", standard_width )); - -#endif /* FT_DEBUG_LEVEL_TRACE */ +#endif /* continue with vertical snap zone */ direction++; @@ -488,145 +469,153 @@ } - /*************************************************************************/ - /* */ - /* */ - /* T1_New_Size_Hinter */ - /* */ - /* */ - /* Allocates a new hinter structure for a given size object. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* FreeType Error code. 0 means success. */ - /* */ +/************************************************************************ + * + * + * T1_New_Size_Hinter + * + * + * Allocates a new hinter structure for a given size object + * + * + * size :: handle to target size object + * + * + * Error code. 0 means success + * + ************************************************************************/ + LOCAL_FUNC FT_Error T1_New_Size_Hinter( T1_Size size ) { FT_Memory memory = size->root.face->memory; - - return MEM_Alloc( size->hints, sizeof ( *size->hints ) ); + return MEM_Alloc( size->hints, sizeof(*size->hints) ); } - /*************************************************************************/ - /* */ - /* */ - /* T1_Done_Size_Hinter */ - /* */ - /* */ - /* Releases a given size object's hinter structure. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ +/************************************************************************ + * + * + * T1_Done_Size_Hinter + * + * + * Releases a given size object's hinter structure + * + * + * size :: handle to target size object + * + ************************************************************************/ + LOCAL_FUNC - void T1_Done_Size_Hinter( T1_Size size ) + void T1_Done_Size_Hinter( T1_Size size ) { FT_Memory memory = size->root.face->memory; - FREE( size->hints ); } - /*************************************************************************/ - /* */ - /* */ - /* T1_Reset_Size_Hinter */ - /* */ - /* */ - /* Recomputes hinting information when a given size object has */ - /* changed its resolutions/char sizes/pixel sizes. */ - /* */ - /* */ - /* size :: A handle to the size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + +/************************************************************************ + * + * + * T1_Reset_Size_Hinter + * + * + * Recomputes hinting information when a given size object has + * changed its resolutions/char sizes/pixel sizes + * + * + * size :: handle to size object + * + * + * Error code. 0 means success + * + ************************************************************************/ + LOCAL_FUNC FT_Error T1_Reset_Size_Hinter( T1_Size size ) { - return t1_set_blue_zones( size ) || t1_set_snap_zones( size ); + return t1_set_blue_zones(size) || t1_set_snap_zones(size); } - /*************************************************************************/ - /* */ - /* */ - /* T1_New_Glyph_Hinter */ - /* */ - /* */ - /* Allocates a new hinter structure for a given glyph slot. */ - /* */ - /* */ - /* glyph :: A handle to the target glyph slot. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + +/************************************************************************ + * + * + * T1_New_Glyph_Hinter + * + * + * Allocates a new hinter structure for a given glyph slot + * + * + * glyph :: handle to target glyph slot + * + * + * Error code. 0 means success + * + ************************************************************************/ + LOCAL_FUNC FT_Error T1_New_Glyph_Hinter( T1_GlyphSlot glyph ) { FT_Memory memory = glyph->root.face->memory; - - return MEM_Alloc( glyph->hints, sizeof ( *glyph->hints ) ); + return MEM_Alloc( glyph->hints, sizeof(*glyph->hints) ); } - /*************************************************************************/ - /* */ - /* */ - /* T1_Done_Glyph_Hinter */ - /* */ - /* */ - /* Releases a given glyph slot's hinter structure. */ - /* */ - /* */ - /* glyph :: A handle to the glyph slot. */ - /* */ +/************************************************************************ + * + * + * T1_Done_Glyph_Hinter + * + * + * Releases a given glyph slot's hinter structure + * + * + * glyph :: handle to glyph slot + * + ************************************************************************/ + LOCAL_FUNC void T1_Done_Glyph_Hinter( T1_GlyphSlot glyph ) { FT_Memory memory = glyph->root.face->memory; - FREE( glyph->hints ); } - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** **********/ - /********** HINTED GLYPH LOADER **********/ - /********** **********/ - /********** The following code is in charge of the first **********/ - /********** and second pass when loading a single outline **********/ - /********** **********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ + /**********************************************************************/ + /**********************************************************************/ + /**********************************************************************/ + /********** *********/ + /********** *********/ + /********** HINTED GLYPH LOADER *********/ + /********** *********/ + /********** The following code is in charge of the first *********/ + /********** and second pass when loading a single outline *********/ + /********** *********/ + /**********************************************************************/ + /**********************************************************************/ + /**********************************************************************/ static - FT_Error t1_hinter_ignore( void ) + FT_Error t1_hinter_ignore( void ) { - /* do nothing, used for `dotsection' which is unsupported for now */ + /* do nothing, used for "dotsection" which is unsupported for now */ return 0; } - static - FT_Error t1_hinter_stem( T1_Builder* builder, - FT_Pos pos, - FT_Int width, - FT_Bool vertical ) + FT_Error t1_hinter_stem( T1_Builder* builder, + FT_Pos pos, + FT_Int width, + FT_Bool vertical ) { T1_Stem_Table* stem_table; T1_Stem_Hint* stems; @@ -635,15 +624,15 @@ FT_Bool new_stem; T1_Glyph_Hints* hinter = builder->glyph->hints; - /* select the appropriate stem array */ stem_table = vertical ? &hinter->vert_stems : &hinter->hori_stems; stems = stem_table->stems; num_stems = stem_table->num_stems; /* Compute minimum and maximum coord for the stem */ - min = pos + ( vertical ? builder->left_bearing.x - : builder->left_bearing.y ); + min = pos + ( vertical + ? builder->left_bearing.x + : builder->left_bearing.y ); if ( width >= 0 ) max = min + width; @@ -656,8 +645,8 @@ max = min; } - /* now scan the array. If we find a stem with the same borders */ - /* simply activate it. */ + /* now scan the array. If we find a stem with the same borders */ + /* simply activate it.. */ cur_stem = stems; new_stem = 1; @@ -667,10 +656,10 @@ cur_stem->max_edge.orus == max ) { /* This stem is already in the table, simply activate it */ - if ( ( cur_stem->hint_flags & T1_HINT_FLAG_ACTIVE ) == 0 ) + if ( (cur_stem->hint_flags & T1_HINT_FLAG_ACTIVE) == 0) { - cur_stem->hint_flags |= T1_HINT_FLAG_ACTIVE; - stem_table->num_active++; + cur_stem->hint_flags |= T1_HINT_FLAG_ACTIVE; + stem_table->num_active ++; } new_stem = 0; break; @@ -678,16 +667,16 @@ } /* add a new stem to the array when necessary */ - if ( new_stem ) + if (new_stem) { - if ( cur_stem >= stems + T1_HINTER_MAX_EDGES ) + if (cur_stem >= stems + T1_HINTER_MAX_EDGES) { - FT_ERROR(( "t1_hinter_stem: : too many stems in glyph charstring\n" )); + FT_ERROR(( "T1.Hinter : too many stems in glyph charstring\n" )); return T1_Err_Syntax_Error; } /* on the first pass, we record the stem, otherwise, this is */ - /* a bug in the glyph loader! */ + /* a bug in the glyph loader !! */ if ( builder->pass == 0 ) { cur_stem->min_edge.orus = min; @@ -699,7 +688,7 @@ } else { - FT_ERROR(( "t1_hinter_stem: fatal glyph loader bug - pass2-stem\n" )); + FT_ERROR(( "T1.Hinter : fatal glyph loader bug - pass2-stem\n" )); return T1_Err_Syntax_Error; } } @@ -709,16 +698,16 @@ static - FT_Error t1_hinter_stem3( T1_Builder* builder, - FT_Pos pos0, - FT_Int width0, - FT_Pos pos1, - FT_Int width1, - FT_Pos pos2, - FT_Int width2, - FT_Bool vertical ) + FT_Error t1_hinter_stem3( T1_Builder* builder, + FT_Pos pos0, + FT_Int width0, + FT_Pos pos1, + FT_Int width1, + FT_Pos pos2, + FT_Int width2, + FT_Bool vertical ) { - /* For now, simply call `stem' 3 times */ + /* For now, don't be elitist and simply call "stem" 3 times */ return t1_hinter_stem( builder, pos0, width0, vertical ) || t1_hinter_stem( builder, pos1, width1, vertical ) || t1_hinter_stem( builder, pos2, width2, vertical ); @@ -732,10 +721,9 @@ T1_Stem_Table* stem_table; T1_Glyph_Hints* hinter = builder->glyph->hints; - - /* If we are in the second pass of glyph hinting, we must */ - /* call the function T1_Hint_Points() on the builder in order */ - /* to force the fit the latest points to the pixel grid. */ + /* if we're in the second pass of glyph hinting, we must */ + /* call the function T1_Hint_Points on the builder in order */ + /* to force the fit the latest points to the pixel grid */ if ( builder->pass == 1 ) T1_Hint_Points( builder ); @@ -747,7 +735,6 @@ T1_Stem_Hint* cur = stem_table->stems; T1_Stem_Hint* limit = cur + stem_table->num_stems; - for ( ; cur < limit; cur++ ) cur->hint_flags &= ~T1_HINT_FLAG_ACTIVE; @@ -762,40 +749,41 @@ LOCAL_FUNC const T1_Hinter_Funcs t1_hinter_funcs = { - (T1_Hinter_ChangeHints)t1_hinter_changehints, - (T1_Hinter_DotSection) t1_hinter_ignore, - (T1_Hinter_Stem) t1_hinter_stem, - (T1_Hinter_Stem3) t1_hinter_stem3 + (T1_Hinter_ChangeHints) t1_hinter_changehints, + (T1_Hinter_DotSection) t1_hinter_ignore, + (T1_Hinter_Stem) t1_hinter_stem, + (T1_Hinter_Stem3) t1_hinter_stem3 }; - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** *********/ - /********** STEM HINTS MANAGEMENT *********/ - /********** *********/ - /********** The following code is in charge of computing *********/ - /********** the placement of each scaled stem hint. *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ + /**********************************************************************/ + /**********************************************************************/ + /**********************************************************************/ + /********** *********/ + /********** *********/ + /********** STEM HINTS MANAGEMENT *********/ + /********** *********/ + /********** The following code is in charge of computing *********/ + /********** the placement of each scaled stem hint.. *********/ + /********** *********/ + /**********************************************************************/ + /**********************************************************************/ + /**********************************************************************/ +/************************************************************************ + * + * + * t1_sort_hints + * + * + * Sort the list of active stems in increasing order, through + * the "sort" indexing table + * + * + * table :: a stem hints table + * + ************************************************************************/ - /*************************************************************************/ - /* */ - /* */ - /* t1_sort_hints */ - /* */ - /* */ - /* Sorta the list of active stems in increasing order, through the */ - /* `sort' indexing table. */ - /* */ - /* */ - /* table :: A stem hints table. */ - /* */ static void t1_sort_hints( T1_Stem_Table* table ) { @@ -805,7 +793,6 @@ T1_Stem_Hint* stems = table->stems; FT_Int n; - /* record active stems in sort table */ for ( n = 0; n < num_stems; n++ ) { @@ -813,65 +800,64 @@ sort[num_active++] = n; } - /* now sort the indices. There are usually very few stems, */ - /* and they are pre-sorted in 90% cases, so we choose a */ - /* simple bubble sort (quicksort would be slower). */ + /* now sort the indices. There are usually very few stems, */ + /* and they are pre-sorted in 90% cases, so we choose a */ + /* simple bubble sort (quicksort would be slower).. */ for ( n = 1; n < num_active; n++ ) { - FT_Int p = n - 1; - T1_Stem_Hint* cur = stems + sort[n]; - + FT_Int p = n-1; + T1_Stem_Hint* cur = stems + sort[n]; do { FT_Int swap; T1_Stem_Hint* prev = stems + sort[p]; - - /* note that by definition, the active stems cannot overlap */ - /* so we simply compare their `min' to sort them (we could compare */ - /* their max values also; this wouldn't change anything). */ + /* note that by definition, the active stems cannot overlap */ + /* so we simply compare their "min" to sort them.. */ + /* (we could compare their max, this wouldn't change anything) */ if ( prev->min_edge.orus <= cur->min_edge.orus ) break; /* swap elements */ - swap = sort[p ]; - sort[p ] = sort[p + 1]; - sort[p + 1] = swap; + swap = sort[ p ]; + sort[ p ] = sort[p+1]; + sort[p+1] = swap; p--; - } while ( p >= 0 ); + } + while ( p >= 0 ); } table->num_active = num_active; } - /*************************************************************************/ - /* */ - /* */ - /* t1_hint_horizontal_stems */ - /* */ - /* */ - /* Computes the location of each scaled horizontal stem hint. This */ - /* takes care of the blue zones and the horizontal stem snap table. */ - /* */ - /* */ - /* table :: The horizontal stem hints table. */ - /* */ - /* hints :: The current size's hint structure. */ - /* */ - /* blueShift :: The value of the /BlueShift as taken from the face */ - /* object. */ - /* */ - /* scale :: The 16.16 scale used to convert outline units to */ - /* 26.6 pixels. */ - /* */ - /* */ - /* For now, all stems are hinted independently from each other. It */ - /* might be necessary, for better performance, to introduce the */ - /* notion of `controlled' hints describing things like counter-stems, */ - /* stem3, as well as overlapping stems control. */ - /* */ +/************************************************************************ + * + * + * t1_hint_horizontal_stems + * + * + * Compute the location of each scaled horizontal stem hint. + * This takes care of the blue zones and the horizontal stem + * snap table + * + * + * table :: the horizontal stem hints table + * hints :: the current size's hint structure + * blueShift :: the value of the /BlueShift as taken from the + * face object. + * scale :: the 16.16 scale used to convert outline + * units to 26.6 pixels + * + * + * For now, all stems are hinted independently from each other. + * It might be necessary, for better performance, to introduce + * the notion of "controlled" hints describing things like + * counter-stems, stem3 as well as overlapping stems control. + * + ************************************************************************/ + static void t1_hint_horizontal_stems( T1_Stem_Table* table, T1_Size_Hints* hints, @@ -881,9 +867,8 @@ T1_Stem_Hint* stem = table->stems; T1_Stem_Hint* limit = stem + table->num_stems; - /* first of all, scale the blueShift */ - blueShift = SCALE( blueShift ); + blueShift = SCALE(blueShift); /* then scan the horizontal stem table */ for ( ; stem < limit; stem++ ) @@ -899,71 +884,56 @@ FT_Pos top = top_pix; FT_Int align = T1_ALIGN_NONE; - - /*********************************************************************/ - /* */ - /* Snap pixel width if in stem snap range */ - /* */ - + /******************************************************************/ + /* Snap pixel width if in stem snap range */ { T1_Snap_Zone* zone = hints->snap_heights; T1_Snap_Zone* zone_limit = zone + hints->num_snap_heights; - FT_Pos best_dist = 32000; - T1_Snap_Zone* best_zone = 0; - + FT_Pos best_dist = 32000; + T1_Snap_Zone* best_zone = 0; for ( ; zone < zone_limit; zone++ ) { FT_Pos dist; - - dist = width_pix - zone->min; - if ( dist < 0 ) - dist = -dist; - if ( dist < best_dist ) + dist = width_pix - zone->min; if (dist < 0) dist = -dist; + if (dist < best_dist) { best_zone = zone; best_dist = dist; } } - if ( best_zone ) + if (best_zone) { - if ( width_pix > best_zone->pix ) + if (width_pix > best_zone->pix) { width_pix -= 0x20; - if ( width_pix < best_zone->pix ) + if (width_pix < best_zone->pix) width_pix = best_zone->pix; } else { width_pix += 0x20; - if ( width_pix > best_zone->pix ) + if (width_pix > best_zone->pix) width_pix = best_zone->pix; } } } - /*********************************************************************/ - /* */ - /* round width - minimum 1 pixel if this isn't a ghost stem */ - /* */ - + /******************************************************************/ + /* round width - minimum 1 pixel if this isn't a ghost stem */ if ( width_pix > 0 ) - width_pix = width_pix < ONE_PIXEL ? ONE_PIXEL : ROUND( width_pix ); + width_pix = ( width_pix < ONE_PIXEL ? ONE_PIXEL : ROUND(width_pix) ); - /*********************************************************************/ - /* */ - /* Now check for bottom blue zones alignement */ - /* */ - + /******************************************************************/ + /* Now check for bottom blue zones alignement */ { FT_Int num_blues = hints->num_bottom_zones; T1_Snap_Zone* blue = hints->blue_zones; T1_Snap_Zone* blue_limit = blue + num_blues; - for ( ; blue < blue_limit; blue++ ) { if ( bottom_pix < blue->min ) @@ -974,24 +944,21 @@ align = T1_ALIGN_BOTTOM; bottom = ROUND( blue->pix ); - /* implement blue shift */ - if ( !hints->supress_overshoots ) + /* implements blue shift */ + if (!hints->supress_overshoots) { FT_Pos delta = blue->pix - bottom_pix; - - delta = delta < blueShift ? 0 : ROUND( delta ); + delta = ( delta < blueShift ? 0 : ROUND( delta ) ); bottom -= delta; } } } } - /*********************************************************************/ - /* */ - /* check for top blue zones alignement */ - /* */ + /******************************************************************/ + /* Check for top blue zones alignement */ { FT_Int num_blues = hints->num_blue_zones - hints->num_bottom_zones; @@ -1001,7 +968,6 @@ T1_Snap_Zone* blue_limit = blue + num_blues; - for ( ; blue < blue_limit; blue++ ) { if ( top_pix < blue->min ) @@ -1009,50 +975,49 @@ if ( top_pix <= blue->max ) { - align |= T1_ALIGN_TOP; - top = ROUND( blue->pix ); + align |= T1_ALIGN_TOP; + top = ROUND( blue->pix ); - /* implement blue shift */ - if ( !hints->supress_overshoots ) + /* implements blue shift */ + if (!hints->supress_overshoots) { FT_Pos delta = top - blue->pix; - - delta = delta < blueShift ? 0 : ROUND( delta ); + delta = ( delta < blueShift ? 0 : ROUND( delta ) ); top += delta; } } } } - /*********************************************************************/ - /* */ - /* compute the hinted stem position, according to its alignment */ - /* */ - switch ( align ) + /******************************************************************/ + /* compute the hinted stem position, according to its alignment */ + switch (align) { - case T1_ALIGN_BOTTOM: /* bottom zone alignment */ - bottom_pix = bottom; - top_pix = bottom + width_pix; - break; + case T1_ALIGN_BOTTOM: /* bottom zone alignement */ + bottom_pix = bottom; + top_pix = bottom + width_pix; + break; - case T1_ALIGN_TOP: /* top zone alignment */ - top_pix = top; - bottom_pix = top - width_pix; - break; + case T1_ALIGN_TOP: /* top zone alignement */ + top_pix = top; + bottom_pix = top - width_pix; - case T1_ALIGN_BOTH: /* bottom+top zone alignment */ - bottom_pix = bottom; - top_pix = top; - break; + break; - default: /* no alignment */ - /* XXXX : TODO : Add management of controlled stems */ - bottom = ( SCALE( bottom_orus + top_orus ) - width_pix ) / 2; + case T1_ALIGN_BOTH: /* bottom+top zone alignement */ + bottom_pix = bottom; + top_pix = top; + break; - bottom_pix = ROUND( bottom ); - top_pix = bottom_pix + width_pix; + default: /* no alignement */ + + /* XXXX : TODO : Add management of controlled stems */ + bottom = ( SCALE(bottom_orus+top_orus) - width_pix )/2; + + bottom_pix = ROUND(bottom); + top_pix = bottom_pix + width_pix; } stem->min_edge.pix = bottom_pix; @@ -1061,27 +1026,33 @@ } - /*************************************************************************/ - /* */ - /* */ - /* t1_hint_vertical_stems */ - /* */ - /* */ - /* Computes the location of each scaled vertical stem hint. This */ - /* takes care of the vertical stem snap table. */ - /* */ - /* */ - /* table :: The vertical stem hints table. */ - /* hints :: The current size's hint structure. */ - /* scale :: The 16.16 scale used to convert outline units to */ - /* 26.6 pixels. */ - /* */ - /* */ - /* For now, all stems are hinted independently from each other. It */ - /* might be necessary, for better performance, to introduce the */ - /* notion of `controlled' hints describing things like counter-stems, */ - /* stem3 as well as overlapping stems control. */ - /* */ + + +/************************************************************************ + * + * + * t1_hint_vertical_stems + * + * + * Compute the location of each scaled vertical stem hint. + * This takes care of the vertical stem snap table + * + * + * table :: the vertical stem hints table + * hints :: the current size's hint structure + * scale :: the 16.16 scale used to convert outline + * units to 26.6 pixels + * + * + * For now, all stems are hinted independently from each other. + * It might be necessary, for better performance, to introduce + * the notion of "controlled" hints describing things like + * counter-stems, stem3 as well as overlapping stems control. + * + ************************************************************************/ + + /* compute the location of each scaled vertical stem hint. */ + /* Take care of blue zones and stem snap table */ static void t1_hint_vertical_stems( T1_Stem_Table* table, T1_Size_Hints* hints, @@ -1090,51 +1061,45 @@ T1_Stem_Hint* stem = table->stems; T1_Stem_Hint* limit = stem + table->num_stems; - for ( ; stem < limit; stem++ ) { FT_Pos stem_left = stem->min_edge.orus; FT_Pos stem_right = stem->max_edge.orus; FT_Pos width_pix, left; - width_pix = SCALE( stem_right - stem_left ); /* Snap pixel width if in stem snap range */ { T1_Snap_Zone* zone = hints->snap_heights; T1_Snap_Zone* zone_limit = zone + hints->num_snap_heights; - FT_Pos best_dist = 32000; - T1_Snap_Zone* best_zone = 0; - + FT_Pos best_dist = 32000; + T1_Snap_Zone* best_zone = 0; for ( ; zone < zone_limit; zone++ ) { FT_Pos dist; - - dist = width_pix - zone->min; - if ( dist < 0 ) - dist = -dist; - if ( dist < best_dist ) + dist = width_pix - zone->min; if (dist < 0) dist = -dist; + if (dist < best_dist) { best_zone = zone; best_dist = dist; } } - if ( best_zone ) + if (best_zone) { - if ( width_pix > best_zone->pix ) + if (width_pix > best_zone->pix) { width_pix -= 0x20; - if ( width_pix < best_zone->pix ) + if (width_pix < best_zone->pix) width_pix = best_zone->pix; } else { width_pix += 0x20; - if ( width_pix > best_zone->pix ) + if (width_pix > best_zone->pix) width_pix = best_zone->pix; } } @@ -1142,44 +1107,49 @@ /* round width - minimum 1 pixel if this isn't a ghost stem */ if ( width_pix > 0 ) - width_pix = width_pix < ONE_PIXEL ? ONE_PIXEL - : ROUND( width_pix ); + width_pix = ( width_pix < ONE_PIXEL ? ONE_PIXEL : + ROUND( width_pix ) ); - /* now place the snapped and rounded stem */ - /* XXX TODO: implement controlled stems for the overlapping */ - /* cases. */ + /* now place the snapped and rounded stem */ - left = ( SCALE( stem_left + stem_right ) - width_pix ) / 2; + /* XXXX : TODO : implement controlled stems for the overlapping */ + /* cases.. */ - stem->min_edge.pix = ROUND( left ); + left = ( SCALE(stem_left+stem_right) - width_pix )/2; + + stem->min_edge.pix = ROUND(left); stem->max_edge.pix = stem->min_edge.pix + width_pix; } } - /*************************************************************************/ - /* */ - /* */ - /* t1_hint_point */ - /* */ - /* */ - /* Grid-fit a coordinate with regards to a given stem hints table. */ - /* */ - /* */ - /* table :: The source stem hints table. */ - /* coord :: The original coordinate, expressed in font units. */ - /* scale :: The 16.16 scale used to convert font units into */ - /* 26.6 pixels. */ - /* */ - /* */ - /* The hinted/scaled value in 26.6 pixels. */ - /* */ - /* */ - /* For now, all stems are hinted independently from each other. It */ - /* might be necessary, for better performance, to introduce the */ - /* notion of `controlled' hints describing things like counter-stems, */ - /* stem3 as well as overlapping stems control. */ - /* */ + + +/************************************************************************ + * + * + * t1_hint_point + * + * + * Grid-fit a coordinate with regards to a given stem hints table + * + * + * table :: the source stem hints table + * coord :: original coordinate, expressed in font units + * scale :: the 16.16 scale used to convert font units into + * 26.6 pixels + * + * + * the hinted/scaled value in 26.6 pixels + * + * + * For now, all stems are hinted independently from each other. + * It might be necessary, for better performance, to introduce + * the notion of "controlled" hints describing things like + * counter-stems, stem3 as well as overlapping stems control. + * + ************************************************************************/ + static FT_Pos t1_hint_point( T1_Stem_Table* table, FT_Pos coord, @@ -1193,10 +1163,9 @@ T1_Edge* max; FT_Pos delta; - /* only hint when there is at least one stem defined */ - if ( num_active <= 0 ) - return SCALE( coord ); + if (num_active <= 0) + return SCALE(coord); /* scan the stem table to determine placement of coordinate */ /* relative to the list of sorted and stems */ @@ -1204,16 +1173,14 @@ { cur = table->stems + table->sort[n]; - /* is it on the left of the current edge? */ + /* is it on the left of the current edge ? */ delta = cur->min_edge.orus - coord; - if ( delta == 0 ) - return cur->min_edge.pix; + if ( delta == 0 ) return cur->min_edge.pix; - if ( delta > 0 ) + if (delta > 0) { /* if this is the left of the first edge, simply shift */ - if ( !prev ) - return cur->min_edge.pix - SCALE( delta ); + if (!prev) return cur->min_edge.pix - SCALE(delta); /* otherwise, interpolate between the maximum of the */ /* previous stem, and the minimum of the current one */ @@ -1222,12 +1189,11 @@ goto Interpolate; } - /* is it within the current edge? */ + /* is it within the current edge ? */ delta = cur->max_edge.orus - coord; - if ( delta == 0 ) - return cur->max_edge.pix; + if ( delta == 0 ) return cur->max_edge.pix; - if ( delta > 0 ) + if (delta > 0) { /* interpolate within the stem */ min = &cur->min_edge; @@ -1238,40 +1204,43 @@ /* apparently, this coordinate is on the right of the last stem */ delta = coord - cur->max_edge.orus; - return cur->max_edge.pix + SCALE( delta ); + return cur->max_edge.pix + SCALE(delta); Interpolate: return min->pix + - FT_MulDiv( coord - min->orus, - max->pix - min->pix, - max->orus - min->orus ); + FT_MulDiv( coord - min->orus, + max->pix - min->pix, + max->orus - min->orus ); } + + + + #if 1 - /*************************************************************************/ - /* */ - /* */ - /* T1_Hint_Points */ - /* */ - /* */ - /* this function grid-fits several points in a given Type 1 builder */ - /* at once. */ - /* */ - /* */ - /* builder :: A handle to target Type 1 builder. */ - /* */ - /* first :: The first point to hint in the builder's current */ - /* outline. */ - /* */ - /* last :: The last point to hint in the builder's current outline. */ - /* */ +/************************************************************************ + * + * + * T1_Hint_Points + * + * + * this function grid-fits several points in a given Type 1 builder + * at once. + * + * + * builder :: handle to target Type 1 builder + * first :: first point to hint in builder's current outline + * last :: last point to hint in builder's current outline + * + ************************************************************************/ + LOCAL_FUNC void T1_Hint_Points( T1_Builder* builder ) { FT_Int first = builder->hint_point; - FT_Int last = builder->current.n_points-1; + FT_Int last = builder->current->n_points-1; T1_Size size = builder->size; FT_Fixed scale_x = size->root.metrics.x_scale; @@ -1281,10 +1250,9 @@ T1_Stem_Table* hori_stems = &hints->hori_stems; T1_Stem_Table* vert_stems = &hints->vert_stems; - FT_Vector* cur = builder->current.points + first; + FT_Vector* cur = builder->current->points + first; FT_Vector* limit = cur + last - first + 1; - /* first of all, sort the active stem hints */ t1_sort_hints( hori_stems ); t1_sort_hints( vert_stems ); @@ -1295,23 +1263,25 @@ cur->y = t1_hint_point( hori_stems, cur->y, scale_y ); } - builder->hint_point = builder->current.n_points; + builder->hint_point = builder->current->n_points; } - /*************************************************************************/ - /* */ - /* */ - /* T1_Hint_Stems */ - /* */ - /* */ - /* This function is used to compute the location of each stem hint */ - /* between the first and second passes of the glyph loader on the */ - /* charstring. */ - /* */ - /* */ - /* builder :: A handle to the target builder. */ - /* */ +/************************************************************************ + * + * + * T1_Hint_Stems + * + * + * This function is used to compute the location of each stem hint + * between the first and second passes of the glyph loader on the + * charstring. + * + * + * builder :: handle to target builder + * + ************************************************************************/ + LOCAL_FUNC void T1_Hint_Stems( T1_Builder* builder ) { @@ -1322,7 +1292,6 @@ FT_Fixed scale_x = size->root.metrics.x_scale; FT_Fixed scale_y = size->root.metrics.y_scale; - t1_hint_horizontal_stems( &hints->hori_stems, builder->size->hints, priv->blue_shift, @@ -1333,7 +1302,4 @@ scale_x ); } -#endif /* 1 */ - - -/* END */ +#endif diff --git a/src/type1/t1objs.c b/src/type1/t1objs.c index fe7c155dc..49498fd3b 100644 --- a/src/type1/t1objs.c +++ b/src/type1/t1objs.c @@ -259,15 +259,11 @@ psnames = (PSNames_Interface*)face->psnames; if (!psnames) { - /* look-up the PSNames driver */ - FT_Driver psnames_driver; - - psnames_driver = FT_Get_Driver( face->root.driver->library, "psnames" ); - if (psnames_driver) - face->psnames = (PSNames_Interface*) - (psnames_driver->interface.format_interface); + psnames = (PSNames_Interface*) + FT_Get_Module_Interface( FT_FACE_LIBRARY(face), "psnames" ); } - + face->psnames = psnames; + /* open the tokenizer, this will also check the font format */ error = New_Tokenizer( stream, &tokenizer ); if (error) goto Fail; @@ -458,16 +454,11 @@ LOCAL_FUNC void T1_Done_GlyphSlot( T1_GlyphSlot glyph ) { - FT_Memory memory = glyph->root.face->memory; - FT_Library library = glyph->root.face->driver->library; - #ifndef T1_CONFIG_OPTION_DISABLE_HINTER T1_Done_Glyph_Hinter( glyph ); +#else + UNUSED(glyph) #endif - /* the bitmaps are created on demand */ - FREE( glyph->root.bitmap.buffer ); - FT_Outline_Done( library, &glyph->root.outline ); - return; } @@ -487,67 +478,16 @@ LOCAL_FUNC FT_Error T1_Init_GlyphSlot( T1_GlyphSlot glyph ) { - FT_Library library = glyph->root.face->driver->library; - FT_Error error; - - glyph->max_points = 0; - glyph->max_contours = 0; - glyph->root.bitmap.buffer = 0; - - error = FT_Outline_New( library, 0, 0, &glyph->root.outline ); - if (error) return error; + FT_Error error = FT_Err_Ok; #ifndef T1_CONFIG_OPTION_DISABLE_HINTER error = T1_New_Glyph_Hinter( glyph ); - if (error) - FT_Outline_Done( library, &glyph->root.outline ); +#else + UNUSED(glyph); #endif return error; } -/******************************************************************* - * - * T1_Init_Driver - * - * - * Initialise a given Type 1 driver object - * - * - * driver :: handle to target driver object - * - * - * Error code. - * - ******************************************************************/ - - LOCAL_FUNC - FT_Error T1_Init_Driver( T1_Driver driver ) - { - UNUSED(driver); - return T1_Err_Ok; - } - - - -/******************************************************************* - * - * T1_Done_Driver - * - * - * finalise a given Type 1 driver - * - * - * driver :: handle to target Type 1 driver - * - ******************************************************************/ - - LOCAL_DEF - void T1_Done_Driver( T1_Driver driver ) - { - UNUSED(driver); - } - - /* END */ diff --git a/src/type1/t1objs.h b/src/type1/t1objs.h index eeebb0199..f010fc189 100644 --- a/src/type1/t1objs.h +++ b/src/type1/t1objs.h @@ -260,40 +260,6 @@ -/******************************************************************* - * - * T1_Init_Driver - * - * - * Initialise a given Type 1 driver object - * - * - * driver :: handle to target driver object - * - * - * Error code. - * - ******************************************************************/ - - LOCAL_DEF - FT_Error T1_Init_Driver( T1_Driver driver ); - - - -/******************************************************************* - * - * T1_Done_Driver - * - * - * finalise a given Type 1 driver - * - * - * driver :: handle to target Type 1 driver - * - ******************************************************************/ - - LOCAL_DEF - void T1_Done_Driver( T1_Driver driver ); #ifdef __cplusplus } diff --git a/src/type1z/module.mk b/src/type1z/module.mk index 66dba41d0..64283af62 100644 --- a/src/type1z/module.mk +++ b/src/type1z/module.mk @@ -1,7 +1,7 @@ make_module_list: add_type1z_driver add_type1z_driver: - $(OPEN_DRIVER)t1z_driver_interface$(CLOSE_DRIVER) + $(OPEN_DRIVER)t1z_driver_class$(CLOSE_DRIVER) $(ECHO_DRIVER)type1z $(ECHO_DRIVER_DESC)Postscript font files with extension *.pfa or *.pfb$(ECHO_DRIVER_DONE) # EOF diff --git a/src/type1z/t1driver.c b/src/type1z/t1driver.c index b8a841ca1..12c483bb5 100644 --- a/src/type1z/t1driver.c +++ b/src/type1z/t1driver.c @@ -55,26 +55,21 @@ /* time). */ /* */ static - FTDriver_Interface Get_Interface( FT_Driver driver, - const FT_String* interface ) + FT_Module_Interface Get_Interface( FT_Driver driver, + const FT_String* interface ) { UNUSED(driver); UNUSED(interface); -#ifndef T1_CONFIG_OPTION_NO_AFM - if ( strcmp( (const char*)interface, "attach_file" ) == 0 ) - return (FTDriver_Interface)T1_Read_AFM; -#endif - #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT if ( strcmp( (const char*)interface, "get_mm" ) == 0 ) - return (FTDriver_Interface)T1_Get_Multi_Master; + return (FT_Module_Interface)T1_Get_Multi_Master; if ( strcmp( (const char*)interface, "set_mm_design") == 0 ) - return (FTDriver_Interface)T1_Set_MM_Design; + return (FT_Module_Interface)T1_Set_MM_Design; if ( strcmp( (const char*)interface, "set_mm_blend") == 0 ) - return (FTDriver_Interface)T1_Set_MM_Blend; + return (FT_Module_Interface)T1_Set_MM_Blend; #endif return 0; } @@ -132,76 +127,6 @@ } #endif - /******************************************************************/ - /* */ - /* Set_Char_Sizes */ - /* */ - /* */ - /* A driver method used to reset a size's character sizes */ - /* (horizontal and vertical) expressed in fractional points. */ - /* */ - /* */ - /* size :: handle to target size object */ - /* char_width :: character width expressed in 26.6 points */ - /* char_height :: character height expressed in 26.6 points */ - /* */ - /* */ - /* FreeType error code. 0 means success */ - /* */ - static - FT_Error Set_Char_Sizes( T1_Size size, - FT_F26Dot6 char_width, - FT_F26Dot6 char_height, - FT_UInt horz_resolution, - FT_UInt vert_resolution ) - { - UNUSED(char_width); - UNUSED(char_height); - UNUSED(horz_resolution); - UNUSED(vert_resolution); - - size->valid = FALSE; - return T1_Reset_Size( size ); - } - - - /******************************************************************/ - /* */ - /* Set_Pixel_Sizes */ - /* */ - /* */ - /* A driver method used to reset a size's character sizes */ - /* (horizontal and vertical) expressed in integer pixels. */ - /* */ - /* */ - /* size :: handle to target size object */ - /* */ - /* pixel_width :: character width expressed in 26.6 points */ - /* */ - /* pixel_height :: character height expressed in 26.6 points */ - /* */ - /* char_size :: the corresponding character size in points */ - /* This value is only sent to the TrueType */ - /* bytecode interpreter, even though 99% of */ - /* glyph programs will simply ignore it. A */ - /* safe value there is the maximum of the */ - /* pixel width and height (multiplied by */ - /* 64 to make it a 26.6 fixed float !) */ - /* */ - /* FreeType error code. 0 means success */ - /* */ - static - FT_Error Set_Pixel_Sizes( T1_Size size, - FT_Int pixel_width, - FT_Int pixel_height ) - { - UNUSED(pixel_width); - UNUSED(pixel_height); - - size->valid = FALSE; - return T1_Reset_Size(size); - } - /*************************************************************************/ /* */ /* */ @@ -298,117 +223,48 @@ } - /******************************************************************/ - /* */ - /* FT_DriverInterface */ - /* */ - /* */ - /* A structure used to hold a font driver's basic interface */ - /* used by the high-level parts of FreeType (or other apps) */ - /* */ - /* Most scalable drivers provide a specialized interface to */ - /* access format-specific features. It can be retrieved with */ - /* a call to the "get_format_interface", and should be defined */ - /* in each font driver header (e.g. ttdriver.h, t1driver.h,..) */ - /* */ - /* All fields are function pointers .. */ - /* */ - /* */ - /* */ - /* */ - /* new_engine :: */ - /* used to create and initialise a new driver object */ - /* */ - /* done_engine :: */ - /* used to finalise and destroy a given driver object */ - /* */ - /* get_format_interface :: */ - /* return a typeless pointer to the format-specific */ - /* driver interface. */ - /* */ - /* new_face :: */ - /* create a new face object from a resource */ - /* */ - /* done_face :: */ - /* discards a face object, as well as all child objects */ - /* ( sizes, charmaps, glyph slots ) */ - /* */ - /* get_face_properties :: */ - /* return generic face properties */ - /* */ - /* get_kerning :: */ - /* return the kerning vector corresponding to a pair */ - /* of glyphs, expressed in unscaled font units. */ - /* */ - /* new_size :: */ - /* create and initialise a new scalable size object. */ - /* */ - /* new_fixed_size :: */ - /* create and initialise a new fixed-size object. */ - /* */ - /* done_size :: */ - /* finalize a given face size object. */ - /* */ - /* set_size_resolutions :: */ - /* reset a scalable size object's output resolutions */ - /* */ - /* set_size_char_sizes :: */ - /* reset a scalable size object's character size */ - /* */ - /* set_pixel_sizes :: */ - /* reset a face size object's pixel dimensions. Applies */ - /* to both scalable and fixed faces. */ - /* */ - /* new_glyph_slot :: */ - /* create and initialise a new glyph slot */ - /* */ - /* done_glyph_slot :: */ - /* discard a given glyph slot */ - /* */ - /* load_glyph :: */ - /* load a given glyph into a given slot */ - /* */ - /* get_glyph_metrics :: */ - /* return a loaded glyph's metrics. */ - /* */ - - const FT_DriverInterface t1z_driver_interface = + const FT_Driver_Class t1z_driver_class = { - sizeof( FT_DriverRec ), + { + ft_module_font_driver | ft_module_driver_scalable, + sizeof( FT_DriverRec ), + + "type1", + 100, + 200, + + 0, /* format interface */ + + (FT_Module_Constructor) T1_Init_Driver, + (FT_Module_Destructor) T1_Done_Driver, + (FT_Module_Requester) Get_Interface, + }, + sizeof( T1_FaceRec ), sizeof( T1_SizeRec ), sizeof( T1_GlyphSlotRec ), - "type1", - 100, - 200, - - 0, /* format interface */ - - (FTDriver_initDriver) T1_Init_Driver, - (FTDriver_doneDriver) T1_Done_Driver, - - (FTDriver_getInterface) Get_Interface, - (FTDriver_initFace) T1_Init_Face, (FTDriver_doneFace) T1_Done_Face, + (FTDriver_initSize) 0, + (FTDriver_doneSize) 0, + (FTDriver_initGlyphSlot) 0, + (FTDriver_doneGlyphSlot) 0, + + (FTDriver_setCharSizes) 0, + (FTDriver_setPixelSizes) 0, + (FTDriver_loadGlyph) T1_Load_Glyph, + (FTDriver_getCharIndex) Get_Char_Index, #ifdef T1_CONFIG_OPTION_NO_AFM (FTDriver_getKerning) 0, + (FTDriver_attachFile) 0, #else (FTDriver_getKerning) Get_Kerning, + (FTDriver_attachFile) T1_Read_AFM, #endif + (FTDriver_getAdvances) 0 - (FTDriver_initSize) T1_Init_Size, - (FTDriver_doneSize) T1_Done_Size, - (FTDriver_setCharSizes) Set_Char_Sizes, - (FTDriver_setPixelSizes) Set_Pixel_Sizes, - - (FTDriver_initGlyphSlot) T1_Init_GlyphSlot, - (FTDriver_doneGlyphSlot) T1_Done_GlyphSlot, - (FTDriver_loadGlyph) T1_Load_Glyph, - - (FTDriver_getCharIndex) Get_Char_Index, }; @@ -434,9 +290,9 @@ #ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS - EXPORT_FUNC(FT_DriverInterface*) getDriverInterface( void ) + EXPORT_FUNC(const FT_Driver_Class*) getDriverClass( void ) { - return &t1z_driver_interface; + return &t1z_driver_class; } #endif /* FT_CONFIG_OPTION_DYNAMIC_DRIVERS */ diff --git a/src/type1z/t1driver.h b/src/type1z/t1driver.h index 08d7a35f8..6c8c92b46 100644 --- a/src/type1z/t1driver.h +++ b/src/type1z/t1driver.h @@ -18,10 +18,9 @@ #ifndef T1DRIVER_H #define T1DRIVER_H -#include -#include +#include - FT_EXPORT_VAR(const FT_DriverInterface) t1z_driver_interface; + FT_EXPORT_VAR(const FT_Driver_Class) t1z_driver_class; #endif /* T1DRIVER_H */ diff --git a/src/type1z/t1gload.c b/src/type1z/t1gload.c index f2a1437be..cba71dea4 100644 --- a/src/type1z/t1gload.c +++ b/src/type1z/t1gload.c @@ -129,9 +129,13 @@ if (glyph) { - builder->base = glyph->root.outline; - builder->max_points = glyph->max_points; - builder->max_contours = glyph->max_contours; + FT_GlyphLoader* loader = glyph->root.loader; + + builder->loader = loader; + builder->current = &loader->current.outline; + builder->base = &loader->base.outline; + + FT_GlyphLoader_Rewind(loader); } if (size) @@ -147,10 +151,6 @@ builder->left_bearing.y = 0; builder->advance.x = 0; builder->advance.y = 0; - - builder->base.n_points = 0; - builder->base.n_contours = 0; - builder->current = builder->base; } @@ -175,11 +175,7 @@ T1_GlyphSlot glyph = builder->glyph; if (glyph) - { - glyph->root.outline = builder->base; - glyph->max_points = builder->max_points; - glyph->max_contours = builder->max_contours; - } + glyph->root.outline = *builder->base; } @@ -217,39 +213,7 @@ FT_Error check_points( T1_Builder* builder, FT_Int count ) { - FT_Outline* base = &builder->base; - FT_Outline* outline = &builder->current; - - if (!builder->load_points) - return T1_Err_Ok; - - count += base->n_points + outline->n_points; - - /* realloc points table if necessary */ - if ( count >= builder->max_points ) - { - FT_Error error; - FT_Memory memory = builder->memory; - FT_Int increment = outline->points - base->points; - FT_Int current = builder->max_points; - - while ( builder->max_points < count ) - builder->max_points += 8; - - if ( REALLOC_ARRAY( base->points, current, - builder->max_points, FT_Vector ) || - - REALLOC_ARRAY( base->tags, current, - builder->max_points, FT_Byte ) ) - { - builder->error = error; - return error; - } - - outline->points = base->points + increment; - outline->tags = base->tags + increment; - } - return T1_Err_Ok; + return FT_GlyphLoader_Check_Points( builder->loader, count, 0 ); } @@ -260,7 +224,7 @@ FT_Pos y, FT_Byte flag ) { - FT_Outline* outline = &builder->current; + FT_Outline* outline = builder->current; if (builder->load_points) { @@ -298,41 +262,25 @@ static FT_Error add_contour( T1_Builder* builder ) { - FT_Outline* base = &builder->base; - FT_Outline* outline = &builder->current; + FT_Outline* outline = builder->current; + FT_Error error; if (!builder->load_points) { outline->n_contours++; - return T1_Err_Ok; + return FT_Err_Ok; } /* realloc contours array if necessary */ - if ( base->n_contours + outline->n_contours >= builder->max_contours && - builder->load_points ) + error = FT_GlyphLoader_Check_Points( builder->loader, 0, 1 ); + if (!error) { - FT_Error error; - FT_Memory memory = builder->memory; - FT_Int increment = outline->contours - base->contours; - FT_Int current = builder->max_contours; - - builder->max_contours += 4; - - if ( REALLOC_ARRAY( base->contours, - current, builder->max_contours, FT_Short ) ) - { - builder->error = error; - return error; - } - - outline->contours = base->contours + increment; + if (outline->n_contours > 0) + outline->contours[ outline->n_contours-1 ] = outline->n_points-1; + + outline->n_contours++; } - - if (outline->n_contours > 0) - outline->contours[ outline->n_contours-1 ] = outline->n_points-1; - - outline->n_contours++; - return T1_Err_Ok; + return error; } /* if a path was begun, add its first on-curve point */ @@ -358,7 +306,7 @@ static void close_contour( T1_Builder* builder ) { - FT_Outline* outline = &builder->current; + FT_Outline* outline = builder->current; if ( outline->n_contours > 0 ) outline->contours[outline->n_contours-1] = outline->n_points-1; @@ -442,60 +390,36 @@ FT_Int achar ) { FT_Error error; - T1_Face face = decoder->builder.face; FT_Int bchar_index, achar_index, n_base_points; - FT_Outline* cur = &decoder->builder.current; - FT_Outline* base = &decoder->builder.base; + FT_Outline* cur = decoder->builder.current; + FT_Outline* base = decoder->builder.base; FT_Vector left_bearing, advance; + T1_Face face = decoder->builder.face; T1_Font* type1 = &face->type1; bchar_index = lookup_glyph_by_stdcharcode( face, bchar ); achar_index = lookup_glyph_by_stdcharcode( face, achar ); - if (bchar_index < 0 || achar_index < 0) + if ( bchar_index < 0 || achar_index < 0 ) { - FT_ERROR(( "T1.Parse_Seac : invalid seac character code arguments\n" )); + FT_ERROR(( "t1operator_seac: invalid seac character code arguments\n" )); return T1_Err_Syntax_Error; } - /* First load "bchar" in builder */ - /* now load the unscaled outline */ - cur->n_points = 0; - cur->n_contours = 0; - cur->points = base->points + base->n_points; - cur->tags = base->tags + base->n_points; - cur->contours = base->contours + base->n_contours; - - error = T1_Parse_CharStrings( decoder, - type1->charstrings [bchar_index], - type1->charstrings_len[bchar_index], - type1->num_subrs, - type1->subrs, - type1->subrs_len ); - if (error) return error; - - n_base_points = cur->n_points; - + /* if we are trying to load a composite glyph, do not load the */ + /* accent character and return the array of subglyphs. */ if ( decoder->builder.no_recurse ) { - /* if we're trying to load a composite glyph, do not load the */ - /* accent character and return the array of subglyphs.. */ - FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph; - FT_SubGlyph* subg; + + FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph; + FT_GlyphLoader* loader = glyph->loader; + FT_SubGlyph* subg; /* reallocate subglyph array if necessary */ - if (glyph->max_subglyphs < 2) - { - FT_Memory memory = decoder->builder.face->root.memory; - - if ( REALLOC_ARRAY( glyph->subglyphs, glyph->max_subglyphs, - 2, FT_SubGlyph ) ) - return error; - - glyph->max_subglyphs = 2; - } - - subg = glyph->subglyphs; + error = FT_GlyphLoader_Check_Subglyphs( loader, 2 ); + if (error) goto Exit; + + subg = loader->current.subglyphs; /* subglyph 0 = base character */ subg->index = bchar_index; @@ -514,53 +438,63 @@ /* set up remaining glyph fields */ glyph->num_subglyphs = 2; glyph->format = ft_glyph_format_composite; + + loader->current.num_subglyphs = 2; } - else + + /* First load `bchar' in builder */ + /* now load the unscaled outline */ + + FT_GlyphLoader_Prepare( decoder->builder.loader ); /* prepare loader */ + + error = T1_Parse_CharStrings( decoder, + type1->charstrings [bchar_index], + type1->charstrings_len[bchar_index], + type1->num_subrs, + type1->subrs, + type1->subrs_len ); + if ( error ) goto Exit; + + n_base_points = cur->n_points; + { /* save the left bearing and width of the base character */ - /* as they will be erase by the next load.. */ + /* as they will be erased by the next load. */ + left_bearing = decoder->builder.left_bearing; advance = decoder->builder.advance; decoder->builder.left_bearing.x = 0; decoder->builder.left_bearing.y = 0; - /* Now load "achar" on top of */ + /* Now load `achar' on top of */ /* the base outline */ - /* */ - cur->n_points = 0; - cur->n_contours = 0; - cur->points = base->points + base->n_points; - cur->tags = base->tags + base->n_points; - cur->contours = base->contours + base->n_contours; - error = T1_Parse_CharStrings( decoder, type1->charstrings [achar_index], type1->charstrings_len[achar_index], type1->num_subrs, type1->subrs, type1->subrs_len ); - if (error) return error; - - /* adjust contours in accented character outline */ - if (decoder->builder.load_points) - { - FT_Int n; - - for ( n = 0; n < cur->n_contours; n++ ) - cur->contours[n] += n_base_points; - } + if ( error ) return error; /* restore the left side bearing and */ /* advance width of the base character */ + decoder->builder.left_bearing = left_bearing; decoder->builder.advance = advance; /* Finally, move the accent */ - if (decoder->builder.load_points) - FT_Outline_Translate( cur, adx - asb, ady ); + if ( decoder->builder.load_points ) + { + FT_Outline dummy; + + dummy.n_points = base->n_points - n_base_points; + dummy.points = base->points + n_base_points; + FT_Outline_Translate( &dummy, adx - asb, ady ); + } } - return T1_Err_Ok; + Exit: + return error; } @@ -615,7 +549,7 @@ ip = zone->cursor = zone->base; error = T1_Err_Ok; - outline = &builder->current; + outline = builder->current; x = builder->pos_x; y = builder->pos_y; @@ -922,8 +856,7 @@ close_contour( builder ); /* add current outline to the glyph slot */ - builder->base.n_points += builder->current.n_points; - builder->base.n_contours += builder->current.n_contours; + FT_GlyphLoader_Add( builder->loader ); /* return now !! */ FT_TRACE4(( "\n\n" )); @@ -1397,7 +1330,7 @@ { /* scale the outline and the metrics */ FT_Int n; - FT_Outline* cur = &decoder.builder.base; + FT_Outline* cur = decoder.builder.base; FT_Vector* vec = cur->points; FT_Fixed x_scale = glyph->x_scale; FT_Fixed y_scale = glyph->y_scale; diff --git a/src/type1z/t1gload.h b/src/type1z/t1gload.h index 7f331c15b..2bfa1b8fa 100644 --- a/src/type1z/t1gload.h +++ b/src/type1z/t1gload.h @@ -83,34 +83,32 @@ typedef struct T1_Builder_ { - FT_Memory memory; - T1_Face face; - T1_GlyphSlot glyph; + FT_Memory memory; + T1_Face face; + T1_GlyphSlot glyph; + FT_GlyphLoader* loader; - FT_Outline current; /* the current glyph outline */ - FT_Outline base; /* the composite glyph outline */ + FT_Outline* current; /* the current glyph outline */ + FT_Outline* base; /* the composite glyph outline */ - FT_Int max_points; /* capacity of base outline in points */ - FT_Int max_contours; /* capacity of base outline in contours */ + FT_Vector last; - FT_Vector last; + FT_Fixed scale_x; + FT_Fixed scale_y; - FT_Fixed scale_x; - FT_Fixed scale_y; + FT_Pos pos_x; + FT_Pos pos_y; - FT_Pos pos_x; - FT_Pos pos_y; + FT_Vector left_bearing; + FT_Vector advance; - FT_Vector left_bearing; - FT_Vector advance; + FT_BBox bbox; /* bounding box */ + FT_Bool path_begun; + FT_Bool load_points; + FT_Bool no_recurse; - FT_BBox bbox; /* bounding box */ - FT_Bool path_begun; - FT_Bool load_points; - FT_Bool no_recurse; - - FT_Error error; /* only used for memory errors */ - FT_Bool metrics_only; + FT_Error error; /* only used for memory errors */ + FT_Bool metrics_only; } T1_Builder; diff --git a/src/type1z/t1objs.c b/src/type1z/t1objs.c index c2dec5691..e4ef784ce 100644 --- a/src/type1z/t1objs.c +++ b/src/type1z/t1objs.c @@ -27,103 +27,6 @@ #undef FT_COMPONENT #define FT_COMPONENT trace_t1objs -/******************************************************************* - * * - * SIZE FUNCTIONS * - * * - * * - *******************************************************************/ - -/******************************************************************* - * - * T1_Done_Size - * - * - * The TrueDoc instance object destructor. Used to discard - * a given instance object.. - * - * - * instance :: handle to the target instance object - * - * - * TrueDoc error code. 0 means success - * - ******************************************************************/ - - LOCAL_FUNC - void T1_Done_Size( T1_Size size ) - { - UNUSED(size); - } - - -/******************************************************************* - * - * T1_Init_Size - * - * - * The instance object constructor - * - * - * instance : handle to new instance object - * face : pointer to parent face object - * - * - * TrueDoc error code. 0 means success. - * - ******************************************************************/ - - LOCAL_DEF - FT_Error T1_Init_Size( T1_Size size ) - { - size->valid = 0; - return T1_Err_Ok; - } - - -/******************************************************************* - * - * T1_Reset_Size - * - * - * Resets an instance to a new pointsize/transform. - * This function is in charge of resetting the blue zones, - * As well as the stem snap tables for a given size.. - * - * - * instance the instance object to destroy - * - * - * Error code. - * - ******************************************************************/ - - LOCAL_FUNC - FT_Error T1_Reset_Size( T1_Size size ) - { - /* recompute ascender, descender, etc.. */ - T1_Face face = (T1_Face)size->root.face; - FT_Size_Metrics* metrics = &size->root.metrics; - - if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 ) - return T1_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 0; - } - - /******************************************************************* * * * FACE FUNCTIONS * @@ -238,15 +141,8 @@ psnames = (PSNames_Interface*)face->psnames; if (!psnames) - { - /* look-up the PSNames driver */ - FT_Driver psnames_driver; - - psnames_driver = FT_Get_Driver( face->root.driver->library, "psnames" ); - if (psnames_driver) - face->psnames = (PSNames_Interface*) - (psnames_driver->interface.format_interface); - } + psnames = (PSNames_Interface*) + FT_Get_Module_Interface( FT_FACE_LIBRARY(face), "psnames" ); /* open the tokenizer, this will also check the font format */ error = T1_Open_Face( face ); @@ -415,57 +311,6 @@ } -/******************************************************************* - * - * Function : Glyph_Destroy - * - * Description : The glyph object destructor. - * - * Input : _glyph typeless pointer to the glyph record to destroy - * - * Output : Error code. - * - ******************************************************************/ - - LOCAL_FUNC - void T1_Done_GlyphSlot( T1_GlyphSlot glyph ) - { - FT_Memory memory = glyph->root.face->memory; - FT_Library library = glyph->root.face->driver->library; - - /* the bitmaps are created on demand */ - FREE( glyph->root.bitmap.buffer ); - FT_Outline_Done( library, &glyph->root.outline ); - return; - } - - -/******************************************************************* - * - * Function : Glyph_Create - * - * Description : The glyph object constructor. - * - * Input : glyph glyph record to build. - * face the glyph's parent face. - * - * Output : Error code. - * - ******************************************************************/ - - LOCAL_FUNC - FT_Error T1_Init_GlyphSlot( T1_GlyphSlot glyph ) - { - FT_Library library = glyph->root.face->driver->library; - - glyph->max_points = 0; - glyph->max_contours = 0; - glyph->root.bitmap.buffer = 0; - - return FT_Outline_New( library, 0, 0, &glyph->root.outline ); - } - - /******************************************************************* * * T1_Init_Driver diff --git a/src/type1z/t1objs.h b/src/type1z/t1objs.h index b872102aa..867f23c2b 100644 --- a/src/type1z/t1objs.h +++ b/src/type1z/t1objs.h @@ -170,95 +170,6 @@ void T1_Done_Face( T1_Face face ); - -/******************************************************************* - * - * T1_Init_Size - * - * - * Initialise a new Type 1 size object - * - * - * size :: handle to size object - * - * - * Type 1 error code. 0 means success. - * - ******************************************************************/ - - LOCAL_DEF - FT_Error T1_Init_Size( T1_Size size ); - - - -/******************************************************************* - * - * T1_Done_Size - * - * - * The Type 1 size object finaliser. - * - * - * size :: handle to the target size object. - * - ******************************************************************/ - - LOCAL_DEF - void T1_Done_Size( T1_Size size ); - - -/******************************************************************* - * - * T1_Reset_Size - * - * - * Reset a Type 1 size when resolutions and character dimensions - * have been changed.. - * - * - * size :: handle to the target size object. - * - ******************************************************************/ - - LOCAL_DEF - FT_Error T1_Reset_Size( T1_Size size ); - - - -/******************************************************************* - * - * T1_Init_GlyphSlot - * - * The TrueType glyph slot initialiser - * - * glyph :: glyph record to build. - * - * Error code. - * - ******************************************************************/ - - LOCAL_DEF - FT_Error T1_Init_GlyphSlot( T1_GlyphSlot slot ); - - - -/******************************************************************* - * - * T1_Done_GlyphSlot - * - * The Type 1 glyph slot finaliser - * - * glyph :: handle to glyph slot object - * - * Error code. - * - ******************************************************************/ - - LOCAL_DEF - void T1_Done_GlyphSlot( T1_GlyphSlot slot ); - - - /******************************************************************* * * T1_Init_Driver