ref: 0dd343480186b918e3b7ef71b9d4bb8260f48cea
parent: 8f43c714a5a74c63c2a6242392790510ac487f80
author: David Turner <[email protected]>
date: Wed Feb 2 07:20:53 EST 2000
The Type 1 experimental driver was updated - small reduction of the code size of "t1encode.c" - removed the hinter (not useful with the upcoming auto-hinter..) - updated "t1load.c" to reduce warnings with Visual C++ - considerably changed the glyph loader (it is simpler) Beware, this code is still experimental, and is _not_ debugged. I don't even guarantee that it works for now - David
--- a/src/type1z/rules.mk
+++ b/src/type1z/rules.mk
@@ -106,13 +106,10 @@
# Type1 driver sources (i.e., C files)
#
T1Z_DRV_SRC := $(T1Z_DIR_)t1parse.c \
- $(T1Z_DIR_)t1load.c
-# $(T1Z_DIR_)t1parse.c \
-# $(T1Z_DIR_)t1tokens.c \
-# $(T1Z_DIR_)t1driver.c \
-# $(T1Z_DIR_)t1encode.c \
-# $(T1Z_DIR_)t1hinter.c \
-# $(T1Z_DIR_)t1gload.c
+ $(T1Z_DIR_)t1load.c \
+ $(T1Z_DIR_)t1driver.c \
+ $(T1Z_DIR_)t1encode.c \
+ $(T1Z_DIR_)t1gload.c
# Type1 driver headers
--- a/src/type1z/t1encode.c
+++ b/src/type1z/t1encode.c
@@ -184,7 +184,7 @@
/* */
/* t1_standard_encoding[33] == 2 */
/* */
- /* which means that the glyph name for character code 32 is */
+ /* which means that the glyph name for character code 33 is */
/* */
/* t1_standard_strings[2] == "exclam" */
/* */
@@ -191,7 +191,7 @@
/* (this correspond to the exclamation mark `!'). */
/* */
LOCAL_FUNC
- T1_Short t1_standard_encoding[256] =
+ T1_Byte t1_standard_encoding[256] =
{
/* 0 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -240,7 +240,7 @@
/* */
/* t1_expert_encoding[33] == 229 */
/* */
- /* which means that the glyph name for character code 32 is */
+ /* which means that the glyph name for character code 33 is */
/* */
/* t1_standard_strings[229] == "exclamsmall" */
/* */
@@ -280,53 +280,5 @@
/* 250 */
373, 374, 375, 376, 377, 378
};
-
-
- /*************************************************************************/
- /* */
- /* t1_expert_subset_encoding: */
- /* */
- /* A simple table used to encode the Adobe ExpertEncoding subset */
- /* defined in the CFF specification. It will probably evolve into */
- /* another form sooner or later, as we deal with charsets */
- /* differently than with encodings. */
- /* */
- LOCAL_FUNC
- FT_Short t1_expert_subset_encoding[256] =
- {
- /* 0 */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 0, 0, 0, 231, 232, 0, 0,
- 235, 236, 237, 238, 13, 14, 15, 99, 239, 240,
- /* 50 */
- 241, 242, 243, 244, 245, 246, 247, 248, 27, 28,
- 249, 250, 251, 252, 0, 253, 254, 255, 256, 257,
- 0, 0, 0, 258, 0, 0, 259, 260, 261, 262,
- 0, 0, 263, 264, 265, 0, 266, 109, 110, 267,
- 268, 269, 0, 270, 0, 272, 0, 0, 0, 0,
- /* 100 */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 300, 301, 302, 303, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- /* 150 */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 304, 305, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 314, 315,
- 0, 0, 0, 0, 0, 0, 0, 0, 158, 155,
- 163, 0, 320, 321, 322, 323, 324, 325, 0, 0,
- /* 200 */
- 326, 150, 164, 169, 327, 328, 329, 330, 331, 332,
- 333, 334, 335, 336, 337, 338, 339, 340, 341, 342,
- 343, 344, 345, 346, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- /* 250 */
- 0, 0, 0, 0, 0, 0
- };
-
/* END */
--- a/src/type1z/t1encode.h
+++ b/src/type1z/t1encode.h
@@ -56,7 +56,7 @@
/* (this correspond to the exclamation mark `!'). */
/* */
LOCAL_DEF
- T1_Short t1_standard_encoding[256];
+ T1_Byte t1_standard_encoding[256];
/*************************************************************************/
@@ -79,17 +79,6 @@
T1_Short t1_expert_encoding[256];
- /*************************************************************************/
- /* */
- /* t1_expert_subset_encoding: */
- /* */
- /* A simple table used to encode the Adobe ExpertEncoding subset */
- /* defined in the CFF specification. It will probably evolve into */
- /* another form sooner or later, as we deal with charsets */
- /* differently than with encodings. */
- /* */
- LOCAL_DEF
- T1_Short t1_expert_subset_encoding[256];
#endif /* T1ENCODE_H */
--- a/src/type1z/t1gload.c
+++ b/src/type1z/t1gload.c
@@ -20,10 +20,6 @@
#include <t1encode.h>
#include <ftstream.h>
-#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
-#include <t1hinter.h>
-#endif
-
/**********************************************************************/
/**********************************************************************/
/**********************************************************************/
@@ -49,23 +45,19 @@
* face :: current face object
* size :: current size object
* glyph :: current glyph object
- * funcs :: glyph builder functions (or "methods").
*
*********************************************************************/
- EXPORT_FUNC
- void T1_Init_Builder( T1_Builder* builder,
- T1_Face face,
- T1_Size size,
- T1_GlyphSlot glyph,
- const T1_Builder_Funcs* funcs )
+ LOCAL_FUNC
+ void T1_Init_Builder( T1_Builder* builder,
+ T1_Face face,
+ T1_Size size,
+ T1_GlyphSlot glyph )
{
- builder->funcs = *funcs;
builder->path_begun = 0;
builder->load_points = 1;
builder->face = face;
- builder->size = size;
builder->glyph = glyph;
builder->memory = face->root.memory;
@@ -93,9 +85,6 @@
builder->base.n_points = 0;
builder->base.n_contours = 0;
builder->current = builder->base;
-
- builder->pass = 0;
- builder->hint_point = 0;
}
@@ -114,7 +103,7 @@
*
*********************************************************************/
- EXPORT_FUNC
+ LOCAL_FUNC
void T1_Done_Builder( T1_Builder* builder )
{
T1_GlyphSlot glyph = builder->glyph;
@@ -144,13 +133,10 @@
*********************************************************************/
EXPORT_FUNC
- void T1_Init_Decoder( T1_Decoder* decoder,
- const T1_Hinter_Funcs* funcs )
+ void T1_Init_Decoder( T1_Decoder* decoder )
{
- decoder->hinter = *funcs; /* copy hinter interface */
- decoder->top = 0;
- decoder->zone = 0;
-
+ decoder->top = 0;
+ decoder->zone = 0;
decoder->flex_state = 0;
decoder->num_flex_vectors = 0;
@@ -159,6 +145,150 @@
}
+ /* check that there is enough room for "count" more points */
+ static
+ T1_Error check_points( T1_Builder* builder,
+ T1_Int count )
+ {
+ FT_Outline* base = &builder->base;
+ FT_Outline* outline = &builder->current;
+
+ if (!builder->load_points)
+ return T1_Err_Ok;
+
+ count += base->n_points + outline->n_points;
+
+ /* realloc points table if necessary */
+ if ( count >= builder->max_points )
+ {
+ T1_Error error;
+ FT_Memory memory = builder->memory;
+ T1_Int increment = outline->points - base->points;
+ T1_Int current = builder->max_points;
+
+ while ( builder->max_points < count )
+ builder->max_points += 8;
+
+ if ( REALLOC_ARRAY( base->points, current,
+ builder->max_points, T1_Vector ) ||
+
+ REALLOC_ARRAY( base->flags, current,
+ builder->max_points, T1_Byte ) )
+ {
+ builder->error = error;
+ return error;
+ }
+
+ outline->points = base->points + increment;
+ outline->flags = base->flags + increment;
+ }
+ return T1_Err_Ok;
+ }
+
+
+ /* add a new point, do not check room */
+ static
+ void add_point( T1_Builder* builder,
+ FT_Pos x,
+ FT_Pos y,
+ FT_Byte flag )
+ {
+ FT_Outline* outline = &builder->current;
+
+ if (builder->load_points)
+ {
+ FT_Vector* point = outline->points + outline->n_points;
+ FT_Byte* control = (FT_Byte*)outline->flags + outline->n_points;
+
+ point->x = x;
+ point->y = y;
+ *control = ( flag ? FT_Curve_Tag_On : FT_Curve_Tag_Cubic );
+
+ builder->last = *point;
+ }
+
+ outline->n_points++;
+ }
+
+
+ /* check room for a new on-curve point, then add it */
+ static
+ T1_Error add_point1( T1_Builder* builder,
+ FT_Pos x,
+ FT_Pos y )
+ {
+ T1_Error error;
+
+ error = check_points(builder,1);
+ if (!error)
+ add_point( builder, x, y, 1 );
+
+ return error;
+ }
+
+
+ /* check room for a new contour, then add it */
+ static
+ T1_Error add_contour( T1_Builder* builder )
+ {
+ FT_Outline* base = &builder->base;
+ FT_Outline* outline = &builder->current;
+
+ if (!builder->load_points)
+ {
+ outline->n_contours++;
+ return T1_Err_Ok;
+ }
+
+ /* realloc contours array if necessary */
+ if ( base->n_contours + outline->n_contours >= builder->max_contours &&
+ builder->load_points )
+ {
+ T1_Error error;
+ FT_Memory memory = builder->memory;
+ T1_Int increment = outline->contours - base->contours;
+ T1_Int current = builder->max_contours;
+
+ builder->max_contours += 4;
+
+ if ( REALLOC_ARRAY( base->contours,
+ current, builder->max_contours, T1_Short ) )
+ {
+ builder->error = error;
+ return error;
+ }
+
+ outline->contours = base->contours + increment;
+ }
+
+ if (outline->n_contours > 0)
+ outline->contours[ outline->n_contours-1 ] = outline->n_points-1;
+
+ return T1_Err_Ok;
+ }
+
+
+ /* if a path was begun, add its first on-curve point */
+ static
+ T1_Error start_point( T1_Builder* builder,
+ T1_Pos x,
+ T1_Pos y )
+ {
+ return builder->path_begun && add_point1( builder, x, y );
+ }
+
+
+ /* close the current contour */
+ static
+ void close_contour( T1_Builder* builder )
+ {
+ FT_Outline* outline = &builder->current;
+
+ if ( outline->n_contours > 0 )
+ outline->contours[outline->n_contours-1] = outline->n_points-1;
+ }
+
+
/*********************************************************************
*
* <Function>
@@ -195,7 +325,7 @@
{
T1_String* name = (T1_String*)face->type1.glyph_names[n];
- if ( name && strcmp(name,glyph_name) == 0 )
+ if ( name && name[0] == glyph_name[0] && strcmp(name,glyph_name) == 0 )
return n;
}
@@ -203,6 +333,7 @@
}
+
/*********************************************************************
*
* <Function>
@@ -293,6 +424,7 @@
if (error) return error;
/* adjust contours in accented character outline */
+ if (decoder->builder.load_points)
{
T1_Int n;
@@ -306,76 +438,14 @@
decoder->builder.advance = advance;
/* Finally, move the accent */
- FT_Translate_Outline( cur, adx - asb, ady );
+ if (decoder->builder.load_points)
+ FT_Translate_Outline( cur, adx - asb, ady );
(void)asb; /* ignore this parameter */
return T1_Err_Ok;
}
-/*********************************************************************
- *
- * <Function>
- * t1operator_flex
- *
- * <Description>
- * Implements the "flex" Type 1 operator for a Type 1 decoder
- *
- * <Input>
- * decoder :: current Type 1 decoder
- * threshold :: threshold
- * end_x :: position of final flex point
- * end_y :: position of final flex point
- *
- * <Return>
- * Error code. 0 means success.
- *
- *********************************************************************/
- static
- T1_Error t1operator_flex( T1_Decoder* decoder,
- T1_Pos threshold,
- T1_Pos end_x,
- T1_Pos end_y )
- {
- T1_Vector vec;
- T1_Vector* flex = decoder->flex_vectors;
- T1_Int n;
-
- /* we don't even try to test the threshold in the non-hinting */
- /* builder, even if the flex operator is said to be a path */
- /* construction statement in the specification. This is better */
- /* left to the hinter.. */
-
- flex = decoder->flex_vectors;
- vec = *flex++;
-
- for ( n = 0; n < 6; n++ )
- {
- flex->x += vec.x;
- flex->y += vec.y;
-
- vec = *flex++;
- }
-
-
- (void)threshold;
- (void)end_x;
- (void)end_y;
-
- flex = decoder->flex_vectors;
-
- return decoder->builder.funcs.rcurve_to( &decoder->builder,
- flex[0].x, flex[0].y,
- flex[1].x, flex[1].y,
- flex[2].x, flex[2].y ) ||
-
- decoder->builder.funcs.rcurve_to( &decoder->builder,
- flex[3].x, flex[3].y,
- flex[4].x, flex[4].y,
- flex[5].x, flex[5].y );
- }
-
-
/*********************************************************************
*
* <Function>
@@ -397,6 +467,8 @@
*
*********************************************************************/
+#define USE_ARGS(n) top -= n; if (top < decoder->stack) goto Stack_Underflow
+
EXPORT_FUNC
T1_Error T1_Parse_CharStrings( T1_Decoder* decoder,
T1_Byte* charstring_base,
@@ -410,39 +482,9 @@
T1_Byte* ip;
T1_Byte* limit;
T1_Builder* builder = &decoder->builder;
- T1_Builder_Funcs* builds = &builder->funcs;
- T1_Hinter_Funcs* hints = &decoder->hinter;
+ FT_Outline* outline;
+ T1_Pos x, y;
- static const T1_Int args_count[ op_max ] =
- {
- 0, /* none */
- 0, /* endchar */
- 2, /* hsbw */
- 5, /* seac */
- 4, /* sbw */
- 0, /* closepath */
- 1, /* hlineto */
- 1, /* hmoveto */
- 4, /* hvcurveto */
- 2, /* rlineto */
- 2, /* rmoveto */
- 6, /* rrcurveto */
- 4, /* vhcurveto */
- 1, /* vlineto */
- 1, /* vmoveto */
- 0, /* dotsection */
- 2, /* hstem */
- 6, /* hstem3 */
- 2, /* vstem */
- 6, /* vstem3 */
- 2, /* div */
- -1, /* callothersubr */
- 1, /* callsubr */
- 0, /* pop */
- 0, /* return */
- 2 /* setcurrentpoint */
- };
-
/* First of all, initialise the decoder */
decoder->top = decoder->stack;
decoder->zone = decoder->zones;
@@ -454,416 +496,445 @@
limit = zone->limit = charstring_base + charstring_len;
ip = zone->cursor = zone->base;
- error = T1_Err_Ok;
+ error = T1_Err_Ok;
+ outline = &builder->current;
+
+ x = builder->pos_x;
+ y = builder->pos_y;
/* now, execute loop */
while ( ip < limit )
{
T1_Int* top = decoder->top;
- T1_Operator op = op_none;
- T1_Long value = 0;
/* First of all, decompress operator or value */
switch (*ip++)
{
- case 1: op = op_hstem; break;
+ case 1: /* hstem */
+ case 3: /* vstem */
+ {
+ Clear_Stack:
+ top = decoder->stack;
+ break;
+ }
- case 3: op = op_vstem; break;
- case 4: op = op_vmoveto; break;
- case 5: op = op_rlineto; break;
- case 6: op = op_hlineto; break;
- case 7: op = op_vlineto; break;
- case 8: op = op_rrcurveto; break;
- case 9: op = op_closepath; break;
- case 10: op = op_callsubr; break;
- case 11: op = op_return; break;
+ case 4: /* vmoveto */
+ {
+ USE_ARGS(1);
+ y += top[0];
+ builder->path_begun = 1;
+ goto Clear_Stack;
+ }
+
+ case 5: /* rlineto */
+ {
+ if ( start_point( builder, x, y ) ) goto Memory_Error;
+
+ USE_ARGS(2);
+ x += top[0];
+ y += top[1];
+ Add_Line:
+ if (add_point1( builder, top[0], top[1] )) goto Memory_Error;
+ goto Clear_Stack;
+ }
+
+ case 6: /* hlineto */
+ {
+ if ( start_point( builder, x, y ) ) goto Memory_Error;
+
+ USE_ARGS(1);
+ x += top[0];
+ goto Add_Line;
+ }
+
+ case 7: /* vlineto */
+ {
+ if ( start_point( builder, x, y ) ) goto Memory_Error;
+
+ USE_ARGS(1);
+ y += top[0];
+ goto Add_Line;
+ }
+
+ case 8: /* rrcurveto */
+ {
+ if ( start_point( builder, x, y ) ||
+ check_points( builder, 3 ) ) goto Memory_Error;
+
+ USE_ARGS(6);
+ x += top[0];
+ y += top[1];
+ add_point( builder, x, y, 0 );
+
+ x += top[2];
+ y += top[3];
+ add_point( builder, x, y, 0 );
- case 13: op = op_hsbw; break;
- case 14: op = op_endchar; break;
-
- case 21: op = op_rmoveto; break;
- case 22: op = op_hmoveto; break;
-
- case 30: op = op_vhcurveto; break;
- case 31: op = op_hvcurveto; break;
-
- case 12:
+ x += top[4];
+ y += top[5];
+ add_point( builder, x, y, 1 );
+ goto Clear_Stack;
+ }
+
+ case 9: /* closepath */
{
- if (ip > limit)
+ close_contour( builder );
+ builder->path_begun = 0;
+ }
+ break;
+
+ case 10: /* callsubr */
+ {
+ T1_Int index;
+
+ USE_ARGS(1);
+
+ index = top[0];
+ if ( index < 0 || index >= num_subrs )
{
- FT_ERROR(( "T1.Parse_CharStrings : invalid escape (12+EOF)\n" ));
+ FT_ERROR(( "T1.Parse_CharStrings : invalid subrs index\n" ));
goto Syntax_Error;
}
- switch (*ip++)
+ if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS )
{
- case 0: op = op_dotsection; break;
- case 1: op = op_vstem3; break;
- case 2: op = op_hstem3; break;
- case 6: op = op_seac; break;
- case 7: op = op_sbw; break;
- case 12: op = op_div; break;
- case 16: op = op_callothersubr; break;
- case 17: op = op_pop; break;
- case 33: op = op_setcurrentpoint; break;
+ FT_ERROR(( "T1.Parse_CharStrings : too many nested subrs\n" ));
+ goto Syntax_Error;
+ }
- default:
- FT_ERROR(( "T1.Parse_CharStrings : invalid escape (12+%d)\n",
- ip[-1] ));
- goto Syntax_Error;
+ zone->cursor = ip; /* save current instruction pointer */
+
+ zone++;
+ zone->base = subrs_base[index];
+ zone->limit = zone->base + subrs_len[index];
+ zone->cursor = zone->base;
+
+ if (!zone->base)
+ {
+ FT_ERROR(( "T1.Parse_CharStrings : invoking empty subrs !!\n" ));
+ goto Syntax_Error;
}
+
+ decoder->zone = zone;
+ ip = zone->base;
+ limit = zone->limit;
+
+ /* do not clear stack */
}
break;
-
- case 255: /* four bytes integer */
+
+ case 11: /* return */
{
- if (ip+4 > limit)
+ if ( zone <= decoder->zones )
{
- FT_ERROR(( "T1.Parse_CharStrings : unexpected EOF in integer\n" ));
+ FT_ERROR(( "T1.Parse_CharStrings : unexpected return\n" ));
goto Syntax_Error;
}
- value = ((long)ip[0] << 24) |
- ((long)ip[1] << 16) |
- ((long)ip[2] << 8) |
- ip[3];
- ip += 4;
+ zone--;
+ ip = zone->cursor;
+ limit = zone->limit;
+ decoder->zone = zone;
}
break;
+
+ case 13: /* hsbw */
+ {
+ USE_ARGS(2);
+ builder->left_bearing.x += top[0];
+ builder->advance.x = top[1];
+ builder->advance.y = 0;
+
+ builder->last.x = x = top[0];
+ builder->last.y = y = 0;
+
+ /* the "metrics_only" indicates that we only want to compute */
+ /* the glyph's metrics (lsb + advance width), not load the */
+ /* rest of it.. so exit immediately */
+ if (builder->metrics_only)
+ return T1_Err_Ok;
+
+ goto Clear_Stack;
+ }
- default:
- if (ip[-1] >= 32)
+ case 14: /* endchar */
{
- if (ip[-1] < 247)
- value = (long)ip[-1] - 139;
- else
- {
- if (++ip > limit)
- {
- FT_ERROR(( "T1.Parse_CharStrings : unexpected EOF in integer\n" ));
- goto Syntax_Error;
- }
+ close_contour( builder );
- if (ip[-2] < 251)
- value = ((long)(ip[-2]-247) << 8) + ip[-1] + 108;
- else
- value = -((((long)ip[-2]-251) << 8) + ip[-1] + 108 );
- }
+ /* add current outline to the glyph slot */
+ builder->base.n_points += builder->current.n_points;
+ builder->base.n_contours += builder->current.n_contours;
+
+ /* return now !! */
+ return T1_Err_Ok;
}
- else
+
+ case 21: /* rmoveto */
{
- FT_ERROR(( "T1.Parse_CharStrings : invalid byte (%d)\n",
- ip[-1] ));
- goto Syntax_Error;
+ USE_ARGS(2);
+ x += top[0];
+ y += top[1];
+ goto Clear_Stack;
}
- }
+
+ case 22: /* hmoveto */
+ {
+ USE_ARGS(1);
+ x += top[0];
+ goto Clear_Stack;
+ }
+
+ case 30: /* vhcurveto */
+ {
+ if ( start_point( builder, x, y ) ||
+ check_points( builder, 3 ) ) goto Memory_Error;
+
+ USE_ARGS(4);
+ y += top[0];
+ add_point( builder, x, y, 0 );
+ x += top[1];
+ y += top[2];
+ add_point( builder, x, y, 0 );
+ x += top[3];
+ add_point( builder, x, y, 1 );
+ goto Clear_Stack;
+ }
+
+ case 31: /* hvcurveto */
+ {
+ if ( start_point( builder, x, y ) ||
+ check_points( builder, 3 ) ) goto Memory_Error;
+
+ USE_ARGS(4);
+ x += top[0];
+ add_point( builder, x, y, 0 );
+ x += top[1];
+ y += top[2];
+ add_point( builder, x, y, 0 );
+ y += top[3];
+ add_point( builder, x, y, 1 );
+ goto Clear_Stack;
+ }
+
+
+ case 12:
+ {
+ if (ip > limit)
+ {
+ FT_ERROR(( "T1.Parse_CharStrings : invalid escape (12+EOF)\n" ));
+ goto Syntax_Error;
+ }
+
+ switch (*ip++)
+ {
+ case 0: /* dotsection */
+ case 1: /* vstem3 */
+ case 2: /* hstem3 */
+ goto Clear_Stack;
+
+ case 6: /* seac */
+ {
+ USE_ARGS(5);
+
+ /* return immediately to implement an accented character */
+ return t1operator_seac( decoder,
+ top[0], top[1], top[3],
+ top[4], top[5] );
+ }
+
+ case 7: /* sbw */
+ {
+ USE_ARGS(4);
+ builder->left_bearing.x += top[0];
+ builder->left_bearing.y += top[1];
+ builder->advance.x = top[2];
+ builder->advance.y = top[3];
+
+ builder->last.x = x = top[0];
+ builder->last.y = y = top[1];
+
+ /* the "metrics_only" indicates that we only want to compute */
+ /* the glyph's metrics (lsb + advance width), not load the */
+ /* rest of it.. so exit immediately */
+ if (builder->metrics_only)
+ return T1_Err_Ok;
+
+ goto Clear_Stack;
+ }
+
+ case 12: /* div */
+ {
+ USE_ARGS(2);
+ top[0] /= top[1];
+ top++;
+ }
+ break;
+
+ case 16: /* callothersubr */
+ {
+ USE_ARGS(1);
+ switch (top[0])
+ {
+ case 1: /* start flex feature ---------------------- */
+ {
+ decoder->flex_state = 1;
+ decoder->num_flex_vectors = 0;
+ if ( start_point(builder, x, y) ||
+ check_points(builder,6) ) goto Memory_Error;
+ }
+ break;
- /* push value if needed */
- if ( op == op_none )
- {
- if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS )
- {
- FT_ERROR(( "T1.Parse_CharStrings : Stack overflow !!\n" ));
- goto Syntax_Error;
- }
-
- *top++ = value;
- decoder->top = top;
- }
-
- else if ( op == op_callothersubr ) /* check arguments differently */
- {
- if ( top - decoder->stack < 2)
- goto Stack_Underflow;
-
- top -= 2;
-
- switch (top[1])
- {
- case 1: /* start flex feature ----------------------------- */
- {
- if (top[0] != 0) goto Unexpected_OtherSubr;
+ case 2: /* add flex vectors ------------------------ */
+ {
+ T1_Int index;
+
+ /* note that we should not add a point for index 0 */
+ /* this will move our current position to the flex */
+ /* point without adding any point to the outline */
+ index = decoder->num_flex_vectors++;
+ if (index > 0 && index < 7)
+ add_point( builder,
+ x,
+ y,
+ (T1_Byte)( index==3 || index==6 ) );
+ }
+ break;
+
+ case 0: /* end flex feature ------------------------- */
+ {
+ USE_ARGS(3); /* ignore parameters */
+
+ if ( decoder->flex_state == 0 ||
+ decoder->num_flex_vectors != 7 )
+ {
+ FT_ERROR(( "T1.Parse_CharStrings: unexpected flex end\n" ));
+ goto Syntax_Error;
+ }
+
+ /* now consume the remaining "pop pop setcurpoint" */
+ if ( ip+6 > limit ||
+ ip[0] != 12 || ip[1] != 17 || /* pop */
+ ip[2] != 12 || ip[3] != 17 || /* pop */
+ ip[4] != 12 || ip[5] != 33 ) /* setcurpoint */
+ {
+ FT_ERROR(( "T1.Parse_CharStrings: invalid flex charstring\n" ));
+ goto Syntax_Error;
+ }
+
+ ip += 6;
+ decoder->flex_state = 0;
+ decoder->top = top;
+
+ goto Clear_Stack;
+ }
+
+ case 3: /* change hints ---------------------------- */
+ {
+ /* eat the following "pop" */
+ if (ip+2 > limit)
+ {
+ FT_ERROR(( "T1.Parse_CharStrings: invalid escape (12+%d)\n",
+ ip[-1] ));
+ goto Syntax_Error;
+ }
+
+ if (ip[0] != 12 || ip[1] != 17)
+ {
+ FT_ERROR(( "T1.Parse_CharStrings: 'pop' expected, found (%d %d)\n",
+ ip[0], ip[1] ));
+ goto Syntax_Error;
+ }
+ ip += 2;
+ goto Clear_Stack;
+ }
+
+ default:
+ FT_ERROR(( "T1.Parse_CharStrings: invalid othersubr %d !!\n",
+ top[0] ));
+ goto Syntax_Error;
+ }
+ }
- decoder->flex_state = 1;
- decoder->num_flex_vectors = 0;
- decoder->flex_vectors[0].x = 0;
- decoder->flex_vectors[0].y = 0;
- }
- break;
-
+ case 17: /* pop - should not happen !! */
+ {
+ FT_ERROR(( "T1.Parse_CharStrings : 'pop' should not happen !!\n" ));
+ goto Syntax_Error;
+ }
+
+ case 33: /* setcurrentpoint */
+ {
+ FT_ERROR(( "T1.Parse_CharStrings : 'setcurrentpoint' should not happen !!\n" ));
+ goto Syntax_Error;
+ }
- case 2: /* add flex vector ------------------------------- */
- {
- T1_Int index;
- T1_Vector* flex;
-
- if (top[0] != 0) goto Unexpected_OtherSubr;
-
- top -= 2;
- if (top < decoder->stack) goto Stack_Underflow;
-
- index = decoder->num_flex_vectors++;
- if (index >= 7)
- {
- FT_ERROR(( "T1.Parse_CharStrings: too many flex vectors !\n" ));
+ default:
+ FT_ERROR(( "T1.Parse_CharStrings : invalid escape (12+%d)\n",
+ ip[-1] ));
goto Syntax_Error;
- }
-
- flex = decoder->flex_vectors + index;
- flex->x += top[0];
- flex->y += top[1];
-
}
- break;
+ }
+ break; /* escape - 12 */
-
- case 0: /* end flex feature ------------------------------ */
+ case 255: /* four bytes integer */
+ {
+ if (ip+4 > limit)
{
- if ( decoder->flex_state == 0 ||
- decoder->num_flex_vectors != 7 )
- {
- FT_ERROR(( "T1.Parse_CharStrings: unexpected flex end\n" ));
- goto Syntax_Error;
- }
-
- if (top[0] != 3) goto Unexpected_OtherSubr;
-
- top -= 3;
- if (top < decoder->stack) goto Stack_Underflow;
-
- /* now consume the remaining "pop pop setcurrentpoint" */
- if ( ip+6 > limit ||
- ip[0] != 12 || ip[1] != 17 || /* pop */
- ip[2] != 12 || ip[3] != 17 || /* pop */
- ip[4] != 12 || ip[5] != 33 ) /* setcurrentpoint */
- {
- FT_ERROR(( "T1.Parse_CharStrings: invalid flex charstring\n" ));
- goto Syntax_Error;
- }
-
- decoder->flex_state = 0;
- decoder->top = top;
-
- error = t1operator_flex( decoder, top[0], top[1], top[2] );
+ FT_ERROR(( "T1.Parse_CharStrings : unexpected EOF in integer\n" ));
+ goto Syntax_Error;
}
- break;
+ *top++ = ((long)ip[0] << 24) |
+ ((long)ip[1] << 16) |
+ ((long)ip[2] << 8) |
+ ip[3];
+ ip += 4;
+ }
+ break;
- case 3: /* change hints ------------------------------------ */
+ default:
+ {
+ T1_Long v, v2;
+
+ v = ip[-1];
+ if (v < 32)
{
- if (top[0] != 1) goto Unexpected_OtherSubr;
-
- /* eat the following "pop" */
- if (ip+2 > limit)
- {
- FT_ERROR(( "T1.Parse_CharStrings: invalid escape (12+%d)\n",
+ FT_ERROR(( "T1.Parse_CharStrings : invalid byte (%d)\n",
ip[-1] ));
- goto Syntax_Error;
- }
-
- if (ip[0] != 12 || ip[1] != 17)
- {
- FT_ERROR(( "T1.Parse_CharStrings: 'pop' expected, found (%d %d)\n",
- ip[0], ip[1] ));
- goto Syntax_Error;
- }
-
- ip += 2;
- error = hints->change_hints(builder);
+ goto Syntax_Error;
}
- break;
-
-
- default:
- /* invalid OtherSubrs call */
- Unexpected_OtherSubr:
- FT_ERROR(( "T1.Parse_CharStrings: unexpected OtherSubrs [%d %d]\n",
- top[0], top[1] ));
- goto Syntax_Error;
- }
- decoder->top = top;
- }
- else
- {
- T1_Int num_args = args_count[op];
-
- if ( top - decoder->stack < num_args )
- goto Stack_Underflow;
-
- top -= num_args;
-
- switch (op)
- {
- case op_endchar:
- error = builds->end_char( builder );
- break;
-
- case op_hsbw:
- error = builds->set_bearing_point( builder, top[0], 0,
- top[1], 0 );
- break;
-
- case op_seac:
- /* return immediately after the processing */
- return t1operator_seac( decoder, top[0], top[1],
- top[2], top[3], top[4] );
-
- case op_sbw:
- error = builds->set_bearing_point( builder, top[0], top[1],
- top[2], top[3] );
- break;
-
- case op_closepath:
- error = builds->close_path( builder );
- break;
-
- case op_hlineto:
- error = builds->rline_to( builder, top[0], 0 );
- break;
-
- case op_hmoveto:
- error = builds->rmove_to( builder, top[0], 0 );
- break;
-
- case op_hvcurveto:
- error = builds->rcurve_to( builder, top[0], 0,
- top[1], top[2],
- 0, top[3] );
- break;
-
- case op_rlineto:
- error = builds->rline_to( builder, top[0], top[1] );
- break;
-
- case op_rmoveto:
- /* ignore operator when in flex mode */
- if (decoder->flex_state == 0)
- error = builds->rmove_to( builder, top[0], top[1] );
+
+ /* compute value ---- */
+ /* */
+ if (v < 247) /* 1-byte value */
+ v -= 139;
else
- top += 2;
- break;
-
- case op_rrcurveto:
{
- error = builds->rcurve_to( builder, top[0], top[1],
- top[2], top[3],
- top[4], top[5] );
- }
- break;
-
- case op_vhcurveto:
- error = builds->rcurve_to( builder, 0, top[0],
- top[1], top[2],
- top[3], 0 );
- break;
-
- case op_vlineto:
- error = builds->rline_to( builder, 0, top[0] );
- break;
-
- case op_vmoveto:
- error = builds->rmove_to( builder, 0, top[0] );
- break;
-
- case op_dotsection:
- error = hints->dot_section( builder );
- break;
-
- case op_hstem:
- error = hints->stem( builder, top[0], top[1], 0 );
- break;
-
- case op_hstem3:
- error = hints->stem3( builder, top[0], top[1], top[2],
- top[3], top[4], top[5], 0 );
- break;
-
- case op_vstem:
- error = hints->stem( builder, top[0], top[1], 1 );
- break;
-
- case op_vstem3:
- error = hints->stem3( builder, top[0], top[1], top[2],
- top[3], top[4], top[5], 1 );
- break;
-
- case op_div:
- if (top[1])
- *top++ = top[0] / top[1];
- else
- {
- FT_ERROR(( "T1.Parse_CHarStrings : division by 0\n" ));
- goto Syntax_Error;
- }
- break;
-
- case op_callsubr:
- {
- T1_Int index = top[0];
-
- if ( index < 0 || index >= num_subrs )
+ if (++ip > limit) /* 2-bytes value, check limits */
{
- FT_ERROR(( "T1.Parse_CharStrings : invalid subrs index\n" ));
+ FT_ERROR(( "T1.Parse_CharStrings : unexpected EOF in integer\n" ));
goto Syntax_Error;
}
-
- if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS )
- {
- FT_ERROR(( "T1.Parse_CharStrings : too many nested subrs\n" ));
- goto Syntax_Error;
- }
-
- zone->cursor = ip; /* save current instruction pointer */
-
- zone++;
- zone->base = subrs_base[index];
- zone->limit = zone->base + subrs_len[index];
- zone->cursor = zone->base;
-
- if (!zone->base)
- {
- FT_ERROR(( "T1.Parse_CharStrings : invoking empty subrs !!\n" ));
- goto Syntax_Error;
- }
-
- decoder->zone = zone;
- ip = zone->base;
- limit = zone->limit;
+
+ v2 = ip[-1] + 108;
+ if (v < 251)
+ v = ((v-247) << 8) + v2;
+ else
+ v = -(((v-251) << 8) + v2);
}
- break;
-
- case op_pop:
- FT_ERROR(( "T1.Parse_CharStrings : unexpected POP\n" ));
- goto Syntax_Error;
-
-
- case op_return:
- if ( zone <= decoder->zones )
+
+ /* store value - is there enough room ?*/
+ if ( top >= decoder->stack + T1_MAX_CHARSTRINGS_OPERANDS )
{
- FT_ERROR(( "T1.Parse_CharStrings : unexpected return\n" ));
+ FT_ERROR(( "T1.Parse_CharStrings : Stack overflow !!\n" ));
goto Syntax_Error;
}
-
- zone--;
- ip = zone->cursor;
- limit = zone->limit;
- decoder->zone = zone;
- break;
-
- case op_setcurrentpoint:
- FT_ERROR(( "T1.Parse_CharStrings : unexpected SETCURRENTPOINT\n" ));
- goto Syntax_Error;
- break;
-
- default:
- FT_ERROR(( "T1.Parse_CharStrings : unhandled opcode %d\n", op ));
- goto Syntax_Error;
- }
-
- decoder->top = top;
- }
- }
-
+
+ *top++ = v;
+ decoder->top = top;
+ }
+ } /* big switch */
+
+ } /* while ip < limit */
return error;
Syntax_Error:
@@ -871,117 +942,13 @@
Stack_Underflow:
return T1_Err_Stack_Underflow;
- }
-
-
-
-/*************************************************************************/
-/* */
-/* <Function> T1_Add_Points */
-/* */
-/* <Description> */
-/* Checks that there is enough room in the current load glyph outline */
-/* to accept "num_points" additional outline points. If not, this */
-/* function grows the load outline's arrays accordingly.. */
-/* */
-/* <Input> */
-/* builder :: pointer to glyph builder object */
-/* num_points :: number of points that will be added later */
-/* */
-/* <Return> */
-/* Type1 error code. 0 means success */
-/* */
-/* <Note> */
-/* This function does NOT update the points count in the glyph builder*/
-/* This must be done by the caller itself, after this function is */
-/* invoked.. */
-/* */
- LOCAL_FUNC
- T1_Error T1_Add_Points( T1_Builder* builder,
- T1_Int num_points )
- {
- T1_Int new_points;
-
- new_points = builder->base.n_points +
- builder->current.n_points +
- num_points;
-
- if ( new_points > builder->max_points )
- {
- FT_Memory memory = builder->memory;
- T1_Error error;
- T1_Int increment = builder->current.points - builder->base.points;
- T1_Int current = builder->max_points;
-
- while ( builder->max_points < new_points )
- builder->max_points += 16;
-
- if ( REALLOC_ARRAY( builder->base.points,
- current, builder->max_points, T1_Vector ) ||
-
- REALLOC_ARRAY( builder->base.flags,
- current, builder->max_points, T1_Byte ) )
- return error;
- builder->current.points = builder->base.points + increment;
- builder->current.flags = builder->base.flags + increment;
- }
-
- return T1_Err_Ok;
+ Memory_Error:
+ return builder->error;
}
-/*************************************************************************/
-/* */
-/* <Function> T1_Add_Contours */
-/* */
-/* <Description> */
-/* Checks that there is enough room in the current load glyph outline */
-/* to accept "num_contours" additional contours. If not, this func */
-/* the load outline's arrays accordingly.. */
-/* */
-/* <Input> */
-/* builder :: pointer to glyph builder object */
-/* num_contours :: number of contours that will be added later */
-/* */
-/* <Return> */
-/* Type1 error code. 0 means success */
-/* */
-/* <Note> */
-/* This function does NOT update the contours count in the load glyph */
-/* This must be done by the caller itself, after this function is */
-/* invoked.. */
-/* */
- LOCAL_FUNC
- T1_Error T1_Add_Contours( T1_Builder* builder,
- T1_Int num_contours )
- {
- T1_Int new_contours;
- new_contours = builder->base.n_contours +
- builder->current.n_contours +
- num_contours;
- if ( new_contours > builder->max_contours && builder->load_points )
- {
- T1_Error error;
- FT_Memory memory = builder->memory;
- T1_Int increment = builder->current.contours - builder->base.contours;
- T1_Int current = builder->max_contours;
-
- while ( builder->max_contours < new_contours )
- builder->max_contours += 4;
-
- if ( REALLOC_ARRAY( builder->base.contours,
- current, builder->max_contours, T1_Short ) )
- return error;
-
- builder->current.contours = builder->base.contours + increment;
- }
-
- return T1_Err_Ok;
- }
-
-
/**********************************************************************/
/**********************************************************************/
/**********************************************************************/
@@ -999,64 +966,6 @@
/**********************************************************************/
/**********************************************************************/
-
-
- static
- T1_Error maxadv_sbw( T1_Decoder* decoder,
- T1_Pos sbx,
- T1_Pos sby,
- T1_Pos wx,
- T1_Pos wy )
- {
- if (wx > decoder->builder.advance.x)
- decoder->builder.advance.x = wx;
-
- (void)sbx;
- (void)sby;
- (void)wy;
- return -1; /* return an error code to exit the Type 1 parser */
- /* immediately. */
- }
-
-
- static
- T1_Int maxadv_error( void )
- {
- /* we should never reach this code, unless with a buggy font */
- return -2;
- }
-
- /* the maxadv_gbuilder_interface is used when computing the maximum */
- /* advance width of all glyphs in a given font. We only process the */
- /* 'sbw' operator here, and return an error for all others.. */
-
- /* Note that "seac" is processed by the T1_Decoder */
- static
- const T1_Builder_Funcs maxadv_builder_interface =
- {
- (T1_Builder_EndChar) maxadv_error,
- (T1_Builder_Sbw) maxadv_sbw,
- (T1_Builder_ClosePath) maxadv_error,
- (T1_Builder_RLineTo) maxadv_error,
- (T1_Builder_RMoveTo) maxadv_error,
- (T1_Builder_RCurveTo) maxadv_error
- };
-
-
- /* the maxadv_interface is used when computing the maximum advance */
- /* with of the set of glyphs in a given font file. We only process */
- /* the "seac" operator and return immediately.. */
- static
- const T1_Hinter_Funcs maxadv_hinter_interface =
- {
- (T1_Hinter_DotSection) maxadv_error,
- (T1_Hinter_ChangeHints) maxadv_error,
- (T1_Hinter_Stem) maxadv_error,
- (T1_Hinter_Stem3) maxadv_error,
- };
-
-
-
LOCAL_FUNC
T1_Error T1_Compute_Max_Advance( T1_Face face,
T1_Int *max_advance )
@@ -1069,10 +978,11 @@
*max_advance = 0;
/* Initialise load decoder */
- T1_Init_Decoder( &decoder, &maxadv_hinter_interface );
+ T1_Init_Decoder( &decoder );
+ T1_Init_Builder( &decoder.builder, face, 0, 0 );
- T1_Init_Builder( &decoder.builder, face, 0, 0,
- &maxadv_builder_interface );
+ decoder.builder.metrics_only = 1;
+ decoder.builder.load_points = 0;
/* For each glyph, parse the glyph charstring and extract */
/* the advance width.. */
@@ -1105,304 +1015,11 @@
/********** single outline. It completely ignores hinting *********/
/********** and is used when FT_LOAD_NO_HINTING is set. *********/
/********** *********/
- /********** The Type 1 hinter is located in "t1hint.c" *********/
- /********** *********/
/**********************************************************************/
/**********************************************************************/
/**********************************************************************/
-
- static
- T1_Error close_open_path( T1_Builder* builder )
- {
- T1_Error error;
- FT_Outline* cur = &builder->current;
- T1_Int num_points;
- T1_Int first_point;
-
- /* Some fonts, like Hershey, are made of "open paths" which are */
- /* now managed directly by FreeType. In this case, it is necessary */
- /* to close the path by duplicating its points in reverse order, */
- /* which is precisely the purpose of this function */
-
- /* first compute the number of points to duplicate.. */
- if (cur->n_contours > 1)
- first_point = cur->contours[ cur->n_contours-2 ]+1;
- else
- first_point = 0;
-
- num_points = cur->n_points - first_point - 2;
- if ( num_points > 0 )
- {
- T1_Vector* source_point;
- char* source_flags;
- T1_Vector* point;
- char* flags;
-
- error = T1_Add_Points( builder, num_points );
- if (error) return error;
-
- point = cur->points + cur->n_points;
- flags = cur->flags + cur->n_points;
-
- source_point = point - 2;
- source_flags = flags - 2;
-
- cur->n_points += num_points;
-
- if ( builder->load_points )
- do
- {
- *point++ = *source_point--;
- *flags++ = *source_flags--;
- num_points--;
- }
- while (num_points > 0);
- }
-
- builder->path_begun = 0;
- return T1_Err_Ok;
- }
-
-
- static
- T1_Error gload_closepath( T1_Builder* builder )
- {
- FT_Outline* cur = &builder->current;
-
- /* save current contour, if any */
- if ( cur->n_contours > 0 )
- cur->contours[cur->n_contours-1] = cur->n_points-1;
-
-#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
- /* hint latest points if needed - this is not strictly required */
- /* there, but it helps for debugging, and doesn't affect performance */
- if ( builder->pass == 1 )
- T1_Hint_Points( builder );
-#endif
-
- builder->path_begun = 0;
- return T1_Err_Ok;
- }
-
-
-
- static
- T1_Error gload_endchar( T1_Builder* builder )
- {
- FT_Outline* cur = &builder->current;
- T1_Error error;
-
- /* close path if needed */
- if (builder->path_begun)
- {
- error = close_open_path( builder );
- if (error) return error;
- }
-
- error = gload_closepath( builder );
-
- builder->base.n_points += cur->n_points;
- builder->base.n_contours += cur->n_contours;
-
- return error;
- }
-
-
-
- static
- T1_Error gload_sbw( T1_Builder* builder,
- T1_Pos sbx,
- T1_Pos sby,
- T1_Pos wx,
- T1_Pos wy )
- {
- builder->left_bearing.x += sbx;
- builder->left_bearing.y += sby;
- builder->advance.x = wx;
- builder->advance.y = wy;
-
- builder->last.x = sbx;
- builder->last.y = sby;
- return 0;
- }
-
-
-
-
- static
- T1_Error gload_rlineto( T1_Builder* builder,
- T1_Pos dx,
- T1_Pos dy )
- {
- T1_Error error;
- FT_Outline* cur = &builder->current;
- T1_Vector vec;
-
- /* grow buffer if necessary */
- error = T1_Add_Points ( builder, 1 );
- if (error) return error;
-
- if ( builder->load_points )
- {
- /* save point */
- vec.x = builder->last.x + dx;
- vec.y = builder->last.y + dy;
-
- cur->points[cur->n_points] = vec;
- cur->flags [cur->n_points] = FT_Curve_Tag_On;
-
- builder->last = vec;
- }
- cur->n_points++;
-
- builder->path_begun = 1;
- return T1_Err_Ok;
- }
-
-
- static
- T1_Error gload_rmoveto( T1_Builder* builder,
- T1_Pos dx,
- T1_Pos dy )
- {
- T1_Error error;
- FT_Outline* cur = &builder->current;
- T1_Vector vec;
-
- /* in the case where "path_begun" is set, we have a rmoveto */
- /* after some normal path definition. When the face's paint */
- /* type is set to 1, this means that we have an "open path", */
- /* also called a 'stroke'. The FreeType raster doesn't support */
- /* opened path, so we'll close it explicitely there.. */
- if ( builder->path_begun && builder->face->type1.paint_type == 1 )
- {
- if ( builder->face->type1.paint_type == 1 )
- {
- error = close_open_path( builder );
- if (error) return error;
- }
- }
-
- /* grow buffer if necessary */
- error = T1_Add_Contours( builder, 1 ) ||
- T1_Add_Points ( builder, 1 );
- if (error) return error;
-
- /* save current contour, if any */
- if ( cur->n_contours > 0 )
- cur->contours[cur->n_contours-1] = cur->n_points-1;
-
- if ( builder->load_points )
- {
- /* save point */
- vec.x = builder->last.x + dx;
- vec.y = builder->last.y + dy;
- cur->points[cur->n_points] = vec;
- cur->flags [cur->n_points] = FT_Curve_Tag_On;
-
- builder->last = vec;
- }
-
- cur->n_contours++;
- cur->n_points++;
-
- return T1_Err_Ok;
- }
-
-
- static
- T1_Error gload_rrcurveto( T1_Builder* builder,
- T1_Pos dx1,
- T1_Pos dy1,
- T1_Pos dx2,
- T1_Pos dy2,
- T1_Pos dx3,
- T1_Pos dy3 )
- {
- T1_Error error;
- FT_Outline* cur = &builder->current;
- T1_Vector vec;
- T1_Vector* points;
- char* flags;
-
- /* grow buffer if necessary */
- error = T1_Add_Points ( builder, 3 );
- if (error) return error;
-
- if ( builder->load_points )
- {
- /* save point */
- points = cur->points + cur->n_points;
- flags = cur->flags + cur->n_points;
-
- vec.x = builder->last.x + dx1;
- vec.y = builder->last.y + dy1;
- points[0] = vec; flags[0] = FT_Curve_Tag_Cubic;
-
- vec.x += dx2;
- vec.y += dy2;
- points[1] = vec; flags[1] = FT_Curve_Tag_Cubic;
-
- vec.x += dx3;
- vec.y += dy3;
- points[2] = vec; flags[2] = FT_Curve_Tag_On;
-
- builder->last = vec;
- }
-
- cur->n_points += 3;
- builder->path_begun = 1;
- return T1_Err_Ok;
- }
-
-
-
-
- static
- T1_Error gload_ignore( void )
- {
- return 0;
- }
-
-
- static
- const T1_Builder_Funcs gload_builder_interface =
- {
- gload_endchar,
- gload_sbw,
- gload_closepath,
- gload_rlineto,
- gload_rmoveto,
- gload_rrcurveto
- };
-
-
- static
- const T1_Builder_Funcs gload_builder_interface_null =
- {
- (T1_Builder_EndChar) gload_ignore,
- (T1_Builder_Sbw) gload_sbw, /* record left bearing */
- (T1_Builder_ClosePath) gload_ignore,
- (T1_Builder_RLineTo) gload_ignore,
- (T1_Builder_RMoveTo) gload_ignore,
- (T1_Builder_RCurveTo) gload_ignore
- };
-
-
- static
- const T1_Hinter_Funcs gload_hinter_interface =
- {
- (T1_Hinter_DotSection) gload_ignore, /* dotsection */
- (T1_Hinter_ChangeHints) gload_ignore, /* changehints */
- (T1_Hinter_Stem) gload_ignore, /* hstem & vstem */
- (T1_Hinter_Stem3) gload_ignore, /* hstem3 & vestem3 */
- };
-
-
-
-
LOCAL_FUNC
T1_Error T1_Load_Glyph( T1_GlyphSlot glyph,
T1_Size size,
@@ -1426,66 +1043,9 @@
glyph->root.format = ft_glyph_format_none;
-#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
- /*****************************************************************/
- /* */
- /* Hinter overview : */
- /* */
- /* This is a two-pass hinter. On the first pass, the hints */
- /* are all recorded by the hinter, and no point is loaded */
- /* in the outline. */
- /* */
- /* When the first pass is finished, all stems hints are */
- /* grid-fitted at once. */
- /* */
- /* Then, a second pass is performed to load the outline */
- /* points as well as hint/scale them correctly. */
- /* */
-
- if ( hinting )
{
- /* Pass 1 - don't record points, simply stem hints */
- T1_Init_Decoder( &decoder, &t1_hinter_funcs );
- T1_Init_Builder( &decoder.builder, face, size, glyph,
- &gload_builder_interface_null );
-
- glyph->hints->hori_stems.num_stems = 0;
- glyph->hints->vert_stems.num_stems = 0;
-
- error = T1_Parse_CharStrings( &decoder,
- type1->charstrings [glyph_index],
- type1->charstrings_len[glyph_index],
- type1->num_subrs,
- type1->subrs,
- type1->subrs_len );
-
- /* All right, pass 1 is finished, now grid-fit all stem hints */
- T1_Hint_Stems( &decoder.builder );
-
- /* Pass 2 - record and scale/hint the points */
- T1_Init_Decoder( &decoder, &t1_hinter_funcs );
- T1_Init_Builder( &decoder.builder, face, size, glyph,
- &gload_builder_interface );
-
- decoder.builder.pass = 1;
-
- error = T1_Parse_CharStrings( &decoder,
- type1->charstrings [glyph_index],
- type1->charstrings_len[glyph_index],
- type1->num_subrs,
- type1->subrs,
- type1->subrs_len );
-
- /* save new glyph tables */
- T1_Done_Builder( &decoder.builder );
- }
- else
-#endif
- {
- T1_Init_Decoder( &decoder, &gload_hinter_interface );
-
- T1_Init_Builder( &decoder.builder, face, size, glyph,
- &gload_builder_interface );
+ T1_Init_Decoder( &decoder );
+ T1_Init_Builder( &decoder.builder, face, size, glyph );
/* now load the unscaled outline */
error = T1_Parse_CharStrings( &decoder,
@@ -1499,7 +1059,6 @@
T1_Done_Builder( &decoder.builder );
}
-
/* Now, set the metrics.. - this is rather simple, as : */
/* the left side bearing is the xMin, and the top side */
/* bearing the yMax.. */
@@ -1539,15 +1098,8 @@
glyph->root.outline.high_precision = ( size->root.metrics.y_ppem < 24 );
glyph->root.outline.dropout_mode = 2;
- if ( hinting )
+ if ( (load_flags & FT_LOAD_NO_SCALE) == 0 )
{
- /* adjust the advance width */
- /* XXX : TODO : consider stem hints grid-fit */
- metrics->horiAdvance = FT_MulFix( metrics->horiAdvance,
- glyph->x_scale );
- }
- else if ( (load_flags & FT_LOAD_NO_SCALE) == 0 )
- {
/* scale the outline and the metrics */
T1_Int n;
FT_Outline* cur = &decoder.builder.base;
@@ -1573,10 +1125,8 @@
metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale );
metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale );
metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, x_scale );
-
}
}
-
return error;
}
--- a/src/type1z/t1gload.h
+++ b/src/type1z/t1gload.h
@@ -44,57 +44,6 @@
/*************************************************************************/
/* */
-/* <Structure> T1_Builder_Funcs */
-/* */
-/* <Description> */
-/* a structure used to store the address of various functions */
-/* used by a glyph builder to implement the outline's "path */
-/* construction". */
-/* */
-/* */
- typedef struct T1_Builder_ T1_Builder;
-
- typedef T1_Error (*T1_Builder_EndChar)( T1_Builder* loader );
-
- typedef T1_Error (*T1_Builder_Sbw) ( T1_Builder* loader,
- T1_Pos sbx,
- T1_Pos sby,
- T1_Pos wx,
- T1_Pos wy );
-
- typedef T1_Error (*T1_Builder_ClosePath)( T1_Builder* loader );
-
- typedef T1_Error (*T1_Builder_RLineTo)( T1_Builder* loader,
- T1_Pos dx,
- T1_Pos dy );
-
- typedef T1_Error (*T1_Builder_RMoveTo)( T1_Builder* loader,
- T1_Pos dx,
- T1_Pos dy );
-
- typedef T1_Error (*T1_Builder_RCurveTo)( T1_Builder* loader,
- T1_Pos dx1,
- T1_Pos dy1,
- T1_Pos dx2,
- T1_Pos dy2,
- T1_Pos dx3,
- T1_Pos dy3 );
-
- typedef struct T1_Builder_Funcs_
- {
- T1_Builder_EndChar end_char;
- T1_Builder_Sbw set_bearing_point;
- T1_Builder_ClosePath close_path;
- T1_Builder_RLineTo rline_to;
- T1_Builder_RMoveTo rmove_to;
- T1_Builder_RCurveTo rcurve_to;
-
- } T1_Builder_Funcs;
-
-
-
-/*************************************************************************/
-/* */
/* <Structure> T1_Builder */
/* */
/* <Description> */
@@ -103,7 +52,6 @@
/* <Fields> */
/* system :: current system object */
/* face :: current face object */
-/* size :: current size object */
/* glyph :: current glyph slot */
/* */
/* current :: current glyph outline */
@@ -125,22 +73,18 @@
/* path_begun :: flag, indicates that a new path has begun */
/* load_points :: flag, if not set, no points are loaded */
/* */
-/* pass :: pass number for multi-pass hinters */
+/* error :: an error code that is only used to report */
+/* memory allocation problems.. */
/* */
-/* funcs :: table of builder functions used to perform */
-/* the outline's path construction */
+/* metrics_only :: a boolean indicating that we only want to */
+/* compute the metrics of a given glyph, not load */
+/* all of its points.. */
/* */
-/* hint_point :: index of next point to hint.. */
-/* */
-/* */
-/* */
-/* */
- struct T1_Builder_
+ typedef struct T1_Builder_
{
FT_Memory memory;
T1_Face face;
- T1_Size size;
T1_GlyphSlot glyph;
FT_Outline current; /* the current glyph outline */
@@ -163,90 +107,13 @@
T1_BBox bbox; /* bounding box */
T1_Bool path_begun;
T1_Bool load_points;
+
+ T1_Error error; /* only used for memory errors */
+ T1_Bool metrics_only;
+
+ } T1_Builder;
- T1_Int pass;
- T1_Int hint_point;
- /* path construction function interface */
- T1_Builder_Funcs funcs;
- };
-
-
-/*************************************************************************/
-/* */
-/* <Structure> T1_Hinter_Funcs */
-/* */
-/* <Description> */
-/* a structure used to store the address of various functions */
-/* used by a Type 1 hinter to perform outline hinting. */
-/* */
-
- typedef T1_Error (*T1_Hinter_ChangeHints)( T1_Builder* builder );
-
- typedef T1_Error (*T1_Hinter_DotSection)( T1_Builder* builder );
-
- typedef T1_Error (*T1_Hinter_Stem)( T1_Builder* builder,
- T1_Pos pos,
- T1_Pos width,
- T1_Bool vertical );
-
-
- typedef T1_Error (*T1_Hinter_Stem3)( T1_Builder* builder,
- T1_Pos pos0,
- T1_Pos width0,
- T1_Pos pos1,
- T1_Pos width1,
- T1_Pos pos2,
- T1_Pos width2,
- T1_Bool vertical );
-
- typedef struct T1_Hinter_Func_
- {
- T1_Hinter_ChangeHints change_hints;
- T1_Hinter_DotSection dot_section;
- T1_Hinter_Stem stem;
- T1_Hinter_Stem3 stem3;
-
- } T1_Hinter_Funcs;
-
-
-
- typedef enum T1_Operator_
- {
- op_none = 0,
- op_endchar,
- op_hsbw,
- op_seac,
- op_sbw,
- op_closepath,
- op_hlineto,
- op_hmoveto,
- op_hvcurveto,
- op_rlineto,
- op_rmoveto,
- op_rrcurveto,
- op_vhcurveto,
- op_vlineto,
- op_vmoveto,
- op_dotsection,
- op_hstem,
- op_hstem3,
- op_vstem,
- op_vstem3,
- op_div,
- op_callothersubr,
- op_callsubr,
- op_pop,
- op_return,
- op_setcurrentpoint,
-
- op_max /* never remove this one */
-
- } T1_Operator;
-
-
-
-
/* execution context charstring zone */
typedef struct T1_Decoder_Zone_
{
@@ -260,7 +127,6 @@
typedef struct T1_Decoder_
{
T1_Builder builder;
- T1_Hinter_Funcs hinter;
T1_Int stack[ T1_MAX_CHARSTRINGS_OPERANDS ];
T1_Int* top;
@@ -276,82 +142,18 @@
-/*********************************************************************
- *
- * <Function>
- * T1_Init_Builder
- *
- * <Description>
- * Initialise a given glyph builder.
- *
- * <Input>
- * builder :: glyph builder to initialise
- * face :: current face object
- * size :: current size object
- * glyph :: current glyph object
- * funcs :: glyph builder functions (or "methods").
- *
- * <Note>
- * This function is exported for now because it is used by the
- * "t1dump" utility. Later, it will be accessed through a
- * format-specific extension
- *
- *********************************************************************/
-
- EXPORT_DEF
+ LOCAL_DEF
void T1_Init_Builder( T1_Builder* builder,
T1_Face face,
T1_Size size,
- T1_GlyphSlot glyph,
- const T1_Builder_Funcs* funcs );
+ T1_GlyphSlot glyph );
-/*********************************************************************
- *
- * <Function>
- * T1_Done_Builder
- *
- * <Description>
- * Finalise a given glyph builder. Its content can still be
- * used after the call, but the function saves important information
- * within the corresponding glyph slot.
- *
- * <Input>
- * builder :: glyph builder to initialise
- *
- * <Note>
- * This function is exported for now because it is used by the
- * "t1dump" utility. Later, it will be accessed through a
- * format-specific extension
- *
- *********************************************************************/
-
- EXPORT_DEF
+ LOCAL_DEF
void T1_Done_Builder( T1_Builder* builder );
-/*********************************************************************
- *
- * <Function>
- * T1_Init_Decoder
- *
- * <Description>
- * Initialise a given Type 1 decoder for parsing
- *
- * <Input>
- * decoder :: Type 1 decoder to initialise
- * funcs :: hinter functions interface
- *
- * <Note>
- * This function is exported for now because it is used by the
- * "t1dump" utility. Later, it will be accessed through a
- * format-specific extension
- *
- *********************************************************************/
-
- EXPORT_DEF
- void T1_Init_Decoder( T1_Decoder* decoder,
- const T1_Hinter_Funcs* funcs );
-
+ LOCAL_DEF
+ void T1_Init_Decoder( T1_Decoder* decoder );
/* Compute the maximum advance width of a font through quick parsing */
--- a/src/type1z/t1load.c
+++ b/src/type1z/t1load.c
@@ -92,13 +92,19 @@
FACE.##x = T1_ToString(&loader->parser); \
FT_TRACE2(( "type1.parse_##x##: \"%s\"\n", FACE.##x )); \
}
-
+
+#define PARSE_NUM(s,x,t) PARSE_(x) \
+ { \
+ FACE.##x = (t)T1_ToInt(&loader->parser); \
+ FT_TRACE2(( "type1.parse_##x##: \"%d\"\n", FACE.##x )); \
+ }
+
#define PARSE_INT(s,x) PARSE_(x) \
{ \
FACE.##x = T1_ToInt(&loader->parser); \
FT_TRACE2(( "type1.parse_##x##: \"%d\"\n", FACE.##x )); \
}
-
+
#define PARSE_BOOL(s,x) PARSE_(x) \
{ \
FACE.##x = T1_ToBool(&loader->parser); \
@@ -381,10 +387,12 @@
/* "ExpertEncoding" */
else
{
- if ( cur+17 < limit && strncmp( cur, "StandardEncoding", 16 ) == 0 )
+ if ( cur+17 < limit &&
+ strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 )
face->type1.encoding_type = t1_encoding_standard;
- else if (cur+15 < limit && strncmp( cur, "ExpertEncoding", 14 ) == 0 )
+ else if ( cur+15 < limit &&
+ strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 )
face->type1.encoding_type = t1_encoding_expert;
else
@@ -515,6 +523,7 @@
#undef PARSE_STRING
#undef PARSE_INT
+#undef PARSE_NUM
#undef PARSE_BOOL
#undef PARSE_FIXED
#undef PARSE_COORDS
@@ -527,6 +536,7 @@
#define PARSE_STRING(s,x) PARSE_(s,x)
#define PARSE_INT(s,x) PARSE_(s,x)
+#define PARSE_NUM(s,x,t) PARSE_(s,x)
#define PARSE_BOOL(s,x) PARSE_(s,x)
#define PARSE_FIXED(s,x) PARSE_(s,x)
#define PARSE_COORDS(s,c,m,x) PARSE_(s,x)
@@ -589,7 +599,8 @@
name = (T1_Byte*)keyword->name;
if (!name) break;
- if (cur[0] == name[0] && len == strlen(name) )
+ if ( cur[0] == name[0] &&
+ len == (T1_Int)strlen((const char*)name) )
{
T1_Int n;
for ( n = 1; n < len; n++ )
@@ -718,11 +729,12 @@
if (char_name)
for ( index = 0; index < type1->num_glyphs; index++ )
{
- glyph_name = type1->glyph_names[index];
- if ( strcmp( char_name, glyph_name ) == 0 )
+ glyph_name = (T1_Byte*)type1->glyph_names[index];
+ if ( strcmp( (const char*)char_name,
+ (const char*)glyph_name ) == 0 )
{
type1->encoding.char_index[charcode] = index;
- type1->encoding.char_name [charcode] = glyph_name;
+ type1->encoding.char_name [charcode] = (char*)glyph_name;
if (charcode < min_char) min_char = charcode;
if (charcode > max_char) max_char = charcode;
--- a/src/type1z/t1objs.c
+++ b/src/type1z/t1objs.c
@@ -21,10 +21,6 @@
#include <t1gload.h>
#include <t1load.h>
-#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
-#include <t1hinter.h>
-#endif
-
/* Required by tracing mode */
#undef FT_COMPONENT
#define FT_COMPONENT trace_t1objs
@@ -55,13 +51,7 @@
LOCAL_FUNC
void T1_Done_Size( T1_Size size )
{
- if (size)
- {
-#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
- T1_Done_Size_Hinter( size );
-#endif
- size->valid = 0;
- }
+ (void)size;
}
@@ -88,13 +78,8 @@
size->valid = 0;
-#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
- error = T1_New_Size_Hinter( size );
- return error;
-#else
(void)error;
return T1_Err_Ok;
-#endif
}
@@ -118,12 +103,8 @@
LOCAL_FUNC
T1_Error T1_Reset_Size( T1_Size size )
{
-#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
- return T1_Reset_Size_Hinter( size );
-#else
(void)size;
return 0;
-#endif
}
@@ -312,9 +293,6 @@
FT_Memory memory = glyph->root.face->memory;
FT_Library library = glyph->root.face->driver->library;
-#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
- T1_Done_Glyph_Hinter( glyph );
-#endif
/* the bitmaps are created on demand */
FREE( glyph->root.bitmap.buffer );
FT_Done_Outline( library, &glyph->root.outline );
@@ -339,22 +317,12 @@
T1_Error T1_Init_GlyphSlot( T1_GlyphSlot glyph )
{
FT_Library library = glyph->root.face->driver->library;
- T1_Error error;
glyph->max_points = 0;
glyph->max_contours = 0;
glyph->root.bitmap.buffer = 0;
- error = FT_New_Outline( library, 0, 0, &glyph->root.outline );
- if (error) return error;
-
-#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
- error = T1_New_Glyph_Hinter( glyph );
- if (error)
- FT_Done_Outline( library, &glyph->root.outline );
-#endif
-
- return error;
+ return FT_New_Outline( library, 0, 0, &glyph->root.outline );
}
--- a/src/type1z/t1tokens.h
+++ b/src/type1z/t1tokens.h
@@ -30,8 +30,8 @@
PARSE_INT("ItalicAngle",italic_angle)
PARSE_BOOL("isFixedPitch",is_fixed_pitch)
- PARSE_INT("UnderlinePosition",underline_position)
- PARSE_INT("UnderlineThickness",underline_thickness)
+ PARSE_NUM("UnderlinePosition",underline_position,T1_Short)
+ PARSE_NUM("UnderlineThickness",underline_thickness,T1_UShort)
/* define the private dict parsing callbacks */
@@ -62,8 +62,8 @@
/* define the top-level dictionary parsing callbacks */
/* PARSE_STRING( "FontName", font_name ) -- handled by special routine */
- PARSE_INT( "PaintType", paint_type )
- PARSE_INT( "FontType", font_type )
+ PARSE_NUM( "PaintType", paint_type, T1_Byte )
+ PARSE_NUM( "FontType", font_type, T1_Byte )
PARSE_FIXEDS2( "FontMatrix", 4, font_matrix )
/* PARSE_COORDS2( "FontBBox", 4, font_bbox ) -- handled by special func */
PARSE_INT( "StrokeWidth", stroke_width )
--- a/src/type1z/type1z.c
+++ b/src/type1z/type1z.c
@@ -33,9 +33,6 @@
#include <t1load.c>
#include <t1objs.c>
#include <t1driver.c>
-/*
-#include <t1hinter.c>
#include <t1gload.c>
#include <t1encode.c>
-*/