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.
This commit is contained in:
parent
33ac83e376
commit
f9d05eb326
20
ChangeLog
20
ChangeLog
|
@ -1,3 +1,23 @@
|
||||||
|
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>
|
2018-06-14 Werner Lemberg <wl@gnu.org>
|
||||||
|
|
||||||
Add glyph index and glyph load flags to glyph slot.
|
Add glyph index and glyph load flags to glyph slot.
|
||||||
|
|
|
@ -3101,7 +3101,7 @@ FT_BEGIN_HEADER
|
||||||
* blending of the color glyph layers associated with the glyph index,
|
* blending of the color glyph layers associated with the glyph index,
|
||||||
* using the same bitmap format as embedded color bitmap images. This
|
* using the same bitmap format as embedded color bitmap images. This
|
||||||
* is mainly for convenience; for full control of color layers use
|
* 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
|
* @FT_Palette_Select instead of setting FT_LOAD_COLOR for rendering
|
||||||
* so that the client application can handle blending by itself.
|
* so that the client application can handle blending by itself.
|
||||||
*
|
*
|
||||||
|
@ -4264,6 +4264,101 @@ FT_BEGIN_HEADER
|
||||||
FT_Glyph_Layer *alayers );
|
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:
|
* @Enum:
|
||||||
|
|
|
@ -526,6 +526,46 @@ FT_BEGIN_HEADER
|
||||||
FT_UShort* num_layers );
|
FT_UShort* num_layers );
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* @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:
|
* @FuncType:
|
||||||
|
@ -769,6 +809,7 @@ FT_BEGIN_HEADER
|
||||||
TT_Free_Table_Func free_colr;
|
TT_Free_Table_Func free_colr;
|
||||||
TT_Set_Palette_Func set_palette;
|
TT_Set_Palette_Func set_palette;
|
||||||
TT_Load_Colr_Layer_Func load_colr_layer;
|
TT_Load_Colr_Layer_Func load_colr_layer;
|
||||||
|
TT_Get_Colr_Layer_Func get_colr_layer;
|
||||||
TT_Blend_Colr_Func colr_blend;
|
TT_Blend_Colr_Func colr_blend;
|
||||||
|
|
||||||
TT_Get_Metrics_Func get_metrics;
|
TT_Get_Metrics_Func get_metrics;
|
||||||
|
@ -819,6 +860,7 @@ FT_BEGIN_HEADER
|
||||||
free_colr_, \
|
free_colr_, \
|
||||||
set_palette_, \
|
set_palette_, \
|
||||||
load_colr_layer_, \
|
load_colr_layer_, \
|
||||||
|
get_colr_layer_, \
|
||||||
colr_blend_, \
|
colr_blend_, \
|
||||||
get_metrics_, \
|
get_metrics_, \
|
||||||
get_name_, \
|
get_name_, \
|
||||||
|
@ -859,6 +901,7 @@ FT_BEGIN_HEADER
|
||||||
free_colr_, \
|
free_colr_, \
|
||||||
set_palette_, \
|
set_palette_, \
|
||||||
load_colr_layer_, \
|
load_colr_layer_, \
|
||||||
|
get_colr_layer_, \
|
||||||
colr_blend_, \
|
colr_blend_, \
|
||||||
get_metrics_, \
|
get_metrics_, \
|
||||||
get_name_, \
|
get_name_, \
|
||||||
|
|
|
@ -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 */
|
/* END */
|
||||||
|
|
|
@ -1270,6 +1270,8 @@
|
||||||
/* TT_Set_Palette_Func set_palette */
|
/* TT_Set_Palette_Func set_palette */
|
||||||
PUT_COLOR_LAYERS( tt_face_load_colr_layers ),
|
PUT_COLOR_LAYERS( tt_face_load_colr_layers ),
|
||||||
/* TT_Load_Colr_Layer_Func load_colr_layer */
|
/* 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 ),
|
PUT_COLOR_LAYERS( tt_face_colr_blend_layer ),
|
||||||
/* TT_Blend_Colr_Func colr_blend */
|
/* TT_Blend_Colr_Func colr_blend */
|
||||||
|
|
||||||
|
|
|
@ -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 )
|
FT_LOCAL_DEF( FT_Error )
|
||||||
tt_face_colr_blend_layer( TT_Face face,
|
tt_face_colr_blend_layer( TT_Face face,
|
||||||
FT_UInt color_index,
|
FT_UInt color_index,
|
||||||
|
|
|
@ -42,6 +42,12 @@ FT_BEGIN_HEADER
|
||||||
FT_Glyph_Layer *ret_layers,
|
FT_Glyph_Layer *ret_layers,
|
||||||
FT_UShort* ret_num_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 )
|
FT_LOCAL( FT_Error )
|
||||||
tt_face_colr_blend_layer( TT_Face face,
|
tt_face_colr_blend_layer( TT_Face face,
|
||||||
FT_UInt color_index,
|
FT_UInt color_index,
|
||||||
|
|
Loading…
Reference in New Issue