src/java.desktop/share/native/libfreetype/src/autofit/aflatin.c
changeset 54876 da3834261f0c
parent 49234 3375a8039fde
equal deleted inserted replaced
54875:bcfedddcf4ce 54876:da3834261f0c
     1 /***************************************************************************/
     1 /****************************************************************************
     2 /*                                                                         */
     2  *
     3 /*  aflatin.c                                                              */
     3  * aflatin.c
     4 /*                                                                         */
     4  *
     5 /*    Auto-fitter hinting routines for latin writing system (body).        */
     5  *   Auto-fitter hinting routines for latin writing system (body).
     6 /*                                                                         */
     6  *
     7 /*  Copyright 2003-2018 by                                                 */
     7  * Copyright (C) 2003-2019 by
     8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
     8  * David Turner, Robert Wilhelm, and Werner Lemberg.
     9 /*                                                                         */
     9  *
    10 /*  This file is part of the FreeType project, and may only be used,       */
    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      */
    11  * modified, and distributed under the terms of the FreeType project
    12 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
    12  * license, LICENSE.TXT.  By continuing to use, modify, or distribute
    13 /*  this file you indicate that you have read the license and              */
    13  * this file you indicate that you have read the license and
    14 /*  understand and accept it fully.                                        */
    14  * understand and accept it fully.
    15 /*                                                                         */
    15  *
    16 /***************************************************************************/
    16  */
    17 
    17 
    18 
    18 
    19 #include <ft2build.h>
    19 #include <ft2build.h>
    20 #include FT_ADVANCES_H
    20 #include FT_ADVANCES_H
    21 #include FT_INTERNAL_DEBUG_H
    21 #include FT_INTERNAL_DEBUG_H
    22 
    22 
    23 #include "afglobal.h"
    23 #include "afglobal.h"
    24 #include "afpic.h"
       
    25 #include "aflatin.h"
    24 #include "aflatin.h"
    26 #include "aferrors.h"
    25 #include "aferrors.h"
    27 
    26 
    28 
    27 
    29 #ifdef AF_CONFIG_OPTION_USE_WARPER
    28 #ifdef AF_CONFIG_OPTION_USE_WARPER
    30 #include "afwarp.h"
    29 #include "afwarp.h"
    31 #endif
    30 #endif
    32 
    31 
    33 
    32 
    34   /*************************************************************************/
    33   /**************************************************************************
    35   /*                                                                       */
    34    *
    36   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
    35    * The macro FT_COMPONENT is used in trace mode.  It is an implicit
    37   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
    36    * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
    38   /* messages during execution.                                            */
    37    * messages during execution.
    39   /*                                                                       */
    38    */
    40 #undef  FT_COMPONENT
    39 #undef  FT_COMPONENT
    41 #define FT_COMPONENT  trace_aflatin
    40 #define FT_COMPONENT  aflatin
    42 
    41 
    43 
    42 
    44   /* needed for computation of round vs. flat segments */
    43   /* needed for computation of round vs. flat segments */
    45 #define FLAT_THRESHOLD( x )  ( x / 14 )
    44 #define FLAT_THRESHOLD( x )  ( x / 14 )
    46 
    45 
    81       FT_ULong            glyph_index;
    80       FT_ULong            glyph_index;
    82       int                 dim;
    81       int                 dim;
    83       AF_LatinMetricsRec  dummy[1];
    82       AF_LatinMetricsRec  dummy[1];
    84       AF_Scaler           scaler = &dummy->root.scaler;
    83       AF_Scaler           scaler = &dummy->root.scaler;
    85 
    84 
    86 #ifdef FT_CONFIG_OPTION_PIC
       
    87       AF_FaceGlobals  globals = metrics->root.globals;
       
    88 #endif
       
    89 
       
    90       AF_StyleClass   style_class  = metrics->root.style_class;
    85       AF_StyleClass   style_class  = metrics->root.style_class;
    91       AF_ScriptClass  script_class = AF_SCRIPT_CLASSES_GET
    86       AF_ScriptClass  script_class = af_script_classes[style_class->script];
    92                                        [style_class->script];
    87 
    93 
    88       /* If HarfBuzz is not available, we need a pointer to a single */
    94       void*        shaper_buf;
    89       /* unsigned long value.                                        */
       
    90 #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
       
    91       void*     shaper_buf;
       
    92 #else
       
    93       FT_ULong  shaper_buf_;
       
    94       void*     shaper_buf = &shaper_buf_;
       
    95 #endif
       
    96 
    95       const char*  p;
    97       const char*  p;
    96 
    98 
    97 #ifdef FT_DEBUG_LEVEL_TRACE
    99 #ifdef FT_DEBUG_LEVEL_TRACE
    98       FT_ULong  ch = 0;
   100       FT_ULong  ch = 0;
    99 #endif
   101 #endif
   100 
   102 
   101       p          = script_class->standard_charstring;
   103 
       
   104       p = script_class->standard_charstring;
       
   105 
       
   106 #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
   102       shaper_buf = af_shaper_buf_create( face );
   107       shaper_buf = af_shaper_buf_create( face );
   103 
   108 #endif
   104       /*
   109       /*
   105        * We check a list of standard characters to catch features like
   110        * We check a list of standard characters to catch features like
   106        * `c2sc' (small caps from caps) that don't contain lowercase letters
   111        * `c2sc' (small caps from caps) that don't contain lowercase letters
   107        * by definition, or other features that mainly operate on numerals.
   112        * by definition, or other features that mainly operate on numerals.
   108        * The first match wins.
   113        * The first match wins.
   184                                                  (AF_Dimension)dim );
   189                                                  (AF_Dimension)dim );
   185         if ( error )
   190         if ( error )
   186           goto Exit;
   191           goto Exit;
   187 
   192 
   188         /*
   193         /*
   189          *  We assume that the glyphs selected for the stem width
   194          * We assume that the glyphs selected for the stem width
   190          *  computation are `featureless' enough so that the linking
   195          * computation are `featureless' enough so that the linking
   191          *  algorithm works fine without adjustments of its scoring
   196          * algorithm works fine without adjustments of its scoring
   192          *  function.
   197          * function.
   193          */
   198          */
   194         af_latin_hints_link_segments( hints,
   199         af_latin_hints_link_segments( hints,
   195                                       0,
   200                                       0,
   196                                       NULL,
   201                                       NULL,
   197                                       (AF_Dimension)dim );
   202                                       (AF_Dimension)dim );
   327     AF_Blue_Stringset         bss = sc->blue_stringset;
   332     AF_Blue_Stringset         bss = sc->blue_stringset;
   328     const AF_Blue_StringRec*  bs  = &af_blue_stringsets[bss];
   333     const AF_Blue_StringRec*  bs  = &af_blue_stringsets[bss];
   329 
   334 
   330     FT_Pos  flat_threshold = FLAT_THRESHOLD( metrics->units_per_em );
   335     FT_Pos  flat_threshold = FLAT_THRESHOLD( metrics->units_per_em );
   331 
   336 
   332     void*  shaper_buf;
   337     /* If HarfBuzz is not available, we need a pointer to a single */
       
   338     /* unsigned long value.                                        */
       
   339 #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
       
   340     void*     shaper_buf;
       
   341 #else
       
   342     FT_ULong  shaper_buf_;
       
   343     void*     shaper_buf = &shaper_buf_;
       
   344 #endif
   333 
   345 
   334 
   346 
   335     /* we walk over the blue character strings as specified in the */
   347     /* we walk over the blue character strings as specified in the */
   336     /* style's entry in the `af_blue_stringset' array              */
   348     /* style's entry in the `af_blue_stringset' array              */
   337 
   349 
   338     FT_TRACE5(( "latin blue zones computation\n"
   350     FT_TRACE5(( "latin blue zones computation\n"
   339                 "============================\n"
   351                 "============================\n"
   340                 "\n" ));
   352                 "\n" ));
   341 
   353 
       
   354 #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
   342     shaper_buf = af_shaper_buf_create( face );
   355     shaper_buf = af_shaper_buf_create( face );
       
   356 #endif
   343 
   357 
   344     for ( ; bs->string != AF_BLUE_STRING_MAX; bs++ )
   358     for ( ; bs->string != AF_BLUE_STRING_MAX; bs++ )
   345     {
   359     {
   346       const char*  p = &af_blue_strings[bs->string];
   360       const char*  p = &af_blue_strings[bs->string];
   347       FT_Pos*      blue_ref;
   361       FT_Pos*      blue_ref;
   882       } /* end while loop */
   896       } /* end while loop */
   883 
   897 
   884       if ( num_flats == 0 && num_rounds == 0 )
   898       if ( num_flats == 0 && num_rounds == 0 )
   885       {
   899       {
   886         /*
   900         /*
   887          *  we couldn't find a single glyph to compute this blue zone,
   901          * we couldn't find a single glyph to compute this blue zone,
   888          *  we will simply ignore it then
   902          * we will simply ignore it then
   889          */
   903          */
   890         FT_TRACE5(( "  empty\n" ));
   904         FT_TRACE5(( "  empty\n" ));
   891         continue;
   905         continue;
   892       }
   906       }
   893 
   907 
  1034                                  FT_Face          face )
  1048                                  FT_Face          face )
  1035   {
  1049   {
  1036     FT_Bool   started = 0, same_width = 1;
  1050     FT_Bool   started = 0, same_width = 1;
  1037     FT_Fixed  advance = 0, old_advance = 0;
  1051     FT_Fixed  advance = 0, old_advance = 0;
  1038 
  1052 
  1039     void*  shaper_buf;
  1053     /* If HarfBuzz is not available, we need a pointer to a single */
       
  1054     /* unsigned long value.                                        */
       
  1055 #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
       
  1056     void*     shaper_buf;
       
  1057 #else
       
  1058     FT_ULong  shaper_buf_;
       
  1059     void*     shaper_buf = &shaper_buf_;
       
  1060 #endif
  1040 
  1061 
  1041     /* in all supported charmaps, digits have character codes 0x30-0x39 */
  1062     /* in all supported charmaps, digits have character codes 0x30-0x39 */
  1042     const char   digits[] = "0 1 2 3 4 5 6 7 8 9";
  1063     const char   digits[] = "0 1 2 3 4 5 6 7 8 9";
  1043     const char*  p;
  1064     const char*  p;
  1044 
  1065 
  1045 
  1066 
  1046     p          = digits;
  1067     p = digits;
       
  1068 
       
  1069 #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
  1047     shaper_buf = af_shaper_buf_create( face );
  1070     shaper_buf = af_shaper_buf_create( face );
       
  1071 #endif
  1048 
  1072 
  1049     while ( *p )
  1073     while ( *p )
  1050     {
  1074     {
  1051       FT_ULong      glyph_index;
  1075       FT_ULong      glyph_index;
  1052       unsigned int  num_idx;
  1076       unsigned int  num_idx;
  1281     FT_TRACE5(( "\n" ));
  1305     FT_TRACE5(( "\n" ));
  1282 
  1306 
  1283     /* an extra-light axis corresponds to a standard width that is */
  1307     /* an extra-light axis corresponds to a standard width that is */
  1284     /* smaller than 5/8 pixels                                     */
  1308     /* smaller than 5/8 pixels                                     */
  1285     axis->extra_light =
  1309     axis->extra_light =
  1286       (FT_Bool)( FT_MulFix( axis->standard_width, scale ) < 32 + 8 );
  1310       FT_BOOL( FT_MulFix( axis->standard_width, scale ) < 32 + 8 );
  1287 
  1311 
  1288 #ifdef FT_DEBUG_LEVEL_TRACE
  1312 #ifdef FT_DEBUG_LEVEL_TRACE
  1289     if ( axis->extra_light )
  1313     if ( axis->extra_light )
  1290       FT_TRACE5(( "`%s' style is extra light (at current resolution)\n"
  1314       FT_TRACE5(( "`%s' style is extra light (at current resolution)\n"
  1291                   "\n",
  1315                   "\n",
  1965           /* (this is, how much they overlap)                          */
  1989           /* (this is, how much they overlap)                          */
  1966           len = max - min;
  1990           len = max - min;
  1967           if ( len >= len_threshold )
  1991           if ( len >= len_threshold )
  1968           {
  1992           {
  1969             /*
  1993             /*
  1970              *  The score is the sum of two demerits indicating the
  1994              * The score is the sum of two demerits indicating the
  1971              *  `badness' of a fit, measured along the segments' main axis
  1995              * `badness' of a fit, measured along the segments' main axis
  1972              *  and orthogonal to it, respectively.
  1996              * and orthogonal to it, respectively.
  1973              *
  1997              *
  1974              *  o The less overlapping along the main axis, the worse it
  1998              * - The less overlapping along the main axis, the worse it
  1975              *    is, causing a larger demerit.
  1999              *   is, causing a larger demerit.
  1976              *
  2000              *
  1977              *  o The nearer the orthogonal distance to a stem width, the
  2001              * - The nearer the orthogonal distance to a stem width, the
  1978              *    better it is, causing a smaller demerit.  For simplicity,
  2002              *   better it is, causing a smaller demerit.  For simplicity,
  1979              *    however, we only increase the demerit for values that
  2003              *   however, we only increase the demerit for values that
  1980              *    exceed the largest stem width.
  2004              *   exceed the largest stem width.
  1981              */
  2005              */
  1982 
  2006 
  1983             FT_Pos  dist = pos2 - pos1;
  2007             FT_Pos  dist = pos2 - pos1;
  1984 
  2008 
  1985             FT_Pos  dist_demerit, score;
  2009             FT_Pos  dist_demerit, score;
  2047     AF_AxisHints  axis   = &hints->axis[dim];
  2071     AF_AxisHints  axis   = &hints->axis[dim];
  2048     FT_Error      error  = FT_Err_Ok;
  2072     FT_Error      error  = FT_Err_Ok;
  2049     FT_Memory     memory = hints->memory;
  2073     FT_Memory     memory = hints->memory;
  2050     AF_LatinAxis  laxis  = &((AF_LatinMetrics)hints->metrics)->axis[dim];
  2074     AF_LatinAxis  laxis  = &((AF_LatinMetrics)hints->metrics)->axis[dim];
  2051 
  2075 
  2052 #ifdef FT_CONFIG_OPTION_PIC
       
  2053     AF_FaceGlobals  globals = hints->metrics->globals;
       
  2054 #endif
       
  2055 
       
  2056     AF_StyleClass   style_class  = hints->metrics->style_class;
  2076     AF_StyleClass   style_class  = hints->metrics->style_class;
  2057     AF_ScriptClass  script_class = AF_SCRIPT_CLASSES_GET
  2077     AF_ScriptClass  script_class = af_script_classes[style_class->script];
  2058                                      [style_class->script];
       
  2059 
  2078 
  2060     FT_Bool  top_to_bottom_hinting = 0;
  2079     FT_Bool  top_to_bottom_hinting = 0;
  2061 
  2080 
  2062     AF_Segment    segments      = axis->segments;
  2081     AF_Segment    segments      = axis->segments;
  2063     AF_Segment    segment_limit = segments + axis->num_segments;
  2082     AF_Segment    segment_limit = segments + axis->num_segments;
  2084 
  2103 
  2085     if ( dim == AF_DIMENSION_VERT )
  2104     if ( dim == AF_DIMENSION_VERT )
  2086       top_to_bottom_hinting = script_class->top_to_bottom_hinting;
  2105       top_to_bottom_hinting = script_class->top_to_bottom_hinting;
  2087 
  2106 
  2088     /*
  2107     /*
  2089      *  We ignore all segments that are less than 1 pixel in length
  2108      * We ignore all segments that are less than 1 pixel in length
  2090      *  to avoid many problems with serif fonts.  We compute the
  2109      * to avoid many problems with serif fonts.  We compute the
  2091      *  corresponding threshold in font units.
  2110      * corresponding threshold in font units.
  2092      */
  2111      */
  2093     if ( dim == AF_DIMENSION_HORZ )
  2112     if ( dim == AF_DIMENSION_HORZ )
  2094       segment_length_threshold = FT_DivFix( 64, hints->y_scale );
  2113       segment_length_threshold = FT_DivFix( 64, hints->y_scale );
  2095     else
  2114     else
  2096       segment_length_threshold = 0;
  2115       segment_length_threshold = 0;
  2097 
  2116 
  2098     /*
  2117     /*
  2099      *  Similarly, we ignore segments that have a width delta
  2118      * Similarly, we ignore segments that have a width delta
  2100      *  larger than 0.5px (i.e., a width larger than 1px).
  2119      * larger than 0.5px (i.e., a width larger than 1px).
  2101      */
  2120      */
  2102     segment_width_threshold = FT_DivFix( 32, scale );
  2121     segment_width_threshold = FT_DivFix( 32, scale );
  2103 
  2122 
  2104     /*********************************************************************/
  2123     /**********************************************************************
  2105     /*                                                                   */
  2124      *
  2106     /* We begin by generating a sorted table of edges for the current    */
  2125      * We begin by generating a sorted table of edges for the current
  2107     /* direction.  To do so, we simply scan each segment and try to find */
  2126      * direction.  To do so, we simply scan each segment and try to find
  2108     /* an edge in our table that corresponds to its position.            */
  2127      * an edge in our table that corresponds to its position.
  2109     /*                                                                   */
  2128      *
  2110     /* If no edge is found, we create and insert a new edge in the       */
  2129      * If no edge is found, we create and insert a new edge in the
  2111     /* sorted table.  Otherwise, we simply add the segment to the edge's */
  2130      * sorted table.  Otherwise, we simply add the segment to the edge's
  2112     /* list which gets processed in the second step to compute the       */
  2131      * list which gets processed in the second step to compute the
  2113     /* edge's properties.                                                */
  2132      * edge's properties.
  2114     /*                                                                   */
  2133      *
  2115     /* Note that the table of edges is sorted along the segment/edge     */
  2134      * Note that the table of edges is sorted along the segment/edge
  2116     /* position.                                                         */
  2135      * position.
  2117     /*                                                                   */
  2136      *
  2118     /*********************************************************************/
  2137      */
  2119 
  2138 
  2120     /* assure that edge distance threshold is at most 0.25px */
  2139     /* assure that edge distance threshold is at most 0.25px */
  2121     edge_distance_threshold = FT_MulFix( laxis->edge_distance_threshold,
  2140     edge_distance_threshold = FT_MulFix( laxis->edge_distance_threshold,
  2122                                          scale );
  2141                                          scale );
  2123     if ( edge_distance_threshold > 64 / 4 )
  2142     if ( edge_distance_threshold > 64 / 4 )
  2235         found->last            = seg;
  2254         found->last            = seg;
  2236       }
  2255       }
  2237     }
  2256     }
  2238 
  2257 
  2239 
  2258 
  2240     /******************************************************************/
  2259     /*******************************************************************
  2241     /*                                                                */
  2260      *
  2242     /* Good, we now compute each edge's properties according to the   */
  2261      * Good, we now compute each edge's properties according to the
  2243     /* segments found on its position.  Basically, these are          */
  2262      * segments found on its position.  Basically, these are
  2244     /*                                                                */
  2263      *
  2245     /*  - the edge's main direction                                   */
  2264      * - the edge's main direction
  2246     /*  - stem edge, serif edge or both (which defaults to stem then) */
  2265      * - stem edge, serif edge or both (which defaults to stem then)
  2247     /*  - rounded edge, straight or both (which defaults to straight) */
  2266      * - rounded edge, straight or both (which defaults to straight)
  2248     /*  - link for edge                                               */
  2267      * - link for edge
  2249     /*                                                                */
  2268      *
  2250     /******************************************************************/
  2269      */
  2251 
  2270 
  2252     /* first of all, set the `edge' field in each segment -- this is */
  2271     /* first of all, set the `edge' field in each segment -- this is */
  2253     /* required in order to compute edge links                       */
  2272     /* required in order to compute edge links                       */
  2254 
  2273 
  2255     /*
  2274     /*
  2307             downs += seg->max_coord - seg->min_coord;
  2326             downs += seg->max_coord - seg->min_coord;
  2308 #endif
  2327 #endif
  2309 
  2328 
  2310           /* check for links -- if seg->serif is set, then seg->link must */
  2329           /* check for links -- if seg->serif is set, then seg->link must */
  2311           /* be ignored                                                   */
  2330           /* be ignored                                                   */
  2312           is_serif = (FT_Bool)( seg->serif               &&
  2331           is_serif = FT_BOOL( seg->serif               &&
  2313                                 seg->serif->edge         &&
  2332                               seg->serif->edge         &&
  2314                                 seg->serif->edge != edge );
  2333                               seg->serif->edge != edge );
  2315 
  2334 
  2316           if ( ( seg->link && seg->link->edge ) || is_serif )
  2335           if ( ( seg->link && seg->link->edge ) || is_serif )
  2317           {
  2336           {
  2318             AF_Edge     edge2;
  2337             AF_Edge     edge2;
  2319             AF_Segment  seg2;
  2338             AF_Segment  seg2;
  2544 
  2563 
  2545 
  2564 
  2546     af_glyph_hints_rescale( hints, (AF_StyleMetrics)metrics );
  2565     af_glyph_hints_rescale( hints, (AF_StyleMetrics)metrics );
  2547 
  2566 
  2548     /*
  2567     /*
  2549      *  correct x_scale and y_scale if needed, since they may have
  2568      * correct x_scale and y_scale if needed, since they may have
  2550      *  been modified by `af_latin_metrics_scale_dim' above
  2569      * been modified by `af_latin_metrics_scale_dim' above
  2551      */
  2570      */
  2552     hints->x_scale = metrics->axis[AF_DIMENSION_HORZ].scale;
  2571     hints->x_scale = metrics->axis[AF_DIMENSION_HORZ].scale;
  2553     hints->x_delta = metrics->axis[AF_DIMENSION_HORZ].delta;
  2572     hints->x_delta = metrics->axis[AF_DIMENSION_HORZ].delta;
  2554     hints->y_scale = metrics->axis[AF_DIMENSION_VERT].scale;
  2573     hints->y_scale = metrics->axis[AF_DIMENSION_VERT].scale;
  2555     hints->y_delta = metrics->axis[AF_DIMENSION_VERT].delta;
  2574     hints->y_delta = metrics->axis[AF_DIMENSION_VERT].delta;
  2564 
  2583 
  2565     scaler_flags = hints->scaler_flags;
  2584     scaler_flags = hints->scaler_flags;
  2566     other_flags  = 0;
  2585     other_flags  = 0;
  2567 
  2586 
  2568     /*
  2587     /*
  2569      *  We snap the width of vertical stems for the monochrome and
  2588      * We snap the width of vertical stems for the monochrome and
  2570      *  horizontal LCD rendering targets only.
  2589      * horizontal LCD rendering targets only.
  2571      */
  2590      */
  2572     if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD )
  2591     if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD )
  2573       other_flags |= AF_LATIN_HINTS_HORZ_SNAP;
  2592       other_flags |= AF_LATIN_HINTS_HORZ_SNAP;
  2574 
  2593 
  2575     /*
  2594     /*
  2576      *  We snap the width of horizontal stems for the monochrome and
  2595      * We snap the width of horizontal stems for the monochrome and
  2577      *  vertical LCD rendering targets only.
  2596      * vertical LCD rendering targets only.
  2578      */
  2597      */
  2579     if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V )
  2598     if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V )
  2580       other_flags |= AF_LATIN_HINTS_VERT_SNAP;
  2599       other_flags |= AF_LATIN_HINTS_VERT_SNAP;
  2581 
  2600 
  2582     /*
  2601     /*
  2583      *  We adjust stems to full pixels unless in `light' or `lcd' mode.
  2602      * We adjust stems to full pixels unless in `light' or `lcd' mode.
  2584      */
  2603      */
  2585     if ( mode != FT_RENDER_MODE_LIGHT && mode != FT_RENDER_MODE_LCD )
  2604     if ( mode != FT_RENDER_MODE_LIGHT && mode != FT_RENDER_MODE_LCD )
  2586       other_flags |= AF_LATIN_HINTS_STEM_ADJUST;
  2605       other_flags |= AF_LATIN_HINTS_STEM_ADJUST;
  2587 
  2606 
  2588     if ( mode == FT_RENDER_MODE_MONO )
  2607     if ( mode == FT_RENDER_MODE_MONO )
  2589       other_flags |= AF_LATIN_HINTS_MONO;
  2608       other_flags |= AF_LATIN_HINTS_MONO;
  2590 
  2609 
  2591     /*
  2610     /*
  2592      *  In `light' or `lcd' mode we disable horizontal hinting completely.
  2611      * In `light' or `lcd' mode we disable horizontal hinting completely.
  2593      *  We also do it if the face is italic.
  2612      * We also do it if the face is italic.
  2594      *
  2613      *
  2595      *  However, if warping is enabled (which only works in `light' hinting
  2614      * However, if warping is enabled (which only works in `light' hinting
  2596      *  mode), advance widths get adjusted, too.
  2615      * mode), advance widths get adjusted, too.
  2597      */
  2616      */
  2598     if ( mode == FT_RENDER_MODE_LIGHT || mode == FT_RENDER_MODE_LCD ||
  2617     if ( mode == FT_RENDER_MODE_LIGHT || mode == FT_RENDER_MODE_LCD ||
  2599          ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0          )
  2618          ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0          )
  2600       scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL;
  2619       scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL;
  2601 
  2620 
  2934     FT_PtrDist    n_edges;
  2953     FT_PtrDist    n_edges;
  2935     AF_Edge       edge;
  2954     AF_Edge       edge;
  2936     AF_Edge       anchor     = NULL;
  2955     AF_Edge       anchor     = NULL;
  2937     FT_Int        has_serifs = 0;
  2956     FT_Int        has_serifs = 0;
  2938 
  2957 
  2939 #ifdef FT_CONFIG_OPTION_PIC
       
  2940     AF_FaceGlobals  globals = hints->metrics->globals;
       
  2941 #endif
       
  2942 
       
  2943     AF_StyleClass   style_class  = hints->metrics->style_class;
  2958     AF_StyleClass   style_class  = hints->metrics->style_class;
  2944     AF_ScriptClass  script_class = AF_SCRIPT_CLASSES_GET
  2959     AF_ScriptClass  script_class = af_script_classes[style_class->script];
  2945                                      [style_class->script];
       
  2946 
  2960 
  2947     FT_Bool  top_to_bottom_hinting = 0;
  2961     FT_Bool  top_to_bottom_hinting = 0;
  2948 
  2962 
  2949 #ifdef FT_DEBUG_LEVEL_TRACE
  2963 #ifdef FT_DEBUG_LEVEL_TRACE
  2950     FT_UInt  num_actions = 0;
  2964     FT_UInt  num_actions = 0;
  2974 
  2988 
  2975         edge1 = NULL;
  2989         edge1 = NULL;
  2976         edge2 = edge->link;
  2990         edge2 = edge->link;
  2977 
  2991 
  2978         /*
  2992         /*
  2979          *  If a stem contains both a neutral and a non-neutral blue zone,
  2993          * If a stem contains both a neutral and a non-neutral blue zone,
  2980          *  skip the neutral one.  Otherwise, outlines with different
  2994          * skip the neutral one.  Otherwise, outlines with different
  2981          *  directions might be incorrectly aligned at the same vertical
  2995          * directions might be incorrectly aligned at the same vertical
  2982          *  position.
  2996          * position.
  2983          *
  2997          *
  2984          *  If we have two neutral blue zones, skip one of them.
  2998          * If we have two neutral blue zones, skip one of them.
  2985          *
  2999          *
  2986          */
  3000          */
  2987         if ( edge->blue_edge && edge2 && edge2->blue_edge )
  3001         if ( edge->blue_edge && edge2 && edge2->blue_edge )
  2988         {
  3002         {
  2989           FT_Byte  neutral  = edge->flags  & AF_EDGE_NEUTRAL;
  3003           FT_Byte  neutral  = edge->flags  & AF_EDGE_NEUTRAL;
  3342     }
  3356     }
  3343 
  3357 
  3344     if ( has_serifs || !anchor )
  3358     if ( has_serifs || !anchor )
  3345     {
  3359     {
  3346       /*
  3360       /*
  3347        *  now hint the remaining edges (serifs and single) in order
  3361        * now hint the remaining edges (serifs and single) in order
  3348        *  to complete our processing
  3362        * to complete our processing
  3349        */
  3363        */
  3350       for ( edge = edges; edge < edge_limit; edge++ )
  3364       for ( edge = edges; edge < edge_limit; edge++ )
  3351       {
  3365       {
  3352         FT_Pos  delta;
  3366         FT_Pos  delta;
  3353 
  3367