xref: /inferno-os/libfreetype/ftglyph.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsyth /***************************************************************************/
2*37da2899SCharles.Forsyth /*                                                                         */
3*37da2899SCharles.Forsyth /*  ftglyph.c                                                              */
4*37da2899SCharles.Forsyth /*                                                                         */
5*37da2899SCharles.Forsyth /*    FreeType convenience functions to handle glyphs (body).              */
6*37da2899SCharles.Forsyth /*                                                                         */
7*37da2899SCharles.Forsyth /*  Copyright 1996-2001, 2002 by                                           */
8*37da2899SCharles.Forsyth /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9*37da2899SCharles.Forsyth /*                                                                         */
10*37da2899SCharles.Forsyth /*  This file is part of the FreeType project, and may only be used,       */
11*37da2899SCharles.Forsyth /*  modified, and distributed under the terms of the FreeType project      */
12*37da2899SCharles.Forsyth /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13*37da2899SCharles.Forsyth /*  this file you indicate that you have read the license and              */
14*37da2899SCharles.Forsyth /*  understand and accept it fully.                                        */
15*37da2899SCharles.Forsyth /*                                                                         */
16*37da2899SCharles.Forsyth /***************************************************************************/
17*37da2899SCharles.Forsyth 
18*37da2899SCharles.Forsyth   /*************************************************************************/
19*37da2899SCharles.Forsyth   /*                                                                       */
20*37da2899SCharles.Forsyth   /*  This file contains the definition of several convenience functions   */
21*37da2899SCharles.Forsyth   /*  that can be used by client applications to easily retrieve glyph     */
22*37da2899SCharles.Forsyth   /*  bitmaps and outlines from a given face.                              */
23*37da2899SCharles.Forsyth   /*                                                                       */
24*37da2899SCharles.Forsyth   /*  These functions should be optional if you are writing a font server  */
25*37da2899SCharles.Forsyth   /*  or text layout engine on top of FreeType.  However, they are pretty  */
26*37da2899SCharles.Forsyth   /*  handy for many other simple uses of the library.                     */
27*37da2899SCharles.Forsyth   /*                                                                       */
28*37da2899SCharles.Forsyth   /*************************************************************************/
29*37da2899SCharles.Forsyth 
30*37da2899SCharles.Forsyth 
31*37da2899SCharles.Forsyth #include <ft2build.h>
32*37da2899SCharles.Forsyth #include FT_GLYPH_H
33*37da2899SCharles.Forsyth #include FT_OUTLINE_H
34*37da2899SCharles.Forsyth #include FT_INTERNAL_OBJECTS_H
35*37da2899SCharles.Forsyth 
36*37da2899SCharles.Forsyth 
37*37da2899SCharles.Forsyth   /*************************************************************************/
38*37da2899SCharles.Forsyth   /*                                                                       */
39*37da2899SCharles.Forsyth   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
40*37da2899SCharles.Forsyth   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
41*37da2899SCharles.Forsyth   /* messages during execution.                                            */
42*37da2899SCharles.Forsyth   /*                                                                       */
43*37da2899SCharles.Forsyth #undef  FT_COMPONENT
44*37da2899SCharles.Forsyth #define FT_COMPONENT  trace_glyph
45*37da2899SCharles.Forsyth 
46*37da2899SCharles.Forsyth 
47*37da2899SCharles.Forsyth   /*************************************************************************/
48*37da2899SCharles.Forsyth   /*************************************************************************/
49*37da2899SCharles.Forsyth   /****                                                                 ****/
50*37da2899SCharles.Forsyth   /****   Convenience functions                                         ****/
51*37da2899SCharles.Forsyth   /****                                                                 ****/
52*37da2899SCharles.Forsyth   /*************************************************************************/
53*37da2899SCharles.Forsyth   /*************************************************************************/
54*37da2899SCharles.Forsyth 
55*37da2899SCharles.Forsyth 
56*37da2899SCharles.Forsyth   /* documentation is in ftglyph.h */
57*37da2899SCharles.Forsyth 
58*37da2899SCharles.Forsyth   FT_EXPORT_DEF( void )
FT_Matrix_Multiply(FT_Matrix * a,FT_Matrix * b)59*37da2899SCharles.Forsyth   FT_Matrix_Multiply( FT_Matrix*  a,
60*37da2899SCharles.Forsyth                       FT_Matrix*  b )
61*37da2899SCharles.Forsyth   {
62*37da2899SCharles.Forsyth     FT_Fixed  xx, xy, yx, yy;
63*37da2899SCharles.Forsyth 
64*37da2899SCharles.Forsyth 
65*37da2899SCharles.Forsyth     if ( !a || !b )
66*37da2899SCharles.Forsyth       return;
67*37da2899SCharles.Forsyth 
68*37da2899SCharles.Forsyth     xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx );
69*37da2899SCharles.Forsyth     xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy );
70*37da2899SCharles.Forsyth     yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx );
71*37da2899SCharles.Forsyth     yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy );
72*37da2899SCharles.Forsyth 
73*37da2899SCharles.Forsyth     b->xx = xx;  b->xy = xy;
74*37da2899SCharles.Forsyth     b->yx = yx;  b->yy = yy;
75*37da2899SCharles.Forsyth   }
76*37da2899SCharles.Forsyth 
77*37da2899SCharles.Forsyth 
78*37da2899SCharles.Forsyth   /* documentation is in ftglyph.h */
79*37da2899SCharles.Forsyth 
80*37da2899SCharles.Forsyth   FT_EXPORT_DEF( FT_Error )
FT_Matrix_Invert(FT_Matrix * matrix)81*37da2899SCharles.Forsyth   FT_Matrix_Invert( FT_Matrix*  matrix )
82*37da2899SCharles.Forsyth   {
83*37da2899SCharles.Forsyth     FT_Pos  delta, xx, yy;
84*37da2899SCharles.Forsyth 
85*37da2899SCharles.Forsyth 
86*37da2899SCharles.Forsyth     if ( !matrix )
87*37da2899SCharles.Forsyth       return FT_Err_Invalid_Argument;
88*37da2899SCharles.Forsyth 
89*37da2899SCharles.Forsyth     /* compute discriminant */
90*37da2899SCharles.Forsyth     delta = FT_MulFix( matrix->xx, matrix->yy ) -
91*37da2899SCharles.Forsyth             FT_MulFix( matrix->xy, matrix->yx );
92*37da2899SCharles.Forsyth 
93*37da2899SCharles.Forsyth     if ( !delta )
94*37da2899SCharles.Forsyth       return FT_Err_Invalid_Argument;  /* matrix can't be inverted */
95*37da2899SCharles.Forsyth 
96*37da2899SCharles.Forsyth     matrix->xy = - FT_DivFix( matrix->xy, delta );
97*37da2899SCharles.Forsyth     matrix->yx = - FT_DivFix( matrix->yx, delta );
98*37da2899SCharles.Forsyth 
99*37da2899SCharles.Forsyth     xx = matrix->xx;
100*37da2899SCharles.Forsyth     yy = matrix->yy;
101*37da2899SCharles.Forsyth 
102*37da2899SCharles.Forsyth     matrix->xx = FT_DivFix( yy, delta );
103*37da2899SCharles.Forsyth     matrix->yy = FT_DivFix( xx, delta );
104*37da2899SCharles.Forsyth 
105*37da2899SCharles.Forsyth     return FT_Err_Ok;
106*37da2899SCharles.Forsyth   }
107*37da2899SCharles.Forsyth 
108*37da2899SCharles.Forsyth 
109*37da2899SCharles.Forsyth   /*************************************************************************/
110*37da2899SCharles.Forsyth   /*************************************************************************/
111*37da2899SCharles.Forsyth   /****                                                                 ****/
112*37da2899SCharles.Forsyth   /****   FT_BitmapGlyph support                                        ****/
113*37da2899SCharles.Forsyth   /****                                                                 ****/
114*37da2899SCharles.Forsyth   /*************************************************************************/
115*37da2899SCharles.Forsyth   /*************************************************************************/
116*37da2899SCharles.Forsyth 
117*37da2899SCharles.Forsyth   static FT_Error
ft_bitmap_copy(FT_Memory memory,FT_Bitmap * source,FT_Bitmap * target)118*37da2899SCharles.Forsyth   ft_bitmap_copy( FT_Memory   memory,
119*37da2899SCharles.Forsyth                   FT_Bitmap*  source,
120*37da2899SCharles.Forsyth                   FT_Bitmap*  target )
121*37da2899SCharles.Forsyth   {
122*37da2899SCharles.Forsyth     FT_Error  error;
123*37da2899SCharles.Forsyth     FT_Int    pitch = source->pitch;
124*37da2899SCharles.Forsyth     FT_ULong  size;
125*37da2899SCharles.Forsyth 
126*37da2899SCharles.Forsyth 
127*37da2899SCharles.Forsyth     *target = *source;
128*37da2899SCharles.Forsyth 
129*37da2899SCharles.Forsyth     if ( pitch < 0 )
130*37da2899SCharles.Forsyth       pitch = -pitch;
131*37da2899SCharles.Forsyth 
132*37da2899SCharles.Forsyth     size = (FT_ULong)( pitch * source->rows );
133*37da2899SCharles.Forsyth 
134*37da2899SCharles.Forsyth     if ( !FT_ALLOC( target->buffer, size ) )
135*37da2899SCharles.Forsyth       FT_MEM_COPY( target->buffer, source->buffer, size );
136*37da2899SCharles.Forsyth 
137*37da2899SCharles.Forsyth     return error;
138*37da2899SCharles.Forsyth   }
139*37da2899SCharles.Forsyth 
140*37da2899SCharles.Forsyth 
141*37da2899SCharles.Forsyth   static FT_Error
ft_bitmap_glyph_init(FT_BitmapGlyph glyph,FT_GlyphSlot slot)142*37da2899SCharles.Forsyth   ft_bitmap_glyph_init( FT_BitmapGlyph  glyph,
143*37da2899SCharles.Forsyth                         FT_GlyphSlot    slot )
144*37da2899SCharles.Forsyth   {
145*37da2899SCharles.Forsyth     FT_Error    error   = FT_Err_Ok;
146*37da2899SCharles.Forsyth     FT_Library  library = FT_GLYPH(glyph)->library;
147*37da2899SCharles.Forsyth     FT_Memory   memory  = library->memory;
148*37da2899SCharles.Forsyth 
149*37da2899SCharles.Forsyth 
150*37da2899SCharles.Forsyth     if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
151*37da2899SCharles.Forsyth     {
152*37da2899SCharles.Forsyth       error = FT_Err_Invalid_Glyph_Format;
153*37da2899SCharles.Forsyth       goto Exit;
154*37da2899SCharles.Forsyth     }
155*37da2899SCharles.Forsyth 
156*37da2899SCharles.Forsyth     /* grab the bitmap in the slot - do lazy copying whenever possible */
157*37da2899SCharles.Forsyth     glyph->bitmap = slot->bitmap;
158*37da2899SCharles.Forsyth     glyph->left   = slot->bitmap_left;
159*37da2899SCharles.Forsyth     glyph->top    = slot->bitmap_top;
160*37da2899SCharles.Forsyth 
161*37da2899SCharles.Forsyth     if ( slot->flags & FT_GLYPH_OWN_BITMAP )
162*37da2899SCharles.Forsyth       slot->flags &= ~FT_GLYPH_OWN_BITMAP;
163*37da2899SCharles.Forsyth     else
164*37da2899SCharles.Forsyth     {
165*37da2899SCharles.Forsyth       /* copy the bitmap into a new buffer */
166*37da2899SCharles.Forsyth       error = ft_bitmap_copy( memory, &slot->bitmap, &glyph->bitmap );
167*37da2899SCharles.Forsyth     }
168*37da2899SCharles.Forsyth 
169*37da2899SCharles.Forsyth   Exit:
170*37da2899SCharles.Forsyth     return error;
171*37da2899SCharles.Forsyth   }
172*37da2899SCharles.Forsyth 
173*37da2899SCharles.Forsyth 
174*37da2899SCharles.Forsyth   static FT_Error
ft_bitmap_glyph_copy(FT_BitmapGlyph source,FT_BitmapGlyph target)175*37da2899SCharles.Forsyth   ft_bitmap_glyph_copy( FT_BitmapGlyph  source,
176*37da2899SCharles.Forsyth                         FT_BitmapGlyph  target )
177*37da2899SCharles.Forsyth   {
178*37da2899SCharles.Forsyth     FT_Memory  memory = source->root.library->memory;
179*37da2899SCharles.Forsyth 
180*37da2899SCharles.Forsyth 
181*37da2899SCharles.Forsyth     target->left = source->left;
182*37da2899SCharles.Forsyth     target->top  = source->top;
183*37da2899SCharles.Forsyth 
184*37da2899SCharles.Forsyth     return ft_bitmap_copy( memory, &source->bitmap, &target->bitmap );
185*37da2899SCharles.Forsyth   }
186*37da2899SCharles.Forsyth 
187*37da2899SCharles.Forsyth 
188*37da2899SCharles.Forsyth   static void
ft_bitmap_glyph_done(FT_BitmapGlyph glyph)189*37da2899SCharles.Forsyth   ft_bitmap_glyph_done( FT_BitmapGlyph  glyph )
190*37da2899SCharles.Forsyth   {
191*37da2899SCharles.Forsyth     FT_Memory  memory = FT_GLYPH(glyph)->library->memory;
192*37da2899SCharles.Forsyth 
193*37da2899SCharles.Forsyth 
194*37da2899SCharles.Forsyth     FT_FREE( glyph->bitmap.buffer );
195*37da2899SCharles.Forsyth   }
196*37da2899SCharles.Forsyth 
197*37da2899SCharles.Forsyth 
198*37da2899SCharles.Forsyth   static void
ft_bitmap_glyph_bbox(FT_BitmapGlyph glyph,FT_BBox * cbox)199*37da2899SCharles.Forsyth   ft_bitmap_glyph_bbox( FT_BitmapGlyph  glyph,
200*37da2899SCharles.Forsyth                         FT_BBox*        cbox )
201*37da2899SCharles.Forsyth   {
202*37da2899SCharles.Forsyth     cbox->xMin = glyph->left << 6;
203*37da2899SCharles.Forsyth     cbox->xMax = cbox->xMin + ( glyph->bitmap.width << 6 );
204*37da2899SCharles.Forsyth     cbox->yMax = glyph->top << 6;
205*37da2899SCharles.Forsyth     cbox->yMin = cbox->yMax - ( glyph->bitmap.rows << 6 );
206*37da2899SCharles.Forsyth   }
207*37da2899SCharles.Forsyth 
208*37da2899SCharles.Forsyth 
209*37da2899SCharles.Forsyth   const FT_Glyph_Class  ft_bitmap_glyph_class =
210*37da2899SCharles.Forsyth   {
211*37da2899SCharles.Forsyth     sizeof( FT_BitmapGlyphRec ),
212*37da2899SCharles.Forsyth     FT_GLYPH_FORMAT_BITMAP,
213*37da2899SCharles.Forsyth 
214*37da2899SCharles.Forsyth     (FT_Glyph_InitFunc)     ft_bitmap_glyph_init,
215*37da2899SCharles.Forsyth     (FT_Glyph_DoneFunc)     ft_bitmap_glyph_done,
216*37da2899SCharles.Forsyth     (FT_Glyph_CopyFunc)     ft_bitmap_glyph_copy,
217*37da2899SCharles.Forsyth     (FT_Glyph_TransformFunc)0,
218*37da2899SCharles.Forsyth     (FT_Glyph_GetBBoxFunc)  ft_bitmap_glyph_bbox,
219*37da2899SCharles.Forsyth     (FT_Glyph_PrepareFunc)  0
220*37da2899SCharles.Forsyth   };
221*37da2899SCharles.Forsyth 
222*37da2899SCharles.Forsyth 
223*37da2899SCharles.Forsyth   /*************************************************************************/
224*37da2899SCharles.Forsyth   /*************************************************************************/
225*37da2899SCharles.Forsyth   /****                                                                 ****/
226*37da2899SCharles.Forsyth   /****   FT_OutlineGlyph support                                       ****/
227*37da2899SCharles.Forsyth   /****                                                                 ****/
228*37da2899SCharles.Forsyth   /*************************************************************************/
229*37da2899SCharles.Forsyth   /*************************************************************************/
230*37da2899SCharles.Forsyth 
231*37da2899SCharles.Forsyth 
232*37da2899SCharles.Forsyth   static FT_Error
ft_outline_glyph_init(FT_OutlineGlyph glyph,FT_GlyphSlot slot)233*37da2899SCharles.Forsyth   ft_outline_glyph_init( FT_OutlineGlyph  glyph,
234*37da2899SCharles.Forsyth                          FT_GlyphSlot     slot )
235*37da2899SCharles.Forsyth   {
236*37da2899SCharles.Forsyth     FT_Error     error   = FT_Err_Ok;
237*37da2899SCharles.Forsyth     FT_Library   library = FT_GLYPH(glyph)->library;
238*37da2899SCharles.Forsyth     FT_Outline*  source  = &slot->outline;
239*37da2899SCharles.Forsyth     FT_Outline*  target  = &glyph->outline;
240*37da2899SCharles.Forsyth 
241*37da2899SCharles.Forsyth 
242*37da2899SCharles.Forsyth     /* check format in glyph slot */
243*37da2899SCharles.Forsyth     if ( slot->format != FT_GLYPH_FORMAT_OUTLINE )
244*37da2899SCharles.Forsyth     {
245*37da2899SCharles.Forsyth       error = FT_Err_Invalid_Glyph_Format;
246*37da2899SCharles.Forsyth       goto Exit;
247*37da2899SCharles.Forsyth     }
248*37da2899SCharles.Forsyth 
249*37da2899SCharles.Forsyth     /* allocate new outline */
250*37da2899SCharles.Forsyth     error = FT_Outline_New( library, source->n_points, source->n_contours,
251*37da2899SCharles.Forsyth                             &glyph->outline );
252*37da2899SCharles.Forsyth     if ( error )
253*37da2899SCharles.Forsyth       goto Exit;
254*37da2899SCharles.Forsyth 
255*37da2899SCharles.Forsyth     /* copy it */
256*37da2899SCharles.Forsyth     FT_MEM_COPY( target->points, source->points,
257*37da2899SCharles.Forsyth               source->n_points * sizeof ( FT_Vector ) );
258*37da2899SCharles.Forsyth 
259*37da2899SCharles.Forsyth     FT_MEM_COPY( target->tags, source->tags,
260*37da2899SCharles.Forsyth               source->n_points * sizeof ( FT_Byte ) );
261*37da2899SCharles.Forsyth 
262*37da2899SCharles.Forsyth     FT_MEM_COPY( target->contours, source->contours,
263*37da2899SCharles.Forsyth               source->n_contours * sizeof ( FT_Short ) );
264*37da2899SCharles.Forsyth 
265*37da2899SCharles.Forsyth     /* copy all flags, except the `FT_OUTLINE_OWNER' one */
266*37da2899SCharles.Forsyth     target->flags = source->flags | FT_OUTLINE_OWNER;
267*37da2899SCharles.Forsyth 
268*37da2899SCharles.Forsyth   Exit:
269*37da2899SCharles.Forsyth     return error;
270*37da2899SCharles.Forsyth   }
271*37da2899SCharles.Forsyth 
272*37da2899SCharles.Forsyth 
273*37da2899SCharles.Forsyth   static void
ft_outline_glyph_done(FT_OutlineGlyph glyph)274*37da2899SCharles.Forsyth   ft_outline_glyph_done( FT_OutlineGlyph  glyph )
275*37da2899SCharles.Forsyth   {
276*37da2899SCharles.Forsyth     FT_Outline_Done( FT_GLYPH( glyph )->library, &glyph->outline );
277*37da2899SCharles.Forsyth   }
278*37da2899SCharles.Forsyth 
279*37da2899SCharles.Forsyth 
280*37da2899SCharles.Forsyth   static FT_Error
ft_outline_glyph_copy(FT_OutlineGlyph source,FT_OutlineGlyph target)281*37da2899SCharles.Forsyth   ft_outline_glyph_copy( FT_OutlineGlyph  source,
282*37da2899SCharles.Forsyth                          FT_OutlineGlyph  target )
283*37da2899SCharles.Forsyth   {
284*37da2899SCharles.Forsyth     FT_Error    error;
285*37da2899SCharles.Forsyth     FT_Library  library = FT_GLYPH( source )->library;
286*37da2899SCharles.Forsyth 
287*37da2899SCharles.Forsyth 
288*37da2899SCharles.Forsyth     error = FT_Outline_New( library, source->outline.n_points,
289*37da2899SCharles.Forsyth                             source->outline.n_contours, &target->outline );
290*37da2899SCharles.Forsyth     if ( !error )
291*37da2899SCharles.Forsyth       FT_Outline_Copy( &source->outline, &target->outline );
292*37da2899SCharles.Forsyth 
293*37da2899SCharles.Forsyth     return error;
294*37da2899SCharles.Forsyth   }
295*37da2899SCharles.Forsyth 
296*37da2899SCharles.Forsyth 
297*37da2899SCharles.Forsyth   static void
ft_outline_glyph_transform(FT_OutlineGlyph glyph,FT_Matrix * matrix,FT_Vector * delta)298*37da2899SCharles.Forsyth   ft_outline_glyph_transform( FT_OutlineGlyph  glyph,
299*37da2899SCharles.Forsyth                               FT_Matrix*       matrix,
300*37da2899SCharles.Forsyth                               FT_Vector*       delta )
301*37da2899SCharles.Forsyth   {
302*37da2899SCharles.Forsyth     if ( matrix )
303*37da2899SCharles.Forsyth       FT_Outline_Transform( &glyph->outline, matrix );
304*37da2899SCharles.Forsyth 
305*37da2899SCharles.Forsyth     if ( delta )
306*37da2899SCharles.Forsyth       FT_Outline_Translate( &glyph->outline, delta->x, delta->y );
307*37da2899SCharles.Forsyth   }
308*37da2899SCharles.Forsyth 
309*37da2899SCharles.Forsyth 
310*37da2899SCharles.Forsyth   static void
ft_outline_glyph_bbox(FT_OutlineGlyph glyph,FT_BBox * bbox)311*37da2899SCharles.Forsyth   ft_outline_glyph_bbox( FT_OutlineGlyph  glyph,
312*37da2899SCharles.Forsyth                          FT_BBox*         bbox )
313*37da2899SCharles.Forsyth   {
314*37da2899SCharles.Forsyth     FT_Outline_Get_CBox( &glyph->outline, bbox );
315*37da2899SCharles.Forsyth   }
316*37da2899SCharles.Forsyth 
317*37da2899SCharles.Forsyth 
318*37da2899SCharles.Forsyth   static FT_Error
ft_outline_glyph_prepare(FT_OutlineGlyph glyph,FT_GlyphSlot slot)319*37da2899SCharles.Forsyth   ft_outline_glyph_prepare( FT_OutlineGlyph  glyph,
320*37da2899SCharles.Forsyth                             FT_GlyphSlot     slot )
321*37da2899SCharles.Forsyth   {
322*37da2899SCharles.Forsyth     slot->format         = FT_GLYPH_FORMAT_OUTLINE;
323*37da2899SCharles.Forsyth     slot->outline        = glyph->outline;
324*37da2899SCharles.Forsyth     slot->outline.flags &= ~FT_OUTLINE_OWNER;
325*37da2899SCharles.Forsyth 
326*37da2899SCharles.Forsyth     return FT_Err_Ok;
327*37da2899SCharles.Forsyth   }
328*37da2899SCharles.Forsyth 
329*37da2899SCharles.Forsyth 
330*37da2899SCharles.Forsyth   const FT_Glyph_Class  ft_outline_glyph_class =
331*37da2899SCharles.Forsyth   {
332*37da2899SCharles.Forsyth     sizeof( FT_OutlineGlyphRec ),
333*37da2899SCharles.Forsyth     FT_GLYPH_FORMAT_OUTLINE,
334*37da2899SCharles.Forsyth 
335*37da2899SCharles.Forsyth     (FT_Glyph_InitFunc)     ft_outline_glyph_init,
336*37da2899SCharles.Forsyth     (FT_Glyph_DoneFunc)     ft_outline_glyph_done,
337*37da2899SCharles.Forsyth     (FT_Glyph_CopyFunc)     ft_outline_glyph_copy,
338*37da2899SCharles.Forsyth     (FT_Glyph_TransformFunc)ft_outline_glyph_transform,
339*37da2899SCharles.Forsyth     (FT_Glyph_GetBBoxFunc)  ft_outline_glyph_bbox,
340*37da2899SCharles.Forsyth     (FT_Glyph_PrepareFunc)  ft_outline_glyph_prepare
341*37da2899SCharles.Forsyth   };
342*37da2899SCharles.Forsyth 
343*37da2899SCharles.Forsyth 
344*37da2899SCharles.Forsyth   /*************************************************************************/
345*37da2899SCharles.Forsyth   /*************************************************************************/
346*37da2899SCharles.Forsyth   /****                                                                 ****/
347*37da2899SCharles.Forsyth   /****   FT_Glyph class and API                                        ****/
348*37da2899SCharles.Forsyth   /****                                                                 ****/
349*37da2899SCharles.Forsyth   /*************************************************************************/
350*37da2899SCharles.Forsyth   /*************************************************************************/
351*37da2899SCharles.Forsyth 
352*37da2899SCharles.Forsyth    static FT_Error
ft_new_glyph(FT_Library library,const FT_Glyph_Class * clazz,FT_Glyph * aglyph)353*37da2899SCharles.Forsyth    ft_new_glyph( FT_Library             library,
354*37da2899SCharles.Forsyth                  const FT_Glyph_Class*  clazz,
355*37da2899SCharles.Forsyth                  FT_Glyph*              aglyph )
356*37da2899SCharles.Forsyth    {
357*37da2899SCharles.Forsyth      FT_Memory  memory = library->memory;
358*37da2899SCharles.Forsyth      FT_Error   error;
359*37da2899SCharles.Forsyth      FT_Glyph   glyph;
360*37da2899SCharles.Forsyth 
361*37da2899SCharles.Forsyth 
362*37da2899SCharles.Forsyth      *aglyph = 0;
363*37da2899SCharles.Forsyth 
364*37da2899SCharles.Forsyth      if ( !FT_ALLOC( glyph, clazz->glyph_size ) )
365*37da2899SCharles.Forsyth      {
366*37da2899SCharles.Forsyth        glyph->library = library;
367*37da2899SCharles.Forsyth        glyph->clazz   = clazz;
368*37da2899SCharles.Forsyth        glyph->format  = clazz->glyph_format;
369*37da2899SCharles.Forsyth 
370*37da2899SCharles.Forsyth        *aglyph = glyph;
371*37da2899SCharles.Forsyth      }
372*37da2899SCharles.Forsyth 
373*37da2899SCharles.Forsyth      return error;
374*37da2899SCharles.Forsyth    }
375*37da2899SCharles.Forsyth 
376*37da2899SCharles.Forsyth 
377*37da2899SCharles.Forsyth   /* documentation is in ftglyph.h */
378*37da2899SCharles.Forsyth 
379*37da2899SCharles.Forsyth   FT_EXPORT_DEF( FT_Error )
FT_Glyph_Copy(FT_Glyph source,FT_Glyph * target)380*37da2899SCharles.Forsyth   FT_Glyph_Copy( FT_Glyph   source,
381*37da2899SCharles.Forsyth                  FT_Glyph  *target )
382*37da2899SCharles.Forsyth   {
383*37da2899SCharles.Forsyth     FT_Glyph               copy;
384*37da2899SCharles.Forsyth     FT_Error               error;
385*37da2899SCharles.Forsyth     const FT_Glyph_Class*  clazz;
386*37da2899SCharles.Forsyth 
387*37da2899SCharles.Forsyth 
388*37da2899SCharles.Forsyth     /* check arguments */
389*37da2899SCharles.Forsyth     if ( !target || !source || !source->clazz )
390*37da2899SCharles.Forsyth     {
391*37da2899SCharles.Forsyth       error = FT_Err_Invalid_Argument;
392*37da2899SCharles.Forsyth       goto Exit;
393*37da2899SCharles.Forsyth     }
394*37da2899SCharles.Forsyth 
395*37da2899SCharles.Forsyth     *target = 0;
396*37da2899SCharles.Forsyth 
397*37da2899SCharles.Forsyth     clazz = source->clazz;
398*37da2899SCharles.Forsyth     error = ft_new_glyph( source->library, clazz, &copy );
399*37da2899SCharles.Forsyth     if ( error )
400*37da2899SCharles.Forsyth       goto Exit;
401*37da2899SCharles.Forsyth 
402*37da2899SCharles.Forsyth     copy->advance = source->advance;
403*37da2899SCharles.Forsyth     copy->format  = source->format;
404*37da2899SCharles.Forsyth 
405*37da2899SCharles.Forsyth     if ( clazz->glyph_copy )
406*37da2899SCharles.Forsyth       error = clazz->glyph_copy( source, copy );
407*37da2899SCharles.Forsyth 
408*37da2899SCharles.Forsyth     if ( error )
409*37da2899SCharles.Forsyth       FT_Done_Glyph( copy );
410*37da2899SCharles.Forsyth     else
411*37da2899SCharles.Forsyth       *target = copy;
412*37da2899SCharles.Forsyth 
413*37da2899SCharles.Forsyth   Exit:
414*37da2899SCharles.Forsyth     return error;
415*37da2899SCharles.Forsyth   }
416*37da2899SCharles.Forsyth 
417*37da2899SCharles.Forsyth 
418*37da2899SCharles.Forsyth   /* documentation is in ftglyph.h */
419*37da2899SCharles.Forsyth 
420*37da2899SCharles.Forsyth   FT_EXPORT_DEF( FT_Error )
FT_Get_Glyph(FT_GlyphSlot slot,FT_Glyph * aglyph)421*37da2899SCharles.Forsyth   FT_Get_Glyph( FT_GlyphSlot  slot,
422*37da2899SCharles.Forsyth                 FT_Glyph     *aglyph )
423*37da2899SCharles.Forsyth   {
424*37da2899SCharles.Forsyth     FT_Library  library = slot->library;
425*37da2899SCharles.Forsyth     FT_Error    error;
426*37da2899SCharles.Forsyth     FT_Glyph    glyph;
427*37da2899SCharles.Forsyth 
428*37da2899SCharles.Forsyth     const FT_Glyph_Class*  clazz = 0;
429*37da2899SCharles.Forsyth 
430*37da2899SCharles.Forsyth 
431*37da2899SCharles.Forsyth     if ( !slot )
432*37da2899SCharles.Forsyth       return FT_Err_Invalid_Slot_Handle;
433*37da2899SCharles.Forsyth 
434*37da2899SCharles.Forsyth     if ( !aglyph )
435*37da2899SCharles.Forsyth       return FT_Err_Invalid_Argument;
436*37da2899SCharles.Forsyth 
437*37da2899SCharles.Forsyth     /* if it is a bitmap, that's easy :-) */
438*37da2899SCharles.Forsyth     if ( slot->format == FT_GLYPH_FORMAT_BITMAP )
439*37da2899SCharles.Forsyth       clazz = &ft_bitmap_glyph_class;
440*37da2899SCharles.Forsyth 
441*37da2899SCharles.Forsyth     /* it it is an outline too */
442*37da2899SCharles.Forsyth     else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
443*37da2899SCharles.Forsyth       clazz = &ft_outline_glyph_class;
444*37da2899SCharles.Forsyth 
445*37da2899SCharles.Forsyth     else
446*37da2899SCharles.Forsyth     {
447*37da2899SCharles.Forsyth       /* try to find a renderer that supports the glyph image format */
448*37da2899SCharles.Forsyth       FT_Renderer  render = FT_Lookup_Renderer( library, slot->format, 0 );
449*37da2899SCharles.Forsyth 
450*37da2899SCharles.Forsyth 
451*37da2899SCharles.Forsyth       if ( render )
452*37da2899SCharles.Forsyth         clazz = &render->glyph_class;
453*37da2899SCharles.Forsyth     }
454*37da2899SCharles.Forsyth 
455*37da2899SCharles.Forsyth     if ( !clazz )
456*37da2899SCharles.Forsyth     {
457*37da2899SCharles.Forsyth       error = FT_Err_Invalid_Glyph_Format;
458*37da2899SCharles.Forsyth       goto Exit;
459*37da2899SCharles.Forsyth     }
460*37da2899SCharles.Forsyth 
461*37da2899SCharles.Forsyth     /* create FT_Glyph object */
462*37da2899SCharles.Forsyth     error = ft_new_glyph( library, clazz, &glyph );
463*37da2899SCharles.Forsyth     if ( error )
464*37da2899SCharles.Forsyth       goto Exit;
465*37da2899SCharles.Forsyth 
466*37da2899SCharles.Forsyth     /* copy advance while converting it to 16.16 format */
467*37da2899SCharles.Forsyth     glyph->advance.x = slot->advance.x << 10;
468*37da2899SCharles.Forsyth     glyph->advance.y = slot->advance.y << 10;
469*37da2899SCharles.Forsyth 
470*37da2899SCharles.Forsyth     /* now import the image from the glyph slot */
471*37da2899SCharles.Forsyth     error = clazz->glyph_init( glyph, slot );
472*37da2899SCharles.Forsyth 
473*37da2899SCharles.Forsyth     /* if an error occurred, destroy the glyph */
474*37da2899SCharles.Forsyth     if ( error )
475*37da2899SCharles.Forsyth       FT_Done_Glyph( glyph );
476*37da2899SCharles.Forsyth     else
477*37da2899SCharles.Forsyth       *aglyph = glyph;
478*37da2899SCharles.Forsyth 
479*37da2899SCharles.Forsyth   Exit:
480*37da2899SCharles.Forsyth     return error;
481*37da2899SCharles.Forsyth   }
482*37da2899SCharles.Forsyth 
483*37da2899SCharles.Forsyth 
484*37da2899SCharles.Forsyth   /* documentation is in ftglyph.h */
485*37da2899SCharles.Forsyth 
486*37da2899SCharles.Forsyth   FT_EXPORT_DEF( FT_Error )
FT_Glyph_Transform(FT_Glyph glyph,FT_Matrix * matrix,FT_Vector * delta)487*37da2899SCharles.Forsyth   FT_Glyph_Transform( FT_Glyph    glyph,
488*37da2899SCharles.Forsyth                       FT_Matrix*  matrix,
489*37da2899SCharles.Forsyth                       FT_Vector*  delta )
490*37da2899SCharles.Forsyth   {
491*37da2899SCharles.Forsyth     const FT_Glyph_Class*  clazz;
492*37da2899SCharles.Forsyth     FT_Error               error = FT_Err_Ok;
493*37da2899SCharles.Forsyth 
494*37da2899SCharles.Forsyth 
495*37da2899SCharles.Forsyth     if ( !glyph || !glyph->clazz )
496*37da2899SCharles.Forsyth       error = FT_Err_Invalid_Argument;
497*37da2899SCharles.Forsyth     else
498*37da2899SCharles.Forsyth     {
499*37da2899SCharles.Forsyth       clazz = glyph->clazz;
500*37da2899SCharles.Forsyth       if ( clazz->glyph_transform )
501*37da2899SCharles.Forsyth       {
502*37da2899SCharles.Forsyth         /* transform glyph image */
503*37da2899SCharles.Forsyth         clazz->glyph_transform( glyph, matrix, delta );
504*37da2899SCharles.Forsyth 
505*37da2899SCharles.Forsyth         /* transform advance vector */
506*37da2899SCharles.Forsyth         if ( matrix )
507*37da2899SCharles.Forsyth           FT_Vector_Transform( &glyph->advance, matrix );
508*37da2899SCharles.Forsyth       }
509*37da2899SCharles.Forsyth       else
510*37da2899SCharles.Forsyth         error = FT_Err_Invalid_Glyph_Format;
511*37da2899SCharles.Forsyth     }
512*37da2899SCharles.Forsyth     return error;
513*37da2899SCharles.Forsyth   }
514*37da2899SCharles.Forsyth 
515*37da2899SCharles.Forsyth 
516*37da2899SCharles.Forsyth   /* documentation is in ftglyph.h */
517*37da2899SCharles.Forsyth 
518*37da2899SCharles.Forsyth   FT_EXPORT_DEF( void )
FT_Glyph_Get_CBox(FT_Glyph glyph,FT_UInt bbox_mode,FT_BBox * acbox)519*37da2899SCharles.Forsyth   FT_Glyph_Get_CBox( FT_Glyph  glyph,
520*37da2899SCharles.Forsyth                      FT_UInt   bbox_mode,
521*37da2899SCharles.Forsyth                      FT_BBox  *acbox )
522*37da2899SCharles.Forsyth   {
523*37da2899SCharles.Forsyth     const FT_Glyph_Class*  clazz;
524*37da2899SCharles.Forsyth 
525*37da2899SCharles.Forsyth 
526*37da2899SCharles.Forsyth     if ( !acbox )
527*37da2899SCharles.Forsyth       return;
528*37da2899SCharles.Forsyth 
529*37da2899SCharles.Forsyth     acbox->xMin = acbox->yMin = acbox->xMax = acbox->yMax = 0;
530*37da2899SCharles.Forsyth 
531*37da2899SCharles.Forsyth     if ( !glyph || !glyph->clazz )
532*37da2899SCharles.Forsyth       return;
533*37da2899SCharles.Forsyth     else
534*37da2899SCharles.Forsyth     {
535*37da2899SCharles.Forsyth       clazz = glyph->clazz;
536*37da2899SCharles.Forsyth       if ( !clazz->glyph_bbox )
537*37da2899SCharles.Forsyth         return;
538*37da2899SCharles.Forsyth       else
539*37da2899SCharles.Forsyth       {
540*37da2899SCharles.Forsyth         /* retrieve bbox in 26.6 coordinates */
541*37da2899SCharles.Forsyth         clazz->glyph_bbox( glyph, acbox );
542*37da2899SCharles.Forsyth 
543*37da2899SCharles.Forsyth         /* perform grid fitting if needed */
544*37da2899SCharles.Forsyth         if ( bbox_mode & ft_glyph_bbox_gridfit )
545*37da2899SCharles.Forsyth         {
546*37da2899SCharles.Forsyth           acbox->xMin &= -64;
547*37da2899SCharles.Forsyth           acbox->yMin &= -64;
548*37da2899SCharles.Forsyth           acbox->xMax  = ( acbox->xMax + 63 ) & -64;
549*37da2899SCharles.Forsyth           acbox->yMax  = ( acbox->yMax + 63 ) & -64;
550*37da2899SCharles.Forsyth         }
551*37da2899SCharles.Forsyth 
552*37da2899SCharles.Forsyth         /* convert to integer pixels if needed */
553*37da2899SCharles.Forsyth         if ( bbox_mode & ft_glyph_bbox_truncate )
554*37da2899SCharles.Forsyth         {
555*37da2899SCharles.Forsyth           acbox->xMin >>= 6;
556*37da2899SCharles.Forsyth           acbox->yMin >>= 6;
557*37da2899SCharles.Forsyth           acbox->xMax >>= 6;
558*37da2899SCharles.Forsyth           acbox->yMax >>= 6;
559*37da2899SCharles.Forsyth         }
560*37da2899SCharles.Forsyth       }
561*37da2899SCharles.Forsyth     }
562*37da2899SCharles.Forsyth     return;
563*37da2899SCharles.Forsyth   }
564*37da2899SCharles.Forsyth 
565*37da2899SCharles.Forsyth 
566*37da2899SCharles.Forsyth   /* documentation is in ftglyph.h */
567*37da2899SCharles.Forsyth 
568*37da2899SCharles.Forsyth   FT_EXPORT_DEF( FT_Error )
FT_Glyph_To_Bitmap(FT_Glyph * the_glyph,FT_Render_Mode render_mode,FT_Vector * origin,FT_Bool destroy)569*37da2899SCharles.Forsyth   FT_Glyph_To_Bitmap( FT_Glyph*       the_glyph,
570*37da2899SCharles.Forsyth                       FT_Render_Mode  render_mode,
571*37da2899SCharles.Forsyth                       FT_Vector*      origin,
572*37da2899SCharles.Forsyth                       FT_Bool         destroy )
573*37da2899SCharles.Forsyth   {
574*37da2899SCharles.Forsyth     FT_GlyphSlotRec  dummy;
575*37da2899SCharles.Forsyth     FT_Error         error = FT_Err_Ok;
576*37da2899SCharles.Forsyth     FT_Glyph         glyph;
577*37da2899SCharles.Forsyth     FT_BitmapGlyph   bitmap = NULL;
578*37da2899SCharles.Forsyth 
579*37da2899SCharles.Forsyth     const FT_Glyph_Class*  clazz;
580*37da2899SCharles.Forsyth 
581*37da2899SCharles.Forsyth 
582*37da2899SCharles.Forsyth     /* check argument */
583*37da2899SCharles.Forsyth     if ( !the_glyph )
584*37da2899SCharles.Forsyth       goto Bad;
585*37da2899SCharles.Forsyth 
586*37da2899SCharles.Forsyth     /* we render the glyph into a glyph bitmap using a `dummy' glyph slot */
587*37da2899SCharles.Forsyth     /* then calling FT_Render_Glyph_Internal()                            */
588*37da2899SCharles.Forsyth 
589*37da2899SCharles.Forsyth     glyph = *the_glyph;
590*37da2899SCharles.Forsyth     if ( !glyph )
591*37da2899SCharles.Forsyth       goto Bad;
592*37da2899SCharles.Forsyth 
593*37da2899SCharles.Forsyth     clazz = glyph->clazz;
594*37da2899SCharles.Forsyth 
595*37da2899SCharles.Forsyth     /* when called with a bitmap glyph, do nothing and return succesfully */
596*37da2899SCharles.Forsyth     if ( clazz == &ft_bitmap_glyph_class )
597*37da2899SCharles.Forsyth       goto Exit;
598*37da2899SCharles.Forsyth 
599*37da2899SCharles.Forsyth     if ( !clazz || !clazz->glyph_prepare )
600*37da2899SCharles.Forsyth       goto Bad;
601*37da2899SCharles.Forsyth 
602*37da2899SCharles.Forsyth     FT_MEM_ZERO( &dummy, sizeof ( dummy ) );
603*37da2899SCharles.Forsyth     dummy.library = glyph->library;
604*37da2899SCharles.Forsyth     dummy.format  = clazz->glyph_format;
605*37da2899SCharles.Forsyth 
606*37da2899SCharles.Forsyth     /* create result bitmap glyph */
607*37da2899SCharles.Forsyth     error = ft_new_glyph( glyph->library, &ft_bitmap_glyph_class,
608*37da2899SCharles.Forsyth                           (FT_Glyph*)&bitmap );
609*37da2899SCharles.Forsyth     if ( error )
610*37da2899SCharles.Forsyth       goto Exit;
611*37da2899SCharles.Forsyth 
612*37da2899SCharles.Forsyth #if 0
613*37da2899SCharles.Forsyth     /* if `origin' is set, translate the glyph image */
614*37da2899SCharles.Forsyth     if ( origin )
615*37da2899SCharles.Forsyth       FT_Glyph_Transform( glyph, 0, origin );
616*37da2899SCharles.Forsyth #else
617*37da2899SCharles.Forsyth     FT_UNUSED( origin );
618*37da2899SCharles.Forsyth #endif
619*37da2899SCharles.Forsyth 
620*37da2899SCharles.Forsyth     /* prepare dummy slot for rendering */
621*37da2899SCharles.Forsyth     error = clazz->glyph_prepare( glyph, &dummy );
622*37da2899SCharles.Forsyth     if ( !error )
623*37da2899SCharles.Forsyth       error = FT_Render_Glyph_Internal( glyph->library, &dummy, render_mode );
624*37da2899SCharles.Forsyth 
625*37da2899SCharles.Forsyth #if 0
626*37da2899SCharles.Forsyth     if ( !destroy && origin )
627*37da2899SCharles.Forsyth     {
628*37da2899SCharles.Forsyth       FT_Vector  v;
629*37da2899SCharles.Forsyth 
630*37da2899SCharles.Forsyth 
631*37da2899SCharles.Forsyth       v.x = -origin->x;
632*37da2899SCharles.Forsyth       v.y = -origin->y;
633*37da2899SCharles.Forsyth       FT_Glyph_Transform( glyph, 0, &v );
634*37da2899SCharles.Forsyth     }
635*37da2899SCharles.Forsyth #endif
636*37da2899SCharles.Forsyth 
637*37da2899SCharles.Forsyth     if ( error )
638*37da2899SCharles.Forsyth       goto Exit;
639*37da2899SCharles.Forsyth 
640*37da2899SCharles.Forsyth     /* in case of success, copy the bitmap to the glyph bitmap */
641*37da2899SCharles.Forsyth     error = ft_bitmap_glyph_init( bitmap, &dummy );
642*37da2899SCharles.Forsyth     if ( error )
643*37da2899SCharles.Forsyth       goto Exit;
644*37da2899SCharles.Forsyth 
645*37da2899SCharles.Forsyth     /* copy advance */
646*37da2899SCharles.Forsyth     bitmap->root.advance = glyph->advance;
647*37da2899SCharles.Forsyth 
648*37da2899SCharles.Forsyth     if ( destroy )
649*37da2899SCharles.Forsyth       FT_Done_Glyph( glyph );
650*37da2899SCharles.Forsyth 
651*37da2899SCharles.Forsyth     *the_glyph = FT_GLYPH( bitmap );
652*37da2899SCharles.Forsyth 
653*37da2899SCharles.Forsyth   Exit:
654*37da2899SCharles.Forsyth     if ( error && bitmap )
655*37da2899SCharles.Forsyth       FT_Done_Glyph( FT_GLYPH( bitmap ) );
656*37da2899SCharles.Forsyth 
657*37da2899SCharles.Forsyth     return error;
658*37da2899SCharles.Forsyth 
659*37da2899SCharles.Forsyth   Bad:
660*37da2899SCharles.Forsyth     error = FT_Err_Invalid_Argument;
661*37da2899SCharles.Forsyth     goto Exit;
662*37da2899SCharles.Forsyth   }
663*37da2899SCharles.Forsyth 
664*37da2899SCharles.Forsyth 
665*37da2899SCharles.Forsyth   /* documentation is in ftglyph.h */
666*37da2899SCharles.Forsyth 
667*37da2899SCharles.Forsyth   FT_EXPORT_DEF( void )
FT_Done_Glyph(FT_Glyph glyph)668*37da2899SCharles.Forsyth   FT_Done_Glyph( FT_Glyph  glyph )
669*37da2899SCharles.Forsyth   {
670*37da2899SCharles.Forsyth     if ( glyph )
671*37da2899SCharles.Forsyth     {
672*37da2899SCharles.Forsyth       FT_Memory              memory = glyph->library->memory;
673*37da2899SCharles.Forsyth       const FT_Glyph_Class*  clazz  = glyph->clazz;
674*37da2899SCharles.Forsyth 
675*37da2899SCharles.Forsyth 
676*37da2899SCharles.Forsyth       if ( clazz->glyph_done )
677*37da2899SCharles.Forsyth         clazz->glyph_done( glyph );
678*37da2899SCharles.Forsyth 
679*37da2899SCharles.Forsyth       FT_FREE( glyph );
680*37da2899SCharles.Forsyth     }
681*37da2899SCharles.Forsyth   }
682*37da2899SCharles.Forsyth 
683*37da2899SCharles.Forsyth 
684*37da2899SCharles.Forsyth /* END */
685