tor-browser

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

hb-paint-extents.cc (7911B)


      1 /*
      2 * Copyright © 2022 Behdad Esfahbod
      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 #include "hb.hh"
     26 
     27 #ifndef HB_NO_PAINT
     28 
     29 #include "hb-paint-extents.hh"
     30 
     31 #include "hb-draw.hh"
     32 
     33 #include "hb-machinery.hh"
     34 
     35 
     36 /*
     37 * This file implements bounds-extraction computation of COLRv1 fonts as described in:
     38 *
     39 * https://learn.microsoft.com/en-us/typography/opentype/spec/colr#glyph-metrics-and-boundedness
     40 */
     41 
     42 static void
     43 hb_paint_extents_push_transform (hb_paint_funcs_t *funcs HB_UNUSED,
     44 			 void *paint_data,
     45 			 float xx, float yx,
     46 			 float xy, float yy,
     47 			 float dx, float dy,
     48 			 void *user_data HB_UNUSED)
     49 {
     50  hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
     51 
     52  c->push_transform (hb_transform_t<> {xx, yx, xy, yy, dx, dy});
     53 }
     54 
     55 static void
     56 hb_paint_extents_pop_transform (hb_paint_funcs_t *funcs HB_UNUSED,
     57 		        void *paint_data,
     58 			void *user_data HB_UNUSED)
     59 {
     60  hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
     61 
     62  c->pop_transform ();
     63 }
     64 
     65 static void
     66 hb_paint_extents_push_clip_glyph (hb_paint_funcs_t *funcs HB_UNUSED,
     67 			  void *paint_data,
     68 			  hb_codepoint_t glyph,
     69 			  hb_font_t *font,
     70 			  void *user_data HB_UNUSED)
     71 {
     72  hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
     73 
     74  hb_extents_t<> extents;
     75  hb_draw_funcs_t *draw_extent_funcs = hb_draw_extents_get_funcs ();
     76  hb_font_draw_glyph (font, glyph, draw_extent_funcs, &extents);
     77  c->push_clip (extents);
     78 }
     79 
     80 static void
     81 hb_paint_extents_push_clip_rectangle (hb_paint_funcs_t *funcs HB_UNUSED,
     82 			      void *paint_data,
     83 			      float xmin, float ymin, float xmax, float ymax,
     84 			      void *user_data)
     85 {
     86  hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
     87 
     88  hb_extents_t<> extents = {xmin, ymin, xmax, ymax};
     89  c->push_clip (extents);
     90 }
     91 
     92 static void
     93 hb_paint_extents_pop_clip (hb_paint_funcs_t *funcs HB_UNUSED,
     94 		   void *paint_data,
     95 		   void *user_data HB_UNUSED)
     96 {
     97  hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
     98 
     99  c->pop_clip ();
    100 }
    101 
    102 static void
    103 hb_paint_extents_push_group (hb_paint_funcs_t *funcs HB_UNUSED,
    104 		     void *paint_data,
    105 		     void *user_data HB_UNUSED)
    106 {
    107  hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
    108 
    109  c->push_group ();
    110 }
    111 
    112 static void
    113 hb_paint_extents_pop_group (hb_paint_funcs_t *funcs HB_UNUSED,
    114 		    void *paint_data,
    115 		    hb_paint_composite_mode_t mode,
    116 		    void *user_data HB_UNUSED)
    117 {
    118  hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
    119 
    120  c->pop_group (mode);
    121 }
    122 
    123 static hb_bool_t
    124 hb_paint_extents_paint_image (hb_paint_funcs_t *funcs HB_UNUSED,
    125 		      void *paint_data,
    126 		      hb_blob_t *blob HB_UNUSED,
    127 		      unsigned int width HB_UNUSED,
    128 		      unsigned int height HB_UNUSED,
    129 		      hb_tag_t format HB_UNUSED,
    130 		      float slant HB_UNUSED,
    131 		      hb_glyph_extents_t *glyph_extents,
    132 		      void *user_data HB_UNUSED)
    133 {
    134  hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
    135 
    136  if (!glyph_extents)
    137    return false; // Happens with SVG images.
    138 
    139  hb_extents_t<> extents = {(float) glyph_extents->x_bearing,
    140 		    (float) glyph_extents->y_bearing + glyph_extents->height,
    141 		    (float) glyph_extents->x_bearing + glyph_extents->width,
    142 		    (float) glyph_extents->y_bearing};
    143  c->push_clip (extents);
    144  c->paint ();
    145  c->pop_clip ();
    146 
    147  return true;
    148 }
    149 
    150 static void
    151 hb_paint_extents_paint_color (hb_paint_funcs_t *funcs HB_UNUSED,
    152 		      void *paint_data,
    153 		      hb_bool_t use_foreground HB_UNUSED,
    154 		      hb_color_t color HB_UNUSED,
    155 		      void *user_data HB_UNUSED)
    156 {
    157  hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
    158 
    159  c->paint ();
    160 }
    161 
    162 static void
    163 hb_paint_extents_paint_linear_gradient (hb_paint_funcs_t *funcs HB_UNUSED,
    164 			        void *paint_data,
    165 			        hb_color_line_t *color_line HB_UNUSED,
    166 			        float x0 HB_UNUSED, float y0 HB_UNUSED,
    167 			        float x1 HB_UNUSED, float y1 HB_UNUSED,
    168 			        float x2 HB_UNUSED, float y2 HB_UNUSED,
    169 			        void *user_data HB_UNUSED)
    170 {
    171  hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
    172 
    173  c->paint ();
    174 }
    175 
    176 static void
    177 hb_paint_extents_paint_radial_gradient (hb_paint_funcs_t *funcs HB_UNUSED,
    178 			        void *paint_data,
    179 			        hb_color_line_t *color_line HB_UNUSED,
    180 			        float x0 HB_UNUSED, float y0 HB_UNUSED, float r0 HB_UNUSED,
    181 			        float x1 HB_UNUSED, float y1 HB_UNUSED, float r1 HB_UNUSED,
    182 			        void *user_data HB_UNUSED)
    183 {
    184  hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
    185 
    186  c->paint ();
    187 }
    188 
    189 static void
    190 hb_paint_extents_paint_sweep_gradient (hb_paint_funcs_t *funcs HB_UNUSED,
    191 			       void *paint_data,
    192 			       hb_color_line_t *color_line HB_UNUSED,
    193 			       float cx HB_UNUSED, float cy HB_UNUSED,
    194 			       float start_angle HB_UNUSED,
    195 			       float end_angle HB_UNUSED,
    196 			       void *user_data HB_UNUSED)
    197 {
    198  hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
    199 
    200  c->paint ();
    201 }
    202 
    203 static inline void free_static_paint_extents_funcs ();
    204 
    205 static struct hb_paint_extents_funcs_lazy_loader_t : hb_paint_funcs_lazy_loader_t<hb_paint_extents_funcs_lazy_loader_t>
    206 {
    207  static hb_paint_funcs_t *create ()
    208  {
    209    hb_paint_funcs_t *funcs = hb_paint_funcs_create ();
    210 
    211    hb_paint_funcs_set_push_transform_func (funcs, hb_paint_extents_push_transform, nullptr, nullptr);
    212    hb_paint_funcs_set_pop_transform_func (funcs, hb_paint_extents_pop_transform, nullptr, nullptr);
    213    hb_paint_funcs_set_push_clip_glyph_func (funcs, hb_paint_extents_push_clip_glyph, nullptr, nullptr);
    214    hb_paint_funcs_set_push_clip_rectangle_func (funcs, hb_paint_extents_push_clip_rectangle, nullptr, nullptr);
    215    hb_paint_funcs_set_pop_clip_func (funcs, hb_paint_extents_pop_clip, nullptr, nullptr);
    216    hb_paint_funcs_set_push_group_func (funcs, hb_paint_extents_push_group, nullptr, nullptr);
    217    hb_paint_funcs_set_pop_group_func (funcs, hb_paint_extents_pop_group, nullptr, nullptr);
    218    hb_paint_funcs_set_color_func (funcs, hb_paint_extents_paint_color, nullptr, nullptr);
    219    hb_paint_funcs_set_image_func (funcs, hb_paint_extents_paint_image, nullptr, nullptr);
    220    hb_paint_funcs_set_linear_gradient_func (funcs, hb_paint_extents_paint_linear_gradient, nullptr, nullptr);
    221    hb_paint_funcs_set_radial_gradient_func (funcs, hb_paint_extents_paint_radial_gradient, nullptr, nullptr);
    222    hb_paint_funcs_set_sweep_gradient_func (funcs, hb_paint_extents_paint_sweep_gradient, nullptr, nullptr);
    223 
    224    hb_paint_funcs_make_immutable (funcs);
    225 
    226    hb_atexit (free_static_paint_extents_funcs);
    227 
    228    return funcs;
    229  }
    230 } static_paint_extents_funcs;
    231 
    232 static inline
    233 void free_static_paint_extents_funcs ()
    234 {
    235  static_paint_extents_funcs.free_instance ();
    236 }
    237 
    238 hb_paint_funcs_t *
    239 hb_paint_extents_get_funcs ()
    240 {
    241  return static_paint_extents_funcs.get_unconst ();
    242 }
    243 
    244 
    245 #endif