summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Lemberg <wl@gnu.org>2018-06-14 21:02:49 +0200
committerWerner Lemberg <wl@gnu.org>2018-06-14 21:17:17 +0200
commitf9d05eb32695dfcbc5c7ae747c0c794e64cc55b8 (patch)
tree2066353596cf7523c5e9a8a0fa39311c412a2c2f
parent33ac83e37637f9980d674f60a2621f3ff2e2de64 (diff)
downloadfreetype2-f9d05eb32695dfcbc5c7ae747c0c794e64cc55b8.tar.gz
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.
-rw-r--r--ChangeLog20
-rw-r--r--include/freetype/freetype.h97
-rw-r--r--include/freetype/internal/sfnt.h43
-rw-r--r--src/base/ftobjs.c31
-rw-r--r--src/sfnt/sfdriver.c2
-rw-r--r--src/sfnt/ttcolr.c48
-rw-r--r--src/sfnt/ttcolr.h6
7 files changed, 246 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index b1bec04ee..5df7fa590 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,25 @@
2018-06-14 Werner Lemberg <wl@gnu.org>
+ 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 <wl@gnu.org>
+
Add glyph index and glyph load flags to glyph slot.
* include/freetype/freetype.h (FT_GlyphSlotRec): Rename unused
diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h
index 35e6ed652..02abd8a59 100644
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -3101,7 +3101,7 @@ FT_BEGIN_HEADER
* 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.
*
@@ -4264,6 +4264,101 @@ FT_BEGIN_HEADER
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 );
+
+
/**************************************************************************
*
* @Enum:
diff --git a/include/freetype/internal/sfnt.h b/include/freetype/internal/sfnt.h
index 731c7fe86..2093c28e7 100644
--- a/include/freetype/internal/sfnt.h
+++ b/include/freetype/internal/sfnt.h
@@ -529,6 +529,46 @@ FT_BEGIN_HEADER
/**************************************************************************
*
* @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 @@ FT_BEGIN_HEADER
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 @@ FT_BEGIN_HEADER
free_colr_, \
set_palette_, \
load_colr_layer_, \
+ get_colr_layer_, \
colr_blend_, \
get_metrics_, \
get_name_, \
@@ -859,6 +901,7 @@ FT_BEGIN_HEADER
free_colr_, \
set_palette_, \
load_colr_layer_, \
+ get_colr_layer_, \
colr_blend_, \
get_metrics_, \
get_name_, \
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index bd3c039b0..29a1c114c 100644
--- 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 */
diff --git a/src/sfnt/sfdriver.c b/src/sfnt/sfdriver.c
index 0c3ddc89f..e1f481802 100644
--- 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 */
diff --git a/src/sfnt/ttcolr.c b/src/sfnt/ttcolr.c
index 66592b626..323f0ca51 100644
--- 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,
diff --git a/src/sfnt/ttcolr.h b/src/sfnt/ttcolr.h
index a5487556c..480fd6770 100644
--- a/src/sfnt/ttcolr.h
+++ b/src/sfnt/ttcolr.h
@@ -42,6 +42,12 @@ FT_BEGIN_HEADER
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,