1 /* 2 * Copyright © 2019 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_AAT_LAYOUT_OPBD_TABLE_HH 26 #define HB_AAT_LAYOUT_OPBD_TABLE_HH 27 28 #include "hb-aat-layout-common.hh" 29 #include "hb-open-type.hh" 30 31 /* 32 * opbd -- Optical Bounds 33 * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6opbd.html 34 */ 35 #define HB_AAT_TAG_opbd HB_TAG('o','p','b','d') 36 37 38 namespace AAT { 39 40 struct OpticalBounds 41 { sanitizeAAT::OpticalBounds42 bool sanitize (hb_sanitize_context_t *c) const 43 { 44 TRACE_SANITIZE (this); 45 return_trace (likely (c->check_struct (this))); 46 } 47 48 FWORD leftSide; 49 FWORD topSide; 50 FWORD rightSide; 51 FWORD bottomSide; 52 public: 53 DEFINE_SIZE_STATIC (8); 54 }; 55 56 struct opbdFormat0 57 { get_boundsAAT::opbdFormat058 bool get_bounds (hb_font_t *font, hb_codepoint_t glyph_id, 59 hb_glyph_extents_t *extents, const void *base) const 60 { 61 const Offset16To<OpticalBounds> *bounds_offset = lookupTable.get_value (glyph_id, font->face->get_num_glyphs ()); 62 if (!bounds_offset) return false; 63 const OpticalBounds &bounds = base+*bounds_offset; 64 65 if (extents) 66 *extents = { 67 font->em_scale_x (bounds.leftSide), 68 font->em_scale_y (bounds.topSide), 69 font->em_scale_x (bounds.rightSide), 70 font->em_scale_y (bounds.bottomSide) 71 }; 72 return true; 73 } 74 sanitizeAAT::opbdFormat075 bool sanitize (hb_sanitize_context_t *c, const void *base) const 76 { 77 TRACE_SANITIZE (this); 78 return_trace (likely (c->check_struct (this) && lookupTable.sanitize (c, base))); 79 } 80 81 protected: 82 Lookup<Offset16To<OpticalBounds>> 83 lookupTable; /* Lookup table associating glyphs with the four 84 * int16 values for the left-side, top-side, 85 * right-side, and bottom-side optical bounds. */ 86 public: 87 DEFINE_SIZE_MIN (2); 88 }; 89 90 struct opbdFormat1 91 { get_boundsAAT::opbdFormat192 bool get_bounds (hb_font_t *font, hb_codepoint_t glyph_id, 93 hb_glyph_extents_t *extents, const void *base) const 94 { 95 const Offset16To<OpticalBounds> *bounds_offset = lookupTable.get_value (glyph_id, font->face->get_num_glyphs ()); 96 if (!bounds_offset) return false; 97 const OpticalBounds &bounds = base+*bounds_offset; 98 99 hb_position_t left = 0, top = 0, right = 0, bottom = 0, ignore; 100 if (font->get_glyph_contour_point (glyph_id, bounds.leftSide, &left, &ignore) || 101 font->get_glyph_contour_point (glyph_id, bounds.topSide, &ignore, &top) || 102 font->get_glyph_contour_point (glyph_id, bounds.rightSide, &right, &ignore) || 103 font->get_glyph_contour_point (glyph_id, bounds.bottomSide, &ignore, &bottom)) 104 { 105 if (extents) 106 *extents = {left, top, right, bottom}; 107 return true; 108 } 109 return false; 110 } 111 sanitizeAAT::opbdFormat1112 bool sanitize (hb_sanitize_context_t *c, const void *base) const 113 { 114 TRACE_SANITIZE (this); 115 return_trace (likely (c->check_struct (this) && lookupTable.sanitize (c, base))); 116 } 117 118 protected: 119 Lookup<Offset16To<OpticalBounds>> 120 lookupTable; /* Lookup table associating glyphs with the four 121 * int16 values for the left-side, top-side, 122 * right-side, and bottom-side optical bounds. */ 123 public: 124 DEFINE_SIZE_MIN (2); 125 }; 126 127 struct opbd 128 { 129 static constexpr hb_tag_t tableTag = HB_AAT_TAG_opbd; 130 get_boundsAAT::opbd131 bool get_bounds (hb_font_t *font, hb_codepoint_t glyph_id, 132 hb_glyph_extents_t *extents) const 133 { 134 switch (format) 135 { 136 case 0: return u.format0.get_bounds (font, glyph_id, extents, this); 137 case 1: return u.format1.get_bounds (font, glyph_id, extents, this); 138 default:return false; 139 } 140 } 141 sanitizeAAT::opbd142 bool sanitize (hb_sanitize_context_t *c) const 143 { 144 TRACE_SANITIZE (this); 145 if (unlikely (!c->check_struct (this) || version.major != 1)) 146 return_trace (false); 147 148 switch (format) 149 { 150 case 0: return_trace (u.format0.sanitize (c, this)); 151 case 1: return_trace (u.format1.sanitize (c, this)); 152 default:return_trace (true); 153 } 154 } 155 156 protected: 157 FixedVersion<>version; /* Version number of the optical bounds 158 * table (0x00010000 for the current version). */ 159 HBUINT16 format; /* Format of the optical bounds table. 160 * Format 0 indicates distance and Format 1 indicates 161 * control point. */ 162 union { 163 opbdFormat0 format0; 164 opbdFormat1 format1; 165 } u; 166 public: 167 DEFINE_SIZE_MIN (8); 168 }; 169 170 } /* namespace AAT */ 171 172 173 #endif /* HB_AAT_LAYOUT_OPBD_TABLE_HH */ 174