~ubuntu-branches/ubuntu/wily/hedgewars/wily

« back to all changes in this revision

Viewing changes to misc/libfreetype/src/pshinter/pshglob.c

  • Committer: Package Import Robot
  • Author(s): Dmitry E. Oboukhov
  • Date: 2011-09-23 10:16:55 UTC
  • mfrom: (1.2.11 upstream)
  • Revision ID: package-import@ubuntu.com-20110923101655-3977th2gc5n0a3pv
Tags: 0.9.16-1
* New upstream version.
 + Downloadable content! Simply click to install any content.
   New voices, hats, maps, themes, translations, music, scripts...
   Hedgewars is now more customisable than ever before! As time goes
   by we will be soliciting community content to feature on this page,
   so remember to check it from time to time. If you decide you want
   to go back to standard Hedgewars, just remove the Data directory
   from your Hedgewars config directory.
 + 3-D rendering! Diorama-like rendering of the game in a variety
   of 3D modes. Let us know which ones work best for you, we didn't
   really have the equipment to test them all.
 + Resizable game window.
 + New utilities! The Time Box will remove one of your hedgehogs
   from the game for a while, protecting from attack until it returns,
   somewhere else on the map. Land spray will allow you to build bridges,
   seal up holes, or just make life unpleasant for your enemies.
 + New single player: Bamboo Thicket, That Sinking Feeling, Newton and
   the Tree and multi-player: The Specialists, Space Invaders,
   Racer - scripts! And a ton more script hooks for scripters
 + New twists on old weapons. Drill strike, seduction and fire have
   been adjusted. Defective mines have been added, rope can attach to
   hogs/crates/barrels again, grenades now have variable bounce (use
   precise key + 1-5). Portal gun is now more usable in flight and
   all game actions are a lot faster.
 + New theme - Golf, dozens of new community hats and a new
   localised Default voice, Ukranian.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************/
 
2
/*                                                                         */
 
3
/*  pshglob.c                                                              */
 
4
/*                                                                         */
 
5
/*    PostScript hinter global hinting management (body).                  */
 
6
/*    Inspired by the new auto-hinter module.                              */
 
7
/*                                                                         */
 
8
/*  Copyright 2001, 2002, 2003, 2004, 2006, 2010 by                        */
 
9
/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 
10
/*                                                                         */
 
11
/*  This file is part of the FreeType project, and may only be used        */
 
12
/*  modified and distributed under the terms of the FreeType project       */
 
13
/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
 
14
/*  this file you indicate that you have read the license and              */
 
15
/*  understand and accept it fully.                                        */
 
16
/*                                                                         */
 
17
/***************************************************************************/
 
18
 
 
19
 
 
20
#include <ft2build.h>
 
21
#include FT_FREETYPE_H
 
22
#include FT_INTERNAL_OBJECTS_H
 
23
#include "pshglob.h"
 
24
 
 
25
#ifdef DEBUG_HINTER
 
26
  PSH_Globals  ps_debug_globals = 0;
 
27
#endif
 
28
 
 
29
 
 
30
  /*************************************************************************/
 
31
  /*************************************************************************/
 
32
  /*****                                                               *****/
 
33
  /*****                       STANDARD WIDTHS                         *****/
 
34
  /*****                                                               *****/
 
35
  /*************************************************************************/
 
36
  /*************************************************************************/
 
37
 
 
38
 
 
39
  /* scale the widths/heights table */
 
40
  static void
 
41
  psh_globals_scale_widths( PSH_Globals  globals,
 
42
                            FT_UInt      direction )
 
43
  {
 
44
    PSH_Dimension  dim   = &globals->dimension[direction];
 
45
    PSH_Widths     stdw  = &dim->stdw;
 
46
    FT_UInt        count = stdw->count;
 
47
    PSH_Width      width = stdw->widths;
 
48
    PSH_Width      stand = width;               /* standard width/height */
 
49
    FT_Fixed       scale = dim->scale_mult;
 
50
 
 
51
 
 
52
    if ( count > 0 )
 
53
    {
 
54
      width->cur = FT_MulFix( width->org, scale );
 
55
      width->fit = FT_PIX_ROUND( width->cur );
 
56
 
 
57
      width++;
 
58
      count--;
 
59
 
 
60
      for ( ; count > 0; count--, width++ )
 
61
      {
 
62
        FT_Pos  w, dist;
 
63
 
 
64
 
 
65
        w    = FT_MulFix( width->org, scale );
 
66
        dist = w - stand->cur;
 
67
 
 
68
        if ( dist < 0 )
 
69
          dist = -dist;
 
70
 
 
71
        if ( dist < 128 )
 
72
          w = stand->cur;
 
73
 
 
74
        width->cur = w;
 
75
        width->fit = FT_PIX_ROUND( w );
 
76
      }
 
77
    }
 
78
  }
 
79
 
 
80
 
 
81
#if 0
 
82
 
 
83
  /* org_width is is font units, result in device pixels, 26.6 format */
 
84
  FT_LOCAL_DEF( FT_Pos )
 
85
  psh_dimension_snap_width( PSH_Dimension  dimension,
 
86
                            FT_Int         org_width )
 
87
  {
 
88
    FT_UInt  n;
 
89
    FT_Pos   width     = FT_MulFix( org_width, dimension->scale_mult );
 
90
    FT_Pos   best      = 64 + 32 + 2;
 
91
    FT_Pos   reference = width;
 
92
 
 
93
 
 
94
    for ( n = 0; n < dimension->stdw.count; n++ )
 
95
    {
 
96
      FT_Pos  w;
 
97
      FT_Pos  dist;
 
98
 
 
99
 
 
100
      w = dimension->stdw.widths[n].cur;
 
101
      dist = width - w;
 
102
      if ( dist < 0 )
 
103
        dist = -dist;
 
104
      if ( dist < best )
 
105
      {
 
106
        best      = dist;
 
107
        reference = w;
 
108
      }
 
109
    }
 
110
 
 
111
    if ( width >= reference )
 
112
    {
 
113
      width -= 0x21;
 
114
      if ( width < reference )
 
115
        width = reference;
 
116
    }
 
117
    else
 
118
    {
 
119
      width += 0x21;
 
120
      if ( width > reference )
 
121
        width = reference;
 
122
    }
 
123
 
 
124
    return width;
 
125
  }
 
126
 
 
127
#endif /* 0 */
 
128
 
 
129
 
 
130
  /*************************************************************************/
 
131
  /*************************************************************************/
 
132
  /*****                                                               *****/
 
133
  /*****                       BLUE ZONES                              *****/
 
134
  /*****                                                               *****/
 
135
  /*************************************************************************/
 
136
  /*************************************************************************/
 
137
 
 
138
  static void
 
139
  psh_blues_set_zones_0( PSH_Blues       target,
 
140
                         FT_Bool         is_others,
 
141
                         FT_UInt         read_count,
 
142
                         FT_Short*       read,
 
143
                         PSH_Blue_Table  top_table,
 
144
                         PSH_Blue_Table  bot_table )
 
145
  {
 
146
    FT_UInt  count_top = top_table->count;
 
147
    FT_UInt  count_bot = bot_table->count;
 
148
    FT_Bool  first     = 1;
 
149
 
 
150
    FT_UNUSED( target );
 
151
 
 
152
 
 
153
    for ( ; read_count > 1; read_count -= 2 )
 
154
    {
 
155
      FT_Int         reference, delta;
 
156
      FT_UInt        count;
 
157
      PSH_Blue_Zone  zones, zone;
 
158
      FT_Bool        top;
 
159
 
 
160
 
 
161
      /* read blue zone entry, and select target top/bottom zone */
 
162
      top = 0;
 
163
      if ( first || is_others )
 
164
      {
 
165
        reference = read[1];
 
166
        delta     = read[0] - reference;
 
167
 
 
168
        zones = bot_table->zones;
 
169
        count = count_bot;
 
170
        first = 0;
 
171
      }
 
172
      else
 
173
      {
 
174
        reference = read[0];
 
175
        delta     = read[1] - reference;
 
176
 
 
177
        zones = top_table->zones;
 
178
        count = count_top;
 
179
        top   = 1;
 
180
      }
 
181
 
 
182
      /* insert into sorted table */
 
183
      zone = zones;
 
184
      for ( ; count > 0; count--, zone++ )
 
185
      {
 
186
        if ( reference < zone->org_ref )
 
187
          break;
 
188
 
 
189
        if ( reference == zone->org_ref )
 
190
        {
 
191
          FT_Int  delta0 = zone->org_delta;
 
192
 
 
193
 
 
194
          /* we have two zones on the same reference position -- */
 
195
          /* only keep the largest one                           */
 
196
          if ( delta < 0 )
 
197
          {
 
198
            if ( delta < delta0 )
 
199
              zone->org_delta = delta;
 
200
          }
 
201
          else
 
202
          {
 
203
            if ( delta > delta0 )
 
204
              zone->org_delta = delta;
 
205
          }
 
206
          goto Skip;
 
207
        }
 
208
      }
 
209
 
 
210
      for ( ; count > 0; count-- )
 
211
        zone[count] = zone[count-1];
 
212
 
 
213
      zone->org_ref   = reference;
 
214
      zone->org_delta = delta;
 
215
 
 
216
      if ( top )
 
217
        count_top++;
 
218
      else
 
219
        count_bot++;
 
220
 
 
221
    Skip:
 
222
      read += 2;
 
223
    }
 
224
 
 
225
    top_table->count = count_top;
 
226
    bot_table->count = count_bot;
 
227
  }
 
228
 
 
229
 
 
230
  /* Re-read blue zones from the original fonts and store them into out */
 
231
  /* private structure.  This function re-orders, sanitizes and         */
 
232
  /* fuzz-expands the zones as well.                                    */
 
233
  static void
 
234
  psh_blues_set_zones( PSH_Blues  target,
 
235
                       FT_UInt    count,
 
236
                       FT_Short*  blues,
 
237
                       FT_UInt    count_others,
 
238
                       FT_Short*  other_blues,
 
239
                       FT_Int     fuzz,
 
240
                       FT_Int     family )
 
241
  {
 
242
    PSH_Blue_Table  top_table, bot_table;
 
243
    FT_Int          count_top, count_bot;
 
244
 
 
245
 
 
246
    if ( family )
 
247
    {
 
248
      top_table = &target->family_top;
 
249
      bot_table = &target->family_bottom;
 
250
    }
 
251
    else
 
252
    {
 
253
      top_table = &target->normal_top;
 
254
      bot_table = &target->normal_bottom;
 
255
    }
 
256
 
 
257
    /* read the input blue zones, and build two sorted tables  */
 
258
    /* (one for the top zones, the other for the bottom zones) */
 
259
    top_table->count = 0;
 
260
    bot_table->count = 0;
 
261
 
 
262
    /* first, the blues */
 
263
    psh_blues_set_zones_0( target, 0,
 
264
                           count, blues, top_table, bot_table );
 
265
    psh_blues_set_zones_0( target, 1,
 
266
                           count_others, other_blues, top_table, bot_table );
 
267
 
 
268
    count_top = top_table->count;
 
269
    count_bot = bot_table->count;
 
270
 
 
271
    /* sanitize top table */
 
272
    if ( count_top > 0 )
 
273
    {
 
274
      PSH_Blue_Zone  zone = top_table->zones;
 
275
 
 
276
 
 
277
      for ( count = count_top; count > 0; count--, zone++ )
 
278
      {
 
279
        FT_Int  delta;
 
280
 
 
281
 
 
282
        if ( count > 1 )
 
283
        {
 
284
          delta = zone[1].org_ref - zone[0].org_ref;
 
285
          if ( zone->org_delta > delta )
 
286
            zone->org_delta = delta;
 
287
        }
 
288
 
 
289
        zone->org_bottom = zone->org_ref;
 
290
        zone->org_top    = zone->org_delta + zone->org_ref;
 
291
      }
 
292
    }
 
293
 
 
294
    /* sanitize bottom table */
 
295
    if ( count_bot > 0 )
 
296
    {
 
297
      PSH_Blue_Zone  zone = bot_table->zones;
 
298
 
 
299
 
 
300
      for ( count = count_bot; count > 0; count--, zone++ )
 
301
      {
 
302
        FT_Int  delta;
 
303
 
 
304
 
 
305
        if ( count > 1 )
 
306
        {
 
307
          delta = zone[0].org_ref - zone[1].org_ref;
 
308
          if ( zone->org_delta < delta )
 
309
            zone->org_delta = delta;
 
310
        }
 
311
 
 
312
        zone->org_top    = zone->org_ref;
 
313
        zone->org_bottom = zone->org_delta + zone->org_ref;
 
314
      }
 
315
    }
 
316
 
 
317
    /* expand top and bottom tables with blue fuzz */
 
318
    {
 
319
      FT_Int         dim, top, bot, delta;
 
320
      PSH_Blue_Zone  zone;
 
321
 
 
322
 
 
323
      zone  = top_table->zones;
 
324
      count = count_top;
 
325
 
 
326
      for ( dim = 1; dim >= 0; dim-- )
 
327
      {
 
328
        if ( count > 0 )
 
329
        {
 
330
          /* expand the bottom of the lowest zone normally */
 
331
          zone->org_bottom -= fuzz;
 
332
 
 
333
          /* expand the top and bottom of intermediate zones;    */
 
334
          /* checking that the interval is smaller than the fuzz */
 
335
          top = zone->org_top;
 
336
 
 
337
          for ( count--; count > 0; count-- )
 
338
          {
 
339
            bot   = zone[1].org_bottom;
 
340
            delta = bot - top;
 
341
 
 
342
            if ( delta < 2 * fuzz )
 
343
              zone[0].org_top = zone[1].org_bottom = top + delta / 2;
 
344
            else
 
345
            {
 
346
              zone[0].org_top    = top + fuzz;
 
347
              zone[1].org_bottom = bot - fuzz;
 
348
            }
 
349
 
 
350
            zone++;
 
351
            top = zone->org_top;
 
352
          }
 
353
 
 
354
          /* expand the top of the highest zone normally */
 
355
          zone->org_top = top + fuzz;
 
356
        }
 
357
        zone  = bot_table->zones;
 
358
        count = count_bot;
 
359
      }
 
360
    }
 
361
  }
 
362
 
 
363
 
 
364
  /* reset the blues table when the device transform changes */
 
365
  static void
 
366
  psh_blues_scale_zones( PSH_Blues  blues,
 
367
                         FT_Fixed   scale,
 
368
                         FT_Pos     delta )
 
369
  {
 
370
    FT_UInt         count;
 
371
    FT_UInt         num;
 
372
    PSH_Blue_Table  table = 0;
 
373
 
 
374
    /*                                                        */
 
375
    /* Determine whether we need to suppress overshoots or    */
 
376
    /* not.  We simply need to compare the vertical scale     */
 
377
    /* parameter to the raw bluescale value.  Here is why:    */
 
378
    /*                                                        */
 
379
    /*   We need to suppress overshoots for all pointsizes.   */
 
380
    /*   At 300dpi that satisfies:                            */
 
381
    /*                                                        */
 
382
    /*      pointsize < 240*bluescale + 0.49                  */
 
383
    /*                                                        */
 
384
    /*   This corresponds to:                                 */
 
385
    /*                                                        */
 
386
    /*      pixelsize < 1000*bluescale + 49/24                */
 
387
    /*                                                        */
 
388
    /*      scale*EM_Size < 1000*bluescale + 49/24            */
 
389
    /*                                                        */
 
390
    /*   However, for normal Type 1 fonts, EM_Size is 1000!   */
 
391
    /*   We thus only check:                                  */
 
392
    /*                                                        */
 
393
    /*      scale < bluescale + 49/24000                      */
 
394
    /*                                                        */
 
395
    /*   which we shorten to                                  */
 
396
    /*                                                        */
 
397
    /*      "scale < bluescale"                               */
 
398
    /*                                                        */
 
399
    /* Note that `blue_scale' is stored 1000 times its real   */
 
400
    /* value, and that `scale' converts from font units to    */
 
401
    /* fractional pixels.                                     */
 
402
    /*                                                        */
 
403
 
 
404
    /* 1000 / 64 = 125 / 8 */
 
405
    if ( scale >= 0x20C49BAL )
 
406
      blues->no_overshoots = FT_BOOL( scale < blues->blue_scale * 8 / 125 );
 
407
    else
 
408
      blues->no_overshoots = FT_BOOL( scale * 125 < blues->blue_scale * 8 );
 
409
 
 
410
    /*                                                        */
 
411
    /*  The blue threshold is the font units distance under   */
 
412
    /*  which overshoots are suppressed due to the BlueShift  */
 
413
    /*  even if the scale is greater than BlueScale.          */
 
414
    /*                                                        */
 
415
    /*  It is the smallest distance such that                 */
 
416
    /*                                                        */
 
417
    /*    dist <= BlueShift && dist*scale <= 0.5 pixels       */
 
418
    /*                                                        */
 
419
    {
 
420
      FT_Int  threshold = blues->blue_shift;
 
421
 
 
422
 
 
423
      while ( threshold > 0 && FT_MulFix( threshold, scale ) > 32 )
 
424
        threshold--;
 
425
 
 
426
      blues->blue_threshold = threshold;
 
427
    }
 
428
 
 
429
    for ( num = 0; num < 4; num++ )
 
430
    {
 
431
      PSH_Blue_Zone  zone;
 
432
 
 
433
 
 
434
      switch ( num )
 
435
      {
 
436
      case 0:
 
437
        table = &blues->normal_top;
 
438
        break;
 
439
      case 1:
 
440
        table = &blues->normal_bottom;
 
441
        break;
 
442
      case 2:
 
443
        table = &blues->family_top;
 
444
        break;
 
445
      default:
 
446
        table = &blues->family_bottom;
 
447
        break;
 
448
      }
 
449
 
 
450
      zone  = table->zones;
 
451
      count = table->count;
 
452
      for ( ; count > 0; count--, zone++ )
 
453
      {
 
454
        zone->cur_top    = FT_MulFix( zone->org_top,    scale ) + delta;
 
455
        zone->cur_bottom = FT_MulFix( zone->org_bottom, scale ) + delta;
 
456
        zone->cur_ref    = FT_MulFix( zone->org_ref,    scale ) + delta;
 
457
        zone->cur_delta  = FT_MulFix( zone->org_delta,  scale );
 
458
 
 
459
        /* round scaled reference position */
 
460
        zone->cur_ref = FT_PIX_ROUND( zone->cur_ref );
 
461
 
 
462
#if 0
 
463
        if ( zone->cur_ref > zone->cur_top )
 
464
          zone->cur_ref -= 64;
 
465
        else if ( zone->cur_ref < zone->cur_bottom )
 
466
          zone->cur_ref += 64;
 
467
#endif
 
468
      }
 
469
    }
 
470
 
 
471
    /* process the families now */
 
472
 
 
473
    for ( num = 0; num < 2; num++ )
 
474
    {
 
475
      PSH_Blue_Zone   zone1, zone2;
 
476
      FT_UInt         count1, count2;
 
477
      PSH_Blue_Table  normal, family;
 
478
 
 
479
 
 
480
      switch ( num )
 
481
      {
 
482
      case 0:
 
483
        normal = &blues->normal_top;
 
484
        family = &blues->family_top;
 
485
        break;
 
486
 
 
487
      default:
 
488
        normal = &blues->normal_bottom;
 
489
        family = &blues->family_bottom;
 
490
      }
 
491
 
 
492
      zone1  = normal->zones;
 
493
      count1 = normal->count;
 
494
 
 
495
      for ( ; count1 > 0; count1--, zone1++ )
 
496
      {
 
497
        /* try to find a family zone whose reference position is less */
 
498
        /* than 1 pixel far from the current zone                     */
 
499
        zone2  = family->zones;
 
500
        count2 = family->count;
 
501
 
 
502
        for ( ; count2 > 0; count2--, zone2++ )
 
503
        {
 
504
          FT_Pos  Delta;
 
505
 
 
506
 
 
507
          Delta = zone1->org_ref - zone2->org_ref;
 
508
          if ( Delta < 0 )
 
509
            Delta = -Delta;
 
510
 
 
511
          if ( FT_MulFix( Delta, scale ) < 64 )
 
512
          {
 
513
            zone1->cur_top    = zone2->cur_top;
 
514
            zone1->cur_bottom = zone2->cur_bottom;
 
515
            zone1->cur_ref    = zone2->cur_ref;
 
516
            zone1->cur_delta  = zone2->cur_delta;
 
517
            break;
 
518
          }
 
519
        }
 
520
      }
 
521
    }
 
522
  }
 
523
 
 
524
 
 
525
  FT_LOCAL_DEF( void )
 
526
  psh_blues_snap_stem( PSH_Blues      blues,
 
527
                       FT_Int         stem_top,
 
528
                       FT_Int         stem_bot,
 
529
                       PSH_Alignment  alignment )
 
530
  {
 
531
    PSH_Blue_Table  table;
 
532
    FT_UInt         count;
 
533
    FT_Pos          delta;
 
534
    PSH_Blue_Zone   zone;
 
535
    FT_Int          no_shoots;
 
536
 
 
537
 
 
538
    alignment->align = PSH_BLUE_ALIGN_NONE;
 
539
 
 
540
    no_shoots = blues->no_overshoots;
 
541
 
 
542
    /* look up stem top in top zones table */
 
543
    table = &blues->normal_top;
 
544
    count = table->count;
 
545
    zone  = table->zones;
 
546
 
 
547
    for ( ; count > 0; count--, zone++ )
 
548
    {
 
549
      delta = stem_top - zone->org_bottom;
 
550
      if ( delta < -blues->blue_fuzz )
 
551
        break;
 
552
 
 
553
      if ( stem_top <= zone->org_top + blues->blue_fuzz )
 
554
      {
 
555
        if ( no_shoots || delta <= blues->blue_threshold )
 
556
        {
 
557
          alignment->align    |= PSH_BLUE_ALIGN_TOP;
 
558
          alignment->align_top = zone->cur_ref;
 
559
        }
 
560
        break;
 
561
      }
 
562
    }
 
563
 
 
564
    /* look up stem bottom in bottom zones table */
 
565
    table = &blues->normal_bottom;
 
566
    count = table->count;
 
567
    zone  = table->zones + count-1;
 
568
 
 
569
    for ( ; count > 0; count--, zone-- )
 
570
    {
 
571
      delta = zone->org_top - stem_bot;
 
572
      if ( delta < -blues->blue_fuzz )
 
573
        break;
 
574
 
 
575
      if ( stem_bot >= zone->org_bottom - blues->blue_fuzz )
 
576
      {
 
577
        if ( no_shoots || delta < blues->blue_threshold )
 
578
        {
 
579
          alignment->align    |= PSH_BLUE_ALIGN_BOT;
 
580
          alignment->align_bot = zone->cur_ref;
 
581
        }
 
582
        break;
 
583
      }
 
584
    }
 
585
  }
 
586
 
 
587
 
 
588
  /*************************************************************************/
 
589
  /*************************************************************************/
 
590
  /*****                                                               *****/
 
591
  /*****                        GLOBAL HINTS                           *****/
 
592
  /*****                                                               *****/
 
593
  /*************************************************************************/
 
594
  /*************************************************************************/
 
595
 
 
596
  static void
 
597
  psh_globals_destroy( PSH_Globals  globals )
 
598
  {
 
599
    if ( globals )
 
600
    {
 
601
      FT_Memory  memory;
 
602
 
 
603
 
 
604
      memory = globals->memory;
 
605
      globals->dimension[0].stdw.count = 0;
 
606
      globals->dimension[1].stdw.count = 0;
 
607
 
 
608
      globals->blues.normal_top.count    = 0;
 
609
      globals->blues.normal_bottom.count = 0;
 
610
      globals->blues.family_top.count    = 0;
 
611
      globals->blues.family_bottom.count = 0;
 
612
 
 
613
      FT_FREE( globals );
 
614
 
 
615
#ifdef DEBUG_HINTER
 
616
      ps_debug_globals = 0;
 
617
#endif
 
618
    }
 
619
  }
 
620
 
 
621
 
 
622
  static FT_Error
 
623
  psh_globals_new( FT_Memory     memory,
 
624
                   T1_Private*   priv,
 
625
                   PSH_Globals  *aglobals )
 
626
  {
 
627
    PSH_Globals  globals = NULL;
 
628
    FT_Error     error;
 
629
 
 
630
 
 
631
    if ( !FT_NEW( globals ) )
 
632
    {
 
633
      FT_UInt    count;
 
634
      FT_Short*  read;
 
635
 
 
636
 
 
637
      globals->memory = memory;
 
638
 
 
639
      /* copy standard widths */
 
640
      {
 
641
        PSH_Dimension  dim   = &globals->dimension[1];
 
642
        PSH_Width      write = dim->stdw.widths;
 
643
 
 
644
 
 
645
        write->org = priv->standard_width[0];
 
646
        write++;
 
647
 
 
648
        read = priv->snap_widths;
 
649
        for ( count = priv->num_snap_widths; count > 0; count-- )
 
650
        {
 
651
          write->org = *read;
 
652
          write++;
 
653
          read++;
 
654
        }
 
655
 
 
656
        dim->stdw.count = priv->num_snap_widths + 1;
 
657
      }
 
658
 
 
659
      /* copy standard heights */
 
660
      {
 
661
        PSH_Dimension  dim = &globals->dimension[0];
 
662
        PSH_Width      write = dim->stdw.widths;
 
663
 
 
664
 
 
665
        write->org = priv->standard_height[0];
 
666
        write++;
 
667
        read = priv->snap_heights;
 
668
        for ( count = priv->num_snap_heights; count > 0; count-- )
 
669
        {
 
670
          write->org = *read;
 
671
          write++;
 
672
          read++;
 
673
        }
 
674
 
 
675
        dim->stdw.count = priv->num_snap_heights + 1;
 
676
      }
 
677
 
 
678
      /* copy blue zones */
 
679
      psh_blues_set_zones( &globals->blues, priv->num_blue_values,
 
680
                           priv->blue_values, priv->num_other_blues,
 
681
                           priv->other_blues, priv->blue_fuzz, 0 );
 
682
 
 
683
      psh_blues_set_zones( &globals->blues, priv->num_family_blues,
 
684
                           priv->family_blues, priv->num_family_other_blues,
 
685
                           priv->family_other_blues, priv->blue_fuzz, 1 );
 
686
 
 
687
      globals->blues.blue_scale = priv->blue_scale;
 
688
      globals->blues.blue_shift = priv->blue_shift;
 
689
      globals->blues.blue_fuzz  = priv->blue_fuzz;
 
690
 
 
691
      globals->dimension[0].scale_mult  = 0;
 
692
      globals->dimension[0].scale_delta = 0;
 
693
      globals->dimension[1].scale_mult  = 0;
 
694
      globals->dimension[1].scale_delta = 0;
 
695
 
 
696
#ifdef DEBUG_HINTER
 
697
      ps_debug_globals = globals;
 
698
#endif
 
699
    }
 
700
 
 
701
    *aglobals = globals;
 
702
    return error;
 
703
  }
 
704
 
 
705
 
 
706
  FT_LOCAL_DEF( FT_Error )
 
707
  psh_globals_set_scale( PSH_Globals  globals,
 
708
                         FT_Fixed     x_scale,
 
709
                         FT_Fixed     y_scale,
 
710
                         FT_Fixed     x_delta,
 
711
                         FT_Fixed     y_delta )
 
712
  {
 
713
    PSH_Dimension  dim = &globals->dimension[0];
 
714
 
 
715
 
 
716
    dim = &globals->dimension[0];
 
717
    if ( x_scale != dim->scale_mult  ||
 
718
         x_delta != dim->scale_delta )
 
719
    {
 
720
      dim->scale_mult  = x_scale;
 
721
      dim->scale_delta = x_delta;
 
722
 
 
723
      psh_globals_scale_widths( globals, 0 );
 
724
    }
 
725
 
 
726
    dim = &globals->dimension[1];
 
727
    if ( y_scale != dim->scale_mult  ||
 
728
         y_delta != dim->scale_delta )
 
729
    {
 
730
      dim->scale_mult  = y_scale;
 
731
      dim->scale_delta = y_delta;
 
732
 
 
733
      psh_globals_scale_widths( globals, 1 );
 
734
      psh_blues_scale_zones( &globals->blues, y_scale, y_delta );
 
735
    }
 
736
 
 
737
    return 0;
 
738
  }
 
739
 
 
740
 
 
741
  FT_LOCAL_DEF( void )
 
742
  psh_globals_funcs_init( PSH_Globals_FuncsRec*  funcs )
 
743
  {
 
744
    funcs->create    = psh_globals_new;
 
745
    funcs->set_scale = psh_globals_set_scale;
 
746
    funcs->destroy   = psh_globals_destroy;
 
747
  }
 
748
 
 
749
 
 
750
/* END */