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*)( -1 )
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;
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 )
415 error = TT_Err_Invalid_Table;
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,
509 for ( i = 0; i < blend->num_axis; ++
i )
511 if ( tuple_coords[i] == 0 )
518 else if ( blend->normalizedcoords[i] == 0 ||
519 ( blend->normalizedcoords[i] < 0 && tuple_coords[i] > 0 ) ||
520 ( blend->normalizedcoords[i] > 0 && tuple_coords[i] < 0 ) )
529 blend->normalizedcoords[i] > 0
530 ? blend->normalizedcoords[i]
531 : -blend->normalizedcoords[i],
534 else if ( blend->normalizedcoords[i] <= im_start_coords[i] ||
535 blend->normalizedcoords[i] >= im_end_coords[i] )
541 else if ( blend->normalizedcoords[i] < tuple_coords[i] )
543 temp =
FT_MulDiv( blend->normalizedcoords[i] - im_start_coords[i],
545 tuple_coords[i] - im_start_coords[i]);
546 apply =
FT_MulDiv( apply, temp, 0x10000L );
551 temp =
FT_MulDiv( im_end_coords[i] - blend->normalizedcoords[i],
553 im_end_coords[i] - tuple_coords[i] );
554 apply =
FT_MulDiv( apply, temp, 0x10000L );
571 typedef struct GX_FVar_Head_
584 typedef struct fvar_axis_
630 GX_FVar_Head fvar_head;
636 #define FT_STRUCTURE GX_FVar_Head
653 #define FT_STRUCTURE GX_FVar_Axis
666 if ( face->blend ==
NULL )
669 if ( (error = face->goto_table( face,
TTAG_gvar,
670 stream, &table_len )) != 0 )
673 if ( (error = face->goto_table( face,
TTAG_fvar,
674 stream, &table_len )) != 0 )
682 if ( fvar_head.version != (
FT_Long)0x00010000L ||
683 fvar_head.countSizePairs != 2 ||
684 fvar_head.axisSize != 20 ||
686 fvar_head.axisCount > 0x3FFE ||
687 fvar_head.instanceSize != 4 + 4 * fvar_head.axisCount ||
689 fvar_head.instanceCount > 0x7EFF ||
690 fvar_head.offsetToData + fvar_head.axisCount * 20U +
691 fvar_head.instanceCount * fvar_head.instanceSize > table_len )
693 error = TT_Err_Invalid_Table;
697 if (
FT_NEW( face->blend ) )
701 face->blend->mmvar_len =
705 fvar_head.instanceCount * fvar_head.axisCount *
sizeof (
FT_Fixed ) +
706 5 * fvar_head.axisCount;
708 if (
FT_ALLOC( mmvar, face->blend->mmvar_len ) )
710 face->blend->mmvar = mmvar;
719 fvar_head.instanceCount;
727 for ( i = 0; i < fvar_head.instanceCount; ++
i )
730 next_coords += fvar_head.axisCount;
734 for ( i = 0; i < fvar_head.axisCount; ++
i )
744 for ( i = 0; i < fvar_head.axisCount; ++
i )
746 GX_FVar_Axis axis_rec;
751 a->
tag = axis_rec.axisTag;
752 a->
minimum = axis_rec.minValue;
753 a->
def = axis_rec.defaultValue;
754 a->
maximum = axis_rec.maxValue;
755 a->
strid = axis_rec.nameID;
767 for ( i = 0; i < fvar_head.instanceCount; ++
i, ++ns )
775 for ( j = 0; j < fvar_head.axisCount; ++
j )
782 if ( master !=
NULL )
787 if (
FT_ALLOC( mmvar, face->blend->mmvar_len ) )
789 FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len );
812 a->
name = (
char *)
"Weight";
814 a->
name = (
char *)
"Width";
816 a->
name = (
char *)
"OpticalSize";
818 a->
name = (
char *)
"Slant";
874 face->doblend =
FALSE;
876 if ( face->blend ==
NULL )
883 mmvar = blend->mmvar;
885 if ( num_coords != mmvar->
num_axis )
887 error = TT_Err_Invalid_Argument;
891 for ( i = 0; i < num_coords; ++
i )
892 if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L )
894 error = TT_Err_Invalid_Argument;
898 if ( blend->glyphoffsets ==
NULL )
899 if ( (error = ft_var_load_gvar( face )) != 0 )
902 if ( blend->normalizedcoords ==
NULL )
904 if (
FT_NEW_ARRAY( blend->normalizedcoords, num_coords ) )
907 manageCvt = mcvt_modify;
915 manageCvt = mcvt_retain;
916 for ( i = 0; i < num_coords; ++
i )
918 if ( blend->normalizedcoords[i] != coords[i] )
920 manageCvt = mcvt_load;
936 face->doblend =
TRUE;
938 if ( face->cvt !=
NULL )
1005 if ( face->blend ==
NULL )
1011 blend = face->blend;
1012 mmvar = blend->mmvar;
1014 if ( num_coords != mmvar->
num_axis )
1016 error = TT_Err_Invalid_Argument;
1032 error = TT_Err_Invalid_Argument;
1036 if ( coords[i] < a->
def )
1052 if ( !blend->avar_checked )
1053 ft_var_load_avar( face );
1055 if ( blend->avar_segment !=
NULL )
1057 av = blend->avar_segment;
1058 for ( i = 0; i < mmvar->
num_axis; ++
i, ++av )
1132 GX_Blend blend = face->blend;
1140 if ( blend ==
NULL )
1142 FT_TRACE2((
"tt_face_vary_cvt: no blend specified\n" ));
1148 if ( face->cvt ==
NULL )
1150 FT_TRACE2((
"tt_face_vary_cvt: no `cvt ' table\n" ));
1156 error = face->goto_table( face,
TTAG_cvar, stream, &table_len );
1171 table_start = FT_Stream_FTell( stream );
1192 for ( i = 0; i < ( tupleCount & 0xFFF ); ++
i )
1207 for ( j = 0; j < blend->num_axis; ++
j )
1215 if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )
1216 for ( j = 0; j < 2 * blend->num_axis; ++
j )
1219 offsetToData += tupleDataSize;
1223 if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )
1225 for ( j = 0; j < blend->num_axis; ++
j )
1227 for ( j = 0; j < blend->num_axis; ++
j )
1231 apply = ft_var_apply_tuple( blend,
1242 offsetToData += tupleDataSize;
1246 here = FT_Stream_FTell( stream );
1248 FT_Stream_SeekSet( stream, offsetToData );
1250 localpoints = ft_var_readpackedpoints( stream, &point_count );
1251 deltas = ft_var_readpackeddeltas( stream,
1252 point_count == 0 ? face->cvt_size
1254 if ( localpoints ==
NULL || deltas ==
NULL )
1257 else if ( localpoints == ALL_POINTS )
1260 for ( j = 0; j < face->cvt_size; ++
j )
1261 face->cvt[j] = (
FT_Short)( face->cvt[
j] +
1267 for ( j = 0; j < point_count; ++
j )
1269 int pindex = localpoints[
j];
1271 face->cvt[pindex] = (
FT_Short)( face->cvt[pindex] +
1276 if ( localpoints != ALL_POINTS )
1280 offsetToData += tupleDataSize;
1282 FT_Stream_SeekSet( stream, here );
1327 GX_Blend blend = face->blend;
1339 FT_UInt point_count, spoint_count = 0;
1346 if ( !face->doblend || blend ==
NULL )
1347 return TT_Err_Invalid_Argument;
1354 if ( glyph_index >= blend->gv_glyphcnt ||
1355 blend->glyphoffsets[glyph_index] ==
1356 blend->glyphoffsets[glyph_index + 1] )
1361 blend->glyphoffsets[glyph_index] ) )
1364 glyph_start = FT_Stream_FTell( stream );
1379 here = FT_Stream_FTell( stream );
1381 FT_Stream_SeekSet( stream, offsetToData );
1383 sharedpoints = ft_var_readpackedpoints( stream, &spoint_count );
1384 offsetToData = FT_Stream_FTell( stream );
1386 FT_Stream_SeekSet( stream, here );
1399 if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD )
1401 for ( j = 0; j < blend->num_axis; ++
j )
1407 error = TT_Err_Invalid_Table;
1414 &blend->tuplecoords[(tupleIndex & 0xFFF) * blend->num_axis],
1418 if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )
1420 for ( j = 0; j < blend->num_axis; ++
j )
1422 for ( j = 0; j < blend->num_axis; ++
j )
1426 apply = ft_var_apply_tuple( blend,
1434 offsetToData += tupleDataSize;
1438 here = FT_Stream_FTell( stream );
1440 if ( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS )
1442 FT_Stream_SeekSet( stream, offsetToData );
1444 localpoints = ft_var_readpackedpoints( stream, &point_count );
1445 points = localpoints;
1449 points = sharedpoints;
1450 point_count = spoint_count;
1453 deltas_x = ft_var_readpackeddeltas( stream,
1454 point_count == 0 ? n_points
1456 deltas_y = ft_var_readpackeddeltas( stream,
1457 point_count == 0 ? n_points
1460 if ( points ==
NULL || deltas_y ==
NULL || deltas_x ==
NULL )
1463 else if ( points == ALL_POINTS )
1466 for ( j = 0; j < n_points; ++
j )
1475 for ( j = 0; j < point_count; ++
j )
1477 if ( localpoints[j] >= n_points )
1480 delta_xy[localpoints[
j]].
x +=
FT_MulFix( deltas_x[j], apply );
1481 delta_xy[localpoints[
j]].
y +=
FT_MulFix( deltas_y[j], apply );
1485 if ( localpoints != ALL_POINTS )
1490 offsetToData += tupleDataSize;
1492 FT_Stream_SeekSet( stream, here );
1527 if ( blend !=
NULL )
1532 FT_FREE( blend->normalizedcoords );
1535 if ( blend->avar_segment !=
NULL )
1537 for ( i = 0; i < blend->num_axis; ++
i )
1538 FT_FREE( blend->avar_segment[i].correspondence );
1539 FT_FREE( blend->avar_segment );
1542 FT_FREE( blend->tuplecoords );
1543 FT_FREE( blend->glyphoffsets );
#define FT_ALLOC(ptr, size)
GLvoid **typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
GLint GLenum GLboolean normalized
GLboolean GLboolean GLboolean GLboolean a
TT_Loader_GotoTableFunc goto_table
tt_face_load_cvt(TT_Face face, FT_Stream stream)
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)
GLenum GLsizei GLsizei GLsizei GLsizei GLbitfield flags
GLuint GLdouble GLdouble GLint GLint const GLdouble * points
#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)