summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog65
-rw-r--r--builds/freetype.mk9
-rw-r--r--devel/ftoption.h13
-rw-r--r--include/config/ftoption.h13
-rw-r--r--include/internal/fttrace.h1
-rw-r--r--src/autofit/afcover.h66
-rw-r--r--src/autofit/afglobal.c37
-rw-r--r--src/autofit/afglobal.h10
-rw-r--r--src/autofit/afmodule.c37
-rw-r--r--src/autofit/afmodule.h2
-rw-r--r--src/autofit/afpic.c4
-rw-r--r--src/autofit/afranges.h2
-rw-r--r--src/autofit/afscript.h13
-rw-r--r--src/autofit/afstyles.h40
-rw-r--r--src/autofit/aftypes.h91
-rw-r--r--src/autofit/afwrtsys.h3
-rw-r--r--src/autofit/autofit.c4
-rw-r--r--src/autofit/hbshim.c269
-rw-r--r--src/autofit/hbshim.h47
-rw-r--r--src/autofit/rules.mk4
20 files changed, 678 insertions, 52 deletions
diff --git a/ChangeLog b/ChangeLog
index 4a1f1ecae..db4b9760e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,70 @@
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>
+
Fix Savannah bug #40975 (sort of).
* src/truetype/ttinterp.c (Ins_IP): Fix sign typo to make FreeType
diff --git a/builds/freetype.mk b/builds/freetype.mk
index 68edfe505..bf372fd6c 100644
--- a/builds/freetype.mk
+++ b/builds/freetype.mk
@@ -126,6 +126,15 @@ INCLUDES := $(subst /,$(COMPILER_SEP),$(OBJ_DIR) \
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
# least the paths for the `base' and `builds/<system>' directories;
diff --git a/devel/ftoption.h b/devel/ftoption.h
index 27d1bd9a5..d7b6a6301 100644
--- a/devel/ftoption.h
+++ b/devel/ftoption.h
@@ -219,6 +219,19 @@ FT_BEGIN_HEADER
/*************************************************************************/
/* */
+ /* 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, */
/* fopen() etc. Enables the use of smaller system libraries on embedded */
/* systems that have multiple system libraries, some with or without */
diff --git a/include/config/ftoption.h b/include/config/ftoption.h
index fe2ba15b4..5b11f0e03 100644
--- a/include/config/ftoption.h
+++ b/include/config/ftoption.h
@@ -230,6 +230,19 @@ FT_BEGIN_HEADER
/*************************************************************************/
/* */
+ /* 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 */
/* */
/* When compiling FreeType as a DLL, some systems/compilers need a */
diff --git a/include/internal/fttrace.h b/include/internal/fttrace.h
index a9d98b60a..29158c08f 100644
--- a/include/internal/fttrace.h
+++ b/include/internal/fttrace.h
@@ -148,5 +148,6 @@ FT_TRACE_DEF( afcjk )
FT_TRACE_DEF( aflatin )
FT_TRACE_DEF( aflatin2 )
FT_TRACE_DEF( afwarp )
+FT_TRACE_DEF( afharfbuzz )
/* END */
diff --git a/src/autofit/afcover.h b/src/autofit/afcover.h
new file mode 100644
index 000000000..13dbecb21
--- /dev/null
+++ b/src/autofit/afcover.h
@@ -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 */
diff --git a/src/autofit/afglobal.c b/src/autofit/afglobal.c
index 1b4721c08..912a32fc3 100644
--- a/src/autofit/afglobal.c
+++ b/src/autofit/afglobal.c
@@ -18,6 +18,7 @@
#include "afglobal.h"
#include "afranges.h"
+#include "hbshim.h"
/* get writing system specific header files */
#undef WRITING_SYSTEM
@@ -29,7 +30,7 @@
#undef SCRIPT
-#define SCRIPT( s, S, d, dc ) \
+#define SCRIPT( s, S, d, h, dc ) \
AF_DEFINE_SCRIPT_CLASS( \
af_ ## s ## _script_class, \
AF_SCRIPT_ ## S, \
@@ -40,13 +41,14 @@
#undef STYLE
-#define STYLE( s, S, d, ws, sc, ss ) \
- AF_DEFINE_STYLE_CLASS( \
- af_ ## s ## _style_class, \
- AF_STYLE_ ## S, \
- ws, \
- sc, \
- ss )
+#define STYLE( s, S, d, ws, sc, ss, c ) \
+ AF_DEFINE_STYLE_CLASS( \
+ af_ ## s ## _style_class, \
+ AF_STYLE_ ## S, \
+ ws, \
+ sc, \
+ ss, \
+ c )
#include "afstyles.h"
@@ -68,7 +70,7 @@
#undef SCRIPT
-#define SCRIPT( s, S, d, dc ) \
+#define SCRIPT( s, S, d, h, dc ) \
&af_ ## s ## _script_class,
FT_LOCAL_ARRAY_DEF( AF_ScriptClass )
@@ -82,7 +84,7 @@
#undef STYLE
-#define STYLE( s, S, d, ws, sc, ss ) \
+#define STYLE( s, S, d, ws, sc, ss, c ) \
&af_ ## s ## _style_class,
FT_LOCAL_ARRAY_DEF( AF_StyleClass )
@@ -100,7 +102,7 @@
#ifdef FT_DEBUG_LEVEL_TRACE
#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* )
af_style_names[] =
@@ -135,7 +137,7 @@
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?
*/
error = FT_Err_Ok;
@@ -186,6 +188,11 @@
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 */
@@ -200,10 +207,10 @@
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?
*/
- if ( globals->module->fallback_script != AF_STYLE_UNASSIGNED )
+ if ( globals->module->fallback_style != AF_STYLE_UNASSIGNED )
{
FT_Long nn;
@@ -213,7 +220,7 @@
if ( ( gstyles[nn] & ~AF_DIGIT ) == AF_STYLE_UNASSIGNED )
{
gstyles[nn] &= ~AF_STYLE_UNASSIGNED;
- gstyles[nn] |= globals->module->fallback_script;
+ gstyles[nn] |= globals->module->fallback_style;
}
}
}
diff --git a/src/autofit/afglobal.h b/src/autofit/afglobal.h
index b0316e67e..43ce39472 100644
--- a/src/autofit/afglobal.h
+++ b/src/autofit/afglobal.h
@@ -33,7 +33,7 @@ FT_BEGIN_HEADER
#undef SCRIPT
-#define SCRIPT( s, S, d, dc ) \
+#define SCRIPT( s, S, d, h, dc ) \
AF_DECLARE_SCRIPT_CLASS( af_ ## s ## _script_class )
#include "afscript.h"
@@ -43,7 +43,7 @@ FT_BEGIN_HEADER
#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 )
#include "afstyles.h"
@@ -63,11 +63,11 @@ FT_BEGIN_HEADER
* 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
-#define AF_SCRIPT_FALLBACK AF_STYLE_HANI_DEFAULT
+#define AF_STYLE_FALLBACK AF_STYLE_HANI_DEFAULT
#else
-#define AF_SCRIPT_FALLBACK AF_STYLE_NONE_DEFAULT
+#define AF_STYLE_FALLBACK AF_STYLE_NONE_DEFAULT
#endif
/* a bit mask indicating an uncovered glyph */
#define AF_STYLE_UNASSIGNED 0x7F
diff --git a/src/autofit/afmodule.c b/src/autofit/afmodule.c
index 1ebe4a46e..d0316b3f7 100644
--- a/src/autofit/afmodule.c
+++ b/src/autofit/afmodule.c
@@ -92,8 +92,31 @@
{
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;
}
@@ -121,9 +144,9 @@
const char* property_name,
void* value )
{
- FT_Error error = FT_Err_Ok;
- AF_Module module = (AF_Module)ft_module;
- FT_UInt fallback_script = module->fallback_script;
+ FT_Error error = FT_Err_Ok;
+ AF_Module module = (AF_Module)ft_module;
+ FT_UInt fallback_style = module->fallback_style;
if ( !ft_strcmp( property_name, "glyph-to-script-map" ) )
@@ -142,8 +165,10 @@
{
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;
}
@@ -206,7 +231,7 @@
AF_Module module = (AF_Module)ft_module;
- module->fallback_script = AF_SCRIPT_FALLBACK;
+ module->fallback_style = AF_STYLE_FALLBACK;
return af_loader_init( module );
}
diff --git a/src/autofit/afmodule.h b/src/autofit/afmodule.h
index c4e8f8f66..d42c5c8ca 100644
--- a/src/autofit/afmodule.h
+++ b/src/autofit/afmodule.h
@@ -40,7 +40,7 @@ FT_BEGIN_HEADER
{
FT_ModuleRec root;
- FT_UInt fallback_script;
+ FT_UInt fallback_style;
AF_LoaderRec loader[1];
diff --git a/src/autofit/afpic.c b/src/autofit/afpic.c
index eba6a8987..3980307f2 100644
--- a/src/autofit/afpic.c
+++ b/src/autofit/afpic.c
@@ -122,7 +122,7 @@
#include "afwrtsys.h"
#undef SCRIPT
-#define SCRIPT( s, S, d, dc ) \
+#define SCRIPT( s, S, d, h, dc ) \
FT_Init_Class_af_ ## s ## _script_class( \
&container->af_script_classes_rec[ss++] );
@@ -130,7 +130,7 @@
#include "afscript.h"
#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( \
&container->af_style_classes_rec[ss++] );
diff --git a/src/autofit/afranges.h b/src/autofit/afranges.h
index 8869695a7..cb04a3b9f 100644
--- a/src/autofit/afranges.h
+++ b/src/autofit/afranges.h
@@ -26,7 +26,7 @@
FT_BEGIN_HEADER
#undef SCRIPT
-#define SCRIPT( s, S, d, dc ) \
+#define SCRIPT( s, S, d, h, dc ) \
extern const AF_Script_UniRangeRec af_ ## s ## _uniranges[];
#include "afscript.h"
diff --git a/src/autofit/afscript.h b/src/autofit/afscript.h
index 063f2af21..a9def1838 100644
--- a/src/autofit/afscript.h
+++ b/src/autofit/afscript.h
@@ -20,34 +20,45 @@
/* 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,
"Cyrillic",
+ HB_SCRIPT_CYRILLIC,
0x43E ) /* о */
SCRIPT( deva, DEVA,
"Indic scripts",
+ HB_SCRIPT_DEVANAGARI,
'o' ) /* XXX */
SCRIPT( none, NONE,
"no script",
+ HB_SCRIPT_INVALID,
'\0' )
SCRIPT( grek, GREK,
"Greek",
+ HB_SCRIPT_GREEK,
0x3BF ) /* ο */
SCRIPT( hani, HANI,
"CJKV ideographs",
+ HB_SCRIPT_HAN,
0x7530 ) /* 田 */
SCRIPT( hebr, HEBR,
"Hebrew",
+ HB_SCRIPT_HEBREW,
0x5DD ) /* ם */
SCRIPT( latn, LATN,
"Latin",
+ HB_SCRIPT_LATIN,
'o' )
diff --git a/src/autofit/afstyles.h b/src/autofit/afstyles.h
index ded804805..b5eb362ea 100644
--- a/src/autofit/afstyles.h
+++ b/src/autofit/afstyles.h
@@ -20,57 +20,69 @@
/* 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,
"Cyrillic default style",
AF_WRITING_SYSTEM_LATIN,
AF_SCRIPT_CYRL,
- AF_BLUE_STRINGSET_CYRL )
+ AF_BLUE_STRINGSET_CYRL,
+ AF_COVERAGE_DEFAULT )
STYLE( deva_default, DEVA_DEFAULT,
"Indic scripts default style",
AF_WRITING_SYSTEM_INDIC,
AF_SCRIPT_DEVA,
- (AF_Blue_Stringset)0 ) /* XXX */
-
- STYLE( none_default, NONE_DEFAULT,
- "no style",
- AF_WRITING_SYSTEM_DUMMY,
- AF_SCRIPT_NONE,
- (AF_Blue_Stringset)0 )
+ (AF_Blue_Stringset)0, /* XXX */
+ AF_COVERAGE_DEFAULT )
STYLE( grek_default, GREK_DEFAULT,
"Greek default style",
AF_WRITING_SYSTEM_LATIN,
AF_SCRIPT_GREK,
- AF_BLUE_STRINGSET_GREK )
+ AF_BLUE_STRINGSET_GREK,
+ AF_COVERAGE_DEFAULT )
STYLE( hani_default, HANI_DEFAULT,
"CJKV ideographs default style",
AF_WRITING_SYSTEM_CJK,
AF_SCRIPT_HANI,
- AF_BLUE_STRINGSET_HANI )
+ AF_BLUE_STRINGSET_HANI,
+ AF_COVERAGE_DEFAULT )
STYLE( hebr_default, HEBR_DEFAULT,
"Hebrew default style",
AF_WRITING_SYSTEM_LATIN,
AF_SCRIPT_HEBR,
- AF_BLUE_STRINGSET_HEBR )
+ AF_BLUE_STRINGSET_HEBR,
+ AF_COVERAGE_DEFAULT )
STYLE( latn_default, LATN_DEFAULT,
"Latin default style",
AF_WRITING_SYSTEM_LATIN,
AF_SCRIPT_LATN,
- AF_BLUE_STRINGSET_LATN )
+ AF_BLUE_STRINGSET_LATN,
+ AF_COVERAGE_DEFAULT )
#ifdef FT_OPTION_AUTOFIT2
STYLE( ltn2_default, LTN2_DEFAULT,
"Latin 2 default style",
AF_WRITING_SYSTEM_LATIN2,
AF_SCRIPT_LATN,
- AF_BLUE_STRINGSET_LATN )
+ AF_BLUE_STRINGSET_LATN,
+ AF_COVERAGE_DEFAULT )
#endif
+ STYLE( none_default, NONE_DEFAULT,
+ "no style",
+ AF_WRITING_SYSTEM_DUMMY,
+ AF_SCRIPT_NONE,
+ (AF_Blue_Stringset)0,
+ AF_COVERAGE_DEFAULT )
+
/* END */
diff --git a/src/autofit/aftypes.h b/src/autofit/aftypes.h
index 70ddc7fff..b6a365b3e 100644
--- a/src/autofit/aftypes.h
+++ b/src/autofit/aftypes.h
@@ -303,7 +303,7 @@ extern void* _af_debug_hints;
*/
#undef SCRIPT
-#define SCRIPT( s, S, d, dc ) \
+#define SCRIPT( s, S, d, h, dc ) \
AF_SCRIPT_ ## S,
/* The list of known scripts. */
@@ -344,6 +344,82 @@ extern void* _af_debug_hints;
/*************************************************************************/
/*************************************************************************/
/***** *****/
+ /***** 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;
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
/***** S T Y L E S *****/
/***** *****/
/*************************************************************************/
@@ -355,7 +431,7 @@ extern void* _af_debug_hints;
*/
#undef STYLE
-#define STYLE( s, S, d, ws, sc, ss ) \
+#define STYLE( s, S, d, ws, sc, ss, c ) \
AF_STYLE_ ## S,
/* The list of known styles. */
@@ -376,6 +452,7 @@ extern void* _af_debug_hints;
AF_WritingSystem writing_system;
AF_Script script;
AF_Blue_Stringset blue_stringset;
+ AF_Coverage coverage;
} AF_StyleClassRec;
@@ -466,14 +543,16 @@ extern void* _af_debug_hints;
style, \
writing_system, \
script, \
- blue_stringset ) \
+ blue_stringset, \
+ coverage ) \
FT_CALLBACK_TABLE_DEF \
const AF_StyleClassRec style_class = \
{ \
style, \
writing_system, \
script, \
- blue_stringset \
+ blue_stringset, \
+ coverage \
};
#else /* FT_CONFIG_OPTION_PIC */
@@ -534,7 +613,8 @@ extern void* _af_debug_hints;
style_, \
writing_system_, \
script_, \
- blue_stringset_ ) \
+ blue_stringset_, \
+ coverage_ ) \
FT_LOCAL_DEF( void ) \
FT_Init_Class_ ## style_class( AF_StyleClassRec* ac ) \
{ \
@@ -542,6 +622,7 @@ extern void* _af_debug_hints;
ac->writing_system = writing_system_; \
ac->script = script_; \
ac->blue_stringset = blue_stringset_; \
+ ac->coverage = coverage_; \
}
#endif /* FT_CONFIG_OPTION_PIC */
diff --git a/src/autofit/afwrtsys.h b/src/autofit/afwrtsys.h
index 602c55884..8aa2ed9e6 100644
--- a/src/autofit/afwrtsys.h
+++ b/src/autofit/afwrtsys.h
@@ -37,7 +37,8 @@
/* 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( latin, LATIN )
diff --git a/src/autofit/autofit.c b/src/autofit/autofit.c
index 930387c54..00c5af3de 100644
--- a/src/autofit/autofit.c
+++ b/src/autofit/autofit.c
@@ -34,6 +34,10 @@
#include "afcjk.c"
#include "afindic.c"
+#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
+#include "hbshim.c"
+#endif
+
#include "afloader.c"
#include "afmodule.c"
diff --git a/src/autofit/hbshim.c b/src/autofit/hbshim.c
new file mode 100644
index 000000000..b2731ad6d
--- /dev/null
+++ b/src/autofit/hbshim.c
@@ -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 */
diff --git a/src/autofit/hbshim.h b/src/autofit/hbshim.h
new file mode 100644
index 000000000..87a771e7a
--- /dev/null
+++ b/src/autofit/hbshim.h
@@ -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 */
diff --git a/src/autofit/rules.mk b/src/autofit/rules.mk
index 5bf3893ca..658f04ea5 100644
--- a/src/autofit/rules.mk
+++ b/src/autofit/rules.mk
@@ -37,11 +37,13 @@ AUTOF_DRV_SRC := $(AUTOF_DIR)/afangles.c \
$(AUTOF_DIR)/afmodule.c \
$(AUTOF_DIR)/afpic.c \
$(AUTOF_DIR)/afranges.c \
- $(AUTOF_DIR)/afwarp.c
+ $(AUTOF_DIR)/afwarp.c \
+ $(AUTOF_DIR)/hbshim.c
# AUTOF driver headers
#
AUTOF_DRV_H := $(AUTOF_DRV_SRC:%c=%h) \
+ $(AUTOF_DIR)/afcover.h \
$(AUTOF_DIR)/aferrors.h \
$(AUTOF_DIR)/afscript.h \
$(AUTOF_DIR)/afstyles.h \