1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/harfbuzz/src/hb-ot-layout-gdef-table.hh Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,433 @@ 1.4 +/* 1.5 + * Copyright © 2007,2008,2009 Red Hat, Inc. 1.6 + * Copyright © 2010,2011,2012 Google, Inc. 1.7 + * 1.8 + * This is part of HarfBuzz, a text shaping library. 1.9 + * 1.10 + * Permission is hereby granted, without written agreement and without 1.11 + * license or royalty fees, to use, copy, modify, and distribute this 1.12 + * software and its documentation for any purpose, provided that the 1.13 + * above copyright notice and the following two paragraphs appear in 1.14 + * all copies of this software. 1.15 + * 1.16 + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 1.17 + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 1.18 + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 1.19 + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 1.20 + * DAMAGE. 1.21 + * 1.22 + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 1.23 + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 1.24 + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 1.25 + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 1.26 + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 1.27 + * 1.28 + * Red Hat Author(s): Behdad Esfahbod 1.29 + * Google Author(s): Behdad Esfahbod 1.30 + */ 1.31 + 1.32 +#ifndef HB_OT_LAYOUT_GDEF_TABLE_HH 1.33 +#define HB_OT_LAYOUT_GDEF_TABLE_HH 1.34 + 1.35 +#include "hb-ot-layout-common-private.hh" 1.36 + 1.37 +#include "hb-font-private.hh" 1.38 + 1.39 + 1.40 +namespace OT { 1.41 + 1.42 + 1.43 +/* 1.44 + * Attachment List Table 1.45 + */ 1.46 + 1.47 +typedef ArrayOf<USHORT> AttachPoint; /* Array of contour point indices--in 1.48 + * increasing numerical order */ 1.49 + 1.50 +struct AttachList 1.51 +{ 1.52 + inline unsigned int get_attach_points (hb_codepoint_t glyph_id, 1.53 + unsigned int start_offset, 1.54 + unsigned int *point_count /* IN/OUT */, 1.55 + unsigned int *point_array /* OUT */) const 1.56 + { 1.57 + unsigned int index = (this+coverage).get_coverage (glyph_id); 1.58 + if (index == NOT_COVERED) 1.59 + { 1.60 + if (point_count) 1.61 + *point_count = 0; 1.62 + return 0; 1.63 + } 1.64 + 1.65 + const AttachPoint &points = this+attachPoint[index]; 1.66 + 1.67 + if (point_count) { 1.68 + const USHORT *array = points.sub_array (start_offset, point_count); 1.69 + unsigned int count = *point_count; 1.70 + for (unsigned int i = 0; i < count; i++) 1.71 + point_array[i] = array[i]; 1.72 + } 1.73 + 1.74 + return points.len; 1.75 + } 1.76 + 1.77 + inline bool sanitize (hb_sanitize_context_t *c) { 1.78 + TRACE_SANITIZE (this); 1.79 + return TRACE_RETURN (coverage.sanitize (c, this) && attachPoint.sanitize (c, this)); 1.80 + } 1.81 + 1.82 + protected: 1.83 + OffsetTo<Coverage> 1.84 + coverage; /* Offset to Coverage table -- from 1.85 + * beginning of AttachList table */ 1.86 + OffsetArrayOf<AttachPoint> 1.87 + attachPoint; /* Array of AttachPoint tables 1.88 + * in Coverage Index order */ 1.89 + public: 1.90 + DEFINE_SIZE_ARRAY (4, attachPoint); 1.91 +}; 1.92 + 1.93 +/* 1.94 + * Ligature Caret Table 1.95 + */ 1.96 + 1.97 +struct CaretValueFormat1 1.98 +{ 1.99 + friend struct CaretValue; 1.100 + 1.101 + private: 1.102 + inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id HB_UNUSED) const 1.103 + { 1.104 + return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) : font->em_scale_y (coordinate); 1.105 + } 1.106 + 1.107 + inline bool sanitize (hb_sanitize_context_t *c) { 1.108 + TRACE_SANITIZE (this); 1.109 + return TRACE_RETURN (c->check_struct (this)); 1.110 + } 1.111 + 1.112 + protected: 1.113 + USHORT caretValueFormat; /* Format identifier--format = 1 */ 1.114 + SHORT coordinate; /* X or Y value, in design units */ 1.115 + public: 1.116 + DEFINE_SIZE_STATIC (4); 1.117 +}; 1.118 + 1.119 +struct CaretValueFormat2 1.120 +{ 1.121 + friend struct CaretValue; 1.122 + 1.123 + private: 1.124 + inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const 1.125 + { 1.126 + hb_position_t x, y; 1.127 + if (font->get_glyph_contour_point_for_origin (glyph_id, caretValuePoint, direction, &x, &y)) 1.128 + return HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y; 1.129 + else 1.130 + return 0; 1.131 + } 1.132 + 1.133 + inline bool sanitize (hb_sanitize_context_t *c) { 1.134 + TRACE_SANITIZE (this); 1.135 + return TRACE_RETURN (c->check_struct (this)); 1.136 + } 1.137 + 1.138 + protected: 1.139 + USHORT caretValueFormat; /* Format identifier--format = 2 */ 1.140 + USHORT caretValuePoint; /* Contour point index on glyph */ 1.141 + public: 1.142 + DEFINE_SIZE_STATIC (4); 1.143 +}; 1.144 + 1.145 +struct CaretValueFormat3 1.146 +{ 1.147 + friend struct CaretValue; 1.148 + 1.149 + inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id HB_UNUSED) const 1.150 + { 1.151 + return HB_DIRECTION_IS_HORIZONTAL (direction) ? 1.152 + font->em_scale_x (coordinate) + (this+deviceTable).get_x_delta (font) : 1.153 + font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font); 1.154 + } 1.155 + 1.156 + inline bool sanitize (hb_sanitize_context_t *c) { 1.157 + TRACE_SANITIZE (this); 1.158 + return TRACE_RETURN (c->check_struct (this) && deviceTable.sanitize (c, this)); 1.159 + } 1.160 + 1.161 + protected: 1.162 + USHORT caretValueFormat; /* Format identifier--format = 3 */ 1.163 + SHORT coordinate; /* X or Y value, in design units */ 1.164 + OffsetTo<Device> 1.165 + deviceTable; /* Offset to Device table for X or Y 1.166 + * value--from beginning of CaretValue 1.167 + * table */ 1.168 + public: 1.169 + DEFINE_SIZE_STATIC (6); 1.170 +}; 1.171 + 1.172 +struct CaretValue 1.173 +{ 1.174 + inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const 1.175 + { 1.176 + switch (u.format) { 1.177 + case 1: return u.format1.get_caret_value (font, direction, glyph_id); 1.178 + case 2: return u.format2.get_caret_value (font, direction, glyph_id); 1.179 + case 3: return u.format3.get_caret_value (font, direction, glyph_id); 1.180 + default:return 0; 1.181 + } 1.182 + } 1.183 + 1.184 + inline bool sanitize (hb_sanitize_context_t *c) { 1.185 + TRACE_SANITIZE (this); 1.186 + if (!u.format.sanitize (c)) return TRACE_RETURN (false); 1.187 + switch (u.format) { 1.188 + case 1: return TRACE_RETURN (u.format1.sanitize (c)); 1.189 + case 2: return TRACE_RETURN (u.format2.sanitize (c)); 1.190 + case 3: return TRACE_RETURN (u.format3.sanitize (c)); 1.191 + default:return TRACE_RETURN (true); 1.192 + } 1.193 + } 1.194 + 1.195 + protected: 1.196 + union { 1.197 + USHORT format; /* Format identifier */ 1.198 + CaretValueFormat1 format1; 1.199 + CaretValueFormat2 format2; 1.200 + CaretValueFormat3 format3; 1.201 + } u; 1.202 + public: 1.203 + DEFINE_SIZE_UNION (2, format); 1.204 +}; 1.205 + 1.206 +struct LigGlyph 1.207 +{ 1.208 + inline unsigned int get_lig_carets (hb_font_t *font, 1.209 + hb_direction_t direction, 1.210 + hb_codepoint_t glyph_id, 1.211 + unsigned int start_offset, 1.212 + unsigned int *caret_count /* IN/OUT */, 1.213 + hb_position_t *caret_array /* OUT */) const 1.214 + { 1.215 + if (caret_count) { 1.216 + const OffsetTo<CaretValue> *array = carets.sub_array (start_offset, caret_count); 1.217 + unsigned int count = *caret_count; 1.218 + for (unsigned int i = 0; i < count; i++) 1.219 + caret_array[i] = (this+array[i]).get_caret_value (font, direction, glyph_id); 1.220 + } 1.221 + 1.222 + return carets.len; 1.223 + } 1.224 + 1.225 + inline bool sanitize (hb_sanitize_context_t *c) { 1.226 + TRACE_SANITIZE (this); 1.227 + return TRACE_RETURN (carets.sanitize (c, this)); 1.228 + } 1.229 + 1.230 + protected: 1.231 + OffsetArrayOf<CaretValue> 1.232 + carets; /* Offset array of CaretValue tables 1.233 + * --from beginning of LigGlyph table 1.234 + * --in increasing coordinate order */ 1.235 + public: 1.236 + DEFINE_SIZE_ARRAY (2, carets); 1.237 +}; 1.238 + 1.239 +struct LigCaretList 1.240 +{ 1.241 + inline unsigned int get_lig_carets (hb_font_t *font, 1.242 + hb_direction_t direction, 1.243 + hb_codepoint_t glyph_id, 1.244 + unsigned int start_offset, 1.245 + unsigned int *caret_count /* IN/OUT */, 1.246 + hb_position_t *caret_array /* OUT */) const 1.247 + { 1.248 + unsigned int index = (this+coverage).get_coverage (glyph_id); 1.249 + if (index == NOT_COVERED) 1.250 + { 1.251 + if (caret_count) 1.252 + *caret_count = 0; 1.253 + return 0; 1.254 + } 1.255 + const LigGlyph &lig_glyph = this+ligGlyph[index]; 1.256 + return lig_glyph.get_lig_carets (font, direction, glyph_id, start_offset, caret_count, caret_array); 1.257 + } 1.258 + 1.259 + inline bool sanitize (hb_sanitize_context_t *c) { 1.260 + TRACE_SANITIZE (this); 1.261 + return TRACE_RETURN (coverage.sanitize (c, this) && ligGlyph.sanitize (c, this)); 1.262 + } 1.263 + 1.264 + protected: 1.265 + OffsetTo<Coverage> 1.266 + coverage; /* Offset to Coverage table--from 1.267 + * beginning of LigCaretList table */ 1.268 + OffsetArrayOf<LigGlyph> 1.269 + ligGlyph; /* Array of LigGlyph tables 1.270 + * in Coverage Index order */ 1.271 + public: 1.272 + DEFINE_SIZE_ARRAY (4, ligGlyph); 1.273 +}; 1.274 + 1.275 + 1.276 +struct MarkGlyphSetsFormat1 1.277 +{ 1.278 + inline bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const 1.279 + { return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; } 1.280 + 1.281 + inline bool sanitize (hb_sanitize_context_t *c) { 1.282 + TRACE_SANITIZE (this); 1.283 + return TRACE_RETURN (coverage.sanitize (c, this)); 1.284 + } 1.285 + 1.286 + protected: 1.287 + USHORT format; /* Format identifier--format = 1 */ 1.288 + LongOffsetArrayOf<Coverage> 1.289 + coverage; /* Array of long offsets to mark set 1.290 + * coverage tables */ 1.291 + public: 1.292 + DEFINE_SIZE_ARRAY (4, coverage); 1.293 +}; 1.294 + 1.295 +struct MarkGlyphSets 1.296 +{ 1.297 + inline bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const 1.298 + { 1.299 + switch (u.format) { 1.300 + case 1: return u.format1.covers (set_index, glyph_id); 1.301 + default:return false; 1.302 + } 1.303 + } 1.304 + 1.305 + inline bool sanitize (hb_sanitize_context_t *c) { 1.306 + TRACE_SANITIZE (this); 1.307 + if (!u.format.sanitize (c)) return TRACE_RETURN (false); 1.308 + switch (u.format) { 1.309 + case 1: return TRACE_RETURN (u.format1.sanitize (c)); 1.310 + default:return TRACE_RETURN (true); 1.311 + } 1.312 + } 1.313 + 1.314 + protected: 1.315 + union { 1.316 + USHORT format; /* Format identifier */ 1.317 + MarkGlyphSetsFormat1 format1; 1.318 + } u; 1.319 + public: 1.320 + DEFINE_SIZE_UNION (2, format); 1.321 +}; 1.322 + 1.323 + 1.324 +/* 1.325 + * GDEF -- The Glyph Definition Table 1.326 + */ 1.327 + 1.328 +struct GDEF 1.329 +{ 1.330 + static const hb_tag_t tableTag = HB_OT_TAG_GDEF; 1.331 + 1.332 + enum GlyphClasses { 1.333 + UnclassifiedGlyph = 0, 1.334 + BaseGlyph = 1, 1.335 + LigatureGlyph = 2, 1.336 + MarkGlyph = 3, 1.337 + ComponentGlyph = 4 1.338 + }; 1.339 + 1.340 + inline bool has_glyph_classes (void) const { return glyphClassDef != 0; } 1.341 + inline unsigned int get_glyph_class (hb_codepoint_t glyph) const 1.342 + { return (this+glyphClassDef).get_class (glyph); } 1.343 + inline void get_glyphs_in_class (unsigned int klass, hb_set_t *glyphs) const 1.344 + { (this+glyphClassDef).add_class (glyphs, klass); } 1.345 + 1.346 + inline bool has_mark_attachment_types (void) const { return markAttachClassDef != 0; } 1.347 + inline unsigned int get_mark_attachment_type (hb_codepoint_t glyph) const 1.348 + { return (this+markAttachClassDef).get_class (glyph); } 1.349 + 1.350 + inline bool has_attach_points (void) const { return attachList != 0; } 1.351 + inline unsigned int get_attach_points (hb_codepoint_t glyph_id, 1.352 + unsigned int start_offset, 1.353 + unsigned int *point_count /* IN/OUT */, 1.354 + unsigned int *point_array /* OUT */) const 1.355 + { return (this+attachList).get_attach_points (glyph_id, start_offset, point_count, point_array); } 1.356 + 1.357 + inline bool has_lig_carets (void) const { return ligCaretList != 0; } 1.358 + inline unsigned int get_lig_carets (hb_font_t *font, 1.359 + hb_direction_t direction, 1.360 + hb_codepoint_t glyph_id, 1.361 + unsigned int start_offset, 1.362 + unsigned int *caret_count /* IN/OUT */, 1.363 + hb_position_t *caret_array /* OUT */) const 1.364 + { return (this+ligCaretList).get_lig_carets (font, direction, glyph_id, start_offset, caret_count, caret_array); } 1.365 + 1.366 + inline bool has_mark_sets (void) const { return version.to_int () >= 0x00010002 && markGlyphSetsDef[0] != 0; } 1.367 + inline bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const 1.368 + { return version.to_int () >= 0x00010002 && (this+markGlyphSetsDef[0]).covers (set_index, glyph_id); } 1.369 + 1.370 + inline bool sanitize (hb_sanitize_context_t *c) { 1.371 + TRACE_SANITIZE (this); 1.372 + return TRACE_RETURN (version.sanitize (c) && 1.373 + likely (version.major == 1) && 1.374 + glyphClassDef.sanitize (c, this) && 1.375 + attachList.sanitize (c, this) && 1.376 + ligCaretList.sanitize (c, this) && 1.377 + markAttachClassDef.sanitize (c, this) && 1.378 + (version.to_int () < 0x00010002 || markGlyphSetsDef[0].sanitize (c, this))); 1.379 + } 1.380 + 1.381 + 1.382 + /* glyph_props is a 16-bit integer where the lower 8-bit have bits representing 1.383 + * glyph class and other bits, and high 8-bit gthe mark attachment type (if any). 1.384 + * Not to be confused with lookup_props which is very similar. */ 1.385 + inline unsigned int get_glyph_props (hb_codepoint_t glyph) const 1.386 + { 1.387 + unsigned int klass = get_glyph_class (glyph); 1.388 + 1.389 + ASSERT_STATIC ((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH == (unsigned int) LookupFlag::IgnoreBaseGlyphs); 1.390 + ASSERT_STATIC ((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE == (unsigned int) LookupFlag::IgnoreLigatures); 1.391 + ASSERT_STATIC ((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_MARK == (unsigned int) LookupFlag::IgnoreMarks); 1.392 + 1.393 + switch (klass) { 1.394 + default: return 0; 1.395 + case BaseGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH; 1.396 + case LigatureGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE; 1.397 + case MarkGlyph: 1.398 + klass = get_mark_attachment_type (glyph); 1.399 + return HB_OT_LAYOUT_GLYPH_PROPS_MARK | (klass << 8); 1.400 + } 1.401 + } 1.402 + 1.403 + 1.404 + protected: 1.405 + FixedVersion version; /* Version of the GDEF table--currently 1.406 + * 0x00010002 */ 1.407 + OffsetTo<ClassDef> 1.408 + glyphClassDef; /* Offset to class definition table 1.409 + * for glyph type--from beginning of 1.410 + * GDEF header (may be Null) */ 1.411 + OffsetTo<AttachList> 1.412 + attachList; /* Offset to list of glyphs with 1.413 + * attachment points--from beginning 1.414 + * of GDEF header (may be Null) */ 1.415 + OffsetTo<LigCaretList> 1.416 + ligCaretList; /* Offset to list of positioning points 1.417 + * for ligature carets--from beginning 1.418 + * of GDEF header (may be Null) */ 1.419 + OffsetTo<ClassDef> 1.420 + markAttachClassDef; /* Offset to class definition table for 1.421 + * mark attachment type--from beginning 1.422 + * of GDEF header (may be Null) */ 1.423 + OffsetTo<MarkGlyphSets> 1.424 + markGlyphSetsDef[VAR]; /* Offset to the table of mark set 1.425 + * definitions--from beginning of GDEF 1.426 + * header (may be NULL). Introduced 1.427 + * in version 00010002. */ 1.428 + public: 1.429 + DEFINE_SIZE_ARRAY (12, markGlyphSetsDef); 1.430 +}; 1.431 + 1.432 + 1.433 +} /* namespace OT */ 1.434 + 1.435 + 1.436 +#endif /* HB_OT_LAYOUT_GDEF_TABLE_HH */