"Fossies" - the Fresh Open Source Software Archive

Member "SDL2_ttf-2.20.2/external/freetype/src/autofit/afhints.h" (25 May 2022, 16039 Bytes) of package /linux/misc/SDL2_ttf-2.20.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "afhints.h" see the Fossies "Dox" file reference documentation.

    1 /****************************************************************************
    2  *
    3  * afhints.h
    4  *
    5  *   Auto-fitter hinting routines (specification).
    6  *
    7  * Copyright (C) 2003-2022 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    * writing system 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    *   https://www.tug.org/TUGboat/Articles/tb24-3/lemberg.pdf
   66    *
   67    * with appropriate updates.
   68    *
   69    *
   70    * Segments
   71    *
   72    *   `af_{cjk,latin,...}_hints_compute_segments' are the functions to
   73    *   find segments in an outline.
   74    *
   75    *   A segment is a series of at least two consecutive points that are
   76    *   approximately aligned along a coordinate axis.  The analysis to do
   77    *   so is specific to a writing system.
   78    *
   79    *
   80    * Edges
   81    *
   82    *   `af_{cjk,latin,...}_hints_compute_edges' are the functions to find
   83    *   edges.
   84    *
   85    *   As soon as segments are defined, the auto-hinter groups them into
   86    *   edges.  An edge corresponds to a single position on the main
   87    *   dimension that collects one or more segments (allowing for a small
   88    *   threshold).
   89    *
   90    *   As an example, the `latin' writing system first tries to grid-fit
   91    *   edges, then to align segments on the edges unless it detects that
   92    *   they form a serif.
   93    *
   94    *
   95    *                     A          H
   96    *                      |        |
   97    *                      |        |
   98    *                      |        |
   99    *                      |        |
  100    *        C             |        |             F
  101    *         +------<-----+        +-----<------+
  102    *         |             B      G             |
  103    *         |                                  |
  104    *         |                                  |
  105    *         +--------------->------------------+
  106    *        D                                    E
  107    *
  108    *
  109    * Stems
  110    *
  111    *   Stems are detected by `af_{cjk,latin,...}_hint_edges'.
  112    *
  113    *   Segments need to be `linked' to other ones in order to detect stems.
  114    *   A stem is made of two segments that face each other in opposite
  115    *   directions and that are sufficiently close to each other.  Using
  116    *   vocabulary from the TrueType specification, stem segments form a
  117    *   `black distance'.
  118    *
  119    *   In the above ASCII drawing, the horizontal segments are BC, DE, and
  120    *   FG; the vertical segments are AB, CD, EF, and GH.
  121    *
  122    *   Each segment has at most one `best' candidate to form a black
  123    *   distance, or no candidate at all.  Notice that two distinct segments
  124    *   can have the same candidate, which frequently means a serif.
  125    *
  126    *   A stem is recognized by the following condition:
  127    *
  128    *     best segment_1 = segment_2 && best segment_2 = segment_1
  129    *
  130    *   The best candidate is stored in field `link' in structure
  131    *   `AF_Segment'.
  132    *
  133    *   In the above ASCII drawing, the best candidate for both AB and CD is
  134    *   GH, while the best candidate for GH is AB.  Similarly, the best
  135    *   candidate for EF and GH is AB, while the best candidate for AB is
  136    *   GH.
  137    *
  138    *   The detection and handling of stems is dependent on the writing
  139    *   system.
  140    *
  141    *
  142    * Serifs
  143    *
  144    *   Serifs are detected by `af_{cjk,latin,...}_hint_edges'.
  145    *
  146    *   In comparison to a stem, a serif (as handled by the auto-hinter
  147    *   module that takes care of the `latin' writing system) has
  148    *
  149    *     best segment_1 = segment_2 && best segment_2 != segment_1
  150    *
  151    *   where segment_1 corresponds to the serif segment (CD and EF in the
  152    *   above ASCII drawing).
  153    *
  154    *   The best candidate is stored in field `serif' in structure
  155    *   `AF_Segment' (and `link' is set to NULL).
  156    *
  157    *
  158    * Touched points
  159    *
  160    *   A point is called `touched' if it has been processed somehow by the
  161    *   auto-hinter.  It basically means that it shouldn't be moved again
  162    *   (or moved only under certain constraints to preserve the already
  163    *   applied processing).
  164    *
  165    *
  166    * Flat and round segments
  167    *
  168    *   Segments are `round' or `flat', depending on the series of points
  169    *   that define them.  A segment is round if the next and previous point
  170    *   of an extremum (which can be either a single point or sequence of
  171    *   points) are both conic or cubic control points.  Otherwise, a
  172    *   segment with an extremum is flat.
  173    *
  174    *
  175    * Strong Points
  176    *
  177    *   Experience has shown that points not part of an edge need to be
  178    *   interpolated linearly between their two closest edges, even if these
  179    *   are not part of the contour of those particular points.  Typical
  180    *   candidates for this are
  181    *
  182    *   - angle points (i.e., points where the `in' and `out' direction
  183    *     differ greatly)
  184    *
  185    *   - inflection points (i.e., where the `in' and `out' angles are the
  186    *     same, but the curvature changes sign) [currently, such points
  187    *     aren't handled specially in the auto-hinter]
  188    *
  189    *   `af_glyph_hints_align_strong_points' is the function that takes
  190    *   care of such situations; it is equivalent to the TrueType `IP'
  191    *   hinting instruction.
  192    *
  193    *
  194    * Weak Points
  195    *
  196    *   Other points in the outline must be interpolated using the
  197    *   coordinates of their previous and next unfitted contour neighbours.
  198    *   These are called `weak points' and are touched by the function
  199    *   `af_glyph_hints_align_weak_points', equivalent to the TrueType `IUP'
  200    *   hinting instruction.  Typical candidates are control points and
  201    *   points on the contour without a major direction.
  202    *
  203    *   The major effect is to reduce possible distortion caused by
  204    *   alignment of edges and strong points, thus weak points are processed
  205    *   after strong points.
  206    */
  207 
  208 
  209   /* point hint flags */
  210 #define AF_FLAG_NONE  0
  211 
  212   /* point type flags */
  213 #define AF_FLAG_CONIC    ( 1U << 0 )
  214 #define AF_FLAG_CUBIC    ( 1U << 1 )
  215 #define AF_FLAG_CONTROL  ( AF_FLAG_CONIC | AF_FLAG_CUBIC )
  216 
  217   /* point touch flags */
  218 #define AF_FLAG_TOUCH_X  ( 1U << 2 )
  219 #define AF_FLAG_TOUCH_Y  ( 1U << 3 )
  220 
  221   /* candidates for weak interpolation have this flag set */
  222 #define AF_FLAG_WEAK_INTERPOLATION  ( 1U << 4 )
  223 
  224   /* the distance to the next point is very small */
  225 #define AF_FLAG_NEAR  ( 1U << 5 )
  226 
  227 
  228   /* edge hint flags */
  229 #define AF_EDGE_NORMAL  0
  230 #define AF_EDGE_ROUND    ( 1U << 0 )
  231 #define AF_EDGE_SERIF    ( 1U << 1 )
  232 #define AF_EDGE_DONE     ( 1U << 2 )
  233 #define AF_EDGE_NEUTRAL  ( 1U << 3 ) /* edge aligns to a neutral blue zone */
  234 
  235 
  236   typedef struct AF_PointRec_*    AF_Point;
  237   typedef struct AF_SegmentRec_*  AF_Segment;
  238   typedef struct AF_EdgeRec_*     AF_Edge;
  239 
  240 
  241   typedef struct  AF_PointRec_
  242   {
  243     FT_UShort  flags;    /* point flags used by hinter   */
  244     FT_Char    in_dir;   /* direction of inwards vector  */
  245     FT_Char    out_dir;  /* direction of outwards vector */
  246 
  247     FT_Pos     ox, oy;   /* original, scaled position                   */
  248     FT_Short   fx, fy;   /* original, unscaled position (in font units) */
  249     FT_Pos     x, y;     /* current position                            */
  250     FT_Pos     u, v;     /* current (x,y) or (y,x) depending on context */
  251 
  252     AF_Point   next;     /* next point in contour     */
  253     AF_Point   prev;     /* previous point in contour */
  254 
  255 #ifdef FT_DEBUG_AUTOFIT
  256     /* track `before' and `after' edges for strong points */
  257     AF_Edge    before[2];
  258     AF_Edge    after[2];
  259 #endif
  260 
  261   } AF_PointRec;
  262 
  263 
  264   typedef struct  AF_SegmentRec_
  265   {
  266     FT_Byte     flags;       /* edge/segment flags for this segment */
  267     FT_Char     dir;         /* segment direction                   */
  268     FT_Short    pos;         /* position of segment                 */
  269     FT_Short    delta;       /* deviation from segment position     */
  270     FT_Short    min_coord;   /* minimum coordinate of segment       */
  271     FT_Short    max_coord;   /* maximum coordinate of segment       */
  272     FT_Short    height;      /* the hinted segment height           */
  273 
  274     AF_Edge     edge;        /* the segment's parent edge           */
  275     AF_Segment  edge_next;   /* link to next segment in parent edge */
  276 
  277     AF_Segment  link;        /* (stem) link segment        */
  278     AF_Segment  serif;       /* primary segment for serifs */
  279     FT_Pos      score;       /* used during stem matching  */
  280     FT_Pos      len;         /* used during stem matching  */
  281 
  282     AF_Point    first;       /* first point in edge segment */
  283     AF_Point    last;        /* last point in edge segment  */
  284 
  285   } AF_SegmentRec;
  286 
  287 
  288   typedef struct  AF_EdgeRec_
  289   {
  290     FT_Short    fpos;       /* original, unscaled position (in font units) */
  291     FT_Pos      opos;       /* original, scaled position                   */
  292     FT_Pos      pos;        /* current position                            */
  293 
  294     FT_Byte     flags;      /* edge flags                                   */
  295     FT_Char     dir;        /* edge direction                               */
  296     FT_Fixed    scale;      /* used to speed up interpolation between edges */
  297 
  298     AF_Width    blue_edge;  /* non-NULL if this is a blue edge */
  299     AF_Edge     link;       /* link edge                       */
  300     AF_Edge     serif;      /* primary edge for serifs         */
  301     FT_Int      score;      /* used during stem matching       */
  302 
  303     AF_Segment  first;      /* first segment in edge */
  304     AF_Segment  last;       /* last segment in edge  */
  305 
  306   } AF_EdgeRec;
  307 
  308 #define AF_SEGMENTS_EMBEDDED  18   /* number of embedded segments   */
  309 #define AF_EDGES_EMBEDDED     12   /* number of embedded edges      */
  310 
  311   typedef struct  AF_AxisHintsRec_
  312   {
  313     FT_Int        num_segments; /* number of used segments      */
  314     FT_Int        max_segments; /* number of allocated segments */
  315     AF_Segment    segments;     /* segments array               */
  316 #ifdef AF_SORT_SEGMENTS
  317     FT_Int        mid_segments;
  318 #endif
  319 
  320     FT_Int        num_edges;    /* number of used edges      */
  321     FT_Int        max_edges;    /* number of allocated edges */
  322     AF_Edge       edges;        /* edges array               */
  323 
  324     AF_Direction  major_dir;    /* either vertical or horizontal */
  325 
  326     /* two arrays to avoid allocation penalty */
  327     struct
  328     {
  329       AF_SegmentRec  segments[AF_SEGMENTS_EMBEDDED];
  330       AF_EdgeRec     edges[AF_EDGES_EMBEDDED];
  331     } embedded;
  332 
  333 
  334   } AF_AxisHintsRec, *AF_AxisHints;
  335 
  336 
  337 #define AF_POINTS_EMBEDDED     96   /* number of embedded points   */
  338 #define AF_CONTOURS_EMBEDDED    8   /* number of embedded contours */
  339 
  340   typedef struct  AF_GlyphHintsRec_
  341   {
  342     FT_Memory        memory;
  343 
  344     FT_Fixed         x_scale;
  345     FT_Pos           x_delta;
  346 
  347     FT_Fixed         y_scale;
  348     FT_Pos           y_delta;
  349 
  350     FT_Int           max_points;    /* number of allocated points */
  351     FT_Int           num_points;    /* number of used points      */
  352     AF_Point         points;        /* points array               */
  353 
  354     FT_Int           max_contours;  /* number of allocated contours */
  355     FT_Int           num_contours;  /* number of used contours      */
  356     AF_Point*        contours;      /* contours array               */
  357 
  358     AF_AxisHintsRec  axis[AF_DIMENSION_MAX];
  359 
  360     FT_UInt32        scaler_flags;  /* copy of scaler flags    */
  361     FT_UInt32        other_flags;   /* free for style-specific */
  362                                     /* implementations         */
  363     AF_StyleMetrics  metrics;
  364 
  365     /* Two arrays to avoid allocation penalty.            */
  366     /* The `embedded' structure must be the last element! */
  367     struct
  368     {
  369       AF_Point       contours[AF_CONTOURS_EMBEDDED];
  370       AF_PointRec    points[AF_POINTS_EMBEDDED];
  371     } embedded;
  372 
  373   } AF_GlyphHintsRec;
  374 
  375 
  376 #define AF_HINTS_TEST_SCALER( h, f )  ( (h)->scaler_flags & (f) )
  377 #define AF_HINTS_TEST_OTHER( h, f )   ( (h)->other_flags  & (f) )
  378 
  379 
  380 #ifdef FT_DEBUG_AUTOFIT
  381 
  382 #define AF_HINTS_DO_HORIZONTAL( h )                                     \
  383           ( !_af_debug_disable_horz_hints                            && \
  384             !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL ) )
  385 
  386 #define AF_HINTS_DO_VERTICAL( h )                                     \
  387           ( !_af_debug_disable_vert_hints                          && \
  388             !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL ) )
  389 
  390 #define AF_HINTS_DO_BLUES( h )  ( !_af_debug_disable_blue_hints )
  391 
  392 #else /* !FT_DEBUG_AUTOFIT */
  393 
  394 #define AF_HINTS_DO_HORIZONTAL( h )                                \
  395           !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL )
  396 
  397 #define AF_HINTS_DO_VERTICAL( h )                                \
  398           !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL )
  399 
  400 #define AF_HINTS_DO_BLUES( h )  1
  401 
  402 #endif /* !FT_DEBUG_AUTOFIT */
  403 
  404 
  405 #define AF_HINTS_DO_ADVANCE( h )                                \
  406           !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE )
  407 
  408 
  409   FT_LOCAL( AF_Direction )
  410   af_direction_compute( FT_Pos  dx,
  411                         FT_Pos  dy );
  412 
  413 
  414   FT_LOCAL( FT_Error )
  415   af_axis_hints_new_segment( AF_AxisHints  axis,
  416                              FT_Memory     memory,
  417                              AF_Segment   *asegment );
  418 
  419   FT_LOCAL( FT_Error)
  420   af_axis_hints_new_edge( AF_AxisHints  axis,
  421                           FT_Int        fpos,
  422                           AF_Direction  dir,
  423                           FT_Bool       top_to_bottom_hinting,
  424                           FT_Memory     memory,
  425                           AF_Edge      *edge );
  426 
  427   FT_LOCAL( void )
  428   af_glyph_hints_init( AF_GlyphHints  hints,
  429                        FT_Memory      memory );
  430 
  431   FT_LOCAL( void )
  432   af_glyph_hints_rescale( AF_GlyphHints    hints,
  433                           AF_StyleMetrics  metrics );
  434 
  435   FT_LOCAL( FT_Error )
  436   af_glyph_hints_reload( AF_GlyphHints  hints,
  437                          FT_Outline*    outline );
  438 
  439   FT_LOCAL( void )
  440   af_glyph_hints_save( AF_GlyphHints  hints,
  441                        FT_Outline*    outline );
  442 
  443   FT_LOCAL( void )
  444   af_glyph_hints_align_edge_points( AF_GlyphHints  hints,
  445                                     AF_Dimension   dim );
  446 
  447   FT_LOCAL( void )
  448   af_glyph_hints_align_strong_points( AF_GlyphHints  hints,
  449                                       AF_Dimension   dim );
  450 
  451   FT_LOCAL( void )
  452   af_glyph_hints_align_weak_points( AF_GlyphHints  hints,
  453                                     AF_Dimension   dim );
  454 
  455   FT_LOCAL( void )
  456   af_glyph_hints_done( AF_GlyphHints  hints );
  457 
  458 /* */
  459 
  460 #define AF_SEGMENT_LEN( seg )          ( (seg)->max_coord - (seg)->min_coord )
  461 
  462 #define AF_SEGMENT_DIST( seg1, seg2 )  ( ( (seg1)->pos > (seg2)->pos )   \
  463                                            ? (seg1)->pos - (seg2)->pos   \
  464                                            : (seg2)->pos - (seg1)->pos )
  465 
  466 
  467 FT_END_HEADER
  468 
  469 #endif /* AFHINTS_H_ */
  470 
  471 
  472 /* END */