tor-browser

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

path-builder.hh (4830B)


      1 #ifndef OT_GLYF_PATH_BUILDER_HH
      2 #define OT_GLYF_PATH_BUILDER_HH
      3 
      4 
      5 #include "../../hb.hh"
      6 
      7 
      8 namespace OT {
      9 namespace glyf_impl {
     10 
     11 
     12 struct path_builder_t
     13 {
     14  hb_font_t *font;
     15  hb_draw_session_t *draw_session;
     16 
     17  struct optional_point_t
     18  {
     19    optional_point_t () {}
     20    optional_point_t (float x_, float y_) : has_data (true), x (x_), y (y_) {}
     21    operator bool () const { return has_data; }
     22 
     23    bool has_data = false;
     24    float x;
     25    float y;
     26 
     27    optional_point_t mid (optional_point_t p)
     28    { return optional_point_t ((x + p.x) * 0.5f, (y + p.y) * 0.5f); }
     29  } first_oncurve, first_offcurve, first_offcurve2, last_offcurve, last_offcurve2;
     30 
     31  path_builder_t (hb_font_t *font_, hb_draw_session_t &draw_session_) :
     32    font (font_), draw_session (&draw_session_) {}
     33 
     34  /* based on https://github.com/RazrFalcon/ttf-parser/blob/4f32821/src/glyf.rs#L287
     35     See also:
     36     * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM01/Chap1.html
     37     * https://stackoverflow.com/a/20772557
     38     *
     39     * Cubic support added. */
     40  HB_ALWAYS_INLINE
     41  void consume_point (const contour_point_t &point)
     42  {
     43    bool is_on_curve = point.flag & glyf_impl::SimpleGlyph::FLAG_ON_CURVE;
     44 #ifdef HB_NO_CUBIC_GLYF
     45    constexpr bool is_cubic = false;
     46 #else
     47    bool is_cubic = !is_on_curve && (point.flag & glyf_impl::SimpleGlyph::FLAG_CUBIC);
     48 #endif
     49    optional_point_t p (font->em_fscalef_x (point.x), font->em_fscalef_y (point.y));
     50    if (unlikely (!first_oncurve))
     51    {
     52      if (is_on_curve)
     53      {
     54 first_oncurve = p;
     55 draw_session->move_to (p.x, p.y);
     56      }
     57      else
     58      {
     59 if (is_cubic && !first_offcurve2)
     60 {
     61   first_offcurve2 = first_offcurve;
     62   first_offcurve = p;
     63 }
     64 else if (first_offcurve)
     65 {
     66   optional_point_t mid = first_offcurve.mid (p);
     67   first_oncurve = mid;
     68   last_offcurve = p;
     69   draw_session->move_to (mid.x, mid.y);
     70 }
     71 else
     72   first_offcurve = p;
     73      }
     74    }
     75    else
     76    {
     77      if (last_offcurve)
     78      {
     79 if (is_on_curve)
     80 {
     81   if (last_offcurve2)
     82   {
     83     draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
     84 			    last_offcurve.x, last_offcurve.y,
     85 			    p.x, p.y);
     86     last_offcurve2 = optional_point_t ();
     87   }
     88   else
     89     draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
     90 			       p.x, p.y);
     91   last_offcurve = optional_point_t ();
     92 }
     93 else
     94 {
     95   if (is_cubic && !last_offcurve2)
     96   {
     97     last_offcurve2 = last_offcurve;
     98     last_offcurve = p;
     99   }
    100   else
    101   {
    102     optional_point_t mid = last_offcurve.mid (p);
    103 
    104     if (is_cubic)
    105     {
    106       draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
    107 			      last_offcurve.x, last_offcurve.y,
    108 			      mid.x, mid.y);
    109       last_offcurve2 = optional_point_t ();
    110     }
    111     else
    112       draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
    113 				 mid.x, mid.y);
    114     last_offcurve = p;
    115   }
    116 }
    117      }
    118      else
    119      {
    120 if (is_on_curve)
    121   draw_session->line_to (p.x, p.y);
    122 else
    123   last_offcurve = p;
    124      }
    125    }
    126 
    127  }
    128 
    129  void contour_end ()
    130  {
    131    if (first_offcurve && last_offcurve)
    132    {
    133      optional_point_t mid = last_offcurve.mid (first_offcurve2 ?
    134 					first_offcurve2 :
    135 					first_offcurve);
    136      if (last_offcurve2)
    137 draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
    138 			last_offcurve.x, last_offcurve.y,
    139 			mid.x, mid.y);
    140      else
    141 draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
    142 			   mid.x, mid.y);
    143      last_offcurve = optional_point_t ();
    144    }
    145    /* now check the rest */
    146 
    147    if (first_offcurve && first_oncurve)
    148    {
    149      if (first_offcurve2)
    150 draw_session->cubic_to (first_offcurve2.x, first_offcurve2.y,
    151 			first_offcurve.x, first_offcurve.y,
    152 			first_oncurve.x, first_oncurve.y);
    153      else
    154 draw_session->quadratic_to (first_offcurve.x, first_offcurve.y,
    155 			   first_oncurve.x, first_oncurve.y);
    156    }
    157    else if (last_offcurve && first_oncurve)
    158    {
    159      if (last_offcurve2)
    160 draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
    161 			last_offcurve.x, last_offcurve.y,
    162 			first_oncurve.x, first_oncurve.y);
    163      else
    164 draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
    165 			   first_oncurve.x, first_oncurve.y);
    166    }
    167    else if (first_oncurve)
    168      draw_session->line_to (first_oncurve.x, first_oncurve.y);
    169    else if (first_offcurve)
    170    {
    171      float x = first_offcurve.x, y = first_offcurve.y;
    172      draw_session->move_to (x, y);
    173      draw_session->quadratic_to (x, y, x, y);
    174    }
    175 
    176    /* Getting ready for the next contour */
    177    first_oncurve = first_offcurve = last_offcurve = last_offcurve2 = optional_point_t ();
    178    draw_session->close_path ();
    179  }
    180 
    181  void points_end () {}
    182 
    183  bool is_consuming_contour_points () { return true; }
    184  contour_point_t *get_phantoms_sink () { return nullptr; }
    185 };
    186 
    187 
    188 } /* namespace glyf_impl */
    189 } /* namespace OT */
    190 
    191 
    192 #endif /* OT_GLYF_PATH_BUILDER_HH */