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