Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  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-2004, 2006, 2010, 2012 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.   /* calculate the maximum height of given blue zones */
  526.   static FT_Short
  527.   psh_calc_max_height( FT_UInt          num,
  528.                        const FT_Short*  values,
  529.                        FT_Short         cur_max )
  530.   {
  531.     FT_UInt  count;
  532.  
  533.  
  534.     for ( count = 0; count < num; count += 2 )
  535.     {
  536.       FT_Short  cur_height = values[count + 1] - values[count];
  537.  
  538.  
  539.       if ( cur_height > cur_max )
  540.         cur_max = cur_height;
  541.     }
  542.  
  543.     return cur_max;
  544.   }
  545.  
  546.  
  547.   FT_LOCAL_DEF( void )
  548.   psh_blues_snap_stem( PSH_Blues      blues,
  549.                        FT_Int         stem_top,
  550.                        FT_Int         stem_bot,
  551.                        PSH_Alignment  alignment )
  552.   {
  553.     PSH_Blue_Table  table;
  554.     FT_UInt         count;
  555.     FT_Pos          delta;
  556.     PSH_Blue_Zone   zone;
  557.     FT_Int          no_shoots;
  558.  
  559.  
  560.     alignment->align = PSH_BLUE_ALIGN_NONE;
  561.  
  562.     no_shoots = blues->no_overshoots;
  563.  
  564.     /* look up stem top in top zones table */
  565.     table = &blues->normal_top;
  566.     count = table->count;
  567.     zone  = table->zones;
  568.  
  569.     for ( ; count > 0; count--, zone++ )
  570.     {
  571.       delta = stem_top - zone->org_bottom;
  572.       if ( delta < -blues->blue_fuzz )
  573.         break;
  574.  
  575.       if ( stem_top <= zone->org_top + blues->blue_fuzz )
  576.       {
  577.         if ( no_shoots || delta <= blues->blue_threshold )
  578.         {
  579.           alignment->align    |= PSH_BLUE_ALIGN_TOP;
  580.           alignment->align_top = zone->cur_ref;
  581.         }
  582.         break;
  583.       }
  584.     }
  585.  
  586.     /* look up stem bottom in bottom zones table */
  587.     table = &blues->normal_bottom;
  588.     count = table->count;
  589.     zone  = table->zones + count-1;
  590.  
  591.     for ( ; count > 0; count--, zone-- )
  592.     {
  593.       delta = zone->org_top - stem_bot;
  594.       if ( delta < -blues->blue_fuzz )
  595.         break;
  596.  
  597.       if ( stem_bot >= zone->org_bottom - blues->blue_fuzz )
  598.       {
  599.         if ( no_shoots || delta < blues->blue_threshold )
  600.         {
  601.           alignment->align    |= PSH_BLUE_ALIGN_BOT;
  602.           alignment->align_bot = zone->cur_ref;
  603.         }
  604.         break;
  605.       }
  606.     }
  607.   }
  608.  
  609.  
  610.   /*************************************************************************/
  611.   /*************************************************************************/
  612.   /*****                                                               *****/
  613.   /*****                        GLOBAL HINTS                           *****/
  614.   /*****                                                               *****/
  615.   /*************************************************************************/
  616.   /*************************************************************************/
  617.  
  618.   static void
  619.   psh_globals_destroy( PSH_Globals  globals )
  620.   {
  621.     if ( globals )
  622.     {
  623.       FT_Memory  memory;
  624.  
  625.  
  626.       memory = globals->memory;
  627.       globals->dimension[0].stdw.count = 0;
  628.       globals->dimension[1].stdw.count = 0;
  629.  
  630.       globals->blues.normal_top.count    = 0;
  631.       globals->blues.normal_bottom.count = 0;
  632.       globals->blues.family_top.count    = 0;
  633.       globals->blues.family_bottom.count = 0;
  634.  
  635.       FT_FREE( globals );
  636.  
  637. #ifdef DEBUG_HINTER
  638.       ps_debug_globals = 0;
  639. #endif
  640.     }
  641.   }
  642.  
  643.  
  644.   static FT_Error
  645.   psh_globals_new( FT_Memory     memory,
  646.                    T1_Private*   priv,
  647.                    PSH_Globals  *aglobals )
  648.   {
  649.     PSH_Globals  globals = NULL;
  650.     FT_Error     error;
  651.  
  652.  
  653.     if ( !FT_NEW( globals ) )
  654.     {
  655.       FT_UInt    count;
  656.       FT_Short*  read;
  657.  
  658.  
  659.       globals->memory = memory;
  660.  
  661.       /* copy standard widths */
  662.       {
  663.         PSH_Dimension  dim   = &globals->dimension[1];
  664.         PSH_Width      write = dim->stdw.widths;
  665.  
  666.  
  667.         write->org = priv->standard_width[0];
  668.         write++;
  669.  
  670.         read = priv->snap_widths;
  671.         for ( count = priv->num_snap_widths; count > 0; count-- )
  672.         {
  673.           write->org = *read;
  674.           write++;
  675.           read++;
  676.         }
  677.  
  678.         dim->stdw.count = priv->num_snap_widths + 1;
  679.       }
  680.  
  681.       /* copy standard heights */
  682.       {
  683.         PSH_Dimension  dim = &globals->dimension[0];
  684.         PSH_Width      write = dim->stdw.widths;
  685.  
  686.  
  687.         write->org = priv->standard_height[0];
  688.         write++;
  689.         read = priv->snap_heights;
  690.         for ( count = priv->num_snap_heights; count > 0; count-- )
  691.         {
  692.           write->org = *read;
  693.           write++;
  694.           read++;
  695.         }
  696.  
  697.         dim->stdw.count = priv->num_snap_heights + 1;
  698.       }
  699.  
  700.       /* copy blue zones */
  701.       psh_blues_set_zones( &globals->blues, priv->num_blue_values,
  702.                            priv->blue_values, priv->num_other_blues,
  703.                            priv->other_blues, priv->blue_fuzz, 0 );
  704.  
  705.       psh_blues_set_zones( &globals->blues, priv->num_family_blues,
  706.                            priv->family_blues, priv->num_family_other_blues,
  707.                            priv->family_other_blues, priv->blue_fuzz, 1 );
  708.  
  709.       /* limit the BlueScale value to `1 / max_of_blue_zone_heights' */
  710.       {
  711.         FT_Fixed  max_scale;
  712.         FT_Short  max_height = 1;
  713.  
  714.  
  715.         max_height = psh_calc_max_height( priv->num_blue_values,
  716.                                           priv->blue_values,
  717.                                           max_height );
  718.         max_height = psh_calc_max_height( priv->num_other_blues,
  719.                                           priv->other_blues,
  720.                                           max_height );
  721.         max_height = psh_calc_max_height( priv->num_family_blues,
  722.                                           priv->family_blues,
  723.                                           max_height );
  724.         max_height = psh_calc_max_height( priv->num_family_other_blues,
  725.                                           priv->family_other_blues,
  726.                                           max_height );
  727.  
  728.         /* BlueScale is scaled 1000 times */
  729.         max_scale = FT_DivFix( 1000, max_height );
  730.         globals->blues.blue_scale = priv->blue_scale < max_scale
  731.                                       ? priv->blue_scale
  732.                                       : max_scale;
  733.       }
  734.  
  735.       globals->blues.blue_shift = priv->blue_shift;
  736.       globals->blues.blue_fuzz  = priv->blue_fuzz;
  737.  
  738.       globals->dimension[0].scale_mult  = 0;
  739.       globals->dimension[0].scale_delta = 0;
  740.       globals->dimension[1].scale_mult  = 0;
  741.       globals->dimension[1].scale_delta = 0;
  742.  
  743. #ifdef DEBUG_HINTER
  744.       ps_debug_globals = globals;
  745. #endif
  746.     }
  747.  
  748.     *aglobals = globals;
  749.     return error;
  750.   }
  751.  
  752.  
  753.   FT_LOCAL_DEF( FT_Error )
  754.   psh_globals_set_scale( PSH_Globals  globals,
  755.                          FT_Fixed     x_scale,
  756.                          FT_Fixed     y_scale,
  757.                          FT_Fixed     x_delta,
  758.                          FT_Fixed     y_delta )
  759.   {
  760.     PSH_Dimension  dim = &globals->dimension[0];
  761.  
  762.  
  763.     dim = &globals->dimension[0];
  764.     if ( x_scale != dim->scale_mult  ||
  765.          x_delta != dim->scale_delta )
  766.     {
  767.       dim->scale_mult  = x_scale;
  768.       dim->scale_delta = x_delta;
  769.  
  770.       psh_globals_scale_widths( globals, 0 );
  771.     }
  772.  
  773.     dim = &globals->dimension[1];
  774.     if ( y_scale != dim->scale_mult  ||
  775.          y_delta != dim->scale_delta )
  776.     {
  777.       dim->scale_mult  = y_scale;
  778.       dim->scale_delta = y_delta;
  779.  
  780.       psh_globals_scale_widths( globals, 1 );
  781.       psh_blues_scale_zones( &globals->blues, y_scale, y_delta );
  782.     }
  783.  
  784.     return 0;
  785.   }
  786.  
  787.  
  788.   FT_LOCAL_DEF( void )
  789.   psh_globals_funcs_init( PSH_Globals_FuncsRec*  funcs )
  790.   {
  791.     funcs->create    = psh_globals_new;
  792.     funcs->set_scale = psh_globals_set_scale;
  793.     funcs->destroy   = psh_globals_destroy;
  794.   }
  795.  
  796.  
  797. /* END */
  798.