tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

hb-subset-plan.hh (10179B)


      1 /*
      2 * Copyright © 2018  Google, Inc.
      3 *
      4 *  This is part of HarfBuzz, a text shaping library.
      5 *
      6 * Permission is hereby granted, without written agreement and without
      7 * license or royalty fees, to use, copy, modify, and distribute this
      8 * software and its documentation for any purpose, provided that the
      9 * above copyright notice and the following two paragraphs appear in
     10 * all copies of this software.
     11 *
     12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
     13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
     14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
     15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
     16 * DAMAGE.
     17 *
     18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
     19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
     20 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
     21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
     22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
     23 *
     24 * Google Author(s): Garret Rieger, Roderick Sheeter
     25 */
     26 
     27 #ifndef HB_SUBSET_PLAN_HH
     28 #define HB_SUBSET_PLAN_HH
     29 
     30 #include "hb.hh"
     31 
     32 #include "hb-subset.h"
     33 #include "hb-subset-input.hh"
     34 #include "hb-subset-accelerator.hh"
     35 
     36 #include "hb-map.hh"
     37 #include "hb-bimap.hh"
     38 #include "hb-set.hh"
     39 
     40 namespace OT {
     41 struct Feature;
     42 }
     43 
     44 struct os2_info_t {
     45  hb_codepoint_t min_cmap_codepoint;
     46  hb_codepoint_t max_cmap_codepoint;
     47 };
     48 
     49 typedef struct os2_info_t os2_info_t;
     50 
     51 struct head_maxp_info_t
     52 {
     53  head_maxp_info_t ()
     54      :xMin (0x7FFF), xMax (-0x7FFF), yMin (0x7FFF), yMax (-0x7FFF),
     55      maxPoints (0), maxContours (0),
     56      maxCompositePoints (0),
     57      maxCompositeContours (0),
     58      maxComponentElements (0),
     59      maxComponentDepth (0),
     60      allXMinIsLsb (true) {}
     61 
     62  int xMin;
     63  int xMax;
     64  int yMin;
     65  int yMax;
     66  unsigned maxPoints;
     67  unsigned maxContours;
     68  unsigned maxCompositePoints;
     69  unsigned maxCompositeContours;
     70  unsigned maxComponentElements;
     71  unsigned maxComponentDepth;
     72  bool allXMinIsLsb;
     73 };
     74 
     75 typedef struct head_maxp_info_t head_maxp_info_t;
     76 
     77 struct contour_point_t
     78 {
     79  void init (float x_ = 0.f, float y_ = 0.f, bool is_end_point_ = false)
     80  { flag = 0; x = x_; y = y_; is_end_point = is_end_point_; }
     81 
     82  void transform (const float (&matrix)[4])
     83  {
     84    float x_ = x * matrix[0] + y * matrix[2];
     85   y  = x * matrix[1] + y * matrix[3];
     86    x  = x_;
     87  }
     88 
     89  void add_delta (float delta_x, float delta_y)
     90  {
     91    x += delta_x;
     92    y += delta_y;
     93  }
     94 
     95  HB_ALWAYS_INLINE
     96  void translate (const contour_point_t &p) { x += p.x; y += p.y; }
     97 
     98  float x;
     99  float y;
    100  uint8_t flag;
    101  bool is_end_point;
    102 };
    103 
    104 struct contour_point_vector_t : hb_vector_t<contour_point_t>
    105 {
    106  bool add_deltas (hb_array_t<const float> deltas_x,
    107                   hb_array_t<const float> deltas_y,
    108                   hb_array_t<const bool> indices)
    109  {
    110    if (indices.length != deltas_x.length ||
    111        indices.length != deltas_y.length)
    112      return false;
    113 
    114    for (unsigned i = 0; i < indices.length; i++)
    115    {
    116      if (!indices.arrayZ[i]) continue;
    117      arrayZ[i].add_delta (deltas_x.arrayZ[i], deltas_y.arrayZ[i]);
    118    }
    119    return true;
    120  }
    121 };
    122 
    123 namespace OT {
    124  struct cff1_subset_accelerator_t;
    125  struct cff2_subset_accelerator_t;
    126 }
    127 
    128 struct hb_subset_plan_t
    129 {
    130  HB_INTERNAL hb_subset_plan_t (hb_face_t *,
    131 			const hb_subset_input_t *input);
    132 
    133  HB_INTERNAL ~hb_subset_plan_t();
    134 
    135  hb_object_header_t header;
    136 
    137  bool successful;
    138  unsigned flags;
    139  bool attach_accelerator_data = false;
    140  bool force_long_loca = false;
    141 
    142  // The glyph subset
    143  hb_map_t *codepoint_to_glyph; // Needs to be heap-allocated
    144 
    145  // Old -> New glyph id mapping
    146  hb_map_t *glyph_map; // Needs to be heap-allocated
    147  hb_map_t *reverse_glyph_map; // Needs to be heap-allocated
    148 
    149  // Plan is only good for a specific source/dest so keep them with it
    150  hb_face_t *source;
    151 #ifndef HB_NO_SUBSET_CFF
    152  // These have to be immediately after source:
    153  hb_face_lazy_loader_t<OT::cff1_subset_accelerator_t, 1> cff1_accel;
    154  hb_face_lazy_loader_t<OT::cff2_subset_accelerator_t, 2> cff2_accel;
    155 #endif
    156 
    157  hb_face_t *dest;
    158 
    159  unsigned int _num_output_glyphs;
    160 
    161  bool all_axes_pinned;
    162  bool pinned_at_default;
    163  bool has_seac;
    164 
    165  // whether to insert a catch-all FeatureVariationRecord
    166  bool gsub_insert_catch_all_feature_variation_rec;
    167  bool gpos_insert_catch_all_feature_variation_rec;
    168 
    169  // whether GDEF ItemVariationStore is retained
    170  mutable bool has_gdef_varstore;
    171 
    172 #define HB_SUBSET_PLAN_MEMBER(Type, Name) Type Name;
    173 #include "hb-subset-plan-member-list.hh"
    174 #undef HB_SUBSET_PLAN_MEMBER
    175 
    176  //recalculated head/maxp table info after instancing
    177  mutable head_maxp_info_t head_maxp_info;
    178 
    179  os2_info_t os2_info;
    180 
    181  const hb_subset_accelerator_t* accelerator;
    182  hb_subset_accelerator_t* inprogress_accelerator;
    183 
    184 public:
    185 
    186  template<typename T>
    187  struct source_table_loader
    188  {
    189    hb_blob_ptr_t<T> operator () (hb_subset_plan_t *plan)
    190    {
    191      hb_lock_t lock (plan->accelerator ? &plan->accelerator->sanitized_table_cache_lock : nullptr);
    192 
    193      auto *cache = plan->accelerator ? &plan->accelerator->sanitized_table_cache : &plan->sanitized_table_cache;
    194      if (cache
    195   && !cache->in_error ()
    196   && cache->has (+T::tableTag)) {
    197 return hb_blob_reference (cache->get (+T::tableTag).get ());
    198      }
    199 
    200      hb::unique_ptr<hb_blob_t> table_blob {hb_sanitize_context_t ().reference_table<T> (plan->source)};
    201      hb_blob_t* ret = hb_blob_reference (table_blob.get ());
    202 
    203      if (likely (cache))
    204 cache->set (+T::tableTag, std::move (table_blob));
    205 
    206      return ret;
    207    }
    208  };
    209 
    210  template<typename T>
    211  auto source_table() HB_AUTO_RETURN (source_table_loader<T> {} (this))
    212 
    213  bool in_error () const { return !successful; }
    214 
    215  bool check_success(bool success)
    216  {
    217    successful = (successful && success);
    218    return successful;
    219  }
    220 
    221  /*
    222   * The set of input glyph ids which will be retained in the subset.
    223   * Does NOT include ids kept due to retain_gids. You probably want to use
    224   * glyph_map/reverse_glyph_map.
    225   */
    226  inline const hb_set_t *
    227  glyphset () const
    228  {
    229    return &_glyphset;
    230  }
    231 
    232  /*
    233   * The set of input glyph ids which will be retained in the subset.
    234   */
    235  inline const hb_set_t *
    236  glyphset_gsub () const
    237  {
    238    return &_glyphset_gsub;
    239  }
    240 
    241  /*
    242   * The total number of output glyphs in the final subset.
    243   */
    244  inline unsigned int
    245  num_output_glyphs () const
    246  {
    247    return _num_output_glyphs;
    248  }
    249 
    250  inline bool new_gid_for_codepoint (hb_codepoint_t codepoint,
    251 			     hb_codepoint_t *new_gid) const
    252  {
    253    hb_codepoint_t old_gid = codepoint_to_glyph->get (codepoint);
    254    if (old_gid == HB_MAP_VALUE_INVALID)
    255      return false;
    256 
    257    return new_gid_for_old_gid (old_gid, new_gid);
    258  }
    259 
    260  inline bool new_gid_for_old_gid (hb_codepoint_t old_gid,
    261 			   hb_codepoint_t *new_gid) const
    262  {
    263    hb_codepoint_t gid = glyph_map->get (old_gid);
    264    if (gid == HB_MAP_VALUE_INVALID)
    265      return false;
    266 
    267    *new_gid = gid;
    268    return true;
    269  }
    270 
    271  inline bool old_gid_for_new_gid (hb_codepoint_t  new_gid,
    272 			   hb_codepoint_t *old_gid) const
    273  {
    274    hb_codepoint_t gid = reverse_glyph_map->get (new_gid);
    275    if (gid == HB_MAP_VALUE_INVALID)
    276      return false;
    277 
    278    *old_gid = gid;
    279    return true;
    280  }
    281 
    282  inline bool
    283  add_table (hb_tag_t tag,
    284      hb_blob_t *contents)
    285  {
    286    if (HB_DEBUG_SUBSET)
    287    {
    288      hb_blob_t *source_blob = source->reference_table (tag);
    289      DEBUG_MSG(SUBSET, nullptr, "add table %c%c%c%c, dest %u bytes, source %u bytes",
    290 	HB_UNTAG(tag),
    291 	hb_blob_get_length (contents),
    292 	hb_blob_get_length (source_blob));
    293      hb_blob_destroy (source_blob);
    294    }
    295    return hb_face_builder_add_table (dest, tag, contents);
    296  }
    297 };
    298 
    299 // hb-subset-plan implementation is split into multiple files to keep
    300 // compile times more reasonable:
    301 // - hb-subset-plan.cc
    302 // - hb-subset-plan-layout.cc
    303 // - hb-subset-plan-var.cc
    304 //
    305 // The functions below are those needed to connect the split files
    306 // above together.
    307 HB_INTERNAL void
    308 remap_indexes (const hb_set_t *indexes,
    309               hb_map_t       *mapping /* OUT */);
    310 
    311 
    312 #ifndef HB_NO_VAR
    313 template<typename ItemVarStore>
    314 HB_INTERNAL void
    315 remap_variation_indices (const ItemVarStore &var_store,
    316                         const hb_set_t &variation_indices,
    317                         const hb_vector_t<int>& normalized_coords,
    318                         bool calculate_delta, /* not pinned at default */
    319                         bool no_variations, /* all axes pinned */
    320                         hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> &variation_idx_delta_map /* OUT */);
    321 
    322 
    323 template<typename DeltaSetIndexMap>
    324 HB_INTERNAL void
    325 remap_colrv1_delta_set_index_indices (const DeltaSetIndexMap &index_map,
    326                                      const hb_set_t &delta_set_idxes,
    327                                      hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> &variation_idx_delta_map, /* IN/OUT */
    328                                      hb_map_t &new_deltaset_idx_varidx_map /* OUT */);
    329 
    330 
    331 HB_INTERNAL void
    332 generate_varstore_inner_maps (const hb_set_t& varidx_set,
    333                              unsigned subtable_count,
    334                              hb_vector_t<hb_inc_bimap_t> &inner_maps /* OUT */);
    335 
    336 HB_INTERNAL bool
    337 normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan);
    338 
    339 HB_INTERNAL void
    340 update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan);
    341 
    342 HB_INTERNAL bool
    343 get_instance_glyphs_contour_points (hb_subset_plan_t *plan);
    344 
    345 #ifndef HB_NO_BASE
    346 HB_INTERNAL void
    347 collect_base_variation_indices (hb_subset_plan_t* plan);
    348 #endif
    349 #endif
    350 
    351 #ifndef HB_NO_SUBSET_LAYOUT
    352 typedef hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> script_langsys_map;
    353 
    354 HB_INTERNAL void
    355 remap_used_mark_sets (hb_subset_plan_t *plan,
    356                      hb_map_t& used_mark_sets_map);
    357 
    358 HB_INTERNAL void
    359 layout_nameid_closure (hb_subset_plan_t* plan,
    360                       hb_set_t* drop_tables);
    361 
    362 HB_INTERNAL void
    363 layout_populate_gids_to_retain (hb_subset_plan_t* plan,
    364                                hb_set_t* drop_tables);
    365 
    366 HB_INTERNAL void
    367 collect_layout_variation_indices (hb_subset_plan_t* plan);
    368 #endif
    369 
    370 
    371 #endif /* HB_SUBSET_PLAN_HH */