ReactOS 0.4.16-dev-2357-g35d0dfe
t1load.c File Reference
#include <ft2build.h>
#include <freetype/internal/ftdebug.h>
#include <freetype/ftmm.h>
#include <freetype/internal/t1types.h>
#include <freetype/internal/ftcalc.h>
#include <freetype/internal/fthash.h>
#include "t1load.h"
#include "t1errors.h"
#include "t1tokens.h"
Include dependency graph for t1load.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define IS_INCREMENTAL   0
 
#define FT_COMPONENT   t1load
 
#define ALIGN_SIZE(n)    ( ( (n) + sizeof (void*) - 1 ) & ~( sizeof (void*) - 1 ) )
 
#define TABLE_EXTEND   5
 

Functions

static FT_Error t1_allocate_blend (T1_Face face, FT_UInt num_designs, FT_UInt num_axis)
 
 T1_Get_Multi_Master (T1_Face face, FT_Multi_Master *master)
 
static FT_Fixed mm_axis_unmap (PS_DesignMap axismap, FT_Fixed ncv)
 
static void mm_weights_unmap (FT_Fixed *weights, FT_Fixed *axiscoords, FT_UInt axis_count)
 
 T1_Get_MM_Var (T1_Face face, FT_MM_Var **master)
 
static FT_Error t1_set_mm_blend (T1_Face face, FT_UInt num_coords, FT_Fixed *coords)
 
 T1_Set_MM_Blend (T1_Face face, FT_UInt num_coords, FT_Fixed *coords)
 
 T1_Get_MM_Blend (T1_Face face, FT_UInt num_coords, FT_Fixed *coords)
 
 T1_Set_MM_WeightVector (T1_Face face, FT_UInt len, FT_Fixed *weightvector)
 
 T1_Get_MM_WeightVector (T1_Face face, FT_UInt *len, FT_Fixed *weightvector)
 
 T1_Set_MM_Design (T1_Face face, FT_UInt num_coords, FT_Long *coords)
 
 T1_Reset_MM_Blend (T1_Face face, FT_UInt instance_index)
 
 T1_Set_Var_Design (T1_Face face, FT_UInt num_coords, FT_Fixed *coords)
 
 T1_Get_Var_Design (T1_Face face, FT_UInt num_coords, FT_Fixed *coords)
 
 T1_Done_Blend (T1_Face face)
 
static void parse_blend_axis_types (T1_Face face, T1_Loader loader)
 
static void parse_blend_design_positions (T1_Face face, T1_Loader loader)
 
static void parse_blend_design_map (T1_Face face, T1_Loader loader)
 
static void parse_weight_vector (T1_Face face, T1_Loader loader)
 
static void parse_buildchar (T1_Face face, T1_Loader loader)
 
static FT_Error t1_load_keyword (T1_Face face, T1_Loader loader, const T1_Field field)
 
static void parse_private (T1_Face face, T1_Loader loader)
 
static int read_binary_data (T1_Parser parser, FT_ULong *size, FT_Byte **base, FT_Bool incremental)
 
static void t1_parse_font_matrix (T1_Face face, T1_Loader loader)
 
static void parse_encoding (T1_Face face, T1_Loader loader)
 
static void parse_subrs (T1_Face face, T1_Loader loader)
 
static void parse_charstrings (T1_Face face, T1_Loader loader)
 
static FT_Error parse_dict (T1_Face face, T1_Loader loader, FT_Byte *base, FT_ULong size)
 
static void t1_init_loader (T1_Loader loader, T1_Face face)
 
static void t1_done_loader (T1_Loader loader)
 
 T1_Open_Face (T1_Face face)
 

Variables

static const T1_FieldRec t1_keywords []
 

Macro Definition Documentation

◆ ALIGN_SIZE

#define ALIGN_SIZE (   n)     ( ( (n) + sizeof (void*) - 1 ) & ~( sizeof (void*) - 1 ) )

◆ FT_COMPONENT

#define FT_COMPONENT   t1load

Definition at line 89 of file t1load.c.

◆ IS_INCREMENTAL

#define IS_INCREMENTAL   0

Definition at line 78 of file t1load.c.

◆ TABLE_EXTEND

#define TABLE_EXTEND   5

Definition at line 1895 of file t1load.c.

Function Documentation

◆ mm_axis_unmap()

static FT_Fixed mm_axis_unmap ( PS_DesignMap  axismap,
FT_Fixed  ncv 
)
static

Definition at line 231 of file t1load.c.

233 {
234 int j;
235
236
237 if ( ncv <= axismap->blend_points[0] )
238 return INT_TO_FIXED( axismap->design_points[0] );
239
240 for ( j = 1; j < axismap->num_points; j++ )
241 {
242 if ( ncv <= axismap->blend_points[j] )
243 return INT_TO_FIXED( axismap->design_points[j - 1] ) +
244 ( axismap->design_points[j] - axismap->design_points[j - 1] ) *
245 FT_DivFix( ncv - axismap->blend_points[j - 1],
246 axismap->blend_points[j] -
247 axismap->blend_points[j - 1] );
248 }
249
250 return INT_TO_FIXED( axismap->design_points[axismap->num_points - 1] );
251 }
FT_DivFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:607
#define INT_TO_FIXED(x)
Definition: ftcalc.h:448
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
FT_Byte num_points
Definition: t1tables.h:285
FT_Fixed * blend_points
Definition: t1tables.h:287
FT_Long * design_points
Definition: t1tables.h:286

Referenced by T1_Get_MM_Var(), and T1_Get_Var_Design().

◆ mm_weights_unmap()

static void mm_weights_unmap ( FT_Fixed weights,
FT_Fixed axiscoords,
FT_UInt  axis_count 
)
static

Definition at line 260 of file t1load.c.

263 {
264 FT_ASSERT( axis_count <= T1_MAX_MM_AXIS );
265
266 if ( axis_count == 1 )
267 axiscoords[0] = weights[1];
268
269 else if ( axis_count == 2 )
270 {
271 axiscoords[0] = weights[3] + weights[1];
272 axiscoords[1] = weights[3] + weights[2];
273 }
274
275 else if ( axis_count == 3 )
276 {
277 axiscoords[0] = weights[7] + weights[5] + weights[3] + weights[1];
278 axiscoords[1] = weights[7] + weights[6] + weights[3] + weights[2];
279 axiscoords[2] = weights[7] + weights[6] + weights[5] + weights[4];
280 }
281
282 else
283 {
284 axiscoords[0] = weights[15] + weights[13] + weights[11] + weights[9] +
285 weights[7] + weights[5] + weights[3] + weights[1];
286 axiscoords[1] = weights[15] + weights[14] + weights[11] + weights[10] +
287 weights[7] + weights[6] + weights[3] + weights[2];
288 axiscoords[2] = weights[15] + weights[14] + weights[13] + weights[12] +
289 weights[7] + weights[6] + weights[5] + weights[4];
290 axiscoords[3] = weights[15] + weights[14] + weights[13] + weights[12] +
291 weights[11] + weights[10] + weights[9] + weights[8];
292 }
293 }
#define FT_ASSERT(condition)
Definition: ftdebug.h:241
const GLbyte * weights
Definition: glext.h:6523
#define T1_MAX_MM_AXIS
Definition: t1tables.h:276

Referenced by T1_Get_MM_Blend(), T1_Get_MM_Var(), and T1_Get_Var_Design().

◆ parse_blend_axis_types()

static void parse_blend_axis_types ( T1_Face  face,
T1_Loader  loader 
)
static

Definition at line 788 of file t1load.c.

790 {
791 T1_TokenRec axis_tokens[T1_MAX_MM_AXIS];
792 FT_Int n, num_axis;
794 PS_Blend blend;
796
797
798 /* take an array of objects */
799 T1_ToTokenArray( &loader->parser, axis_tokens,
800 T1_MAX_MM_AXIS, &num_axis );
801 if ( num_axis < 0 )
802 {
803 error = FT_ERR( Ignore );
804 goto Exit;
805 }
806 if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS )
807 {
808 FT_ERROR(( "parse_blend_axis_types: incorrect number of axes: %d\n",
809 num_axis ));
810 error = FT_THROW( Invalid_File_Format );
811 goto Exit;
812 }
813
814 /* allocate blend if necessary */
815 error = t1_allocate_blend( face, 0, (FT_UInt)num_axis );
816 if ( error )
817 goto Exit;
818
819 FT_TRACE4(( " [" ));
820
821 blend = face->blend;
822 memory = face->root.memory;
823
824 /* each token is an immediate containing the name of the axis */
825 for ( n = 0; n < num_axis; n++ )
826 {
827 T1_Token token = axis_tokens + n;
828 FT_Byte* name;
829 FT_UInt len;
830
831
832 /* skip first slash, if any */
833 if ( token->start[0] == '/' )
834 token->start++;
835
836 len = (FT_UInt)( token->limit - token->start );
837 if ( len == 0 )
838 {
839 error = FT_THROW( Invalid_File_Format );
840 goto Exit;
841 }
842
843 FT_TRACE4(( " /%.*s", len, token->start ));
844
845 name = (FT_Byte*)blend->axis_names[n];
846 if ( name )
847 {
848 FT_TRACE0(( "parse_blend_axis_types:"
849 " overwriting axis name `%s' with `%.*s'\n",
850 name, len, token->start ));
851 FT_FREE( name );
852 }
853
854 if ( FT_ALLOC( blend->axis_names[n], len + 1 ) )
855 goto Exit;
856
857 name = (FT_Byte*)blend->axis_names[n];
858 FT_MEM_COPY( name, token->start, len );
859 name[len] = '\0';
860 }
861
862 FT_TRACE4(( "]\n" ));
863
864 Exit:
865 loader->parser.root.error = error;
866 }
return FT_Err_Ok
Definition: ftbbox.c:526
#define FT_TRACE0(varformat)
Definition: ftdebug.h:187
#define FT_ERROR(varformat)
Definition: ftdebug.h:211
#define FT_THROW(e)
Definition: ftdebug.h:243
#define FT_TRACE4(varformat)
Definition: ftdebug.h:191
#define FT_ALLOC(ptr, size)
Definition: ftmemory.h:311
#define FT_FREE(ptr)
Definition: ftmemory.h:337
#define FT_MEM_COPY(dest, source, count)
Definition: ftmemory.h:237
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:64
unsigned char FT_Byte
Definition: fttypes.h:154
int FT_Error
Definition: fttypes.h:299
#define FT_ERR(e)
Definition: fttypes.h:599
unsigned int FT_UInt
Definition: fttypes.h:231
signed int FT_Int
Definition: fttypes.h:220
GLdouble n
Definition: glext.h:7729
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat token
Definition: glfuncs.h:210
if(dx< 0)
Definition: linetemp.h:194
#define error(str)
Definition: mkdosfs.c:1605
static char memory[1024 *256]
Definition: process.c:122
static void Exit(void)
Definition: sock.c:1330
FT_String * axis_names[T1_MAX_MM_AXIS]
Definition: t1tables.h:300
Definition: name.c:39
static FT_Error t1_allocate_blend(T1_Face face, FT_UInt num_designs, FT_UInt num_axis)
Definition: t1load.c:104
#define T1_ToTokenArray(p, t, m, c)
Definition: t1parse.h:108

◆ parse_blend_design_map()

static void parse_blend_design_map ( T1_Face  face,
T1_Loader  loader 
)
static

Definition at line 976 of file t1load.c.

978 {
980 T1_Parser parser = &loader->parser;
981 PS_Blend blend;
982 T1_TokenRec axis_tokens[T1_MAX_MM_AXIS];
983 FT_Int n, num_axis;
984 FT_Byte* old_cursor;
985 FT_Byte* old_limit;
986 FT_Memory memory = face->root.memory;
987
988
989 T1_ToTokenArray( parser, axis_tokens,
990 T1_MAX_MM_AXIS, &num_axis );
991 if ( num_axis < 0 )
992 {
993 error = FT_ERR( Ignore );
994 goto Exit;
995 }
996 if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS )
997 {
998 FT_ERROR(( "parse_blend_design_map: incorrect number of axes: %d\n",
999 num_axis ));
1000 error = FT_THROW( Invalid_File_Format );
1001 goto Exit;
1002 }
1003
1004 old_cursor = parser->root.cursor;
1005 old_limit = parser->root.limit;
1006
1007 error = t1_allocate_blend( face, 0, (FT_UInt)num_axis );
1008 if ( error )
1009 goto Exit;
1010 blend = face->blend;
1011
1012 FT_TRACE4(( " [" ));
1013
1014 /* now read each axis design map */
1015 for ( n = 0; n < num_axis; n++ )
1016 {
1017 PS_DesignMap map = blend->design_map + n;
1018 T1_Token axis_token;
1019 T1_TokenRec point_tokens[T1_MAX_MM_MAP_POINTS];
1020 FT_Int p, num_points;
1021
1022
1023 axis_token = axis_tokens + n;
1024
1025 parser->root.cursor = axis_token->start;
1026 parser->root.limit = axis_token->limit;
1027 T1_ToTokenArray( parser, point_tokens,
1028 T1_MAX_MM_MAP_POINTS, &num_points );
1029
1030 FT_TRACE4(( " [" ));
1031
1032 if ( num_points <= 0 || num_points > T1_MAX_MM_MAP_POINTS )
1033 {
1034 FT_ERROR(( "parse_blend_design_map: incorrect table\n" ));
1035 error = FT_THROW( Invalid_File_Format );
1036 goto Exit;
1037 }
1038
1039 if ( map->design_points )
1040 {
1041 FT_ERROR(( "parse_blend_design_map: duplicate table\n" ));
1042 error = FT_THROW( Invalid_File_Format );
1043 goto Exit;
1044 }
1045
1046 /* allocate design map data */
1047 if ( FT_NEW_ARRAY( map->design_points, num_points * 2 ) )
1048 goto Exit;
1049 map->blend_points = map->design_points + num_points;
1050 map->num_points = (FT_Byte)num_points;
1051
1052 for ( p = 0; p < num_points; p++ )
1053 {
1054 T1_Token point_token;
1055
1056
1057 point_token = point_tokens + p;
1058
1059 /* don't include delimiting brackets */
1060 parser->root.cursor = point_token->start + 1;
1061 parser->root.limit = point_token->limit - 1;
1062
1063 map->design_points[p] = T1_ToInt( parser );
1064 map->blend_points [p] = T1_ToFixed( parser, 0 );
1065
1066 FT_TRACE4(( " [%ld %f]",
1067 map->design_points[p],
1068 (double)map->blend_points[p] / 65536 ));
1069 }
1070
1071 FT_TRACE4(( "]" ));
1072 }
1073
1074 FT_TRACE4(( "]\n" ));
1075
1076 parser->root.cursor = old_cursor;
1077 parser->root.limit = old_limit;
1078
1079 Exit:
1080 parser->root.error = error;
1081 }
Definition: _map.h:48
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:341
GLfloat GLfloat p
Definition: glext.h:8902
PS_DesignMapRec design_map[T1_MAX_MM_AXIS]
Definition: t1tables.h:302
FT_Byte * start
Definition: psaux.h:201
FT_Byte * limit
Definition: psaux.h:202
Definition: import.c:81
unsigned int error
Definition: inffile.c:97
#define T1_ToFixed(p, t)
Definition: t1parse.h:100
FT_BEGIN_HEADER struct T1_ParserRec_ * T1_Parser
#define T1_ToInt(p)
Definition: t1parse.h:99
#define T1_MAX_MM_MAP_POINTS
Definition: t1tables.h:279

◆ parse_blend_design_positions()

static void parse_blend_design_positions ( T1_Face  face,
T1_Loader  loader 
)
static

Definition at line 870 of file t1load.c.

872 {
873 T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS];
874 FT_Int num_designs;
875 FT_Int num_axis;
876 T1_Parser parser = &loader->parser;
877
879 PS_Blend blend;
880
881
882 /* get the array of design tokens -- compute number of designs */
883 T1_ToTokenArray( parser, design_tokens,
884 T1_MAX_MM_DESIGNS, &num_designs );
885 if ( num_designs < 0 )
886 {
887 error = FT_ERR( Ignore );
888 goto Exit;
889 }
890 if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS )
891 {
892 FT_ERROR(( "parse_blend_design_positions:"
893 " incorrect number of designs: %d\n",
894 num_designs ));
895 error = FT_THROW( Invalid_File_Format );
896 goto Exit;
897 }
898
899 {
900 FT_Byte* old_cursor = parser->root.cursor;
901 FT_Byte* old_limit = parser->root.limit;
902 FT_Int n;
903
904
905 blend = face->blend;
906 num_axis = 0; /* make compiler happy */
907
908 FT_TRACE4(( " [" ));
909
910 for ( n = 0; n < num_designs; n++ )
911 {
912 T1_TokenRec axis_tokens[T1_MAX_MM_AXIS];
914 FT_Int axis, n_axis;
915
916
917 /* read axis/coordinates tokens */
918 token = design_tokens + n;
919 parser->root.cursor = token->start;
920 parser->root.limit = token->limit;
921 T1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &n_axis );
922
923 if ( n == 0 )
924 {
925 if ( n_axis <= 0 || n_axis > T1_MAX_MM_AXIS )
926 {
927 FT_ERROR(( "parse_blend_design_positions:"
928 " invalid number of axes: %d\n",
929 n_axis ));
930 error = FT_THROW( Invalid_File_Format );
931 goto Exit;
932 }
933
934 num_axis = n_axis;
936 (FT_UInt)num_designs,
937 (FT_UInt)num_axis );
938 if ( error )
939 goto Exit;
940 blend = face->blend;
941 }
942 else if ( n_axis != num_axis )
943 {
944 FT_ERROR(( "parse_blend_design_positions: incorrect table\n" ));
945 error = FT_THROW( Invalid_File_Format );
946 goto Exit;
947 }
948
949 /* now read each axis token into the design position */
950 FT_TRACE4(( " [" )) ;
951 for ( axis = 0; axis < n_axis; axis++ )
952 {
953 T1_Token token2 = axis_tokens + axis;
954
955
956 parser->root.cursor = token2->start;
957 parser->root.limit = token2->limit;
958 blend->design_pos[n][axis] = T1_ToFixed( parser, 0 );
959 FT_TRACE4(( " %f", (double)blend->design_pos[n][axis] / 65536 ));
960 }
961 FT_TRACE4(( "]" )) ;
962 }
963
964 FT_TRACE4(( "]\n" ));
965
966 loader->parser.root.cursor = old_cursor;
967 loader->parser.root.limit = old_limit;
968 }
969
970 Exit:
971 loader->parser.root.error = error;
972 }
FT_Fixed * design_pos[T1_MAX_MM_DESIGNS]
Definition: t1tables.h:301
#define T1_MAX_MM_DESIGNS
Definition: t1tables.h:273

◆ parse_buildchar()

static void parse_buildchar ( T1_Face  face,
T1_Loader  loader 
)
static

Definition at line 1162 of file t1load.c.

1164 {
1165 face->len_buildchar = (FT_UInt)T1_ToFixedArray( &loader->parser,
1166 0, NULL, 0 );
1167
1168#ifdef FT_DEBUG_LEVEL_TRACE
1169 {
1170 FT_UInt i;
1171
1172
1173 FT_TRACE4(( " [" ));
1174 for ( i = 0; i < face->len_buildchar; i++ )
1175 FT_TRACE4(( " 0" ));
1176
1177 FT_TRACE4(( "]\n" ));
1178 }
1179#endif
1180
1181 return;
1182 }
#define NULL
Definition: types.h:112
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define T1_ToFixedArray(p, m, f, t)
Definition: t1parse.h:104

◆ parse_charstrings()

static void parse_charstrings ( T1_Face  face,
T1_Loader  loader 
)
static

Definition at line 1899 of file t1load.c.

1901 {
1902 T1_Parser parser = &loader->parser;
1903 PS_Table code_table = &loader->charstrings;
1904 PS_Table name_table = &loader->glyph_names;
1905 PS_Table swap_table = &loader->swap_table;
1906 FT_Memory memory = parser->root.memory;
1908
1909 PSAux_Service psaux = (PSAux_Service)face->psaux;
1910
1911 FT_Byte* cur = parser->root.cursor;
1912 FT_Byte* limit = parser->root.limit;
1913 FT_Int n, num_glyphs;
1914 FT_Int notdef_index = 0;
1915 FT_Byte notdef_found = 0;
1916
1917
1918 num_glyphs = (FT_Int)T1_ToInt( parser );
1919 if ( num_glyphs < 0 )
1920 {
1921 error = FT_THROW( Invalid_File_Format );
1922 goto Fail;
1923 }
1924
1925 /* we certainly need more than 8 bytes per glyph */
1926 if ( num_glyphs > ( limit - cur ) >> 3 )
1927 {
1928 FT_TRACE0(( "parse_charstrings: adjusting number of glyphs"
1929 " (from %d to %ld)\n",
1930 num_glyphs, ( limit - cur ) >> 3 ));
1931 num_glyphs = ( limit - cur ) >> 3;
1932 }
1933
1934 /* some fonts like Optima-Oblique not only define the /CharStrings */
1935 /* array but access it also */
1936 if ( num_glyphs == 0 || parser->root.error )
1937 return;
1938
1939 /* initialize tables, leaving space for addition of .notdef, */
1940 /* if necessary, and a few other glyphs to handle buggy */
1941 /* fonts which have more glyphs than specified. */
1942
1943 /* for some non-standard fonts like `Optima' which provides */
1944 /* different outlines depending on the resolution it is */
1945 /* possible to get here twice */
1946 if ( !loader->num_glyphs )
1947 {
1948 error = psaux->ps_table_funcs->init(
1949 code_table, num_glyphs + 1 + TABLE_EXTEND, memory );
1950 if ( error )
1951 goto Fail;
1952
1953 error = psaux->ps_table_funcs->init(
1954 name_table, num_glyphs + 1 + TABLE_EXTEND, memory );
1955 if ( error )
1956 goto Fail;
1957
1958 /* Initialize table for swapping index notdef_index and */
1959 /* index 0 names and codes (if necessary). */
1960
1961 error = psaux->ps_table_funcs->init( swap_table, 4, memory );
1962 if ( error )
1963 goto Fail;
1964 }
1965
1966 n = 0;
1967
1968 for (;;)
1969 {
1970 FT_ULong size;
1971 FT_Byte* base;
1972
1973
1974 /* the format is simple: */
1975 /* `/glyphname' + binary data */
1976
1978
1979 cur = parser->root.cursor;
1980 if ( cur >= limit )
1981 break;
1982
1983 /* we stop when we find a `def' or `end' keyword */
1984 if ( cur + 3 < limit && IS_PS_DELIM( cur[3] ) )
1985 {
1986 if ( cur[0] == 'd' &&
1987 cur[1] == 'e' &&
1988 cur[2] == 'f' )
1989 {
1990 /* There are fonts which have this: */
1991 /* */
1992 /* /CharStrings 118 dict def */
1993 /* Private begin */
1994 /* CharStrings begin */
1995 /* ... */
1996 /* */
1997 /* To catch this we ignore `def' if */
1998 /* no charstring has actually been */
1999 /* seen. */
2000 if ( n )
2001 break;
2002 }
2003
2004 if ( cur[0] == 'e' &&
2005 cur[1] == 'n' &&
2006 cur[2] == 'd' )
2007 break;
2008 }
2009
2011 if ( parser->root.cursor >= limit )
2012 {
2013 error = FT_THROW( Invalid_File_Format );
2014 goto Fail;
2015 }
2016 if ( parser->root.error )
2017 return;
2018
2019 if ( *cur == '/' )
2020 {
2021 FT_UInt len;
2022
2023
2024 if ( cur + 2 >= limit )
2025 {
2026 error = FT_THROW( Invalid_File_Format );
2027 goto Fail;
2028 }
2029
2030 cur++; /* skip `/' */
2031 len = (FT_UInt)( parser->root.cursor - cur );
2032
2034 return;
2035
2036 /* for some non-standard fonts like `Optima' which provides */
2037 /* different outlines depending on the resolution it is */
2038 /* possible to get here twice */
2039 if ( loader->num_glyphs )
2040 continue;
2041
2042 error = T1_Add_Table( name_table, n, cur, len + 1 );
2043 if ( error )
2044 goto Fail;
2045
2046 /* add a trailing zero to the name table */
2047 name_table->elements[n][len] = '\0';
2048
2049 /* record index of /.notdef */
2050 if ( *cur == '.' &&
2051 ft_strcmp( ".notdef",
2052 (const char*)(name_table->elements[n]) ) == 0 )
2053 {
2054 notdef_index = n;
2055 notdef_found = 1;
2056 }
2057
2058 if ( face->type1.private_dict.lenIV >= 0 &&
2059 n < num_glyphs + TABLE_EXTEND )
2060 {
2061 FT_Byte* temp = NULL;
2062
2063
2064 if ( size <= (FT_ULong)face->type1.private_dict.lenIV )
2065 {
2066 error = FT_THROW( Invalid_File_Format );
2067 goto Fail;
2068 }
2069
2070 /* t1_decrypt() shouldn't write to base -- make temporary copy */
2071 if ( FT_ALLOC( temp, size ) )
2072 goto Fail;
2074 psaux->t1_decrypt( temp, size, 4330 );
2075 size -= (FT_ULong)face->type1.private_dict.lenIV;
2076 error = T1_Add_Table( code_table, n,
2077 temp + face->type1.private_dict.lenIV, size );
2078 FT_FREE( temp );
2079 }
2080 else
2081 error = T1_Add_Table( code_table, n, base, size );
2082 if ( error )
2083 goto Fail;
2084
2085 n++;
2086 }
2087 }
2088
2089 if ( !n )
2090 {
2091 error = FT_THROW( Invalid_File_Format );
2092 goto Fail;
2093 }
2094
2095 loader->num_glyphs = n;
2096
2097 /* if /.notdef is found but does not occupy index 0, do our magic. */
2098 if ( notdef_found &&
2099 ft_strcmp( ".notdef", (const char*)name_table->elements[0] ) )
2100 {
2101 /* Swap glyph in index 0 with /.notdef glyph. First, add index 0 */
2102 /* name and code entries to swap_table. Then place notdef_index */
2103 /* name and code entries into swap_table. Then swap name and code */
2104 /* entries at indices notdef_index and 0 using values stored in */
2105 /* swap_table. */
2106
2107 /* Index 0 name */
2108 error = T1_Add_Table( swap_table, 0,
2109 name_table->elements[0],
2110 name_table->lengths [0] );
2111 if ( error )
2112 goto Fail;
2113
2114 /* Index 0 code */
2115 error = T1_Add_Table( swap_table, 1,
2116 code_table->elements[0],
2117 code_table->lengths [0] );
2118 if ( error )
2119 goto Fail;
2120
2121 /* Index notdef_index name */
2122 error = T1_Add_Table( swap_table, 2,
2123 name_table->elements[notdef_index],
2124 name_table->lengths [notdef_index] );
2125 if ( error )
2126 goto Fail;
2127
2128 /* Index notdef_index code */
2129 error = T1_Add_Table( swap_table, 3,
2130 code_table->elements[notdef_index],
2131 code_table->lengths [notdef_index] );
2132 if ( error )
2133 goto Fail;
2134
2135 error = T1_Add_Table( name_table, notdef_index,
2136 swap_table->elements[0],
2137 swap_table->lengths [0] );
2138 if ( error )
2139 goto Fail;
2140
2141 error = T1_Add_Table( code_table, notdef_index,
2142 swap_table->elements[1],
2143 swap_table->lengths [1] );
2144 if ( error )
2145 goto Fail;
2146
2147 error = T1_Add_Table( name_table, 0,
2148 swap_table->elements[2],
2149 swap_table->lengths [2] );
2150 if ( error )
2151 goto Fail;
2152
2153 error = T1_Add_Table( code_table, 0,
2154 swap_table->elements[3],
2155 swap_table->lengths [3] );
2156 if ( error )
2157 goto Fail;
2158
2159 }
2160 else if ( !notdef_found )
2161 {
2162 /* notdef_index is already 0, or /.notdef is undefined in */
2163 /* charstrings dictionary. Worry about /.notdef undefined. */
2164 /* We take index 0 and add it to the end of the table(s) */
2165 /* and add our own /.notdef glyph to index 0. */
2166
2167 /* 0 333 hsbw endchar */
2168 FT_Byte notdef_glyph[] = { 0x8B, 0xF7, 0xE1, 0x0D, 0x0E };
2169
2170
2171 error = T1_Add_Table( swap_table, 0,
2172 name_table->elements[0],
2173 name_table->lengths [0] );
2174 if ( error )
2175 goto Fail;
2176
2177 error = T1_Add_Table( swap_table, 1,
2178 code_table->elements[0],
2179 code_table->lengths [0] );
2180 if ( error )
2181 goto Fail;
2182
2183 error = T1_Add_Table( name_table, 0, ".notdef", 8 );
2184 if ( error )
2185 goto Fail;
2186
2187 error = T1_Add_Table( code_table, 0, notdef_glyph, 5 );
2188
2189 if ( error )
2190 goto Fail;
2191
2192 error = T1_Add_Table( name_table, n,
2193 swap_table->elements[0],
2194 swap_table->lengths [0] );
2195 if ( error )
2196 goto Fail;
2197
2198 error = T1_Add_Table( code_table, n,
2199 swap_table->elements[1],
2200 swap_table->lengths [1] );
2201 if ( error )
2202 goto Fail;
2203
2204 /* we added a glyph. */
2205 loader->num_glyphs += 1;
2206 }
2207
2208#ifdef FT_DEBUG_LEVEL_TRACE
2209 FT_TRACE4(( " <" ));
2210
2211 /* XXX show charstrings? */
2212 FT_TRACE4(( "%d elements", loader->num_glyphs ));
2213
2214 FT_TRACE4(( ">\n" ));
2215#endif
2216
2217 return;
2218
2219 Fail:
2220 parser->root.error = error;
2221 }
int Fail
Definition: ehthrow.cxx:24
#define ft_strcmp
Definition: ftstdlib.h:86
unsigned long FT_ULong
Definition: fttypes.h:253
FxCollectionEntry * cur
GLsizeiptr size
Definition: glext.h:5919
GLint limit
Definition: glext.h:10326
struct PSAux_ServiceRec_ * PSAux_Service
#define IS_PS_DELIM(ch)
Definition: psaux.h:1410
static calc_node_t temp
Definition: rpn_ieee.c:38
void(* t1_decrypt)(FT_Byte *buffer, FT_Offset length, FT_UShort seed)
Definition: psaux.h:1353
const PS_Table_FuncsRec * ps_table_funcs
Definition: psaux.h:1347
FT_Byte ** elements
Definition: psaux.h:159
FT_UInt * lengths
Definition: psaux.h:160
FT_Error(* init)(PS_Table table, FT_Int count, FT_Memory memory)
Definition: psaux.h:90
#define TABLE_EXTEND
Definition: t1load.c:1895
#define IS_INCREMENTAL
Definition: t1load.c:78
static int read_binary_data(T1_Parser parser, FT_ULong *size, FT_Byte **base, FT_Bool incremental)
Definition: t1load.c:1338
#define T1_Add_Table(p, i, o, l)
Definition: t1parse.h:87
#define T1_Skip_Spaces(p)
Definition: t1parse.h:96
#define T1_Skip_PS_Token(p)
Definition: t1parse.h:97

◆ parse_dict()

static FT_Error parse_dict ( T1_Face  face,
T1_Loader  loader,
FT_Byte base,
FT_ULong  size 
)
static

Definition at line 2268 of file t1load.c.

2272 {
2273 T1_Parser parser = &loader->parser;
2274 FT_Byte *limit, *start_binary = NULL;
2275 FT_Bool have_integer = 0;
2276
2277
2278 parser->root.cursor = base;
2279 parser->root.limit = base + size;
2280 parser->root.error = FT_Err_Ok;
2281
2282 limit = parser->root.limit;
2283
2285
2286 while ( parser->root.cursor < limit )
2287 {
2288 FT_Byte* cur;
2289
2290
2291 cur = parser->root.cursor;
2292
2293 /* look for `eexec' */
2294 if ( IS_PS_TOKEN( cur, limit, "eexec" ) )
2295 break;
2296
2297 /* look for `closefile' which ends the eexec section */
2298 else if ( IS_PS_TOKEN( cur, limit, "closefile" ) )
2299 break;
2300
2301 /* in a synthetic font the base font starts after a */
2302 /* `FontDictionary' token that is placed after a Private dict */
2303 else if ( IS_PS_TOKEN( cur, limit, "FontDirectory" ) )
2304 {
2305 if ( loader->keywords_encountered & T1_PRIVATE )
2306 loader->keywords_encountered |=
2308 parser->root.cursor += 13;
2309 }
2310
2311 /* check whether we have an integer */
2312 else if ( ft_isdigit( *cur ) )
2313 {
2314 start_binary = cur;
2316 if ( parser->root.error )
2317 goto Exit;
2318 have_integer = 1;
2319 }
2320
2321 /* in valid Type 1 fonts we don't see `RD' or `-|' directly */
2322 /* since those tokens are handled by parse_subrs and */
2323 /* parse_charstrings */
2324 else if ( *cur == 'R' && cur + 6 < limit && *(cur + 1) == 'D' &&
2325 have_integer )
2326 {
2327 FT_ULong s;
2328 FT_Byte* b;
2329
2330
2331 parser->root.cursor = start_binary;
2332 if ( !read_binary_data( parser, &s, &b, IS_INCREMENTAL ) )
2333 return FT_THROW( Invalid_File_Format );
2334 have_integer = 0;
2335 }
2336
2337 else if ( *cur == '-' && cur + 6 < limit && *(cur + 1) == '|' &&
2338 have_integer )
2339 {
2340 FT_ULong s;
2341 FT_Byte* b;
2342
2343
2344 parser->root.cursor = start_binary;
2345 if ( !read_binary_data( parser, &s, &b, IS_INCREMENTAL ) )
2346 return FT_THROW( Invalid_File_Format );
2347 have_integer = 0;
2348 }
2349
2350 /* look for immediates */
2351 else if ( *cur == '/' && cur + 2 < limit )
2352 {
2353 FT_UInt len;
2354
2355
2356 cur++;
2357
2358 parser->root.cursor = cur;
2360 if ( parser->root.error )
2361 goto Exit;
2362
2363 len = (FT_UInt)( parser->root.cursor - cur );
2364
2365 if ( len > 0 && len < 22 && parser->root.cursor < limit )
2366 {
2367 /* now compare the immediate name to the keyword table */
2369
2370
2371 for (;;)
2372 {
2373 FT_Byte* name;
2374
2375
2376 name = (FT_Byte*)keyword->ident;
2377 if ( !name )
2378 break;
2379
2380 if ( cur[0] == name[0] &&
2381 len == ft_strlen( (const char *)name ) &&
2382 ft_memcmp( cur, name, len ) == 0 )
2383 {
2384 /* We found it -- run the parsing callback! */
2385 /* We record every instance of every field */
2386 /* (until we reach the base font of a */
2387 /* synthetic font) to deal adequately with */
2388 /* multiple master fonts; this is also */
2389 /* necessary because later PostScript */
2390 /* definitions override earlier ones. */
2391
2392 /* Once we encounter `FontDirectory' after */
2393 /* `/Private', we know that this is a synthetic */
2394 /* font; except for `/CharStrings' we are not */
2395 /* interested in anything that follows this */
2396 /* `FontDirectory'. */
2397
2398 /* MM fonts have more than one /Private token at */
2399 /* the top level; let's hope that all the junk */
2400 /* that follows the first /Private token is not */
2401 /* interesting to us. */
2402
2403 /* According to Adobe Tech Note #5175 (CID-Keyed */
2404 /* Font Installation for ATM Software) a `begin' */
2405 /* must be followed by exactly one `end', and */
2406 /* `begin' -- `end' pairs must be accurately */
2407 /* paired. We could use this to distinguish */
2408 /* between the global Private and the Private */
2409 /* dict that is a member of the Blend dict. */
2410
2411 const FT_UInt dict =
2412 ( loader->keywords_encountered & T1_PRIVATE )
2415
2416
2417 if ( !( dict & keyword->dict ) )
2418 {
2419 FT_TRACE1(( "parse_dict: found `%s' but ignoring it"
2420 " since it is in the wrong dictionary\n",
2421 keyword->ident ));
2422 break;
2423 }
2424
2425 if ( !( loader->keywords_encountered &
2427 ft_strcmp( (const char*)name, "CharStrings" ) == 0 )
2428 {
2430 loader,
2431 keyword );
2432 if ( parser->root.error )
2433 {
2434 if ( FT_ERR_EQ( parser->root.error, Ignore ) )
2435 parser->root.error = FT_Err_Ok;
2436 else
2437 return parser->root.error;
2438 }
2439 }
2440 break;
2441 }
2442
2443 keyword++;
2444 }
2445 }
2446
2447 have_integer = 0;
2448 }
2449 else
2450 {
2452 if ( parser->root.error )
2453 goto Exit;
2454 have_integer = 0;
2455 }
2456
2458 }
2459
2460 Exit:
2461 return parser->root.error;
2462 }
#define FT_TRACE1(varformat)
Definition: ftdebug.h:188
#define ft_isdigit(x)
Definition: ftobjs.h:116
#define ft_memcmp
Definition: ftstdlib.h:81
#define ft_strlen
Definition: ftstdlib.h:88
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
#define FT_ERR_EQ(x, e)
Definition: fttypes.h:604
GLdouble s
Definition: gl.h:2039
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define b
Definition: ke_i.h:79
#define T1_FIELD_DICT_FONTDICT
Definition: psaux.h:273
#define T1_FIELD_DICT_PRIVATE
Definition: psaux.h:274
#define IS_PS_TOKEN(cur, limit, token)
Definition: psaux.h:1425
struct T1_FieldRec_ * T1_Field
Definition: psaux.h:180
static FT_Error t1_load_keyword(T1_Face face, T1_Loader loader, const T1_Field field)
Definition: t1load.c:1199
static const T1_FieldRec t1_keywords[]
Definition: t1load.c:2233
#define T1_FONTDIR_AFTER_PRIVATE
Definition: t1load.h:60
#define T1_PRIVATE
Definition: t1load.h:59

Referenced by T1_Open_Face().

◆ parse_encoding()

static void parse_encoding ( T1_Face  face,
T1_Loader  loader 
)
static

Definition at line 1460 of file t1load.c.

1462 {
1463 T1_Parser parser = &loader->parser;
1464 FT_Byte* cur;
1465 FT_Byte* limit = parser->root.limit;
1466
1467 PSAux_Service psaux = (PSAux_Service)face->psaux;
1468
1469
1471 cur = parser->root.cursor;
1472 if ( cur >= limit )
1473 {
1474 FT_ERROR(( "parse_encoding: out of bounds\n" ));
1475 parser->root.error = FT_THROW( Invalid_File_Format );
1476 return;
1477 }
1478
1479 /* if we have a number or `[', the encoding is an array, */
1480 /* and we must load it now */
1481 if ( ft_isdigit( *cur ) || *cur == '[' )
1482 {
1483 T1_Encoding encode = &face->type1.encoding;
1485 PS_Table char_table = &loader->encoding_table;
1486 FT_Memory memory = parser->root.memory;
1488 FT_Bool only_immediates = 0;
1489
1490
1491 /* read the number of entries in the encoding; should be 256 */
1492 if ( *cur == '[' )
1493 {
1494 count = 256;
1495 only_immediates = 1;
1496 parser->root.cursor++;
1497 }
1498 else
1500
1501 array_size = count;
1502 if ( count > 256 )
1503 {
1504 FT_TRACE2(( "parse_encoding:"
1505 " only using first 256 encoding array entries\n" ));
1506 array_size = 256;
1507 }
1508
1510 if ( parser->root.cursor >= limit )
1511 return;
1512
1513 /* PostScript happily allows overwriting of encoding arrays */
1514 if ( encode->char_index )
1515 {
1516 FT_FREE( encode->char_index );
1517 FT_FREE( encode->char_name );
1518 T1_Release_Table( char_table );
1519 }
1520
1521 /* we use a T1_Table to store our charnames */
1522 loader->num_chars = encode->num_chars = array_size;
1523 if ( FT_NEW_ARRAY( encode->char_index, array_size ) ||
1524 FT_NEW_ARRAY( encode->char_name, array_size ) ||
1526 char_table, array_size, memory ) ) )
1527 {
1528 parser->root.error = error;
1529 return;
1530 }
1531
1532 /* We need to `zero' out encoding_table.elements */
1533 for ( n = 0; n < array_size; n++ )
1534 (void)T1_Add_Table( char_table, n, ".notdef", 8 );
1535
1536 /* Now we need to read records of the form */
1537 /* */
1538 /* ... charcode /charname ... */
1539 /* */
1540 /* for each entry in our table. */
1541 /* */
1542 /* We simply look for a number followed by an immediate */
1543 /* name. Note that this ignores correctly the sequence */
1544 /* that is often seen in type1 fonts: */
1545 /* */
1546 /* 0 1 255 { 1 index exch /.notdef put } for dup */
1547 /* */
1548 /* used to clean the encoding array before anything else. */
1549 /* */
1550 /* Alternatively, if the array is directly given as */
1551 /* */
1552 /* /Encoding [ ... ] */
1553 /* */
1554 /* we only read immediates. */
1555
1556 n = 0;
1558
1559 while ( parser->root.cursor < limit )
1560 {
1561 cur = parser->root.cursor;
1562
1563 /* we stop when we encounter a `def' or `]' */
1564 if ( *cur == 'd' && cur + 3 < limit )
1565 {
1566 if ( cur[1] == 'e' &&
1567 cur[2] == 'f' &&
1568 IS_PS_DELIM( cur[3] ) )
1569 {
1570 FT_TRACE6(( "encoding end\n" ));
1571 cur += 3;
1572 break;
1573 }
1574 }
1575 if ( *cur == ']' )
1576 {
1577 FT_TRACE6(( "encoding end\n" ));
1578 cur++;
1579 break;
1580 }
1581
1582 /* check whether we've found an entry */
1583 if ( ft_isdigit( *cur ) || only_immediates )
1584 {
1585 FT_Int charcode;
1586
1587
1588 if ( only_immediates )
1589 charcode = n;
1590 else
1591 {
1592 charcode = (FT_Int)T1_ToInt( parser );
1594
1595 /* protect against invalid charcode */
1596 if ( cur == parser->root.cursor )
1597 {
1598 parser->root.error = FT_THROW( Unknown_File_Format );
1599 return;
1600 }
1601 }
1602
1603 cur = parser->root.cursor;
1604
1605 if ( cur + 2 < limit && *cur == '/' && n < count )
1606 {
1607 FT_UInt len;
1608
1609
1610 cur++;
1611
1612 parser->root.cursor = cur;
1614 if ( parser->root.cursor >= limit )
1615 return;
1616 if ( parser->root.error )
1617 return;
1618
1619 len = (FT_UInt)( parser->root.cursor - cur );
1620
1621 if ( n < array_size )
1622 {
1623 parser->root.error = T1_Add_Table( char_table, charcode,
1624 cur, len + 1 );
1625 if ( parser->root.error )
1626 return;
1627 char_table->elements[charcode][len] = '\0';
1628 }
1629
1630 n++;
1631 }
1632 else if ( only_immediates )
1633 {
1634 /* Since the current position is not updated for */
1635 /* immediates-only mode we would get an infinite loop if */
1636 /* we don't do anything here. */
1637 /* */
1638 /* This encoding array is not valid according to the type1 */
1639 /* specification (it might be an encoding for a CID type1 */
1640 /* font, however), so we conclude that this font is NOT a */
1641 /* type1 font. */
1642 parser->root.error = FT_THROW( Unknown_File_Format );
1643 return;
1644 }
1645 }
1646 else
1647 {
1649 if ( parser->root.error )
1650 return;
1651 }
1652
1654 }
1655
1656#ifdef FT_DEBUG_LEVEL_TRACE
1657 FT_TRACE4(( " [" ));
1658
1659 /* XXX show encoding vector */
1660 FT_TRACE4(( "..." ));
1661
1662 FT_TRACE4(( "]\n" ));
1663#endif
1664
1665 face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY;
1666 parser->root.cursor = cur;
1667 }
1668
1669 /* Otherwise, we should have either `StandardEncoding', */
1670 /* `ExpertEncoding', or `ISOLatin1Encoding' */
1671 else
1672 {
1673 if ( cur + 17 < limit &&
1674 ft_strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 )
1675 {
1676 face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD;
1677 FT_TRACE4(( " StandardEncoding\n" ));
1678 }
1679
1680 else if ( cur + 15 < limit &&
1681 ft_strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 )
1682 {
1683 face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT;
1684 FT_TRACE4(( " ExpertEncoding\n" ));
1685 }
1686
1687 else if ( cur + 18 < limit &&
1688 ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 )
1689 {
1690 face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1;
1691 FT_TRACE4(( " ISOLatin1Encoding\n" ));
1692 }
1693
1694 else
1695 {
1696 parser->root.error = FT_ERR( Ignore );
1697 FT_TRACE4(( "<unknown>\n" ));
1698 }
1699 }
1700 }
#define FT_TRACE6(varformat)
Definition: ftdebug.h:193
#define FT_TRACE2(varformat)
Definition: ftdebug.h:189
#define FT_SET_ERROR(expression)
Definition: ftmemory.h:43
#define ft_strncmp
Definition: ftstdlib.h:89
GLuint GLuint GLsizei count
Definition: gl.h:1545
static UINT array_size
Definition: msctf.cpp:39
#define T1_Release_Table(p)
Definition: t1parse.h:88
@ T1_ENCODING_TYPE_ISOLATIN1
Definition: t1tables.h:568
@ T1_ENCODING_TYPE_STANDARD
Definition: t1tables.h:567
@ T1_ENCODING_TYPE_ARRAY
Definition: t1tables.h:566
@ T1_ENCODING_TYPE_EXPERT
Definition: t1tables.h:569
FT_BEGIN_HEADER struct T1_EncodingRecRec_ * T1_Encoding

◆ parse_private()

static void parse_private ( T1_Face  face,
T1_Loader  loader 
)
static

Definition at line 1324 of file t1load.c.

1326 {
1327 FT_UNUSED( face );
1328
1329 loader->keywords_encountered |= T1_PRIVATE;
1330
1331 FT_TRACE4(( "\n" ));
1332 }
#define FT_UNUSED(arg)

◆ parse_subrs()

static void parse_subrs ( T1_Face  face,
T1_Loader  loader 
)
static

Definition at line 1704 of file t1load.c.

1706 {
1707 T1_Parser parser = &loader->parser;
1708 PS_Table table = &loader->subrs;
1709 FT_Memory memory = parser->root.memory;
1711 FT_Int num_subrs;
1712 FT_UInt count;
1713
1714 PSAux_Service psaux = (PSAux_Service)face->psaux;
1715
1716
1718
1719 /* test for empty array */
1720 if ( parser->root.cursor < parser->root.limit &&
1721 *parser->root.cursor == '[' )
1722 {
1725 if ( parser->root.cursor >= parser->root.limit ||
1726 *parser->root.cursor != ']' )
1727 parser->root.error = FT_THROW( Invalid_File_Format );
1728 return;
1729 }
1730
1731 num_subrs = (FT_Int)T1_ToInt( parser );
1732 if ( num_subrs < 0 )
1733 {
1734 parser->root.error = FT_THROW( Invalid_File_Format );
1735 return;
1736 }
1737
1738 /* we certainly need more than 8 bytes per subroutine */
1739 if ( parser->root.limit >= parser->root.cursor &&
1740 num_subrs > ( parser->root.limit - parser->root.cursor ) >> 3 )
1741 {
1742 /*
1743 * There are two possibilities. Either the font contains an invalid
1744 * value for `num_subrs', or we have a subsetted font where the
1745 * subroutine indices are not adjusted, e.g.
1746 *
1747 * /Subrs 812 array
1748 * dup 0 { ... } NP
1749 * dup 51 { ... } NP
1750 * dup 681 { ... } NP
1751 * ND
1752 *
1753 * In both cases, we use a number hash that maps from subr indices to
1754 * actual array elements.
1755 */
1756
1757 FT_TRACE0(( "parse_subrs: adjusting number of subroutines"
1758 " (from %d to %ld)\n",
1759 num_subrs,
1760 ( parser->root.limit - parser->root.cursor ) >> 3 ));
1761 num_subrs = ( parser->root.limit - parser->root.cursor ) >> 3;
1762
1763 if ( !loader->subrs_hash )
1764 {
1765 if ( FT_NEW( loader->subrs_hash ) )
1766 goto Fail;
1767
1768 error = ft_hash_num_init( loader->subrs_hash, memory );
1769 if ( error )
1770 goto Fail;
1771 }
1772 }
1773
1774 /* position the parser right before the `dup' of the first subr */
1775 T1_Skip_PS_Token( parser ); /* `array' */
1776 if ( parser->root.error )
1777 return;
1779
1780 /* initialize subrs array -- with synthetic fonts it is possible */
1781 /* we get here twice */
1782 if ( !loader->num_subrs )
1783 {
1784 error = psaux->ps_table_funcs->init( table, num_subrs, memory );
1785 if ( error )
1786 goto Fail;
1787 }
1788
1789 /* the format is simple: */
1790 /* */
1791 /* `index' + binary data */
1792 /* */
1793 for ( count = 0; ; count++ )
1794 {
1795 FT_Long idx;
1796 FT_ULong size;
1797 FT_Byte* base;
1798
1799
1800 /* If we are out of data, or if the next token isn't `dup', */
1801 /* we are done. */
1802 if ( parser->root.cursor + 4 >= parser->root.limit ||
1803 ft_strncmp( (char*)parser->root.cursor, "dup", 3 ) != 0 )
1804 break;
1805
1806 T1_Skip_PS_Token( parser ); /* `dup' */
1807
1808 idx = T1_ToInt( parser );
1809
1811 return;
1812
1813 /* The binary string is followed by one token, e.g. `NP' */
1814 /* (bound to `noaccess put') or by two separate tokens: */
1815 /* `noaccess' & `put'. We position the parser right */
1816 /* before the next `dup', if any. */
1817 T1_Skip_PS_Token( parser ); /* `NP' or `|' or `noaccess' */
1818 if ( parser->root.error )
1819 return;
1821
1822 if ( parser->root.cursor + 4 < parser->root.limit &&
1823 ft_strncmp( (char*)parser->root.cursor, "put", 3 ) == 0 )
1824 {
1825 T1_Skip_PS_Token( parser ); /* skip `put' */
1827 }
1828
1829 /* if we use a hash, the subrs index is the key, and a running */
1830 /* counter specified for `T1_Add_Table' acts as the value */
1831 if ( loader->subrs_hash )
1832 {
1833 ft_hash_num_insert( idx, count, loader->subrs_hash, memory );
1834 idx = count;
1835 }
1836
1837 /* with synthetic fonts it is possible we get here twice */
1838 if ( loader->num_subrs )
1839 continue;
1840
1841 /* some fonts use a value of -1 for lenIV to indicate that */
1842 /* the charstrings are unencoded */
1843 /* */
1844 /* thanks to Tom Kacvinsky for pointing this out */
1845 /* */
1846 if ( face->type1.private_dict.lenIV >= 0 )
1847 {
1848 FT_Byte* temp = NULL;
1849
1850
1851 /* some fonts define empty subr records -- this is not totally */
1852 /* compliant to the specification (which says they should at */
1853 /* least contain a `return'), but we support them anyway */
1854 if ( size < (FT_ULong)face->type1.private_dict.lenIV )
1855 {
1856 error = FT_THROW( Invalid_File_Format );
1857 goto Fail;
1858 }
1859
1860 /* t1_decrypt() shouldn't write to base -- make temporary copy */
1861 if ( FT_ALLOC( temp, size ) )
1862 goto Fail;
1864 psaux->t1_decrypt( temp, size, 4330 );
1865 size -= (FT_ULong)face->type1.private_dict.lenIV;
1867 temp + face->type1.private_dict.lenIV, size );
1868 FT_FREE( temp );
1869 }
1870 else
1872 if ( error )
1873 goto Fail;
1874 }
1875
1876 if ( !loader->num_subrs )
1877 loader->num_subrs = num_subrs;
1878
1879#ifdef FT_DEBUG_LEVEL_TRACE
1880 FT_TRACE4(( " <" ));
1881
1882 /* XXX show subrs? */
1883 FT_TRACE4(( "%d elements", num_subrs ));
1884
1885 FT_TRACE4(( ">\n" ));
1886#endif
1887
1888 return;
1889
1890 Fail:
1891 parser->root.error = error;
1892 }
unsigned int idx
Definition: utils.c:41
FT_Error ft_hash_num_init(FT_Hash hash, FT_Memory memory)
Definition: fthash.c:203
FT_Error ft_hash_num_insert(FT_Int num, size_t data, FT_Hash hash, FT_Memory memory)
Definition: fthash.c:286
#define FT_NEW(ptr)
Definition: ftmemory.h:339
signed long FT_Long
Definition: fttypes.h:242

◆ parse_weight_vector()

static void parse_weight_vector ( T1_Face  face,
T1_Loader  loader 
)
static

Definition at line 1085 of file t1load.c.

1087 {
1088 T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS];
1089 FT_Int num_designs;
1091 T1_Parser parser = &loader->parser;
1092 PS_Blend blend = face->blend;
1094 FT_Int n;
1095 FT_Byte* old_cursor;
1096 FT_Byte* old_limit;
1097
1098
1099 T1_ToTokenArray( parser, design_tokens,
1100 T1_MAX_MM_DESIGNS, &num_designs );
1101 if ( num_designs < 0 )
1102 {
1103 error = FT_ERR( Ignore );
1104 goto Exit;
1105 }
1106 if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS )
1107 {
1108 FT_ERROR(( "parse_weight_vector:"
1109 " incorrect number of designs: %d\n",
1110 num_designs ));
1111 error = FT_THROW( Invalid_File_Format );
1112 goto Exit;
1113 }
1114
1115 if ( !blend || !blend->num_designs )
1116 {
1117 error = t1_allocate_blend( face, (FT_UInt)num_designs, 0 );
1118 if ( error )
1119 goto Exit;
1120 blend = face->blend;
1121 }
1122 else if ( blend->num_designs != (FT_UInt)num_designs )
1123 {
1124 FT_ERROR(( "parse_weight_vector:"
1125 " /BlendDesignPosition and /WeightVector have\n"
1126 " "
1127 " different number of elements\n" ));
1128 error = FT_THROW( Invalid_File_Format );
1129 goto Exit;
1130 }
1131
1132 old_cursor = parser->root.cursor;
1133 old_limit = parser->root.limit;
1134
1135 FT_TRACE4(( "[" ));
1136
1137 for ( n = 0; n < num_designs; n++ )
1138 {
1139 token = design_tokens + n;
1140 parser->root.cursor = token->start;
1141 parser->root.limit = token->limit;
1142
1143 blend->default_weight_vector[n] =
1144 blend->weight_vector[n] = T1_ToFixed( parser, 0 );
1145
1146 FT_TRACE4(( " %f", (double)blend->weight_vector[n] / 65536 ));
1147 }
1148
1149 FT_TRACE4(( "]\n" ));
1150
1151 parser->root.cursor = old_cursor;
1152 parser->root.limit = old_limit;
1153
1154 Exit:
1155 parser->root.error = error;
1156 }
FT_Fixed * default_weight_vector
Definition: t1tables.h:305
FT_UInt num_designs
Definition: t1tables.h:297
FT_Fixed * weight_vector
Definition: t1tables.h:304

◆ read_binary_data()

static int read_binary_data ( T1_Parser  parser,
FT_ULong size,
FT_Byte **  base,
FT_Bool  incremental 
)
static

Definition at line 1338 of file t1load.c.

1342 {
1343 FT_Byte* cur;
1344 FT_Byte* limit = parser->root.limit;
1345
1346
1347 /* the binary data has one of the following formats */
1348 /* */
1349 /* `size' [white*] RD white ....... ND */
1350 /* `size' [white*] -| white ....... |- */
1351 /* */
1352
1354
1355 cur = parser->root.cursor;
1356
1357 if ( cur < limit && ft_isdigit( *cur ) )
1358 {
1359 FT_Long s = T1_ToInt( parser );
1360
1361
1362 T1_Skip_PS_Token( parser ); /* `RD' or `-|' or something else */
1363
1364 /* there is only one whitespace char after the */
1365 /* `RD' or `-|' token */
1366 *base = parser->root.cursor + 1;
1367
1368 if ( s >= 0 && s < limit - *base )
1369 {
1370 parser->root.cursor += s + 1;
1371 *size = (FT_ULong)s;
1372 return !parser->root.error;
1373 }
1374 }
1375
1376 if( !incremental )
1377 {
1378 FT_ERROR(( "read_binary_data: invalid size field\n" ));
1379 parser->root.error = FT_THROW( Invalid_File_Format );
1380 }
1381
1382 return 0;
1383 }

Referenced by parse_charstrings(), parse_dict(), and parse_subrs().

◆ t1_allocate_blend()

static FT_Error t1_allocate_blend ( T1_Face  face,
FT_UInt  num_designs,
FT_UInt  num_axis 
)
static

Definition at line 104 of file t1load.c.

107 {
108 PS_Blend blend;
109 FT_Memory memory = face->root.memory;
111
112
113 blend = face->blend;
114 if ( !blend )
115 {
116 if ( FT_NEW( blend ) )
117 goto Exit;
118
119 blend->num_default_design_vector = 0;
120
121 face->blend = blend;
122 }
123
124 /* allocate design data if needed */
125 if ( num_designs > 0 )
126 {
127 if ( blend->num_designs == 0 )
128 {
129 FT_UInt nn;
130
131
132 /* allocate the blend `private' and `font_info' dictionaries */
133 if ( FT_NEW_ARRAY( blend->font_infos[1], num_designs ) ||
134 FT_NEW_ARRAY( blend->privates [1], num_designs ) ||
135 FT_NEW_ARRAY( blend->bboxes [1], num_designs ) ||
136 FT_NEW_ARRAY( blend->weight_vector, num_designs * 2 ) )
137 goto Exit;
138
139 blend->default_weight_vector = blend->weight_vector + num_designs;
140
141 blend->font_infos[0] = &face->type1.font_info;
142 blend->privates [0] = &face->type1.private_dict;
143 blend->bboxes [0] = &face->type1.font_bbox;
144
145 for ( nn = 2; nn <= num_designs; nn++ )
146 {
147 blend->font_infos[nn] = blend->font_infos[nn - 1] + 1;
148 blend->privates [nn] = blend->privates [nn - 1] + 1;
149 blend->bboxes [nn] = blend->bboxes [nn - 1] + 1;
150 }
151
152 blend->num_designs = num_designs;
153 }
154 else if ( blend->num_designs != num_designs )
155 goto Fail;
156 }
157
158 /* allocate axis data if needed */
159 if ( num_axis > 0 )
160 {
161 if ( blend->num_axis != 0 && blend->num_axis != num_axis )
162 goto Fail;
163
164 blend->num_axis = num_axis;
165 }
166
167 /* allocate the blend design pos table if needed */
168 num_designs = blend->num_designs;
169 num_axis = blend->num_axis;
170 if ( num_designs && num_axis && blend->design_pos[0] == 0 )
171 {
172 FT_UInt n;
173
174
175 if ( FT_NEW_ARRAY( blend->design_pos[0], num_designs * num_axis ) )
176 goto Exit;
177
178 for ( n = 1; n < num_designs; n++ )
179 blend->design_pos[n] = blend->design_pos[0] + num_axis * n;
180 }
181
182 Exit:
183 return error;
184
185 Fail:
186 error = FT_THROW( Invalid_File_Format );
187 goto Exit;
188 }
PS_Private privates[T1_MAX_MM_DESIGNS+1]
Definition: t1tables.h:308
FT_BBox * bboxes[T1_MAX_MM_DESIGNS+1]
Definition: t1tables.h:312
PS_FontInfo font_infos[T1_MAX_MM_DESIGNS+1]
Definition: t1tables.h:307
FT_UInt num_axis
Definition: t1tables.h:298
FT_UInt num_default_design_vector
Definition: t1tables.h:321

Referenced by parse_blend_axis_types(), parse_blend_design_map(), parse_blend_design_positions(), and parse_weight_vector().

◆ T1_Done_Blend()

T1_Done_Blend ( T1_Face  face)

Definition at line 734 of file t1load.c.

735 {
736 FT_Memory memory = face->root.memory;
737 PS_Blend blend = face->blend;
738
739
740 if ( blend )
741 {
742 FT_UInt num_designs = blend->num_designs;
743 FT_UInt num_axis = blend->num_axis;
744 FT_UInt n;
745
746
747 /* release design pos table */
748 FT_FREE( blend->design_pos[0] );
749 for ( n = 1; n < num_designs; n++ )
750 blend->design_pos[n] = NULL;
751
752 /* release blend `private' and `font info' dictionaries */
753 FT_FREE( blend->privates[1] );
754 FT_FREE( blend->font_infos[1] );
755 FT_FREE( blend->bboxes[1] );
756
757 for ( n = 0; n < num_designs; n++ )
758 {
759 blend->privates [n] = NULL;
760 blend->font_infos[n] = NULL;
761 blend->bboxes [n] = NULL;
762 }
763
764 /* release weight vectors */
765 FT_FREE( blend->weight_vector );
767
768 /* release axis names */
769 for ( n = 0; n < num_axis; n++ )
770 FT_FREE( blend->axis_names[n] );
771
772 /* release design map */
773 for ( n = 0; n < num_axis; n++ )
774 {
775 PS_DesignMap dmap = blend->design_map + n;
776
777
778 FT_FREE( dmap->design_points );
779 dmap->num_points = 0;
780 }
781
782 FT_FREE( face->blend );
783 }
784 }

Referenced by T1_Face_Done(), and T1_Open_Face().

◆ t1_done_loader()

static void t1_done_loader ( T1_Loader  loader)
static

Definition at line 2476 of file t1load.c.

2477 {
2478 T1_Parser parser = &loader->parser;
2479 FT_Memory memory = parser->root.memory;
2480
2481
2482 /* finalize tables */
2483 T1_Release_Table( &loader->encoding_table );
2484 T1_Release_Table( &loader->charstrings );
2485 T1_Release_Table( &loader->glyph_names );
2486 T1_Release_Table( &loader->swap_table );
2487 T1_Release_Table( &loader->subrs );
2488
2489 /* finalize hash */
2490 ft_hash_num_free( loader->subrs_hash, memory );
2491 FT_FREE( loader->subrs_hash );
2492
2493 /* finalize parser */
2495 }
#define ft_hash_num_free
Definition: fthash.h:106
T1_Finalize_Parser(T1_Parser parser)
Definition: t1parse.c:243

Referenced by T1_Open_Face().

◆ T1_Get_MM_Blend()

T1_Get_MM_Blend ( T1_Face  face,
FT_UInt  num_coords,
FT_Fixed coords 
)

Definition at line 473 of file t1load.c.

476 {
477 PS_Blend blend = face->blend;
478
479 FT_Fixed axiscoords[4];
480 FT_UInt i, nc;
481
482
483 if ( !blend )
484 return FT_THROW( Invalid_Argument );
485
487 axiscoords,
488 blend->num_axis );
489
490 nc = num_coords;
491 if ( num_coords > blend->num_axis )
492 {
493 FT_TRACE2(( "T1_Get_MM_Blend: only using first %d of %d coordinates\n",
494 blend->num_axis, num_coords ));
495 nc = blend->num_axis;
496 }
497
498 for ( i = 0; i < nc; i++ )
499 coords[i] = axiscoords[i];
500 for ( ; i < num_coords; i++ )
501 coords[i] = 0x8000;
502
503 return FT_Err_Ok;
504 }
signed long FT_Fixed
Definition: fttypes.h:287
GLuint coords
Definition: glext.h:7368
static void mm_weights_unmap(FT_Fixed *weights, FT_Fixed *axiscoords, FT_UInt axis_count)
Definition: t1load.c:260

◆ T1_Get_MM_Var()

T1_Get_MM_Var ( T1_Face  face,
FT_MM_Var **  master 
)

Definition at line 302 of file t1load.c.

304 {
305 FT_Memory memory = face->root.memory;
306 FT_MM_Var *mmvar = NULL;
307 FT_Multi_Master mmaster;
309 FT_UInt i;
310 FT_Fixed axiscoords[T1_MAX_MM_AXIS];
311 PS_Blend blend = face->blend;
312 FT_UShort* axis_flags;
313
314 FT_Offset mmvar_size;
315 FT_Offset axis_flags_size;
316 FT_Offset axis_size;
317
318
319 error = T1_Get_Multi_Master( face, &mmaster );
320 if ( error )
321 goto Exit;
322
323 /* the various `*_size' variables, which we also use as */
324 /* offsets into the `mmvar' array, must be multiples of the */
325 /* pointer size (except the last one); without such an */
326 /* alignment there might be runtime errors due to */
327 /* misaligned addresses */
328#undef ALIGN_SIZE
329#define ALIGN_SIZE( n ) \
330 ( ( (n) + sizeof (void*) - 1 ) & ~( sizeof (void*) - 1 ) )
331
332 mmvar_size = ALIGN_SIZE( sizeof ( FT_MM_Var ) );
333 axis_flags_size = ALIGN_SIZE( mmaster.num_axis *
334 sizeof ( FT_UShort ) );
335 axis_size = mmaster.num_axis * sizeof ( FT_Var_Axis );
336
337 if ( FT_ALLOC( mmvar, mmvar_size +
338 axis_flags_size +
339 axis_size ) )
340 goto Exit;
341
342 mmvar->num_axis = mmaster.num_axis;
343 mmvar->num_designs = mmaster.num_designs;
344 mmvar->num_namedstyles = 0; /* Not supported */
345
346 /* while axis flags are meaningless here, we have to provide the array */
347 /* to make `FT_Get_Var_Axis_Flags' work: the function expects that the */
348 /* values directly follow the data of `FT_MM_Var' */
349 axis_flags = (FT_UShort*)( (char*)mmvar + mmvar_size );
350 for ( i = 0; i < mmaster.num_axis; i++ )
351 axis_flags[i] = 0;
352
353 mmvar->axis = (FT_Var_Axis*)( (char*)axis_flags + axis_flags_size );
354 mmvar->namedstyle = NULL;
355
356 for ( i = 0; i < mmaster.num_axis; i++ )
357 {
358 mmvar->axis[i].name = mmaster.axis[i].name;
359 mmvar->axis[i].minimum = INT_TO_FIXED( mmaster.axis[i].minimum );
360 mmvar->axis[i].maximum = INT_TO_FIXED( mmaster.axis[i].maximum );
361 mmvar->axis[i].strid = ~0U; /* Does not apply */
362 mmvar->axis[i].tag = ~0U; /* Does not apply */
363
364 if ( !mmvar->axis[i].name )
365 continue;
366
367 if ( ft_strcmp( mmvar->axis[i].name, "Weight" ) == 0 )
368 mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'g', 'h', 't' );
369 else if ( ft_strcmp( mmvar->axis[i].name, "Width" ) == 0 )
370 mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'd', 't', 'h' );
371 else if ( ft_strcmp( mmvar->axis[i].name, "OpticalSize" ) == 0 )
372 mmvar->axis[i].tag = FT_MAKE_TAG( 'o', 'p', 's', 'z' );
373 }
374
376 axiscoords,
377 blend->num_axis );
378
379 for ( i = 0; i < mmaster.num_axis; i++ )
380 mmvar->axis[i].def = mm_axis_unmap( &blend->design_map[i],
381 axiscoords[i] );
382
383 *master = mmvar;
384
385 Exit:
386 return error;
387 }
#define U(x)
Definition: wordpad.c:45
struct FT_Var_Axis_ FT_Var_Axis
unsigned short FT_UShort
Definition: fttypes.h:209
#define FT_MAKE_TAG(_x1, _x2, _x3, _x4)
Definition: fttypes.h:488
size_t FT_Offset
Definition: fttypes.h:323
FT_Var_Axis * axis
Definition: ftmm.h:247
FT_UInt num_designs
Definition: ftmm.h:245
FT_UInt num_namedstyles
Definition: ftmm.h:246
FT_UInt num_axis
Definition: ftmm.h:244
FT_Var_Named_Style * namedstyle
Definition: ftmm.h:248
FT_MM_Axis axis[T1_MAX_MM_AXIS]
Definition: ftmm.h:111
FT_UInt num_designs
Definition: ftmm.h:110
FT_UInt num_axis
Definition: ftmm.h:109
FT_ULong tag
Definition: ftmm.h:163
FT_UInt strid
Definition: ftmm.h:164
FT_Fixed def
Definition: ftmm.h:160
FT_Fixed maximum
Definition: ftmm.h:161
FT_String * name
Definition: ftmm.h:157
FT_Fixed minimum
Definition: ftmm.h:159
#define ALIGN_SIZE(n)
static FT_Fixed mm_axis_unmap(PS_DesignMap axismap, FT_Fixed ncv)
Definition: t1load.c:231
T1_Get_Multi_Master(T1_Face face, FT_Multi_Master *master)
Definition: t1load.c:192
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList

◆ T1_Get_MM_WeightVector()

T1_Get_MM_WeightVector ( T1_Face  face,
FT_UInt len,
FT_Fixed weightvector 
)

Definition at line 548 of file t1load.c.

551 {
552 PS_Blend blend = face->blend;
553 FT_UInt i;
554
555
556 if ( !blend )
557 return FT_THROW( Invalid_Argument );
558
559 if ( *len < blend->num_designs )
560 {
561 *len = blend->num_designs;
562 return FT_THROW( Invalid_Argument );
563 }
564
565 for ( i = 0; i < blend->num_designs; i++ )
566 weightvector[i] = blend->weight_vector[i];
567 for ( ; i < *len; i++ )
568 weightvector[i] = (FT_Fixed)0;
569
570 *len = blend->num_designs;
571
572 return FT_Err_Ok;
573 }
#define for
Definition: utility.h:88

◆ T1_Get_Multi_Master()

T1_Get_Multi_Master ( T1_Face  face,
FT_Multi_Master master 
)

Definition at line 192 of file t1load.c.

194 {
195 PS_Blend blend = face->blend;
196 FT_UInt n;
198
199
200 error = FT_THROW( Invalid_Argument );
201
202 if ( blend )
203 {
204 master->num_axis = blend->num_axis;
205 master->num_designs = blend->num_designs;
206
207 for ( n = 0; n < blend->num_axis; n++ )
208 {
209 FT_MM_Axis* axis = master->axis + n;
210 PS_DesignMap map = blend->design_map + n;
211
212
213 axis->name = blend->axis_names[n];
214 axis->minimum = map->design_points[0];
215 axis->maximum = map->design_points[map->num_points - 1];
216 }
217
219 }
220
221 return error;
222 }
FT_BEGIN_HEADER struct FT_MM_Axis_ FT_MM_Axis

Referenced by T1_Get_MM_Var().

◆ T1_Get_Var_Design()

T1_Get_Var_Design ( T1_Face  face,
FT_UInt  num_coords,
FT_Fixed coords 
)

Definition at line 698 of file t1load.c.

701 {
702 PS_Blend blend = face->blend;
703
704 FT_Fixed axiscoords[4];
705 FT_UInt i, nc;
706
707
708 if ( !blend )
709 return FT_THROW( Invalid_Argument );
710
712 axiscoords,
713 blend->num_axis );
714
715 nc = num_coords;
716 if ( num_coords > blend->num_axis )
717 {
718 FT_TRACE2(( "T1_Get_Var_Design:"
719 " only using first %d of %d coordinates\n",
720 blend->num_axis, num_coords ));
721 nc = blend->num_axis;
722 }
723
724 for ( i = 0; i < nc; i++ )
725 coords[i] = mm_axis_unmap( &blend->design_map[i], axiscoords[i] );
726 for ( ; i < num_coords; i++ )
727 coords[i] = 0;
728
729 return FT_Err_Ok;
730 }

◆ t1_init_loader()

static void t1_init_loader ( T1_Loader  loader,
T1_Face  face 
)
static

Definition at line 2466 of file t1load.c.

2468 {
2469 FT_UNUSED( face );
2470
2471 FT_ZERO( loader );
2472 }
#define FT_ZERO(p)
Definition: ftmemory.h:246

Referenced by T1_Open_Face().

◆ t1_load_keyword()

static FT_Error t1_load_keyword ( T1_Face  face,
T1_Loader  loader,
const T1_Field  field 
)
static

Definition at line 1199 of file t1load.c.

1202 {
1204 void* dummy_object;
1205 void** objects;
1206 FT_UInt max_objects;
1207 PS_Blend blend = face->blend;
1208
1209
1210 if ( blend && blend->num_designs == 0 )
1211 blend = NULL;
1212
1213 /* if the keyword has a dedicated callback, call it */
1215 {
1216 FT_TRACE4(( " %s", field->ident ));
1217
1218 field->reader( (FT_Face)face, loader );
1219 error = loader->parser.root.error;
1220 goto Exit;
1221 }
1222
1223 /* now, the keyword is either a simple field, or a table of fields; */
1224 /* we are now going to take care of it */
1225 switch ( field->location )
1226 {
1228 dummy_object = &face->type1.font_info;
1229 objects = &dummy_object;
1230 max_objects = 0;
1231
1232 if ( blend )
1233 {
1234 objects = (void**)blend->font_infos;
1235 max_objects = blend->num_designs;
1236 }
1237 break;
1238
1240 dummy_object = &face->type1.font_extra;
1241 objects = &dummy_object;
1242 max_objects = 0;
1243 break;
1244
1246 dummy_object = &face->type1.private_dict;
1247 objects = &dummy_object;
1248 max_objects = 0;
1249
1250 if ( blend )
1251 {
1252 objects = (void**)blend->privates;
1253 max_objects = blend->num_designs;
1254 }
1255 break;
1256
1258 dummy_object = &face->type1.font_bbox;
1259 objects = &dummy_object;
1260 max_objects = 0;
1261
1262 if ( blend )
1263 {
1264 objects = (void**)blend->bboxes;
1265 max_objects = blend->num_designs;
1266 }
1267 break;
1268
1270 dummy_object = loader;
1271 objects = &dummy_object;
1272 max_objects = 0;
1273 break;
1274
1276 dummy_object = face;
1277 objects = &dummy_object;
1278 max_objects = 0;
1279 break;
1280
1281#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
1283 dummy_object = face->blend;
1284 objects = &dummy_object;
1285 max_objects = 0;
1286 break;
1287#endif
1288
1289 default:
1290 dummy_object = &face->type1;
1291 objects = &dummy_object;
1292 max_objects = 0;
1293 }
1294
1295 FT_TRACE4(( " %s", field->ident ));
1296
1297 if ( *objects )
1298 {
1301 error = T1_Load_Field_Table( &loader->parser, field,
1302 objects, max_objects, 0 );
1303 else
1304 error = T1_Load_Field( &loader->parser, field,
1305 objects, max_objects, 0 );
1306 }
1307 else
1308 {
1309 FT_TRACE1(( "t1_load_keyword: ignoring keyword `%s'"
1310 " which is not valid at this point\n"
1311 " (probably due to missing keywords)\n",
1312 field->ident ));
1313 error = FT_Err_Ok;
1314 }
1315
1316 FT_TRACE4(( "\n" ));
1317
1318 Exit:
1319 return error;
1320 }
WORD face[3]
Definition: mesh.c:4747
static const CLSID * objects[]
Definition: apphelp.c:112
@ T1_FIELD_TYPE_INTEGER_ARRAY
Definition: psaux.h:220
@ T1_FIELD_TYPE_CALLBACK
Definition: psaux.h:222
@ T1_FIELD_TYPE_FIXED_ARRAY
Definition: psaux.h:221
@ T1_FIELD_LOCATION_FONT_EXTRA
Definition: psaux.h:234
@ T1_FIELD_LOCATION_BLEND
Definition: psaux.h:240
@ T1_FIELD_LOCATION_BBOX
Definition: psaux.h:237
@ T1_FIELD_LOCATION_PRIVATE
Definition: psaux.h:236
@ T1_FIELD_LOCATION_LOADER
Definition: psaux.h:238
@ T1_FIELD_LOCATION_FONT_INFO
Definition: psaux.h:235
@ T1_FIELD_LOCATION_FACE
Definition: psaux.h:239
Definition: parser.c:44
#define T1_Load_Field(p, f, o, m, pf)
Definition: t1parse.h:111
#define T1_Load_Field_Table(p, f, o, m, pf)
Definition: t1parse.h:114

Referenced by parse_dict().

◆ T1_Open_Face()

T1_Open_Face ( T1_Face  face)

Definition at line 2499 of file t1load.c.

2500 {
2501 T1_LoaderRec loader;
2503 T1_Font type1 = &face->type1;
2504 PS_Private priv = &type1->private_dict;
2506
2507 PSAux_Service psaux = (PSAux_Service)face->psaux;
2508
2509
2510 t1_init_loader( &loader, face );
2511
2512 /* default values */
2513 face->ndv_idx = -1;
2514 face->cdv_idx = -1;
2515 face->len_buildchar = 0;
2516
2517 priv->blue_shift = 7;
2518 priv->blue_fuzz = 1;
2519 priv->lenIV = 4;
2520 priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
2521 priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
2522
2523 parser = &loader.parser;
2525 face->root.stream,
2526 face->root.memory,
2527 psaux );
2528 if ( error )
2529 goto Exit;
2530
2531 FT_TRACE4(( " top dictionary:\n" ));
2532 error = parse_dict( face, &loader,
2533 parser->base_dict, parser->base_len );
2534 if ( error )
2535 goto Exit;
2536
2537 error = T1_Get_Private_Dict( parser, psaux );
2538 if ( error )
2539 goto Exit;
2540
2541 FT_TRACE4(( " private dictionary:\n" ));
2542 error = parse_dict( face, &loader,
2543 parser->private_dict, parser->private_len );
2544 if ( error )
2545 goto Exit;
2546
2547 /* ensure even-ness of `num_blue_values' */
2548 priv->num_blue_values &= ~1;
2549
2550#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
2551
2552 /* we don't support Multiple Master fonts with intermediate designs; */
2553 /* this implies that `num_designs' must be equal to `2^^num_axis' */
2554 if ( face->blend &&
2555 face->blend->num_designs != ( 1U << face->blend->num_axis ) )
2556 {
2557 FT_ERROR(( "T1_Open_Face:"
2558 " number-of-designs != 2 ^^ number-of-axes\n" ));
2560 }
2561
2562 if ( face->blend &&
2563 face->blend->num_default_design_vector != 0 &&
2564 face->blend->num_default_design_vector != face->blend->num_axis )
2565 {
2566 /* we don't use it currently so just warn, reset, and ignore */
2567 FT_ERROR(( "T1_Open_Face(): /DesignVector contains %u entries "
2568 "while there are %u axes.\n",
2569 face->blend->num_default_design_vector,
2570 face->blend->num_axis ));
2571
2572 face->blend->num_default_design_vector = 0;
2573 }
2574
2575 /* the following can happen for MM instances; we then treat the */
2576 /* font as a normal PS font */
2577 if ( face->blend &&
2578 ( !face->blend->num_designs || !face->blend->num_axis ) )
2580
2581 /* another safety check */
2582 if ( face->blend )
2583 {
2584 FT_UInt i;
2585
2586
2587 for ( i = 0; i < face->blend->num_axis; i++ )
2588 if ( !face->blend->design_map[i].num_points )
2589 {
2591 break;
2592 }
2593 }
2594
2595 if ( face->blend )
2596 {
2597 if ( face->len_buildchar > 0 )
2598 {
2599 FT_Memory memory = face->root.memory;
2600
2601
2602 if ( FT_NEW_ARRAY( face->buildchar, face->len_buildchar ) )
2603 {
2604 FT_ERROR(( "T1_Open_Face: cannot allocate BuildCharArray\n" ));
2605 face->len_buildchar = 0;
2606 goto Exit;
2607 }
2608 }
2609 }
2610 else
2611 face->len_buildchar = 0;
2612
2613#endif /* !T1_CONFIG_OPTION_NO_MM_SUPPORT */
2614
2615 /* now, propagate the subrs, charstrings, and glyphnames tables */
2616 /* to the Type1 data */
2617 type1->num_glyphs = loader.num_glyphs;
2618
2619 if ( loader.subrs.init )
2620 {
2621 type1->num_subrs = loader.num_subrs;
2622 type1->subrs_block = loader.subrs.block;
2623 type1->subrs = loader.subrs.elements;
2624 type1->subrs_len = loader.subrs.lengths;
2625 type1->subrs_hash = loader.subrs_hash;
2626
2627 /* prevent `t1_done_loader' from freeing the propagated data */
2628 loader.subrs.init = 0;
2629 loader.subrs_hash = NULL;
2630 }
2631
2632 if ( !IS_INCREMENTAL )
2633 if ( !loader.charstrings.init )
2634 {
2635 FT_ERROR(( "T1_Open_Face: no `/CharStrings' array in face\n" ));
2636 error = FT_THROW( Invalid_File_Format );
2637 }
2638
2639 loader.charstrings.init = 0;
2640 type1->charstrings_block = loader.charstrings.block;
2641 type1->charstrings = loader.charstrings.elements;
2642 type1->charstrings_len = loader.charstrings.lengths;
2643
2644 /* we copy the glyph names `block' and `elements' fields; */
2645 /* the `lengths' field must be released later */
2646 type1->glyph_names_block = loader.glyph_names.block;
2647 type1->glyph_names = (FT_String**)loader.glyph_names.elements;
2648 loader.glyph_names.block = NULL;
2649 loader.glyph_names.elements = NULL;
2650
2651 /* we must now build type1.encoding when we have a custom array */
2653 {
2654 FT_Int charcode, idx, min_char, max_char;
2655
2656
2657 /* OK, we do the following: for each element in the encoding */
2658 /* table, look up the index of the glyph having the same name */
2659 /* the index is then stored in type1.encoding.char_index, and */
2660 /* the name to type1.encoding.char_name */
2661
2662 min_char = 0;
2663 max_char = 0;
2664
2665 charcode = 0;
2666 for ( ; charcode < loader.encoding_table.max_elems; charcode++ )
2667 {
2668 const FT_String* char_name =
2669 (const FT_String*)loader.encoding_table.elements[charcode];
2670
2671
2672 type1->encoding.char_index[charcode] = 0;
2673 type1->encoding.char_name [charcode] = ".notdef";
2674
2675 if ( char_name )
2676 for ( idx = 0; idx < type1->num_glyphs; idx++ )
2677 {
2678 const FT_String* glyph_name = type1->glyph_names[idx];
2679
2680
2681 if ( ft_strcmp( char_name, glyph_name ) == 0 )
2682 {
2683 type1->encoding.char_index[charcode] = (FT_UShort)idx;
2684 type1->encoding.char_name [charcode] = glyph_name;
2685
2686 /* Change min/max encoded char only if glyph name is */
2687 /* not /.notdef */
2688 if ( ft_strcmp( ".notdef", glyph_name ) != 0 )
2689 {
2690 if ( charcode < min_char )
2691 min_char = charcode;
2692 if ( charcode >= max_char )
2693 max_char = charcode + 1;
2694 }
2695 break;
2696 }
2697 }
2698 }
2699
2700 type1->encoding.code_first = min_char;
2701 type1->encoding.code_last = max_char;
2702 type1->encoding.num_chars = loader.num_chars;
2703 }
2704
2705 /* some sanitizing to avoid overflows later on; */
2706 /* the upper limits are ad-hoc values */
2707 if ( priv->blue_shift > 1000 || priv->blue_shift < 0 )
2708 {
2709 FT_TRACE2(( "T1_Open_Face:"
2710 " setting unlikely BlueShift value %d to default (7)\n",
2711 priv->blue_shift ));
2712 priv->blue_shift = 7;
2713 }
2714
2715 if ( priv->blue_fuzz > 1000 || priv->blue_fuzz < 0 )
2716 {
2717 FT_TRACE2(( "T1_Open_Face:"
2718 " setting unlikely BlueFuzz value %d to default (1)\n",
2719 priv->blue_fuzz ));
2720 priv->blue_fuzz = 1;
2721 }
2722
2723 Exit:
2724 t1_done_loader( &loader );
2725 return error;
2726 }
char FT_String
Definition: fttypes.h:187
FT_Int blue_fuzz
Definition: t1tables.h:154
FT_Fixed expansion_factor
Definition: t1tables.h:167
FT_Int lenIV
Definition: t1tables.h:139
FT_Int blue_shift
Definition: t1tables.h:153
FT_Byte num_blue_values
Definition: t1tables.h:141
FT_Fixed blue_scale
Definition: t1tables.h:152
PS_PrivateRec private_dict
Definition: t1types.h:100
T1_EncodingType encoding_type
Definition: t1types.h:103
FT_Byte * subrs_block
Definition: t1types.h:106
FT_Byte ** subrs
Definition: t1types.h:111
FT_Int num_glyphs
Definition: t1types.h:115
FT_UInt * charstrings_len
Definition: t1types.h:118
FT_String ** glyph_names
Definition: t1types.h:116
T1_EncodingRec encoding
Definition: t1types.h:104
FT_Int num_subrs
Definition: t1types.h:110
FT_Byte * charstrings_block
Definition: t1types.h:107
FT_Hash subrs_hash
Definition: t1types.h:113
FT_Byte ** charstrings
Definition: t1types.h:117
FT_UInt * subrs_len
Definition: t1types.h:112
FT_Byte * glyph_names_block
Definition: t1types.h:108
static void t1_init_loader(T1_Loader loader, T1_Face face)
Definition: t1load.c:2466
T1_Done_Blend(T1_Face face)
Definition: t1load.c:734
static void t1_done_loader(T1_Loader loader)
Definition: t1load.c:2476
static FT_Error parse_dict(T1_Face face, T1_Loader loader, FT_Byte *base, FT_ULong size)
Definition: t1load.c:2268
FT_BEGIN_HEADER struct T1_Loader_ T1_LoaderRec
T1_New_Parser(T1_Parser parser, FT_Stream stream, FT_Memory memory, PSAux_Service psaux)
Definition: t1parse.c:135
T1_Get_Private_Dict(T1_Parser parser, PSAux_Service psaux)
Definition: t1parse.c:260

Referenced by T1_Face_Init().

◆ t1_parse_font_matrix()

static void t1_parse_font_matrix ( T1_Face  face,
T1_Loader  loader 
)
static

Definition at line 1390 of file t1load.c.

1392 {
1393 T1_Parser parser = &loader->parser;
1394 FT_Matrix* matrix = &face->type1.font_matrix;
1395 FT_Vector* offset = &face->type1.font_offset;
1396 FT_Face root = (FT_Face)&face->root;
1397 FT_Fixed temp[6];
1398 FT_Fixed temp_scale;
1399 FT_Int result;
1400
1401
1402 /* input is scaled by 1000 to accommodate default FontMatrix */
1403 result = T1_ToFixedArray( parser, 6, temp, 3 );
1404
1405 if ( result < 6 )
1406 {
1407 parser->root.error = FT_THROW( Invalid_File_Format );
1408 return;
1409 }
1410
1411 FT_TRACE4(( " [%f %f %f %f %f %f]\n",
1412 (double)temp[0] / 65536 / 1000,
1413 (double)temp[1] / 65536 / 1000,
1414 (double)temp[2] / 65536 / 1000,
1415 (double)temp[3] / 65536 / 1000,
1416 (double)temp[4] / 65536 / 1000,
1417 (double)temp[5] / 65536 / 1000 ));
1418
1419 temp_scale = FT_ABS( temp[3] );
1420
1421 if ( temp_scale == 0 )
1422 {
1423 FT_ERROR(( "t1_parse_font_matrix: invalid font matrix\n" ));
1424 parser->root.error = FT_THROW( Invalid_File_Format );
1425 return;
1426 }
1427
1428 /* atypical case */
1429 if ( temp_scale != 0x10000L )
1430 {
1431 /* set units per EM based on FontMatrix values */
1432 root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale );
1433
1434 temp[0] = FT_DivFix( temp[0], temp_scale );
1435 temp[1] = FT_DivFix( temp[1], temp_scale );
1436 temp[2] = FT_DivFix( temp[2], temp_scale );
1437 temp[4] = FT_DivFix( temp[4], temp_scale );
1438 temp[5] = FT_DivFix( temp[5], temp_scale );
1439 temp[3] = temp[3] < 0 ? -0x10000L : 0x10000L;
1440 }
1441 matrix->xx = temp[0];
1442 matrix->yx = temp[1];
1443 matrix->xy = temp[2];
1444 matrix->yy = temp[3];
1445
1446 if ( !FT_Matrix_Check( matrix ) )
1447 {
1448 FT_ERROR(( "t1_parse_font_matrix: invalid font matrix\n" ));
1449 parser->root.error = FT_THROW( Invalid_File_Format );
1450 return;
1451 }
1452
1453 /* note that the offsets must be expressed in integer font units */
1454 offset->x = temp[4] >> 16;
1455 offset->y = temp[5] >> 16;
1456 }
struct FT_FaceRec_ * FT_Face
Definition: freetype.h:483
FT_Matrix_Check(const FT_Matrix *matrix)
Definition: ftcalc.c:750
#define FT_ABS(a)
Definition: ftobjs.h:73
GLintptr offset
Definition: glext.h:5920
GLuint GLenum matrix
Definition: glext.h:9407
GLuint64EXT * result
Definition: glext.h:11304

◆ T1_Reset_MM_Blend()

T1_Reset_MM_Blend ( T1_Face  face,
FT_UInt  instance_index 
)

Definition at line 664 of file t1load.c.

666 {
667 FT_UNUSED( instance_index );
668
669 return T1_Set_MM_Blend( face, 0, NULL );
670 }
T1_Set_MM_Blend(T1_Face face, FT_UInt num_coords, FT_Fixed *coords)
Definition: t1load.c:452

◆ t1_set_mm_blend()

static FT_Error t1_set_mm_blend ( T1_Face  face,
FT_UInt  num_coords,
FT_Fixed coords 
)
static

Definition at line 391 of file t1load.c.

394 {
395 PS_Blend blend = face->blend;
396 FT_UInt n, m;
397
398 FT_Bool have_diff = 0;
399
400
401 if ( !blend )
402 return FT_THROW( Invalid_Argument );
403
404 if ( num_coords > blend->num_axis )
405 num_coords = blend->num_axis;
406
407 /* recompute the weight vector from the blend coordinates */
408 for ( n = 0; n < blend->num_designs; n++ )
409 {
410 FT_Fixed result = 0x10000L; /* 1.0 fixed */
412
413
414 for ( m = 0; m < blend->num_axis; m++ )
415 {
416 /* use a default value if we don't have a coordinate */
417 if ( m >= num_coords )
418 {
419 result >>= 1;
420 continue;
421 }
422
423 /* get current blend axis position */
424 factor = coords[m];
425 if ( ( n & ( 1 << m ) ) == 0 )
426 factor = 0x10000L - factor;
427
428 if ( factor <= 0 )
429 {
430 result = 0;
431 break;
432 }
433 else if ( factor >= 0x10000L )
434 continue;
435
437 }
438
439 if ( blend->weight_vector[n] != result )
440 {
441 blend->weight_vector[n] = result;
442 have_diff = 1;
443 }
444 }
445
446 /* return value -1 indicates `no change' */
447 return have_diff ? FT_Err_Ok : -1;
448 }
FT_MulFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:508
const GLfloat * m
Definition: glext.h:10848
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint factor
Definition: glfuncs.h:178

Referenced by T1_Set_MM_Blend(), and T1_Set_MM_Design().

◆ T1_Set_MM_Blend()

T1_Set_MM_Blend ( T1_Face  face,
FT_UInt  num_coords,
FT_Fixed coords 
)

Definition at line 452 of file t1load.c.

455 {
457
458
459 error = t1_set_mm_blend( face, num_coords, coords );
460 if ( error )
461 return error;
462
463 if ( num_coords )
464 face->root.face_flags |= FT_FACE_FLAG_VARIATION;
465 else
466 face->root.face_flags &= ~FT_FACE_FLAG_VARIATION;
467
468 return FT_Err_Ok;
469 }
#define FT_FACE_FLAG_VARIATION
Definition: freetype.h:1212
static FT_Error t1_set_mm_blend(T1_Face face, FT_UInt num_coords, FT_Fixed *coords)
Definition: t1load.c:391

Referenced by T1_Reset_MM_Blend().

◆ T1_Set_MM_Design()

T1_Set_MM_Design ( T1_Face  face,
FT_UInt  num_coords,
FT_Long coords 
)

Definition at line 577 of file t1load.c.

580 {
582 PS_Blend blend = face->blend;
583 FT_UInt n, p;
584 FT_Fixed final_blends[T1_MAX_MM_DESIGNS];
585
586
587 if ( !blend )
588 return FT_THROW( Invalid_Argument );
589
590 if ( num_coords > blend->num_axis )
591 num_coords = blend->num_axis;
592
593 /* compute the blend coordinates through the blend design map */
594
595 for ( n = 0; n < blend->num_axis; n++ )
596 {
597 FT_Long design;
598 FT_Fixed the_blend;
599 PS_DesignMap map = blend->design_map + n;
600 FT_Long* designs = map->design_points;
601 FT_Fixed* blends = map->blend_points;
602 FT_Int before = -1, after = -1;
603
604
605 /* use a default value if we don't have a coordinate */
606 if ( n < num_coords )
607 design = coords[n];
608 else
609 design = ( designs[map->num_points - 1] - designs[0] ) / 2;
610
611 for ( p = 0; p < (FT_UInt)map->num_points; p++ )
612 {
613 FT_Long p_design = designs[p];
614
615
616 /* exact match? */
617 if ( design == p_design )
618 {
619 the_blend = blends[p];
620 goto Found;
621 }
622
623 if ( design < p_design )
624 {
625 after = (FT_Int)p;
626 break;
627 }
628
629 before = (FT_Int)p;
630 }
631
632 /* now interpolate if necessary */
633 if ( before < 0 )
634 the_blend = blends[0];
635
636 else if ( after < 0 )
637 the_blend = blends[map->num_points - 1];
638
639 else
640 the_blend = FT_MulDiv( design - designs[before],
641 blends [after] - blends [before],
642 designs[after] - designs[before] );
643
644 Found:
645 final_blends[n] = the_blend;
646 }
647
648 error = t1_set_mm_blend( face, blend->num_axis, final_blends );
649 if ( error )
650 return error;
651
652 if ( num_coords )
653 face->root.face_flags |= FT_FACE_FLAG_VARIATION;
654 else
655 face->root.face_flags &= ~FT_FACE_FLAG_VARIATION;
656
657 return FT_Err_Ok;
658 }
return Found
Definition: dirsup.c:1270
FT_MulDiv(FT_Long a, FT_Long b, FT_Long c)
Definition: ftcalc.c:415
__inline int before(__u32 seq1, __u32 seq2)
Definition: tcpcore.h:2390
__inline int after(__u32 seq1, __u32 seq2)
Definition: tcpcore.h:2395

Referenced by T1_Set_Var_Design().

◆ T1_Set_MM_WeightVector()

T1_Set_MM_WeightVector ( T1_Face  face,
FT_UInt  len,
FT_Fixed weightvector 
)

Definition at line 508 of file t1load.c.

511 {
512 PS_Blend blend = face->blend;
513 FT_UInt i, n;
514
515
516 if ( !blend )
517 return FT_THROW( Invalid_Argument );
518
519 if ( !len && !weightvector )
520 {
521 for ( i = 0; i < blend->num_designs; i++ )
522 blend->weight_vector[i] = blend->default_weight_vector[i];
523 }
524 else
525 {
526 if ( !weightvector )
527 return FT_THROW( Invalid_Argument );
528
529 n = len < blend->num_designs ? len : blend->num_designs;
530
531 for ( i = 0; i < n; i++ )
532 blend->weight_vector[i] = weightvector[i];
533
534 for ( ; i < blend->num_designs; i++ )
535 blend->weight_vector[i] = (FT_Fixed)0;
536
537 if ( len )
538 face->root.face_flags |= FT_FACE_FLAG_VARIATION;
539 else
540 face->root.face_flags &= ~FT_FACE_FLAG_VARIATION;
541 }
542
543 return FT_Err_Ok;
544 }

◆ T1_Set_Var_Design()

T1_Set_Var_Design ( T1_Face  face,
FT_UInt  num_coords,
FT_Fixed coords 
)

Definition at line 679 of file t1load.c.

682 {
683 FT_Long lcoords[T1_MAX_MM_AXIS];
684 FT_UInt i;
685
686
687 if ( num_coords > T1_MAX_MM_AXIS )
688 num_coords = T1_MAX_MM_AXIS;
689
690 for ( i = 0; i < num_coords; i++ )
691 lcoords[i] = FIXED_TO_INT( coords[i] );
692
693 return T1_Set_MM_Design( face, num_coords, lcoords );
694 }
#define FIXED_TO_INT(x)
Definition: ftcalc.h:450
T1_Set_MM_Design(T1_Face face, FT_UInt num_coords, FT_Long *coords)
Definition: t1load.c:577

Variable Documentation

◆ t1_keywords

const T1_FieldRec t1_keywords[]
static

Definition at line 2233 of file t1load.c.

Referenced by parse_dict().