hb-paint-extents.hh (3594B)
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 #ifndef HB_PAINT_EXTENTS_HH 26 #define HB_PAINT_EXTENTS_HH 27 28 #include "hb.hh" 29 #include "hb-paint.h" 30 31 #include "hb-geometry.hh" 32 33 34 typedef struct hb_paint_extents_context_t hb_paint_extents_context_t; 35 36 struct hb_paint_extents_context_t 37 { 38 void clear () 39 { 40 transforms.clear (); 41 clips.clear (); 42 groups.clear (); 43 44 transforms.push (hb_transform_t<>{}); 45 clips.push (hb_bounds_t<>{hb_bounds_t<>::UNBOUNDED}); 46 groups.push (hb_bounds_t<>{hb_bounds_t<>::EMPTY}); 47 } 48 49 hb_paint_extents_context_t () 50 { 51 clear (); 52 } 53 54 hb_extents_t<> get_extents () 55 { 56 return groups.tail().extents; 57 } 58 59 bool is_bounded () 60 { 61 return groups.tail().status != hb_bounds_t<>::UNBOUNDED; 62 } 63 64 void push_transform (const hb_transform_t<> &trans) 65 { 66 hb_transform_t<> t = transforms.tail (); 67 t.multiply (trans); 68 transforms.push (t); 69 } 70 71 void pop_transform () 72 { 73 transforms.pop (); 74 } 75 76 void push_clip (hb_extents_t<> extents) 77 { 78 /* Transform extents and push a new clip. */ 79 const hb_transform_t<> &t = transforms.tail (); 80 t.transform_extents (extents); 81 82 auto bounds = hb_bounds_t<> {extents}; 83 bounds.intersect (clips.tail ()); 84 85 clips.push (bounds); 86 } 87 88 void pop_clip () 89 { 90 clips.pop (); 91 } 92 93 void push_group () 94 { 95 groups.push (hb_bounds_t<> {hb_bounds_t<>::EMPTY}); 96 } 97 98 void pop_group (hb_paint_composite_mode_t mode) 99 { 100 const hb_bounds_t<> src_bounds = groups.pop (); 101 hb_bounds_t<> &backdrop_bounds = groups.tail (); 102 103 // https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-32-paintcomposite 104 switch ((int) mode) 105 { 106 case HB_PAINT_COMPOSITE_MODE_CLEAR: 107 backdrop_bounds.status = hb_bounds_t<>::EMPTY; 108 break; 109 case HB_PAINT_COMPOSITE_MODE_SRC: 110 case HB_PAINT_COMPOSITE_MODE_SRC_OUT: 111 backdrop_bounds = src_bounds; 112 break; 113 case HB_PAINT_COMPOSITE_MODE_DEST: 114 case HB_PAINT_COMPOSITE_MODE_DEST_OUT: 115 break; 116 case HB_PAINT_COMPOSITE_MODE_SRC_IN: 117 case HB_PAINT_COMPOSITE_MODE_DEST_IN: 118 backdrop_bounds.intersect (src_bounds); 119 break; 120 default: 121 backdrop_bounds.union_ (src_bounds); 122 break; 123 } 124 } 125 126 void paint () 127 { 128 const hb_bounds_t<> &clip = clips.tail (); 129 hb_bounds_t<> &group = groups.tail (); 130 131 group.union_ (clip); 132 } 133 134 protected: 135 hb_vector_t<hb_transform_t<>> transforms; 136 hb_vector_t<hb_bounds_t<>> clips; 137 hb_vector_t<hb_bounds_t<>> groups; 138 }; 139 140 HB_INTERNAL hb_paint_funcs_t * 141 hb_paint_extents_get_funcs (); 142 143 144 #endif /* HB_PAINT_EXTENTS_HH */