... |
... |
@@ -509,7 +509,7 @@ |
509
|
509
|
FT_UShort axis_count;
|
510
|
510
|
FT_UInt region_count;
|
511
|
511
|
|
512
|
|
- FT_UInt i, j, k;
|
|
512
|
+ FT_UInt i, j;
|
513
|
513
|
FT_Bool long_words;
|
514
|
514
|
|
515
|
515
|
GX_Blend blend = ttface->blend;
|
... |
... |
@@ -624,6 +624,7 @@ |
624
|
624
|
FT_UInt item_count;
|
625
|
625
|
FT_UInt word_delta_count;
|
626
|
626
|
FT_UInt region_idx_count;
|
|
627
|
+ FT_UInt per_region_size;
|
627
|
628
|
|
628
|
629
|
|
629
|
630
|
if ( FT_STREAM_SEEK( offset + dataOffsetArray[i] ) )
|
... |
... |
@@ -660,6 +661,8 @@ |
660
|
661
|
if ( FT_NEW_ARRAY( varData->regionIndices, region_idx_count ) )
|
661
|
662
|
goto Exit;
|
662
|
663
|
varData->regionIdxCount = region_idx_count;
|
|
664
|
+ varData->wordDeltaCount = word_delta_count;
|
|
665
|
+ varData->longWords = long_words;
|
663
|
666
|
|
664
|
667
|
for ( j = 0; j < varData->regionIdxCount; j++ )
|
665
|
668
|
{
|
... |
... |
@@ -675,37 +678,22 @@ |
675
|
678
|
}
|
676
|
679
|
}
|
677
|
680
|
|
678
|
|
- /* Parse delta set. */
|
679
|
|
- /* */
|
680
|
|
- /* On input, deltas are (word_delta_count + region_idx_count) bytes */
|
681
|
|
- /* each if `long_words` isn't set, and twice as much otherwise. */
|
682
|
|
- /* */
|
683
|
|
- /* On output, deltas are expanded to `region_idx_count` shorts each. */
|
684
|
|
- if ( FT_NEW_ARRAY( varData->deltaSet, item_count * region_idx_count ) )
|
685
|
|
- goto Exit;
|
686
|
|
- varData->itemCount = item_count;
|
|
681
|
+ per_region_size = word_delta_count + region_idx_count;
|
|
682
|
+ if ( long_words )
|
|
683
|
+ per_region_size *= 2;
|
687
|
684
|
|
688
|
|
- for ( j = 0; j < item_count * region_idx_count; )
|
|
685
|
+ if ( FT_NEW_ARRAY( varData->deltaSet, per_region_size * item_count ) )
|
|
686
|
+ goto Exit;
|
|
687
|
+ if ( FT_Stream_Read( stream,
|
|
688
|
+ varData->deltaSet,
|
|
689
|
+ per_region_size * item_count ) )
|
689
|
690
|
{
|
690
|
|
- if ( long_words )
|
691
|
|
- {
|
692
|
|
- for ( k = 0; k < word_delta_count; k++, j++ )
|
693
|
|
- if ( FT_READ_LONG( varData->deltaSet[j] ) )
|
694
|
|
- goto Exit;
|
695
|
|
- for ( ; k < region_idx_count; k++, j++ )
|
696
|
|
- if ( FT_READ_SHORT( varData->deltaSet[j] ) )
|
697
|
|
- goto Exit;
|
698
|
|
- }
|
699
|
|
- else
|
700
|
|
- {
|
701
|
|
- for ( k = 0; k < word_delta_count; k++, j++ )
|
702
|
|
- if ( FT_READ_SHORT( varData->deltaSet[j] ) )
|
703
|
|
- goto Exit;
|
704
|
|
- for ( ; k < region_idx_count; k++, j++ )
|
705
|
|
- if ( FT_READ_CHAR( varData->deltaSet[j] ) )
|
706
|
|
- goto Exit;
|
707
|
|
- }
|
|
691
|
+ FT_TRACE2(( "deltaSet read failed." ));
|
|
692
|
+ error = FT_THROW( Invalid_Table );
|
|
693
|
+ goto Exit;
|
708
|
694
|
}
|
|
695
|
+
|
|
696
|
+ varData->itemCount = item_count;
|
709
|
697
|
}
|
710
|
698
|
|
711
|
699
|
Exit:
|
... |
... |
@@ -1005,11 +993,16 @@ |
1005
|
993
|
FT_Error error = FT_Err_Ok;
|
1006
|
994
|
|
1007
|
995
|
GX_ItemVarData varData;
|
1008
|
|
- FT_ItemVarDelta* deltaSet;
|
|
996
|
+ FT_ItemVarDelta* deltaSet = NULL;
|
|
997
|
+ FT_ItemVarDelta deltaSetStack[16];
|
|
998
|
+
|
|
999
|
+ FT_Fixed* scalars = NULL;
|
|
1000
|
+ FT_Fixed scalarsStack[16];
|
1009
|
1001
|
|
1010
|
1002
|
FT_UInt master, j;
|
1011
|
|
- FT_Fixed* scalars = NULL;
|
1012
|
|
- FT_ItemVarDelta returnValue;
|
|
1003
|
+ FT_ItemVarDelta returnValue = 0;
|
|
1004
|
+ FT_UInt per_region_size;
|
|
1005
|
+ FT_Byte* bytes;
|
1013
|
1006
|
|
1014
|
1007
|
|
1015
|
1008
|
if ( !ttface->blend || !ttface->blend->normalizedcoords )
|
... |
... |
@@ -1026,15 +1019,48 @@ |
1026
|
1019
|
if ( outerIndex >= itemStore->dataCount )
|
1027
|
1020
|
return 0; /* Out of range. */
|
1028
|
1021
|
|
1029
|
|
- varData = &itemStore->varData[outerIndex];
|
1030
|
|
- deltaSet = FT_OFFSET( varData->deltaSet,
|
1031
|
|
- varData->regionIdxCount * innerIndex );
|
|
1022
|
+ varData = &itemStore->varData[outerIndex];
|
1032
|
1023
|
|
1033
|
1024
|
if ( innerIndex >= varData->itemCount )
|
1034
|
1025
|
return 0; /* Out of range. */
|
1035
|
1026
|
|
1036
|
|
- if ( FT_QNEW_ARRAY( scalars, varData->regionIdxCount ) )
|
1037
|
|
- return 0;
|
|
1027
|
+ if ( varData->regionIdxCount < 16 )
|
|
1028
|
+ {
|
|
1029
|
+ deltaSet = deltaSetStack;
|
|
1030
|
+ scalars = scalarsStack;
|
|
1031
|
+ }
|
|
1032
|
+ else
|
|
1033
|
+ {
|
|
1034
|
+ if ( FT_QNEW_ARRAY( deltaSet, varData->regionIdxCount ) )
|
|
1035
|
+ goto Exit;
|
|
1036
|
+ if ( FT_QNEW_ARRAY( scalars, varData->regionIdxCount ) )
|
|
1037
|
+ goto Exit;
|
|
1038
|
+ }
|
|
1039
|
+
|
|
1040
|
+ /* Parse delta set. */
|
|
1041
|
+ /* */
|
|
1042
|
+ /* Deltas are (word_delta_count + region_idx_count) bytes each */
|
|
1043
|
+ /* if `longWords` isn't set, and twice as much otherwise. */
|
|
1044
|
+ per_region_size = varData->wordDeltaCount + varData->regionIdxCount;
|
|
1045
|
+ if ( varData->longWords )
|
|
1046
|
+ per_region_size *= 2;
|
|
1047
|
+
|
|
1048
|
+ bytes = varData->deltaSet + per_region_size * innerIndex;
|
|
1049
|
+
|
|
1050
|
+ if ( varData->longWords )
|
|
1051
|
+ {
|
|
1052
|
+ for ( master = 0; master < varData->wordDeltaCount; master++ )
|
|
1053
|
+ deltaSet[master] = FT_NEXT_LONG( bytes );
|
|
1054
|
+ for ( ; master < varData->regionIdxCount; master++ )
|
|
1055
|
+ deltaSet[master] = FT_NEXT_SHORT( bytes );
|
|
1056
|
+ }
|
|
1057
|
+ else
|
|
1058
|
+ {
|
|
1059
|
+ for ( master = 0; master < varData->wordDeltaCount; master++ )
|
|
1060
|
+ deltaSet[master] = FT_NEXT_SHORT( bytes );
|
|
1061
|
+ for ( ; master < varData->regionIdxCount; master++ )
|
|
1062
|
+ deltaSet[master] = FT_NEXT_CHAR( bytes );
|
|
1063
|
+ }
|
1038
|
1064
|
|
1039
|
1065
|
/* outer loop steps through master designs to be blended */
|
1040
|
1066
|
for ( master = 0; master < varData->regionIdxCount; master++ )
|
... |
... |
@@ -1109,7 +1135,11 @@ |
1109
|
1135
|
*/
|
1110
|
1136
|
returnValue = FT_MulAddFix( scalars, deltaSet, varData->regionIdxCount );
|
1111
|
1137
|
|
1112
|
|
- FT_FREE( scalars );
|
|
1138
|
+ Exit:
|
|
1139
|
+ if ( scalars != scalarsStack )
|
|
1140
|
+ FT_FREE( scalars );
|
|
1141
|
+ if ( deltaSet != deltaSetStack )
|
|
1142
|
+ FT_FREE( deltaSet );
|
1113
|
1143
|
|
1114
|
1144
|
return returnValue;
|
1115
|
1145
|
}
|