Commit b85d4e8f0403b245492ac8222a78e8fc9e465050

Werner Lemberg 2018-06-12T05:53:58

Finish CPAL/COLR support (2/4). * src/sfnt/ttcolr.c (tt_face_palette_set): New function. (tt_face_load_colr): Allocate `face->palette' and call `tt_face_palette_set'. Adjust return error code in case of error. * src/sfnt/ttcolr.h: Updated. * include/freetype/internal/sfnt.h (TT_Set_Palette_Func): New function type. (SFNT_Interface, FT_DEFINE_SFNT_INTERFACE): Add it. * src/sfnt/sfdriver.c (sfnt_interface), src/sfnt/sfobjs.c (sfnt_done_face): Updated.

diff --git a/ChangeLog b/ChangeLog
index b69f740..604d3e5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,23 @@
 2018-06-12  Werner Lemberg  <wl@gnu.org>
 
+	Finish CPAL/COLR support (2/4).
+
+	* src/sfnt/ttcolr.c (tt_face_palette_set): New function.
+	(tt_face_load_colr): Allocate `face->palette' and call
+	`tt_face_palette_set'.
+	Adjust return error code in case of error.
+
+	* src/sfnt/ttcolr.h: Updated.
+
+	* include/freetype/internal/sfnt.h (TT_Set_Palette_Func): New
+	function type.
+	(SFNT_Interface, FT_DEFINE_SFNT_INTERFACE): Add it.
+
+	* src/sfnt/sfdriver.c (sfnt_interface), src/sfnt/sfobjs.c
+	(sfnt_done_face): Updated.
+
+2018-06-12  Werner Lemberg  <wl@gnu.org>
+
 	Finish CPAL/COLR support (1/4).
 
 	* include/freetype/internal/tttypes.h (TT_FaceRec): New fields
diff --git a/include/freetype/internal/sfnt.h b/include/freetype/internal/sfnt.h
index 00b7ae5..7270d12 100644
--- a/include/freetype/internal/sfnt.h
+++ b/include/freetype/internal/sfnt.h
@@ -472,6 +472,29 @@ FT_BEGIN_HEADER
   /**************************************************************************
    *
    * @FuncType:
+   *   TT_Set_Palette_Func
+   *
+   * @Description:
+   *   Load the colors into `face->palette' for a given palette index.
+   *
+   * @Input:
+   *   face ::
+   *     The target face object.
+   *
+   *   idx ::
+   *     The palette index.
+   *
+   * @Return:
+   *   FreeType error code.  0 means success.
+   */
+  typedef FT_Error
+  (*TT_Set_Palette_Func)( TT_Face  face,
+                          FT_UInt  idx );
+
+
+  /**************************************************************************
+   *
+   * @FuncType:
    *   TT_Load_Colr_Layer_Func
    *
    * @Description:
@@ -739,6 +762,7 @@ FT_BEGIN_HEADER
 
     TT_Load_Table_Func           load_colr;
     TT_Free_Table_Func           free_colr;
+    TT_Set_Palette_Func          set_palette;
     TT_Load_Colr_Layer_Func      load_colr_layer;
     TT_Blend_Colr_Func           colr_blend;
 
@@ -786,6 +810,7 @@ FT_BEGIN_HEADER
           load_strike_metrics_,          \
           load_colr_,                    \
           free_colr_,                    \
+          set_palette_,                  \
           load_colr_layer_,              \
           colr_blend_,                   \
           get_metrics_,                  \
@@ -823,6 +848,7 @@ FT_BEGIN_HEADER
     load_strike_metrics_,                \
     load_colr_,                          \
     free_colr_,                          \
+    set_palette_,                        \
     load_colr_layer_,                    \
     colr_blend_,                         \
     get_metrics_,                        \
diff --git a/src/sfnt/sfdriver.c b/src/sfnt/sfdriver.c
index 6005771..dd3f801 100644
--- a/src/sfnt/sfdriver.c
+++ b/src/sfnt/sfdriver.c
@@ -1261,6 +1261,8 @@
                             /* TT_Load_Table_Func      load_colr       */
     PUT_COLOR_LAYERS( tt_face_free_colr ),
                             /* TT_Free_Table_Func      free_colr       */
+    PUT_COLOR_LAYERS( tt_face_palette_set ),
+                            /* TT_Set_Palette_Func     set_palette     */
     PUT_COLOR_LAYERS( tt_face_load_colr_layers ),
                             /* TT_Load_Colr_Layer_Func load_colr_layer */
     PUT_COLOR_LAYERS( tt_face_colr_blend_layer ),
diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index 67b5ff4..6a431ed 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -1812,6 +1812,7 @@
     FT_FREE( face->palette_data.palette_name_ids );
     FT_FREE( face->palette_data.palette_types );
     FT_FREE( face->palette_data.palette_entry_name_ids );
+    FT_FREE( face->palette );
 
     face->sfnt = NULL;
   }
diff --git a/src/sfnt/ttcolr.c b/src/sfnt/ttcolr.c
index 8e232c3..9783b70 100644
--- a/src/sfnt/ttcolr.c
+++ b/src/sfnt/ttcolr.c
@@ -289,16 +289,26 @@
 
     face->colr_and_cpal = cc;
 
+    /* set up default palette */
+    if ( FT_NEW_ARRAY( face->palette,
+                       face->palette_data.num_palette_entries ) )
+      goto NoColor;
+
+    tt_face_palette_set( face, 0 );
+
     return FT_Err_Ok;
 
   InvalidTable:
-    error = FT_THROW( Invalid_File_Format );
+    error = FT_THROW( Invalid_Table );
 
   NoColor:
     FT_FRAME_RELEASE( colr_table );
     FT_FRAME_RELEASE( cpal_table );
 
-    /* arrays in `face->palette_data' are freed in `sfnt_face_done' */
+    FT_FREE( cc );
+
+    /* arrays in `face->palette_data' and `face->palette' */
+    /* are freed in `sfnt_done_face'                      */
 
     return error;
   }
@@ -463,6 +473,43 @@
 
 
   FT_LOCAL_DEF( FT_Error )
+  tt_face_palette_set( TT_Face  face,
+                       FT_UInt  palette_index )
+  {
+    ColrCpal*  colr_and_cpal = (ColrCpal *)face->colr_and_cpal;
+    Cpal*      cpal          = &colr_and_cpal->cpal;
+
+    FT_Byte*   offset;
+    FT_Byte*   p;
+
+    FT_Color*  q;
+    FT_Color*  limit;
+
+
+    if ( palette_index >= face->palette_data.num_palettes )
+      return FT_THROW( Invalid_Argument );
+
+    offset = cpal->color_indices + 2 * palette_index;
+    p      = cpal->colors + COLOR_SIZE * FT_PEEK_USHORT( offset );
+
+    q     = face->palette;
+    limit = q + face->palette_data.num_palette_entries * sizeof ( FT_Color );
+
+    while ( q < limit )
+    {
+      q->blue  = FT_NEXT_BYTE( p );
+      q->green = FT_NEXT_BYTE( p );
+      q->red   = FT_NEXT_BYTE( p );
+      q->alpha = FT_NEXT_BYTE( p );
+
+      q++;
+    }
+
+    return FT_Err_Ok;
+  }
+
+
+  FT_LOCAL_DEF( FT_Error )
   tt_face_colr_blend_layer( TT_Face       face,
                             FT_UInt       color_index,
                             FT_GlyphSlot  dstSlot,
diff --git a/src/sfnt/ttcolr.h b/src/sfnt/ttcolr.h
index 1e1b4a2..bb9b407 100644
--- a/src/sfnt/ttcolr.h
+++ b/src/sfnt/ttcolr.h
@@ -43,6 +43,10 @@ FT_BEGIN_HEADER
                             FT_UShort*       ret_num_layers );
 
   FT_LOCAL( FT_Error )
+  tt_face_palette_set( TT_Face  face,
+                       FT_UInt  palette_index );
+
+  FT_LOCAL( FT_Error )
   tt_face_colr_blend_layer( TT_Face       face,
                             FT_UInt       color_index,
                             FT_GlyphSlot  dstSlot,