1 /* 2 * Copyright © 2018 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 #ifndef HB_AAT_LAYOUT_LCAR_TABLE_HH 25 #define HB_AAT_LAYOUT_LCAR_TABLE_HH 26 27 #include "hb-open-type.hh" 28 #include "hb-aat-layout-common.hh" 29 30 /* 31 * lcar -- Ligature caret 32 * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6lcar.html 33 */ 34 #define HB_AAT_TAG_lcar HB_TAG('l','c','a','r') 35 36 37 namespace AAT { 38 39 typedef ArrayOf<HBINT16> LigCaretClassEntry; 40 41 struct lcarFormat0 42 { get_lig_caretsAAT::lcarFormat043 unsigned int get_lig_carets (hb_font_t *font, 44 hb_direction_t direction, 45 hb_codepoint_t glyph, 46 unsigned int start_offset, 47 unsigned int *caret_count /* IN/OUT */, 48 hb_position_t *caret_array /* OUT */, 49 const void *base) const 50 { 51 const OffsetTo<LigCaretClassEntry>* entry_offset = lookupTable.get_value (glyph, 52 font->face->get_num_glyphs ()); 53 const LigCaretClassEntry& array = entry_offset ? base+*entry_offset : Null (LigCaretClassEntry); 54 if (caret_count) 55 { 56 hb_array_t<const HBINT16> arr = array.sub_array (start_offset, caret_count); 57 for (unsigned int i = 0; i < arr.length; ++i) 58 caret_array[i] = font->em_scale_dir (arr[i], direction); 59 } 60 return array.len; 61 } 62 sanitizeAAT::lcarFormat063 bool sanitize (hb_sanitize_context_t *c, const void *base) const 64 { 65 TRACE_SANITIZE (this); 66 return_trace (likely (c->check_struct (this) && lookupTable.sanitize (c, base))); 67 } 68 69 protected: 70 Lookup<OffsetTo<LigCaretClassEntry>> 71 lookupTable; /* data Lookup table associating glyphs */ 72 public: 73 DEFINE_SIZE_MIN (2); 74 }; 75 76 struct lcarFormat1 77 { get_lig_caretsAAT::lcarFormat178 unsigned int get_lig_carets (hb_font_t *font, 79 hb_direction_t direction, 80 hb_codepoint_t glyph, 81 unsigned int start_offset, 82 unsigned int *caret_count /* IN/OUT */, 83 hb_position_t *caret_array /* OUT */, 84 const void *base) const 85 { 86 const OffsetTo<LigCaretClassEntry>* entry_offset = lookupTable.get_value (glyph, 87 font->face->get_num_glyphs ()); 88 const LigCaretClassEntry& array = entry_offset ? base+*entry_offset : Null (LigCaretClassEntry); 89 if (caret_count) 90 { 91 hb_array_t<const HBINT16> arr = array.sub_array (start_offset, caret_count); 92 for (unsigned int i = 0; i < arr.length; ++i) 93 { 94 hb_position_t x = 0, y = 0; 95 font->get_glyph_contour_point_for_origin (glyph, arr[i], direction, &x, &y); 96 caret_array[i] = HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y; 97 } 98 } 99 return array.len; 100 } 101 sanitizeAAT::lcarFormat1102 bool sanitize (hb_sanitize_context_t *c, const void *base) const 103 { 104 TRACE_SANITIZE (this); 105 return_trace (likely (c->check_struct (this) && lookupTable.sanitize (c, base))); 106 } 107 108 protected: 109 Lookup<OffsetTo<LigCaretClassEntry>> 110 lookupTable; /* data Lookup table associating glyphs */ 111 public: 112 DEFINE_SIZE_MIN (2); 113 }; 114 115 struct lcar 116 { 117 static constexpr hb_tag_t tableTag = HB_AAT_TAG_lcar; 118 get_lig_caretsAAT::lcar119 unsigned int get_lig_carets (hb_font_t *font, 120 hb_direction_t direction, 121 hb_codepoint_t glyph, 122 unsigned int start_offset, 123 unsigned int *caret_count /* IN/OUT */, 124 hb_position_t *caret_array /* OUT */) const 125 { 126 switch (format) 127 { 128 case 0: return u.format0.get_lig_carets (font, direction, glyph, start_offset, 129 caret_count, caret_array, this); 130 case 1: return u.format1.get_lig_carets (font, direction, glyph, start_offset, 131 caret_count, caret_array, this); 132 default:if (caret_count) *caret_count = 0; return 0; 133 } 134 } 135 sanitizeAAT::lcar136 bool sanitize (hb_sanitize_context_t *c) const 137 { 138 TRACE_SANITIZE (this); 139 if (unlikely (!c->check_struct (this) || version.major != 1)) 140 return_trace (false); 141 142 switch (format) { 143 case 0: return_trace (u.format0.sanitize (c, this)); 144 case 1: return_trace (u.format1.sanitize (c, this)); 145 default:return_trace (true); 146 } 147 } 148 149 protected: 150 FixedVersion<>version; /* Version number of the ligature caret table */ 151 HBUINT16 format; /* Format of the ligature caret table. */ 152 union { 153 lcarFormat0 format0; 154 lcarFormat0 format1; 155 } u; 156 public: 157 DEFINE_SIZE_MIN (8); 158 }; 159 160 } /* namespace AAT */ 161 162 #endif /* HB_AAT_LAYOUT_LCAR_TABLE_HH */ 163