tor-browser

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

VARC.hh (6307B)


      1 #ifndef OT_VAR_VARC_VARC_HH
      2 #define OT_VAR_VARC_VARC_HH
      3 
      4 #include "../../../hb-decycler.hh"
      5 #include "../../../hb-geometry.hh"
      6 #include "../../../hb-ot-layout-common.hh"
      7 #include "../../../hb-ot-glyf-table.hh"
      8 #include "../../../hb-ot-cff2-table.hh"
      9 #include "../../../hb-ot-cff1-table.hh"
     10 
     11 #include "coord-setter.hh"
     12 
     13 namespace OT {
     14 
     15 //namespace Var {
     16 
     17 /*
     18 * VARC -- Variable Composites
     19 * https://github.com/harfbuzz/boring-expansion-spec/blob/main/VARC.md
     20 */
     21 
     22 #ifndef HB_NO_VAR_COMPOSITES
     23 
     24 struct hb_varc_scratch_t
     25 {
     26  hb_vector_t<unsigned> axisIndices;
     27  hb_vector_t<float> axisValues;
     28  hb_glyf_scratch_t glyf_scratch;
     29 };
     30 
     31 struct hb_varc_context_t
     32 {
     33  hb_font_t *font;
     34  hb_draw_session_t *draw_session;
     35  hb_extents_t<> *extents;
     36  mutable hb_decycler_t decycler;
     37  mutable signed edges_left;
     38  mutable signed depth_left;
     39  hb_varc_scratch_t &scratch;
     40 };
     41 
     42 struct VarComponent
     43 {
     44  enum class flags_t : uint32_t
     45  {
     46    RESET_UNSPECIFIED_AXES	= 1u << 0,
     47    HAVE_AXES			= 1u << 1,
     48    AXIS_VALUES_HAVE_VARIATION	= 1u << 2,
     49    TRANSFORM_HAS_VARIATION	= 1u << 3,
     50    HAVE_TRANSLATE_X		= 1u << 4,
     51    HAVE_TRANSLATE_Y		= 1u << 5,
     52    HAVE_ROTATION		= 1u << 6,
     53    HAVE_CONDITION		= 1u << 7,
     54    HAVE_SCALE_X		= 1u << 8,
     55    HAVE_SCALE_Y		= 1u << 9,
     56    HAVE_TCENTER_X		= 1u << 10,
     57    HAVE_TCENTER_Y		= 1u << 11,
     58    GID_IS_24BIT		= 1u << 12,
     59    HAVE_SKEW_X			= 1u << 13,
     60    HAVE_SKEW_Y			= 1u << 14,
     61    RESERVED_MASK		= ~((1u << 15) - 1),
     62  };
     63 
     64  HB_INTERNAL hb_ubytes_t
     65  get_path_at (const hb_varc_context_t &c,
     66        hb_codepoint_t parent_gid,
     67        hb_array_t<const int> coords,
     68        hb_transform_t<> transform,
     69        hb_ubytes_t record,
     70        hb_scalar_cache_t *cache = nullptr) const;
     71 };
     72 
     73 struct VarCompositeGlyph
     74 {
     75  static void
     76  get_path_at (const hb_varc_context_t &c,
     77        hb_codepoint_t gid,
     78        hb_array_t<const int> coords,
     79        hb_transform_t<> transform,
     80        hb_ubytes_t record,
     81        hb_scalar_cache_t *cache)
     82  {
     83    while (record)
     84    {
     85      const VarComponent &comp = * (const VarComponent *) (record.arrayZ);
     86      record = comp.get_path_at (c,
     87 			 gid,
     88 			 coords, transform,
     89 			 record,
     90 			 cache);
     91    }
     92  }
     93 };
     94 
     95 HB_MARK_AS_FLAG_T (VarComponent::flags_t);
     96 
     97 struct VARC
     98 {
     99  friend struct VarComponent;
    100 
    101  static constexpr hb_tag_t tableTag = HB_TAG ('V', 'A', 'R', 'C');
    102 
    103  HB_INTERNAL bool
    104  get_path_at (const hb_varc_context_t &c,
    105        hb_codepoint_t gid,
    106        hb_array_t<const int> coords,
    107        hb_transform_t<> transform = HB_TRANSFORM_IDENTITY,
    108        hb_codepoint_t parent_gid = HB_CODEPOINT_INVALID,
    109        hb_scalar_cache_t *parent_cache = nullptr) const;
    110 
    111  bool
    112  get_path (hb_font_t *font,
    113     hb_codepoint_t gid,
    114     hb_draw_session_t &draw_session,
    115     hb_varc_scratch_t &scratch) const
    116  {
    117    hb_varc_context_t c {font,
    118 		 &draw_session,
    119 		 nullptr,
    120 		 hb_decycler_t {},
    121 		 HB_MAX_GRAPH_EDGE_COUNT,
    122 		 HB_MAX_NESTING_LEVEL,
    123 		 scratch};
    124 
    125    return get_path_at (c, gid,
    126 		hb_array (font->coords, font->num_coords));
    127  }
    128 
    129  bool
    130  get_extents (hb_font_t *font,
    131        hb_codepoint_t gid,
    132        hb_extents_t<> *extents,
    133        hb_varc_scratch_t &scratch) const
    134  {
    135    hb_varc_context_t c {font,
    136 		 nullptr,
    137 		 extents,
    138 		 hb_decycler_t {},
    139 		 HB_MAX_GRAPH_EDGE_COUNT,
    140 		 HB_MAX_NESTING_LEVEL,
    141 		 scratch};
    142 
    143    return get_path_at (c, gid,
    144 		hb_array (font->coords, font->num_coords));
    145  }
    146 
    147  bool sanitize (hb_sanitize_context_t *c) const
    148  {
    149    TRACE_SANITIZE (this);
    150    return_trace (version.sanitize (c) &&
    151 	  hb_barrier () &&
    152 	  version.major == 1 &&
    153 	  coverage.sanitize (c, this) &&
    154 	  varStore.sanitize (c, this) &&
    155 	  conditionList.sanitize (c, this) &&
    156 	  axisIndicesList.sanitize (c, this) &&
    157 	  glyphRecords.sanitize (c, this));
    158  }
    159 
    160  struct accelerator_t
    161  {
    162    friend struct VarComponent;
    163 
    164    accelerator_t (hb_face_t *face)
    165    {
    166      table = hb_sanitize_context_t ().reference_table<VARC> (face);
    167    }
    168    ~accelerator_t ()
    169    {
    170      auto *scratch = cached_scratch.get_relaxed ();
    171      if (scratch)
    172      {
    173 scratch->~hb_varc_scratch_t ();
    174 hb_free (scratch);
    175      }
    176 
    177      table.destroy ();
    178    }
    179 
    180    bool
    181    get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const
    182    {
    183      if (!table->has_data ()) return false;
    184 
    185      auto *scratch = acquire_scratch ();
    186      if (unlikely (!scratch)) return true;
    187      bool ret = table->get_path (font, gid, draw_session, *scratch);
    188      release_scratch (scratch);
    189      return ret;
    190    }
    191 
    192    bool
    193    get_extents (hb_font_t *font,
    194 	 hb_codepoint_t gid,
    195 	 hb_glyph_extents_t *extents) const
    196    {
    197 #ifndef HB_NO_DRAW
    198      if (!table->has_data ()) return false;
    199 
    200      hb_extents_t<> f_extents;
    201 
    202      auto *scratch = acquire_scratch ();
    203      if (unlikely (!scratch)) return true;
    204      bool ret = table->get_extents (font, gid, &f_extents, *scratch);
    205      release_scratch (scratch);
    206 
    207      if (ret)
    208 *extents = f_extents.to_glyph_extents (font->x_scale < 0, font->y_scale < 0);
    209 
    210      return ret;
    211 #else
    212      return false;
    213 #endif
    214    }
    215 
    216    private:
    217 
    218    hb_varc_scratch_t *acquire_scratch () const
    219    {
    220      hb_varc_scratch_t *scratch = cached_scratch.get_acquire ();
    221 
    222      if (!scratch || unlikely (!cached_scratch.cmpexch (scratch, nullptr)))
    223      {
    224 scratch = (hb_varc_scratch_t *) hb_calloc (1, sizeof (hb_varc_scratch_t));
    225 if (unlikely (!scratch))
    226   return nullptr;
    227      }
    228 
    229      return scratch;
    230    }
    231    void release_scratch (hb_varc_scratch_t *scratch) const
    232    {
    233      if (!cached_scratch.cmpexch (nullptr, scratch))
    234      {
    235 scratch->~hb_varc_scratch_t ();
    236 hb_free (scratch);
    237      }
    238    }
    239 
    240    private:
    241    hb_blob_ptr_t<VARC> table;
    242    mutable hb_atomic_t<hb_varc_scratch_t *> cached_scratch;
    243  };
    244 
    245  bool has_data () const { return version.major != 0; }
    246 
    247  protected:
    248  FixedVersion<> version; /* Version identifier */
    249  Offset32To<Coverage> coverage;
    250  Offset32To<MultiItemVariationStore> varStore;
    251  Offset32To<ConditionList> conditionList;
    252  Offset32To<TupleList> axisIndicesList;
    253  Offset32To<CFF2Index/*Of<VarCompositeGlyph>*/> glyphRecords;
    254  public:
    255  DEFINE_SIZE_STATIC (24);
    256 };
    257 
    258 struct VARC_accelerator_t : VARC::accelerator_t {
    259  VARC_accelerator_t (hb_face_t *face) : VARC::accelerator_t (face) {}
    260 };
    261 
    262 #endif
    263 
    264 //}
    265 
    266 }
    267 
    268 #endif  /* OT_VAR_VARC_VARC_HH */