1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  ftgloadr.c                                                             */
4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*    The FreeType glyph loader (body).                                    */
6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
7aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich/*  Copyright 2002, 2003, 2004, 2005, 2006, 2010 by                        */
8049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  David Turner, Robert Wilhelm, and Werner Lemberg                       */
9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  This file is part of the FreeType project, and may only be used,       */
11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  modified, and distributed under the terms of the FreeType project      */
12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  this file you indicate that you have read the license and              */
14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  understand and accept it fully.                                        */
15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
19049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <ft2build.h>
20049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_GLYPH_LOADER_H
21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_MEMORY_H
22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_OBJECTS_H
23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_gloader
26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
30049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*****                                                               *****/
32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*****                                                               *****/
33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*****                    G L Y P H   L O A D E R                    *****/
34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*****                                                               *****/
35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*****                                                               *****/
36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The glyph loader is a simple object which is used to load a set of    */
43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* glyphs easily.  It is critical for the correct loading of composites. */
44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Ideally, one can see it as a stack of abstract `glyph' objects.       */
46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*   loader.base     Is really the bottom of the stack.  It describes a  */
48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                   single glyph image made of the juxtaposition of     */
49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                   several glyphs (those `in the stack').              */
50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*   loader.current  Describes the top of the stack, on which a new      */
52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                   glyph can be loaded.                                */
53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*   Rewind          Clears the stack.                                   */
55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*   Prepare         Set up `loader.current' for addition of a new glyph */
56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                   image.                                              */
57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*   Add             Add the `current' glyph image to the `base' one,    */
58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                   and prepare for another one.                        */
59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The glyph loader is now a base object.  Each driver used to           */
61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* re-implement it in one way or the other, which wasted code and        */
62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* energy.                                                               */
63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* create a new glyph loader */
68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_GlyphLoader_New( FT_Memory        memory,
70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_GlyphLoader  *aloader )
71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
72aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_GlyphLoader  loader = NULL;
73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error        error;
74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !FT_NEW( loader ) )
77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->memory = memory;
79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *aloader       = loader;
80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* rewind the glyph loader - reset counters to 0 */
86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_GlyphLoader_Rewind( FT_GlyphLoader  loader )
88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphLoad  base    = &loader->base;
90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphLoad  current = &loader->current;
91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base->outline.n_points   = 0;
94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base->outline.n_contours = 0;
95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base->num_subglyphs      = 0;
96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *current = *base;
98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* reset the glyph loader, frees all allocated tables */
102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* and starts from zero                               */
103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_GlyphLoader_Reset( FT_GlyphLoader  loader )
105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory memory = loader->memory;
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( loader->base.outline.points );
110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( loader->base.outline.tags );
111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( loader->base.outline.contours );
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( loader->base.extra_points );
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( loader->base.subglyphs );
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->base.extra_points2 = NULL;
116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->max_points    = 0;
118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->max_contours  = 0;
119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->max_subglyphs = 0;
120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphLoader_Rewind( loader );
122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* delete a glyph loader */
126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_GlyphLoader_Done( FT_GlyphLoader  loader )
128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( loader )
130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Memory memory = loader->memory;
132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_GlyphLoader_Reset( loader );
135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( loader );
136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* re-adjust the `current' outline fields */
141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_GlyphLoader_Adjust_Points( FT_GlyphLoader  loader )
143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Outline*  base    = &loader->base.outline;
145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Outline*  current = &loader->current.outline;
146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    current->points   = base->points   + base->n_points;
149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    current->tags     = base->tags     + base->n_points;
150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    current->contours = base->contours + base->n_contours;
151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* handle extra points table - if any */
153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( loader->use_extra )
154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->current.extra_points  = loader->base.extra_points +
156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      base->n_points;
157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->current.extra_points2 = loader->base.extra_points2 +
159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      base->n_points;
160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_GlyphLoader_CreateExtra( FT_GlyphLoader  loader )
166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = loader->memory;
169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !FT_NEW_ARRAY( loader->base.extra_points, 2 * loader->max_points ) )
172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->use_extra          = 1;
174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->base.extra_points2 = loader->base.extra_points +
175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   loader->max_points;
176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_GlyphLoader_Adjust_Points( loader );
178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* re-adjust the `current' subglyphs field */
184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_GlyphLoader_Adjust_Subglyphs( FT_GlyphLoader  loader )
186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphLoad  base    = &loader->base;
188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphLoad  current = &loader->current;
189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    current->subglyphs = base->subglyphs + base->num_subglyphs;
192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Ensure that we can add `n_points' and `n_contours' to our glyph.      */
196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* This function reallocates its outline tables if necessary.  Note that */
197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* it DOESN'T change the number of points within the loader!             */
198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_GlyphLoader_CheckPoints( FT_GlyphLoader  loader,
201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              FT_UInt         n_points,
202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              FT_UInt         n_contours )
203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory    memory  = loader->memory;
205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error     error   = FT_Err_Ok;
206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Outline*  base    = &loader->base.outline;
207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Outline*  current = &loader->current.outline;
208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Bool      adjust  = 0;
209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt      new_max, old_max;
211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* check points & tags */
214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    new_max = base->n_points + current->n_points + n_points;
215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    old_max = loader->max_points;
216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( new_max > old_max )
218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      new_max = FT_PAD_CEIL( new_max, 8 );
220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
221295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      if ( new_max > FT_OUTLINE_POINTS_MAX )
222295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        return FT_Err_Array_Too_Large;
223295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) ||
225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           FT_RENEW_ARRAY( base->tags,   old_max, new_max ) )
226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( loader->use_extra )
229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_RENEW_ARRAY( loader->base.extra_points,
231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             old_max * 2, new_max * 2 ) )
232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_ARRAY_MOVE( loader->base.extra_points + new_max,
235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       loader->base.extra_points + old_max,
236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       old_max );
237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        loader->base.extra_points2 = loader->base.extra_points + new_max;
239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      adjust = 1;
242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->max_points = new_max;
243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* check contours */
246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    old_max = loader->max_contours;
247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    new_max = base->n_contours + current->n_contours +
248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              n_contours;
249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( new_max > old_max )
250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      new_max = FT_PAD_CEIL( new_max, 4 );
252295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
253295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      if ( new_max > FT_OUTLINE_CONTOURS_MAX )
254295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        return FT_Err_Array_Too_Large;
255295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) )
257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      adjust = 1;
260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->max_contours = new_max;
261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( adjust )
264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_GlyphLoader_Adjust_Points( loader );
265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Ensure that we can add `n_subglyphs' to our glyph. this function */
272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* reallocates its subglyphs table if necessary.  Note that it DOES */
273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* NOT change the number of subglyphs within the loader!            */
274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                  */
275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_GlyphLoader_CheckSubGlyphs( FT_GlyphLoader  loader,
277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 FT_UInt         n_subs )
278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory     memory = loader->memory;
280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error      error  = FT_Err_Ok;
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt       new_max, old_max;
282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphLoad  base    = &loader->base;
284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphLoad  current = &loader->current;
285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    new_max = base->num_subglyphs + current->num_subglyphs + n_subs;
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    old_max = loader->max_subglyphs;
289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( new_max > old_max )
290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      new_max = FT_PAD_CEIL( new_max, 2 );
292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_RENEW_ARRAY( base->subglyphs, old_max, new_max ) )
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->max_subglyphs = new_max;
296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_GlyphLoader_Adjust_Subglyphs( loader );
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* prepare loader for the addition of a new glyph on top of the base one */
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_GlyphLoader_Prepare( FT_GlyphLoader  loader )
308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphLoad  current = &loader->current;
310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    current->outline.n_points   = 0;
313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    current->outline.n_contours = 0;
314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    current->num_subglyphs      = 0;
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphLoader_Adjust_Points   ( loader );
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphLoader_Adjust_Subglyphs( loader );
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* add current glyph to the base image - and prepare for another */
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_GlyphLoader_Add( FT_GlyphLoader  loader )
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphLoad  base;
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphLoad  current;
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt       n_curr_contours;
329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt       n_base_points;
330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt       n;
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !loader )
334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base    = &loader->base;
337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    current = &loader->current;
338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    n_curr_contours = current->outline.n_contours;
340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    n_base_points   = base->outline.n_points;
341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base->outline.n_points =
343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      (short)( base->outline.n_points + current->outline.n_points );
344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base->outline.n_contours =
345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      (short)( base->outline.n_contours + current->outline.n_contours );
346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base->num_subglyphs += current->num_subglyphs;
348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* adjust contours count in newest outline */
350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( n = 0; n < n_curr_contours; n++ )
351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      current->outline.contours[n] =
352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        (short)( current->outline.contours[n] + n_base_points );
353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* prepare for another new glyph image */
355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphLoader_Prepare( loader );
356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_GlyphLoader_CopyPoints( FT_GlyphLoader  target,
361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             FT_GlyphLoader  source )
362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error;
364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt   num_points   = source->base.outline.n_points;
365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt   num_contours = source->base.outline.n_contours;
366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_GlyphLoader_CheckPoints( target, num_points, num_contours );
369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error )
370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Outline*  out = &target->base.outline;
372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Outline*  in  = &source->base.outline;
373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ARRAY_COPY( out->points, in->points,
376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     num_points );
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ARRAY_COPY( out->tags, in->tags,
378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     num_points );
379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ARRAY_COPY( out->contours, in->contours,
380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     num_contours );
381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* do we need to copy the extra points? */
383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( target->use_extra && source->use_extra )
384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_ARRAY_COPY( target->base.extra_points, source->base.extra_points,
386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       num_points );
387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_ARRAY_COPY( target->base.extra_points2, source->base.extra_points2,
388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       num_points );
389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      out->n_points   = (short)num_points;
392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      out->n_contours = (short)num_contours;
393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_GlyphLoader_Adjust_Points( target );
395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
402