ref: f9d05eb32695dfcbc5c7ae747c0c794e64cc55b8
parent: 33ac83e37637f9980d674f60a2621f3ff2e2de64
author: Werner Lemberg <[email protected]>
date: Thu Jun 14 17:02:49 EDT 2018
Provide iterative API to access `COLR' data. This solution doesn't store any data in an `FT_GlyphSlot' object. * include/freetype/freetype.h (FT_LayerIterator): New structure. (FT_Get_Color_Glyph_Layer): New function. * include/freetype/internal/sfnt.h (TT_Get_Colr_Layer_Func): New function type. (SFNT_Interface, FT_DEFINE_SFNT_INTERFACE): Add it. * src/base/ftobjs.c (FT_Get_Color_Glyph_Layer): Implement it. * src/sfnt/ttcolr.c (tt_face_get_colr_layer): New function. * src/sfnt/ttcolr.h: Updated. * src/sfnt/sfdriver.c (sfnt_interface): Updated.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,25 @@
2018-06-14 Werner Lemberg <[email protected]>
+ Provide iterative API to access `COLR' data.
+
+ This solution doesn't store any data in an `FT_GlyphSlot' object.
+
+ * include/freetype/freetype.h (FT_LayerIterator): New structure.
+ (FT_Get_Color_Glyph_Layer): New function.
+
+ * include/freetype/internal/sfnt.h (TT_Get_Colr_Layer_Func): New
+ function type.
+ (SFNT_Interface, FT_DEFINE_SFNT_INTERFACE): Add it.
+
+ * src/base/ftobjs.c (FT_Get_Color_Glyph_Layer): Implement it.
+
+ * src/sfnt/ttcolr.c (tt_face_get_colr_layer): New function.
+ * src/sfnt/ttcolr.h: Updated.
+
+ * src/sfnt/sfdriver.c (sfnt_interface): Updated.
+
+2018-06-14 Werner Lemberg <[email protected]>
+
Add glyph index and glyph load flags to glyph slot.
* include/freetype/freetype.h (FT_GlyphSlotRec): Rename unused
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -3101,7 +3101,7 @@
* blending of the color glyph layers associated with the glyph index,
* using the same bitmap format as embedded color bitmap images. This
* is mainly for convenience; for full control of color layers use
- * @FT_Get_GlyphLayers and FreeType's color functions like
+ * @FT_Get_Color_Glyph_Layer and FreeType's color functions like
* @FT_Palette_Select instead of setting FT_LOAD_COLOR for rendering
* so that the client application can handle blending by itself.
*
@@ -4262,6 +4262,101 @@
FT_Get_GlyphLayers( FT_GlyphSlot glyph,
FT_UShort *anum_layers,
FT_Glyph_Layer *alayers );
+
+
+ /**********************************************************************
+ *
+ * @struct:
+ * FT_LayerIterator
+ *
+ * @description:
+ * This iterator object is needed for @FT_Get_Color_Glyph_Layer.
+ *
+ * @fields:
+ * num_layers ::
+ * The number of glyph layers for the requested glyph index. Will be
+ * set by @FT_Get_Color_Glyph_Layer.
+ *
+ * layer ::
+ * The current layer. Will be set by @FT_Get_Color_Glyph_Layer.
+ *
+ * p ::
+ * An opaque pointer into `COLR' table data. The caller must set this
+ * to NULL before the first call of @FT_Get_Color_Glyph_Layer.
+ */
+ typedef struct FT_LayerIterator_
+ {
+ FT_UInt num_layers;
+ FT_UInt layer;
+ FT_Byte* p;
+
+ } FT_LayerIterator;
+
+
+ /*************************************************************************
+ *
+ * @func:
+ * FT_Get_Color_Glyph_Layer
+ *
+ * @description:
+ * This is an interface to the `COLR' table in OpenType fonts to
+ * iteratively retrieve the colored glyph layers associated with the
+ * current glyph slot.
+ *
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/colr
+ *
+ * The glyph layer data for a given glyph index, if present, provides an
+ * alternative, multi-colour glyph representation: Instead of rendering
+ * the outline or bitmap with the given glyph index, glyphs with the
+ * indices and colors returned by this function are rendered layer by
+ * layer.
+ *
+ * The returned elements are ordered in the z~direction from bottom to
+ * top; the `n'th element should be rendered with the associated palette
+ * color and blended on top of the already rendered layers (elements 0,
+ * 1, ..., n-1).
+ *
+ * @input:
+ * face ::
+ * A handle to the parent face object.
+ *
+ * base_glyph ::
+ * The glyph index the colored glyph layers are associated with.
+ *
+ * @inout:
+ * iterator ::
+ * An @FT_LayerIterator object. For the first call you should set
+ * `iterator->p' to NULL. For all following calls, simply use the
+ * same object again.
+ *
+ * @output:
+ * acolor_index ::
+ * The color index into the font face's color palette of the current
+ * layer. The value 0xFFFF is special; it doesn't reference a palette
+ * entry but indicates that the text foreground color should be used
+ * instead (to be set up by the application outside of FreeType).
+ *
+ * The color palette can be retrieved with @FT_Palette_Select.
+ *
+ * @return:
+ * The glyph index of the current layer. If there are no more layers
+ * (or if there are no layers at all), value~0 gets returned. In case
+ * of an error, value~0 is returned also.
+ *
+ * @note:
+ * This function is necessary if you want to handle glyph layers by
+ * yourself. In particular, functions that operate with @FT_GlyphRec
+ * objects (like @FT_Get_Glyph or @FT_Glyph_To_Bitmap) don't have access
+ * to this information.
+ *
+ * @FT_Render_Glyph, however, handles colored glyph layers
+ * automatically if the @FT_LOAD_COLOR flag is passed to it.
+ */
+ FT_EXPORT( FT_UInt )
+ FT_Get_Color_Glyph_Layer( FT_Face face,
+ FT_UInt base_glyph,
+ FT_UInt *acolor_index,
+ FT_LayerIterator* iterator );
/**************************************************************************
--- a/include/freetype/internal/sfnt.h
+++ b/include/freetype/internal/sfnt.h
@@ -529,6 +529,46 @@
/**************************************************************************
*
* @FuncType:
+ * TT_Get_Colr_Layer_Func
+ *
+ * @Description:
+ * Iteratively get the color layer data of a given glyph index.
+ *
+ * @Input:
+ * face ::
+ * The target face object.
+ *
+ * base_glyph ::
+ * The glyph index the colored glyph layers are associated with.
+ *
+ * @inout:
+ * iterator ::
+ * An @FT_LayerIterator object. For the first call you should set
+ * `iterator->p' to NULL. For all following calls, simply use the
+ * same object again.
+ *
+ * @output:
+ * acolor_index ::
+ * The color index into the font face's color palette of the current
+ * layer. The value 0xFFFF is special; it doesn't reference a palette
+ * entry but indicates that the text foreground color should be used
+ * instead (to be set up by the application outside of FreeType).
+ *
+ * @return:
+ * The glyph index of the current layer. If there are no more layers
+ * (or if there are no layers at all), value~0 gets returned. In case
+ * of an error, value~0 is returned also.
+ */
+ typedef FT_UInt
+ (*TT_Get_Colr_Layer_Func)( TT_Face face,
+ FT_UInt base_glyph,
+ FT_UInt *acolor_index,
+ FT_LayerIterator* iterator );
+
+
+ /**************************************************************************
+ *
+ * @FuncType:
* TT_Blend_Colr_Func
*
* @Description:
@@ -769,6 +809,7 @@
TT_Free_Table_Func free_colr;
TT_Set_Palette_Func set_palette;
TT_Load_Colr_Layer_Func load_colr_layer;
+ TT_Get_Colr_Layer_Func get_colr_layer;
TT_Blend_Colr_Func colr_blend;
TT_Get_Metrics_Func get_metrics;
@@ -819,6 +860,7 @@
free_colr_, \
set_palette_, \
load_colr_layer_, \
+ get_colr_layer_, \
colr_blend_, \
get_metrics_, \
get_name_, \
@@ -859,6 +901,7 @@
free_colr_, \
set_palette_, \
load_colr_layer_, \
+ get_colr_layer_, \
colr_blend_, \
get_metrics_, \
get_name_, \
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -5490,4 +5490,35 @@
}
+ /* documentation is in freetype.h */
+
+ FT_EXPORT_DEF( FT_UInt )
+ FT_Get_Color_Glyph_Layer( FT_Face face,
+ FT_UInt base_glyph,
+ FT_UInt *acolor_index,
+ FT_LayerIterator* iterator )
+ {
+ TT_Face ttface;
+ SFNT_Service sfnt;
+
+
+ if ( !face ||
+ !acolor_index ||
+ !iterator ||
+ base_glyph >= (FT_UInt)face->num_glyphs )
+ return 0;
+
+ if ( !FT_IS_SFNT( face ) )
+ return 0;
+
+ ttface = (TT_Face)face;
+ sfnt = (SFNT_Service)ttface->sfnt;
+
+ return sfnt->get_colr_layer( ttface,
+ base_glyph,
+ acolor_index,
+ iterator );
+ }
+
+
/* END */
--- a/src/sfnt/sfdriver.c
+++ b/src/sfnt/sfdriver.c
@@ -1270,6 +1270,8 @@
/* 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_get_colr_layer ),
+ /* TT_Get_Colr_Layer_Func get_colr_layer */
PUT_COLOR_LAYERS( tt_face_colr_blend_layer ),
/* TT_Blend_Colr_Func colr_blend */
--- a/src/sfnt/ttcolr.c
+++ b/src/sfnt/ttcolr.c
@@ -275,6 +275,54 @@
}
+ FT_LOCAL_DEF( FT_UInt )
+ tt_face_get_colr_layer( TT_Face face,
+ FT_UInt base_glyph,
+ FT_UInt *acolor_index,
+ FT_LayerIterator* iterator )
+ {
+ Colr* colr = (Colr*)face->colr;
+ BaseGlyphRecord glyph_record;
+ FT_UInt glyph_index;
+
+
+ if ( !iterator->p )
+ {
+ /* first call to function */
+ iterator->layer = 0;
+
+ if ( !find_base_glyph_record( colr->base_glyphs,
+ colr->num_base_glyphs,
+ base_glyph,
+ &glyph_record ) )
+ return 0;
+
+ iterator->p = colr->layers +
+ LAYER_SIZE * glyph_record.first_layer_index;
+
+ if ( glyph_record.num_layers )
+ iterator->num_layers = glyph_record.num_layers;
+ else
+ return 0;
+ }
+
+ if ( iterator->layer >= iterator->num_layers )
+ return 0;
+
+ glyph_index = FT_NEXT_USHORT( iterator->p );
+ *acolor_index = FT_NEXT_USHORT( iterator->p );
+
+ if ( glyph_index >= FT_FACE( face )->num_glyphs ||
+ ( *acolor_index != 0xFFFF &&
+ *acolor_index >= face->palette_data.num_palette_entries ) )
+ return 0;
+
+ iterator->layer++;
+
+ return glyph_index;
+ }
+
+
FT_LOCAL_DEF( FT_Error )
tt_face_colr_blend_layer( TT_Face face,
FT_UInt color_index,
--- a/src/sfnt/ttcolr.h
+++ b/src/sfnt/ttcolr.h
@@ -42,6 +42,12 @@
FT_Glyph_Layer *ret_layers,
FT_UShort* ret_num_layers );
+ FT_LOCAL( FT_UInt )
+ tt_face_get_colr_layer( TT_Face face,
+ FT_UInt base_glyph,
+ FT_UInt *acolor_index,
+ FT_LayerIterator* iterator );
+
FT_LOCAL( FT_Error )
tt_face_colr_blend_layer( TT_Face face,
FT_UInt color_index,