Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /*  afhints.h                                                              */
  4. /*                                                                         */
  5. /*    Auto-fitter hinting routines (specification).                        */
  6. /*                                                                         */
  7. /*  Copyright 2003-2008, 2010-2012 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 (in 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.  
  288.   } AF_SegmentRec;
  289.  
  290.  
  291.   typedef struct  AF_EdgeRec_
  292.   {
  293.     FT_Short    fpos;       /* original, unscaled position (in font units) */
  294.     FT_Pos      opos;       /* original, scaled position                   */
  295.     FT_Pos      pos;        /* current position                            */
  296.  
  297.     FT_Byte     flags;      /* edge flags                                   */
  298.     FT_Char     dir;        /* edge direction                               */
  299.     FT_Fixed    scale;      /* used to speed up interpolation between edges */
  300.  
  301.     AF_Width    blue_edge;  /* non-NULL if this is a blue edge */
  302.     AF_Edge     link;       /* link edge                       */
  303.     AF_Edge     serif;      /* primary edge for serifs         */
  304.     FT_Short    num_linked; /* number of linked edges          */
  305.     FT_Int      score;      /* used during stem matching       */
  306.  
  307.     AF_Segment  first;      /* first segment in edge */
  308.     AF_Segment  last;       /* last segment in edge  */
  309.  
  310.   } AF_EdgeRec;
  311.  
  312.  
  313.   typedef struct  AF_AxisHintsRec_
  314.   {
  315.     FT_Int        num_segments; /* number of used segments      */
  316.     FT_Int        max_segments; /* number of allocated segments */
  317.     AF_Segment    segments;     /* segments array               */
  318. #ifdef AF_SORT_SEGMENTS
  319.     FT_Int        mid_segments;
  320. #endif
  321.  
  322.     FT_Int        num_edges;    /* number of used edges      */
  323.     FT_Int        max_edges;    /* number of allocated edges */
  324.     AF_Edge       edges;        /* edges array               */
  325.  
  326.     AF_Direction  major_dir;    /* either vertical or horizontal */
  327.  
  328.   } AF_AxisHintsRec, *AF_AxisHints;
  329.  
  330.  
  331.   typedef struct  AF_GlyphHintsRec_
  332.   {
  333.     FT_Memory         memory;
  334.  
  335.     FT_Fixed          x_scale;
  336.     FT_Pos            x_delta;
  337.  
  338.     FT_Fixed          y_scale;
  339.     FT_Pos            y_delta;
  340.  
  341.     FT_Int            max_points;    /* number of allocated points */
  342.     FT_Int            num_points;    /* number of used points      */
  343.     AF_Point          points;        /* points array               */
  344.  
  345.     FT_Int            max_contours;  /* number of allocated contours */
  346.     FT_Int            num_contours;  /* number of used contours      */
  347.     AF_Point*         contours;      /* contours array               */
  348.  
  349.     AF_AxisHintsRec   axis[AF_DIMENSION_MAX];
  350.  
  351.     FT_UInt32         scaler_flags;  /* copy of scaler flags     */
  352.     FT_UInt32         other_flags;   /* free for script-specific */
  353.                                      /* implementations          */
  354.     AF_ScriptMetrics  metrics;
  355.  
  356.     FT_Pos            xmin_delta;    /* used for warping */
  357.     FT_Pos            xmax_delta;
  358.  
  359.   } AF_GlyphHintsRec;
  360.  
  361.  
  362. #define AF_HINTS_TEST_SCALER( h, f )  ( (h)->scaler_flags & (f) )
  363. #define AF_HINTS_TEST_OTHER( h, f )   ( (h)->other_flags  & (f) )
  364.  
  365.  
  366. #ifdef FT_DEBUG_AUTOFIT
  367.  
  368. #define AF_HINTS_DO_HORIZONTAL( h )                                     \
  369.           ( !_af_debug_disable_horz_hints                            && \
  370.             !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL ) )
  371.  
  372. #define AF_HINTS_DO_VERTICAL( h )                                     \
  373.           ( !_af_debug_disable_vert_hints                          && \
  374.             !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL ) )
  375.  
  376. #define AF_HINTS_DO_ADVANCE( h )                                \
  377.           !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE )
  378.  
  379. #define AF_HINTS_DO_BLUES( h )  ( !_af_debug_disable_blue_hints )
  380.  
  381. #else /* !FT_DEBUG_AUTOFIT */
  382.  
  383. #define AF_HINTS_DO_HORIZONTAL( h )                                \
  384.           !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL )
  385.  
  386. #define AF_HINTS_DO_VERTICAL( h )                                \
  387.           !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL )
  388.  
  389. #define AF_HINTS_DO_ADVANCE( h )                                \
  390.           !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE )
  391.  
  392. #define AF_HINTS_DO_BLUES( h )  1
  393.  
  394. #endif /* !FT_DEBUG_AUTOFIT */
  395.  
  396.  
  397.   FT_LOCAL( AF_Direction )
  398.   af_direction_compute( FT_Pos  dx,
  399.                         FT_Pos  dy );
  400.  
  401.  
  402.   FT_LOCAL( FT_Error )
  403.   af_axis_hints_new_segment( AF_AxisHints  axis,
  404.                              FT_Memory     memory,
  405.                              AF_Segment   *asegment );
  406.  
  407.   FT_LOCAL( FT_Error)
  408.   af_axis_hints_new_edge( AF_AxisHints  axis,
  409.                           FT_Int        fpos,
  410.                           AF_Direction  dir,
  411.                           FT_Memory     memory,
  412.                           AF_Edge      *edge );
  413.  
  414.   FT_LOCAL( void )
  415.   af_glyph_hints_init( AF_GlyphHints  hints,
  416.                        FT_Memory      memory );
  417.  
  418.   FT_LOCAL( void )
  419.   af_glyph_hints_rescale( AF_GlyphHints     hints,
  420.                           AF_ScriptMetrics  metrics );
  421.  
  422.   FT_LOCAL( FT_Error )
  423.   af_glyph_hints_reload( AF_GlyphHints  hints,
  424.                          FT_Outline*    outline );
  425.  
  426.   FT_LOCAL( void )
  427.   af_glyph_hints_save( AF_GlyphHints  hints,
  428.                        FT_Outline*    outline );
  429.  
  430.   FT_LOCAL( void )
  431.   af_glyph_hints_align_edge_points( AF_GlyphHints  hints,
  432.                                     AF_Dimension   dim );
  433.  
  434.   FT_LOCAL( void )
  435.   af_glyph_hints_align_strong_points( AF_GlyphHints  hints,
  436.                                       AF_Dimension   dim );
  437.  
  438.   FT_LOCAL( void )
  439.   af_glyph_hints_align_weak_points( AF_GlyphHints  hints,
  440.                                     AF_Dimension   dim );
  441.  
  442. #ifdef AF_CONFIG_OPTION_USE_WARPER
  443.   FT_LOCAL( void )
  444.   af_glyph_hints_scale_dim( AF_GlyphHints  hints,
  445.                             AF_Dimension   dim,
  446.                             FT_Fixed       scale,
  447.                             FT_Pos         delta );
  448. #endif
  449.  
  450.   FT_LOCAL( void )
  451.   af_glyph_hints_done( AF_GlyphHints  hints );
  452.  
  453. /* */
  454.  
  455. #define AF_SEGMENT_LEN( seg )          ( (seg)->max_coord - (seg)->min_coord )
  456.  
  457. #define AF_SEGMENT_DIST( seg1, seg2 )  ( ( (seg1)->pos > (seg2)->pos )   \
  458.                                            ? (seg1)->pos - (seg2)->pos   \
  459.                                            : (seg2)->pos - (seg1)->pos )
  460.  
  461.  
  462. FT_END_HEADER
  463.  
  464. #endif /* __AFHINTS_H__ */
  465.  
  466.  
  467. /* END */
  468.