blob: cc291e83a728cf3d3bb6f6f1178b070666922235 [file] [log] [blame]
Werner Lemberg4e6dd852000-06-05 05:26:15 +00001/***************************************************************************/
2/* */
3/* sfdriver.c */
4/* */
5/* High-level SFNT driver interface (body). */
6/* */
Werner Lemberg415235d2001-06-28 17:49:10 +00007/* Copyright 1996-2001 by */
Werner Lemberg4e6dd852000-06-05 05:26:15 +00008/* David Turner, Robert Wilhelm, and Werner Lemberg. */
9/* */
10/* This file is part of the FreeType project, and may only be used, */
11/* modified, and distributed under the terms of the FreeType project */
12/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13/* this file you indicate that you have read the license and */
14/* understand and accept it fully. */
15/* */
16/***************************************************************************/
17
Werner Lembergcc069be2000-12-08 16:17:16 +000018
David Turner19ed8af2000-12-08 02:42:29 +000019#include <ft2build.h>
20#include FT_INTERNAL_SFNT_H
21#include FT_INTERNAL_OBJECTS_H
Werner Lemberg4e6dd852000-06-05 05:26:15 +000022
David Turner8d3a4012001-03-20 11:14:24 +000023#include "sfdriver.h"
24#include "ttload.h"
25#include "ttcmap.h"
26#include "sfobjs.h"
Werner Lemberg7fa51b52000-07-08 19:51:42 +000027
Werner Lembergf1ca2342000-11-29 15:18:54 +000028#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
David Turner8d3a4012001-03-20 11:14:24 +000029#include "ttsbit.h"
Werner Lembergf1ca2342000-11-29 15:18:54 +000030#endif
31
32#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
David Turner8d3a4012001-03-20 11:14:24 +000033#include "ttpost.h"
Werner Lembergf1ca2342000-11-29 15:18:54 +000034#endif
35
Werner Lemberga8bbc262000-07-01 14:06:46 +000036#include <string.h> /* for strcmp() */
37
Werner Lemberga929ba92000-06-25 06:47:11 +000038
Werner Lemberg52005c32001-06-27 23:25:46 +000039 static void*
40 get_sfnt_table( TT_Face face,
41 FT_Sfnt_Tag tag )
David Turner2e421312000-05-26 22:13:17 +000042 {
43 void* table;
44
David Turner2e421312000-05-26 22:13:17 +000045
Werner Lemberg4e6dd852000-06-05 05:26:15 +000046 switch ( tag )
47 {
48 case ft_sfnt_head:
49 table = &face->header;
50 break;
51
52 case ft_sfnt_hhea:
53 table = &face->horizontal;
54 break;
55
56 case ft_sfnt_vhea:
57 table = face->vertical_info ? &face->vertical : 0;
58 break;
59
60 case ft_sfnt_os2:
61 table = face->os2.version == 0xFFFF ? 0 : &face->os2;
62 break;
63
64 case ft_sfnt_post:
65 table = &face->postscript;
66 break;
67
68 case ft_sfnt_maxp:
69 table = &face->max_profile;
70 break;
71
72 case ft_sfnt_pclt:
73 table = face->pclt.Version ? &face->pclt : 0;
74 break;
75
76 default:
77 table = 0;
David Turner2e421312000-05-26 22:13:17 +000078 }
Werner Lemberg4e6dd852000-06-05 05:26:15 +000079
David Turner2e421312000-05-26 22:13:17 +000080 return table;
81 }
82
83
David Turner6930b452000-07-19 17:13:03 +000084#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
Werner Lembergd060a752000-07-20 06:57:41 +000085
86
Werner Lemberg52005c32001-06-27 23:25:46 +000087 static FT_Error
88 get_sfnt_glyph_name( TT_Face face,
89 FT_UInt glyph_index,
90 FT_Pointer buffer,
91 FT_UInt buffer_max )
David Turner6930b452000-07-19 17:13:03 +000092 {
93 FT_String* gname;
94 FT_Error error;
Werner Lemberge4b32a52000-10-31 20:42:18 +000095
Werner Lembergd060a752000-07-20 06:57:41 +000096
David Turner6930b452000-07-19 17:13:03 +000097 error = TT_Get_PS_Name( face, glyph_index, &gname );
Werner Lembergd060a752000-07-20 06:57:41 +000098 if ( !error && buffer_max > 0 )
David Turner6930b452000-07-19 17:13:03 +000099 {
Werner Lemberg914b2892001-03-10 17:07:42 +0000100 FT_UInt len = (FT_UInt)( strlen( gname ) );
Werner Lemberge4b32a52000-10-31 20:42:18 +0000101
Werner Lembergd060a752000-07-20 06:57:41 +0000102
103 if ( len >= buffer_max )
104 len = buffer_max - 1;
Werner Lemberge4b32a52000-10-31 20:42:18 +0000105
David Turnere459d742002-03-22 13:52:37 +0000106 FT_MEM_COPY( buffer, gname, len );
David Turner6930b452000-07-19 17:13:03 +0000107 ((FT_Byte*)buffer)[len] = 0;
108 }
Werner Lemberge4b32a52000-10-31 20:42:18 +0000109
David Turner6930b452000-07-19 17:13:03 +0000110 return error;
Werner Lemberge4b32a52000-10-31 20:42:18 +0000111 }
Werner Lembergd060a752000-07-20 06:57:41 +0000112
113
David Turner23bcde12001-10-17 13:48:10 +0000114 static const char*
115 get_sfnt_postscript_name( TT_Face face )
116 {
David Turner28ea6f62002-03-05 16:12:57 +0000117 FT_Int n, found_win, found_apple;
David Turner678e0d42002-03-20 10:47:38 +0000118 const char* result = NULL;
David Turner23bcde12001-10-17 13:48:10 +0000119
Werner Lembergc3b21602001-12-05 01:22:05 +0000120
121 /* shouldn't happen, but just in case to avoid memory leaks */
David Turner23bcde12001-10-17 13:48:10 +0000122 if ( face->root.internal->postscript_name )
123 return face->root.internal->postscript_name;
124
Werner Lemberg8880f2c2002-01-25 16:05:39 +0000125 /* scan the name table to see whether we have a Postscript name here, */
126 /* either in Macintosh or Windows platform encodings */
David Turner28ea6f62002-03-05 16:12:57 +0000127 found_win = -1;
128 found_apple = -1;
129
David Turner23bcde12001-10-17 13:48:10 +0000130 for ( n = 0; n < face->num_names; n++ )
131 {
David Turnerb5713c52002-03-14 11:26:29 +0000132 TT_NameEntryRec* name = face->name_table.names + n;
Werner Lembergc3b21602001-12-05 01:22:05 +0000133
134
David Turner28ea6f62002-03-05 16:12:57 +0000135 if ( name->nameID == 6 && name->string != NULL )
David Turner23bcde12001-10-17 13:48:10 +0000136 {
David Turner28ea6f62002-03-05 16:12:57 +0000137 if ( name->platformID == 3 &&
138 name->encodingID == 1 &&
139 name->languageID == 0x409 )
140 found_win = n;
141
142 if ( name->platformID == 1 &&
143 name->encodingID == 0 &&
144 name->languageID == 0 )
145 found_apple = n;
David Turner23bcde12001-10-17 13:48:10 +0000146 }
147 }
David Turner28ea6f62002-03-05 16:12:57 +0000148
149 if ( found_win )
150 {
151 FT_Memory memory = face->root.memory;
David Turnerb5713c52002-03-14 11:26:29 +0000152 TT_NameEntryRec* name = face->name_table.names + found_win;
David Turner28ea6f62002-03-05 16:12:57 +0000153 FT_UInt len = name->stringLength/2;
154 FT_Error error;
David Turner28ea6f62002-03-05 16:12:57 +0000155
David Turnere459d742002-03-22 13:52:37 +0000156 if ( !FT_ALLOC( result, len+1 ) )
David Turner28ea6f62002-03-05 16:12:57 +0000157 {
David Turner678e0d42002-03-20 10:47:38 +0000158 FT_String* r = (FT_String*)result;
David Turner28ea6f62002-03-05 16:12:57 +0000159 FT_Byte* p = (FT_Byte*) name->string;
160
161 for ( ; len > 0; len--, p += 2 )
162 {
163 if ( p[0] == 0 && p[1] >= 32 && p[1] < 128 )
164 *r++ = p[1];
165 }
166 *r = '\0';
167 }
David Turner678e0d42002-03-20 10:47:38 +0000168 goto Exit;
David Turner28ea6f62002-03-05 16:12:57 +0000169 }
170
171 if ( found_apple )
172 {
David Turner678e0d42002-03-20 10:47:38 +0000173 FT_Memory memory = face->root.memory;
David Turnerb5713c52002-03-14 11:26:29 +0000174 TT_NameEntryRec* name = face->name_table.names + found_win;
David Turner678e0d42002-03-20 10:47:38 +0000175 FT_UInt len = name->stringLength;
176 FT_Error error;
177 FT_String* result;
David Turner28ea6f62002-03-05 16:12:57 +0000178
David Turnere459d742002-03-22 13:52:37 +0000179 if ( !FT_ALLOC( result, len+1 ) )
David Turner28ea6f62002-03-05 16:12:57 +0000180 {
David Turnere459d742002-03-22 13:52:37 +0000181 FT_MEM_COPY( result, name->string, len );
David Turner28ea6f62002-03-05 16:12:57 +0000182 result[len] = '\0';
183 }
David Turner678e0d42002-03-20 10:47:38 +0000184 goto Exit;
David Turner28ea6f62002-03-05 16:12:57 +0000185 }
Werner Lembergc3b21602001-12-05 01:22:05 +0000186
David Turner678e0d42002-03-20 10:47:38 +0000187 Exit:
188 face->root.internal->postscript_name = result;
189 return result;
David Turner23bcde12001-10-17 13:48:10 +0000190 }
191
192
Werner Lembergd060a752000-07-20 06:57:41 +0000193#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
194
David Turner6930b452000-07-19 17:13:03 +0000195
Werner Lemberg52005c32001-06-27 23:25:46 +0000196 FT_CALLBACK_DEF( FT_Module_Interface )
David Turnerdee78132001-06-27 09:26:46 +0000197 SFNT_Get_Interface( FT_Module module,
198 const char* interface )
David Turner2e421312000-05-26 22:13:17 +0000199 {
David Turnerc6a92202000-07-04 18:12:13 +0000200 FT_UNUSED( module );
David Turner2e421312000-05-26 22:13:17 +0000201
Werner Lemberg4e6dd852000-06-05 05:26:15 +0000202 if ( strcmp( interface, "get_sfnt" ) == 0 )
David Turnerf0df85b2000-06-22 00:17:42 +0000203 return (FT_Module_Interface)get_sfnt_table;
David Turner2e421312000-05-26 22:13:17 +0000204
David Turner6930b452000-07-19 17:13:03 +0000205#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
206 if ( strcmp( interface, "glyph_name" ) == 0 )
207 return (FT_Module_Interface)get_sfnt_glyph_name;
208#endif
David Turner23bcde12001-10-17 13:48:10 +0000209
210 if ( strcmp( interface, "postscript_name" ) == 0 )
211 return (FT_Module_Interface)get_sfnt_postscript_name;
212
David Turner2e421312000-05-26 22:13:17 +0000213 return 0;
214 }
215
David Turnerd2b1f351999-12-16 23:11:37 +0000216
Werner Lemberga8bbc262000-07-01 14:06:46 +0000217 static
218 const SFNT_Interface sfnt_interface =
David Turnerd2b1f351999-12-16 23:11:37 +0000219 {
220 TT_Goto_Table,
David Turnere49ab252000-05-16 23:44:38 +0000221
David Turner2e421312000-05-26 22:13:17 +0000222 SFNT_Init_Face,
223 SFNT_Load_Face,
224 SFNT_Done_Face,
225 SFNT_Get_Interface,
226
David Turnerd2b1f351999-12-16 23:11:37 +0000227 TT_Load_Any,
David Turnerb5713c52002-03-14 11:26:29 +0000228 TT_Load_SFNT_HeaderRec,
David Turnerd2b1f351999-12-16 23:11:37 +0000229 TT_Load_Directory,
230
231 TT_Load_Header,
232 TT_Load_Metrics_Header,
233 TT_Load_CMap,
234 TT_Load_MaxProfile,
235 TT_Load_OS2,
236 TT_Load_PostScript,
237
238 TT_Load_Names,
239 TT_Free_Names,
240
241 TT_Load_Hdmx,
242 TT_Free_Hdmx,
243
244 TT_Load_Kern,
245 TT_Load_Gasp,
Werner Lemberg4e6dd852000-06-05 05:26:15 +0000246 TT_Load_PCLT,
David Turnerd2b1f351999-12-16 23:11:37 +0000247
248#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
Werner Lemberga8bbc262000-07-01 14:06:46 +0000249
Werner Lemberg4b680072000-11-07 06:30:29 +0000250 /* see `ttload.h' */
David Turnerf96594f2000-11-06 23:07:51 +0000251 TT_Load_Bitmap_Header,
252
David Turnerd2b1f351999-12-16 23:11:37 +0000253 /* see `ttsbit.h' */
David Turnerf96594f2000-11-06 23:07:51 +0000254 TT_Set_SBit_Strike,
David Turnerd2b1f351999-12-16 23:11:37 +0000255 TT_Load_SBit_Strikes,
256 TT_Load_SBit_Image,
257 TT_Free_SBit_Strikes,
Werner Lemberga8bbc262000-07-01 14:06:46 +0000258
Werner Lemberg4e6dd852000-06-05 05:26:15 +0000259#else /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
Werner Lemberga8bbc262000-07-01 14:06:46 +0000260
David Turnerd2b1f351999-12-16 23:11:37 +0000261 0,
262 0,
263 0,
David Turnerf96594f2000-11-06 23:07:51 +0000264 0,
265 0,
Werner Lemberga8bbc262000-07-01 14:06:46 +0000266
Werner Lemberg4e6dd852000-06-05 05:26:15 +0000267#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
David Turnere49ab252000-05-16 23:44:38 +0000268
David Turnere49ab252000-05-16 23:44:38 +0000269#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
Werner Lemberga8bbc262000-07-01 14:06:46 +0000270
Werner Lemberg4e6dd852000-06-05 05:26:15 +0000271 /* see `ttpost.h' */
David Turnerd2b1f351999-12-16 23:11:37 +0000272 TT_Get_PS_Name,
David Turnere49ab252000-05-16 23:44:38 +0000273 TT_Free_Post_Names,
Werner Lemberga8bbc262000-07-01 14:06:46 +0000274
Werner Lemberg4e6dd852000-06-05 05:26:15 +0000275#else /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
Werner Lemberga8bbc262000-07-01 14:06:46 +0000276
David Turnerd2b1f351999-12-16 23:11:37 +0000277 0,
278 0,
Werner Lemberga8bbc262000-07-01 14:06:46 +0000279
Werner Lemberg4e6dd852000-06-05 05:26:15 +0000280#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
David Turnerd2b1f351999-12-16 23:11:37 +0000281
282 /* see `ttcmap.h' */
283 TT_CharMap_Load,
284 TT_CharMap_Free,
285 };
David Turnere49ab252000-05-16 23:44:38 +0000286
David Turnerd2b1f351999-12-16 23:11:37 +0000287
David Turner76a5f622000-11-04 01:55:49 +0000288 FT_CALLBACK_TABLE_DEF
289 const FT_Module_Class sfnt_module_class =
David Turnerd2b1f351999-12-16 23:11:37 +0000290 {
David Turnerf0df85b2000-06-22 00:17:42 +0000291 0, /* not a font driver or renderer */
292 sizeof( FT_ModuleRec ),
Werner Lembergfbeb41d2000-07-02 00:27:53 +0000293
David Turnerf0df85b2000-06-22 00:17:42 +0000294 "sfnt", /* driver name */
Werner Lemberga929ba92000-06-25 06:47:11 +0000295 0x10000L, /* driver version 1.0 */
296 0x20000L, /* driver requires FreeType 2.0 or higher */
Werner Lembergfbeb41d2000-07-02 00:27:53 +0000297
David Turnerf0df85b2000-06-22 00:17:42 +0000298 (const void*)&sfnt_interface, /* module specific interface */
Werner Lembergfbeb41d2000-07-02 00:27:53 +0000299
Werner Lemberga929ba92000-06-25 06:47:11 +0000300 (FT_Module_Constructor)0,
301 (FT_Module_Destructor) 0,
302 (FT_Module_Requester) SFNT_Get_Interface
David Turnerd2b1f351999-12-16 23:11:37 +0000303 };
Werner Lembergfbeb41d2000-07-02 00:27:53 +0000304
David Turnerd2b1f351999-12-16 23:11:37 +0000305
Werner Lemberg4e6dd852000-06-05 05:26:15 +0000306/* END */