blob: af0eadf728af72e630293355487fa99337fc4c02 [file] [log] [blame]
David Turner37379e22000-03-28 11:22:31 +00001/***************************************************************************/
2/* */
3/* ftglyph.c */
4/* */
Werner Lembergf13e6332000-05-30 16:49:14 +00005/* FreeType convenience functions to handle glyphs (body). */
David Turner37379e22000-03-28 11:22:31 +00006/* */
Werner Lembergfa420252005-05-11 20:04:35 +00007/* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */
David Turner37379e22000-03-28 11:22:31 +00008/* David Turner, Robert Wilhelm, and Werner Lemberg. */
9/* */
Werner Lemberg4e6dd852000-06-05 05:26:15 +000010/* This file is part of the FreeType project, and may only be used, */
11/* modified, and distributed under the terms of the FreeType project */
David Turner37379e22000-03-28 11:22:31 +000012/* 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/* */
David Turner37379e22000-03-28 11:22:31 +000016/***************************************************************************/
17
Werner Lembergf13e6332000-05-30 16:49:14 +000018 /*************************************************************************/
19 /* */
20 /* This file contains the definition of several convenience functions */
21 /* that can be used by client applications to easily retrieve glyph */
22 /* bitmaps and outlines from a given face. */
23 /* */
24 /* These functions should be optional if you are writing a font server */
25 /* or text layout engine on top of FreeType. However, they are pretty */
26 /* handy for many other simple uses of the library. */
27 /* */
28 /*************************************************************************/
29
Werner Lembergcc069be2000-12-08 16:17:16 +000030
31#include <ft2build.h>
32#include FT_GLYPH_H
33#include FT_OUTLINE_H
Werner Lembergb9ee7372005-05-20 21:52:19 +000034#include FT_BITMAP_H
Werner Lembergcc069be2000-12-08 16:17:16 +000035#include FT_INTERNAL_OBJECTS_H
David Turner37379e22000-03-28 11:22:31 +000036
Werner Lembergf13e6332000-05-30 16:49:14 +000037
Werner Lembergeb81e372000-06-03 06:03:11 +000038 /*************************************************************************/
39 /* */
40 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
41 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
42 /* messages during execution. */
43 /* */
44#undef FT_COMPONENT
45#define FT_COMPONENT trace_glyph
46
Werner Lemberga8bbc262000-07-01 14:06:46 +000047
David Turnerf9ca2bb2000-06-30 23:12:55 +000048 /*************************************************************************/
49 /*************************************************************************/
50 /**** ****/
51 /**** Convenience functions ****/
52 /**** ****/
53 /*************************************************************************/
54 /*************************************************************************/
Werner Lembergeb81e372000-06-03 06:03:11 +000055
David Turnerf9ca2bb2000-06-30 23:12:55 +000056
Werner Lemberg90a03302000-11-07 17:21:11 +000057 /* documentation is in ftglyph.h */
58
Werner Lembergf814d0f2001-06-27 16:18:10 +000059 FT_EXPORT_DEF( void )
Graham Asherbe1a8da2003-01-14 15:53:33 +000060 FT_Matrix_Multiply( const FT_Matrix* a,
Werner Lembergc8c6bf52003-04-23 05:38:13 +000061 FT_Matrix *b )
David Turner1fb6eea2000-05-24 00:31:14 +000062 {
David Turnerf9ca2bb2000-06-30 23:12:55 +000063 FT_Fixed xx, xy, yx, yy;
David Turnere49ab252000-05-16 23:44:38 +000064
David Turnere49ab252000-05-16 23:44:38 +000065
Werner Lemberga8bbc262000-07-01 14:06:46 +000066 if ( !a || !b )
67 return;
68
David Turnerf9ca2bb2000-06-30 23:12:55 +000069 xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx );
70 xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy );
71 yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx );
72 yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy );
Werner Lembergf13e6332000-05-30 16:49:14 +000073
David Turnerf9ca2bb2000-06-30 23:12:55 +000074 b->xx = xx; b->xy = xy;
75 b->yx = yx; b->yy = yy;
76 }
77
78
Werner Lemberg90a03302000-11-07 17:21:11 +000079 /* documentation is in ftglyph.h */
80
Werner Lembergf814d0f2001-06-27 16:18:10 +000081 FT_EXPORT_DEF( FT_Error )
82 FT_Matrix_Invert( FT_Matrix* matrix )
David Turnerf9ca2bb2000-06-30 23:12:55 +000083 {
84 FT_Pos delta, xx, yy;
85
86
Werner Lemberga8bbc262000-07-01 14:06:46 +000087 if ( !matrix )
88 return FT_Err_Invalid_Argument;
89
David Turnerf9ca2bb2000-06-30 23:12:55 +000090 /* compute discriminant */
91 delta = FT_MulFix( matrix->xx, matrix->yy ) -
92 FT_MulFix( matrix->xy, matrix->yx );
93
94 if ( !delta )
95 return FT_Err_Invalid_Argument; /* matrix can't be inverted */
96
97 matrix->xy = - FT_DivFix( matrix->xy, delta );
98 matrix->yx = - FT_DivFix( matrix->yx, delta );
99
100 xx = matrix->xx;
101 yy = matrix->yy;
102
103 matrix->xx = FT_DivFix( yy, delta );
104 matrix->yy = FT_DivFix( xx, delta );
105
106 return FT_Err_Ok;
107 }
108
109
110 /*************************************************************************/
111 /*************************************************************************/
112 /**** ****/
113 /**** FT_BitmapGlyph support ****/
114 /**** ****/
115 /*************************************************************************/
116 /*************************************************************************/
117
Werner Lemberge260d252004-05-17 09:25:04 +0000118 FT_CALLBACK_DEF( FT_Error )
119 ft_bitmap_glyph_init( FT_Glyph bitmap_glyph,
120 FT_GlyphSlot slot )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000121 {
Werner Lemberge260d252004-05-17 09:25:04 +0000122 FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph;
123 FT_Error error = FT_Err_Ok;
124 FT_Library library = FT_GLYPH( glyph )->library;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000125
126
David Turnerb08fe2d2002-08-27 20:20:29 +0000127 if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
David Turner37379e22000-03-28 11:22:31 +0000128 {
David Turnerf9ca2bb2000-06-30 23:12:55 +0000129 error = FT_Err_Invalid_Glyph_Format;
130 goto Exit;
131 }
Werner Lemberga8bbc262000-07-01 14:06:46 +0000132
Werner Lembergb9ee7372005-05-20 21:52:19 +0000133 glyph->left = slot->bitmap_left;
134 glyph->top = slot->bitmap_top;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000135
Werner Lembergb9ee7372005-05-20 21:52:19 +0000136 /* do lazy copying whenever possible */
Werner Lemberg7a024102003-06-18 06:59:57 +0000137 if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
Werner Lembergb9ee7372005-05-20 21:52:19 +0000138 {
139 glyph->bitmap = slot->bitmap;
Werner Lemberg7a024102003-06-18 06:59:57 +0000140 slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
Werner Lembergb9ee7372005-05-20 21:52:19 +0000141 }
David Turner37379e22000-03-28 11:22:31 +0000142 else
143 {
Werner Lembergb9ee7372005-05-20 21:52:19 +0000144 FT_Bitmap_New( &glyph->bitmap );
145 error = FT_Bitmap_Copy( library, &slot->bitmap, &glyph->bitmap );
David Turner37379e22000-03-28 11:22:31 +0000146 }
Werner Lemberga8bbc262000-07-01 14:06:46 +0000147
David Turner37379e22000-03-28 11:22:31 +0000148 Exit:
149 return error;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000150 }
David Turnere49ab252000-05-16 23:44:38 +0000151
David Turnerf9ca2bb2000-06-30 23:12:55 +0000152
Werner Lemberge260d252004-05-17 09:25:04 +0000153 FT_CALLBACK_DEF( FT_Error )
154 ft_bitmap_glyph_copy( FT_Glyph bitmap_source,
155 FT_Glyph bitmap_target )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000156 {
Werner Lembergb9ee7372005-05-20 21:52:19 +0000157 FT_Library library = bitmap_source->library;
158 FT_BitmapGlyph source = (FT_BitmapGlyph)bitmap_source;
159 FT_BitmapGlyph target = (FT_BitmapGlyph)bitmap_target;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000160
161
162 target->left = source->left;
163 target->top = source->top;
164
Werner Lembergb9ee7372005-05-20 21:52:19 +0000165 return FT_Bitmap_Copy( library, &source->bitmap, &target->bitmap );
Werner Lemberga8bbc262000-07-01 14:06:46 +0000166 }
David Turnerf9ca2bb2000-06-30 23:12:55 +0000167
168
Werner Lemberge260d252004-05-17 09:25:04 +0000169 FT_CALLBACK_DEF( void )
170 ft_bitmap_glyph_done( FT_Glyph bitmap_glyph )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000171 {
Werner Lembergb9ee7372005-05-20 21:52:19 +0000172 FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph;
173 FT_Library library = FT_GLYPH( glyph )->library;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000174
175
Werner Lembergb9ee7372005-05-20 21:52:19 +0000176 FT_Bitmap_Done( library, &glyph->bitmap );
David Turner37379e22000-03-28 11:22:31 +0000177 }
178
David Turnere49ab252000-05-16 23:44:38 +0000179
Werner Lemberge260d252004-05-17 09:25:04 +0000180 FT_CALLBACK_DEF( void )
181 ft_bitmap_glyph_bbox( FT_Glyph bitmap_glyph,
182 FT_BBox* cbox )
David Turner37379e22000-03-28 11:22:31 +0000183 {
Werner Lemberge260d252004-05-17 09:25:04 +0000184 FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph;
185
186
David Turnerf9ca2bb2000-06-30 23:12:55 +0000187 cbox->xMin = glyph->left << 6;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000188 cbox->xMax = cbox->xMin + ( glyph->bitmap.width << 6 );
David Turnerf9ca2bb2000-06-30 23:12:55 +0000189 cbox->yMax = glyph->top << 6;
Werner Lemberg5a96b072000-10-17 14:29:48 +0000190 cbox->yMin = cbox->yMax - ( glyph->bitmap.rows << 6 );
Werner Lemberga8bbc262000-07-01 14:06:46 +0000191 }
David Turner37379e22000-03-28 11:22:31 +0000192
Werner Lembergf13e6332000-05-30 16:49:14 +0000193
Werner Lembergc846eac2004-02-19 21:39:58 +0000194 FT_CALLBACK_TABLE_DEF
Werner Lemberga8bbc262000-07-01 14:06:46 +0000195 const FT_Glyph_Class ft_bitmap_glyph_class =
David Turnerf9ca2bb2000-06-30 23:12:55 +0000196 {
Werner Lemberge260d252004-05-17 09:25:04 +0000197 sizeof ( FT_BitmapGlyphRec ),
David Turnerb08fe2d2002-08-27 20:20:29 +0000198 FT_GLYPH_FORMAT_BITMAP,
Werner Lemberga8bbc262000-07-01 14:06:46 +0000199
Werner Lemberge260d252004-05-17 09:25:04 +0000200 ft_bitmap_glyph_init,
201 ft_bitmap_glyph_done,
202 ft_bitmap_glyph_copy,
203 0, /* FT_Glyph_TransformFunc */
204 ft_bitmap_glyph_bbox,
205 0 /* FT_Glyph_PrepareFunc */
David Turnerf9ca2bb2000-06-30 23:12:55 +0000206 };
Werner Lemberg2fbf7e42000-06-02 00:01:14 +0000207
Werner Lemberga8bbc262000-07-01 14:06:46 +0000208
David Turnerf9ca2bb2000-06-30 23:12:55 +0000209 /*************************************************************************/
210 /*************************************************************************/
211 /**** ****/
212 /**** FT_OutlineGlyph support ****/
213 /**** ****/
214 /*************************************************************************/
215 /*************************************************************************/
Werner Lemberg2fbf7e42000-06-02 00:01:14 +0000216
David Turnere49ab252000-05-16 23:44:38 +0000217
Werner Lemberge260d252004-05-17 09:25:04 +0000218 FT_CALLBACK_DEF( FT_Error )
219 ft_outline_glyph_init( FT_Glyph outline_glyph,
220 FT_GlyphSlot slot )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000221 {
Werner Lemberge260d252004-05-17 09:25:04 +0000222 FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph;
223 FT_Error error = FT_Err_Ok;
224 FT_Library library = FT_GLYPH( glyph )->library;
225 FT_Outline* source = &slot->outline;
226 FT_Outline* target = &glyph->outline;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000227
228
David Turnerf9ca2bb2000-06-30 23:12:55 +0000229 /* check format in glyph slot */
David Turnerb08fe2d2002-08-27 20:20:29 +0000230 if ( slot->format != FT_GLYPH_FORMAT_OUTLINE )
David Turner37379e22000-03-28 11:22:31 +0000231 {
David Turnerf9ca2bb2000-06-30 23:12:55 +0000232 error = FT_Err_Invalid_Glyph_Format;
David Turner37379e22000-03-28 11:22:31 +0000233 goto Exit;
234 }
Werner Lemberga8bbc262000-07-01 14:06:46 +0000235
David Turnerf9ca2bb2000-06-30 23:12:55 +0000236 /* allocate new outline */
237 error = FT_Outline_New( library, source->n_points, source->n_contours,
David Turner37379e22000-03-28 11:22:31 +0000238 &glyph->outline );
Werner Lemberga8bbc262000-07-01 14:06:46 +0000239 if ( error )
240 goto Exit;
David Turnere49ab252000-05-16 23:44:38 +0000241
Werner Lembergb9ee7372005-05-20 21:52:19 +0000242 FT_Outline_Copy( source, target );
Werner Lembergf13e6332000-05-30 16:49:14 +0000243
David Turner37379e22000-03-28 11:22:31 +0000244 Exit:
245 return error;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000246 }
247
David Turnere49ab252000-05-16 23:44:38 +0000248
Werner Lemberge260d252004-05-17 09:25:04 +0000249 FT_CALLBACK_DEF( void )
250 ft_outline_glyph_done( FT_Glyph outline_glyph )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000251 {
Werner Lemberge260d252004-05-17 09:25:04 +0000252 FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph;
253
254
Werner Lemberga8bbc262000-07-01 14:06:46 +0000255 FT_Outline_Done( FT_GLYPH( glyph )->library, &glyph->outline );
David Turner37379e22000-03-28 11:22:31 +0000256 }
257
David Turnere49ab252000-05-16 23:44:38 +0000258
Werner Lemberge260d252004-05-17 09:25:04 +0000259 FT_CALLBACK_DEF( FT_Error )
260 ft_outline_glyph_copy( FT_Glyph outline_source,
261 FT_Glyph outline_target )
David Turner37379e22000-03-28 11:22:31 +0000262 {
Werner Lemberge260d252004-05-17 09:25:04 +0000263 FT_OutlineGlyph source = (FT_OutlineGlyph)outline_source;
264 FT_OutlineGlyph target = (FT_OutlineGlyph)outline_target;
265 FT_Error error;
266 FT_Library library = FT_GLYPH( source )->library;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000267
268
David Turnerf9ca2bb2000-06-30 23:12:55 +0000269 error = FT_Outline_New( library, source->outline.n_points,
270 source->outline.n_contours, &target->outline );
Werner Lemberga8bbc262000-07-01 14:06:46 +0000271 if ( !error )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000272 FT_Outline_Copy( &source->outline, &target->outline );
Werner Lemberga8bbc262000-07-01 14:06:46 +0000273
David Turnerf9ca2bb2000-06-30 23:12:55 +0000274 return error;
275 }
276
Werner Lemberga8bbc262000-07-01 14:06:46 +0000277
Werner Lemberge260d252004-05-17 09:25:04 +0000278 FT_CALLBACK_DEF( void )
Werner Lembergfa420252005-05-11 20:04:35 +0000279 ft_outline_glyph_transform( FT_Glyph outline_glyph,
280 const FT_Matrix* matrix,
281 const FT_Vector* delta )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000282 {
Werner Lemberge260d252004-05-17 09:25:04 +0000283 FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph;
284
285
Werner Lemberga8bbc262000-07-01 14:06:46 +0000286 if ( matrix )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000287 FT_Outline_Transform( &glyph->outline, matrix );
Werner Lemberga8bbc262000-07-01 14:06:46 +0000288
289 if ( delta )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000290 FT_Outline_Translate( &glyph->outline, delta->x, delta->y );
291 }
292
Werner Lemberga8bbc262000-07-01 14:06:46 +0000293
Werner Lemberge260d252004-05-17 09:25:04 +0000294 FT_CALLBACK_DEF( void )
295 ft_outline_glyph_bbox( FT_Glyph outline_glyph,
296 FT_BBox* bbox )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000297 {
Werner Lemberge260d252004-05-17 09:25:04 +0000298 FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph;
299
300
David Turnerf9ca2bb2000-06-30 23:12:55 +0000301 FT_Outline_Get_CBox( &glyph->outline, bbox );
Werner Lemberga8bbc262000-07-01 14:06:46 +0000302 }
303
David Turnerf9ca2bb2000-06-30 23:12:55 +0000304
Werner Lemberge260d252004-05-17 09:25:04 +0000305 FT_CALLBACK_DEF( FT_Error )
306 ft_outline_glyph_prepare( FT_Glyph outline_glyph,
307 FT_GlyphSlot slot )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000308 {
Werner Lemberge260d252004-05-17 09:25:04 +0000309 FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph;
310
311
David Turnerb08fe2d2002-08-27 20:20:29 +0000312 slot->format = FT_GLYPH_FORMAT_OUTLINE;
David Turnerf9ca2bb2000-06-30 23:12:55 +0000313 slot->outline = glyph->outline;
David Turnerb08fe2d2002-08-27 20:20:29 +0000314 slot->outline.flags &= ~FT_OUTLINE_OWNER;
David Turnerf9ca2bb2000-06-30 23:12:55 +0000315
Werner Lemberga8bbc262000-07-01 14:06:46 +0000316 return FT_Err_Ok;
317 }
318
319
Werner Lembergc846eac2004-02-19 21:39:58 +0000320 FT_CALLBACK_TABLE_DEF
Werner Lemberga8bbc262000-07-01 14:06:46 +0000321 const FT_Glyph_Class ft_outline_glyph_class =
David Turnerf9ca2bb2000-06-30 23:12:55 +0000322 {
Werner Lemberge260d252004-05-17 09:25:04 +0000323 sizeof ( FT_OutlineGlyphRec ),
David Turnerb08fe2d2002-08-27 20:20:29 +0000324 FT_GLYPH_FORMAT_OUTLINE,
Werner Lemberga8bbc262000-07-01 14:06:46 +0000325
Werner Lemberge260d252004-05-17 09:25:04 +0000326 ft_outline_glyph_init,
327 ft_outline_glyph_done,
328 ft_outline_glyph_copy,
329 ft_outline_glyph_transform,
330 ft_outline_glyph_bbox,
331 ft_outline_glyph_prepare
David Turnerf9ca2bb2000-06-30 23:12:55 +0000332 };
333
Werner Lemberga8bbc262000-07-01 14:06:46 +0000334
David Turnerf9ca2bb2000-06-30 23:12:55 +0000335 /*************************************************************************/
336 /*************************************************************************/
337 /**** ****/
338 /**** FT_Glyph class and API ****/
339 /**** ****/
340 /*************************************************************************/
341 /*************************************************************************/
342
Werner Lembergf814d0f2001-06-27 16:18:10 +0000343 static FT_Error
344 ft_new_glyph( FT_Library library,
345 const FT_Glyph_Class* clazz,
346 FT_Glyph* aglyph )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000347 {
348 FT_Memory memory = library->memory;
349 FT_Error error;
350 FT_Glyph glyph;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000351
352
David Turnerf9ca2bb2000-06-30 23:12:55 +0000353 *aglyph = 0;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000354
David Turnere459d742002-03-22 13:52:37 +0000355 if ( !FT_ALLOC( glyph, clazz->glyph_size ) )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000356 {
357 glyph->library = library;
358 glyph->clazz = clazz;
359 glyph->format = clazz->glyph_format;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000360
David Turnerf9ca2bb2000-06-30 23:12:55 +0000361 *aglyph = glyph;
362 }
Werner Lemberga8bbc262000-07-01 14:06:46 +0000363
David Turnerf9ca2bb2000-06-30 23:12:55 +0000364 return error;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000365 }
David Turnerf9ca2bb2000-06-30 23:12:55 +0000366
367
Werner Lemberg90a03302000-11-07 17:21:11 +0000368 /* documentation is in ftglyph.h */
369
Werner Lembergf814d0f2001-06-27 16:18:10 +0000370 FT_EXPORT_DEF( FT_Error )
371 FT_Glyph_Copy( FT_Glyph source,
372 FT_Glyph *target )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000373 {
374 FT_Glyph copy;
375 FT_Error error;
376 const FT_Glyph_Class* clazz;
377
Werner Lemberga8bbc262000-07-01 14:06:46 +0000378
David Turnerf9ca2bb2000-06-30 23:12:55 +0000379 /* check arguments */
Werner Lemberga8bbc262000-07-01 14:06:46 +0000380 if ( !target || !source || !source->clazz )
David Turner37379e22000-03-28 11:22:31 +0000381 {
David Turnerf9ca2bb2000-06-30 23:12:55 +0000382 error = FT_Err_Invalid_Argument;
383 goto Exit;
384 }
Werner Lemberga8bbc262000-07-01 14:06:46 +0000385
386 *target = 0;
387
David Turnerf9ca2bb2000-06-30 23:12:55 +0000388 clazz = source->clazz;
389 error = ft_new_glyph( source->library, clazz, &copy );
Werner Lemberga8bbc262000-07-01 14:06:46 +0000390 if ( error )
391 goto Exit;
David Turnerf9ca2bb2000-06-30 23:12:55 +0000392
David Turner8fe916c2001-02-16 16:27:35 +0000393 copy->advance = source->advance;
394 copy->format = source->format;
395
Werner Lemberga8bbc262000-07-01 14:06:46 +0000396 if ( clazz->glyph_copy )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000397 error = clazz->glyph_copy( source, copy );
Werner Lemberga8bbc262000-07-01 14:06:46 +0000398
399 if ( error )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000400 FT_Done_Glyph( copy );
401 else
402 *target = copy;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000403
David Turnerf9ca2bb2000-06-30 23:12:55 +0000404 Exit:
405 return error;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000406 }
David Turnere49ab252000-05-16 23:44:38 +0000407
Werner Lembergf13e6332000-05-30 16:49:14 +0000408
Werner Lemberg90a03302000-11-07 17:21:11 +0000409 /* documentation is in ftglyph.h */
410
Werner Lembergf814d0f2001-06-27 16:18:10 +0000411 FT_EXPORT_DEF( FT_Error )
412 FT_Get_Glyph( FT_GlyphSlot slot,
413 FT_Glyph *aglyph )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000414 {
David Turnerc4ec9732003-09-29 20:35:34 +0000415 FT_Library library;
David Turnerf9ca2bb2000-06-30 23:12:55 +0000416 FT_Error error;
417 FT_Glyph glyph;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000418
David Turnerf9ca2bb2000-06-30 23:12:55 +0000419 const FT_Glyph_Class* clazz = 0;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000420
421
422 if ( !slot )
423 return FT_Err_Invalid_Slot_Handle;
424
David Turnerc4ec9732003-09-29 20:35:34 +0000425 library = slot->library;
426
Werner Lembergaa8c7da2000-07-04 03:37:18 +0000427 if ( !aglyph )
Werner Lemberga8bbc262000-07-01 14:06:46 +0000428 return FT_Err_Invalid_Argument;
429
430 /* if it is a bitmap, that's easy :-) */
David Turnerb08fe2d2002-08-27 20:20:29 +0000431 if ( slot->format == FT_GLYPH_FORMAT_BITMAP )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000432 clazz = &ft_bitmap_glyph_class;
433
Werner Lemberga8bbc262000-07-01 14:06:46 +0000434 /* it it is an outline too */
David Turnerb08fe2d2002-08-27 20:20:29 +0000435 else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000436 clazz = &ft_outline_glyph_class;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000437
David Turnerf9ca2bb2000-06-30 23:12:55 +0000438 else
439 {
440 /* try to find a renderer that supports the glyph image format */
441 FT_Renderer render = FT_Lookup_Renderer( library, slot->format, 0 );
Werner Lemberga8bbc262000-07-01 14:06:46 +0000442
443
444 if ( render )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000445 clazz = &render->glyph_class;
446 }
Werner Lemberga8bbc262000-07-01 14:06:46 +0000447
448 if ( !clazz )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000449 {
450 error = FT_Err_Invalid_Glyph_Format;
451 goto Exit;
452 }
Werner Lemberga8bbc262000-07-01 14:06:46 +0000453
David Turnerf9ca2bb2000-06-30 23:12:55 +0000454 /* create FT_Glyph object */
455 error = ft_new_glyph( library, clazz, &glyph );
Werner Lemberga8bbc262000-07-01 14:06:46 +0000456 if ( error )
457 goto Exit;
458
459 /* copy advance while converting it to 16.16 format */
David Turnerf9ca2bb2000-06-30 23:12:55 +0000460 glyph->advance.x = slot->advance.x << 10;
461 glyph->advance.y = slot->advance.y << 10;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000462
David Turnerf9ca2bb2000-06-30 23:12:55 +0000463 /* now import the image from the glyph slot */
464 error = clazz->glyph_init( glyph, slot );
Werner Lemberga8bbc262000-07-01 14:06:46 +0000465
466 /* if an error occurred, destroy the glyph */
467 if ( error )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000468 FT_Done_Glyph( glyph );
469 else
470 *aglyph = glyph;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000471
David Turnerf9ca2bb2000-06-30 23:12:55 +0000472 Exit:
473 return error;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000474 }
David Turnerf9ca2bb2000-06-30 23:12:55 +0000475
476
Werner Lemberg90a03302000-11-07 17:21:11 +0000477 /* documentation is in ftglyph.h */
478
Werner Lembergf814d0f2001-06-27 16:18:10 +0000479 FT_EXPORT_DEF( FT_Error )
480 FT_Glyph_Transform( FT_Glyph glyph,
481 FT_Matrix* matrix,
482 FT_Vector* delta )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000483 {
484 const FT_Glyph_Class* clazz;
485 FT_Error error = FT_Err_Ok;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000486
487
488 if ( !glyph || !glyph->clazz )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000489 error = FT_Err_Invalid_Argument;
490 else
491 {
492 clazz = glyph->clazz;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000493 if ( clazz->glyph_transform )
David Turner37379e22000-03-28 11:22:31 +0000494 {
David Turnerf9ca2bb2000-06-30 23:12:55 +0000495 /* transform glyph image */
496 clazz->glyph_transform( glyph, matrix, delta );
Werner Lemberga8bbc262000-07-01 14:06:46 +0000497
David Turnerf9ca2bb2000-06-30 23:12:55 +0000498 /* transform advance vector */
Werner Lemberga8bbc262000-07-01 14:06:46 +0000499 if ( matrix )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000500 FT_Vector_Transform( &glyph->advance, matrix );
David Turner37379e22000-03-28 11:22:31 +0000501 }
David Turnerf9ca2bb2000-06-30 23:12:55 +0000502 else
503 error = FT_Err_Invalid_Glyph_Format;
504 }
505 return error;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000506 }
David Turnerf9ca2bb2000-06-30 23:12:55 +0000507
Werner Lemberga8bbc262000-07-01 14:06:46 +0000508
Werner Lemberg90a03302000-11-07 17:21:11 +0000509 /* documentation is in ftglyph.h */
510
Werner Lembergf814d0f2001-06-27 16:18:10 +0000511 FT_EXPORT_DEF( void )
512 FT_Glyph_Get_CBox( FT_Glyph glyph,
513 FT_UInt bbox_mode,
514 FT_BBox *acbox )
Werner Lemberga8bbc262000-07-01 14:06:46 +0000515 {
David Turnerf9ca2bb2000-06-30 23:12:55 +0000516 const FT_Glyph_Class* clazz;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000517
518
Werner Lembergcf24d512001-06-18 14:23:45 +0000519 if ( !acbox )
520 return;
521
522 acbox->xMin = acbox->yMin = acbox->xMax = acbox->yMax = 0;
523
524 if ( !glyph || !glyph->clazz )
525 return;
David Turnerf9ca2bb2000-06-30 23:12:55 +0000526 else
527 {
528 clazz = glyph->clazz;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000529 if ( !clazz->glyph_bbox )
Werner Lembergcf24d512001-06-18 14:23:45 +0000530 return;
David Turnerf9ca2bb2000-06-30 23:12:55 +0000531 else
David Turner37379e22000-03-28 11:22:31 +0000532 {
David Turnerf9ca2bb2000-06-30 23:12:55 +0000533 /* retrieve bbox in 26.6 coordinates */
Werner Lemberg4b680072000-11-07 06:30:29 +0000534 clazz->glyph_bbox( glyph, acbox );
Werner Lemberga8bbc262000-07-01 14:06:46 +0000535
David Turnerf9ca2bb2000-06-30 23:12:55 +0000536 /* perform grid fitting if needed */
Werner Lemberg052904e2003-06-17 10:42:27 +0000537 if ( bbox_mode == FT_GLYPH_BBOX_GRIDFIT ||
538 bbox_mode == FT_GLYPH_BBOX_PIXELS )
David Turner37379e22000-03-28 11:22:31 +0000539 {
David Turner87c0d302003-12-24 01:10:46 +0000540 acbox->xMin = FT_PIX_FLOOR( acbox->xMin );
541 acbox->yMin = FT_PIX_FLOOR( acbox->yMin );
542 acbox->xMax = FT_PIX_CEIL( acbox->xMax );
543 acbox->yMax = FT_PIX_CEIL( acbox->yMax );
David Turnerf9ca2bb2000-06-30 23:12:55 +0000544 }
Werner Lemberga8bbc262000-07-01 14:06:46 +0000545
David Turnerf9ca2bb2000-06-30 23:12:55 +0000546 /* convert to integer pixels if needed */
Werner Lemberg052904e2003-06-17 10:42:27 +0000547 if ( bbox_mode == FT_GLYPH_BBOX_TRUNCATE ||
548 bbox_mode == FT_GLYPH_BBOX_PIXELS )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000549 {
Werner Lemberg4b680072000-11-07 06:30:29 +0000550 acbox->xMin >>= 6;
551 acbox->yMin >>= 6;
552 acbox->xMax >>= 6;
553 acbox->yMax >>= 6;
David Turner37379e22000-03-28 11:22:31 +0000554 }
555 }
David Turnerf9ca2bb2000-06-30 23:12:55 +0000556 }
557 return;
558 }
David Turnere49ab252000-05-16 23:44:38 +0000559
David Turnerf9ca2bb2000-06-30 23:12:55 +0000560
Werner Lemberg90a03302000-11-07 17:21:11 +0000561 /* documentation is in ftglyph.h */
562
Werner Lembergf814d0f2001-06-27 16:18:10 +0000563 FT_EXPORT_DEF( FT_Error )
Werner Lemberg68e9f922002-09-27 11:09:23 +0000564 FT_Glyph_To_Bitmap( FT_Glyph* the_glyph,
565 FT_Render_Mode render_mode,
566 FT_Vector* origin,
567 FT_Bool destroy )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000568 {
Werner Lemberg7a024102003-06-18 06:59:57 +0000569 FT_GlyphSlotRec dummy;
570 FT_GlyphSlot_InternalRec dummy_internal;
571 FT_Error error = FT_Err_Ok;
572 FT_Glyph glyph;
573 FT_BitmapGlyph bitmap = NULL;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000574
Werner Lemberg7a024102003-06-18 06:59:57 +0000575 const FT_Glyph_Class* clazz;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000576
577
578 /* check argument */
579 if ( !the_glyph )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000580 goto Bad;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000581
582 /* we render the glyph into a glyph bitmap using a `dummy' glyph slot */
583 /* then calling FT_Render_Glyph_Internal() */
584
David Turnerf9ca2bb2000-06-30 23:12:55 +0000585 glyph = *the_glyph;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000586 if ( !glyph )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000587 goto Bad;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000588
David Turnerf9ca2bb2000-06-30 23:12:55 +0000589 clazz = glyph->clazz;
David Turnerf0f1b6a2002-07-08 23:05:14 +0000590
Werner Lemberg75ad4b82003-05-28 06:10:57 +0000591 /* when called with a bitmap glyph, do nothing and return successfully */
David Turnerf0f1b6a2002-07-08 23:05:14 +0000592 if ( clazz == &ft_bitmap_glyph_class )
593 goto Exit;
594
Werner Lemberga8bbc262000-07-01 14:06:46 +0000595 if ( !clazz || !clazz->glyph_prepare )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000596 goto Bad;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000597
Werner Lembergb3d5e9c2002-07-28 05:05:24 +0000598 FT_MEM_ZERO( &dummy, sizeof ( dummy ) );
Werner Lemberg7a024102003-06-18 06:59:57 +0000599 FT_MEM_ZERO( &dummy_internal, sizeof ( dummy_internal ) );
600 dummy.internal = &dummy_internal;
601 dummy.library = glyph->library;
602 dummy.format = clazz->glyph_format;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000603
Werner Lemberga8bbc262000-07-01 14:06:46 +0000604 /* create result bitmap glyph */
David Turnerf9ca2bb2000-06-30 23:12:55 +0000605 error = ft_new_glyph( glyph->library, &ft_bitmap_glyph_class,
Werner Lemberg92aa5272005-05-23 21:33:02 +0000606 (FT_Glyph*)(void*)&bitmap );
Werner Lemberge9e130c2001-12-07 21:56:32 +0000607 if ( error )
Werner Lemberga8bbc262000-07-01 14:06:46 +0000608 goto Exit;
609
Werner Lemberg75ad4b82003-05-28 06:10:57 +0000610#if 1
David Turnerc8ad30a2001-12-05 17:24:34 +0000611 /* if `origin' is set, translate the glyph image */
612 if ( origin )
613 FT_Glyph_Transform( glyph, 0, origin );
Werner Lemberg5da9dd72001-12-16 08:17:33 +0000614#else
615 FT_UNUSED( origin );
David Turnerc8ad30a2001-12-05 17:24:34 +0000616#endif
617
David Turnerf9ca2bb2000-06-30 23:12:55 +0000618 /* prepare dummy slot for rendering */
David Turnerc38ddff2000-08-21 04:43:01 +0000619 error = clazz->glyph_prepare( glyph, &dummy );
Werner Lemberg8728f292000-08-23 17:32:42 +0000620 if ( !error )
David Turnerc38ddff2000-08-21 04:43:01 +0000621 error = FT_Render_Glyph_Internal( glyph->library, &dummy, render_mode );
Werner Lemberga8bbc262000-07-01 14:06:46 +0000622
Werner Lemberg75ad4b82003-05-28 06:10:57 +0000623#if 1
Werner Lemberga8bbc262000-07-01 14:06:46 +0000624 if ( !destroy && origin )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000625 {
626 FT_Vector v;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000627
628
David Turnerf9ca2bb2000-06-30 23:12:55 +0000629 v.x = -origin->x;
630 v.y = -origin->y;
631 FT_Glyph_Transform( glyph, 0, &v );
632 }
David Turnerc8ad30a2001-12-05 17:24:34 +0000633#endif
634
Werner Lemberge9e130c2001-12-07 21:56:32 +0000635 if ( error )
David Turnerc8ad30a2001-12-05 17:24:34 +0000636 goto Exit;
David Turnerf9ca2bb2000-06-30 23:12:55 +0000637
Werner Lemberg40911092000-11-03 07:57:51 +0000638 /* in case of success, copy the bitmap to the glyph bitmap */
Werner Lemberge260d252004-05-17 09:25:04 +0000639 error = ft_bitmap_glyph_init( (FT_Glyph)bitmap, &dummy );
David Turnerc8ad30a2001-12-05 17:24:34 +0000640 if ( error )
641 goto Exit;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000642
David Turnerc8ad30a2001-12-05 17:24:34 +0000643 /* copy advance */
644 bitmap->root.advance = glyph->advance;
Werner Lemberg40911092000-11-03 07:57:51 +0000645
David Turnerc8ad30a2001-12-05 17:24:34 +0000646 if ( destroy )
647 FT_Done_Glyph( glyph );
Werner Lemberga8bbc262000-07-01 14:06:46 +0000648
David Turnerc8ad30a2001-12-05 17:24:34 +0000649 *the_glyph = FT_GLYPH( bitmap );
Werner Lemberga8bbc262000-07-01 14:06:46 +0000650
David Turnerf9ca2bb2000-06-30 23:12:55 +0000651 Exit:
Werner Lemberge9e130c2001-12-07 21:56:32 +0000652 if ( error && bitmap )
653 FT_Done_Glyph( FT_GLYPH( bitmap ) );
654
David Turnerf9ca2bb2000-06-30 23:12:55 +0000655 return error;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000656
David Turnerf9ca2bb2000-06-30 23:12:55 +0000657 Bad:
658 error = FT_Err_Invalid_Argument;
659 goto Exit;
Werner Lemberga8bbc262000-07-01 14:06:46 +0000660 }
David Turnerf9ca2bb2000-06-30 23:12:55 +0000661
David Turnerf9ca2bb2000-06-30 23:12:55 +0000662
Werner Lemberg90a03302000-11-07 17:21:11 +0000663 /* documentation is in ftglyph.h */
664
Werner Lembergf814d0f2001-06-27 16:18:10 +0000665 FT_EXPORT_DEF( void )
666 FT_Done_Glyph( FT_Glyph glyph )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000667 {
Werner Lemberga8bbc262000-07-01 14:06:46 +0000668 if ( glyph )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000669 {
670 FT_Memory memory = glyph->library->memory;
671 const FT_Glyph_Class* clazz = glyph->clazz;
672
Werner Lemberga8bbc262000-07-01 14:06:46 +0000673
674 if ( clazz->glyph_done )
David Turnerf9ca2bb2000-06-30 23:12:55 +0000675 clazz->glyph_done( glyph );
Werner Lemberga8bbc262000-07-01 14:06:46 +0000676
David Turnere459d742002-03-22 13:52:37 +0000677 FT_FREE( glyph );
David Turner37379e22000-03-28 11:22:31 +0000678 }
679 }
680
681
Werner Lembergf13e6332000-05-30 16:49:14 +0000682/* END */