... |
... |
@@ -66,6 +66,9 @@ |
66
|
66
|
typedef enum FT_PaintFormat_Internal_
|
67
|
67
|
{
|
68
|
68
|
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SOLID = 3,
|
|
69
|
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_LINEAR_GRADIENT = 5,
|
|
70
|
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_RADIAL_GRADIENT = 7,
|
|
71
|
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SWEEP_GRADIENT = 9,
|
69
|
72
|
FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER = 18,
|
70
|
73
|
FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM = 20,
|
71
|
74
|
FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER = 22,
|
... |
... |
@@ -477,8 +480,9 @@ |
477
|
480
|
|
478
|
481
|
|
479
|
482
|
static FT_Bool
|
480
|
|
- read_color_line( FT_Byte* color_line_p,
|
481
|
|
- FT_ColorLine *colorline )
|
|
483
|
+ read_color_line( FT_Byte* color_line_p,
|
|
484
|
+ FT_ColorLine* colorline,
|
|
485
|
+ FT_Bool read_variable )
|
482
|
486
|
{
|
483
|
487
|
FT_Byte* p = color_line_p;
|
484
|
488
|
FT_PaintExtend paint_extend;
|
... |
... |
@@ -493,6 +497,7 @@ |
493
|
497
|
colorline->color_stop_iterator.num_color_stops = FT_NEXT_USHORT( p );
|
494
|
498
|
colorline->color_stop_iterator.p = p;
|
495
|
499
|
colorline->color_stop_iterator.current_color_stop = 0;
|
|
500
|
+ colorline->color_stop_iterator.read_variable = read_variable;
|
496
|
501
|
|
497
|
502
|
return 1;
|
498
|
503
|
}
|
... |
... |
@@ -604,6 +609,7 @@ |
604
|
609
|
{
|
605
|
610
|
FT_Byte* paint_base = p;
|
606
|
611
|
FT_Byte* child_table_p = NULL;
|
|
612
|
+ FT_Bool do_read_var = FALSE;
|
607
|
613
|
FT_ULong var_index_base = 0;
|
608
|
614
|
/* Longest varIndexBase offset is 5 in the spec. */
|
609
|
615
|
FT_ItemVarDelta item_deltas[6] = { 0, 0, 0, 0, 0, 0 };
|
... |
... |
@@ -691,10 +697,14 @@ |
691
|
697
|
if ( !get_child_table_pointer( colr, paint_base, &p, &child_table_p ) )
|
692
|
698
|
return 0;
|
693
|
699
|
|
694
|
|
- if ( apaint->format == FT_COLR_PAINTFORMAT_LINEAR_GRADIENT )
|
|
700
|
+ if ( apaint->format == FT_COLR_PAINTFORMAT_LINEAR_GRADIENT ||
|
|
701
|
+ ( do_read_var =
|
|
702
|
+ ( (FT_PaintFormat_Internal)apaint->format ==
|
|
703
|
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_LINEAR_GRADIENT ) ) )
|
695
|
704
|
{
|
696
|
705
|
if ( !read_color_line( child_table_p,
|
697
|
|
- &apaint->u.linear_gradient.colorline ) )
|
|
706
|
+ &apaint->u.linear_gradient.colorline,
|
|
707
|
+ do_read_var ) )
|
698
|
708
|
return 0;
|
699
|
709
|
|
700
|
710
|
/*
|
... |
... |
@@ -708,16 +718,22 @@ |
708
|
718
|
apaint->u.linear_gradient.p2.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
|
709
|
719
|
apaint->u.linear_gradient.p2.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
|
710
|
720
|
|
|
721
|
+ apaint->format = FT_COLR_PAINTFORMAT_LINEAR_GRADIENT;
|
|
722
|
+
|
711
|
723
|
return 1;
|
712
|
724
|
}
|
713
|
725
|
|
714
|
|
- else if ( apaint->format == FT_COLR_PAINTFORMAT_RADIAL_GRADIENT )
|
|
726
|
+ else if ( apaint->format == FT_COLR_PAINTFORMAT_RADIAL_GRADIENT ||
|
|
727
|
+ ( do_read_var =
|
|
728
|
+ ( (FT_PaintFormat_Internal)apaint->format ==
|
|
729
|
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_RADIAL_GRADIENT ) ) )
|
715
|
730
|
{
|
716
|
731
|
FT_Pos tmp;
|
717
|
732
|
|
718
|
733
|
|
719
|
734
|
if ( !read_color_line( child_table_p,
|
720
|
|
- &apaint->u.radial_gradient.colorline ) )
|
|
735
|
+ &apaint->u.radial_gradient.colorline,
|
|
736
|
+ do_read_var ) )
|
721
|
737
|
return 0;
|
722
|
738
|
|
723
|
739
|
/* In the OpenType specification, `r0` and `r1` are defined as */
|
... |
... |
@@ -737,13 +753,19 @@ |
737
|
753
|
tmp = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
|
738
|
754
|
apaint->u.radial_gradient.r1 = tmp < 0 ? FT_INT_MAX : tmp;
|
739
|
755
|
|
|
756
|
+ apaint->format = FT_COLR_PAINTFORMAT_RADIAL_GRADIENT;
|
|
757
|
+
|
740
|
758
|
return 1;
|
741
|
759
|
}
|
742
|
760
|
|
743
|
|
- else if ( apaint->format == FT_COLR_PAINTFORMAT_SWEEP_GRADIENT )
|
|
761
|
+ else if ( apaint->format == FT_COLR_PAINTFORMAT_SWEEP_GRADIENT ||
|
|
762
|
+ ( do_read_var =
|
|
763
|
+ ( (FT_PaintFormat_Internal)apaint->format ==
|
|
764
|
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SWEEP_GRADIENT ) ) )
|
744
|
765
|
{
|
745
|
766
|
if ( !read_color_line( child_table_p,
|
746
|
|
- &apaint->u.sweep_gradient.colorline ) )
|
|
767
|
+ &apaint->u.sweep_gradient.colorline,
|
|
768
|
+ do_read_var) )
|
747
|
769
|
return 0;
|
748
|
770
|
|
749
|
771
|
apaint->u.sweep_gradient.center.x =
|
... |
... |
@@ -756,6 +778,8 @@ |
756
|
778
|
apaint->u.sweep_gradient.end_angle =
|
757
|
779
|
F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
|
758
|
780
|
|
|
781
|
+ apaint->format = FT_COLR_PAINTFORMAT_SWEEP_GRADIENT;
|
|
782
|
+
|
759
|
783
|
return 1;
|
760
|
784
|
}
|
761
|
785
|
|
... |
... |
@@ -1228,6 +1252,8 @@ |
1228
|
1252
|
Colr* colr = (Colr*)face->colr;
|
1229
|
1253
|
|
1230
|
1254
|
FT_Byte* p;
|
|
1255
|
+ FT_Long var_index_base;
|
|
1256
|
+ FT_Int item_deltas[2];
|
1231
|
1257
|
|
1232
|
1258
|
|
1233
|
1259
|
if ( !colr || !colr->table )
|
... |
... |
@@ -1251,6 +1277,28 @@ |
1251
|
1277
|
|
1252
|
1278
|
color_stop->color.alpha = FT_NEXT_SHORT( p );
|
1253
|
1279
|
|
|
1280
|
+ if ( iterator->read_variable )
|
|
1281
|
+ {
|
|
1282
|
+ /* Pointer p needs to be advanced independently of whether we intend */
|
|
1283
|
+ /* to take variable deltas into account or not. Otherwise iteration */
|
|
1284
|
+ /* would fail due to wrong offsets. */
|
|
1285
|
+ var_index_base = FT_NEXT_ULONG( p );
|
|
1286
|
+
|
|
1287
|
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
|
|
1288
|
+ if ( VARIABLE_COLRV1_ENABLED )
|
|
1289
|
+ {
|
|
1290
|
+ if ( !get_deltas_for_var_index_base( face, colr,
|
|
1291
|
+ var_index_base,
|
|
1292
|
+ 2,
|
|
1293
|
+ item_deltas ) )
|
|
1294
|
+ return 0;
|
|
1295
|
+
|
|
1296
|
+ color_stop->stop_offset += (FT_Fixed)item_deltas[0] << 2;
|
|
1297
|
+ color_stop->color.alpha += item_deltas[1];
|
|
1298
|
+ }
|
|
1299
|
+#endif
|
|
1300
|
+ }
|
|
1301
|
+
|
1254
|
1302
|
iterator->p = p;
|
1255
|
1303
|
iterator->current_color_stop++;
|
1256
|
1304
|
|