| 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 |