From 2be60cfe7e01abaf1f15bf986069ac7abe93ff4c Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Sat, 1 Sep 2012 22:31:43 +0200 Subject: [PATCH] [autofit] Implement `glyph-to-script-map' property. * include/freetype/ftautoh.h: New public header file. * include/freetype/config/ftheader.h (FT_AUTOHINTER_H): New macro. * src/autofit/afglobal.c (AF_FaceGlobalsRec): Move structure to... * src/autofit/afglobal.h: This header file. * src/autofit/afmodule.c: Include FT_AUTOHINTER_H. (af_property_get): Handle `glyph-to-script-map'. --- ChangeLog | 12 ++ include/freetype/config/ftheader.h | 15 +- include/freetype/ftautoh.h | 253 +++++++++++++++++++++++++++++ include/freetype/ftchapters.h | 14 ++ src/autofit/afglobal.c | 16 -- src/autofit/afglobal.h | 20 ++- src/autofit/afmodule.c | 35 +++- 7 files changed, 345 insertions(+), 20 deletions(-) create mode 100644 include/freetype/ftautoh.h diff --git a/ChangeLog b/ChangeLog index 79ada24e6..5a08dee51 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2012-09-01 Werner Lemberg + + [autofit] Implement `glyph-to-script-map' property. + + * include/freetype/ftautoh.h: New public header file. + * include/freetype/config/ftheader.h (FT_AUTOHINTER_H): New macro. + + * src/autofit/afglobal.c (AF_FaceGlobalsRec): Move structure to... + * src/autofit/afglobal.h: This header file. + * src/autofit/afmodule.c: Include FT_AUTOHINTER_H. + (af_property_get): Handle `glyph-to-script-map'. + 2012-08-31 Werner Lemberg [autofit] Implement properties service framework. diff --git a/include/freetype/config/ftheader.h b/include/freetype/config/ftheader.h index 2a7b8c4e0..33d6b4054 100644 --- a/include/freetype/config/ftheader.h +++ b/include/freetype/config/ftheader.h @@ -4,7 +4,7 @@ /* */ /* Build macros of the FreeType 2 library. */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 by */ +/* Copyright 1996-2008, 2010, 2012 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -315,6 +315,19 @@ #define FT_RENDER_H + /************************************************************************* + * + * @macro: + * FT_AUTOHINTER_H + * + * @description: + * A macro used in #include statements to name the file containing + * structures and macros related to the auto-hinting module. + * + */ +#define FT_AUTOHINTER_H + + /************************************************************************* * * @macro: diff --git a/include/freetype/ftautoh.h b/include/freetype/ftautoh.h new file mode 100644 index 000000000..593c18f21 --- /dev/null +++ b/include/freetype/ftautoh.h @@ -0,0 +1,253 @@ +/***************************************************************************/ +/* */ +/* ftautoh.h */ +/* */ +/* FreeType API for controlling the auto-hinter (specification only). */ +/* */ +/* Copyright 2012 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTAUTOH_H__ +#define __FTAUTOH_H__ + +#include +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /************************************************************************** + * + * @section: + * auto_hinter + * + * @title: + * The auto-hinter + * + * @abstract: + * Controlling the auto-hinting module. + * + * @description: + * While FreeType's auto-hinter doesn't expose API functions by itself, + * it is possible to control its behaviour with @FT_Property_Set and + * @FT_Property_Get. The following lists the available properties + * together with the necessary macros and structures. + * + * Note that the auto-hinter's module name is `autofitter' for + * historical reasons. + * + */ + + + /************************************************************************** + * + * @property: + * glyph-to-script-map + * + * @description: + * The auto-hinter provides various script modules to hint glyphs. + * Examples of supported scripts are Latin or CJK. Before a glyph is + * auto-hinted, the Unicode character map of the font gets examined, and + * the script is then determined based on Unicode character ranges, see + * below. + * + * OpenType fonts, however, often provide much more glyphs than + * character codes (small caps, superscripts, ligatures, swashes, etc.), + * to be controlled by so-called `features'. Handling OpenType features + * can be quite complicated and thus needs a separate library on top of + * FreeType. + * + * The mapping between glyph indices and scripts (in the auto-hinter + * sense, see the @FT_AUTOHINTER_SCRIPT_XXX values) is stored as an + * array with `num_glyphs' elements, as found in the font's @FT_Face + * structure. The `glyph-to-script-map' property returns a pointer to + * this array which can be modified as needed. Note that the + * modification should happen before the first glyph gets processed by + * the auto-hinter so that the global analysis of the font shapes + * actually uses the modified mapping. + * + * The following example code demonstrates how to access it (omitting + * the error handling). + * + * { + * FT_Library library; + * FT_Face face; + * FT_Prop_GlyphToScriptMap prop; + * + * + * FT_Init_FreeType( &library ); + * FT_New_Face( library, "foo.ttf", 0, &face ); + * + * prop.face = face; + * + * FT_Property_Get( library, "autofitter", + * "glyph-to-script-map", &prop ); + * + * // adjust `prop.map' as needed right here + * + * FT_Load_Glyph( face, ..., FT_LOAD_FORCE_AUTOHINT ); + * } + * + */ + + + /************************************************************************** + * + * @enum: + * FT_AUTOHINTER_SCRIPT_XXX + * + * @description: + * A list of constants used for the @glyph-to-script-map property to + * specify the script submodule the auto-hinter should use for hinting a + * particular glyph. + * + * @values: + * FT_AUTOHINTER_SCRIPT_NONE :: + * Don't auto-hint this glyph. + * + * FT_AUTOHINTER_SCRIPT_LATIN :: + * Apply the latin auto-hinter. For the auto-hinter, `latin' is a + * very broad term, including Cyrillic and Greek also since characters + * from those scripts share the same design constraints. + * + * By default, characters from the following Unicode ranges are + * assigned to this submodule. + * + * { + * U+0020 - U+007F // Basic Latin (no control chars) + * U+00A0 - U+00FF // Latin-1 Supplement (no control chars) + * U+0100 - U+017F // Latin Extended-A + * U+0180 - U+024F // Latin Extended-B + * U+0250 - U+02AF // IPA Extensions + * U+02B0 - U+02FF // Spacing Modifier Letters + * U+0300 - U+036F // Combining Diacritical Marks + * U+0370 - U+03FF // Greek and Coptic + * U+0400 - U+04FF // Cyrillic + * U+0500 - U+052F // Cyrillic Supplement + * U+1D00 - U+1D7F // Phonetic Extensions + * U+1D80 - U+1DBF // Phonetic Extensions Supplement + * U+1DC0 - U+1DFF // Combining Diacritical Marks Supplement + * U+1E00 - U+1EFF // Latin Extended Additional + * U+1F00 - U+1FFF // Greek Extended + * U+2000 - U+206F // General Punctuation + * U+2070 - U+209F // Superscripts and Subscripts + * U+20A0 - U+20CF // Currency Symbols + * U+2150 - U+218F // Number Forms + * U+2460 - U+24FF // Enclosed Alphanumerics + * U+2C60 - U+2C7F // Latin Extended-C + * U+2DE0 - U+2DFF // Cyrillic Extended-A + * U+A640 - U+A69F // Cyrillic Extended-B + * U+A720 - U+A7FF // Latin Extended-D + * U+FB00 - U+FB06 // Alphab. Present. Forms (Latin Ligs) + * U+1D400 - U+1D7FF // Mathematical Alphanumeric Symbols + * } + * + * FT_AUTOHINTER_SCRIPT_CJK :: + * Apply the CJK auto-hinter, covering Chinese, Japanese, Korean, old + * Vietnamese, and some other scripts. + * + * By default, characters from the following Unicode ranges are + * assigned to this submodule. + * + * { + * U+2E80 - U+2EFF // CJK Radicals Supplement + * U+2F00 - U+2FDF // Kangxi Radicals + * U+2FF0 - U+2FFF // Ideographic Description Characters + * U+3000 - U+303F // CJK Symbols and Punctuation + * U+3040 - U+309F // Hiragana + * U+30A0 - U+30FF // Katakana + * U+3100 - U+312F // Bopomofo + * U+3130 - U+318F // Hangul Compatibility Jamo + * U+3190 - U+319F // Kanbun + * U+31A0 - U+31BF // Bopomofo Extended + * U+31C0 - U+31EF // CJK Strokes + * U+31F0 - U+31FF // Katakana Phonetic Extensions + * U+3200 - U+32FF // Enclosed CJK Letters and Months + * U+3300 - U+33FF // CJK Compatibility + * U+3400 - U+4DBF // CJK Unified Ideographs Extension A + * U+4DC0 - U+4DFF // Yijing Hexagram Symbols + * U+4E00 - U+9FFF // CJK Unified Ideographs + * U+A960 - U+A97F // Hangul Jamo Extended-A + * U+AC00 - U+D7AF // Hangul Syllables + * U+D7B0 - U+D7FF // Hangul Jamo Extended-B + * U+F900 - U+FAFF // CJK Compatibility Ideographs + * U+FE10 - U+FE1F // Vertical forms + * U+FE30 - U+FE4F // CJK Compatibility Forms + * U+FF00 - U+FFEF // Halfwidth and Fullwidth Forms + * U+1B000 - U+1B0FF // Kana Supplement + * U+1D300 - U+1D35F // Tai Xuan Hing Symbols + * U+1F200 - U+1F2FF // Enclosed Ideographic Supplement + * U+20000 - U+2A6DF // CJK Unified Ideographs Extension B + * U+2A700 - U+2B73F // CJK Unified Ideographs Extension C + * U+2B740 - U+2B81F // CJK Unified Ideographs Extension D + * U+2F800 - U+2FA1F // CJK Compatibility Ideographs Supplement + * } + * + * FT_AUTOHINTER_SCRIPT_INDIC :: + * Apply the indic auto-hinter, covering all major scripts from the + * Indian sub-continent and some other related scripts like Thai, Lao, + * or Tibetan. + * + * By default, characters from the following Unicode ranges are + * assigned to this submodule. + * + * { + * U+0900 - U+0DFF // Indic Range + * U+0F00 - U+0FFF // Tibetan + * U+1900 - U+194F // Limbu + * U+1B80 - U+1BBF // Sundanese + * U+1C80 - U+1CDF // Meetei Mayak + * U+A800 - U+A82F // Syloti Nagri + * U+11800 - U+118DF // Sharada + * } + * + * Note that currently Indic support is rudimentary only, missing blue + * zone support. + * + */ +#define FT_AUTOHINTER_SCRIPT_NONE 0 +#define FT_AUTOHINTER_SCRIPT_LATIN 1 +#define FT_AUTOHINTER_SCRIPT_CJK 2 +#define FT_AUTOHINTER_SCRIPT_INDIC 3 + + + /************************************************************************** + * + * @struct: + * FT_Prop_GlyphToScriptMap + * + * @description: + * The data exchange structure for the @glyph-to-script-map property. + * + */ + typedef struct FT_Prop_GlyphToScriptMap_ + { + FT_Face face; + FT_Byte* map; + + } FT_Prop_GlyphToScriptMap; + + /* */ + +FT_END_HEADER + +#endif /* __FTAUTOH_H__ */ + + +/* END */ diff --git a/include/freetype/ftchapters.h b/include/freetype/ftchapters.h index 6cdf54e49..984eef372 100644 --- a/include/freetype/ftchapters.h +++ b/include/freetype/ftchapters.h @@ -64,6 +64,20 @@ /***************************************************************************/ +/***************************************************************************/ +/* */ +/* */ +/* auto_hinter */ +/* */ +/* */ +/* The Auto-Hinter */ +/* */ +/* <Sections> */ +/* auto_hinter */ +/* */ +/***************************************************************************/ + + /***************************************************************************/ /* */ /* <Chapter> */ diff --git a/src/autofit/afglobal.c b/src/autofit/afglobal.c index 008bf4c16..9a5bac29d 100644 --- a/src/autofit/afglobal.c +++ b/src/autofit/afglobal.c @@ -57,22 +57,6 @@ #define AF_DIGIT 0x80 - /* - * Note that glyph_scripts[] is used to map each glyph into - * an index into the `af_script_classes' array. - * - */ - typedef struct AF_FaceGlobalsRec_ - { - FT_Face face; - FT_Long glyph_count; /* same as face->num_glyphs */ - FT_Byte* glyph_scripts; - - AF_ScriptMetrics metrics[AF_SCRIPT_MAX]; - - } AF_FaceGlobalsRec; - - /* Compute the script index of each glyph within a given face. */ static FT_Error diff --git a/src/autofit/afglobal.h b/src/autofit/afglobal.h index cc6860b26..9137dced2 100644 --- a/src/autofit/afglobal.h +++ b/src/autofit/afglobal.h @@ -5,7 +5,7 @@ /* Auto-fitter routines to compute global hinting values */ /* (specification). */ /* */ -/* Copyright 2003-2005, 2007, 2009, 2011 by */ +/* Copyright 2003-2005, 2007, 2009, 2011-2012 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -36,11 +36,27 @@ FT_BEGIN_HEADER /************************************************************************/ + /* + * Note that glyph_scripts[] is used to map each glyph into + * an index into the `af_script_classes' array. + * + */ + typedef struct AF_FaceGlobalsRec_ + { + FT_Face face; + FT_Long glyph_count; /* same as face->num_glyphs */ + FT_Byte* glyph_scripts; + + AF_ScriptMetrics metrics[AF_SCRIPT_MAX]; + + } AF_FaceGlobalsRec; + + /* * model the global hints data for a given face, decomposed into * script-specific items */ - typedef struct AF_FaceGlobalsRec_* AF_FaceGlobals; + typedef struct AF_FaceGlobalsRec_* AF_FaceGlobals; FT_LOCAL( FT_Error ) diff --git a/src/autofit/afmodule.c b/src/autofit/afmodule.c index ce208666b..b13e6a9aa 100644 --- a/src/autofit/afmodule.c +++ b/src/autofit/afmodule.c @@ -28,6 +28,7 @@ #endif #include FT_INTERNAL_OBJECTS_H +#include FT_AUTOHINTER_H #include FT_SERVICE_PROPERTIES_H @@ -50,8 +51,40 @@ const char* property_name, void* value ) { + FT_Error error = FT_Err_Ok; + FT_UNUSED( library ); - FT_UNUSED( value ); + + + if ( !ft_strcmp( property_name, "glyph-to-script-map" ) ) + { + FT_Prop_GlyphToScriptMap* prop = (FT_Prop_GlyphToScriptMap*)value; + AF_FaceGlobals globals; + + + if ( !prop->face ) + return FT_Err_Invalid_Argument; + + globals = (AF_FaceGlobals)prop->face->autohint.data; + if ( !globals ) + { + /* trigger computation of the global script data */ + /* in case it hasn't been done yet */ + error = af_face_globals_new( prop->face, &globals ); + if ( !error ) + { + prop->face->autohint.data = + (FT_Pointer)globals; + prop->face->autohint.finalizer = + (FT_Generic_Finalizer)af_face_globals_free; + } + } + + if ( !error ) + prop->map = globals->glyph_scripts; + + return error; + } FT_TRACE0(( "af_property_get: missing property `%s'\n", property_name ));