1 /****************************************************************************
   2  *
   3  * aftypes.h
   4  *
   5  *   Auto-fitter types (specification only).
   6  *
   7  * Copyright (C) 2003-2020 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 subpixels */
  81     FT_Pos  fit;  /* current/fitted position/width in device subpixels */
  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   /*
 154    * opaque handle to glyph-specific hints -- see `afhints.h' for more
 155    * details
 156    */
 157   typedef struct AF_GlyphHintsRec_*  AF_GlyphHints;
 158 
 159 
 160   /*************************************************************************/
 161   /*************************************************************************/
 162   /*****                                                               *****/
 163   /*****                       S C A L E R S                           *****/
 164   /*****                                                               *****/
 165   /*************************************************************************/
 166   /*************************************************************************/
 167 
 168   /*
 169    * A scaler models the target pixel device that will receive the
 170    * auto-hinted glyph image.
 171    */
 172 
 173 #define AF_SCALER_FLAG_NO_HORIZONTAL  1U /* disable horizontal hinting */
 174 #define AF_SCALER_FLAG_NO_VERTICAL    2U /* disable vertical hinting   */
 175 #define AF_SCALER_FLAG_NO_ADVANCE     4U /* disable advance hinting    */
 176 #define AF_SCALER_FLAG_NO_WARPER      8U /* disable warper             */
 177 
 178 
 179   typedef struct  AF_ScalerRec_
 180   {
 181     FT_Face         face;        /* source font face                        */
 182     FT_Fixed        x_scale;     /* from font units to 1/64th device pixels */
 183     FT_Fixed        y_scale;     /* from font units to 1/64th device pixels */
 184     FT_Pos          x_delta;     /* in 1/64th device pixels                 */
 185     FT_Pos          y_delta;     /* in 1/64th device pixels                 */
 186     FT_Render_Mode  render_mode; /* monochrome, anti-aliased, LCD, etc.     */
 187     FT_UInt32       flags;       /* additional control flags, see above     */
 188 
 189   } AF_ScalerRec, *AF_Scaler;
 190 
 191 
 192 #define AF_SCALER_EQUAL_SCALES( a, b )      \
 193           ( (a)->x_scale == (b)->x_scale && \
 194             (a)->y_scale == (b)->y_scale && \
 195             (a)->x_delta == (b)->x_delta && \
 196             (a)->y_delta == (b)->y_delta )
 197 
 198 
 199   typedef struct AF_StyleMetricsRec_*  AF_StyleMetrics;
 200 
 201   /*
 202    * This function parses an FT_Face to compute global metrics for
 203    * a specific style.
 204    */
 205   typedef FT_Error
 206   (*AF_WritingSystem_InitMetricsFunc)( AF_StyleMetrics  metrics,
 207                                        FT_Face          face );
 208 
 209   typedef void
 210   (*AF_WritingSystem_ScaleMetricsFunc)( AF_StyleMetrics  metrics,
 211                                         AF_Scaler        scaler );
 212 
 213   typedef void
 214   (*AF_WritingSystem_DoneMetricsFunc)( AF_StyleMetrics  metrics );
 215 
 216   typedef void
 217   (*AF_WritingSystem_GetStdWidthsFunc)( AF_StyleMetrics  metrics,
 218                                         FT_Pos*          stdHW,
 219                                         FT_Pos*          stdVW );
 220 
 221 
 222   typedef FT_Error
 223   (*AF_WritingSystem_InitHintsFunc)( AF_GlyphHints    hints,
 224                                      AF_StyleMetrics  metrics );
 225 
 226   typedef FT_Error
 227   (*AF_WritingSystem_ApplyHintsFunc)( FT_UInt          glyph_index,
 228                                       AF_GlyphHints    hints,
 229                                       FT_Outline*      outline,
 230                                       AF_StyleMetrics  metrics );
 231 
 232 
 233   /*************************************************************************/
 234   /*************************************************************************/
 235   /*****                                                               *****/
 236   /*****                W R I T I N G   S Y S T E M S                  *****/
 237   /*****                                                               *****/
 238   /*************************************************************************/
 239   /*************************************************************************/
 240 
 241   /*
 242    * For the auto-hinter, a writing system consists of multiple scripts that
 243    * can be handled similarly *in a typographical way*; the relationship is
 244    * not based on history.  For example, both the Greek and the unrelated
 245    * Armenian scripts share the same features like ascender, descender,
 246    * x-height, etc.  Essentially, a writing system is covered by a
 247    * submodule of the auto-fitter; it contains
 248    *
 249    * - a specific global analyzer that computes global metrics specific to
 250    *   the script (based on script-specific characters to identify ascender
 251    *   height, x-height, etc.),
 252    *
 253    * - a specific glyph analyzer that computes segments and edges for each
 254    *   glyph covered by the script,
 255    *
 256    * - a specific grid-fitting algorithm that distorts the scaled glyph
 257    *   outline according to the results of the glyph analyzer.
 258    */
 259 
 260 #define AFWRTSYS_H_  /* don't load header files */
 261 #undef  WRITING_SYSTEM
 262 #define WRITING_SYSTEM( ws, WS )    \
 263           AF_WRITING_SYSTEM_ ## WS,
 264 
 265   /* The list of known writing systems. */
 266   typedef enum  AF_WritingSystem_
 267   {
 268 
 269 #include "afwrtsys.h"
 270 
 271     AF_WRITING_SYSTEM_MAX   /* do not remove */
 272 
 273   } AF_WritingSystem;
 274 
 275 #undef  AFWRTSYS_H_
 276 
 277 
 278   typedef struct  AF_WritingSystemClassRec_
 279   {
 280     AF_WritingSystem  writing_system;
 281 
 282     FT_Offset                          style_metrics_size;
 283     AF_WritingSystem_InitMetricsFunc   style_metrics_init;
 284     AF_WritingSystem_ScaleMetricsFunc  style_metrics_scale;
 285     AF_WritingSystem_DoneMetricsFunc   style_metrics_done;
 286     AF_WritingSystem_GetStdWidthsFunc  style_metrics_getstdw;
 287 
 288     AF_WritingSystem_InitHintsFunc     style_hints_init;
 289     AF_WritingSystem_ApplyHintsFunc    style_hints_apply;
 290 
 291   } AF_WritingSystemClassRec;
 292 
 293   typedef const AF_WritingSystemClassRec*  AF_WritingSystemClass;
 294 
 295 
 296   /*************************************************************************/
 297   /*************************************************************************/
 298   /*****                                                               *****/
 299   /*****                        S C R I P T S                          *****/
 300   /*****                                                               *****/
 301   /*************************************************************************/
 302   /*************************************************************************/
 303 
 304   /*
 305    * Each script is associated with two sets of Unicode ranges to test
 306    * whether the font face supports the script, and which non-base
 307    * characters the script contains.
 308    *
 309    * We use four-letter script tags from the OpenType specification,
 310    * extended by `NONE', which indicates `no script'.
 311    */
 312 
 313 #undef  SCRIPT
 314 #define SCRIPT( s, S, d, h, H, ss ) \
 315           AF_SCRIPT_ ## S,
 316 
 317   /* The list of known scripts. */
 318   typedef enum  AF_Script_
 319   {
 320 
 321 #include "afscript.h"
 322 
 323     AF_SCRIPT_MAX   /* do not remove */
 324 
 325   } AF_Script;
 326 
 327 
 328   typedef struct  AF_Script_UniRangeRec_
 329   {
 330     FT_UInt32  first;
 331     FT_UInt32  last;
 332 
 333   } AF_Script_UniRangeRec;
 334 
 335 #define AF_UNIRANGE_REC( a, b ) { (FT_UInt32)(a), (FT_UInt32)(b) }
 336 
 337   typedef const AF_Script_UniRangeRec*  AF_Script_UniRange;
 338 
 339 
 340   typedef struct  AF_ScriptClassRec_
 341   {
 342     AF_Script  script;
 343 
 344     /* last element in the ranges must be { 0, 0 } */
 345     AF_Script_UniRange  script_uni_ranges;
 346     AF_Script_UniRange  script_uni_nonbase_ranges;
 347 
 348     FT_Bool  top_to_bottom_hinting;
 349 
 350     const char*  standard_charstring;      /* for default width and height */
 351 
 352   } AF_ScriptClassRec;
 353 
 354   typedef const AF_ScriptClassRec*  AF_ScriptClass;
 355 
 356 
 357   /*************************************************************************/
 358   /*************************************************************************/
 359   /*****                                                               *****/
 360   /*****                      C O V E R A G E S                        *****/
 361   /*****                                                               *****/
 362   /*************************************************************************/
 363   /*************************************************************************/
 364 
 365   /*
 366    * Usually, a font contains more glyphs than can be addressed by its
 367    * character map.
 368    *
 369    * In the PostScript font world, encoding vectors specific to a given
 370    * task are used to select such glyphs, and these glyphs can be often
 371    * recognized by having a suffix in its glyph names.  For example, a
 372    * superscript glyph `A' might be called `A.sup'.  Unfortunately, this
 373    * naming scheme is not standardized and thus unusable for us.
 374    *
 375    * In the OpenType world, a better solution was invented, namely
 376    * `features', which cleanly separate a character's input encoding from
 377    * the corresponding glyph's appearance, and which don't use glyph names
 378    * at all.  For our purposes, and slightly generalized, an OpenType
 379    * feature is a name of a mapping that maps character codes to
 380    * non-standard glyph indices (features get used for other things also).
 381    * For example, the `sups' feature provides superscript glyphs, thus
 382    * mapping character codes like `A' or `B' to superscript glyph
 383    * representation forms.  How this mapping happens is completely
 384    * uninteresting to us.
 385    *
 386    * For the auto-hinter, a `coverage' represents all glyphs of an OpenType
 387    * feature collected in a set (as listed below) that can be hinted
 388    * together.  To continue the above example, superscript glyphs must not
 389    * be hinted together with normal glyphs because the blue zones
 390    * completely differ.
 391    *
 392    * Note that FreeType itself doesn't compute coverages; it only provides
 393    * the glyphs addressable by the default Unicode character map.  Instead,
 394    * we use the HarfBuzz library (if available), which has many functions
 395    * exactly for this purpose.
 396    *
 397    * AF_COVERAGE_DEFAULT is special: It should cover everything that isn't
 398    * listed separately (including the glyphs addressable by the character
 399    * map).  In case HarfBuzz isn't available, it exactly covers the glyphs
 400    * addressable by the character map.
 401    *
 402    */
 403 
 404 #undef  COVERAGE
 405 #define COVERAGE( name, NAME, description, \
 406                   tag1, tag2, tag3, tag4 ) \
 407           AF_COVERAGE_ ## NAME,
 408 
 409 
 410   typedef enum  AF_Coverage_
 411   {
 412 #include "afcover.h"
 413 
 414     AF_COVERAGE_DEFAULT
 415 
 416   } AF_Coverage;
 417 
 418 
 419   /*************************************************************************/
 420   /*************************************************************************/
 421   /*****                                                               *****/
 422   /*****                         S T Y L E S                           *****/
 423   /*****                                                               *****/
 424   /*************************************************************************/
 425   /*************************************************************************/
 426 
 427   /*
 428    * The topmost structure for modelling the auto-hinter glyph input data
 429    * is a `style class', grouping everything together.
 430    */
 431 
 432 #undef  STYLE
 433 #define STYLE( s, S, d, ws, sc, ss, c ) \
 434           AF_STYLE_ ## S,
 435 
 436   /* The list of known styles. */
 437   typedef enum  AF_Style_
 438   {
 439 
 440 #include "afstyles.h"
 441 
 442     AF_STYLE_MAX   /* do not remove */
 443 
 444   } AF_Style;
 445 
 446 
 447   typedef struct  AF_StyleClassRec_
 448   {
 449     AF_Style  style;
 450 
 451     AF_WritingSystem   writing_system;
 452     AF_Script          script;
 453     AF_Blue_Stringset  blue_stringset;
 454     AF_Coverage        coverage;
 455 
 456   } AF_StyleClassRec;
 457 
 458   typedef const AF_StyleClassRec*  AF_StyleClass;
 459 
 460 
 461   /*************************************************************************/
 462   /*************************************************************************/
 463   /*****                                                               *****/
 464   /*****                   S T Y L E   M E T R I C S                   *****/
 465   /*****                                                               *****/
 466   /*************************************************************************/
 467   /*************************************************************************/
 468 
 469   typedef struct AF_FaceGlobalsRec_*  AF_FaceGlobals;
 470 
 471   /* This is the main structure that combines everything.  Autofit modules */
 472   /* specific to writing systems derive their structures from it, for      */
 473   /* example `AF_LatinMetrics'.                                            */
 474 
 475   typedef struct  AF_StyleMetricsRec_
 476   {
 477     AF_StyleClass   style_class;
 478     AF_ScalerRec    scaler;
 479     FT_Bool         digits_have_same_width;
 480 
 481     AF_FaceGlobals  globals;    /* to access properties */
 482 
 483   } AF_StyleMetricsRec;
 484 
 485 
 486 #define AF_HINTING_BOTTOM_TO_TOP  0
 487 #define AF_HINTING_TOP_TO_BOTTOM  1
 488 
 489 
 490   /* Declare and define vtables for classes */
 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 /* */
 566 
 567 
 568 FT_END_HEADER
 569 
 570 #endif /* AFTYPES_H_ */
 571 
 572 
 573 /* END */