tor-browser

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

AnchorFormat3.hh (4747B)


      1 #ifndef OT_LAYOUT_GPOS_ANCHORFORMAT3_HH
      2 #define OT_LAYOUT_GPOS_ANCHORFORMAT3_HH
      3 
      4 namespace OT {
      5 namespace Layout {
      6 namespace GPOS_impl {
      7 
      8 struct AnchorFormat3
      9 {
     10  protected:
     11  HBUINT16      format;                 /* Format identifier--format = 3 */
     12  FWORD         xCoordinate;            /* Horizontal value--in design units */
     13  FWORD         yCoordinate;            /* Vertical value--in design units */
     14  Offset16To<Device>
     15                xDeviceTable;           /* Offset to Device table for X
     16                                         * coordinate-- from beginning of
     17                                         * Anchor table (may be NULL) */
     18  Offset16To<Device>
     19                yDeviceTable;           /* Offset to Device table for Y
     20                                         * coordinate-- from beginning of
     21                                         * Anchor table (may be NULL) */
     22  public:
     23  DEFINE_SIZE_STATIC (10);
     24 
     25  bool sanitize (hb_sanitize_context_t *c) const
     26  {
     27    TRACE_SANITIZE (this);
     28    if (unlikely (!c->check_struct (this))) return_trace (false);
     29 
     30    return_trace (xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this));
     31  }
     32 
     33  void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED,
     34                   float *x, float *y) const
     35  {
     36    hb_font_t *font = c->font;
     37    *x = font->em_fscale_x (xCoordinate);
     38    *y = font->em_fscale_y (yCoordinate);
     39 
     40    if ((font->x_ppem || font->has_nonzero_coords) && xDeviceTable.sanitize (&c->sanitizer, this))
     41    {
     42      hb_barrier ();
     43      *x += (this+xDeviceTable).get_x_delta (font, c->var_store, c->var_store_cache);
     44    }
     45    if ((font->y_ppem || font->has_nonzero_coords) && yDeviceTable.sanitize (&c->sanitizer, this))
     46    {
     47      hb_barrier ();
     48      *y += (this+yDeviceTable).get_y_delta (font, c->var_store, c->var_store_cache);
     49    }
     50  }
     51 
     52  bool subset (hb_subset_context_t *c) const
     53  {
     54    TRACE_SUBSET (this);
     55    auto *out = c->serializer->start_embed (*this);
     56    if (unlikely (!c->serializer->embed (format))) return_trace (false);
     57    if (unlikely (!c->serializer->embed (xCoordinate))) return_trace (false);
     58    if (unlikely (!c->serializer->embed (yCoordinate))) return_trace (false);
     59 
     60    unsigned x_varidx = xDeviceTable ? (this+xDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX;
     61    if (x_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX)
     62    {
     63      hb_pair_t<unsigned, int> *new_varidx_delta;
     64      if (!c->plan->layout_variation_idx_delta_map.has (x_varidx, &new_varidx_delta))
     65        return_trace (false);
     66 
     67      x_varidx = hb_first (*new_varidx_delta);
     68      int delta = hb_second (*new_varidx_delta);
     69      if (delta != 0)
     70      {
     71        if (!c->serializer->check_assign (out->xCoordinate, xCoordinate + delta,
     72                                          HB_SERIALIZE_ERROR_INT_OVERFLOW))
     73          return_trace (false);
     74      }
     75    }
     76 
     77    unsigned y_varidx = yDeviceTable ? (this+yDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX;
     78    if (y_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX)
     79    {
     80      hb_pair_t<unsigned, int> *new_varidx_delta;
     81      if (!c->plan->layout_variation_idx_delta_map.has (y_varidx, &new_varidx_delta))
     82        return_trace (false);
     83 
     84      y_varidx = hb_first (*new_varidx_delta);
     85      int delta = hb_second (*new_varidx_delta);
     86      if (delta != 0)
     87      {
     88        if (!c->serializer->check_assign (out->yCoordinate, yCoordinate + delta,
     89                                          HB_SERIALIZE_ERROR_INT_OVERFLOW))
     90          return_trace (false);
     91      }
     92    }
     93 
     94 
     95    bool no_downgrade = (!xDeviceTable.is_null () && !(this+xDeviceTable).is_variation_device ()) ||
     96                        x_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX ||
     97                        y_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX ||
     98                        (!yDeviceTable.is_null () && !(this+yDeviceTable).is_variation_device ());
     99 
    100    if (!no_downgrade)
    101      return_trace (c->serializer->check_assign (out->format, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW));
    102 
    103    if (!c->serializer->embed (xDeviceTable)) return_trace (false);
    104    if (!c->serializer->embed (yDeviceTable)) return_trace (false);
    105 
    106    out->xDeviceTable.serialize_copy (c->serializer, xDeviceTable, this, 0, hb_serialize_context_t::Head, &c->plan->layout_variation_idx_delta_map);
    107    out->yDeviceTable.serialize_copy (c->serializer, yDeviceTable, this, 0, hb_serialize_context_t::Head, &c->plan->layout_variation_idx_delta_map);
    108    return_trace (out);
    109  }
    110 
    111  void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
    112  {
    113    (this+xDeviceTable).collect_variation_indices (c);
    114    (this+yDeviceTable).collect_variation_indices (c);
    115  }
    116 };
    117 
    118 
    119 }
    120 }
    121 }
    122 
    123 #endif  // OT_LAYOUT_GPOS_ANCHORFORMAT3_HH