tor-browser

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

hb-paint.hh (8957B)


      1 /*
      2 * Copyright © 2022 Matthias Clasen
      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_PAINT_HH
     26 #define HB_PAINT_HH
     27 
     28 #include "hb.hh"
     29 #include "hb-face.hh"
     30 #include "hb-font.hh"
     31 #include "hb-geometry.hh"
     32 
     33 #define HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS \
     34  HB_PAINT_FUNC_IMPLEMENT (push_transform) \
     35  HB_PAINT_FUNC_IMPLEMENT (pop_transform) \
     36  HB_PAINT_FUNC_IMPLEMENT (color_glyph) \
     37  HB_PAINT_FUNC_IMPLEMENT (push_clip_glyph) \
     38  HB_PAINT_FUNC_IMPLEMENT (push_clip_rectangle) \
     39  HB_PAINT_FUNC_IMPLEMENT (pop_clip) \
     40  HB_PAINT_FUNC_IMPLEMENT (color) \
     41  HB_PAINT_FUNC_IMPLEMENT (image) \
     42  HB_PAINT_FUNC_IMPLEMENT (linear_gradient) \
     43  HB_PAINT_FUNC_IMPLEMENT (radial_gradient) \
     44  HB_PAINT_FUNC_IMPLEMENT (sweep_gradient) \
     45  HB_PAINT_FUNC_IMPLEMENT (push_group) \
     46  HB_PAINT_FUNC_IMPLEMENT (pop_group) \
     47  HB_PAINT_FUNC_IMPLEMENT (custom_palette_color) \
     48  /* ^--- Add new callbacks here */
     49 
     50 struct hb_paint_funcs_t
     51 {
     52  hb_object_header_t header;
     53 
     54  struct {
     55 #define HB_PAINT_FUNC_IMPLEMENT(name) hb_paint_##name##_func_t name;
     56    HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS
     57 #undef HB_PAINT_FUNC_IMPLEMENT
     58  } func;
     59 
     60  struct {
     61 #define HB_PAINT_FUNC_IMPLEMENT(name) void *name;
     62    HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS
     63 #undef HB_PAINT_FUNC_IMPLEMENT
     64  } *user_data;
     65 
     66  struct {
     67 #define HB_PAINT_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
     68    HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS
     69 #undef HB_PAINT_FUNC_IMPLEMENT
     70  } *destroy;
     71 
     72  void push_transform (void *paint_data,
     73                       float xx, float yx,
     74                       float xy, float yy,
     75                       float dx, float dy)
     76  {
     77    // Handle -0.f to avoid -0.f == 0.f in the transform matrix.
     78    if (dx == -0.f) dx = 0.f;
     79    if (dy == -0.f) dy = 0.f;
     80    func.push_transform (this, paint_data,
     81                         xx, yx, xy, yy, dx, dy,
     82                         !user_data ? nullptr : user_data->push_transform); }
     83  void pop_transform (void *paint_data)
     84  { func.pop_transform (this, paint_data,
     85                        !user_data ? nullptr : user_data->pop_transform); }
     86  bool color_glyph (void *paint_data,
     87                    hb_codepoint_t glyph,
     88                    hb_font_t *font)
     89  { return func.color_glyph (this, paint_data,
     90                             glyph,
     91                             font,
     92                             !user_data ? nullptr : user_data->push_clip_glyph); }
     93  void push_clip_glyph (void *paint_data,
     94                        hb_codepoint_t glyph,
     95                        hb_font_t *font)
     96  { func.push_clip_glyph (this, paint_data,
     97                          glyph,
     98                          font,
     99                          !user_data ? nullptr : user_data->push_clip_glyph); }
    100  void push_clip_rectangle (void *paint_data,
    101                           float xmin, float ymin, float xmax, float ymax)
    102  { func.push_clip_rectangle (this, paint_data,
    103                              xmin, ymin, xmax, ymax,
    104                              !user_data ? nullptr : user_data->push_clip_rectangle); }
    105  void pop_clip (void *paint_data)
    106  { func.pop_clip (this, paint_data,
    107                   !user_data ? nullptr : user_data->pop_clip); }
    108  void color (void *paint_data,
    109              hb_bool_t is_foreground,
    110              hb_color_t color)
    111  { func.color (this, paint_data,
    112                is_foreground, color,
    113                !user_data ? nullptr : user_data->color); }
    114  bool image (void *paint_data,
    115              hb_blob_t *image,
    116              unsigned width, unsigned height,
    117              hb_tag_t format,
    118              float slant,
    119              hb_glyph_extents_t *extents)
    120  { return func.image (this, paint_data,
    121                       image, width, height, format, slant, extents,
    122                       !user_data ? nullptr : user_data->image); }
    123  void linear_gradient (void *paint_data,
    124                        hb_color_line_t *color_line,
    125                        float x0, float y0,
    126                        float x1, float y1,
    127                        float x2, float y2)
    128  { func.linear_gradient (this, paint_data,
    129                          color_line, x0, y0, x1, y1, x2, y2,
    130                          !user_data ? nullptr : user_data->linear_gradient); }
    131  void radial_gradient (void *paint_data,
    132                        hb_color_line_t *color_line,
    133                        float x0, float y0, float r0,
    134                        float x1, float y1, float r1)
    135  { func.radial_gradient (this, paint_data,
    136                          color_line, x0, y0, r0, x1, y1, r1,
    137                          !user_data ? nullptr : user_data->radial_gradient); }
    138  void sweep_gradient (void *paint_data,
    139                       hb_color_line_t *color_line,
    140                       float x0, float y0,
    141                       float start_angle,
    142                       float end_angle)
    143  { func.sweep_gradient (this, paint_data,
    144                         color_line, x0, y0, start_angle, end_angle,
    145                         !user_data ? nullptr : user_data->sweep_gradient); }
    146  void push_group (void *paint_data)
    147  { func.push_group (this, paint_data,
    148                     !user_data ? nullptr : user_data->push_group); }
    149  void pop_group (void *paint_data,
    150                  hb_paint_composite_mode_t mode)
    151  { func.pop_group (this, paint_data,
    152                    mode,
    153                    !user_data ? nullptr : user_data->pop_group); }
    154  bool custom_palette_color (void *paint_data,
    155                             unsigned int color_index,
    156                             hb_color_t *color)
    157  { return func.custom_palette_color (this, paint_data,
    158                                      color_index,
    159                                      color,
    160                                      !user_data ? nullptr : user_data->custom_palette_color); }
    161 
    162 
    163  /* Internal specializations. */
    164 
    165  void push_font_transform (void *paint_data,
    166                            const hb_font_t *font)
    167  {
    168    float upem = font->face->get_upem ();
    169    int xscale = font->x_scale, yscale = font->y_scale;
    170 
    171    push_transform (paint_data,
    172 	    xscale/upem, 0,
    173 	    0, yscale/upem,
    174 	    0, 0);
    175  }
    176 
    177  void push_inverse_font_transform (void *paint_data,
    178                                    const hb_font_t *font)
    179  {
    180    float upem = font->face->get_upem ();
    181    int xscale = font->x_scale ? font->x_scale : upem;
    182    int yscale = font->y_scale ? font->y_scale : upem;
    183 
    184    push_transform (paint_data,
    185 	    upem/xscale, 0,
    186 	    0, upem/yscale,
    187 	    0, 0);
    188  }
    189 
    190  void push_transform (void *paint_data, hb_transform_t<float> t)
    191  {
    192    push_transform (paint_data, t.xx, t.yx, t.xy, t.yy, t.x0, t.y0);
    193  }
    194 
    195  void push_translate (void *paint_data,
    196                       float dx, float dy)
    197  {
    198    push_transform (paint_data,
    199 	    hb_transform_t<float>::translation (dx, dy));
    200  }
    201 
    202  void push_scale (void *paint_data,
    203                   float sx, float sy)
    204  {
    205    push_transform (paint_data,
    206 	    hb_transform_t<float>::scaling (sx, sy));
    207  }
    208  void push_scale_around_center (void *paint_data,
    209 			 float sx, float sy,
    210 			 float cx, float cy)
    211  {
    212    push_transform (paint_data,
    213 	    hb_transform_t<float>::scaling_around_center (sx, sy, cx, cy));
    214  }
    215 
    216  void push_rotate (void *paint_data,
    217                    float a)
    218  {
    219    push_transform (paint_data,
    220 	    hb_transform_t<float>::rotation (a * HB_PI));
    221  }
    222 
    223  void push_rotate_around_center (void *paint_data,
    224 			  float a,
    225 			  float cx, float cy)
    226  {
    227    push_transform (paint_data,
    228 	    hb_transform_t<float>::rotation_around_center (a * HB_PI, cx, cy));
    229  }
    230 
    231  void push_skew (void *paint_data,
    232                  float sx, float sy)
    233  {
    234    push_transform (paint_data,
    235 	    hb_transform_t<float>::skewing (-sx * HB_PI, sy * HB_PI));
    236  }
    237  void push_skew_around_center (void *paint_data,
    238 			float sx, float sy,
    239 			float cx, float cy)
    240  {
    241    push_transform (paint_data,
    242 	    hb_transform_t<float>::skewing_around_center (-sx * HB_PI, sy * HB_PI, cx, cy));
    243  }
    244 };
    245 DECLARE_NULL_INSTANCE (hb_paint_funcs_t);
    246 
    247 
    248 #endif /* HB_PAINT_HH */