tor-browser

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

hb-draw.hh (6274B)


      1 /*
      2 * Copyright © 2020  Ebrahim Byagowi
      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 
     25 #ifndef HB_DRAW_HH
     26 #define HB_DRAW_HH
     27 
     28 #include "hb.hh"
     29 
     30 
     31 /*
     32 * hb_draw_funcs_t
     33 */
     34 
     35 #define HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS \
     36  HB_DRAW_FUNC_IMPLEMENT (move_to) \
     37  HB_DRAW_FUNC_IMPLEMENT (line_to) \
     38  HB_DRAW_FUNC_IMPLEMENT (quadratic_to) \
     39  HB_DRAW_FUNC_IMPLEMENT (cubic_to) \
     40  HB_DRAW_FUNC_IMPLEMENT (close_path) \
     41  /* ^--- Add new callbacks here */
     42 
     43 struct hb_draw_funcs_t
     44 {
     45  hb_object_header_t header;
     46 
     47  struct {
     48 #define HB_DRAW_FUNC_IMPLEMENT(name) hb_draw_##name##_func_t name;
     49    HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
     50 #undef HB_DRAW_FUNC_IMPLEMENT
     51  } func;
     52 
     53  struct {
     54 #define HB_DRAW_FUNC_IMPLEMENT(name) void *name;
     55    HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
     56 #undef HB_DRAW_FUNC_IMPLEMENT
     57  } *user_data;
     58 
     59  struct {
     60 #define HB_DRAW_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
     61    HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
     62 #undef HB_DRAW_FUNC_IMPLEMENT
     63  } *destroy;
     64 
     65  void emit_move_to (void *draw_data, hb_draw_state_t &st,
     66 	     float to_x, float to_y)
     67  { func.move_to (this, draw_data, &st,
     68 	  to_x, to_y,
     69 	  !user_data ? nullptr : user_data->move_to); }
     70  void emit_line_to (void *draw_data, hb_draw_state_t &st,
     71 	     float to_x, float to_y)
     72  { func.line_to (this, draw_data, &st,
     73 	  to_x, to_y,
     74 	  !user_data ? nullptr : user_data->line_to); }
     75  void emit_quadratic_to (void *draw_data, hb_draw_state_t &st,
     76 		  float control_x, float control_y,
     77 		  float to_x, float to_y)
     78  { func.quadratic_to (this, draw_data, &st,
     79 	       control_x, control_y,
     80 	       to_x, to_y,
     81 	       !user_data ? nullptr : user_data->quadratic_to); }
     82  void emit_cubic_to (void *draw_data, hb_draw_state_t &st,
     83 	      float control1_x, float control1_y,
     84 	      float control2_x, float control2_y,
     85 	      float to_x, float to_y)
     86  { func.cubic_to (this, draw_data, &st,
     87 	   control1_x, control1_y,
     88 	   control2_x, control2_y,
     89 	   to_x, to_y,
     90 	   !user_data ? nullptr : user_data->cubic_to); }
     91  void emit_close_path (void *draw_data, hb_draw_state_t &st)
     92  { func.close_path (this, draw_data, &st,
     93 	     !user_data ? nullptr : user_data->close_path); }
     94 
     95 
     96  void
     97  HB_ALWAYS_INLINE
     98  move_to (void *draw_data, hb_draw_state_t &st,
     99    float to_x, float to_y)
    100  {
    101    if (unlikely (st.path_open)) close_path (draw_data, st);
    102 
    103    st.current_x = to_x;
    104    st.current_y = to_y;
    105  }
    106 
    107  void
    108  HB_ALWAYS_INLINE
    109  line_to (void *draw_data, hb_draw_state_t &st,
    110    float to_x, float to_y)
    111  {
    112    if (unlikely (!st.path_open)) start_path (draw_data, st);
    113 
    114    emit_line_to (draw_data, st, to_x, to_y);
    115 
    116    st.current_x = to_x;
    117    st.current_y = to_y;
    118  }
    119 
    120  void
    121  HB_ALWAYS_INLINE
    122  quadratic_to (void *draw_data, hb_draw_state_t &st,
    123 	float control_x, float control_y,
    124 	float to_x, float to_y)
    125  {
    126    if (unlikely (!st.path_open)) start_path (draw_data, st);
    127 
    128    emit_quadratic_to (draw_data, st, control_x, control_y, to_x, to_y);
    129 
    130    st.current_x = to_x;
    131    st.current_y = to_y;
    132  }
    133 
    134  void
    135  HB_ALWAYS_INLINE
    136  cubic_to (void *draw_data, hb_draw_state_t &st,
    137     float control1_x, float control1_y,
    138     float control2_x, float control2_y,
    139     float to_x, float to_y)
    140  {
    141    if (unlikely (!st.path_open)) start_path (draw_data, st);
    142 
    143    emit_cubic_to (draw_data, st, control1_x, control1_y, control2_x, control2_y, to_x, to_y);
    144 
    145    st.current_x = to_x;
    146    st.current_y = to_y;
    147  }
    148 
    149  void
    150  HB_ALWAYS_INLINE
    151  close_path (void *draw_data, hb_draw_state_t &st)
    152  {
    153    if (likely (st.path_open))
    154    {
    155      if ((st.path_start_x != st.current_x) || (st.path_start_y != st.current_y))
    156 emit_line_to (draw_data, st, st.path_start_x, st.path_start_y);
    157      emit_close_path (draw_data, st);
    158    }
    159    st.path_open = false;
    160    st.path_start_x = st.current_x = st.path_start_y = st.current_y = 0;
    161  }
    162 
    163  protected:
    164 
    165  void start_path (void *draw_data, hb_draw_state_t &st)
    166  {
    167    assert (!st.path_open);
    168    emit_move_to (draw_data, st, st.current_x, st.current_y);
    169    st.path_open = true;
    170    st.path_start_x = st.current_x;
    171    st.path_start_y = st.current_y;
    172  }
    173 };
    174 DECLARE_NULL_INSTANCE (hb_draw_funcs_t);
    175 
    176 struct hb_draw_session_t
    177 {
    178  hb_draw_session_t (hb_draw_funcs_t *funcs_, void *draw_data_)
    179    : funcs {funcs_}, draw_data {draw_data_}, st HB_DRAW_STATE_DEFAULT
    180  {}
    181 
    182  ~hb_draw_session_t () { close_path (); }
    183 
    184  HB_ALWAYS_INLINE
    185  void move_to (float to_x, float to_y)
    186  {
    187    funcs->move_to (draw_data, st,
    188 	    to_x, to_y);
    189  }
    190  HB_ALWAYS_INLINE
    191  void line_to (float to_x, float to_y)
    192  {
    193    funcs->line_to (draw_data, st,
    194 	    to_x, to_y);
    195  }
    196  void
    197  HB_ALWAYS_INLINE
    198  quadratic_to (float control_x, float control_y,
    199 	float to_x, float to_y)
    200  {
    201    funcs->quadratic_to (draw_data, st,
    202 		 control_x, control_y,
    203 		 to_x, to_y);
    204  }
    205  void
    206  HB_ALWAYS_INLINE
    207  cubic_to (float control1_x, float control1_y,
    208     float control2_x, float control2_y,
    209     float to_x, float to_y)
    210  {
    211    funcs->cubic_to (draw_data, st,
    212 	     control1_x, control1_y,
    213 	     control2_x, control2_y,
    214 	     to_x, to_y);
    215  }
    216  HB_ALWAYS_INLINE
    217  void close_path ()
    218  {
    219    funcs->close_path (draw_data, st);
    220  }
    221 
    222  public:
    223  hb_draw_funcs_t *funcs;
    224  void *draw_data;
    225  hb_draw_state_t st;
    226 };
    227 
    228 
    229 HB_INTERNAL hb_draw_funcs_t *
    230 hb_draw_extents_get_funcs ();
    231 
    232 
    233 #endif /* HB_DRAW_HH */