freetype-commit
[Top][All Lists]
Advanced

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

[freetype2] parthw-cleaned 743b415: [gf] Change `cmap' encoding scheme.


From: Parth Wazurkar
Subject: [freetype2] parthw-cleaned 743b415: [gf] Change `cmap' encoding scheme.
Date: Sun, 12 Aug 2018 02:07:45 -0400 (EDT)

branch: parthw-cleaned
commit 743b415ca95ad25722a2fb260920cfab21220479
Author: Parth Wazurkar <address@hidden>
Commit: Parth Wazurkar <address@hidden>

    [gf] Change `cmap' encoding scheme.
    
    * src/gf/gfdrivr.c(GF_Face_Init):
      - Change `gf_cmap_class' functions to use new encoding
        scheme.
      - Set charmap to `0: synthetic, platform 0, encoding  0
        language 0' values.
    
    * src/gf/gflib.c(gf_set_encodings, gf_load_font): Modify
      to set encoding so as to load glyphs in the order they appear
      in the font file.
---
 src/gf/gfdrivr.c | 145 ++++++++++++++++++++++++++++++++++-------------
 src/gf/gfdrivr.h |  15 +++++
 src/gf/gflib.c   | 170 ++++++++++++++++++++++++++++++++++++++++++++++++-------
 3 files changed, 270 insertions(+), 60 deletions(-)

diff --git a/src/gf/gfdrivr.c b/src/gf/gfdrivr.c
index 7b01530..e51f10a 100644
--- a/src/gf/gfdrivr.c
+++ b/src/gf/gfdrivr.c
@@ -43,9 +43,9 @@
 
   typedef struct  GF_CMapRec_
   {
-    FT_CMapRec        cmap;
-    FT_UInt32         bc;       /* Beginning Character */
-    FT_UInt32         ec;       /* End Character */
+    FT_CMapRec      cmap;
+    FT_ULong        num_encodings;
+    GF_Encoding     encodings;
   } GF_CMapRec, *GF_CMap;
 
 
@@ -57,8 +57,8 @@
     GF_Face  face = (GF_Face)FT_CMAP_FACE( cmap );
     FT_UNUSED( init_data );
 
-    cmap->bc     = face->gf_glyph->code_min;
-    cmap->ec     = face->gf_glyph->code_max;
+    cmap->num_encodings = face->gf_glyph->nencodings;
+    cmap->encodings     = face->gf_glyph->encodings;
 
     return FT_Err_Ok;
   }
@@ -69,54 +69,98 @@
   {
     GF_CMap  cmap = (GF_CMap)gfcmap;
 
-    cmap->bc     =  0;
-    cmap->ec     = -1;
+    cmap->encodings     = NULL;
+    cmap->num_encodings = 0;
 
   }
 
 
   FT_CALLBACK_DEF( FT_UInt )
   gf_cmap_char_index(  FT_CMap    gfcmap,
-                       FT_UInt32  char_code )
+                       FT_UInt32  charcode )
   {
-    FT_UInt  gindex = 0;
-    GF_CMap  cmap   = (GF_CMap)gfcmap;
+    GF_CMap       cmap      = (GF_CMap)gfcmap;
+    GF_Encoding   encodings = cmap->encodings;
+    FT_ULong      min, max, mid;
+    FT_UInt       result    = 0;
 
-    char_code -= cmap->bc;
+    min = 0;
+    max = cmap->num_encodings;
 
-    if ( char_code < cmap->ec - cmap->bc + 1 )
-      gindex = (FT_UInt)( char_code );
+    while ( min < max )
+    {
+      FT_ULong  code;
+
+
+      mid  = ( min + max ) >> 1;
+      code = (FT_ULong)encodings[mid].enc;
+
+      if ( charcode == code )
+      {
+        result = encodings[mid].glyph;
+        break;
+      }
+
+      if ( charcode < code )
+        max = mid;
+      else
+        min = mid + 1;
+    }
 
-    return gindex;
+    return result;
   }
 
   FT_CALLBACK_DEF( FT_UInt )
   gf_cmap_char_next(  FT_CMap     gfcmap,
-                      FT_UInt32  *achar_code )
+                      FT_UInt32  *acharcode )
   {
-    GF_CMap    cmap   = (GF_CMap)gfcmap;
-    FT_UInt    gindex = 0;
-    FT_UInt32  result = 0;
-    FT_UInt32  char_code = *achar_code + 1;
+    GF_CMap       cmap      = (GF_CMap)gfcmap;
+    GF_Encoding   encodings = cmap->encodings;
+    FT_ULong      min, max, mid;
+    FT_ULong      charcode  = *acharcode + 1;
+    FT_UInt       result    = 0;
 
 
-    if ( char_code <= cmap->bc )
-    {
-      result = cmap->bc;
-      gindex = 1;
-    }
-    else
+    min = 0;
+    max = cmap->num_encodings;
+
+    while ( min < max )
     {
-      char_code -= cmap->bc;
-      if ( char_code < cmap->ec - cmap->bc + 1 )
+      FT_ULong  code;
+
+
+      mid  = ( min + max ) >> 1;
+      code = (FT_ULong)encodings[mid].enc;
+
+      if ( charcode == code )
       {
-        result = char_code;
-        gindex = (FT_UInt)( char_code );
+        result = encodings[mid].glyph + 1;
+        goto Exit;
       }
+
+      if ( charcode < code )
+        max = mid;
+      else
+        min = mid + 1;
     }
 
-    *achar_code = result;
-    return gindex;
+    charcode = 0;
+    if ( min < cmap->num_encodings )
+    {
+      charcode = (FT_ULong)encodings[min].enc;
+      result   = encodings[min].glyph ;
+    }
+
+  Exit:
+    if ( charcode > 0xFFFFFFFFUL )
+    {
+      FT_TRACE1(( "gf_cmap_char_next: charcode 0x%x > 32bit API" ));
+      *acharcode = 0;
+      /* XXX: result should be changed to indicate an overflow error */
+    }
+    else
+      *acharcode = (FT_UInt32)charcode;
+    return result;
   }
 
 
@@ -145,9 +189,10 @@
 
     memory = FT_FACE_MEMORY( face );
 
-    gf_free_font( face );
-
     FT_FREE( gfface->available_sizes );
+    FT_FREE( face->gf_glyph->encodings );
+
+    gf_free_font( face );
 
   }
 
@@ -270,15 +315,37 @@
                                          y_res ); ;
     }
 
+    /* set up charmap */
+    {
+      /* FT_Bool     unicode_charmap ; */
+
+      /*
+       * XXX: TO-DO
+       * Currently the unicode_charmap is set to `0'
+       * The functionality of extracting coding scheme
+       * from `xxx' and `yyy' commands will be used to
+       * set the unicode_charmap.
+      */
+    }
+
     /* Charmaps */
     {
       FT_CharMapRec  charmap;
+      FT_Bool        unicode_charmap = 0;
 
-      /* Unicode Charmap */
-      charmap.encoding    = FT_ENCODING_UNICODE;
-      charmap.platform_id = TT_PLATFORM_MICROSOFT;
-      charmap.encoding_id = TT_MS_ID_UNICODE_CS;
       charmap.face        = FT_FACE( face );
+      charmap.encoding    = FT_ENCODING_NONE;
+      /* initial platform/encoding should indicate unset status? */
+      charmap.platform_id = TT_PLATFORM_APPLE_UNICODE;
+      charmap.encoding_id = TT_APPLE_ID_DEFAULT;
+
+      if( unicode_charmap )
+      {
+        /* Unicode Charmap */
+        charmap.encoding    = FT_ENCODING_UNICODE;
+        charmap.platform_id = TT_PLATFORM_MICROSOFT;
+        charmap.encoding_id = TT_MS_ID_UNICODE_CS;
+      }
 
       error = FT_CMap_New( &gf_cmap_class, NULL, &charmap, NULL );
 
@@ -387,7 +454,7 @@
       goto Exit;
     }
 
-    FT_TRACE1(( "GF_Glyph_Load: glyph index %d\n", glyph_index ));
+    FT_TRACE1(( "GF_Glyph_Load: glyph index %d charcode is %d\n", glyph_index, 
go->bm_table[glyph_index].code ));
 
     if ( (FT_Int)glyph_index < 0 )
       glyph_index = 0;
@@ -563,7 +630,7 @@
   }
 
 
-   FT_CALLBACK_TABLE_DEF
+  FT_CALLBACK_TABLE_DEF
   const FT_Driver_ClassRec  gf_driver_class =
   {
     {
diff --git a/src/gf/gfdrivr.h b/src/gf/gfdrivr.h
index b6e25ab..5df04e9 100644
--- a/src/gf/gfdrivr.h
+++ b/src/gf/gfdrivr.h
@@ -27,6 +27,14 @@
 
 FT_BEGIN_HEADER
 
+
+  typedef struct  GF_EncodingRec_
+  {
+    FT_Long   enc;
+    FT_UShort  glyph;
+
+  } GF_EncodingRec, *GF_Encoding;
+
   /* BitmapRec for GF format specific glyphs  */
   typedef struct GF_BitmapRec_
   {
@@ -35,6 +43,8 @@ FT_BEGIN_HEADER
     FT_Long         mv_x,  mv_y;
     FT_Byte         *bitmap;
     FT_UInt         raster;
+    FT_UShort       code;
+    FT_ULong        nglyphs;
 
   } GF_BitmapRec, *GF_Bitmap;
 
@@ -47,6 +57,11 @@ FT_BEGIN_HEADER
     FT_Int          font_bbx_w, font_bbx_h;
     FT_Int          font_bbx_xoff, font_bbx_yoff;
 
+    FT_ULong        nencodings;
+    GF_Encoding     encodings;
+
+    FT_ULong        nglyphs;
+
   } GF_GlyphRec, *GF_Glyph;
 
 
diff --git a/src/gf/gflib.c b/src/gf/gflib.c
index 25bb3b6..0efbb90 100644
--- a/src/gf/gflib.c
+++ b/src/gf/gflib.c
@@ -43,6 +43,14 @@
 FT_Byte  bit_table[] = {
   0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
 
+  typedef struct GF_CharOffsetRec_
+  {
+    FT_Long         char_offset;
+    FT_UShort       code;
+    FT_Short        gid;
+
+  } GF_CharOffsetRec, *GF_CharOffset;
+
   /**************************************************************************
    *
    * GF font utility functions.
@@ -111,12 +119,80 @@ FT_Byte  bit_table[] = {
     return v;
   }
 
+  static int
+  compare( FT_Long*  a,
+           FT_Long*  b )
+  {
+    if ( *a < *b )
+      return -1;
+    else if ( *a > *b )
+      return 1;
+    else
+      return 0;
+  }
+
   /**************************************************************************
    *
    * API.
    *
    */
 
+  static FT_Error
+  gf_set_encodings( GF_CharOffset of,
+                    FT_Int        ngphs,
+                    GF_Glyph      go,
+                    FT_Memory     memory )
+  {
+    FT_Error      error;
+    FT_ULong      nencoding;
+    FT_Int        i, j;
+    FT_ULong      k;
+    GF_Encoding   encoding = NULL;
+    FT_Long       *tosort;
+
+    nencoding = ngphs;
+    FT_TRACE2(( "gf_set_encodings: Reached here.\n" ));
+
+    if ( FT_NEW_ARRAY( encoding, nencoding ) )
+      return error;
+
+    if ( FT_NEW_ARRAY( tosort, nencoding ) )
+      return error;
+
+
+    FT_TRACE2(( "gf_set_encodings: Allocated sufficient memory.\n" ));
+
+    for( i = 0 ; i < 256 ; i++ )
+    {
+      if( of[i].char_offset >= 0 )
+        tosort[i] = of[i].char_offset;
+    }
+
+    ft_qsort( (void*)tosort, ngphs, sizeof(FT_Long),
+               (int(*)(const void*, const void*) )compare );
+
+    k = 0;
+    for ( i = 0; i < ngphs; i++ )
+    {
+      for ( j = 0; j < 256; j++ )
+      {
+        if( of[j].char_offset == tosort[i] )
+        break;
+      }
+      encoding[k].enc   = of[j].code;
+      encoding[k].glyph = k;
+      of[j].gid         = k;
+      k++;
+    }
+
+    FT_FREE(tosort);
+
+    go->nencodings = k;
+    go->encodings  = encoding;
+
+    return error;
+  }
+
   FT_LOCAL_DEF( FT_Error )
   gf_read_glyph( FT_Stream    stream,
                  GF_Bitmap    bm,
@@ -314,16 +390,17 @@ FT_Byte  bit_table[] = {
                  FT_Memory    extmemory,
                  GF_Glyph     *goptr  )
   {
-    GF_Glyph        go;
-    GF_Bitmap       bm;
-    FT_Byte         instr, d, pre, id, k, code;
-    FT_Long         ds, check_sum, hppp, vppp;
-    FT_Long         min_m, max_m, min_n, max_n, w;
-    FT_UInt         dx, dy;
-    FT_Long         ptr_post, ptr_p, ptr, optr;
-    FT_Int          bc, ec, nchars, i;
-    FT_Error        error  = FT_Err_Ok;
-    FT_Memory       memory = extmemory; /* needed for FT_NEW */
+    GF_Glyph         go;
+    GF_Bitmap        bm;
+    GF_CharOffset    of;
+    FT_Byte          instr, d, pre, id, k, code;
+    FT_Long          ds, check_sum, hppp, vppp;
+    FT_Long          min_m, max_m, min_n, max_n, w;
+    FT_UInt          dx, dy;
+    FT_Long          ptr_post, ptr_p, ptr, optr, rptr;
+    FT_Int           bc, ec, nchars, i, ngphs, idx;
+    FT_Error         error  = FT_Err_Ok;
+    FT_Memory        memory = extmemory; /* needed for FT_NEW */
 
     go = NULL;
     nchars = -1;
@@ -502,11 +579,16 @@ FT_Byte  bit_table[] = {
     go->code_min = bc;
     go->code_max = ec;
 
-    /* read glyph */
-    #if 0
-      fseek(fp, gptr, SEEK_SET);
-    #endif
+    go->nglyphs = 0;
 
+    if( FT_ALLOC_MULT(of, sizeof(GF_CharOffsetRec), nchars) )
+      goto Exit;
+
+    for( i = 0; i < 256 ; i++)
+      of[i].char_offset = -1;
+
+    rptr = stream->pos;
+    i=0; ngphs=0;
     for (  ;  ;  )
     {
       if ((instr = READ_UINT1( stream )) == GF_POST_POST)
@@ -533,27 +615,73 @@ FT_Byte  bit_table[] = {
         goto Exit;
       }
 
-      /*
-      if( w > max_m)   Defined to use w
+      of[i].char_offset = (FT_ULong)ptr;
+      of[i].code        = (FT_UShort)code;
+      of[i].gid         = -1;
+      ngphs            += 1;
+      i++;
+    }
+
+    error = gf_set_encodings( of, ngphs, go, memory );
+    if( error )
+      goto Exit;
+
+    if( FT_STREAM_SEEK( rptr ) )
+        goto Exit;
+
+    for (  ;  ;  )
+    {
+      if ((instr = READ_UINT1( stream )) == GF_POST_POST)
+        break;
+      switch ((FT_Int)instr)
       {
-        FT_ERROR(( "gf_load_font: invalid width in charloc\n" ));
+      case GF_CHAR_LOC:
+        code = READ_UINT1( stream );
+        dx   = (FT_UInt)READ_INT4( stream )/(FT_UInt)(1<<16);
+        dy   = (FT_UInt)READ_INT4( stream )/(FT_UInt)(1<<16);
+        w    = READ_INT4( stream );
+        ptr  = READ_INT4( stream );
+        break;
+      case GF_CHAR_LOC0:
+        code = READ_UINT1( stream );
+        dx   = (FT_UInt)READ_INT1( stream );
+        dy   = (FT_UInt)0;
+        w    = READ_INT4( stream );
+        ptr  = READ_INT4( stream );
+        break;
+      default:
+        FT_ERROR(( "gf_load_font: missing character locators in postamble\n" 
));
+        error = FT_THROW( Unknown_File_Format );
         goto Exit;
       }
-      */
 
       optr = stream->pos;
       if( FT_STREAM_SEEK( ptr ) )
         goto Exit;
 
-      bm = &go->bm_table[code - bc];
+      for ( i = 0; i < 256; i++ )
+      {
+        if( of[i].code == code && of[i].char_offset == ptr )
+        {
+          idx = of[i].gid;
+          break;
+        }
+      }
+      bm = &go->bm_table[idx];
+
+      bm->mv_x     = dx;
+      bm->mv_y     = dy;
+      bm->code     = code;
+      go->nglyphs += 1;
+
       if (gf_read_glyph( stream, bm, memory ) < 0)
         goto Exit;
 
-      bm->mv_x = dx;
-      bm->mv_y = dy;
       if(FT_STREAM_SEEK( optr ))
         goto Exit;
     }
+
+    FT_FREE(of);
     *goptr          = go;
     return error;
 



reply via email to

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