Replace `FT_Get_GlyphLayers' with `FT_Get_Color_Glyph_Layer'.
This avoids any additional allocation of COLR related structures in a glyph slot. * include/freetype/freetype.h (FT_Glyph_Layer, FT_Glyph_LayerRec, FT_Get_GlyphLayers): Removed. * include/freetype/internal/ftobjs.h (FT_Colr_InternalRec): Removed. (FT_Slot_InternalRec): Remove `color_layers'. * include/freetype/internal/sfnt.h (TT_Load_Colr_Layer_Func): Removed. (SFNT_Interface, FT_DEFINE_SFNT_INTERFACE): Remove `load_colr_layer'. * src/base/ftobjs.c (ft_glyph_slot_done): Updated. (FT_Render_Glyph_Internal): Use `FT_Get_Color_Glyph_Layer'. (FT_Get_GlyphLayers): Removed. * src/sfnt/sfdriver.c (sfnt_interface): Updated. * src/sfnt/ttcolr.c (tt_face_load_colr_layers): Removed. * src/sfnt/ttcolr.h: Updated. * src/truetype/ttgload.c (TT_Load_Glyph): Updated.
This commit is contained in:
parent
f9d05eb326
commit
9b31c44620
29
ChangeLog
29
ChangeLog
|
@ -1,3 +1,32 @@
|
|||
2018-06-14 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
Replace `FT_Get_GlyphLayers' with `FT_Get_Color_Glyph_Layer'.
|
||||
|
||||
This avoids any additional allocation of COLR related structures in
|
||||
a glyph slot.
|
||||
|
||||
* include/freetype/freetype.h (FT_Glyph_Layer, FT_Glyph_LayerRec,
|
||||
FT_Get_GlyphLayers): Removed.
|
||||
|
||||
* include/freetype/internal/ftobjs.h (FT_Colr_InternalRec): Removed.
|
||||
(FT_Slot_InternalRec): Remove `color_layers'.
|
||||
|
||||
* include/freetype/internal/sfnt.h (TT_Load_Colr_Layer_Func):
|
||||
Removed.
|
||||
(SFNT_Interface, FT_DEFINE_SFNT_INTERFACE): Remove
|
||||
`load_colr_layer'.
|
||||
|
||||
* src/base/ftobjs.c (ft_glyph_slot_done): Updated.
|
||||
(FT_Render_Glyph_Internal): Use `FT_Get_Color_Glyph_Layer'.
|
||||
(FT_Get_GlyphLayers): Removed.
|
||||
|
||||
* src/sfnt/sfdriver.c (sfnt_interface): Updated.
|
||||
|
||||
* src/sfnt/ttcolr.c (tt_face_load_colr_layers): Removed.
|
||||
* src/sfnt/ttcolr.h: Updated.
|
||||
|
||||
* src/truetype/ttgload.c (TT_Load_Glyph): Updated.
|
||||
|
||||
2018-06-14 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
Provide iterative API to access `COLR' data.
|
||||
|
|
|
@ -4169,101 +4169,6 @@ 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_Glyph_Layer 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_Glyph_Layer 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 if the @FT_LOAD_COLOR flag is passed to it.
|
||||
*/
|
||||
FT_EXPORT( FT_Error )
|
||||
FT_Get_GlyphLayers( FT_GlyphSlot glyph,
|
||||
FT_UShort *anum_layers,
|
||||
FT_Glyph_Layer *alayers );
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* @struct:
|
||||
|
|
|
@ -384,15 +384,6 @@ FT_BEGIN_HEADER
|
|||
} FT_Face_InternalRec;
|
||||
|
||||
|
||||
typedef struct FT_Colr_InternalRec_
|
||||
{
|
||||
FT_Glyph_Layer layers;
|
||||
FT_UShort num_layers;
|
||||
FT_Int32 load_flags;
|
||||
|
||||
} FT_Colr_InternalRec, *FT_Colr_Internal;
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @Struct:
|
||||
|
@ -432,9 +423,6 @@ FT_BEGIN_HEADER
|
|||
* glyph_hints ::
|
||||
* Format-specific glyph hints management.
|
||||
*
|
||||
* color_layers ::
|
||||
* Data from (SFNT) COLR/CPAL tables.
|
||||
*
|
||||
* load_flags ::
|
||||
* The load flags passed as an argument to @FT_Load_Glyph while
|
||||
* initializing the glyph slot.
|
||||
|
@ -451,8 +439,6 @@ FT_BEGIN_HEADER
|
|||
FT_Vector glyph_delta;
|
||||
void* glyph_hints;
|
||||
|
||||
FT_Colr_Internal color_layers;
|
||||
|
||||
FT_Int32 load_flags;
|
||||
|
||||
} FT_GlyphSlot_InternalRec;
|
||||
|
|
|
@ -492,40 +492,6 @@ FT_BEGIN_HEADER
|
|||
FT_UInt idx );
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @FuncType:
|
||||
* TT_Load_Colr_Layer_Func
|
||||
*
|
||||
* @Description:
|
||||
* Load the color layer data given a glyph index.
|
||||
*
|
||||
* @Input:
|
||||
* face ::
|
||||
* The target face object.
|
||||
*
|
||||
* idx ::
|
||||
* The glyph index.
|
||||
*
|
||||
* @Output:
|
||||
* layers ::
|
||||
* The layer info with color index and glyph index.
|
||||
* Deallocate with `FT_FREE'.
|
||||
*
|
||||
* num_layers ::
|
||||
* Number of layers.
|
||||
*
|
||||
* @Return:
|
||||
* FreeType error code. 0 means success. Returns an error if no
|
||||
* color layer information exists for `idx'.
|
||||
*/
|
||||
typedef FT_Error
|
||||
(*TT_Load_Colr_Layer_Func)( TT_Face face,
|
||||
FT_UInt idx,
|
||||
FT_Glyph_Layer *layers,
|
||||
FT_UShort* num_layers );
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @FuncType:
|
||||
|
@ -808,7 +774,6 @@ FT_BEGIN_HEADER
|
|||
TT_Free_Table_Func free_cpal;
|
||||
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;
|
||||
|
||||
|
@ -859,7 +824,6 @@ FT_BEGIN_HEADER
|
|||
free_cpal_, \
|
||||
free_colr_, \
|
||||
set_palette_, \
|
||||
load_colr_layer_, \
|
||||
get_colr_layer_, \
|
||||
colr_blend_, \
|
||||
get_metrics_, \
|
||||
|
@ -900,7 +864,6 @@ FT_BEGIN_HEADER
|
|||
free_cpal_, \
|
||||
free_colr_, \
|
||||
set_palette_, \
|
||||
load_colr_layer_, \
|
||||
get_colr_layer_, \
|
||||
colr_blend_, \
|
||||
get_metrics_, \
|
||||
|
|
|
@ -532,16 +532,6 @@
|
|||
/* free bitmap buffer if needed */
|
||||
ft_glyphslot_free_bitmap( slot );
|
||||
|
||||
/* free glyph color layers if needed */
|
||||
if ( slot->internal->color_layers )
|
||||
{
|
||||
FT_Colr_InternalRec* color_layers = slot->internal->color_layers;
|
||||
|
||||
|
||||
FT_FREE( color_layers->layers );
|
||||
FT_FREE( slot->internal->color_layers );
|
||||
}
|
||||
|
||||
/* slot->internal might be NULL in out-of-memory situations */
|
||||
if ( slot->internal )
|
||||
{
|
||||
|
@ -4513,69 +4503,85 @@
|
|||
FT_Render_Mode render_mode )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_Face face = slot->face;
|
||||
FT_Renderer renderer;
|
||||
|
||||
|
||||
/* if it is already a bitmap, no need to do anything */
|
||||
switch ( slot->format )
|
||||
{
|
||||
case FT_GLYPH_FORMAT_BITMAP: /* already a bitmap, don't do anything */
|
||||
break;
|
||||
|
||||
default:
|
||||
if ( slot->internal->color_layers )
|
||||
if ( slot->internal->load_flags & FT_LOAD_COLOR )
|
||||
{
|
||||
FT_Face face = slot->face;
|
||||
FT_LayerIterator iterator;
|
||||
|
||||
FT_UInt base_glyph = slot->glyph_index;
|
||||
|
||||
FT_UInt glyph_index;
|
||||
FT_UInt color_index;
|
||||
|
||||
|
||||
error = FT_New_GlyphSlot( face, NULL );
|
||||
if ( !error )
|
||||
/* check whether we have colored glyph layers */
|
||||
iterator.p = NULL;
|
||||
glyph_index = FT_Get_Color_Glyph_Layer( face,
|
||||
base_glyph,
|
||||
&color_index,
|
||||
&iterator );
|
||||
if ( glyph_index )
|
||||
{
|
||||
TT_Face ttface = (TT_Face)face;
|
||||
SFNT_Service sfnt = (SFNT_Service)ttface->sfnt;
|
||||
|
||||
FT_Glyph_Layer glyph_layers =
|
||||
slot->internal->color_layers->layers;
|
||||
|
||||
FT_Int idx;
|
||||
|
||||
|
||||
for ( idx = 0;
|
||||
idx < slot->internal->color_layers->num_layers;
|
||||
idx++ )
|
||||
error = FT_New_GlyphSlot( face, NULL );
|
||||
if ( !error )
|
||||
{
|
||||
FT_Int32 load_flags;
|
||||
TT_Face ttface = (TT_Face)face;
|
||||
SFNT_Service sfnt = (SFNT_Service)ttface->sfnt;
|
||||
|
||||
|
||||
load_flags = slot->internal->color_layers->load_flags
|
||||
& ~FT_LOAD_COLOR;
|
||||
load_flags |= FT_LOAD_RENDER;
|
||||
do
|
||||
{
|
||||
FT_Int32 load_flags = slot->internal->load_flags;
|
||||
|
||||
error = FT_Load_Glyph( face,
|
||||
glyph_layers[idx].glyph_index,
|
||||
load_flags );
|
||||
if ( error )
|
||||
break;
|
||||
|
||||
error = sfnt->colr_blend( ttface,
|
||||
glyph_layers[idx].color_index,
|
||||
slot,
|
||||
face->glyph );
|
||||
if ( error )
|
||||
break;
|
||||
/* disable the `FT_LOAD_COLOR' flag to avoid recursion */
|
||||
/* right here in this function */
|
||||
load_flags &= ~FT_LOAD_COLOR;
|
||||
|
||||
/* render into the new `face->glyph' glyph slot */
|
||||
load_flags |= FT_LOAD_RENDER;
|
||||
|
||||
error = FT_Load_Glyph( face, glyph_index, load_flags );
|
||||
if ( error )
|
||||
break;
|
||||
|
||||
/* blend new `face->glyph' into old `slot'; */
|
||||
/* at the first call, `slot' is still empty */
|
||||
error = sfnt->colr_blend( ttface,
|
||||
color_index,
|
||||
slot,
|
||||
face->glyph );
|
||||
if ( error )
|
||||
break;
|
||||
|
||||
} while ( ( glyph_index =
|
||||
FT_Get_Color_Glyph_Layer( face,
|
||||
base_glyph,
|
||||
&color_index,
|
||||
&iterator ) ) != 0 );
|
||||
|
||||
if ( !error )
|
||||
slot->format = FT_GLYPH_FORMAT_BITMAP;
|
||||
|
||||
/* this call also restores `slot' as the glyph slot */
|
||||
FT_Done_GlyphSlot( face->glyph );
|
||||
}
|
||||
|
||||
if ( !error )
|
||||
slot->format = FT_GLYPH_FORMAT_BITMAP;
|
||||
return error;
|
||||
|
||||
FT_Done_GlyphSlot( face->glyph );
|
||||
/* Failed to do the colored layer. Draw outline instead. */
|
||||
slot->format = FT_GLYPH_FORMAT_OUTLINE;
|
||||
}
|
||||
|
||||
if ( !error )
|
||||
return error;
|
||||
|
||||
/* Failed to do the colored layer. Draw outline instead. */
|
||||
slot->format = FT_GLYPH_FORMAT_OUTLINE;
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -5465,31 +5471,6 @@
|
|||
}
|
||||
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in freetype.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_UInt )
|
||||
|
|
|
@ -1268,8 +1268,6 @@
|
|||
/* TT_Free_Table_Func free_colr */
|
||||
PUT_COLOR_LAYERS( tt_face_palette_set ),
|
||||
/* 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 ),
|
||||
|
|
|
@ -207,74 +207,6 @@
|
|||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
tt_face_load_colr_layers( TT_Face face,
|
||||
FT_UInt glyph_id,
|
||||
FT_Glyph_Layer *ret_layers,
|
||||
FT_UShort* ret_num_layers )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Memory memory = face->root.memory;
|
||||
|
||||
Colr* colr = (Colr*)face->colr;
|
||||
|
||||
BaseGlyphRecord glyph_record;
|
||||
FT_Glyph_Layer layers = NULL;
|
||||
int layer_idx;
|
||||
FT_Byte* layer_record_ptr;
|
||||
|
||||
|
||||
if ( !ret_layers || !ret_num_layers )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
if ( !find_base_glyph_record( colr->base_glyphs,
|
||||
colr->num_base_glyphs,
|
||||
glyph_id,
|
||||
&glyph_record ) )
|
||||
{
|
||||
*ret_layers = NULL;
|
||||
*ret_num_layers = 0;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
/* Load all colors for the glyphs; this would be stored in the slot. */
|
||||
layer_record_ptr = colr->layers +
|
||||
glyph_record.first_layer_index * LAYER_SIZE;
|
||||
|
||||
if ( FT_NEW_ARRAY( layers, glyph_record.num_layers ) )
|
||||
goto Error;
|
||||
|
||||
for ( layer_idx = 0; layer_idx < glyph_record.num_layers; layer_idx++ )
|
||||
{
|
||||
FT_UShort gid = FT_NEXT_USHORT( layer_record_ptr );
|
||||
FT_UShort palette_entry_index = FT_NEXT_USHORT( layer_record_ptr );
|
||||
|
||||
|
||||
if ( palette_entry_index != 0xFFFF &&
|
||||
palette_entry_index >= face->palette_data.num_palette_entries )
|
||||
{
|
||||
error = FT_THROW( Invalid_Table );
|
||||
goto Error;
|
||||
}
|
||||
|
||||
layers[layer_idx].color_index = palette_entry_index;
|
||||
layers[layer_idx].glyph_index = gid;
|
||||
}
|
||||
|
||||
*ret_layers = layers;
|
||||
*ret_num_layers = glyph_record.num_layers;
|
||||
|
||||
return FT_Err_Ok;
|
||||
|
||||
Error:
|
||||
if ( layers )
|
||||
FT_FREE( layers );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_UInt )
|
||||
tt_face_get_colr_layer( TT_Face face,
|
||||
FT_UInt base_glyph,
|
||||
|
|
|
@ -36,12 +36,6 @@ FT_BEGIN_HEADER
|
|||
FT_LOCAL( void )
|
||||
tt_face_free_colr( TT_Face face );
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
tt_face_load_colr_layers( TT_Face face,
|
||||
FT_UInt glyph_id,
|
||||
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,
|
||||
|
|
|
@ -2904,39 +2904,6 @@
|
|||
size->metrics->y_ppem < 24 )
|
||||
glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
|
||||
|
||||
/* 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 )
|
||||
{
|
||||
TT_Face face = (TT_Face)glyph->face;
|
||||
FT_Memory memory = face->root.memory;
|
||||
SFNT_Service sfnt = (SFNT_Service)face->sfnt;
|
||||
|
||||
FT_Glyph_Layer glyph_layers;
|
||||
FT_UShort num_glyph_layers;
|
||||
|
||||
|
||||
error = sfnt->load_colr_layer( face,
|
||||
glyph_index,
|
||||
&glyph_layers,
|
||||
&num_glyph_layers );
|
||||
if ( error )
|
||||
return error;
|
||||
|
||||
if ( !glyph->internal->color_layers )
|
||||
{
|
||||
if ( FT_NEW( glyph->internal->color_layers ) )
|
||||
return error;
|
||||
}
|
||||
|
||||
FT_FREE( glyph->internal->color_layers->layers );
|
||||
|
||||
glyph->internal->color_layers->layers = glyph_layers;
|
||||
glyph->internal->color_layers->num_layers = num_glyph_layers;
|
||||
glyph->internal->color_layers->load_flags = load_flags;
|
||||
}
|
||||
|
||||
Exit:
|
||||
#ifdef FT_DEBUG_LEVEL_TRACE
|
||||
if ( error )
|
||||
|
|
Loading…
Reference in New Issue