From 583dabf2918cc9ca82cac0b16482d2c56de8c3fa Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Wed, 16 May 2018 20:37:43 +0200 Subject: [PATCH] Add function `FT_Get_GlyphLayers' to access `COLR' table data. * include/freetype/internal/ftobjs.h (FT_Glyph_LayerRec): Move this structure to... * include/freetype/freetype.h (FT_Glyph_LayerRec): ... this header file. (FT_Glyph_Layer): New typedef. Update code to use it where appropriate. * src/base/ftobjs.c (FT_Get_GlyphLayers): New function. --- ChangeLog | 13 ++++ include/freetype/freetype.h | 95 ++++++++++++++++++++++++++++++ include/freetype/internal/ftobjs.h | 14 +---- include/freetype/internal/sfnt.h | 8 +-- src/base/ftobjs.c | 29 ++++++++- src/sfnt/ttcolr.c | 16 ++--- src/sfnt/ttcolr.h | 8 +-- src/truetype/ttgload.c | 8 +-- 8 files changed, 158 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index b590def26..4b726e55a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2018-05-16 Werner Lemberg + + Add function `FT_Get_GlyphLayers' to access `COLR' table data. + + * include/freetype/internal/ftobjs.h (FT_Glyph_LayerRec): Move this + structure to... + * include/freetype/freetype.h (FT_Glyph_LayerRec): ... this + header file. + (FT_Glyph_Layer): New typedef. + Update code to use it where appropriate. + + * src/base/ftobjs.c (FT_Get_GlyphLayers): New function. + 2018-05-15 Alexei Podtelezhnikov [base] Fix mono bitmap presetting (#53896). diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h index 96644046e..4151b0645 100644 --- a/include/freetype/freetype.h +++ b/include/freetype/freetype.h @@ -3986,6 +3986,101 @@ FT_BEGIN_HEADER FT_Matrix *p_transform ); + /********************************************************************** + * + * @type: + * FT_Glyph_Layer + * + * @description: + * A handle to an @FT_Glyph_LayerRec structure to model a given + * colored glyph layer. + */ + typedef struct FT_Glyph_LayerRec_* FT_Glyph_Layer; + + + /********************************************************************** + * + * @struct: + * FT_Glyph_LayerRec + * + * @description: + * This structure models a given colored glyph layer as defined in the + * OpenType `COLR' table. It is used by @FT_Get_GlyphLayers. + * + * @fields: + * glyph_index :: + * The glyph index of the current glyph layer. + * + * color_index :: + * The color index into the font face's color palette, which can be + * retrieved with @FT_Palette_Select. 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). + */ + typedef struct FT_Glyph_LayerRec_ + { + FT_UShort glyph_index; + FT_UShort color_index; + + } FT_Glyph_LayerRec; + + + /************************************************************************* + * + * @func: + * FT_Get_GlyphLayers + * + * @description: + * This is an interface to the `COLR' table in OpenType fonts to + * retrieve the colored glyph layers array associated with the current + * glyph slot. + * + * https://docs.microsoft.com/en-us/typography/opentype/spec/colr + * + * The glyph layer data for a given glyph slot, if present, provides an + * alternative, multi-colour glyph representation: Instead of rendering + * the outline or bitmap in the glyph slot, glyphs with the indices and + * colors returned in the @FT_GlyphLayer array are rendered layer by + * layer. + * + * @input: + * glyph :: + * The source glyph slot. + * + * @output: + * anum_layers :: + * The number of colored glyph layers for `glyph'. + * + * alayers :: + * An @FT_GlyphLayer array with `anum_layers' elements. NULL if there + * aren't glyph layers. + * + * The elements are ordered in the z~direction from bottom to top; an + * element `n' should be rendered with the associated palette color + * and blended on top of the already rendered layers (elements 0, 1, + * ..., n-1). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The data in `alayers' is owned and managed by the glyph slot. + * + * 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. + */ + FT_EXPORT( FT_Error ) + FT_Get_GlyphLayers( FT_GlyphSlot glyph, + FT_UShort *anum_layers, + FT_Glyph_Layer *alayers ); + + /*************************************************************************/ /* */ /* */ diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h index 301388337..a8d987fcc 100644 --- a/include/freetype/internal/ftobjs.h +++ b/include/freetype/internal/ftobjs.h @@ -384,19 +384,11 @@ FT_BEGIN_HEADER } FT_Face_InternalRec; - typedef struct FT_Glyph_LayerRec_ - { - FT_UShort glyph_index; - FT_UShort color_index; - - } FT_Glyph_LayerRec; - - typedef struct FT_Colr_InternalRec_ { - FT_Glyph_LayerRec* layers; - FT_UShort num_layers; - FT_Int load_flags; + FT_Glyph_Layer layers; + FT_UShort num_layers; + FT_Int load_flags; } FT_Colr_InternalRec, *FT_Colr_Internal; diff --git a/include/freetype/internal/sfnt.h b/include/freetype/internal/sfnt.h index f543535f0..d28b6825a 100644 --- a/include/freetype/internal/sfnt.h +++ b/include/freetype/internal/sfnt.h @@ -452,10 +452,10 @@ FT_BEGIN_HEADER /* color layer information exists for `idx'. */ /* */ typedef FT_Error - (*TT_Load_Colr_Layer_Func)( TT_Face face, - FT_Int idx, - FT_Glyph_LayerRec* *layers, - FT_UShort* num_layers ); + (*TT_Load_Colr_Layer_Func)( TT_Face face, + FT_Int idx, + FT_Glyph_Layer *layers, + FT_UShort* num_layers ); /*************************************************************************/ diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index 05e2a038a..d7768dd69 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -4531,8 +4531,8 @@ TT_Face ttface = (TT_Face)face; SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; - FT_Glyph_LayerRec* glyph_layers = - slot->internal->color_layers->layers; + FT_Glyph_Layer glyph_layers = + slot->internal->color_layers->layers; FT_Int idx; @@ -5461,4 +5461,29 @@ } + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_GlyphLayers( FT_GlyphSlot glyph, + FT_UShort *anum_layers, + FT_Glyph_Layer *alayers ) + { + if ( !glyph ) + return FT_THROW( Invalid_Argument ); + + if ( glyph->internal->color_layers ) + { + *anum_layers = glyph->internal->color_layers->num_layers; + *alayers = glyph->internal->color_layers->layers; + } + else + { + *anum_layers = 0; + *alayers = NULL; + } + + return FT_Err_Ok; + } + + /* END */ diff --git a/src/sfnt/ttcolr.c b/src/sfnt/ttcolr.c index 67d320b11..24d350e6c 100644 --- a/src/sfnt/ttcolr.c +++ b/src/sfnt/ttcolr.c @@ -290,10 +290,10 @@ FT_LOCAL_DEF( FT_Error ) - tt_face_load_colr_layers( TT_Face face, - FT_Int glyph_id, - FT_Glyph_LayerRec* *ret_layers, - FT_UShort* ret_num_layers ) + tt_face_load_colr_layers( TT_Face face, + FT_Int glyph_id, + FT_Glyph_Layer *ret_layers, + FT_UShort* ret_num_layers ) { FT_Error error; FT_Memory memory = face->root.memory; @@ -302,10 +302,10 @@ Colr* colr = &colr_and_cpal->colr; Cpal* cpal = &colr_and_cpal->cpal; - BaseGlyphRecord glyph_record; - FT_Glyph_LayerRec* layers; - int layer_idx; - FT_Byte* layer_record_ptr; + BaseGlyphRecord glyph_record; + FT_Glyph_Layer layers; + int layer_idx; + FT_Byte* layer_record_ptr; if ( !ret_layers || !ret_num_layers ) diff --git a/src/sfnt/ttcolr.h b/src/sfnt/ttcolr.h index 84062c04b..1c58153a5 100644 --- a/src/sfnt/ttcolr.h +++ b/src/sfnt/ttcolr.h @@ -37,10 +37,10 @@ FT_BEGIN_HEADER tt_face_free_colr( TT_Face face ); FT_LOCAL( FT_Error ) - tt_face_load_colr_layers( TT_Face face, - FT_Int glyph_id, - FT_Glyph_LayerRec* *ret_layers, - FT_UShort* ret_num_layers ); + tt_face_load_colr_layers( TT_Face face, + FT_Int glyph_id, + FT_Glyph_Layer *ret_layers, + FT_UShort* ret_num_layers ); FT_LOCAL( FT_Error ) tt_face_colr_blend_layer( TT_Face face, diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c index 0bd9af73f..95ba68dd3 100644 --- a/src/truetype/ttgload.c +++ b/src/truetype/ttgload.c @@ -2894,15 +2894,15 @@ /* The outline based algorithm took care of metrics. */ /* Read additional color info if requested. */ - if ( ( load_flags & FT_LOAD_COLOR ) && - ( (TT_Face)(glyph->face) )->colr_and_cpal ) + if ( ( load_flags & FT_LOAD_COLOR ) && + ( (TT_Face)glyph->face )->colr_and_cpal ) { TT_Face face = (TT_Face)glyph->face; FT_Memory memory = face->root.memory; SFNT_Service sfnt = (SFNT_Service)face->sfnt; - FT_Glyph_LayerRec* glyph_layers; - FT_UShort num_glyph_layers; + FT_Glyph_Layer glyph_layers; + FT_UShort num_glyph_layers; error = sfnt->load_colr_layer( face,