ReactOS 0.4.15-dev-7934-g1dc8d80
t1load.c File Reference
#include <ft2build.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   trace_t1load
 
#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_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

◆ FT_COMPONENT

#define FT_COMPONENT   trace_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 1706 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:608
#define INT_TO_FIXED(x)
Definition: ftcalc.h:404
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:288
FT_Fixed * blend_points
Definition: t1tables.h:290
FT_Long * design_points
Definition: t1tables.h:289

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:211
const GLbyte * weights
Definition: glext.h:6523
#define T1_MAX_MM_AXIS
Definition: t1tables.h:279

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 691 of file t1load.c.

693 {
694 T1_TokenRec axis_tokens[T1_MAX_MM_AXIS];
695 FT_Int n, num_axis;
697 PS_Blend blend;
699
700
701 /* take an array of objects */
702 T1_ToTokenArray( &loader->parser, axis_tokens,
703 T1_MAX_MM_AXIS, &num_axis );
704 if ( num_axis < 0 )
705 {
706 error = FT_ERR( Ignore );
707 goto Exit;
708 }
709 if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS )
710 {
711 FT_ERROR(( "parse_blend_axis_types: incorrect number of axes: %d\n",
712 num_axis ));
713 error = FT_THROW( Invalid_File_Format );
714 goto Exit;
715 }
716
717 /* allocate blend if necessary */
718 error = t1_allocate_blend( face, 0, (FT_UInt)num_axis );
719 if ( error )
720 goto Exit;
721
722 blend = face->blend;
723 memory = face->root.memory;
724
725 /* each token is an immediate containing the name of the axis */
726 for ( n = 0; n < num_axis; n++ )
727 {
728 T1_Token token = axis_tokens + n;
729 FT_Byte* name;
730 FT_UInt len;
731
732
733 /* skip first slash, if any */
734 if ( token->start[0] == '/' )
735 token->start++;
736
737 len = (FT_UInt)( token->limit - token->start );
738 if ( len == 0 )
739 {
740 error = FT_THROW( Invalid_File_Format );
741 goto Exit;
742 }
743
744 name = (FT_Byte*)blend->axis_names[n];
745 if ( name )
746 {
747 FT_TRACE0(( "parse_blend_axis_types:"
748 " overwriting axis name `%s' with `%*.s'\n",
749 name, len, token->start ));
750 FT_FREE( name );
751 }
752
753 if ( FT_ALLOC( blend->axis_names[n], len + 1 ) )
754 goto Exit;
755
756 name = (FT_Byte*)blend->axis_names[n];
757 FT_MEM_COPY( name, token->start, len );
758 name[len] = '\0';
759 }
760
761 Exit:
762 loader->parser.root.error = error;
763 }
return FT_Err_Ok
Definition: ftbbox.c:511
#define FT_TRACE0(varformat)
Definition: ftdebug.h:157
#define FT_ERROR(varformat)
Definition: ftdebug.h:181
#define FT_THROW(e)
Definition: ftdebug.h:213
#define FT_ALLOC(ptr, size)
Definition: ftmemory.h:303
#define FT_FREE(ptr)
Definition: ftmemory.h:329
#define FT_MEM_COPY(dest, source, count)
Definition: ftmemory.h:228
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
unsigned char FT_Byte
Definition: fttypes.h:154
int FT_Error
Definition: fttypes.h:300
#define FT_ERR(e)
Definition: fttypes.h:586
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:116
static void Exit(void)
Definition: sock.c:1330
FT_String * axis_names[T1_MAX_MM_AXIS]
Definition: t1tables.h:303
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:100

◆ parse_blend_design_map()

static void parse_blend_design_map ( T1_Face  face,
T1_Loader  loader 
)
static

Definition at line 866 of file t1load.c.

868 {
870 T1_Parser parser = &loader->parser;
871 PS_Blend blend;
872 T1_TokenRec axis_tokens[T1_MAX_MM_AXIS];
873 FT_Int n, num_axis;
874 FT_Byte* old_cursor;
875 FT_Byte* old_limit;
876 FT_Memory memory = face->root.memory;
877
878
879 T1_ToTokenArray( parser, axis_tokens,
880 T1_MAX_MM_AXIS, &num_axis );
881 if ( num_axis < 0 )
882 {
883 error = FT_ERR( Ignore );
884 goto Exit;
885 }
886 if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS )
887 {
888 FT_ERROR(( "parse_blend_design_map: incorrect number of axes: %d\n",
889 num_axis ));
890 error = FT_THROW( Invalid_File_Format );
891 goto Exit;
892 }
893
894 old_cursor = parser->root.cursor;
895 old_limit = parser->root.limit;
896
897 error = t1_allocate_blend( face, 0, (FT_UInt)num_axis );
898 if ( error )
899 goto Exit;
900 blend = face->blend;
901
902 /* now read each axis design map */
903 for ( n = 0; n < num_axis; n++ )
904 {
905 PS_DesignMap map = blend->design_map + n;
906 T1_Token axis_token;
907 T1_TokenRec point_tokens[T1_MAX_MM_MAP_POINTS];
908 FT_Int p, num_points;
909
910
911 axis_token = axis_tokens + n;
912
913 parser->root.cursor = axis_token->start;
914 parser->root.limit = axis_token->limit;
915 T1_ToTokenArray( parser, point_tokens,
916 T1_MAX_MM_MAP_POINTS, &num_points );
917
918 if ( num_points <= 0 || num_points > T1_MAX_MM_MAP_POINTS )
919 {
920 FT_ERROR(( "parse_blend_design_map: incorrect table\n" ));
921 error = FT_THROW( Invalid_File_Format );
922 goto Exit;
923 }
924
925 if ( map->design_points )
926 {
927 FT_ERROR(( "parse_blend_design_map: duplicate table\n" ));
928 error = FT_THROW( Invalid_File_Format );
929 goto Exit;
930 }
931
932 /* allocate design map data */
933 if ( FT_NEW_ARRAY( map->design_points, num_points * 2 ) )
934 goto Exit;
935 map->blend_points = map->design_points + num_points;
936 map->num_points = (FT_Byte)num_points;
937
938 for ( p = 0; p < num_points; p++ )
939 {
940 T1_Token point_token;
941
942
943 point_token = point_tokens + p;
944
945 /* don't include delimiting brackets */
946 parser->root.cursor = point_token->start + 1;
947 parser->root.limit = point_token->limit - 1;
948
949 map->design_points[p] = T1_ToInt( parser );
950 map->blend_points [p] = T1_ToFixed( parser, 0 );
951 }
952 }
953
954 parser->root.cursor = old_cursor;
955 parser->root.limit = old_limit;
956
957 Exit:
958 parser->root.error = error;
959 }
Definition: _map.h:48
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:333
GLfloat GLfloat p
Definition: glext.h:8902
PS_DesignMapRec design_map[T1_MAX_MM_AXIS]
Definition: t1tables.h:305
FT_Byte * start
Definition: psaux.h:192
FT_Byte * limit
Definition: psaux.h:193
Definition: import.c:81
unsigned int error
Definition: inffile.c:97
#define T1_ToFixed(p, t)
Definition: t1parse.h:92
FT_BEGIN_HEADER struct T1_ParserRec_ * T1_Parser
#define T1_ToInt(p)
Definition: t1parse.h:91
#define T1_MAX_MM_MAP_POINTS
Definition: t1tables.h:282

◆ parse_blend_design_positions()

static void parse_blend_design_positions ( T1_Face  face,
T1_Loader  loader 
)
static

Definition at line 767 of file t1load.c.

769 {
770 T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS];
771 FT_Int num_designs;
772 FT_Int num_axis;
773 T1_Parser parser = &loader->parser;
774
776 PS_Blend blend;
777
778
779 /* get the array of design tokens -- compute number of designs */
780 T1_ToTokenArray( parser, design_tokens,
781 T1_MAX_MM_DESIGNS, &num_designs );
782 if ( num_designs < 0 )
783 {
784 error = FT_ERR( Ignore );
785 goto Exit;
786 }
787 if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS )
788 {
789 FT_ERROR(( "parse_blend_design_positions:"
790 " incorrect number of designs: %d\n",
791 num_designs ));
792 error = FT_THROW( Invalid_File_Format );
793 goto Exit;
794 }
795
796 {
797 FT_Byte* old_cursor = parser->root.cursor;
798 FT_Byte* old_limit = parser->root.limit;
799 FT_Int n;
800
801
802 blend = face->blend;
803 num_axis = 0; /* make compiler happy */
804
805 for ( n = 0; n < num_designs; n++ )
806 {
807 T1_TokenRec axis_tokens[T1_MAX_MM_AXIS];
809 FT_Int axis, n_axis;
810
811
812 /* read axis/coordinates tokens */
813 token = design_tokens + n;
814 parser->root.cursor = token->start;
815 parser->root.limit = token->limit;
816 T1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &n_axis );
817
818 if ( n == 0 )
819 {
820 if ( n_axis <= 0 || n_axis > T1_MAX_MM_AXIS )
821 {
822 FT_ERROR(( "parse_blend_design_positions:"
823 " invalid number of axes: %d\n",
824 n_axis ));
825 error = FT_THROW( Invalid_File_Format );
826 goto Exit;
827 }
828
829 num_axis = n_axis;
831 (FT_UInt)num_designs,
832 (FT_UInt)num_axis );
833 if ( error )
834 goto Exit;
835 blend = face->blend;
836 }
837 else if ( n_axis != num_axis )
838 {
839 FT_ERROR(( "parse_blend_design_positions: incorrect table\n" ));
840 error = FT_THROW( Invalid_File_Format );
841 goto Exit;
842 }
843
844 /* now read each axis token into the design position */
845 for ( axis = 0; axis < n_axis; axis++ )
846 {
847 T1_Token token2 = axis_tokens + axis;
848
849
850 parser->root.cursor = token2->start;
851 parser->root.limit = token2->limit;
852 blend->design_pos[n][axis] = T1_ToFixed( parser, 0 );
853 }
854 }
855
856 loader->parser.root.cursor = old_cursor;
857 loader->parser.root.limit = old_limit;
858 }
859
860 Exit:
861 loader->parser.root.error = error;
862 }
FT_Fixed * design_pos[T1_MAX_MM_DESIGNS]
Definition: t1tables.h:304
#define T1_MAX_MM_DESIGNS
Definition: t1tables.h:276

◆ parse_buildchar()

static void parse_buildchar ( T1_Face  face,
T1_Loader  loader 
)
static

Definition at line 1034 of file t1load.c.

1036 {
1037 face->len_buildchar = (FT_UInt)T1_ToFixedArray( &loader->parser,
1038 0, NULL, 0 );
1039 return;
1040 }
#define NULL
Definition: types.h:112
#define T1_ToFixedArray(p, m, f, t)
Definition: t1parse.h:96

◆ parse_charstrings()

static void parse_charstrings ( T1_Face  face,
T1_Loader  loader 
)
static

Definition at line 1710 of file t1load.c.

1712 {
1713 T1_Parser parser = &loader->parser;
1714 PS_Table code_table = &loader->charstrings;
1715 PS_Table name_table = &loader->glyph_names;
1716 PS_Table swap_table = &loader->swap_table;
1717 FT_Memory memory = parser->root.memory;
1719
1720 PSAux_Service psaux = (PSAux_Service)face->psaux;
1721
1722 FT_Byte* cur = parser->root.cursor;
1723 FT_Byte* limit = parser->root.limit;
1724 FT_Int n, num_glyphs;
1725 FT_Int notdef_index = 0;
1726 FT_Byte notdef_found = 0;
1727
1728
1729 num_glyphs = (FT_Int)T1_ToInt( parser );
1730 if ( num_glyphs < 0 )
1731 {
1732 error = FT_THROW( Invalid_File_Format );
1733 goto Fail;
1734 }
1735
1736 /* we certainly need more than 8 bytes per glyph */
1737 if ( num_glyphs > ( limit - cur ) >> 3 )
1738 {
1739 FT_TRACE0(( "parse_charstrings: adjusting number of glyphs"
1740 " (from %d to %d)\n",
1741 num_glyphs, ( limit - cur ) >> 3 ));
1742 num_glyphs = ( limit - cur ) >> 3;
1743 }
1744
1745 /* some fonts like Optima-Oblique not only define the /CharStrings */
1746 /* array but access it also */
1747 if ( num_glyphs == 0 || parser->root.error )
1748 return;
1749
1750 /* initialize tables, leaving space for addition of .notdef, */
1751 /* if necessary, and a few other glyphs to handle buggy */
1752 /* fonts which have more glyphs than specified. */
1753
1754 /* for some non-standard fonts like `Optima' which provides */
1755 /* different outlines depending on the resolution it is */
1756 /* possible to get here twice */
1757 if ( !loader->num_glyphs )
1758 {
1759 error = psaux->ps_table_funcs->init(
1760 code_table, num_glyphs + 1 + TABLE_EXTEND, memory );
1761 if ( error )
1762 goto Fail;
1763
1764 error = psaux->ps_table_funcs->init(
1765 name_table, num_glyphs + 1 + TABLE_EXTEND, memory );
1766 if ( error )
1767 goto Fail;
1768
1769 /* Initialize table for swapping index notdef_index and */
1770 /* index 0 names and codes (if necessary). */
1771
1772 error = psaux->ps_table_funcs->init( swap_table, 4, memory );
1773 if ( error )
1774 goto Fail;
1775 }
1776
1777 n = 0;
1778
1779 for (;;)
1780 {
1781 FT_ULong size;
1782 FT_Byte* base;
1783
1784
1785 /* the format is simple: */
1786 /* `/glyphname' + binary data */
1787
1789
1790 cur = parser->root.cursor;
1791 if ( cur >= limit )
1792 break;
1793
1794 /* we stop when we find a `def' or `end' keyword */
1795 if ( cur + 3 < limit && IS_PS_DELIM( cur[3] ) )
1796 {
1797 if ( cur[0] == 'd' &&
1798 cur[1] == 'e' &&
1799 cur[2] == 'f' )
1800 {
1801 /* There are fonts which have this: */
1802 /* */
1803 /* /CharStrings 118 dict def */
1804 /* Private begin */
1805 /* CharStrings begin */
1806 /* ... */
1807 /* */
1808 /* To catch this we ignore `def' if */
1809 /* no charstring has actually been */
1810 /* seen. */
1811 if ( n )
1812 break;
1813 }
1814
1815 if ( cur[0] == 'e' &&
1816 cur[1] == 'n' &&
1817 cur[2] == 'd' )
1818 break;
1819 }
1820
1822 if ( parser->root.cursor >= limit )
1823 {
1824 error = FT_THROW( Invalid_File_Format );
1825 goto Fail;
1826 }
1827 if ( parser->root.error )
1828 return;
1829
1830 if ( *cur == '/' )
1831 {
1832 FT_UInt len;
1833
1834
1835 if ( cur + 2 >= limit )
1836 {
1837 error = FT_THROW( Invalid_File_Format );
1838 goto Fail;
1839 }
1840
1841 cur++; /* skip `/' */
1842 len = (FT_UInt)( parser->root.cursor - cur );
1843
1845 return;
1846
1847 /* for some non-standard fonts like `Optima' which provides */
1848 /* different outlines depending on the resolution it is */
1849 /* possible to get here twice */
1850 if ( loader->num_glyphs )
1851 continue;
1852
1853 error = T1_Add_Table( name_table, n, cur, len + 1 );
1854 if ( error )
1855 goto Fail;
1856
1857 /* add a trailing zero to the name table */
1858 name_table->elements[n][len] = '\0';
1859
1860 /* record index of /.notdef */
1861 if ( *cur == '.' &&
1862 ft_strcmp( ".notdef",
1863 (const char*)(name_table->elements[n]) ) == 0 )
1864 {
1865 notdef_index = n;
1866 notdef_found = 1;
1867 }
1868
1869 if ( face->type1.private_dict.lenIV >= 0 &&
1870 n < num_glyphs + TABLE_EXTEND )
1871 {
1872 FT_Byte* temp = NULL;
1873
1874
1875 if ( size <= (FT_ULong)face->type1.private_dict.lenIV )
1876 {
1877 error = FT_THROW( Invalid_File_Format );
1878 goto Fail;
1879 }
1880
1881 /* t1_decrypt() shouldn't write to base -- make temporary copy */
1882 if ( FT_ALLOC( temp, size ) )
1883 goto Fail;
1885 psaux->t1_decrypt( temp, size, 4330 );
1886 size -= (FT_ULong)face->type1.private_dict.lenIV;
1887 error = T1_Add_Table( code_table, n,
1888 temp + face->type1.private_dict.lenIV, size );
1889 FT_FREE( temp );
1890 }
1891 else
1892 error = T1_Add_Table( code_table, n, base, size );
1893 if ( error )
1894 goto Fail;
1895
1896 n++;
1897 }
1898 }
1899
1900 if ( !n )
1901 {
1902 error = FT_THROW( Invalid_File_Format );
1903 goto Fail;
1904 }
1905
1906 loader->num_glyphs = n;
1907
1908 /* if /.notdef is found but does not occupy index 0, do our magic. */
1909 if ( notdef_found &&
1910 ft_strcmp( ".notdef", (const char*)name_table->elements[0] ) )
1911 {
1912 /* Swap glyph in index 0 with /.notdef glyph. First, add index 0 */
1913 /* name and code entries to swap_table. Then place notdef_index */
1914 /* name and code entries into swap_table. Then swap name and code */
1915 /* entries at indices notdef_index and 0 using values stored in */
1916 /* swap_table. */
1917
1918 /* Index 0 name */
1919 error = T1_Add_Table( swap_table, 0,
1920 name_table->elements[0],
1921 name_table->lengths [0] );
1922 if ( error )
1923 goto Fail;
1924
1925 /* Index 0 code */
1926 error = T1_Add_Table( swap_table, 1,
1927 code_table->elements[0],
1928 code_table->lengths [0] );
1929 if ( error )
1930 goto Fail;
1931
1932 /* Index notdef_index name */
1933 error = T1_Add_Table( swap_table, 2,
1934 name_table->elements[notdef_index],
1935 name_table->lengths [notdef_index] );
1936 if ( error )
1937 goto Fail;
1938
1939 /* Index notdef_index code */
1940 error = T1_Add_Table( swap_table, 3,
1941 code_table->elements[notdef_index],
1942 code_table->lengths [notdef_index] );
1943 if ( error )
1944 goto Fail;
1945
1946 error = T1_Add_Table( name_table, notdef_index,
1947 swap_table->elements[0],
1948 swap_table->lengths [0] );
1949 if ( error )
1950 goto Fail;
1951
1952 error = T1_Add_Table( code_table, notdef_index,
1953 swap_table->elements[1],
1954 swap_table->lengths [1] );
1955 if ( error )
1956 goto Fail;
1957
1958 error = T1_Add_Table( name_table, 0,
1959 swap_table->elements[2],
1960 swap_table->lengths [2] );
1961 if ( error )
1962 goto Fail;
1963
1964 error = T1_Add_Table( code_table, 0,
1965 swap_table->elements[3],
1966 swap_table->lengths [3] );
1967 if ( error )
1968 goto Fail;
1969
1970 }
1971 else if ( !notdef_found )
1972 {
1973 /* notdef_index is already 0, or /.notdef is undefined in */
1974 /* charstrings dictionary. Worry about /.notdef undefined. */
1975 /* We take index 0 and add it to the end of the table(s) */
1976 /* and add our own /.notdef glyph to index 0. */
1977
1978 /* 0 333 hsbw endchar */
1979 FT_Byte notdef_glyph[] = { 0x8B, 0xF7, 0xE1, 0x0D, 0x0E };
1980 char* notdef_name = (char *)".notdef";
1981
1982
1983 error = T1_Add_Table( swap_table, 0,
1984 name_table->elements[0],
1985 name_table->lengths [0] );
1986 if ( error )
1987 goto Fail;
1988
1989 error = T1_Add_Table( swap_table, 1,
1990 code_table->elements[0],
1991 code_table->lengths [0] );
1992 if ( error )
1993 goto Fail;
1994
1995 error = T1_Add_Table( name_table, 0, notdef_name, 8 );
1996 if ( error )
1997 goto Fail;
1998
1999 error = T1_Add_Table( code_table, 0, notdef_glyph, 5 );
2000
2001 if ( error )
2002 goto Fail;
2003
2004 error = T1_Add_Table( name_table, n,
2005 swap_table->elements[0],
2006 swap_table->lengths [0] );
2007 if ( error )
2008 goto Fail;
2009
2010 error = T1_Add_Table( code_table, n,
2011 swap_table->elements[1],
2012 swap_table->lengths [1] );
2013 if ( error )
2014 goto Fail;
2015
2016 /* we added a glyph. */
2017 loader->num_glyphs += 1;
2018 }
2019
2020 return;
2021
2022 Fail:
2023 parser->root.error = error;
2024 }
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:1344
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:1287
const PS_Table_FuncsRec * ps_table_funcs
Definition: psaux.h:1281
FT_Byte ** elements
Definition: psaux.h:150
FT_UInt * lengths
Definition: psaux.h:151
FT_Error(* init)(PS_Table table, FT_Int count, FT_Memory memory)
Definition: psaux.h:87
#define TABLE_EXTEND
Definition: t1load.c:1706
#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:1188
#define T1_Add_Table(p, i, o, l)
Definition: t1parse.h:79
#define T1_Skip_Spaces(p)
Definition: t1parse.h:88
#define T1_Skip_PS_Token(p)
Definition: t1parse.h:89

◆ parse_dict()

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

Definition at line 2071 of file t1load.c.

2075 {
2076 T1_Parser parser = &loader->parser;
2077 FT_Byte *limit, *start_binary = NULL;
2078 FT_Bool have_integer = 0;
2079
2080
2081 parser->root.cursor = base;
2082 parser->root.limit = base + size;
2083 parser->root.error = FT_Err_Ok;
2084
2085 limit = parser->root.limit;
2086
2088
2089 while ( parser->root.cursor < limit )
2090 {
2091 FT_Byte* cur;
2092
2093
2094 cur = parser->root.cursor;
2095
2096 /* look for `eexec' */
2097 if ( IS_PS_TOKEN( cur, limit, "eexec" ) )
2098 break;
2099
2100 /* look for `closefile' which ends the eexec section */
2101 else if ( IS_PS_TOKEN( cur, limit, "closefile" ) )
2102 break;
2103
2104 /* in a synthetic font the base font starts after a */
2105 /* `FontDictionary' token that is placed after a Private dict */
2106 else if ( IS_PS_TOKEN( cur, limit, "FontDirectory" ) )
2107 {
2108 if ( loader->keywords_encountered & T1_PRIVATE )
2109 loader->keywords_encountered |=
2111 parser->root.cursor += 13;
2112 }
2113
2114 /* check whether we have an integer */
2115 else if ( ft_isdigit( *cur ) )
2116 {
2117 start_binary = cur;
2119 if ( parser->root.error )
2120 goto Exit;
2121 have_integer = 1;
2122 }
2123
2124 /* in valid Type 1 fonts we don't see `RD' or `-|' directly */
2125 /* since those tokens are handled by parse_subrs and */
2126 /* parse_charstrings */
2127 else if ( *cur == 'R' && cur + 6 < limit && *(cur + 1) == 'D' &&
2128 have_integer )
2129 {
2130 FT_ULong s;
2131 FT_Byte* b;
2132
2133
2134 parser->root.cursor = start_binary;
2135 if ( !read_binary_data( parser, &s, &b, IS_INCREMENTAL ) )
2136 return FT_THROW( Invalid_File_Format );
2137 have_integer = 0;
2138 }
2139
2140 else if ( *cur == '-' && cur + 6 < limit && *(cur + 1) == '|' &&
2141 have_integer )
2142 {
2143 FT_ULong s;
2144 FT_Byte* b;
2145
2146
2147 parser->root.cursor = start_binary;
2148 if ( !read_binary_data( parser, &s, &b, IS_INCREMENTAL ) )
2149 return FT_THROW( Invalid_File_Format );
2150 have_integer = 0;
2151 }
2152
2153 /* look for immediates */
2154 else if ( *cur == '/' && cur + 2 < limit )
2155 {
2156 FT_UInt len;
2157
2158
2159 cur++;
2160
2161 parser->root.cursor = cur;
2163 if ( parser->root.error )
2164 goto Exit;
2165
2166 len = (FT_UInt)( parser->root.cursor - cur );
2167
2168 if ( len > 0 && len < 22 && parser->root.cursor < limit )
2169 {
2170 /* now compare the immediate name to the keyword table */
2172
2173
2174 for (;;)
2175 {
2176 FT_Byte* name;
2177
2178
2179 name = (FT_Byte*)keyword->ident;
2180 if ( !name )
2181 break;
2182
2183 if ( cur[0] == name[0] &&
2184 len == ft_strlen( (const char *)name ) &&
2185 ft_memcmp( cur, name, len ) == 0 )
2186 {
2187 /* We found it -- run the parsing callback! */
2188 /* We record every instance of every field */
2189 /* (until we reach the base font of a */
2190 /* synthetic font) to deal adequately with */
2191 /* multiple master fonts; this is also */
2192 /* necessary because later PostScript */
2193 /* definitions override earlier ones. */
2194
2195 /* Once we encounter `FontDirectory' after */
2196 /* `/Private', we know that this is a synthetic */
2197 /* font; except for `/CharStrings' we are not */
2198 /* interested in anything that follows this */
2199 /* `FontDirectory'. */
2200
2201 /* MM fonts have more than one /Private token at */
2202 /* the top level; let's hope that all the junk */
2203 /* that follows the first /Private token is not */
2204 /* interesting to us. */
2205
2206 /* According to Adobe Tech Note #5175 (CID-Keyed */
2207 /* Font Installation for ATM Software) a `begin' */
2208 /* must be followed by exactly one `end', and */
2209 /* `begin' -- `end' pairs must be accurately */
2210 /* paired. We could use this to distinguish */
2211 /* between the global Private and the Private */
2212 /* dict that is a member of the Blend dict. */
2213
2214 const FT_UInt dict =
2215 ( loader->keywords_encountered & T1_PRIVATE )
2218
2219 if ( !( dict & keyword->dict ) )
2220 {
2221 FT_TRACE1(( "parse_dict: found `%s' but ignoring it"
2222 " since it is in the wrong dictionary\n",
2223 keyword->ident ));
2224 break;
2225 }
2226
2227 if ( !( loader->keywords_encountered &
2229 ft_strcmp( (const char*)name, "CharStrings" ) == 0 )
2230 {
2232 loader,
2233 keyword );
2234 if ( parser->root.error )
2235 {
2236 if ( FT_ERR_EQ( parser->root.error, Ignore ) )
2237 parser->root.error = FT_Err_Ok;
2238 else
2239 return parser->root.error;
2240 }
2241 }
2242 break;
2243 }
2244
2245 keyword++;
2246 }
2247 }
2248
2249 have_integer = 0;
2250 }
2251 else
2252 {
2254 if ( parser->root.error )
2255 goto Exit;
2256 have_integer = 0;
2257 }
2258
2260 }
2261
2262 Exit:
2263 return parser->root.error;
2264 }
#define FT_TRACE1(varformat)
Definition: ftdebug.h:158
#define ft_isdigit(x)
Definition: ftobjs.h:118
#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:591
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:264
#define T1_FIELD_DICT_PRIVATE
Definition: psaux.h:265
#define IS_PS_TOKEN(cur, limit, token)
Definition: psaux.h:1359
struct T1_FieldRec_ * T1_Field
Definition: psaux.h:171
static FT_Error t1_load_keyword(T1_Face face, T1_Loader loader, const T1_Field field)
Definition: t1load.c:1057
static const T1_FieldRec t1_keywords[]
Definition: t1load.c:2036
#define T1_FONTDIR_AFTER_PRIVATE
Definition: t1load.h:61
#define T1_PRIVATE
Definition: t1load.h:60

Referenced by T1_Open_Face().

◆ parse_encoding()

static void parse_encoding ( T1_Face  face,
T1_Loader  loader 
)
static

Definition at line 1296 of file t1load.c.

1298 {
1299 T1_Parser parser = &loader->parser;
1300 FT_Byte* cur;
1301 FT_Byte* limit = parser->root.limit;
1302
1303 PSAux_Service psaux = (PSAux_Service)face->psaux;
1304
1305
1307 cur = parser->root.cursor;
1308 if ( cur >= limit )
1309 {
1310 FT_ERROR(( "parse_encoding: out of bounds\n" ));
1311 parser->root.error = FT_THROW( Invalid_File_Format );
1312 return;
1313 }
1314
1315 /* if we have a number or `[', the encoding is an array, */
1316 /* and we must load it now */
1317 if ( ft_isdigit( *cur ) || *cur == '[' )
1318 {
1319 T1_Encoding encode = &face->type1.encoding;
1321 PS_Table char_table = &loader->encoding_table;
1322 FT_Memory memory = parser->root.memory;
1324 FT_Bool only_immediates = 0;
1325
1326
1327 /* read the number of entries in the encoding; should be 256 */
1328 if ( *cur == '[' )
1329 {
1330 count = 256;
1331 only_immediates = 1;
1332 parser->root.cursor++;
1333 }
1334 else
1336
1337 array_size = count;
1338 if ( count > 256 )
1339 {
1340 FT_TRACE2(( "parse_encoding:"
1341 " only using first 256 encoding array entries\n" ));
1342 array_size = 256;
1343 }
1344
1346 if ( parser->root.cursor >= limit )
1347 return;
1348
1349 /* PostScript happily allows overwriting of encoding arrays */
1350 if ( encode->char_index )
1351 {
1352 FT_FREE( encode->char_index );
1353 FT_FREE( encode->char_name );
1354 T1_Release_Table( char_table );
1355 }
1356
1357 /* we use a T1_Table to store our charnames */
1358 loader->num_chars = encode->num_chars = array_size;
1359 if ( FT_NEW_ARRAY( encode->char_index, array_size ) ||
1360 FT_NEW_ARRAY( encode->char_name, array_size ) ||
1362 char_table, array_size, memory ) ) )
1363 {
1364 parser->root.error = error;
1365 return;
1366 }
1367
1368 /* We need to `zero' out encoding_table.elements */
1369 for ( n = 0; n < array_size; n++ )
1370 {
1371 char* notdef = (char *)".notdef";
1372
1373
1374 (void)T1_Add_Table( char_table, n, notdef, 8 );
1375 }
1376
1377 /* Now we need to read records of the form */
1378 /* */
1379 /* ... charcode /charname ... */
1380 /* */
1381 /* for each entry in our table. */
1382 /* */
1383 /* We simply look for a number followed by an immediate */
1384 /* name. Note that this ignores correctly the sequence */
1385 /* that is often seen in type1 fonts: */
1386 /* */
1387 /* 0 1 255 { 1 index exch /.notdef put } for dup */
1388 /* */
1389 /* used to clean the encoding array before anything else. */
1390 /* */
1391 /* Alternatively, if the array is directly given as */
1392 /* */
1393 /* /Encoding [ ... ] */
1394 /* */
1395 /* we only read immediates. */
1396
1397 n = 0;
1399
1400 while ( parser->root.cursor < limit )
1401 {
1402 cur = parser->root.cursor;
1403
1404 /* we stop when we encounter a `def' or `]' */
1405 if ( *cur == 'd' && cur + 3 < limit )
1406 {
1407 if ( cur[1] == 'e' &&
1408 cur[2] == 'f' &&
1409 IS_PS_DELIM( cur[3] ) )
1410 {
1411 FT_TRACE6(( "encoding end\n" ));
1412 cur += 3;
1413 break;
1414 }
1415 }
1416 if ( *cur == ']' )
1417 {
1418 FT_TRACE6(( "encoding end\n" ));
1419 cur++;
1420 break;
1421 }
1422
1423 /* check whether we've found an entry */
1424 if ( ft_isdigit( *cur ) || only_immediates )
1425 {
1426 FT_Int charcode;
1427
1428
1429 if ( only_immediates )
1430 charcode = n;
1431 else
1432 {
1433 charcode = (FT_Int)T1_ToInt( parser );
1435
1436 /* protect against invalid charcode */
1437 if ( cur == parser->root.cursor )
1438 {
1439 parser->root.error = FT_THROW( Unknown_File_Format );
1440 return;
1441 }
1442 }
1443
1444 cur = parser->root.cursor;
1445
1446 if ( cur + 2 < limit && *cur == '/' && n < count )
1447 {
1448 FT_UInt len;
1449
1450
1451 cur++;
1452
1453 parser->root.cursor = cur;
1455 if ( parser->root.cursor >= limit )
1456 return;
1457 if ( parser->root.error )
1458 return;
1459
1460 len = (FT_UInt)( parser->root.cursor - cur );
1461
1462 if ( n < array_size )
1463 {
1464 parser->root.error = T1_Add_Table( char_table, charcode,
1465 cur, len + 1 );
1466 if ( parser->root.error )
1467 return;
1468 char_table->elements[charcode][len] = '\0';
1469 }
1470
1471 n++;
1472 }
1473 else if ( only_immediates )
1474 {
1475 /* Since the current position is not updated for */
1476 /* immediates-only mode we would get an infinite loop if */
1477 /* we don't do anything here. */
1478 /* */
1479 /* This encoding array is not valid according to the type1 */
1480 /* specification (it might be an encoding for a CID type1 */
1481 /* font, however), so we conclude that this font is NOT a */
1482 /* type1 font. */
1483 parser->root.error = FT_THROW( Unknown_File_Format );
1484 return;
1485 }
1486 }
1487 else
1488 {
1490 if ( parser->root.error )
1491 return;
1492 }
1493
1495 }
1496
1497 face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY;
1498 parser->root.cursor = cur;
1499 }
1500
1501 /* Otherwise, we should have either `StandardEncoding', */
1502 /* `ExpertEncoding', or `ISOLatin1Encoding' */
1503 else
1504 {
1505 if ( cur + 17 < limit &&
1506 ft_strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 )
1507 face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD;
1508
1509 else if ( cur + 15 < limit &&
1510 ft_strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 )
1511 face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT;
1512
1513 else if ( cur + 18 < limit &&
1514 ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 )
1515 face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1;
1516
1517 else
1518 parser->root.error = FT_ERR( Ignore );
1519 }
1520 }
#define FT_TRACE6(varformat)
Definition: ftdebug.h:163
#define FT_TRACE2(varformat)
Definition: ftdebug.h:159
#define FT_SET_ERROR(expression)
Definition: ftmemory.h:42
#define ft_strncmp
Definition: ftstdlib.h:89
GLuint GLuint GLsizei count
Definition: gl.h:1545
static UINT array_size
Definition: msctf.c:67
#define T1_Release_Table(p)
Definition: t1parse.h:80
@ T1_ENCODING_TYPE_ISOLATIN1
Definition: t1tables.h:565
@ T1_ENCODING_TYPE_STANDARD
Definition: t1tables.h:564
@ T1_ENCODING_TYPE_ARRAY
Definition: t1tables.h:563
@ T1_ENCODING_TYPE_EXPERT
Definition: t1tables.h:566
FT_BEGIN_HEADER struct T1_EncodingRecRec_ * T1_Encoding

◆ parse_private()

static void parse_private ( T1_Face  face,
T1_Loader  loader 
)
static

Definition at line 1176 of file t1load.c.

1178 {
1179 FT_UNUSED( face );
1180
1181 loader->keywords_encountered |= T1_PRIVATE;
1182 }
#define FT_UNUSED(arg)
Definition: ftconfig.h:101

◆ parse_subrs()

static void parse_subrs ( T1_Face  face,
T1_Loader  loader 
)
static

Definition at line 1524 of file t1load.c.

1526 {
1527 T1_Parser parser = &loader->parser;
1528 PS_Table table = &loader->subrs;
1529 FT_Memory memory = parser->root.memory;
1531 FT_Int num_subrs;
1532 FT_UInt count;
1533
1534 PSAux_Service psaux = (PSAux_Service)face->psaux;
1535
1536
1538
1539 /* test for empty array */
1540 if ( parser->root.cursor < parser->root.limit &&
1541 *parser->root.cursor == '[' )
1542 {
1545 if ( parser->root.cursor >= parser->root.limit ||
1546 *parser->root.cursor != ']' )
1547 parser->root.error = FT_THROW( Invalid_File_Format );
1548 return;
1549 }
1550
1551 num_subrs = (FT_Int)T1_ToInt( parser );
1552 if ( num_subrs < 0 )
1553 {
1554 parser->root.error = FT_THROW( Invalid_File_Format );
1555 return;
1556 }
1557
1558 /* we certainly need more than 8 bytes per subroutine */
1559 if ( parser->root.limit >= parser->root.cursor &&
1560 num_subrs > ( parser->root.limit - parser->root.cursor ) >> 3 )
1561 {
1562 /*
1563 * There are two possibilities. Either the font contains an invalid
1564 * value for `num_subrs', or we have a subsetted font where the
1565 * subroutine indices are not adjusted, e.g.
1566 *
1567 * /Subrs 812 array
1568 * dup 0 { ... } NP
1569 * dup 51 { ... } NP
1570 * dup 681 { ... } NP
1571 * ND
1572 *
1573 * In both cases, we use a number hash that maps from subr indices to
1574 * actual array elements.
1575 */
1576
1577 FT_TRACE0(( "parse_subrs: adjusting number of subroutines"
1578 " (from %d to %d)\n",
1579 num_subrs,
1580 ( parser->root.limit - parser->root.cursor ) >> 3 ));
1581 num_subrs = ( parser->root.limit - parser->root.cursor ) >> 3;
1582
1583 if ( !loader->subrs_hash )
1584 {
1585 if ( FT_NEW( loader->subrs_hash ) )
1586 goto Fail;
1587
1588 error = ft_hash_num_init( loader->subrs_hash, memory );
1589 if ( error )
1590 goto Fail;
1591 }
1592 }
1593
1594 /* position the parser right before the `dup' of the first subr */
1595 T1_Skip_PS_Token( parser ); /* `array' */
1596 if ( parser->root.error )
1597 return;
1599
1600 /* initialize subrs array -- with synthetic fonts it is possible */
1601 /* we get here twice */
1602 if ( !loader->num_subrs )
1603 {
1604 error = psaux->ps_table_funcs->init( table, num_subrs, memory );
1605 if ( error )
1606 goto Fail;
1607 }
1608
1609 /* the format is simple: */
1610 /* */
1611 /* `index' + binary data */
1612 /* */
1613 for ( count = 0; ; count++ )
1614 {
1615 FT_Long idx;
1616 FT_ULong size;
1617 FT_Byte* base;
1618
1619
1620 /* If we are out of data, or if the next token isn't `dup', */
1621 /* we are done. */
1622 if ( parser->root.cursor + 4 >= parser->root.limit ||
1623 ft_strncmp( (char*)parser->root.cursor, "dup", 3 ) != 0 )
1624 break;
1625
1626 T1_Skip_PS_Token( parser ); /* `dup' */
1627
1628 idx = T1_ToInt( parser );
1629
1631 return;
1632
1633 /* The binary string is followed by one token, e.g. `NP' */
1634 /* (bound to `noaccess put') or by two separate tokens: */
1635 /* `noaccess' & `put'. We position the parser right */
1636 /* before the next `dup', if any. */
1637 T1_Skip_PS_Token( parser ); /* `NP' or `|' or `noaccess' */
1638 if ( parser->root.error )
1639 return;
1641
1642 if ( parser->root.cursor + 4 < parser->root.limit &&
1643 ft_strncmp( (char*)parser->root.cursor, "put", 3 ) == 0 )
1644 {
1645 T1_Skip_PS_Token( parser ); /* skip `put' */
1647 }
1648
1649 /* if we use a hash, the subrs index is the key, and a running */
1650 /* counter specified for `T1_Add_Table' acts as the value */
1651 if ( loader->subrs_hash )
1652 {
1653 ft_hash_num_insert( idx, count, loader->subrs_hash, memory );
1654 idx = count;
1655 }
1656
1657 /* with synthetic fonts it is possible we get here twice */
1658 if ( loader->num_subrs )
1659 continue;
1660
1661 /* some fonts use a value of -1 for lenIV to indicate that */
1662 /* the charstrings are unencoded */
1663 /* */
1664 /* thanks to Tom Kacvinsky for pointing this out */
1665 /* */
1666 if ( face->type1.private_dict.lenIV >= 0 )
1667 {
1668 FT_Byte* temp = NULL;
1669
1670
1671 /* some fonts define empty subr records -- this is not totally */
1672 /* compliant to the specification (which says they should at */
1673 /* least contain a `return'), but we support them anyway */
1674 if ( size < (FT_ULong)face->type1.private_dict.lenIV )
1675 {
1676 error = FT_THROW( Invalid_File_Format );
1677 goto Fail;
1678 }
1679
1680 /* t1_decrypt() shouldn't write to base -- make temporary copy */
1681 if ( FT_ALLOC( temp, size ) )
1682 goto Fail;
1684 psaux->t1_decrypt( temp, size, 4330 );
1685 size -= (FT_ULong)face->type1.private_dict.lenIV;
1687 temp + face->type1.private_dict.lenIV, size );
1688 FT_FREE( temp );
1689 }
1690 else
1692 if ( error )
1693 goto Fail;
1694 }
1695
1696 if ( !loader->num_subrs )
1697 loader->num_subrs = num_subrs;
1698
1699 return;
1700
1701 Fail:
1702 parser->root.error = error;
1703 }
unsigned int idx
Definition: utils.c:41
FT_Error ft_hash_num_init(FT_Hash hash, FT_Memory memory)
Definition: fthash.c:204
FT_Error ft_hash_num_insert(FT_Int num, size_t data, FT_Hash hash, FT_Memory memory)
Definition: fthash.c:287
#define FT_NEW(ptr)
Definition: ftmemory.h:331
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 963 of file t1load.c.

965 {
966 T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS];
967 FT_Int num_designs;
969 T1_Parser parser = &loader->parser;
970 PS_Blend blend = face->blend;
972 FT_Int n;
973 FT_Byte* old_cursor;
974 FT_Byte* old_limit;
975
976
977 T1_ToTokenArray( parser, design_tokens,
978 T1_MAX_MM_DESIGNS, &num_designs );
979 if ( num_designs < 0 )
980 {
981 error = FT_ERR( Ignore );
982 goto Exit;
983 }
984 if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS )
985 {
986 FT_ERROR(( "parse_weight_vector:"
987 " incorrect number of designs: %d\n",
988 num_designs ));
989 error = FT_THROW( Invalid_File_Format );
990 goto Exit;
991 }
992
993 if ( !blend || !blend->num_designs )
994 {
995 error = t1_allocate_blend( face, (FT_UInt)num_designs, 0 );
996 if ( error )
997 goto Exit;
998 blend = face->blend;
999 }
1000 else if ( blend->num_designs != (FT_UInt)num_designs )
1001 {
1002 FT_ERROR(( "parse_weight_vector:"
1003 " /BlendDesignPosition and /WeightVector have\n"
1004 " "
1005 " different number of elements\n" ));
1006 error = FT_THROW( Invalid_File_Format );
1007 goto Exit;
1008 }
1009
1010 old_cursor = parser->root.cursor;
1011 old_limit = parser->root.limit;
1012
1013 for ( n = 0; n < num_designs; n++ )
1014 {
1015 token = design_tokens + n;
1016 parser->root.cursor = token->start;
1017 parser->root.limit = token->limit;
1018
1019 blend->default_weight_vector[n] =
1020 blend->weight_vector[n] = T1_ToFixed( parser, 0 );
1021 }
1022
1023 parser->root.cursor = old_cursor;
1024 parser->root.limit = old_limit;
1025
1026 Exit:
1027 parser->root.error = error;
1028 }
FT_Fixed * default_weight_vector
Definition: t1tables.h:308
FT_UInt num_designs
Definition: t1tables.h:300
FT_Fixed * weight_vector
Definition: t1tables.h:307

◆ read_binary_data()

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

Definition at line 1188 of file t1load.c.

1192 {
1193 FT_Byte* cur;
1194 FT_Byte* limit = parser->root.limit;
1195
1196
1197 /* the binary data has one of the following formats */
1198 /* */
1199 /* `size' [white*] RD white ....... ND */
1200 /* `size' [white*] -| white ....... |- */
1201 /* */
1202
1204
1205 cur = parser->root.cursor;
1206
1207 if ( cur < limit && ft_isdigit( *cur ) )
1208 {
1209 FT_Long s = T1_ToInt( parser );
1210
1211
1212 T1_Skip_PS_Token( parser ); /* `RD' or `-|' or something else */
1213
1214 /* there is only one whitespace char after the */
1215 /* `RD' or `-|' token */
1216 *base = parser->root.cursor + 1;
1217
1218 if ( s >= 0 && s < limit - *base )
1219 {
1220 parser->root.cursor += s + 1;
1221 *size = (FT_ULong)s;
1222 return !parser->root.error;
1223 }
1224 }
1225
1226 if( !incremental )
1227 {
1228 FT_ERROR(( "read_binary_data: invalid size field\n" ));
1229 parser->root.error = FT_THROW( Invalid_File_Format );
1230 }
1231
1232 return 0;
1233 }

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:311
FT_BBox * bboxes[T1_MAX_MM_DESIGNS+1]
Definition: t1tables.h:315
PS_FontInfo font_infos[T1_MAX_MM_DESIGNS+1]
Definition: t1tables.h:310
FT_UInt num_axis
Definition: t1tables.h:301
FT_UInt num_default_design_vector
Definition: t1tables.h:324

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 637 of file t1load.c.

638 {
639 FT_Memory memory = face->root.memory;
640 PS_Blend blend = face->blend;
641
642
643 if ( blend )
644 {
645 FT_UInt num_designs = blend->num_designs;
646 FT_UInt num_axis = blend->num_axis;
647 FT_UInt n;
648
649
650 /* release design pos table */
651 FT_FREE( blend->design_pos[0] );
652 for ( n = 1; n < num_designs; n++ )
653 blend->design_pos[n] = NULL;
654
655 /* release blend `private' and `font info' dictionaries */
656 FT_FREE( blend->privates[1] );
657 FT_FREE( blend->font_infos[1] );
658 FT_FREE( blend->bboxes[1] );
659
660 for ( n = 0; n < num_designs; n++ )
661 {
662 blend->privates [n] = NULL;
663 blend->font_infos[n] = NULL;
664 blend->bboxes [n] = NULL;
665 }
666
667 /* release weight vectors */
668 FT_FREE( blend->weight_vector );
670
671 /* release axis names */
672 for ( n = 0; n < num_axis; n++ )
673 FT_FREE( blend->axis_names[n] );
674
675 /* release design map */
676 for ( n = 0; n < num_axis; n++ )
677 {
678 PS_DesignMap dmap = blend->design_map + n;
679
680
681 FT_FREE( dmap->design_points );
682 dmap->num_points = 0;
683 }
684
685 FT_FREE( face->blend );
686 }
687 }

Referenced by T1_Face_Done(), and T1_Open_Face().

◆ t1_done_loader()

static void t1_done_loader ( T1_Loader  loader)
static

Definition at line 2278 of file t1load.c.

2279 {
2280 T1_Parser parser = &loader->parser;
2281 FT_Memory memory = parser->root.memory;
2282
2283
2284 /* finalize tables */
2285 T1_Release_Table( &loader->encoding_table );
2286 T1_Release_Table( &loader->charstrings );
2287 T1_Release_Table( &loader->glyph_names );
2288 T1_Release_Table( &loader->swap_table );
2289 T1_Release_Table( &loader->subrs );
2290
2291 /* finalize hash */
2292 ft_hash_num_free( loader->subrs_hash, memory );
2293 FT_FREE( loader->subrs_hash );
2294
2295 /* finalize parser */
2297 }
#define ft_hash_num_free
Definition: fthash.h:107
T1_Finalize_Parser(T1_Parser parser)
Definition: t1parse.c:244

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 445 of file t1load.c.

448 {
449 PS_Blend blend = face->blend;
450
451 FT_Fixed axiscoords[4];
452 FT_UInt i, nc;
453
454
455 if ( !blend )
456 return FT_THROW( Invalid_Argument );
457
459 axiscoords,
460 blend->num_axis );
461
462 nc = num_coords;
463 if ( num_coords > blend->num_axis )
464 {
465 FT_TRACE2(( "T1_Get_MM_Blend: only using first %d of %d coordinates\n",
466 blend->num_axis, num_coords ));
467 nc = blend->num_axis;
468 }
469
470 for ( i = 0; i < nc; i++ )
471 coords[i] = axiscoords[i];
472 for ( ; i < num_coords; i++ )
473 coords[i] = 0x8000;
474
475 return FT_Err_Ok;
476 }
signed long FT_Fixed
Definition: fttypes.h:288
GLuint coords
Definition: glext.h:7368
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
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
313
314 error = T1_Get_Multi_Master( face, &mmaster );
315 if ( error )
316 goto Exit;
317 if ( FT_ALLOC( mmvar,
318 sizeof ( FT_MM_Var ) +
319 mmaster.num_axis * sizeof ( FT_Var_Axis ) ) )
320 goto Exit;
321
322 mmvar->num_axis = mmaster.num_axis;
323 mmvar->num_designs = mmaster.num_designs;
324 mmvar->num_namedstyles = 0; /* Not supported */
325 mmvar->axis = (FT_Var_Axis*)&mmvar[1];
326 /* Point to axes after MM_Var struct */
327 mmvar->namedstyle = NULL;
328
329 for ( i = 0; i < mmaster.num_axis; i++ )
330 {
331 mmvar->axis[i].name = mmaster.axis[i].name;
332 mmvar->axis[i].minimum = INT_TO_FIXED( mmaster.axis[i].minimum );
333 mmvar->axis[i].maximum = INT_TO_FIXED( mmaster.axis[i].maximum );
334 mmvar->axis[i].def = ( mmvar->axis[i].minimum +
335 mmvar->axis[i].maximum ) / 2;
336 /* Does not apply. But this value is in range */
337 mmvar->axis[i].strid = ~0U; /* Does not apply */
338 mmvar->axis[i].tag = ~0U; /* Does not apply */
339
340 if ( !mmvar->axis[i].name )
341 continue;
342
343 if ( ft_strcmp( mmvar->axis[i].name, "Weight" ) == 0 )
344 mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'g', 'h', 't' );
345 else if ( ft_strcmp( mmvar->axis[i].name, "Width" ) == 0 )
346 mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'd', 't', 'h' );
347 else if ( ft_strcmp( mmvar->axis[i].name, "OpticalSize" ) == 0 )
348 mmvar->axis[i].tag = FT_MAKE_TAG( 'o', 'p', 's', 'z' );
349 }
350
351 if ( blend->num_designs == ( 1U << blend->num_axis ) )
352 {
354 axiscoords,
355 blend->num_axis );
356
357 for ( i = 0; i < mmaster.num_axis; i++ )
358 mmvar->axis[i].def = mm_axis_unmap( &blend->design_map[i],
359 axiscoords[i] );
360 }
361
362 *master = mmvar;
363
364 Exit:
365 return error;
366 }
#define U(x)
Definition: wordpad.c:45
#define FT_MAKE_TAG(_x1, _x2, _x3, _x4)
Definition: fttypes.h:480
FT_Var_Axis * axis
Definition: ftmm.h:242
FT_UInt num_designs
Definition: ftmm.h:240
FT_UInt num_namedstyles
Definition: ftmm.h:241
FT_UInt num_axis
Definition: ftmm.h:239
FT_Var_Named_Style * namedstyle
Definition: ftmm.h:243
FT_MM_Axis axis[T1_MAX_MM_AXIS]
Definition: ftmm.h:108
FT_UInt num_designs
Definition: ftmm.h:107
FT_UInt num_axis
Definition: ftmm.h:106
FT_ULong tag
Definition: ftmm.h:157
FT_UInt strid
Definition: ftmm.h:158
FT_Fixed def
Definition: ftmm.h:154
FT_Fixed maximum
Definition: ftmm.h:155
FT_String * name
Definition: ftmm.h:151
FT_Fixed minimum
Definition: ftmm.h:153
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_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 601 of file t1load.c.

604 {
605 PS_Blend blend = face->blend;
606
607 FT_Fixed axiscoords[4];
608 FT_UInt i, nc;
609
610
611 if ( !blend )
612 return FT_THROW( Invalid_Argument );
613
615 axiscoords,
616 blend->num_axis );
617
618 nc = num_coords;
619 if ( num_coords > blend->num_axis )
620 {
621 FT_TRACE2(( "T1_Get_Var_Design:"
622 " only using first %d of %d coordinates\n",
623 blend->num_axis, num_coords ));
624 nc = blend->num_axis;
625 }
626
627 for ( i = 0; i < nc; i++ )
628 coords[i] = mm_axis_unmap( &blend->design_map[i], axiscoords[i] );
629 for ( ; i < num_coords; i++ )
630 coords[i] = 0;
631
632 return FT_Err_Ok;
633 }

◆ t1_init_loader()

static void t1_init_loader ( T1_Loader  loader,
T1_Face  face 
)
static

Definition at line 2268 of file t1load.c.

2270 {
2271 FT_UNUSED( face );
2272
2273 FT_ZERO( loader );
2274 }
#define FT_ZERO(p)
Definition: ftmemory.h:237

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 1057 of file t1load.c.

1060 {
1062 void* dummy_object;
1063 void** objects;
1064 FT_UInt max_objects;
1065 PS_Blend blend = face->blend;
1066
1067
1068 if ( blend && blend->num_designs == 0 )
1069 blend = NULL;
1070
1071 /* if the keyword has a dedicated callback, call it */
1073 {
1074 field->reader( (FT_Face)face, loader );
1075 error = loader->parser.root.error;
1076 goto Exit;
1077 }
1078
1079 /* now, the keyword is either a simple field, or a table of fields; */
1080 /* we are now going to take care of it */
1081 switch ( field->location )
1082 {
1084 dummy_object = &face->type1.font_info;
1085 objects = &dummy_object;
1086 max_objects = 0;
1087
1088 if ( blend )
1089 {
1090 objects = (void**)blend->font_infos;
1091 max_objects = blend->num_designs;
1092 }
1093 break;
1094
1096 dummy_object = &face->type1.font_extra;
1097 objects = &dummy_object;
1098 max_objects = 0;
1099 break;
1100
1102 dummy_object = &face->type1.private_dict;
1103 objects = &dummy_object;
1104 max_objects = 0;
1105
1106 if ( blend )
1107 {
1108 objects = (void**)blend->privates;
1109 max_objects = blend->num_designs;
1110 }
1111 break;
1112
1114 dummy_object = &face->type1.font_bbox;
1115 objects = &dummy_object;
1116 max_objects = 0;
1117
1118 if ( blend )
1119 {
1120 objects = (void**)blend->bboxes;
1121 max_objects = blend->num_designs;
1122 }
1123 break;
1124
1126 dummy_object = loader;
1127 objects = &dummy_object;
1128 max_objects = 0;
1129 break;
1130
1132 dummy_object = face;
1133 objects = &dummy_object;
1134 max_objects = 0;
1135 break;
1136
1137#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
1139 dummy_object = face->blend;
1140 objects = &dummy_object;
1141 max_objects = 0;
1142 break;
1143#endif
1144
1145 default:
1146 dummy_object = &face->type1;
1147 objects = &dummy_object;
1148 max_objects = 0;
1149 }
1150
1151 if ( *objects )
1152 {
1155 error = T1_Load_Field_Table( &loader->parser, field,
1156 objects, max_objects, 0 );
1157 else
1158 error = T1_Load_Field( &loader->parser, field,
1159 objects, max_objects, 0 );
1160 }
1161 else
1162 {
1163 FT_TRACE1(( "t1_load_keyword: ignoring keyword `%s'"
1164 " which is not valid at this point\n"
1165 " (probably due to missing keywords)\n",
1166 field->ident ));
1167 error = FT_Err_Ok;
1168 }
1169
1170 Exit:
1171 return error;
1172 }
WORD face[3]
Definition: mesh.c:4747
static const CLSID * objects[]
Definition: apphelp.c:112
@ T1_FIELD_TYPE_INTEGER_ARRAY
Definition: psaux.h:211
@ T1_FIELD_TYPE_CALLBACK
Definition: psaux.h:213
@ T1_FIELD_TYPE_FIXED_ARRAY
Definition: psaux.h:212
@ T1_FIELD_LOCATION_FONT_EXTRA
Definition: psaux.h:225
@ T1_FIELD_LOCATION_BLEND
Definition: psaux.h:231
@ T1_FIELD_LOCATION_BBOX
Definition: psaux.h:228
@ T1_FIELD_LOCATION_PRIVATE
Definition: psaux.h:227
@ T1_FIELD_LOCATION_LOADER
Definition: psaux.h:229
@ T1_FIELD_LOCATION_FONT_INFO
Definition: psaux.h:226
@ T1_FIELD_LOCATION_FACE
Definition: psaux.h:230
Definition: parser.c:44
#define T1_Load_Field(p, f, o, m, pf)
Definition: t1parse.h:103
#define T1_Load_Field_Table(p, f, o, m, pf)
Definition: t1parse.h:106

Referenced by parse_dict().

◆ T1_Open_Face()

T1_Open_Face ( T1_Face  face)

Definition at line 2301 of file t1load.c.

2302 {
2303 T1_LoaderRec loader;
2305 T1_Font type1 = &face->type1;
2306 PS_Private priv = &type1->private_dict;
2308
2309 PSAux_Service psaux = (PSAux_Service)face->psaux;
2310
2311
2312 t1_init_loader( &loader, face );
2313
2314 /* default values */
2315 face->ndv_idx = -1;
2316 face->cdv_idx = -1;
2317 face->len_buildchar = 0;
2318
2319 priv->blue_shift = 7;
2320 priv->blue_fuzz = 1;
2321 priv->lenIV = 4;
2322 priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
2323 priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
2324
2325 parser = &loader.parser;
2327 face->root.stream,
2328 face->root.memory,
2329 psaux );
2330 if ( error )
2331 goto Exit;
2332
2333 error = parse_dict( face, &loader,
2334 parser->base_dict, parser->base_len );
2335 if ( error )
2336 goto Exit;
2337
2338 error = T1_Get_Private_Dict( parser, psaux );
2339 if ( error )
2340 goto Exit;
2341
2342 error = parse_dict( face, &loader,
2343 parser->private_dict, parser->private_len );
2344 if ( error )
2345 goto Exit;
2346
2347 /* ensure even-ness of `num_blue_values' */
2348 priv->num_blue_values &= ~1;
2349
2350#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
2351
2352 if ( face->blend &&
2353 face->blend->num_default_design_vector != 0 &&
2354 face->blend->num_default_design_vector != face->blend->num_axis )
2355 {
2356 /* we don't use it currently so just warn, reset, and ignore */
2357 FT_ERROR(( "T1_Open_Face(): /DesignVector contains %u entries "
2358 "while there are %u axes.\n",
2359 face->blend->num_default_design_vector,
2360 face->blend->num_axis ));
2361
2362 face->blend->num_default_design_vector = 0;
2363 }
2364
2365 /* the following can happen for MM instances; we then treat the */
2366 /* font as a normal PS font */
2367 if ( face->blend &&
2368 ( !face->blend->num_designs || !face->blend->num_axis ) )
2370
2371 /* another safety check */
2372 if ( face->blend )
2373 {
2374 FT_UInt i;
2375
2376
2377 for ( i = 0; i < face->blend->num_axis; i++ )
2378 if ( !face->blend->design_map[i].num_points )
2379 {
2381 break;
2382 }
2383 }
2384
2385 if ( face->blend )
2386 {
2387 if ( face->len_buildchar > 0 )
2388 {
2389 FT_Memory memory = face->root.memory;
2390
2391
2392 if ( FT_NEW_ARRAY( face->buildchar, face->len_buildchar ) )
2393 {
2394 FT_ERROR(( "T1_Open_Face: cannot allocate BuildCharArray\n" ));
2395 face->len_buildchar = 0;
2396 goto Exit;
2397 }
2398 }
2399 }
2400 else
2401 face->len_buildchar = 0;
2402
2403#endif /* !T1_CONFIG_OPTION_NO_MM_SUPPORT */
2404
2405 /* now, propagate the subrs, charstrings, and glyphnames tables */
2406 /* to the Type1 data */
2407 type1->num_glyphs = loader.num_glyphs;
2408
2409 if ( loader.subrs.init )
2410 {
2411 type1->num_subrs = loader.num_subrs;
2412 type1->subrs_block = loader.subrs.block;
2413 type1->subrs = loader.subrs.elements;
2414 type1->subrs_len = loader.subrs.lengths;
2415 type1->subrs_hash = loader.subrs_hash;
2416
2417 /* prevent `t1_done_loader' from freeing the propagated data */
2418 loader.subrs.init = 0;
2419 loader.subrs_hash = NULL;
2420 }
2421
2422 if ( !IS_INCREMENTAL )
2423 if ( !loader.charstrings.init )
2424 {
2425 FT_ERROR(( "T1_Open_Face: no `/CharStrings' array in face\n" ));
2426 error = FT_THROW( Invalid_File_Format );
2427 }
2428
2429 loader.charstrings.init = 0;
2430 type1->charstrings_block = loader.charstrings.block;
2431 type1->charstrings = loader.charstrings.elements;
2432 type1->charstrings_len = loader.charstrings.lengths;
2433
2434 /* we copy the glyph names `block' and `elements' fields; */
2435 /* the `lengths' field must be released later */
2436 type1->glyph_names_block = loader.glyph_names.block;
2437 type1->glyph_names = (FT_String**)loader.glyph_names.elements;
2438 loader.glyph_names.block = NULL;
2439 loader.glyph_names.elements = NULL;
2440
2441 /* we must now build type1.encoding when we have a custom array */
2443 {
2444 FT_Int charcode, idx, min_char, max_char;
2445 FT_Byte* glyph_name;
2446
2447
2448 /* OK, we do the following: for each element in the encoding */
2449 /* table, look up the index of the glyph having the same name */
2450 /* the index is then stored in type1.encoding.char_index, and */
2451 /* the name to type1.encoding.char_name */
2452
2453 min_char = 0;
2454 max_char = 0;
2455
2456 charcode = 0;
2457 for ( ; charcode < loader.encoding_table.max_elems; charcode++ )
2458 {
2459 FT_Byte* char_name;
2460
2461
2462 type1->encoding.char_index[charcode] = 0;
2463 type1->encoding.char_name [charcode] = (char *)".notdef";
2464
2465 char_name = loader.encoding_table.elements[charcode];
2466 if ( char_name )
2467 for ( idx = 0; idx < type1->num_glyphs; idx++ )
2468 {
2469 glyph_name = (FT_Byte*)type1->glyph_names[idx];
2470 if ( ft_strcmp( (const char*)char_name,
2471 (const char*)glyph_name ) == 0 )
2472 {
2473 type1->encoding.char_index[charcode] = (FT_UShort)idx;
2474 type1->encoding.char_name [charcode] = (char*)glyph_name;
2475
2476 /* Change min/max encoded char only if glyph name is */
2477 /* not /.notdef */
2478 if ( ft_strcmp( (const char*)".notdef",
2479 (const char*)glyph_name ) != 0 )
2480 {
2481 if ( charcode < min_char )
2482 min_char = charcode;
2483 if ( charcode >= max_char )
2484 max_char = charcode + 1;
2485 }
2486 break;
2487 }
2488 }
2489 }
2490
2491 type1->encoding.code_first = min_char;
2492 type1->encoding.code_last = max_char;
2493 type1->encoding.num_chars = loader.num_chars;
2494 }
2495
2496 Exit:
2497 t1_done_loader( &loader );
2498 return error;
2499 }
unsigned short FT_UShort
Definition: fttypes.h:209
char FT_String
Definition: fttypes.h:187
FT_Int blue_fuzz
Definition: t1tables.h:156
FT_Fixed expansion_factor
Definition: t1tables.h:169
FT_Int lenIV
Definition: t1tables.h:141
FT_Int blue_shift
Definition: t1tables.h:155
FT_Byte num_blue_values
Definition: t1tables.h:143
FT_Fixed blue_scale
Definition: t1tables.h:154
PS_PrivateRec private_dict
Definition: t1types.h:98
T1_EncodingType encoding_type
Definition: t1types.h:101
FT_Byte * subrs_block
Definition: t1types.h:104
FT_Byte ** subrs
Definition: t1types.h:109
FT_Int num_glyphs
Definition: t1types.h:113
FT_UInt * charstrings_len
Definition: t1types.h:116
FT_String ** glyph_names
Definition: t1types.h:114
T1_EncodingRec encoding
Definition: t1types.h:102
FT_Int num_subrs
Definition: t1types.h:108
FT_Byte * charstrings_block
Definition: t1types.h:105
FT_Hash subrs_hash
Definition: t1types.h:111
FT_Byte ** charstrings
Definition: t1types.h:115
FT_UInt * subrs_len
Definition: t1types.h:110
FT_Byte * glyph_names_block
Definition: t1types.h:106
static void t1_init_loader(T1_Loader loader, T1_Face face)
Definition: t1load.c:2268
T1_Done_Blend(T1_Face face)
Definition: t1load.c:637
static void t1_done_loader(T1_Loader loader)
Definition: t1load.c:2278
static FT_Error parse_dict(T1_Face face, T1_Loader loader, FT_Byte *base, FT_ULong size)
Definition: t1load.c:2071
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:136
T1_Get_Private_Dict(T1_Parser parser, PSAux_Service psaux)
Definition: t1parse.c:261

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 1240 of file t1load.c.

1242 {
1243 T1_Parser parser = &loader->parser;
1244 FT_Matrix* matrix = &face->type1.font_matrix;
1245 FT_Vector* offset = &face->type1.font_offset;
1246 FT_Face root = (FT_Face)&face->root;
1247 FT_Fixed temp[6];
1248 FT_Fixed temp_scale;
1249 FT_Int result;
1250
1251
1252 /* input is scaled by 1000 to accommodate default FontMatrix */
1253 result = T1_ToFixedArray( parser, 6, temp, 3 );
1254
1255 if ( result < 6 )
1256 {
1257 parser->root.error = FT_THROW( Invalid_File_Format );
1258 return;
1259 }
1260
1261 temp_scale = FT_ABS( temp[3] );
1262
1263 if ( temp_scale == 0 )
1264 {
1265 FT_ERROR(( "t1_parse_font_matrix: invalid font matrix\n" ));
1266 parser->root.error = FT_THROW( Invalid_File_Format );
1267 return;
1268 }
1269
1270 /* atypical case */
1271 if ( temp_scale != 0x10000L )
1272 {
1273 /* set units per EM based on FontMatrix values */
1274 root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale );
1275
1276 temp[0] = FT_DivFix( temp[0], temp_scale );
1277 temp[1] = FT_DivFix( temp[1], temp_scale );
1278 temp[2] = FT_DivFix( temp[2], temp_scale );
1279 temp[4] = FT_DivFix( temp[4], temp_scale );
1280 temp[5] = FT_DivFix( temp[5], temp_scale );
1281 temp[3] = temp[3] < 0 ? -0x10000L : 0x10000L;
1282 }
1283
1284 matrix->xx = temp[0];
1285 matrix->yx = temp[1];
1286 matrix->xy = temp[2];
1287 matrix->yy = temp[3];
1288
1289 /* note that the offsets must be expressed in integer font units */
1290 offset->x = temp[4] >> 16;
1291 offset->y = temp[5] >> 16;
1292 }
struct FT_FaceRec_ * FT_Face
Definition: freetype.h:503
#define FT_ABS(a)
Definition: ftobjs.h:74
GLuint GLenum matrix
Definition: glext.h:9407
GLuint64EXT * result
Definition: glext.h:11304
GLintptr offset
Definition: glext.h:5920

◆ T1_Reset_MM_Blend()

T1_Reset_MM_Blend ( T1_Face  face,
FT_UInt  instance_index 
)

Definition at line 567 of file t1load.c.

569 {
570 FT_UNUSED( instance_index );
571
572 return T1_Set_MM_Blend( face, 0, NULL );
573 }
T1_Set_MM_Blend(T1_Face face, FT_UInt num_coords, FT_Fixed *coords)
Definition: t1load.c:424

◆ 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 370 of file t1load.c.

373 {
374 PS_Blend blend = face->blend;
375 FT_UInt n, m;
376
377 FT_Bool have_diff = 0;
378
379
380 if ( !blend )
381 return FT_THROW( Invalid_Argument );
382
383 if ( num_coords > blend->num_axis )
384 num_coords = blend->num_axis;
385
386 /* recompute the weight vector from the blend coordinates */
387 for ( n = 0; n < blend->num_designs; n++ )
388 {
389 FT_Fixed result = 0x10000L; /* 1.0 fixed */
390
391
392 for ( m = 0; m < blend->num_axis; m++ )
393 {
395
396
397 /* get current blend axis position; */
398 /* use a default value if we don't have a coordinate */
399 factor = m < num_coords ? coords[m] : 0x8000;
400 if ( factor < 0 )
401 factor = 0;
402 if ( factor > 0x10000L )
403 factor = 0x10000L;
404
405 if ( ( n & ( 1 << m ) ) == 0 )
406 factor = 0x10000L - factor;
407
409 }
410
411 if ( blend->weight_vector[n] != result )
412 {
413 blend->weight_vector[n] = result;
414 have_diff = 1;
415 }
416 }
417
418 /* return value -1 indicates `no change' */
419 return have_diff ? FT_Err_Ok : -1;
420 }
FT_MulFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:509
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 424 of file t1load.c.

427 {
429
430
431 error = t1_set_mm_blend( face, num_coords, coords );
432 if ( error )
433 return error;
434
435 if ( num_coords )
436 face->root.face_flags |= FT_FACE_FLAG_VARIATION;
437 else
438 face->root.face_flags &= ~FT_FACE_FLAG_VARIATION;
439
440 return FT_Err_Ok;
441 }
#define FT_FACE_FLAG_VARIATION
Definition: freetype.h:1253
static FT_Error t1_set_mm_blend(T1_Face face, FT_UInt num_coords, FT_Fixed *coords)
Definition: t1load.c:370

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 480 of file t1load.c.

483 {
485 PS_Blend blend = face->blend;
486 FT_UInt n, p;
487 FT_Fixed final_blends[T1_MAX_MM_DESIGNS];
488
489
490 if ( !blend )
491 return FT_THROW( Invalid_Argument );
492
493 if ( num_coords > blend->num_axis )
494 num_coords = blend->num_axis;
495
496 /* compute the blend coordinates through the blend design map */
497
498 for ( n = 0; n < blend->num_axis; n++ )
499 {
500 FT_Long design;
501 FT_Fixed the_blend;
502 PS_DesignMap map = blend->design_map + n;
503 FT_Long* designs = map->design_points;
504 FT_Fixed* blends = map->blend_points;
505 FT_Int before = -1, after = -1;
506
507
508 /* use a default value if we don't have a coordinate */
509 if ( n < num_coords )
510 design = coords[n];
511 else
512 design = ( designs[map->num_points - 1] - designs[0] ) / 2;
513
514 for ( p = 0; p < (FT_UInt)map->num_points; p++ )
515 {
516 FT_Long p_design = designs[p];
517
518
519 /* exact match? */
520 if ( design == p_design )
521 {
522 the_blend = blends[p];
523 goto Found;
524 }
525
526 if ( design < p_design )
527 {
528 after = (FT_Int)p;
529 break;
530 }
531
532 before = (FT_Int)p;
533 }
534
535 /* now interpolate if necessary */
536 if ( before < 0 )
537 the_blend = blends[0];
538
539 else if ( after < 0 )
540 the_blend = blends[map->num_points - 1];
541
542 else
543 the_blend = FT_MulDiv( design - designs[before],
544 blends [after] - blends [before],
545 designs[after] - designs[before] );
546
547 Found:
548 final_blends[n] = the_blend;
549 }
550
551 error = t1_set_mm_blend( face, blend->num_axis, final_blends );
552 if ( error )
553 return error;
554
555 if ( num_coords )
556 face->root.face_flags |= FT_FACE_FLAG_VARIATION;
557 else
558 face->root.face_flags &= ~FT_FACE_FLAG_VARIATION;
559
560 return FT_Err_Ok;
561 }
return Found
Definition: dirsup.c:1270
FT_MulDiv(FT_Long a, FT_Long b, FT_Long c)
Definition: ftcalc.c:416
__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_Var_Design()

T1_Set_Var_Design ( T1_Face  face,
FT_UInt  num_coords,
FT_Fixed coords 
)

Definition at line 582 of file t1load.c.

585 {
586 FT_Long lcoords[T1_MAX_MM_AXIS];
587 FT_UInt i;
588
589
590 if ( num_coords > T1_MAX_MM_AXIS )
591 num_coords = T1_MAX_MM_AXIS;
592
593 for ( i = 0; i < num_coords; i++ )
594 lcoords[i] = FIXED_TO_INT( coords[i] );
595
596 return T1_Set_MM_Design( face, num_coords, lcoords );
597 }
#define FIXED_TO_INT(x)
Definition: ftcalc.h:406
T1_Set_MM_Design(T1_Face face, FT_UInt num_coords, FT_Long *coords)
Definition: t1load.c:480

Variable Documentation

◆ t1_keywords

const T1_FieldRec t1_keywords[]
static

Definition at line 2036 of file t1load.c.

Referenced by parse_dict().