2018-02-06 00:22:30 +01:00
/*
* Copyright © 2018 Google , Inc .
*
* This is part of HarfBuzz , a text shaping library .
*
* Permission is hereby granted , without written agreement and without
* license or royalty fees , to use , copy , modify , and distribute this
* software and its documentation for any purpose , provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software .
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT , INDIRECT , SPECIAL , INCIDENTAL , OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION , EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE .
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES , INCLUDING ,
* BUT NOT LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE . THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN " AS IS " BASIS , AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE , SUPPORT , UPDATES , ENHANCEMENTS , OR MODIFICATIONS .
*
2018-02-07 01:58:35 +01:00
* Google Author ( s ) : Garret Rieger , Roderick Sheeter
2018-02-06 00:22:30 +01:00
*/
2018-08-31 22:25:19 +02:00
# include "hb-subset-plan.hh"
2018-08-26 07:36:36 +02:00
# include "hb-map.hh"
# include "hb-set.hh"
2018-02-06 00:22:30 +01:00
2018-02-07 19:07:46 +01:00
# include "hb-ot-cmap-table.hh"
2018-02-16 19:27:03 +01:00
# include "hb-ot-glyf-table.hh"
2020-02-26 22:11:42 +01:00
# include "hb-ot-layout-gdef-table.hh"
# include "hb-ot-layout-gpos-table.hh"
2020-06-11 20:27:57 +02:00
# include "hb-ot-layout-gsub-table.hh"
2018-11-14 22:38:03 +01:00
# include "hb-ot-cff1-table.hh"
2020-01-24 14:52:23 +01:00
# include "hb-ot-color-colr-table.hh"
2021-04-01 21:01:19 +02:00
# include "hb-ot-color-colrv1-closure.hh"
2019-05-13 18:38:42 +02:00
# include "hb-ot-var-fvar-table.hh"
2022-06-22 04:29:52 +02:00
# include "hb-ot-var-avar-table.hh"
2019-05-13 18:38:42 +02:00
# include "hb-ot-stat-table.hh"
2021-09-20 23:42:51 +02:00
# include "hb-ot-math-table.hh"
2018-02-07 19:07:46 +01:00
2022-06-30 01:52:08 +02:00
using OT : : Layout : : GSUB ;
2022-06-29 01:55:32 +02:00
using OT : : Layout : : GPOS ;
2020-02-26 22:11:42 +01:00
2022-06-03 09:17:20 +02:00
typedef hb_hashmap_t < unsigned , hb : : unique_ptr < hb_set_t > > script_langsys_map ;
2019-05-12 20:08:45 +02:00
# ifndef HB_NO_SUBSET_CFF
2019-05-11 08:46:22 +02:00
static inline void
2018-11-14 22:38:03 +01:00
_add_cff_seac_components ( const OT : : cff1 : : accelerator_t & cff ,
2019-10-08 11:54:26 +02:00
hb_codepoint_t gid ,
hb_set_t * gids_to_retain )
2018-11-14 22:38:03 +01:00
{
hb_codepoint_t base_gid , accent_gid ;
if ( cff . get_seac_components ( gid , & base_gid , & accent_gid ) )
{
2019-10-08 11:54:26 +02:00
gids_to_retain - > add ( base_gid ) ;
gids_to_retain - > add ( accent_gid ) ;
2018-11-14 22:38:03 +01:00
}
}
2019-05-12 20:08:45 +02:00
# endif
2018-11-14 22:38:03 +01:00
2021-05-11 20:44:32 +02:00
static void
_remap_palette_indexes ( const hb_set_t * palette_indexes ,
2021-06-09 22:46:35 +02:00
hb_map_t * mapping /* OUT */ )
2021-05-11 20:44:32 +02:00
{
unsigned new_idx = 0 ;
for ( unsigned palette_index : palette_indexes - > iter ( ) )
{
if ( palette_index = = 0xFFFF )
{
mapping - > set ( palette_index , palette_index ) ;
continue ;
}
mapping - > set ( palette_index , new_idx ) ;
new_idx + + ;
}
}
2019-10-23 01:00:43 +02:00
static void
2019-10-31 23:59:02 +01:00
_remap_indexes ( const hb_set_t * indexes ,
hb_map_t * mapping /* OUT */ )
2019-10-23 01:00:43 +02:00
{
2019-10-31 23:59:02 +01:00
unsigned count = indexes - > get_population ( ) ;
2019-10-23 01:00:43 +02:00
2019-10-31 23:59:02 +01:00
for ( auto _ : + hb_zip ( indexes - > iter ( ) , hb_range ( count ) ) )
mapping - > set ( _ . first , _ . second ) ;
2019-10-23 01:00:43 +02:00
}
2021-05-18 11:31:14 +02:00
# ifndef HB_NO_SUBSET_LAYOUT
2021-05-20 02:33:46 +02:00
typedef void ( * layout_collect_func_t ) ( hb_face_t * face , hb_tag_t table_tag , const hb_tag_t * scripts , const hb_tag_t * languages , const hb_tag_t * features , hb_set_t * lookup_indexes /* OUT */ ) ;
2021-08-25 02:06:14 +02:00
2022-07-01 01:04:35 +02:00
/*
2022-06-30 22:03:33 +02:00
* Removes all tags from ' tags ' that are not in filter . Additionally eliminates any duplicates .
* Returns true if anything was removed ( not including duplicates ) .
*/
static bool _filter_tag_list ( hb_vector_t < hb_tag_t > * tags , /* IN/OUT */
const hb_set_t * filter )
2018-06-07 23:32:34 +02:00
{
2022-06-30 22:03:33 +02:00
hb_vector_t < hb_tag_t > out ;
2022-07-05 19:49:12 +02:00
out . alloc ( tags - > get_size ( ) + 1 ) ; // +1 is to allocate room for the null terminator.
2021-08-25 00:53:32 +02:00
2022-06-30 22:03:33 +02:00
bool removed = false ;
hb_set_t visited ;
2021-08-25 00:53:32 +02:00
2022-06-30 22:03:33 +02:00
for ( hb_tag_t tag : * tags )
2021-08-25 00:53:32 +02:00
{
2021-11-16 04:58:33 +01:00
if ( ! tag ) continue ;
2022-06-30 22:03:33 +02:00
if ( visited . has ( tag ) ) continue ;
if ( ! filter - > has ( tag ) )
2021-11-16 04:58:33 +01:00
{
2022-06-30 22:03:33 +02:00
removed = true ;
2021-11-16 04:58:33 +01:00
continue ;
}
2022-02-11 21:44:58 +01:00
2022-06-30 22:03:33 +02:00
visited . add ( tag ) ;
out . push ( tag ) ;
2021-05-20 02:33:46 +02:00
}
2020-09-29 22:16:01 +02:00
2021-08-25 00:53:32 +02:00
// The collect function needs a null element to signal end of the array.
2022-07-05 20:33:19 +02:00
out . push ( HB_TAG_NONE ) ;
2021-05-20 02:33:46 +02:00
2022-06-30 22:03:33 +02:00
hb_swap ( out , * tags ) ;
return removed ;
}
2021-05-20 02:33:46 +02:00
2022-06-30 22:03:33 +02:00
template < typename T >
2022-06-30 22:14:29 +02:00
static void _collect_layout_indices ( hb_subset_plan_t * plan ,
2022-06-30 22:03:33 +02:00
const T & table ,
layout_collect_func_t layout_collect_func ,
hb_set_t * indices /* OUT */ )
{
2022-07-05 19:49:12 +02:00
unsigned num_features = table . get_feature_count ( ) ;
2022-06-30 22:03:33 +02:00
hb_vector_t < hb_tag_t > features ;
2022-06-30 22:14:29 +02:00
if ( ! plan - > check_success ( features . resize ( num_features ) ) ) return ;
2022-06-30 22:03:33 +02:00
table . get_feature_tags ( 0 , & num_features , features . arrayZ ) ;
2022-06-30 22:14:29 +02:00
bool retain_all_features = ! _filter_tag_list ( & features , plan - > layout_features ) ;
2022-06-30 22:03:33 +02:00
2022-07-05 19:49:12 +02:00
unsigned num_scripts = table . get_script_count ( ) ;
2022-06-30 22:24:42 +02:00
hb_vector_t < hb_tag_t > scripts ;
if ( ! plan - > check_success ( scripts . resize ( num_scripts ) ) ) return ;
table . get_script_tags ( 0 , & num_scripts , scripts . arrayZ ) ;
bool retain_all_scripts = ! _filter_tag_list ( & scripts , plan - > layout_scripts ) ;
if ( ! plan - > check_success ( ! features . in_error ( ) ) | | ! features
| | ! plan - > check_success ( ! scripts . in_error ( ) ) | | ! scripts )
2021-08-25 00:53:32 +02:00
return ;
2021-06-18 23:14:20 +02:00
2022-06-30 22:14:29 +02:00
layout_collect_func ( plan - > source ,
2021-08-25 00:53:32 +02:00
T : : tableTag ,
2022-06-30 22:24:42 +02:00
retain_all_scripts ? nullptr : scripts . arrayZ ,
2021-05-20 02:33:46 +02:00
nullptr ,
2022-06-30 22:24:42 +02:00
retain_all_features ? nullptr : features . arrayZ ,
2021-08-25 07:22:49 +02:00
indices ) ;
2019-10-23 01:00:43 +02:00
}
2022-07-11 19:39:41 +02:00
static inline void
_GSUBGPOS_find_duplicate_features ( const OT : : GSUBGPOS & g ,
const hb_map_t * lookup_indices ,
const hb_set_t * feature_indices ,
hb_map_t * duplicate_feature_map /* OUT */ )
{
if ( feature_indices - > is_empty ( ) ) return ;
hb_hashmap_t < hb_tag_t , hb : : unique_ptr < hb_set_t > > unique_features ;
//find out duplicate features after subset
for ( unsigned i : feature_indices - > iter ( ) )
{
hb_tag_t t = g . get_feature_tag ( i ) ;
if ( t = = HB_MAP_VALUE_INVALID ) continue ;
if ( ! unique_features . has ( t ) )
{
if ( unlikely ( ! unique_features . set ( t , hb : : unique_ptr < hb_set_t > { hb_set_create ( ) } ) ) )
return ;
if ( unique_features . has ( t ) )
unique_features . get ( t ) - > add ( i ) ;
duplicate_feature_map - > set ( i , i ) ;
continue ;
}
bool found = false ;
hb_set_t * same_tag_features = unique_features . get ( t ) ;
for ( unsigned other_f_index : same_tag_features - > iter ( ) )
{
const OT : : Feature & f = g . get_feature ( i ) ;
const OT : : Feature & other_f = g . get_feature ( other_f_index ) ;
auto f_iter =
+ hb_iter ( f . lookupIndex )
| hb_filter ( lookup_indices )
;
auto other_f_iter =
+ hb_iter ( other_f . lookupIndex )
| hb_filter ( lookup_indices )
;
bool is_equal = true ;
for ( ; f_iter & & other_f_iter ; f_iter + + , other_f_iter + + )
{
unsigned a = * f_iter ;
unsigned b = * other_f_iter ;
if ( a ! = b ) { is_equal = false ; break ; }
}
if ( is_equal = = false | | f_iter | | other_f_iter ) continue ;
found = true ;
duplicate_feature_map - > set ( i , other_f_index ) ;
break ;
}
if ( found = = false )
{
same_tag_features - > add ( i ) ;
duplicate_feature_map - > set ( i , i ) ;
}
}
}
2021-05-20 02:33:46 +02:00
template < typename T >
2019-10-23 01:00:43 +02:00
static inline void
2022-06-30 22:14:29 +02:00
_closure_glyphs_lookups_features ( hb_subset_plan_t * plan ,
2021-06-09 22:46:35 +02:00
hb_set_t * gids_to_retain ,
hb_map_t * lookups ,
hb_map_t * features ,
2021-05-20 02:33:46 +02:00
script_langsys_map * langsys_map )
2019-10-23 01:00:43 +02:00
{
2022-07-07 22:16:16 +02:00
hb_blob_ptr_t < T > table = plan - > source_table < T > ( ) ;
2021-05-20 02:33:46 +02:00
hb_tag_t table_tag = table - > tableTag ;
2019-10-23 01:00:43 +02:00
hb_set_t lookup_indices ;
2022-06-30 22:14:29 +02:00
_collect_layout_indices < T > ( plan ,
2021-08-25 02:06:14 +02:00
* table ,
hb_ot_layout_collect_lookups ,
& lookup_indices ) ;
2021-05-20 02:33:46 +02:00
if ( table_tag = = HB_OT_TAG_GSUB )
2022-06-30 22:14:29 +02:00
hb_ot_layout_lookups_substitute_closure ( plan - > source ,
& lookup_indices ,
2021-05-20 02:33:46 +02:00
gids_to_retain ) ;
2022-06-30 22:14:29 +02:00
table - > closure_lookups ( plan - > source ,
2021-05-20 02:33:46 +02:00
gids_to_retain ,
2022-06-30 22:14:29 +02:00
& lookup_indices ) ;
2021-05-20 02:33:46 +02:00
_remap_indexes ( & lookup_indices , lookups ) ;
2019-10-31 23:59:02 +01:00
2020-09-29 22:16:01 +02:00
// Collect and prune features
2019-10-31 23:59:02 +01:00
hb_set_t feature_indices ;
2022-06-30 22:14:29 +02:00
_collect_layout_indices < T > ( plan ,
2021-08-25 02:06:14 +02:00
* table ,
hb_ot_layout_collect_features ,
& feature_indices ) ;
2021-05-20 02:33:46 +02:00
table - > prune_features ( lookups , & feature_indices ) ;
2021-01-29 00:21:26 +01:00
hb_map_t duplicate_feature_map ;
2022-07-11 19:39:41 +02:00
_GSUBGPOS_find_duplicate_features ( * table , lookups , & feature_indices , & duplicate_feature_map ) ;
2021-01-29 00:21:26 +01:00
feature_indices . clear ( ) ;
2021-05-20 02:33:46 +02:00
table - > prune_langsys ( & duplicate_feature_map , langsys_map , & feature_indices ) ;
_remap_indexes ( & feature_indices , features ) ;
2021-01-29 00:21:26 +01:00
2021-05-20 02:33:46 +02:00
table . destroy ( ) ;
2018-06-07 23:32:34 +02:00
}
2021-05-20 02:33:46 +02:00
2019-05-14 12:26:18 +02:00
# endif
2018-06-07 23:32:34 +02:00
2020-02-26 22:11:42 +01:00
# ifndef HB_NO_VAR
static inline void
2022-08-01 20:37:47 +02:00
_generate_varstore_inner_maps ( const hb_set_t & varidx_set ,
unsigned subtable_count ,
hb_vector_t < hb_inc_bimap_t > & inner_maps /* OUT */ )
{
if ( varidx_set . is_empty ( ) | | subtable_count = = 0 ) return ;
inner_maps . resize ( subtable_count ) ;
for ( unsigned idx : varidx_set )
{
uint16_t major = idx > > 16 ;
uint16_t minor = idx & 0xFFFF ;
if ( major > = subtable_count )
continue ;
inner_maps [ major ] . add ( minor ) ;
}
}
2022-08-01 23:48:01 +02:00
static inline hb_font_t *
_get_hb_font_with_variations ( const hb_subset_plan_t * plan )
{
hb_font_t * font = hb_font_create ( plan - > source ) ;
hb_vector_t < hb_variation_t > vars ;
vars . alloc ( plan - > user_axes_location - > get_population ( ) ) ;
for ( auto _ : * plan - > user_axes_location )
{
hb_variation_t var ;
var . tag = _ . first ;
var . value = _ . second ;
vars . push ( var ) ;
}
hb_font_set_variations ( font , vars . arrayZ , plan - > user_axes_location - > get_population ( ) ) ;
return font ;
}
2022-08-01 20:37:47 +02:00
static inline void
_collect_layout_variation_indices ( hb_subset_plan_t * plan )
2020-02-26 22:11:42 +01:00
{
2022-07-07 22:16:16 +02:00
hb_blob_ptr_t < OT : : GDEF > gdef = plan - > source_table < OT : : GDEF > ( ) ;
hb_blob_ptr_t < GPOS > gpos = plan - > source_table < GPOS > ( ) ;
2020-02-26 22:11:42 +01:00
if ( ! gdef - > has_data ( ) )
{
gdef . destroy ( ) ;
gpos . destroy ( ) ;
return ;
}
2022-08-01 20:37:47 +02:00
2022-08-01 23:48:01 +02:00
const OT : : VariationStore * var_store = nullptr ;
2022-08-01 20:37:47 +02:00
hb_set_t varidx_set ;
2022-08-01 23:48:01 +02:00
hb_font_t * font = nullptr ;
float * store_cache = nullptr ;
bool collect_delta = plan - > pinned_at_default ? false : true ;
if ( collect_delta )
{
font = _get_hb_font_with_variations ( plan ) ;
if ( gdef - > has_var_store ( ) )
{
var_store = & ( gdef - > get_var_store ( ) ) ;
store_cache = var_store - > create_cache ( ) ;
}
}
OT : : hb_collect_variation_indices_context_t c ( & varidx_set ,
plan - > layout_variation_idx_delta_map ,
font , var_store ,
plan - > _glyphset_gsub ,
plan - > gpos_lookups ,
store_cache ) ;
2020-02-26 22:11:42 +01:00
gdef - > collect_variation_indices ( & c ) ;
2022-07-07 22:16:16 +02:00
if ( hb_ot_layout_has_positioning ( plan - > source ) )
2020-02-26 22:11:42 +01:00
gpos - > collect_variation_indices ( & c ) ;
2022-08-01 23:48:01 +02:00
hb_font_destroy ( font ) ;
var_store - > destroy_cache ( store_cache ) ;
2022-08-01 20:37:47 +02:00
gdef - > remap_layout_variation_indices ( & varidx_set , plan - > layout_variation_idx_delta_map ) ;
unsigned subtable_count = gdef - > has_var_store ( ) ? gdef - > get_var_store ( ) . get_sub_table_count ( ) : 0 ;
_generate_varstore_inner_maps ( varidx_set , subtable_count , plan - > gdef_varstore_inner_maps ) ;
2020-07-29 06:03:32 +02:00
2020-02-26 22:11:42 +01:00
gdef . destroy ( ) ;
gpos . destroy ( ) ;
2020-02-26 22:11:42 +01:00
}
# endif
2019-08-07 22:17:26 +02:00
static inline void
2021-06-09 22:46:35 +02:00
_cmap_closure ( hb_face_t * face ,
const hb_set_t * unicodes ,
hb_set_t * glyphset )
2019-08-07 22:17:26 +02:00
{
2022-01-20 19:47:17 +01:00
OT : : cmap : : accelerator_t cmap ( face ) ;
2019-10-29 01:12:55 +01:00
cmap . table - > closure_glyphs ( unicodes , glyphset ) ;
2019-08-07 22:17:26 +02:00
}
2021-10-03 05:32:30 +02:00
static void _colr_closure ( hb_face_t * face ,
hb_map_t * layers_map ,
hb_map_t * palettes_map ,
hb_set_t * glyphs_colred )
{
2022-01-20 20:37:21 +01:00
OT : : COLR : : accelerator_t colr ( face ) ;
2021-10-03 05:32:30 +02:00
if ( ! colr . is_valid ( ) ) return ;
hb_set_t palette_indices , layer_indices ;
2022-07-20 23:59:02 +02:00
// Collect all glyphs referenced by COLRv0
hb_set_t glyphset_colrv0 ;
for ( hb_codepoint_t gid : * glyphs_colred )
colr . closure_glyphs ( gid , & glyphset_colrv0 ) ;
glyphs_colred - > union_ ( glyphset_colrv0 ) ;
//closure for COLRv1
colr . closure_forV1 ( glyphs_colred , & layer_indices , & palette_indices ) ;
2021-10-03 05:32:30 +02:00
colr . closure_V0palette_indices ( glyphs_colred , & palette_indices ) ;
_remap_indexes ( & layer_indices , layers_map ) ;
_remap_palette_indexes ( & palette_indices , palettes_map ) ;
}
2021-09-20 23:42:51 +02:00
static inline void
2022-07-07 22:16:16 +02:00
_math_closure ( hb_subset_plan_t * plan ,
hb_set_t * glyphset )
2021-09-20 23:42:51 +02:00
{
2022-07-07 22:16:16 +02:00
hb_blob_ptr_t < OT : : MATH > math = plan - > source_table < OT : : MATH > ( ) ;
2021-09-20 23:42:51 +02:00
if ( math - > has_data ( ) )
math - > closure_glyphs ( glyphset ) ;
math . destroy ( ) ;
}
2019-05-11 08:46:22 +02:00
static inline void
2018-11-16 07:48:26 +01:00
_remove_invalid_gids ( hb_set_t * glyphs ,
unsigned int num_glyphs )
{
2022-05-05 18:19:16 +02:00
glyphs - > del_range ( num_glyphs , HB_SET_VALUE_INVALID ) ;
2018-11-16 07:48:26 +01:00
}
2018-06-07 23:32:34 +02:00
2021-07-15 02:27:14 +02:00
static void
_populate_unicodes_to_retain ( const hb_set_t * unicodes ,
const hb_set_t * glyphs ,
hb_subset_plan_t * plan )
{
2022-01-20 19:47:17 +01:00
OT : : cmap : : accelerator_t cmap ( plan - > source ) ;
2021-07-15 02:27:14 +02:00
2022-05-04 23:22:26 +02:00
unsigned size_threshold = plan - > source - > get_num_glyphs ( ) ;
if ( glyphs - > is_empty ( ) & & unicodes - > get_population ( ) < size_threshold )
2021-07-15 02:27:14 +02:00
{
2022-05-04 00:40:56 +02:00
// This is approach to collection is faster, but can only be used if glyphs
2022-05-04 23:22:26 +02:00
// are not being explicitly added to the subset and the input unicodes set is
// not excessively large (eg. an inverted set).
2022-05-04 00:02:59 +02:00
plan - > unicode_to_new_gid_list . alloc ( unicodes - > get_population ( ) ) ;
2021-08-25 22:34:05 +02:00
for ( hb_codepoint_t cp : * unicodes )
2021-07-15 02:27:14 +02:00
{
2021-08-25 22:34:05 +02:00
hb_codepoint_t gid ;
if ( ! cmap . get_nominal_glyph ( cp , & gid ) )
{
DEBUG_MSG ( SUBSET , nullptr , " Drop U+%04X; no gid " , cp ) ;
continue ;
}
2021-08-25 23:42:00 +02:00
2021-08-25 22:34:05 +02:00
plan - > codepoint_to_glyph - > set ( cp , gid ) ;
2022-05-04 00:02:59 +02:00
plan - > unicode_to_new_gid_list . push ( hb_pair ( cp , gid ) ) ;
2021-07-15 02:27:14 +02:00
}
2021-08-26 00:25:08 +02:00
}
else
{
2022-05-04 00:40:56 +02:00
// This approach is slower, but can handle adding in glyphs to the subset and will match
// them with cmap entries.
2021-08-25 23:42:00 +02:00
hb_map_t unicode_glyphid_map ;
2022-05-04 23:48:18 +02:00
hb_set_t cmap_unicodes ;
cmap . collect_mapping ( & cmap_unicodes , & unicode_glyphid_map ) ;
2022-05-04 23:22:26 +02:00
plan - > unicode_to_new_gid_list . alloc ( hb_min ( unicodes - > get_population ( )
+ glyphs - > get_population ( ) ,
2022-05-04 23:48:18 +02:00
cmap_unicodes . get_population ( ) ) ) ;
2021-07-15 02:27:14 +02:00
2022-05-04 23:48:18 +02:00
for ( hb_codepoint_t cp : cmap_unicodes )
2021-08-25 23:42:00 +02:00
{
2022-05-04 23:48:18 +02:00
hb_codepoint_t gid = unicode_glyphid_map [ cp ] ;
if ( ! unicodes - > has ( cp ) & & ! glyphs - > has ( gid ) )
continue ;
2021-07-15 02:27:14 +02:00
2022-05-04 23:48:18 +02:00
plan - > codepoint_to_glyph - > set ( cp , gid ) ;
plan - > unicode_to_new_gid_list . push ( hb_pair ( cp , gid ) ) ;
2021-08-25 23:42:00 +02:00
}
2021-08-25 22:34:05 +02:00
2021-08-26 00:25:08 +02:00
/* Add gids which where requested, but not mapped in cmap */
2022-05-04 23:48:18 +02:00
for ( hb_codepoint_t gid : * glyphs )
2021-08-25 23:42:00 +02:00
{
if ( gid > = plan - > source - > get_num_glyphs ( ) )
2021-08-26 00:25:08 +02:00
break ;
2021-08-25 23:42:00 +02:00
plan - > _glyphset_gsub - > add ( gid ) ;
}
2021-08-25 22:34:05 +02:00
}
2022-05-05 01:06:18 +02:00
auto & arr = plan - > unicode_to_new_gid_list ;
if ( arr . length )
2022-05-03 00:29:43 +02:00
{
2022-05-05 01:06:18 +02:00
plan - > unicodes - > add_sorted_array ( & arr . arrayZ - > first , arr . length , sizeof ( * arr . arrayZ ) ) ;
plan - > _glyphset_gsub - > add_array ( & arr . arrayZ - > second , arr . length , sizeof ( * arr . arrayZ ) ) ;
2022-05-03 00:29:43 +02:00
}
2021-07-15 02:27:14 +02:00
}
2022-06-26 01:01:11 +02:00
# ifndef HB_COMPOSITE_OPERATIONS_PER_GLYPH
# define HB_COMPOSITE_OPERATIONS_PER_GLYPH 64
2022-06-26 00:54:46 +02:00
# endif
static unsigned
_glyf_add_gid_and_children ( const OT : : glyf_accelerator_t & glyf ,
hb_codepoint_t gid ,
hb_set_t * gids_to_retain ,
2022-06-26 01:01:11 +02:00
int operation_count ,
unsigned depth = 0 )
2022-06-26 00:54:46 +02:00
{
if ( unlikely ( depth + + > HB_MAX_NESTING_LEVEL ) ) return operation_count ;
2022-06-26 01:01:11 +02:00
if ( unlikely ( - - operation_count < 0 ) ) return operation_count ;
2022-06-26 00:54:46 +02:00
/* Check if is already visited */
if ( gids_to_retain - > has ( gid ) ) return operation_count ;
gids_to_retain - > add ( gid ) ;
for ( auto item : glyf . glyph_for_gid ( gid ) . get_composite_iterator ( ) )
operation_count =
_glyf_add_gid_and_children ( glyf ,
2022-07-11 23:08:22 +02:00
item . get_gid ( ) ,
2022-06-26 00:54:46 +02:00
gids_to_retain ,
2022-06-26 01:01:11 +02:00
operation_count ,
depth ) ;
2022-06-26 00:54:46 +02:00
return operation_count ;
}
2019-05-21 00:04:20 +02:00
static void
_populate_gids_to_retain ( hb_subset_plan_t * plan ,
2019-10-23 01:00:43 +02:00
bool close_over_gsub ,
2020-02-26 22:11:42 +01:00
bool close_over_gpos ,
2020-07-29 06:14:23 +02:00
bool close_over_gdef )
2018-02-06 02:26:25 +01:00
{
2022-06-25 22:38:43 +02:00
OT : : glyf_accelerator_t glyf ( plan - > source ) ;
2019-11-20 05:36:56 +01:00
# ifndef HB_NO_SUBSET_CFF
2022-01-20 19:47:17 +01:00
OT : : cff1 : : accelerator_t cff ( plan - > source ) ;
2019-11-20 05:36:56 +01:00
# endif
2018-02-09 04:22:47 +01:00
2019-05-21 00:04:20 +02:00
plan - > _glyphset_gsub - > add ( 0 ) ; // Not-def
2018-02-09 04:22:47 +01:00
2019-08-07 22:17:26 +02:00
_cmap_closure ( plan - > source , plan - > unicodes , plan - > _glyphset_gsub ) ;
2018-02-07 18:32:36 +01:00
2019-05-11 08:46:22 +02:00
# ifndef HB_NO_SUBSET_LAYOUT
2018-06-07 23:32:34 +02:00
if ( close_over_gsub )
2019-10-31 23:59:02 +01:00
// closure all glyphs/lookups/features needed for GSUB substitutions.
2022-03-24 00:28:22 +01:00
_closure_glyphs_lookups_features < GSUB > (
2022-06-30 22:14:29 +02:00
plan ,
2021-07-30 00:07:13 +02:00
plan - > _glyphset_gsub ,
plan - > gsub_lookups ,
plan - > gsub_features ,
plan - > gsub_langsys ) ;
2019-10-23 01:00:43 +02:00
if ( close_over_gpos )
2022-06-25 01:14:30 +02:00
_closure_glyphs_lookups_features < GPOS > (
2022-06-30 22:14:29 +02:00
plan ,
2021-07-30 00:07:13 +02:00
plan - > _glyphset_gsub ,
plan - > gpos_lookups ,
plan - > gpos_features ,
plan - > gpos_langsys ) ;
2019-05-11 08:46:22 +02:00
# endif
2019-05-21 00:04:20 +02:00
_remove_invalid_gids ( plan - > _glyphset_gsub , plan - > source - > get_num_glyphs ( ) ) ;
2018-06-07 23:32:34 +02:00
2021-09-20 23:42:51 +02:00
hb_set_set ( plan - > _glyphset_mathed , plan - > _glyphset_gsub ) ;
2022-07-07 22:16:16 +02:00
_math_closure ( plan , plan - > _glyphset_mathed ) ;
2021-09-20 23:42:51 +02:00
_remove_invalid_gids ( plan - > _glyphset_mathed , plan - > source - > get_num_glyphs ( ) ) ;
2021-10-03 05:32:30 +02:00
hb_set_t cur_glyphset = * plan - > _glyphset_mathed ;
_colr_closure ( plan - > source , plan - > colrv1_layers , plan - > colr_palettes , & cur_glyphset ) ;
_remove_invalid_gids ( & cur_glyphset , plan - > source - > get_num_glyphs ( ) ) ;
2021-06-18 23:14:20 +02:00
2021-12-06 04:27:57 +01:00
hb_set_set ( plan - > _glyphset_colred , & cur_glyphset ) ;
2022-05-05 18:33:50 +02:00
/* Populate a full set of glyphs to retain by adding all referenced
* composite glyphs . */
if ( glyf . has_data ( ) )
for ( hb_codepoint_t gid : cur_glyphset )
2022-06-26 01:01:11 +02:00
_glyf_add_gid_and_children ( glyf , gid , plan - > _glyphset ,
cur_glyphset . get_population ( ) * HB_COMPOSITE_OPERATIONS_PER_GLYPH ) ;
2022-05-05 18:33:50 +02:00
else
plan - > _glyphset - > union_ ( cur_glyphset ) ;
2019-05-11 08:46:22 +02:00
# ifndef HB_NO_SUBSET_CFF
2022-05-05 18:33:50 +02:00
if ( cff . is_valid ( ) )
for ( hb_codepoint_t gid : cur_glyphset )
2019-05-21 00:04:20 +02:00
_add_cff_seac_components ( cff , gid , plan - > _glyphset ) ;
2019-05-11 08:46:22 +02:00
# endif
2018-05-30 21:23:51 +02:00
2019-05-21 00:04:20 +02:00
_remove_invalid_gids ( plan - > _glyphset , plan - > source - > get_num_glyphs ( ) ) ;
2021-05-11 20:44:32 +02:00
2018-11-16 07:48:26 +01:00
2020-02-26 22:11:42 +01:00
# ifndef HB_NO_VAR
if ( close_over_gdef )
2022-08-01 20:37:47 +02:00
_collect_layout_variation_indices ( plan ) ;
2020-02-26 22:11:42 +01:00
# endif
2018-02-06 02:26:25 +01:00
}
2018-02-06 00:22:30 +01:00
2022-05-18 23:42:28 +02:00
static void
_create_glyph_map_gsub ( const hb_set_t * glyph_set_gsub ,
const hb_map_t * glyph_map ,
hb_map_t * out )
{
+ hb_iter ( glyph_set_gsub )
| hb_map ( [ & ] ( hb_codepoint_t gid ) {
return hb_pair_t < hb_codepoint_t , hb_codepoint_t > ( gid ,
glyph_map - > get ( gid ) ) ;
} )
| hb_sink ( out )
;
}
2018-05-30 21:23:51 +02:00
static void
2019-05-09 01:33:03 +02:00
_create_old_gid_to_new_gid_map ( const hb_face_t * face ,
2021-06-09 22:46:35 +02:00
bool retain_gids ,
const hb_set_t * all_gids_to_retain ,
hb_map_t * glyph_map , /* OUT */
hb_map_t * reverse_glyph_map , /* OUT */
unsigned int * num_glyphs /* OUT */ )
2018-05-30 21:23:51 +02:00
{
2022-05-18 20:34:27 +02:00
unsigned pop = all_gids_to_retain - > get_population ( ) ;
reverse_glyph_map - > resize ( pop ) ;
glyph_map - > resize ( pop ) ;
2019-05-09 01:33:03 +02:00
if ( ! retain_gids )
2019-01-19 02:49:35 +01:00
{
2019-05-09 01:33:03 +02:00
+ hb_enumerate ( hb_iter ( all_gids_to_retain ) , ( hb_codepoint_t ) 0 )
| hb_sink ( reverse_glyph_map )
;
* num_glyphs = reverse_glyph_map - > get_population ( ) ;
2022-05-18 20:34:27 +02:00
}
else
{
2019-05-09 01:33:03 +02:00
+ hb_iter ( all_gids_to_retain )
2019-05-16 03:15:05 +02:00
| hb_map ( [ ] ( hb_codepoint_t _ ) {
2019-05-09 01:33:03 +02:00
return hb_pair_t < hb_codepoint_t , hb_codepoint_t > ( _ , _ ) ;
} )
2019-05-14 02:35:02 +02:00
| hb_sink ( reverse_glyph_map )
2019-05-09 01:33:03 +02:00
;
2022-05-05 18:48:24 +02:00
hb_codepoint_t max_glyph = HB_SET_VALUE_INVALID ;
hb_set_previous ( all_gids_to_retain , & max_glyph ) ;
2019-05-15 18:42:38 +02:00
* num_glyphs = max_glyph + 1 ;
2019-01-19 02:49:35 +01:00
}
2019-05-09 01:33:03 +02:00
+ reverse_glyph_map - > iter ( )
| hb_map ( & hb_pair_t < hb_codepoint_t , hb_codepoint_t > : : reverse )
| hb_sink ( glyph_map )
;
2018-05-30 21:23:51 +02:00
}
2019-05-13 18:38:42 +02:00
static void
2019-08-24 15:27:14 +02:00
_nameid_closure ( hb_face_t * face ,
2022-06-30 23:24:36 +02:00
hb_set_t * nameids ,
bool all_axes_pinned ,
hb_hashmap_t < hb_tag_t , float > * user_axes_location )
2019-05-13 18:38:42 +02:00
{
2019-08-04 09:01:31 +02:00
# ifndef HB_NO_STYLE
2022-06-30 23:24:36 +02:00
face - > table . STAT - > collect_name_ids ( user_axes_location , nameids ) ;
2019-06-20 03:36:35 +02:00
# endif
2019-06-20 04:26:22 +02:00
# ifndef HB_NO_VAR
2022-06-30 23:24:36 +02:00
if ( ! all_axes_pinned )
face - > table . fvar - > collect_name_ids ( user_axes_location , nameids ) ;
2019-06-20 04:26:22 +02:00
# endif
2019-05-13 18:38:42 +02:00
}
2022-07-19 22:57:14 +02:00
# ifndef HB_NO_VAR
2022-06-22 04:29:52 +02:00
static void
2022-07-22 18:37:09 +02:00
_normalize_axes_location ( hb_face_t * face , hb_subset_plan_t * plan )
2022-06-22 04:29:52 +02:00
{
2022-07-22 18:37:09 +02:00
if ( plan - > user_axes_location - > is_empty ( ) )
2022-06-22 04:29:52 +02:00
return ;
hb_array_t < const OT : : AxisRecord > axes = face - > table . fvar - > get_axes ( ) ;
bool has_avar = face - > table . avar - > has_data ( ) ;
const OT : : SegmentMaps * seg_maps = nullptr ;
if ( has_avar )
seg_maps = face - > table . avar - > get_segment_maps ( ) ;
bool axis_not_pinned = false ;
unsigned axis_count = 0 ;
for ( const auto & axis : axes )
{
hb_tag_t axis_tag = axis . get_axis_tag ( ) ;
2022-07-22 18:37:09 +02:00
if ( ! plan - > user_axes_location - > has ( axis_tag ) )
2022-06-22 04:29:52 +02:00
{
axis_not_pinned = true ;
}
else
{
2022-07-22 18:37:09 +02:00
int normalized_v = axis . normalize_axis_value ( plan - > user_axes_location - > get ( axis_tag ) ) ;
2022-06-22 04:29:52 +02:00
if ( has_avar & & axis_count < face - > table . avar - > get_axis_count ( ) )
{
normalized_v = seg_maps - > map ( normalized_v ) ;
}
2022-07-22 18:37:09 +02:00
plan - > axes_location - > set ( axis_tag , normalized_v ) ;
if ( normalized_v ! = 0 )
plan - > pinned_at_default = false ;
2022-06-22 04:29:52 +02:00
}
if ( has_avar )
seg_maps = & StructAfter < OT : : SegmentMaps > ( * seg_maps ) ;
2022-08-18 23:05:48 +02:00
2022-06-22 04:29:52 +02:00
axis_count + + ;
}
2022-07-22 18:37:09 +02:00
plan - > all_axes_pinned = ! axis_not_pinned ;
2022-06-22 04:29:52 +02:00
}
2022-07-19 22:57:14 +02:00
# endif
2018-02-06 00:22:30 +01:00
/**
2022-02-12 01:01:33 +01:00
* hb_subset_plan_create_or_fail :
2021-06-28 21:57:39 +02:00
* @ face : font face to create the plan for .
2021-07-26 02:13:49 +02:00
* @ input : a # hb_subset_input_t input .
2021-06-28 21:57:39 +02:00
*
2018-02-06 00:22:30 +01:00
* Computes a plan for subsetting the supplied face according
2018-08-30 03:09:55 +02:00
* to a provided input . The plan describes
2018-02-06 00:22:30 +01:00
* which tables and glyphs should be retained .
*
2021-07-26 02:13:49 +02:00
* Return value : ( transfer full ) : New subset plan . Destroy with
2022-02-12 01:01:33 +01:00
* hb_subset_plan_destroy ( ) . If there is a failure creating the plan
* nullptr will be returned .
2018-02-06 00:22:30 +01:00
*
2022-03-01 20:27:32 +01:00
* Since : 4.0 .0
2018-02-06 00:22:30 +01:00
* */
hb_subset_plan_t *
2022-02-12 01:01:33 +01:00
hb_subset_plan_create_or_fail ( hb_face_t * face ,
const hb_subset_input_t * input )
2018-02-06 00:22:30 +01:00
{
2020-07-29 03:31:46 +02:00
hb_subset_plan_t * plan ;
2020-07-29 06:03:32 +02:00
if ( unlikely ( ! ( plan = hb_object_create < hb_subset_plan_t > ( ) ) ) )
2022-02-12 01:01:33 +01:00
return nullptr ;
2018-02-10 21:20:10 +01:00
2020-07-29 03:31:46 +02:00
plan - > successful = true ;
2021-07-30 00:07:13 +02:00
plan - > flags = input - > flags ;
2019-04-05 19:05:55 +02:00
plan - > unicodes = hb_set_create ( ) ;
2022-05-04 00:02:59 +02:00
plan - > unicode_to_new_gid_list . init ( ) ;
2021-08-30 20:16:51 +02:00
plan - > name_ids = hb_set_copy ( input - > sets . name_ids ) ;
plan - > name_languages = hb_set_copy ( input - > sets . name_languages ) ;
plan - > layout_features = hb_set_copy ( input - > sets . layout_features ) ;
2022-06-30 23:00:48 +02:00
plan - > layout_scripts = hb_set_copy ( input - > sets . layout_scripts ) ;
2021-08-30 20:16:51 +02:00
plan - > glyphs_requested = hb_set_copy ( input - > sets . glyphs ) ;
plan - > drop_tables = hb_set_copy ( input - > sets . drop_tables ) ;
plan - > no_subset_tables = hb_set_copy ( input - > sets . no_subset_tables ) ;
2018-02-15 01:05:39 +01:00
plan - > source = hb_face_reference ( face ) ;
2018-08-25 17:18:53 +02:00
plan - > dest = hb_face_builder_create ( ) ;
2019-05-21 00:04:20 +02:00
plan - > _glyphset = hb_set_create ( ) ;
plan - > _glyphset_gsub = hb_set_create ( ) ;
2021-09-20 23:42:51 +02:00
plan - > _glyphset_mathed = hb_set_create ( ) ;
2021-12-06 04:27:57 +01:00
plan - > _glyphset_colred = hb_set_create ( ) ;
2019-04-05 19:05:55 +02:00
plan - > codepoint_to_glyph = hb_map_create ( ) ;
plan - > glyph_map = hb_map_create ( ) ;
plan - > reverse_glyph_map = hb_map_create ( ) ;
2022-05-18 23:42:28 +02:00
plan - > glyph_map_gsub = hb_map_create ( ) ;
2019-10-23 01:00:43 +02:00
plan - > gsub_lookups = hb_map_create ( ) ;
plan - > gpos_lookups = hb_map_create ( ) ;
2021-01-29 00:21:26 +01:00
2022-06-22 04:29:52 +02:00
plan - > check_success ( plan - > gsub_langsys = hb_hashmap_create < unsigned , hb : : unique_ptr < hb_set_t > > ( ) ) ;
plan - > check_success ( plan - > gpos_langsys = hb_hashmap_create < unsigned , hb : : unique_ptr < hb_set_t > > ( ) ) ;
2021-03-25 19:39:57 +01:00
2019-10-31 23:59:02 +01:00
plan - > gsub_features = hb_map_create ( ) ;
plan - > gpos_features = hb_map_create ( ) ;
2021-04-01 21:01:19 +02:00
plan - > colrv1_layers = hb_map_create ( ) ;
2021-05-11 20:44:32 +02:00
plan - > colr_palettes = hb_map_create ( ) ;
2022-08-01 20:37:47 +02:00
plan - > check_success ( plan - > layout_variation_idx_delta_map = hb_hashmap_create < unsigned , hb_pair_t < unsigned , int > > ( ) ) ;
plan - > gdef_varstore_inner_maps . init ( ) ;
2019-05-21 00:04:20 +02:00
2022-06-22 04:29:52 +02:00
plan - > check_success ( plan - > sanitized_table_cache = hb_hashmap_create < hb_tag_t , hb : : unique_ptr < hb_blob_t > > ( ) ) ;
plan - > check_success ( plan - > axes_location = hb_hashmap_create < hb_tag_t , int > ( ) ) ;
2022-06-30 18:36:19 +02:00
plan - > check_success ( plan - > user_axes_location = hb_hashmap_create < hb_tag_t , float > ( ) ) ;
if ( plan - > user_axes_location & & input - > axes_location )
* plan - > user_axes_location = * input - > axes_location ;
2022-06-22 04:29:52 +02:00
plan - > all_axes_pinned = false ;
2022-07-22 18:37:09 +02:00
plan - > pinned_at_default = true ;
plan - > check_success ( plan - > vmtx_map = hb_hashmap_create < unsigned , hb_pair_t < unsigned , int > > ( ) ) ;
plan - > check_success ( plan - > hmtx_map = hb_hashmap_create < unsigned , hb_pair_t < unsigned , int > > ( ) ) ;
2022-07-07 22:16:16 +02:00
2022-02-12 01:01:33 +01:00
if ( unlikely ( plan - > in_error ( ) ) ) {
2022-02-12 01:19:43 +01:00
hb_subset_plan_destroy ( plan ) ;
2022-02-12 01:01:33 +01:00
return nullptr ;
2021-03-25 19:39:57 +01:00
}
2021-08-30 20:16:51 +02:00
_populate_unicodes_to_retain ( input - > sets . unicodes , input - > sets . glyphs , plan ) ;
2021-07-15 02:27:14 +02:00
2019-05-21 00:04:20 +02:00
_populate_gids_to_retain ( plan ,
2021-08-30 20:16:51 +02:00
! input - > sets . drop_tables - > has ( HB_OT_TAG_GSUB ) ,
! input - > sets . drop_tables - > has ( HB_OT_TAG_GPOS ) ,
! input - > sets . drop_tables - > has ( HB_OT_TAG_GDEF ) ) ;
2019-01-18 03:55:56 +01:00
2019-01-29 03:10:56 +01:00
_create_old_gid_to_new_gid_map ( face ,
2021-07-29 20:52:14 +02:00
input - > flags & HB_SUBSET_FLAGS_RETAIN_GIDS ,
2019-03-26 17:15:56 +01:00
plan - > _glyphset ,
2019-01-19 02:49:35 +01:00
plan - > glyph_map ,
2019-08-24 15:27:14 +02:00
plan - > reverse_glyph_map ,
& plan - > _num_output_glyphs ) ;
2018-02-14 23:16:25 +01:00
2022-05-18 23:42:28 +02:00
_create_glyph_map_gsub (
plan - > _glyphset_gsub ,
plan - > glyph_map ,
plan - > glyph_map_gsub ) ;
2022-05-02 23:29:16 +02:00
// Now that we have old to new gid map update the unicode to new gid list.
2022-05-04 00:02:59 +02:00
for ( unsigned i = 0 ; i < plan - > unicode_to_new_gid_list . length ; i + + )
2022-05-02 23:29:16 +02:00
{
2022-05-04 00:02:59 +02:00
// Use raw array access for performance.
plan - > unicode_to_new_gid_list . arrayZ [ i ] . second =
plan - > glyph_map - > get ( plan - > unicode_to_new_gid_list . arrayZ [ i ] . second ) ;
2022-05-02 23:29:16 +02:00
}
2022-07-19 22:57:14 +02:00
# ifndef HB_NO_VAR
2022-07-22 18:37:09 +02:00
_normalize_axes_location ( face , plan ) ;
2022-07-19 22:57:14 +02:00
# endif
2022-06-22 04:29:52 +02:00
2022-06-30 23:24:36 +02:00
_nameid_closure ( face , plan - > name_ids , plan - > all_axes_pinned , plan - > user_axes_location ) ;
2022-02-12 01:01:33 +01:00
if ( unlikely ( plan - > in_error ( ) ) ) {
2022-02-12 01:19:43 +01:00
hb_subset_plan_destroy ( plan ) ;
2022-02-12 01:01:33 +01:00
return nullptr ;
}
2018-02-06 02:26:25 +01:00
return plan ;
2018-02-06 00:22:30 +01:00
}
/**
* hb_subset_plan_destroy :
2021-07-26 02:13:49 +02:00
* @ plan : a # hb_subset_plan_t
*
* Decreases the reference count on @ plan , and if it reaches zero , destroys
* @ plan , freeing all memory .
2018-02-06 00:22:30 +01:00
*
2022-03-01 20:27:32 +01:00
* Since : 4.0 .0
2018-02-06 00:22:30 +01:00
* */
void
hb_subset_plan_destroy ( hb_subset_plan_t * plan )
{
if ( ! hb_object_destroy ( plan ) ) return ;
2021-07-08 18:58:50 +02:00
hb_free ( plan ) ;
2018-02-06 00:22:30 +01:00
}
2022-02-11 21:44:58 +01:00
/**
* hb_subset_plan_old_to_new_glyph_mapping :
* @ plan : a subsetting plan .
*
2022-02-25 03:22:33 +01:00
* Returns the mapping between glyphs in the original font to glyphs in the
* subset that will be produced by @ plan
*
* Return value : ( transfer none ) :
* A pointer to the # hb_map_t of the mapping .
2022-02-11 21:44:58 +01:00
*
2022-03-01 20:27:32 +01:00
* Since : 4.0 .0
2022-02-11 21:44:58 +01:00
* */
const hb_map_t *
hb_subset_plan_old_to_new_glyph_mapping ( const hb_subset_plan_t * plan )
{
return plan - > glyph_map ;
}
/**
2022-02-25 03:22:33 +01:00
* hb_subset_plan_new_to_old_glyph_mapping :
2022-02-11 21:44:58 +01:00
* @ plan : a subsetting plan .
*
* Returns the mapping between glyphs in the subset that will be produced by
* @ plan and the glyph in the original font .
*
2022-02-25 03:22:33 +01:00
* Return value : ( transfer none ) :
* A pointer to the # hb_map_t of the mapping .
*
2022-03-01 20:27:32 +01:00
* Since : 4.0 .0
2022-02-11 21:44:58 +01:00
* */
const hb_map_t *
hb_subset_plan_new_to_old_glyph_mapping ( const hb_subset_plan_t * plan )
{
return plan - > reverse_glyph_map ;
}
/**
2022-03-01 11:01:18 +01:00
* hb_subset_plan_unicode_to_old_glyph_mapping :
2022-02-11 21:44:58 +01:00
* @ plan : a subsetting plan .
*
* Returns the mapping between codepoints in the original font and the
* associated glyph id in the original font .
*
2022-02-25 03:22:33 +01:00
* Return value : ( transfer none ) :
* A pointer to the # hb_map_t of the mapping .
*
2022-03-01 20:27:32 +01:00
* Since : 4.0 .0
2022-02-11 21:44:58 +01:00
* */
const hb_map_t *
2022-02-28 22:45:40 +01:00
hb_subset_plan_unicode_to_old_glyph_mapping ( const hb_subset_plan_t * plan )
2022-02-11 21:44:58 +01:00
{
return plan - > codepoint_to_glyph ;
}
2022-02-11 23:54:23 +01:00
/**
* hb_subset_plan_reference : ( skip )
* @ plan : a # hb_subset_plan_t object .
*
* Increases the reference count on @ plan .
*
* Return value : @ plan .
*
2022-03-01 20:27:32 +01:00
* Since : 4.0 .0
2022-02-11 23:54:23 +01:00
* */
hb_subset_plan_t *
hb_subset_plan_reference ( hb_subset_plan_t * plan )
{
return hb_object_reference ( plan ) ;
}
/**
* hb_subset_plan_set_user_data : ( skip )
* @ plan : a # hb_subset_plan_t object .
* @ key : The user - data key to set
* @ data : A pointer to the user data
* @ destroy : ( nullable ) : A callback to call when @ data is not needed anymore
* @ replace : Whether to replace an existing data with the same key
*
* Attaches a user - data key / data pair to the given subset plan object .
*
2022-06-30 08:43:57 +02:00
* Return value : ` true ` if success , ` false ` otherwise
2022-02-11 23:54:23 +01:00
*
2022-03-01 20:27:32 +01:00
* Since : 4.0 .0
2022-02-11 23:54:23 +01:00
* */
hb_bool_t
hb_subset_plan_set_user_data ( hb_subset_plan_t * plan ,
hb_user_data_key_t * key ,
void * data ,
hb_destroy_func_t destroy ,
hb_bool_t replace )
{
return hb_object_set_user_data ( plan , key , data , destroy , replace ) ;
}
/**
* hb_subset_plan_get_user_data : ( skip )
* @ plan : a # hb_subset_plan_t object .
* @ key : The user - data key to query
*
* Fetches the user data associated with the specified key ,
* attached to the specified subset plan object .
*
* Return value : ( transfer none ) : A pointer to the user data
*
2022-03-01 20:27:32 +01:00
* Since : 4.0 .0
2022-02-11 23:54:23 +01:00
* */
void *
hb_subset_plan_get_user_data ( const hb_subset_plan_t * plan ,
hb_user_data_key_t * key )
{
return hb_object_get_user_data ( plan , key ) ;
}