/**************************************************************************** * * afcjk.c * * Auto-fitter hinting routines for CJK writing system (body). * * Copyright (C) 2006-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. * */ /* * The algorithm is based on akito's autohint patch, archived at * * https://web.archive.org/web/20051219160454/http://www.kde.gr.jp:80/~akito/patch/freetype2/2.1.7/ * */ #include <freetype/ftadvanc.h> #include <freetype/internal/ftdebug.h> #include "afglobal.h" #include "aflatin.h" #include "afcjk.h" #ifdef AF_CONFIG_OPTION_CJK #undef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT #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 … /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** C J K G L O B A L M E T R I C S *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* Basically the Latin version with AF_CJKMetrics */ /* to replace AF_LatinMetrics. */ FT_LOCAL_DEF( void ) af_cjk_metrics_init_widths( AF_CJKMetrics metrics, FT_Face face ) { … } /* Find all blue zones. */ static void af_cjk_metrics_init_blues( AF_CJKMetrics metrics, FT_Face face ) { … } /* Basically the Latin version with type AF_CJKMetrics for metrics. */ FT_LOCAL_DEF( void ) af_cjk_metrics_check_digits( AF_CJKMetrics metrics, FT_Face face ) { … } /* Initialize global metrics. */ FT_LOCAL_DEF( FT_Error ) af_cjk_metrics_init( AF_StyleMetrics metrics_, /* AF_CJKMetrics */ FT_Face face ) { … } /* Adjust scaling value, then scale and shift widths */ /* and blue zones (if applicable) for given dimension. */ static void af_cjk_metrics_scale_dim( AF_CJKMetrics metrics, AF_Scaler scaler, AF_Dimension dim ) { … } /* Scale global values in both directions. */ FT_LOCAL_DEF( void ) af_cjk_metrics_scale( AF_StyleMetrics metrics_, /* AF_CJKMetrics */ AF_Scaler scaler ) { … } /* Extract standard_width from writing system/script specific */ /* metrics class. */ FT_CALLBACK_DEF( void ) af_cjk_get_standard_widths( AF_StyleMetrics metrics_, /* AF_CJKMetrics */ FT_Pos* stdHW, FT_Pos* stdVW ) { … } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** C J K G L Y P H A N A L Y S I S *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* Walk over all contours and compute its segments. */ static FT_Error af_cjk_hints_compute_segments( AF_GlyphHints hints, AF_Dimension dim ) { … } static void af_cjk_hints_link_segments( AF_GlyphHints hints, AF_Dimension dim ) { … } static FT_Error af_cjk_hints_compute_edges( AF_GlyphHints hints, AF_Dimension dim ) { … } /* Detect segments and edges for given dimension. */ static FT_Error af_cjk_hints_detect_features( AF_GlyphHints hints, AF_Dimension dim ) { … } /* Compute all edges which lie within blue zones. */ static void af_cjk_hints_compute_blue_edges( AF_GlyphHints hints, AF_CJKMetrics metrics, AF_Dimension dim ) { … } /* Initalize hinting engine. */ FT_LOCAL_DEF( FT_Error ) af_cjk_hints_init( AF_GlyphHints hints, AF_StyleMetrics metrics_ ) /* AF_CJKMetrics */ { … } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** C J K 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_cjk_snap_width( AF_Width widths, FT_UInt count, FT_Pos width ) { … } /* Compute the snapped width of a given stem. */ /* There is a lot of voodoo in this function; changing the hard-coded */ /* parameters influence the whole hinting process. */ static FT_Pos af_cjk_compute_stem_width( AF_GlyphHints hints, AF_Dimension dim, FT_Pos width, FT_UInt base_flags, FT_UInt stem_flags ) { … } /* Align one stem edge relative to the previous stem edge. */ static void af_cjk_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_cjk_align_serif_edge( AF_GlyphHints hints, AF_Edge base, AF_Edge serif ) { … } /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** E D G E H I N T I N G ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ #define AF_LIGHT_MODE_MAX_HORZ_GAP … #define AF_LIGHT_MODE_MAX_VERT_GAP … #define AF_LIGHT_MODE_MAX_DELTA_ABS … static FT_Pos af_hint_normal_stem( AF_GlyphHints hints, AF_Edge edge, AF_Edge edge2, FT_Pos anchor, AF_Dimension dim ) { … } /* The main grid-fitting routine. */ static void af_cjk_hint_edges( AF_GlyphHints hints, AF_Dimension dim ) { … } static void af_cjk_align_edge_points( AF_GlyphHints hints, AF_Dimension dim ) { … } /* Apply the complete hinting algorithm to a CJK glyph. */ FT_LOCAL_DEF( FT_Error ) af_cjk_hints_apply( FT_UInt glyph_index, AF_GlyphHints hints, FT_Outline* outline, AF_StyleMetrics metrics_ ) /* AF_CJKMetrics */ { … } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** C J K S C R I P T C L A S S *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ AF_DEFINE_WRITING_SYSTEM_CLASS( af_cjk_writing_system_class, AF_WRITING_SYSTEM_CJK, sizeof ( AF_CJKMetricsRec ), (AF_WritingSystem_InitMetricsFunc) af_cjk_metrics_init, /* style_metrics_init */ (AF_WritingSystem_ScaleMetricsFunc)af_cjk_metrics_scale, /* style_metrics_scale */ (AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done */ (AF_WritingSystem_GetStdWidthsFunc)af_cjk_get_standard_widths, /* style_metrics_getstdw */ (AF_WritingSystem_InitHintsFunc) af_cjk_hints_init, /* style_hints_init */ (AF_WritingSystem_ApplyHintsFunc) af_cjk_hints_apply /* style_hints_apply */ ) #else /* !AF_CONFIG_OPTION_CJK */ AF_DEFINE_WRITING_SYSTEM_CLASS( af_cjk_writing_system_class, AF_WRITING_SYSTEM_CJK, sizeof ( AF_CJKMetricsRec ), (AF_WritingSystem_InitMetricsFunc) NULL, /* style_metrics_init */ (AF_WritingSystem_ScaleMetricsFunc)NULL, /* style_metrics_scale */ (AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done */ (AF_WritingSystem_GetStdWidthsFunc)NULL, /* style_metrics_getstdw */ (AF_WritingSystem_InitHintsFunc) NULL, /* style_hints_init */ (AF_WritingSystem_ApplyHintsFunc) NULL /* style_hints_apply */ ) #endif /* !AF_CONFIG_OPTION_CJK */ /* END */