... |
... |
@@ -502,13 +502,15 @@ |
502
|
502
|
FT_Error error;
|
503
|
503
|
FT_UShort format;
|
504
|
504
|
FT_ULong region_offset;
|
505
|
|
- FT_UInt i, j, k;
|
506
|
|
- FT_UInt wordDeltaCount;
|
507
|
|
- FT_Bool long_words;
|
508
|
505
|
|
509
|
|
- GX_Blend blend = face->blend;
|
510
|
|
- GX_ItemVarData varData;
|
|
506
|
+ FT_UInt data_count;
|
|
507
|
+ FT_UShort axis_count;
|
|
508
|
+ FT_UInt region_count;
|
511
|
509
|
|
|
510
|
+ FT_UInt i, j, k;
|
|
511
|
+ FT_Bool long_words;
|
|
512
|
+
|
|
513
|
+ GX_Blend blend = face->blend;
|
512
|
514
|
FT_ULong* dataOffsetArray = NULL;
|
513
|
515
|
|
514
|
516
|
|
... |
... |
@@ -525,12 +527,12 @@ |
525
|
527
|
}
|
526
|
528
|
|
527
|
529
|
/* read top level fields */
|
528
|
|
- if ( FT_READ_ULONG( region_offset ) ||
|
529
|
|
- FT_READ_USHORT( itemStore->dataCount ) )
|
|
530
|
+ if ( FT_READ_ULONG( region_offset ) ||
|
|
531
|
+ FT_READ_USHORT( data_count ) )
|
530
|
532
|
goto Exit;
|
531
|
533
|
|
532
|
534
|
/* we need at least one entry in `itemStore->varData' */
|
533
|
|
- if ( !itemStore->dataCount )
|
|
535
|
+ if ( !data_count )
|
534
|
536
|
{
|
535
|
537
|
FT_TRACE2(( "tt_var_load_item_variation_store: missing varData\n" ));
|
536
|
538
|
error = FT_THROW( Invalid_Table );
|
... |
... |
@@ -539,10 +541,10 @@ |
539
|
541
|
|
540
|
542
|
/* make temporary copy of item variation data offsets; */
|
541
|
543
|
/* we will parse region list first, then come back */
|
542
|
|
- if ( FT_QNEW_ARRAY( dataOffsetArray, itemStore->dataCount ) )
|
|
544
|
+ if ( FT_QNEW_ARRAY( dataOffsetArray, data_count ) )
|
543
|
545
|
goto Exit;
|
544
|
546
|
|
545
|
|
- for ( i = 0; i < itemStore->dataCount; i++ )
|
|
547
|
+ for ( i = 0; i < data_count; i++ )
|
546
|
548
|
{
|
547
|
549
|
if ( FT_READ_ULONG( dataOffsetArray[i] ) )
|
548
|
550
|
goto Exit;
|
... |
... |
@@ -552,11 +554,11 @@ |
552
|
554
|
if ( FT_STREAM_SEEK( offset + region_offset ) )
|
553
|
555
|
goto Exit;
|
554
|
556
|
|
555
|
|
- if ( FT_READ_USHORT( itemStore->axisCount ) ||
|
556
|
|
- FT_READ_USHORT( itemStore->regionCount ) )
|
|
557
|
+ if ( FT_READ_USHORT( axis_count ) ||
|
|
558
|
+ FT_READ_USHORT( region_count ) )
|
557
|
559
|
goto Exit;
|
558
|
560
|
|
559
|
|
- if ( itemStore->axisCount != (FT_Long)blend->mmvar->num_axis )
|
|
561
|
+ if ( axis_count != (FT_Long)blend->mmvar->num_axis )
|
560
|
562
|
{
|
561
|
563
|
FT_TRACE2(( "tt_var_load_item_variation_store:"
|
562
|
564
|
" number of axes in item variation store\n" ));
|
... |
... |
@@ -565,9 +567,10 @@ |
565
|
567
|
error = FT_THROW( Invalid_Table );
|
566
|
568
|
goto Exit;
|
567
|
569
|
}
|
|
570
|
+ itemStore->axisCount = axis_count;
|
568
|
571
|
|
569
|
572
|
/* new constraint in OpenType 1.8.4 */
|
570
|
|
- if ( itemStore->regionCount >= 32768U )
|
|
573
|
+ if ( region_count >= 32768U )
|
571
|
574
|
{
|
572
|
575
|
FT_TRACE2(( "tt_var_load_item_variation_store:"
|
573
|
576
|
" too many variation region tables\n" ));
|
... |
... |
@@ -575,16 +578,16 @@ |
575
|
578
|
goto Exit;
|
576
|
579
|
}
|
577
|
580
|
|
578
|
|
- if ( FT_NEW_ARRAY( itemStore->varRegionList, itemStore->regionCount ) )
|
|
581
|
+ if ( FT_NEW_ARRAY( itemStore->varRegionList, region_count ) )
|
579
|
582
|
goto Exit;
|
|
583
|
+ itemStore->regionCount = region_count;
|
580
|
584
|
|
581
|
585
|
for ( i = 0; i < itemStore->regionCount; i++ )
|
582
|
586
|
{
|
583
|
587
|
GX_AxisCoords axisCoords;
|
584
|
588
|
|
585
|
589
|
|
586
|
|
- if ( FT_NEW_ARRAY( itemStore->varRegionList[i].axisList,
|
587
|
|
- itemStore->axisCount ) )
|
|
590
|
+ if ( FT_NEW_ARRAY( itemStore->varRegionList[i].axisList, axis_count ) )
|
588
|
591
|
goto Exit;
|
589
|
592
|
|
590
|
593
|
axisCoords = itemStore->varRegionList[i].axisList;
|
... |
... |
@@ -608,47 +611,53 @@ |
608
|
611
|
/* end of region list parse */
|
609
|
612
|
|
610
|
613
|
/* use dataOffsetArray now to parse varData items */
|
611
|
|
- if ( FT_NEW_ARRAY( itemStore->varData, itemStore->dataCount ) )
|
|
614
|
+ if ( FT_NEW_ARRAY( itemStore->varData, data_count ) )
|
612
|
615
|
goto Exit;
|
|
616
|
+ itemStore->dataCount = data_count;
|
613
|
617
|
|
614
|
|
- for ( i = 0; i < itemStore->dataCount; i++ )
|
|
618
|
+ for ( i = 0; i < data_count; i++ )
|
615
|
619
|
{
|
616
|
|
- varData = &itemStore->varData[i];
|
|
620
|
+ GX_ItemVarData varData = &itemStore->varData[i];
|
|
621
|
+
|
|
622
|
+ FT_UInt item_count;
|
|
623
|
+ FT_UInt word_delta_count;
|
|
624
|
+ FT_UInt region_idx_count;
|
|
625
|
+
|
617
|
626
|
|
618
|
627
|
if ( FT_STREAM_SEEK( offset + dataOffsetArray[i] ) )
|
619
|
628
|
goto Exit;
|
620
|
629
|
|
621
|
|
- if ( FT_READ_USHORT( varData->itemCount ) ||
|
622
|
|
- FT_READ_USHORT( wordDeltaCount ) ||
|
623
|
|
- FT_READ_USHORT( varData->regionIdxCount ) )
|
|
630
|
+ if ( FT_READ_USHORT( item_count ) ||
|
|
631
|
+ FT_READ_USHORT( word_delta_count ) ||
|
|
632
|
+ FT_READ_USHORT( region_idx_count ) )
|
624
|
633
|
goto Exit;
|
625
|
634
|
|
626
|
|
- long_words = !!( wordDeltaCount & 0x8000 );
|
627
|
|
- wordDeltaCount &= 0x7FFF;
|
|
635
|
+ long_words = !!( word_delta_count & 0x8000 );
|
|
636
|
+ word_delta_count &= 0x7FFF;
|
628
|
637
|
|
629
|
638
|
/* check some data consistency */
|
630
|
|
- if ( wordDeltaCount > varData->regionIdxCount )
|
|
639
|
+ if ( word_delta_count > region_idx_count )
|
631
|
640
|
{
|
632
|
641
|
FT_TRACE2(( "bad short count %d or region count %d\n",
|
633
|
|
- wordDeltaCount,
|
634
|
|
- varData->regionIdxCount ));
|
|
642
|
+ word_delta_count,
|
|
643
|
+ region_idx_count ));
|
635
|
644
|
error = FT_THROW( Invalid_Table );
|
636
|
645
|
goto Exit;
|
637
|
646
|
}
|
638
|
647
|
|
639
|
|
- if ( varData->regionIdxCount > itemStore->regionCount )
|
|
648
|
+ if ( region_idx_count > itemStore->regionCount )
|
640
|
649
|
{
|
641
|
650
|
FT_TRACE2(( "inconsistent regionCount %d in varData[%d]\n",
|
642
|
|
- varData->regionIdxCount,
|
|
651
|
+ region_idx_count,
|
643
|
652
|
i ));
|
644
|
653
|
error = FT_THROW( Invalid_Table );
|
645
|
654
|
goto Exit;
|
646
|
655
|
}
|
647
|
656
|
|
648
|
657
|
/* parse region indices */
|
649
|
|
- if ( FT_NEW_ARRAY( varData->regionIndices,
|
650
|
|
- varData->regionIdxCount ) )
|
|
658
|
+ if ( FT_NEW_ARRAY( varData->regionIndices, region_idx_count ) )
|
651
|
659
|
goto Exit;
|
|
660
|
+ varData->regionIdxCount = region_idx_count;
|
652
|
661
|
|
653
|
662
|
for ( j = 0; j < varData->regionIdxCount; j++ )
|
654
|
663
|
{
|
... |
... |
@@ -664,33 +673,33 @@ |
664
|
673
|
}
|
665
|
674
|
}
|
666
|
675
|
|
667
|
|
- /* Parse delta set. */
|
668
|
|
- /* */
|
669
|
|
- /* On input, deltas are (wordDeltaCount + regionIdxCount) bytes */
|
670
|
|
- /* each if `long_words` isn't set, and twice as much otherwise. */
|
671
|
|
- /* */
|
672
|
|
- /* On output, deltas are expanded to `regionIdxCount` shorts each. */
|
673
|
|
- if ( FT_NEW_ARRAY( varData->deltaSet,
|
674
|
|
- varData->regionIdxCount * varData->itemCount ) )
|
|
676
|
+ /* Parse delta set. */
|
|
677
|
+ /* */
|
|
678
|
+ /* On input, deltas are (word_delta_count + region_idx_count) bytes */
|
|
679
|
+ /* each if `long_words` isn't set, and twice as much otherwise. */
|
|
680
|
+ /* */
|
|
681
|
+ /* On output, deltas are expanded to `region_idx_count` shorts each. */
|
|
682
|
+ if ( FT_NEW_ARRAY( varData->deltaSet, item_count * region_idx_count ) )
|
675
|
683
|
goto Exit;
|
|
684
|
+ varData->itemCount = item_count;
|
676
|
685
|
|
677
|
|
- for ( j = 0; j < varData->itemCount * varData->regionIdxCount; )
|
|
686
|
+ for ( j = 0; j < item_count * region_idx_count; )
|
678
|
687
|
{
|
679
|
688
|
if ( long_words )
|
680
|
689
|
{
|
681
|
|
- for ( k = 0; k < wordDeltaCount; k++, j++ )
|
|
690
|
+ for ( k = 0; k < word_delta_count; k++, j++ )
|
682
|
691
|
if ( FT_READ_LONG( varData->deltaSet[j] ) )
|
683
|
692
|
goto Exit;
|
684
|
|
- for ( ; k < varData->regionIdxCount; k++, j++ )
|
|
693
|
+ for ( ; k < region_idx_count; k++, j++ )
|
685
|
694
|
if ( FT_READ_SHORT( varData->deltaSet[j] ) )
|
686
|
695
|
goto Exit;
|
687
|
696
|
}
|
688
|
697
|
else
|
689
|
698
|
{
|
690
|
|
- for ( k = 0; k < wordDeltaCount; k++, j++ )
|
|
699
|
+ for ( k = 0; k < word_delta_count; k++, j++ )
|
691
|
700
|
if ( FT_READ_SHORT( varData->deltaSet[j] ) )
|
692
|
701
|
goto Exit;
|
693
|
|
- for ( ; k < varData->regionIdxCount; k++, j++ )
|
|
702
|
+ for ( ; k < region_idx_count; k++, j++ )
|
694
|
703
|
if ( FT_READ_CHAR( varData->deltaSet[j] ) )
|
695
|
704
|
goto Exit;
|
696
|
705
|
}
|