~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/freetype/src/pshinter/pshglob.c

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

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 */