source: trunk/poppler/freetype-2.1.10/src/autofit/afglobal.c @ 2

Last change on this file since 2 was 2, checked in by Eugene Romanenko, 15 years ago

First import

File size: 7.1 KB
Line 
1/***************************************************************************/
2/*                                                                         */
3/*  afglobal.c                                                             */
4/*                                                                         */
5/*    Auto-fitter routines to compute global hinting values (body).        */
6/*                                                                         */
7/*  Copyright 2003, 2004, 2005 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
18
19#include "afglobal.h"
20#include "afdummy.h"
21#include "aflatin.h"
22#include "aferrors.h"
23
24
25  /* populate this list when you add new scripts */
26  static AF_ScriptClass const  af_script_classes[] =
27  {
28    &af_dummy_script_class,
29    &af_latin_script_class,
30
31    NULL  /* do not remove */
32  };
33
34  /* index of default script in `af_script_classes' */
35#define AF_SCRIPT_LIST_DEFAULT  1
36  /* indicates an uncovered glyph                   */
37#define AF_SCRIPT_LIST_NONE   255
38
39
40  /*
41   *  Note that glyph_scripts[] is used to map each glyph into
42   *  an index into the `af_script_classes' array.
43   *
44   */
45  typedef struct  AF_FaceGlobalsRec_
46  {
47    FT_Face           face;
48    FT_UInt           glyph_count;    /* same as face->num_glyphs */
49    FT_Byte*          glyph_scripts;
50
51    AF_ScriptMetrics  metrics[AF_SCRIPT_MAX];
52
53  } AF_FaceGlobalsRec;
54
55
56  /* Compute the script index of each glyph within a given face. */
57
58  static FT_Error
59  af_face_globals_compute_script_coverage( AF_FaceGlobals  globals )
60  {
61    FT_Error    error       = AF_Err_Ok;
62    FT_Face     face        = globals->face;
63    FT_CharMap  old_charmap = face->charmap;
64    FT_Byte*    gscripts    = globals->glyph_scripts;
65    FT_UInt     ss;
66
67
68    /* the value 255 means `uncovered glyph' */
69    FT_MEM_SET( globals->glyph_scripts,
70                AF_SCRIPT_LIST_NONE,
71                globals->glyph_count );
72
73    error = FT_Select_Charmap( face, FT_ENCODING_UNICODE );
74    if ( error )
75    {
76     /*
77      *  Ignore this error; we simply use Latin as the standard
78      *  script.  XXX: Shouldn't we rather disable hinting?
79      */
80      error = AF_Err_Ok;
81      goto Exit;
82    }
83
84    /* scan each script in a Unicode charmap */
85    for ( ss = 0; af_script_classes[ss]; ss++ )
86    {
87      AF_ScriptClass      clazz = af_script_classes[ss];
88      AF_Script_UniRange  range;
89
90
91      if ( clazz->script_uni_ranges == NULL )
92        continue;
93
94      /*
95       *  Scan all unicode points in the range and set the corresponding
96       *  glyph script index.
97       */
98      for ( range = clazz->script_uni_ranges; range->first != 0; range++ )
99      {
100        FT_ULong  charcode = range->first;
101        FT_UInt   gindex;
102
103
104        gindex = FT_Get_Char_Index( face, charcode );
105
106        if ( gindex != 0                             &&
107             gindex < globals->glyph_count           &&
108             gscripts[gindex] == AF_SCRIPT_LIST_NONE )
109        {
110          gscripts[gindex] = (FT_Byte)ss;
111        }
112
113        for (;;)
114        {
115          charcode = FT_Get_Next_Char( face, charcode, &gindex );
116
117          if ( gindex == 0 || charcode > range->last )
118            break;
119
120          if ( gindex < globals->glyph_count           &&
121               gscripts[gindex] == AF_SCRIPT_LIST_NONE )
122          {
123            gscripts[gindex] = (FT_Byte)ss;
124          }
125        }
126      }
127    }
128
129  Exit:
130    /*
131     *  By default, all uncovered glyphs are set to the latin script.
132     *  XXX: Shouldnt' we disable hinting or do something similar?
133     */
134    {
135      FT_UInt  nn;
136
137
138      for ( nn = 0; nn < globals->glyph_count; nn++ )
139      {
140        if ( gscripts[nn] == AF_SCRIPT_LIST_NONE )
141          gscripts[nn] = AF_SCRIPT_LIST_DEFAULT;
142      }
143    }
144
145    FT_Set_Charmap( face, old_charmap );
146    return error;
147  }
148
149
150  FT_LOCAL_DEF( FT_Error )
151  af_face_globals_new( FT_Face          face,
152                       AF_FaceGlobals  *aglobals )
153  {
154    FT_Error        error;
155    FT_Memory       memory;
156    AF_FaceGlobals  globals;
157
158
159    memory = face->memory;
160
161    if ( !FT_ALLOC( globals, sizeof ( *globals ) +
162                             face->num_glyphs * sizeof ( FT_Byte ) ) )
163    {
164      globals->face          = face;
165      globals->glyph_count   = face->num_glyphs;
166      globals->glyph_scripts = (FT_Byte*)( globals + 1 );
167
168      error = af_face_globals_compute_script_coverage( globals );
169      if ( error )
170      {
171        af_face_globals_free( globals );
172        globals = NULL;
173      }
174    }
175
176    *aglobals = globals;
177    return error;
178  }
179
180
181  FT_LOCAL_DEF( void )
182  af_face_globals_free( AF_FaceGlobals  globals )
183  {
184    if ( globals )
185    {
186      FT_Memory  memory = globals->face->memory;
187      FT_UInt    nn;
188
189
190      for ( nn = 0; nn < AF_SCRIPT_MAX; nn++ )
191      {
192        if ( globals->metrics[nn] )
193        {
194          AF_ScriptClass  clazz = af_script_classes[nn];
195
196
197          FT_ASSERT( globals->metrics[nn]->clazz == clazz );
198
199          if ( clazz->script_metrics_done )
200            clazz->script_metrics_done( globals->metrics[nn] );
201
202          FT_FREE( globals->metrics[nn] );
203        }
204      }
205
206      globals->glyph_count   = 0;
207      globals->glyph_scripts = NULL;  /* no need to free this one! */
208      globals->face          = NULL;
209
210      FT_FREE( globals );
211    }
212  }
213
214
215  FT_LOCAL_DEF( FT_Error )
216  af_face_globals_get_metrics( AF_FaceGlobals     globals,
217                               FT_UInt            gindex,
218                               AF_ScriptMetrics  *ametrics )
219  {
220    AF_ScriptMetrics  metrics = NULL;
221    FT_UInt           gidx;
222    AF_ScriptClass    clazz;
223    FT_Error          error = AF_Err_Ok;
224
225
226    if ( gindex >= globals->glyph_count )
227    {
228      error = AF_Err_Invalid_Argument;
229      goto Exit;
230    }
231
232    gidx    = globals->glyph_scripts[gindex];
233    clazz   = af_script_classes[gidx];
234    metrics = globals->metrics[clazz->script];
235    if ( metrics == NULL )
236    {
237      /* create the global metrics object when needed */
238      FT_Memory  memory = globals->face->memory;
239
240
241      if ( FT_ALLOC( metrics, clazz->script_metrics_size ) )
242        goto Exit;
243
244      metrics->clazz = clazz;
245
246      if ( clazz->script_metrics_init )
247      {
248        error = clazz->script_metrics_init( metrics, globals->face );
249        if ( error )
250        {
251          if ( clazz->script_metrics_done )
252            clazz->script_metrics_done( metrics );
253
254          FT_FREE( metrics );
255          goto Exit;
256        }
257      }
258
259      globals->metrics[clazz->script] = metrics;
260    }
261
262  Exit:
263    *ametrics = metrics;
264
265    return error;
266  }
267
268
269/* END */
Note: See TracBrowser for help on using the repository browser.