freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2] ewaldhew-cleaned f5631c9 32/41: [psaux] Extend Adobe interpr


From: Hew Yih Shiuan Ewald
Subject: [freetype2] ewaldhew-cleaned f5631c9 32/41: [psaux] Extend Adobe interpreter. (seac)
Date: Mon, 21 Aug 2017 02:20:00 -0400 (EDT)

branch: ewaldhew-cleaned
commit f5631c9957d8add85075448b7daf8a5aa9d96eb8
Author: Ewald Hew <address@hidden>
Commit: Ewald Hew <address@hidden>

    [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.
---
 src/psaux/psft.c     |  68 +++++++++++++++++++
 src/psaux/psft.h     |   8 +++
 src/psaux/psintrp.c  | 182 +++++++++++++++++++++++++++++++++++++++++++++++++--
 src/psaux/t1decode.c |  49 ++++++++++++++
 src/psaux/t1decode.h |   3 +
 5 files changed, 303 insertions(+), 7 deletions(-)

diff --git a/src/psaux/psft.c b/src/psaux/psft.c
index 81d3fd8..b12d9d1 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 1628970..95e7954 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 5705af0..e4018c9 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 81f5797..37790c5 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 12c27de..1ca7e01 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,



reply via email to

[Prev in Thread] Current Thread [Next in Thread]