diff --git a/ChangeLog b/ChangeLog index d96e85f7f..f67ddcb6d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2002-04-19 David Turner + + * src/type1/t1gload.h, src/type1/t1gload.c: fixed incorrect + parameter sign-ness in callback function + + * include/freetype/config/ftmodule.h, + include/freetype/internal/fttrace.h, + src/Jamfile, src/pfr/*: + + adding a PFR font driver to the FreeType sources. Not that it + doesn't support embedded bitmaps or kerning tables for now.. + + + * include/freetype/internal/ftmemory.h: adding the FT_MEM_ZERO + and FT_ZERO macros + + * include/freetype/internal/ftstream.h: adding the FT_NEXT_OFF3, + FT_NEXT_UOFF3, FT_NEXT_OFF3_LE and FT_NEXT_UOFF3_LE to parse + in-memory 24-bit integers. + + 2002-04-18 David Turner * src/base/ftobjs.c, builds/win32/ftdebug.c, diff --git a/include/freetype/config/ftmodule.h b/include/freetype/config/ftmodule.h index 71e668e50..2ca7fa714 100644 --- a/include/freetype/config/ftmodule.h +++ b/include/freetype/config/ftmodule.h @@ -10,5 +10,6 @@ FT_USE_MODULE(sfnt_module_class) FT_USE_MODULE(ft_smooth_renderer_class) FT_USE_MODULE(tt_driver_class) FT_USE_MODULE(t1_driver_class) +FT_USE_MODULE(pfr_driver_class) FT_USE_MODULE(winfnt_driver_class) diff --git a/include/freetype/config/ftoption.h b/include/freetype/config/ftoption.h index bd06fecd9..9fd37ee51 100644 --- a/include/freetype/config/ftoption.h +++ b/include/freetype/config/ftoption.h @@ -375,7 +375,7 @@ FT_BEGIN_HEADER /* By undefining this, you will only compile the code necessary to load */ /* TrueType glyphs without hinting. */ /* */ -#undef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#undef TT_CONFIG_OPTION_BYTECODE_INTERPRETER /*************************************************************************/ diff --git a/include/freetype/internal/ftmemory.h b/include/freetype/internal/ftmemory.h index 597b64d90..dcd591d9f 100644 --- a/include/freetype/internal/ftmemory.h +++ b/include/freetype/internal/ftmemory.h @@ -178,6 +178,9 @@ FT_BEGIN_HEADER #define FT_MEM_MOVE( dest, source, count ) ft_memmove( dest, source, count ) +#define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) + +#define FT_ZERO(p) FT_MEM_ZERO( p, sizeof(*(p)) ) /*************************************************************************/ /* */ diff --git a/include/freetype/internal/ftstream.h b/include/freetype/internal/ftstream.h index ead5e09bc..1b5e4d1a4 100644 --- a/include/freetype/internal/ftstream.h +++ b/include/freetype/internal/ftstream.h @@ -120,6 +120,8 @@ FT_BEGIN_HEADER #define FT_FRAME_ULONG( f ) FT_FRAME_FIELD( ft_frame_ulong_be, f ) #define FT_FRAME_SHORT( f ) FT_FRAME_FIELD( ft_frame_short_be, f ) #define FT_FRAME_USHORT( f ) FT_FRAME_FIELD( ft_frame_ushort_be, f ) +#define FT_FRAME_OFF3( f ) FT_FRAME_FIELD( ft_frame_off3_be, f ) +#define FT_FRAME_UOFF3( f ) FT_FRAME_FIELD( ft_frame_uoff3_be, f ) #define FT_FRAME_BYTE( f ) FT_FRAME_FIELD( ft_frame_byte, f ) #define FT_FRAME_CHAR( f ) FT_FRAME_FIELD( ft_frame_schar, f ) @@ -127,6 +129,8 @@ FT_BEGIN_HEADER #define FT_FRAME_ULONG_LE( f ) FT_FRAME_FIELD( ft_frame_ulong_le, f ) #define FT_FRAME_SHORT_LE( f ) FT_FRAME_FIELD( ft_frame_short_le, f ) #define FT_FRAME_USHORT_LE( f ) FT_FRAME_FIELD( ft_frame_ushort_le, f ) +#define FT_FRAME_OFF3_LE( f ) FT_FRAME_FIELD( ft_frame_off3_le, f ) +#define FT_FRAME_UOFF3_LE( f ) FT_FRAME_FIELD( ft_frame_uoff3_le, f ) #define FT_FRAME_SKIP_LONG { ft_frame_long_be, 0, 0 } #define FT_FRAME_SKIP_SHORT { ft_frame_short_be, 0, 0 } diff --git a/include/freetype/internal/fttrace.h b/include/freetype/internal/fttrace.h index 6295d127c..0753e43b8 100644 --- a/include/freetype/internal/fttrace.h +++ b/include/freetype/internal/fttrace.h @@ -92,5 +92,7 @@ FT_TRACE_DEF( winfnt ) FT_TRACE_DEF( pcfdriver ) FT_TRACE_DEF( pcfread ) +/* PFR fonts component */ +FT_TRACE_DEF( pfr ) /* END */ diff --git a/src/Jamfile b/src/Jamfile index c37cbcbcd..b2f5d6e1c 100644 --- a/src/Jamfile +++ b/src/Jamfile @@ -21,6 +21,7 @@ SubInclude FT2_TOP src cache ; SubInclude FT2_TOP src cff ; SubInclude FT2_TOP src cid ; SubInclude FT2_TOP src pcf ; +SubInclude FT2_TOP src pfr ; SubInclude FT2_TOP src psaux ; SubInclude FT2_TOP src psnames ; SubInclude FT2_TOP src raster ; diff --git a/src/pfr/Jamfile b/src/pfr/Jamfile new file mode 100644 index 000000000..e29c67470 --- /dev/null +++ b/src/pfr/Jamfile @@ -0,0 +1,23 @@ +# FreeType 2 src/pfr Jamfile (c) 2002 David Turner +# + +SubDir FT2_TOP src pfr ; + +SubDirHdrs [ FT2_SubDir src pfr ] ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = pfrdrivr pfrgload pfrload pfrobjs pfrcmap ; + } + else + { + _sources = pfr ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/pfr Jamfile diff --git a/src/pfr/descrip.mms b/src/pfr/descrip.mms new file mode 100644 index 000000000..f5b11d63a --- /dev/null +++ b/src/pfr/descrip.mms @@ -0,0 +1,23 @@ +# +# FreeType 2 PFR driver compilation rules for VMS +# + + +# Copyright 1996-2002 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. + + +CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.pfr]) + +OBJS=pfr.obj + +all : $(OBJS) + library [--.lib]freetype.olb $(OBJS) + +# EOF diff --git a/src/pfr/module.mk b/src/pfr/module.mk new file mode 100644 index 000000000..24ca8b2d2 --- /dev/null +++ b/src/pfr/module.mk @@ -0,0 +1,22 @@ +# +# FreeType 2 PFR module definition +# + + +# Copyright 1996-2002 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. + + +make_module_list: add_pfr_driver + +add_pfr_driver: + $(OPEN_DRIVER)pfr_driver_class$(CLOSE_DRIVER) + $(ECHO_DRIVER)pfr $(ECHO_DRIVER_DESC)PFR/TrueDoc font files with extension *.pfr$(ECHO_DRIVER_DONE) + +# EOF diff --git a/src/pfr/pfr.c b/src/pfr/pfr.c new file mode 100644 index 000000000..fa384d5f3 --- /dev/null +++ b/src/pfr/pfr.c @@ -0,0 +1,28 @@ +/***************************************************************************/ +/* */ +/* pfr.c */ +/* */ +/* FreeType PFR driver component */ +/* */ +/* Copyright 1996-2002 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 + +#include "pfrload.c" +#include "pfrgload.c" +#include "pfrcmap.c" +#include "pfrobjs.c" +#include "pfrdrivr.c" + +/* END */ diff --git a/src/pfr/pfrcmap.c b/src/pfr/pfrcmap.c new file mode 100644 index 000000000..900a8a37d --- /dev/null +++ b/src/pfr/pfrcmap.c @@ -0,0 +1,129 @@ +#include "pfrcmap.h" +#include "pfrobjs.h" +#include FT_INTERNAL_DEBUG_H + + FT_CALLBACK_DEF( FT_Error ) + pfr_cmap_init( PFR_CMap cmap ) + { + PFR_Face face = (PFR_Face)FT_CMAP_FACE(cmap); + + + cmap->num_chars = face->phy_font.num_chars; + cmap->chars = face->phy_font.chars; + + /* just for safety, check that the character entries are correctly */ + /* sorted in increasing character code order.. */ + { + FT_UInt n; + + for ( n = 1; n < cmap->num_chars; n++ ) + { + if ( cmap->chars[n-1].char_code >= cmap->chars[n].char_code ) + FT_ASSERT(0); + } + } + + return 0; + } + + + FT_CALLBACK_DEF( void ) + pfr_cmap_done( PFR_CMap cmap ) + { + cmap->chars = NULL; + cmap->num_chars = 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + pfr_cmap_char_index( PFR_CMap cmap, + FT_UInt32 char_code ) + { + FT_UInt min = 0; + FT_UInt max = cmap->num_chars; + FT_UInt mid; + PFR_Char gchar; + + + while ( min < max ) + { + mid = min + ( max - min ) / 2; + gchar = cmap->chars + mid; + + if ( gchar->char_code == char_code ) + return mid; + + if ( gchar->char_code < char_code ) + min = mid + 1; + else + max = mid; + } + return 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + pfr_cmap_char_next( PFR_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_UInt result = 0; + FT_UInt32 char_code = *pchar_code + 1; + + + Restart: + { + FT_UInt min = 0; + FT_UInt max = cmap->num_chars; + FT_UInt mid; + PFR_Char gchar; + + + while ( min < max ) + { + mid = min + ( ( max - min ) >> 1 ); + gchar = cmap->chars + mid; + + if ( gchar->char_code == char_code ) + { + result = mid; + if ( result != 0 ) + goto Exit; + + char_code++; + goto Restart; + } + + if ( gchar->char_code < char_code ) + min = mid+1; + else + max = mid; + } + + /* we didn't find it, but we have a pair just above it */ + char_code = 0; + + if ( min < cmap->num_chars ) + { + gchar = cmap->chars + min; + result = min; + if ( result != 0 ) + char_code = gchar->char_code; + } + } + + Exit: + *pchar_code = char_code; + return result; + } + + + FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec + pfr_cmap_class_rec = + { + sizeof ( PFR_CMapRec ), + + (FT_CMap_InitFunc) pfr_cmap_init, + (FT_CMap_DoneFunc) pfr_cmap_done, + (FT_CMap_CharIndexFunc) pfr_cmap_char_index, + (FT_CMap_CharNextFunc) pfr_cmap_char_next + }; diff --git a/src/pfr/pfrcmap.h b/src/pfr/pfrcmap.h new file mode 100644 index 000000000..922d7b996 --- /dev/null +++ b/src/pfr/pfrcmap.h @@ -0,0 +1,23 @@ +#ifndef __PFR_CMAP_H__ +#define __PFR_CMAP_H__ + +#include +#include FT_INTERNAL_OBJECTS_H +#include "pfrtypes.h" + +FT_BEGIN_HEADER + + typedef struct PFR_CMapRec_ + { + FT_CMapRec cmap; + FT_UInt num_chars; + PFR_Char chars; + + } PFR_CMapRec, *PFR_CMap; + + + FT_CALLBACK_TABLE const FT_CMap_ClassRec pfr_cmap_class_rec; + +FT_END_HEADER + +#endif /* __PFR_CMAP_H__ */ diff --git a/src/pfr/pfrdrivr.c b/src/pfr/pfrdrivr.c new file mode 100644 index 000000000..a10bc936f --- /dev/null +++ b/src/pfr/pfrdrivr.c @@ -0,0 +1,52 @@ +#include +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include "pfrdrivr.h" +#include "pfrobjs.h" + + + FT_CALLBACK_TABLE_DEF + const FT_Driver_ClassRec pfr_driver_class = + { + { + ft_module_font_driver | + ft_module_driver_scalable, + + sizeof( FT_DriverRec ), + + "pfr", + 0x10000L, + 0x20000L, + + 0, /* format interface */ + + (FT_Module_Constructor) NULL, + (FT_Module_Destructor) NULL, + (FT_Module_Requester) NULL + }, + + sizeof( PFR_FaceRec ), + sizeof( PFR_SizeRec ), + sizeof( PFR_SlotRec ), + + (FT_Face_InitFunc) pfr_face_init, + (FT_Face_DoneFunc) pfr_face_done, + (FT_Size_InitFunc) NULL, + (FT_Size_DoneFunc) NULL, + (FT_Slot_InitFunc) pfr_slot_init, + (FT_Slot_DoneFunc) pfr_slot_done, + + (FT_Size_ResetPointsFunc) NULL, + (FT_Size_ResetPixelsFunc) NULL, + (FT_Slot_LoadFunc) pfr_slot_load, + (FT_CharMap_CharIndexFunc) NULL, + + (FT_Face_GetKerningFunc) 0, + (FT_Face_AttachFunc) 0, + (FT_Face_GetAdvancesFunc) 0, + + (FT_CharMap_CharNextFunc) NULL + }; + + + diff --git a/src/pfr/pfrdrivr.h b/src/pfr/pfrdrivr.h new file mode 100644 index 000000000..1575ebec2 --- /dev/null +++ b/src/pfr/pfrdrivr.h @@ -0,0 +1,38 @@ +/***************************************************************************/ +/* */ +/* pfrdrivr.h */ +/* */ +/* High-level Type PFR driver interface */ +/* */ +/* Copyright 1996-2002 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 __PFR_DRIVER_H__ +#define __PFR_DRIVER_H__ + + +#include +#include FT_INTERNAL_DRIVER_H + + +FT_BEGIN_HEADER + + + FT_EXPORT_VAR( const FT_Driver_ClassRec ) pfr_driver_class; + + +FT_END_HEADER + +#endif /* __PFR_DRIVER_H__ */ + + +/* END */ diff --git a/src/pfr/pfrgload.c b/src/pfr/pfrgload.c new file mode 100644 index 000000000..33de64d44 --- /dev/null +++ b/src/pfr/pfrgload.c @@ -0,0 +1,751 @@ +#include "pfrgload.h" +#include "pfrload.h" /* for macro definitions */ +#include FT_INTERNAL_DEBUG_H + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pfr + + /**************************************************************************/ + /**************************************************************************/ + /***** *****/ + /***** PFR GLYPH BUILDER *****/ + /***** *****/ + /**************************************************************************/ + /**************************************************************************/ + + + FT_LOCAL_DEF( void ) + pfr_glyph_init( PFR_Glyph glyph, + FT_GlyphLoader loader ) + { + FT_ZERO( glyph ); + + glyph->loader = loader; + glyph->path_begun = 0; + + FT_GlyphLoader_Rewind( loader ); + } + + + FT_LOCAL_DEF( void ) + pfr_glyph_done( PFR_Glyph glyph ) + { + FT_Memory memory = glyph->loader->memory; + + FT_FREE( glyph->x_control ); + glyph->y_control = NULL; + + glyph->max_xy_control = 0; + glyph->num_x_control = 0; + glyph->num_y_control = 0; + + FT_FREE( glyph->subs ); + + glyph->max_subs = 0; + glyph->num_subs = 0; + + glyph->loader = NULL; + glyph->path_begun = 0; + } + + + /* close current contour, if any */ + static void + pfr_glyph_close_contour( PFR_Glyph glyph ) + { + FT_GlyphLoader loader = glyph->loader; + FT_Outline* outline = &loader->current.outline; + FT_Int last, first; + + if ( !glyph->path_begun ) + return; + + /* compute first and last point indices in current glyph outline */ + last = outline->n_points - 1; + first = 0; + if ( outline->n_contours > 0 ) + first = outline->contours[ outline->n_contours-1 ]; + + /* if the last point falls on the same location than the first one */ + /* we need to delete it */ + if ( last > first ) + { + FT_Vector* p1 = outline->points + first; + FT_Vector* p2 = outline->points + last; + + if ( p1->x == p2->x && p1->y == p2->y ) + { + outline->n_points--; + last--; + } + } + + /* don't add empty contours */ + if ( last >= first ) + outline->contours[ outline->n_contours++ ] = (short) last; + + glyph->path_begun = 0; + } + + + + /* reset glyph to start the loading of a new glyph */ + static void + pfr_glyph_start( PFR_Glyph glyph ) + { + glyph->path_begun = 0; + } + + + static FT_Error + pfr_glyph_line_to( PFR_Glyph glyph, + FT_Vector* to ) + { + FT_GlyphLoader loader = glyph->loader; + FT_Outline* outline = &loader->current.outline; + FT_Error error; + + /* check that we've begun a new path */ + FT_ASSERT( glyph->path_begun != 0 ); + + error = FT_GlyphLoader_CheckPoints( loader, 1, 0 ); + if ( !error ) + { + FT_UInt n = outline->n_points; + + outline->points[n] = *to; + outline->tags [n] = FT_Curve_Tag_On; + + outline->n_points++; + } + + return error; + } + + + static FT_Error + pfr_glyph_curve_to( PFR_Glyph glyph, + FT_Vector* control1, + FT_Vector* control2, + FT_Vector* to ) + { + FT_GlyphLoader loader = glyph->loader; + FT_Outline* outline = &loader->current.outline; + FT_Error error; + + /* check that we've begun a new path */ + FT_ASSERT( glyph->path_begun != 0 ); + + error = FT_GlyphLoader_CheckPoints( loader, 3, 0 ); + if ( !error ) + { + FT_Vector* vec = outline->points + outline->n_points; + FT_Byte* tag = (FT_Byte*)outline->tags + outline->n_points; + + vec[0] = *control1; + vec[1] = *control2; + vec[2] = *to; + tag[0] = FT_Curve_Tag_Cubic; + tag[1] = FT_Curve_Tag_Cubic; + tag[2] = FT_Curve_Tag_On; + + outline->n_points = (FT_Short)( outline->n_points + 3 ); + } + + return error; + } + + + static FT_Error + pfr_glyph_move_to( PFR_Glyph glyph, + FT_Vector* to ) + { + FT_GlyphLoader loader = glyph->loader; + FT_Error error; + + /* close current contour if any */ + pfr_glyph_close_contour( glyph ); + + /* indicate that a new contour has started */ + glyph->path_begun = 1; + + /* check that there is room for a new contour and a new point */ + error = FT_GlyphLoader_CheckPoints( loader, 1, 1 ); + if ( !error ) + /* add new start point */ + error = pfr_glyph_line_to( glyph, to ); + + return error; + } + + + + static void + pfr_glyph_end( PFR_Glyph glyph ) + { + /* close current contour if any */ + pfr_glyph_close_contour( glyph ); + + /* merge the current glyph into the stack */ + FT_GlyphLoader_Add( glyph->loader ); + } + + + /**************************************************************************/ + /**************************************************************************/ + /***** *****/ + /***** PFR GLYPH LOADER *****/ + /***** *****/ + /**************************************************************************/ + /**************************************************************************/ + + /* Load a simple glyph */ + + static FT_Error + pfr_glyph_load_simple( PFR_Glyph glyph, + FT_Byte* p, + FT_Byte* limit ) + { + FT_Error error = 0; + FT_Memory memory = glyph->loader->memory; + FT_UInt flags, x_count, y_count, i, count, mask; + FT_Int x; + + PFR_CHECK(1); + flags = PFR_NEXT_BYTE(p); + + /* test for composite glyphs */ + FT_ASSERT( (flags & PFR_GLYPH_IS_COMPOUND) == 0 ); + + x_count = 0; + y_count = 0; + + if ( flags & PFR_GLYPH_1BYTE_XYCOUNT ) + { + PFR_CHECK(1); + count = PFR_NEXT_BYTE(p); + x_count = (count & 15); + y_count = (count >> 4); + } + else + { + if ( flags & PFR_GLYPH_XCOUNT ) + { + PFR_CHECK(1); + x_count = PFR_NEXT_BYTE(p); + } + + if ( flags & PFR_GLYPH_YCOUNT ) + { + PFR_CHECK(1); + y_count = PFR_NEXT_BYTE(p); + } + } + + count = x_count + y_count; + + /* re-allocate array when necessary */ + if ( count > glyph->max_xy_control ) + { + FT_UInt new_max = (count+7) & -8; + + if ( FT_RENEW_ARRAY( glyph->x_control, glyph->max_xy_control, new_max ) ) + goto Exit; + + glyph->max_xy_control = new_max; + } + + glyph->y_control = glyph->x_control + x_count; + + mask = 0; + x = 0; + for ( i = 0; i < count; i++ ) + { + if ( (i & 7) == 0 ) + { + PFR_CHECK(1); + mask = PFR_NEXT_BYTE(p); + } + + if ( mask & 1 ) + { + PFR_CHECK(2); + x = PFR_NEXT_SHORT(p); + } + else + { + PFR_CHECK(1); + x += PFR_NEXT_BYTE(p); + } + + glyph->x_control[i] = x; + + mask >>= 1; + } + + /* XXXX: for now we ignore the secondary stroke and edge definitions */ + /* since we don't want to support native PFR hinting.. */ + /* */ + if ( flags & PFR_GLYPH_EXTRA_ITEMS ) + { + error = pfr_extra_items_skip( &p, limit ); + if (error) goto Exit; + } + + + pfr_glyph_start( glyph ); + + /* now load a simple glyph */ + { + FT_Vector pos[4]; + FT_Vector* cur; + + pos[0].x = pos[0].y = 0; + pos[3] = pos[0]; + + for (;;) + { + FT_Int format, args_format = 0, args_count, n; + + /***************************************************************/ + /* read instruction */ + /* */ + PFR_CHECK(1); + format = PFR_NEXT_BYTE(p); + switch (format >> 4) + { + case 0: /* end glyph */ + FT_TRACE6(( "- end glyph" )); + args_count = 0; + break; + + case 1: /* general line operation */ + FT_TRACE6(( "- general line" )); + goto Line1; + + case 4: /* move to inside contour */ + FT_TRACE6(( "- move to inside" )); + goto Line1; + + case 5: /* move to outside contour */ + FT_TRACE6(( "- move to outside" )); + Line1: + args_format = format & 15; + args_count = 1; + break; + + case 2: /* horizontal line to */ + FT_TRACE6(( "- horizontal line to cx.%d", format & 15 )); + pos[0].y = pos[3].y; + pos[0].x = glyph->x_control[ format & 15 ]; + pos[3] = pos[0]; + args_count = 0; + break; + + case 3: /* vertical line to */ + FT_TRACE6(( "- vertical line to cy.%d", format & 15 )); + pos[0].x = pos[3].x; + pos[0].y = glyph->y_control[ format & 15 ]; + pos[3] = pos[0]; + args_count = 0; + break; + + case 6: /* horizontal to vertical curve */ + FT_TRACE6(( "- hv curve " )); + args_format = 0xB8E; + args_count = 3; + break; + + case 7: /* vertical to horizontal curve */ + FT_TRACE6(( "- vh curve" )); + args_format = 0xE2B; + args_count = 3; + break; + + default: /* general curve to */ + FT_TRACE6(( "- general curve" )); + args_count = 4; + args_format = (format & 15); + } + + /***********************************************************/ + /* now read arguments */ + /* */ + cur = pos; + for ( n = 0; n < args_count; n++ ) + { + FT_Int index, delta; + + /* read the X argument */ + switch ( args_format & 3 ) + { + case 0: /* 8-bit index */ + PFR_CHECK(1); + index = PFR_NEXT_BYTE(p); + cur->x = glyph->x_control[index]; + FT_TRACE7(( " cx#%d", index )); + break; + + case 1: /* 16-bit value */ + PFR_CHECK(2); + cur->x = PFR_NEXT_SHORT(p); + FT_TRACE7(( " x.%d", cur->x )); + break; + + case 2: /* 8-bit delta */ + PFR_CHECK(1); + delta = PFR_NEXT_INT8(p); + cur->x = pos[3].x + delta; + FT_TRACE7(( " dx.%d", delta )); + break; + + default: + FT_TRACE7(( " |" )); + cur->x = pos[3].x; + } + + /* read the Y argument */ + switch ( (args_format >> 2) & 3 ) + { + case 0: /* 8-bit index */ + PFR_CHECK(1); + index = PFR_NEXT_BYTE(p); + cur->y = glyph->y_control[index]; + FT_TRACE7(( " cy#%d", index )); + break; + + case 1: /* 16-bit absolute value */ + PFR_CHECK(2); + cur->y = PFR_NEXT_SHORT(p); + FT_TRACE7(( " y.%d", cur->y )); + break; + + case 2: /* 8-bit delta */ + PFR_CHECK(1); + delta = PFR_NEXT_INT8(p); + cur->y = pos[3].y + delta; + FT_TRACE7(( " dy.%d", delta )); + break; + + default: + FT_TRACE7(( " -" )); + cur->y = pos[3].y; + } + + /* read the additional format flag for the general curve */ + if ( n == 0 && args_count == 4 ) + { + PFR_CHECK(1); + args_format = PFR_NEXT_BYTE(p); + args_count--; + } + else + args_format >>= 4; + + /* save the previous point */ + pos[3] = cur[0]; + cur++; + } + + FT_TRACE7(( "\n" )); + + /***********************************************************/ + /* finally, execute instruction */ + /* */ + switch (format >> 4) + { + case 0: /* end glyph => EXIT */ + pfr_glyph_end( glyph ); + goto Exit; + + case 1: /* line operations */ + case 2: + case 3: + error = pfr_glyph_line_to( glyph, pos ); + goto Test_Error; + + case 4: /* move to inside contour */ + case 5: /* move to outside contour */ + error = pfr_glyph_move_to( glyph, pos ); + goto Test_Error; + + default: /* curve operations */ + error = pfr_glyph_curve_to( glyph, pos, pos+1, pos+2 ); + + Test_Error: /* test error condition */ + if (error) + goto Exit; + } + } /* for (;;) */ + } + + Exit: + return error; + + Too_Short: + error = FT_Err_Invalid_Table; + FT_ERROR(( "pfr_glyph_load: invalid glyph data\n" )); + goto Exit; + } + + + + /* load a composite/compound glyph */ + + static FT_Error + pfr_glyph_load_compound( PFR_Glyph glyph, + FT_Byte* p, + FT_Byte* limit ) + { + FT_Error error = 0; + FT_GlyphLoader loader = glyph->loader; + FT_Memory memory = loader->memory; + PFR_SubGlyph subglyph; + FT_UInt flags, i, count, org_count; + FT_Int x_pos, y_pos; + + PFR_CHECK(1); + flags = PFR_NEXT_BYTE(p); + + /* test for composite glyphs */ + FT_ASSERT( (flags & PFR_GLYPH_IS_COMPOUND) != 0 ); + + count = flags & 0x3F; + + /* ignore extra items when present */ + /* */ + if ( flags & PFR_GLYPH_EXTRA_ITEMS ) + { + error = pfr_extra_items_skip( &p, limit ); + if (error) goto Exit; + } + + /* we can't rely on the FT_GlyphLoader to load sub-glyphs, because */ + /* the PFR format is so damn stupid that it uses direct file offsets */ + /* to point to the sub-glyphs (instead of glyph indices).. */ + /* */ + /* for now, we'll load the list of sub-glyphs in a different array */ + /* but this will prevent us from using the auto-hinter at its best */ + /* quality.. */ + /* */ + org_count = glyph->num_subs; + + if ( org_count + count > glyph->max_subs ) + { + FT_UInt new_max = ( org_count + count + 3 ) & -4; + + if ( FT_RENEW_ARRAY( glyph->subs, glyph->max_subs, new_max ) ) + goto Exit; + + glyph->max_subs = new_max; + } + + subglyph = glyph->subs + org_count; + x_pos = 0; + y_pos = 0; + + for ( i = 0; i < count; i++, subglyph++ ) + { + FT_UInt format; + + PFR_CHECK(1); + format = PFR_NEXT_BYTE(p); + + /* read scale when available */ + subglyph->x_scale = 0x10000L; + if ( format & PFR_SUBGLYPH_XSCALE ) + { + PFR_CHECK(2); + subglyph->x_scale = PFR_NEXT_SHORT(p) << 4; + } + + subglyph->y_scale = 0x10000L; + if ( format & PFR_SUBGLYPH_YSCALE ) + { + PFR_CHECK(2); + subglyph->y_scale = PFR_NEXT_SHORT(p) << 4; + } + + /* read offset */ + switch ( format & 3 ) + { + case 1: + PFR_CHECK(2); + x_pos = PFR_NEXT_SHORT(p); + break; + + case 2: + PFR_CHECK(1); + x_pos += PFR_NEXT_INT8(p); + break; + + default: + ; + } + + switch ( (format >> 2) & 3 ) + { + case 1: + PFR_CHECK(2); + y_pos = PFR_NEXT_SHORT(p); + break; + + case 2: + PFR_CHECK(1); + y_pos += PFR_NEXT_INT8(p); + break; + + default: + ; + } + + subglyph->x_delta = x_pos; + subglyph->y_delta = y_pos; + + /* read glyph position and size now */ + if ( format & PFR_SUBGLYPH_2BYTE_SIZE ) + { + PFR_CHECK(2); + subglyph->gps_size = PFR_NEXT_USHORT(p); + } + else + { + PFR_CHECK(1); + subglyph->gps_size = PFR_NEXT_BYTE(p); + } + + if ( format & PFR_SUBGLYPH_3BYTE_OFFSET ) + { + PFR_CHECK(3); + subglyph->gps_offset = PFR_NEXT_LONG(p); + } + else + { + PFR_CHECK(2); + subglyph->gps_offset = PFR_NEXT_USHORT(p); + } + + glyph->num_subs++; + } + + + Exit: + return error; + + Too_Short: + error = FT_Err_Invalid_Table; + FT_ERROR(( "pfr_glyph_load: invalid glyph data\n" )); + goto Exit; + } + + + + static FT_Error + pfr_glyph_load_rec( PFR_Glyph glyph, + FT_Stream stream, + FT_ULong gps_offset, + FT_ULong offset, + FT_ULong size ) + { + FT_Error error; + FT_Byte* p; + FT_Byte* limit; + + if ( FT_STREAM_SEEK( gps_offset + offset ) || + FT_FRAME_ENTER( size ) ) + goto Exit; + + p = (FT_Byte*) stream->cursor; + limit = p + size; + + if ( size > 0 && *p & PFR_GLYPH_IS_COMPOUND ) + { + FT_Int n, old_count, count; + FT_GlyphLoader loader = glyph->loader; + FT_Outline* base = &loader->base.outline; + + + old_count = glyph->num_subs; + + /* this is a compound glyph - load it */ + error = pfr_glyph_load_compound( glyph, p, limit ); + + FT_FRAME_EXIT(); + + if ( error ) goto Exit; + + count = glyph->num_subs - old_count; + + /* now, load each individual glyph */ + for ( n = 0; n < count; n++ ) + { + FT_Int i, old_points, num_points; + PFR_SubGlyph subglyph; + + + subglyph = glyph->subs + old_count + n; + old_points = base->n_points; + + error = pfr_glyph_load_rec( glyph, stream, gps_offset, + subglyph->gps_offset, subglyph->gps_size ); + if ( error ) + goto Exit; + + /* note that the 'glyph->subs' might have been re-allocated */ + subglyph = glyph->subs + old_count + n; + num_points = base->n_points - old_points; + + /* translate and eventually scale the new glyph points */ + if ( subglyph->x_scale != 0x10000L || subglyph->y_scale != 0x10000L ) + { + FT_Vector* vec = base->points + old_points; + + + for ( i = 0; i < num_points; i++, vec++ ) + { + vec->x = FT_MulFix( vec->x, subglyph->x_scale ) + subglyph->x_delta; + vec->y = FT_MulFix( vec->y, subglyph->y_scale ) + subglyph->y_delta; + } + } + else + { + FT_Vector* vec = loader->base.outline.points + old_points; + + + for ( i = 0; i < num_points; i++, vec++ ) + { + vec->x += subglyph->x_delta; + vec->y += subglyph->y_delta; + } + } + + /* proceed to next sub-glyph */ + } + } + else + { + /* load a simple glyph */ + error = pfr_glyph_load_simple( glyph, p, limit ); + + FT_FRAME_EXIT(); + } + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + pfr_glyph_load( PFR_Glyph glyph, + FT_Stream stream, + FT_ULong gps_offset, + FT_ULong offset, + FT_ULong size ) + { + /* initialize glyph loader */ + FT_GlyphLoader_Rewind( glyph->loader ); + + /* load the glyph, recursively when needed */ + return pfr_glyph_load_rec( glyph, stream, gps_offset, offset, size ); + } + diff --git a/src/pfr/pfrgload.h b/src/pfr/pfrgload.h new file mode 100644 index 000000000..a706ad916 --- /dev/null +++ b/src/pfr/pfrgload.h @@ -0,0 +1,27 @@ +#ifndef __PFR_GLYPH_LOAD_H__ +#define __PFR_GLYPH_LOAD_H__ + +#include "pfrtypes.h" + +FT_BEGIN_HEADER + + FT_LOCAL( void ) + pfr_glyph_init( PFR_Glyph glyph, + FT_GlyphLoader loader ); + + FT_LOCAL( void ) + pfr_glyph_done( PFR_Glyph glyph ); + + + FT_LOCAL( FT_Error ) + pfr_glyph_load( PFR_Glyph glyph, + FT_Stream stream, + FT_ULong gps_offset, + FT_ULong offset, + FT_ULong size ); + + +FT_END_HEADER + + +#endif /* __PFR_GLYPH_LOAD_H__ */ diff --git a/src/pfr/pfrload.c b/src/pfr/pfrload.c new file mode 100644 index 000000000..a6d59172e --- /dev/null +++ b/src/pfr/pfrload.c @@ -0,0 +1,657 @@ +#include "pfrload.h" +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pfr + + /***********************************************************************/ + /***********************************************************************/ + /***** *****/ + /***** EXTRA ITEMS *****/ + /***** *****/ + /***********************************************************************/ + /***********************************************************************/ + + + FT_LOCAL_DEF( FT_Error ) + pfr_extra_items_skip( FT_Byte* *pp, FT_Byte* limit ) + { + return pfr_extra_items_parse( pp, limit, NULL, NULL ); + } + + + FT_LOCAL_DEF( FT_Error ) + pfr_extra_items_parse( FT_Byte* *pp, + FT_Byte* limit, + PFR_ExtraItem item_list, + FT_Pointer item_data ) + { + FT_Error error = 0; + FT_Byte* p = *pp; + FT_UInt num_items, item_type, item_size; + + PFR_CHECK(1); + num_items = PFR_NEXT_BYTE(p); + for ( ; num_items > 0; num_items-- ) + { + PFR_CHECK(2); + item_size = PFR_NEXT_BYTE(p); + item_type = PFR_NEXT_BYTE(p); + + PFR_CHECK(item_size); + + if ( item_list ) + { + PFR_ExtraItem extra = item_list; + + for ( extra = item_list; extra->parser != NULL; extra++ ) + { + if ( extra->type == item_type ) + { + error = extra->parser( p, p + item_size, item_data ); + if ( error ) goto Exit; + + break; + } + } + } + + p += item_size; + } + + Exit: + *pp = p; + return error; + + Too_Short: + FT_ERROR(( "pfr.extra_items.skip: invalid extra items table\n" )); + error = FT_Err_Invalid_Table; + goto Exit; + } + + + + /***********************************************************************/ + /***********************************************************************/ + /***** *****/ + /***** PFR HEADER *****/ + /***** *****/ + /***********************************************************************/ + /***********************************************************************/ + + static const FT_Frame_Field pfr_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PFR_HeaderRec + + FT_FRAME_START(58), + FT_FRAME_ULONG (signature), + FT_FRAME_USHORT(version), + FT_FRAME_USHORT(signature2), + FT_FRAME_USHORT(header_size), + + FT_FRAME_USHORT(log_dir_size), + FT_FRAME_USHORT(log_dir_offset), + + FT_FRAME_USHORT(log_font_max_size), + FT_FRAME_UOFF3 (log_font_section_size), + FT_FRAME_UOFF3 (log_font_section_offset), + + FT_FRAME_USHORT(phy_font_max_size), + FT_FRAME_UOFF3 (phy_font_section_size), + FT_FRAME_UOFF3 (phy_font_section_offset), + + FT_FRAME_USHORT(gps_max_size), + FT_FRAME_UOFF3 (gps_section_size), + FT_FRAME_UOFF3 (gps_section_offset), + + FT_FRAME_BYTE (max_blue_values), + FT_FRAME_BYTE (max_x_orus), + FT_FRAME_BYTE (max_y_orus), + + FT_FRAME_BYTE (phy_font_max_size_high), + FT_FRAME_BYTE (color_flags), + + FT_FRAME_UOFF3 (bct_max_size), + FT_FRAME_UOFF3 (bct_set_max_size), + FT_FRAME_UOFF3 (phy_bct_set_max_size), + + FT_FRAME_USHORT(num_phy_fonts), + FT_FRAME_BYTE (max_vert_stem_snap), + FT_FRAME_BYTE (max_horz_stem_snap), + FT_FRAME_USHORT(max_chars), + FT_FRAME_END + }; + + + FT_LOCAL_DEF( FT_Error ) + pfr_header_load( PFR_Header header, + FT_Stream stream ) + { + FT_Error error; + + /* read header directly */ + if ( !FT_STREAM_SEEK( 0 ) && + !FT_STREAM_READ_FIELDS( pfr_header_fields, header ) ) + { + /* make a few adjustments to the header */ + header->phy_font_max_size += + (FT_UInt32)header->phy_font_max_size_high << 16; + } + + return error; + } + + + FT_LOCAL_DEF( FT_Bool ) + pfr_header_check( PFR_Header header ) + { + FT_Bool result = 1; + + /* check signature and header size */ + if ( header->signature != 0x50465230 || /* "PFR0" */ + header->version > 4 || + header->header_size < 58 || + header->signature2 != 0x0d0a ) /* CR/LF */ + { + result = 0; + } + return result; + } + + + /***********************************************************************/ + /***********************************************************************/ + /***** *****/ + /***** PFR LOGICAL FONTS *****/ + /***** *****/ + /***********************************************************************/ + /***********************************************************************/ + + + FT_LOCAL_DEF( FT_Error ) + pfr_log_font_count( FT_Stream stream, + FT_UInt32 section_offset, + FT_UInt *acount ) + { + FT_Error error; + FT_UInt count; + FT_UInt result = 0; + + if ( FT_STREAM_SEEK( section_offset ) || FT_READ_USHORT(count) ) + goto Exit; + + result = count; + + Exit: + *acount = result; + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + pfr_log_font_load( PFR_LogFont log_font, + FT_Stream stream, + FT_UInt index, + FT_UInt32 section_offset, + FT_Bool size_increment ) + { + FT_UInt num_log_fonts; + FT_UInt flags; + FT_UInt32 offset; + FT_UInt32 size; + FT_Error error; + + if ( FT_STREAM_SEEK( section_offset ) || FT_READ_USHORT(num_log_fonts) ) + goto Exit; + + if ( index >= num_log_fonts ) + return FT_Err_Invalid_Argument; + + if ( FT_STREAM_SKIP( index*5 ) || + FT_READ_USHORT(size) || + FT_READ_UOFF3 (offset) ) + goto Exit; + + /* save logical font size and offset */ + log_font->size = size; + log_font->offset = offset; + + /* now, check the rest of the table before loading it */ + { + FT_Byte* p; + FT_Byte* limit; + FT_UInt local; + + if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) ) + goto Exit; + + p = stream->cursor; + limit = p + size; + + PFR_CHECK(13); + + log_font->matrix[0] = PFR_NEXT_LONG(p); + log_font->matrix[1] = PFR_NEXT_LONG(p); + log_font->matrix[2] = PFR_NEXT_LONG(p); + log_font->matrix[3] = PFR_NEXT_LONG(p); + + flags = PFR_NEXT_BYTE(p); + + local = 0; + if ( flags & PFR_LOG_STROKE ) + { + local++; + if ( flags & PFR_LOG_2BYTE_STROKE ) + local++; + + if ( (flags & PFR_LINE_JOIN_MASK) == PFR_LINE_JOIN_MITER ) + local += 3; + } + if ( flags & PFR_LOG_BOLD ) + { + local++; + if ( flags & PFR_LOG_2BYTE_BOLD ) + local++; + } + + PFR_CHECK(local); + + if ( flags & PFR_LOG_STROKE ) + { + log_font->stroke_thickness = ( flags & PFR_LOG_2BYTE_STROKE ) + ? PFR_NEXT_SHORT(p) + : PFR_NEXT_BYTE(p); + + if ( (flags & PFR_LINE_JOIN_MASK) == PFR_LINE_JOIN_MITER ) + log_font->miter_limit = PFR_NEXT_LONG(p); + } + + if ( flags & PFR_LOG_BOLD ) + { + log_font->bold_thickness = ( flags & PFR_LOG_2BYTE_BOLD ) + ? PFR_NEXT_SHORT(p) + : PFR_NEXT_BYTE(p); + } + + if ( flags & PFR_LOG_EXTRA_ITEMS ) + { + error = pfr_extra_items_skip( &p, limit ); + if (error) goto Fail; + } + + PFR_CHECK(5); + log_font->phys_size = PFR_NEXT_USHORT(p); + log_font->phys_offset = PFR_NEXT_ULONG(p); + if ( size_increment ) + { + PFR_CHECK(1); + log_font->phys_size += (FT_UInt32)PFR_NEXT_BYTE(p) << 16; + } + } + + Fail: + FT_FRAME_EXIT(); + + Exit: + return error; + + Too_Short: + FT_ERROR(( "pfr_log_font_load: invalid logical font table\n" )); + error = FT_Err_Invalid_Table; + goto Fail; + } + + + /***********************************************************************/ + /***********************************************************************/ + /***** *****/ + /***** PFR PHYSICAL FONTS *****/ + /***** *****/ + /***********************************************************************/ + /***********************************************************************/ + + + /* load bitmap strikes lists */ + FT_CALLBACK_DEF( FT_Error ) + pfr_extra_item_load_bitmap_info( FT_Byte* p, + FT_Byte* limit, + PFR_PhyFont phy_font ) + { + FT_Memory memory = phy_font->memory; + PFR_Strike strike; + FT_UInt flags0; + FT_UInt n, count, size1; + FT_Error error = 0; + + PFR_CHECK(5); + + p += 3; /* skip bctSize */ + flags0 = PFR_NEXT_BYTE(p); + count = PFR_NEXT_BYTE(p); + + /* re-allocate when needed */ + if ( phy_font->num_strikes + count > phy_font->max_strikes ) + { + FT_UInt new_max = (phy_font->num_strikes + count + 3) & -4; + + if ( FT_RENEW_ARRAY( phy_font->strikes, phy_font->num_strikes, new_max ) ) + goto Exit; + + phy_font->max_strikes = new_max; + } + + size1 = 1 + 1 + 1 + 2 + 2 + 1; + if ( flags0 & PFR_STRIKE_2BYTE_XPPM ) + size1++; + + if ( flags0 & PFR_STRIKE_2BYTE_YPPM ) + size1++; + + if ( flags0 & PFR_STRIKE_3BYTE_SIZE ) + size1++; + + if ( flags0 & PFR_STRIKE_3BYTE_OFFSET ) + size1++; + + if ( flags0 & PFR_STRIKE_2BYTE_COUNT ) + size1++; + + strike = phy_font->strikes + phy_font->num_strikes; + + PFR_CHECK( count*size1 ); + + for ( n = 0; n < count; n++, strike++ ) + { + strike->x_ppm = ( flags0 & PFR_STRIKE_2BYTE_XPPM ) + ? PFR_NEXT_USHORT(p) + : PFR_NEXT_BYTE(p); + + strike->y_ppm = ( flags0 & PFR_STRIKE_2BYTE_YPPM ) + ? PFR_NEXT_USHORT(p) + : PFR_NEXT_BYTE(p); + + strike->flags = PFR_NEXT_BYTE(p); + + strike->bct_size = ( flags0 & PFR_STRIKE_3BYTE_SIZE ) + ? PFR_NEXT_ULONG(p) + : PFR_NEXT_USHORT(p); + + strike->bct_offset = ( flags0 & PFR_STRIKE_3BYTE_OFFSET ) + ? PFR_NEXT_ULONG(p) + : PFR_NEXT_USHORT(p); + + strike->num_bitmaps = ( flags0 & PFR_STRIKE_2BYTE_COUNT ) + ? PFR_NEXT_USHORT(p) + : PFR_NEXT_BYTE(p); + } + + phy_font->num_strikes += count; + + Exit: + return error; + + Too_Short: + error = FT_Err_Invalid_Table; + FT_ERROR(( "pfr.extra_item_load: invalid bitmap info table\n" )); + goto Exit; + } + + + /* load font ID, i.e. name */ + FT_CALLBACK_DEF( FT_Error ) + pfr_extra_item_load_font_id( FT_Byte* p, + FT_Byte* limit, + PFR_PhyFont phy_font ) + { + FT_Error error = 0; + FT_Memory memory = phy_font->memory; + FT_UInt len = (FT_UInt)( limit - p ); + + if ( phy_font->font_id != NULL ) + goto Exit; + + if ( FT_ALLOC( phy_font->font_id, len+1 ) ) + goto Exit; + + /* copy font ID name, and terminate it for safety */ + FT_MEM_COPY( phy_font->font_id, p, len ); + phy_font->font_id[len] = 0; + + Exit: + return error; + } + + + /* load stem snap tables */ + FT_CALLBACK_DEF( FT_Error ) + pfr_extra_item_load_stem_snaps( FT_Byte* p, + FT_Byte* limit, + PFR_PhyFont phy_font ) + { + FT_UInt count, num_vert, num_horz; + FT_Int* snaps; + FT_Error error = 0; + FT_Memory memory = phy_font->memory; + + if ( phy_font->vertical.stem_snaps != NULL ) + goto Exit; + + PFR_CHECK(1); + count = PFR_NEXT_BYTE(p); + + num_vert = count & 15; + num_horz = count >> 4; + count = num_vert + num_horz; + + PFR_CHECK( count*2 ); + + if ( FT_NEW_ARRAY( snaps, count ) ) + goto Exit; + + phy_font->vertical.stem_snaps = snaps; + phy_font->horizontal.stem_snaps = snaps + num_vert; + + for ( ; count > 0; count--, snaps++ ) + *snaps = FT_NEXT_SHORT(p); + + Exit: + return error; + + Too_Short: + error = FT_Err_Invalid_Table; + FT_ERROR(( "pfr.exta_item_load: invalid stem snaps table\n" )); + goto Exit; + } + + + static const PFR_ExtraItemRec pfr_phy_font_extra_items[] = + { + { 1, (PFR_ExtraItem_ParseFunc) pfr_extra_item_load_bitmap_info }, + { 2, (PFR_ExtraItem_ParseFunc) pfr_extra_item_load_font_id }, + { 3, (PFR_ExtraItem_ParseFunc) pfr_extra_item_load_stem_snaps }, + { 0, NULL } + }; + + + + + + FT_LOCAL_DEF( void ) + pfr_phy_font_done( PFR_PhyFont phy_font, + FT_Memory memory ) + { + if ( phy_font->font_id ) + FT_FREE( phy_font->font_id ); + + FT_FREE( phy_font->vertical.stem_snaps ); + phy_font->vertical.num_stem_snaps = 0; + + phy_font->horizontal.stem_snaps = NULL; + phy_font->horizontal.num_stem_snaps = 0; + + FT_FREE( phy_font->strikes ); + phy_font->num_strikes = 0; + phy_font->max_strikes = 0; + + FT_FREE( phy_font->chars ); + phy_font->num_chars = 0; + phy_font->chars_offset = 0; + } + + + + + + + FT_LOCAL_DEF( FT_Error ) + pfr_phy_font_load( PFR_PhyFont phy_font, + FT_Stream stream, + FT_UInt32 offset, + FT_UInt32 size ) + { + FT_Error error; + FT_Memory memory = stream->memory; + FT_UInt flags, num_aux; + FT_Byte* p; + FT_Byte* limit; + + phy_font->memory = memory; + phy_font->offset = offset; + + if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) ) + goto Exit; + + p = stream->cursor; + limit = p + size; + + PFR_CHECK( 15 ); + phy_font->font_ref_number = PFR_NEXT_USHORT(p); + phy_font->outline_resolution = PFR_NEXT_USHORT(p); + phy_font->metrics_resolution = PFR_NEXT_USHORT(p); + phy_font->bbox.xMin = PFR_NEXT_SHORT(p); + phy_font->bbox.yMin = PFR_NEXT_SHORT(p); + phy_font->bbox.xMax = PFR_NEXT_SHORT(p); + phy_font->bbox.yMax = PFR_NEXT_SHORT(p); + phy_font->flags = flags = PFR_NEXT_BYTE(p); + + /* get the standard advance for non-proprotional fonts */ + if ( !(flags & PFR_PHY_PROPORTIONAL) ) + { + PFR_CHECK(2); + phy_font->standard_advance = PFR_NEXT_SHORT(p); + } + + /* load the extra items when present */ + if ( flags & PFR_PHY_EXTRA_ITEMS ) + { + error = + pfr_extra_items_parse( &p, limit, pfr_phy_font_extra_items, phy_font ); + + if ( error ) + goto Fail; + } + + /* skip the aux bytes */ + PFR_CHECK(3); + num_aux = PFR_NEXT_ULONG(p); + + PFR_CHECK(num_aux); + p += num_aux; + + /* read the blue values */ + { + FT_UInt n, count; + + PFR_CHECK( 1 ); + phy_font->num_blue_values = count = PFR_NEXT_BYTE(p); + + PFR_CHECK( count*2 ); + + if ( FT_NEW_ARRAY( phy_font->blue_values, count ) ) + goto Fail; + + for ( n = 0; n < count; n++ ) + phy_font->blue_values[n] = PFR_NEXT_SHORT(p); + } + + PFR_CHECK(8); + phy_font->blue_fuzz = PFR_NEXT_BYTE(p); + phy_font->blue_scale = PFR_NEXT_BYTE(p); + + phy_font->vertical.standard = PFR_NEXT_USHORT(p); + phy_font->horizontal.standard = PFR_NEXT_USHORT(p); + + /* read the character descriptors */ + { + FT_UInt n, count, size; + + phy_font->num_chars = count = PFR_NEXT_USHORT(p); + phy_font->chars_offset = offset + (p - stream->cursor); + + if ( FT_NEW_ARRAY( phy_font->chars, count ) ) + goto Fail; + + size = 1 + 1 + 2; + if ( flags & PFR_PHY_2BYTE_CHARCODE ) + size += 1; + + if ( flags & PFR_PHY_PROPORTIONAL ) + size += 2; + + if ( flags & PFR_PHY_ASCII_CODE ) + size += 1; + + if ( flags & PFR_PHY_2BYTE_GPS_SIZE ) + size += 1; + + if ( flags & PFR_PHY_3BYTE_GPS_OFFSET ) + size += 1; + + PFR_CHECK( count*size ); + + for ( n = 0; n < count; n++ ) + { + PFR_Char cur = &phy_font->chars[n]; + + cur->char_code = ( flags & PFR_PHY_2BYTE_CHARCODE ) + ? PFR_NEXT_USHORT(p) + : PFR_NEXT_BYTE(p); + + cur->advance = ( flags & PFR_PHY_PROPORTIONAL ) + ? PFR_NEXT_SHORT(p) + : phy_font->standard_advance; + +#if 0 + cur->ascii = ( flags & PFR_PHY_ASCII_CODE ) + ? PFR_NEXT_BYTE(p) + : 0; +#else + if ( flags & PFR_PHY_ASCII_CODE ) + p += 1; +#endif + cur->gps_size = ( flags & PFR_PHY_2BYTE_GPS_SIZE ) + ? PFR_NEXT_USHORT(p) + : PFR_NEXT_BYTE(p); + + cur->gps_offset = ( flags & PFR_PHY_3BYTE_GPS_OFFSET ) + ? PFR_NEXT_ULONG(p) + : PFR_NEXT_USHORT(p); + } + } + + /* that's it !! */ + Fail: + FT_FRAME_EXIT(); + + Exit: + return error; + + Too_Short: + error = FT_Err_Invalid_Table; + FT_ERROR(( "pfr_phy_font_load: invalid physical font table\n" )); + goto Fail; + } + + diff --git a/src/pfr/pfrload.h b/src/pfr/pfrload.h new file mode 100644 index 000000000..58b8a6fb4 --- /dev/null +++ b/src/pfr/pfrload.h @@ -0,0 +1,89 @@ +#ifndef __PFR_LOAD_H__ +#define __PFR_LOAD_H__ + +#include "pfrobjs.h" +#include FT_INTERNAL_STREAM_H + +FT_BEGIN_HEADER + +#ifdef PFR_CONFIG_NO_CHECKS +# define PFR_CHECK(x) do { } while (0) +#else +# define PFR_CHECK(x) do { if ( p + (x) > limit ) goto Too_Short; } while (0) +#endif + +#define PFR_NEXT_BYTE(p) FT_NEXT_BYTE(p) +#define PFR_NEXT_INT8(p) FT_NEXT_CHAR(p) +#define PFR_NEXT_SHORT(p) FT_NEXT_SHORT(p) +#define PFR_NEXT_USHORT(p) FT_NEXT_USHORT(p) +#define PFR_NEXT_LONG(p) FT_NEXT_OFF3(p) +#define PFR_NEXT_ULONG(p) FT_NEXT_UOFF3(p) + + /* handling extra items */ + + typedef FT_Error (*PFR_ExtraItem_ParseFunc)( FT_Byte* p, + FT_Byte* limit, + FT_Pointer data ); + typedef struct PFR_ExtraItemRec_ + { + FT_UInt type; + PFR_ExtraItem_ParseFunc parser; + + } PFR_ExtraItemRec; + + typedef const struct PFR_ExtraItemRec_* PFR_ExtraItem; + + FT_LOCAL( FT_Error ) + pfr_extra_items_skip( FT_Byte* *pp, FT_Byte* limit ); + + FT_LOCAL( FT_Error ) + pfr_extra_items_parse( FT_Byte* *pp, + FT_Byte* limit, + PFR_ExtraItem item_list, + FT_Pointer item_data ); + + + /* load a PFR header */ + FT_LOCAL( FT_Error ) + pfr_header_load( PFR_Header header, + FT_Stream stream ); + + /* check a PFR header */ + FT_LOCAL( FT_Bool ) + pfr_header_check( PFR_Header header ); + + + + /* return number of logical fonts in this file */ + FT_LOCAL( FT_Error ) + pfr_log_font_count( FT_Stream stream, + FT_UInt32 log_section_offset, + FT_UInt *acount ); + + + /* load a pfr logical font entry */ + FT_LOCAL( FT_Error ) + pfr_log_font_load( PFR_LogFont log_font, + FT_Stream stream, + FT_UInt face_index, + FT_UInt32 section_offset, + FT_Bool size_increment ); + + + /* load a physical font entry */ + FT_LOCAL( FT_Error ) + pfr_phy_font_load( PFR_PhyFont phy_font, + FT_Stream stream, + FT_UInt32 offset, + FT_UInt32 size ); + + /* finalize a physical font */ + FT_LOCAL( void ) + pfr_phy_font_done( PFR_PhyFont phy_font, + FT_Memory memory ); + + /* */ + +FT_END_HEADER + +#endif /* __PFR_LOAD_H__ */ diff --git a/src/pfr/pfrobjs.c b/src/pfr/pfrobjs.c new file mode 100644 index 000000000..fb9a54e57 --- /dev/null +++ b/src/pfr/pfrobjs.c @@ -0,0 +1,280 @@ +#include "pfrobjs.h" +#include "pfrload.h" +#include "pfrgload.h" +#include "pfrcmap.h" +#include FT_OUTLINE_H +#include FT_INTERNAL_DEBUG_H + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pfr + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FACE OBJECT METHODS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + pfr_face_done( PFR_Face face ) + { + /* finalize the physical font record */ + pfr_phy_font_done( &face->phy_font, FT_FACE_MEMORY(face) ); + + /* no need to finalize the logical font or the header */ + } + + + FT_LOCAL_DEF( FT_Error ) + pfr_face_init( FT_Stream stream, + PFR_Face face, + FT_Int face_index ) + { + FT_Error error; + + /* load the header and check it */ + error = pfr_header_load( &face->header, stream ); + if ( error ) goto Exit; + + if ( !pfr_header_check( &face->header ) ) + { + FT_TRACE4(( "PFR.Face.Init: not a valid PFR font\n" )); + error = FT_Err_Invalid_Argument; + goto Exit; + } + + /* check face index */ + { + FT_UInt num_faces; + + error = pfr_log_font_count( stream, + face->header.log_dir_offset, + &num_faces ); + if ( error ) goto Exit; + + face->root.num_faces = num_faces; + } + + if ( face_index < 0 ) + goto Exit; + + if ( face_index >= face->root.num_faces ) + { + FT_ERROR(( "PFR.Face.Init: invalid face index\n" )); + error = FT_Err_Invalid_Argument; + goto Exit; + } + + /* load the face */ + error = pfr_log_font_load( + &face->log_font, stream, face_index, + face->header.log_dir_offset, + FT_BOOL( face->header.phy_font_max_size_high != 0 ) ); + if ( error ) + goto Exit; + + /* now load the physical font descriptor */ + error = pfr_phy_font_load( &face->phy_font, stream, + face->log_font.phys_offset, + face->log_font.phys_size ); + if ( error ) + goto Exit; + + /* now, set-up all root face fields */ + { + FT_Face root = FT_FACE(face); + PFR_PhyFont phy_font = &face->phy_font; + + root->face_index = face_index; + root->num_glyphs = phy_font->num_chars; + root->face_flags = FT_FACE_FLAG_SCALABLE; + + if ( (phy_font->flags & PFR_PHY_PROPORTIONAL) == 0 ) + root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + + if ( phy_font->flags & PFR_PHY_VERTICAL ) + root->face_flags |= FT_FACE_FLAG_HORIZONTAL; + else + root->face_flags |= FT_FACE_FLAG_VERTICAL; + + /* XXXX: kerning and embedded bitmap support isn't there yet */ + + root->family_name = phy_font->font_id; + root->style_name = NULL; /* no style name in font file */ + + root->num_fixed_sizes = 0; + root->available_sizes = 0; + + root->bbox = phy_font->bbox; + root->units_per_EM = (FT_UShort) phy_font->outline_resolution; + root->ascender = (FT_Short) phy_font->bbox.yMax; + root->descender = (FT_Short) phy_font->bbox.yMin; + root->height = (FT_Short)( ((root->ascender - root->descender)*12) / 10 ); + + /* now compute maximum advance width */ + if ( (phy_font->flags & PFR_PHY_PROPORTIONAL) == 0 ) + root->max_advance_width = (FT_Short) phy_font->standard_advance; + else + { + FT_Int max = 0; + FT_UInt count = phy_font->num_chars; + PFR_Char gchar = phy_font->chars; + + for ( ; count > 0; count--, gchar++ ) + { + if ( max < gchar->advance ) + max = gchar->advance; + } + + root->max_advance_width = (FT_Short) max; + } + + root->max_advance_height = root->height; + + root->underline_position = (FT_Short)( - root->units_per_EM/10 ); + root->underline_thickness = (FT_Short)( root->units_per_EM/30 ); + + /* create charmap */ + { + FT_CharMapRec charmap; + + charmap.face = root; + charmap.platform_id = 3; + charmap.encoding_id = 1; + charmap.encoding = ft_encoding_unicode; + + FT_CMap_New( &pfr_cmap_class_rec, NULL, &charmap, NULL ); + } + } + + Exit: + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** SLOT OBJECT METHOD *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( FT_Error ) + pfr_slot_init( PFR_Slot slot ) + { + FT_GlyphLoader loader = slot->root.internal->loader; + + pfr_glyph_init( &slot->glyph, loader ); + + return 0; + } + + + FT_LOCAL_DEF( void ) + pfr_slot_done( PFR_Slot slot ) + { + pfr_glyph_done( &slot->glyph ); + } + + + FT_LOCAL_DEF( FT_Error ) + pfr_slot_load( PFR_Slot slot, + PFR_Size size, + FT_UInt gindex, + FT_Int load_flags ) + { + FT_Error error; + PFR_Face face = (PFR_Face) slot->root.face; + PFR_Char gchar = face->phy_font.chars + gindex; + FT_Outline* outline = &slot->root.outline; + FT_ULong gps_offset; + + /* check that the glyph index is correct */ + FT_ASSERT( gindex < face->phy_font.num_chars ); + + slot->root.format = ft_glyph_format_outline; + outline->n_points = 0; + outline->n_contours = 0; + gps_offset = face->header.gps_section_offset; + + + /* load the glyph outline ( FT_LOAD_NO_RECURSE isn't supported ) */ + error = pfr_glyph_load( &slot->glyph, face->root.stream, + gps_offset, gchar->gps_offset, gchar->gps_size ); + + if (!error) + { + FT_BBox cbox; + FT_Outline* outline = &slot->root.outline; + FT_Glyph_Metrics* metrics = &slot->root.metrics; + FT_Pos advance; + FT_Int em_metrics, em_outline; + FT_Bool scaling; + + scaling = FT_BOOL( (load_flags & FT_LOAD_NO_SCALE) == 0 ); + + /* copy outline data */ + *outline = slot->glyph.loader->base.outline; + + outline->flags &= ~ft_outline_owner; + outline->flags |= ft_outline_reverse_fill; + + if ( size && size->root.metrics.y_ppem < 24 ) + outline->flags |= ft_outline_high_precision; + + /* compute the advance vector */ + metrics->horiAdvance = 0; + metrics->vertAdvance = 0; + + advance = gchar->advance; + em_metrics = face->phy_font.metrics_resolution; + em_outline = face->phy_font.outline_resolution; + + if ( em_metrics != em_outline ) + advance = FT_MulDiv( advance, em_outline, em_metrics ); + + if ( face->phy_font.flags & PFR_PHY_VERTICAL ) + metrics->vertAdvance = gchar->advance; + else + metrics->horiAdvance = gchar->advance; + + slot->root.linearHoriAdvance = metrics->horiAdvance; + slot->root.linearVertAdvance = metrics->vertAdvance; + + /* make-up vertical metrics (?) */ + metrics->vertBearingX = 0; + metrics->vertBearingY = 0; + + /* scale when needed */ + if ( scaling ) + { + FT_Int n; + FT_Fixed x_scale = size->root.metrics.x_scale; + FT_Fixed y_scale = size->root.metrics.y_scale; + FT_Vector* vec = outline->points; + + /* scale outline points */ + for ( n = 0; n < outline->n_points; n++, vec++ ) + { + vec->x = FT_MulFix( vec->x, x_scale ); + vec->y = FT_MulFix( vec->y, y_scale ); + } + + /* scale the advance */ + metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); + metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); + } + + /* compute the rest of the metrics */ + FT_Outline_Get_CBox( outline, &cbox ); + + metrics->width = cbox.xMax - cbox.xMin; + metrics->height = cbox.yMax - cbox.yMin; + metrics->horiBearingX = cbox.xMin; + metrics->horiBearingY = cbox.yMax - metrics->height; + } + + return error; + } diff --git a/src/pfr/pfrobjs.h b/src/pfr/pfrobjs.h new file mode 100644 index 000000000..644ff8c57 --- /dev/null +++ b/src/pfr/pfrobjs.h @@ -0,0 +1,68 @@ +#ifndef __PFR_OBJS_H__ +#define __PFR_OBJS_H__ + +#include "pfrtypes.h" + +FT_BEGIN_HEADER + + typedef struct PFR_FaceRec_* PFR_Face; + + typedef struct PFR_SizeRec_* PFR_Size; + + typedef struct PFR_SlotRec_* PFR_Slot; + + + + typedef struct PFR_FaceRec_ + { + FT_FaceRec root; + PFR_HeaderRec header; + PFR_LogFontRec log_font; + PFR_PhyFontRec phy_font; + + } PFR_FaceRec; + + + typedef struct PFR_SizeRec_ + { + FT_SizeRec root; + + } PFR_SizeRec; + + + typedef struct PFR_SlotRec_ + { + FT_GlyphSlotRec root; + PFR_GlyphRec glyph; + + } PFR_SlotRec; + + + FT_LOCAL( FT_Error ) + pfr_face_init( FT_Stream stream, + PFR_Face face, + FT_Int face_index ); + + + FT_LOCAL( void ) + pfr_face_done( PFR_Face face ); + + + FT_LOCAL( FT_Error ) + pfr_slot_init( PFR_Slot slot ); + + + FT_LOCAL( void ) + pfr_slot_done( PFR_Slot slot ); + + + FT_LOCAL( FT_Error ) + pfr_slot_load( PFR_Slot slot, + PFR_Size size, + FT_UInt gindex, + FT_Int load_flags ); + + +FT_END_HEADER + +#endif /* __PFR_OBJS_H__ */ diff --git a/src/pfr/pfrtypes.h b/src/pfr/pfrtypes.h new file mode 100644 index 000000000..e965b5b16 --- /dev/null +++ b/src/pfr/pfrtypes.h @@ -0,0 +1,289 @@ +#ifndef __PFR_TYPES_H__ +#define __PFR_TYPES_H__ + +#include +#include FT_INTERNAL_OBJECTS_H + +FT_BEGIN_HEADER + + /************************************************************************/ + + /* the PFR Header structure */ + typedef struct PFR_HeaderRec_ + { + FT_UInt32 signature; + FT_UInt version; + FT_UInt signature2; + FT_UInt header_size; + + FT_UInt log_dir_size; + FT_UInt log_dir_offset; + + FT_UInt log_font_max_size; + FT_UInt32 log_font_section_size; + FT_UInt32 log_font_section_offset; + + FT_UInt32 phy_font_max_size; + FT_UInt32 phy_font_section_size; + FT_UInt32 phy_font_section_offset; + + FT_UInt gps_max_size; + FT_UInt32 gps_section_size; + FT_UInt32 gps_section_offset; + + FT_UInt max_blue_values; + FT_UInt max_x_orus; + FT_UInt max_y_orus; + + FT_UInt phy_font_max_size_high; + FT_UInt color_flags; + + FT_UInt32 bct_max_size; + FT_UInt32 bct_set_max_size; + FT_UInt32 phy_bct_set_max_size; + + FT_UInt num_phy_fonts; + FT_UInt max_vert_stem_snap; + FT_UInt max_horz_stem_snap; + FT_UInt max_chars; + + } PFR_HeaderRec, *PFR_Header; + + + /* used in 'color_flags' field of the PFR_Header */ + typedef enum PFR_HeaderFlags_ + { + PFR_FLAG_BLACK_PIXEL = 1, + PFR_FLAG_INVERT_BITMAP = 2 + + } PFR_HeaderFlags; + + + /************************************************************************/ + + typedef struct PFR_LogFontRec_ + { + FT_UInt32 size; + FT_UInt32 offset; + + FT_Int32 matrix[4]; + FT_UInt stroke_flags; + FT_Int stroke_thickness; + FT_Int bold_thickness; + FT_Int32 miter_limit; + + FT_UInt32 phys_size; + FT_UInt32 phys_offset; + + } PFR_LogFontRec, *PFR_LogFont; + + + typedef enum PFR_LogFlags_ + { + PFR_LOG_EXTRA_ITEMS = 0x40, + PFR_LOG_2BYTE_BOLD = 0x20, + PFR_LOG_BOLD = 0x10, + PFR_LOG_2BYTE_STROKE = 8, + PFR_LOG_STROKE = 4, + PFR_LINE_JOIN_MASK = 3 + + } PFR_LogFlags; + + + typedef enum PFR_LineJoinFlags_ + { + PFR_LINE_JOIN_MITER = 0, + PFR_LINE_JOIN_ROUND = 1, + PFR_LINE_JOIN_BEVEL = 2 + + } PFR_LineJoinFlags; + + + /************************************************************************/ + + typedef enum PFR_BitmapFlags_ + { + PFR_BITMAP_3BYTE_OFFSET = 4, + PFR_BITMAP_2BYTE_SIZE = 2, + PFR_BITMAP_2BYTE_CHARCODE = 1 + + } PFR_BitmapFlags; + + + typedef struct PFR_BitmapCharRec_ + { + FT_UInt char_code; + FT_UInt gps_size; + FT_UInt32 gps_offset; + + } PFR_BitmapCharRec, *PFR_BitmapChar; + + + typedef enum PFR_StrikeFlags_ + { + PFR_STRIKE_2BYTE_COUNT = 0x10, + PFR_STRIKE_3BYTE_OFFSET = 0x08, + PFR_STRIKE_3BYTE_SIZE = 0x04, + PFR_STRIKE_2BYTE_YPPM = 0x02, + PFR_STRIKE_2BYTE_XPPM = 0x01 + + } PFR_StrikeFlags; + + + typedef struct PFR_StrikeRec_ + { + FT_UInt x_ppm; + FT_UInt y_ppm; + FT_UInt flags; + + FT_UInt32 gps_size; + FT_UInt32 gps_offset; + + FT_UInt32 bct_size; + FT_UInt32 bct_offset; + + /* optional */ + FT_UInt num_bitmaps; + PFR_BitmapChar bitmaps; + + } PFR_StrikeRec, *PFR_Strike; + + + + /************************************************************************/ + + typedef struct PFR_CharRec_ + { + FT_UInt char_code; + FT_Int advance; + FT_UInt gps_size; + FT_UInt32 gps_offset; + + } PFR_CharRec, *PFR_Char; + + + /************************************************************************/ + + typedef struct PFR_DimensionRec_ + { + FT_UInt standard; + FT_UInt num_stem_snaps; + FT_Int* stem_snaps; + + } PFR_DimensionRec, *PFR_Dimension; + + + /************************************************************************/ + + typedef struct PFR_PhyFontRec_ + { + FT_Memory memory; + FT_UInt32 offset; + + FT_UInt font_ref_number; + FT_UInt outline_resolution; + FT_UInt metrics_resolution; + FT_BBox bbox; + FT_UInt flags; + FT_UInt standard_advance; + + PFR_DimensionRec horizontal; + PFR_DimensionRec vertical; + + FT_String* font_id; + + FT_UInt num_strikes; + FT_UInt max_strikes; + PFR_StrikeRec* strikes; + + FT_UInt num_blue_values; + FT_Int *blue_values; + FT_UInt blue_fuzz; + FT_UInt blue_scale; + + FT_UInt num_chars; + FT_UInt32 chars_offset; + PFR_Char chars; + + } PFR_PhyFontRec, *PFR_PhyFont; + + typedef enum PFR_PhyFlags_ + { + PFR_PHY_EXTRA_ITEMS = 0x80, + PFR_PHY_3BYTE_GPS_OFFSET = 0x20, + PFR_PHY_2BYTE_GPS_SIZE = 0x10, + PFR_PHY_ASCII_CODE = 0x08, + PFR_PHY_PROPORTIONAL = 0x04, + PFR_PHY_2BYTE_CHARCODE = 0x02, + PFR_PHY_VERTICAL = 0x01 + + } PFR_PhyFlags; + + /************************************************************************/ + + typedef enum PFR_GlyphFlags_ + { + PFR_GLYPH_IS_COMPOUND = 0x80, + PFR_GLYPH_EXTRA_ITEMS = 0x08, + PFR_GLYPH_1BYTE_XYCOUNT = 0x04, + PFR_GLYPH_XCOUNT = 0x02, + PFR_GLYPH_YCOUNT = 0x01 + + } PFR_GlyphFlags; + + /* controlled coordinate */ + typedef struct PFR_CoordRec_ + { + FT_UInt org; + FT_UInt cur; + + } PFR_CoordRec, *PFR_Coord; + + + typedef struct PFR_SubGlyphRec_ + { + FT_Fixed x_scale; + FT_Fixed y_scale; + FT_Int x_delta; + FT_Int y_delta; + FT_UInt32 gps_offset; + FT_UInt gps_size; + + } PFR_SubGlyphRec, *PFR_SubGlyph; + + + typedef enum PFR_SubgGlyphFlags_ + { + PFR_SUBGLYPH_3BYTE_OFFSET = 0x80, + PFR_SUBGLYPH_2BYTE_SIZE = 0x40, + PFR_SUBGLYPH_YSCALE = 0x20, + PFR_SUBGLYPH_XSCALE = 0x10 + + } PFR_SubGlyphFlags; + + + + typedef struct PFR_GlyphRec_ + { + FT_Byte format; + + FT_UInt num_x_control; + FT_UInt num_y_control; + FT_UInt max_xy_control; + FT_Pos* x_control; + FT_Pos* y_control; + + + FT_UInt num_subs; + FT_UInt max_subs; + PFR_SubGlyphRec* subs; + + FT_GlyphLoader loader; + FT_Bool path_begun; + + } PFR_GlyphRec, *PFR_Glyph; + + +FT_END_HEADER + +#endif /* __PFR_TYPES_H__ */ diff --git a/src/pfr/rules.mk b/src/pfr/rules.mk new file mode 100644 index 000000000..f79072f4d --- /dev/null +++ b/src/pfr/rules.mk @@ -0,0 +1,70 @@ +# +# FreeType 2 PFR driver configuration rules +# + + +# Copyright 1996-2002 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. + + +# Pfr driver directory +# +PFR_DIR := $(SRC_)pfr +PFR_DIR_ := $(PFR_DIR)$(SEP) + + +# compilation flags for the driver +# +PFR_COMPILE := $(FT_COMPILE) $I$(PFR_DIR) + + +# Pfr driver sources (i.e., C files) +# +PFR_DRV_SRC := $(PFR_DIR_)pfrload.c \ + $(PFR_DIR_)pfrgload.c \ + $(PFR_DIR_)pfrcmap.c \ + $(PFR_DIR_)pfrdrivr.c \ + $(PFR_DIR_)pfrobjs.c + +# Pfr driver headers +# +PFR_DRV_H := $(PFR_DRV_SRC:%.c=%.h) + + +# Pfr driver object(s) +# +# PFR_DRV_OBJ_M is used during `multi' builds +# PFR_DRV_OBJ_S is used during `single' builds +# +PFR_DRV_OBJ_M := $(PFR_DRV_SRC:$(PFR_DIR_)%.c=$(OBJ_)%.$O) +PFR_DRV_OBJ_S := $(OBJ_)pfr.$O + +# Pfr driver source file for single build +# +PFR_DRV_SRC_S := $(PFR_DIR_)pfr.c + + +# Pfr driver - single object +# +$(PFR_DRV_OBJ_S): $(PFR_DRV_SRC_S) $(PFR_DRV_SRC) $(FREETYPE_H) $(PFR_DRV_H) + $(PFR_COMPILE) $T$@ $(PFR_DRV_SRC_S) + + +# Pfr driver - multiple objects +# +$(OBJ_)%.$O: $(PFR_DIR_)%.c $(FREETYPE_H) $(PFR_DRV_H) + $(PFR_COMPILE) $T$@ $< + + +# update main driver object lists +# +DRV_OBJS_S += $(PFR_DRV_OBJ_S) +DRV_OBJS_M += $(PFR_DRV_OBJ_M) + +# EOF diff --git a/src/type1/t1gload.c b/src/type1/t1gload.c index ecaccb218..6bf71cfcf 100644 --- a/src/type1/t1gload.c +++ b/src/type1/t1gload.c @@ -141,7 +141,7 @@ FT_LOCAL_DEF( FT_Error ) T1_Load_Glyph( T1_GlyphSlot glyph, T1_Size size, - FT_Int glyph_index, + FT_UInt glyph_index, FT_Int load_flags ) { FT_Error error; diff --git a/src/type1/t1gload.h b/src/type1/t1gload.h index 9f79f5bcc..4b7ba5d62 100644 --- a/src/type1/t1gload.h +++ b/src/type1/t1gload.h @@ -34,7 +34,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) T1_Load_Glyph( T1_GlyphSlot glyph, T1_Size size, - FT_Int glyph_index, + FT_UInt glyph_index, FT_Int load_flags );