misc/libfreetype/src/autofit/afhints.h
branchwebgl
changeset 9521 8054d9d775fd
parent 9282 92af50454cf2
parent 9519 b8b5c82eb61b
child 9950 2759212a27de
equal deleted inserted replaced
9282:92af50454cf2 9521:8054d9d775fd
     1 /***************************************************************************/
       
     2 /*                                                                         */
       
     3 /*  afhints.h                                                              */
       
     4 /*                                                                         */
       
     5 /*    Auto-fitter hinting routines (specification).                        */
       
     6 /*                                                                         */
       
     7 /*  Copyright 2003-2008, 2010-2011 by                                      */
       
     8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
       
     9 /*                                                                         */
       
    10 /*  This file is part of the FreeType project, and may only be used,       */
       
    11 /*  modified, and distributed under the terms of the FreeType project      */
       
    12 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
       
    13 /*  this file you indicate that you have read the license and              */
       
    14 /*  understand and accept it fully.                                        */
       
    15 /*                                                                         */
       
    16 /***************************************************************************/
       
    17 
       
    18 
       
    19 #ifndef __AFHINTS_H__
       
    20 #define __AFHINTS_H__
       
    21 
       
    22 #include "aftypes.h"
       
    23 
       
    24 #define xxAF_SORT_SEGMENTS
       
    25 
       
    26 FT_BEGIN_HEADER
       
    27 
       
    28   /*
       
    29    *  The definition of outline glyph hints.  These are shared by all
       
    30    *  script analysis routines (until now).
       
    31    */
       
    32 
       
    33   typedef enum  AF_Dimension_
       
    34   {
       
    35     AF_DIMENSION_HORZ = 0,  /* x coordinates,                    */
       
    36                             /* i.e., vertical segments & edges   */
       
    37     AF_DIMENSION_VERT = 1,  /* y coordinates,                    */
       
    38                             /* i.e., horizontal segments & edges */
       
    39 
       
    40     AF_DIMENSION_MAX  /* do not remove */
       
    41 
       
    42   } AF_Dimension;
       
    43 
       
    44 
       
    45   /* hint directions -- the values are computed so that two vectors are */
       
    46   /* in opposite directions iff `dir1 + dir2 == 0'                      */
       
    47   typedef enum  AF_Direction_
       
    48   {
       
    49     AF_DIR_NONE  =  4,
       
    50     AF_DIR_RIGHT =  1,
       
    51     AF_DIR_LEFT  = -1,
       
    52     AF_DIR_UP    =  2,
       
    53     AF_DIR_DOWN  = -2
       
    54 
       
    55   } AF_Direction;
       
    56 
       
    57 
       
    58   /*
       
    59    *  The following explanations are mostly taken from the article
       
    60    *
       
    61    *    Real-Time Grid Fitting of Typographic Outlines
       
    62    *
       
    63    *  by David Turner and Werner Lemberg
       
    64    *
       
    65    *   http://www.tug.org/TUGboat/Articles/tb24-3/lemberg.pdf
       
    66    *
       
    67    *
       
    68    *  Segments
       
    69    *
       
    70    *    `af_{cjk,latin,...}_hints_compute_segments' are the functions to
       
    71    *    find segments in an outline.  A segment is a series of consecutive
       
    72    *    points that are approximately aligned along a coordinate axis.  The
       
    73    *    analysis to do so is specific to a script.
       
    74    *
       
    75    *    A segment must have at least two points, except in the case of
       
    76    *    `fake' segments that are generated to hint metrics appropriately,
       
    77    *    and which consist of a single point.
       
    78    *
       
    79    *
       
    80    *  Edges
       
    81    *
       
    82    *    As soon as segments are defined, the auto-hinter groups them into
       
    83    *    edges.  An edge corresponds to a single position on the main
       
    84    *    dimension that collects one or more segments (allowing for a small
       
    85    *    threshold).
       
    86    *
       
    87    *    The auto-hinter first tries to grid fit edges, then to align
       
    88    *    segments on the edges unless it detects that they form a serif.
       
    89    *
       
    90    *    `af_{cjk,latin,...}_hints_compute_edges' are the functions to find
       
    91    *    edges; they are specific to a script.
       
    92    *
       
    93    *
       
    94    *                      A          H
       
    95    *                       |        |
       
    96    *                       |        |
       
    97    *                       |        |
       
    98    *                       |        |
       
    99    *         C             |        |             F
       
   100    *          +------<-----+        +-----<------+
       
   101    *          |             B      G             |
       
   102    *          |                                  |
       
   103    *          |                                  |
       
   104    *          +--------------->------------------+
       
   105    *         D                                    E
       
   106    *
       
   107    *
       
   108    *  Stems
       
   109    *
       
   110    *    Segments need to be `linked' to other ones in order to detect stems.
       
   111    *    A stem is made of two segments that face each other in opposite
       
   112    *    directions and that are sufficiently close to each other.  Using
       
   113    *    vocabulary from the TrueType specification, stem segments form a
       
   114    *    `black distance'.
       
   115    *
       
   116    *    In the above ASCII drawing, the horizontal segments are BC, DE, and
       
   117    *    FG; the vertical segments are AB, CD, EF, and GH.
       
   118    *
       
   119    *    Each segment has at most one `best' candidate to form a black
       
   120    *    distance, or no candidate at all.  Notice that two distinct segments
       
   121    *    can have the same candidate, which frequently means a serif.
       
   122    *
       
   123    *    A stem is recognized by the following condition:
       
   124    *
       
   125    *      best segment_1 = segment_2 && best segment_2 = segment_1
       
   126    *
       
   127    *    The best candidate is stored in field `link' in structure
       
   128    *    `AF_Segment'.
       
   129    *
       
   130    *    Stems are detected by `af_{cjk,latin,...}_hint_edges'.
       
   131    *
       
   132    *    In the above ASCII drawing, the best candidate for both AB and CD is
       
   133    *    GH, while the best candidate for GH is AB.  Similarly, the best
       
   134    *    candidate for EF and GH is AB, while the best candidate for AB is
       
   135    *    GH.
       
   136    *
       
   137    *
       
   138    *  Serifs
       
   139    *
       
   140    *    On the opposite, a serif has
       
   141    *
       
   142    *      best segment_1 = segment_2 && best segment_2 != segment_1
       
   143    *
       
   144    *    where segment_1 corresponds to the serif segment (CD and EF in the
       
   145    *    above ASCII drawing).
       
   146    *
       
   147    *    The best candidate is stored in field `serif' in structure
       
   148    *    `AF_Segment' (and `link' is set to NULL).
       
   149    *
       
   150    *    Serifs are detected by `af_{cjk,latin,...}_hint_edges'.
       
   151    *
       
   152    *
       
   153    *  Touched points
       
   154    *
       
   155    *    A point is called `touched' if it has been processed somehow by the
       
   156    *    auto-hinter.  It basically means that it shouldn't be moved again
       
   157    *    (or moved only under certain constraints to preserve the already
       
   158    *    applied processing).
       
   159    *
       
   160    *
       
   161    *  Flat and round segments
       
   162    *
       
   163    *    Segments are `round' or `flat', depending on the series of points
       
   164    *    that define them.  A segment is round if the next and previous point
       
   165    *    of an extremum (which can be either a single point or sequence of
       
   166    *    points) are both conic or cubic control points.  Otherwise, a
       
   167    *    segment with an extremum is flat.
       
   168    *
       
   169    *
       
   170    *  Strong Points
       
   171    *
       
   172    *    Experience has shown that points which are not part of an edge need
       
   173    *    to be interpolated linearly between their two closest edges, even if
       
   174    *    these are not part of the contour of those particular points.
       
   175    *    Typical candidates for this are
       
   176    *
       
   177    *    - angle points (i.e., points where the `in' and `out' direction
       
   178    *      differ greatly)
       
   179    *
       
   180    *    - inflection points (i.e., where the `in' and `out' angles are the
       
   181    *      same, but the curvature changes sign)
       
   182    *
       
   183    *    `af_glyph_hints_align_strong_points' is the function which takes
       
   184    *    care of such situations; it is equivalent to the TrueType `IP'
       
   185    *    hinting instruction.
       
   186    *
       
   187    *
       
   188    *  Weak Points
       
   189    *
       
   190    *    Other points in the outline must be interpolated using the
       
   191    *    coordinates of their previous and next unfitted contour neighbours.
       
   192    *    These are called `weak points' and are touched by the function
       
   193    *    `af_glyph_hints_align_weak_points', equivalent to the TrueType `IUP'
       
   194    *    hinting instruction.  Typical candidates are control points and
       
   195    *    points on the contour without a major direction.
       
   196    *
       
   197    *    The major effect is to reduce possible distortion caused by
       
   198    *    alignment of edges and strong points, thus weak points are processed
       
   199    *    after strong points.
       
   200    */
       
   201 
       
   202 
       
   203   /* point hint flags */
       
   204   typedef enum  AF_Flags_
       
   205   {
       
   206     AF_FLAG_NONE = 0,
       
   207 
       
   208     /* point type flags */
       
   209     AF_FLAG_CONIC   = 1 << 0,
       
   210     AF_FLAG_CUBIC   = 1 << 1,
       
   211     AF_FLAG_CONTROL = AF_FLAG_CONIC | AF_FLAG_CUBIC,
       
   212 
       
   213     /* point extremum flags */
       
   214     AF_FLAG_EXTREMA_X = 1 << 2,
       
   215     AF_FLAG_EXTREMA_Y = 1 << 3,
       
   216 
       
   217     /* point roundness flags */
       
   218     AF_FLAG_ROUND_X = 1 << 4,
       
   219     AF_FLAG_ROUND_Y = 1 << 5,
       
   220 
       
   221     /* point touch flags */
       
   222     AF_FLAG_TOUCH_X = 1 << 6,
       
   223     AF_FLAG_TOUCH_Y = 1 << 7,
       
   224 
       
   225     /* candidates for weak interpolation have this flag set */
       
   226     AF_FLAG_WEAK_INTERPOLATION = 1 << 8,
       
   227 
       
   228     /* all inflection points in the outline have this flag set */
       
   229     AF_FLAG_INFLECTION = 1 << 9
       
   230 
       
   231   } AF_Flags;
       
   232 
       
   233 
       
   234   /* edge hint flags */
       
   235   typedef enum  AF_Edge_Flags_
       
   236   {
       
   237     AF_EDGE_NORMAL = 0,
       
   238     AF_EDGE_ROUND  = 1 << 0,
       
   239     AF_EDGE_SERIF  = 1 << 1,
       
   240     AF_EDGE_DONE   = 1 << 2
       
   241 
       
   242   } AF_Edge_Flags;
       
   243 
       
   244 
       
   245   typedef struct AF_PointRec_*    AF_Point;
       
   246   typedef struct AF_SegmentRec_*  AF_Segment;
       
   247   typedef struct AF_EdgeRec_*     AF_Edge;
       
   248 
       
   249 
       
   250   typedef struct  AF_PointRec_
       
   251   {
       
   252     FT_UShort  flags;    /* point flags used by hinter   */
       
   253     FT_Char    in_dir;   /* direction of inwards vector  */
       
   254     FT_Char    out_dir;  /* direction of outwards vector */
       
   255 
       
   256     FT_Pos     ox, oy;   /* original, scaled position                   */
       
   257     FT_Short   fx, fy;   /* original, unscaled position (font units)    */
       
   258     FT_Pos     x, y;     /* current position                            */
       
   259     FT_Pos     u, v;     /* current (x,y) or (y,x) depending on context */
       
   260 
       
   261     AF_Point   next;     /* next point in contour     */
       
   262     AF_Point   prev;     /* previous point in contour */
       
   263 
       
   264   } AF_PointRec;
       
   265 
       
   266 
       
   267   typedef struct  AF_SegmentRec_
       
   268   {
       
   269     FT_Byte     flags;       /* edge/segment flags for this segment */
       
   270     FT_Char     dir;         /* segment direction                   */
       
   271     FT_Short    pos;         /* position of segment                 */
       
   272     FT_Short    min_coord;   /* minimum coordinate of segment       */
       
   273     FT_Short    max_coord;   /* maximum coordinate of segment       */
       
   274     FT_Short    height;      /* the hinted segment height           */
       
   275 
       
   276     AF_Edge     edge;        /* the segment's parent edge           */
       
   277     AF_Segment  edge_next;   /* link to next segment in parent edge */
       
   278 
       
   279     AF_Segment  link;        /* (stem) link segment        */
       
   280     AF_Segment  serif;       /* primary segment for serifs */
       
   281     FT_Pos      num_linked;  /* number of linked segments  */
       
   282     FT_Pos      score;       /* used during stem matching  */
       
   283     FT_Pos      len;         /* used during stem matching  */
       
   284 
       
   285     AF_Point    first;       /* first point in edge segment             */
       
   286     AF_Point    last;        /* last point in edge segment              */
       
   287     AF_Point*   contour;     /* ptr to first point of segment's contour */
       
   288 
       
   289   } AF_SegmentRec;
       
   290 
       
   291 
       
   292   typedef struct  AF_EdgeRec_
       
   293   {
       
   294     FT_Short    fpos;       /* original, unscaled position (font units) */
       
   295     FT_Pos      opos;       /* original, scaled position                */
       
   296     FT_Pos      pos;        /* current position                         */
       
   297 
       
   298     FT_Byte     flags;      /* edge flags                                   */
       
   299     FT_Char     dir;        /* edge direction                               */
       
   300     FT_Fixed    scale;      /* used to speed up interpolation between edges */
       
   301     AF_Width    blue_edge;  /* non-NULL if this is a blue edge              */
       
   302 
       
   303     AF_Edge     link;       /* link edge                 */
       
   304     AF_Edge     serif;      /* primary edge for serifs   */
       
   305     FT_Short    num_linked; /* number of linked edges    */
       
   306     FT_Int      score;      /* used during stem matching */
       
   307 
       
   308     AF_Segment  first;      /* first segment in edge */
       
   309     AF_Segment  last;       /* last segment in edge  */
       
   310 
       
   311   } AF_EdgeRec;
       
   312 
       
   313 
       
   314   typedef struct  AF_AxisHintsRec_
       
   315   {
       
   316     FT_Int        num_segments; /* number of used segments      */
       
   317     FT_Int        max_segments; /* number of allocated segments */
       
   318     AF_Segment    segments;     /* segments array               */
       
   319 #ifdef AF_SORT_SEGMENTS
       
   320     FT_Int        mid_segments;
       
   321 #endif
       
   322 
       
   323     FT_Int        num_edges;    /* number of used edges      */
       
   324     FT_Int        max_edges;    /* number of allocated edges */
       
   325     AF_Edge       edges;        /* edges array               */
       
   326 
       
   327     AF_Direction  major_dir;    /* either vertical or horizontal */
       
   328 
       
   329   } AF_AxisHintsRec, *AF_AxisHints;
       
   330 
       
   331 
       
   332   typedef struct  AF_GlyphHintsRec_
       
   333   {
       
   334     FT_Memory         memory;
       
   335 
       
   336     FT_Fixed          x_scale;
       
   337     FT_Pos            x_delta;
       
   338 
       
   339     FT_Fixed          y_scale;
       
   340     FT_Pos            y_delta;
       
   341 
       
   342     FT_Int            max_points;    /* number of allocated points */
       
   343     FT_Int            num_points;    /* number of used points      */
       
   344     AF_Point          points;        /* points array               */
       
   345 
       
   346     FT_Int            max_contours;  /* number of allocated contours */
       
   347     FT_Int            num_contours;  /* number of used contours      */
       
   348     AF_Point*         contours;      /* contours array               */
       
   349 
       
   350     AF_AxisHintsRec   axis[AF_DIMENSION_MAX];
       
   351 
       
   352     FT_UInt32         scaler_flags;  /* copy of scaler flags     */
       
   353     FT_UInt32         other_flags;   /* free for script-specific */
       
   354                                      /* implementations          */
       
   355     AF_ScriptMetrics  metrics;
       
   356 
       
   357     FT_Pos            xmin_delta;    /* used for warping */
       
   358     FT_Pos            xmax_delta;
       
   359 
       
   360   } AF_GlyphHintsRec;
       
   361 
       
   362 
       
   363 #define AF_HINTS_TEST_SCALER( h, f )  ( (h)->scaler_flags & (f) )
       
   364 #define AF_HINTS_TEST_OTHER( h, f )   ( (h)->other_flags  & (f) )
       
   365 
       
   366 
       
   367 #ifdef FT_DEBUG_AUTOFIT
       
   368 
       
   369 #define AF_HINTS_DO_HORIZONTAL( h )                                     \
       
   370           ( !_af_debug_disable_horz_hints                            && \
       
   371             !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL ) )
       
   372 
       
   373 #define AF_HINTS_DO_VERTICAL( h )                                     \
       
   374           ( !_af_debug_disable_vert_hints                          && \
       
   375             !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL ) )
       
   376 
       
   377 #define AF_HINTS_DO_ADVANCE( h )                                \
       
   378           !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE )
       
   379 
       
   380 #define AF_HINTS_DO_BLUES( h )  ( !_af_debug_disable_blue_hints )
       
   381 
       
   382 #else /* !FT_DEBUG_AUTOFIT */
       
   383 
       
   384 #define AF_HINTS_DO_HORIZONTAL( h )                                \
       
   385           !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL )
       
   386 
       
   387 #define AF_HINTS_DO_VERTICAL( h )                                \
       
   388           !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL )
       
   389 
       
   390 #define AF_HINTS_DO_ADVANCE( h )                                \
       
   391           !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE )
       
   392 
       
   393 #define AF_HINTS_DO_BLUES( h )  1
       
   394 
       
   395 #endif /* !FT_DEBUG_AUTOFIT */
       
   396 
       
   397 
       
   398   FT_LOCAL( AF_Direction )
       
   399   af_direction_compute( FT_Pos  dx,
       
   400                         FT_Pos  dy );
       
   401 
       
   402 
       
   403   FT_LOCAL( FT_Error )
       
   404   af_axis_hints_new_segment( AF_AxisHints  axis,
       
   405                              FT_Memory     memory,
       
   406                              AF_Segment   *asegment );
       
   407 
       
   408   FT_LOCAL( FT_Error)
       
   409   af_axis_hints_new_edge( AF_AxisHints  axis,
       
   410                           FT_Int        fpos,
       
   411                           AF_Direction  dir,
       
   412                           FT_Memory     memory,
       
   413                           AF_Edge      *edge );
       
   414 
       
   415   FT_LOCAL( void )
       
   416   af_glyph_hints_init( AF_GlyphHints  hints,
       
   417                        FT_Memory      memory );
       
   418 
       
   419   FT_LOCAL( void )
       
   420   af_glyph_hints_rescale( AF_GlyphHints     hints,
       
   421                           AF_ScriptMetrics  metrics );
       
   422 
       
   423   FT_LOCAL( FT_Error )
       
   424   af_glyph_hints_reload( AF_GlyphHints  hints,
       
   425                          FT_Outline*    outline );
       
   426 
       
   427   FT_LOCAL( void )
       
   428   af_glyph_hints_save( AF_GlyphHints  hints,
       
   429                        FT_Outline*    outline );
       
   430 
       
   431   FT_LOCAL( void )
       
   432   af_glyph_hints_align_edge_points( AF_GlyphHints  hints,
       
   433                                     AF_Dimension   dim );
       
   434 
       
   435   FT_LOCAL( void )
       
   436   af_glyph_hints_align_strong_points( AF_GlyphHints  hints,
       
   437                                       AF_Dimension   dim );
       
   438 
       
   439   FT_LOCAL( void )
       
   440   af_glyph_hints_align_weak_points( AF_GlyphHints  hints,
       
   441                                     AF_Dimension   dim );
       
   442 
       
   443 #ifdef AF_CONFIG_OPTION_USE_WARPER
       
   444   FT_LOCAL( void )
       
   445   af_glyph_hints_scale_dim( AF_GlyphHints  hints,
       
   446                             AF_Dimension   dim,
       
   447                             FT_Fixed       scale,
       
   448                             FT_Pos         delta );
       
   449 #endif
       
   450 
       
   451   FT_LOCAL( void )
       
   452   af_glyph_hints_done( AF_GlyphHints  hints );
       
   453 
       
   454 /* */
       
   455 
       
   456 #define AF_SEGMENT_LEN( seg )          ( (seg)->max_coord - (seg)->min_coord )
       
   457 
       
   458 #define AF_SEGMENT_DIST( seg1, seg2 )  ( ( (seg1)->pos > (seg2)->pos )   \
       
   459                                            ? (seg1)->pos - (seg2)->pos   \
       
   460                                            : (seg2)->pos - (seg1)->pos )
       
   461 
       
   462 
       
   463 FT_END_HEADER
       
   464 
       
   465 #endif /* __AFHINTS_H__ */
       
   466 
       
   467 
       
   468 /* END */