OLD | NEW |
1 /* | 1 /* |
2 * Copyright © 2007,2008,2009,2010 Red Hat, Inc. | 2 * Copyright © 2007,2008,2009,2010 Red Hat, Inc. |
3 * Copyright © 2010,2012,2013 Google, Inc. | 3 * Copyright © 2010,2012,2013 Google, Inc. |
4 * | 4 * |
5 * This is part of HarfBuzz, a text shaping library. | 5 * This is part of HarfBuzz, a text shaping library. |
6 * | 6 * |
7 * Permission is hereby granted, without written agreement and without | 7 * Permission is hereby granted, without written agreement and without |
8 * license or royalty fees, to use, copy, modify, and distribute this | 8 * license or royalty fees, to use, copy, modify, and distribute this |
9 * software and its documentation for any purpose, provided that the | 9 * software and its documentation for any purpose, provided that the |
10 * above copyright notice and the following two paragraphs appear in | 10 * above copyright notice and the following two paragraphs appear in |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 values++; | 139 values++; |
140 } | 140 } |
141 if (format & yAdvDevice) { | 141 if (format & yAdvDevice) { |
142 /* y_advance values grow downward but font-space grows upward, hence negat
ion */ | 142 /* y_advance values grow downward but font-space grows upward, hence negat
ion */ |
143 if (!horizontal && y_ppem) glyph_pos.y_advance -= (base + get_device (valu
es)).get_y_delta (font); | 143 if (!horizontal && y_ppem) glyph_pos.y_advance -= (base + get_device (valu
es)).get_y_delta (font); |
144 values++; | 144 values++; |
145 } | 145 } |
146 } | 146 } |
147 | 147 |
148 private: | 148 private: |
149 inline bool sanitize_value_devices (hb_sanitize_context_t *c, void *base, Valu
e *values) { | 149 inline bool sanitize_value_devices (hb_sanitize_context_t *c, const void *base
, const Value *values) const |
| 150 { |
150 unsigned int format = *this; | 151 unsigned int format = *this; |
151 | 152 |
152 if (format & xPlacement) values++; | 153 if (format & xPlacement) values++; |
153 if (format & yPlacement) values++; | 154 if (format & yPlacement) values++; |
154 if (format & xAdvance) values++; | 155 if (format & xAdvance) values++; |
155 if (format & yAdvance) values++; | 156 if (format & yAdvance) values++; |
156 | 157 |
157 if ((format & xPlaDevice) && !get_device (values++).sanitize (c, base)) retu
rn false; | 158 if ((format & xPlaDevice) && !get_device (values++).sanitize (c, base)) retu
rn false; |
158 if ((format & yPlaDevice) && !get_device (values++).sanitize (c, base)) retu
rn false; | 159 if ((format & yPlaDevice) && !get_device (values++).sanitize (c, base)) retu
rn false; |
159 if ((format & xAdvDevice) && !get_device (values++).sanitize (c, base)) retu
rn false; | 160 if ((format & xAdvDevice) && !get_device (values++).sanitize (c, base)) retu
rn false; |
(...skipping 10 matching lines...) Expand all Loading... |
170 static inline const SHORT& get_short (const Value* value) | 171 static inline const SHORT& get_short (const Value* value) |
171 { return *CastP<SHORT> (value); } | 172 { return *CastP<SHORT> (value); } |
172 | 173 |
173 public: | 174 public: |
174 | 175 |
175 inline bool has_device (void) const { | 176 inline bool has_device (void) const { |
176 unsigned int format = *this; | 177 unsigned int format = *this; |
177 return (format & devices) != 0; | 178 return (format & devices) != 0; |
178 } | 179 } |
179 | 180 |
180 inline bool sanitize_value (hb_sanitize_context_t *c, void *base, Value *value
s) { | 181 inline bool sanitize_value (hb_sanitize_context_t *c, const void *base, const
Value *values) const |
| 182 { |
181 TRACE_SANITIZE (this); | 183 TRACE_SANITIZE (this); |
182 return TRACE_RETURN (c->check_range (values, get_size ()) && (!has_device ()
|| sanitize_value_devices (c, base, values))); | 184 return TRACE_RETURN (c->check_range (values, get_size ()) && (!has_device ()
|| sanitize_value_devices (c, base, values))); |
183 } | 185 } |
184 | 186 |
185 inline bool sanitize_values (hb_sanitize_context_t *c, void *base, Value *valu
es, unsigned int count) { | 187 inline bool sanitize_values (hb_sanitize_context_t *c, const void *base, const
Value *values, unsigned int count) const |
| 188 { |
186 TRACE_SANITIZE (this); | 189 TRACE_SANITIZE (this); |
187 unsigned int len = get_len (); | 190 unsigned int len = get_len (); |
188 | 191 |
189 if (!c->check_array (values, get_size (), count)) return TRACE_RETURN (false
); | 192 if (!c->check_array (values, get_size (), count)) return TRACE_RETURN (false
); |
190 | 193 |
191 if (!has_device ()) return TRACE_RETURN (true); | 194 if (!has_device ()) return TRACE_RETURN (true); |
192 | 195 |
193 for (unsigned int i = 0; i < count; i++) { | 196 for (unsigned int i = 0; i < count; i++) { |
194 if (!sanitize_value_devices (c, base, values)) | 197 if (!sanitize_value_devices (c, base, values)) |
195 return TRACE_RETURN (false); | 198 return TRACE_RETURN (false); |
196 values += len; | 199 values += len; |
197 } | 200 } |
198 | 201 |
199 return TRACE_RETURN (true); | 202 return TRACE_RETURN (true); |
200 } | 203 } |
201 | 204 |
202 /* Just sanitize referenced Device tables. Doesn't check the values themselve
s. */ | 205 /* Just sanitize referenced Device tables. Doesn't check the values themselve
s. */ |
203 inline bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, void *bas
e, Value *values, unsigned int count, unsigned int stride) { | 206 inline bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, const voi
d *base, const Value *values, unsigned int count, unsigned int stride) const |
| 207 { |
204 TRACE_SANITIZE (this); | 208 TRACE_SANITIZE (this); |
205 | 209 |
206 if (!has_device ()) return TRACE_RETURN (true); | 210 if (!has_device ()) return TRACE_RETURN (true); |
207 | 211 |
208 for (unsigned int i = 0; i < count; i++) { | 212 for (unsigned int i = 0; i < count; i++) { |
209 if (!sanitize_value_devices (c, base, values)) | 213 if (!sanitize_value_devices (c, base, values)) |
210 return TRACE_RETURN (false); | 214 return TRACE_RETURN (false); |
211 values += stride; | 215 values += stride; |
212 } | 216 } |
213 | 217 |
214 return TRACE_RETURN (true); | 218 return TRACE_RETURN (true); |
215 } | 219 } |
216 }; | 220 }; |
217 | 221 |
218 | 222 |
219 struct AnchorFormat1 | 223 struct AnchorFormat1 |
220 { | 224 { |
221 inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED, | 225 inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED, |
222 hb_position_t *x, hb_position_t *y) const | 226 hb_position_t *x, hb_position_t *y) const |
223 { | 227 { |
224 *x = font->em_scale_x (xCoordinate); | 228 *x = font->em_scale_x (xCoordinate); |
225 *y = font->em_scale_y (yCoordinate); | 229 *y = font->em_scale_y (yCoordinate); |
226 } | 230 } |
227 | 231 |
228 inline bool sanitize (hb_sanitize_context_t *c) { | 232 inline bool sanitize (hb_sanitize_context_t *c) const |
| 233 { |
229 TRACE_SANITIZE (this); | 234 TRACE_SANITIZE (this); |
230 return TRACE_RETURN (c->check_struct (this)); | 235 return TRACE_RETURN (c->check_struct (this)); |
231 } | 236 } |
232 | 237 |
233 protected: | 238 protected: |
234 USHORT format; /* Format identifier--format = 1 */ | 239 USHORT format; /* Format identifier--format = 1 */ |
235 SHORT xCoordinate; /* Horizontal value--in design units */ | 240 SHORT xCoordinate; /* Horizontal value--in design units */ |
236 SHORT yCoordinate; /* Vertical value--in design units */ | 241 SHORT yCoordinate; /* Vertical value--in design units */ |
237 public: | 242 public: |
238 DEFINE_SIZE_STATIC (6); | 243 DEFINE_SIZE_STATIC (6); |
239 }; | 244 }; |
240 | 245 |
241 struct AnchorFormat2 | 246 struct AnchorFormat2 |
242 { | 247 { |
243 inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id, | 248 inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id, |
244 hb_position_t *x, hb_position_t *y) const | 249 hb_position_t *x, hb_position_t *y) const |
245 { | 250 { |
246 unsigned int x_ppem = font->x_ppem; | 251 unsigned int x_ppem = font->x_ppem; |
247 unsigned int y_ppem = font->y_ppem; | 252 unsigned int y_ppem = font->y_ppem; |
248 hb_position_t cx, cy; | 253 hb_position_t cx, cy; |
249 hb_bool_t ret; | 254 hb_bool_t ret; |
250 | 255 |
251 ret = (x_ppem || y_ppem) && | 256 ret = (x_ppem || y_ppem) && |
252 font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB
_DIRECTION_LTR, &cx, &cy); | 257 font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB
_DIRECTION_LTR, &cx, &cy); |
253 *x = ret && x_ppem ? cx : font->em_scale_x (xCoordinate); | 258 *x = ret && x_ppem ? cx : font->em_scale_x (xCoordinate); |
254 *y = ret && y_ppem ? cy : font->em_scale_y (yCoordinate); | 259 *y = ret && y_ppem ? cy : font->em_scale_y (yCoordinate); |
255 } | 260 } |
256 | 261 |
257 inline bool sanitize (hb_sanitize_context_t *c) { | 262 inline bool sanitize (hb_sanitize_context_t *c) const |
| 263 { |
258 TRACE_SANITIZE (this); | 264 TRACE_SANITIZE (this); |
259 return TRACE_RETURN (c->check_struct (this)); | 265 return TRACE_RETURN (c->check_struct (this)); |
260 } | 266 } |
261 | 267 |
262 protected: | 268 protected: |
263 USHORT format; /* Format identifier--format = 2 */ | 269 USHORT format; /* Format identifier--format = 2 */ |
264 SHORT xCoordinate; /* Horizontal value--in design units */ | 270 SHORT xCoordinate; /* Horizontal value--in design units */ |
265 SHORT yCoordinate; /* Vertical value--in design units */ | 271 SHORT yCoordinate; /* Vertical value--in design units */ |
266 USHORT anchorPoint; /* Index to glyph contour point */ | 272 USHORT anchorPoint; /* Index to glyph contour point */ |
267 public: | 273 public: |
268 DEFINE_SIZE_STATIC (8); | 274 DEFINE_SIZE_STATIC (8); |
269 }; | 275 }; |
270 | 276 |
271 struct AnchorFormat3 | 277 struct AnchorFormat3 |
272 { | 278 { |
273 inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED, | 279 inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED, |
274 hb_position_t *x, hb_position_t *y) const | 280 hb_position_t *x, hb_position_t *y) const |
275 { | 281 { |
276 *x = font->em_scale_x (xCoordinate); | 282 *x = font->em_scale_x (xCoordinate); |
277 *y = font->em_scale_y (yCoordinate); | 283 *y = font->em_scale_y (yCoordinate); |
278 | 284 |
279 if (font->x_ppem) | 285 if (font->x_ppem) |
280 *x += (this+xDeviceTable).get_x_delta (font); | 286 *x += (this+xDeviceTable).get_x_delta (font); |
281 if (font->y_ppem) | 287 if (font->y_ppem) |
282 *y += (this+yDeviceTable).get_x_delta (font); | 288 *y += (this+yDeviceTable).get_x_delta (font); |
283 } | 289 } |
284 | 290 |
285 inline bool sanitize (hb_sanitize_context_t *c) { | 291 inline bool sanitize (hb_sanitize_context_t *c) const |
| 292 { |
286 TRACE_SANITIZE (this); | 293 TRACE_SANITIZE (this); |
287 return TRACE_RETURN (c->check_struct (this) && xDeviceTable.sanitize (c, thi
s) && yDeviceTable.sanitize (c, this)); | 294 return TRACE_RETURN (c->check_struct (this) && xDeviceTable.sanitize (c, thi
s) && yDeviceTable.sanitize (c, this)); |
288 } | 295 } |
289 | 296 |
290 protected: | 297 protected: |
291 USHORT format; /* Format identifier--format = 3 */ | 298 USHORT format; /* Format identifier--format = 3 */ |
292 SHORT xCoordinate; /* Horizontal value--in design units */ | 299 SHORT xCoordinate; /* Horizontal value--in design units */ |
293 SHORT yCoordinate; /* Vertical value--in design units */ | 300 SHORT yCoordinate; /* Vertical value--in design units */ |
294 OffsetTo<Device> | 301 OffsetTo<Device> |
295 xDeviceTable; /* Offset to Device table for X | 302 xDeviceTable; /* Offset to Device table for X |
(...skipping 14 matching lines...) Expand all Loading... |
310 { | 317 { |
311 *x = *y = 0; | 318 *x = *y = 0; |
312 switch (u.format) { | 319 switch (u.format) { |
313 case 1: u.format1.get_anchor (font, glyph_id, x, y); return; | 320 case 1: u.format1.get_anchor (font, glyph_id, x, y); return; |
314 case 2: u.format2.get_anchor (font, glyph_id, x, y); return; | 321 case 2: u.format2.get_anchor (font, glyph_id, x, y); return; |
315 case 3: u.format3.get_anchor (font, glyph_id, x, y); return; | 322 case 3: u.format3.get_anchor (font, glyph_id, x, y); return; |
316 default: return; | 323 default: return; |
317 } | 324 } |
318 } | 325 } |
319 | 326 |
320 inline bool sanitize (hb_sanitize_context_t *c) { | 327 inline bool sanitize (hb_sanitize_context_t *c) const |
| 328 { |
321 TRACE_SANITIZE (this); | 329 TRACE_SANITIZE (this); |
322 if (!u.format.sanitize (c)) return TRACE_RETURN (false); | 330 if (!u.format.sanitize (c)) return TRACE_RETURN (false); |
323 switch (u.format) { | 331 switch (u.format) { |
324 case 1: return TRACE_RETURN (u.format1.sanitize (c)); | 332 case 1: return TRACE_RETURN (u.format1.sanitize (c)); |
325 case 2: return TRACE_RETURN (u.format2.sanitize (c)); | 333 case 2: return TRACE_RETURN (u.format2.sanitize (c)); |
326 case 3: return TRACE_RETURN (u.format3.sanitize (c)); | 334 case 3: return TRACE_RETURN (u.format3.sanitize (c)); |
327 default:return TRACE_RETURN (true); | 335 default:return TRACE_RETURN (true); |
328 } | 336 } |
329 } | 337 } |
330 | 338 |
(...skipping 11 matching lines...) Expand all Loading... |
342 | 350 |
343 struct AnchorMatrix | 351 struct AnchorMatrix |
344 { | 352 { |
345 inline const Anchor& get_anchor (unsigned int row, unsigned int col, unsigned
int cols, bool *found) const { | 353 inline const Anchor& get_anchor (unsigned int row, unsigned int col, unsigned
int cols, bool *found) const { |
346 *found = false; | 354 *found = false; |
347 if (unlikely (row >= rows || col >= cols)) return Null(Anchor); | 355 if (unlikely (row >= rows || col >= cols)) return Null(Anchor); |
348 *found = !matrixZ[row * cols + col].is_null (); | 356 *found = !matrixZ[row * cols + col].is_null (); |
349 return this+matrixZ[row * cols + col]; | 357 return this+matrixZ[row * cols + col]; |
350 } | 358 } |
351 | 359 |
352 inline bool sanitize (hb_sanitize_context_t *c, unsigned int cols) { | 360 inline bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const |
| 361 { |
353 TRACE_SANITIZE (this); | 362 TRACE_SANITIZE (this); |
354 if (!c->check_struct (this)) return TRACE_RETURN (false); | 363 if (!c->check_struct (this)) return TRACE_RETURN (false); |
355 if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return TRACE_
RETURN (false); | 364 if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return TRACE_
RETURN (false); |
356 unsigned int count = rows * cols; | 365 unsigned int count = rows * cols; |
357 if (!c->check_array (matrixZ, matrixZ[0].static_size, count)) return TRACE_R
ETURN (false); | 366 if (!c->check_array (matrixZ, matrixZ[0].static_size, count)) return TRACE_R
ETURN (false); |
358 for (unsigned int i = 0; i < count; i++) | 367 for (unsigned int i = 0; i < count; i++) |
359 if (!matrixZ[i].sanitize (c, this)) return TRACE_RETURN (false); | 368 if (!matrixZ[i].sanitize (c, this)) return TRACE_RETURN (false); |
360 return TRACE_RETURN (true); | 369 return TRACE_RETURN (true); |
361 } | 370 } |
362 | 371 |
363 USHORT rows; /* Number of rows */ | 372 USHORT rows; /* Number of rows */ |
364 protected: | 373 protected: |
365 OffsetTo<Anchor> | 374 OffsetTo<Anchor> |
366 matrixZ[VAR]; /* Matrix of offsets to Anchor tables-- | 375 matrixZ[VAR]; /* Matrix of offsets to Anchor tables-- |
367 * from beginning of AnchorMatrix table
*/ | 376 * from beginning of AnchorMatrix table
*/ |
368 public: | 377 public: |
369 DEFINE_SIZE_ARRAY (2, matrixZ); | 378 DEFINE_SIZE_ARRAY (2, matrixZ); |
370 }; | 379 }; |
371 | 380 |
372 | 381 |
373 struct MarkRecord | 382 struct MarkRecord |
374 { | 383 { |
375 friend struct MarkArray; | 384 friend struct MarkArray; |
376 | 385 |
377 inline bool sanitize (hb_sanitize_context_t *c, void *base) { | 386 inline bool sanitize (hb_sanitize_context_t *c, const void *base) const |
| 387 { |
378 TRACE_SANITIZE (this); | 388 TRACE_SANITIZE (this); |
379 return TRACE_RETURN (c->check_struct (this) && markAnchor.sanitize (c, base)
); | 389 return TRACE_RETURN (c->check_struct (this) && markAnchor.sanitize (c, base)
); |
380 } | 390 } |
381 | 391 |
382 protected: | 392 protected: |
383 USHORT klass; /* Class defined for this mark */ | 393 USHORT klass; /* Class defined for this mark */ |
384 OffsetTo<Anchor> | 394 OffsetTo<Anchor> |
385 markAnchor; /* Offset to Anchor table--from | 395 markAnchor; /* Offset to Anchor table--from |
386 * beginning of MarkArray table */ | 396 * beginning of MarkArray table */ |
387 public: | 397 public: |
(...skipping 26 matching lines...) Expand all Loading... |
414 | 424 |
415 hb_glyph_position_t &o = buffer->cur_pos(); | 425 hb_glyph_position_t &o = buffer->cur_pos(); |
416 o.x_offset = base_x - mark_x; | 426 o.x_offset = base_x - mark_x; |
417 o.y_offset = base_y - mark_y; | 427 o.y_offset = base_y - mark_y; |
418 o.attach_lookback() = buffer->idx - glyph_pos; | 428 o.attach_lookback() = buffer->idx - glyph_pos; |
419 | 429 |
420 buffer->idx++; | 430 buffer->idx++; |
421 return TRACE_RETURN (true); | 431 return TRACE_RETURN (true); |
422 } | 432 } |
423 | 433 |
424 inline bool sanitize (hb_sanitize_context_t *c) { | 434 inline bool sanitize (hb_sanitize_context_t *c) const |
| 435 { |
425 TRACE_SANITIZE (this); | 436 TRACE_SANITIZE (this); |
426 return TRACE_RETURN (ArrayOf<MarkRecord>::sanitize (c, this)); | 437 return TRACE_RETURN (ArrayOf<MarkRecord>::sanitize (c, this)); |
427 } | 438 } |
428 }; | 439 }; |
429 | 440 |
430 | 441 |
431 /* Lookups */ | 442 /* Lookups */ |
432 | 443 |
433 struct SinglePosFormat1 | 444 struct SinglePosFormat1 |
434 { | 445 { |
(...skipping 15 matching lines...) Expand all Loading... |
450 unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint)
; | 461 unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint)
; |
451 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); | 462 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); |
452 | 463 |
453 valueFormat.apply_value (c->font, c->direction, this, | 464 valueFormat.apply_value (c->font, c->direction, this, |
454 values, buffer->cur_pos()); | 465 values, buffer->cur_pos()); |
455 | 466 |
456 buffer->idx++; | 467 buffer->idx++; |
457 return TRACE_RETURN (true); | 468 return TRACE_RETURN (true); |
458 } | 469 } |
459 | 470 |
460 inline bool sanitize (hb_sanitize_context_t *c) { | 471 inline bool sanitize (hb_sanitize_context_t *c) const |
| 472 { |
461 TRACE_SANITIZE (this); | 473 TRACE_SANITIZE (this); |
462 return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) &
& valueFormat.sanitize_value (c, this, values)); | 474 return TRACE_RETURN (c->check_struct (this) |
| 475 && coverage.sanitize (c, this) |
| 476 » && valueFormat.sanitize_value (c, this, values)); |
463 } | 477 } |
464 | 478 |
465 protected: | 479 protected: |
466 USHORT format; /* Format identifier--format = 1 */ | 480 USHORT format; /* Format identifier--format = 1 */ |
467 OffsetTo<Coverage> | 481 OffsetTo<Coverage> |
468 coverage; /* Offset to Coverage table--from | 482 coverage; /* Offset to Coverage table--from |
469 * beginning of subtable */ | 483 * beginning of subtable */ |
470 ValueFormat valueFormat; /* Defines the types of data in the | 484 ValueFormat valueFormat; /* Defines the types of data in the |
471 * ValueRecord */ | 485 * ValueRecord */ |
472 ValueRecord values; /* Defines positioning | 486 ValueRecord values; /* Defines positioning |
(...skipping 26 matching lines...) Expand all Loading... |
499 if (likely (index >= valueCount)) return TRACE_RETURN (false); | 513 if (likely (index >= valueCount)) return TRACE_RETURN (false); |
500 | 514 |
501 valueFormat.apply_value (c->font, c->direction, this, | 515 valueFormat.apply_value (c->font, c->direction, this, |
502 &values[index * valueFormat.get_len ()], | 516 &values[index * valueFormat.get_len ()], |
503 buffer->cur_pos()); | 517 buffer->cur_pos()); |
504 | 518 |
505 buffer->idx++; | 519 buffer->idx++; |
506 return TRACE_RETURN (true); | 520 return TRACE_RETURN (true); |
507 } | 521 } |
508 | 522 |
509 inline bool sanitize (hb_sanitize_context_t *c) { | 523 inline bool sanitize (hb_sanitize_context_t *c) const |
| 524 { |
510 TRACE_SANITIZE (this); | 525 TRACE_SANITIZE (this); |
511 return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) &
& valueFormat.sanitize_values (c, this, values, valueCount)); | 526 return TRACE_RETURN (c->check_struct (this) |
| 527 » && coverage.sanitize (c, this) |
| 528 » && valueFormat.sanitize_values (c, this, values, valueCount)); |
512 } | 529 } |
513 | 530 |
514 protected: | 531 protected: |
515 USHORT format; /* Format identifier--format = 2 */ | 532 USHORT format; /* Format identifier--format = 2 */ |
516 OffsetTo<Coverage> | 533 OffsetTo<Coverage> |
517 coverage; /* Offset to Coverage table--from | 534 coverage; /* Offset to Coverage table--from |
518 * beginning of subtable */ | 535 * beginning of subtable */ |
519 ValueFormat valueFormat; /* Defines the types of data in the | 536 ValueFormat valueFormat; /* Defines the types of data in the |
520 * ValueRecord */ | 537 * ValueRecord */ |
521 USHORT valueCount; /* Number of ValueRecords */ | 538 USHORT valueCount; /* Number of ValueRecords */ |
522 ValueRecord values; /* Array of ValueRecords--positioning | 539 ValueRecord values; /* Array of ValueRecords--positioning |
523 * values applied to glyphs */ | 540 * values applied to glyphs */ |
524 public: | 541 public: |
525 DEFINE_SIZE_ARRAY (8, values); | 542 DEFINE_SIZE_ARRAY (8, values); |
526 }; | 543 }; |
527 | 544 |
528 struct SinglePos | 545 struct SinglePos |
529 { | 546 { |
530 template <typename context_t> | 547 template <typename context_t> |
531 inline typename context_t::return_t dispatch (context_t *c) const | 548 inline typename context_t::return_t dispatch (context_t *c) const |
532 { | 549 { |
533 TRACE_DISPATCH (this, u.format); | 550 TRACE_DISPATCH (this, u.format); |
| 551 if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_
return_value ()); |
534 switch (u.format) { | 552 switch (u.format) { |
535 case 1: return TRACE_RETURN (c->dispatch (u.format1)); | 553 case 1: return TRACE_RETURN (c->dispatch (u.format1)); |
536 case 2: return TRACE_RETURN (c->dispatch (u.format2)); | 554 case 2: return TRACE_RETURN (c->dispatch (u.format2)); |
537 default:return TRACE_RETURN (c->default_return_value ()); | 555 default:return TRACE_RETURN (c->default_return_value ()); |
538 } | 556 } |
539 } | 557 } |
540 | 558 |
541 inline bool sanitize (hb_sanitize_context_t *c) { | |
542 TRACE_SANITIZE (this); | |
543 if (!u.format.sanitize (c)) return TRACE_RETURN (false); | |
544 switch (u.format) { | |
545 case 1: return TRACE_RETURN (u.format1.sanitize (c)); | |
546 case 2: return TRACE_RETURN (u.format2.sanitize (c)); | |
547 default:return TRACE_RETURN (true); | |
548 } | |
549 } | |
550 | |
551 protected: | 559 protected: |
552 union { | 560 union { |
553 USHORT format; /* Format identifier */ | 561 USHORT format; /* Format identifier */ |
554 SinglePosFormat1 format1; | 562 SinglePosFormat1 format1; |
555 SinglePosFormat2 format2; | 563 SinglePosFormat2 format2; |
556 } u; | 564 } u; |
557 }; | 565 }; |
558 | 566 |
559 | 567 |
560 struct PairValueRecord | 568 struct PairValueRecord |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
629 pos++; | 637 pos++; |
630 buffer->idx = pos; | 638 buffer->idx = pos; |
631 return TRACE_RETURN (true); | 639 return TRACE_RETURN (true); |
632 } | 640 } |
633 } | 641 } |
634 | 642 |
635 return TRACE_RETURN (false); | 643 return TRACE_RETURN (false); |
636 } | 644 } |
637 | 645 |
638 struct sanitize_closure_t { | 646 struct sanitize_closure_t { |
639 void *base; | 647 const void *base; |
640 ValueFormat *valueFormats; | 648 const ValueFormat *valueFormats; |
641 unsigned int len1; /* valueFormats[0].get_len() */ | 649 unsigned int len1; /* valueFormats[0].get_len() */ |
642 unsigned int stride; /* 1 + len1 + len2 */ | 650 unsigned int stride; /* 1 + len1 + len2 */ |
643 }; | 651 }; |
644 | 652 |
645 inline bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *clos
ure) { | 653 inline bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *clos
ure) const |
| 654 { |
646 TRACE_SANITIZE (this); | 655 TRACE_SANITIZE (this); |
647 if (!(c->check_struct (this) | 656 if (!(c->check_struct (this) |
648 && c->check_array (arrayZ, USHORT::static_size * closure->stride, len)))
return TRACE_RETURN (false); | 657 && c->check_array (arrayZ, USHORT::static_size * closure->stride, len)))
return TRACE_RETURN (false); |
649 | 658 |
650 unsigned int count = len; | 659 unsigned int count = len; |
651 PairValueRecord *record = CastP<PairValueRecord> (arrayZ); | 660 const PairValueRecord *record = CastP<PairValueRecord> (arrayZ); |
652 return TRACE_RETURN (closure->valueFormats[0].sanitize_values_stride_unsafe
(c, closure->base, &record->values[0], count, closure->stride) | 661 return TRACE_RETURN (closure->valueFormats[0].sanitize_values_stride_unsafe
(c, closure->base, &record->values[0], count, closure->stride) |
653 && closure->valueFormats[1].sanitize_values_stride_unsafe
(c, closure->base, &record->values[closure->len1], count, closure->stride)); | 662 && closure->valueFormats[1].sanitize_values_stride_unsafe
(c, closure->base, &record->values[closure->len1], count, closure->stride)); |
654 } | 663 } |
655 | 664 |
656 protected: | 665 protected: |
657 USHORT len; /* Number of PairValueRecords */ | 666 USHORT len; /* Number of PairValueRecords */ |
658 USHORT arrayZ[VAR]; /* Array of PairValueRecords--ordered | 667 USHORT arrayZ[VAR]; /* Array of PairValueRecords--ordered |
659 * by GlyphID of the second glyph */ | 668 * by GlyphID of the second glyph */ |
660 public: | 669 public: |
661 DEFINE_SIZE_ARRAY (2, arrayZ); | 670 DEFINE_SIZE_ARRAY (2, arrayZ); |
(...skipping 12 matching lines...) Expand all Loading... |
674 | 683 |
675 inline const Coverage &get_coverage (void) const | 684 inline const Coverage &get_coverage (void) const |
676 { | 685 { |
677 return this+coverage; | 686 return this+coverage; |
678 } | 687 } |
679 | 688 |
680 inline bool apply (hb_apply_context_t *c) const | 689 inline bool apply (hb_apply_context_t *c) const |
681 { | 690 { |
682 TRACE_APPLY (this); | 691 TRACE_APPLY (this); |
683 hb_buffer_t *buffer = c->buffer; | 692 hb_buffer_t *buffer = c->buffer; |
684 hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx,
1); | |
685 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); | |
686 | |
687 unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint)
; | 693 unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint)
; |
688 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); | 694 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); |
689 | 695 |
| 696 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; |
| 697 skippy_iter.reset (buffer->idx, 1); |
690 if (!skippy_iter.next ()) return TRACE_RETURN (false); | 698 if (!skippy_iter.next ()) return TRACE_RETURN (false); |
691 | 699 |
692 return TRACE_RETURN ((this+pairSet[index]).apply (c, &valueFormat1, skippy_i
ter.idx)); | 700 return TRACE_RETURN ((this+pairSet[index]).apply (c, &valueFormat1, skippy_i
ter.idx)); |
693 } | 701 } |
694 | 702 |
695 inline bool sanitize (hb_sanitize_context_t *c) { | 703 inline bool sanitize (hb_sanitize_context_t *c) const |
| 704 { |
696 TRACE_SANITIZE (this); | 705 TRACE_SANITIZE (this); |
697 | 706 |
698 unsigned int len1 = valueFormat1.get_len (); | 707 unsigned int len1 = valueFormat1.get_len (); |
699 unsigned int len2 = valueFormat2.get_len (); | 708 unsigned int len2 = valueFormat2.get_len (); |
700 PairSet::sanitize_closure_t closure = { | 709 PairSet::sanitize_closure_t closure = { |
701 this, | 710 this, |
702 &valueFormat1, | 711 &valueFormat1, |
703 len1, | 712 len1, |
704 1 + len1 + len2 | 713 1 + len1 + len2 |
705 }; | 714 }; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
745 | 754 |
746 inline const Coverage &get_coverage (void) const | 755 inline const Coverage &get_coverage (void) const |
747 { | 756 { |
748 return this+coverage; | 757 return this+coverage; |
749 } | 758 } |
750 | 759 |
751 inline bool apply (hb_apply_context_t *c) const | 760 inline bool apply (hb_apply_context_t *c) const |
752 { | 761 { |
753 TRACE_APPLY (this); | 762 TRACE_APPLY (this); |
754 hb_buffer_t *buffer = c->buffer; | 763 hb_buffer_t *buffer = c->buffer; |
755 hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx,
1); | |
756 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); | |
757 | |
758 unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint)
; | 764 unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint)
; |
759 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); | 765 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); |
760 | 766 |
| 767 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; |
| 768 skippy_iter.reset (buffer->idx, 1); |
761 if (!skippy_iter.next ()) return TRACE_RETURN (false); | 769 if (!skippy_iter.next ()) return TRACE_RETURN (false); |
762 | 770 |
763 unsigned int len1 = valueFormat1.get_len (); | 771 unsigned int len1 = valueFormat1.get_len (); |
764 unsigned int len2 = valueFormat2.get_len (); | 772 unsigned int len2 = valueFormat2.get_len (); |
765 unsigned int record_len = len1 + len2; | 773 unsigned int record_len = len1 + len2; |
766 | 774 |
767 unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint); | 775 unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint); |
768 unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.i
dx].codepoint); | 776 unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.i
dx].codepoint); |
769 if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return TRACE_
RETURN (false); | 777 if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return TRACE_
RETURN (false); |
770 | 778 |
771 const Value *v = &values[record_len * (klass1 * class2Count + klass2)]; | 779 const Value *v = &values[record_len * (klass1 * class2Count + klass2)]; |
772 valueFormat1.apply_value (c->font, c->direction, this, | 780 valueFormat1.apply_value (c->font, c->direction, this, |
773 v, buffer->cur_pos()); | 781 v, buffer->cur_pos()); |
774 valueFormat2.apply_value (c->font, c->direction, this, | 782 valueFormat2.apply_value (c->font, c->direction, this, |
775 v + len1, buffer->pos[skippy_iter.idx]); | 783 v + len1, buffer->pos[skippy_iter.idx]); |
776 | 784 |
777 buffer->idx = skippy_iter.idx; | 785 buffer->idx = skippy_iter.idx; |
778 if (len2) | 786 if (len2) |
779 buffer->idx++; | 787 buffer->idx++; |
780 | 788 |
781 return TRACE_RETURN (true); | 789 return TRACE_RETURN (true); |
782 } | 790 } |
783 | 791 |
784 inline bool sanitize (hb_sanitize_context_t *c) { | 792 inline bool sanitize (hb_sanitize_context_t *c) const |
| 793 { |
785 TRACE_SANITIZE (this); | 794 TRACE_SANITIZE (this); |
786 if (!(c->check_struct (this) | 795 if (!(c->check_struct (this) |
787 && coverage.sanitize (c, this) | 796 && coverage.sanitize (c, this) |
788 && classDef1.sanitize (c, this) | 797 && classDef1.sanitize (c, this) |
789 && classDef2.sanitize (c, this))) return TRACE_RETURN (false); | 798 && classDef2.sanitize (c, this))) return TRACE_RETURN (false); |
790 | 799 |
791 unsigned int len1 = valueFormat1.get_len (); | 800 unsigned int len1 = valueFormat1.get_len (); |
792 unsigned int len2 = valueFormat2.get_len (); | 801 unsigned int len2 = valueFormat2.get_len (); |
793 unsigned int stride = len1 + len2; | 802 unsigned int stride = len1 + len2; |
794 unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size
(); | 803 unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size
(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
827 public: | 836 public: |
828 DEFINE_SIZE_ARRAY (16, values); | 837 DEFINE_SIZE_ARRAY (16, values); |
829 }; | 838 }; |
830 | 839 |
831 struct PairPos | 840 struct PairPos |
832 { | 841 { |
833 template <typename context_t> | 842 template <typename context_t> |
834 inline typename context_t::return_t dispatch (context_t *c) const | 843 inline typename context_t::return_t dispatch (context_t *c) const |
835 { | 844 { |
836 TRACE_DISPATCH (this, u.format); | 845 TRACE_DISPATCH (this, u.format); |
| 846 if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_
return_value ()); |
837 switch (u.format) { | 847 switch (u.format) { |
838 case 1: return TRACE_RETURN (c->dispatch (u.format1)); | 848 case 1: return TRACE_RETURN (c->dispatch (u.format1)); |
839 case 2: return TRACE_RETURN (c->dispatch (u.format2)); | 849 case 2: return TRACE_RETURN (c->dispatch (u.format2)); |
840 default:return TRACE_RETURN (c->default_return_value ()); | 850 default:return TRACE_RETURN (c->default_return_value ()); |
841 } | 851 } |
842 } | 852 } |
843 | 853 |
844 inline bool sanitize (hb_sanitize_context_t *c) { | |
845 TRACE_SANITIZE (this); | |
846 if (!u.format.sanitize (c)) return TRACE_RETURN (false); | |
847 switch (u.format) { | |
848 case 1: return TRACE_RETURN (u.format1.sanitize (c)); | |
849 case 2: return TRACE_RETURN (u.format2.sanitize (c)); | |
850 default:return TRACE_RETURN (true); | |
851 } | |
852 } | |
853 | |
854 protected: | 854 protected: |
855 union { | 855 union { |
856 USHORT format; /* Format identifier */ | 856 USHORT format; /* Format identifier */ |
857 PairPosFormat1 format1; | 857 PairPosFormat1 format1; |
858 PairPosFormat2 format2; | 858 PairPosFormat2 format2; |
859 } u; | 859 } u; |
860 }; | 860 }; |
861 | 861 |
862 | 862 |
863 struct EntryExitRecord | 863 struct EntryExitRecord |
864 { | 864 { |
865 friend struct CursivePosFormat1; | 865 friend struct CursivePosFormat1; |
866 | 866 |
867 inline bool sanitize (hb_sanitize_context_t *c, void *base) { | 867 inline bool sanitize (hb_sanitize_context_t *c, const void *base) const |
| 868 { |
868 TRACE_SANITIZE (this); | 869 TRACE_SANITIZE (this); |
869 return TRACE_RETURN (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (
c, base)); | 870 return TRACE_RETURN (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (
c, base)); |
870 } | 871 } |
871 | 872 |
872 protected: | 873 protected: |
873 OffsetTo<Anchor> | 874 OffsetTo<Anchor> |
874 entryAnchor; /* Offset to EntryAnchor table--from | 875 entryAnchor; /* Offset to EntryAnchor table--from |
875 * beginning of CursivePos | 876 * beginning of CursivePos |
876 * subtable--may be NULL */ | 877 * subtable--may be NULL */ |
877 OffsetTo<Anchor> | 878 OffsetTo<Anchor> |
(...skipping 18 matching lines...) Expand all Loading... |
896 } | 897 } |
897 | 898 |
898 inline bool apply (hb_apply_context_t *c) const | 899 inline bool apply (hb_apply_context_t *c) const |
899 { | 900 { |
900 TRACE_APPLY (this); | 901 TRACE_APPLY (this); |
901 hb_buffer_t *buffer = c->buffer; | 902 hb_buffer_t *buffer = c->buffer; |
902 | 903 |
903 /* We don't handle mark glyphs here. */ | 904 /* We don't handle mark glyphs here. */ |
904 if (unlikely (_hb_glyph_info_is_mark (&buffer->cur()))) return TRACE_RETURN
(false); | 905 if (unlikely (_hb_glyph_info_is_mark (&buffer->cur()))) return TRACE_RETURN
(false); |
905 | 906 |
906 hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx,
1); | |
907 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); | |
908 | |
909 const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_cov
erage (buffer->cur().codepoint)]; | 907 const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_cov
erage (buffer->cur().codepoint)]; |
910 if (!this_record.exitAnchor) return TRACE_RETURN (false); | 908 if (!this_record.exitAnchor) return TRACE_RETURN (false); |
911 | 909 |
| 910 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; |
| 911 skippy_iter.reset (buffer->idx, 1); |
912 if (!skippy_iter.next ()) return TRACE_RETURN (false); | 912 if (!skippy_iter.next ()) return TRACE_RETURN (false); |
913 | 913 |
914 const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_cov
erage (buffer->info[skippy_iter.idx].codepoint)]; | 914 const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_cov
erage (buffer->info[skippy_iter.idx].codepoint)]; |
915 if (!next_record.entryAnchor) return TRACE_RETURN (false); | 915 if (!next_record.entryAnchor) return TRACE_RETURN (false); |
916 | 916 |
917 unsigned int i = buffer->idx; | 917 unsigned int i = buffer->idx; |
918 unsigned int j = skippy_iter.idx; | 918 unsigned int j = skippy_iter.idx; |
919 | 919 |
920 hb_position_t entry_x, entry_y, exit_x, exit_y; | 920 hb_position_t entry_x, entry_y, exit_x, exit_y; |
921 (this+this_record.exitAnchor).get_anchor (c->font, buffer->info[i].codepoint
, &exit_x, &exit_y); | 921 (this+this_record.exitAnchor).get_anchor (c->font, buffer->info[i].codepoint
, &exit_x, &exit_y); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
971 if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) | 971 if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) |
972 pos[j].y_offset = exit_y - entry_y; | 972 pos[j].y_offset = exit_y - entry_y; |
973 else | 973 else |
974 pos[j].x_offset = exit_x - entry_x; | 974 pos[j].x_offset = exit_x - entry_x; |
975 } | 975 } |
976 | 976 |
977 buffer->idx = j; | 977 buffer->idx = j; |
978 return TRACE_RETURN (true); | 978 return TRACE_RETURN (true); |
979 } | 979 } |
980 | 980 |
981 inline bool sanitize (hb_sanitize_context_t *c) { | 981 inline bool sanitize (hb_sanitize_context_t *c) const |
| 982 { |
982 TRACE_SANITIZE (this); | 983 TRACE_SANITIZE (this); |
983 return TRACE_RETURN (coverage.sanitize (c, this) && entryExitRecord.sanitize
(c, this)); | 984 return TRACE_RETURN (coverage.sanitize (c, this) && entryExitRecord.sanitize
(c, this)); |
984 } | 985 } |
985 | 986 |
986 protected: | 987 protected: |
987 USHORT format; /* Format identifier--format = 1 */ | 988 USHORT format; /* Format identifier--format = 1 */ |
988 OffsetTo<Coverage> | 989 OffsetTo<Coverage> |
989 coverage; /* Offset to Coverage table--from | 990 coverage; /* Offset to Coverage table--from |
990 * beginning of subtable */ | 991 * beginning of subtable */ |
991 ArrayOf<EntryExitRecord> | 992 ArrayOf<EntryExitRecord> |
992 entryExitRecord; /* Array of EntryExit records--in | 993 entryExitRecord; /* Array of EntryExit records--in |
993 * Coverage Index order */ | 994 * Coverage Index order */ |
994 public: | 995 public: |
995 DEFINE_SIZE_ARRAY (6, entryExitRecord); | 996 DEFINE_SIZE_ARRAY (6, entryExitRecord); |
996 }; | 997 }; |
997 | 998 |
998 struct CursivePos | 999 struct CursivePos |
999 { | 1000 { |
1000 template <typename context_t> | 1001 template <typename context_t> |
1001 inline typename context_t::return_t dispatch (context_t *c) const | 1002 inline typename context_t::return_t dispatch (context_t *c) const |
1002 { | 1003 { |
1003 TRACE_DISPATCH (this, u.format); | 1004 TRACE_DISPATCH (this, u.format); |
| 1005 if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_
return_value ()); |
1004 switch (u.format) { | 1006 switch (u.format) { |
1005 case 1: return TRACE_RETURN (c->dispatch (u.format1)); | 1007 case 1: return TRACE_RETURN (c->dispatch (u.format1)); |
1006 default:return TRACE_RETURN (c->default_return_value ()); | 1008 default:return TRACE_RETURN (c->default_return_value ()); |
1007 } | 1009 } |
1008 } | 1010 } |
1009 | 1011 |
1010 inline bool sanitize (hb_sanitize_context_t *c) { | |
1011 TRACE_SANITIZE (this); | |
1012 if (!u.format.sanitize (c)) return TRACE_RETURN (false); | |
1013 switch (u.format) { | |
1014 case 1: return TRACE_RETURN (u.format1.sanitize (c)); | |
1015 default:return TRACE_RETURN (true); | |
1016 } | |
1017 } | |
1018 | |
1019 protected: | 1012 protected: |
1020 union { | 1013 union { |
1021 USHORT format; /* Format identifier */ | 1014 USHORT format; /* Format identifier */ |
1022 CursivePosFormat1 format1; | 1015 CursivePosFormat1 format1; |
1023 } u; | 1016 } u; |
1024 }; | 1017 }; |
1025 | 1018 |
1026 | 1019 |
1027 typedef AnchorMatrix BaseArray; /* base-major-- | 1020 typedef AnchorMatrix BaseArray; /* base-major-- |
1028 * in order of BaseCoverage Index--, | 1021 * in order of BaseCoverage Index--, |
(...skipping 15 matching lines...) Expand all Loading... |
1044 } | 1037 } |
1045 | 1038 |
1046 inline bool apply (hb_apply_context_t *c) const | 1039 inline bool apply (hb_apply_context_t *c) const |
1047 { | 1040 { |
1048 TRACE_APPLY (this); | 1041 TRACE_APPLY (this); |
1049 hb_buffer_t *buffer = c->buffer; | 1042 hb_buffer_t *buffer = c->buffer; |
1050 unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().c
odepoint); | 1043 unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().c
odepoint); |
1051 if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); | 1044 if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); |
1052 | 1045 |
1053 /* now we search backwards for a non-mark glyph */ | 1046 /* now we search backwards for a non-mark glyph */ |
1054 hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx
, 1); | 1047 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; |
| 1048 skippy_iter.reset (buffer->idx, 1); |
1055 skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); | 1049 skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); |
1056 do { | 1050 do { |
1057 if (!skippy_iter.prev ()) return TRACE_RETURN (false); | 1051 if (!skippy_iter.prev ()) return TRACE_RETURN (false); |
1058 /* We only want to attach to the first of a MultipleSubst sequence. Rejec
t others. */ | 1052 /* We only want to attach to the first of a MultipleSubst sequence. Rejec
t others. */ |
1059 if (0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx])) bre
ak; | 1053 if (0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx])) bre
ak; |
1060 skippy_iter.reject (); | 1054 skippy_iter.reject (); |
1061 } while (1); | 1055 } while (1); |
1062 | 1056 |
1063 /* Checking that matched glyph is actually a base glyph by GDEF is too stron
g; disabled */ | 1057 /* Checking that matched glyph is actually a base glyph by GDEF is too stron
g; disabled */ |
1064 if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { /*retu
rn TRACE_RETURN (false);*/ } | 1058 if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { /*retu
rn TRACE_RETURN (false);*/ } |
1065 | 1059 |
1066 unsigned int base_index = (this+baseCoverage).get_coverage (buffer->info[sk
ippy_iter.idx].codepoint); | 1060 unsigned int base_index = (this+baseCoverage).get_coverage (buffer->info[sk
ippy_iter.idx].codepoint); |
1067 if (base_index == NOT_COVERED) return TRACE_RETURN (false); | 1061 if (base_index == NOT_COVERED) return TRACE_RETURN (false); |
1068 | 1062 |
1069 return TRACE_RETURN ((this+markArray).apply (c, mark_index, base_index, this
+baseArray, classCount, skippy_iter.idx)); | 1063 return TRACE_RETURN ((this+markArray).apply (c, mark_index, base_index, this
+baseArray, classCount, skippy_iter.idx)); |
1070 } | 1064 } |
1071 | 1065 |
1072 inline bool sanitize (hb_sanitize_context_t *c) { | 1066 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1067 { |
1073 TRACE_SANITIZE (this); | 1068 TRACE_SANITIZE (this); |
1074 return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, thi
s) && baseCoverage.sanitize (c, this) && | 1069 return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, thi
s) && baseCoverage.sanitize (c, this) && |
1075 markArray.sanitize (c, this) && baseArray.sanitize (c,
this, (unsigned int) classCount)); | 1070 markArray.sanitize (c, this) && baseArray.sanitize (c,
this, (unsigned int) classCount)); |
1076 } | 1071 } |
1077 | 1072 |
1078 protected: | 1073 protected: |
1079 USHORT format; /* Format identifier--format = 1 */ | 1074 USHORT format; /* Format identifier--format = 1 */ |
1080 OffsetTo<Coverage> | 1075 OffsetTo<Coverage> |
1081 markCoverage; /* Offset to MarkCoverage table--from | 1076 markCoverage; /* Offset to MarkCoverage table--from |
1082 * beginning of MarkBasePos subtable */ | 1077 * beginning of MarkBasePos subtable */ |
(...skipping 10 matching lines...) Expand all Loading... |
1093 public: | 1088 public: |
1094 DEFINE_SIZE_STATIC (12); | 1089 DEFINE_SIZE_STATIC (12); |
1095 }; | 1090 }; |
1096 | 1091 |
1097 struct MarkBasePos | 1092 struct MarkBasePos |
1098 { | 1093 { |
1099 template <typename context_t> | 1094 template <typename context_t> |
1100 inline typename context_t::return_t dispatch (context_t *c) const | 1095 inline typename context_t::return_t dispatch (context_t *c) const |
1101 { | 1096 { |
1102 TRACE_DISPATCH (this, u.format); | 1097 TRACE_DISPATCH (this, u.format); |
| 1098 if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_
return_value ()); |
1103 switch (u.format) { | 1099 switch (u.format) { |
1104 case 1: return TRACE_RETURN (c->dispatch (u.format1)); | 1100 case 1: return TRACE_RETURN (c->dispatch (u.format1)); |
1105 default:return TRACE_RETURN (c->default_return_value ()); | 1101 default:return TRACE_RETURN (c->default_return_value ()); |
1106 } | 1102 } |
1107 } | 1103 } |
1108 | 1104 |
1109 inline bool sanitize (hb_sanitize_context_t *c) { | |
1110 TRACE_SANITIZE (this); | |
1111 if (!u.format.sanitize (c)) return TRACE_RETURN (false); | |
1112 switch (u.format) { | |
1113 case 1: return TRACE_RETURN (u.format1.sanitize (c)); | |
1114 default:return TRACE_RETURN (true); | |
1115 } | |
1116 } | |
1117 | |
1118 protected: | 1105 protected: |
1119 union { | 1106 union { |
1120 USHORT format; /* Format identifier */ | 1107 USHORT format; /* Format identifier */ |
1121 MarkBasePosFormat1 format1; | 1108 MarkBasePosFormat1 format1; |
1122 } u; | 1109 } u; |
1123 }; | 1110 }; |
1124 | 1111 |
1125 | 1112 |
1126 typedef AnchorMatrix LigatureAttach; /* component-major-- | 1113 typedef AnchorMatrix LigatureAttach; /* component-major-- |
1127 * in order of writing direction--, | 1114 * in order of writing direction--, |
(...skipping 20 matching lines...) Expand all Loading... |
1148 } | 1135 } |
1149 | 1136 |
1150 inline bool apply (hb_apply_context_t *c) const | 1137 inline bool apply (hb_apply_context_t *c) const |
1151 { | 1138 { |
1152 TRACE_APPLY (this); | 1139 TRACE_APPLY (this); |
1153 hb_buffer_t *buffer = c->buffer; | 1140 hb_buffer_t *buffer = c->buffer; |
1154 unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().c
odepoint); | 1141 unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().c
odepoint); |
1155 if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); | 1142 if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); |
1156 | 1143 |
1157 /* now we search backwards for a non-mark glyph */ | 1144 /* now we search backwards for a non-mark glyph */ |
1158 hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx
, 1); | 1145 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; |
| 1146 skippy_iter.reset (buffer->idx, 1); |
1159 skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); | 1147 skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); |
1160 if (!skippy_iter.prev ()) return TRACE_RETURN (false); | 1148 if (!skippy_iter.prev ()) return TRACE_RETURN (false); |
1161 | 1149 |
1162 /* Checking that matched glyph is actually a ligature by GDEF is too strong;
disabled */ | 1150 /* Checking that matched glyph is actually a ligature by GDEF is too strong;
disabled */ |
1163 if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { /*return
TRACE_RETURN (false);*/ } | 1151 if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { /*return
TRACE_RETURN (false);*/ } |
1164 | 1152 |
1165 unsigned int j = skippy_iter.idx; | 1153 unsigned int j = skippy_iter.idx; |
1166 unsigned int lig_index = (this+ligatureCoverage).get_coverage (buffer->info
[j].codepoint); | 1154 unsigned int lig_index = (this+ligatureCoverage).get_coverage (buffer->info
[j].codepoint); |
1167 if (lig_index == NOT_COVERED) return TRACE_RETURN (false); | 1155 if (lig_index == NOT_COVERED) return TRACE_RETURN (false); |
1168 | 1156 |
(...skipping 13 matching lines...) Expand all Loading... |
1182 unsigned int mark_id = _hb_glyph_info_get_lig_id (&buffer->cur()); | 1170 unsigned int mark_id = _hb_glyph_info_get_lig_id (&buffer->cur()); |
1183 unsigned int mark_comp = _hb_glyph_info_get_lig_comp (&buffer->cur()); | 1171 unsigned int mark_comp = _hb_glyph_info_get_lig_comp (&buffer->cur()); |
1184 if (lig_id && lig_id == mark_id && mark_comp > 0) | 1172 if (lig_id && lig_id == mark_id && mark_comp > 0) |
1185 comp_index = MIN (comp_count, _hb_glyph_info_get_lig_comp (&buffer->cur())
) - 1; | 1173 comp_index = MIN (comp_count, _hb_glyph_info_get_lig_comp (&buffer->cur())
) - 1; |
1186 else | 1174 else |
1187 comp_index = comp_count - 1; | 1175 comp_index = comp_count - 1; |
1188 | 1176 |
1189 return TRACE_RETURN ((this+markArray).apply (c, mark_index, comp_index, lig_
attach, classCount, j)); | 1177 return TRACE_RETURN ((this+markArray).apply (c, mark_index, comp_index, lig_
attach, classCount, j)); |
1190 } | 1178 } |
1191 | 1179 |
1192 inline bool sanitize (hb_sanitize_context_t *c) { | 1180 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1181 { |
1193 TRACE_SANITIZE (this); | 1182 TRACE_SANITIZE (this); |
1194 return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, thi
s) && ligatureCoverage.sanitize (c, this) && | 1183 return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, thi
s) && ligatureCoverage.sanitize (c, this) && |
1195 markArray.sanitize (c, this) && ligatureArray.sanitize
(c, this, (unsigned int) classCount)); | 1184 markArray.sanitize (c, this) && ligatureArray.sanitize
(c, this, (unsigned int) classCount)); |
1196 } | 1185 } |
1197 | 1186 |
1198 protected: | 1187 protected: |
1199 USHORT format; /* Format identifier--format = 1 */ | 1188 USHORT format; /* Format identifier--format = 1 */ |
1200 OffsetTo<Coverage> | 1189 OffsetTo<Coverage> |
1201 markCoverage; /* Offset to Mark Coverage table--from | 1190 markCoverage; /* Offset to Mark Coverage table--from |
1202 * beginning of MarkLigPos subtable */ | 1191 * beginning of MarkLigPos subtable */ |
(...skipping 11 matching lines...) Expand all Loading... |
1214 public: | 1203 public: |
1215 DEFINE_SIZE_STATIC (12); | 1204 DEFINE_SIZE_STATIC (12); |
1216 }; | 1205 }; |
1217 | 1206 |
1218 struct MarkLigPos | 1207 struct MarkLigPos |
1219 { | 1208 { |
1220 template <typename context_t> | 1209 template <typename context_t> |
1221 inline typename context_t::return_t dispatch (context_t *c) const | 1210 inline typename context_t::return_t dispatch (context_t *c) const |
1222 { | 1211 { |
1223 TRACE_DISPATCH (this, u.format); | 1212 TRACE_DISPATCH (this, u.format); |
| 1213 if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_
return_value ()); |
1224 switch (u.format) { | 1214 switch (u.format) { |
1225 case 1: return TRACE_RETURN (c->dispatch (u.format1)); | 1215 case 1: return TRACE_RETURN (c->dispatch (u.format1)); |
1226 default:return TRACE_RETURN (c->default_return_value ()); | 1216 default:return TRACE_RETURN (c->default_return_value ()); |
1227 } | 1217 } |
1228 } | 1218 } |
1229 | 1219 |
1230 inline bool sanitize (hb_sanitize_context_t *c) { | |
1231 TRACE_SANITIZE (this); | |
1232 if (!u.format.sanitize (c)) return TRACE_RETURN (false); | |
1233 switch (u.format) { | |
1234 case 1: return TRACE_RETURN (u.format1.sanitize (c)); | |
1235 default:return TRACE_RETURN (true); | |
1236 } | |
1237 } | |
1238 | |
1239 protected: | 1220 protected: |
1240 union { | 1221 union { |
1241 USHORT format; /* Format identifier */ | 1222 USHORT format; /* Format identifier */ |
1242 MarkLigPosFormat1 format1; | 1223 MarkLigPosFormat1 format1; |
1243 } u; | 1224 } u; |
1244 }; | 1225 }; |
1245 | 1226 |
1246 | 1227 |
1247 typedef AnchorMatrix Mark2Array; /* mark2-major-- | 1228 typedef AnchorMatrix Mark2Array; /* mark2-major-- |
1248 * in order of Mark2Coverage Index--, | 1229 * in order of Mark2Coverage Index--, |
(...skipping 15 matching lines...) Expand all Loading... |
1264 } | 1245 } |
1265 | 1246 |
1266 inline bool apply (hb_apply_context_t *c) const | 1247 inline bool apply (hb_apply_context_t *c) const |
1267 { | 1248 { |
1268 TRACE_APPLY (this); | 1249 TRACE_APPLY (this); |
1269 hb_buffer_t *buffer = c->buffer; | 1250 hb_buffer_t *buffer = c->buffer; |
1270 unsigned int mark1_index = (this+mark1Coverage).get_coverage (buffer->cur()
.codepoint); | 1251 unsigned int mark1_index = (this+mark1Coverage).get_coverage (buffer->cur()
.codepoint); |
1271 if (likely (mark1_index == NOT_COVERED)) return TRACE_RETURN (false); | 1252 if (likely (mark1_index == NOT_COVERED)) return TRACE_RETURN (false); |
1272 | 1253 |
1273 /* now we search backwards for a suitable mark glyph until a non-mark glyph
*/ | 1254 /* now we search backwards for a suitable mark glyph until a non-mark glyph
*/ |
1274 hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx
, 1); | 1255 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; |
| 1256 skippy_iter.reset (buffer->idx, 1); |
1275 skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags); | 1257 skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags); |
1276 if (!skippy_iter.prev ()) return TRACE_RETURN (false); | 1258 if (!skippy_iter.prev ()) return TRACE_RETURN (false); |
1277 | 1259 |
1278 if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx])) { return TRACE
_RETURN (false); } | 1260 if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx])) { return TRACE
_RETURN (false); } |
1279 | 1261 |
1280 unsigned int j = skippy_iter.idx; | 1262 unsigned int j = skippy_iter.idx; |
1281 | 1263 |
1282 unsigned int id1 = _hb_glyph_info_get_lig_id (&buffer->cur()); | 1264 unsigned int id1 = _hb_glyph_info_get_lig_id (&buffer->cur()); |
1283 unsigned int id2 = _hb_glyph_info_get_lig_id (&buffer->info[j]); | 1265 unsigned int id2 = _hb_glyph_info_get_lig_id (&buffer->info[j]); |
1284 unsigned int comp1 = _hb_glyph_info_get_lig_comp (&buffer->cur()); | 1266 unsigned int comp1 = _hb_glyph_info_get_lig_comp (&buffer->cur()); |
(...skipping 14 matching lines...) Expand all Loading... |
1299 /* Didn't match. */ | 1281 /* Didn't match. */ |
1300 return TRACE_RETURN (false); | 1282 return TRACE_RETURN (false); |
1301 | 1283 |
1302 good: | 1284 good: |
1303 unsigned int mark2_index = (this+mark2Coverage).get_coverage (buffer->info[
j].codepoint); | 1285 unsigned int mark2_index = (this+mark2Coverage).get_coverage (buffer->info[
j].codepoint); |
1304 if (mark2_index == NOT_COVERED) return TRACE_RETURN (false); | 1286 if (mark2_index == NOT_COVERED) return TRACE_RETURN (false); |
1305 | 1287 |
1306 return TRACE_RETURN ((this+mark1Array).apply (c, mark1_index, mark2_index, t
his+mark2Array, classCount, j)); | 1288 return TRACE_RETURN ((this+mark1Array).apply (c, mark1_index, mark2_index, t
his+mark2Array, classCount, j)); |
1307 } | 1289 } |
1308 | 1290 |
1309 inline bool sanitize (hb_sanitize_context_t *c) { | 1291 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1292 { |
1310 TRACE_SANITIZE (this); | 1293 TRACE_SANITIZE (this); |
1311 return TRACE_RETURN (c->check_struct (this) && mark1Coverage.sanitize (c, th
is) && | 1294 return TRACE_RETURN (c->check_struct (this) && mark1Coverage.sanitize (c, th
is) && |
1312 mark2Coverage.sanitize (c, this) && mark1Array.sanitize
(c, this) | 1295 mark2Coverage.sanitize (c, this) && mark1Array.sanitize
(c, this) |
1313 && mark2Array.sanitize (c, this, (unsigned int) classCo
unt)); | 1296 && mark2Array.sanitize (c, this, (unsigned int) classCo
unt)); |
1314 } | 1297 } |
1315 | 1298 |
1316 protected: | 1299 protected: |
1317 USHORT format; /* Format identifier--format = 1 */ | 1300 USHORT format; /* Format identifier--format = 1 */ |
1318 OffsetTo<Coverage> | 1301 OffsetTo<Coverage> |
1319 mark1Coverage; /* Offset to Combining Mark1 Coverage | 1302 mark1Coverage; /* Offset to Combining Mark1 Coverage |
(...skipping 13 matching lines...) Expand all Loading... |
1333 public: | 1316 public: |
1334 DEFINE_SIZE_STATIC (12); | 1317 DEFINE_SIZE_STATIC (12); |
1335 }; | 1318 }; |
1336 | 1319 |
1337 struct MarkMarkPos | 1320 struct MarkMarkPos |
1338 { | 1321 { |
1339 template <typename context_t> | 1322 template <typename context_t> |
1340 inline typename context_t::return_t dispatch (context_t *c) const | 1323 inline typename context_t::return_t dispatch (context_t *c) const |
1341 { | 1324 { |
1342 TRACE_DISPATCH (this, u.format); | 1325 TRACE_DISPATCH (this, u.format); |
| 1326 if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_
return_value ()); |
1343 switch (u.format) { | 1327 switch (u.format) { |
1344 case 1: return TRACE_RETURN (c->dispatch (u.format1)); | 1328 case 1: return TRACE_RETURN (c->dispatch (u.format1)); |
1345 default:return TRACE_RETURN (c->default_return_value ()); | 1329 default:return TRACE_RETURN (c->default_return_value ()); |
1346 } | 1330 } |
1347 } | 1331 } |
1348 | 1332 |
1349 inline bool sanitize (hb_sanitize_context_t *c) { | |
1350 TRACE_SANITIZE (this); | |
1351 if (!u.format.sanitize (c)) return TRACE_RETURN (false); | |
1352 switch (u.format) { | |
1353 case 1: return TRACE_RETURN (u.format1.sanitize (c)); | |
1354 default:return TRACE_RETURN (true); | |
1355 } | |
1356 } | |
1357 | |
1358 protected: | 1333 protected: |
1359 union { | 1334 union { |
1360 USHORT format; /* Format identifier */ | 1335 USHORT format; /* Format identifier */ |
1361 MarkMarkPosFormat1 format1; | 1336 MarkMarkPosFormat1 format1; |
1362 } u; | 1337 } u; |
1363 }; | 1338 }; |
1364 | 1339 |
1365 | 1340 |
1366 struct ContextPos : Context {}; | 1341 struct ContextPos : Context {}; |
1367 | 1342 |
(...skipping 24 matching lines...) Expand all Loading... |
1392 MarkMark = 6, | 1367 MarkMark = 6, |
1393 Context = 7, | 1368 Context = 7, |
1394 ChainContext = 8, | 1369 ChainContext = 8, |
1395 Extension = 9 | 1370 Extension = 9 |
1396 }; | 1371 }; |
1397 | 1372 |
1398 template <typename context_t> | 1373 template <typename context_t> |
1399 inline typename context_t::return_t dispatch (context_t *c, unsigned int looku
p_type) const | 1374 inline typename context_t::return_t dispatch (context_t *c, unsigned int looku
p_type) const |
1400 { | 1375 { |
1401 TRACE_DISPATCH (this, lookup_type); | 1376 TRACE_DISPATCH (this, lookup_type); |
| 1377 /* The sub_format passed to may_dispatch is unnecessary but harmless. */ |
| 1378 if (unlikely (!c->may_dispatch (this, &u.sub_format))) TRACE_RETURN (c->defa
ult_return_value ()); |
1402 switch (lookup_type) { | 1379 switch (lookup_type) { |
1403 case Single: return TRACE_RETURN (u.single.dispatch (c)); | 1380 case Single: return TRACE_RETURN (u.single.dispatch (c)); |
1404 case Pair: return TRACE_RETURN (u.pair.dispatch (c)); | 1381 case Pair: return TRACE_RETURN (u.pair.dispatch (c)); |
1405 case Cursive: return TRACE_RETURN (u.cursive.dispatch (c)); | 1382 case Cursive: return TRACE_RETURN (u.cursive.dispatch (c)); |
1406 case MarkBase: return TRACE_RETURN (u.markBase.dispatch (c)); | 1383 case MarkBase: return TRACE_RETURN (u.markBase.dispatch (c)); |
1407 case MarkLig: return TRACE_RETURN (u.markLig.dispatch (c)); | 1384 case MarkLig: return TRACE_RETURN (u.markLig.dispatch (c)); |
1408 case MarkMark: return TRACE_RETURN (u.markMark.dispatch (c)); | 1385 case MarkMark: return TRACE_RETURN (u.markMark.dispatch (c)); |
1409 case Context: return TRACE_RETURN (u.context.dispatch (c)); | 1386 case Context: return TRACE_RETURN (u.context.dispatch (c)); |
1410 case ChainContext: return TRACE_RETURN (u.chainContext.dispatch (c)
); | 1387 case ChainContext: return TRACE_RETURN (u.chainContext.dispatch (c)
); |
1411 case Extension: return TRACE_RETURN (u.extension.dispatch (c)); | 1388 case Extension: return TRACE_RETURN (u.extension.dispatch (c)); |
1412 default: return TRACE_RETURN (c->default_return_value ())
; | 1389 default: return TRACE_RETURN (c->default_return_value ())
; |
1413 } | 1390 } |
1414 } | 1391 } |
1415 | 1392 |
1416 inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) { | |
1417 TRACE_SANITIZE (this); | |
1418 if (!u.header.sub_format.sanitize (c)) | |
1419 return TRACE_RETURN (false); | |
1420 switch (lookup_type) { | |
1421 case Single: return TRACE_RETURN (u.single.sanitize (c)); | |
1422 case Pair: return TRACE_RETURN (u.pair.sanitize (c)); | |
1423 case Cursive: return TRACE_RETURN (u.cursive.sanitize (c)); | |
1424 case MarkBase: return TRACE_RETURN (u.markBase.sanitize (c)); | |
1425 case MarkLig: return TRACE_RETURN (u.markLig.sanitize (c)); | |
1426 case MarkMark: return TRACE_RETURN (u.markMark.sanitize (c)); | |
1427 case Context: return TRACE_RETURN (u.context.sanitize (c)); | |
1428 case ChainContext: return TRACE_RETURN (u.chainContext.sanitize (c)
); | |
1429 case Extension: return TRACE_RETURN (u.extension.sanitize (c)); | |
1430 default: return TRACE_RETURN (true); | |
1431 } | |
1432 } | |
1433 | |
1434 protected: | 1393 protected: |
1435 union { | 1394 union { |
1436 struct { | 1395 USHORT» » sub_format; |
1437 USHORT» » sub_format; | |
1438 } header; | |
1439 SinglePos single; | 1396 SinglePos single; |
1440 PairPos pair; | 1397 PairPos pair; |
1441 CursivePos cursive; | 1398 CursivePos cursive; |
1442 MarkBasePos markBase; | 1399 MarkBasePos markBase; |
1443 MarkLigPos markLig; | 1400 MarkLigPos markLig; |
1444 MarkMarkPos markMark; | 1401 MarkMarkPos markMark; |
1445 ContextPos context; | 1402 ContextPos context; |
1446 ChainContextPos chainContext; | 1403 ChainContextPos chainContext; |
1447 ExtensionPos extension; | 1404 ExtensionPos extension; |
1448 } u; | 1405 } u; |
1449 public: | 1406 public: |
1450 DEFINE_SIZE_UNION (2, header.sub_format); | 1407 DEFINE_SIZE_UNION (2, sub_format); |
1451 }; | 1408 }; |
1452 | 1409 |
1453 | 1410 |
1454 struct PosLookup : Lookup | 1411 struct PosLookup : Lookup |
1455 { | 1412 { |
1456 inline const PosLookupSubTable& get_subtable (unsigned int i) const | 1413 inline const PosLookupSubTable& get_subtable (unsigned int i) const |
1457 { return this+CastR<OffsetArrayOf<PosLookupSubTable> > (subTable)[i]; } | 1414 { return Lookup::get_subtable<PosLookupSubTable> (i); } |
1458 | 1415 |
1459 inline bool is_reverse (void) const | 1416 inline bool is_reverse (void) const |
1460 { | 1417 { |
1461 return false; | 1418 return false; |
1462 } | 1419 } |
1463 | 1420 |
| 1421 inline bool apply (hb_apply_context_t *c) const |
| 1422 { |
| 1423 TRACE_APPLY (this); |
| 1424 return TRACE_RETURN (dispatch (c)); |
| 1425 } |
| 1426 |
1464 inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs
_context_t *c) const | 1427 inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs
_context_t *c) const |
1465 { | 1428 { |
1466 TRACE_COLLECT_GLYPHS (this); | 1429 TRACE_COLLECT_GLYPHS (this); |
1467 c->set_recurse_func (NULL); | |
1468 return TRACE_RETURN (dispatch (c)); | 1430 return TRACE_RETURN (dispatch (c)); |
1469 } | 1431 } |
1470 | 1432 |
1471 template <typename set_t> | 1433 template <typename set_t> |
1472 inline void add_coverage (set_t *glyphs) const | 1434 inline void add_coverage (set_t *glyphs) const |
1473 { | 1435 { |
1474 hb_get_coverage_context_t c; | 1436 hb_add_coverage_context_t<set_t> c (glyphs); |
1475 const Coverage *last = NULL; | 1437 dispatch (&c); |
1476 unsigned int count = get_subtable_count (); | |
1477 for (unsigned int i = 0; i < count; i++) { | |
1478 const Coverage *coverage = &get_subtable (i).dispatch (&c, get_type ()); | |
1479 if (coverage != last) { | |
1480 coverage->add_coverage (glyphs); | |
1481 last = coverage; | |
1482 } | |
1483 } | |
1484 } | |
1485 | |
1486 inline bool apply_once (hb_apply_context_t *c) const | |
1487 { | |
1488 TRACE_APPLY (this); | |
1489 if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props)) | |
1490 return TRACE_RETURN (false); | |
1491 return TRACE_RETURN (dispatch (c)); | |
1492 } | 1438 } |
1493 | 1439 |
1494 static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_ind
ex); | 1440 static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_ind
ex); |
1495 | 1441 |
1496 template <typename context_t> | 1442 template <typename context_t> |
1497 static inline typename context_t::return_t dispatch_recurse_func (context_t *c
, unsigned int lookup_index); | 1443 static inline typename context_t::return_t dispatch_recurse_func (context_t *c
, unsigned int lookup_index); |
1498 | 1444 |
1499 template <typename context_t> | 1445 template <typename context_t> |
1500 inline typename context_t::return_t dispatch (context_t *c) const | 1446 inline typename context_t::return_t dispatch (context_t *c) const |
| 1447 { return Lookup::dispatch<PosLookupSubTable> (c); } |
| 1448 |
| 1449 inline bool sanitize (hb_sanitize_context_t *c) const |
1501 { | 1450 { |
1502 unsigned int lookup_type = get_type (); | |
1503 TRACE_DISPATCH (this, lookup_type); | |
1504 unsigned int count = get_subtable_count (); | |
1505 for (unsigned int i = 0; i < count; i++) { | |
1506 typename context_t::return_t r = get_subtable (i).dispatch (c, lookup_type
); | |
1507 if (c->stop_sublookup_iteration (r)) | |
1508 return TRACE_RETURN (r); | |
1509 } | |
1510 return TRACE_RETURN (c->default_return_value ()); | |
1511 } | |
1512 | |
1513 inline bool sanitize (hb_sanitize_context_t *c) { | |
1514 TRACE_SANITIZE (this); | 1451 TRACE_SANITIZE (this); |
1515 if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false); | 1452 if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false); |
1516 OffsetArrayOf<PosLookupSubTable> &list = CastR<OffsetArrayOf<PosLookupSubTab
le> > (subTable); | 1453 const OffsetArrayOf<PosLookupSubTable> &list = get_subtables<PosLookupSubTab
le> (); |
1517 return TRACE_RETURN (list.sanitize (c, this, get_type ())); | 1454 return TRACE_RETURN (dispatch (c)); |
1518 } | 1455 } |
1519 }; | 1456 }; |
1520 | 1457 |
1521 typedef OffsetListOf<PosLookup> PosLookupList; | 1458 typedef OffsetListOf<PosLookup> PosLookupList; |
1522 | 1459 |
1523 /* | 1460 /* |
1524 * GPOS -- The Glyph Positioning Table | 1461 * GPOS -- The Glyph Positioning Table |
1525 */ | 1462 */ |
1526 | 1463 |
1527 struct GPOS : GSUBGPOS | 1464 struct GPOS : GSUBGPOS |
1528 { | 1465 { |
1529 static const hb_tag_t tableTag = HB_OT_TAG_GPOS; | 1466 static const hb_tag_t tableTag = HB_OT_TAG_GPOS; |
1530 | 1467 |
1531 inline const PosLookup& get_lookup (unsigned int i) const | 1468 inline const PosLookup& get_lookup (unsigned int i) const |
1532 { return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); } | 1469 { return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); } |
1533 | 1470 |
1534 static inline void position_start (hb_font_t *font, hb_buffer_t *buffer); | 1471 static inline void position_start (hb_font_t *font, hb_buffer_t *buffer); |
1535 static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer); | 1472 static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer); |
1536 | 1473 |
1537 inline bool sanitize (hb_sanitize_context_t *c) { | 1474 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1475 { |
1538 TRACE_SANITIZE (this); | 1476 TRACE_SANITIZE (this); |
1539 if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false); | 1477 if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false); |
1540 OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList)
; | 1478 const OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (looku
pList); |
1541 return TRACE_RETURN (list.sanitize (c, this)); | 1479 return TRACE_RETURN (list.sanitize (c, this)); |
1542 } | 1480 } |
1543 public: | 1481 public: |
1544 DEFINE_SIZE_STATIC (10); | 1482 DEFINE_SIZE_STATIC (10); |
1545 }; | 1483 }; |
1546 | 1484 |
1547 | 1485 |
1548 static void | 1486 static void |
1549 fix_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction
_t direction) | 1487 fix_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction
_t direction) |
1550 { | 1488 { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1625 const PosLookup &l = gpos.get_lookup (lookup_index); | 1563 const PosLookup &l = gpos.get_lookup (lookup_index); |
1626 return l.dispatch (c); | 1564 return l.dispatch (c); |
1627 } | 1565 } |
1628 | 1566 |
1629 /*static*/ inline bool PosLookup::apply_recurse_func (hb_apply_context_t *c, uns
igned int lookup_index) | 1567 /*static*/ inline bool PosLookup::apply_recurse_func (hb_apply_context_t *c, uns
igned int lookup_index) |
1630 { | 1568 { |
1631 const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos); | 1569 const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos); |
1632 const PosLookup &l = gpos.get_lookup (lookup_index); | 1570 const PosLookup &l = gpos.get_lookup (lookup_index); |
1633 unsigned int saved_lookup_props = c->lookup_props; | 1571 unsigned int saved_lookup_props = c->lookup_props; |
1634 c->set_lookup (l); | 1572 c->set_lookup (l); |
1635 bool ret = l.apply_once (c); | 1573 bool ret = l.dispatch (c); |
1636 c->lookup_props = saved_lookup_props; | 1574 c->set_lookup_props (saved_lookup_props); |
1637 return ret; | 1575 return ret; |
1638 } | 1576 } |
1639 | 1577 |
1640 | 1578 |
1641 #undef attach_lookback | 1579 #undef attach_lookback |
1642 #undef cursive_chain | 1580 #undef cursive_chain |
1643 | 1581 |
1644 | 1582 |
1645 } /* namespace OT */ | 1583 } /* namespace OT */ |
1646 | 1584 |
1647 | 1585 |
1648 #endif /* HB_OT_LAYOUT_GPOS_TABLE_HH */ | 1586 #endif /* HB_OT_LAYOUT_GPOS_TABLE_HH */ |
OLD | NEW |