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 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   /*  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 */