Home | History | Annotate | Download | only in autofit
      1 /***************************************************************************/
      2 /*                                                                         */
      3 /*  aftypes.h                                                              */
      4 /*                                                                         */
      5 /*    Auto-fitter types (specification only).                              */
      6 /*                                                                         */
      7 /*  Copyright 2003-2018 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   /*************************************************************************
     20    *
     21    *  The auto-fitter is a complete rewrite of the old auto-hinter.
     22    *  Its main feature is the ability to differentiate between different
     23    *  writing systems and scripts in order to apply specific rules.
     24    *
     25    *  The code has also been compartmentalized into several entities that
     26    *  should make algorithmic experimentation easier than with the old
     27    *  code.
     28    *
     29    *************************************************************************/
     30 
     31 
     32 #ifndef AFTYPES_H_
     33 #define AFTYPES_H_
     34 
     35 #include <ft2build.h>
     36 
     37 #include FT_FREETYPE_H
     38 #include FT_OUTLINE_H
     39 #include FT_INTERNAL_OBJECTS_H
     40 #include FT_INTERNAL_DEBUG_H
     41 
     42 #include "afblue.h"
     43 
     44 #ifdef FT_DEBUG_AUTOFIT
     45 #include FT_CONFIG_STANDARD_LIBRARY_H
     46 #endif
     47 
     48 
     49 FT_BEGIN_HEADER
     50 
     51   /*************************************************************************/
     52   /*************************************************************************/
     53   /*****                                                               *****/
     54   /*****                    D E B U G G I N G                          *****/
     55   /*****                                                               *****/
     56   /*************************************************************************/
     57   /*************************************************************************/
     58 
     59 #ifdef FT_DEBUG_AUTOFIT
     60 
     61 extern int    _af_debug_disable_horz_hints;
     62 extern int    _af_debug_disable_vert_hints;
     63 extern int    _af_debug_disable_blue_hints;
     64 extern void*  _af_debug_hints;
     65 
     66 #endif /* FT_DEBUG_AUTOFIT */
     67 
     68 
     69   /*************************************************************************/
     70   /*************************************************************************/
     71   /*****                                                               *****/
     72   /*****                 U T I L I T Y   S T U F F                     *****/
     73   /*****                                                               *****/
     74   /*************************************************************************/
     75   /*************************************************************************/
     76 
     77   typedef struct  AF_WidthRec_
     78   {
     79     FT_Pos  org;  /* original position/width in font units              */
     80     FT_Pos  cur;  /* current/scaled position/width in device sub-pixels */
     81     FT_Pos  fit;  /* current/fitted position/width in device sub-pixels */
     82 
     83   } AF_WidthRec, *AF_Width;
     84 
     85 
     86   FT_LOCAL( void )
     87   af_sort_pos( FT_UInt  count,
     88                FT_Pos*  table );
     89 
     90   FT_LOCAL( void )
     91   af_sort_and_quantize_widths( FT_UInt*  count,
     92                                AF_Width  widths,
     93                                FT_Pos    threshold );
     94 
     95 
     96   /*************************************************************************/
     97   /*************************************************************************/
     98   /*****                                                               *****/
     99   /*****                   A N G L E   T Y P E S                       *****/
    100   /*****                                                               *****/
    101   /*************************************************************************/
    102   /*************************************************************************/
    103 
    104   /*
    105    *  The auto-fitter doesn't need a very high angular accuracy;
    106    *  this allows us to speed up some computations considerably with a
    107    *  light Cordic algorithm (see afangles.c).
    108    */
    109 
    110   typedef FT_Int  AF_Angle;
    111 
    112 
    113 #define AF_ANGLE_PI   256
    114 #define AF_ANGLE_2PI  ( AF_ANGLE_PI * 2 )
    115 #define AF_ANGLE_PI2  ( AF_ANGLE_PI / 2 )
    116 #define AF_ANGLE_PI4  ( AF_ANGLE_PI / 4 )
    117 
    118 
    119 #if 0
    120   /*
    121    *  compute the angle of a given 2-D vector
    122    */
    123   FT_LOCAL( AF_Angle )
    124   af_angle_atan( FT_Pos  dx,
    125                  FT_Pos  dy );
    126 
    127 
    128   /*
    129    *  compute `angle2 - angle1'; the result is always within
    130    *  the range [-AF_ANGLE_PI .. AF_ANGLE_PI - 1]
    131    */
    132   FT_LOCAL( AF_Angle )
    133   af_angle_diff( AF_Angle  angle1,
    134                  AF_Angle  angle2 );
    135 #endif /* 0 */
    136 
    137 
    138 #define AF_ANGLE_DIFF( result, angle1, angle2 ) \
    139   FT_BEGIN_STMNT                                \
    140     AF_Angle  _delta = (angle2) - (angle1);     \
    141                                                 \
    142                                                 \
    143     while ( _delta <= -AF_ANGLE_PI )            \
    144       _delta += AF_ANGLE_2PI;                   \
    145                                                 \
    146     while ( _delta > AF_ANGLE_PI )              \
    147       _delta -= AF_ANGLE_2PI;                   \
    148                                                 \
    149     result = _delta;                            \
    150   FT_END_STMNT
    151 
    152 
    153   /*  opaque handle to glyph-specific hints -- see `afhints.h' for more
    154    *  details
    155    */
    156   typedef struct AF_GlyphHintsRec_*  AF_GlyphHints;
    157 
    158 
    159   /*************************************************************************/
    160   /*************************************************************************/
    161   /*****                                                               *****/
    162   /*****                       S C A L E R S                           *****/
    163   /*****                                                               *****/
    164   /*************************************************************************/
    165   /*************************************************************************/
    166 
    167   /*
    168    *  A scaler models the target pixel device that will receive the
    169    *  auto-hinted glyph image.
    170    */
    171 
    172 #define AF_SCALER_FLAG_NO_HORIZONTAL  1U /* disable horizontal hinting */
    173 #define AF_SCALER_FLAG_NO_VERTICAL    2U /* disable vertical hinting   */
    174 #define AF_SCALER_FLAG_NO_ADVANCE     4U /* disable advance hinting    */
    175 #define AF_SCALER_FLAG_NO_WARPER      8U /* disable warper             */
    176 
    177 
    178   typedef struct  AF_ScalerRec_
    179   {
    180     FT_Face         face;        /* source font face                        */
    181     FT_Fixed        x_scale;     /* from font units to 1/64th device pixels */
    182     FT_Fixed        y_scale;     /* from font units to 1/64th device pixels */
    183     FT_Pos          x_delta;     /* in 1/64th device pixels                 */
    184     FT_Pos          y_delta;     /* in 1/64th device pixels                 */
    185     FT_Render_Mode  render_mode; /* monochrome, anti-aliased, LCD, etc.     */
    186     FT_UInt32       flags;       /* additional control flags, see above     */
    187 
    188   } AF_ScalerRec, *AF_Scaler;
    189 
    190 
    191 #define AF_SCALER_EQUAL_SCALES( a, b )      \
    192           ( (a)->x_scale == (b)->x_scale && \
    193             (a)->y_scale == (b)->y_scale && \
    194             (a)->x_delta == (b)->x_delta && \
    195             (a)->y_delta == (b)->y_delta )
    196 
    197 
    198   typedef struct AF_StyleMetricsRec_*  AF_StyleMetrics;
    199 
    200   /*  This function parses an FT_Face to compute global metrics for
    201    *  a specific style.
    202    */
    203   typedef FT_Error
    204   (*AF_WritingSystem_InitMetricsFunc)( AF_StyleMetrics  metrics,
    205                                        FT_Face          face );
    206 
    207   typedef void
    208   (*AF_WritingSystem_ScaleMetricsFunc)( AF_StyleMetrics  metrics,
    209                                         AF_Scaler        scaler );
    210 
    211   typedef void
    212   (*AF_WritingSystem_DoneMetricsFunc)( AF_StyleMetrics  metrics );
    213 
    214   typedef void
    215   (*AF_WritingSystem_GetStdWidthsFunc)( AF_StyleMetrics  metrics,
    216                                         FT_Pos*          stdHW,
    217                                         FT_Pos*          stdVW );
    218 
    219 
    220   typedef FT_Error
    221   (*AF_WritingSystem_InitHintsFunc)( AF_GlyphHints    hints,
    222                                      AF_StyleMetrics  metrics );
    223 
    224   typedef FT_Error
    225   (*AF_WritingSystem_ApplyHintsFunc)( FT_UInt          glyph_index,
    226                                       AF_GlyphHints    hints,
    227                                       FT_Outline*      outline,
    228                                       AF_StyleMetrics  metrics );
    229 
    230 
    231   /*************************************************************************/
    232   /*************************************************************************/
    233   /*****                                                               *****/
    234   /*****                W R I T I N G   S Y S T E M S                  *****/
    235   /*****                                                               *****/
    236   /*************************************************************************/
    237   /*************************************************************************/
    238 
    239   /*
    240    *  For the auto-hinter, a writing system consists of multiple scripts that
    241    *  can be handled similarly *in a typographical way*; the relationship is
    242    *  not based on history.  For example, both the Greek and the unrelated
    243    *  Armenian scripts share the same features like ascender, descender,
    244    *  x-height, etc.  Essentially, a writing system is covered by a
    245    *  submodule of the auto-fitter; it contains
    246    *
    247    *  - a specific global analyzer that computes global metrics specific to
    248    *    the script (based on script-specific characters to identify ascender
    249    *    height, x-height, etc.),
    250    *
    251    *  - a specific glyph analyzer that computes segments and edges for each
    252    *    glyph covered by the script,
    253    *
    254    *  - a specific grid-fitting algorithm that distorts the scaled glyph
    255    *    outline according to the results of the glyph analyzer.
    256    */
    257 
    258 #define AFWRTSYS_H_  /* don't load header files */
    259 #undef  WRITING_SYSTEM
    260 #define WRITING_SYSTEM( ws, WS )    \
    261           AF_WRITING_SYSTEM_ ## WS,
    262 
    263   /* The list of known writing systems. */
    264   typedef enum  AF_WritingSystem_
    265   {
    266 
    267 #include "afwrtsys.h"
    268 
    269     AF_WRITING_SYSTEM_MAX   /* do not remove */
    270 
    271   } AF_WritingSystem;
    272 
    273 #undef  AFWRTSYS_H_
    274 
    275 
    276   typedef struct  AF_WritingSystemClassRec_
    277   {
    278     AF_WritingSystem  writing_system;
    279 
    280     FT_Offset                          style_metrics_size;
    281     AF_WritingSystem_InitMetricsFunc   style_metrics_init;
    282     AF_WritingSystem_ScaleMetricsFunc  style_metrics_scale;
    283     AF_WritingSystem_DoneMetricsFunc   style_metrics_done;
    284     AF_WritingSystem_GetStdWidthsFunc  style_metrics_getstdw;
    285 
    286     AF_WritingSystem_InitHintsFunc     style_hints_init;
    287     AF_WritingSystem_ApplyHintsFunc    style_hints_apply;
    288 
    289   } AF_WritingSystemClassRec;
    290 
    291   typedef const AF_WritingSystemClassRec*  AF_WritingSystemClass;
    292 
    293 
    294   /*************************************************************************/
    295   /*************************************************************************/
    296   /*****                                                               *****/
    297   /*****                        S C R I P T S                          *****/
    298   /*****                                                               *****/
    299   /*************************************************************************/
    300   /*************************************************************************/
    301 
    302   /*
    303    *  Each script is associated with two sets of Unicode ranges to test
    304    *  whether the font face supports the script, and which non-base
    305    *  characters the script contains.
    306    *
    307    *  We use four-letter script tags from the OpenType specification,
    308    *  extended by `NONE', which indicates `no script'.
    309    */
    310 
    311 #undef  SCRIPT
    312 #define SCRIPT( s, S, d, h, H, ss ) \
    313           AF_SCRIPT_ ## S,
    314 
    315   /* The list of known scripts. */
    316   typedef enum  AF_Script_
    317   {
    318 
    319 #include "afscript.h"
    320 
    321     AF_SCRIPT_MAX   /* do not remove */
    322 
    323   } AF_Script;
    324 
    325 
    326   typedef struct  AF_Script_UniRangeRec_
    327   {
    328     FT_UInt32  first;
    329     FT_UInt32  last;
    330 
    331   } AF_Script_UniRangeRec;
    332 
    333 #define AF_UNIRANGE_REC( a, b ) { (FT_UInt32)(a), (FT_UInt32)(b) }
    334 
    335   typedef const AF_Script_UniRangeRec*  AF_Script_UniRange;
    336 
    337 
    338   typedef struct  AF_ScriptClassRec_
    339   {
    340     AF_Script  script;
    341 
    342     /* last element in the ranges must be { 0, 0 } */
    343     AF_Script_UniRange  script_uni_ranges;
    344     AF_Script_UniRange  script_uni_nonbase_ranges;
    345 
    346     FT_Bool  top_to_bottom_hinting;
    347 
    348     const char*  standard_charstring;      /* for default width and height */
    349 
    350   } AF_ScriptClassRec;
    351 
    352   typedef const AF_ScriptClassRec*  AF_ScriptClass;
    353 
    354 
    355   /*************************************************************************/
    356   /*************************************************************************/
    357   /*****                                                               *****/
    358   /*****                      C O V E R A G E S                        *****/
    359   /*****                                                               *****/
    360   /*************************************************************************/
    361   /*************************************************************************/
    362 
    363   /*
    364    *  Usually, a font contains more glyphs than can be addressed by its
    365    *  character map.
    366    *
    367    *  In the PostScript font world, encoding vectors specific to a given
    368    *  task are used to select such glyphs, and these glyphs can be often
    369    *  recognized by having a suffix in its glyph names.  For example, a
    370    *  superscript glyph `A' might be called `A.sup'.  Unfortunately, this
    371    *  naming scheme is not standardized and thus unusable for us.
    372    *
    373    *  In the OpenType world, a better solution was invented, namely
    374    *  `features', which cleanly separate a character's input encoding from
    375    *  the corresponding glyph's appearance, and which don't use glyph names
    376    *  at all.  For our purposes, and slightly generalized, an OpenType
    377    *  feature is a name of a mapping that maps character codes to
    378    *  non-standard glyph indices (features get used for other things also).
    379    *  For example, the `sups' feature provides superscript glyphs, thus
    380    *  mapping character codes like `A' or `B' to superscript glyph
    381    *  representation forms.  How this mapping happens is completely
    382    *  uninteresting to us.
    383    *
    384    *  For the auto-hinter, a `coverage' represents all glyphs of an OpenType
    385    *  feature collected in a set (as listed below) that can be hinted
    386    *  together.  To continue the above example, superscript glyphs must not
    387    *  be hinted together with normal glyphs because the blue zones
    388    *  completely differ.
    389    *
    390    *  Note that FreeType itself doesn't compute coverages; it only provides
    391    *  the glyphs addressable by the default Unicode character map.  Instead,
    392    *  we use the HarfBuzz library (if available), which has many functions
    393    *  exactly for this purpose.
    394    *
    395    *  AF_COVERAGE_DEFAULT is special: It should cover everything that isn't
    396    *  listed separately (including the glyphs addressable by the character
    397    *  map).  In case HarfBuzz isn't available, it exactly covers the glyphs
    398    *  addressable by the character map.
    399    *
    400    */
    401 
    402 #undef  COVERAGE
    403 #define COVERAGE( name, NAME, description, \
    404                   tag1, tag2, tag3, tag4 ) \
    405           AF_COVERAGE_ ## NAME,
    406 
    407 
    408   typedef enum  AF_Coverage_
    409   {
    410 #include "afcover.h"
    411 
    412     AF_COVERAGE_DEFAULT
    413 
    414   } AF_Coverage;
    415 
    416 
    417   /*************************************************************************/
    418   /*************************************************************************/
    419   /*****                                                               *****/
    420   /*****                         S T Y L E S                           *****/
    421   /*****                                                               *****/
    422   /*************************************************************************/
    423   /*************************************************************************/
    424 
    425   /*
    426    *  The topmost structure for modelling the auto-hinter glyph input data
    427    *  is a `style class', grouping everything together.
    428    */
    429 
    430 #undef  STYLE
    431 #define STYLE( s, S, d, ws, sc, ss, c ) \
    432           AF_STYLE_ ## S,
    433 
    434   /* The list of known styles. */
    435   typedef enum  AF_Style_
    436   {
    437 
    438 #include "afstyles.h"
    439 
    440     AF_STYLE_MAX   /* do not remove */
    441 
    442   } AF_Style;
    443 
    444 
    445   typedef struct  AF_StyleClassRec_
    446   {
    447     AF_Style  style;
    448 
    449     AF_WritingSystem   writing_system;
    450     AF_Script          script;
    451     AF_Blue_Stringset  blue_stringset;
    452     AF_Coverage        coverage;
    453 
    454   } AF_StyleClassRec;
    455 
    456   typedef const AF_StyleClassRec*  AF_StyleClass;
    457 
    458 
    459   /*************************************************************************/
    460   /*************************************************************************/
    461   /*****                                                               *****/
    462   /*****                   S T Y L E   M E T R I C S                   *****/
    463   /*****                                                               *****/
    464   /*************************************************************************/
    465   /*************************************************************************/
    466 
    467   typedef struct AF_FaceGlobalsRec_*  AF_FaceGlobals;
    468 
    469   /* This is the main structure that combines everything.  Autofit modules */
    470   /* specific to writing systems derive their structures from it, for      */
    471   /* example `AF_LatinMetrics'.                                            */
    472 
    473   typedef struct  AF_StyleMetricsRec_
    474   {
    475     AF_StyleClass   style_class;
    476     AF_ScalerRec    scaler;
    477     FT_Bool         digits_have_same_width;
    478 
    479     AF_FaceGlobals  globals;    /* to access properties */
    480 
    481   } AF_StyleMetricsRec;
    482 
    483 
    484 #define AF_HINTING_BOTTOM_TO_TOP  0
    485 #define AF_HINTING_TOP_TO_BOTTOM  1
    486 
    487 
    488   /* Declare and define vtables for classes */
    489 #ifndef FT_CONFIG_OPTION_PIC
    490 
    491 #define AF_DECLARE_WRITING_SYSTEM_CLASS( writing_system_class ) \
    492   FT_CALLBACK_TABLE const AF_WritingSystemClassRec              \
    493   writing_system_class;
    494 
    495 #define AF_DEFINE_WRITING_SYSTEM_CLASS(                  \
    496           writing_system_class,                          \
    497           system,                                        \
    498           m_size,                                        \
    499           m_init,                                        \
    500           m_scale,                                       \
    501           m_done,                                        \
    502           m_stdw,                                        \
    503           h_init,                                        \
    504           h_apply )                                      \
    505   FT_CALLBACK_TABLE_DEF                                  \
    506   const AF_WritingSystemClassRec  writing_system_class = \
    507   {                                                      \
    508     system,                                              \
    509                                                          \
    510     m_size,                                              \
    511                                                          \
    512     m_init,                                              \
    513     m_scale,                                             \
    514     m_done,                                              \
    515     m_stdw,                                              \
    516                                                          \
    517     h_init,                                              \
    518     h_apply                                              \
    519   };
    520 
    521 
    522 #define AF_DECLARE_SCRIPT_CLASS( script_class ) \
    523   FT_CALLBACK_TABLE const AF_ScriptClassRec     \
    524   script_class;
    525 
    526 #define AF_DEFINE_SCRIPT_CLASS(           \
    527           script_class,                   \
    528           script,                         \
    529           ranges,                         \
    530           nonbase_ranges,                 \
    531           top_to_bottom,                  \
    532           std_charstring )                \
    533   FT_CALLBACK_TABLE_DEF                   \
    534   const AF_ScriptClassRec  script_class = \
    535   {                                       \
    536     script,                               \
    537     ranges,                               \
    538     nonbase_ranges,                       \
    539     top_to_bottom,                        \
    540     std_charstring,                       \
    541   };
    542 
    543 
    544 #define AF_DECLARE_STYLE_CLASS( style_class ) \
    545   FT_CALLBACK_TABLE const AF_StyleClassRec    \
    546   style_class;
    547 
    548 #define AF_DEFINE_STYLE_CLASS(          \
    549           style_class,                  \
    550           style,                        \
    551           writing_system,               \
    552           script,                       \
    553           blue_stringset,               \
    554           coverage )                    \
    555   FT_CALLBACK_TABLE_DEF                 \
    556   const AF_StyleClassRec  style_class = \
    557   {                                     \
    558     style,                              \
    559     writing_system,                     \
    560     script,                             \
    561     blue_stringset,                     \
    562     coverage                            \
    563   };
    564 
    565 #else /* FT_CONFIG_OPTION_PIC */
    566 
    567 #define AF_DECLARE_WRITING_SYSTEM_CLASS( writing_system_class )            \
    568   FT_LOCAL( void )                                                         \
    569   FT_Init_Class_ ## writing_system_class( AF_WritingSystemClassRec*  ac );
    570 
    571 #define AF_DEFINE_WRITING_SYSTEM_CLASS(                                   \
    572           writing_system_class,                                           \
    573           system,                                                         \
    574           m_size,                                                         \
    575           m_init,                                                         \
    576           m_scale,                                                        \
    577           m_done,                                                         \
    578           m_stdw,                                                         \
    579           h_init,                                                         \
    580           h_apply )                                                       \
    581   FT_LOCAL_DEF( void )                                                    \
    582   FT_Init_Class_ ## writing_system_class( AF_WritingSystemClassRec*  ac ) \
    583   {                                                                       \
    584     ac->writing_system        = system;                                   \
    585                                                                           \
    586     ac->style_metrics_size    = m_size;                                   \
    587                                                                           \
    588     ac->style_metrics_init    = m_init;                                   \
    589     ac->style_metrics_scale   = m_scale;                                  \
    590     ac->style_metrics_done    = m_done;                                   \
    591     ac->style_metrics_getstdw = m_stdw;                                   \
    592                                                                           \
    593     ac->style_hints_init      = h_init;                                   \
    594     ac->style_hints_apply     = h_apply;                                  \
    595   }
    596 
    597 
    598 #define AF_DECLARE_SCRIPT_CLASS( script_class )             \
    599   FT_LOCAL( void )                                          \
    600   FT_Init_Class_ ## script_class( AF_ScriptClassRec*  ac );
    601 
    602 #define AF_DEFINE_SCRIPT_CLASS(                            \
    603           script_class,                                    \
    604           script_,                                         \
    605           ranges,                                          \
    606           nonbase_ranges,                                  \
    607           top_to_bottom,                                   \
    608           std_charstring )                                 \
    609   FT_LOCAL_DEF( void )                                     \
    610   FT_Init_Class_ ## script_class( AF_ScriptClassRec*  ac ) \
    611   {                                                        \
    612     ac->script                    = script_;               \
    613     ac->script_uni_ranges         = ranges;                \
    614     ac->script_uni_nonbase_ranges = nonbase_ranges;        \
    615     ac->top_to_bottom_hinting     = top_to_bottom;         \
    616     ac->standard_charstring       = std_charstring;        \
    617   }
    618 
    619 
    620 #define AF_DECLARE_STYLE_CLASS( style_class )             \
    621   FT_LOCAL( void )                                        \
    622   FT_Init_Class_ ## style_class( AF_StyleClassRec*  ac );
    623 
    624 #define AF_DEFINE_STYLE_CLASS(                           \
    625           style_class,                                   \
    626           style_,                                        \
    627           writing_system_,                               \
    628           script_,                                       \
    629           blue_stringset_,                               \
    630           coverage_ )                                    \
    631   FT_LOCAL_DEF( void )                                   \
    632   FT_Init_Class_ ## style_class( AF_StyleClassRec*  ac ) \
    633   {                                                      \
    634     ac->style          = style_;                         \
    635     ac->writing_system = writing_system_;                \
    636     ac->script         = script_;                        \
    637     ac->blue_stringset = blue_stringset_;                \
    638     ac->coverage       = coverage_;                      \
    639   }
    640 
    641 #endif /* FT_CONFIG_OPTION_PIC */
    642 
    643 
    644 /* */
    645 
    646 FT_END_HEADER
    647 
    648 #endif /* AFTYPES_H_ */
    649 
    650 
    651 /* END */
    652