new version of the CFF driver, this one works :-)

This commit is contained in:
David Turner 2000-06-07 20:04:34 +00:00
parent e1d5dd78f4
commit 0f991b4312
10 changed files with 1815 additions and 1246 deletions

View File

@ -167,6 +167,11 @@
CFF_Top_Dict top_dict;
CFF_Private private_dict;
FT_UInt num_global_subrs;
FT_UInt num_local_subrs;
FT_Byte** global_subrs;
FT_Byte** local_subrs;
} CFF_Font;
#ifdef __cplusplus

View File

@ -45,5 +45,6 @@
#include <t2parse.c> /* token parser */
#include <t2load.c> /* tables loader */
#include <t2objs.c> /* object management */
#include <t2gload.c> /* glyph loader */
/* END */

View File

@ -288,19 +288,15 @@
if ( size )
{
/* these two object must have the same parent */
if ( size->face != slot->face )
if ( size->face != slot->root.face )
return FT_Err_Invalid_Face_Handle;
}
/* now load the glyph outline if necessary */
#if 1 /* XXXX: TODO */
error = FT_Err_Unimplemented_Feature;
#else
error = T2_Load_Glyph( size, slot, glyph_index, load_flags );
#endif
error = T2_Load_Glyph( slot, size, glyph_index, load_flags );
/* force drop-out mode to 2 - irrelevant now */
/* slot->outline.dropout_mode = 2; */
return error;
}
@ -382,7 +378,7 @@
sizeof ( T2_DriverRec ),
sizeof ( TT_FaceRec ),
sizeof ( FT_SizeRec ),
sizeof ( FT_GlyphSlotRec ),
sizeof ( T2_GlyphSlotRec ),
"cff", /* driver name */
100, /* driver version == 1.0 */

File diff suppressed because it is too large Load Diff

View File

@ -25,110 +25,160 @@
extern "C" {
#endif
typedef struct T2_Loader_
#define T2_MAX_OPERANDS 48
#define T2_MAX_SUBRS_CALLS 32
/*************************************************************************/
/* */
/* <Structure> T2_Builder */
/* */
/* <Description> */
/* a structure used during glyph loading to store its outline. */
/* */
/* <Fields> */
/* system :: current system object */
/* face :: current face object */
/* glyph :: current glyph slot */
/* */
/* current :: current glyph outline */
/* base :: base glyph outline */
/* */
/* max_points :: maximum points in builder outline */
/* max_contours :: maximum contours in builder outline */
/* */
/* last :: last point position */
/* */
/* scale_x :: horizontal scale ( FUnits to sub-pixels ) */
/* scale_y :: vertical scale ( FUnits to sub-pixels ) */
/* pos_x :: horizontal translation (composite glyphs) */
/* pos_y :: vertical translation (composite glyph) */
/* */
/* left_bearing :: left side bearing point */
/* advance :: horizontal advance vector */
/* */
/* path_begun :: flag, indicates that a new path has begun */
/* load_points :: flag, if not set, no points are loaded */
/* */
/* error :: an error code that is only used to report */
/* memory allocation problems.. */
/* */
/* metrics_only :: a boolean indicating that we only want to */
/* compute the metrics of a given glyph, not load */
/* all of its points.. */
/* */
typedef struct T2_Builder_
{
T2_Face face;
T2_Size size;
T2_GlyphSlot glyph;
FT_Memory memory;
TT_Face face;
T2_GlyphSlot glyph;
FT_ULong load_flags;
FT_UInt glyph_index;
FT_Outline current; /* the current glyph outline */
FT_Outline base; /* the composite glyph outline */
FT_Stream stream;
FT_Int byte_len;
FT_Int left_points;
FT_Int left_contours;
FT_Int max_points; /* capacity of base outline in points */
FT_Int max_contours; /* capacity of base outline in contours */
FT_BBox bbox;
FT_Int left_bearing;
FT_Int advance;
FT_Bool preserve_pps;
FT_Vector pp1;
FT_Vector pp2;
FT_Vector last;
FT_ULong glyf_offset;
FT_Fixed scale_x;
FT_Fixed scale_y;
/* the zone where we load our glyphs */
FT_GlyphZone base;
FT_GlyphZone zone;
FT_Pos pos_x;
FT_Pos pos_y;
FT_Vector left_bearing;
FT_Vector advance;
FT_BBox bbox; /* bounding box */
FT_Bool path_begun;
FT_Bool load_points;
FT_Bool no_recurse;
FT_Error error; /* only used for memory errors */
FT_Bool metrics_only;
} T2_Builder;
/* execution context charstring zone */
typedef struct T2_Decoder_Zone_
{
FT_Byte* base;
FT_Byte* limit;
FT_Byte* cursor;
} T2_Decoder_Zone;
typedef struct T2_Decoder_
{
T2_Builder builder;
CFF_Font* cff;
FT_Fixed stack[ T2_MAX_OPERANDS+1 ];
FT_Fixed* top;
T2_Decoder_Zone zones[ T2_MAX_SUBRS_CALLS+1 ];
T2_Decoder_Zone* zone;
FT_Int flex_state;
FT_Int num_flex_vectors;
FT_Vector flex_vectors[7];
FT_Pos glyph_width;
FT_Pos nominal_width;
FT_Bool read_width;
FT_Int num_hints;
FT_Fixed* buildchar;
FT_Int len_buildchar;
FT_UInt num_locals;
FT_UInt num_globals;
FT_Int locals_bias;
FT_Int globals_bias;
FT_Byte** locals;
FT_Byte** globals;
} T2_Decoder;
} T2_Loader;
#if 0
/*************************************************************************/
/* */
/* <Function> */
/* T2_Get_Metrics */
/* */
/* <Description> */
/* Returns the horizontal or vertical metrics in font units for a */
/* given glyph. The metrics are the left side bearing (resp. top */
/* side bearing) and advance width (resp. advance height). */
/* */
/* <Input> */
/* header :: A pointer to either the horizontal or vertical metrics */
/* structure. */
/* */
/* index :: The glyph index. */
/* */
/* <Output> */
/* bearing :: The bearing, either left side or top side. */
/* */
/* advance :: The advance width resp. advance height. */
/* */
/* <Note> */
/* This function will much probably move to another component in the */
/* near future, but I haven't decided which yet. */
/* */
LOCAL_DEF
void T2_Get_Metrics( TT_HoriHeader* header,
FT_UInt index,
FT_Short* bearing,
FT_UShort* advance );
void T2_Init_Decoder( T2_Decoder* decoder,
TT_Face face,
T2_Size size,
T2_GlyphSlot slot );
/*************************************************************************/
/* */
/* <Function> */
/* T2_Load_Glyph */
/* */
/* <Description> */
/* A function used to load a single glyph within a given glyph slot, */
/* for a given size. */
/* */
/* <Input> */
/* glyph :: A handle to a target slot object where the glyph */
/* will be loaded. */
/* */
/* size :: A handle to the source face size at which the glyph */
/* must be scaled/loaded. */
/* */
/* glyph_index :: The index of the glyph in the font file. */
/* */
/* load_flags :: A flag indicating what to load for this glyph. The */
/* FT_LOAD_XXX constants can be used to control the */
/* glyph loading process (e.g., whether the outline */
/* should be scaled, whether to load bitmaps or not, */
/* whether to hint the outline, etc). */
/* <Output> */
/* result :: A set of bit flags indicating the type of data that */
/* was loaded in the glyph slot (outline or bitmap, */
/* etc). */
/* */
/* You can set this field to 0 if you don't want this */
/* information. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
#if 0 /* unused until we support pure CFF fonts */
/* Compute the maximum advance width of a font through quick parsing */
LOCAL_DEF
FT_Error T2_Load_Glyph( T2_Size size,
T2_GlyphSlot glyph,
FT_UShort glyph_index,
FT_UInt load_flags );
FT_Error T2_Compute_Max_Advance( TT_Face face,
FT_Int *max_advance );
#endif
/* This function is exported, because it is used by the T1Dump utility */
LOCAL_DEF
FT_Error T2_Parse_CharStrings( T2_Decoder* decoder,
FT_Byte* charstring_base,
FT_Int charstring_len );
LOCAL_DEF
FT_Error T2_Load_Glyph( T2_GlyphSlot glyph,
T2_Size size,
FT_Int glyph_index,
FT_Int load_flags );
#ifdef __cplusplus
}
#endif

View File

@ -25,7 +25,7 @@
#include <freetype/tttags.h>
#include <t2load.h>
#include <t2parse.h>
#include <freetype/internal/t2errors.h>
#include <t2errors.h>
#undef FT_COMPONENT
#define FT_COMPONENT trace_ttload
@ -53,6 +53,7 @@
FT_UShort count;
MEM_Set( index, 0, sizeof(*index) );
index->stream = stream;
if ( !READ_UShort( count ) &&
count > 0 )
{
@ -127,7 +128,36 @@
static
FT_Error t2_access_element( CFF_Index* index,
FT_Error t2_explicit_cff_index( CFF_Index* index,
FT_Byte** *table )
{
FT_Error error = 0;
FT_Memory memory = index->stream->memory;
FT_UInt n, offset, old_offset;
FT_Byte** t;
*table = 0;
if ( index->count > 0 && !ALLOC_ARRAY( t, index->count+1, FT_Byte* ) )
{
old_offset = 1;
for ( n = 0; n <= index->count; n++ )
{
offset = index->offsets[n];
if (!offset)
offset = old_offset;
t[n] = index->bytes + offset - 1;
old_offset = offset;
}
*table = t;
}
return error;
}
LOCAL_FUNC
FT_Error T2_Access_Element( CFF_Index* index,
FT_UInt element,
FT_Byte* *pbytes,
FT_ULong *pbyte_len )
@ -187,8 +217,8 @@
}
static
void t2_forget_element( CFF_Index* index,
LOCAL_FUNC
void T2_Forget_Element( CFF_Index* index,
FT_Byte* *pbytes )
{
if (index->bytes == 0)
@ -199,8 +229,8 @@
}
static
FT_String* t2_get_name( CFF_Index* index,
LOCAL_FUNC
FT_String* T2_Get_Name( CFF_Index* index,
FT_UInt element )
{
FT_Memory memory = index->stream->memory;
@ -209,7 +239,7 @@
FT_Error error;
FT_String* name = 0;
error = t2_access_element( index, element, &bytes, &byte_len );
error = T2_Access_Element( index, element, &bytes, &byte_len );
if (error) goto Exit;
if ( !ALLOC( name, byte_len+1 ) )
@ -217,14 +247,14 @@
MEM_Copy( name, bytes, byte_len );
name[byte_len] = 0;
}
t2_forget_element( index, &bytes );
T2_Forget_Element( index, &bytes );
Exit:
return name;
}
#if 0
#if 0 /* unused until we fully support pure-CFF fonts */
LOCAL_FUNC
FT_String* T2_Get_String( CFF_Index* index,
FT_UInt sid,
@ -232,7 +262,7 @@
{
/* if it's not a standard string, return it */
if ( sid > 390 )
return t2_get_name( index, sid - 390 );
return T2_Get_Name( index, sid - 390 );
/* that's a standard string, fetch a copy from the psnamed module */
{
@ -318,20 +348,39 @@
FT_Byte* dict;
FT_ULong dict_len;
CFF_Index* index = &font->top_dict_index;
CFF_Top_Dict* top = &font->top_dict;
/* parse the top-level font dictionary */
T2_Parser_Init( &parser, T2CODE_TOPDICT, &font->top_dict );
/* set defaults */
memset( top, 0, sizeof(*top) );
top->underline_position = -100;
top->underline_thickness = 50;
top->charstring_type = 2;
top->font_matrix.xx = 0x10000;
top->font_matrix.yy = 0x10000;
top->cid_count = 8720;
error = t2_access_element( index, face_index, &dict, &dict_len ) ||
error = T2_Access_Element( index, face_index, &dict, &dict_len ) ||
T2_Parser_Run( &parser, dict, dict + dict_len );
t2_forget_element( &font->top_dict_index, &dict );
T2_Forget_Element( &font->top_dict_index, &dict );
if (error) goto Exit;
/* parse the private dictionary, if any */
if (font->top_dict.private_offset && font->top_dict.private_size)
{
T2_Parser_Init( &parser, T2CODE_PRIVATE, &font->private_dict );
CFF_Private* priv = &font->private_dict;
/* set defaults */
priv->blue_shift = 7;
priv->blue_fuzz = 1;
priv->lenIV = -1;
priv->expansion_factor = (FT_Fixed)0.06*0x10000;
priv->blue_scale = (FT_Fixed)0.039625*0x10000;
T2_Parser_Init( &parser, T2CODE_PRIVATE, priv );
if ( FILE_Seek( base_offset + font->top_dict.private_offset ) ||
ACCESS_Frame( font->top_dict.private_size ) )
@ -357,10 +406,28 @@
error = t2_new_cff_index( &font->charstrings_index, stream, 0 );
if (error) goto Exit;
/* read the local subrs */
if ( FILE_Seek( base_offset + font->top_dict.private_offset +
font->private_dict.local_subrs_offset ) )
goto Exit;
error = t2_new_cff_index( &font->local_subrs_index, stream, 1 );
if (error) goto Exit;
/* explicit the global and local subrs */
font->num_local_subrs = font->local_subrs_index.count;
font->num_global_subrs = font->global_subrs_index.count;
error = t2_explicit_cff_index( &font->global_subrs_index,
&font->global_subrs ) ||
t2_explicit_cff_index( &font->local_subrs_index,
&font->local_subrs );
if (error) goto Exit;
}
/* get the font name */
font->font_name = t2_get_name( &font->name_index, face_index );
font->font_name = T2_Get_Name( &font->name_index, face_index );
Exit:
return error;
@ -369,11 +436,17 @@
LOCAL_FUNC
void T2_Done_CFF_Font( CFF_Font* font )
{
FT_Memory memory = font->memory;
t2_done_cff_index( &font->global_subrs_index );
t2_done_cff_index( &font->string_index );
t2_done_cff_index( &font->top_dict_index );
t2_done_cff_index( &font->name_index );
t2_done_cff_index( &font->charstrings_index );
FREE( font->local_subrs );
FREE( font->global_subrs );
FREE( font->font_name );
}

View File

@ -25,6 +25,28 @@
extern "C" {
#endif
LOCAL_FUNC
FT_String* T2_Get_Name( CFF_Index* index,
FT_UInt element );
#if 0 /* will be used later for pure-CFF font support */
LOCAL_DEF
FT_String* T2_Get_String( CFF_Index* index,
FT_UInt sid,
PSNames_Interface* interface );
#endif
LOCAL_DEF
FT_Error T2_Access_Element( CFF_Index* index,
FT_UInt element,
FT_Byte* *pbytes,
FT_ULong *pbyte_len );
LOCAL_DEF
void T2_Forget_Element( CFF_Index* index,
FT_Byte* *pbytes );
#ifdef __cplusplus
}
#endif

View File

@ -104,12 +104,19 @@
{
CFF_Font* cff;
FT_Memory memory = face->root.memory;
FT_Face root;
if ( ALLOC( cff, sizeof(*cff) ) )
goto Exit;
face->other = cff;
error = T2_Load_CFF_Font( stream, face_index, cff );
if (error) goto Exit;
/* complement the root flags with some interesting information */
/* note that for OpenType/CFF, there is no need to do this, but */
/* this will be necessary for pure CFF fonts through.. */
root = &face->root;
}
Exit:
@ -258,17 +265,13 @@
LOCAL_FUNC
FT_Error T2_Init_GlyphSlot( T2_GlyphSlot slot )
{
/* allocate the outline space */
FT_Face face = slot->face;
FT_Library library = face->driver->library;
FT_Library library = slot->root.face->driver->library;
FT_TRACE4(( "TT.Init_GlyphSlot: Creating outline maxp = %d, maxc = %d\n",
face->max_points, face->max_contours ));
slot->max_points = 0;
slot->max_contours = 0;
slot->root.bitmap.buffer = 0;
return FT_Outline_New( library,
face->max_points + 2,
face->max_contours,
&slot->outline );
return FT_Outline_New( library, 0, 0, &slot->root.outline );
}
@ -286,13 +289,13 @@
LOCAL_FUNC
void T2_Done_GlyphSlot( T2_GlyphSlot slot )
{
FT_Library library = slot->face->driver->library;
FT_Library library = slot->root.face->driver->library;
FT_Memory memory = library->memory;
if (slot->flags & ft_glyph_own_bitmap)
FREE( slot->bitmap.buffer );
if (slot->root.flags & ft_glyph_own_bitmap)
FREE( slot->root.bitmap.buffer );
FT_Outline_Done( library, &slot->outline );
FT_Outline_Done( library, &slot->root.outline );
return;
}

View File

@ -65,7 +65,21 @@
/* This is a direct typedef of FT_GlyphSlot, as there is nothing */
/* specific about the OpenType glyph slot. */
/* */
typedef FT_GlyphSlot T2_GlyphSlot;
typedef struct T2_GlyphSlotRec_
{
FT_GlyphSlotRec root;
FT_Bool hint;
FT_Bool scaled;
FT_Int max_points;
FT_Int max_contours;
FT_Fixed x_scale;
FT_Fixed y_scale;
} T2_GlyphSlotRec, *T2_GlyphSlot;

View File

@ -64,7 +64,7 @@
if (v == 28)
{
if ( p+2 > limit ) goto Bad;
val = ((FT_Long)p[0] << 8) | p[1];
val = (FT_Short)(((FT_Int)p[0] << 8) | p[1]);
p += 2;
}
else if (v == 29)
@ -261,10 +261,10 @@
error = T2_Err_Stack_Underflow;
if (parser->top >= parser->stack + 4)
{
bbox->xMin = t2_parse_fixed( data++ );
bbox->yMin = t2_parse_fixed( data++ );
bbox->xMax = t2_parse_fixed( data++ );
bbox->yMax = t2_parse_fixed( data );
bbox->xMin = t2_parse_num( data++ );
bbox->yMin = t2_parse_num( data++ );
bbox->xMax = t2_parse_num( data++ );
bbox->yMax = t2_parse_num( data );
error = 0;
}
return error;
@ -281,8 +281,8 @@
error = T2_Err_Stack_Underflow;
if (parser->top >= parser->stack + 2)
{
dict->private_offset = t2_parse_num( data++ );
dict->private_size = t2_parse_num( data );
dict->private_size = t2_parse_num( data++ );
dict->private_offset = t2_parse_num( data );
error = 0;
}
return error;
@ -319,7 +319,7 @@
#define T2_REF(s,f) (((s*)0)->f)
#define T2_FIELD_CALLBACK( code, name ) \
{ t2_kind_callback, code, 0, 0, parse_ ## name, 0, 0 },
{ t2_kind_callback, code | T2CODE, 0, 0, parse_ ## name, 0, 0 },
#undef T2_FIELD
#define T2_FIELD( code, name, kind ) \
@ -363,7 +363,7 @@
while (p < limit)
{
FT_Byte v = *p;
if ( v >= 27 || v != 31 )
if ( v >= 27 && v != 31 )
{
/* its a number, we'll push its position on the stack */
if (parser->top - parser->stack >= T2_MAX_STACK_DEPTH)
@ -404,6 +404,7 @@
/* first of all, a trivial check */
if ( num_args < 1 ) goto Stack_Underflow;
*parser->top = p;
code = v;
if (v == 12)
{
@ -476,16 +477,14 @@
error = field->reader( parser );
if (error) goto Exit;
}
/* clear stack */
parser->top = parser->stack;
goto Found;
}
goto Found; /* exit loop */
}
/* this is an unknown operator, or it is unsupported, we will ignore */
/* it for now... */
Found:
Found:
/* clear stack */
parser->top = parser->stack;
}