ftgloadr.c
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:13k
源码类别:

其他游戏

开发平台:

Visual C++

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /*  ftgloadr.c                                                             */
  4. /*                                                                         */
  5. /*    The FreeType glyph loader (body).                                    */
  6. /*                                                                         */
  7. /*  Copyright 2002, 2003, 2004, 2005, 2006 by                              */
  8. /*  David Turner, Robert Wilhelm, and Werner Lemberg                       */
  9. /*                                                                         */
  10. /*  This file is part of the FreeType project, and may only be used,       */
  11. /*  modified, and distributed under the terms of the FreeType project      */
  12. /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  13. /*  this file you indicate that you have read the license and              */
  14. /*  understand and accept it fully.                                        */
  15. /*                                                                         */
  16. /***************************************************************************/
  17. #include <ft2build.h>
  18. #include FT_INTERNAL_GLYPH_LOADER_H
  19. #include FT_INTERNAL_MEMORY_H
  20. #include FT_INTERNAL_OBJECTS_H
  21. #undef  FT_COMPONENT
  22. #define FT_COMPONENT  trace_gloader
  23.   /*************************************************************************/
  24.   /*************************************************************************/
  25.   /*************************************************************************/
  26.   /*****                                                               *****/
  27.   /*****                                                               *****/
  28.   /*****                    G L Y P H   L O A D E R                    *****/
  29.   /*****                                                               *****/
  30.   /*****                                                               *****/
  31.   /*************************************************************************/
  32.   /*************************************************************************/
  33.   /*************************************************************************/
  34.   /*************************************************************************/
  35.   /*                                                                       */
  36.   /* The glyph loader is a simple object which is used to load a set of    */
  37.   /* glyphs easily.  It is critical for the correct loading of composites. */
  38.   /*                                                                       */
  39.   /* Ideally, one can see it as a stack of abstract `glyph' objects.       */
  40.   /*                                                                       */
  41.   /*   loader.base     Is really the bottom of the stack.  It describes a  */
  42.   /*                   single glyph image made of the juxtaposition of     */
  43.   /*                   several glyphs (those `in the stack').              */
  44.   /*                                                                       */
  45.   /*   loader.current  Describes the top of the stack, on which a new      */
  46.   /*                   glyph can be loaded.                                */
  47.   /*                                                                       */
  48.   /*   Rewind          Clears the stack.                                   */
  49.   /*   Prepare         Set up `loader.current' for addition of a new glyph */
  50.   /*                   image.                                              */
  51.   /*   Add             Add the `current' glyph image to the `base' one,    */
  52.   /*                   and prepare for another one.                        */
  53.   /*                                                                       */
  54.   /* The glyph loader is now a base object.  Each driver used to           */
  55.   /* re-implement it in one way or the other, which wasted code and        */
  56.   /* energy.                                                               */
  57.   /*                                                                       */
  58.   /*************************************************************************/
  59.   /* create a new glyph loader */
  60.   FT_BASE_DEF( FT_Error )
  61.   FT_GlyphLoader_New( FT_Memory        memory,
  62.                       FT_GlyphLoader  *aloader )
  63.   {
  64.     FT_GlyphLoader  loader;
  65.     FT_Error        error;
  66.     if ( !FT_NEW( loader ) )
  67.     {
  68.       loader->memory = memory;
  69.       *aloader       = loader;
  70.     }
  71.     return error;
  72.   }
  73.   /* rewind the glyph loader - reset counters to 0 */
  74.   FT_BASE_DEF( void )
  75.   FT_GlyphLoader_Rewind( FT_GlyphLoader  loader )
  76.   {
  77.     FT_GlyphLoad  base    = &loader->base;
  78.     FT_GlyphLoad  current = &loader->current;
  79.     base->outline.n_points   = 0;
  80.     base->outline.n_contours = 0;
  81.     base->num_subglyphs      = 0;
  82.     *current = *base;
  83.   }
  84.   /* reset the glyph loader, frees all allocated tables */
  85.   /* and starts from zero                               */
  86.   FT_BASE_DEF( void )
  87.   FT_GlyphLoader_Reset( FT_GlyphLoader  loader )
  88.   {
  89.     FT_Memory memory = loader->memory;
  90.     FT_FREE( loader->base.outline.points );
  91.     FT_FREE( loader->base.outline.tags );
  92.     FT_FREE( loader->base.outline.contours );
  93.     FT_FREE( loader->base.extra_points );
  94.     FT_FREE( loader->base.subglyphs );
  95.     loader->base.extra_points2 = NULL;
  96.     loader->max_points    = 0;
  97.     loader->max_contours  = 0;
  98.     loader->max_subglyphs = 0;
  99.     FT_GlyphLoader_Rewind( loader );
  100.   }
  101.   /* delete a glyph loader */
  102.   FT_BASE_DEF( void )
  103.   FT_GlyphLoader_Done( FT_GlyphLoader  loader )
  104.   {
  105.     if ( loader )
  106.     {
  107.       FT_Memory memory = loader->memory;
  108.       FT_GlyphLoader_Reset( loader );
  109.       FT_FREE( loader );
  110.     }
  111.   }
  112.   /* re-adjust the `current' outline fields */
  113.   static void
  114.   FT_GlyphLoader_Adjust_Points( FT_GlyphLoader  loader )
  115.   {
  116.     FT_Outline*  base    = &loader->base.outline;
  117.     FT_Outline*  current = &loader->current.outline;
  118.     current->points   = base->points   + base->n_points;
  119.     current->tags     = base->tags     + base->n_points;
  120.     current->contours = base->contours + base->n_contours;
  121.     /* handle extra points table - if any */
  122.     if ( loader->use_extra )
  123.     {
  124.       loader->current.extra_points  = loader->base.extra_points +
  125.                                       base->n_points;
  126.       loader->current.extra_points2 = loader->base.extra_points2 +
  127.                                       base->n_points;
  128.     }
  129.   }
  130.   FT_BASE_DEF( FT_Error )
  131.   FT_GlyphLoader_CreateExtra( FT_GlyphLoader  loader )
  132.   {
  133.     FT_Error   error;
  134.     FT_Memory  memory = loader->memory;
  135.     if ( !FT_NEW_ARRAY( loader->base.extra_points, 2 * loader->max_points ) )
  136.     {
  137.       loader->use_extra          = 1;
  138.       loader->base.extra_points2 = loader->base.extra_points +
  139.                                    loader->max_points;
  140.       FT_GlyphLoader_Adjust_Points( loader );
  141.     }
  142.     return error;
  143.   }
  144.   /* re-adjust the `current' subglyphs field */
  145.   static void
  146.   FT_GlyphLoader_Adjust_Subglyphs( FT_GlyphLoader  loader )
  147.   {
  148.     FT_GlyphLoad  base    = &loader->base;
  149.     FT_GlyphLoad  current = &loader->current;
  150.     current->subglyphs = base->subglyphs + base->num_subglyphs;
  151.   }
  152.   /* Ensure that we can add `n_points' and `n_contours' to our glyph.      */
  153.   /* This function reallocates its outline tables if necessary.  Note that */
  154.   /* it DOESN'T change the number of points within the loader!             */
  155.   /*                                                                       */
  156.   FT_BASE_DEF( FT_Error )
  157.   FT_GlyphLoader_CheckPoints( FT_GlyphLoader  loader,
  158.                               FT_UInt         n_points,
  159.                               FT_UInt         n_contours )
  160.   {
  161.     FT_Memory    memory  = loader->memory;
  162.     FT_Error     error   = FT_Err_Ok;
  163.     FT_Outline*  base    = &loader->base.outline;
  164.     FT_Outline*  current = &loader->current.outline;
  165.     FT_Bool      adjust  = 0;
  166.     FT_UInt      new_max, old_max;
  167.     /* check points & tags */
  168.     new_max = base->n_points + current->n_points + n_points;
  169.     old_max = loader->max_points;
  170.     if ( new_max > old_max )
  171.     {
  172.       new_max = FT_PAD_CEIL( new_max, 8 );
  173.       if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) ||
  174.            FT_RENEW_ARRAY( base->tags,   old_max, new_max ) )
  175.         goto Exit;
  176.       if ( loader->use_extra )
  177.       {
  178.         if ( FT_RENEW_ARRAY( loader->base.extra_points,
  179.                              old_max * 2, new_max * 2 ) )
  180.           goto Exit;
  181.         FT_ARRAY_MOVE( loader->base.extra_points + new_max,
  182.                        loader->base.extra_points + old_max,
  183.                        old_max );
  184.         loader->base.extra_points2 = loader->base.extra_points + new_max;
  185.       }
  186.       adjust = 1;
  187.       loader->max_points = new_max;
  188.     }
  189.     /* check contours */
  190.     old_max = loader->max_contours;
  191.     new_max = base->n_contours + current->n_contours +
  192.               n_contours;
  193.     if ( new_max > old_max )
  194.     {
  195.       new_max = FT_PAD_CEIL( new_max, 4 );
  196.       if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) )
  197.         goto Exit;
  198.       adjust = 1;
  199.       loader->max_contours = new_max;
  200.     }
  201.     if ( adjust )
  202.       FT_GlyphLoader_Adjust_Points( loader );
  203.   Exit:
  204.     return error;
  205.   }
  206.   /* Ensure that we can add `n_subglyphs' to our glyph. this function */
  207.   /* reallocates its subglyphs table if necessary.  Note that it DOES */
  208.   /* NOT change the number of subglyphs within the loader!            */
  209.   /*                                                                  */
  210.   FT_BASE_DEF( FT_Error )
  211.   FT_GlyphLoader_CheckSubGlyphs( FT_GlyphLoader  loader,
  212.                                  FT_UInt         n_subs )
  213.   {
  214.     FT_Memory     memory = loader->memory;
  215.     FT_Error      error  = FT_Err_Ok;
  216.     FT_UInt       new_max, old_max;
  217.     FT_GlyphLoad  base    = &loader->base;
  218.     FT_GlyphLoad  current = &loader->current;
  219.     new_max = base->num_subglyphs + current->num_subglyphs + n_subs;
  220.     old_max = loader->max_subglyphs;
  221.     if ( new_max > old_max )
  222.     {
  223.       new_max = FT_PAD_CEIL( new_max, 2 );
  224.       if ( FT_RENEW_ARRAY( base->subglyphs, old_max, new_max ) )
  225.         goto Exit;
  226.       loader->max_subglyphs = new_max;
  227.       FT_GlyphLoader_Adjust_Subglyphs( loader );
  228.     }
  229.   Exit:
  230.     return error;
  231.   }
  232.   /* prepare loader for the addition of a new glyph on top of the base one */
  233.   FT_BASE_DEF( void )
  234.   FT_GlyphLoader_Prepare( FT_GlyphLoader  loader )
  235.   {
  236.     FT_GlyphLoad  current = &loader->current;
  237.     current->outline.n_points   = 0;
  238.     current->outline.n_contours = 0;
  239.     current->num_subglyphs      = 0;
  240.     FT_GlyphLoader_Adjust_Points   ( loader );
  241.     FT_GlyphLoader_Adjust_Subglyphs( loader );
  242.   }
  243.   /* add current glyph to the base image - and prepare for another */
  244.   FT_BASE_DEF( void )
  245.   FT_GlyphLoader_Add( FT_GlyphLoader  loader )
  246.   {
  247.     FT_GlyphLoad  base;
  248.     FT_GlyphLoad  current;
  249.     FT_UInt       n_curr_contours;
  250.     FT_UInt       n_base_points;
  251.     FT_UInt       n;
  252.     if ( !loader )
  253.       return;
  254.     base    = &loader->base;
  255.     current = &loader->current;
  256.     n_curr_contours = current->outline.n_contours;
  257.     n_base_points   = base->outline.n_points;
  258.     base->outline.n_points =
  259.       (short)( base->outline.n_points + current->outline.n_points );
  260.     base->outline.n_contours =
  261.       (short)( base->outline.n_contours + current->outline.n_contours );
  262.     base->num_subglyphs += current->num_subglyphs;
  263.     /* adjust contours count in newest outline */
  264.     for ( n = 0; n < n_curr_contours; n++ )
  265.       current->outline.contours[n] =
  266.         (short)( current->outline.contours[n] + n_base_points );
  267.     /* prepare for another new glyph image */
  268.     FT_GlyphLoader_Prepare( loader );
  269.   }
  270.   FT_BASE_DEF( FT_Error )
  271.   FT_GlyphLoader_CopyPoints( FT_GlyphLoader  target,
  272.                              FT_GlyphLoader  source )
  273.   {
  274.     FT_Error  error;
  275.     FT_UInt   num_points   = source->base.outline.n_points;
  276.     FT_UInt   num_contours = source->base.outline.n_contours;
  277.     error = FT_GlyphLoader_CheckPoints( target, num_points, num_contours );
  278.     if ( !error )
  279.     {
  280.       FT_Outline*  out = &target->base.outline;
  281.       FT_Outline*  in  = &source->base.outline;
  282.       FT_ARRAY_COPY( out->points, in->points,
  283.                      num_points );
  284.       FT_ARRAY_COPY( out->tags, in->tags,
  285.                      num_points );
  286.       FT_ARRAY_COPY( out->contours, in->contours,
  287.                      num_contours );
  288.       /* do we need to copy the extra points? */
  289.       if ( target->use_extra && source->use_extra )
  290.       {
  291.         FT_ARRAY_COPY( target->base.extra_points, source->base.extra_points,
  292.                        num_points );
  293.         FT_ARRAY_COPY( target->base.extra_points2, source->base.extra_points2,
  294.                        num_points );
  295.       }
  296.       out->n_points   = (short)num_points;
  297.       out->n_contours = (short)num_contours;
  298.       FT_GlyphLoader_Adjust_Points( target );
  299.     }
  300.     return error;
  301.   }
  302. /* END */