... |
... |
@@ -353,15 +353,21 @@ |
353
|
353
|
static void
|
354
|
354
|
ft_var_load_avar( TT_Face face )
|
355
|
355
|
{
|
356
|
|
- FT_Stream stream = FT_FACE_STREAM( face );
|
357
|
|
- FT_Memory memory = stream->memory;
|
|
356
|
+ FT_Error error;
|
|
357
|
+ FT_Stream stream = FT_FACE_STREAM( face );
|
|
358
|
+ FT_Memory memory = stream->memory;
|
|
359
|
+ FT_Int i, j;
|
|
360
|
+
|
358
|
361
|
GX_Blend blend = face->blend;
|
359
|
362
|
GX_AVarSegment segment;
|
360
|
|
- FT_Error error;
|
361
|
|
- FT_Long version;
|
362
|
|
- FT_Long axisCount;
|
363
|
|
- FT_Int i, j;
|
364
|
|
- FT_ULong table_len;
|
|
363
|
+ GX_AVarTable table;
|
|
364
|
+
|
|
365
|
+ FT_Long version;
|
|
366
|
+ FT_Long axisCount;
|
|
367
|
+ FT_ULong table_offset;
|
|
368
|
+ FT_ULong table_len;
|
|
369
|
+ FT_ULong store_offset;
|
|
370
|
+ FT_ULong axisMap_offset;
|
365
|
371
|
|
366
|
372
|
|
367
|
373
|
FT_TRACE2(( "AVAR " ));
|
... |
... |
@@ -374,13 +380,15 @@ |
374
|
380
|
return;
|
375
|
381
|
}
|
376
|
382
|
|
|
383
|
+ table_offset = FT_STREAM_POS();
|
|
384
|
+
|
377
|
385
|
if ( FT_FRAME_ENTER( table_len ) )
|
378
|
386
|
return;
|
379
|
387
|
|
380
|
388
|
version = FT_GET_LONG();
|
381
|
389
|
axisCount = FT_GET_LONG();
|
382
|
390
|
|
383
|
|
- if ( version != 0x00010000L )
|
|
391
|
+ if ( version != 0x00010000L && version != 0x00020000L )
|
384
|
392
|
{
|
385
|
393
|
FT_TRACE2(( "bad table version\n" ));
|
386
|
394
|
goto Exit;
|
... |
... |
@@ -396,10 +404,14 @@ |
396
|
404
|
goto Exit;
|
397
|
405
|
}
|
398
|
406
|
|
399
|
|
- if ( FT_QNEW_ARRAY( blend->avar_segment, axisCount ) )
|
|
407
|
+ if ( FT_NEW( blend->avar_table ) )
|
|
408
|
+ goto Exit;
|
|
409
|
+ table = blend->avar_table;
|
|
410
|
+
|
|
411
|
+ if ( FT_QNEW_ARRAY( table->avar_segment, axisCount ) )
|
400
|
412
|
goto Exit;
|
401
|
413
|
|
402
|
|
- segment = &blend->avar_segment[0];
|
|
414
|
+ segment = &table->avar_segment[0];
|
403
|
415
|
for ( i = 0; i < axisCount; i++, segment++ )
|
404
|
416
|
{
|
405
|
417
|
FT_TRACE5(( " axis %d:\n", i ));
|
... |
... |
@@ -412,9 +424,9 @@ |
412
|
424
|
/* it right now since loading the `avar' table is optional. */
|
413
|
425
|
|
414
|
426
|
for ( j = i - 1; j >= 0; j-- )
|
415
|
|
- FT_FREE( blend->avar_segment[j].correspondence );
|
|
427
|
+ FT_FREE( table->avar_segment[j].correspondence );
|
416
|
428
|
|
417
|
|
- FT_FREE( blend->avar_segment );
|
|
429
|
+ FT_FREE( table->avar_segment );
|
418
|
430
|
goto Exit;
|
419
|
431
|
}
|
420
|
432
|
|
... |
... |
@@ -433,6 +445,35 @@ |
433
|
445
|
FT_TRACE5(( "\n" ));
|
434
|
446
|
}
|
435
|
447
|
|
|
448
|
+ if ( version < 0x00020000L )
|
|
449
|
+ goto Exit;
|
|
450
|
+
|
|
451
|
+ axisMap_offset = FT_GET_ULONG();
|
|
452
|
+ store_offset = FT_GET_ULONG();
|
|
453
|
+
|
|
454
|
+ if ( store_offset )
|
|
455
|
+ {
|
|
456
|
+ error = tt_var_load_item_variation_store(
|
|
457
|
+ face,
|
|
458
|
+ table_offset + store_offset,
|
|
459
|
+ &table->itemStore );
|
|
460
|
+ if ( error )
|
|
461
|
+ goto Exit;
|
|
462
|
+ }
|
|
463
|
+
|
|
464
|
+ if ( axisMap_offset )
|
|
465
|
+ {
|
|
466
|
+ error = tt_var_load_delta_set_index_mapping(
|
|
467
|
+ face,
|
|
468
|
+ table_offset + axisMap_offset,
|
|
469
|
+ &table->axisMap,
|
|
470
|
+ &table->itemStore,
|
|
471
|
+ table_len );
|
|
472
|
+ if ( error )
|
|
473
|
+ goto Exit;
|
|
474
|
+ }
|
|
475
|
+
|
|
476
|
+
|
436
|
477
|
Exit:
|
437
|
478
|
FT_FRAME_EXIT();
|
438
|
479
|
}
|
... |
... |
@@ -888,12 +929,15 @@ |
888
|
929
|
table = blend->hvar_table;
|
889
|
930
|
}
|
890
|
931
|
|
891
|
|
- error = tt_var_load_item_variation_store(
|
892
|
|
- face,
|
893
|
|
- table_offset + store_offset,
|
894
|
|
- &table->itemStore );
|
895
|
|
- if ( error )
|
896
|
|
- goto Exit;
|
|
932
|
+ if ( store_offset )
|
|
933
|
+ {
|
|
934
|
+ error = tt_var_load_item_variation_store(
|
|
935
|
+ face,
|
|
936
|
+ table_offset + store_offset,
|
|
937
|
+ &table->itemStore );
|
|
938
|
+ if ( error )
|
|
939
|
+ goto Exit;
|
|
940
|
+ }
|
897
|
941
|
|
898
|
942
|
if ( widthMap_offset )
|
899
|
943
|
{
|
... |
... |
@@ -1924,12 +1968,18 @@ |
1924
|
1968
|
FT_Fixed* coords,
|
1925
|
1969
|
FT_Fixed* normalized )
|
1926
|
1970
|
{
|
|
1971
|
+ FT_Error error = FT_Err_Ok;
|
|
1972
|
+ FT_Memory memory = face->root.memory;
|
|
1973
|
+ FT_UInt i, j;
|
|
1974
|
+
|
1927
|
1975
|
GX_Blend blend;
|
1928
|
1976
|
FT_MM_Var* mmvar;
|
1929
|
|
- FT_UInt i, j;
|
1930
|
1977
|
FT_Var_Axis* a;
|
1931
|
1978
|
GX_AVarSegment av;
|
1932
|
1979
|
|
|
1980
|
+ FT_Fixed* new_normalized;
|
|
1981
|
+ FT_Fixed* old_normalized;
|
|
1982
|
+
|
1933
|
1983
|
|
1934
|
1984
|
blend = face->blend;
|
1935
|
1985
|
mmvar = blend->mmvar;
|
... |
... |
@@ -1980,30 +2030,91 @@ |
1980
|
2030
|
for ( ; i < mmvar->num_axis; i++ )
|
1981
|
2031
|
normalized[i] = 0;
|
1982
|
2032
|
|
1983
|
|
- if ( blend->avar_segment )
|
|
2033
|
+ if ( blend->avar_table )
|
1984
|
2034
|
{
|
|
2035
|
+ GX_AVarTable table = blend->avar_table;
|
|
2036
|
+
|
|
2037
|
+
|
1985
|
2038
|
FT_TRACE5(( "normalized design coordinates"
|
1986
|
2039
|
" before applying `avar' data:\n" ));
|
1987
|
2040
|
|
1988
|
|
- av = blend->avar_segment;
|
1989
|
|
- for ( i = 0; i < mmvar->num_axis; i++, av++ )
|
|
2041
|
+ if ( table->avar_segment )
|
1990
|
2042
|
{
|
1991
|
|
- for ( j = 1; j < (FT_UInt)av->pairCount; j++ )
|
|
2043
|
+ av = table->avar_segment;
|
|
2044
|
+
|
|
2045
|
+ for ( i = 0; i < mmvar->num_axis; i++, av++ )
|
1992
|
2046
|
{
|
1993
|
|
- if ( normalized[i] < av->correspondence[j].fromCoord )
|
|
2047
|
+ for ( j = 1; j < (FT_UInt)av->pairCount; j++ )
|
1994
|
2048
|
{
|
1995
|
|
- FT_TRACE5(( " %.5f\n", normalized[i] / 65536.0 ));
|
|
2049
|
+ if ( normalized[i] < av->correspondence[j].fromCoord )
|
|
2050
|
+ {
|
|
2051
|
+ FT_TRACE5(( " %.5f\n", normalized[i] / 65536.0 ));
|
|
2052
|
+
|
|
2053
|
+ normalized[i] =
|
|
2054
|
+ FT_MulDiv( normalized[i] - av->correspondence[j - 1].fromCoord,
|
|
2055
|
+ av->correspondence[j].toCoord -
|
|
2056
|
+ av->correspondence[j - 1].toCoord,
|
|
2057
|
+ av->correspondence[j].fromCoord -
|
|
2058
|
+ av->correspondence[j - 1].fromCoord ) +
|
|
2059
|
+ av->correspondence[j - 1].toCoord;
|
|
2060
|
+ break;
|
|
2061
|
+ }
|
|
2062
|
+ }
|
|
2063
|
+ }
|
|
2064
|
+ }
|
1996
|
2065
|
|
1997
|
|
- normalized[i] =
|
1998
|
|
- FT_MulDiv( normalized[i] - av->correspondence[j - 1].fromCoord,
|
1999
|
|
- av->correspondence[j].toCoord -
|
2000
|
|
- av->correspondence[j - 1].toCoord,
|
2001
|
|
- av->correspondence[j].fromCoord -
|
2002
|
|
- av->correspondence[j - 1].fromCoord ) +
|
2003
|
|
- av->correspondence[j - 1].toCoord;
|
2004
|
|
- break;
|
|
2066
|
+ if ( table->itemStore.varData )
|
|
2067
|
+ {
|
|
2068
|
+ if ( FT_QNEW_ARRAY( new_normalized, mmvar->num_axis ) )
|
|
2069
|
+ return;
|
|
2070
|
+
|
|
2071
|
+ /* Install our half-normalized coordinates for the next */
|
|
2072
|
+ /* Item Variation Store to work with. */
|
|
2073
|
+ old_normalized = face->blend->normalizedcoords;
|
|
2074
|
+ face->blend->normalizedcoords = normalized;
|
|
2075
|
+
|
|
2076
|
+ for ( i = 0; i < mmvar->num_axis; i++ )
|
|
2077
|
+ {
|
|
2078
|
+ FT_Fixed v = normalized[i];
|
|
2079
|
+ FT_UInt innerIndex = i;
|
|
2080
|
+ FT_UInt outerIndex = 0;
|
|
2081
|
+ FT_Int delta;
|
|
2082
|
+
|
|
2083
|
+
|
|
2084
|
+ if ( table->axisMap.innerIndex )
|
|
2085
|
+ {
|
|
2086
|
+ FT_UInt idx = i;
|
|
2087
|
+
|
|
2088
|
+
|
|
2089
|
+ if ( idx >= table->axisMap.mapCount )
|
|
2090
|
+ idx = table->axisMap.mapCount - 1;
|
|
2091
|
+
|
|
2092
|
+ outerIndex = table->axisMap.outerIndex[idx];
|
|
2093
|
+ innerIndex = table->axisMap.innerIndex[idx];
|
2005
|
2094
|
}
|
|
2095
|
+
|
|
2096
|
+ delta = tt_var_get_item_delta( face,
|
|
2097
|
+ &table->itemStore,
|
|
2098
|
+ outerIndex,
|
|
2099
|
+ innerIndex );
|
|
2100
|
+
|
|
2101
|
+ v += delta << 2;
|
|
2102
|
+
|
|
2103
|
+ /* Clamp value range. */
|
|
2104
|
+ v = v >= 0x10000L ? 0x10000 : v;
|
|
2105
|
+ v = v <= -0x10000L ? -0x10000 : v;
|
|
2106
|
+
|
|
2107
|
+ new_normalized[i] = v;
|
2006
|
2108
|
}
|
|
2109
|
+
|
|
2110
|
+ for ( i = 0; i < mmvar->num_axis; i++ )
|
|
2111
|
+ {
|
|
2112
|
+ normalized[i] = new_normalized[i];
|
|
2113
|
+ }
|
|
2114
|
+
|
|
2115
|
+ face->blend->normalizedcoords = old_normalized;
|
|
2116
|
+
|
|
2117
|
+ FT_FREE( new_normalized );
|
2007
|
2118
|
}
|
2008
|
2119
|
}
|
2009
|
2120
|
}
|
... |
... |
@@ -2041,9 +2152,9 @@ |
2041
|
2152
|
for ( ; i < num_coords; i++ )
|
2042
|
2153
|
design[i] = 0;
|
2043
|
2154
|
|
2044
|
|
- if ( blend->avar_segment )
|
|
2155
|
+ if ( blend->avar_table && blend->avar_table->avar_segment )
|
2045
|
2156
|
{
|
2046
|
|
- GX_AVarSegment av = blend->avar_segment;
|
|
2157
|
+ GX_AVarSegment av = blend->avar_table->avar_segment;
|
2047
|
2158
|
|
2048
|
2159
|
|
2049
|
2160
|
FT_TRACE5(( "design coordinates"
|
... |
... |
@@ -4390,11 +4501,19 @@ |
4390
|
4501
|
FT_FREE( blend->normalized_stylecoords );
|
4391
|
4502
|
FT_FREE( blend->mmvar );
|
4392
|
4503
|
|
4393
|
|
- if ( blend->avar_segment )
|
|
4504
|
+ if ( blend->avar_table )
|
4394
|
4505
|
{
|
4395
|
4506
|
for ( i = 0; i < num_axes; i++ )
|
4396
|
|
- FT_FREE( blend->avar_segment[i].correspondence );
|
4397
|
|
- FT_FREE( blend->avar_segment );
|
|
4507
|
+ FT_FREE( blend->avar_table->avar_segment[i].correspondence );
|
|
4508
|
+ FT_FREE( blend->avar_table->avar_segment );
|
|
4509
|
+
|
|
4510
|
+ tt_var_done_item_variation_store( face,
|
|
4511
|
+ &blend->avar_table->itemStore );
|
|
4512
|
+
|
|
4513
|
+ tt_var_done_delta_set_index_map( face,
|
|
4514
|
+ &blend->avar_table->axisMap );
|
|
4515
|
+
|
|
4516
|
+ FT_FREE( blend->avar_table );
|
4398
|
4517
|
}
|
4399
|
4518
|
|
4400
|
4519
|
if ( blend->hvar_table )
|