]>
Commit | Line | Data |
---|---|---|
1 | /***************************************************************************/ | |
2 | /* */ | |
3 | /* t2driver.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 | ||
18 | ||
19 | #include <freetype/freetype.h> | |
20 | #include <freetype/internal/ftdebug.h> | |
21 | #include <freetype/internal/ftstream.h> | |
22 | #include <freetype/internal/sfnt.h> | |
23 | #include <freetype/ttnameid.h> | |
24 | ||
25 | #include <freetype/internal/t2errors.h> | |
26 | ||
27 | ||
28 | #ifdef FT_FLAT_COMPILE | |
29 | ||
30 | #include "t2driver.h" | |
31 | #include "t2gload.h" | |
32 | ||
33 | #else | |
34 | ||
35 | #include <cff/t2driver.h> | |
36 | #include <cff/t2gload.h> | |
37 | ||
38 | #endif | |
39 | ||
40 | ||
41 | /*************************************************************************/ | |
42 | /* */ | |
43 | /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ | |
44 | /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ | |
45 | /* messages during execution. */ | |
46 | /* */ | |
47 | #undef FT_COMPONENT | |
48 | #define FT_COMPONENT trace_t2driver | |
49 | ||
50 | ||
51 | /*************************************************************************/ | |
52 | /*************************************************************************/ | |
53 | /*************************************************************************/ | |
54 | /**** ****/ | |
55 | /**** ****/ | |
56 | /**** F A C E S ****/ | |
57 | /**** ****/ | |
58 | /**** ****/ | |
59 | /*************************************************************************/ | |
60 | /*************************************************************************/ | |
61 | /*************************************************************************/ | |
62 | ||
63 | ||
64 | #undef PAIR_TAG | |
65 | #define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \ | |
66 | (FT_ULong)right ) | |
67 | ||
68 | ||
69 | /*************************************************************************/ | |
70 | /* */ | |
71 | /* <Function> */ | |
72 | /* Get_Kerning */ | |
73 | /* */ | |
74 | /* <Description> */ | |
75 | /* A driver method used to return the kerning vector between two */ | |
76 | /* glyphs of the same face. */ | |
77 | /* */ | |
78 | /* <Input> */ | |
79 | /* face :: A handle to the source face object. */ | |
80 | /* */ | |
81 | /* left_glyph :: The index of the left glyph in the kern pair. */ | |
82 | /* */ | |
83 | /* right_glyph :: The index of the right glyph in the kern pair. */ | |
84 | /* */ | |
85 | /* <Output> */ | |
86 | /* kerning :: The kerning vector. This is in font units for */ | |
87 | /* scalable formats, and in pixels for fixed-sizes */ | |
88 | /* formats. */ | |
89 | /* */ | |
90 | /* <Return> */ | |
91 | /* FreeType error code. 0 means success. */ | |
92 | /* */ | |
93 | /* <Note> */ | |
94 | /* Only horizontal layouts (left-to-right & right-to-left) are */ | |
95 | /* supported by this function. Other layouts, or more sophisticated */ | |
96 | /* kernings, are out of scope of this method (the basic driver */ | |
97 | /* interface is meant to be simple). */ | |
98 | /* */ | |
99 | /* They can be implemented by format-specific interfaces. */ | |
100 | /* */ | |
101 | static | |
102 | FT_Error Get_Kerning( TT_Face face, | |
103 | FT_UInt left_glyph, | |
104 | FT_UInt right_glyph, | |
105 | FT_Vector* kerning ) | |
106 | { | |
107 | TT_Kern_0_Pair* pair; | |
108 | ||
109 | ||
110 | if ( !face ) | |
111 | return T2_Err_Invalid_Face_Handle; | |
112 | ||
113 | kerning->x = 0; | |
114 | kerning->y = 0; | |
115 | ||
116 | if ( face->kern_pairs ) | |
117 | { | |
118 | /* there are some kerning pairs in this font file! */ | |
119 | FT_ULong search_tag = PAIR_TAG( left_glyph, right_glyph ); | |
120 | FT_Long left, right; | |
121 | ||
122 | ||
123 | left = 0; | |
124 | right = face->num_kern_pairs - 1; | |
125 | ||
126 | while ( left <= right ) | |
127 | { | |
128 | FT_Int middle = left + ( ( right - left ) >> 1 ); | |
129 | FT_ULong cur_pair; | |
130 | ||
131 | ||
132 | pair = face->kern_pairs + middle; | |
133 | cur_pair = PAIR_TAG( pair->left, pair->right ); | |
134 | ||
135 | if ( cur_pair == search_tag ) | |
136 | goto Found; | |
137 | ||
138 | if ( cur_pair < search_tag ) | |
139 | left = middle + 1; | |
140 | else | |
141 | right = middle - 1; | |
142 | } | |
143 | } | |
144 | ||
145 | Exit: | |
146 | return T2_Err_Ok; | |
147 | ||
148 | Found: | |
149 | kerning->x = pair->value; | |
150 | goto Exit; | |
151 | } | |
152 | ||
153 | ||
154 | #undef PAIR_TAG | |
155 | ||
156 | ||
157 | /*************************************************************************/ | |
158 | /* */ | |
159 | /* <Function> */ | |
160 | /* Load_Glyph */ | |
161 | /* */ | |
162 | /* <Description> */ | |
163 | /* A driver method used to load a glyph within a given glyph slot. */ | |
164 | /* */ | |
165 | /* <Input> */ | |
166 | /* slot :: A handle to the target slot object where the glyph */ | |
167 | /* will be loaded. */ | |
168 | /* */ | |
169 | /* size :: A handle to the source face size at which the glyph */ | |
170 | /* must be scaled, loaded, etc. */ | |
171 | /* */ | |
172 | /* glyph_index :: The index of the glyph in the font file. */ | |
173 | /* */ | |
174 | /* load_flags :: A flag indicating what to load for this glyph. The */ | |
175 | /* FTLOAD_??? constants can be used to control the */ | |
176 | /* glyph loading process (e.g., whether the outline */ | |
177 | /* should be scaled, whether to load bitmaps or not, */ | |
178 | /* whether to hint the outline, etc). */ | |
179 | /* */ | |
180 | /* <Return> */ | |
181 | /* FreeType error code. 0 means success. */ | |
182 | /* */ | |
183 | static | |
184 | FT_Error Load_Glyph( T2_GlyphSlot slot, | |
185 | T2_Size size, | |
186 | FT_UShort glyph_index, | |
187 | FT_UInt load_flags ) | |
188 | { | |
189 | FT_Error error; | |
190 | ||
191 | ||
192 | if ( !slot ) | |
193 | return T2_Err_Invalid_Glyph_Handle; | |
194 | ||
195 | /* check whether we want a scaled outline or bitmap */ | |
196 | if ( !size ) | |
197 | load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; | |
198 | ||
199 | if ( load_flags & FT_LOAD_NO_SCALE ) | |
200 | size = NULL; | |
201 | ||
202 | /* reset the size object if necessary */ | |
203 | if ( size ) | |
204 | { | |
205 | /* these two object must have the same parent */ | |
206 | if ( size->face != slot->root.face ) | |
207 | return T2_Err_Invalid_Face_Handle; | |
208 | } | |
209 | ||
210 | /* now load the glyph outline if necessary */ | |
211 | error = T2_Load_Glyph( slot, size, glyph_index, load_flags ); | |
212 | ||
213 | /* force drop-out mode to 2 - irrelevant now */ | |
214 | /* slot->outline.dropout_mode = 2; */ | |
215 | ||
216 | return error; | |
217 | } | |
218 | ||
219 | ||
220 | /*************************************************************************/ | |
221 | /*************************************************************************/ | |
222 | /*************************************************************************/ | |
223 | /**** ****/ | |
224 | /**** ****/ | |
225 | /**** C H A R A C T E R M A P P I N G S ****/ | |
226 | /**** ****/ | |
227 | /**** ****/ | |
228 | /*************************************************************************/ | |
229 | /*************************************************************************/ | |
230 | /*************************************************************************/ | |
231 | ||
232 | /*************************************************************************/ | |
233 | /* */ | |
234 | /* <Function> */ | |
235 | /* Get_Char_Index */ | |
236 | /* */ | |
237 | /* <Description> */ | |
238 | /* Uses a charmap to return a given character code's glyph index. */ | |
239 | /* */ | |
240 | /* <Input> */ | |
241 | /* charmap :: A handle to the source charmap object. */ | |
242 | /* charcode :: The character code. */ | |
243 | /* */ | |
244 | /* <Return> */ | |
245 | /* Glyph index. 0 means `undefined character code'. */ | |
246 | /* */ | |
247 | static | |
248 | FT_UInt t2_get_char_index( TT_CharMap charmap, | |
249 | FT_Long charcode ) | |
250 | { | |
251 | FT_Error error; | |
252 | T2_Face face; | |
253 | TT_CMapTable* cmap; | |
254 | ||
255 | ||
256 | cmap = &charmap->cmap; | |
257 | face = (T2_Face)charmap->root.face; | |
258 | ||
259 | /* Load table if needed */ | |
260 | if ( !cmap->loaded ) | |
261 | { | |
262 | SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt; | |
263 | ||
264 | ||
265 | error = sfnt->load_charmap( face, cmap, face->root.stream ); | |
266 | if ( error ) | |
267 | return 0; | |
268 | ||
269 | cmap->loaded = TRUE; | |
270 | } | |
271 | ||
272 | return ( cmap->get_index ? cmap->get_index( cmap, charcode ) : 0 ); | |
273 | } | |
274 | ||
275 | ||
276 | /*************************************************************************/ | |
277 | /*************************************************************************/ | |
278 | /*************************************************************************/ | |
279 | /**** ****/ | |
280 | /**** ****/ | |
281 | /**** D R I V E R I N T E R F A C E ****/ | |
282 | /**** ****/ | |
283 | /**** ****/ | |
284 | /*************************************************************************/ | |
285 | /*************************************************************************/ | |
286 | /*************************************************************************/ | |
287 | ||
288 | ||
289 | static | |
290 | FT_Module_Interface t2_get_interface( T2_Driver driver, | |
291 | const char* interface ) | |
292 | { | |
293 | FT_Module sfnt; | |
294 | ||
295 | ||
296 | /* we simply pass our request to the `sfnt' module */ | |
297 | sfnt = FT_Get_Module( driver->root.root.library, "sfnt" ); | |
298 | ||
299 | return sfnt ? sfnt->clazz->get_interface( sfnt, interface ) : 0; | |
300 | } | |
301 | ||
302 | ||
303 | /* The FT_DriverInterface structure is defined in ftdriver.h. */ | |
304 | ||
305 | const FT_Driver_Class cff_driver_class = | |
306 | { | |
307 | /* begin with the FT_Module_Class fields */ | |
308 | { | |
309 | ft_module_font_driver | ft_module_driver_scalable, | |
310 | sizeof( T2_DriverRec ), | |
311 | "cff", | |
312 | 0x10000L, | |
313 | 0x20000L, | |
314 | ||
315 | 0, /* module-specific interface */ | |
316 | ||
317 | (FT_Module_Constructor)T2_Init_Driver, | |
318 | (FT_Module_Destructor) T2_Done_Driver, | |
319 | (FT_Module_Requester) t2_get_interface, | |
320 | }, | |
321 | ||
322 | /* now the specific driver fields */ | |
323 | sizeof( TT_FaceRec ), | |
324 | sizeof( FT_SizeRec ), | |
325 | sizeof( T2_GlyphSlotRec ), | |
326 | ||
327 | (FTDriver_initFace) T2_Init_Face, | |
328 | (FTDriver_doneFace) T2_Done_Face, | |
329 | (FTDriver_initSize) 0, | |
330 | (FTDriver_doneSize) 0, | |
331 | (FTDriver_initGlyphSlot)0, | |
332 | (FTDriver_doneGlyphSlot)0, | |
333 | ||
334 | (FTDriver_setCharSizes) 0, | |
335 | (FTDriver_setPixelSizes)0, | |
336 | ||
337 | (FTDriver_loadGlyph) Load_Glyph, | |
338 | (FTDriver_getCharIndex) t2_get_char_index, | |
339 | ||
340 | (FTDriver_getKerning) Get_Kerning, | |
341 | (FTDriver_attachFile) 0, | |
342 | (FTDriver_getAdvances) 0 | |
343 | }; | |
344 | ||
345 | ||
346 | #ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS | |
347 | ||
348 | ||
349 | /*************************************************************************/ | |
350 | /* */ | |
351 | /* <Function> */ | |
352 | /* getDriverClass */ | |
353 | /* */ | |
354 | /* <Description> */ | |
355 | /* This function is used when compiling the TrueType driver as a */ | |
356 | /* shared library (`.DLL' or `.so'). It will be used by the */ | |
357 | /* high-level library of FreeType to retrieve the address of the */ | |
358 | /* driver's generic interface. */ | |
359 | /* */ | |
360 | /* It shouldn't be implemented in a static build, as each driver must */ | |
361 | /* have the same function as an exported entry point. */ | |
362 | /* */ | |
363 | /* <Return> */ | |
364 | /* The address of the TrueType's driver generic interface. The */ | |
365 | /* format-specific interface can then be retrieved through the method */ | |
366 | /* interface->get_format_interface. */ | |
367 | /* */ | |
368 | EXPORT_FUNC( FT_Driver_Class* ) getDriverClass( void ) | |
369 | { | |
370 | return &cff_driver_class; | |
371 | } | |
372 | ||
373 | ||
374 | #endif /* CONFIG_OPTION_DYNAMIC_DRIVERS */ | |
375 | ||
376 | ||
377 | /* END */ |