ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ftgloadr.c
Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  ftgloadr.c                                                             */
00004 /*                                                                         */
00005 /*    The FreeType glyph loader (body).                                    */
00006 /*                                                                         */
00007 /*  Copyright 2002, 2003, 2004, 2005, 2006, 2010 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 #include <ft2build.h>
00020 #include FT_INTERNAL_GLYPH_LOADER_H
00021 #include FT_INTERNAL_MEMORY_H
00022 #include FT_INTERNAL_OBJECTS_H
00023 
00024 #undef  FT_COMPONENT
00025 #define FT_COMPONENT  trace_gloader
00026 
00027 
00028   /*************************************************************************/
00029   /*************************************************************************/
00030   /*************************************************************************/
00031   /*****                                                               *****/
00032   /*****                                                               *****/
00033   /*****                    G L Y P H   L O A D E R                    *****/
00034   /*****                                                               *****/
00035   /*****                                                               *****/
00036   /*************************************************************************/
00037   /*************************************************************************/
00038   /*************************************************************************/
00039 
00040   /*************************************************************************/
00041   /*                                                                       */
00042   /* The glyph loader is a simple object which is used to load a set of    */
00043   /* glyphs easily.  It is critical for the correct loading of composites. */
00044   /*                                                                       */
00045   /* Ideally, one can see it as a stack of abstract `glyph' objects.       */
00046   /*                                                                       */
00047   /*   loader.base     Is really the bottom of the stack.  It describes a  */
00048   /*                   single glyph image made of the juxtaposition of     */
00049   /*                   several glyphs (those `in the stack').              */
00050   /*                                                                       */
00051   /*   loader.current  Describes the top of the stack, on which a new      */
00052   /*                   glyph can be loaded.                                */
00053   /*                                                                       */
00054   /*   Rewind          Clears the stack.                                   */
00055   /*   Prepare         Set up `loader.current' for addition of a new glyph */
00056   /*                   image.                                              */
00057   /*   Add             Add the `current' glyph image to the `base' one,    */
00058   /*                   and prepare for another one.                        */
00059   /*                                                                       */
00060   /* The glyph loader is now a base object.  Each driver used to           */
00061   /* re-implement it in one way or the other, which wasted code and        */
00062   /* energy.                                                               */
00063   /*                                                                       */
00064   /*************************************************************************/
00065 
00066 
00067   /* create a new glyph loader */
00068   FT_BASE_DEF( FT_Error )
00069   FT_GlyphLoader_New( FT_Memory        memory,
00070                       FT_GlyphLoader  *aloader )
00071   {
00072     FT_GlyphLoader  loader = NULL;
00073     FT_Error        error;
00074 
00075 
00076     if ( !FT_NEW( loader ) )
00077     {
00078       loader->memory = memory;
00079       *aloader       = loader;
00080     }
00081     return error;
00082   }
00083 
00084 
00085   /* rewind the glyph loader - reset counters to 0 */
00086   FT_BASE_DEF( void )
00087   FT_GlyphLoader_Rewind( FT_GlyphLoader  loader )
00088   {
00089     FT_GlyphLoad  base    = &loader->base;
00090     FT_GlyphLoad  current = &loader->current;
00091 
00092 
00093     base->outline.n_points   = 0;
00094     base->outline.n_contours = 0;
00095     base->num_subglyphs      = 0;
00096 
00097     *current = *base;
00098   }
00099 
00100 
00101   /* reset the glyph loader, frees all allocated tables */
00102   /* and starts from zero                               */
00103   FT_BASE_DEF( void )
00104   FT_GlyphLoader_Reset( FT_GlyphLoader  loader )
00105   {
00106     FT_Memory memory = loader->memory;
00107 
00108 
00109     FT_FREE( loader->base.outline.points );
00110     FT_FREE( loader->base.outline.tags );
00111     FT_FREE( loader->base.outline.contours );
00112     FT_FREE( loader->base.extra_points );
00113     FT_FREE( loader->base.subglyphs );
00114 
00115     loader->base.extra_points2 = NULL;
00116 
00117     loader->max_points    = 0;
00118     loader->max_contours  = 0;
00119     loader->max_subglyphs = 0;
00120 
00121     FT_GlyphLoader_Rewind( loader );
00122   }
00123 
00124 
00125   /* delete a glyph loader */
00126   FT_BASE_DEF( void )
00127   FT_GlyphLoader_Done( FT_GlyphLoader  loader )
00128   {
00129     if ( loader )
00130     {
00131       FT_Memory memory = loader->memory;
00132 
00133 
00134       FT_GlyphLoader_Reset( loader );
00135       FT_FREE( loader );
00136     }
00137   }
00138 
00139 
00140   /* re-adjust the `current' outline fields */
00141   static void
00142   FT_GlyphLoader_Adjust_Points( FT_GlyphLoader  loader )
00143   {
00144     FT_Outline*  base    = &loader->base.outline;
00145     FT_Outline*  current = &loader->current.outline;
00146 
00147 
00148     current->points   = base->points   + base->n_points;
00149     current->tags     = base->tags     + base->n_points;
00150     current->contours = base->contours + base->n_contours;
00151 
00152     /* handle extra points table - if any */
00153     if ( loader->use_extra )
00154     {
00155       loader->current.extra_points  = loader->base.extra_points +
00156                                       base->n_points;
00157 
00158       loader->current.extra_points2 = loader->base.extra_points2 +
00159                                       base->n_points;
00160     }
00161   }
00162 
00163 
00164   FT_BASE_DEF( FT_Error )
00165   FT_GlyphLoader_CreateExtra( FT_GlyphLoader  loader )
00166   {
00167     FT_Error   error;
00168     FT_Memory  memory = loader->memory;
00169 
00170 
00171     if ( !FT_NEW_ARRAY( loader->base.extra_points, 2 * loader->max_points ) )
00172     {
00173       loader->use_extra          = 1;
00174       loader->base.extra_points2 = loader->base.extra_points +
00175                                    loader->max_points;
00176 
00177       FT_GlyphLoader_Adjust_Points( loader );
00178     }
00179     return error;
00180   }
00181 
00182 
00183   /* re-adjust the `current' subglyphs field */
00184   static void
00185   FT_GlyphLoader_Adjust_Subglyphs( FT_GlyphLoader  loader )
00186   {
00187     FT_GlyphLoad  base    = &loader->base;
00188     FT_GlyphLoad  current = &loader->current;
00189 
00190 
00191     current->subglyphs = base->subglyphs + base->num_subglyphs;
00192   }
00193 
00194 
00195   /* Ensure that we can add `n_points' and `n_contours' to our glyph.      */
00196   /* This function reallocates its outline tables if necessary.  Note that */
00197   /* it DOESN'T change the number of points within the loader!             */
00198   /*                                                                       */
00199   FT_BASE_DEF( FT_Error )
00200   FT_GlyphLoader_CheckPoints( FT_GlyphLoader  loader,
00201                               FT_UInt         n_points,
00202                               FT_UInt         n_contours )
00203   {
00204     FT_Memory    memory  = loader->memory;
00205     FT_Error     error   = FT_Err_Ok;
00206     FT_Outline*  base    = &loader->base.outline;
00207     FT_Outline*  current = &loader->current.outline;
00208     FT_Bool      adjust  = 0;
00209 
00210     FT_UInt      new_max, old_max;
00211 
00212 
00213     /* check points & tags */
00214     new_max = base->n_points + current->n_points + n_points;
00215     old_max = loader->max_points;
00216 
00217     if ( new_max > old_max )
00218     {
00219       new_max = FT_PAD_CEIL( new_max, 8 );
00220 
00221       if ( new_max > FT_OUTLINE_POINTS_MAX )
00222         return FT_Err_Array_Too_Large;
00223 
00224       if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) ||
00225            FT_RENEW_ARRAY( base->tags,   old_max, new_max ) )
00226         goto Exit;
00227 
00228       if ( loader->use_extra )
00229       {
00230         if ( FT_RENEW_ARRAY( loader->base.extra_points,
00231                              old_max * 2, new_max * 2 ) )
00232           goto Exit;
00233 
00234         FT_ARRAY_MOVE( loader->base.extra_points + new_max,
00235                        loader->base.extra_points + old_max,
00236                        old_max );
00237 
00238         loader->base.extra_points2 = loader->base.extra_points + new_max;
00239       }
00240 
00241       adjust = 1;
00242       loader->max_points = new_max;
00243     }
00244 
00245     /* check contours */
00246     old_max = loader->max_contours;
00247     new_max = base->n_contours + current->n_contours +
00248               n_contours;
00249     if ( new_max > old_max )
00250     {
00251       new_max = FT_PAD_CEIL( new_max, 4 );
00252 
00253       if ( new_max > FT_OUTLINE_CONTOURS_MAX )
00254         return FT_Err_Array_Too_Large;
00255 
00256       if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) )
00257         goto Exit;
00258 
00259       adjust = 1;
00260       loader->max_contours = new_max;
00261     }
00262 
00263     if ( adjust )
00264       FT_GlyphLoader_Adjust_Points( loader );
00265 
00266   Exit:
00267     return error;
00268   }
00269 
00270 
00271   /* Ensure that we can add `n_subglyphs' to our glyph. this function */
00272   /* reallocates its subglyphs table if necessary.  Note that it DOES */
00273   /* NOT change the number of subglyphs within the loader!            */
00274   /*                                                                  */
00275   FT_BASE_DEF( FT_Error )
00276   FT_GlyphLoader_CheckSubGlyphs( FT_GlyphLoader  loader,
00277                                  FT_UInt         n_subs )
00278   {
00279     FT_Memory     memory = loader->memory;
00280     FT_Error      error  = FT_Err_Ok;
00281     FT_UInt       new_max, old_max;
00282 
00283     FT_GlyphLoad  base    = &loader->base;
00284     FT_GlyphLoad  current = &loader->current;
00285 
00286 
00287     new_max = base->num_subglyphs + current->num_subglyphs + n_subs;
00288     old_max = loader->max_subglyphs;
00289     if ( new_max > old_max )
00290     {
00291       new_max = FT_PAD_CEIL( new_max, 2 );
00292       if ( FT_RENEW_ARRAY( base->subglyphs, old_max, new_max ) )
00293         goto Exit;
00294 
00295       loader->max_subglyphs = new_max;
00296 
00297       FT_GlyphLoader_Adjust_Subglyphs( loader );
00298     }
00299 
00300   Exit:
00301     return error;
00302   }
00303 
00304 
00305   /* prepare loader for the addition of a new glyph on top of the base one */
00306   FT_BASE_DEF( void )
00307   FT_GlyphLoader_Prepare( FT_GlyphLoader  loader )
00308   {
00309     FT_GlyphLoad  current = &loader->current;
00310 
00311 
00312     current->outline.n_points   = 0;
00313     current->outline.n_contours = 0;
00314     current->num_subglyphs      = 0;
00315 
00316     FT_GlyphLoader_Adjust_Points   ( loader );
00317     FT_GlyphLoader_Adjust_Subglyphs( loader );
00318   }
00319 
00320 
00321   /* add current glyph to the base image - and prepare for another */
00322   FT_BASE_DEF( void )
00323   FT_GlyphLoader_Add( FT_GlyphLoader  loader )
00324   {
00325     FT_GlyphLoad  base;
00326     FT_GlyphLoad  current;
00327 
00328     FT_UInt       n_curr_contours;
00329     FT_UInt       n_base_points;
00330     FT_UInt       n;
00331 
00332 
00333     if ( !loader )
00334       return;
00335 
00336     base    = &loader->base;
00337     current = &loader->current;
00338 
00339     n_curr_contours = current->outline.n_contours;
00340     n_base_points   = base->outline.n_points;
00341 
00342     base->outline.n_points =
00343       (short)( base->outline.n_points + current->outline.n_points );
00344     base->outline.n_contours =
00345       (short)( base->outline.n_contours + current->outline.n_contours );
00346 
00347     base->num_subglyphs += current->num_subglyphs;
00348 
00349     /* adjust contours count in newest outline */
00350     for ( n = 0; n < n_curr_contours; n++ )
00351       current->outline.contours[n] =
00352         (short)( current->outline.contours[n] + n_base_points );
00353 
00354     /* prepare for another new glyph image */
00355     FT_GlyphLoader_Prepare( loader );
00356   }
00357 
00358 
00359   FT_BASE_DEF( FT_Error )
00360   FT_GlyphLoader_CopyPoints( FT_GlyphLoader  target,
00361                              FT_GlyphLoader  source )
00362   {
00363     FT_Error  error;
00364     FT_UInt   num_points   = source->base.outline.n_points;
00365     FT_UInt   num_contours = source->base.outline.n_contours;
00366 
00367 
00368     error = FT_GlyphLoader_CheckPoints( target, num_points, num_contours );
00369     if ( !error )
00370     {
00371       FT_Outline*  out = &target->base.outline;
00372       FT_Outline*  in  = &source->base.outline;
00373 
00374 
00375       FT_ARRAY_COPY( out->points, in->points,
00376                      num_points );
00377       FT_ARRAY_COPY( out->tags, in->tags,
00378                      num_points );
00379       FT_ARRAY_COPY( out->contours, in->contours,
00380                      num_contours );
00381 
00382       /* do we need to copy the extra points? */
00383       if ( target->use_extra && source->use_extra )
00384       {
00385         FT_ARRAY_COPY( target->base.extra_points, source->base.extra_points,
00386                        num_points );
00387         FT_ARRAY_COPY( target->base.extra_points2, source->base.extra_points2,
00388                        num_points );
00389       }
00390 
00391       out->n_points   = (short)num_points;
00392       out->n_contours = (short)num_contours;
00393 
00394       FT_GlyphLoader_Adjust_Points( target );
00395     }
00396 
00397     return error;
00398   }
00399 
00400 
00401 /* END */

Generated on Fri May 25 2012 04:32:09 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.