47 #include FT_INTERNAL_DEBUG_H 48 #include FT_CONFIG_CONFIG_H 49 #include FT_INTERNAL_STREAM_H 50 #include FT_INTERNAL_SFNT_H 51 #include FT_TRUETYPE_TAGS_H 52 #include FT_MULTIPLE_MASTERS_H 60 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 63 #define FT_Stream_FTell( stream ) \ 64 ( (stream)->cursor - (stream)->base ) 65 #define FT_Stream_SeekSet( stream, off ) \ 66 ( (stream)->cursor = (stream)->base+(off) ) 76 #define FT_COMPONENT trace_ttgxvar 94 #define ALL_POINTS (FT_UShort*)( ~0 ) 97 #define GX_PT_POINTS_ARE_WORDS 0x80 98 #define GX_PT_POINT_RUN_COUNT_MASK 0x7F 142 if ( n & GX_PT_POINTS_ARE_WORDS )
143 n =
FT_GET_BYTE() | ( ( n & GX_PT_POINT_RUN_COUNT_MASK ) << 8 );
152 if ( runcnt & GX_PT_POINTS_ARE_WORDS )
154 runcnt = runcnt & GX_PT_POINT_RUN_COUNT_MASK;
157 if ( runcnt < 1 || i + runcnt >= n )
161 for ( j = 0; j < runcnt; ++j )
168 if ( runcnt < 1 || i + runcnt >= n )
171 for ( j = 0; j < runcnt; ++j )
183 GX_DT_DELTAS_ARE_ZERO = 0x80,
184 GX_DT_DELTAS_ARE_WORDS = 0x40,
185 GX_DT_DELTA_RUN_COUNT_MASK = 0x3F
210 ft_var_readpackeddeltas(
FT_Stream stream,
227 while ( i < delta_cnt )
230 if ( runcnt & GX_DT_DELTAS_ARE_ZERO )
234 j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt;
238 else if ( runcnt & GX_DT_DELTAS_ARE_WORDS )
242 j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt;
250 j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt;
255 if ( j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) )
284 GX_Blend blend = face->blend;
295 blend->avar_checked =
TRUE;
305 if ( version != 0x00010000L ||
306 axisCount != (
FT_Long)blend->mmvar->num_axis )
312 segment = &blend->avar_segment[0];
313 for ( i = 0; i < axisCount; ++
i, ++segment )
321 for ( j = i - 1; j >= 0; --j )
322 FT_FREE( blend->avar_segment[j].correspondence );
324 FT_FREE( blend->avar_segment );
325 blend->avar_segment =
NULL;
329 for ( j = 0; j < segment->
pairCount; ++j )
343 typedef struct GX_GVar_Head_
372 ft_var_load_gvar(
TT_Face face )
376 GX_Blend blend = face->blend;
382 GX_GVar_Head gvar_head;
388 #define FT_STRUCTURE GX_GVar_Head 408 blend->tuplecount = gvar_head.globalCoordCount;
409 blend->gv_glyphcnt = gvar_head.glyphCount;
410 offsetToData = gvar_start + gvar_head.offsetToData;
412 if ( gvar_head.version != (
FT_Long)0x00010000L ||
413 gvar_head.axisCount != (
FT_UShort)blend->mmvar->num_axis )
419 if (
FT_NEW_ARRAY( blend->glyphoffsets, blend->gv_glyphcnt + 1 ) )
422 if ( gvar_head.flags & 1 )
428 for ( i = 0; i <= blend->gv_glyphcnt; ++
i )
429 blend->glyphoffsets[i] = offsetToData +
FT_GET_LONG();
439 for ( i = 0; i <= blend->gv_glyphcnt; ++
i )
446 if ( blend->tuplecount != 0 )
449 gvar_head.axisCount * blend->tuplecount ) )
456 for ( i = 0; i < blend->tuplecount; ++
i )
457 for ( j = 0 ; j < (
FT_UInt)gvar_head.axisCount; ++j )
458 blend->tuplecoords[i * gvar_head.axisCount + j] =
497 ft_var_apply_tuple( GX_Blend blend,
507 for ( i = 0; i < blend->num_axis; ++
i )
509 if ( tuple_coords[i] == 0 )
516 else if ( blend->normalizedcoords[i] == 0 ||
517 ( blend->normalizedcoords[i] < 0 && tuple_coords[i] > 0 ) ||
518 ( blend->normalizedcoords[i] > 0 && tuple_coords[i] < 0 ) )
527 blend->normalizedcoords[i] > 0
528 ? blend->normalizedcoords[i]
529 : -blend->normalizedcoords[i] );
531 else if ( blend->normalizedcoords[i] <= im_start_coords[i] ||
532 blend->normalizedcoords[i] >= im_end_coords[i] )
538 else if ( blend->normalizedcoords[i] < tuple_coords[i] )
540 blend->normalizedcoords[i] - im_start_coords[i],
541 tuple_coords[i] - im_start_coords[i] );
545 im_end_coords[i] - blend->normalizedcoords[i],
546 im_end_coords[i] - tuple_coords[i] );
562 typedef struct GX_FVar_Head_
575 typedef struct fvar_axis_
621 GX_FVar_Head fvar_head;
627 #define FT_STRUCTURE GX_FVar_Head 644 #define FT_STRUCTURE GX_FVar_Axis 657 if ( face->blend ==
NULL )
661 stream, &table_len )) != 0 )
665 stream, &table_len )) != 0 )
673 if ( fvar_head.version != (
FT_Long)0x00010000L ||
674 fvar_head.countSizePairs != 2 ||
675 fvar_head.axisSize != 20 ||
677 fvar_head.axisCount > 0x3FFE ||
678 fvar_head.instanceSize != 4 + 4 * fvar_head.axisCount ||
680 fvar_head.instanceCount > 0x7EFF ||
681 fvar_head.offsetToData + fvar_head.axisCount * 20U +
682 fvar_head.instanceCount * fvar_head.instanceSize > table_len )
688 if (
FT_NEW( face->blend ) )
692 face->blend->mmvar_len =
696 fvar_head.instanceCount * fvar_head.axisCount *
sizeof (
FT_Fixed ) +
697 5 * fvar_head.axisCount;
699 if (
FT_ALLOC( mmvar, face->blend->mmvar_len ) )
701 face->blend->mmvar = mmvar;
710 fvar_head.instanceCount;
718 for ( i = 0; i < fvar_head.instanceCount; ++
i )
721 next_coords += fvar_head.axisCount;
725 for ( i = 0; i < fvar_head.axisCount; ++
i )
735 for ( i = 0; i < fvar_head.axisCount; ++
i )
737 GX_FVar_Axis axis_rec;
742 a->
tag = axis_rec.axisTag;
743 a->
minimum = axis_rec.minValue;
744 a->
def = axis_rec.defaultValue;
745 a->
maximum = axis_rec.maxValue;
746 a->
strid = axis_rec.nameID;
758 for ( i = 0; i < fvar_head.instanceCount; ++
i, ++ns )
766 for ( j = 0; j < fvar_head.axisCount; ++j )
773 if ( master !=
NULL )
778 if (
FT_ALLOC( mmvar, face->blend->mmvar_len ) )
780 FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len );
803 a->
name = (
char *)
"Weight";
805 a->
name = (
char *)
"Width";
807 a->
name = (
char *)
"OpticalSize";
809 a->
name = (
char *)
"Slant";
865 face->doblend =
FALSE;
867 if ( face->blend ==
NULL )
874 mmvar = blend->mmvar;
876 if ( num_coords != mmvar->
num_axis )
878 error =
FT_THROW( Invalid_Argument );
882 for ( i = 0; i < num_coords; ++
i )
883 if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L )
885 error =
FT_THROW( Invalid_Argument );
889 if ( blend->glyphoffsets ==
NULL )
890 if ( (error = ft_var_load_gvar( face )) != 0 )
893 if ( blend->normalizedcoords ==
NULL )
895 if (
FT_NEW_ARRAY( blend->normalizedcoords, num_coords ) )
898 manageCvt = mcvt_modify;
906 manageCvt = mcvt_retain;
907 for ( i = 0; i < num_coords; ++
i )
909 if ( blend->normalizedcoords[i] != coords[i] )
911 manageCvt = mcvt_load;
922 blend->num_axis = num_coords;
927 face->doblend =
TRUE;
996 if ( face->blend ==
NULL )
1002 blend = face->blend;
1003 mmvar = blend->mmvar;
1005 if ( num_coords != mmvar->
num_axis )
1007 error =
FT_THROW( Invalid_Argument );
1023 error =
FT_THROW( Invalid_Argument );
1027 if ( coords[i] < a->
def )
1035 if ( !blend->avar_checked )
1036 ft_var_load_avar( face );
1038 if ( blend->avar_segment !=
NULL )
1040 av = blend->avar_segment;
1041 for ( i = 0; i < mmvar->
num_axis; ++
i, ++av )
1111 GX_Blend blend = face->blend;
1119 if ( blend ==
NULL )
1121 FT_TRACE2((
"tt_face_vary_cvt: no blend specified\n" ));
1129 FT_TRACE2((
"tt_face_vary_cvt: no `cvt ' table\n" ));
1150 table_start = FT_Stream_FTell( stream );
1171 for ( i = 0; i < ( tupleCount & 0xFFF ); ++
i )
1186 for ( j = 0; j < blend->num_axis; ++j )
1194 if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )
1195 for ( j = 0; j < 2 * blend->num_axis; ++j )
1198 offsetToData += tupleDataSize;
1202 if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )
1204 for ( j = 0; j < blend->num_axis; ++j )
1206 for ( j = 0; j < blend->num_axis; ++j )
1210 apply = ft_var_apply_tuple( blend,
1221 offsetToData += tupleDataSize;
1225 here = FT_Stream_FTell( stream );
1227 FT_Stream_SeekSet( stream, offsetToData );
1229 localpoints = ft_var_readpackedpoints( stream, &point_count );
1230 deltas = ft_var_readpackeddeltas( stream,
1233 if ( localpoints ==
NULL || deltas ==
NULL )
1236 else if ( localpoints == ALL_POINTS )
1239 for ( j = 0; j < face->
cvt_size; ++j )
1246 for ( j = 0; j < point_count; ++j )
1248 int pindex = localpoints[j];
1255 if ( localpoints != ALL_POINTS )
1259 offsetToData += tupleDataSize;
1261 FT_Stream_SeekSet( stream, here );
1306 GX_Blend blend = face->blend;
1318 FT_UInt point_count, spoint_count = 0;
1325 if ( !face->doblend || blend ==
NULL )
1326 return FT_THROW( Invalid_Argument );
1333 if ( glyph_index >= blend->gv_glyphcnt ||
1334 blend->glyphoffsets[glyph_index] ==
1335 blend->glyphoffsets[glyph_index + 1] )
1340 blend->glyphoffsets[glyph_index] ) )
1343 glyph_start = FT_Stream_FTell( stream );
1358 here = FT_Stream_FTell( stream );
1360 FT_Stream_SeekSet( stream, offsetToData );
1362 sharedpoints = ft_var_readpackedpoints( stream, &spoint_count );
1363 offsetToData = FT_Stream_FTell( stream );
1365 FT_Stream_SeekSet( stream, here );
1378 if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD )
1380 for ( j = 0; j < blend->num_axis; ++j )
1393 &blend->tuplecoords[(tupleIndex & 0xFFF) * blend->num_axis],
1397 if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )
1399 for ( j = 0; j < blend->num_axis; ++j )
1401 for ( j = 0; j < blend->num_axis; ++j )
1405 apply = ft_var_apply_tuple( blend,
1413 offsetToData += tupleDataSize;
1417 here = FT_Stream_FTell( stream );
1419 if ( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS )
1421 FT_Stream_SeekSet( stream, offsetToData );
1423 localpoints = ft_var_readpackedpoints( stream, &point_count );
1424 points = localpoints;
1428 points = sharedpoints;
1429 point_count = spoint_count;
1432 deltas_x = ft_var_readpackeddeltas( stream,
1433 point_count == 0 ? n_points
1435 deltas_y = ft_var_readpackeddeltas( stream,
1436 point_count == 0 ? n_points
1439 if ( points ==
NULL || deltas_y ==
NULL || deltas_x ==
NULL )
1442 else if ( points == ALL_POINTS )
1445 for ( j = 0; j < n_points; ++j )
1447 delta_xy[j].
x +=
FT_MulFix( deltas_x[j], apply );
1448 delta_xy[j].
y +=
FT_MulFix( deltas_y[j], apply );
1454 for ( j = 0; j < point_count; ++j )
1456 if ( localpoints[j] >= n_points )
1459 delta_xy[localpoints[j]].
x +=
FT_MulFix( deltas_x[j], apply );
1460 delta_xy[localpoints[j]].
y +=
FT_MulFix( deltas_y[j], apply );
1464 if ( localpoints != ALL_POINTS )
1469 offsetToData += tupleDataSize;
1471 FT_Stream_SeekSet( stream, here );
1506 if ( blend !=
NULL )
1511 FT_FREE( blend->normalizedcoords );
1514 if ( blend->avar_segment !=
NULL )
1516 for ( i = 0; i < blend->num_axis; ++
i )
1517 FT_FREE( blend->avar_segment[i].correspondence );
1518 FT_FREE( blend->avar_segment );
1521 FT_FREE( blend->tuplecoords );
1522 FT_FREE( blend->glyphoffsets );
#define FT_ALLOC(ptr, size)
FT_DivFix(FT_Long a, FT_Long b)
GLboolean GLboolean GLboolean GLboolean a
GLsizei const GLfloat * points
return FT_THROW(Missing_Property)
typedef void(APIENTRY *GLDEBUGPROCARB)(GLenum source
TT_Loader_GotoTableFunc goto_table
tt_face_load_cvt(TT_Face face, FT_Stream stream)
GLenum GLuint GLint GLenum face
TT_Get_MM_Var(TT_Face face, FT_MM_Var **master)
TT_Vary_Get_Glyph_Deltas(TT_Face face, FT_UInt glyph_index, FT_Vector **deltas, FT_UInt n_points)
GX_AVarCorrespondence correspondence
#define FT_STREAM_READ_FIELDS(fields, object)
struct FT_MM_Var_ FT_MM_Var
struct FT_Var_Named_Style_ FT_Var_Named_Style
#define FT_FRAME_USHORT(f)
tt_done_blend(FT_Memory memory, GX_Blend blend)
FT_MulDiv(FT_Long a, FT_Long b, FT_Long c)
#define FT_TRACE2(varformat)
TT_Set_MM_Blend(TT_Face face, FT_UInt num_coords, FT_Fixed *coords)
TT_Set_Var_Design(TT_Face face, FT_UInt num_coords, FT_Fixed *coords)
tt_face_vary_cvt(TT_Face face, FT_Stream stream)
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
#define FT_NEW_ARRAY(ptr, count)
#define FT_STREAM_SEEK(position)
FT_MulFix(FT_Long a, FT_Long b)
#define FT_FRAME_ULONG(f)
#define FT_FRAME_ENTER(size)
#define FT_MEM_COPY(dest, source, count)
FT_Var_Named_Style * namedstyle
#define FT_FACE_STREAM(x)
#define FT_FRAME_START(size)
GLint GLenum GLboolean normalized