freetype-commit
[Top][All Lists]
Advanced

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

[freetype2] wl/colr 9d86c63f4: Improve handling of color palettes.


From: Werner Lemberg
Subject: [freetype2] wl/colr 9d86c63f4: Improve handling of color palettes.
Date: Mon, 7 Mar 2022 11:39:36 -0500 (EST)

branch: wl/colr
commit 9d86c63f4a315738646138c57d85b49249efde86
Author: Werner Lemberg <wl@gnu.org>
Commit: Werner Lemberg <wl@gnu.org>

    Improve handling of color palettes.
    
    This commit adds new functions to streamline palette access:
    
      FT_Palette_Set: Set a user-defined palette.
      FT_Palette_Get: Get palette and palette index.
      FT_Palette_Get_Foreground_Color: Get foreground color.
    
    Fixes issue #1134.
    
    * include/freetype/internal/tttypes.h (TT_FaceRec): Change type of
    `palette_index` to `FT_Int`.  Negative values now represent user-defined
    palettes.
    
    * src/base/ftcolor.c (FT_Palette_Set, FT_Palette_Get,
    FT_Palette_Get_Foreground_Color): New functions.
    
    * include/freetype/ftcolor.h: Updated.
---
 include/freetype/ftcolor.h          | 172 +++++++++++++++++++++++++++++++-----
 include/freetype/internal/tttypes.h |   2 +-
 src/base/ftcolor.c                  | 131 ++++++++++++++++++++++++++-
 3 files changed, 283 insertions(+), 22 deletions(-)

diff --git a/include/freetype/ftcolor.h b/include/freetype/ftcolor.h
index 777fa8b8c..22030b5d7 100644
--- a/include/freetype/ftcolor.h
+++ b/include/freetype/ftcolor.h
@@ -45,6 +45,12 @@ FT_BEGIN_HEADER
    * @description:
    *   The functions described here allow access and manipulation of color
    *   palette entries in OpenType's 'CPAL' tables.
+   *
+   *   FreeType maintains a 'working palette' (together with a corresponding
+   *   'working palette index'), which can be set either to a palette stored
+   *   in the font (function @FT_Palette_Select) or to a user-defined palette
+   *   (function @FT_Palette_Set).  For user-defined palettes, the working
+   *   palette index is negative, and positive otherwise.
    */
 
 
@@ -218,18 +224,13 @@ FT_BEGIN_HEADER
    *   FT_Palette_Select
    *
    * @description:
-   *   This function has two purposes.
-   *
-   *   (1) It activates a palette for rendering color glyphs, and
-   *
-   *   (2) it retrieves all (unmodified) color entries of this palette.  This
-   *       function returns a read-write array, which means that a calling
-   *       application can modify the palette entries on demand.
+   *   This function copies a palette entry in the font's 'CPAL' table into a
+   *   'working palette', which is a read-write array managed by FreeType.
+   *   It also sets the 'working palette index' to the index value given as
+   *   an argument.
    *
-   * A corollary of (2) is that calling the function, then modifying some
-   * values, then calling the function again with the same arguments resets
-   * all color entries to the original 'CPAL' values; all user modifications
-   * are lost.
+   *   The current working palette and palette index can be retrieved with
+   *   @FT_Palette_Get.
    *
    * @input:
    *   face ::
@@ -240,10 +241,10 @@ FT_BEGIN_HEADER
    *
    * @output:
    *   apalette ::
-   *     An array of color entries for a palette with index `palette_index`,
-   *     having `num_palette_entries` elements (as found in the
-   *     `FT_Palette_Data` structure).  If `apalette` is set to `NULL`, no
-   *     array gets returned (and no color entries can be modified).
+   *     A pointer to the 'working palette', which is an array of color
+   *     entries for a palette with index `palette_index`, having
+   *     `num_palette_entries` elements (as found in the `FT_Palette_Data`
+   *     structure).  If `apalette` is set to `NULL`, no array gets returned.
    *
    *     In case the font doesn't support color palettes, `NULL` is returned.
    *
@@ -266,6 +267,92 @@ FT_BEGIN_HEADER
                      FT_Color*  *apalette );
 
 
+  /**************************************************************************
+   *
+   * @function:
+   *   FT_Palette_Set
+   *
+   * @description:
+   *   Set FreeType's 'working palette' and 'working palette index' to the
+   *   given arguments.  Use this function if you want to provide a
+   *   user-defined palette, not being part of the font's 'CPAL' table.
+   *
+   *   The current working palette and palette index can be retrieved with
+   *   @FT_Palette_Get.
+   *
+   * @input:
+   *   face ::
+   *     The source face handle.
+   *
+   *   palette_index ::
+   *     A palette index, which must be an arbitrary, negative integer (since
+   *     positive values are reserved for indices from the 'CPAL' table).
+   *     FreeType sets the 'working palette index' to this value.
+   *
+   *   palette ::
+   *     A pointer to an array of color entries, having `num_palette_entries`
+   *     elements (as found in the `FT_Palette_Data` structure).  FreeType
+   *     copies this array into its 'working palette'.
+   *
+   * @return:
+   *   FreeType error code.  0~means success.
+   *
+   * @note:
+   *   This function always returns an error if the config macro
+   *   `TT_CONFIG_OPTION_COLOR_LAYERS` is not defined in `ftoption.h`.
+   *
+   * @since:
+   *   2.12
+   */
+  FT_EXPORT( FT_Error )
+  FT_Palette_Set( FT_Face    face,
+                  FT_Int     index,
+                  FT_Color*  palette );
+
+
+  /**************************************************************************
+   *
+   * @function:
+   *   FT_Palette_Get
+   *
+   * @description:
+   *   Get FreeType's 'working palette' and 'working palette index'.
+   *
+   *   The working palette and palette index can be set with @FT_Palette_Set.
+   *
+   * @input:
+   *   face ::
+   *     The source face handle.
+   *
+   * @output:
+   *   anindex ::
+   *     The 'working palette index'.  If the value is zero or positive, the
+   *     working palette represents an entry from the font's 'CPAL' table
+   *     (with the given index).  Otherwise it is a user-defined palette.  If
+   *     `anindex` is set to `NULL`, no value gets returned.
+   *
+   *   apalette ::
+   *     A pointer to the 'working palette', which is an array of color
+   *     entries for a palette having `num_palette_entries` elements (as
+   *     found in the `FT_Palette_Data` structure).  If `apalette` is set to
+   *     `NULL`, no array gets returned.
+   *
+   * @return:
+   *   FreeType error code.  0~means success.
+   *
+   * @note:
+   *   This function always returns an error if the config macro
+   *   `TT_CONFIG_OPTION_COLOR_LAYERS` is not defined in `ftoption.h`.
+   *
+   * @since:
+   *   2.12
+   */
+  FT_EXPORT( FT_Error )
+  FT_Palette_Get( FT_Face     face,
+                  FT_Int     *anindex,
+                  FT_Color*  *apalette );
+
+
   /**************************************************************************
    *
    * @function:
@@ -286,11 +373,9 @@ FT_BEGIN_HEADER
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   If this function isn't called, the text foreground color is set to
-   *   white opaque (BGRA value 0xFFFFFFFF) if
-   *   @FT_PALETTE_FOR_DARK_BACKGROUND is present for the current palette,
-   *   and black opaque (BGRA value 0x000000FF) otherwise, including the case
-   *   that no palette types are available in the 'CPAL' table.
+   *   See function @FT_Palette_Get_Foreground_Color for details on what
+   *   foreground color is used if `FT_Palette_Set_Foreground_Color` is not
+   *   called.
    *
    *   This function always returns an error if the config macro
    *   `TT_CONFIG_OPTION_COLOR_LAYERS` is not defined in `ftoption.h`.
@@ -303,6 +388,53 @@ FT_BEGIN_HEADER
                                    FT_Color  foreground_color );
 
 
+  /**************************************************************************
+   *
+   * @function:
+   *   FT_Palette_Get_Foreground_Color
+   *
+   * @description:
+   *   Get the 'text foreground color' as set by a previous call to
+   *   @FT_Palette_Set_Foreground_Color.
+   *
+   * @input:
+   *   face ::
+   *     The source face handle.
+   *
+   * @output:
+   *   aforeground_color ::
+   *     The text foreground color.
+   *
+   * @return:
+   *   FreeType error code.  0~means success.
+   *
+   * @note:
+   *   The returned color is as follows.
+   *
+   *   * If a foreground color was set with @FT_Palette_Get_Foreground_Color,
+   *     return this value.
+   *
+   *   * Otherwise, return black opaque (BGRA value 0x000000FF) if the
+   *     'working palette' is a user-defined palette.
+   *
+   *   * Otherwise, return white opaque (BGRA value 0xFFFFFFFF) if
+   *     @FT_PALETTE_FOR_DARK_BACKGROUND is present for the current palette.
+   *
+   *   * Otherwise, return black opaque (BGRA value 0x000000FF).  This
+   *     includes the case that no palette types are available in the 'CPAL'
+   *     table.
+   *
+   *   This function always returns an error if the config macro
+   *   `TT_CONFIG_OPTION_COLOR_LAYERS` is not defined in `ftoption.h`.
+   *
+   * @since:
+   *   2.12
+   */
+  FT_EXPORT( FT_Error )
+  FT_Palette_Get_Foreground_Color( FT_Face    face,
+                                   FT_Color*  aforeground_color );
+
+
   /**************************************************************************
    *
    * @section:
diff --git a/include/freetype/internal/tttypes.h 
b/include/freetype/internal/tttypes.h
index df719387b..5ecd08455 100644
--- a/include/freetype/internal/tttypes.h
+++ b/include/freetype/internal/tttypes.h
@@ -1537,7 +1537,7 @@ FT_BEGIN_HEADER
 
     /* glyph colors */
     FT_Palette_Data       palette_data;         /* since 2.10 */
-    FT_UShort             palette_index;
+    FT_Int                palette_index;
     FT_Color*             palette;
     FT_Bool               have_foreground_color;
     FT_Color              foreground_color;
diff --git a/src/base/ftcolor.c b/src/base/ftcolor.c
index 0edf379b4..d769c9627 100644
--- a/src/base/ftcolor.c
+++ b/src/base/ftcolor.c
@@ -36,7 +36,7 @@
   {
     if ( !face )
       return FT_THROW( Invalid_Face_Handle );
-    if ( !apalette_data)
+    if ( !apalette_data )
       return FT_THROW( Invalid_Argument );
 
     if ( FT_IS_SFNT( face ) )
@@ -88,6 +88,57 @@
   }
 
 
+  /* documentation is in ftcolor.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Palette_Set( FT_Face    face,
+                  FT_Int     index,
+                  FT_Color*  palette )
+  {
+    TT_Face    ttface;
+    FT_UShort  i;
+
+
+    if ( !face || !FT_IS_SFNT( face ) )
+      return FT_THROW( Invalid_Face_Handle );
+
+    if ( !palette || index >= 0 )
+      return FT_THROW( Invalid_Argument );
+
+    ttface = (TT_Face)face;
+
+    for ( i = 0; i < ttface->palette_data.num_palette_entries; i++ )
+      ttface->palette[i] = palette[i];
+    ttface->palette_index = index;
+
+    return FT_Err_Ok;
+  }
+
+
+  /* documentation is in ftcolor.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Palette_Get( FT_Face     face,
+                  FT_Int     *anindex,
+                  FT_Color*  *apalette )
+  {
+    TT_Face  ttface;
+
+
+    if ( !face || !FT_IS_SFNT( face ) )
+      return FT_THROW( Invalid_Face_Handle );
+
+    ttface = (TT_Face)face;
+
+    if ( anindex )
+      *anindex  = ttface->palette_index;
+    if ( apalette )
+      *apalette = ttface->palette;
+
+    return FT_Err_Ok;
+  }
+
+
   /* documentation is in ftcolor.h */
 
   FT_EXPORT_DEF( FT_Error )
@@ -111,6 +162,44 @@
     return FT_Err_Ok;
   }
 
+
+  /* documentation is in ftcolor.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Palette_Get_Foreground_Color( FT_Face    face,
+                                   FT_Color*  aforeground_color )
+  {
+    TT_Face  ttface;
+
+    FT_Color  white = { 0xFF, 0xFF, 0xFF, 0xFF };
+    FT_Color  black = { 0x00, 0x00, 0x00, 0xFF };
+
+
+    if ( !face || !FT_IS_SFNT( face ) )
+      return FT_THROW( Invalid_Face_Handle );
+
+    if ( !aforeground_color )
+      return FT_THROW( Invalid_Argument );
+
+    ttface = (TT_Face)face;
+
+    if ( ttface->have_foreground_color )
+      *aforeground_color = ttface->foreground_color;
+    else if ( ttface->palette_index < 0 )
+      *aforeground_color = black;
+    else
+    {
+      if ( ttface->palette_data.palette_flags                            &&
+           ( ttface->palette_data.palette_flags[ttface->palette_index] &
+               FT_PALETTE_FOR_DARK_BACKGROUND                          ) )
+        *aforeground_color = white;
+      else
+        *aforeground_color = black;
+    }
+
+    return FT_Err_Ok;
+  }
+
 #else /* !TT_CONFIG_OPTION_COLOR_LAYERS */
 
   FT_EXPORT_DEF( FT_Error )
@@ -139,6 +228,34 @@
   }
 
 
+  FT_EXPORT_DEF( FT_Error )
+  FT_Palette_Set( FT_Face    face,
+                  FT_Int     index,
+                  FT_Color*  palette )
+  {
+    FT_UNUSED( face );
+    FT_UNUSED( index );
+    FT_UNUSED( palette );
+
+
+    return FT_THROW( Unimplemented_Feature );
+  }
+
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Palette_Get( FT_Face     face,
+                  FT_Int     *anindex,
+                  FT_Color*  *apalette )
+  {
+    FT_UNUSED( face );
+    FT_UNUSED( anindex );
+    FT_UNUSED( apalette );
+
+
+    return FT_THROW( Unimplemented_Feature );
+  }
+
+
   FT_EXPORT_DEF( FT_Error )
   FT_Palette_Set_Foreground_Color( FT_Face   face,
                                    FT_Color  foreground_color )
@@ -150,6 +267,18 @@
     return FT_THROW( Unimplemented_Feature );
   }
 
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Palette_Get_Foreground_Color( FT_Face    face,
+                                   FT_Color*  aforeground_color )
+  {
+    FT_UNUSED( face );
+    FT_UNUSED( aforeground_color );
+
+
+    return FT_THROW( Unimplemented_Feature );
+  }
+
 #endif /* !TT_CONFIG_OPTION_COLOR_LAYERS */
 
 



reply via email to

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