... |
... |
@@ -320,13 +320,11 @@ |
320
|
320
|
|
321
|
321
|
|
322
|
322
|
static FT_Bool
|
323
|
|
- read_color_line( FT_Byte* paint_base,
|
324
|
|
- FT_ULong colorline_offset,
|
|
323
|
+ read_color_line( FT_Byte* color_line_p,
|
325
|
324
|
FT_ColorLine *colorline )
|
326
|
325
|
{
|
327
|
|
- FT_Byte* p = (FT_Byte *)( paint_base + colorline_offset );
|
|
326
|
+ FT_Byte* p = color_line_p;
|
328
|
327
|
FT_PaintExtend paint_extend;
|
329
|
|
- /* TODO: Check pointer limits. */
|
330
|
328
|
|
331
|
329
|
|
332
|
330
|
paint_extend = FT_NEXT_BYTE( p );
|
... |
... |
@@ -343,14 +341,53 @@ |
343
|
341
|
}
|
344
|
342
|
|
345
|
343
|
|
|
344
|
+ /*
|
|
345
|
+ * Read a paint offset for `FT_Paint*` objects that have them and check
|
|
346
|
+ * whether it is within reasonable limits within the font and the COLR
|
|
347
|
+ * table.
|
|
348
|
+ *
|
|
349
|
+ * Return 1 on success, 0 on failure.
|
|
350
|
+ */
|
|
351
|
+ static FT_Bool
|
|
352
|
+ get_child_table_pointer ( Colr* colr,
|
|
353
|
+ FT_Byte* paint_base,
|
|
354
|
+ FT_Byte** p,
|
|
355
|
+ FT_Byte** child_table_pointer )
|
|
356
|
+ {
|
|
357
|
+ FT_UInt32 paint_offset;
|
|
358
|
+ FT_Byte* child_table_p;
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+ if ( !child_table_pointer )
|
|
362
|
+ return 0;
|
|
363
|
+
|
|
364
|
+ paint_offset = FT_NEXT_UOFF3( *p );
|
|
365
|
+ if ( !paint_offset )
|
|
366
|
+ return 0;
|
|
367
|
+
|
|
368
|
+ child_table_p = (FT_Byte*)( paint_base + paint_offset );
|
|
369
|
+
|
|
370
|
+ if ( child_table_p < colr->base_glyphs_v1 ||
|
|
371
|
+ child_table_p >= ( (FT_Byte*)colr->table + colr->table_size ) )
|
|
372
|
+ return 0;
|
|
373
|
+
|
|
374
|
+ *child_table_pointer = child_table_p;
|
|
375
|
+ return 1;
|
|
376
|
+ }
|
|
377
|
+
|
|
378
|
+
|
346
|
379
|
static FT_Bool
|
347
|
380
|
read_paint( Colr* colr,
|
348
|
381
|
FT_Byte* p,
|
349
|
382
|
FT_COLR_Paint* apaint )
|
350
|
383
|
{
|
351
|
|
- FT_Byte* paint_base = p;
|
|
384
|
+ FT_Byte* paint_base = p;
|
|
385
|
+ FT_Byte* child_table_p = NULL;
|
352
|
386
|
|
353
|
387
|
|
|
388
|
+ if ( !p || !colr || !colr->table )
|
|
389
|
+ return 0;
|
|
390
|
+
|
354
|
391
|
apaint->format = FT_NEXT_BYTE( p );
|
355
|
392
|
|
356
|
393
|
if ( apaint->format >= FT_COLR_PAINT_FORMAT_MAX )
|
... |
... |
@@ -382,38 +419,34 @@ |
382
|
419
|
return 1;
|
383
|
420
|
}
|
384
|
421
|
|
385
|
|
- if ( apaint->format == FT_COLR_PAINTFORMAT_GLYPH )
|
386
|
|
- {
|
387
|
|
- FT_UInt32 paint_offset;
|
388
|
|
- FT_Byte* paint_p;
|
389
|
|
-
|
390
|
|
-
|
391
|
|
- paint_offset = FT_NEXT_UOFF3( p );
|
392
|
|
- if ( !paint_offset )
|
393
|
|
- return 0;
|
394
|
|
-
|
395
|
|
- paint_p = (FT_Byte*)( paint_base + paint_offset );
|
396
|
|
- if ( paint_p > ( (FT_Byte*)colr->table + colr->table_size ) )
|
397
|
|
- return 0;
|
398
|
|
-
|
399
|
|
- apaint->u.glyph.paint.p = paint_p;
|
400
|
|
- apaint->u.glyph.paint.insert_root_transform = 0;
|
401
|
|
- apaint->u.glyph.glyphID = FT_NEXT_USHORT( p );
|
402
|
|
- }
|
403
|
|
-
|
404
|
422
|
else if ( apaint->format == FT_COLR_PAINTFORMAT_SOLID )
|
405
|
423
|
{
|
406
|
424
|
apaint->u.solid.color.palette_index = FT_NEXT_USHORT ( p );
|
407
|
425
|
apaint->u.solid.color.alpha = FT_NEXT_USHORT ( p );
|
|
426
|
+
|
|
427
|
+ return 1;
|
408
|
428
|
}
|
409
|
429
|
|
410
|
|
- else if ( apaint->format == FT_COLR_PAINTFORMAT_LINEAR_GRADIENT )
|
|
430
|
+ else if ( apaint->format == FT_COLR_PAINTFORMAT_COLR_GLYPH )
|
411
|
431
|
{
|
412
|
|
- FT_ULong color_line_offset = FT_NEXT_OFF3( p );
|
|
432
|
+ apaint->u.colr_glyph.glyphID = FT_NEXT_USHORT( p );
|
|
433
|
+
|
|
434
|
+ return 1;
|
|
435
|
+ }
|
|
436
|
+
|
|
437
|
+ /*
|
|
438
|
+ * Grouped below here are all paint formats that have an offset to a
|
|
439
|
+ * child paint table as the first entry (for example, a color line or a
|
|
440
|
+ * child paint table). Retrieve that and determine whether that paint
|
|
441
|
+ * offset is valid first.
|
|
442
|
+ */
|
413
|
443
|
|
|
444
|
+ if ( !get_child_table_pointer( colr, paint_base, &p, &child_table_p ) )
|
|
445
|
+ return 0;
|
414
|
446
|
|
415
|
|
- if ( !read_color_line( paint_base,
|
416
|
|
- color_line_offset,
|
|
447
|
+ if ( apaint->format == FT_COLR_PAINTFORMAT_LINEAR_GRADIENT )
|
|
448
|
+ {
|
|
449
|
+ if ( !read_color_line( child_table_p,
|
417
|
450
|
&apaint->u.linear_gradient.colorline ) )
|
418
|
451
|
return 0;
|
419
|
452
|
|
... |
... |
@@ -423,15 +456,13 @@ |
423
|
456
|
apaint->u.linear_gradient.p1.y = FT_NEXT_SHORT ( p );
|
424
|
457
|
apaint->u.linear_gradient.p2.x = FT_NEXT_SHORT ( p );
|
425
|
458
|
apaint->u.linear_gradient.p2.y = FT_NEXT_SHORT ( p );
|
|
459
|
+
|
|
460
|
+ return 1;
|
426
|
461
|
}
|
427
|
462
|
|
428
|
463
|
else if ( apaint->format == FT_COLR_PAINTFORMAT_RADIAL_GRADIENT )
|
429
|
464
|
{
|
430
|
|
- FT_ULong color_line_offset = color_line_offset = FT_NEXT_OFF3( p );
|
431
|
|
-
|
432
|
|
-
|
433
|
|
- if ( !read_color_line( paint_base,
|
434
|
|
- color_line_offset,
|
|
465
|
+ if ( !read_color_line( child_table_p,
|
435
|
466
|
&apaint->u.radial_gradient.colorline ) )
|
436
|
467
|
return 0;
|
437
|
468
|
|
... |
... |
@@ -444,15 +475,13 @@ |
444
|
475
|
apaint->u.radial_gradient.c1.y = FT_NEXT_SHORT ( p );
|
445
|
476
|
|
446
|
477
|
apaint->u.radial_gradient.r1 = FT_NEXT_USHORT ( p );
|
|
478
|
+
|
|
479
|
+ return 1;
|
447
|
480
|
}
|
448
|
481
|
|
449
|
482
|
else if ( apaint->format == FT_COLR_PAINTFORMAT_SWEEP_GRADIENT )
|
450
|
483
|
{
|
451
|
|
- FT_ULong color_line_offset = color_line_offset = FT_NEXT_OFF3( p );
|
452
|
|
-
|
453
|
|
-
|
454
|
|
- if ( !read_color_line( paint_base,
|
455
|
|
- color_line_offset,
|
|
484
|
+ if ( !read_color_line( child_table_p,
|
456
|
485
|
&apaint->u.sweep_gradient.colorline ) )
|
457
|
486
|
return 0;
|
458
|
487
|
|
... |
... |
@@ -461,23 +490,22 @@ |
461
|
490
|
|
462
|
491
|
apaint->u.sweep_gradient.start_angle = FT_NEXT_LONG( p );
|
463
|
492
|
apaint->u.sweep_gradient.end_angle = FT_NEXT_LONG( p );
|
|
493
|
+
|
|
494
|
+ return 1;
|
464
|
495
|
}
|
465
|
496
|
|
466
|
|
- else if ( apaint->format == FT_COLR_PAINTFORMAT_TRANSFORMED )
|
|
497
|
+ if ( apaint->format == FT_COLR_PAINTFORMAT_GLYPH )
|
467
|
498
|
{
|
468
|
|
- FT_UInt32 paint_offset;
|
469
|
|
- FT_Byte* paint_p;
|
470
|
|
-
|
471
|
|
-
|
472
|
|
- paint_offset = FT_NEXT_UOFF3( p );
|
473
|
|
- if ( !paint_offset )
|
474
|
|
- return 0;
|
|
499
|
+ apaint->u.glyph.paint.p = child_table_p;
|
|
500
|
+ apaint->u.glyph.paint.insert_root_transform = 0;
|
|
501
|
+ apaint->u.glyph.glyphID = FT_NEXT_USHORT( p );
|
475
|
502
|
|
476
|
|
- paint_p = (FT_Byte*)( paint_base + paint_offset );
|
477
|
|
- if ( paint_p > ( (FT_Byte*)colr->table + colr->table_size ) )
|
478
|
|
- return 0;
|
|
503
|
+ return 1;
|
|
504
|
+ }
|
479
|
505
|
|
480
|
|
- apaint->u.transformed.paint.p = paint_p;
|
|
506
|
+ else if ( apaint->format == FT_COLR_PAINTFORMAT_TRANSFORMED )
|
|
507
|
+ {
|
|
508
|
+ apaint->u.transformed.paint.p = child_table_p;
|
481
|
509
|
apaint->u.transformed.paint.insert_root_transform = 0;
|
482
|
510
|
|
483
|
511
|
apaint->u.transformed.affine.xx = FT_NEXT_LONG( p );
|
... |
... |
@@ -486,67 +514,37 @@ |
486
|
514
|
apaint->u.transformed.affine.yy = FT_NEXT_LONG( p );
|
487
|
515
|
apaint->u.transformed.affine.dx = FT_NEXT_LONG( p );
|
488
|
516
|
apaint->u.transformed.affine.dy = FT_NEXT_LONG( p );
|
|
517
|
+
|
|
518
|
+ return 1;
|
489
|
519
|
}
|
490
|
520
|
|
491
|
521
|
else if ( apaint->format == FT_COLR_PAINTFORMAT_TRANSLATE )
|
492
|
522
|
{
|
493
|
|
- FT_UInt32 paint_offset;
|
494
|
|
- FT_Byte* paint_p;
|
495
|
|
-
|
496
|
|
-
|
497
|
|
- paint_offset = FT_NEXT_UOFF3( p );
|
498
|
|
- if ( !paint_offset )
|
499
|
|
- return 0;
|
500
|
|
-
|
501
|
|
- paint_p = (FT_Byte*)( paint_base + paint_offset );
|
502
|
|
- if ( paint_p > ( (FT_Byte*)colr->table + colr->table_size ) )
|
503
|
|
- return 0;
|
504
|
|
-
|
505
|
|
- apaint->u.translate.paint.p = paint_p;
|
|
523
|
+ apaint->u.translate.paint.p = child_table_p;
|
506
|
524
|
apaint->u.translate.paint.insert_root_transform = 0;
|
507
|
525
|
|
508
|
526
|
apaint->u.translate.dx = FT_NEXT_LONG( p );
|
509
|
527
|
apaint->u.translate.dy = FT_NEXT_LONG( p );
|
|
528
|
+
|
|
529
|
+ return 1;
|
510
|
530
|
}
|
511
|
531
|
|
512
|
532
|
else if ( apaint->format == FT_COLR_PAINTFORMAT_ROTATE )
|
513
|
533
|
{
|
514
|
|
- FT_UInt32 paint_offset;
|
515
|
|
- FT_Byte* paint_p;
|
516
|
|
-
|
517
|
|
-
|
518
|
|
- paint_offset = FT_NEXT_UOFF3( p );
|
519
|
|
- if ( !paint_offset )
|
520
|
|
- return 0;
|
521
|
|
-
|
522
|
|
- paint_p = (FT_Byte*)( paint_base + paint_offset );
|
523
|
|
- if ( paint_p > ( (FT_Byte*)colr->table + colr->table_size ) )
|
524
|
|
- return 0;
|
525
|
|
-
|
526
|
|
- apaint->u.rotate.paint.p = paint_p;
|
|
534
|
+ apaint->u.rotate.paint.p = child_table_p;
|
527
|
535
|
apaint->u.rotate.paint.insert_root_transform = 0;
|
528
|
536
|
|
529
|
537
|
apaint->u.rotate.angle = FT_NEXT_LONG( p );
|
530
|
538
|
|
531
|
539
|
apaint->u.rotate.center_x = FT_NEXT_LONG( p );
|
532
|
540
|
apaint->u.rotate.center_y = FT_NEXT_LONG( p );
|
|
541
|
+
|
|
542
|
+ return 1;
|
533
|
543
|
}
|
534
|
544
|
|
535
|
545
|
else if ( apaint->format == FT_COLR_PAINTFORMAT_SKEW )
|
536
|
546
|
{
|
537
|
|
- FT_UInt32 paint_offset;
|
538
|
|
- FT_Byte* paint_p;
|
539
|
|
-
|
540
|
|
-
|
541
|
|
- paint_offset = FT_NEXT_UOFF3( p );
|
542
|
|
- if ( !paint_offset )
|
543
|
|
- return 0;
|
544
|
|
-
|
545
|
|
- paint_p = (FT_Byte*)( paint_base + paint_offset );
|
546
|
|
- if ( paint_p > ( (FT_Byte*)colr->table + colr->table_size ) )
|
547
|
|
- return 0;
|
548
|
|
-
|
549
|
|
- apaint->u.skew.paint.p = paint_p;
|
|
547
|
+ apaint->u.skew.paint.p = child_table_p;
|
550
|
548
|
apaint->u.skew.paint.insert_root_transform = 0;
|
551
|
549
|
|
552
|
550
|
apaint->u.skew.x_skew_angle = FT_NEXT_LONG( p );
|
... |
... |
@@ -554,31 +552,17 @@ |
554
|
552
|
|
555
|
553
|
apaint->u.skew.center_x = FT_NEXT_LONG( p );
|
556
|
554
|
apaint->u.skew.center_y = FT_NEXT_LONG( p );
|
|
555
|
+
|
|
556
|
+ return 1;
|
557
|
557
|
}
|
558
|
558
|
|
559
|
559
|
else if ( apaint->format == FT_COLR_PAINTFORMAT_COMPOSITE )
|
560
|
560
|
{
|
561
|
|
- FT_UInt32 source_paint_offset;
|
562
|
|
- FT_Byte* source_paint_p;
|
563
|
|
-
|
564
|
|
- FT_UInt32 backdrop_paint_offset;
|
565
|
|
- FT_Byte* backdrop_paint_p;
|
|
561
|
+ FT_UInt composite_mode;
|
566
|
562
|
|
567
|
|
- FT_UInt composite_mode;
|
568
|
563
|
|
569
|
|
-
|
570
|
|
- source_paint_offset = FT_NEXT_UOFF3( p );
|
571
|
|
- if ( !source_paint_offset )
|
572
|
|
- return 0;
|
573
|
|
-
|
574
|
|
- source_paint_p = (FT_Byte*)( paint_base + source_paint_offset );
|
575
|
|
- if ( source_paint_p > ( (FT_Byte*)colr->table + colr->table_size ) )
|
576
|
|
- return 0;
|
577
|
|
-
|
578
|
|
- apaint->u.composite.source_paint.p =
|
579
|
|
- source_paint_p;
|
580
|
|
- apaint->u.composite.source_paint.insert_root_transform =
|
581
|
|
- 0;
|
|
564
|
+ apaint->u.composite.source_paint.p = child_table_p;
|
|
565
|
+ apaint->u.composite.source_paint.insert_root_transform = 0;
|
582
|
566
|
|
583
|
567
|
composite_mode = FT_NEXT_BYTE( p );
|
584
|
568
|
if ( composite_mode >= FT_COLR_COMPOSITE_MAX )
|
... |
... |
@@ -586,24 +570,18 @@ |
586
|
570
|
|
587
|
571
|
apaint->u.composite.composite_mode = composite_mode;
|
588
|
572
|
|
589
|
|
- backdrop_paint_offset = FT_NEXT_UOFF3( p );
|
590
|
|
- if ( !backdrop_paint_offset )
|
591
|
|
- return 0;
|
592
|
|
-
|
593
|
|
- backdrop_paint_p = (FT_Byte*)( paint_base + backdrop_paint_offset );
|
594
|
|
- if ( backdrop_paint_p > ( (FT_Byte*)colr->table + colr->table_size ) )
|
595
|
|
- return 0;
|
|
573
|
+ if ( !get_child_table_pointer( colr, paint_base, &p, &child_table_p ) )
|
|
574
|
+ return 0;
|
596
|
575
|
|
597
|
576
|
apaint->u.composite.backdrop_paint.p =
|
598
|
|
- backdrop_paint_p;
|
|
577
|
+ child_table_p;
|
599
|
578
|
apaint->u.composite.backdrop_paint.insert_root_transform =
|
600
|
579
|
0;
|
601
|
|
- }
|
602
|
580
|
|
603
|
|
- else if ( apaint->format == FT_COLR_PAINTFORMAT_COLR_GLYPH )
|
604
|
|
- apaint->u.colr_glyph.glyphID = FT_NEXT_USHORT( p );
|
|
581
|
+ return 1;
|
|
582
|
+ }
|
605
|
583
|
|
606
|
|
- return 1;
|
|
584
|
+ return 0;
|
607
|
585
|
}
|
608
|
586
|
|
609
|
587
|
|
... |
... |
@@ -759,7 +737,7 @@ |
759
|
737
|
FT_Byte* p;
|
760
|
738
|
|
761
|
739
|
|
762
|
|
- if ( !colr )
|
|
740
|
+ if ( !colr || !colr->table )
|
763
|
741
|
return 0;
|
764
|
742
|
|
765
|
743
|
if ( iterator->current_color_stop >= iterator->num_color_stops )
|