| 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 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 Offset yAdvDevice; /* Offset to Device table for vertical | 96 Offset yAdvDevice; /* Offset to Device table for vertical |
| 97 * advance--measured from beginning of | 97 * advance--measured from beginning of |
| 98 * PosTable (may be NULL) */ | 98 * PosTable (may be NULL) */ |
| 99 #endif | 99 #endif |
| 100 | 100 |
| 101 inline unsigned int get_len (void) const | 101 inline unsigned int get_len (void) const |
| 102 { return _hb_popcount32 ((unsigned int) *this); } | 102 { return _hb_popcount32 ((unsigned int) *this); } |
| 103 inline unsigned int get_size (void) const | 103 inline unsigned int get_size (void) const |
| 104 { return get_len () * Value::static_size; } | 104 { return get_len () * Value::static_size; } |
| 105 | 105 |
| 106 void apply_value (hb_font_t *font, | 106 void apply_value (hb_apply_context_t *c, |
| 107 » » hb_direction_t direction, | |
| 108 const void *base, | 107 const void *base, |
| 109 const Value *values, | 108 const Value *values, |
| 110 hb_glyph_position_t &glyph_pos) const | 109 hb_glyph_position_t &glyph_pos) const |
| 111 { | 110 { |
| 112 unsigned int x_ppem, y_ppem; | |
| 113 unsigned int format = *this; | 111 unsigned int format = *this; |
| 114 hb_bool_t horizontal = HB_DIRECTION_IS_HORIZONTAL (direction); | 112 if (!format) return; |
| 115 | 113 |
| 116 if (!format) return; | 114 hb_font_t *font = c->font; |
| 115 hb_bool_t horizontal = HB_DIRECTION_IS_HORIZONTAL (c->direction); |
| 117 | 116 |
| 118 if (format & xPlacement) glyph_pos.x_offset += font->em_scale_x (get_short
(values++)); | 117 if (format & xPlacement) glyph_pos.x_offset += font->em_scale_x (get_short
(values++)); |
| 119 if (format & yPlacement) glyph_pos.y_offset += font->em_scale_y (get_short
(values++)); | 118 if (format & yPlacement) glyph_pos.y_offset += font->em_scale_y (get_short
(values++)); |
| 120 if (format & xAdvance) { | 119 if (format & xAdvance) { |
| 121 if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_shor
t (values)); | 120 if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_shor
t (values)); |
| 122 values++; | 121 values++; |
| 123 } | 122 } |
| 124 /* y_advance values grow downward but font-space grows upward, hence negatio
n */ | 123 /* y_advance values grow downward but font-space grows upward, hence negatio
n */ |
| 125 if (format & yAdvance) { | 124 if (format & yAdvance) { |
| 126 if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_s
hort (values)); | 125 if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_s
hort (values)); |
| 127 values++; | 126 values++; |
| 128 } | 127 } |
| 129 | 128 |
| 130 if (!has_device ()) return; | 129 if (!has_device ()) return; |
| 131 | 130 |
| 132 x_ppem = font->x_ppem; | 131 bool use_x_device = font->x_ppem || font->num_coords; |
| 133 y_ppem = font->y_ppem; | 132 bool use_y_device = font->y_ppem || font->num_coords; |
| 134 | 133 |
| 135 if (!x_ppem && !y_ppem) return; | 134 if (!use_x_device && !use_y_device) return; |
| 135 |
| 136 const VariationStore &store = c->var_store; |
| 136 | 137 |
| 137 /* pixel -> fractional pixel */ | 138 /* pixel -> fractional pixel */ |
| 138 if (format & xPlaDevice) { | 139 if (format & xPlaDevice) { |
| 139 if (x_ppem) glyph_pos.x_offset += (base + get_device (values)).get_x_delt
a (font); | 140 if (use_x_device) glyph_pos.x_offset += (base + get_device (values)).get_
x_delta (font, store); |
| 140 values++; | 141 values++; |
| 141 } | 142 } |
| 142 if (format & yPlaDevice) { | 143 if (format & yPlaDevice) { |
| 143 if (y_ppem) glyph_pos.y_offset += (base + get_device (values)).get_y_delt
a (font); | 144 if (use_y_device) glyph_pos.y_offset += (base + get_device (values)).get_
y_delta (font, store); |
| 144 values++; | 145 values++; |
| 145 } | 146 } |
| 146 if (format & xAdvDevice) { | 147 if (format & xAdvDevice) { |
| 147 if (horizontal && x_ppem) glyph_pos.x_advance += (base + get_device (value
s)).get_x_delta (font); | 148 if (horizontal && use_x_device) glyph_pos.x_advance += (base + get_device
(values)).get_x_delta (font, store); |
| 148 values++; | 149 values++; |
| 149 } | 150 } |
| 150 if (format & yAdvDevice) { | 151 if (format & yAdvDevice) { |
| 151 /* y_advance values grow downward but font-space grows upward, hence negat
ion */ | 152 /* y_advance values grow downward but font-space grows upward, hence negat
ion */ |
| 152 if (!horizontal && y_ppem) glyph_pos.y_advance -= (base + get_device (valu
es)).get_y_delta (font); | 153 if (!horizontal && use_y_device) glyph_pos.y_advance -= (base + get_device
(values)).get_y_delta (font, store); |
| 153 values++; | 154 values++; |
| 154 } | 155 } |
| 155 } | 156 } |
| 156 | 157 |
| 157 private: | 158 private: |
| 158 inline bool sanitize_value_devices (hb_sanitize_context_t *c, const void *base
, const Value *values) const | 159 inline bool sanitize_value_devices (hb_sanitize_context_t *c, const void *base
, const Value *values) const |
| 159 { | 160 { |
| 160 unsigned int format = *this; | 161 unsigned int format = *this; |
| 161 | 162 |
| 162 if (format & xPlacement) values++; | 163 if (format & xPlacement) values++; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 values += stride; | 225 values += stride; |
| 225 } | 226 } |
| 226 | 227 |
| 227 return_trace (true); | 228 return_trace (true); |
| 228 } | 229 } |
| 229 }; | 230 }; |
| 230 | 231 |
| 231 | 232 |
| 232 struct AnchorFormat1 | 233 struct AnchorFormat1 |
| 233 { | 234 { |
| 234 inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED, | 235 inline void get_anchor (hb_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUS
ED, |
| 235 hb_position_t *x, hb_position_t *y) const | 236 hb_position_t *x, hb_position_t *y) const |
| 236 { | 237 { |
| 237 *x = font->em_scale_x (xCoordinate); | 238 hb_font_t *font = c->font; |
| 238 *y = font->em_scale_y (yCoordinate); | 239 *x = font->em_scale_x (xCoordinate); |
| 240 *y = font->em_scale_y (yCoordinate); |
| 239 } | 241 } |
| 240 | 242 |
| 241 inline bool sanitize (hb_sanitize_context_t *c) const | 243 inline bool sanitize (hb_sanitize_context_t *c) const |
| 242 { | 244 { |
| 243 TRACE_SANITIZE (this); | 245 TRACE_SANITIZE (this); |
| 244 return_trace (c->check_struct (this)); | 246 return_trace (c->check_struct (this)); |
| 245 } | 247 } |
| 246 | 248 |
| 247 protected: | 249 protected: |
| 248 USHORT format; /* Format identifier--format = 1 */ | 250 USHORT format; /* Format identifier--format = 1 */ |
| 249 SHORT xCoordinate; /* Horizontal value--in design units */ | 251 SHORT xCoordinate; /* Horizontal value--in design units */ |
| 250 SHORT yCoordinate; /* Vertical value--in design units */ | 252 SHORT yCoordinate; /* Vertical value--in design units */ |
| 251 public: | 253 public: |
| 252 DEFINE_SIZE_STATIC (6); | 254 DEFINE_SIZE_STATIC (6); |
| 253 }; | 255 }; |
| 254 | 256 |
| 255 struct AnchorFormat2 | 257 struct AnchorFormat2 |
| 256 { | 258 { |
| 257 inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id, | 259 inline void get_anchor (hb_apply_context_t *c, hb_codepoint_t glyph_id, |
| 258 hb_position_t *x, hb_position_t *y) const | 260 hb_position_t *x, hb_position_t *y) const |
| 259 { | 261 { |
| 260 unsigned int x_ppem = font->x_ppem; | 262 hb_font_t *font = c->font; |
| 261 unsigned int y_ppem = font->y_ppem; | 263 unsigned int x_ppem = font->x_ppem; |
| 262 hb_position_t cx, cy; | 264 unsigned int y_ppem = font->y_ppem; |
| 263 hb_bool_t ret; | 265 hb_position_t cx, cy; |
| 266 hb_bool_t ret; |
| 264 | 267 |
| 265 ret = (x_ppem || y_ppem) && | 268 ret = (x_ppem || y_ppem) && |
| 266 font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB
_DIRECTION_LTR, &cx, &cy); | 269 » font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB_D
IRECTION_LTR, &cx, &cy); |
| 267 *x = ret && x_ppem ? cx : font->em_scale_x (xCoordinate); | 270 *x = ret && x_ppem ? cx : font->em_scale_x (xCoordinate); |
| 268 *y = ret && y_ppem ? cy : font->em_scale_y (yCoordinate); | 271 *y = ret && y_ppem ? cy : font->em_scale_y (yCoordinate); |
| 269 } | 272 } |
| 270 | 273 |
| 271 inline bool sanitize (hb_sanitize_context_t *c) const | 274 inline bool sanitize (hb_sanitize_context_t *c) const |
| 272 { | 275 { |
| 273 TRACE_SANITIZE (this); | 276 TRACE_SANITIZE (this); |
| 274 return_trace (c->check_struct (this)); | 277 return_trace (c->check_struct (this)); |
| 275 } | 278 } |
| 276 | 279 |
| 277 protected: | 280 protected: |
| 278 USHORT format; /* Format identifier--format = 2 */ | 281 USHORT format; /* Format identifier--format = 2 */ |
| 279 SHORT xCoordinate; /* Horizontal value--in design units */ | 282 SHORT xCoordinate; /* Horizontal value--in design units */ |
| 280 SHORT yCoordinate; /* Vertical value--in design units */ | 283 SHORT yCoordinate; /* Vertical value--in design units */ |
| 281 USHORT anchorPoint; /* Index to glyph contour point */ | 284 USHORT anchorPoint; /* Index to glyph contour point */ |
| 282 public: | 285 public: |
| 283 DEFINE_SIZE_STATIC (8); | 286 DEFINE_SIZE_STATIC (8); |
| 284 }; | 287 }; |
| 285 | 288 |
| 286 struct AnchorFormat3 | 289 struct AnchorFormat3 |
| 287 { | 290 { |
| 288 inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED, | 291 inline void get_anchor (hb_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUS
ED, |
| 289 hb_position_t *x, hb_position_t *y) const | 292 hb_position_t *x, hb_position_t *y) const |
| 290 { | 293 { |
| 291 *x = font->em_scale_x (xCoordinate); | 294 hb_font_t *font = c->font; |
| 292 *y = font->em_scale_y (yCoordinate); | 295 *x = font->em_scale_x (xCoordinate); |
| 296 *y = font->em_scale_y (yCoordinate); |
| 293 | 297 |
| 294 if (font->x_ppem) | 298 if (font->x_ppem || font->num_coords) |
| 295 » *x += (this+xDeviceTable).get_x_delta (font); | 299 *x += (this+xDeviceTable).get_x_delta (font, c->var_store); |
| 296 if (font->y_ppem) | 300 if (font->y_ppem || font->num_coords) |
| 297 » *y += (this+yDeviceTable).get_x_delta (font); | 301 *y += (this+yDeviceTable).get_y_delta (font, c->var_store); |
| 298 } | 302 } |
| 299 | 303 |
| 300 inline bool sanitize (hb_sanitize_context_t *c) const | 304 inline bool sanitize (hb_sanitize_context_t *c) const |
| 301 { | 305 { |
| 302 TRACE_SANITIZE (this); | 306 TRACE_SANITIZE (this); |
| 303 return_trace (c->check_struct (this) && xDeviceTable.sanitize (c, this) && y
DeviceTable.sanitize (c, this)); | 307 return_trace (c->check_struct (this) && xDeviceTable.sanitize (c, this) && y
DeviceTable.sanitize (c, this)); |
| 304 } | 308 } |
| 305 | 309 |
| 306 protected: | 310 protected: |
| 307 USHORT format; /* Format identifier--format = 3 */ | 311 USHORT format; /* Format identifier--format = 3 */ |
| 308 SHORT xCoordinate; /* Horizontal value--in design units */ | 312 SHORT xCoordinate; /* Horizontal value--in design units */ |
| 309 SHORT yCoordinate; /* Vertical value--in design units */ | 313 SHORT yCoordinate; /* Vertical value--in design units */ |
| 310 OffsetTo<Device> | 314 OffsetTo<Device> |
| 311 xDeviceTable; /* Offset to Device table for X | 315 xDeviceTable; /* Offset to Device table for X |
| 312 * coordinate-- from beginning of | 316 * coordinate-- from beginning of |
| 313 * Anchor table (may be NULL) */ | 317 * Anchor table (may be NULL) */ |
| 314 OffsetTo<Device> | 318 OffsetTo<Device> |
| 315 yDeviceTable; /* Offset to Device table for Y | 319 yDeviceTable; /* Offset to Device table for Y |
| 316 * coordinate-- from beginning of | 320 * coordinate-- from beginning of |
| 317 * Anchor table (may be NULL) */ | 321 * Anchor table (may be NULL) */ |
| 318 public: | 322 public: |
| 319 DEFINE_SIZE_STATIC (10); | 323 DEFINE_SIZE_STATIC (10); |
| 320 }; | 324 }; |
| 321 | 325 |
| 322 struct Anchor | 326 struct Anchor |
| 323 { | 327 { |
| 324 inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id, | 328 inline void get_anchor (hb_apply_context_t *c, hb_codepoint_t glyph_id, |
| 325 hb_position_t *x, hb_position_t *y) const | 329 hb_position_t *x, hb_position_t *y) const |
| 326 { | 330 { |
| 327 *x = *y = 0; | 331 *x = *y = 0; |
| 328 switch (u.format) { | 332 switch (u.format) { |
| 329 case 1: u.format1.get_anchor (font, glyph_id, x, y); return; | 333 case 1: u.format1.get_anchor (c, glyph_id, x, y); return; |
| 330 case 2: u.format2.get_anchor (font, glyph_id, x, y); return; | 334 case 2: u.format2.get_anchor (c, glyph_id, x, y); return; |
| 331 case 3: u.format3.get_anchor (font, glyph_id, x, y); return; | 335 case 3: u.format3.get_anchor (c, glyph_id, x, y); return; |
| 332 default: return; | 336 default: return; |
| 333 } | 337 } |
| 334 } | 338 } |
| 335 | 339 |
| 336 inline bool sanitize (hb_sanitize_context_t *c) const | 340 inline bool sanitize (hb_sanitize_context_t *c) const |
| 337 { | 341 { |
| 338 TRACE_SANITIZE (this); | 342 TRACE_SANITIZE (this); |
| 339 if (!u.format.sanitize (c)) return_trace (false); | 343 if (!u.format.sanitize (c)) return_trace (false); |
| 340 switch (u.format) { | 344 switch (u.format) { |
| 341 case 1: return_trace (u.format1.sanitize (c)); | 345 case 1: return_trace (u.format1.sanitize (c)); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 363 *found = false; | 367 *found = false; |
| 364 if (unlikely (row >= rows || col >= cols)) return Null(Anchor); | 368 if (unlikely (row >= rows || col >= cols)) return Null(Anchor); |
| 365 *found = !matrixZ[row * cols + col].is_null (); | 369 *found = !matrixZ[row * cols + col].is_null (); |
| 366 return this+matrixZ[row * cols + col]; | 370 return this+matrixZ[row * cols + col]; |
| 367 } | 371 } |
| 368 | 372 |
| 369 inline bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const | 373 inline bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const |
| 370 { | 374 { |
| 371 TRACE_SANITIZE (this); | 375 TRACE_SANITIZE (this); |
| 372 if (!c->check_struct (this)) return_trace (false); | 376 if (!c->check_struct (this)) return_trace (false); |
| 373 if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return_trace
(false); | 377 if (unlikely (_hb_unsigned_int_mul_overflows (rows, cols))) return_trace (fa
lse); |
| 374 unsigned int count = rows * cols; | 378 unsigned int count = rows * cols; |
| 375 if (!c->check_array (matrixZ, matrixZ[0].static_size, count)) return_trace (
false); | 379 if (!c->check_array (matrixZ, matrixZ[0].static_size, count)) return_trace (
false); |
| 376 for (unsigned int i = 0; i < count; i++) | 380 for (unsigned int i = 0; i < count; i++) |
| 377 if (!matrixZ[i].sanitize (c, this)) return_trace (false); | 381 if (!matrixZ[i].sanitize (c, this)) return_trace (false); |
| 378 return_trace (true); | 382 return_trace (true); |
| 379 } | 383 } |
| 380 | 384 |
| 381 USHORT rows; /* Number of rows */ | 385 USHORT rows; /* Number of rows */ |
| 382 protected: | 386 protected: |
| 383 OffsetTo<Anchor> | 387 OffsetTo<Anchor> |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 | 425 |
| 422 const Anchor& mark_anchor = this + record.markAnchor; | 426 const Anchor& mark_anchor = this + record.markAnchor; |
| 423 bool found; | 427 bool found; |
| 424 const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, cl
ass_count, &found); | 428 const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, cl
ass_count, &found); |
| 425 /* If this subtable doesn't have an anchor for this base and this class, | 429 /* If this subtable doesn't have an anchor for this base and this class, |
| 426 * return false such that the subsequent subtables have a chance at it. */ | 430 * return false such that the subsequent subtables have a chance at it. */ |
| 427 if (unlikely (!found)) return_trace (false); | 431 if (unlikely (!found)) return_trace (false); |
| 428 | 432 |
| 429 hb_position_t mark_x, mark_y, base_x, base_y; | 433 hb_position_t mark_x, mark_y, base_x, base_y; |
| 430 | 434 |
| 431 mark_anchor.get_anchor (c->font, buffer->cur().codepoint, &mark_x, &mark_y); | 435 mark_anchor.get_anchor (c, buffer->cur().codepoint, &mark_x, &mark_y); |
| 432 glyph_anchor.get_anchor (c->font, buffer->info[glyph_pos].codepoint, &base_x
, &base_y); | 436 glyph_anchor.get_anchor (c, buffer->info[glyph_pos].codepoint, &base_x, &bas
e_y); |
| 433 | 437 |
| 434 hb_glyph_position_t &o = buffer->cur_pos(); | 438 hb_glyph_position_t &o = buffer->cur_pos(); |
| 435 o.x_offset = base_x - mark_x; | 439 o.x_offset = base_x - mark_x; |
| 436 o.y_offset = base_y - mark_y; | 440 o.y_offset = base_y - mark_y; |
| 437 o.attach_type() = ATTACH_TYPE_MARK; | 441 o.attach_type() = ATTACH_TYPE_MARK; |
| 438 o.attach_chain() = (int) glyph_pos - (int) buffer->idx; | 442 o.attach_chain() = (int) glyph_pos - (int) buffer->idx; |
| 439 buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; | 443 buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; |
| 440 | 444 |
| 441 buffer->idx++; | 445 buffer->idx++; |
| 442 return_trace (true); | 446 return_trace (true); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 465 return this+coverage; | 469 return this+coverage; |
| 466 } | 470 } |
| 467 | 471 |
| 468 inline bool apply (hb_apply_context_t *c) const | 472 inline bool apply (hb_apply_context_t *c) const |
| 469 { | 473 { |
| 470 TRACE_APPLY (this); | 474 TRACE_APPLY (this); |
| 471 hb_buffer_t *buffer = c->buffer; | 475 hb_buffer_t *buffer = c->buffer; |
| 472 unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint)
; | 476 unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint)
; |
| 473 if (likely (index == NOT_COVERED)) return_trace (false); | 477 if (likely (index == NOT_COVERED)) return_trace (false); |
| 474 | 478 |
| 475 valueFormat.apply_value (c->font, c->direction, this, | 479 valueFormat.apply_value (c, this, values, buffer->cur_pos()); |
| 476 » » » values, buffer->cur_pos()); | |
| 477 | 480 |
| 478 buffer->idx++; | 481 buffer->idx++; |
| 479 return_trace (true); | 482 return_trace (true); |
| 480 } | 483 } |
| 481 | 484 |
| 482 inline bool sanitize (hb_sanitize_context_t *c) const | 485 inline bool sanitize (hb_sanitize_context_t *c) const |
| 483 { | 486 { |
| 484 TRACE_SANITIZE (this); | 487 TRACE_SANITIZE (this); |
| 485 return_trace (c->check_struct (this) && | 488 return_trace (c->check_struct (this) && |
| 486 coverage.sanitize (c, this) && | 489 coverage.sanitize (c, this) && |
| (...skipping 29 matching lines...) Expand all Loading... |
| 516 | 519 |
| 517 inline bool apply (hb_apply_context_t *c) const | 520 inline bool apply (hb_apply_context_t *c) const |
| 518 { | 521 { |
| 519 TRACE_APPLY (this); | 522 TRACE_APPLY (this); |
| 520 hb_buffer_t *buffer = c->buffer; | 523 hb_buffer_t *buffer = c->buffer; |
| 521 unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint)
; | 524 unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint)
; |
| 522 if (likely (index == NOT_COVERED)) return_trace (false); | 525 if (likely (index == NOT_COVERED)) return_trace (false); |
| 523 | 526 |
| 524 if (likely (index >= valueCount)) return_trace (false); | 527 if (likely (index >= valueCount)) return_trace (false); |
| 525 | 528 |
| 526 valueFormat.apply_value (c->font, c->direction, this, | 529 valueFormat.apply_value (c, this, |
| 527 &values[index * valueFormat.get_len ()], | 530 &values[index * valueFormat.get_len ()], |
| 528 buffer->cur_pos()); | 531 buffer->cur_pos()); |
| 529 | 532 |
| 530 buffer->idx++; | 533 buffer->idx++; |
| 531 return_trace (true); | 534 return_trace (true); |
| 532 } | 535 } |
| 533 | 536 |
| 534 inline bool sanitize (hb_sanitize_context_t *c) const | 537 inline bool sanitize (hb_sanitize_context_t *c) const |
| 535 { | 538 { |
| 536 TRACE_SANITIZE (this); | 539 TRACE_SANITIZE (this); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 633 { | 636 { |
| 634 int mid = (min + max) / 2; | 637 int mid = (min + max) / 2; |
| 635 const PairValueRecord *record = &StructAtOffset<PairValueRecord> (record_a
rray, record_size * mid); | 638 const PairValueRecord *record = &StructAtOffset<PairValueRecord> (record_a
rray, record_size * mid); |
| 636 hb_codepoint_t mid_x = record->secondGlyph; | 639 hb_codepoint_t mid_x = record->secondGlyph; |
| 637 if (x < mid_x) | 640 if (x < mid_x) |
| 638 max = mid - 1; | 641 max = mid - 1; |
| 639 else if (x > mid_x) | 642 else if (x > mid_x) |
| 640 min = mid + 1; | 643 min = mid + 1; |
| 641 else | 644 else |
| 642 { | 645 { |
| 643 » valueFormats[0].apply_value (c->font, c->direction, this, | 646 » valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_po
s()); |
| 644 » » » » &record->values[0], buffer->cur_pos()); | 647 » valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos
[pos]); |
| 645 » valueFormats[1].apply_value (c->font, c->direction, this, | |
| 646 » » » » &record->values[len1], buffer->pos[pos]); | |
| 647 if (len2) | 648 if (len2) |
| 648 pos++; | 649 pos++; |
| 649 buffer->idx = pos; | 650 buffer->idx = pos; |
| 650 return_trace (true); | 651 return_trace (true); |
| 651 } | 652 } |
| 652 } | 653 } |
| 653 | 654 |
| 654 return_trace (false); | 655 return_trace (false); |
| 655 } | 656 } |
| 656 | 657 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 682 }; | 683 }; |
| 683 | 684 |
| 684 struct PairPosFormat1 | 685 struct PairPosFormat1 |
| 685 { | 686 { |
| 686 inline void collect_glyphs (hb_collect_glyphs_context_t *c) const | 687 inline void collect_glyphs (hb_collect_glyphs_context_t *c) const |
| 687 { | 688 { |
| 688 TRACE_COLLECT_GLYPHS (this); | 689 TRACE_COLLECT_GLYPHS (this); |
| 689 (this+coverage).add_coverage (c->input); | 690 (this+coverage).add_coverage (c->input); |
| 690 unsigned int count = pairSet.len; | 691 unsigned int count = pairSet.len; |
| 691 for (unsigned int i = 0; i < count; i++) | 692 for (unsigned int i = 0; i < count; i++) |
| 692 (this+pairSet[i]).collect_glyphs (c, &valueFormat1); | 693 (this+pairSet[i]).collect_glyphs (c, valueFormat); |
| 693 } | 694 } |
| 694 | 695 |
| 695 inline const Coverage &get_coverage (void) const | 696 inline const Coverage &get_coverage (void) const |
| 696 { | 697 { |
| 697 return this+coverage; | 698 return this+coverage; |
| 698 } | 699 } |
| 699 | 700 |
| 700 inline bool apply (hb_apply_context_t *c) const | 701 inline bool apply (hb_apply_context_t *c) const |
| 701 { | 702 { |
| 702 TRACE_APPLY (this); | 703 TRACE_APPLY (this); |
| 703 hb_buffer_t *buffer = c->buffer; | 704 hb_buffer_t *buffer = c->buffer; |
| 704 unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint)
; | 705 unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint)
; |
| 705 if (likely (index == NOT_COVERED)) return_trace (false); | 706 if (likely (index == NOT_COVERED)) return_trace (false); |
| 706 | 707 |
| 707 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; | 708 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; |
| 708 skippy_iter.reset (buffer->idx, 1); | 709 skippy_iter.reset (buffer->idx, 1); |
| 709 if (!skippy_iter.next ()) return_trace (false); | 710 if (!skippy_iter.next ()) return_trace (false); |
| 710 | 711 |
| 711 return_trace ((this+pairSet[index]).apply (c, &valueFormat1, skippy_iter.idx
)); | 712 return_trace ((this+pairSet[index]).apply (c, valueFormat, skippy_iter.idx))
; |
| 712 } | 713 } |
| 713 | 714 |
| 714 inline bool sanitize (hb_sanitize_context_t *c) const | 715 inline bool sanitize (hb_sanitize_context_t *c) const |
| 715 { | 716 { |
| 716 TRACE_SANITIZE (this); | 717 TRACE_SANITIZE (this); |
| 717 | 718 |
| 718 if (!c->check_struct (this)) return_trace (false); | 719 if (!c->check_struct (this)) return_trace (false); |
| 719 | 720 |
| 720 unsigned int len1 = valueFormat1.get_len (); | 721 unsigned int len1 = valueFormat[0].get_len (); |
| 721 unsigned int len2 = valueFormat2.get_len (); | 722 unsigned int len2 = valueFormat[1].get_len (); |
| 722 PairSet::sanitize_closure_t closure = { | 723 PairSet::sanitize_closure_t closure = { |
| 723 this, | 724 this, |
| 724 &valueFormat1, | 725 valueFormat, |
| 725 len1, | 726 len1, |
| 726 1 + len1 + len2 | 727 1 + len1 + len2 |
| 727 }; | 728 }; |
| 728 | 729 |
| 729 return_trace (coverage.sanitize (c, this) && pairSet.sanitize (c, this, &clo
sure)); | 730 return_trace (coverage.sanitize (c, this) && pairSet.sanitize (c, this, &clo
sure)); |
| 730 } | 731 } |
| 731 | 732 |
| 732 protected: | 733 protected: |
| 733 USHORT format; /* Format identifier--format = 1 */ | 734 USHORT format; /* Format identifier--format = 1 */ |
| 734 OffsetTo<Coverage> | 735 OffsetTo<Coverage> |
| 735 coverage; /* Offset to Coverage table--from | 736 coverage; /* Offset to Coverage table--from |
| 736 * beginning of subtable */ | 737 * beginning of subtable */ |
| 737 ValueFormat» valueFormat1;» » /* Defines the types of data in | 738 ValueFormat» valueFormat[2];»» /* [0] Defines the types of data in |
| 738 * ValueRecord1--for the first glyph | 739 * ValueRecord1--for the first glyph |
| 739 * in the pair--may be zero (0) */ | 740 * in the pair--may be zero (0) */ |
| 740 ValueFormat» valueFormat2;» » /* Defines the types of data in | 741 » » » » » /* [1] Defines the types of data in |
| 741 * ValueRecord2--for the second glyph | 742 * ValueRecord2--for the second glyph |
| 742 * in the pair--may be zero (0) */ | 743 * in the pair--may be zero (0) */ |
| 743 OffsetArrayOf<PairSet> | 744 OffsetArrayOf<PairSet> |
| 744 pairSet; /* Array of PairSet tables | 745 pairSet; /* Array of PairSet tables |
| 745 * ordered by Coverage Index */ | 746 * ordered by Coverage Index */ |
| 746 public: | 747 public: |
| 747 DEFINE_SIZE_ARRAY (10, pairSet); | 748 DEFINE_SIZE_ARRAY (10, pairSet); |
| 748 }; | 749 }; |
| 749 | 750 |
| 750 struct PairPosFormat2 | 751 struct PairPosFormat2 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 783 | 784 |
| 784 unsigned int len1 = valueFormat1.get_len (); | 785 unsigned int len1 = valueFormat1.get_len (); |
| 785 unsigned int len2 = valueFormat2.get_len (); | 786 unsigned int len2 = valueFormat2.get_len (); |
| 786 unsigned int record_len = len1 + len2; | 787 unsigned int record_len = len1 + len2; |
| 787 | 788 |
| 788 unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint); | 789 unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint); |
| 789 unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.i
dx].codepoint); | 790 unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.i
dx].codepoint); |
| 790 if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return_trace
(false); | 791 if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return_trace
(false); |
| 791 | 792 |
| 792 const Value *v = &values[record_len * (klass1 * class2Count + klass2)]; | 793 const Value *v = &values[record_len * (klass1 * class2Count + klass2)]; |
| 793 valueFormat1.apply_value (c->font, c->direction, this, | 794 valueFormat1.apply_value (c, this, v, buffer->cur_pos()); |
| 794 » » » v, buffer->cur_pos()); | 795 valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]); |
| 795 valueFormat2.apply_value (c->font, c->direction, this, | |
| 796 » » » v + len1, buffer->pos[skippy_iter.idx]); | |
| 797 | 796 |
| 798 buffer->idx = skippy_iter.idx; | 797 buffer->idx = skippy_iter.idx; |
| 799 if (len2) | 798 if (len2) |
| 800 buffer->idx++; | 799 buffer->idx++; |
| 801 | 800 |
| 802 return_trace (true); | 801 return_trace (true); |
| 803 } | 802 } |
| 804 | 803 |
| 805 inline bool sanitize (hb_sanitize_context_t *c) const | 804 inline bool sanitize (hb_sanitize_context_t *c) const |
| 806 { | 805 { |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 924 skippy_iter.reset (buffer->idx, 1); | 923 skippy_iter.reset (buffer->idx, 1); |
| 925 if (!skippy_iter.next ()) return_trace (false); | 924 if (!skippy_iter.next ()) return_trace (false); |
| 926 | 925 |
| 927 const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_cov
erage (buffer->info[skippy_iter.idx].codepoint)]; | 926 const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_cov
erage (buffer->info[skippy_iter.idx].codepoint)]; |
| 928 if (!next_record.entryAnchor) return_trace (false); | 927 if (!next_record.entryAnchor) return_trace (false); |
| 929 | 928 |
| 930 unsigned int i = buffer->idx; | 929 unsigned int i = buffer->idx; |
| 931 unsigned int j = skippy_iter.idx; | 930 unsigned int j = skippy_iter.idx; |
| 932 | 931 |
| 933 hb_position_t entry_x, entry_y, exit_x, exit_y; | 932 hb_position_t entry_x, entry_y, exit_x, exit_y; |
| 934 (this+this_record.exitAnchor).get_anchor (c->font, buffer->info[i].codepoint
, &exit_x, &exit_y); | 933 (this+this_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exi
t_x, &exit_y); |
| 935 (this+next_record.entryAnchor).get_anchor (c->font, buffer->info[j].codepoin
t, &entry_x, &entry_y); | 934 (this+next_record.entryAnchor).get_anchor (c, buffer->info[j].codepoint, &en
try_x, &entry_y); |
| 936 | 935 |
| 937 hb_glyph_position_t *pos = buffer->pos; | 936 hb_glyph_position_t *pos = buffer->pos; |
| 938 | 937 |
| 939 hb_position_t d; | 938 hb_position_t d; |
| 940 /* Main-direction adjustment */ | 939 /* Main-direction adjustment */ |
| 941 switch (c->direction) { | 940 switch (c->direction) { |
| 942 case HB_DIRECTION_LTR: | 941 case HB_DIRECTION_LTR: |
| 943 pos[i].x_advance = exit_x + pos[i].x_offset; | 942 pos[i].x_advance = exit_x + pos[i].x_offset; |
| 944 | 943 |
| 945 d = entry_x + pos[j].x_offset; | 944 d = entry_x + pos[j].x_offset; |
| (...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1512 static inline void position_finish_advances (hb_font_t *font, hb_buffer_t *buf
fer); | 1511 static inline void position_finish_advances (hb_font_t *font, hb_buffer_t *buf
fer); |
| 1513 static inline void position_finish_offsets (hb_font_t *font, hb_buffer_t *buff
er); | 1512 static inline void position_finish_offsets (hb_font_t *font, hb_buffer_t *buff
er); |
| 1514 | 1513 |
| 1515 inline bool sanitize (hb_sanitize_context_t *c) const | 1514 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1516 { | 1515 { |
| 1517 TRACE_SANITIZE (this); | 1516 TRACE_SANITIZE (this); |
| 1518 if (unlikely (!GSUBGPOS::sanitize (c))) return_trace (false); | 1517 if (unlikely (!GSUBGPOS::sanitize (c))) return_trace (false); |
| 1519 const OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (looku
pList); | 1518 const OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (looku
pList); |
| 1520 return_trace (list.sanitize (c, this)); | 1519 return_trace (list.sanitize (c, this)); |
| 1521 } | 1520 } |
| 1522 public: | |
| 1523 DEFINE_SIZE_STATIC (10); | |
| 1524 }; | 1521 }; |
| 1525 | 1522 |
| 1526 | 1523 |
| 1527 static void | 1524 static void |
| 1528 reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direc
tion_t direction, unsigned int new_parent) | 1525 reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direc
tion_t direction, unsigned int new_parent) |
| 1529 { | 1526 { |
| 1530 int chain = pos[i].attach_chain(), type = pos[i].attach_type(); | 1527 int chain = pos[i].attach_chain(), type = pos[i].attach_type(); |
| 1531 if (likely (!chain || 0 == (type & ATTACH_TYPE_CURSIVE))) | 1528 if (likely (!chain || 0 == (type & ATTACH_TYPE_CURSIVE))) |
| 1532 return; | 1529 return; |
| 1533 | 1530 |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1648 | 1645 |
| 1649 | 1646 |
| 1650 #undef attach_chain | 1647 #undef attach_chain |
| 1651 #undef attach_type | 1648 #undef attach_type |
| 1652 | 1649 |
| 1653 | 1650 |
| 1654 } /* namespace OT */ | 1651 } /* namespace OT */ |
| 1655 | 1652 |
| 1656 | 1653 |
| 1657 #endif /* HB_OT_LAYOUT_GPOS_TABLE_HH */ | 1654 #endif /* HB_OT_LAYOUT_GPOS_TABLE_HH */ |
| OLD | NEW |