Introduce `coverages'.

Coverages are the interface to the HarfBuzz library to access
OpenType features for handling glyphs not addressable by the cmap.

Right now, compilation of HarfBuzz is only added to the development
build.  A solution for standard build mode will be delayed until
HarfBuzz gets split into two libraries to avoid mutual dependencies
between FreeType and HarfBuzz.

Note that this is only a first step in handling coverages, basically
providing the framework only.  Code for handling selected OpenType
features (this is, actually using the data in `afcover.h') will
follow.

* devel/ftoption.h, include/config/ftoption.h
(FT_CONFIG_OPTION_USE_HARFBUZZ): New macro.

* src/autofit/hbshim.c, src/autofit/hbshim.h, src/autofit/afcover.h:
New files.

* src/autofit/afscript.h: Add HarfBuzz script name tags.

* src/autofit/afstyles.h: Add default coverage enumeration values.

* src/autofit/aftypes.h: Update use of `SCRIPT' and `STYLE' macros.
(AF_Coverage): New enumeration (generated by `afcover.h').
(AF_StyleClassRec): New member `coverage'.
(AF_DEFINE_STYLE_CLASS): Updated.

* include/internal/fttrace.h: Add `afharfbuzz' for tracing coverage
data.

* src/autofit/afglobal.h: Update use of `SCRIPT' and `STYLE' macros.
(AF_SCRIPT_FALLBACK): Renamed to ...
(AF_STYLE_FALLBACK): ... this.

* src/autofit/afglobal.c: Include `hbshim.c'.
Update use of `SCRIPT' and `STYLE' macros.
(af_face_globals_compute_style_coverage)
[FT_CONFIG_OPTION_USE_HARFBUZZ]: Call `af_get_coverage'.
Update.

* src/autofit/afmodule.h (AF_ModuleRec):
s/fallback_script/fallback_style/.

* src/autofit/afmodule.c (af_property_set): Adapt handling of
`fallback-script' property to set a fallback style.
(af_property_get, af_autofitter_init): Updated.

* src/autofit/afpic.c: Update use of `SCRIPT' and `STYLE' macros.

* src/autofit/afranges.h: Update use of `SCRIPT' macro.

* src/autofit/autofit.c [FT_CONFIG_OPTION_USE_HARFBUZZ]: Include
`hbshim.c'.

* src/autofit/rules.mk (AUTOF_DRV_SRC): Add `hbshim.c'.
(AUTOF_DRV_H): Add `afcover.h'.

* builds/freetype.mk (INCLUDE_FLAGS) [DEVEL_DIR]: Use pkg-config for
all libraries needed by FreeType.
This commit is contained in:
Werner Lemberg 2013-12-21 21:31:38 +01:00
parent b337fa25cf
commit 1924134710
20 changed files with 678 additions and 52 deletions

View File

@ -1,3 +1,68 @@
2013-12-21 Werner Lemberg <wl@gnu.org>
[autofit] Introduce `coverages'.
Coverages are the interface to the HarfBuzz library to acces
OpenType features for handling glyphs not addressable by the cmap.
Right now, compilation of HarfBuzz is only added to the development
build. A solution for standard build mode will be delayed until
HarfBuzz gets split into two libraries to avoid mutual dependencies
between FreeType and HarfBuzz.
Note that this is only a first step in handling coverages, basically
providing the framework only. Code for handling selected OpenType
features (this is, actually using the data in `afcover.h') will
follow.
* devel/ftoption.h, include/config/ftoption.h
(FT_CONFIG_OPTION_USE_HARFBUZZ): New macro.
* src/autofit/hbshim.c, src/autofit/hbshim.h, src/autofit/afcover.h:
New files.
* src/autofit/afscript.h: Add HarfBuzz script name tags.
* src/autofit/afstyles.h: Add default coverage enumeration values.
* src/autofit/aftypes.h: Update use of `SCRIPT' and `STYLE' macros.
(AF_Coverage): New enumeration (generated by `afcover.h').
(AF_StyleClassRec): New member `coverage'.
(AF_DEFINE_STYLE_CLASS): Updated.
* include/internal/fttrace.h: Add `afharfbuzz' for tracing coverage
data.
* src/autofit/afglobal.h: Update use of `SCRIPT' and `STYLE' macros.
(AF_SCRIPT_FALLBACK): Renamed to ...
(AF_STYLE_FALLBACK): ... this.
* src/autofit/afglobal.c: Include `hbshim.c'.
Update use of `SCRIPT' and `STYLE' macros.
(af_face_globals_compute_style_coverage)
[FT_CONFIG_OPTION_USE_HARFBUZZ]: Call `af_get_coverage'.
Update.
* src/autofit/afmodule.h (AF_ModuleRec):
s/fallback_script/fallback_style/.
* src/autofit/afmodule.c (af_property_set): Adapt handling of
`fallback-script' property to set a fallback style.
(af_property_get, af_autofitter_init): Updated.
* src/autofit/afpic.c: Update use of `SCRIPT' and `STYLE' macros.
* src/autofit/afranges.h: Update use of `SCRIPT' macro.
* src/autofit/autofit.c [FT_CONFIG_OPTION_USE_HARFBUZZ]: Include
`hbshim.c'.
* src/autofit/rules.mk (AUTOF_DRV_SRC): Add `hbshim.c'.
(AUTOF_DRV_H): Add `afcover.h'.
* builds/freetype.mk (INCLUDE_FLAGS) [DEVEL_DIR]: Use pkg-config for
all libraries needed by FreeType.
2013-12-21 Werner Lemberg <wl@gnu.org> 2013-12-21 Werner Lemberg <wl@gnu.org>
Fix Savannah bug #40975 (sort of). Fix Savannah bug #40975 (sort of).

View File

@ -126,6 +126,15 @@ INCLUDES := $(subst /,$(COMPILER_SEP),$(OBJ_DIR) \
INCLUDE_FLAGS := $(INCLUDES:%=$I%) INCLUDE_FLAGS := $(INCLUDES:%=$I%)
ifdef DEVEL_DIR
# We assume that all library dependencies for FreeType are fulfilled for a
# development build, so we directly access the necessary include directory
# information using `pkg-config'.
INCLUDE_FLAGS += $(shell pkg-config --cflags bzip2 \
libpng \
harfbuzz )
endif
# C flags used for the compilation of an object file. This must include at # C flags used for the compilation of an object file. This must include at
# least the paths for the `base' and `builds/<system>' directories; # least the paths for the `base' and `builds/<system>' directories;

View File

@ -217,6 +217,19 @@ FT_BEGIN_HEADER
#define FT_CONFIG_OPTION_USE_PNG #define FT_CONFIG_OPTION_USE_PNG
/*************************************************************************/
/* */
/* HarfBuzz support. */
/* */
/* FreeType uses the HarfBuzz library to improve auto-hinting of */
/* OpenType fonts. If available, many glyphs not directly addressable */
/* by a font's character map will be hinted also. */
/* */
/* Define this macro if you want to enable this `feature'. */
/* */
#define FT_CONFIG_OPTION_USE_HARFBUZZ
/*************************************************************************/ /*************************************************************************/
/* */ /* */
/* Define to disable the use of file stream functions and types, FILE, */ /* Define to disable the use of file stream functions and types, FILE, */

View File

@ -228,6 +228,19 @@ FT_BEGIN_HEADER
/* #define FT_CONFIG_OPTION_USE_PNG */ /* #define FT_CONFIG_OPTION_USE_PNG */
/*************************************************************************/
/* */
/* HarfBuzz support. */
/* */
/* FreeType uses the HarfBuzz library to improve auto-hinting of */
/* OpenType fonts. If available, many glyphs not directly addressable */
/* by a font's character map will be hinted also. */
/* */
/* Define this macro if you want to enable this `feature'. */
/* */
/* #define FT_CONFIG_OPTION_USE_HARFBUZZ */
/*************************************************************************/ /*************************************************************************/
/* */ /* */
/* DLL export compilation */ /* DLL export compilation */

View File

@ -148,5 +148,6 @@ FT_TRACE_DEF( afcjk )
FT_TRACE_DEF( aflatin ) FT_TRACE_DEF( aflatin )
FT_TRACE_DEF( aflatin2 ) FT_TRACE_DEF( aflatin2 )
FT_TRACE_DEF( afwarp ) FT_TRACE_DEF( afwarp )
FT_TRACE_DEF( afharfbuzz )
/* END */ /* END */

66
src/autofit/afcover.h Normal file
View File

@ -0,0 +1,66 @@
/***************************************************************************/
/* */
/* afcover.h */
/* */
/* Auto-fitter coverages (specification only). */
/* */
/* 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. */
/* */
/***************************************************************************/
/* This header file can be included multiple times. */
/* Define `COVERAGE_{1,2,3}' as needed. */
/* Add new coverages here. The first and second arguments are the */
/* coverage name in lowercase and uppercase, respectively, followed */
/* by a description string. The remaining arguments the */
/* corresponding OpenType features (with four characters a feature). */
COVERAGE_1( oldstyle_figures, OLDSTYLE_FIGURES,
"oldstyle figures",
'o', 'n', 'u', 'm' ) /* Oldstyle Figures */
COVERAGE_2( petite_capitals, PETITE_CAPITALS,
"petite capitals",
'c', '2', 'c', 'p', /* Petite Capitals from Capitals */
'p', 'c', 'a', 'p' ) /* Petite Capitals */
COVERAGE_2( small_capitals, SMALL_CAPITALS,
"small capitals",
'c', '2', 's', 'c', /* Small Capitals from Capitals */
's', 'm', 'c', 'p' ) /* Small Capitals */
COVERAGE_1( titling, TITLING,
"titling",
't', 'i', 't', 'l' ) /* Titling */
COVERAGE_2( sub_superscript_1, SUB_SUPERSCRIPT_1,
"sub- and superscripts group 1",
's', 'u', 'b', 's', /* Subscript */
's', 'u', 'p', 's' ) /* Superscript */
COVERAGE_2( sub_superscript_2, SUB_SUPERSCRIPT_2,
"sub- and superscripts group 2",
'o', 'r', 'd', 'n', /* Ordinals */
's', 'i', 'n', 'f' ) /* Scientific Inferiors */
COVERAGE_3( fractions, FRACTIONS,
"fractions",
'd', 'n', 'o', 'm', /* Denominators */
'f', 'r', 'a', 'c', /* Fractions */
'n', 'u', 'm', 'r' ) /* Numerators */
COVERAGE_1( alternative_fractions, ALTERNATIVE_FRACTIONS,
"alternative fractions",
'a', 'f', 'r', 'c' ) /* Alternative Fractions */
/* END */

View File

@ -18,6 +18,7 @@
#include "afglobal.h" #include "afglobal.h"
#include "afranges.h" #include "afranges.h"
#include "hbshim.h"
/* get writing system specific header files */ /* get writing system specific header files */
#undef WRITING_SYSTEM #undef WRITING_SYSTEM
@ -29,7 +30,7 @@
#undef SCRIPT #undef SCRIPT
#define SCRIPT( s, S, d, dc ) \ #define SCRIPT( s, S, d, h, dc ) \
AF_DEFINE_SCRIPT_CLASS( \ AF_DEFINE_SCRIPT_CLASS( \
af_ ## s ## _script_class, \ af_ ## s ## _script_class, \
AF_SCRIPT_ ## S, \ AF_SCRIPT_ ## S, \
@ -40,13 +41,14 @@
#undef STYLE #undef STYLE
#define STYLE( s, S, d, ws, sc, ss ) \ #define STYLE( s, S, d, ws, sc, ss, c ) \
AF_DEFINE_STYLE_CLASS( \ AF_DEFINE_STYLE_CLASS( \
af_ ## s ## _style_class, \ af_ ## s ## _style_class, \
AF_STYLE_ ## S, \ AF_STYLE_ ## S, \
ws, \ ws, \
sc, \ sc, \
ss ) ss, \
c )
#include "afstyles.h" #include "afstyles.h"
@ -68,7 +70,7 @@
#undef SCRIPT #undef SCRIPT
#define SCRIPT( s, S, d, dc ) \ #define SCRIPT( s, S, d, h, dc ) \
&af_ ## s ## _script_class, &af_ ## s ## _script_class,
FT_LOCAL_ARRAY_DEF( AF_ScriptClass ) FT_LOCAL_ARRAY_DEF( AF_ScriptClass )
@ -82,7 +84,7 @@
#undef STYLE #undef STYLE
#define STYLE( s, S, d, ws, sc, ss ) \ #define STYLE( s, S, d, ws, sc, ss, c ) \
&af_ ## s ## _style_class, &af_ ## s ## _style_class,
FT_LOCAL_ARRAY_DEF( AF_StyleClass ) FT_LOCAL_ARRAY_DEF( AF_StyleClass )
@ -100,7 +102,7 @@
#ifdef FT_DEBUG_LEVEL_TRACE #ifdef FT_DEBUG_LEVEL_TRACE
#undef STYLE #undef STYLE
#define STYLE( s, S, d, ws, sc, ss ) #s, #define STYLE( s, S, d, ws, sc, ss, c ) #s,
FT_LOCAL_ARRAY_DEF( char* ) FT_LOCAL_ARRAY_DEF( char* )
af_style_names[] = af_style_names[] =
@ -135,7 +137,7 @@
if ( error ) if ( error )
{ {
/* /*
* Ignore this error; we simply use the fallback script. * Ignore this error; we simply use the fallback style.
* XXX: Shouldn't we rather disable hinting? * XXX: Shouldn't we rather disable hinting?
*/ */
error = FT_Err_Ok; error = FT_Err_Ok;
@ -186,6 +188,11 @@
gstyles[gindex] = (FT_Byte)ss; gstyles[gindex] = (FT_Byte)ss;
} }
} }
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
/* get glyphs not directly addressable by cmap */
af_get_coverage( face, style_class, gstyles );
#endif
} }
/* mark ASCII digits */ /* mark ASCII digits */
@ -200,10 +207,10 @@
Exit: Exit:
/* /*
* By default, all uncovered glyphs are set to the fallback script. * By default, all uncovered glyphs are set to the fallback style.
* XXX: Shouldn't we disable hinting or do something similar? * XXX: Shouldn't we disable hinting or do something similar?
*/ */
if ( globals->module->fallback_script != AF_STYLE_UNASSIGNED ) if ( globals->module->fallback_style != AF_STYLE_UNASSIGNED )
{ {
FT_Long nn; FT_Long nn;
@ -213,7 +220,7 @@
if ( ( gstyles[nn] & ~AF_DIGIT ) == AF_STYLE_UNASSIGNED ) if ( ( gstyles[nn] & ~AF_DIGIT ) == AF_STYLE_UNASSIGNED )
{ {
gstyles[nn] &= ~AF_STYLE_UNASSIGNED; gstyles[nn] &= ~AF_STYLE_UNASSIGNED;
gstyles[nn] |= globals->module->fallback_script; gstyles[nn] |= globals->module->fallback_style;
} }
} }
} }

View File

@ -33,7 +33,7 @@ FT_BEGIN_HEADER
#undef SCRIPT #undef SCRIPT
#define SCRIPT( s, S, d, dc ) \ #define SCRIPT( s, S, d, h, dc ) \
AF_DECLARE_SCRIPT_CLASS( af_ ## s ## _script_class ) AF_DECLARE_SCRIPT_CLASS( af_ ## s ## _script_class )
#include "afscript.h" #include "afscript.h"
@ -43,7 +43,7 @@ FT_BEGIN_HEADER
#undef STYLE #undef STYLE
#define STYLE( s, S, d, ws, sc, ss ) \ #define STYLE( s, S, d, ws, sc, ss, c ) \
AF_DECLARE_STYLE_CLASS( af_ ## s ## _style_class ) AF_DECLARE_STYLE_CLASS( af_ ## s ## _style_class )
#include "afstyles.h" #include "afstyles.h"
@ -63,11 +63,11 @@ FT_BEGIN_HEADER
* AF_ModuleRec) and face globals (in AF_FaceGlobalsRec). * AF_ModuleRec) and face globals (in AF_FaceGlobalsRec).
*/ */
/* index of fallback script in `af_style_classes' */ /* index of fallback style in `af_style_classes' */
#ifdef AF_CONFIG_OPTION_CJK #ifdef AF_CONFIG_OPTION_CJK
#define AF_SCRIPT_FALLBACK AF_STYLE_HANI_DEFAULT #define AF_STYLE_FALLBACK AF_STYLE_HANI_DEFAULT
#else #else
#define AF_SCRIPT_FALLBACK AF_STYLE_NONE_DEFAULT #define AF_STYLE_FALLBACK AF_STYLE_NONE_DEFAULT
#endif #endif
/* a bit mask indicating an uncovered glyph */ /* a bit mask indicating an uncovered glyph */
#define AF_STYLE_UNASSIGNED 0x7F #define AF_STYLE_UNASSIGNED 0x7F

View File

@ -92,8 +92,31 @@
{ {
FT_UInt* fallback_script = (FT_UInt*)value; FT_UInt* fallback_script = (FT_UInt*)value;
FT_UInt ss;
module->fallback_script = *fallback_script;
/* We translate the fallback script to a fallback style that uses */
/* `fallback-script' as its script and `AF_COVERAGE_NONE' as its */
/* coverage value. */
for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ )
{
AF_StyleClass style_class = AF_STYLE_CLASSES_GET[ss];
if ( style_class->script == *fallback_script &&
style_class->coverage == AF_COVERAGE_DEFAULT )
{
module->fallback_style = ss;
break;
}
}
if ( !AF_STYLE_CLASSES_GET[ss] )
{
FT_TRACE0(( "af_property_set: Invalid value %d for property `%s'\n",
fallback_script, property_name ));
return FT_THROW( Invalid_Argument );
}
return error; return error;
} }
@ -121,9 +144,9 @@
const char* property_name, const char* property_name,
void* value ) void* value )
{ {
FT_Error error = FT_Err_Ok; FT_Error error = FT_Err_Ok;
AF_Module module = (AF_Module)ft_module; AF_Module module = (AF_Module)ft_module;
FT_UInt fallback_script = module->fallback_script; FT_UInt fallback_style = module->fallback_style;
if ( !ft_strcmp( property_name, "glyph-to-script-map" ) ) if ( !ft_strcmp( property_name, "glyph-to-script-map" ) )
@ -142,8 +165,10 @@
{ {
FT_UInt* val = (FT_UInt*)value; FT_UInt* val = (FT_UInt*)value;
AF_StyleClass style_class = AF_STYLE_CLASSES_GET[fallback_style];
*val = fallback_script;
*val = style_class->script;
return error; return error;
} }
@ -206,7 +231,7 @@
AF_Module module = (AF_Module)ft_module; AF_Module module = (AF_Module)ft_module;
module->fallback_script = AF_SCRIPT_FALLBACK; module->fallback_style = AF_STYLE_FALLBACK;
return af_loader_init( module ); return af_loader_init( module );
} }

View File

@ -40,7 +40,7 @@ FT_BEGIN_HEADER
{ {
FT_ModuleRec root; FT_ModuleRec root;
FT_UInt fallback_script; FT_UInt fallback_style;
AF_LoaderRec loader[1]; AF_LoaderRec loader[1];

View File

@ -122,7 +122,7 @@
#include "afwrtsys.h" #include "afwrtsys.h"
#undef SCRIPT #undef SCRIPT
#define SCRIPT( s, S, d, dc ) \ #define SCRIPT( s, S, d, h, dc ) \
FT_Init_Class_af_ ## s ## _script_class( \ FT_Init_Class_af_ ## s ## _script_class( \
&container->af_script_classes_rec[ss++] ); &container->af_script_classes_rec[ss++] );
@ -130,7 +130,7 @@
#include "afscript.h" #include "afscript.h"
#undef STYLE #undef STYLE
#define STYLE( s, S, d, ws, sc, bss ) \ #define STYLE( s, S, d, ws, sc, bss, c ) \
FT_Init_Class_af_ ## s ## _style_class( \ FT_Init_Class_af_ ## s ## _style_class( \
&container->af_style_classes_rec[ss++] ); &container->af_style_classes_rec[ss++] );

View File

@ -26,7 +26,7 @@
FT_BEGIN_HEADER FT_BEGIN_HEADER
#undef SCRIPT #undef SCRIPT
#define SCRIPT( s, S, d, dc ) \ #define SCRIPT( s, S, d, h, dc ) \
extern const AF_Script_UniRangeRec af_ ## s ## _uniranges[]; extern const AF_Script_UniRangeRec af_ ## s ## _uniranges[];
#include "afscript.h" #include "afscript.h"

View File

@ -20,34 +20,45 @@
/* Define `SCRIPT' as needed. */ /* Define `SCRIPT' as needed. */
/* Add new scripts here. */ /* Add new scripts here. The first and second arguments are the */
/* script name in lowercase and uppercase, respectively, followed */
/* by a description string. Then comes the corresponding HarfBuzz */
/* script name tag, followed by the default character (to derive */
/* the standard width and height of stems). */
SCRIPT( cyrl, CYRL, SCRIPT( cyrl, CYRL,
"Cyrillic", "Cyrillic",
HB_SCRIPT_CYRILLIC,
0x43E ) /* о */ 0x43E ) /* о */
SCRIPT( deva, DEVA, SCRIPT( deva, DEVA,
"Indic scripts", "Indic scripts",
HB_SCRIPT_DEVANAGARI,
'o' ) /* XXX */ 'o' ) /* XXX */
SCRIPT( none, NONE, SCRIPT( none, NONE,
"no script", "no script",
HB_SCRIPT_INVALID,
'\0' ) '\0' )
SCRIPT( grek, GREK, SCRIPT( grek, GREK,
"Greek", "Greek",
HB_SCRIPT_GREEK,
0x3BF ) /* ο */ 0x3BF ) /* ο */
SCRIPT( hani, HANI, SCRIPT( hani, HANI,
"CJKV ideographs", "CJKV ideographs",
HB_SCRIPT_HAN,
0x7530 ) /* 田 */ 0x7530 ) /* 田 */
SCRIPT( hebr, HEBR, SCRIPT( hebr, HEBR,
"Hebrew", "Hebrew",
HB_SCRIPT_HEBREW,
0x5DD ) /* ם */ 0x5DD ) /* ם */
SCRIPT( latn, LATN, SCRIPT( latn, LATN,
"Latin", "Latin",
HB_SCRIPT_LATIN,
'o' ) 'o' )

View File

@ -20,57 +20,69 @@
/* Define `STYLE' as needed. */ /* Define `STYLE' as needed. */
/* Add new styles here. */ /* Add new styles here. The first and second arguments are the */
/* style name in lowercase and uppercase, respectively, followed */
/* by a description string. The next arguments are the */
/* corresponding writing system, script, blue stringset, and */
/* coverage. */
STYLE( cyrl_default, CYRL_DEFAULT, STYLE( cyrl_default, CYRL_DEFAULT,
"Cyrillic default style", "Cyrillic default style",
AF_WRITING_SYSTEM_LATIN, AF_WRITING_SYSTEM_LATIN,
AF_SCRIPT_CYRL, AF_SCRIPT_CYRL,
AF_BLUE_STRINGSET_CYRL ) AF_BLUE_STRINGSET_CYRL,
AF_COVERAGE_DEFAULT )
STYLE( deva_default, DEVA_DEFAULT, STYLE( deva_default, DEVA_DEFAULT,
"Indic scripts default style", "Indic scripts default style",
AF_WRITING_SYSTEM_INDIC, AF_WRITING_SYSTEM_INDIC,
AF_SCRIPT_DEVA, AF_SCRIPT_DEVA,
(AF_Blue_Stringset)0 ) /* XXX */ (AF_Blue_Stringset)0, /* XXX */
AF_COVERAGE_DEFAULT )
STYLE( none_default, NONE_DEFAULT,
"no style",
AF_WRITING_SYSTEM_DUMMY,
AF_SCRIPT_NONE,
(AF_Blue_Stringset)0 )
STYLE( grek_default, GREK_DEFAULT, STYLE( grek_default, GREK_DEFAULT,
"Greek default style", "Greek default style",
AF_WRITING_SYSTEM_LATIN, AF_WRITING_SYSTEM_LATIN,
AF_SCRIPT_GREK, AF_SCRIPT_GREK,
AF_BLUE_STRINGSET_GREK ) AF_BLUE_STRINGSET_GREK,
AF_COVERAGE_DEFAULT )
STYLE( hani_default, HANI_DEFAULT, STYLE( hani_default, HANI_DEFAULT,
"CJKV ideographs default style", "CJKV ideographs default style",
AF_WRITING_SYSTEM_CJK, AF_WRITING_SYSTEM_CJK,
AF_SCRIPT_HANI, AF_SCRIPT_HANI,
AF_BLUE_STRINGSET_HANI ) AF_BLUE_STRINGSET_HANI,
AF_COVERAGE_DEFAULT )
STYLE( hebr_default, HEBR_DEFAULT, STYLE( hebr_default, HEBR_DEFAULT,
"Hebrew default style", "Hebrew default style",
AF_WRITING_SYSTEM_LATIN, AF_WRITING_SYSTEM_LATIN,
AF_SCRIPT_HEBR, AF_SCRIPT_HEBR,
AF_BLUE_STRINGSET_HEBR ) AF_BLUE_STRINGSET_HEBR,
AF_COVERAGE_DEFAULT )
STYLE( latn_default, LATN_DEFAULT, STYLE( latn_default, LATN_DEFAULT,
"Latin default style", "Latin default style",
AF_WRITING_SYSTEM_LATIN, AF_WRITING_SYSTEM_LATIN,
AF_SCRIPT_LATN, AF_SCRIPT_LATN,
AF_BLUE_STRINGSET_LATN ) AF_BLUE_STRINGSET_LATN,
AF_COVERAGE_DEFAULT )
#ifdef FT_OPTION_AUTOFIT2 #ifdef FT_OPTION_AUTOFIT2
STYLE( ltn2_default, LTN2_DEFAULT, STYLE( ltn2_default, LTN2_DEFAULT,
"Latin 2 default style", "Latin 2 default style",
AF_WRITING_SYSTEM_LATIN2, AF_WRITING_SYSTEM_LATIN2,
AF_SCRIPT_LATN, AF_SCRIPT_LATN,
AF_BLUE_STRINGSET_LATN ) AF_BLUE_STRINGSET_LATN,
AF_COVERAGE_DEFAULT )
#endif #endif
STYLE( none_default, NONE_DEFAULT,
"no style",
AF_WRITING_SYSTEM_DUMMY,
AF_SCRIPT_NONE,
(AF_Blue_Stringset)0,
AF_COVERAGE_DEFAULT )
/* END */ /* END */

View File

@ -303,7 +303,7 @@ extern void* _af_debug_hints;
*/ */
#undef SCRIPT #undef SCRIPT
#define SCRIPT( s, S, d, dc ) \ #define SCRIPT( s, S, d, h, dc ) \
AF_SCRIPT_ ## S, AF_SCRIPT_ ## S,
/* The list of known scripts. */ /* The list of known scripts. */
@ -341,6 +341,82 @@ extern void* _af_debug_hints;
typedef const AF_ScriptClassRec* AF_ScriptClass; typedef const AF_ScriptClassRec* AF_ScriptClass;
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** C O V E R A G E S *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/*
* Usually, a font contains more glyphs than can be addressed by its
* character map.
*
* In the PostScript font world, encoding vectors specific to a given
* task are used to select such glyphs, and these glyphs can be often
* recognized by having a suffix in its glyph names. For example, a
* superscript glyph `A' might be called `A.sup'. Unfortunately, this
* naming scheme is not standardized and thus unusable for us.
*
* In the OpenType world, a better solution was invented, namely
* `features', which cleanly separate a character's input encoding from
* the corresponding glyph's appearance, and which don't use glyph names
* at all. For our purposes, and slightly generalized, an OpenType
* feature is a name of a mapping that maps character codes to
* non-standard glyph indices (features get used for other things also).
* For example, the `sups' feature provides superscript glyphs, thus
* mapping character codes like `A' or `B' to superscript glyph
* representation forms. How this mapping happens is completely
* uninteresting to us.
*
* For the auto-hinter, a `coverage' represents all glyphs of one or more
* OpenType features collected in a set (as listed below) that can be
* hinted together. To continue the above example, superscript glyphs
* must not be hinted together with normal glyphs because the blue zones
* completely differ. On the other hand, superscripts and subscripts
* don't overlap, so they can be combined into a single set.
*
* Note that FreeType itself doesn't compute coverages; it only provides
* the glyphs addressable by the default Unicode character map. Instead,
* we use the HarfBuzz library (if available), which has many functions
* exactly for this purpose.
*
* AF_COVERAGE_DEFAULT is special: It should cover everything that isn't
* listed separately (including the glyphs addressable by the character
* map). In case HarfBuzz isn't available, it exactly covers the glyphs
* addressable by the character map.
*
*/
#undef COVERAGE_1
#define COVERAGE_1( name, NAME, description, \
tag_a1, tag_a2, tag_a3, tag_a4 ) \
AF_COVERAGE_ ## NAME,
#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 ) \
AF_COVERAGE_ ## NAME,
#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 ) \
AF_COVERAGE_ ## NAME,
typedef enum AF_Coverage_
{
#include "afcover.h"
AF_COVERAGE_DEFAULT
} AF_Coverage;
/*************************************************************************/ /*************************************************************************/
/*************************************************************************/ /*************************************************************************/
/***** *****/ /***** *****/
@ -355,7 +431,7 @@ extern void* _af_debug_hints;
*/ */
#undef STYLE #undef STYLE
#define STYLE( s, S, d, ws, sc, ss ) \ #define STYLE( s, S, d, ws, sc, ss, c ) \
AF_STYLE_ ## S, AF_STYLE_ ## S,
/* The list of known styles. */ /* The list of known styles. */
@ -376,6 +452,7 @@ extern void* _af_debug_hints;
AF_WritingSystem writing_system; AF_WritingSystem writing_system;
AF_Script script; AF_Script script;
AF_Blue_Stringset blue_stringset; AF_Blue_Stringset blue_stringset;
AF_Coverage coverage;
} AF_StyleClassRec; } AF_StyleClassRec;
@ -466,14 +543,16 @@ extern void* _af_debug_hints;
style, \ style, \
writing_system, \ writing_system, \
script, \ script, \
blue_stringset ) \ blue_stringset, \
coverage ) \
FT_CALLBACK_TABLE_DEF \ FT_CALLBACK_TABLE_DEF \
const AF_StyleClassRec style_class = \ const AF_StyleClassRec style_class = \
{ \ { \
style, \ style, \
writing_system, \ writing_system, \
script, \ script, \
blue_stringset \ blue_stringset, \
coverage \
}; };
#else /* FT_CONFIG_OPTION_PIC */ #else /* FT_CONFIG_OPTION_PIC */
@ -534,7 +613,8 @@ extern void* _af_debug_hints;
style_, \ style_, \
writing_system_, \ writing_system_, \
script_, \ script_, \
blue_stringset_ ) \ blue_stringset_, \
coverage_ ) \
FT_LOCAL_DEF( void ) \ FT_LOCAL_DEF( void ) \
FT_Init_Class_ ## style_class( AF_StyleClassRec* ac ) \ FT_Init_Class_ ## style_class( AF_StyleClassRec* ac ) \
{ \ { \
@ -542,6 +622,7 @@ extern void* _af_debug_hints;
ac->writing_system = writing_system_; \ ac->writing_system = writing_system_; \
ac->script = script_; \ ac->script = script_; \
ac->blue_stringset = blue_stringset_; \ ac->blue_stringset = blue_stringset_; \
ac->coverage = coverage_; \
} }
#endif /* FT_CONFIG_OPTION_PIC */ #endif /* FT_CONFIG_OPTION_PIC */

View File

@ -37,7 +37,8 @@
/* Define `WRITING_SYSTEM' as needed. */ /* Define `WRITING_SYSTEM' as needed. */
/* Add new writing systems here. */ /* Add new writing systems here. The arguments are the writing system */
/* name in lowercase and uppercase, respectively. */
WRITING_SYSTEM( dummy, DUMMY ) WRITING_SYSTEM( dummy, DUMMY )
WRITING_SYSTEM( latin, LATIN ) WRITING_SYSTEM( latin, LATIN )

View File

@ -34,6 +34,10 @@
#include "afcjk.c" #include "afcjk.c"
#include "afindic.c" #include "afindic.c"
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
#include "hbshim.c"
#endif
#include "afloader.c" #include "afloader.c"
#include "afmodule.c" #include "afmodule.c"

269
src/autofit/hbshim.c Normal file
View File

@ -0,0 +1,269 @@
/***************************************************************************/
/* */
/* 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 */

47
src/autofit/hbshim.h Normal file
View File

@ -0,0 +1,47 @@
/***************************************************************************/
/* */
/* hbshim.h */
/* */
/* HarfBuzz interface for accessing OpenType features (specification). */
/* */
/* 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. */
/* */
/***************************************************************************/
#ifndef __HBSHIM_H__
#define __HBSHIM_H__
#include <ft2build.h>
#include FT_FREETYPE_H
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
FT_BEGIN_HEADER
FT_Error
af_get_coverage( FT_Face face,
AF_StyleClass style_class,
FT_Byte* gstyles );
/* */
FT_END_HEADER
#endif /* FT_CONFIG_OPTION_USE_HARFBUZZ */
#endif /* __HBSHIM_H__ */
/* END */

View File

@ -37,11 +37,13 @@ AUTOF_DRV_SRC := $(AUTOF_DIR)/afangles.c \
$(AUTOF_DIR)/afmodule.c \ $(AUTOF_DIR)/afmodule.c \
$(AUTOF_DIR)/afpic.c \ $(AUTOF_DIR)/afpic.c \
$(AUTOF_DIR)/afranges.c \ $(AUTOF_DIR)/afranges.c \
$(AUTOF_DIR)/afwarp.c $(AUTOF_DIR)/afwarp.c \
$(AUTOF_DIR)/hbshim.c
# AUTOF driver headers # AUTOF driver headers
# #
AUTOF_DRV_H := $(AUTOF_DRV_SRC:%c=%h) \ AUTOF_DRV_H := $(AUTOF_DRV_SRC:%c=%h) \
$(AUTOF_DIR)/afcover.h \
$(AUTOF_DIR)/aferrors.h \ $(AUTOF_DIR)/aferrors.h \
$(AUTOF_DIR)/afscript.h \ $(AUTOF_DIR)/afscript.h \
$(AUTOF_DIR)/afstyles.h \ $(AUTOF_DIR)/afstyles.h \