blob: e7648b117a9dd088c115d116c76750b87060ffcf [file] [log] [blame]
David Turner19ed8af2000-12-08 02:42:29 +00001/***************************************************************************/
2/* */
3/* cffdrivr.c */
4/* */
5/* OpenType font driver implementation (body). */
6/* */
7/* Copyright 1996-2000 by */
8/* 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_FREETYPE_H
21#include FT_INTERNAL_DEBUG_H
22#include FT_INTERNAL_STREAM_H
23#include FT_INTERNAL_SFNT_H
David Turner6ce03ef2001-03-20 14:50:04 +000024#include FT_TRUETYPE_IDS_H
David Turner19ed8af2000-12-08 02:42:29 +000025
David Turner8d3a4012001-03-20 11:14:24 +000026#include "cffdrivr.h"
27#include "cffgload.h"
28#include "cffload.h"
Werner Lembergcc069be2000-12-08 16:17:16 +000029
Werner Lemberg1f7f0e82001-06-06 17:30:41 +000030#include "cfferrs.h"
31
32
David Turner19ed8af2000-12-08 02:42:29 +000033 /*************************************************************************/
34 /* */
35 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
36 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
37 /* messages during execution. */
38 /* */
39#undef FT_COMPONENT
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +000040#define FT_COMPONENT trace_cffdriver
David Turner19ed8af2000-12-08 02:42:29 +000041
42
43 /*************************************************************************/
44 /*************************************************************************/
45 /*************************************************************************/
46 /**** ****/
47 /**** ****/
48 /**** F A C E S ****/
49 /**** ****/
50 /**** ****/
51 /*************************************************************************/
52 /*************************************************************************/
53 /*************************************************************************/
54
55
56#undef PAIR_TAG
57#define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \
58 (FT_ULong)right )
59
60
61 /*************************************************************************/
62 /* */
63 /* <Function> */
64 /* Get_Kerning */
65 /* */
66 /* <Description> */
67 /* A driver method used to return the kerning vector between two */
68 /* glyphs of the same face. */
69 /* */
70 /* <Input> */
71 /* face :: A handle to the source face object. */
72 /* */
73 /* left_glyph :: The index of the left glyph in the kern pair. */
74 /* */
75 /* right_glyph :: The index of the right glyph in the kern pair. */
76 /* */
77 /* <Output> */
78 /* kerning :: The kerning vector. This is in font units for */
79 /* scalable formats, and in pixels for fixed-sizes */
80 /* formats. */
81 /* */
82 /* <Return> */
83 /* FreeType error code. 0 means success. */
84 /* */
85 /* <Note> */
86 /* Only horizontal layouts (left-to-right & right-to-left) are */
87 /* supported by this function. Other layouts, or more sophisticated */
88 /* kernings, are out of scope of this method (the basic driver */
89 /* interface is meant to be simple). */
90 /* */
91 /* They can be implemented by format-specific interfaces. */
92 /* */
93 static
94 FT_Error Get_Kerning( TT_Face face,
95 FT_UInt left_glyph,
96 FT_UInt right_glyph,
97 FT_Vector* kerning )
98 {
99 TT_Kern_0_Pair* pair;
100
101
102 if ( !face )
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000103 return CFF_Err_Invalid_Face_Handle;
David Turner19ed8af2000-12-08 02:42:29 +0000104
105 kerning->x = 0;
106 kerning->y = 0;
107
108 if ( face->kern_pairs )
109 {
110 /* there are some kerning pairs in this font file! */
111 FT_ULong search_tag = PAIR_TAG( left_glyph, right_glyph );
112 FT_Long left, right;
113
114
115 left = 0;
116 right = face->num_kern_pairs - 1;
117
118 while ( left <= right )
119 {
120 FT_Int middle = left + ( ( right - left ) >> 1 );
121 FT_ULong cur_pair;
122
123
124 pair = face->kern_pairs + middle;
125 cur_pair = PAIR_TAG( pair->left, pair->right );
126
127 if ( cur_pair == search_tag )
128 goto Found;
129
130 if ( cur_pair < search_tag )
131 left = middle + 1;
132 else
133 right = middle - 1;
134 }
135 }
136
137 Exit:
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000138 return CFF_Err_Ok;
David Turner19ed8af2000-12-08 02:42:29 +0000139
140 Found:
141 kerning->x = pair->value;
142 goto Exit;
143 }
144
145
146#undef PAIR_TAG
147
148
149 /*************************************************************************/
150 /* */
151 /* <Function> */
152 /* Load_Glyph */
153 /* */
154 /* <Description> */
155 /* A driver method used to load a glyph within a given glyph slot. */
156 /* */
157 /* <Input> */
158 /* slot :: A handle to the target slot object where the glyph */
159 /* will be loaded. */
160 /* */
161 /* size :: A handle to the source face size at which the glyph */
162 /* must be scaled, loaded, etc. */
163 /* */
164 /* glyph_index :: The index of the glyph in the font file. */
165 /* */
166 /* load_flags :: A flag indicating what to load for this glyph. The */
167 /* FTLOAD_??? constants can be used to control the */
168 /* glyph loading process (e.g., whether the outline */
169 /* should be scaled, whether to load bitmaps or not, */
170 /* whether to hint the outline, etc). */
171 /* */
172 /* <Return> */
173 /* FreeType error code. 0 means success. */
174 /* */
175 static
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000176 FT_Error Load_Glyph( CFF_GlyphSlot slot,
177 CFF_Size size,
Werner Lembergd573c7e2001-01-03 07:14:12 +0000178 FT_UShort glyph_index,
179 FT_UInt load_flags )
David Turner19ed8af2000-12-08 02:42:29 +0000180 {
181 FT_Error error;
182
183
184 if ( !slot )
Werner Lemberg1f7f0e82001-06-06 17:30:41 +0000185 return CFF_Err_Invalid_Slot_Handle;
David Turner19ed8af2000-12-08 02:42:29 +0000186
187 /* check whether we want a scaled outline or bitmap */
188 if ( !size )
189 load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
190
191 if ( load_flags & FT_LOAD_NO_SCALE )
192 size = NULL;
193
194 /* reset the size object if necessary */
195 if ( size )
196 {
197 /* these two object must have the same parent */
198 if ( size->face != slot->root.face )
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000199 return CFF_Err_Invalid_Face_Handle;
David Turner19ed8af2000-12-08 02:42:29 +0000200 }
201
202 /* now load the glyph outline if necessary */
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000203 error = CFF_Load_Glyph( slot, size, glyph_index, load_flags );
David Turner19ed8af2000-12-08 02:42:29 +0000204
205 /* force drop-out mode to 2 - irrelevant now */
206 /* slot->outline.dropout_mode = 2; */
207
208 return error;
209 }
210
211
212 /*************************************************************************/
213 /*************************************************************************/
214 /*************************************************************************/
215 /**** ****/
216 /**** ****/
217 /**** C H A R A C T E R M A P P I N G S ****/
218 /**** ****/
219 /**** ****/
220 /*************************************************************************/
221 /*************************************************************************/
222 /*************************************************************************/
223
Tom Kacvinsky84ad2a22001-03-16 15:03:13 +0000224 static
225 FT_Error get_cff_glyph_name( CFF_Face face,
226 FT_UInt glyph_index,
227 FT_Pointer buffer,
228 FT_UInt buffer_max )
229 {
Werner Lemberg521a2d72001-03-20 22:58:56 +0000230 CFF_Font* font = (CFF_Font*)face->extra.data;
Tom Kacvinsky84ad2a22001-03-16 15:03:13 +0000231 FT_Memory memory = FT_FACE_MEMORY(face);
232 FT_String* gname;
233 FT_UShort sid;
234 PSNames_Interface* psnames;
235 FT_Error error;
236
Werner Lemberg521a2d72001-03-20 22:58:56 +0000237 psnames = (PSNames_Interface*)FT_Get_Module_Interface(
238 face->root.driver->root.library, "psnames" );
Tom Kacvinsky84ad2a22001-03-16 15:03:13 +0000239
240 if ( !psnames )
241 {
242 FT_ERROR(( "CFF_Init_Face:" ));
243 FT_ERROR(( " cannot open CFF & CEF fonts\n" ));
244 FT_ERROR(( " " ));
245 FT_ERROR(( " without the `PSNames' module\n" ));
Werner Lemberg1429db62001-04-02 23:54:01 +0000246 error = CFF_Err_Unknown_File_Format;
Tom Kacvinsky84ad2a22001-03-16 15:03:13 +0000247 goto Exit;
248 }
249
250 /* first, locate the sid in the charset table */
251 sid = font->charset.sids[glyph_index];
252
253 /* now, lookup the name itself */
254 gname = CFF_Get_String( &font->string_index, sid, psnames );
255
256 if ( buffer_max > 0 )
257 {
258 FT_UInt len = strlen( gname );
259
260
Werner Lemberg521a2d72001-03-20 22:58:56 +0000261 if ( len >= buffer_max )
Tom Kacvinsky84ad2a22001-03-16 15:03:13 +0000262 len = buffer_max - 1;
263
264 MEM_Copy( buffer, gname, len );
265 ((FT_Byte*)buffer)[len] = 0;
266 }
267
268 FREE ( gname );
269 error = CFF_Err_Ok;
270
271 Exit:
272 return error;
273 }
274
Werner Lemberg521a2d72001-03-20 22:58:56 +0000275
David Turner19ed8af2000-12-08 02:42:29 +0000276 /*************************************************************************/
277 /* */
278 /* <Function> */
279 /* Get_Char_Index */
280 /* */
281 /* <Description> */
282 /* Uses a charmap to return a given character code's glyph index. */
283 /* */
284 /* <Input> */
285 /* charmap :: A handle to the source charmap object. */
286 /* charcode :: The character code. */
287 /* */
288 /* <Return> */
289 /* Glyph index. 0 means `undefined character code'. */
290 /* */
291 static
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000292 FT_UInt cff_get_char_index( TT_CharMap charmap,
Werner Lembergd573c7e2001-01-03 07:14:12 +0000293 FT_Long charcode )
David Turner19ed8af2000-12-08 02:42:29 +0000294 {
295 FT_Error error;
Werner Lembergd573c7e2001-01-03 07:14:12 +0000296 CFF_Face face;
David Turner19ed8af2000-12-08 02:42:29 +0000297 TT_CMapTable* cmap;
298
299
300 cmap = &charmap->cmap;
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000301 face = (CFF_Face)charmap->root.face;
David Turner19ed8af2000-12-08 02:42:29 +0000302
303 /* Load table if needed */
304 if ( !cmap->loaded )
305 {
306 SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt;
307
308
309 error = sfnt->load_charmap( face, cmap, face->root.stream );
310 if ( error )
311 return 0;
312
313 cmap->loaded = TRUE;
314 }
315
316 return ( cmap->get_index ? cmap->get_index( cmap, charcode ) : 0 );
317 }
318
319
320 /*************************************************************************/
321 /*************************************************************************/
322 /*************************************************************************/
323 /**** ****/
324 /**** ****/
325 /**** D R I V E R I N T E R F A C E ****/
326 /**** ****/
327 /**** ****/
328 /*************************************************************************/
329 /*************************************************************************/
330 /*************************************************************************/
331
David Turner19ed8af2000-12-08 02:42:29 +0000332 static
Werner Lembergd573c7e2001-01-03 07:14:12 +0000333 FT_Module_Interface cff_get_interface( CFF_Driver driver,
334 const char* interface )
David Turner19ed8af2000-12-08 02:42:29 +0000335 {
336 FT_Module sfnt;
337
Tom Kacvinsky84ad2a22001-03-16 15:03:13 +0000338#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
339 if ( strcmp( (const char*)interface, "glyph_name" ) == 0 )
340 return (FT_Module_Interface)get_cff_glyph_name;
341#endif
David Turner19ed8af2000-12-08 02:42:29 +0000342
343 /* we simply pass our request to the `sfnt' module */
344 sfnt = FT_Get_Module( driver->root.root.library, "sfnt" );
345
346 return sfnt ? sfnt->clazz->get_interface( sfnt, interface ) : 0;
347 }
348
349
350 /* The FT_DriverInterface structure is defined in ftdriver.h. */
351
352 FT_CALLBACK_TABLE_DEF
353 const FT_Driver_Class cff_driver_class =
354 {
355 /* begin with the FT_Module_Class fields */
356 {
357 ft_module_font_driver | ft_module_driver_scalable,
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000358 sizeof( CFF_DriverRec ),
David Turner19ed8af2000-12-08 02:42:29 +0000359 "cff",
360 0x10000L,
361 0x20000L,
362
363 0, /* module-specific interface */
364
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000365 (FT_Module_Constructor)CFF_Init_Driver,
366 (FT_Module_Destructor) CFF_Done_Driver,
367 (FT_Module_Requester) cff_get_interface,
David Turner19ed8af2000-12-08 02:42:29 +0000368 },
369
370 /* now the specific driver fields */
371 sizeof( TT_FaceRec ),
372 sizeof( FT_SizeRec ),
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000373 sizeof( CFF_GlyphSlotRec ),
David Turner19ed8af2000-12-08 02:42:29 +0000374
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000375 (FTDriver_initFace) CFF_Init_Face,
376 (FTDriver_doneFace) CFF_Done_Face,
David Turner19ed8af2000-12-08 02:42:29 +0000377 (FTDriver_initSize) 0,
378 (FTDriver_doneSize) 0,
379 (FTDriver_initGlyphSlot)0,
380 (FTDriver_doneGlyphSlot)0,
381
382 (FTDriver_setCharSizes) 0,
383 (FTDriver_setPixelSizes)0,
384
385 (FTDriver_loadGlyph) Load_Glyph,
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000386 (FTDriver_getCharIndex) cff_get_char_index,
David Turner19ed8af2000-12-08 02:42:29 +0000387
388 (FTDriver_getKerning) Get_Kerning,
389 (FTDriver_attachFile) 0,
390 (FTDriver_getAdvances) 0
391 };
392
393
394#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS
395
396
397 /*************************************************************************/
398 /* */
399 /* <Function> */
400 /* getDriverClass */
401 /* */
402 /* <Description> */
403 /* This function is used when compiling the TrueType driver as a */
404 /* shared library (`.DLL' or `.so'). It will be used by the */
405 /* high-level library of FreeType to retrieve the address of the */
406 /* driver's generic interface. */
407 /* */
408 /* It shouldn't be implemented in a static build, as each driver must */
409 /* have the same function as an exported entry point. */
410 /* */
411 /* <Return> */
412 /* The address of the TrueType's driver generic interface. The */
413 /* format-specific interface can then be retrieved through the method */
414 /* interface->get_format_interface. */
415 /* */
416 FT_EXPORT_DEF( const FT_Driver_Class* ) getDriverClass( void )
417 {
418 return &cff_driver_class;
419 }
420
421
422#endif /* CONFIG_OPTION_DYNAMIC_DRIVERS */
423
424
425/* END */