ref: 00a7b51fab76e8331f4ae86507e468b79856b47e
dir: /src/autofit/hbshim.c/
/***************************************************************************/ /* */ /* hbshim.c */ /* */ /* HarfBuzz interface for accessing OpenType features (body). */ /* */ /* Copyright 2013 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 <ft2build.h> #include FT_FREETYPE_H #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ #include <hb.h> #include <hb-ot.h> #include <hb-ft.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 trace_afharfbuzz /* * We use `sets' (in the HarfBuzz sense, which comes quite near to the * usual mathematical meaning) to manage both lookups and glyph indices. * * 1. For each coverage, collect lookup IDs in a set. Note that an * auto-hinter `coverage' is represented by one or more `feature's, and * a feature consists of an arbitrary number of (font specific) * `lookup's that actually do the mapping job. Please check the * OpenType specification for more details on features and lookups. * * 2. Create glyph ID sets from the corresponding lookup sets. * * 3. The glyph set corresponding to AF_COVERAGE_DEFAULT is computed * with all lookups specific to the OpenType script activated. It * relies on the order of AF_DEFINE_STYLE_CLASS entries so that * special coverages (like `oldstyle figures') don't get overwritten. * */ /* load coverage tags */ #undef COVERAGE_1 #define COVERAGE_1( name, NAME, description, \ tag_a1, tag_a2, tag_a3, tag_a4 ) \ static const hb_tag_t name ## _coverage[] = \ { \ HB_TAG( tag_a1, tag_a2, tag_a3, tag_a4 ), \ HB_TAG_NONE \ }; #undef COVERAGE_2 #define COVERAGE_2( name, NAME, description, \ tag_a1, tag_a2, tag_a3, tag_a4, \ tag_b1, tag_b2, tag_b3, tag_b4 ) \ static const hb_tag_t name ## _coverage[] = \ { \ HB_TAG( tag_a1, tag_a2, tag_a3, tag_a4 ), \ HB_TAG( tag_b1, tag_b2, tag_b3, tag_b4 ), \ HB_TAG_NONE \ }; #undef COVERAGE_3 #define COVERAGE_3( name, NAME, description, \ tag_a1, tag_a2, tag_a3, tag_a4, \ tag_b1, tag_b2, tag_b3, tag_b4, \ tag_c1, tag_c2, tag_c3, tag_c4 ) \ static const hb_tag_t name ## _coverage[] = \ { \ HB_TAG( tag_a1, tag_a2, tag_a3, tag_a4 ), \ HB_TAG( tag_b1, tag_b2, tag_b3, tag_b4 ), \ HB_TAG( tag_c1, tag_c2, tag_c3, tag_c4 ), \ HB_TAG_NONE \ }; #include "afcover.h" /* define mapping between coverage tags and AF_Coverage */ #undef COVERAGE_1 #define COVERAGE_1( name, NAME, description, \ tag_a1, tag_a2, tag_a3, tag_a4 ) \ name ## _coverage, #undef COVERAGE_2 #define COVERAGE_2( name, NAME, description, \ tag_a1, tag_a2, tag_a3, tag_a4, \ tag_b1, tag_b2, tag_b3, tag_b4 ) \ name ## _coverage, #undef COVERAGE_3 #define COVERAGE_3( name, NAME, description, \ tag_a1, tag_a2, tag_a3, tag_a4, \ tag_b1, tag_b2, tag_b3, tag_b4, \ tag_c1, tag_c2, tag_c3, tag_c4 ) \ name ## _coverage, static const hb_tag_t* coverages[] = { #include "afcover.h" NULL /* AF_COVERAGE_DEFAULT */ }; /* load HarfBuzz script tags */ #undef SCRIPT #define SCRIPT( s, S, d, h, dc ) h, static const hb_tag_t scripts[] = { #include "afscript.h" }; FT_Error af_get_coverage( FT_Face ft_face, AF_StyleClass style_class, FT_Byte* gstyles ) { hb_face_t* face; hb_set_t* lookups; /* lookups for a given script */ hb_set_t* glyphs; /* glyphs covered by lookups */ hb_tag_t script; const hb_tag_t* coverage_tags; hb_tag_t script_tags[] = { HB_TAG_NONE, HB_TAG_NONE, HB_TAG_NONE }; hb_codepoint_t idx; #ifdef FT_DEBUG_LEVEL_TRACE int count; #endif if ( !ft_face || !style_class || !gstyles ) return FT_THROW( Invalid_Argument ); face = hb_ft_face_create( ft_face, NULL ); lookups = hb_set_create(); glyphs = hb_set_create(); coverage_tags = coverages[style_class->coverage]; script = scripts[style_class->script]; /* Convert a HarfBuzz script tag into the corresponding OpenType */ /* tag or tags -- some Indic scripts like Devanagari have an old */ /* and a new set of features. */ hb_ot_tags_from_script( script, &script_tags[0], &script_tags[1] ); /* `hb_ot_tags_from_script' usually returns HB_OT_TAG_DEFAULT_SCRIPT */ /* as the second tag. We change that to HB_TAG_NONE since the */ /* default script gets handled later on. */ if ( script_tags[1] == HB_OT_TAG_DEFAULT_SCRIPT ) script_tags[1] = HB_TAG_NONE; hb_ot_layout_collect_lookups( face, HB_OT_TAG_GSUB, script_tags, NULL, coverage_tags, lookups ); FT_TRACE4(( "lookups (style `%s'):\n" " ", af_style_names[style_class->style] )); #ifdef FT_DEBUG_LEVEL_TRACE count = 0; #endif for ( idx = -1; hb_set_next( lookups, &idx ); ) { #ifdef FT_DEBUG_LEVEL_TRACE FT_TRACE4(( " %d", idx )); count++; #endif hb_ot_layout_lookup_collect_glyphs( face, HB_OT_TAG_GSUB, idx, NULL, NULL, NULL, glyphs ); } #ifdef FT_DEBUG_LEVEL_TRACE if ( !count ) FT_TRACE4(( " (none)" )); FT_TRACE4(( "\n\n" )); FT_TRACE4(( " glyphs (`*' means already assigned)" )); count = 0; #endif for ( idx = -1; hb_set_next( glyphs, &idx ); ) { #ifdef FT_DEBUG_LEVEL_TRACE if ( !( count % 10 ) ) FT_TRACE4(( "\n" " " )); FT_TRACE4(( " %d", idx )); count++; #endif if ( gstyles[idx] == AF_STYLE_UNASSIGNED ) gstyles[idx] = (FT_Byte)style_class->style; #ifdef FT_DEBUG_LEVEL_TRACE else FT_TRACE4(( "*" )); #endif } #ifdef FT_DEBUG_LEVEL_TRACE if ( !count ) FT_TRACE4(( "\n" " (none)" )); FT_TRACE4(( "\n\n" )); #endif hb_set_destroy( lookups ); hb_set_destroy( glyphs ); hb_face_destroy( face ); return FT_Err_Ok; } #if 0 /* to be always excluded */ COVERAGE(nalt, 'n', 'a', 'l', 't'); /* Alternate Annotation Forms (?) */ COVERAGE(ornm, 'o', 'r', 'n', 'm'); /* Ornaments (?) */ /* COVERAGE(ruby, 'r', 'u', 'b', 'y') */ /* (only for Japanese) */ #endif #endif /* FT_CONFIG_OPTION_USE_HARFBUZZ */ /* END */