summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEwald Hew <ewaldhew@gmail.com>2017-07-24 11:42:07 +0800
committerEwald Hew <ewaldhew@gmail.com>2017-08-21 14:17:43 +0800
commitf5631c9957d8add85075448b7daf8a5aa9d96eb8 (patch)
tree43318e189a2bb9a70daec334c895febe8f9f3bd1
parent5242f8cf4e8f445a6e44c669fd61ce53b367161e (diff)
downloadfreetype2-f5631c9957d8add85075448b7daf8a5aa9d96eb8.tar.gz
[psaux] Extend Adobe interpreter. (seac)
This concludes the changes needed to add Type 1 support. * src/psaux/psintrp.c (cf2_interpT2CharString): Update includes. <seac>: Implement this similarly to implied seac for CFF. * src/psaux/t1decode.c: New function to lookup the glyph index. * src/psaux/psft.c: New procedures cf2_getT1SeacComponent and cf2_freeT1SeacComponent to get the charstrings for seac components. * src/psaux/t1decode.h, src/psaux/psft.h: Update declarations.
-rw-r--r--src/psaux/psft.c68
-rw-r--r--src/psaux/psft.h8
-rw-r--r--src/psaux/psintrp.c182
-rw-r--r--src/psaux/t1decode.c49
-rw-r--r--src/psaux/t1decode.h3
5 files changed, 303 insertions, 7 deletions
diff --git a/src/psaux/psft.c b/src/psaux/psft.c
index 81d3fd835..b12d9d163 100644
--- a/src/psaux/psft.c
+++ b/src/psaux/psft.c
@@ -705,6 +705,74 @@
}
+ FT_LOCAL_DEF( FT_Error )
+ cf2_getT1SeacComponent( PS_Decoder* decoder,
+ FT_UInt glyph_index,
+ CF2_Buffer buf )
+ {
+ FT_Data glyph_data;
+ FT_Error error = FT_Err_Ok;
+ T1_Face face = (T1_Face)decoder->builder.face;
+ T1_Font type1 = &face->type1;
+
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+ FT_Incremental_InterfaceRec *inc =
+ face->root.internal->incremental_interface;
+ /* For incremental fonts get the character data using the */
+ /* callback function. */
+ if ( inc )
+ error = inc->funcs->get_glyph_data( inc->object,
+ glyph_index, &glyph_data );
+ else
+#endif
+ /* For ordinary fonts get the character data stored in the face record. */
+ {
+ glyph_data.pointer = type1->charstrings[glyph_index];
+ glyph_data.length = (FT_Int)type1->charstrings_len[glyph_index];
+ }
+
+ if ( !error )
+ {
+ FT_Byte* charstring_base = (FT_Byte*)glyph_data.pointer;
+ FT_ULong charstring_len = (FT_ULong)glyph_data.length;
+
+
+ FT_ASSERT( charstring_base + charstring_len >= charstring_base );
+
+ FT_ZERO( buf );
+ buf->start =
+ buf->ptr = charstring_base;
+ buf->end = charstring_base + charstring_len;
+ }
+
+ return error;
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_freeT1SeacComponent( PS_Decoder* decoder,
+ CF2_Buffer buf )
+ {
+ T1_Face face;
+ FT_Data data;
+
+
+ FT_ASSERT( decoder );
+
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+ face = (T1_Face)decoder->builder.face;
+
+ data.pointer = buf->start;
+ data.length = (FT_Int)( buf->end - buf->start );
+
+ if ( face->root.internal->incremental_interface )
+ face->root.internal->incremental_interface->funcs->free_glyph_data(
+ face->root.internal->incremental_interface->object,
+ &data );
+#endif /* FT_CONFIG_OPTION_INCREMENTAL */
+ }
+
+
FT_LOCAL_DEF( CF2_Int )
cf2_initLocalRegionBuffer( PS_Decoder* decoder,
CF2_Int subrNum,
diff --git a/src/psaux/psft.h b/src/psaux/psft.h
index 1628970cc..95e79542f 100644
--- a/src/psaux/psft.h
+++ b/src/psaux/psft.h
@@ -131,6 +131,14 @@ FT_BEGIN_HEADER
cf2_getNominalWidthX( PS_Decoder* decoder );
+ FT_LOCAL( FT_Error )
+ cf2_getT1SeacComponent( PS_Decoder* decoder,
+ FT_UInt glyph_index,
+ CF2_Buffer buf );
+ FT_LOCAL( void )
+ cf2_freeT1SeacComponent( PS_Decoder* decoder,
+ CF2_Buffer buf );
+
/*
* FreeType client outline
*
diff --git a/src/psaux/psintrp.c b/src/psaux/psintrp.c
index 5705af063..e4018c916 100644
--- a/src/psaux/psintrp.c
+++ b/src/psaux/psintrp.c
@@ -47,8 +47,9 @@
#include "psintrp.h"
#include "pserror.h"
-#include "psobjs.h" /* for cff_random */
+#include "psobjs.h" /* for cff_random */
+#include "t1decode.h" /* for t1 seac */
/*************************************************************************/
/* */
@@ -1289,12 +1290,179 @@
FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
else
{
- return t1operator_seac( decoder,
- top[0],
- top[1],
- top[2],
- Fix2Int( top[3] ),
- Fix2Int( top[4] ) );
+ FT_Error error2;
+ CF2_Int bchar_index, achar_index;
+ FT_Vector left_bearing, advance;
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+ T1_Face face = (T1_Face)decoder->builder.face;
+#endif
+ CF2_BufferRec component;
+ CF2_Fixed dummyWidth;
+
+ CF2_Int achar = cf2_stack_popInt( opStack );
+ CF2_Int bchar = cf2_stack_popInt( opStack );
+
+ FT_Pos ady = cf2_stack_popFixed ( opStack );
+ FT_Pos adx = cf2_stack_popFixed ( opStack );
+ FT_Pos asb = cf2_stack_popFixed ( opStack );
+
+
+ FT_TRACE4(( " seac\n" ));
+
+ if ( doingSeac )
+ {
+ FT_ERROR(( " nested seac\n" ));
+ lastError = FT_THROW( Invalid_Glyph_Format );
+ goto exit; /* nested seac */
+ }
+
+ if ( decoder->builder.metrics_only )
+ {
+ FT_ERROR(( " unexpected seac\n" ));
+ lastError = FT_THROW( Invalid_Glyph_Format );
+ goto exit; /* unexpected seac */
+ }
+
+ /* `glyph_names' is set to 0 for CID fonts which do not */
+ /* include an encoding. How can we deal with these? */
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+ if ( decoder->glyph_names == 0 &&
+ !face->root.internal->incremental_interface )
+#else
+ if ( decoder->glyph_names == 0 )
+#endif /* FT_CONFIG_OPTION_INCREMENTAL */
+ {
+ FT_ERROR(( "cf2_interpT2CharString: (Type 1 seac)"
+ " glyph names table not available in this font\n" ));
+ lastError = FT_THROW( Invalid_Glyph_Format );
+ goto exit;
+ }
+
+
+ /* seac weirdness */
+ adx += decoder->builder.left_bearing->x;
+
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+ if ( face->root.internal->incremental_interface )
+ {
+ /* the caller must handle the font encoding also */
+ bchar_index = bchar;
+ achar_index = achar;
+ }
+ else
+#endif
+ {
+ bchar_index = t1_lookup_glyph_by_stdcharcode_ps( decoder, bchar );
+ achar_index = t1_lookup_glyph_by_stdcharcode_ps( decoder, achar );
+ }
+
+ if ( bchar_index < 0 || achar_index < 0 )
+ {
+ FT_ERROR(( "cf2_interpT2CharString: (Type 1 seac)"
+ " invalid seac character code arguments\n" ));
+ lastError = FT_THROW( Invalid_Glyph_Format );
+ goto exit;
+ }
+
+ /* if we are trying to load a composite glyph, do not load the */
+ /* accent character and return the array of subglyphs. */
+ if ( decoder->builder.no_recurse )
+ {
+ FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph;
+ FT_GlyphLoader loader = glyph->internal->loader;
+ FT_SubGlyph subg;
+
+
+ /* reallocate subglyph array if necessary */
+ error2 = FT_GlyphLoader_CheckSubGlyphs( loader, 2 );
+ if ( error2 )
+ {
+ lastError = error2; /* pass FreeType error through */
+ goto exit;
+ }
+
+ subg = loader->current.subglyphs;
+
+ /* subglyph 0 = base character */
+ subg->index = bchar_index;
+ subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
+ FT_SUBGLYPH_FLAG_USE_MY_METRICS;
+ subg->arg1 = 0;
+ subg->arg2 = 0;
+ subg++;
+
+ /* subglyph 1 = accent character */
+ subg->index = achar_index;
+ subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;
+ subg->arg1 = (FT_Int)FIXED_TO_INT( adx - asb );
+ subg->arg2 = (FT_Int)FIXED_TO_INT( ady );
+
+ /* set up remaining glyph fields */
+ glyph->num_subglyphs = 2;
+ glyph->subglyphs = loader->base.subglyphs;
+ glyph->format = FT_GLYPH_FORMAT_COMPOSITE;
+
+ loader->current.num_subglyphs = 2;
+
+ goto exit;
+ }
+
+ /* First load `bchar' in builder */
+ /* now load the unscaled outline */
+
+ FT_GlyphLoader_Prepare( decoder->builder.loader ); /* prepare loader */
+
+ error2 = cf2_getT1SeacComponent( decoder, (FT_UInt)bchar_index, &component );
+ if ( error2 )
+ {
+ lastError = error2; /* pass FreeType error through */
+ goto exit;
+ }
+ cf2_interpT2CharString( font,
+ &component,
+ callbacks,
+ translation,
+ TRUE,
+ 0,
+ 0,
+ &dummyWidth );
+ cf2_freeT1SeacComponent( decoder, &component );
+
+ /* save the left bearing and width of the base character */
+ /* as they will be erased by the next load. */
+
+ left_bearing = *decoder->builder.left_bearing;
+ advance = *decoder->builder.advance;
+
+ decoder->builder.left_bearing->x = 0;
+ decoder->builder.left_bearing->y = 0;
+
+ /* Now load `achar' on top of */
+ /* the base outline */
+
+ error2 = cf2_getT1SeacComponent( decoder, (FT_UInt)achar_index, &component );
+ if ( error2 )
+ {
+ lastError = error2; /* pass FreeType error through */
+ goto exit;
+ }
+ cf2_interpT2CharString( font,
+ &component,
+ callbacks,
+ translation,
+ TRUE,
+ adx - asb,
+ ady,
+ &dummyWidth );
+ cf2_freeT1SeacComponent( decoder, &component );
+
+ /* restore the left side bearing and */
+ /* advance width of the base character */
+
+ *decoder->builder.left_bearing = left_bearing;
+ *decoder->builder.advance = advance;
+
+ goto exit;
}
}
break;
diff --git a/src/psaux/t1decode.c b/src/psaux/t1decode.c
index 81f579744..37790c50b 100644
--- a/src/psaux/t1decode.c
+++ b/src/psaux/t1decode.c
@@ -112,6 +112,55 @@
/*************************************************************************/
/* */
/* <Function> */
+ /* t1_lookup_glyph_by_stdcharcode_ps */
+ /* */
+ /* <Description> */
+ /* Looks up a given glyph by its StandardEncoding charcode. Used to */
+ /* implement the SEAC Type 1 operator in the Adobe engine */
+ /* */
+ /* <Input> */
+ /* face :: The current face object. */
+ /* */
+ /* charcode :: The character code to look for. */
+ /* */
+ /* <Return> */
+ /* A glyph index in the font face. Returns -1 if the corresponding */
+ /* glyph wasn't found. */
+ /* */
+ FT_LOCAL_DEF( FT_Int )
+ t1_lookup_glyph_by_stdcharcode_ps( PS_Decoder* decoder,
+ FT_Int charcode )
+ {
+ FT_UInt n;
+ const FT_String* glyph_name;
+ FT_Service_PsCMaps psnames = decoder->psnames;
+
+
+ /* check range of standard char code */
+ if ( charcode < 0 || charcode > 255 )
+ return -1;
+
+ glyph_name = psnames->adobe_std_strings(
+ psnames->adobe_std_encoding[charcode]);
+
+ for ( n = 0; n < decoder->num_glyphs; n++ )
+ {
+ FT_String* name = (FT_String*)decoder->glyph_names[n];
+
+
+ if ( name &&
+ name[0] == glyph_name[0] &&
+ ft_strcmp( name, glyph_name ) == 0 )
+ return (FT_Int)n;
+ }
+
+ return -1;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
/* t1_lookup_glyph_by_stdcharcode */
/* */
/* <Description> */
diff --git a/src/psaux/t1decode.h b/src/psaux/t1decode.h
index 12c27de77..1ca7e013d 100644
--- a/src/psaux/t1decode.h
+++ b/src/psaux/t1decode.h
@@ -31,6 +31,9 @@ FT_BEGIN_HEADER
FT_CALLBACK_TABLE
const T1_Decoder_FuncsRec t1_decoder_funcs;
+ FT_LOCAL( FT_Int )
+ t1_lookup_glyph_by_stdcharcode_ps( PS_Decoder* decoder,
+ FT_Int charcode );
FT_LOCAL( FT_Error )
t1_decoder_parse_glyph( T1_Decoder decoder,