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"
# include "hb-ot-stat-table.hh"
2018-02-07 19:07:46 +01:00
2020-02-26 22:11:42 +01:00
2021-01-29 00:21:26 +01:00
typedef hb_hashmap_t < unsigned , hb_set_t * , ( unsigned ) - 1 , nullptr > 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-06-09 22:46:35 +02:00
static void _collect_subset_layout ( hb_face_t * face ,
hb_tag_t table_tag ,
const hb_set_t * layout_features_to_retain ,
bool retain_all_features ,
2021-05-20 02:33:46 +02:00
layout_collect_func_t layout_collect_func ,
2021-06-09 22:46:35 +02:00
hb_set_t * lookup_indices /* OUT */ )
2018-06-07 23:32:34 +02:00
{
2021-05-20 02:33:46 +02:00
if ( retain_all_features )
{
layout_collect_func ( face ,
table_tag ,
nullptr ,
nullptr ,
nullptr ,
lookup_indices ) ;
return ;
}
2020-09-29 22:16:01 +02:00
2021-05-20 02:33:46 +02:00
if ( hb_set_is_empty ( layout_features_to_retain ) ) return ;
unsigned num = layout_features_to_retain - > get_population ( ) + 1 ;
2021-07-08 18:58:50 +02:00
hb_tag_t * features = ( hb_tag_t * ) hb_malloc ( num * sizeof ( hb_tag_t ) ) ;
2021-05-20 02:33:46 +02:00
if ( ! features ) return ;
unsigned i = 0 ;
for ( hb_tag_t f : layout_features_to_retain - > iter ( ) )
features [ i + + ] = f ;
features [ i ] = 0 ;
2021-06-18 23:14:20 +02:00
2021-05-20 02:33:46 +02:00
layout_collect_func ( face ,
table_tag ,
nullptr ,
nullptr ,
features ,
lookup_indices ) ;
2021-07-08 18:58:50 +02:00
hb_free ( features ) ;
2019-10-23 01:00:43 +02:00
}
2021-05-20 02:33:46 +02:00
template < typename T >
2019-10-23 01:00:43 +02:00
static inline void
2021-06-09 22:46:35 +02:00
_closure_glyphs_lookups_features ( hb_face_t * face ,
hb_set_t * gids_to_retain ,
2021-05-20 02:33:46 +02:00
const hb_set_t * layout_features_to_retain ,
2021-06-09 22:46:35 +02:00
bool retain_all_features ,
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
{
2021-05-20 02:33:46 +02:00
hb_blob_ptr_t < T > table = hb_sanitize_context_t ( ) . reference_table < T > ( face ) ;
hb_tag_t table_tag = table - > tableTag ;
2019-10-23 01:00:43 +02:00
hb_set_t lookup_indices ;
2021-05-20 02:33:46 +02:00
_collect_subset_layout ( face ,
table_tag ,
layout_features_to_retain ,
retain_all_features ,
hb_ot_layout_collect_lookups ,
& lookup_indices ) ;
if ( table_tag = = HB_OT_TAG_GSUB )
hb_ot_layout_lookups_substitute_closure ( face ,
& lookup_indices ,
gids_to_retain ) ;
table - > closure_lookups ( face ,
gids_to_retain ,
2020-06-11 20:27:57 +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 ;
2021-05-20 02:33:46 +02:00
_collect_subset_layout ( face ,
table_tag ,
layout_features_to_retain ,
retain_all_features ,
hb_ot_layout_collect_features ,
& feature_indices ) ;
table - > prune_features ( lookups , & feature_indices ) ;
2021-01-29 00:21:26 +01:00
hb_map_t duplicate_feature_map ;
2021-05-20 02:33:46 +02:00
table - > find_duplicate_features ( 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
_collect_layout_variation_indices ( hb_face_t * face ,
const hb_set_t * glyphset ,
const hb_map_t * gpos_lookups ,
hb_set_t * layout_variation_indices ,
hb_map_t * layout_variation_idx_map )
{
2020-02-26 22:11:42 +01:00
hb_blob_ptr_t < OT : : GDEF > gdef = hb_sanitize_context_t ( ) . reference_table < OT : : GDEF > ( face ) ;
hb_blob_ptr_t < OT : : GPOS > gpos = hb_sanitize_context_t ( ) . reference_table < OT : : GPOS > ( face ) ;
if ( ! gdef - > has_data ( ) )
{
gdef . destroy ( ) ;
gpos . destroy ( ) ;
return ;
}
OT : : hb_collect_variation_indices_context_t c ( layout_variation_indices , glyphset , gpos_lookups ) ;
gdef - > collect_variation_indices ( & c ) ;
if ( hb_ot_layout_has_positioning ( face ) )
gpos - > collect_variation_indices ( & c ) ;
gdef - > remap_layout_variation_indices ( layout_variation_indices , layout_variation_idx_map ) ;
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
{
2019-10-29 01:12:55 +01:00
OT : : cmap : : accelerator_t cmap ;
cmap . init ( face ) ;
cmap . table - > closure_glyphs ( unicodes , glyphset ) ;
cmap . fini ( ) ;
2019-08-07 22:17:26 +02:00
}
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 )
{
hb_codepoint_t gid = HB_SET_VALUE_INVALID ;
while ( glyphs - > next ( & gid ) )
{
if ( gid > = num_glyphs )
glyphs - > del ( gid ) ;
}
}
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 )
{
OT : : cmap : : accelerator_t cmap ;
cmap . init ( plan - > source ) ;
for ( hb_codepoint_t cp : * unicodes )
{
hb_codepoint_t gid ;
if ( ! cmap . get_nominal_glyph ( cp , & gid ) )
{
DEBUG_MSG ( SUBSET , nullptr , " Drop U+%04X; no gid " , cp ) ;
continue ;
}
plan - > unicodes - > add ( cp ) ;
plan - > codepoint_to_glyph - > set ( cp , gid ) ;
plan - > _glyphset_gsub - > add ( gid ) ;
}
if ( glyphs - > is_empty ( ) )
{
cmap . fini ( ) ;
return ;
}
hb_map_t unicode_glyphid_map ;
cmap . collect_mapping ( hb_set_get_empty ( ) , & unicode_glyphid_map ) ;
cmap . fini ( ) ;
for ( hb_pair_t < hb_codepoint_t , hb_codepoint_t > cp_gid :
+ unicode_glyphid_map . iter ( ) | hb_filter ( glyphs , hb_second ) )
{
plan - > unicodes - > add ( cp_gid . first ) ;
plan - > codepoint_to_glyph - > set ( cp_gid . first , cp_gid . second ) ;
}
}
2019-05-21 00:04:20 +02:00
static void
_populate_gids_to_retain ( hb_subset_plan_t * plan ,
2018-11-15 20:40:56 +01:00
const hb_set_t * unicodes ,
2019-08-24 15:27:14 +02:00
const hb_set_t * input_glyphs_to_retain ,
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
{
2018-02-16 19:27:03 +01:00
OT : : glyf : : accelerator_t glyf ;
2019-11-20 05:36:56 +01:00
# ifndef HB_NO_SUBSET_CFF
2018-11-14 22:38:03 +01:00
OT : : cff1 : : accelerator_t cff ;
2019-11-20 05:36:56 +01:00
# endif
2020-01-24 14:52:23 +01:00
OT : : COLR : : accelerator_t colr ;
2019-05-21 00:04:20 +02:00
glyf . init ( plan - > source ) ;
2019-11-20 05:36:56 +01:00
# ifndef HB_NO_SUBSET_CFF
2019-05-21 00:04:20 +02:00
cff . init ( plan - > source ) ;
2019-11-20 05:36:56 +01:00
# endif
2020-01-24 14:52:23 +01:00
colr . init ( plan - > source ) ;
2018-02-09 04:22:47 +01:00
2019-05-21 00:04:20 +02:00
plan - > _glyphset_gsub - > add ( 0 ) ; // Not-def
hb_set_union ( plan - > _glyphset_gsub , input_glyphs_to_retain ) ;
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.
2021-05-20 02:33:46 +02:00
_closure_glyphs_lookups_features < OT : : GSUB > ( plan - > source , plan - > _glyphset_gsub , plan - > layout_features , plan - > retain_all_layout_features , plan - > gsub_lookups , plan - > gsub_features , plan - > gsub_langsys ) ;
2019-10-23 01:00:43 +02:00
if ( close_over_gpos )
2021-05-20 02:33:46 +02:00
_closure_glyphs_lookups_features < OT : : GPOS > ( plan - > source , plan - > _glyphset_gsub , plan - > layout_features , plan - > retain_all_layout_features , 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-05-05 01:48:41 +02:00
// Collect all glyphs referenced by COLRv0
hb_set_t * cur_glyphset = plan - > _glyphset_gsub ;
hb_set_t glyphset_colrv0 ;
if ( colr . is_valid ( ) )
{
2021-06-09 19:51:32 +02:00
glyphset_colrv0 . union_ ( * cur_glyphset ) ;
2021-05-05 01:48:41 +02:00
for ( hb_codepoint_t gid : cur_glyphset - > iter ( ) )
colr . closure_glyphs ( gid , & glyphset_colrv0 ) ;
cur_glyphset = & glyphset_colrv0 ;
}
2021-06-18 23:14:20 +02:00
hb_set_t palette_indices ;
colr . closure_V0palette_indices ( cur_glyphset , & palette_indices ) ;
hb_set_t layer_indices ;
colr . closure_forV1 ( cur_glyphset , & layer_indices , & palette_indices ) ;
_remap_indexes ( & layer_indices , plan - > colrv1_layers ) ;
_remap_palette_indexes ( & palette_indices , plan - > colr_palettes ) ;
colr . fini ( ) ;
_remove_invalid_gids ( cur_glyphset , plan - > source - > get_num_glyphs ( ) ) ;
2018-02-16 19:27:03 +01:00
// Populate a full set of glyphs to retain by adding all referenced
// composite glyphs.
2021-05-05 01:48:41 +02:00
for ( hb_codepoint_t gid : cur_glyphset - > iter ( ) )
2018-05-30 21:23:51 +02:00
{
2019-10-08 12:16:55 +02:00
glyf . add_gid_and_children ( gid , plan - > _glyphset ) ;
2019-05-11 08:46:22 +02:00
# ifndef HB_NO_SUBSET_CFF
2018-11-14 22:38:03 +01:00
if ( cff . is_valid ( ) )
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 )
2020-10-06 19:26:17 +02:00
_collect_layout_variation_indices ( plan - > source ,
2021-06-09 22:46:35 +02:00
plan - > _glyphset_gsub ,
plan - > gpos_lookups ,
plan - > layout_variation_indices ,
plan - > layout_variation_idx_map ) ;
2020-02-26 22:11:42 +01:00
# endif
2019-11-20 05:36:56 +01:00
# ifndef HB_NO_SUBSET_CFF
2018-11-14 22:38:03 +01:00
cff . fini ( ) ;
2019-11-20 05:36:56 +01:00
# endif
2018-02-16 19:27:03 +01:00
glyf . fini ( ) ;
2018-02-06 02:26:25 +01:00
}
2018-02-06 00:22:30 +01:00
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
{
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 ( ) ;
} else {
+ 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
;
2019-05-15 18:42:38 +02:00
unsigned max_glyph =
+ hb_iter ( all_gids_to_retain )
2019-07-17 20:20:08 +02:00
| hb_reduce ( hb_max , 0u )
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 ,
hb_set_t * nameids )
2019-05-13 18:38:42 +02:00
{
2019-08-04 09:01:31 +02:00
# ifndef HB_NO_STYLE
2019-06-20 03:42:39 +02:00
face - > table . STAT - > collect_name_ids ( nameids ) ;
2019-06-20 03:36:35 +02:00
# endif
2019-06-20 04:26:22 +02:00
# ifndef HB_NO_VAR
2019-06-20 03:42:39 +02:00
face - > table . fvar - > collect_name_ids ( nameids ) ;
2019-06-20 04:26:22 +02:00
# endif
2019-05-13 18:38:42 +02:00
}
2018-02-06 00:22:30 +01:00
/**
* hb_subset_plan_create :
2021-06-28 21:57:39 +02:00
* @ face : font face to create the plan for .
* @ input : a subset input .
*
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 .
*
2018-02-06 02:14:46 +01:00
* Return value : New subset plan .
2018-02-06 00:22:30 +01:00
*
* Since : 1.7 .5
* */
hb_subset_plan_t *
2021-06-09 22:46:35 +02:00
hb_subset_plan_create ( hb_face_t * face ,
2021-06-09 19:42:48 +02:00
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 > ( ) ) ) )
2020-07-29 03:31:46 +02:00
return const_cast < hb_subset_plan_t * > ( & Null ( hb_subset_plan_t ) ) ;
2018-02-10 21:20:10 +01:00
2020-07-29 03:31:46 +02:00
plan - > successful = true ;
2018-05-30 21:23:51 +02:00
plan - > drop_hints = input - > drop_hints ;
2018-11-01 06:30:34 +01:00
plan - > desubroutinize = input - > desubroutinize ;
2019-04-26 19:12:38 +02:00
plan - > retain_gids = input - > retain_gids ;
2020-01-21 22:37:28 +01:00
plan - > name_legacy = input - > name_legacy ;
2021-05-19 01:54:01 +02:00
plan - > overlaps_flag = input - > overlaps_flag ;
2021-06-10 00:36:40 +02:00
plan - > notdef_outline = input - > notdef_outline ;
2021-06-24 19:17:46 +02:00
plan - > prune_unicode_ranges = ! input - > no_prune_unicode_ranges ;
2021-05-20 02:33:46 +02:00
plan - > retain_all_layout_features = input - > retain_all_layout_features ;
2021-06-10 02:46:47 +02:00
plan - > passthrough_unrecognized = input - > passthrough_unrecognized ;
2019-04-05 19:05:55 +02:00
plan - > unicodes = hb_set_create ( ) ;
2021-06-09 23:05:17 +02:00
plan - > name_ids = hb_set_copy ( input - > name_ids ) ;
2019-05-13 18:38:42 +02:00
_nameid_closure ( face , plan - > name_ids ) ;
2021-06-09 22:46:35 +02:00
plan - > name_languages = hb_set_copy ( input - > name_languages ) ;
plan - > layout_features = hb_set_copy ( input - > layout_features ) ;
plan - > glyphs_requested = hb_set_copy ( input - > glyphs ) ;
plan - > drop_tables = hb_set_copy ( input - > drop_tables ) ;
2021-06-10 02:46:47 +02:00
plan - > no_subset_tables = hb_set_copy ( input - > 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 ( ) ;
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 ( ) ;
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
2021-03-25 19:39:57 +01:00
if ( plan - > check_success ( plan - > gsub_langsys = hb_object_create < script_langsys_map > ( ) ) )
plan - > gsub_langsys - > init_shallow ( ) ;
if ( plan - > check_success ( plan - > gpos_langsys = hb_object_create < script_langsys_map > ( ) ) )
plan - > gpos_langsys - > init_shallow ( ) ;
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 ( ) ;
2020-02-26 22:11:42 +01:00
plan - > layout_variation_indices = hb_set_create ( ) ;
plan - > layout_variation_idx_map = hb_map_create ( ) ;
2019-05-21 00:04:20 +02:00
2021-03-25 19:39:57 +01:00
if ( plan - > in_error ( ) ) {
return plan ;
}
2021-07-15 02:27:14 +02:00
_populate_unicodes_to_retain ( input - > unicodes , input - > glyphs , plan ) ;
2019-05-21 00:04:20 +02:00
_populate_gids_to_retain ( plan ,
2019-08-24 15:27:14 +02:00
input - > unicodes ,
input - > glyphs ,
2019-10-23 01:00:43 +02:00
! input - > drop_tables - > has ( HB_OT_TAG_GSUB ) ,
2020-02-26 22:11:42 +01:00
! input - > drop_tables - > has ( HB_OT_TAG_GPOS ) ,
2020-07-29 06:14:23 +02:00
! input - > 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 ,
2019-08-24 15:27:14 +02:00
input - > 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
2018-02-06 02:26:25 +01:00
return plan ;
2018-02-06 00:22:30 +01:00
}
/**
* hb_subset_plan_destroy :
*
* Since : 1.7 .5
* */
void
hb_subset_plan_destroy ( hb_subset_plan_t * plan )
{
if ( ! hb_object_destroy ( plan ) ) return ;
2018-05-30 21:23:51 +02:00
hb_set_destroy ( plan - > unicodes ) ;
2019-04-05 19:05:55 +02:00
hb_set_destroy ( plan - > name_ids ) ;
2020-01-21 22:37:28 +01:00
hb_set_destroy ( plan - > name_languages ) ;
2021-05-20 02:33:46 +02:00
hb_set_destroy ( plan - > layout_features ) ;
2020-04-23 00:58:41 +02:00
hb_set_destroy ( plan - > glyphs_requested ) ;
2019-05-16 20:29:15 +02:00
hb_set_destroy ( plan - > drop_tables ) ;
2021-07-22 22:26:03 +02:00
hb_set_destroy ( plan - > no_subset_tables ) ;
2018-02-15 01:05:39 +01:00
hb_face_destroy ( plan - > source ) ;
hb_face_destroy ( plan - > dest ) ;
2018-05-30 21:23:51 +02:00
hb_map_destroy ( plan - > codepoint_to_glyph ) ;
hb_map_destroy ( plan - > glyph_map ) ;
2019-01-19 03:33:21 +01:00
hb_map_destroy ( plan - > reverse_glyph_map ) ;
2019-01-29 01:59:15 +01:00
hb_set_destroy ( plan - > _glyphset ) ;
2019-05-21 00:04:20 +02:00
hb_set_destroy ( plan - > _glyphset_gsub ) ;
2019-10-23 01:00:43 +02:00
hb_map_destroy ( plan - > gsub_lookups ) ;
hb_map_destroy ( plan - > gpos_lookups ) ;
2019-10-31 23:59:02 +01:00
hb_map_destroy ( plan - > gsub_features ) ;
hb_map_destroy ( plan - > gpos_features ) ;
2021-04-01 21:01:19 +02:00
hb_map_destroy ( plan - > colrv1_layers ) ;
2021-05-11 20:44:32 +02:00
hb_map_destroy ( plan - > colr_palettes ) ;
2020-02-26 22:11:42 +01:00
hb_set_destroy ( plan - > layout_variation_indices ) ;
hb_map_destroy ( plan - > layout_variation_idx_map ) ;
2019-10-31 23:59:02 +01:00
2021-03-25 19:39:57 +01:00
if ( plan - > gsub_langsys )
{
for ( auto _ : plan - > gsub_langsys - > iter ( ) )
hb_set_destroy ( _ . second ) ;
hb_object_destroy ( plan - > gsub_langsys ) ;
plan - > gsub_langsys - > fini_shallow ( ) ;
2021-07-08 18:58:50 +02:00
hb_free ( plan - > gsub_langsys ) ;
2021-03-25 19:39:57 +01:00
}
if ( plan - > gpos_langsys )
{
for ( auto _ : plan - > gpos_langsys - > iter ( ) )
hb_set_destroy ( _ . second ) ;
hb_object_destroy ( plan - > gpos_langsys ) ;
plan - > gpos_langsys - > fini_shallow ( ) ;
2021-07-08 18:58:50 +02:00
hb_free ( plan - > gpos_langsys ) ;
2021-03-25 19:39:57 +01:00
}
2018-02-15 01:05:39 +01:00
2021-07-08 18:58:50 +02:00
hb_free ( plan ) ;
2018-02-06 00:22:30 +01:00
}