/**************************************************************************** * * aflatin.c * * Auto-fitter hinting routines for latin writing system (body). * * Copyright (C) 2003-2023 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, * modified, and distributed under the terms of the FreeType project * license, LICENSE.TXT. By continuing to use, modify, or distribute * this file you indicate that you have read the license and * understand and accept it fully. * */ #include <freetype/ftadvanc.h> #include <freetype/internal/ftdebug.h> #include "afglobal.h" #include "aflatin.h" #include "aferrors.h" /************************************************************************** * * The macro FT_COMPONENT is used in trace mode. It is an implicit * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log * messages during execution. */ #undef FT_COMPONENT #define FT_COMPONENT … /* needed for computation of round vs. flat segments */ #define FLAT_THRESHOLD( x ) … /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** L A T I N G L O B A L M E T R I C S *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* Find segments and links, compute all stem widths, and initialize */ /* standard width and height for the glyph with given charcode. */ FT_LOCAL_DEF( void ) af_latin_metrics_init_widths( AF_LatinMetrics metrics, FT_Face face ) { … } static void af_latin_sort_blue( FT_UInt count, AF_LatinBlue* table ) { … } /* Find all blue zones. Flat segments give the reference points, */ /* round segments the overshoot positions. */ static int af_latin_metrics_init_blues( AF_LatinMetrics metrics, FT_Face face ) { … } /* Check whether all ASCII digits have the same advance width. */ FT_LOCAL_DEF( void ) af_latin_metrics_check_digits( AF_LatinMetrics metrics, FT_Face face ) { … } /* Initialize global metrics. */ FT_LOCAL_DEF( FT_Error ) af_latin_metrics_init( AF_StyleMetrics metrics_, /* AF_LatinMetrics */ FT_Face face ) { … } /* Adjust scaling value, then scale and shift widths */ /* and blue zones (if applicable) for given dimension. */ static void af_latin_metrics_scale_dim( AF_LatinMetrics metrics, AF_Scaler scaler, AF_Dimension dim ) { … } /* Scale global values in both directions. */ FT_LOCAL_DEF( void ) af_latin_metrics_scale( AF_StyleMetrics metrics_, /* AF_LatinMetrics */ AF_Scaler scaler ) { … } /* Extract standard_width from writing system/script specific */ /* metrics class. */ FT_CALLBACK_DEF( void ) af_latin_get_standard_widths( AF_StyleMetrics metrics_, /* AF_LatinMetrics */ FT_Pos* stdHW, FT_Pos* stdVW ) { … } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** L A T I N G L Y P H A N A L Y S I S *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* Walk over all contours and compute its segments. */ FT_LOCAL_DEF( FT_Error ) af_latin_hints_compute_segments( AF_GlyphHints hints, AF_Dimension dim ) { … } /* Link segments to form stems and serifs. If `width_count' and */ /* `widths' are non-zero, use them to fine-tune the scoring function. */ FT_LOCAL_DEF( void ) af_latin_hints_link_segments( AF_GlyphHints hints, FT_UInt width_count, AF_WidthRec* widths, AF_Dimension dim ) { … } /* Link segments to edges, using feature analysis for selection. */ FT_LOCAL_DEF( FT_Error ) af_latin_hints_compute_edges( AF_GlyphHints hints, AF_Dimension dim ) { … } /* Detect segments and edges for given dimension. */ FT_LOCAL_DEF( FT_Error ) af_latin_hints_detect_features( AF_GlyphHints hints, FT_UInt width_count, AF_WidthRec* widths, AF_Dimension dim ) { … } /* Compute all edges which lie within blue zones. */ static void af_latin_hints_compute_blue_edges( AF_GlyphHints hints, AF_LatinMetrics metrics ) { … } /* Initalize hinting engine. */ static FT_Error af_latin_hints_init( AF_GlyphHints hints, AF_StyleMetrics metrics_ ) /* AF_LatinMetrics */ { … } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** L A T I N G L Y P H G R I D - F I T T I N G *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* Snap a given width in scaled coordinates to one of the */ /* current standard widths. */ static FT_Pos af_latin_snap_width( AF_Width widths, FT_UInt count, FT_Pos width ) { … } /* Compute the snapped width of a given stem, ignoring very thin ones. */ /* There is a lot of voodoo in this function; changing the hard-coded */ /* parameters influence the whole hinting process. */ static FT_Pos af_latin_compute_stem_width( AF_GlyphHints hints, AF_Dimension dim, FT_Pos width, FT_Pos base_delta, FT_UInt base_flags, FT_UInt stem_flags ) { … } /* Align one stem edge relative to the previous stem edge. */ static void af_latin_align_linked_edge( AF_GlyphHints hints, AF_Dimension dim, AF_Edge base_edge, AF_Edge stem_edge ) { … } /* Shift the coordinates of the `serif' edge by the same amount */ /* as the corresponding `base' edge has been moved already. */ static void af_latin_align_serif_edge( AF_GlyphHints hints, AF_Edge base, AF_Edge serif ) { … } /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** E D G E H I N T I N G ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* The main grid-fitting routine. */ static void af_latin_hint_edges( AF_GlyphHints hints, AF_Dimension dim ) { … } /* Apply the complete hinting algorithm to a latin glyph. */ static FT_Error af_latin_hints_apply( FT_UInt glyph_index, AF_GlyphHints hints, FT_Outline* outline, AF_StyleMetrics metrics_ ) /* AF_LatinMetrics */ { … } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** L A T I N S C R I P T C L A S S *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ AF_DEFINE_WRITING_SYSTEM_CLASS( af_latin_writing_system_class, AF_WRITING_SYSTEM_LATIN, sizeof ( AF_LatinMetricsRec ), (AF_WritingSystem_InitMetricsFunc) af_latin_metrics_init, /* style_metrics_init */ (AF_WritingSystem_ScaleMetricsFunc)af_latin_metrics_scale, /* style_metrics_scale */ (AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done */ (AF_WritingSystem_GetStdWidthsFunc)af_latin_get_standard_widths, /* style_metrics_getstdw */ (AF_WritingSystem_InitHintsFunc) af_latin_hints_init, /* style_hints_init */ (AF_WritingSystem_ApplyHintsFunc) af_latin_hints_apply /* style_hints_apply */ ) /* END */