ref: 609e28c3be484792936271dacefe9b48c378e7eb
parent: f123ab6e5f1f7c912ac2102547ab2178305d8c1d
author: David Turner <[email protected]>
date: Fri Apr 19 11:13:47 EDT 2002
* 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.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2002-04-19 David Turner <[email protected]>
+
+ * 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 <[email protected]>
* src/base/ftobjs.c, builds/win32/ftdebug.c,
--- a/include/freetype/config/ftmodule.h
+++ b/include/freetype/config/ftmodule.h
@@ -10,5 +10,6 @@
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)
--- a/include/freetype/config/ftoption.h
+++ b/include/freetype/config/ftoption.h
@@ -375,7 +375,7 @@
/* 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
/*************************************************************************/
--- a/include/freetype/internal/ftmemory.h
+++ b/include/freetype/internal/ftmemory.h
@@ -178,6 +178,9 @@
#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)) )
/*************************************************************************/
/* */
--- a/include/freetype/internal/ftstream.h
+++ b/include/freetype/internal/ftstream.h
@@ -120,6 +120,8 @@
#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 @@
#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 }
--- a/include/freetype/internal/fttrace.h
+++ b/include/freetype/internal/fttrace.h
@@ -92,5 +92,7 @@
FT_TRACE_DEF( pcfdriver )
FT_TRACE_DEF( pcfread )
+/* PFR fonts component */
+FT_TRACE_DEF( pfr )
/* END */
--- a/src/Jamfile
+++ b/src/Jamfile
@@ -21,6 +21,7 @@
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 ;
--- /dev/null
+++ b/src/pfr/Jamfile
@@ -1,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
--- /dev/null
+++ b/src/pfr/descrip.mms
@@ -1,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
--- /dev/null
+++ b/src/pfr/module.mk
@@ -1,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
--- /dev/null
+++ b/src/pfr/pfr.c
@@ -1,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 <ft2build.h>
+
+#include "pfrload.c"
+#include "pfrgload.c"
+#include "pfrcmap.c"
+#include "pfrobjs.c"
+#include "pfrdrivr.c"
+
+/* END */
--- /dev/null
+++ b/src/pfr/pfrcmap.c
@@ -1,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
+ };
--- /dev/null
+++ b/src/pfr/pfrcmap.h
@@ -1,0 +1,23 @@
+#ifndef __PFR_CMAP_H__
+#define __PFR_CMAP_H__
+
+#include <ft2build.h>
+#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__ */
--- /dev/null
+++ b/src/pfr/pfrdrivr.c
@@ -1,0 +1,52 @@
+#include <ft2build.h>
+#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
+ };
+
+
+
--- /dev/null
+++ b/src/pfr/pfrdrivr.h
@@ -1,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 <ft2build.h>
+#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 */
--- /dev/null
+++ b/src/pfr/pfrgload.c
@@ -1,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 );
+ }
+
--- /dev/null
+++ b/src/pfr/pfrgload.h
@@ -1,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__ */
--- /dev/null
+++ b/src/pfr/pfrload.c
@@ -1,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;
+ }
+
+
--- /dev/null
+++ b/src/pfr/pfrload.h
@@ -1,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__ */
--- /dev/null
+++ b/src/pfr/pfrobjs.c
@@ -1,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;
+ }
--- /dev/null
+++ b/src/pfr/pfrobjs.h
@@ -1,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__ */
--- /dev/null
+++ b/src/pfr/pfrtypes.h
@@ -1,0 +1,289 @@
+#ifndef __PFR_TYPES_H__
+#define __PFR_TYPES_H__
+
+#include <ft2build.h>
+#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__ */
--- /dev/null
+++ b/src/pfr/rules.mk
@@ -1,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
--- 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;
--- a/src/type1/t1gload.h
+++ b/src/type1/t1gload.h
@@ -34,7 +34,7 @@
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 );