ftglyph.c

Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  ftglyph.c                                                              */
00004 /*                                                                         */
00005 /*    FreeType convenience functions to handle glyphs (body).              */
00006 /*                                                                         */
00007 /*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2007, 2008 by             */
00008 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
00009 /*                                                                         */
00010 /*  This file is part of the FreeType project, and may only be used,       */
00011 /*  modified, and distributed under the terms of the FreeType project      */
00012 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
00013 /*  this file you indicate that you have read the license and              */
00014 /*  understand and accept it fully.                                        */
00015 /*                                                                         */
00016 /***************************************************************************/
00017 
00018   /*************************************************************************/
00019   /*                                                                       */
00020   /*  This file contains the definition of several convenience functions   */
00021   /*  that can be used by client applications to easily retrieve glyph     */
00022   /*  bitmaps and outlines from a given face.                              */
00023   /*                                                                       */
00024   /*  These functions should be optional if you are writing a font server  */
00025   /*  or text layout engine on top of FreeType.  However, they are pretty  */
00026   /*  handy for many other simple uses of the library.                     */
00027   /*                                                                       */
00028   /*************************************************************************/
00029 
00030 
00031 #include <ft2build.h>
00032 #include FT_GLYPH_H
00033 #include FT_OUTLINE_H
00034 #include FT_BITMAP_H
00035 #include FT_INTERNAL_OBJECTS_H
00036 
00037 #include "basepic.h"
00038 
00039   /*************************************************************************/
00040   /*                                                                       */
00041   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
00042   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
00043   /* messages during execution.                                            */
00044   /*                                                                       */
00045 #undef  FT_COMPONENT
00046 #define FT_COMPONENT  trace_glyph
00047 
00048 
00049   /*************************************************************************/
00050   /*************************************************************************/
00051   /****                                                                 ****/
00052   /****   FT_BitmapGlyph support                                        ****/
00053   /****                                                                 ****/
00054   /*************************************************************************/
00055   /*************************************************************************/
00056 
00057   FT_CALLBACK_DEF( FT_Error )
00058   ft_bitmap_glyph_init( FT_Glyph      bitmap_glyph,
00059                         FT_GlyphSlot  slot )
00060   {
00061     FT_BitmapGlyph  glyph   = (FT_BitmapGlyph)bitmap_glyph;
00062     FT_Error        error   = FT_Err_Ok;
00063     FT_Library      library = FT_GLYPH( glyph )->library;
00064 
00065 
00066     if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
00067     {
00068       error = FT_Err_Invalid_Glyph_Format;
00069       goto Exit;
00070     }
00071 
00072     glyph->left = slot->bitmap_left;
00073     glyph->top  = slot->bitmap_top;
00074 
00075     /* do lazy copying whenever possible */
00076     if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
00077     {
00078       glyph->bitmap = slot->bitmap;
00079       slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
00080     }
00081     else
00082     {
00083       FT_Bitmap_New( &glyph->bitmap );
00084       error = FT_Bitmap_Copy( library, &slot->bitmap, &glyph->bitmap );
00085     }
00086 
00087   Exit:
00088     return error;
00089   }
00090 
00091 
00092   FT_CALLBACK_DEF( FT_Error )
00093   ft_bitmap_glyph_copy( FT_Glyph  bitmap_source,
00094                         FT_Glyph  bitmap_target )
00095   {
00096     FT_Library      library = bitmap_source->library;
00097     FT_BitmapGlyph  source  = (FT_BitmapGlyph)bitmap_source;
00098     FT_BitmapGlyph  target  = (FT_BitmapGlyph)bitmap_target;
00099 
00100 
00101     target->left = source->left;
00102     target->top  = source->top;
00103 
00104     return FT_Bitmap_Copy( library, &source->bitmap, &target->bitmap );
00105   }
00106 
00107 
00108   FT_CALLBACK_DEF( void )
00109   ft_bitmap_glyph_done( FT_Glyph  bitmap_glyph )
00110   {
00111     FT_BitmapGlyph  glyph   = (FT_BitmapGlyph)bitmap_glyph;
00112     FT_Library      library = FT_GLYPH( glyph )->library;
00113 
00114 
00115     FT_Bitmap_Done( library, &glyph->bitmap );
00116   }
00117 
00118 
00119   FT_CALLBACK_DEF( void )
00120   ft_bitmap_glyph_bbox( FT_Glyph  bitmap_glyph,
00121                         FT_BBox*  cbox )
00122   {
00123     FT_BitmapGlyph  glyph = (FT_BitmapGlyph)bitmap_glyph;
00124 
00125 
00126     cbox->xMin = glyph->left << 6;
00127     cbox->xMax = cbox->xMin + ( glyph->bitmap.width << 6 );
00128     cbox->yMax = glyph->top << 6;
00129     cbox->yMin = cbox->yMax - ( glyph->bitmap.rows << 6 );
00130   }
00131 
00132 
00133   FT_DEFINE_GLYPH(ft_bitmap_glyph_class,
00134     sizeof ( FT_BitmapGlyphRec ),
00135     FT_GLYPH_FORMAT_BITMAP,
00136 
00137     ft_bitmap_glyph_init,
00138     ft_bitmap_glyph_done,
00139     ft_bitmap_glyph_copy,
00140     0,                          /* FT_Glyph_TransformFunc */
00141     ft_bitmap_glyph_bbox,
00142     0                           /* FT_Glyph_PrepareFunc   */
00143   )
00144 
00145 
00146   /*************************************************************************/
00147   /*************************************************************************/
00148   /****                                                                 ****/
00149   /****   FT_OutlineGlyph support                                       ****/
00150   /****                                                                 ****/
00151   /*************************************************************************/
00152   /*************************************************************************/
00153 
00154 
00155   FT_CALLBACK_DEF( FT_Error )
00156   ft_outline_glyph_init( FT_Glyph      outline_glyph,
00157                          FT_GlyphSlot  slot )
00158   {
00159     FT_OutlineGlyph  glyph   = (FT_OutlineGlyph)outline_glyph;
00160     FT_Error         error   = FT_Err_Ok;
00161     FT_Library       library = FT_GLYPH( glyph )->library;
00162     FT_Outline*      source  = &slot->outline;
00163     FT_Outline*      target  = &glyph->outline;
00164 
00165 
00166     /* check format in glyph slot */
00167     if ( slot->format != FT_GLYPH_FORMAT_OUTLINE )
00168     {
00169       error = FT_Err_Invalid_Glyph_Format;
00170       goto Exit;
00171     }
00172 
00173     /* allocate new outline */
00174     error = FT_Outline_New( library, source->n_points, source->n_contours,
00175                             &glyph->outline );
00176     if ( error )
00177       goto Exit;
00178 
00179     FT_Outline_Copy( source, target );
00180 
00181   Exit:
00182     return error;
00183   }
00184 
00185 
00186   FT_CALLBACK_DEF( void )
00187   ft_outline_glyph_done( FT_Glyph  outline_glyph )
00188   {
00189     FT_OutlineGlyph  glyph = (FT_OutlineGlyph)outline_glyph;
00190 
00191 
00192     FT_Outline_Done( FT_GLYPH( glyph )->library, &glyph->outline );
00193   }
00194 
00195 
00196   FT_CALLBACK_DEF( FT_Error )
00197   ft_outline_glyph_copy( FT_Glyph  outline_source,
00198                          FT_Glyph  outline_target )
00199   {
00200     FT_OutlineGlyph  source  = (FT_OutlineGlyph)outline_source;
00201     FT_OutlineGlyph  target  = (FT_OutlineGlyph)outline_target;
00202     FT_Error         error;
00203     FT_Library       library = FT_GLYPH( source )->library;
00204 
00205 
00206     error = FT_Outline_New( library, source->outline.n_points,
00207                             source->outline.n_contours, &target->outline );
00208     if ( !error )
00209       FT_Outline_Copy( &source->outline, &target->outline );
00210 
00211     return error;
00212   }
00213 
00214 
00215   FT_CALLBACK_DEF( void )
00216   ft_outline_glyph_transform( FT_Glyph          outline_glyph,
00217                               const FT_Matrix*  matrix,
00218                               const FT_Vector*  delta )
00219   {
00220     FT_OutlineGlyph  glyph = (FT_OutlineGlyph)outline_glyph;
00221 
00222 
00223     if ( matrix )
00224       FT_Outline_Transform( &glyph->outline, matrix );
00225 
00226     if ( delta )
00227       FT_Outline_Translate( &glyph->outline, delta->x, delta->y );
00228   }
00229 
00230 
00231   FT_CALLBACK_DEF( void )
00232   ft_outline_glyph_bbox( FT_Glyph  outline_glyph,
00233                          FT_BBox*  bbox )
00234   {
00235     FT_OutlineGlyph  glyph = (FT_OutlineGlyph)outline_glyph;
00236 
00237 
00238     FT_Outline_Get_CBox( &glyph->outline, bbox );
00239   }
00240 
00241 
00242   FT_CALLBACK_DEF( FT_Error )
00243   ft_outline_glyph_prepare( FT_Glyph      outline_glyph,
00244                             FT_GlyphSlot  slot )
00245   {
00246     FT_OutlineGlyph  glyph = (FT_OutlineGlyph)outline_glyph;
00247 
00248 
00249     slot->format         = FT_GLYPH_FORMAT_OUTLINE;
00250     slot->outline        = glyph->outline;
00251     slot->outline.flags &= ~FT_OUTLINE_OWNER;
00252 
00253     return FT_Err_Ok;
00254   }
00255 
00256 
00257   FT_DEFINE_GLYPH( ft_outline_glyph_class, 
00258     sizeof ( FT_OutlineGlyphRec ),
00259     FT_GLYPH_FORMAT_OUTLINE,
00260 
00261     ft_outline_glyph_init,
00262     ft_outline_glyph_done,
00263     ft_outline_glyph_copy,
00264     ft_outline_glyph_transform,
00265     ft_outline_glyph_bbox,
00266     ft_outline_glyph_prepare
00267   )
00268 
00269 
00270   /*************************************************************************/
00271   /*************************************************************************/
00272   /****                                                                 ****/
00273   /****   FT_Glyph class and API                                        ****/
00274   /****                                                                 ****/
00275   /*************************************************************************/
00276   /*************************************************************************/
00277 
00278    static FT_Error
00279    ft_new_glyph( FT_Library             library,
00280                  const FT_Glyph_Class*  clazz,
00281                  FT_Glyph*              aglyph )
00282    {
00283      FT_Memory  memory = library->memory;
00284      FT_Error   error;
00285      FT_Glyph   glyph;
00286 
00287 
00288      *aglyph = 0;
00289 
00290      if ( !FT_ALLOC( glyph, clazz->glyph_size ) )
00291      {
00292        glyph->library = library;
00293        glyph->clazz   = clazz;
00294        glyph->format  = clazz->glyph_format;
00295 
00296        *aglyph = glyph;
00297      }
00298 
00299      return error;
00300    }
00301 
00302 
00303   /* documentation is in ftglyph.h */
00304 
00305   FT_EXPORT_DEF( FT_Error )
00306   FT_Glyph_Copy( FT_Glyph   source,
00307                  FT_Glyph  *target )
00308   {
00309     FT_Glyph               copy;
00310     FT_Error               error;
00311     const FT_Glyph_Class*  clazz;
00312 
00313 
00314     /* check arguments */
00315     if ( !target )
00316     {
00317       error = FT_Err_Invalid_Argument;
00318       goto Exit;
00319     }
00320 
00321     *target = 0;
00322 
00323     if ( !source || !source->clazz )
00324     {
00325       error = FT_Err_Invalid_Argument;
00326       goto Exit;
00327     }
00328 
00329     clazz = source->clazz;
00330     error = ft_new_glyph( source->library, clazz, &copy );
00331     if ( error )
00332       goto Exit;
00333 
00334     copy->advance = source->advance;
00335     copy->format  = source->format;
00336 
00337     if ( clazz->glyph_copy )
00338       error = clazz->glyph_copy( source, copy );
00339 
00340     if ( error )
00341       FT_Done_Glyph( copy );
00342     else
00343       *target = copy;
00344 
00345   Exit:
00346     return error;
00347   }
00348 
00349 
00350   /* documentation is in ftglyph.h */
00351 
00352   FT_EXPORT_DEF( FT_Error )
00353   FT_Get_Glyph( FT_GlyphSlot  slot,
00354                 FT_Glyph     *aglyph )
00355   {
00356     FT_Library  library;
00357     FT_Error    error;
00358     FT_Glyph    glyph;
00359 
00360     const FT_Glyph_Class*  clazz = 0;
00361 
00362 
00363     if ( !slot )
00364       return FT_Err_Invalid_Slot_Handle;
00365 
00366     library = slot->library;
00367 
00368     if ( !aglyph )
00369       return FT_Err_Invalid_Argument;
00370 
00371     /* if it is a bitmap, that's easy :-) */
00372     if ( slot->format == FT_GLYPH_FORMAT_BITMAP )
00373       clazz = FT_BITMAP_GLYPH_CLASS_GET;
00374 
00375     /* if it is an outline */
00376     else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
00377       clazz = FT_OUTLINE_GLYPH_CLASS_GET;
00378 
00379     else
00380     {
00381       /* try to find a renderer that supports the glyph image format */
00382       FT_Renderer  render = FT_Lookup_Renderer( library, slot->format, 0 );
00383 
00384 
00385       if ( render )
00386         clazz = &render->glyph_class;
00387     }
00388 
00389     if ( !clazz )
00390     {
00391       error = FT_Err_Invalid_Glyph_Format;
00392       goto Exit;
00393     }
00394 
00395     /* create FT_Glyph object */
00396     error = ft_new_glyph( library, clazz, &glyph );
00397     if ( error )
00398       goto Exit;
00399 
00400     /* copy advance while converting it to 16.16 format */
00401     glyph->advance.x = slot->advance.x << 10;
00402     glyph->advance.y = slot->advance.y << 10;
00403 
00404     /* now import the image from the glyph slot */
00405     error = clazz->glyph_init( glyph, slot );
00406 
00407     /* if an error occurred, destroy the glyph */
00408     if ( error )
00409       FT_Done_Glyph( glyph );
00410     else
00411       *aglyph = glyph;
00412 
00413   Exit:
00414     return error;
00415   }
00416 
00417 
00418   /* documentation is in ftglyph.h */
00419 
00420   FT_EXPORT_DEF( FT_Error )
00421   FT_Glyph_Transform( FT_Glyph    glyph,
00422                       FT_Matrix*  matrix,
00423                       FT_Vector*  delta )
00424   {
00425     const FT_Glyph_Class*  clazz;
00426     FT_Error               error = FT_Err_Ok;
00427 
00428 
00429     if ( !glyph || !glyph->clazz )
00430       error = FT_Err_Invalid_Argument;
00431     else
00432     {
00433       clazz = glyph->clazz;
00434       if ( clazz->glyph_transform )
00435       {
00436         /* transform glyph image */
00437         clazz->glyph_transform( glyph, matrix, delta );
00438 
00439         /* transform advance vector */
00440         if ( matrix )
00441           FT_Vector_Transform( &glyph->advance, matrix );
00442       }
00443       else
00444         error = FT_Err_Invalid_Glyph_Format;
00445     }
00446     return error;
00447   }
00448 
00449 
00450   /* documentation is in ftglyph.h */
00451 
00452   FT_EXPORT_DEF( void )
00453   FT_Glyph_Get_CBox( FT_Glyph  glyph,
00454                      FT_UInt   bbox_mode,
00455                      FT_BBox  *acbox )
00456   {
00457     const FT_Glyph_Class*  clazz;
00458 
00459 
00460     if ( !acbox )
00461       return;
00462 
00463     acbox->xMin = acbox->yMin = acbox->xMax = acbox->yMax = 0;
00464 
00465     if ( !glyph || !glyph->clazz )
00466       return;
00467     else
00468     {
00469       clazz = glyph->clazz;
00470       if ( !clazz->glyph_bbox )
00471         return;
00472       else
00473       {
00474         /* retrieve bbox in 26.6 coordinates */
00475         clazz->glyph_bbox( glyph, acbox );
00476 
00477         /* perform grid fitting if needed */
00478         if ( bbox_mode == FT_GLYPH_BBOX_GRIDFIT ||
00479              bbox_mode == FT_GLYPH_BBOX_PIXELS  )
00480         {
00481           acbox->xMin = FT_PIX_FLOOR( acbox->xMin );
00482           acbox->yMin = FT_PIX_FLOOR( acbox->yMin );
00483           acbox->xMax = FT_PIX_CEIL( acbox->xMax );
00484           acbox->yMax = FT_PIX_CEIL( acbox->yMax );
00485         }
00486 
00487         /* convert to integer pixels if needed */
00488         if ( bbox_mode == FT_GLYPH_BBOX_TRUNCATE ||
00489              bbox_mode == FT_GLYPH_BBOX_PIXELS   )
00490         {
00491           acbox->xMin >>= 6;
00492           acbox->yMin >>= 6;
00493           acbox->xMax >>= 6;
00494           acbox->yMax >>= 6;
00495         }
00496       }
00497     }
00498     return;
00499   }
00500 
00501 
00502   /* documentation is in ftglyph.h */
00503 
00504   FT_EXPORT_DEF( FT_Error )
00505   FT_Glyph_To_Bitmap( FT_Glyph*       the_glyph,
00506                       FT_Render_Mode  render_mode,
00507                       FT_Vector*      origin,
00508                       FT_Bool         destroy )
00509   {
00510     FT_GlyphSlotRec           dummy;
00511     FT_GlyphSlot_InternalRec  dummy_internal;
00512     FT_Error                  error = FT_Err_Ok;
00513     FT_Glyph                  glyph;
00514     FT_BitmapGlyph            bitmap = NULL;
00515 
00516     const FT_Glyph_Class*     clazz;
00517 
00518 #ifdef FT_CONFIG_OPTION_PIC
00519     FT_Library                library = FT_GLYPH( glyph )->library;
00520 #endif
00521 
00522 
00523     /* check argument */
00524     if ( !the_glyph )
00525       goto Bad;
00526 
00527     /* we render the glyph into a glyph bitmap using a `dummy' glyph slot */
00528     /* then calling FT_Render_Glyph_Internal()                            */
00529 
00530     glyph = *the_glyph;
00531     if ( !glyph )
00532       goto Bad;
00533 
00534     clazz = glyph->clazz;
00535 
00536     /* when called with a bitmap glyph, do nothing and return successfully */
00537     if ( clazz == FT_BITMAP_GLYPH_CLASS_GET )
00538       goto Exit;
00539 
00540     if ( !clazz || !clazz->glyph_prepare )
00541       goto Bad;
00542 
00543     FT_MEM_ZERO( &dummy, sizeof ( dummy ) );
00544     FT_MEM_ZERO( &dummy_internal, sizeof ( dummy_internal ) );
00545     dummy.internal = &dummy_internal;
00546     dummy.library  = glyph->library;
00547     dummy.format   = clazz->glyph_format;
00548 
00549     /* create result bitmap glyph */
00550     error = ft_new_glyph( glyph->library, FT_BITMAP_GLYPH_CLASS_GET,
00551                           (FT_Glyph*)(void*)&bitmap );
00552     if ( error )
00553       goto Exit;
00554 
00555 #if 1
00556     /* if `origin' is set, translate the glyph image */
00557     if ( origin )
00558       FT_Glyph_Transform( glyph, 0, origin );
00559 #else
00560     FT_UNUSED( origin );
00561 #endif
00562 
00563     /* prepare dummy slot for rendering */
00564     error = clazz->glyph_prepare( glyph, &dummy );
00565     if ( !error )
00566       error = FT_Render_Glyph_Internal( glyph->library, &dummy, render_mode );
00567 
00568 #if 1
00569     if ( !destroy && origin )
00570     {
00571       FT_Vector  v;
00572 
00573 
00574       v.x = -origin->x;
00575       v.y = -origin->y;
00576       FT_Glyph_Transform( glyph, 0, &v );
00577     }
00578 #endif
00579 
00580     if ( error )
00581       goto Exit;
00582 
00583     /* in case of success, copy the bitmap to the glyph bitmap */
00584     error = ft_bitmap_glyph_init( (FT_Glyph)bitmap, &dummy );
00585     if ( error )
00586       goto Exit;
00587 
00588     /* copy advance */
00589     bitmap->root.advance = glyph->advance;
00590 
00591     if ( destroy )
00592       FT_Done_Glyph( glyph );
00593 
00594     *the_glyph = FT_GLYPH( bitmap );
00595 
00596   Exit:
00597     if ( error && bitmap )
00598       FT_Done_Glyph( FT_GLYPH( bitmap ) );
00599 
00600     return error;
00601 
00602   Bad:
00603     error = FT_Err_Invalid_Argument;
00604     goto Exit;
00605   }
00606 
00607 
00608   /* documentation is in ftglyph.h */
00609 
00610   FT_EXPORT_DEF( void )
00611   FT_Done_Glyph( FT_Glyph  glyph )
00612   {
00613     if ( glyph )
00614     {
00615       FT_Memory              memory = glyph->library->memory;
00616       const FT_Glyph_Class*  clazz  = glyph->clazz;
00617 
00618 
00619       if ( clazz->glyph_done )
00620         clazz->glyph_done( glyph );
00621 
00622       FT_FREE( glyph );
00623     }
00624   }
00625 
00626 
00627 /* END */

Generated on Tue Jul 5 14:13:42 2011 for ROOT_528-00b_version by  doxygen 1.5.1