aboutsummaryrefslogtreecommitdiff
path: root/freetype/src
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2013-02-13 09:55:16 +0100
committermarha <marha@users.sourceforge.net>2013-02-13 09:55:16 +0100
commit88bcd02cfecbf8ba9cf726b0d337c56f9c9b2bc4 (patch)
treeded42639873b943c7ec97b06961ad067228652d1 /freetype/src
parent3247a4e031a7d5160332c0d7ca2a91a516c082bb (diff)
parentaaf21968deb85b635cb6aa6544df233ea5981346 (diff)
downloadvcxsrv-88bcd02cfecbf8ba9cf726b0d337c56f9c9b2bc4.tar.gz
vcxsrv-88bcd02cfecbf8ba9cf726b0d337c56f9c9b2bc4.tar.bz2
vcxsrv-88bcd02cfecbf8ba9cf726b0d337c56f9c9b2bc4.zip
Merge remote-tracking branch 'origin/released'
* origin/released: Update to following packages: Conflicts: freetype/src/autofit/afhints.c freetype/src/autofit/afmodule.c freetype/src/psaux/psconv.c freetype/src/sfnt/sfntpic.h openssl/Makefile openssl/util/pl/VC-32.pl
Diffstat (limited to 'freetype/src')
-rw-r--r--freetype/src/autofit/afangles.c65
-rw-r--r--freetype/src/autofit/afcjk.c16
-rw-r--r--freetype/src/autofit/afcjk.h11
-rw-r--r--freetype/src/autofit/afdummy.c3
-rw-r--r--freetype/src/autofit/afglobal.c87
-rw-r--r--freetype/src/autofit/afglobal.h46
-rwxr-xr-x[-rw-r--r--]freetype/src/autofit/afhints.c200
-rw-r--r--freetype/src/autofit/afhints.h20
-rw-r--r--freetype/src/autofit/afindic.c6
-rw-r--r--freetype/src/autofit/afindic.h4
-rw-r--r--freetype/src/autofit/aflatin.c354
-rw-r--r--freetype/src/autofit/aflatin.h19
-rw-r--r--freetype/src/autofit/aflatin2.c82
-rw-r--r--freetype/src/autofit/aflatin2.h4
-rw-r--r--freetype/src/autofit/afloader.c37
-rw-r--r--freetype/src/autofit/afloader.h30
-rwxr-xr-x[-rw-r--r--]freetype/src/autofit/afmodule.c213
-rw-r--r--freetype/src/autofit/afmodule.h21
-rw-r--r--freetype/src/autofit/afpic.c49
-rw-r--r--freetype/src/autofit/afpic.h48
-rw-r--r--freetype/src/autofit/aftypes.h38
-rw-r--r--freetype/src/base/basepic.c40
-rw-r--r--freetype/src/base/ftgloadr.c2
-rw-r--r--freetype/src/base/ftglyph.c8
-rw-r--r--freetype/src/base/ftinit.c4
-rw-r--r--freetype/src/base/ftobjs.c169
-rw-r--r--freetype/src/base/ftoutln.c27
-rw-r--r--freetype/src/base/ftrfork.c4
-rw-r--r--freetype/src/base/ftstroke.c11
-rw-r--r--freetype/src/base/ftsynth.c2
-rw-r--r--freetype/src/base/fttrigon.c97
-rw-r--r--freetype/src/bdf/bdflib.c15
-rw-r--r--freetype/src/cache/ftccmap.c5
-rw-r--r--freetype/src/cff/cffdrivr.c26
-rw-r--r--freetype/src/cff/cffload.c41
-rw-r--r--freetype/src/cff/cffobjs.c23
-rw-r--r--freetype/src/cff/cffparse.c115
-rw-r--r--freetype/src/cff/cffpic.c4
-rw-r--r--freetype/src/cff/cffpic.h76
-rw-r--r--freetype/src/cid/cidload.c10
-rwxr-xr-x[-rw-r--r--]freetype/src/psaux/psconv.c206
-rw-r--r--freetype/src/psaux/psconv.h10
-rw-r--r--freetype/src/psaux/t1decode.c8
-rw-r--r--freetype/src/pshinter/pshglob.c51
-rw-r--r--freetype/src/pshinter/pshmod.c17
-rw-r--r--freetype/src/pshinter/pshpic.c10
-rw-r--r--freetype/src/pshinter/pshpic.h16
-rw-r--r--freetype/src/psnames/psmodule.c53
-rw-r--r--freetype/src/psnames/pspic.c15
-rw-r--r--freetype/src/psnames/pspic.h23
-rw-r--r--freetype/src/raster/rastpic.c4
-rw-r--r--freetype/src/sfnt/sfdriver.c169
-rw-r--r--freetype/src/sfnt/sfntpic.c26
-rwxr-xr-x[-rw-r--r--]freetype/src/sfnt/sfntpic.h81
-rw-r--r--freetype/src/sfnt/sfobjs.c21
-rw-r--r--freetype/src/sfnt/ttcmap.c333
-rw-r--r--freetype/src/sfnt/ttcmap.h99
-rw-r--r--freetype/src/sfnt/ttcmapc.h19
-rw-r--r--freetype/src/sfnt/ttload.c21
-rw-r--r--freetype/src/smooth/ftgrays.c29
-rw-r--r--freetype/src/smooth/ftsmooth.c57
-rw-r--r--freetype/src/smooth/ftspic.c4
-rw-r--r--freetype/src/tools/docmaker/content.py4
-rw-r--r--freetype/src/tools/docmaker/sources.py8
-rw-r--r--freetype/src/truetype/rules.mk5
-rw-r--r--freetype/src/truetype/truetype.c3
-rw-r--r--freetype/src/truetype/ttdriver.c39
-rw-r--r--freetype/src/truetype/ttgload.c163
-rw-r--r--freetype/src/truetype/ttgxvar.c59
-rw-r--r--freetype/src/truetype/ttinterp.c824
-rw-r--r--freetype/src/truetype/ttinterp.h79
-rw-r--r--freetype/src/truetype/ttobjs.c10
-rw-r--r--freetype/src/truetype/ttobjs.h18
-rw-r--r--freetype/src/truetype/ttpic.c11
-rw-r--r--freetype/src/truetype/ttpic.h31
-rw-r--r--freetype/src/truetype/ttsubpix.c265
-rw-r--r--freetype/src/truetype/ttsubpix.h908
-rw-r--r--freetype/src/type1/t1load.c36
-rw-r--r--freetype/src/type1/t1parse.c17
-rw-r--r--freetype/src/type42/t42parse.c3
80 files changed, 4404 insertions, 1383 deletions
diff --git a/freetype/src/autofit/afangles.c b/freetype/src/autofit/afangles.c
index 790af1779..b44a5ba2c 100644
--- a/freetype/src/autofit/afangles.c
+++ b/freetype/src/autofit/afangles.c
@@ -5,7 +5,7 @@
/* Routines used to compute vector angles with limited accuracy */
/* and very high speed. It also contains sorting routines (body). */
/* */
-/* Copyright 2003-2006, 2011 by */
+/* Copyright 2003-2006, 2011-2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -255,7 +255,7 @@
{
for ( j = i; j > 0; j-- )
{
- if ( table[j] > table[j - 1] )
+ if ( table[j] >= table[j - 1] )
break;
swap = table[j];
@@ -267,18 +267,26 @@
FT_LOCAL_DEF( void )
- af_sort_widths( FT_UInt count,
- AF_Width table )
+ af_sort_and_quantize_widths( FT_UInt* count,
+ AF_Width table,
+ FT_Pos threshold )
{
FT_UInt i, j;
+ FT_UInt cur_idx;
+ FT_Pos cur_val;
+ FT_Pos sum;
AF_WidthRec swap;
- for ( i = 1; i < count; i++ )
+ if ( *count == 1 )
+ return;
+
+ /* sort */
+ for ( i = 1; i < *count; i++ )
{
for ( j = i; j > 0; j-- )
{
- if ( table[j].org > table[j - 1].org )
+ if ( table[j].org >= table[j - 1].org )
break;
swap = table[j];
@@ -286,6 +294,51 @@
table[j - 1] = swap;
}
}
+
+ cur_idx = 0;
+ cur_val = table[cur_idx].org;
+
+ /* compute and use mean values for clusters not larger than */
+ /* `threshold'; this is very primitive and might not yield */
+ /* the best result, but normally, using reference character */
+ /* `o', `*count' is 2, so the code below is fully sufficient */
+ for ( i = 1; i < *count; i++ )
+ {
+ if ( table[i].org - cur_val > threshold ||
+ i == *count - 1 )
+ {
+ sum = 0;
+
+ /* fix loop for end of array */
+ if ( table[i].org - cur_val <= threshold &&
+ i == *count - 1 )
+ i++;
+
+ for ( j = cur_idx; j < i; j++ )
+ {
+ sum += table[j].org;
+ table[j].org = 0;
+ }
+ table[cur_idx].org = sum / j;
+
+ if ( i < *count - 1 )
+ {
+ cur_idx = i + 1;
+ cur_val = table[cur_idx].org;
+ }
+ }
+ }
+
+ cur_idx = 1;
+
+ /* compress array to remove zero values */
+ for ( i = 1; i < *count; i++ )
+ {
+ if ( table[i].org )
+ table[cur_idx++] = table[i];
+ }
+
+ *count = cur_idx;
}
diff --git a/freetype/src/autofit/afcjk.c b/freetype/src/autofit/afcjk.c
index f24500194..e621c44ad 100644
--- a/freetype/src/autofit/afcjk.c
+++ b/freetype/src/autofit/afcjk.c
@@ -67,8 +67,7 @@
FT_LOCAL_DEF( void )
af_cjk_metrics_init_widths( AF_CJKMetrics metrics,
- FT_Face face,
- FT_ULong charcode )
+ FT_Face face )
{
/* scan the array of segments in each direction */
AF_GlyphHintsRec hints[1];
@@ -87,7 +86,8 @@
AF_Scaler scaler = &dummy->root.scaler;
- glyph_index = FT_Get_Char_Index( face, charcode );
+ glyph_index = FT_Get_Char_Index( face,
+ metrics->root.clazz->standard_char );
if ( glyph_index == 0 )
goto Exit;
@@ -150,7 +150,10 @@
}
}
- af_sort_widths( num_widths, axis->widths );
+ /* this also replaces multiple almost identical stem widths */
+ /* with a single one (the value 100 is heuristic) */
+ af_sort_and_quantize_widths( &num_widths, axis->widths,
+ dummy->units_per_em / 100 );
axis->width_count = num_widths;
}
@@ -556,7 +559,7 @@
face->charmap = NULL;
else
{
- af_cjk_metrics_init_widths( metrics, face, 0x7530 );
+ af_cjk_metrics_init_widths( metrics, face );
af_cjk_metrics_init_blues( metrics, face, af_cjk_hani_blue_chars );
af_cjk_metrics_check_digits( metrics, face );
}
@@ -2190,6 +2193,7 @@
static const AF_Script_UniRangeRec af_cjk_uniranges[] =
{
+ AF_UNIRANGE_REC( 0x1100UL, 0x11FFUL ), /* Hangul Jamo */
AF_UNIRANGE_REC( 0x2E80UL, 0x2EFFUL ), /* CJK Radicals Supplement */
AF_UNIRANGE_REC( 0x2F00UL, 0x2FDFUL ), /* Kangxi Radicals */
AF_UNIRANGE_REC( 0x2FF0UL, 0x2FFFUL ), /* Ideographic Description Characters */
@@ -2228,6 +2232,7 @@
AF_DEFINE_SCRIPT_CLASS( af_cjk_script_class,
AF_SCRIPT_CJK,
af_cjk_uniranges,
+ 0x7530, /* 田 */
sizeof ( AF_CJKMetricsRec ),
@@ -2250,6 +2255,7 @@
AF_DEFINE_SCRIPT_CLASS( af_cjk_script_class,
AF_SCRIPT_CJK,
af_cjk_uniranges,
+ 0,
sizeof ( AF_CJKMetricsRec ),
diff --git a/freetype/src/autofit/afcjk.h b/freetype/src/autofit/afcjk.h
index 8416c0d02..ab816f20b 100644
--- a/freetype/src/autofit/afcjk.h
+++ b/freetype/src/autofit/afcjk.h
@@ -4,7 +4,7 @@
/* */
/* Auto-fitter hinting routines for CJK script (specification). */
/* */
-/* Copyright 2006, 2007, 2011 by */
+/* Copyright 2006, 2007, 2011, 2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -28,7 +28,7 @@ FT_BEGIN_HEADER
/* the CJK-specific script class */
- AF_DECLARE_SCRIPT_CLASS(af_cjk_script_class)
+ AF_DECLARE_SCRIPT_CLASS( af_cjk_script_class )
/* CJK (global) metrics management */
@@ -103,6 +103,7 @@ FT_BEGIN_HEADER
} AF_CJKMetricsRec, *AF_CJKMetrics;
+#ifdef AF_CONFIG_OPTION_CJK
FT_LOCAL( FT_Error )
af_cjk_metrics_init( AF_CJKMetrics metrics,
FT_Face face );
@@ -120,15 +121,15 @@ FT_BEGIN_HEADER
FT_Outline* outline,
AF_CJKMetrics metrics );
- /* Shared. called from afindic.c */
+ /* shared; called from afindic.c */
FT_LOCAL( void )
af_cjk_metrics_check_digits( AF_CJKMetrics metrics,
FT_Face face );
FT_LOCAL( void )
af_cjk_metrics_init_widths( AF_CJKMetrics metrics,
- FT_Face face,
- FT_ULong charcode );
+ FT_Face face );
+#endif /* AF_CONFIG_OPTION_CJK */
/* */
diff --git a/freetype/src/autofit/afdummy.c b/freetype/src/autofit/afdummy.c
index 4bf278ce2..2258a198a 100644
--- a/freetype/src/autofit/afdummy.c
+++ b/freetype/src/autofit/afdummy.c
@@ -44,8 +44,9 @@
AF_DEFINE_SCRIPT_CLASS( af_dummy_script_class,
- AF_SCRIPT_NONE,
+ AF_SCRIPT_DUMMY,
NULL,
+ 0,
sizeof ( AF_ScriptMetricsRec ),
diff --git a/freetype/src/autofit/afglobal.c b/freetype/src/autofit/afglobal.c
index 3e0c02d3f..3c1e837ed 100644
--- a/freetype/src/autofit/afglobal.c
+++ b/freetype/src/autofit/afglobal.c
@@ -4,7 +4,7 @@
/* */
/* Auto-fitter routines to compute global hinting values (body). */
/* */
-/* Copyright 2003-2011 by */
+/* Copyright 2003-2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -49,29 +49,6 @@
#endif /* !FT_CONFIG_OPTION_PIC */
- /* index of default script in `af_script_classes' */
-#define AF_SCRIPT_LIST_DEFAULT 2
- /* a bit mask indicating an uncovered glyph */
-#define AF_SCRIPT_LIST_NONE 0x7F
- /* if this flag is set, we have an ASCII digit */
-#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. */
@@ -82,19 +59,20 @@
FT_Face face = globals->face;
FT_CharMap old_charmap = face->charmap;
FT_Byte* gscripts = globals->glyph_scripts;
- FT_UInt ss, i;
+ FT_UInt ss;
+ FT_UInt i;
- /* the value AF_SCRIPT_LIST_NONE means `uncovered glyph' */
+ /* the value AF_SCRIPT_NONE means `uncovered glyph' */
FT_MEM_SET( globals->glyph_scripts,
- AF_SCRIPT_LIST_NONE,
+ AF_SCRIPT_NONE,
globals->glyph_count );
error = FT_Select_Charmap( face, FT_ENCODING_UNICODE );
if ( error )
{
/*
- * Ignore this error; we simply use the default script.
+ * Ignore this error; we simply use the fallback script.
* XXX: Shouldn't we rather disable hinting?
*/
error = AF_Err_Ok;
@@ -112,7 +90,7 @@
continue;
/*
- * Scan all unicode points in the range and set the corresponding
+ * Scan all Unicode points in the range and set the corresponding
* glyph script index.
*/
for ( range = clazz->script_uni_ranges; range->first != 0; range++ )
@@ -125,7 +103,7 @@
if ( gindex != 0 &&
gindex < (FT_ULong)globals->glyph_count &&
- gscripts[gindex] == AF_SCRIPT_LIST_NONE )
+ gscripts[gindex] == AF_SCRIPT_NONE )
gscripts[gindex] = (FT_Byte)ss;
for (;;)
@@ -136,7 +114,7 @@
break;
if ( gindex < (FT_ULong)globals->glyph_count &&
- gscripts[gindex] == AF_SCRIPT_LIST_NONE )
+ gscripts[gindex] == AF_SCRIPT_NONE )
gscripts[gindex] = (FT_Byte)ss;
}
}
@@ -154,19 +132,20 @@
Exit:
/*
- * By default, all uncovered glyphs are set to the latin script.
+ * By default, all uncovered glyphs are set to the fallback script.
* XXX: Shouldn't we disable hinting or do something similar?
*/
+ if ( globals->module->fallback_script != AF_SCRIPT_NONE )
{
FT_Long nn;
for ( nn = 0; nn < globals->glyph_count; nn++ )
{
- if ( ( gscripts[nn] & ~AF_DIGIT ) == AF_SCRIPT_LIST_NONE )
+ if ( ( gscripts[nn] & ~AF_DIGIT ) == AF_SCRIPT_NONE )
{
- gscripts[nn] &= ~AF_SCRIPT_LIST_NONE;
- gscripts[nn] |= AF_SCRIPT_LIST_DEFAULT;
+ gscripts[nn] &= ~AF_SCRIPT_NONE;
+ gscripts[nn] |= globals->module->fallback_script;
}
}
}
@@ -178,7 +157,8 @@
FT_LOCAL_DEF( FT_Error )
af_face_globals_new( FT_Face face,
- AF_FaceGlobals *aglobals )
+ AF_FaceGlobals *aglobals,
+ AF_Module module )
{
FT_Error error;
FT_Memory memory;
@@ -187,21 +167,25 @@
memory = face->memory;
- if ( !FT_ALLOC( globals, sizeof ( *globals ) +
- face->num_glyphs * sizeof ( FT_Byte ) ) )
- {
- globals->face = face;
- globals->glyph_count = face->num_glyphs;
- globals->glyph_scripts = (FT_Byte*)( globals + 1 );
+ if ( FT_ALLOC( globals, sizeof ( *globals ) +
+ face->num_glyphs * sizeof ( FT_Byte ) ) )
+ goto Exit;
- error = af_face_globals_compute_script_coverage( globals );
- if ( error )
- {
- af_face_globals_free( globals );
- globals = NULL;
- }
+ globals->face = face;
+ globals->glyph_count = face->num_glyphs;
+ globals->glyph_scripts = (FT_Byte*)( globals + 1 );
+ globals->module = module;
+
+ error = af_face_globals_compute_script_coverage( globals );
+ if ( error )
+ {
+ af_face_globals_free( globals );
+ globals = NULL;
}
+ globals->increase_x_height = AF_PROP_INCREASE_X_HEIGHT_MAX;
+
+ Exit:
*aglobals = globals;
return error;
}
@@ -264,7 +248,7 @@
gidx = script;
if ( gidx == 0 || gidx + 1 >= script_max )
- gidx = globals->glyph_scripts[gindex] & AF_SCRIPT_LIST_NONE;
+ gidx = globals->glyph_scripts[gindex] & AF_SCRIPT_NONE;
clazz = AF_SCRIPT_CLASSES_GET[gidx];
if ( script == 0 )
@@ -273,14 +257,15 @@
metrics = globals->metrics[clazz->script];
if ( metrics == NULL )
{
- /* create the global metrics object when needed */
+ /* create the global metrics object if necessary */
FT_Memory memory = globals->face->memory;
if ( FT_ALLOC( metrics, clazz->script_metrics_size ) )
goto Exit;
- metrics->clazz = clazz;
+ metrics->clazz = clazz;
+ metrics->globals = globals;
if ( clazz->script_metrics_init )
{
diff --git a/freetype/src/autofit/afglobal.h b/freetype/src/autofit/afglobal.h
index cc6860b26..2e2490082 100644
--- a/freetype/src/autofit/afglobal.h
+++ b/freetype/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, */
@@ -22,11 +22,29 @@
#include "aftypes.h"
+#include "afmodule.h"
FT_BEGIN_HEADER
+ /*
+ * Default values and flags for both autofitter globals (found in
+ * AF_ModuleRec) and face globals (in AF_FaceGlobalsRec).
+ */
+
+ /* index of fallback script in `af_script_classes' */
+#define AF_SCRIPT_FALLBACK 2
+ /* a bit mask indicating an uncovered glyph */
+#define AF_SCRIPT_NONE 0x7F
+ /* if this flag is set, we have an ASCII digit */
+#define AF_DIGIT 0x80
+
+ /* `increase-x-height' property */
+#define AF_PROP_INCREASE_X_HEIGHT_MIN 6
+#define AF_PROP_INCREASE_X_HEIGHT_MAX 0
+
+
/************************************************************************/
/************************************************************************/
/***** *****/
@@ -37,15 +55,35 @@ 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;
+
+ /* per-face auto-hinter properties */
+ FT_UInt increase_x_height;
+
+ AF_ScriptMetrics metrics[AF_SCRIPT_MAX];
+
+ AF_Module module; /* to access global properties */
+
+ } AF_FaceGlobalsRec;
+
+
+ /*
* model the global hints data for a given face, decomposed into
* script-specific items
*/
- typedef struct AF_FaceGlobalsRec_* AF_FaceGlobals;
-
FT_LOCAL( FT_Error )
af_face_globals_new( FT_Face face,
- AF_FaceGlobals *aglobals );
+ AF_FaceGlobals *aglobals,
+ AF_Module module );
FT_LOCAL( FT_Error )
af_face_globals_get_metrics( AF_FaceGlobals globals,
diff --git a/freetype/src/autofit/afhints.c b/freetype/src/autofit/afhints.c
index 25864c52f..01708b3d7 100644..100755
--- a/freetype/src/autofit/afhints.c
+++ b/freetype/src/autofit/afhints.c
@@ -4,7 +4,7 @@
/* */
/* Auto-fitter hinting routines (body). */
/* */
-/* Copyright 2003-2007, 2009-2011 by */
+/* Copyright 2003-2007, 2009-2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -19,6 +19,17 @@
#include "afhints.h"
#include "aferrors.h"
#include <freetype/internal/ftcalc.h>
+#include FT_INTERNAL_DEBUG_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_afhints
/* Get new segment for given axis. */
@@ -70,7 +81,7 @@
FT_Int fpos,
AF_Direction dir,
FT_Memory memory,
- AF_Edge *aedge )
+ AF_Edge *anedge )
{
FT_Error error = AF_Err_Ok;
AF_Edge edge = NULL;
@@ -124,7 +135,7 @@
edge->dir = (FT_Char)dir;
Exit:
- *aedge = edge;
+ *anedge = edge;
return error;
}
@@ -175,29 +186,27 @@
AF_Point point;
- printf( "Table of points:\n" );
- printf( " [ index | xorg | yorg | xscale | yscale"
- " | xfit | yfit | flags ]\n" );
+ FT_TRACE7(( "Table of points:\n"
+ " [ index | xorg | yorg | xscale | yscale"
+ " | xfit | yfit | flags ]\n" ));
for ( point = points; point < limit; point++ )
- {
- printf( " [ %5d | %5d | %5d | %6.2f | %6.2f"
- " | %5.2f | %5.2f | %c%c%c%c%c%c ]\n",
- point - points,
- point->fx,
- point->fy,
- point->ox / 64.0,
- point->oy / 64.0,
- point->x / 64.0,
- point->y / 64.0,
- ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ? 'w' : ' ',
- ( point->flags & AF_FLAG_INFLECTION ) ? 'i' : ' ',
- ( point->flags & AF_FLAG_EXTREMA_X ) ? '<' : ' ',
- ( point->flags & AF_FLAG_EXTREMA_Y ) ? 'v' : ' ',
- ( point->flags & AF_FLAG_ROUND_X ) ? '(' : ' ',
- ( point->flags & AF_FLAG_ROUND_Y ) ? 'u' : ' ');
- }
- printf( "\n" );
+ FT_TRACE7(( " [ %5d | %5d | %5d | %6.2f | %6.2f"
+ " | %5.2f | %5.2f | %c%c%c%c%c%c ]\n",
+ point - points,
+ point->fx,
+ point->fy,
+ point->ox / 64.0,
+ point->oy / 64.0,
+ point->x / 64.0,
+ point->y / 64.0,
+ ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ? 'w' : ' ',
+ ( point->flags & AF_FLAG_INFLECTION ) ? 'i' : ' ',
+ ( point->flags & AF_FLAG_EXTREMA_X ) ? '<' : ' ',
+ ( point->flags & AF_FLAG_EXTREMA_Y ) ? 'v' : ' ',
+ ( point->flags & AF_FLAG_ROUND_X ) ? '(' : ' ',
+ ( point->flags & AF_FLAG_ROUND_Y ) ? 'u' : ' '));
+ FT_TRACE7(( "\n" ));
}
#ifdef __cplusplus
}
@@ -226,7 +235,7 @@
if ( pos == 0 )
return "normal";
- temp[pos] = 0;
+ temp[pos] = '\0';
return temp;
}
@@ -246,30 +255,41 @@
for ( dimension = 1; dimension >= 0; dimension-- )
{
AF_AxisHints axis = &hints->axis[dimension];
+ AF_Point points = hints->points;
+ AF_Edge edges = axis->edges;
AF_Segment segments = axis->segments;
AF_Segment limit = segments + axis->num_segments;
AF_Segment seg;
- printf ( "Table of %s segments:\n",
- dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" );
- printf ( " [ index | pos | dir | link | serif |"
- " height | extra | flags ]\n" );
+ FT_TRACE7(( "Table of %s segments:\n",
+ dimension == AF_DIMENSION_HORZ ? "vertical"
+ : "horizontal" ));
+ if (axis->num_segments)
+ FT_TRACE7(( " [ index | pos | dir | from"
+ " | to | link | serif | edge"
+ " | height | extra | flags ]\n" ));
+ else
+ FT_TRACE7(( " (none)\n" ));
for ( seg = segments; seg < limit; seg++ )
- {
- printf ( " [ %5d | %5.2g | %5s | %4d | %5d | %6d | %5d | %11s ]\n",
- seg - segments,
- dimension == AF_DIMENSION_HORZ ? (int)seg->first->ox / 64.0
- : (int)seg->first->oy / 64.0,
- af_dir_str( (AF_Direction)seg->dir ),
- AF_INDEX_NUM( seg->link, segments ),
- AF_INDEX_NUM( seg->serif, segments ),
- seg->height,
- seg->height - ( seg->max_coord - seg->min_coord ),
- af_edge_flags_to_string( (AF_Edge_Flags)seg->flags ) );
- }
- printf( "\n" );
+ FT_TRACE7(( " [ %5d | %5.2g | %5s | %4d"
+ " | %4d | %4d | %5d | %4d"
+ " | %6d | %5d | %11s ]\n",
+ seg - segments,
+ dimension == AF_DIMENSION_HORZ
+ ? (int)seg->first->ox / 64.0
+ : (int)seg->first->oy / 64.0,
+ af_dir_str( (AF_Direction)seg->dir ),
+ AF_INDEX_NUM( seg->first, points ),
+ AF_INDEX_NUM( seg->last, points ),
+ AF_INDEX_NUM( seg->link, segments ),
+ AF_INDEX_NUM( seg->serif, segments ),
+ AF_INDEX_NUM( seg->edge, edges ),
+ seg->height,
+ seg->height - ( seg->max_coord - seg->min_coord ),
+ af_edge_flags_to_string( (AF_Edge_Flags)seg->flags ) ));
+ FT_TRACE7(( "\n" ));
}
}
#ifdef __cplusplus
@@ -363,26 +383,28 @@
* note: AF_DIMENSION_HORZ corresponds to _vertical_ edges
* since they have a constant X coordinate.
*/
- printf ( "Table of %s edges:\n",
- dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" );
- printf ( " [ index | pos | dir | link |"
- " serif | blue | opos | pos | flags ]\n" );
+ FT_TRACE7(( "Table of %s edges:\n",
+ dimension == AF_DIMENSION_HORZ ? "vertical"
+ : "horizontal" ));
+ if ( axis->num_edges )
+ FT_TRACE7(( " [ index | pos | dir | link"
+ " | serif | blue | opos | pos | flags ]\n" ));
+ else
+ FT_TRACE7(( " (none)\n" ));
for ( edge = edges; edge < limit; edge++ )
- {
- printf ( " [ %5d | %5.2g | %5s | %4d |"
- " %5d | %c | %5.2f | %5.2f | %11s ]\n",
- edge - edges,
- (int)edge->opos / 64.0,
- af_dir_str( (AF_Direction)edge->dir ),
- AF_INDEX_NUM( edge->link, edges ),
- AF_INDEX_NUM( edge->serif, edges ),
- edge->blue_edge ? 'y' : 'n',
- edge->opos / 64.0,
- edge->pos / 64.0,
- af_edge_flags_to_string( (AF_Edge_Flags)edge->flags ) );
- }
- printf( "\n" );
+ FT_TRACE7(( " [ %5d | %5.2g | %5s | %4d"
+ " | %5d | %c | %5.2f | %5.2f | %11s ]\n",
+ edge - edges,
+ (int)edge->opos / 64.0,
+ af_dir_str( (AF_Direction)edge->dir ),
+ AF_INDEX_NUM( edge->link, edges ),
+ AF_INDEX_NUM( edge->serif, edges ),
+ edge->blue_edge ? 'y' : 'n',
+ edge->opos / 64.0,
+ edge->pos / 64.0,
+ af_edge_flags_to_string( (AF_Edge_Flags)edge->flags ) ));
+ FT_TRACE7(( "\n" ));
}
}
#ifdef __cplusplus
@@ -494,8 +516,8 @@
}
}
- /* return no direction if arm lengths differ too much */
- /* (value 14 is heuristic) */
+ /* return no direction if arm lengths differ too much */
+ /* (value 14 is heuristic, corresponding to approx. 4.1 degrees) */
ss *= 14;
if ( FT_ABS( ll ) <= FT_ABS( ss ) )
dir = AF_DIR_NONE;
@@ -516,40 +538,40 @@
FT_LOCAL_DEF( void )
af_glyph_hints_done( AF_GlyphHints hints )
{
- if ( hints && hints->memory )
- {
- FT_Memory memory = hints->memory;
- int dim;
+ FT_Memory memory = hints->memory;
+ int dim;
- /*
- * note that we don't need to free the segment and edge
- * buffers since they are really within the hints->points array
- */
- for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
- {
- AF_AxisHints axis = &hints->axis[dim];
+ if ( !( hints && hints->memory ) )
+ return;
+ /*
+ * note that we don't need to free the segment and edge
+ * buffers since they are really within the hints->points array
+ */
+ for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
+ {
+ AF_AxisHints axis = &hints->axis[dim];
- axis->num_segments = 0;
- axis->max_segments = 0;
- FT_FREE( axis->segments );
- axis->num_edges = 0;
- axis->max_edges = 0;
- FT_FREE( axis->edges );
- }
+ axis->num_segments = 0;
+ axis->max_segments = 0;
+ FT_FREE( axis->segments );
- FT_FREE( hints->contours );
- hints->max_contours = 0;
- hints->num_contours = 0;
+ axis->num_edges = 0;
+ axis->max_edges = 0;
+ FT_FREE( axis->edges );
+ }
- FT_FREE( hints->points );
- hints->num_points = 0;
- hints->max_points = 0;
+ FT_FREE( hints->contours );
+ hints->max_contours = 0;
+ hints->num_contours = 0;
- hints->memory = NULL;
- }
+ FT_FREE( hints->points );
+ hints->num_points = 0;
+ hints->max_points = 0;
+
+ hints->memory = NULL;
}
@@ -745,7 +767,7 @@
/* check for weak points */
- if ( point->flags & ( AF_FLAG_CONIC | AF_FLAG_CUBIC ) )
+ if ( point->flags & AF_FLAG_CONTROL )
{
Is_Weak_Point:
point->flags |= AF_FLAG_WEAK_INTERPOLATION;
diff --git a/freetype/src/autofit/afhints.h b/freetype/src/autofit/afhints.h
index 1c52e0de7..776b3c844 100644
--- a/freetype/src/autofit/afhints.h
+++ b/freetype/src/autofit/afhints.h
@@ -4,7 +4,7 @@
/* */
/* Auto-fitter hinting routines (specification). */
/* */
-/* Copyright 2003-2008, 2010-2011 by */
+/* Copyright 2003-2008, 2010-2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -254,7 +254,7 @@ FT_BEGIN_HEADER
FT_Char out_dir; /* direction of outwards vector */
FT_Pos ox, oy; /* original, scaled position */
- FT_Short fx, fy; /* original, unscaled position (font units) */
+ FT_Short fx, fy; /* original, unscaled position (in font units) */
FT_Pos x, y; /* current position */
FT_Pos u, v; /* current (x,y) or (y,x) depending on context */
@@ -290,19 +290,19 @@ FT_BEGIN_HEADER
typedef struct AF_EdgeRec_
{
- FT_Short fpos; /* original, unscaled position (font units) */
- FT_Pos opos; /* original, scaled position */
- FT_Pos pos; /* current position */
+ FT_Short fpos; /* original, unscaled position (in font units) */
+ FT_Pos opos; /* original, scaled position */
+ FT_Pos pos; /* current position */
FT_Byte flags; /* edge flags */
FT_Char dir; /* edge direction */
FT_Fixed scale; /* used to speed up interpolation between edges */
- AF_Width blue_edge; /* non-NULL if this is a blue edge */
- AF_Edge link; /* link edge */
- AF_Edge serif; /* primary edge for serifs */
- FT_Short num_linked; /* number of linked edges */
- FT_Int score; /* used during stem matching */
+ AF_Width blue_edge; /* non-NULL if this is a blue edge */
+ AF_Edge link; /* link edge */
+ AF_Edge serif; /* primary edge for serifs */
+ FT_Short num_linked; /* number of linked edges */
+ FT_Int score; /* used during stem matching */
AF_Segment first; /* first segment in edge */
AF_Segment last; /* last segment in edge */
diff --git a/freetype/src/autofit/afindic.c b/freetype/src/autofit/afindic.c
index 9c74838fe..70de70ba9 100644
--- a/freetype/src/autofit/afindic.c
+++ b/freetype/src/autofit/afindic.c
@@ -4,7 +4,7 @@
/* */
/* Auto-fitter hinting routines for Indic scripts (body). */
/* */
-/* Copyright 2007, 2011 by */
+/* Copyright 2007, 2011, 2012 by */
/* Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -46,7 +46,7 @@
face->charmap = NULL;
else
{
- af_cjk_metrics_init_widths( metrics, face, 0x7530 );
+ af_cjk_metrics_init_widths( metrics, face );
#if 0
/* either need indic specific blue_chars[] or just skip blue zones */
af_cjk_metrics_init_blues( metrics, face, af_cjk_blue_chars );
@@ -116,6 +116,7 @@
AF_DEFINE_SCRIPT_CLASS( af_indic_script_class,
AF_SCRIPT_INDIC,
af_indic_uniranges,
+ 'o', /* XXX */
sizeof ( AF_CJKMetricsRec ),
@@ -138,6 +139,7 @@
AF_DEFINE_SCRIPT_CLASS( af_indic_script_class,
AF_SCRIPT_INDIC,
af_indic_uniranges,
+ 0,
sizeof ( AF_CJKMetricsRec ),
diff --git a/freetype/src/autofit/afindic.h b/freetype/src/autofit/afindic.h
index 662a98220..c252cf20d 100644
--- a/freetype/src/autofit/afindic.h
+++ b/freetype/src/autofit/afindic.h
@@ -4,7 +4,7 @@
/* */
/* Auto-fitter hinting routines for Indic scripts (specification). */
/* */
-/* Copyright 2007 by */
+/* Copyright 2007, 2012 by */
/* Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -27,7 +27,7 @@ FT_BEGIN_HEADER
/* the Indic-specific script class */
- AF_DECLARE_SCRIPT_CLASS(af_indic_script_class)
+ AF_DECLARE_SCRIPT_CLASS( af_indic_script_class )
/* */
diff --git a/freetype/src/autofit/aflatin.c b/freetype/src/autofit/aflatin.c
index 532747ea4..fd2bfe96e 100644
--- a/freetype/src/autofit/aflatin.c
+++ b/freetype/src/autofit/aflatin.c
@@ -20,6 +20,7 @@
#include <freetype/ftadvanc.h>
#include <freetype/internal/ftdebug.h>
+#include "afglobal.h"
#include "aflatin.h"
#include "aferrors.h"
@@ -53,30 +54,36 @@
FT_LOCAL_DEF( void )
af_latin_metrics_init_widths( AF_LatinMetrics metrics,
- FT_Face face,
- FT_ULong charcode )
+ FT_Face face )
{
/* scan the array of segments in each direction */
AF_GlyphHintsRec hints[1];
+ FT_TRACE5(( "standard widths computation\n"
+ "===========================\n\n" ));
+
af_glyph_hints_init( hints, face->memory );
metrics->axis[AF_DIMENSION_HORZ].width_count = 0;
metrics->axis[AF_DIMENSION_VERT].width_count = 0;
{
- FT_Error error;
- FT_UInt glyph_index;
- int dim;
- AF_LatinMetricsRec dummy[1];
- AF_Scaler scaler = &dummy->root.scaler;
+ FT_Error error;
+ FT_UInt glyph_index;
+ int dim;
+ AF_LatinMetricsRec dummy[1];
+ AF_Scaler scaler = &dummy->root.scaler;
- glyph_index = FT_Get_Char_Index( face, charcode );
+ glyph_index = FT_Get_Char_Index( face,
+ metrics->root.clazz->standard_char );
if ( glyph_index == 0 )
goto Exit;
+ FT_TRACE5(( "standard character: 0x%X (glyph index %d)\n",
+ metrics->root.clazz->standard_char, glyph_index ));
+
error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );
if ( error || face->glyph->outline.n_points <= 0 )
goto Exit;
@@ -138,7 +145,10 @@
}
}
- af_sort_widths( num_widths, axis->widths );
+ /* this also replaces multiple almost identical stem widths */
+ /* with a single one (the value 100 is heuristic) */
+ af_sort_and_quantize_widths( &num_widths, axis->widths,
+ dummy->units_per_em / 100 );
axis->width_count = num_widths;
}
@@ -157,9 +167,28 @@
axis->edge_distance_threshold = stdw / 5;
axis->standard_width = stdw;
axis->extra_light = 0;
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+ {
+ FT_UInt i;
+
+
+ FT_TRACE5(( "%s widths:\n",
+ dim == AF_DIMENSION_VERT ? "horizontal"
+ : "vertical" ));
+
+ FT_TRACE5(( " %d (standard)", axis->standard_width ));
+ for ( i = 1; i < axis->width_count; i++ )
+ FT_TRACE5(( " %d", axis->widths[i].org ));
+
+ FT_TRACE5(( "\n" ));
+ }
+#endif
}
}
+ FT_TRACE5(( "\n" ));
+
af_glyph_hints_done( hints );
}
@@ -195,15 +224,15 @@
AF_LatinBlue blue;
FT_Error error;
AF_LatinAxis axis = &metrics->axis[AF_DIMENSION_VERT];
- FT_GlyphSlot glyph = face->glyph;
+ FT_Outline outline;
/* we compute the blues simply by loading each character from the */
/* `af_latin_blue_chars[blues]' string, then finding its top-most or */
/* bottom-most points (depending on `AF_IS_TOP_BLUE') */
- FT_TRACE5(( "blue zones computation\n" ));
- FT_TRACE5(( "------------------------------------------------\n" ));
+ FT_TRACE5(( "blue zones computation\n"
+ "======================\n\n" ));
for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ )
{
@@ -213,7 +242,7 @@
FT_Pos* blue_shoot;
- FT_TRACE5(( "blue %3d: ", bb ));
+ FT_TRACE5(( "blue zone %d:\n", bb ));
num_flats = 0;
num_rounds = 0;
@@ -222,28 +251,27 @@
{
FT_UInt glyph_index;
FT_Pos best_y; /* same as points.y */
- FT_Int best_point, best_first, best_last;
+ FT_Int best_point, best_contour_first, best_contour_last;
FT_Vector* points;
FT_Bool round = 0;
- FT_TRACE5(( "'%c'", *p ));
-
/* load the character in the face -- skip unknown or empty ones */
glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p );
if ( glyph_index == 0 )
continue;
- error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );
- if ( error || glyph->outline.n_points <= 0 )
+ error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );
+ outline = face->glyph->outline;
+ if ( error || outline.n_points <= 0 )
continue;
/* now compute min or max point indices and coordinates */
- points = glyph->outline.points;
- best_point = -1;
- best_y = 0; /* make compiler happy */
- best_first = 0; /* ditto */
- best_last = 0; /* ditto */
+ points = outline.points;
+ best_point = -1;
+ best_y = 0; /* make compiler happy */
+ best_contour_first = 0; /* ditto */
+ best_contour_last = 0; /* ditto */
{
FT_Int nn;
@@ -251,15 +279,13 @@
FT_Int last = -1;
- for ( nn = 0;
- nn < glyph->outline.n_contours;
- first = last + 1, nn++ )
+ for ( nn = 0; nn < outline.n_contours; first = last + 1, nn++ )
{
FT_Int old_best_point = best_point;
FT_Int pp;
- last = glyph->outline.contours[nn];
+ last = outline.contours[nn];
/* Avoid single-point contours since they are never rasterized. */
/* In some fonts, they correspond to mark attachment points */
@@ -288,11 +314,11 @@
if ( best_point != old_best_point )
{
- best_first = first;
- best_last = last;
+ best_contour_first = first;
+ best_contour_last = last;
}
}
- FT_TRACE5(( "%5d", best_y ));
+ FT_TRACE5(( " %c %ld", *p, best_y ));
}
/* now check whether the point belongs to a straight or round */
@@ -300,47 +326,86 @@
/* lies, then inspect its previous and next points */
if ( best_point >= 0 )
{
+ FT_Pos best_x = points[best_point].x;
FT_Int prev, next;
+ FT_Int best_on_point_first, best_on_point_last;
FT_Pos dist;
- /* now look for the previous and next points that are not on the */
- /* same Y coordinate. Threshold the `closeness'... */
+ if ( FT_CURVE_TAG( outline.tags[best_point] ) == FT_CURVE_TAG_ON )
+ {
+ best_on_point_first = best_point;
+ best_on_point_last = best_point;
+ }
+ else
+ {
+ best_on_point_first = -1;
+ best_on_point_last = -1;
+ }
+
+ /* look for the previous and next points that are not on the */
+ /* same Y coordinate, then threshold the `closeness'... */
prev = best_point;
next = prev;
do
{
- if ( prev > best_first )
+ if ( prev > best_contour_first )
prev--;
else
- prev = best_last;
+ prev = best_contour_last;
- dist = points[prev].y - best_y;
- if ( dist < -5 || dist > 5 )
- break;
+ dist = FT_ABS( points[prev].y - best_y );
+ /* accept a small distance or a small angle (both values are */
+ /* heuristic; value 20 corresponds to approx. 2.9 degrees) */
+ if ( dist > 5 )
+ if ( FT_ABS( points[prev].x - best_x ) <= 20 * dist )
+ break;
+
+ if ( FT_CURVE_TAG( outline.tags[prev] ) == FT_CURVE_TAG_ON )
+ {
+ best_on_point_first = prev;
+ if ( best_on_point_last < 0 )
+ best_on_point_last = prev;
+ }
} while ( prev != best_point );
do
{
- if ( next < best_last )
+ if ( next < best_contour_last )
next++;
else
- next = best_first;
+ next = best_contour_first;
- dist = points[next].y - best_y;
- if ( dist < -5 || dist > 5 )
- break;
+ dist = FT_ABS( points[next].y - best_y );
+ if ( dist > 5 )
+ if ( FT_ABS( points[next].x - best_x ) <= 20 * dist )
+ break;
+
+ if ( FT_CURVE_TAG( outline.tags[next] ) == FT_CURVE_TAG_ON )
+ {
+ best_on_point_last = next;
+ if ( best_on_point_first < 0 )
+ best_on_point_first = next;
+ }
} while ( next != best_point );
/* now set the `round' flag depending on the segment's kind */
- round = FT_BOOL(
- FT_CURVE_TAG( glyph->outline.tags[prev] ) != FT_CURVE_TAG_ON ||
- FT_CURVE_TAG( glyph->outline.tags[next] ) != FT_CURVE_TAG_ON );
+ /* (value 8 is heuristic) */
+ if ( best_on_point_first >= 0 &&
+ best_on_point_last >= 0 &&
+ (FT_UInt)( FT_ABS( points[best_on_point_last].x -
+ points[best_on_point_first].x ) ) >
+ metrics->units_per_em / 8 )
+ round = 0;
+ else
+ round = FT_BOOL(
+ FT_CURVE_TAG( outline.tags[prev] ) != FT_CURVE_TAG_ON ||
+ FT_CURVE_TAG( outline.tags[next] ) != FT_CURVE_TAG_ON );
- FT_TRACE5(( "%c ", round ? 'r' : 'f' ));
+ FT_TRACE5(( " (%s)\n", round ? "round" : "flat" ));
}
if ( round )
@@ -349,15 +414,13 @@
flats[num_flats++] = best_y;
}
- FT_TRACE5(( "\n" ));
-
if ( num_flats == 0 && num_rounds == 0 )
{
/*
* we couldn't find a single glyph to compute this blue zone,
* we will simply ignore it then
*/
- FT_TRACE5(( "empty\n" ));
+ FT_TRACE5(( " empty\n" ));
continue;
}
@@ -400,8 +463,13 @@
if ( AF_LATIN_IS_TOP_BLUE( bb ) ^ over_ref )
+ {
*blue_ref =
*blue_shoot = ( shoot + ref ) / 2;
+
+ FT_TRACE5(( " [overshoot smaller than reference,"
+ " taking mean value]\n" ));
+ }
}
blue->flags = 0;
@@ -416,7 +484,9 @@
if ( bb == AF_LATIN_BLUE_SMALL_TOP )
blue->flags |= AF_LATIN_BLUE_ADJUSTMENT;
- FT_TRACE5(( "-- ref = %ld, shoot = %ld\n", *blue_ref, *blue_shoot ));
+ FT_TRACE5(( " -> reference = %ld\n"
+ " overshoot = %ld\n",
+ *blue_ref, *blue_shoot ));
}
FT_TRACE5(( "\n" ));
@@ -478,35 +548,14 @@
af_latin_metrics_init( AF_LatinMetrics metrics,
FT_Face face )
{
- FT_Error error = AF_Err_Ok;
FT_CharMap oldmap = face->charmap;
- FT_UInt ee;
-
- static const FT_Encoding latin_encodings[] =
- {
- FT_ENCODING_UNICODE,
- FT_ENCODING_APPLE_ROMAN,
- FT_ENCODING_ADOBE_STANDARD,
- FT_ENCODING_ADOBE_LATIN_1,
-
- FT_ENCODING_NONE /* end of list */
- };
metrics->units_per_em = face->units_per_EM;
- /* do we have a latin charmap in there? */
- for ( ee = 0; latin_encodings[ee] != FT_ENCODING_NONE; ee++ )
- {
- error = FT_Select_Charmap( face, latin_encodings[ee] );
- if ( !error )
- break;
- }
-
- if ( !error )
+ if ( !FT_Select_Charmap( face, FT_ENCODING_UNICODE ) )
{
- /* For now, compute the standard width and height from the `o'. */
- af_latin_metrics_init_widths( metrics, face, 'o' );
+ af_latin_metrics_init_widths( metrics, face );
af_latin_metrics_init_blues( metrics, face );
af_latin_metrics_check_digits( metrics, face );
}
@@ -569,9 +618,26 @@
if ( blue )
{
- FT_Pos scaled = FT_MulFix( blue->shoot.org, scaler->y_scale );
- FT_Pos fitted = ( scaled + 40 ) & ~63;
+ FT_Pos scaled;
+ FT_Pos threshold;
+ FT_Pos fitted;
+ FT_UInt limit;
+ FT_UInt ppem;
+
+
+ scaled = FT_MulFix( blue->shoot.org, scaler->y_scale );
+ ppem = metrics->root.scaler.face->size->metrics.x_ppem;
+ limit = metrics->root.globals->increase_x_height;
+ threshold = 40;
+
+ /* if the `increase-x-height' property is active, */
+ /* we round up much more often */
+ if ( limit &&
+ ppem <= limit &&
+ ppem >= AF_PROP_INCREASE_X_HEIGHT_MIN )
+ threshold = 52;
+ fitted = ( scaled + threshold ) & ~63;
if ( scaled != fitted )
{
@@ -849,7 +915,7 @@
on_edge = 0;
segment = NULL;
- /* fallthrough */
+ /* fall through */
}
}
@@ -885,8 +951,8 @@
} /* contours */
- /* now slightly increase the height of segments when this makes */
- /* sense -- this is used to better detect and ignore serifs */
+ /* now slightly increase the height of segments if this makes */
+ /* sense -- this is used to better detect and ignore serifs */
{
AF_Segment segments = axis->segments;
AF_Segment segments_end = segments + axis->num_segments;
@@ -1170,17 +1236,17 @@
}
- /*********************************************************************/
- /* */
- /* Good, we will now compute each edge's properties according to */
- /* the segments found on its position. Basically, these are */
- /* */
- /* - the edge's main direction */
- /* - stem edge, serif edge or both (which defaults to stem then) */
- /* - rounded edge, straight or both (which defaults to straight) */
- /* - link for edge */
- /* */
- /*********************************************************************/
+ /******************************************************************/
+ /* */
+ /* Good, we now compute each edge's properties according to the */
+ /* segments found on its position. Basically, these are */
+ /* */
+ /* - the edge's main direction */
+ /* - stem edge, serif edge or both (which defaults to stem then) */
+ /* - rounded edge, straight or both (which defaults to straight) */
+ /* - link for edge */
+ /* */
+ /******************************************************************/
/* first of all, set the `edge' field in each segment -- this is */
/* required in order to compute edge links */
@@ -1368,7 +1434,7 @@
/* for each horizontal edge search the blue zone which is closest */
for ( ; edge < edge_limit; edge++ )
{
- FT_Int bb;
+ FT_UInt bb;
AF_Width best_blue = NULL;
FT_Pos best_dist; /* initial threshold */
@@ -1381,7 +1447,7 @@
if ( best_dist > 64 / 2 )
best_dist = 64 / 2;
- for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ )
+ for ( bb = 0; bb < latin->blue_count; bb++ )
{
AF_LatinBlue blue = latin->blues + bb;
FT_Bool is_top_blue, is_major_dir;
@@ -1477,9 +1543,7 @@
#if 0 /* #ifdef AF_CONFIG_OPTION_USE_WARPER */
if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V )
- {
metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL;
- }
#endif
scaler_flags = hints->scaler_flags;
@@ -1763,7 +1827,7 @@
stem_edge->pos = base_edge->pos + fitted_width;
- FT_TRACE5(( " LINK: edge %d (opos=%.2f) linked to (%.2f),"
+ FT_TRACE5(( " LINK: edge %d (opos=%.2f) linked to %.2f,"
" dist was %.2f, now %.2f\n",
stem_edge-hints->axis[dim].edges, stem_edge->opos / 64.0,
stem_edge->pos / 64.0, dist / 64.0, fitted_width / 64.0 ));
@@ -1809,9 +1873,13 @@
AF_Edge anchor = NULL;
FT_Int has_serifs = 0;
+#ifdef FT_DEBUG_LEVEL_TRACE
+ FT_UInt num_actions = 0;
+#endif
+
- FT_TRACE5(("%s edge hinting\n", dim == AF_DIMENSION_VERT ? "horizontal"
- : "vertical"));
+ FT_TRACE5(( "%s edge hinting\n",
+ dim == AF_DIMENSION_VERT ? "horizontal" : "vertical" ));
/* we begin by aligning all stems relative to the blue zone */
/* if needed -- that's only for horizontal edges */
@@ -1845,10 +1913,20 @@
if ( !edge1 )
continue;
- FT_TRACE5(( " BLUE: edge %d (opos=%.2f) snapped to (%.2f),"
- " was (%.2f)\n",
- edge1 - edges, edge1->opos / 64.0, blue->fit / 64.0,
- edge1->pos / 64.0 ));
+#ifdef FT_DEBUG_LEVEL_TRACE
+ if (!anchor)
+ FT_TRACE5(( " BLUE_ANCHOR: edge %d (opos=%.2f) snapped to %.2f,"
+ " was %.2f (anchor=edge %d)\n",
+ edge1 - edges, edge1->opos / 64.0, blue->fit / 64.0,
+ edge1->pos / 64.0, edge - edges ));
+ else
+ FT_TRACE5(( " BLUE: edge %d (opos=%.2f) snapped to %.2f,"
+ " was %.2f\n",
+ edge1 - edges, edge1->opos / 64.0, blue->fit / 64.0,
+ edge1->pos / 64.0 ));
+
+ num_actions++;
+#endif
edge1->pos = blue->fit;
edge1->flags |= AF_EDGE_DONE;
@@ -1857,6 +1935,10 @@
{
af_latin_align_linked_edge( hints, dim, edge1, edge2 );
edge2->flags |= AF_EDGE_DONE;
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+ num_actions++;
+#endif
}
if ( !anchor )
@@ -1891,6 +1973,10 @@
af_latin_align_linked_edge( hints, dim, edge2, edge );
edge->flags |= AF_EDGE_DONE;
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+ num_actions++;
+#endif
continue;
}
@@ -1948,16 +2034,20 @@
else
edge->pos = FT_PIX_ROUND( edge->opos );
+ anchor = edge;
+ edge->flags |= AF_EDGE_DONE;
+
FT_TRACE5(( " ANCHOR: edge %d (opos=%.2f) and %d (opos=%.2f)"
- " snapped to (%.2f) (%.2f)\n",
+ " snapped to %.2f and %.2f\n",
edge - edges, edge->opos / 64.0,
edge2 - edges, edge2->opos / 64.0,
edge->pos / 64.0, edge2->pos / 64.0 ));
- anchor = edge;
-
- edge->flags |= AF_EDGE_DONE;
af_latin_align_linked_edge( hints, dim, edge, edge2 );
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+ num_actions += 2;
+#endif
}
else
{
@@ -2017,12 +2107,13 @@
edge->pos = cur_pos1 - cur_len / 2;
edge2->pos = cur_pos1 + cur_len / 2;
- FT_TRACE5(( " STEM: %d (opos=%.2f) to %d (opos=%.2f)"
- " snapped to (%.2f) and (%.2f)\n",
+ FT_TRACE5(( " STEM: edge %d (opos=%.2f) linked to %d (opos=%.2f)"
+ " snapped to %.2f and %.2f\n",
edge - edges, edge->opos / 64.0,
edge2 - edges, edge2->opos / 64.0,
edge->pos / 64.0, edge2->pos / 64.0 ));
}
+
else
{
org_pos = anchor->pos + ( edge->opos - anchor->opos );
@@ -2047,20 +2138,29 @@
edge->pos = ( delta1 < delta2 ) ? cur_pos1 : cur_pos2;
edge2->pos = edge->pos + cur_len;
- FT_TRACE5(( " STEM: %d (opos=%.2f) to %d (opos=%.2f)"
- " snapped to (%.2f) and (%.2f)\n",
+ FT_TRACE5(( " STEM: edge %d (opos=%.2f) linked to %d (opos=%.2f)"
+ " snapped to %.2f and %.2f\n",
edge - edges, edge->opos / 64.0,
edge2 - edges, edge2->opos / 64.0,
edge->pos / 64.0, edge2->pos / 64.0 ));
}
+#ifdef FT_DEBUG_LEVEL_TRACE
+ num_actions++;
+#endif
+
edge->flags |= AF_EDGE_DONE;
edge2->flags |= AF_EDGE_DONE;
if ( edge > edges && edge->pos < edge[-1].pos )
{
- FT_TRACE5(( " BOUND: %d (pos=%.2f) to (%.2f)\n",
+#ifdef FT_DEBUG_LEVEL_TRACE
+ FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n",
edge - edges, edge->pos / 64.0, edge[-1].pos / 64.0 ));
+
+ num_actions++;
+#endif
+
edge->pos = edge[-1].pos;
}
}
@@ -2155,7 +2255,7 @@
{
af_latin_align_serif_edge( hints, edge->serif, edge );
FT_TRACE5(( " SERIF: edge %d (opos=%.2f) serif to %d (opos=%.2f)"
- " aligned to (%.2f)\n",
+ " aligned to %.2f\n",
edge - edges, edge->opos / 64.0,
edge->serif - edges, edge->serif->opos / 64.0,
edge->pos / 64.0 ));
@@ -2165,7 +2265,7 @@
edge->pos = FT_PIX_ROUND( edge->opos );
anchor = edge;
FT_TRACE5(( " SERIF_ANCHOR: edge %d (opos=%.2f)"
- " snapped to (%.2f)\n",
+ " snapped to %.2f\n",
edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));
}
else
@@ -2192,7 +2292,7 @@
after->pos - before->pos,
after->opos - before->opos );
- FT_TRACE5(( " SERIF_LINK1: edge %d (opos=%.2f) snapped to (%.2f)"
+ FT_TRACE5(( " SERIF_LINK1: edge %d (opos=%.2f) snapped to %.2f"
" from %d (opos=%.2f)\n",
edge - edges, edge->opos / 64.0,
edge->pos / 64.0,
@@ -2202,26 +2302,49 @@
{
edge->pos = anchor->pos +
( ( edge->opos - anchor->opos + 16 ) & ~31 );
-
FT_TRACE5(( " SERIF_LINK2: edge %d (opos=%.2f)"
- " snapped to (%.2f)\n",
+ " snapped to %.2f\n",
edge - edges, edge->opos / 64.0, edge->pos / 64.0 ));
}
}
+#ifdef FT_DEBUG_LEVEL_TRACE
+ num_actions++;
+#endif
edge->flags |= AF_EDGE_DONE;
if ( edge > edges && edge->pos < edge[-1].pos )
+ {
+#ifdef FT_DEBUG_LEVEL_TRACE
+ FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n",
+ edge - edges, edge->pos / 64.0, edge[-1].pos / 64.0 ));
+
+ num_actions++;
+#endif
edge->pos = edge[-1].pos;
+ }
if ( edge + 1 < edge_limit &&
edge[1].flags & AF_EDGE_DONE &&
edge->pos > edge[1].pos )
+ {
+#ifdef FT_DEBUG_LEVEL_TRACE
+ FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n",
+ edge - edges, edge->pos / 64.0, edge[1].pos / 64.0 ));
+
+ num_actions++;
+#endif
+
edge->pos = edge[1].pos;
+ }
}
}
+#ifdef FT_DEBUG_LEVEL_TRACE
+ if ( !num_actions )
+ FT_TRACE5(( " (none)\n" ));
FT_TRACE5(( "\n" ));
+#endif
}
@@ -2334,10 +2457,12 @@
AF_UNIRANGE_REC( 0x2460UL, 0x24FFUL ), /* Enclosed Alphanumerics */
AF_UNIRANGE_REC( 0x2C60UL, 0x2C7FUL ), /* Latin Extended-C */
AF_UNIRANGE_REC( 0x2DE0UL, 0x2DFFUL ), /* Cyrillic Extended-A */
+ AF_UNIRANGE_REC( 0x2E00UL, 0x2E7FUL ), /* Supplemental Punctuation */
AF_UNIRANGE_REC( 0xA640UL, 0xA69FUL ), /* Cyrillic Extended-B */
AF_UNIRANGE_REC( 0xA720UL, 0xA7FFUL ), /* Latin Extended-D */
AF_UNIRANGE_REC( 0xFB00UL, 0xFB06UL ), /* Alphab. Present. Forms (Latin Ligs) */
AF_UNIRANGE_REC( 0x1D400UL, 0x1D7FFUL ), /* Mathematical Alphanumeric Symbols */
+ AF_UNIRANGE_REC( 0x1F100UL, 0x1F1FFUL ), /* Enclosed Alphanumeric Supplement */
AF_UNIRANGE_REC( 0UL, 0UL )
};
@@ -2345,6 +2470,7 @@
AF_DEFINE_SCRIPT_CLASS( af_latin_script_class,
AF_SCRIPT_LATIN,
af_latin_uniranges,
+ 'o',
sizeof ( AF_LatinMetricsRec ),
diff --git a/freetype/src/autofit/aflatin.h b/freetype/src/autofit/aflatin.h
index c5c2d13f8..d9170b3dc 100644
--- a/freetype/src/autofit/aflatin.h
+++ b/freetype/src/autofit/aflatin.h
@@ -4,7 +4,7 @@
/* */
/* Auto-fitter hinting routines for latin script (specification). */
/* */
-/* Copyright 2003-2007, 2009, 2011 by */
+/* Copyright 2003-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, */
@@ -27,7 +27,7 @@ FT_BEGIN_HEADER
/* the latin-specific script class */
- AF_DECLARE_SCRIPT_CLASS(af_latin_script_class)
+ AF_DECLARE_SCRIPT_CLASS( af_latin_script_class )
/* constants are given with units_per_em == 2048 in mind */
@@ -133,8 +133,7 @@ FT_BEGIN_HEADER
FT_LOCAL( void )
af_latin_metrics_init_widths( AF_LatinMetrics metrics,
- FT_Face face,
- FT_ULong charcode );
+ FT_Face face );
FT_LOCAL( void )
af_latin_metrics_check_digits( AF_LatinMetrics metrics,
@@ -174,25 +173,17 @@ FT_BEGIN_HEADER
/*
- * This shouldn't normally be exported. However, other scripts might
- * like to use this function as-is.
+ * The next functions shouldn't normally be exported. However, other
+ * scripts might like to use these functions as-is.
*/
FT_LOCAL( FT_Error )
af_latin_hints_compute_segments( AF_GlyphHints hints,
AF_Dimension dim );
- /*
- * This shouldn't normally be exported. However, other scripts might
- * want to use this function as-is.
- */
FT_LOCAL( void )
af_latin_hints_link_segments( AF_GlyphHints hints,
AF_Dimension dim );
- /*
- * This shouldn't normally be exported. However, other scripts might
- * want to use this function as-is.
- */
FT_LOCAL( FT_Error )
af_latin_hints_compute_edges( AF_GlyphHints hints,
AF_Dimension dim );
diff --git a/freetype/src/autofit/aflatin2.c b/freetype/src/autofit/aflatin2.c
index 927cce7b4..40a5ffd6a 100644
--- a/freetype/src/autofit/aflatin2.c
+++ b/freetype/src/autofit/aflatin2.c
@@ -18,6 +18,7 @@
#include FT_ADVANCES_H
+#include "afglobal.h"
#include "aflatin.h"
#include "aflatin2.h"
#include "aferrors.h"
@@ -56,8 +57,7 @@
FT_LOCAL_DEF( void )
af_latin2_metrics_init_widths( AF_LatinMetrics metrics,
- FT_Face face,
- FT_ULong charcode )
+ FT_Face face )
{
/* scan the array of segments in each direction */
AF_GlyphHintsRec hints[1];
@@ -76,7 +76,8 @@
AF_Scaler scaler = &dummy->root.scaler;
- glyph_index = FT_Get_Char_Index( face, charcode );
+ glyph_index = FT_Get_Char_Index( face,
+ metrics->root.clazz->standard_char );
if ( glyph_index == 0 )
goto Exit;
@@ -198,8 +199,8 @@
/* 'af_latin2_blue_chars[blues]' string, then compute its top-most or */
/* bottom-most points (depending on `AF_IS_TOP_BLUE') */
- FT_TRACE5(( "blue zones computation\n" ));
- FT_TRACE5(( "------------------------------------------------\n" ));
+ FT_TRACE5(( "blue zones computation\n"
+ "======================\n\n" ));
for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ )
{
@@ -209,7 +210,7 @@
FT_Pos* blue_shoot;
- FT_TRACE5(( "blue %3d: ", bb ));
+ FT_TRACE5(( "blue zone %d:\n", bb ));
num_flats = 0;
num_rounds = 0;
@@ -222,8 +223,6 @@
FT_Bool round;
- FT_TRACE5(( "'%c'", *p ));
-
/* load the character in the face -- skip unknown or empty ones */
glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p );
if ( glyph_index == 0 )
@@ -285,13 +284,14 @@
best_last = last;
}
}
- FT_TRACE5(( "%5d", best_y ));
+ FT_TRACE5(( " %c %d", *p, best_y ));
}
/* now check whether the point belongs to a straight or round */
/* segment; we first need to find in which contour the extremum */
/* lies, then inspect its previous and next points */
{
+ FT_Pos best_x = points[best_point].x;
FT_Int start, end, prev, next;
FT_Pos dist;
@@ -302,13 +302,16 @@
do
{
- prev = start-1;
+ prev = start - 1;
if ( prev < best_first )
prev = best_last;
- dist = points[prev].y - best_y;
- if ( dist < -5 || dist > 5 )
- break;
+ dist = FT_ABS( points[prev].y - best_y );
+ /* accept a small distance or a small angle (both values are */
+ /* heuristic; value 20 corresponds to approx. 2.9 degrees) */
+ if ( dist > 5 )
+ if ( FT_ABS( points[prev].x - best_x ) <= 20 * dist )
+ break;
start = prev;
@@ -316,13 +319,14 @@
do
{
- next = end+1;
+ next = end + 1;
if ( next > best_last )
next = best_first;
- dist = points[next].y - best_y;
- if ( dist < -5 || dist > 5 )
- break;
+ dist = FT_ABS( points[next].y - best_y );
+ if ( dist > 5 )
+ if ( FT_ABS( points[next].x - best_x ) <= 20 * dist )
+ break;
end = next;
@@ -333,7 +337,7 @@
FT_CURVE_TAG( glyph->outline.tags[start] ) != FT_CURVE_TAG_ON ||
FT_CURVE_TAG( glyph->outline.tags[ end ] ) != FT_CURVE_TAG_ON );
- FT_TRACE5(( "%c ", round ? 'r' : 'f' ));
+ FT_TRACE5(( " (%s)\n", round ? "round" : "flat" ));
}
if ( round )
@@ -342,15 +346,13 @@
flats[num_flats++] = best_y;
}
- FT_TRACE5(( "\n" ));
-
if ( num_flats == 0 && num_rounds == 0 )
{
/*
* we couldn't find a single glyph to compute this blue zone,
* we will simply ignore it then
*/
- FT_TRACE5(( "empty\n" ));
+ FT_TRACE5(( " empty\n" ));
continue;
}
@@ -393,7 +395,13 @@
if ( AF_LATIN_IS_TOP_BLUE( bb ) ^ over_ref )
- *blue_shoot = *blue_ref = ( shoot + ref ) / 2;
+ {
+ *blue_ref =
+ *blue_shoot = ( shoot + ref ) / 2;
+
+ FT_TRACE5(( " [overshoot smaller than reference,"
+ " taking mean value]\n" ));
+ }
}
blue->flags = 0;
@@ -408,7 +416,9 @@
if ( bb == AF_LATIN_BLUE_SMALL_TOP )
blue->flags |= AF_LATIN_BLUE_ADJUSTMENT;
- FT_TRACE5(( "-- ref = %ld, shoot = %ld\n", *blue_ref, *blue_shoot ));
+ FT_TRACE5(( " -> reference = %ld\n"
+ " overshoot = %ld\n",
+ *blue_ref, *blue_shoot ));
}
return;
@@ -491,8 +501,7 @@
if ( !error )
{
- /* For now, compute the standard width and height from the `o'. */
- af_latin2_metrics_init_widths( metrics, face, 'o' );
+ af_latin2_metrics_init_widths( metrics, face );
af_latin2_metrics_init_blues( metrics, face );
af_latin2_metrics_check_digits( metrics, face );
}
@@ -553,8 +562,26 @@
if ( blue )
{
- FT_Pos scaled = FT_MulFix( blue->shoot.org, scaler->y_scale );
- FT_Pos fitted = ( scaled + 40 ) & ~63;
+ FT_Pos scaled;
+ FT_Pos threshold;
+ FT_Pos fitted;
+ FT_UInt limit;
+ FT_UInt ppem;
+
+
+ scaled = FT_MulFix( blue->shoot.org, scaler->y_scale );
+ ppem = metrics->root.scaler.face->size->metrics.x_ppem;
+ limit = metrics->root.globals->increase_x_height;
+ threshold = 40;
+
+ /* if the `increase-x-height' property is active, */
+ /* we round up much more often */
+ if ( limit &&
+ ppem <= limit &&
+ ppem >= AF_PROP_INCREASE_X_HEIGHT_MIN )
+ threshold = 52;
+
+ fitted = ( scaled + threshold ) & ~63;
#if 1
if ( scaled != fitted )
@@ -2360,6 +2387,7 @@
AF_DEFINE_SCRIPT_CLASS( af_latin2_script_class,
AF_SCRIPT_LATIN2,
af_latin2_uniranges,
+ 'o',
sizeof ( AF_LatinMetricsRec ),
diff --git a/freetype/src/autofit/aflatin2.h b/freetype/src/autofit/aflatin2.h
index 925c6214d..cbfa39552 100644
--- a/freetype/src/autofit/aflatin2.h
+++ b/freetype/src/autofit/aflatin2.h
@@ -4,7 +4,7 @@
/* */
/* Auto-fitter hinting routines for latin script (specification). */
/* */
-/* Copyright 2003, 2004, 2005, 2006, 2007 by */
+/* Copyright 2003-2007, 2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -27,7 +27,7 @@ FT_BEGIN_HEADER
/* the latin-specific script class */
- AF_DECLARE_SCRIPT_CLASS(af_latin2_script_class)
+ AF_DECLARE_SCRIPT_CLASS( af_latin2_script_class )
/* */
diff --git a/freetype/src/autofit/afloader.c b/freetype/src/autofit/afloader.c
index dabd6193d..f280beda2 100644
--- a/freetype/src/autofit/afloader.c
+++ b/freetype/src/autofit/afloader.c
@@ -16,18 +16,22 @@
/***************************************************************************/
+#include "afglobal.h"
#include "afloader.h"
#include "afhints.h"
-#include "afglobal.h"
#include "aferrors.h"
+#include "afmodule.h"
/* Initialize glyph loader. */
FT_LOCAL_DEF( FT_Error )
- af_loader_init( AF_Loader loader,
- FT_Memory memory )
+ af_loader_init( AF_Module module )
{
+ AF_Loader loader = module->loader;
+ FT_Memory memory = module->root.library->memory;
+
+
FT_ZERO( loader );
af_glyph_hints_init( &loader->hints, memory );
@@ -41,10 +45,11 @@
/* Reset glyph loader and compute globals if necessary. */
FT_LOCAL_DEF( FT_Error )
- af_loader_reset( AF_Loader loader,
+ af_loader_reset( AF_Module module,
FT_Face face )
{
- FT_Error error = AF_Err_Ok;
+ FT_Error error = AF_Err_Ok;
+ AF_Loader loader = module->loader;
loader->face = face;
@@ -54,7 +59,7 @@
if ( loader->globals == NULL )
{
- error = af_face_globals_new( face, &loader->globals );
+ error = af_face_globals_new( face, &loader->globals, module );
if ( !error )
{
face->autohint.data =
@@ -71,8 +76,11 @@
/* Finalize glyph loader. */
FT_LOCAL_DEF( void )
- af_loader_done( AF_Loader loader )
+ af_loader_done( AF_Module module )
{
+ AF_Loader loader = module->loader;
+
+
af_glyph_hints_done( &loader->hints );
loader->face = NULL;
@@ -135,8 +143,8 @@
loader->trans_delta.x,
loader->trans_delta.y );
- /* copy the outline points in the loader's current */
- /* extra points which is used to keep original glyph coordinates */
+ /* copy the outline points in the loader's current */
+ /* extra points which are used to keep original glyph coordinates */
error = FT_GLYPHLOADER_CHECK_POINTS( gloader,
slot->outline.n_points + 4,
slot->outline.n_contours );
@@ -347,8 +355,8 @@
l += num_base_points;
- /* for now, only use the current point coordinates; */
- /* we may consider another approach in the near future */
+ /* for now, only use the current point coordinates; */
+ /* we eventually may consider another approach */
p1 = gloader->base.outline.points + start_point + k;
p2 = gloader->base.outline.points + start_point + l;
@@ -482,13 +490,14 @@
/* Load a glyph. */
FT_LOCAL_DEF( FT_Error )
- af_loader_load_glyph( AF_Loader loader,
+ af_loader_load_glyph( AF_Module module,
FT_Face face,
FT_UInt gindex,
FT_Int32 load_flags )
{
FT_Error error;
- FT_Size size = face->size;
+ FT_Size size = face->size;
+ AF_Loader loader = module->loader;
AF_ScalerRec scaler;
@@ -506,7 +515,7 @@
scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags );
scaler.flags = 0; /* XXX: fix this */
- error = af_loader_reset( loader, face );
+ error = af_loader_reset( module, face );
if ( !error )
{
AF_ScriptMetrics metrics;
diff --git a/freetype/src/autofit/afloader.h b/freetype/src/autofit/afloader.h
index eec0e9271..1f34d17cc 100644
--- a/freetype/src/autofit/afloader.h
+++ b/freetype/src/autofit/afloader.h
@@ -25,11 +25,24 @@
FT_BEGIN_HEADER
- typedef struct AF_LoaderRec_
+ typedef struct AF_ModuleRec_* AF_Module;
+
+ /*
+ * The autofitter module's (global) data structure to communicate with
+ * actual fonts. If necessary, `local' data like the current face, the
+ * current face's auto-hint data, or the current glyph's parameters
+ * relevant to auto-hinting are `swapped in'. Cf. functions like
+ * `af_loader_reset' and `af_loader_load_g'.
+ */
+
+ typedef struct AF_LoaderRec_
{
- FT_Face face; /* current face */
- AF_FaceGlobals globals; /* current face globals */
- FT_GlyphLoader gloader; /* glyph loader */
+ /* current face data */
+ FT_Face face;
+ AF_FaceGlobals globals;
+
+ /* current glyph data */
+ FT_GlyphLoader gloader;
AF_GlyphHintsRec hints;
AF_ScriptMetrics metrics;
FT_Bool transformed;
@@ -43,21 +56,20 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
- af_loader_init( AF_Loader loader,
- FT_Memory memory );
+ af_loader_init( AF_Module module );
FT_LOCAL( FT_Error )
- af_loader_reset( AF_Loader loader,
+ af_loader_reset( AF_Module module,
FT_Face face );
FT_LOCAL( void )
- af_loader_done( AF_Loader loader );
+ af_loader_done( AF_Module module );
FT_LOCAL( FT_Error )
- af_loader_load_glyph( AF_Loader loader,
+ af_loader_load_glyph( AF_Module module,
FT_Face face,
FT_UInt gindex,
FT_Int32 load_flags );
diff --git a/freetype/src/autofit/afmodule.c b/freetype/src/autofit/afmodule.c
index 683106121..5257aeb95 100644..100755
--- a/freetype/src/autofit/afmodule.c
+++ b/freetype/src/autofit/afmodule.c
@@ -4,7 +4,7 @@
/* */
/* Auto-fitter module implementation (body). */
/* */
-/* Copyright 2003-2006, 2009, 2011 by */
+/* Copyright 2003-2006, 2009, 2011-2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -16,8 +16,10 @@
/***************************************************************************/
+#include "afglobal.h"
#include "afmodule.h"
#include "afloader.h"
+#include "aferrors.h"
#include "afpic.h"
#ifdef FT_DEBUG_AUTOFIT
@@ -28,66 +30,229 @@
#endif
#include <freetype/internal/ftobjs.h>
+#include FT_INTERNAL_DEBUG_H
+#include FT_AUTOHINTER_H
+#include FT_SERVICE_PROPERTIES_H
- typedef struct FT_AutofitterRec_
+ /*************************************************************************/
+ /* */
+ /* 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_afmodule
+
+
+ FT_Error
+ af_property_get_face_globals( FT_Face face,
+ AF_FaceGlobals* aglobals,
+ AF_Module module )
+ {
+ FT_Error error = AF_Err_Ok;
+ AF_FaceGlobals globals;
+
+
+ if ( !face )
+ return AF_Err_Invalid_Argument;
+
+ globals = (AF_FaceGlobals)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( face, &globals, module );
+ if ( !error )
+ {
+ face->autohint.data =
+ (FT_Pointer)globals;
+ face->autohint.finalizer =
+ (FT_Generic_Finalizer)af_face_globals_free;
+ }
+ }
+
+ if ( !error )
+ *aglobals = globals;
+
+ return error;
+ }
+
+
+ FT_Error
+ af_property_set( FT_Module ft_module,
+ const char* property_name,
+ const void* value )
+ {
+ FT_Error error = AF_Err_Ok;
+ AF_Module module = (AF_Module)ft_module;
+
+
+ if ( !ft_strcmp( property_name, "fallback-script" ) )
+ {
+ FT_UInt* fallback_script = (FT_UInt*)value;
+
+
+ module->fallback_script = *fallback_script;
+
+ return error;
+ }
+ else if ( !ft_strcmp( property_name, "increase-x-height" ) )
+ {
+ FT_Prop_IncreaseXHeight* prop = (FT_Prop_IncreaseXHeight*)value;
+ AF_FaceGlobals globals;
+
+
+ error = af_property_get_face_globals( prop->face, &globals, module );
+ if ( !error )
+ globals->increase_x_height = prop->limit;
+
+ return error;
+ }
+
+ FT_TRACE0(( "af_property_get: missing property `%s'\n",
+ property_name ));
+ return AF_Err_Missing_Property;
+ }
+
+
+ FT_Error
+ af_property_get( FT_Module ft_module,
+ const char* property_name,
+ void* value )
{
- FT_ModuleRec root;
- AF_LoaderRec loader[1];
+ FT_Error error = AF_Err_Ok;
+ AF_Module module = (AF_Module)ft_module;
+ FT_UInt fallback_script = module->fallback_script;
+
+
+ if ( !ft_strcmp( property_name, "glyph-to-script-map" ) )
+ {
+ FT_Prop_GlyphToScriptMap* prop = (FT_Prop_GlyphToScriptMap*)value;
+ AF_FaceGlobals globals;
- } FT_AutofitterRec, *FT_Autofitter;
+
+ error = af_property_get_face_globals( prop->face, &globals, module );
+ if ( !error )
+ prop->map = globals->glyph_scripts;
+
+ return error;
+ }
+ else if ( !ft_strcmp( property_name, "fallback-script" ) )
+ {
+ FT_UInt* val = (FT_UInt*)value;
+
+
+ *val = fallback_script;
+
+ return error;
+ }
+ else if ( !ft_strcmp( property_name, "increase-x-height" ) )
+ {
+ FT_Prop_IncreaseXHeight* prop = (FT_Prop_IncreaseXHeight*)value;
+ AF_FaceGlobals globals;
+
+
+ error = af_property_get_face_globals( prop->face, &globals, module );
+ if ( !error )
+ prop->limit = globals->increase_x_height;
+
+ return error;
+ }
+
+
+ FT_TRACE0(( "af_property_get: missing property `%s'\n",
+ property_name ));
+ return AF_Err_Missing_Property;
+ }
+
+
+ FT_DEFINE_SERVICE_PROPERTIESREC(
+ af_service_properties,
+ (FT_Properties_SetFunc)af_property_set,
+ (FT_Properties_GetFunc)af_property_get )
+
+
+ FT_DEFINE_SERVICEDESCREC1(
+ af_services,
+ FT_SERVICE_ID_PROPERTIES, &AF_SERVICE_PROPERTIES_GET )
+
+
+ FT_CALLBACK_DEF( FT_Module_Interface )
+ af_get_interface( FT_Module module,
+ const char* module_interface )
+ {
+ /* AF_SERVICES_GET derefers `library' in PIC mode */
+#ifdef FT_CONFIG_OPTION_PIC
+ FT_Library library;
+
+
+ if ( !module )
+ return NULL;
+ library = module->library;
+ if ( !library )
+ return NULL;
+#else
+ FT_UNUSED( module );
+#endif
+
+ return ft_service_list_lookup( AF_SERVICES_GET, module_interface );
+ }
FT_CALLBACK_DEF( FT_Error )
- af_autofitter_init( FT_Autofitter module )
+ af_autofitter_init( AF_Module module )
{
- return af_loader_init( module->loader, module->root.library->memory );
+ module->fallback_script = AF_SCRIPT_FALLBACK;
+
+ return af_loader_init( module );
}
FT_CALLBACK_DEF( void )
- af_autofitter_done( FT_Autofitter module )
+ af_autofitter_done( AF_Module module )
{
- af_loader_done( module->loader );
+ af_loader_done( module );
}
FT_CALLBACK_DEF( FT_Error )
- af_autofitter_load_glyph( FT_Autofitter module,
- FT_GlyphSlot slot,
- FT_Size size,
- FT_UInt glyph_index,
- FT_Int32 load_flags )
+ af_autofitter_load_glyph( AF_Module module,
+ FT_GlyphSlot slot,
+ FT_Size size,
+ FT_UInt glyph_index,
+ FT_Int32 load_flags )
{
FT_UNUSED( size );
- return af_loader_load_glyph( module->loader, slot->face,
+ return af_loader_load_glyph( module, slot->face,
glyph_index, load_flags );
}
- FT_DEFINE_AUTOHINTER_SERVICE(
- af_autofitter_service,
- NULL,
- NULL,
- NULL,
- (FT_AutoHinter_GlyphLoadFunc)af_autofitter_load_glyph )
+ FT_DEFINE_AUTOHINTER_INTERFACE(
+ af_autofitter_interface,
+ NULL, /* reset_face */
+ NULL, /* get_global_hints */
+ NULL, /* done_global_hints */
+ (FT_AutoHinter_GlyphLoadFunc)af_autofitter_load_glyph ) /* load_glyph */
+
FT_DEFINE_MODULE(
autofit_module_class,
FT_MODULE_HINTER,
- sizeof ( FT_AutofitterRec ),
+ sizeof ( AF_ModuleRec ),
"autofitter",
0x10000L, /* version 1.0 of the autofitter */
0x20000L, /* requires FreeType 2.0 or above */
- (const void*)&AF_AF_AUTOFITTER_SERVICE_GET,
+ (const void*)&AF_INTERFACE_GET,
(FT_Module_Constructor)af_autofitter_init,
(FT_Module_Destructor) af_autofitter_done,
- (FT_Module_Requester) NULL )
+ (FT_Module_Requester) af_get_interface )
/* END */
diff --git a/freetype/src/autofit/afmodule.h b/freetype/src/autofit/afmodule.h
index 6bda1463d..cae3054ab 100644
--- a/freetype/src/autofit/afmodule.h
+++ b/freetype/src/autofit/afmodule.h
@@ -23,9 +23,30 @@
#include <freetype/internal/ftobjs.h>
#include FT_MODULE_H
+#include "afloader.h"
+
FT_BEGIN_HEADER
+
+ /*
+ * This is the `extended' FT_Module structure which holds the
+ * autofitter's global data. Right before hinting a glyph, the data
+ * specific to the glyph's face (blue zones, stem widths, etc.) are
+ * loaded into `loader' (see function `af_loader_reset').
+ */
+
+ typedef struct AF_ModuleRec_
+ {
+ FT_ModuleRec root;
+
+ FT_UInt fallback_script;
+
+ AF_LoaderRec loader[1];
+
+ } AF_ModuleRec;
+
+
FT_DECLARE_MODULE(autofit_module_class)
diff --git a/freetype/src/autofit/afpic.c b/freetype/src/autofit/afpic.c
index 9d26f990f..99feb47e4 100644
--- a/freetype/src/autofit/afpic.c
+++ b/freetype/src/autofit/afpic.c
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for autofit module. */
/* */
-/* Copyright 2009, 2010, 2011 by */
+/* Copyright 2009-2012 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -22,12 +22,25 @@
#include "afpic.h"
#include "aferrors.h"
+
#ifdef FT_CONFIG_OPTION_PIC
/* forward declaration of PIC init functions from afmodule.c */
- void FT_Init_Class_af_autofitter_service(
- FT_Library library,
- FT_AutoHinter_ServiceRec* clazz );
+ FT_Error
+ FT_Create_Class_af_services( FT_Library library,
+ FT_ServiceDescRec** output_class );
+
+ void
+ FT_Destroy_Class_af_services( FT_Library library,
+ FT_ServiceDescRec* clazz );
+
+ void
+ FT_Init_Class_af_service_properties( FT_Service_PropertiesRec* clazz );
+
+ void FT_Init_Class_af_autofitter_interface(
+ FT_Library library,
+ FT_AutoHinter_InterfaceRec* clazz );
+
/* forward declaration of PIC init functions from script classes */
#include "aflatin.h"
@@ -38,6 +51,7 @@
#include "afdummy.h"
#include "afindic.h"
+
void
autofit_module_class_pic_free( FT_Library library )
{
@@ -47,7 +61,15 @@
if ( pic_container->autofit )
{
- FT_FREE( pic_container->autofit );
+ AFModulePIC* container = (AFModulePIC*)pic_container->autofit;
+
+
+ if ( container->af_services )
+ FT_Destroy_Class_af_services( library,
+ container->af_services );
+ container->af_services = NULL;
+
+ FT_FREE( container );
pic_container->autofit = NULL;
}
}
@@ -59,7 +81,7 @@
FT_PIC_Container* pic_container = &library->pic_container;
FT_UInt ss;
FT_Error error = AF_Err_Ok;
- AFModulePIC* container;
+ AFModulePIC* container = NULL;
FT_Memory memory = library->memory;
@@ -71,6 +93,13 @@
/* initialize pointer table - */
/* this is how the module usually expects this data */
+ error = FT_Create_Class_af_services( library,
+ &container->af_services );
+ if ( error )
+ goto Exit;
+
+ FT_Init_Class_af_service_properties( &container->af_service_properties );
+
for ( ss = 0 ; ss < AF_SCRIPT_CLASSES_REC_COUNT ; ss++ )
{
container->af_script_classes[ss] =
@@ -93,17 +122,15 @@
FT_Init_Class_af_indic_script_class(
&container->af_script_classes_rec[ss++] );
- FT_Init_Class_af_autofitter_service(
- library, &container->af_autofitter_service );
-
-/* Exit: */
+ FT_Init_Class_af_autofitter_interface(
+ library, &container->af_autofitter_interface );
+ Exit:
if ( error )
autofit_module_class_pic_free( library );
return error;
}
-
#endif /* FT_CONFIG_OPTION_PIC */
diff --git a/freetype/src/autofit/afpic.h b/freetype/src/autofit/afpic.h
index 4ba85fa13..4ce95e3a4 100644
--- a/freetype/src/autofit/afpic.h
+++ b/freetype/src/autofit/afpic.h
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for autofit module. */
/* */
-/* Copyright 2009, 2011 by */
+/* Copyright 2009, 2011-2012 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -24,38 +24,58 @@ FT_BEGIN_HEADER
#include <freetype/internal/ftpic.h>
+
#ifndef FT_CONFIG_OPTION_PIC
-#define AF_SCRIPT_CLASSES_GET af_script_classes
-#define AF_AF_AUTOFITTER_SERVICE_GET af_autofitter_service
+#define AF_SERVICES_GET af_services
+#define AF_SERVICE_PROPERTIES_GET af_service_properties
+
+#define AF_SCRIPT_CLASSES_GET af_script_classes
+#define AF_INTERFACE_GET af_autofitter_interface
#else /* FT_CONFIG_OPTION_PIC */
+ /* some include files required for members of AFModulePIC */
+#include FT_SERVICE_PROPERTIES_H
+
#include "aftypes.h"
/* increase these when you add new scripts, */
/* and update autofit_module_class_pic_init */
#ifdef FT_OPTION_AUTOFIT2
-#define AF_SCRIPT_CLASSES_COUNT 6
+#define AF_SCRIPT_CLASSES_COUNT 6
#else
-#define AF_SCRIPT_CLASSES_COUNT 5
+#define AF_SCRIPT_CLASSES_COUNT 5
#endif
+
#define AF_SCRIPT_CLASSES_REC_COUNT ( AF_SCRIPT_CLASSES_COUNT - 1 )
- typedef struct AFModulePIC_
+
+ typedef struct AFModulePIC_
{
- AF_ScriptClass af_script_classes[AF_SCRIPT_CLASSES_COUNT];
- AF_ScriptClassRec af_script_classes_rec[AF_SCRIPT_CLASSES_REC_COUNT];
- FT_AutoHinter_ServiceRec af_autofitter_service;
+ FT_ServiceDescRec* af_services;
+ FT_Service_PropertiesRec af_service_properties;
+
+ AF_ScriptClass af_script_classes[AF_SCRIPT_CLASSES_COUNT];
+ AF_ScriptClassRec af_script_classes_rec[AF_SCRIPT_CLASSES_REC_COUNT];
+ FT_AutoHinter_InterfaceRec af_autofitter_interface;
} AFModulePIC;
-#define GET_PIC( lib ) \
+
+#define GET_PIC( lib ) \
( (AFModulePIC*)((lib)->pic_container.autofit) )
-#define AF_SCRIPT_CLASSES_GET \
- ( GET_PIC( FT_FACE_LIBRARY(globals->face) )->af_script_classes )
-#define AF_AF_AUTOFITTER_SERVICE_GET \
- ( GET_PIC( library )->af_autofitter_service )
+
+#define AF_SERVICES_GET \
+ ( GET_PIC( library )->af_services )
+#define AF_SERVICE_PROPERTIES_GET \
+ ( GET_PIC( library)->af_service_properties )
+
+#define AF_SCRIPT_CLASSES_GET \
+ ( GET_PIC( FT_FACE_LIBRARY( globals->face ) )->af_script_classes )
+#define AF_INTERFACE_GET \
+ ( GET_PIC( library )->af_autofitter_interface )
+
/* see afpic.c for the implementation */
void
diff --git a/freetype/src/autofit/aftypes.h b/freetype/src/autofit/aftypes.h
index cb92890b1..191a76f39 100644
--- a/freetype/src/autofit/aftypes.h
+++ b/freetype/src/autofit/aftypes.h
@@ -4,7 +4,7 @@
/* */
/* Auto-fitter types (specification only). */
/* */
-/* Copyright 2003-2009, 2011 by */
+/* Copyright 2003-2009, 2011-2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -87,8 +87,9 @@ extern void* _af_debug_hints;
FT_Pos* table );
FT_LOCAL( void )
- af_sort_widths( FT_UInt count,
- AF_Width widths );
+ af_sort_and_quantize_widths( FT_UInt* count,
+ AF_Width widths,
+ FT_Pos threshold );
/*************************************************************************/
@@ -228,12 +229,12 @@ extern void* _af_debug_hints;
typedef enum AF_Script_
{
- AF_SCRIPT_NONE = 0,
+ AF_SCRIPT_DUMMY = 0,
AF_SCRIPT_LATIN = 1,
AF_SCRIPT_CJK = 2,
AF_SCRIPT_INDIC = 3,
#ifdef FT_OPTION_AUTOFIT2
- AF_SCRIPT_LATIN2,
+ AF_SCRIPT_LATIN2 = 4,
#endif
/* add new scripts here. Don't forget to update the list in */
@@ -245,6 +246,7 @@ extern void* _af_debug_hints;
typedef struct AF_ScriptClassRec_ const* AF_ScriptClass;
+ typedef struct AF_FaceGlobalsRec_* AF_FaceGlobals;
typedef struct AF_ScriptMetricsRec_
{
@@ -252,6 +254,8 @@ extern void* _af_debug_hints;
AF_ScalerRec scaler;
FT_Bool digits_have_same_width;
+ AF_FaceGlobals globals; /* to access properties */
+
} AF_ScriptMetricsRec, *AF_ScriptMetrics;
@@ -294,8 +298,9 @@ extern void* _af_debug_hints;
typedef struct AF_ScriptClassRec_
{
- AF_Script script;
- AF_Script_UniRange script_uni_ranges; /* last must be { 0, 0 } */
+ AF_Script script;
+ AF_Script_UniRange script_uni_ranges; /* last must be { 0, 0 } */
+ FT_UInt32 standard_char; /* for default width and height */
FT_Offset script_metrics_size;
AF_Script_InitMetricsFunc script_metrics_init;
@@ -315,13 +320,14 @@ extern void* _af_debug_hints;
FT_CALLBACK_TABLE const AF_ScriptClassRec \
script_class;
-#define AF_DEFINE_SCRIPT_CLASS( script_class, script_, ranges, m_size, \
+#define AF_DEFINE_SCRIPT_CLASS( script_class, script_, ranges, def_char, \
+ m_size, \
m_init, m_scale, m_done, h_init, h_apply ) \
- FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec \
- script_class = \
+ FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec script_class = \
{ \
script_, \
ranges, \
+ def_char, \
\
m_size, \
\
@@ -335,17 +341,19 @@ extern void* _af_debug_hints;
#else /* FT_CONFIG_OPTION_PIC */
-#define AF_DECLARE_SCRIPT_CLASS( script_class ) \
- FT_LOCAL( void ) \
- FT_Init_Class_##script_class( AF_ScriptClassRec* ac );
+#define AF_DECLARE_SCRIPT_CLASS( script_class ) \
+ FT_LOCAL( void ) \
+ FT_Init_Class_ ## script_class( AF_ScriptClassRec* ac );
-#define AF_DEFINE_SCRIPT_CLASS( script_class, script_, ranges, m_size, \
+#define AF_DEFINE_SCRIPT_CLASS( script_class, script_, ranges, def_char, \
+ m_size, \
m_init, m_scale, m_done, h_init, h_apply ) \
FT_LOCAL_DEF( void ) \
- FT_Init_Class_##script_class( AF_ScriptClassRec* ac ) \
+ FT_Init_Class_ ## script_class( AF_ScriptClassRec* ac ) \
{ \
ac->script = script_; \
ac->script_uni_ranges = ranges; \
+ ac->default_char = def_char; \
\
ac->script_metrics_size = m_size; \
\
diff --git a/freetype/src/base/basepic.c b/freetype/src/base/basepic.c
index 7e9d7da66..222772b41 100644
--- a/freetype/src/base/basepic.c
+++ b/freetype/src/base/basepic.c
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for base. */
/* */
-/* Copyright 2009 by */
+/* Copyright 2009, 2012 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -21,14 +21,22 @@
#include <freetype/internal/ftobjs.h>
#include "basepic.h"
+
#ifdef FT_CONFIG_OPTION_PIC
/* forward declaration of PIC init functions from ftglyph.c */
- void FT_Init_Class_ft_outline_glyph_class( FT_Glyph_Class* clazz );
- void FT_Init_Class_ft_bitmap_glyph_class( FT_Glyph_Class* clazz );
+ void
+ FT_Init_Class_ft_outline_glyph_class( FT_Glyph_Class* clazz );
- /* forward declaration of PIC init function from ftrfork.c (not modularized) */
- void FT_Init_Table_raccess_guess_table( ft_raccess_guess_rec* record );
+ void
+ FT_Init_Class_ft_bitmap_glyph_class( FT_Glyph_Class* clazz );
+
+#ifdef FT_CONFIG_OPTION_MAC_FONTS
+ /* forward declaration of PIC init function from ftrfork.c */
+ /* (not modularized) */
+ void
+ FT_Init_Table_raccess_guess_table( ft_raccess_guess_rec* record );
+#endif
/* forward declaration of PIC init functions from ftinit.c */
FT_Error
@@ -37,14 +45,18 @@
void
ft_destroy_default_module_classes( FT_Library library );
+
void
ft_base_pic_free( FT_Library library )
{
FT_PIC_Container* pic_container = &library->pic_container;
- FT_Memory memory = library->memory;
+ FT_Memory memory = library->memory;
+
+
if ( pic_container->base )
{
- /* Destroy default module classes (in case FT_Add_Default_Modules was used) */
+ /* destroy default module classes */
+ /* (in case FT_Add_Default_Modules was used) */
ft_destroy_default_module_classes( library );
FT_FREE( pic_container->base );
@@ -57,9 +69,10 @@
ft_base_pic_init( FT_Library library )
{
FT_PIC_Container* pic_container = &library->pic_container;
- FT_Error error = FT_Err_Ok;
- BasePIC* container;
- FT_Memory memory = library->memory;
+ FT_Error error = FT_Err_Ok;
+ BasePIC* container = NULL;
+ FT_Memory memory = library->memory;
+
/* allocate pointer, clear and set global container pointer */
if ( FT_ALLOC ( container, sizeof ( *container ) ) )
@@ -72,13 +85,16 @@
if ( error )
goto Exit;
- /* initialize pointer table - this is how the module usually expects this data */
+ /* initialize pointer table - */
+ /* this is how the module usually expects this data */
FT_Init_Class_ft_outline_glyph_class(
&container->ft_outline_glyph_class );
FT_Init_Class_ft_bitmap_glyph_class(
&container->ft_bitmap_glyph_class );
+#ifdef FT_CONFIG_OPTION_MAC_FONTS
FT_Init_Table_raccess_guess_table(
- (ft_raccess_guess_rec*)&container->ft_raccess_guess_table);
+ (ft_raccess_guess_rec*)&container->ft_raccess_guess_table );
+#endif
Exit:
if( error )
diff --git a/freetype/src/base/ftgloadr.c b/freetype/src/base/ftgloadr.c
index 7d620ec19..173fb5f50 100644
--- a/freetype/src/base/ftgloadr.c
+++ b/freetype/src/base/ftgloadr.c
@@ -318,7 +318,7 @@
}
- /* add current glyph to the base image - and prepare for another */
+ /* add current glyph to the base image -- and prepare for another */
FT_BASE_DEF( void )
FT_GlyphLoader_Add( FT_GlyphLoader loader )
{
diff --git a/freetype/src/base/ftglyph.c b/freetype/src/base/ftglyph.c
index 0cb780388..4f33d71a2 100644
--- a/freetype/src/base/ftglyph.c
+++ b/freetype/src/base/ftglyph.c
@@ -4,7 +4,7 @@
/* */
/* FreeType convenience functions to handle glyphs (body). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2007, 2008, 2010 by */
+/* Copyright 1996-2005, 2007, 2008, 2010, 2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -510,7 +510,7 @@
FT_GlyphSlotRec dummy;
FT_GlyphSlot_InternalRec dummy_internal;
FT_Error error = FT_Err_Ok;
- FT_Glyph glyph;
+ FT_Glyph b, glyph;
FT_BitmapGlyph bitmap = NULL;
const FT_Glyph_Class* clazz;
@@ -547,10 +547,10 @@
dummy.format = clazz->glyph_format;
/* create result bitmap glyph */
- error = ft_new_glyph( library, FT_BITMAP_GLYPH_CLASS_GET,
- (FT_Glyph*)(void*)&bitmap );
+ error = ft_new_glyph( library, FT_BITMAP_GLYPH_CLASS_GET, &b );
if ( error )
goto Exit;
+ bitmap = (FT_BitmapGlyph)b;
#if 1
/* if `origin' is set, translate the glyph image */
diff --git a/freetype/src/base/ftinit.c b/freetype/src/base/ftinit.c
index bb738825c..be594da1e 100644
--- a/freetype/src/base/ftinit.c
+++ b/freetype/src/base/ftinit.c
@@ -4,7 +4,7 @@
/* */
/* FreeType initialization layer (body). */
/* */
-/* Copyright 1996-2001, 2002, 2005, 2007, 2009, 2012 by */
+/* Copyright 1996-2002, 2005, 2007, 2009, 2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -156,7 +156,7 @@
{
FT_Error error;
FT_Memory memory;
- FT_Module_Class* *classes;
+ FT_Module_Class* *classes = NULL;
FT_Module_Class* clazz;
FT_UInt i;
BasePIC* pic_container = (BasePIC*)library->pic_container.base;
diff --git a/freetype/src/base/ftobjs.c b/freetype/src/base/ftobjs.c
index 8552bfb74..202174962 100644
--- a/freetype/src/base/ftobjs.c
+++ b/freetype/src/base/ftobjs.c
@@ -29,6 +29,7 @@
#include FT_TRUETYPE_TAGS_H
#include FT_TRUETYPE_IDS_H
+#include FT_SERVICE_PROPERTIES_H
#include FT_SERVICE_SFNT_H
#include FT_SERVICE_POSTSCRIPT_NAME_H
#include FT_SERVICE_GLYPH_DICT_H
@@ -651,7 +652,7 @@
if ( autohint )
{
- FT_AutoHinter_Service hinting;
+ FT_AutoHinter_Interface hinting;
/* try to load embedded bitmaps first if available */
@@ -680,7 +681,7 @@
internal->transform_flags = 0;
/* load auto-hinted outline */
- hinting = (FT_AutoHinter_Service)hinter->clazz->module_interface;
+ hinting = (FT_AutoHinter_Interface)hinter->clazz->module_interface;
error = hinting->load_glyph( (FT_AutoHinter)hinter,
slot, face->size,
@@ -2055,11 +2056,12 @@
}
else
{
+ error = FT_Err_Missing_Module;
+
/* check each font driver for an appropriate format */
cur = library->modules;
limit = cur + library->num_modules;
-
for ( ; cur < limit; cur++ )
{
/* not all modules are font drivers, so check... */
@@ -2109,30 +2111,30 @@
}
}
- Fail3:
- /* If we are on the mac, and we get an FT_Err_Invalid_Stream_Operation */
- /* it may be because we have an empty data fork, so we need to check */
- /* the resource fork. */
- if ( FT_ERROR_BASE( error ) != FT_Err_Cannot_Open_Stream &&
- FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format &&
- FT_ERROR_BASE( error ) != FT_Err_Invalid_Stream_Operation )
- goto Fail2;
+ Fail3:
+ /* If we are on the mac, and we get an */
+ /* FT_Err_Invalid_Stream_Operation it may be because we have an */
+ /* empty data fork, so we need to check the resource fork. */
+ if ( FT_ERROR_BASE( error ) != FT_Err_Cannot_Open_Stream &&
+ FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format &&
+ FT_ERROR_BASE( error ) != FT_Err_Invalid_Stream_Operation )
+ goto Fail2;
#if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS )
- error = load_mac_face( library, stream, face_index, aface, args );
- if ( !error )
- {
- /* We don't want to go to Success here. We've already done that. */
- /* On the other hand, if we succeeded we still need to close this */
- /* stream (we opened a different stream which extracted the */
- /* interesting information out of this stream here. That stream */
- /* will still be open and the face will point to it). */
- FT_Stream_Free( stream, external_stream );
- return error;
- }
+ error = load_mac_face( library, stream, face_index, aface, args );
+ if ( !error )
+ {
+ /* We don't want to go to Success here. We've already done that. */
+ /* On the other hand, if we succeeded we still need to close this */
+ /* stream (we opened a different stream which extracted the */
+ /* interesting information out of this stream here. That stream */
+ /* will still be open and the face will point to it). */
+ FT_Stream_Free( stream, external_stream );
+ return error;
+ }
- if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format )
- goto Fail2;
+ if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format )
+ goto Fail2;
#endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */
/* no driver is able to handle this format */
@@ -4301,19 +4303,18 @@
{
FT_Pointer result = NULL;
+
if ( module )
{
FT_ASSERT( module->clazz && module->clazz->get_interface );
- /* first, look for the service in the module
- */
+ /* first, look for the service in the module */
if ( module->clazz->get_interface )
result = module->clazz->get_interface( module, service_id );
if ( result == NULL )
{
- /* we didn't find it, look in all other modules then
- */
+ /* we didn't find it, look in all other modules then */
FT_Library library = module->library;
FT_Module* cur = library->modules;
FT_Module* limit = cur + library->num_modules;
@@ -4382,6 +4383,118 @@
}
+ FT_Error
+ ft_property_do( FT_Library library,
+ const FT_String* module_name,
+ const FT_String* property_name,
+ void* value,
+ FT_Bool set )
+ {
+ FT_Module* cur;
+ FT_Module* limit;
+ FT_Module_Interface interface;
+
+ FT_Service_Properties service;
+
+#ifdef FT_DEBUG_LEVEL_ERROR
+ const FT_String* set_name = "FT_Property_Set";
+ const FT_String* get_name = "FT_Property_Get";
+ const FT_String* func_name = set ? set_name : get_name;
+#endif
+
+ FT_Bool missing_func;
+
+
+ if ( !library )
+ return FT_Err_Invalid_Library_Handle;
+
+ if ( !module_name || !property_name || !value )
+ return FT_Err_Invalid_Argument;
+
+ cur = library->modules;
+ limit = cur + library->num_modules;
+
+ /* search module */
+ for ( ; cur < limit; cur++ )
+ if ( !ft_strcmp( cur[0]->clazz->module_name, module_name ) )
+ break;
+
+ if ( cur == limit )
+ {
+ FT_ERROR(( "%s: can't find module `%s'\n",
+ func_name, module_name ));
+ return FT_Err_Missing_Module;
+ }
+
+ /* check whether we have a service interface */
+ if ( !cur[0]->clazz->get_interface )
+ {
+ FT_ERROR(( "%s: module `%s' doesn't support properties\n",
+ func_name, module_name ));
+ return FT_Err_Unimplemented_Feature;
+ }
+
+ /* search property service */
+ interface = cur[0]->clazz->get_interface( cur[0],
+ FT_SERVICE_ID_PROPERTIES );
+ if ( !interface )
+ {
+ FT_ERROR(( "%s: module `%s' doesn't support properties\n",
+ func_name, module_name ));
+ return FT_Err_Unimplemented_Feature;
+ }
+
+ service = (FT_Service_Properties)interface;
+
+ if ( set )
+ missing_func = !service->set_property;
+ else
+ missing_func = !service->get_property;
+
+ if ( missing_func )
+ {
+ FT_ERROR(( "%s: property service of module `%s' is broken\n",
+ func_name, module_name ));
+ return FT_Err_Unimplemented_Feature;
+ }
+
+ return set ? service->set_property( cur[0], property_name, value )
+ : service->get_property( cur[0], property_name, value );
+ }
+
+
+ /* documentation is in ftmodapi.h */
+
+ FT_Error
+ FT_Property_Set( FT_Library library,
+ const FT_String* module_name,
+ const FT_String* property_name,
+ const void* value )
+ {
+ return ft_property_do( library,
+ module_name,
+ property_name,
+ (void*)value,
+ TRUE );
+ }
+
+
+ /* documentation is in ftmodapi.h */
+
+ FT_Error
+ FT_Property_Get( FT_Library library,
+ const FT_String* module_name,
+ const FT_String* property_name,
+ void* value )
+ {
+ return ft_property_do( library,
+ module_name,
+ property_name,
+ value,
+ FALSE );
+ }
+
+
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
diff --git a/freetype/src/base/ftoutln.c b/freetype/src/base/ftoutln.c
index f94319d0b..f542f01c8 100644
--- a/freetype/src/base/ftoutln.c
+++ b/freetype/src/base/ftoutln.c
@@ -922,7 +922,7 @@
for ( c = 0; c < outline->n_contours; c++ )
{
FT_Vector in, out, shift;
- FT_Fixed l_in, l_out, d;
+ FT_Fixed l_in, l_out, l, q, d;
int last = outline->contours[c];
@@ -952,17 +952,32 @@
/* shift only if turn is less then ~160 degrees */
if ( 16 * d > l_in * l_out )
{
- /* shift components are rotated */
- shift.x = FT_DivFix( l_out * in.y + l_in * out.y, d );
- shift.y = FT_DivFix( l_out * in.x + l_in * out.x, d );
+ /* shift components are aligned along bisector */
+ /* and directed according to the outline orientation. */
+ shift.x = l_out * in.y + l_in * out.y;
+ shift.y = l_out * in.x + l_in * out.x;
if ( orientation == FT_ORIENTATION_TRUETYPE )
shift.x = -shift.x;
else
shift.y = -shift.y;
- shift.x = FT_MulFix( xstrength, shift.x );
- shift.y = FT_MulFix( ystrength, shift.y );
+ /* threshold strength to better handle collapsing segments */
+ l = FT_MIN( l_in, l_out );
+ q = out.x * in.y - out.y * in.x;
+ if ( orientation == FT_ORIENTATION_TRUETYPE )
+ q = -q;
+
+ if ( FT_MulDiv( xstrength, q, l ) < d )
+ shift.x = FT_MulDiv( shift.x, xstrength, d );
+ else
+ shift.x = FT_MulDiv( shift.x, l, q );
+
+
+ if ( FT_MulDiv( ystrength, q, l ) < d )
+ shift.y = FT_MulDiv( shift.y, ystrength, d );
+ else
+ shift.y = FT_MulDiv( shift.y, l, q );
}
else
shift.x = shift.y = 0;
diff --git a/freetype/src/base/ftrfork.c b/freetype/src/base/ftrfork.c
index b452b2333..9c9395f6b 100644
--- a/freetype/src/base/ftrfork.c
+++ b/freetype/src/base/ftrfork.c
@@ -362,7 +362,7 @@
FT_Long *offsets,
FT_Error *errors )
{
- FT_Long i;
+ FT_Int i;
for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
@@ -827,7 +827,7 @@
FT_Long *offsets,
FT_Error *errors )
{
- int i;
+ FT_Int i;
FT_UNUSED( library );
FT_UNUSED( stream );
diff --git a/freetype/src/base/ftstroke.c b/freetype/src/base/ftstroke.c
index 9b215895f..27537fc97 100644
--- a/freetype/src/base/ftstroke.c
+++ b/freetype/src/base/ftstroke.c
@@ -789,7 +789,7 @@
FT_Stroker_New( FT_Library library,
FT_Stroker *astroker )
{
- FT_Error error;
+ FT_Error error; /* assigned in FT_NEW */
FT_Memory memory;
FT_Stroker stroker = NULL;
@@ -1126,9 +1126,8 @@
middle.y += stroker->center.y;
/* compute first angle point */
- length = FT_MulFix( radius,
- FT_DivFix( 0x10000L - sigma,
- ft_pos_abs( FT_Sin( theta ) ) ) );
+ length = FT_MulDiv( radius, 0x10000L - sigma,
+ ft_pos_abs( FT_Sin( theta ) ) );
FT_Vector_From_Polar( &delta, length, phi + rotate );
delta.x += middle.x;
@@ -1495,7 +1494,7 @@
sinA = ft_pos_abs( FT_Sin( alpha1 - gamma ) );
sinB = ft_pos_abs( FT_Sin( beta - gamma ) );
- alen = FT_DivFix( FT_MulFix( blen, sinA ), sinB );
+ alen = FT_MulDiv( blen, sinA, sinB );
FT_Vector_From_Polar( &delta, alen, beta );
delta.x += start.x;
@@ -1702,7 +1701,7 @@
sinA = ft_pos_abs( FT_Sin( alpha1 - gamma ) );
sinB = ft_pos_abs( FT_Sin( beta - gamma ) );
- alen = FT_DivFix( FT_MulFix( blen, sinA ), sinB );
+ alen = FT_MulDiv( blen, sinA, sinB );
FT_Vector_From_Polar( &delta, alen, beta );
delta.x += start.x;
diff --git a/freetype/src/base/ftsynth.c b/freetype/src/base/ftsynth.c
index 2d110fb7e..a25280d0c 100644
--- a/freetype/src/base/ftsynth.c
+++ b/freetype/src/base/ftsynth.c
@@ -63,7 +63,7 @@
transform.xx = 0x10000L;
transform.yx = 0x00000L;
- transform.xy = 0x06000L;
+ transform.xy = 0x0366AL;
transform.yy = 0x10000L;
FT_Outline_Transform( outline, &transform );
diff --git a/freetype/src/base/fttrigon.c b/freetype/src/base/fttrigon.c
index efee35f11..6b8913a14 100644
--- a/freetype/src/base/fttrigon.c
+++ b/freetype/src/base/fttrigon.c
@@ -4,7 +4,7 @@
/* */
/* FreeType trigonometric functions (body). */
/* */
-/* Copyright 2001, 2002, 2003, 2004, 2005 by */
+/* Copyright 2001-2005, 2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -21,25 +21,30 @@
#include FT_TRIGONOMETRY_H
- /* the following is 0.2715717684432231 * 2^30 */
-#define FT_TRIG_COSCALE 0x11616E8EUL
+#ifdef FT_LONG64
+ typedef FT_INT64 FT_Int64;
+#endif
+
+
+ /* the Cordic shrink factor 0.607252935008887 * 2^32 */
+#define FT_TRIG_SCALE 0x9B74EDA8UL
+
+ /* the following is 0.607252935008887 * 2^30 */
+#define FT_TRIG_COSCALE 0x26DD3B6AUL
/* this table was generated for FT_PI = 180L << 16, i.e. degrees */
#define FT_TRIG_MAX_ITERS 23
static const FT_Fixed
- ft_trig_arctan_table[24] =
+ ft_trig_arctan_table[23] =
{
- 4157273L, 2949120L, 1740967L, 919879L, 466945L, 234379L, 117304L,
- 58666L, 29335L, 14668L, 7334L, 3667L, 1833L, 917L, 458L, 229L, 115L,
+ 2949120L, 1740967L, 919879L, 466945L, 234379L, 117304L, 58666L,
+ 29335L, 14668L, 7334L, 3667L, 1833L, 917L, 458L, 229L, 115L,
57L, 29L, 14L, 7L, 4L, 2L, 1L
};
- /* the Cordic shrink factor, multiplied by 2^32 */
-#define FT_TRIG_SCALE 1166391785UL /* 0x4585BA38UL */
-
-#ifdef FT_CONFIG_HAS_INT64
+#ifdef FT_LONG64
/* multiply a given value by the CORDIC shrink factor */
static FT_Fixed
@@ -58,7 +63,7 @@
return ( s >= 0 ) ? val : -val;
}
-#else /* !FT_CONFIG_HAS_INT64 */
+#else /* !FT_LONG64 */
/* multiply a given value by the CORDIC shrink factor */
static FT_Fixed
@@ -72,10 +77,10 @@
val = ( val >= 0 ) ? val : -val;
v1 = (FT_UInt32)val >> 16;
- v2 = (FT_UInt32)(val & 0xFFFFL);
+ v2 = (FT_UInt32)( val & 0xFFFFL );
- k1 = (FT_UInt32)FT_TRIG_SCALE >> 16; /* constant */
- k2 = (FT_UInt32)(FT_TRIG_SCALE & 0xFFFFL); /* constant */
+ k1 = (FT_UInt32)FT_TRIG_SCALE >> 16; /* constant */
+ k2 = (FT_UInt32)( FT_TRIG_SCALE & 0xFFFFL ); /* constant */
hi = k1 * v1;
lo1 = k1 * v2 + k2 * v1; /* can't overflow */
@@ -93,7 +98,7 @@
return ( s >= 0 ) ? val : -val;
}
-#endif /* !FT_CONFIG_HAS_INT64 */
+#endif /* !FT_LONG64 */
static FT_Int
@@ -209,25 +214,9 @@
theta -= FT_ANGLE_PI;
}
- /* Initial pseudorotation, with left shift */
arctanptr = ft_trig_arctan_table;
- if ( theta < 0 )
- {
- xtemp = x + ( y << 1 );
- y = y - ( x << 1 );
- x = xtemp;
- theta += *arctanptr++;
- }
- else
- {
- xtemp = x - ( y << 1 );
- y = y + ( x << 1 );
- x = xtemp;
- theta -= *arctanptr++;
- }
-
- /* Subsequent pseudorotations, with right shifts */
+ /* Pseudorotations, with right shifts */
i = 0;
do
{
@@ -255,9 +244,9 @@
static void
ft_trig_pseudo_polarize( FT_Vector* vec )
{
- FT_Fixed theta;
- FT_Fixed yi, i;
- FT_Fixed x, y;
+ FT_Angle theta;
+ FT_Int i;
+ FT_Fixed x, y, xtemp;
const FT_Fixed *arctanptr;
@@ -278,41 +267,23 @@
arctanptr = ft_trig_arctan_table;
- if ( y < 0 )
- {
- /* Rotate positive */
- yi = y + ( x << 1 );
- x = x - ( y << 1 );
- y = yi;
- theta -= *arctanptr++; /* Subtract angle */
- }
- else
- {
- /* Rotate negative */
- yi = y - ( x << 1 );
- x = x + ( y << 1 );
- y = yi;
- theta += *arctanptr++; /* Add angle */
- }
-
+ /* Pseudorotations, with right shifts */
i = 0;
do
{
- if ( y < 0 )
+ if ( y > 0 )
{
- /* Rotate positive */
- yi = y + ( x >> i );
- x = x - ( y >> i );
- y = yi;
- theta -= *arctanptr++;
+ xtemp = x + ( y >> i );
+ y = y - ( x >> i );
+ x = xtemp;
+ theta += *arctanptr++;
}
else
{
- /* Rotate negative */
- yi = y - ( x >> i );
- x = x + ( y >> i );
- y = yi;
- theta += *arctanptr++;
+ xtemp = x - ( y >> i );
+ y = y + ( x >> i );
+ x = xtemp;
+ theta -= *arctanptr++;
}
} while ( ++i < FT_TRIG_MAX_ITERS );
diff --git a/freetype/src/bdf/bdflib.c b/freetype/src/bdf/bdflib.c
index fb1589411..8626c8bc9 100644
--- a/freetype/src/bdf/bdflib.c
+++ b/freetype/src/bdf/bdflib.c
@@ -770,11 +770,11 @@
/* XXX: Use encoding independent value for 0x1a */
if ( buf[start] != '#' && buf[start] != 0x1a && end > start )
{
- error = (*cb)( buf + start, end - start, lineno,
+ error = (*cb)( buf + start, (unsigned long)( end - start ), lineno,
(void*)&cb, client_data );
/* Redo if we have encountered CHARS without properties. */
if ( error == -1 )
- error = (*cb)( buf + start, end - start, lineno,
+ error = (*cb)( buf + start, (unsigned long)( end - start ), lineno,
(void*)&cb, client_data );
if ( error )
break;
@@ -1624,12 +1624,16 @@
if ( p->glyph_enc == -1 && p->list.used > 2 )
p->glyph_enc = _bdf_atol( p->list.field[2], 0, 10 );
+ if ( p->glyph_enc < -1 )
+ p->glyph_enc = -1;
+
FT_TRACE4(( DBGMSG2, p->glyph_enc ));
/* Check that the encoding is in the Unicode range because */
/* otherwise p->have (a bitmap with static size) overflows. */
- if ( p->glyph_enc > 0 &&
- (size_t)p->glyph_enc >= sizeof ( p->have ) * 8 )
+ if ( p->glyph_enc > 0 &&
+ (size_t)p->glyph_enc >= sizeof ( p->have ) /
+ sizeof ( unsigned long ) * 32 )
{
FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG5, lineno, "ENCODING" ));
error = BDF_Err_Invalid_File_Format;
@@ -2169,7 +2173,10 @@
p->cnt = p->font->props_size = _bdf_atoul( p->list.field[1], 0, 10 );
if ( FT_NEW_ARRAY( p->font->props, p->cnt ) )
+ {
+ p->font->props_size = 0;
goto Exit;
+ }
p->flags |= _BDF_PROPS;
*next = _bdf_parse_properties;
diff --git a/freetype/src/cache/ftccmap.c b/freetype/src/cache/ftccmap.c
index 4ac5dcdd8..1b50bb1e8 100644
--- a/freetype/src/cache/ftccmap.c
+++ b/freetype/src/cache/ftccmap.c
@@ -4,8 +4,7 @@
/* */
/* FreeType CharMap cache (body) */
/* */
-/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */
-/* 2010, 2011 by */
+/* Copyright 2000-2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -121,7 +120,7 @@
/* if (indices[n] == FTC_CMAP_UNKNOWN), we assume that the corresponding */
/* glyph indices haven't been queried through FT_Get_Glyph_Index() yet */
-#define FTC_CMAP_UNKNOWN ( (FT_UInt16)-1 )
+#define FTC_CMAP_UNKNOWN (FT_UInt16)~0
/*************************************************************************/
diff --git a/freetype/src/cff/cffdrivr.c b/freetype/src/cff/cffdrivr.c
index e1b2ff237..971a904ca 100644
--- a/freetype/src/cff/cffdrivr.c
+++ b/freetype/src/cff/cffdrivr.c
@@ -412,8 +412,8 @@
cmap_info->language = 0;
cmap_info->format = 0;
- if ( cmap->clazz != &FT_CFF_CMAP_ENCODING_CLASS_REC_GET &&
- cmap->clazz != &FT_CFF_CMAP_UNICODE_CLASS_REC_GET )
+ if ( cmap->clazz != &CFF_CMAP_ENCODING_CLASS_REC_GET &&
+ cmap->clazz != &CFF_CMAP_UNICODE_CLASS_REC_GET )
{
FT_Module sfnt = FT_Get_Module( library, "sfnt" );
FT_Service_TTCMaps service =
@@ -579,19 +579,19 @@
#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
FT_DEFINE_SERVICEDESCREC6(cff_services,
FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF,
- FT_SERVICE_ID_POSTSCRIPT_INFO, &FT_CFF_SERVICE_PS_INFO_GET,
- FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_CFF_SERVICE_PS_NAME_GET,
- FT_SERVICE_ID_GLYPH_DICT, &FT_CFF_SERVICE_GLYPH_DICT_GET,
- FT_SERVICE_ID_TT_CMAP, &FT_CFF_SERVICE_GET_CMAP_INFO_GET,
- FT_SERVICE_ID_CID, &FT_CFF_SERVICE_CID_INFO_GET
+ FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET,
+ FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET,
+ FT_SERVICE_ID_GLYPH_DICT, &CFF_SERVICE_GLYPH_DICT_GET,
+ FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET,
+ FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET
)
#else
FT_DEFINE_SERVICEDESCREC5(cff_services,
FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF,
- FT_SERVICE_ID_POSTSCRIPT_INFO, &FT_CFF_SERVICE_PS_INFO_GET,
- FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_CFF_SERVICE_PS_NAME_GET,
- FT_SERVICE_ID_TT_CMAP, &FT_CFF_SERVICE_GET_CMAP_INFO_GET,
- FT_SERVICE_ID_CID, &FT_CFF_SERVICE_CID_INFO_GET
+ FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET,
+ FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET,
+ FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET,
+ FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET
)
#endif
@@ -604,7 +604,7 @@
FT_Module_Interface result;
- /* FT_CFF_SERVICES_GET derefers `library' in PIC mode */
+ /* CFF_SERVICES_GET derefers `library' in PIC mode */
#ifdef FT_CONFIG_OPTION_PIC
if ( !driver )
return NULL;
@@ -613,7 +613,7 @@
return NULL;
#endif
- result = ft_service_list_lookup( FT_CFF_SERVICES_GET, module_interface );
+ result = ft_service_list_lookup( CFF_SERVICES_GET, module_interface );
if ( result != NULL )
return result;
diff --git a/freetype/src/cff/cffload.c b/freetype/src/cff/cffload.c
index 744b138a7..47fc1261c 100644
--- a/freetype/src/cff/cffload.c
+++ b/freetype/src/cff/cffload.c
@@ -4,7 +4,7 @@
/* */
/* OpenType and CFF data/program tables loader (body). */
/* */
-/* Copyright 1996-2011 by */
+/* Copyright 1996-2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -1439,6 +1439,7 @@
FT_ULong base_offset;
CFF_FontRecDict dict;
CFF_IndexRec string_index;
+ FT_Int subfont_index;
FT_ZERO( font );
@@ -1483,13 +1484,35 @@
font->num_strings = string_index.count;
- /* well, we don't really forget the `disabled' fonts... */
- font->num_faces = font->name_index.count;
- if ( face_index >= (FT_Int)font->num_faces )
+ if ( pure_cff )
{
- FT_ERROR(( "cff_font_load: incorrect face index = %d\n",
- face_index ));
- error = CFF_Err_Invalid_Argument;
+ /* well, we don't really forget the `disabled' fonts... */
+ subfont_index = face_index;
+
+ if ( subfont_index >= (FT_Int)font->name_index.count )
+ {
+ FT_ERROR(( "cff_font_load:"
+ " invalid subfont index for pure CFF font (%d)\n",
+ subfont_index ));
+ error = CFF_Err_Invalid_Argument;
+ goto Exit;
+ }
+
+ font->num_faces = font->name_index.count;
+ }
+ else
+ {
+ subfont_index = 0;
+
+ if ( font->name_index.count > 1 )
+ {
+ FT_ERROR(( "cff_font_load:"
+ " invalid CFF font with multiple subfonts\n"
+ " "
+ " in SFNT wrapper\n" ));
+ error = CFF_Err_Invalid_File_Format;
+ goto Exit;
+ }
}
/* in case of a font format check, simply exit now */
@@ -1500,7 +1523,7 @@
FT_TRACE4(( "parsing top-level\n" ));
error = cff_subfont_load( &font->top_font,
&font->font_dict_index,
- face_index,
+ subfont_index,
stream,
base_offset,
library );
@@ -1615,7 +1638,7 @@
/* get the font name (/CIDFontName for CID-keyed fonts, */
/* /FontName otherwise) */
- font->font_name = cff_index_get_name( font, face_index );
+ font->font_name = cff_index_get_name( font, subfont_index );
Exit:
cff_index_done( &string_index );
diff --git a/freetype/src/cff/cffobjs.c b/freetype/src/cff/cffobjs.c
index bd6e1d7d2..c4d9ef6b0 100644
--- a/freetype/src/cff/cffobjs.c
+++ b/freetype/src/cff/cffobjs.c
@@ -527,14 +527,6 @@
if ( face_index < 0 )
return CFF_Err_Ok;
- /* UNDOCUMENTED! A CFF in an SFNT can have only a single font. */
- if ( face_index > 0 )
- {
- FT_ERROR(( "cff_face_init: invalid face index\n" ));
- error = CFF_Err_Invalid_Argument;
- goto Exit;
- }
-
sfnt_format = 1;
/* now, the font can be either an OpenType/CFF font, or an SVG CEF */
@@ -545,7 +537,8 @@
pure_cff = 0;
/* load font directory */
- error = sfnt->load_face( stream, face, 0, num_params, params );
+ error = sfnt->load_face( stream, face, face_index,
+ num_params, params );
if ( error )
goto Exit;
}
@@ -555,10 +548,6 @@
error = sfnt->load_cmap( face, stream );
if ( error )
goto Exit;
-
- /* XXX: we don't load the GPOS table, as OpenType Layout */
- /* support will be added later to a layout library on top of */
- /* FreeType 2 */
}
/* now load the CFF part of the file */
@@ -969,7 +958,7 @@
nn = (FT_UInt)cffface->num_charmaps;
- error = FT_CMap_New( &FT_CFF_CMAP_UNICODE_CLASS_REC_GET, NULL,
+ error = FT_CMap_New( &CFF_CMAP_UNICODE_CLASS_REC_GET, NULL,
&cmaprec, NULL );
if ( error && FT_Err_No_Unicode_Glyph_Name != error )
goto Exit;
@@ -1001,19 +990,19 @@
{
cmaprec.encoding_id = TT_ADOBE_ID_STANDARD;
cmaprec.encoding = FT_ENCODING_ADOBE_STANDARD;
- clazz = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET;
+ clazz = &CFF_CMAP_ENCODING_CLASS_REC_GET;
}
else if ( encoding->offset == 1 )
{
cmaprec.encoding_id = TT_ADOBE_ID_EXPERT;
cmaprec.encoding = FT_ENCODING_ADOBE_EXPERT;
- clazz = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET;
+ clazz = &CFF_CMAP_ENCODING_CLASS_REC_GET;
}
else
{
cmaprec.encoding_id = TT_ADOBE_ID_CUSTOM;
cmaprec.encoding = FT_ENCODING_ADOBE_CUSTOM;
- clazz = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET;
+ clazz = &CFF_CMAP_ENCODING_CLASS_REC_GET;
}
error = FT_CMap_New( clazz, NULL, &cmaprec, NULL );
diff --git a/freetype/src/cff/cffparse.c b/freetype/src/cff/cffparse.c
index cb8f08c7e..e538f3b6f 100644
--- a/freetype/src/cff/cffparse.c
+++ b/freetype/src/cff/cffparse.c
@@ -4,7 +4,7 @@
/* */
/* CFF token stream parser (body) */
/* */
-/* Copyright 1996-2004, 2007-2011 by */
+/* Copyright 1996-2004, 2007-2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -105,6 +105,7 @@
Bad:
val = 0;
+ FT_TRACE4(( "!!!END OF DATA:!!!" ));
goto Exit;
}
@@ -136,7 +137,7 @@
FT_UInt phase;
FT_Long result, number, exponent;
- FT_Int sign = 0, exponent_sign = 0;
+ FT_Int sign = 0, exponent_sign = 0, have_overflow = 0;
FT_Long exponent_add, integer_length, fraction_length;
@@ -165,7 +166,7 @@
/* Make sure we don't read past the end. */
if ( p >= limit )
- goto Exit;
+ goto Bad;
}
/* Get the nibble. */
@@ -202,7 +203,7 @@
/* Make sure we don't read past the end. */
if ( p >= limit )
- goto Exit;
+ goto Bad;
}
/* Get the nibble. */
@@ -241,7 +242,7 @@
/* Make sure we don't read past the end. */
if ( p >= limit )
- goto Exit;
+ goto Bad;
}
/* Get the nibble. */
@@ -250,17 +251,28 @@
if ( nib >= 10 )
break;
- exponent = exponent * 10 + nib;
-
/* Arbitrarily limit exponent. */
if ( exponent > 1000 )
- goto Exit;
+ have_overflow = 1;
+ else
+ exponent = exponent * 10 + nib;
}
if ( exponent_sign )
exponent = -exponent;
}
+ if ( !number )
+ goto Exit;
+
+ if ( have_overflow )
+ {
+ if ( exponent_sign )
+ goto Underflow;
+ else
+ goto Overflow;
+ }
+
/* We don't check `power_ten' and `exponent_add'. */
exponent += power_ten + exponent_add;
@@ -286,15 +298,20 @@
/* Make `scaling' as small as possible. */
new_fraction_length = FT_MIN( exponent, 5 );
- exponent -= new_fraction_length;
shift = new_fraction_length - fraction_length;
- number *= power_tens[shift];
- if ( number > 0x7FFFL )
+ if ( shift > 0 )
{
- number /= 10;
- exponent += 1;
+ exponent -= new_fraction_length;
+ number *= power_tens[shift];
+ if ( number > 0x7FFFL )
+ {
+ number /= 10;
+ exponent += 1;
+ }
}
+ else
+ exponent -= fraction_length;
}
else
exponent -= fraction_length;
@@ -322,9 +339,10 @@
integer_length += exponent;
fraction_length -= exponent;
- /* Check for overflow and underflow. */
- if ( FT_ABS( integer_length ) > 5 )
- goto Exit;
+ if ( integer_length > 5 )
+ goto Overflow;
+ if ( integer_length < -5 )
+ goto Underflow;
/* Remove non-significant digits. */
if ( integer_length < 0 )
@@ -353,17 +371,32 @@
number *= power_tens[-fraction_length];
if ( number > 0x7FFFL )
- goto Exit;
+ goto Overflow;
result = number << 16;
}
}
+ Exit:
if ( sign )
result = -result;
- Exit:
return result;
+
+ Overflow:
+ result = 0x7FFFFFFFL;
+ FT_TRACE4(( "!!!OVERFLOW:!!!" ));
+ goto Exit;
+
+ Underflow:
+ result = 0;
+ FT_TRACE4(( "!!!UNDERFLOW:!!!" ));
+ goto Exit;
+
+ Bad:
+ result = 0;
+ FT_TRACE4(( "!!!END OF DATA:!!!" ));
+ goto Exit;
}
@@ -378,10 +411,44 @@
/* read a floating point number, either integer or real */
static FT_Fixed
+ do_fixed( FT_Byte** d,
+ FT_Long scaling )
+ {
+ if ( **d == 30 )
+ return cff_parse_real( d[0], d[1], scaling, NULL );
+ else
+ {
+ FT_Long val = cff_parse_integer( d[0], d[1] );
+
+
+ if ( scaling )
+ val *= power_tens[scaling];
+
+ if ( val > 0x7FFF )
+ {
+ val = 0x7FFFFFFFL;
+ goto Overflow;
+ }
+ else if ( val < -0x7FFF )
+ {
+ val = -0x7FFFFFFFL;
+ goto Overflow;
+ }
+
+ return val << 16;
+
+ Overflow:
+ FT_TRACE4(( "!!!OVERFLOW:!!!" ));
+ return val;
+ }
+ }
+
+
+ /* read a floating point number, either integer or real */
+ static FT_Fixed
cff_parse_fixed( FT_Byte** d )
{
- return **d == 30 ? cff_parse_real( d[0], d[1], 0, NULL )
- : cff_parse_integer( d[0], d[1] ) << 16;
+ return do_fixed( d, 0 );
}
@@ -391,9 +458,7 @@
cff_parse_fixed_scaled( FT_Byte** d,
FT_Long scaling )
{
- return **d == 30 ? cff_parse_real( d[0], d[1], scaling, NULL )
- : ( cff_parse_integer( d[0], d[1] ) *
- power_tens[scaling] ) << 16;
+ return do_fixed( d, scaling );
}
@@ -730,7 +795,7 @@
FT_Create_Class_cff_field_handlers( FT_Library library,
CFF_Field_Handler** output_class )
{
- CFF_Field_Handler* clazz;
+ CFF_Field_Handler* clazz = NULL;
FT_Error error;
FT_Memory memory = library->memory;
@@ -944,7 +1009,7 @@
}
code = code | parser->object_code;
- for ( field = FT_CFF_FIELD_HANDLERS_GET; field->kind; field++ )
+ for ( field = CFF_FIELD_HANDLERS_GET; field->kind; field++ )
{
if ( field->code == (FT_Int)code )
{
diff --git a/freetype/src/cff/cffpic.c b/freetype/src/cff/cffpic.c
index c34015ba8..f42126092 100644
--- a/freetype/src/cff/cffpic.c
+++ b/freetype/src/cff/cffpic.c
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for cff module. */
/* */
-/* Copyright 2009, 2010 by */
+/* Copyright 2009, 2010, 2012 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -103,7 +103,7 @@
{
FT_PIC_Container* pic_container = &library->pic_container;
FT_Error error = CFF_Err_Ok;
- CffModulePIC* container;
+ CffModulePIC* container = NULL;
FT_Memory memory = library->memory;
diff --git a/freetype/src/cff/cffpic.h b/freetype/src/cff/cffpic.h
index 076c220d6..ab17326c5 100644
--- a/freetype/src/cff/cffpic.h
+++ b/freetype/src/cff/cffpic.h
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for cff module. */
/* */
-/* Copyright 2009 by */
+/* Copyright 2009, 2012 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -24,16 +24,18 @@ FT_BEGIN_HEADER
#include <freetype/internal/ftpic.h>
+
#ifndef FT_CONFIG_OPTION_PIC
-#define FT_CFF_SERVICE_PS_INFO_GET cff_service_ps_info
-#define FT_CFF_SERVICE_GLYPH_DICT_GET cff_service_glyph_dict
-#define FT_CFF_SERVICE_PS_NAME_GET cff_service_ps_name
-#define FT_CFF_SERVICE_GET_CMAP_INFO_GET cff_service_get_cmap_info
-#define FT_CFF_SERVICE_CID_INFO_GET cff_service_cid_info
-#define FT_CFF_SERVICES_GET cff_services
-#define FT_CFF_CMAP_ENCODING_CLASS_REC_GET cff_cmap_encoding_class_rec
-#define FT_CFF_CMAP_UNICODE_CLASS_REC_GET cff_cmap_unicode_class_rec
-#define FT_CFF_FIELD_HANDLERS_GET cff_field_handlers
+
+#define CFF_SERVICE_PS_INFO_GET cff_service_ps_info
+#define CFF_SERVICE_GLYPH_DICT_GET cff_service_glyph_dict
+#define CFF_SERVICE_PS_NAME_GET cff_service_ps_name
+#define CFF_SERVICE_GET_CMAP_INFO_GET cff_service_get_cmap_info
+#define CFF_SERVICE_CID_INFO_GET cff_service_cid_info
+#define CFF_SERVICES_GET cff_services
+#define CFF_CMAP_ENCODING_CLASS_REC_GET cff_cmap_encoding_class_rec
+#define CFF_CMAP_UNICODE_CLASS_REC_GET cff_cmap_unicode_class_rec
+#define CFF_FIELD_HANDLERS_GET cff_field_handlers
#else /* FT_CONFIG_OPTION_PIC */
@@ -44,29 +46,43 @@ FT_BEGIN_HEADER
#include FT_SERVICE_TT_CMAP_H
#include FT_SERVICE_CID_H
- typedef struct CffModulePIC_
+
+ typedef struct CffModulePIC_
{
- FT_ServiceDescRec* cff_services;
- CFF_Field_Handler* cff_field_handlers;
- FT_Service_PsInfoRec cff_service_ps_info;
- FT_Service_GlyphDictRec cff_service_glyph_dict;
- FT_Service_PsFontNameRec cff_service_ps_name;
- FT_Service_TTCMapsRec cff_service_get_cmap_info;
- FT_Service_CIDRec cff_service_cid_info;
- FT_CMap_ClassRec cff_cmap_encoding_class_rec;
- FT_CMap_ClassRec cff_cmap_unicode_class_rec;
+ FT_ServiceDescRec* cff_services;
+ CFF_Field_Handler* cff_field_handlers;
+ FT_Service_PsInfoRec cff_service_ps_info;
+ FT_Service_GlyphDictRec cff_service_glyph_dict;
+ FT_Service_PsFontNameRec cff_service_ps_name;
+ FT_Service_TTCMapsRec cff_service_get_cmap_info;
+ FT_Service_CIDRec cff_service_cid_info;
+ FT_CMap_ClassRec cff_cmap_encoding_class_rec;
+ FT_CMap_ClassRec cff_cmap_unicode_class_rec;
+
} CffModulePIC;
-#define GET_PIC(lib) ((CffModulePIC*)((lib)->pic_container.cff))
-#define FT_CFF_SERVICE_PS_INFO_GET (GET_PIC(library)->cff_service_ps_info)
-#define FT_CFF_SERVICE_GLYPH_DICT_GET (GET_PIC(library)->cff_service_glyph_dict)
-#define FT_CFF_SERVICE_PS_NAME_GET (GET_PIC(library)->cff_service_ps_name)
-#define FT_CFF_SERVICE_GET_CMAP_INFO_GET (GET_PIC(library)->cff_service_get_cmap_info)
-#define FT_CFF_SERVICE_CID_INFO_GET (GET_PIC(library)->cff_service_cid_info)
-#define FT_CFF_SERVICES_GET (GET_PIC(library)->cff_services)
-#define FT_CFF_CMAP_ENCODING_CLASS_REC_GET (GET_PIC(library)->cff_cmap_encoding_class_rec)
-#define FT_CFF_CMAP_UNICODE_CLASS_REC_GET (GET_PIC(library)->cff_cmap_unicode_class_rec)
-#define FT_CFF_FIELD_HANDLERS_GET (GET_PIC(library)->cff_field_handlers)
+
+#define GET_PIC( lib ) \
+ ( (CffModulePIC*)((lib)->pic_container.cff) )
+
+#define CFF_SERVICE_PS_INFO_GET \
+ ( GET_PIC( library )->cff_service_ps_info )
+#define CFF_SERVICE_GLYPH_DICT_GET \
+ ( GET_PIC( library )->cff_service_glyph_dict )
+#define CFF_SERVICE_PS_NAME_GET \
+ ( GET_PIC( library )->cff_service_ps_name )
+#define CFF_SERVICE_GET_CMAP_INFO_GET \
+ ( GET_PIC( library )->cff_service_get_cmap_info )
+#define CFF_SERVICE_CID_INFO_GET \
+ ( GET_PIC( library )->cff_service_cid_info )
+#define CFF_SERVICES_GET \
+ ( GET_PIC( library )->cff_services )
+#define CFF_CMAP_ENCODING_CLASS_REC_GET \
+ ( GET_PIC( library )->cff_cmap_encoding_class_rec )
+#define CFF_CMAP_UNICODE_CLASS_REC_GET \
+ ( GET_PIC( library )->cff_cmap_unicode_class_rec )
+#define CFF_FIELD_HANDLERS_GET \
+ ( GET_PIC( library )->cff_field_handlers )
/* see cffpic.c for the implementation */
void
diff --git a/freetype/src/cid/cidload.c b/freetype/src/cid/cidload.c
index 748b1d126..bf88d849f 100644
--- a/freetype/src/cid/cidload.c
+++ b/freetype/src/cid/cidload.c
@@ -168,11 +168,11 @@
temp_scale = FT_ABS( temp[3] );
- /* Set units per EM based on FontMatrix values. We set the value to */
- /* `1000/temp_scale', because temp_scale was already multiplied by */
- /* 1000 (in `t1_tofixed', from psobjs.c). */
- root->units_per_EM = (FT_UShort)( FT_DivFix( 0x10000L,
- FT_DivFix( temp_scale, 1000 ) ) );
+ /* Set Units per EM based on FontMatrix values. We set the value to */
+ /* 1000 / temp_scale, because temp_scale was already multiplied by */
+ /* 1000 (in t1_tofixed, from psobjs.c). */
+
+ root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale );
/* we need to scale the values by 1.0/temp[3] */
if ( temp_scale != 0x10000L )
diff --git a/freetype/src/psaux/psconv.c b/freetype/src/psaux/psconv.c
index 1993042ca..21263f14c 100644..100755
--- a/freetype/src/psaux/psconv.c
+++ b/freetype/src/psaux/psconv.c
@@ -18,11 +18,22 @@
#include <ft2build.h>
#include <freetype/internal/psaux.h>
+#include FT_INTERNAL_DEBUG_H
#include "psconv.h"
#include "psauxerr.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_psconv
+
+
/* The following array is used by various functions to quickly convert */
/* digits (both decimal and non-decimal) into numbers. */
@@ -69,18 +80,29 @@
#endif /* 'A' == 193 */
- FT_LOCAL_DEF( FT_Int )
+ FT_LOCAL_DEF( FT_Long )
PS_Conv_Strtol( FT_Byte** cursor,
FT_Byte* limit,
- FT_Int base )
+ FT_Long base )
{
FT_Byte* p = *cursor;
- FT_Int num = 0;
- FT_Bool sign = 0;
+ FT_Long num = 0;
+ FT_Bool sign = 0;
+ FT_Bool have_overflow = 0;
+
+ FT_Long num_limit;
+ FT_Char c_limit;
+
+
+ if ( p >= limit )
+ goto Bad;
- if ( p >= limit || base < 2 || base > 36 )
+ if ( base < 2 || base > 36 )
+ {
+ FT_TRACE4(( "!!!INVALID BASE:!!!" ));
return 0;
+ }
if ( *p == '-' || *p == '+' )
{
@@ -88,9 +110,12 @@
p++;
if ( p == limit )
- return 0;
+ goto Bad;
}
+ num_limit = 0x7FFFFFFFL / base;
+ c_limit = (FT_Char)( 0x7FFFFFFFL % base );
+
for ( ; p < limit; p++ )
{
FT_Char c;
@@ -104,54 +129,84 @@
if ( c < 0 || c >= base )
break;
- num = num * base + c;
+ if ( num > num_limit || ( num == num_limit && c > c_limit ) )
+ have_overflow = 1;
+ else
+ num = num * base + c;
+ }
+
+ *cursor = p;
+
+ if ( have_overflow )
+ {
+ num = 0x7FFFFFFFL;
+ FT_TRACE4(( "!!!OVERFLOW:!!!" ));
}
if ( sign )
num = -num;
- *cursor = p;
-
return num;
+
+ Bad:
+ FT_TRACE4(( "!!!END OF DATA:!!!" ));
+ return 0;
}
- FT_LOCAL_DEF( FT_Int )
+ FT_LOCAL_DEF( FT_Long )
PS_Conv_ToInt( FT_Byte** cursor,
FT_Byte* limit )
{
- FT_Byte* p;
- FT_Int num;
+ FT_Byte* p = *cursor;
+ FT_Byte* curp;
+
+ FT_Long num;
- num = PS_Conv_Strtol( cursor, limit, 10 );
- p = *cursor;
+ curp = p;
+ num = PS_Conv_Strtol( &p, limit, 10 );
+
+ if ( p == curp )
+ return 0;
if ( p < limit && *p == '#' )
{
- *cursor = p + 1;
+ p++;
+
+ curp = p;
+ num = PS_Conv_Strtol( &p, limit, num );
- return PS_Conv_Strtol( cursor, limit, num );
+ if ( p == curp )
+ return 0;
}
- else
- return num;
+
+ *cursor = p;
+
+ return num;
}
FT_LOCAL_DEF( FT_Fixed )
PS_Conv_ToFixed( FT_Byte** cursor,
FT_Byte* limit,
- FT_Int power_ten )
+ FT_Long power_ten )
{
FT_Byte* p = *cursor;
- FT_Fixed integral;
- FT_Long decimal = 0, divider = 1;
- FT_Bool sign = 0;
+ FT_Byte* curp;
+
+ FT_Fixed integral = 0;
+ FT_Long decimal = 0;
+ FT_Long divider = 1;
+
+ FT_Bool sign = 0;
+ FT_Bool have_overflow = 0;
+ FT_Bool have_underflow = 0;
if ( p >= limit )
- return 0;
+ goto Bad;
if ( *p == '-' || *p == '+' )
{
@@ -159,13 +214,23 @@
p++;
if ( p == limit )
- return 0;
+ goto Bad;
}
+ /* read the integer part */
if ( *p != '.' )
- integral = PS_Conv_ToInt( &p, limit ) << 16;
- else
- integral = 0;
+ {
+ curp = p;
+ integral = PS_Conv_ToInt( &p, limit );
+
+ if ( p == curp )
+ return 0;
+
+ if ( integral > 0x7FFF )
+ have_overflow = 1;
+ else
+ integral <<= 16;
+ }
/* read the decimal part */
if ( p < limit && *p == '.' )
@@ -185,18 +250,14 @@
if ( c < 0 || c >= 10 )
break;
- if ( !integral && power_ten > 0 )
+ if ( decimal < 0xCCCCCCCL )
{
- power_ten--;
decimal = decimal * 10 + c;
- }
- else
- {
- if ( divider < 10000000L )
- {
- decimal = decimal * 10 + c;
+
+ if ( !integral && power_ten > 0 )
+ power_ten--;
+ else
divider *= 10;
- }
}
}
}
@@ -204,33 +265,94 @@
/* read exponent, if any */
if ( p + 1 < limit && ( *p == 'e' || *p == 'E' ) )
{
+ FT_Long exponent;
+
+
p++;
- power_ten += PS_Conv_ToInt( &p, limit );
+
+ curp = p;
+ exponent = PS_Conv_ToInt( &p, limit );
+
+ if ( curp == p )
+ return 0;
+
+ /* arbitrarily limit exponent */
+ if ( exponent > 1000 )
+ have_overflow = 1;
+ else if ( exponent < -1000 )
+ have_underflow = 1;
+ else
+ power_ten += exponent;
}
+ *cursor = p;
+
+ if ( !integral && !decimal )
+ return 0;
+
+ if ( have_overflow )
+ goto Overflow;
+ if ( have_underflow )
+ goto Underflow;
+
while ( power_ten > 0 )
{
+ if ( integral >= 0xCCCCCCCL )
+ goto Overflow;
integral *= 10;
- decimal *= 10;
+
+ if ( decimal >= 0xCCCCCCCL )
+ {
+ if ( divider == 1 )
+ goto Overflow;
+ divider /= 10;
+ }
+ else
+ decimal *= 10;
+
power_ten--;
}
while ( power_ten < 0 )
{
integral /= 10;
- divider *= 10;
+ if ( divider < 0xCCCCCCCL )
+ divider *= 10;
+ else
+ decimal /= 10;
+
+ if ( !integral && !decimal )
+ goto Underflow;
+
power_ten++;
}
if ( decimal )
- integral += FT_DivFix( decimal, divider );
+ {
+ decimal = FT_DivFix( decimal, divider );
+ /* it's not necessary to check this addition for overflow */
+ /* due to the structure of the real number representation */
+ integral += decimal;
+ }
+ Exit:
if ( sign )
integral = -integral;
- *cursor = p;
-
return integral;
+
+ Bad:
+ FT_TRACE4(( "!!!END OF DATA:!!!" ));
+ return 0;
+
+ Overflow:
+ integral = 0x7FFFFFFFL;
+ FT_TRACE4(( "!!!OVERFLOW:!!!" ));
+ goto Exit;
+
+ Underflow:
+ FT_TRACE4(( "!!!UNDERFLOW:!!!" ));
+ return 0;
}
diff --git a/freetype/src/psaux/psconv.h b/freetype/src/psaux/psconv.h
index 295ad692b..913ff00f6 100644
--- a/freetype/src/psaux/psconv.h
+++ b/freetype/src/psaux/psconv.h
@@ -4,7 +4,7 @@
/* */
/* Some convenience conversions (specification). */
/* */
-/* Copyright 2006 by */
+/* Copyright 2006, 2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -26,20 +26,20 @@
FT_BEGIN_HEADER
- FT_LOCAL( FT_Int )
+ FT_LOCAL( FT_Long )
PS_Conv_Strtol( FT_Byte** cursor,
FT_Byte* limit,
- FT_Int base );
+ FT_Long base );
- FT_LOCAL( FT_Int )
+ FT_LOCAL( FT_Long )
PS_Conv_ToInt( FT_Byte** cursor,
FT_Byte* limit );
FT_LOCAL( FT_Fixed )
PS_Conv_ToFixed( FT_Byte** cursor,
FT_Byte* limit,
- FT_Int power_ten );
+ FT_Long power_ten );
#if 0
FT_LOCAL( FT_UInt )
diff --git a/freetype/src/psaux/t1decode.c b/freetype/src/psaux/t1decode.c
index 1b4bc48a3..838c51df5 100644
--- a/freetype/src/psaux/t1decode.c
+++ b/freetype/src/psaux/t1decode.c
@@ -4,7 +4,7 @@
/* */
/* PostScript Type 1 decoding routines (body). */
/* */
-/* Copyright 2000-2011 by */
+/* Copyright 2000-2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -208,6 +208,12 @@
return PSaux_Err_Syntax_Error;
}
+ if ( decoder->builder.metrics_only )
+ {
+ FT_ERROR(( "t1operator_seac: unexpected seac\n" ));
+ return PSaux_Err_Syntax_Error;
+ }
+
/* seac weirdness */
adx += decoder->builder.left_bearing.x;
diff --git a/freetype/src/pshinter/pshglob.c b/freetype/src/pshinter/pshglob.c
index a34b2e508..b3e224203 100644
--- a/freetype/src/pshinter/pshglob.c
+++ b/freetype/src/pshinter/pshglob.c
@@ -5,7 +5,7 @@
/* PostScript hinter global hinting management (body). */
/* Inspired by the new auto-hinter module. */
/* */
-/* Copyright 2001, 2002, 2003, 2004, 2006, 2010 by */
+/* Copyright 2001-2004, 2006, 2010, 2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used */
@@ -522,6 +522,28 @@
}
+ /* calculate the maximum height of given blue zones */
+ static FT_Short
+ psh_calc_max_height( FT_UInt num,
+ const FT_Short* values,
+ FT_Short cur_max )
+ {
+ FT_UInt count;
+
+
+ for ( count = 0; count < num; count += 2 )
+ {
+ FT_Short cur_height = values[count + 1] - values[count];
+
+
+ if ( cur_height > cur_max )
+ cur_max = cur_height;
+ }
+
+ return cur_max;
+ }
+
+
FT_LOCAL_DEF( void )
psh_blues_snap_stem( PSH_Blues blues,
FT_Int stem_top,
@@ -684,7 +706,32 @@
priv->family_blues, priv->num_family_other_blues,
priv->family_other_blues, priv->blue_fuzz, 1 );
- globals->blues.blue_scale = priv->blue_scale;
+ /* limit the BlueScale value to `1 / max_of_blue_zone_heights' */
+ {
+ FT_Fixed max_scale;
+ FT_Short max_height = 1;
+
+
+ max_height = psh_calc_max_height( priv->num_blue_values,
+ priv->blue_values,
+ max_height );
+ max_height = psh_calc_max_height( priv->num_other_blues,
+ priv->other_blues,
+ max_height );
+ max_height = psh_calc_max_height( priv->num_family_blues,
+ priv->family_blues,
+ max_height );
+ max_height = psh_calc_max_height( priv->num_family_other_blues,
+ priv->family_other_blues,
+ max_height );
+
+ /* BlueScale is scaled 1000 times */
+ max_scale = FT_DivFix( 1000, max_height );
+ globals->blues.blue_scale = priv->blue_scale < max_scale
+ ? priv->blue_scale
+ : max_scale;
+ }
+
globals->blues.blue_shift = priv->blue_shift;
globals->blues.blue_fuzz = priv->blue_fuzz;
diff --git a/freetype/src/pshinter/pshmod.c b/freetype/src/pshinter/pshmod.c
index 911c495ab..762d4aa16 100644
--- a/freetype/src/pshinter/pshmod.c
+++ b/freetype/src/pshinter/pshmod.c
@@ -4,7 +4,7 @@
/* */
/* FreeType PostScript hinter module implementation (body). */
/* */
-/* Copyright 2001, 2002, 2007 by */
+/* Copyright 2001, 2002, 2007, 2009, 2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -93,14 +93,15 @@
}
- FT_DEFINE_PSHINTER_INTERFACE(pshinter_interface,
+ FT_DEFINE_PSHINTER_INTERFACE(
+ pshinter_interface,
pshinter_get_globals_funcs,
pshinter_get_t1_funcs,
- pshinter_get_t2_funcs
- )
+ pshinter_get_t2_funcs )
- FT_DEFINE_MODULE(pshinter_module_class,
+ FT_DEFINE_MODULE(
+ pshinter_module_class,
0,
sizeof ( PS_Hinter_ModuleRec ),
@@ -108,11 +109,11 @@
0x10000L,
0x20000L,
- &FTPSHINTER_INTERFACE_GET, /* module-specific interface */
+ &PSHINTER_INTERFACE_GET, /* module-specific interface */
(FT_Module_Constructor)ps_hinter_init,
(FT_Module_Destructor) ps_hinter_done,
- (FT_Module_Requester) 0 /* no additional interface for now */
- )
+ (FT_Module_Requester) NULL ) /* no additional interface for now */
+
/* END */
diff --git a/freetype/src/pshinter/pshpic.c b/freetype/src/pshinter/pshpic.c
index 0eaf7335f..626e93228 100644
--- a/freetype/src/pshinter/pshpic.c
+++ b/freetype/src/pshinter/pshpic.c
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for pshinter module. */
/* */
-/* Copyright 2009, 2010 by */
+/* Copyright 2009, 2010, 2012 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -22,6 +22,7 @@
#include "pshpic.h"
#include "pshnterr.h"
+
#ifdef FT_CONFIG_OPTION_PIC
/* forward declaration of PIC init functions from pshmod.c */
@@ -33,7 +34,7 @@
pshinter_module_class_pic_free( FT_Library library )
{
FT_PIC_Container* pic_container = &library->pic_container;
- FT_Memory memory = library->memory;
+ FT_Memory memory = library->memory;
if ( pic_container->pshinter )
@@ -49,7 +50,7 @@
{
FT_PIC_Container* pic_container = &library->pic_container;
FT_Error error = PSH_Err_Ok;
- PSHinterPIC* container;
+ PSHinterPIC* container = NULL;
FT_Memory memory = library->memory;
@@ -63,13 +64,12 @@
FT_Init_Class_pshinter_interface(
library, &container->pshinter_interface );
-/*Exit:*/
if( error )
pshinter_module_class_pic_free( library );
return error;
}
-
#endif /* FT_CONFIG_OPTION_PIC */
+
/* END */
diff --git a/freetype/src/pshinter/pshpic.h b/freetype/src/pshinter/pshpic.h
index e54899acd..4189a4fdc 100644
--- a/freetype/src/pshinter/pshpic.h
+++ b/freetype/src/pshinter/pshpic.h
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for pshinter module. */
/* */
-/* Copyright 2009 by */
+/* Copyright 2009, 2012 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -24,21 +24,25 @@ FT_BEGIN_HEADER
#include <freetype/internal/ftpic.h>
+
#ifndef FT_CONFIG_OPTION_PIC
-#define FTPSHINTER_INTERFACE_GET pshinter_interface
+#define PSHINTER_INTERFACE_GET pshinter_interface
#else /* FT_CONFIG_OPTION_PIC */
#include FT_INTERNAL_POSTSCRIPT_HINTS_H
- typedef struct PSHinterPIC_
+ typedef struct PSHinterPIC_
{
- PSHinter_Interface pshinter_interface;
+ PSHinter_Interface pshinter_interface;
+
} PSHinterPIC;
-#define GET_PIC(lib) ((PSHinterPIC*)((lib)->pic_container.autofit))
-#define FTPSHINTER_INTERFACE_GET (GET_PIC(library)->pshinter_interface)
+
+#define GET_PIC( lib ) ( (PSHinterPIC*)((lib)->pic_container.autofit) )
+
+#define PSHINTER_INTERFACE_GET ( GET_PIC( library )->pshinter_interface )
/* see pshpic.c for the implementation */
void
diff --git a/freetype/src/psnames/psmodule.c b/freetype/src/psnames/psmodule.c
index 47e538b26..0c4f54a67 100644
--- a/freetype/src/psnames/psmodule.c
+++ b/freetype/src/psnames/psmodule.c
@@ -4,7 +4,7 @@
/* */
/* PSNames module implementation (body). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007, 2008 by */
+/* Copyright 1996-2003, 2005-2008, 2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -521,7 +521,9 @@
#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
- FT_DEFINE_SERVICE_PSCMAPSREC(pscmaps_interface,
+
+ FT_DEFINE_SERVICE_PSCMAPSREC(
+ pscmaps_interface,
(PS_Unicode_ValueFunc) ps_unicode_value,
(PS_Unicodes_InitFunc) ps_unicodes_init,
(PS_Unicodes_CharIndexFunc)ps_unicodes_char_index,
@@ -531,39 +533,36 @@
(PS_Adobe_Std_StringsFunc) ps_get_standard_strings,
t1_standard_encoding,
- t1_expert_encoding
- )
+ t1_expert_encoding )
#else
- FT_DEFINE_SERVICE_PSCMAPSREC(pscmaps_interface,
- 0,
- 0,
- 0,
- 0,
+ FT_DEFINE_SERVICE_PSCMAPSREC(
+ pscmaps_interface,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
(PS_Macintosh_NameFunc) ps_get_macintosh_name,
(PS_Adobe_Std_StringsFunc) ps_get_standard_strings,
t1_standard_encoding,
- t1_expert_encoding
- )
+ t1_expert_encoding )
#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
- FT_DEFINE_SERVICEDESCREC1(pscmaps_services,
- FT_SERVICE_ID_POSTSCRIPT_CMAPS, &FT_PSCMAPS_INTERFACE_GET
- )
-
-
+ FT_DEFINE_SERVICEDESCREC1(
+ pscmaps_services,
+ FT_SERVICE_ID_POSTSCRIPT_CMAPS, &PSCMAPS_INTERFACE_GET )
static FT_Pointer
psnames_get_service( FT_Module module,
const char* service_id )
{
- /* FT_PSCMAPS_SERVICES_GET derefers `library' in PIC mode */
+ /* PSCMAPS_SERVICES_GET derefers `library' in PIC mode */
#ifdef FT_CONFIG_OPTION_PIC
FT_Library library;
@@ -577,19 +576,20 @@
FT_UNUSED( module );
#endif
- return ft_service_list_lookup( FT_PSCMAPS_SERVICES_GET, service_id );
+ return ft_service_list_lookup( PSCMAPS_SERVICES_GET, service_id );
}
#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
#ifndef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
-#define PUT_PS_NAMES_SERVICE(a) 0
+#define PUT_PS_NAMES_SERVICE( a ) NULL
#else
-#define PUT_PS_NAMES_SERVICE(a) a
+#define PUT_PS_NAMES_SERVICE( a ) a
#endif
- FT_DEFINE_MODULE(psnames_module_class,
+ FT_DEFINE_MODULE(
+ psnames_module_class,
0, /* this is not a font driver, nor a renderer */
sizeof ( FT_ModuleRec ),
@@ -598,12 +598,11 @@
0x10000L, /* driver version */
0x20000L, /* driver requires FreeType 2 or above */
- PUT_PS_NAMES_SERVICE((void*)&FT_PSCMAPS_INTERFACE_GET), /* module specific interface */
- (FT_Module_Constructor)0,
- (FT_Module_Destructor) 0,
- (FT_Module_Requester) PUT_PS_NAMES_SERVICE(psnames_get_service)
- )
-
+ PUT_PS_NAMES_SERVICE(
+ (void*)&PSCMAPS_INTERFACE_GET ), /* module specific interface */
+ (FT_Module_Constructor)NULL,
+ (FT_Module_Destructor) NULL,
+ (FT_Module_Requester) PUT_PS_NAMES_SERVICE( psnames_get_service ) )
/* END */
diff --git a/freetype/src/psnames/pspic.c b/freetype/src/psnames/pspic.c
index 061bcd784..fc3292174 100644
--- a/freetype/src/psnames/pspic.c
+++ b/freetype/src/psnames/pspic.c
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for psnames module. */
/* */
-/* Copyright 2009, 2010 by */
+/* Copyright 2009, 2010, 2012 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -22,6 +22,7 @@
#include "pspic.h"
#include "psnamerr.h"
+
#ifdef FT_CONFIG_OPTION_PIC
/* forward declaration of PIC init functions from psmodule.c */
@@ -36,11 +37,12 @@
FT_Init_Class_pscmaps_interface( FT_Library library,
FT_Service_PsCMapsRec* clazz );
+
void
psnames_module_class_pic_free( FT_Library library )
{
FT_PIC_Container* pic_container = &library->pic_container;
- FT_Memory memory = library->memory;
+ FT_Memory memory = library->memory;
if ( pic_container->psnames )
@@ -48,7 +50,7 @@
PSModulePIC* container = (PSModulePIC*)pic_container->psnames;
- if(container->pscmaps_services)
+ if ( container->pscmaps_services )
FT_Destroy_Class_pscmaps_services( library,
container->pscmaps_services );
container->pscmaps_services = NULL;
@@ -63,7 +65,7 @@
{
FT_PIC_Container* pic_container = &library->pic_container;
FT_Error error = PSnames_Err_Ok;
- PSModulePIC* container;
+ PSModulePIC* container = NULL;
FT_Memory memory = library->memory;
@@ -73,7 +75,8 @@
FT_MEM_SET( container, 0, sizeof ( *container ) );
pic_container->psnames = container;
- /* initialize pointer table - this is how the module usually expects this data */
+ /* initialize pointer table - */
+ /* this is how the module usually expects this data */
error = FT_Create_Class_pscmaps_services(
library, &container->pscmaps_services );
if ( error )
@@ -81,7 +84,7 @@
FT_Init_Class_pscmaps_interface( library,
&container->pscmaps_interface );
-Exit:
+ Exit:
if ( error )
psnames_module_class_pic_free( library );
return error;
diff --git a/freetype/src/psnames/pspic.h b/freetype/src/psnames/pspic.h
index 87d6fb162..3cbc93db1 100644
--- a/freetype/src/psnames/pspic.h
+++ b/freetype/src/psnames/pspic.h
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for psnames module. */
/* */
-/* Copyright 2009 by */
+/* Copyright 2009, 2012 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -25,22 +25,27 @@ FT_BEGIN_HEADER
#include <freetype/internal/ftpic.h>
#ifndef FT_CONFIG_OPTION_PIC
-#define FT_PSCMAPS_SERVICES_GET pscmaps_services
-#define FT_PSCMAPS_INTERFACE_GET pscmaps_interface
+
+#define PSCMAPS_SERVICES_GET pscmaps_services
+#define PSCMAPS_INTERFACE_GET pscmaps_interface
#else /* FT_CONFIG_OPTION_PIC */
#include FT_SERVICE_POSTSCRIPT_CMAPS_H
- typedef struct PSModulePIC_
+ typedef struct PSModulePIC_
{
- FT_ServiceDescRec* pscmaps_services;
- FT_Service_PsCMapsRec pscmaps_interface;
+ FT_ServiceDescRec* pscmaps_services;
+ FT_Service_PsCMapsRec pscmaps_interface;
+
} PSModulePIC;
-#define GET_PIC(lib) ((PSModulePIC*)((lib)->pic_container.psnames))
-#define FT_PSCMAPS_SERVICES_GET (GET_PIC(library)->pscmaps_services)
-#define FT_PSCMAPS_INTERFACE_GET (GET_PIC(library)->pscmaps_interface)
+
+#define GET_PIC( lib ) \
+ ( (PSModulePIC*)((lib)->pic_container.psnames) )
+#define PSCMAPS_SERVICES_GET ( GET_PIC( library )->pscmaps_services )
+#define PSCMAPS_INTERFACE_GET ( GET_PIC( library )->pscmaps_interface )
+
/* see pspic.c for the implementation */
void
diff --git a/freetype/src/raster/rastpic.c b/freetype/src/raster/rastpic.c
index 66a439606..daffaeb49 100644
--- a/freetype/src/raster/rastpic.c
+++ b/freetype/src/raster/rastpic.c
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for raster module. */
/* */
-/* Copyright 2009, 2010 by */
+/* Copyright 2009, 2010, 2012 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -51,7 +51,7 @@
{
FT_PIC_Container* pic_container = &library->pic_container;
FT_Error error = Raster_Err_Ok;
- RasterPIC* container;
+ RasterPIC* container = NULL;
FT_Memory memory = library->memory;
diff --git a/freetype/src/sfnt/sfdriver.c b/freetype/src/sfnt/sfdriver.c
index d2eeefac3..3cd766d38 100644
--- a/freetype/src/sfnt/sfdriver.c
+++ b/freetype/src/sfnt/sfdriver.c
@@ -4,7 +4,7 @@
/* */
/* High-level SFNT driver interface (body). */
/* */
-/* Copyright 1996-2007, 2009-2011 by */
+/* Copyright 1996-2007, 2009-2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -50,6 +50,7 @@
#include FT_SERVICE_SFNT_H
#include FT_SERVICE_TT_CMAP_H
+
/*************************************************************************/
/* */
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
@@ -60,10 +61,10 @@
#define FT_COMPONENT trace_sfdriver
- /*
- * SFNT TABLE SERVICE
- *
- */
+ /*
+ * SFNT TABLE SERVICE
+ *
+ */
static void*
get_sfnt_table( TT_Face face,
@@ -136,19 +137,19 @@
}
- FT_DEFINE_SERVICE_SFNT_TABLEREC(sfnt_service_sfnt_table,
+ FT_DEFINE_SERVICE_SFNT_TABLEREC(
+ sfnt_service_sfnt_table,
(FT_SFNT_TableLoadFunc)tt_face_load_any,
(FT_SFNT_TableGetFunc) get_sfnt_table,
- (FT_SFNT_TableInfoFunc)sfnt_table_info
- )
+ (FT_SFNT_TableInfoFunc)sfnt_table_info )
#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
- /*
- * GLYPH DICT SERVICE
- *
- */
+ /*
+ * GLYPH DICT SERVICE
+ *
+ */
static FT_Error
sfnt_get_glyph_name( TT_Face face,
@@ -172,17 +173,18 @@
sfnt_get_name_index( TT_Face face,
FT_String* glyph_name )
{
- FT_Face root = &face->root;
- FT_UInt i, max_gid = FT_UINT_MAX;
+ FT_Face root = &face->root;
+
+ FT_UInt i, max_gid = FT_UINT_MAX;
if ( root->num_glyphs < 0 )
return 0;
- else if ( ( FT_ULong ) root->num_glyphs < FT_UINT_MAX )
- max_gid = ( FT_UInt ) root->num_glyphs;
+ else if ( (FT_ULong)root->num_glyphs < FT_UINT_MAX )
+ max_gid = (FT_UInt)root->num_glyphs;
else
FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n",
- FT_UINT_MAX, root->num_glyphs ));
+ FT_UINT_MAX, root->num_glyphs ));
for ( i = 0; i < max_gid; i++ )
{
@@ -201,18 +203,19 @@
}
- FT_DEFINE_SERVICE_GLYPHDICTREC(sfnt_service_glyph_dict,
+ FT_DEFINE_SERVICE_GLYPHDICTREC(
+ sfnt_service_glyph_dict,
(FT_GlyphDict_GetNameFunc) sfnt_get_glyph_name,
- (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index
- )
+ (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index )
+
#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
- /*
- * POSTSCRIPT NAME SERVICE
- *
- */
+ /*
+ * POSTSCRIPT NAME SERVICE
+ *
+ */
static const char*
sfnt_get_ps_name( TT_Face face )
@@ -324,17 +327,18 @@
return result;
}
- FT_DEFINE_SERVICE_PSFONTNAMEREC(sfnt_service_ps_name,
- (FT_PsName_GetFunc)sfnt_get_ps_name
- )
+
+ FT_DEFINE_SERVICE_PSFONTNAMEREC(
+ sfnt_service_ps_name,
+ (FT_PsName_GetFunc)sfnt_get_ps_name )
/*
* TT CMAP INFO
*/
- FT_DEFINE_SERVICE_TTCMAPSREC(tt_service_get_cmap_info,
- (TT_CMap_Info_GetFunc)tt_get_cmap_info
- )
+ FT_DEFINE_SERVICE_TTCMAPSREC(
+ tt_service_get_cmap_info,
+ (TT_CMap_Info_GetFunc)tt_get_cmap_info )
#ifdef TT_CONFIG_OPTION_BDF
@@ -375,10 +379,11 @@
}
- FT_DEFINE_SERVICE_BDFRec(sfnt_service_bdf,
- (FT_BDF_GetCharsetIdFunc) sfnt_get_charset_id,
- (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop
- )
+ FT_DEFINE_SERVICE_BDFRec(
+ sfnt_service_bdf,
+ (FT_BDF_GetCharsetIdFunc)sfnt_get_charset_id,
+ (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop )
+
#endif /* TT_CONFIG_OPTION_BDF */
@@ -388,33 +393,33 @@
*/
#if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF
- FT_DEFINE_SERVICEDESCREC5(sfnt_services,
- FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET,
- FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
- FT_SERVICE_ID_GLYPH_DICT, &FT_SFNT_SERVICE_GLYPH_DICT_GET,
- FT_SERVICE_ID_BDF, &FT_SFNT_SERVICE_BDF_GET,
- FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET
- )
+ FT_DEFINE_SERVICEDESCREC5(
+ sfnt_services,
+ FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET,
+ FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET,
+ FT_SERVICE_ID_GLYPH_DICT, &SFNT_SERVICE_GLYPH_DICT_GET,
+ FT_SERVICE_ID_BDF, &SFNT_SERVICE_BDF_GET,
+ FT_SERVICE_ID_TT_CMAP, &TT_SERVICE_CMAP_INFO_GET )
#elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES
- FT_DEFINE_SERVICEDESCREC4(sfnt_services,
- FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET,
- FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
- FT_SERVICE_ID_GLYPH_DICT, &FT_SFNT_SERVICE_GLYPH_DICT_GET,
- FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET
- )
+ FT_DEFINE_SERVICEDESCREC4(
+ sfnt_services,
+ FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET,
+ FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET,
+ FT_SERVICE_ID_GLYPH_DICT, &SFNT_SERVICE_GLYPH_DICT_GET,
+ FT_SERVICE_ID_TT_CMAP, &TT_SERVICE_CMAP_INFO_GET )
#elif defined TT_CONFIG_OPTION_BDF
- FT_DEFINE_SERVICEDESCREC4(sfnt_services,
- FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET,
- FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
- FT_SERVICE_ID_BDF, &FT_SFNT_SERVICE_BDF_GET,
- FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET
- )
+ FT_DEFINE_SERVICEDESCREC4(
+ sfnt_services,
+ FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET,
+ FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET,
+ FT_SERVICE_ID_BDF, &SFNT_SERVICE_BDF_GET,
+ FT_SERVICE_ID_TT_CMAP, &TT_SERVICE_CMAP_INFO_GET )
#else
- FT_DEFINE_SERVICEDESCREC3(sfnt_services,
- FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET,
- FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
- FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET
- )
+ FT_DEFINE_SERVICEDESCREC3(
+ sfnt_services,
+ FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET,
+ FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET,
+ FT_SERVICE_ID_TT_CMAP, &TT_SERVICE_CMAP_INFO_GET )
#endif
@@ -422,7 +427,7 @@
sfnt_get_interface( FT_Module module,
const char* module_interface )
{
- /* FT_SFNT_SERVICES_GET derefers `library' in PIC mode */
+ /* SFNT_SERVICES_GET derefers `library' in PIC mode */
#ifdef FT_CONFIG_OPTION_PIC
FT_Library library;
@@ -435,7 +440,8 @@
#else
FT_UNUSED( module );
#endif
- return ft_service_list_lookup( FT_SFNT_SERVICES_GET, module_interface );
+
+ return ft_service_list_lookup( SFNT_SERVICES_GET, module_interface );
}
@@ -566,18 +572,21 @@
#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
+
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
-#define PUT_EMBEDDED_BITMAPS(a) a
+#define PUT_EMBEDDED_BITMAPS( a ) a
#else
-#define PUT_EMBEDDED_BITMAPS(a) 0
+#define PUT_EMBEDDED_BITMAPS( a ) NULL
#endif
+
#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
-#define PUT_PS_NAMES(a) a
+#define PUT_PS_NAMES( a ) a
#else
-#define PUT_PS_NAMES(a) 0
+#define PUT_PS_NAMES( a ) NULL
#endif
- FT_DEFINE_SFNT_INTERFACE(sfnt_interface,
+ FT_DEFINE_SFNT_INTERFACE(
+ sfnt_interface,
tt_face_goto_table,
sfnt_init_face,
@@ -588,7 +597,7 @@
tt_face_load_any,
tt_face_load_sfnt_header_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
- tt_face_load_directory_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
+ tt_face_load_directory_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
tt_face_load_head,
tt_face_load_hhea,
@@ -608,21 +617,21 @@
tt_face_load_pclt,
/* see `ttload.h' */
- PUT_EMBEDDED_BITMAPS(tt_face_load_bhed),
+ PUT_EMBEDDED_BITMAPS( tt_face_load_bhed ),
tt_face_set_sbit_strike_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
- tt_face_load_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
+ tt_face_load_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
- tt_find_sbit_image, /* FT_CONFIG_OPTION_OLD_INTERNALS */
+ tt_find_sbit_image, /* FT_CONFIG_OPTION_OLD_INTERNALS */
tt_load_sbit_metrics, /* FT_CONFIG_OPTION_OLD_INTERNALS */
- PUT_EMBEDDED_BITMAPS(tt_face_load_sbit_image),
+ PUT_EMBEDDED_BITMAPS( tt_face_load_sbit_image ),
tt_face_free_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
/* see `ttpost.h' */
- PUT_PS_NAMES(tt_face_get_ps_name),
- PUT_PS_NAMES(tt_face_free_ps_names),
+ PUT_PS_NAMES( tt_face_get_ps_name ),
+ PUT_PS_NAMES( tt_face_free_ps_names ),
tt_face_load_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
tt_face_free_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
@@ -637,17 +646,18 @@
tt_face_load_hmtx,
/* see `ttsbit.h' and `sfnt.h' */
- PUT_EMBEDDED_BITMAPS(tt_face_load_eblc),
- PUT_EMBEDDED_BITMAPS(tt_face_free_eblc),
+ PUT_EMBEDDED_BITMAPS( tt_face_load_eblc ),
+ PUT_EMBEDDED_BITMAPS( tt_face_free_eblc ),
- PUT_EMBEDDED_BITMAPS(tt_face_set_sbit_strike),
- PUT_EMBEDDED_BITMAPS(tt_face_load_strike_metrics),
+ PUT_EMBEDDED_BITMAPS( tt_face_set_sbit_strike ),
+ PUT_EMBEDDED_BITMAPS( tt_face_load_strike_metrics ),
tt_face_get_metrics
)
- FT_DEFINE_MODULE(sfnt_module_class,
+ FT_DEFINE_MODULE(
+ sfnt_module_class,
0, /* not a font driver or renderer */
sizeof ( FT_ModuleRec ),
@@ -656,12 +666,11 @@
0x10000L, /* driver version 1.0 */
0x20000L, /* driver requires FreeType 2.0 or higher */
- (const void*)&FT_SFNT_INTERFACE_GET, /* module specific interface */
+ (const void*)&SFNT_INTERFACE_GET, /* module specific interface */
(FT_Module_Constructor)0,
(FT_Module_Destructor) 0,
- (FT_Module_Requester) sfnt_get_interface
- )
+ (FT_Module_Requester) sfnt_get_interface )
/* END */
diff --git a/freetype/src/sfnt/sfntpic.c b/freetype/src/sfnt/sfntpic.c
index 1ddd7f0ba..4a6ed9740 100644
--- a/freetype/src/sfnt/sfntpic.c
+++ b/freetype/src/sfnt/sfntpic.c
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for sfnt module. */
/* */
-/* Copyright 2009, 2010 by */
+/* Copyright 2009, 2010, 2012 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -22,12 +22,13 @@
#include "sfntpic.h"
#include "sferrors.h"
+
#ifdef FT_CONFIG_OPTION_PIC
/* forward declaration of PIC init functions from sfdriver.c */
FT_Error
FT_Create_Class_sfnt_services( FT_Library library,
- FT_ServiceDescRec** ouput_class );
+ FT_ServiceDescRec** output_class );
void
FT_Destroy_Class_sfnt_services( FT_Library library,
@@ -68,11 +69,12 @@
FT_Destroy_Class_tt_cmap_classes( FT_Library library,
TT_CMap_Class* clazz );
+
void
sfnt_module_class_pic_free( FT_Library library )
{
FT_PIC_Container* pic_container = &library->pic_container;
- FT_Memory memory = library->memory;
+ FT_Memory memory = library->memory;
if ( pic_container->sfnt )
@@ -84,10 +86,12 @@
FT_Destroy_Class_sfnt_services( library,
container->sfnt_services );
container->sfnt_services = NULL;
+
if ( container->tt_cmap_classes )
FT_Destroy_Class_tt_cmap_classes( library,
container->tt_cmap_classes );
container->tt_cmap_classes = NULL;
+
FT_FREE( container );
pic_container->sfnt = NULL;
}
@@ -95,12 +99,12 @@
FT_Error
- sfnt_module_class_pic_init( FT_Library library )
+ sfnt_module_class_pic_init( FT_Library library )
{
FT_PIC_Container* pic_container = &library->pic_container;
- FT_Error error = SFNT_Err_Ok;
- sfntModulePIC* container;
- FT_Memory memory = library->memory;
+ FT_Error error = SFNT_Err_Ok;
+ sfntModulePIC* container = NULL;
+ FT_Memory memory = library->memory;
/* allocate pointer, clear and set global container pointer */
@@ -109,11 +113,13 @@
FT_MEM_SET( container, 0, sizeof ( *container ) );
pic_container->sfnt = container;
- /* initialize pointer table - this is how the module usually expects this data */
+ /* initialize pointer table - */
+ /* this is how the module usually expects this data */
error = FT_Create_Class_sfnt_services( library,
&container->sfnt_services );
if ( error )
goto Exit;
+
error = FT_Create_Class_tt_cmap_classes( library,
&container->tt_cmap_classes );
if ( error )
@@ -132,14 +138,12 @@
#endif
FT_Init_Class_sfnt_interface( library, &container->sfnt_interface );
-Exit:
+ Exit:
if ( error )
sfnt_module_class_pic_free( library );
return error;
}
-
-
#endif /* FT_CONFIG_OPTION_PIC */
diff --git a/freetype/src/sfnt/sfntpic.h b/freetype/src/sfnt/sfntpic.h
index e67cfe60b..e107b924b 100644..100755
--- a/freetype/src/sfnt/sfntpic.h
+++ b/freetype/src/sfnt/sfntpic.h
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for sfnt module. */
/* */
-/* Copyright 2009 by */
+/* Copyright 2009, 2012 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -24,57 +24,76 @@ FT_BEGIN_HEADER
#include <freetype/internal/ftpic.h>
- #ifndef FT_CONFIG_OPTION_PIC
-#define FT_SFNT_SERVICES_GET sfnt_services
-#define FT_SFNT_SERVICE_GLYPH_DICT_GET sfnt_service_glyph_dict
-#define FT_SFNT_SERVICE_PS_NAME_GET sfnt_service_ps_name
-#define FT_TT_SERVICE_GET_CMAP_INFO_GET tt_service_get_cmap_info
-#define FT_SFNT_SERVICES_GET sfnt_services
-#define FT_TT_CMAP_CLASSES_GET tt_cmap_classes
-#define FT_SFNT_SERVICE_SFNT_TABLE_GET sfnt_service_sfnt_table
-#define FT_SFNT_SERVICE_BDF_GET sfnt_service_bdf
-#define FT_SFNT_INTERFACE_GET sfnt_interface
+
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define SFNT_SERVICES_GET sfnt_services
+#define SFNT_SERVICE_GLYPH_DICT_GET sfnt_service_glyph_dict
+#define SFNT_SERVICE_PS_NAME_GET sfnt_service_ps_name
+#define TT_SERVICE_CMAP_INFO_GET tt_service_get_cmap_info
+#define SFNT_SERVICES_GET sfnt_services
+#define TT_CMAP_CLASSES_GET tt_cmap_classes
+#define SFNT_SERVICE_SFNT_TABLE_GET sfnt_service_sfnt_table
+#define SFNT_SERVICE_BDF_GET sfnt_service_bdf
+#define SFNT_INTERFACE_GET sfnt_interface
#else /* FT_CONFIG_OPTION_PIC */
-/* some include files required for members of sfntModulePIC */
+ /* some include files required for members of sfntModulePIC */
#include FT_SERVICE_GLYPH_DICT_H
#include FT_SERVICE_POSTSCRIPT_NAME_H
#include FT_SERVICE_SFNT_H
#include FT_SERVICE_TT_CMAP_H
+
#ifdef TT_CONFIG_OPTION_BDF
#include "ttbdf.h"
#include FT_SERVICE_BDF_H
#endif
+
#include <freetype/internal/ftdebug.h>
#include <freetype/internal/ftstream.h>
#include FT_INTERNAL_SFNT_H
#include "ttcmap.h"
-typedef struct sfntModulePIC_
+
+ typedef struct sfntModulePIC_
{
- FT_ServiceDescRec* sfnt_services;
- FT_Service_GlyphDictRec sfnt_service_glyph_dict;
+ FT_ServiceDescRec* sfnt_services;
+ FT_Service_GlyphDictRec sfnt_service_glyph_dict;
FT_Service_PsFontNameRec sfnt_service_ps_name;
- FT_Service_TTCMapsRec tt_service_get_cmap_info;
- TT_CMap_Class* tt_cmap_classes;
- FT_Service_SFNT_TableRec sfnt_service_sfnt_table;
+ FT_Service_TTCMapsRec tt_service_get_cmap_info;
+ TT_CMap_Class* tt_cmap_classes;
+ FT_Service_SFNT_TableRec sfnt_service_sfnt_table;
#ifdef TT_CONFIG_OPTION_BDF
- FT_Service_BDFRec sfnt_service_bdf;
+ FT_Service_BDFRec sfnt_service_bdf;
#endif
- SFNT_Interface sfnt_interface;
+ SFNT_Interface sfnt_interface;
+
} sfntModulePIC;
-#define GET_PIC(lib) ((sfntModulePIC*)((lib)->pic_container.sfnt))
-#define FT_SFNT_SERVICES_GET (GET_PIC(library)->sfnt_services)
-#define FT_SFNT_SERVICE_GLYPH_DICT_GET (GET_PIC(library)->sfnt_service_glyph_dict)
-#define FT_SFNT_SERVICE_PS_NAME_GET (GET_PIC(library)->sfnt_service_ps_name)
-#define FT_TT_SERVICE_GET_CMAP_INFO_GET (GET_PIC(library)->tt_service_get_cmap_info)
-#define FT_SFNT_SERVICES_GET (GET_PIC(library)->sfnt_services)
-#define FT_TT_CMAP_CLASSES_GET (GET_PIC(library)->tt_cmap_classes)
-#define FT_SFNT_SERVICE_SFNT_TABLE_GET (GET_PIC(library)->sfnt_service_sfnt_table)
-#define FT_SFNT_SERVICE_BDF_GET (GET_PIC(library)->sfnt_service_bdf)
-#define FT_SFNT_INTERFACE_GET (GET_PIC(library)->sfnt_interface)
+
+#define GET_PIC( lib ) \
+ ( (sfntModulePIC*)((lib)->pic_container.sfnt) )
+
+#define SFNT_SERVICES_GET \
+ ( GET_PIC( library )->sfnt_services )
+#define SFNT_SERVICE_GLYPH_DICT_GET \
+ ( GET_PIC( library )->sfnt_service_glyph_dict )
+#define SFNT_SERVICE_PS_NAME_GET \
+ ( GET_PIC( library )->sfnt_service_ps_name )
+#define TT_SERVICE_CMAP_INFO_GET \
+ ( GET_PIC( library )->tt_service_get_cmap_info )
+#define SFNT_SERVICES_GET \
+ ( GET_PIC( library )->sfnt_services )
+#define TT_CMAP_CLASSES_GET \
+ ( GET_PIC( library )->tt_cmap_classes )
+#define SFNT_SERVICE_SFNT_TABLE_GET \
+ ( GET_PIC( library )->sfnt_service_sfnt_table )
+#define SFNT_SERVICE_BDF_GET \
+ ( GET_PIC( library )->sfnt_service_bdf )
+#define SFNT_INTERFACE_GET \
+ ( GET_PIC( library )->sfnt_interface )
+
/* see sfntpic.c for the implementation */
void
@@ -85,7 +104,7 @@ typedef struct sfntModulePIC_
#endif /* FT_CONFIG_OPTION_PIC */
-/* */
+ /* */
FT_END_HEADER
diff --git a/freetype/src/sfnt/sfobjs.c b/freetype/src/sfnt/sfobjs.c
index 64bf75744..8963732a8 100644
--- a/freetype/src/sfnt/sfobjs.c
+++ b/freetype/src/sfnt/sfobjs.c
@@ -508,7 +508,7 @@
FT_TRACE2(( "`" #x "' " )); \
FT_TRACE3(( "-->\n" )); \
\
- error = sfnt->load_##x( face, stream ); \
+ error = sfnt->load_ ## x( face, stream ); \
\
FT_TRACE2(( "%s\n", ( !error ) \
? "loaded" \
@@ -524,7 +524,7 @@
vertical ? "vertical " : "" )); \
FT_TRACE3(( "-->\n" )); \
\
- error = sfnt->load_##x( face, stream, vertical ); \
+ error = sfnt->load_ ## x( face, stream, vertical ); \
\
FT_TRACE2(( "%s\n", ( !error ) \
? "loaded" \
@@ -534,11 +534,11 @@
FT_TRACE3(( "\n" )); \
} while ( 0 )
-#define GET_NAME( id, field ) \
- do { \
- error = tt_face_get_name( face, TT_NAME_ID_##id, field ); \
- if ( error ) \
- goto Exit; \
+#define GET_NAME( id, field ) \
+ do { \
+ error = tt_face_get_name( face, TT_NAME_ID_ ## id, field ); \
+ if ( error ) \
+ goto Exit; \
} while ( 0 )
@@ -555,13 +555,14 @@
#endif
FT_Bool has_outline;
FT_Bool is_apple_sbit;
- FT_Bool ignore_preferred_family = FALSE;
+ FT_Bool ignore_preferred_family = FALSE;
FT_Bool ignore_preferred_subfamily = FALSE;
SFNT_Service sfnt = (SFNT_Service)face->sfnt;
FT_UNUSED( face_index );
+
/* Check parameters */
{
@@ -667,7 +668,7 @@
get_glyph_metrics )
{
face->horizontal.number_Of_HMetrics = 0;
- error = SFNT_Err_Ok;
+ error = SFNT_Err_Ok;
}
#endif
}
@@ -694,7 +695,7 @@
get_glyph_metrics )
{
face->horizontal.number_Of_HMetrics = 0;
- error = SFNT_Err_Ok;
+ error = SFNT_Err_Ok;
}
#endif
diff --git a/freetype/src/sfnt/ttcmap.c b/freetype/src/sfnt/ttcmap.c
index c8d4818a9..07cf12550 100644
--- a/freetype/src/sfnt/ttcmap.c
+++ b/freetype/src/sfnt/ttcmap.c
@@ -4,7 +4,7 @@
/* */
/* TrueType character mapping table (cmap) support (body). */
/* */
-/* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 by */
+/* Copyright 2002-2010, 2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -165,20 +165,24 @@
}
- FT_DEFINE_TT_CMAP(tt_cmap0_class_rec,
- sizeof ( TT_CMapRec ),
+ FT_DEFINE_TT_CMAP(
+ tt_cmap0_class_rec,
+ sizeof ( TT_CMapRec ),
- (FT_CMap_InitFunc) tt_cmap_init,
- (FT_CMap_DoneFunc) NULL,
- (FT_CMap_CharIndexFunc)tt_cmap0_char_index,
- (FT_CMap_CharNextFunc) tt_cmap0_char_next,
+ (FT_CMap_InitFunc) tt_cmap_init,
+ (FT_CMap_DoneFunc) NULL,
+ (FT_CMap_CharIndexFunc)tt_cmap0_char_index,
+ (FT_CMap_CharNextFunc) tt_cmap0_char_next,
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
- NULL, NULL, NULL, NULL, NULL
- ,
0,
- (TT_CMap_ValidateFunc) tt_cmap0_validate,
- (TT_CMap_Info_GetFunc) tt_cmap0_get_info
- )
+ (TT_CMap_ValidateFunc)tt_cmap0_validate,
+ (TT_CMap_Info_GetFunc)tt_cmap0_get_info )
#endif /* TT_CONFIG_CMAP_FORMAT_0 */
@@ -541,20 +545,24 @@
}
- FT_DEFINE_TT_CMAP(tt_cmap2_class_rec,
- sizeof ( TT_CMapRec ),
+ FT_DEFINE_TT_CMAP(
+ tt_cmap2_class_rec,
+ sizeof ( TT_CMapRec ),
- (FT_CMap_InitFunc) tt_cmap_init,
- (FT_CMap_DoneFunc) NULL,
- (FT_CMap_CharIndexFunc)tt_cmap2_char_index,
- (FT_CMap_CharNextFunc) tt_cmap2_char_next,
+ (FT_CMap_InitFunc) tt_cmap_init,
+ (FT_CMap_DoneFunc) NULL,
+ (FT_CMap_CharIndexFunc)tt_cmap2_char_index,
+ (FT_CMap_CharNextFunc) tt_cmap2_char_next,
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
- NULL, NULL, NULL, NULL, NULL
- ,
2,
- (TT_CMap_ValidateFunc) tt_cmap2_validate,
- (TT_CMap_Info_GetFunc) tt_cmap2_get_info
- )
+ (TT_CMap_ValidateFunc)tt_cmap2_validate,
+ (TT_CMap_Info_GetFunc)tt_cmap2_get_info )
#endif /* TT_CONFIG_CMAP_FORMAT_2 */
@@ -1377,19 +1385,23 @@
}
- FT_DEFINE_TT_CMAP(tt_cmap4_class_rec,
- sizeof ( TT_CMap4Rec ),
- (FT_CMap_InitFunc) tt_cmap4_init,
- (FT_CMap_DoneFunc) NULL,
- (FT_CMap_CharIndexFunc)tt_cmap4_char_index,
- (FT_CMap_CharNextFunc) tt_cmap4_char_next,
+ FT_DEFINE_TT_CMAP(
+ tt_cmap4_class_rec,
+ sizeof ( TT_CMap4Rec ),
+ (FT_CMap_InitFunc) tt_cmap4_init,
+ (FT_CMap_DoneFunc) NULL,
+ (FT_CMap_CharIndexFunc)tt_cmap4_char_index,
+ (FT_CMap_CharNextFunc) tt_cmap4_char_next,
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
- NULL, NULL, NULL, NULL, NULL
- ,
4,
- (TT_CMap_ValidateFunc) tt_cmap4_validate,
- (TT_CMap_Info_GetFunc) tt_cmap4_get_info
- )
+ (TT_CMap_ValidateFunc)tt_cmap4_validate,
+ (TT_CMap_Info_GetFunc)tt_cmap4_get_info )
#endif /* TT_CONFIG_CMAP_FORMAT_4 */
@@ -1536,20 +1548,24 @@
}
- FT_DEFINE_TT_CMAP(tt_cmap6_class_rec,
- sizeof ( TT_CMapRec ),
+ FT_DEFINE_TT_CMAP(
+ tt_cmap6_class_rec,
+ sizeof ( TT_CMapRec ),
- (FT_CMap_InitFunc) tt_cmap_init,
- (FT_CMap_DoneFunc) NULL,
- (FT_CMap_CharIndexFunc)tt_cmap6_char_index,
- (FT_CMap_CharNextFunc) tt_cmap6_char_next,
+ (FT_CMap_InitFunc) tt_cmap_init,
+ (FT_CMap_DoneFunc) NULL,
+ (FT_CMap_CharIndexFunc)tt_cmap6_char_index,
+ (FT_CMap_CharNextFunc) tt_cmap6_char_next,
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
- NULL, NULL, NULL, NULL, NULL
- ,
6,
- (TT_CMap_ValidateFunc) tt_cmap6_validate,
- (TT_CMap_Info_GetFunc) tt_cmap6_get_info
- )
+ (TT_CMap_ValidateFunc)tt_cmap6_validate,
+ (TT_CMap_Info_GetFunc)tt_cmap6_get_info )
#endif /* TT_CONFIG_CMAP_FORMAT_6 */
@@ -1789,20 +1805,24 @@
}
- FT_DEFINE_TT_CMAP(tt_cmap8_class_rec,
- sizeof ( TT_CMapRec ),
+ FT_DEFINE_TT_CMAP(
+ tt_cmap8_class_rec,
+ sizeof ( TT_CMapRec ),
- (FT_CMap_InitFunc) tt_cmap_init,
- (FT_CMap_DoneFunc) NULL,
- (FT_CMap_CharIndexFunc)tt_cmap8_char_index,
- (FT_CMap_CharNextFunc) tt_cmap8_char_next,
+ (FT_CMap_InitFunc) tt_cmap_init,
+ (FT_CMap_DoneFunc) NULL,
+ (FT_CMap_CharIndexFunc)tt_cmap8_char_index,
+ (FT_CMap_CharNextFunc) tt_cmap8_char_next,
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
- NULL, NULL, NULL, NULL, NULL
- ,
8,
- (TT_CMap_ValidateFunc) tt_cmap8_validate,
- (TT_CMap_Info_GetFunc) tt_cmap8_get_info
- )
+ (TT_CMap_ValidateFunc)tt_cmap8_validate,
+ (TT_CMap_Info_GetFunc)tt_cmap8_get_info )
#endif /* TT_CONFIG_CMAP_FORMAT_8 */
@@ -1938,20 +1958,24 @@
}
- FT_DEFINE_TT_CMAP(tt_cmap10_class_rec,
- sizeof ( TT_CMapRec ),
+ FT_DEFINE_TT_CMAP(
+ tt_cmap10_class_rec,
+ sizeof ( TT_CMapRec ),
+
+ (FT_CMap_InitFunc) tt_cmap_init,
+ (FT_CMap_DoneFunc) NULL,
+ (FT_CMap_CharIndexFunc)tt_cmap10_char_index,
+ (FT_CMap_CharNextFunc) tt_cmap10_char_next,
- (FT_CMap_InitFunc) tt_cmap_init,
- (FT_CMap_DoneFunc) NULL,
- (FT_CMap_CharIndexFunc)tt_cmap10_char_index,
- (FT_CMap_CharNextFunc) tt_cmap10_char_next,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
- NULL, NULL, NULL, NULL, NULL
- ,
10,
- (TT_CMap_ValidateFunc) tt_cmap10_validate,
- (TT_CMap_Info_GetFunc) tt_cmap10_get_info
- )
+ (TT_CMap_ValidateFunc)tt_cmap10_validate,
+ (TT_CMap_Info_GetFunc)tt_cmap10_get_info )
#endif /* TT_CONFIG_CMAP_FORMAT_10 */
@@ -2258,20 +2282,24 @@
}
- FT_DEFINE_TT_CMAP(tt_cmap12_class_rec,
- sizeof ( TT_CMap12Rec ),
+ FT_DEFINE_TT_CMAP(
+ tt_cmap12_class_rec,
+ sizeof ( TT_CMap12Rec ),
+
+ (FT_CMap_InitFunc) tt_cmap12_init,
+ (FT_CMap_DoneFunc) NULL,
+ (FT_CMap_CharIndexFunc)tt_cmap12_char_index,
+ (FT_CMap_CharNextFunc) tt_cmap12_char_next,
- (FT_CMap_InitFunc) tt_cmap12_init,
- (FT_CMap_DoneFunc) NULL,
- (FT_CMap_CharIndexFunc)tt_cmap12_char_index,
- (FT_CMap_CharNextFunc) tt_cmap12_char_next,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
- NULL, NULL, NULL, NULL, NULL
- ,
12,
- (TT_CMap_ValidateFunc) tt_cmap12_validate,
- (TT_CMap_Info_GetFunc) tt_cmap12_get_info
- )
+ (TT_CMap_ValidateFunc)tt_cmap12_validate,
+ (TT_CMap_Info_GetFunc)tt_cmap12_get_info )
#endif /* TT_CONFIG_CMAP_FORMAT_12 */
@@ -2338,9 +2366,9 @@
tt_cmap13_validate( FT_Byte* table,
FT_Validator valid )
{
- FT_Byte* p;
- FT_ULong length;
- FT_ULong num_groups;
+ FT_Byte* p;
+ FT_ULong length;
+ FT_ULong num_groups;
if ( table + 16 > valid->limit )
@@ -2490,7 +2518,6 @@
/* if `char_code' is not in any group, then `mid' is */
/* the group nearest to `char_code' */
- /* */
if ( char_code > end )
{
@@ -2574,20 +2601,24 @@
}
- FT_DEFINE_TT_CMAP(tt_cmap13_class_rec,
- sizeof ( TT_CMap13Rec ),
+ FT_DEFINE_TT_CMAP(
+ tt_cmap13_class_rec,
+ sizeof ( TT_CMap13Rec ),
- (FT_CMap_InitFunc) tt_cmap13_init,
- (FT_CMap_DoneFunc) NULL,
- (FT_CMap_CharIndexFunc)tt_cmap13_char_index,
- (FT_CMap_CharNextFunc) tt_cmap13_char_next,
+ (FT_CMap_InitFunc) tt_cmap13_init,
+ (FT_CMap_DoneFunc) NULL,
+ (FT_CMap_CharIndexFunc)tt_cmap13_char_index,
+ (FT_CMap_CharNextFunc) tt_cmap13_char_next,
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
- NULL, NULL, NULL, NULL, NULL
- ,
13,
- (TT_CMap_ValidateFunc) tt_cmap13_validate,
- (TT_CMap_Info_GetFunc) tt_cmap13_get_info
- )
+ (TT_CMap_ValidateFunc)tt_cmap13_validate,
+ (TT_CMap_Info_GetFunc)tt_cmap13_get_info )
#endif /* TT_CONFIG_CMAP_FORMAT_13 */
@@ -2688,8 +2719,8 @@
FT_UInt32 num_results,
FT_Memory memory )
{
- FT_UInt32 old_max = cmap->max_results;
- FT_Error error = SFNT_Err_Ok;
+ FT_UInt32 old_max = cmap->max_results;
+ FT_Error error = SFNT_Err_Ok;
if ( num_results > cmap->max_results )
@@ -2713,9 +2744,9 @@
cmap->cmap.data = table;
table += 6;
- cmap->num_selectors = FT_PEEK_ULONG( table );
- cmap->max_results = 0;
- cmap->results = NULL;
+ cmap->num_selectors = FT_PEEK_ULONG( table );
+ cmap->max_results = 0;
+ cmap->results = NULL;
return SFNT_Err_Ok;
}
@@ -2791,7 +2822,7 @@
{
FT_Byte* ndp = table + nondefOff;
FT_ULong numMappings = TT_NEXT_ULONG( ndp );
- FT_ULong i, lastUni = 0;
+ FT_ULong i, lastUni = 0;
if ( numMappings * 4 > (FT_ULong)( valid->limit - ndp ) )
@@ -2965,7 +2996,7 @@
tt_cmap14_char_var_index( TT_CMap cmap,
TT_CMap ucmap,
FT_UInt32 charcode,
- FT_UInt32 variantSelector)
+ FT_UInt32 variantSelector )
{
FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );
FT_ULong defOff;
@@ -3106,9 +3137,9 @@
static FT_UInt32*
- tt_cmap14_get_def_chars( TT_CMap cmap,
- FT_Byte* p,
- FT_Memory memory )
+ tt_cmap14_get_def_chars( TT_CMap cmap,
+ FT_Byte* p,
+ FT_Memory memory )
{
TT_CMap14 cmap14 = (TT_CMap14) cmap;
FT_UInt32 numRanges;
@@ -3124,7 +3155,7 @@
for ( q = cmap14->results; numRanges > 0; --numRanges )
{
- FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p );
+ FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p );
cnt = FT_NEXT_BYTE( p ) + 1;
@@ -3133,6 +3164,7 @@
q[0] = uni;
uni += 1;
q += 1;
+
} while ( --cnt != 0 );
}
q[0] = 0;
@@ -3306,25 +3338,25 @@
}
- FT_DEFINE_TT_CMAP(tt_cmap14_class_rec,
- sizeof ( TT_CMap14Rec ),
+ FT_DEFINE_TT_CMAP(
+ tt_cmap14_class_rec,
+ sizeof ( TT_CMap14Rec ),
- (FT_CMap_InitFunc) tt_cmap14_init,
- (FT_CMap_DoneFunc) tt_cmap14_done,
- (FT_CMap_CharIndexFunc)tt_cmap14_char_index,
- (FT_CMap_CharNextFunc) tt_cmap14_char_next,
+ (FT_CMap_InitFunc) tt_cmap14_init,
+ (FT_CMap_DoneFunc) tt_cmap14_done,
+ (FT_CMap_CharIndexFunc)tt_cmap14_char_index,
+ (FT_CMap_CharNextFunc) tt_cmap14_char_next,
+
+ /* Format 14 extension functions */
+ (FT_CMap_CharVarIndexFunc) tt_cmap14_char_var_index,
+ (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault,
+ (FT_CMap_VariantListFunc) tt_cmap14_variants,
+ (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants,
+ (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars,
- /* Format 14 extension functions */
- (FT_CMap_CharVarIndexFunc) tt_cmap14_char_var_index,
- (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault,
- (FT_CMap_VariantListFunc) tt_cmap14_variants,
- (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants,
- (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars
- ,
14,
(TT_CMap_ValidateFunc)tt_cmap14_validate,
- (TT_CMap_Info_GetFunc)tt_cmap14_get_info
- )
+ (TT_CMap_Info_GetFunc)tt_cmap14_get_info )
#endif /* TT_CONFIG_CMAP_FORMAT_14 */
@@ -3333,43 +3365,55 @@
static const TT_CMap_Class tt_cmap_classes[] =
{
-#define TTCMAPCITEM(a) &a,
+#define TTCMAPCITEM( a ) &a,
#include "ttcmapc.h"
NULL,
};
#else /*FT_CONFIG_OPTION_PIC*/
- void FT_Destroy_Class_tt_cmap_classes(FT_Library library, TT_CMap_Class* clazz)
+ void
+ FT_Destroy_Class_tt_cmap_classes( FT_Library library,
+ TT_CMap_Class* clazz )
{
- FT_Memory memory = library->memory;
+ FT_Memory memory = library->memory;
+
+
if ( clazz )
FT_FREE( clazz );
}
- FT_Error FT_Create_Class_tt_cmap_classes(FT_Library library, TT_CMap_Class** output_class)
+
+ FT_Error
+ FT_Create_Class_tt_cmap_classes( FT_Library library,
+ TT_CMap_Class** output_class )
{
- TT_CMap_Class* clazz;
- TT_CMap_ClassRec* recs;
- FT_Error error;
- FT_Memory memory = library->memory;
- int i = 0;
+ TT_CMap_Class* clazz = NULL;
+ TT_CMap_ClassRec* recs;
+ FT_Error error;
+ FT_Memory memory = library->memory;
-#define TTCMAPCITEM(a) i++;
+ int i = 0;
+
+
+#define TTCMAPCITEM( a ) i++;
#include "ttcmapc.h"
- /* allocate enough space for both the pointers +terminator and the class instances */
- if ( FT_ALLOC( clazz, sizeof(*clazz)*(i+1)+sizeof(TT_CMap_ClassRec)*i ) )
+ /* allocate enough space for both the pointers */
+ /* plus terminator and the class instances */
+ if ( FT_ALLOC( clazz, sizeof ( *clazz ) * ( i + 1 ) +
+ sizeof ( TT_CMap_ClassRec ) * i ) )
return error;
/* the location of the class instances follows the array of pointers */
- recs = (TT_CMap_ClassRec*) (((char*)clazz)+(sizeof(*clazz)*(i+1)));
- i=0;
+ recs = (TT_CMap_ClassRec*)( (char*)clazz +
+ sizeof ( *clazz ) * ( i + 1 ) );
+ i = 0;
#undef TTCMAPCITEM
-#define TTCMAPCITEM(a) \
- FT_Init_Class_##a(&recs[i]); \
- clazz[i] = &recs[i]; \
+#define TTCMAPCITEM( a ) \
+ FT_Init_Class_ ## a( &recs[i] ); \
+ clazz[i] = &recs[i]; \
i++;
#include "ttcmapc.h"
@@ -3411,10 +3455,12 @@
}
num_cmaps = TT_NEXT_USHORT( p );
+
#ifdef FT_MAX_CHARMAP_CACHEABLE
if ( num_cmaps > FT_MAX_CHARMAP_CACHEABLE )
- FT_ERROR(( "tt_face_build_cmaps: too many cmap subtables(%d) "
- "subtable#%d and later are loaded but cannot be searched\n",
+ FT_ERROR(( "tt_face_build_cmaps: too many cmap subtables (%d)\n"
+ " subtable #%d and higher are loaded"
+ " but cannot be searched\n",
num_cmaps, FT_MAX_CHARMAP_CACHEABLE + 1 ));
#endif
@@ -3434,7 +3480,7 @@
{
FT_Byte* volatile cmap = table + offset;
volatile FT_UInt format = TT_PEEK_USHORT( cmap );
- const TT_CMap_Class* volatile pclazz = FT_TT_CMAP_CLASSES_GET;
+ const TT_CMap_Class* volatile pclazz = TT_CMAP_CLASSES_GET;
TT_CMap_Class volatile clazz;
@@ -3452,8 +3498,7 @@
valid.num_glyphs = (FT_UInt)face->max_profile.numGlyphs;
- if ( ft_setjmp(
- *((ft_jmp_buf*)&FT_VALIDATOR( &valid )->jump_buffer) ) == 0 )
+ if ( ft_setjmp( FT_VALIDATOR( &valid )->jump_buffer) == 0 )
{
/* validate this cmap sub-table */
error = clazz->validate( cmap, FT_VALIDATOR( &valid ) );
@@ -3464,9 +3509,9 @@
FT_CMap ttcmap;
- /* It might make sense to store the single variation selector */
- /* cmap somewhere special. But it would have to be in the */
- /* public FT_FaceRec, and we can't change that. */
+ /* It might make sense to store the single variation */
+ /* selector cmap somewhere special. But it would have to be */
+ /* in the public FT_FaceRec, and we can't change that. */
if ( !FT_CMap_New( (FT_CMap_Class)clazz,
cmap, &charmap, &ttcmap ) )
diff --git a/freetype/src/sfnt/ttcmap.h b/freetype/src/sfnt/ttcmap.h
index 0f7c7d18f..87aadc31c 100644
--- a/freetype/src/sfnt/ttcmap.h
+++ b/freetype/src/sfnt/ttcmap.h
@@ -4,7 +4,7 @@
/* */
/* TrueType character mapping table (cmap) support (specification). */
/* */
-/* Copyright 2002, 2003, 2004, 2005 by */
+/* Copyright 2002-2005, 2009, 2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -55,47 +55,80 @@ FT_BEGIN_HEADER
} TT_CMap_ClassRec;
+
#ifndef FT_CONFIG_OPTION_PIC
-#define FT_DEFINE_TT_CMAP(class_, size_, init_, done_, char_index_, \
- char_next_, char_var_index_, char_var_default_, variant_list_, \
- charvariant_list_,variantchar_list_, \
- format_, validate_, get_cmap_info_) \
- FT_CALLBACK_TABLE_DEF \
- const TT_CMap_ClassRec class_ = \
- { \
- {size_, init_, done_, char_index_, \
- char_next_, char_var_index_, char_var_default_, variant_list_, \
- charvariant_list_, variantchar_list_}, \
- format_, validate_, get_cmap_info_ \
+#define FT_DEFINE_TT_CMAP( class_, \
+ size_, \
+ init_, \
+ done_, \
+ char_index_, \
+ char_next_, \
+ char_var_index_, \
+ char_var_default_, \
+ variant_list_, \
+ charvariant_list_, \
+ variantchar_list_, \
+ format_, \
+ validate_, \
+ get_cmap_info_ ) \
+ FT_CALLBACK_TABLE_DEF \
+ const TT_CMap_ClassRec class_ = \
+ { \
+ { size_, \
+ init_, \
+ done_, \
+ char_index_, \
+ char_next_, \
+ char_var_index_, \
+ char_var_default_, \
+ variant_list_, \
+ charvariant_list_, \
+ variantchar_list_ \
+ }, \
+ \
+ format_, \
+ validate_, \
+ get_cmap_info_ \
};
#else /* FT_CONFIG_OPTION_PIC */
-#define FT_DEFINE_TT_CMAP(class_, size_, init_, done_, char_index_, \
- char_next_, char_var_index_, char_var_default_, variant_list_, \
- charvariant_list_,variantchar_list_, \
- format_, validate_, get_cmap_info_) \
- void \
- FT_Init_Class_##class_( TT_CMap_ClassRec* clazz ) \
- { \
- clazz->clazz.size = size_; \
- clazz->clazz.init = init_; \
- clazz->clazz.done = done_; \
- clazz->clazz.char_index = char_index_; \
- clazz->clazz.char_next = char_next_; \
- clazz->clazz.char_var_index = char_var_index_; \
- clazz->clazz.char_var_default = char_var_default_; \
- clazz->clazz.variant_list = variant_list_; \
- clazz->clazz.charvariant_list = charvariant_list_; \
- clazz->clazz.variantchar_list = variantchar_list_; \
- clazz->format = format_; \
- clazz->validate = validate_; \
- clazz->get_cmap_info = get_cmap_info_; \
+#define FT_DEFINE_TT_CMAP( class_, \
+ size_, \
+ init_, \
+ done_, \
+ char_index_, \
+ char_next_, \
+ char_var_index_, \
+ char_var_default_, \
+ variant_list_, \
+ charvariant_list_, \
+ variantchar_list_, \
+ format_, \
+ validate_, \
+ get_cmap_info_ ) \
+ void \
+ FT_Init_Class_ ## class_( TT_CMap_ClassRec* clazz ) \
+ { \
+ clazz->clazz.size = size_; \
+ clazz->clazz.init = init_; \
+ clazz->clazz.done = done_; \
+ clazz->clazz.char_index = char_index_; \
+ clazz->clazz.char_next = char_next_; \
+ clazz->clazz.char_var_index = char_var_index_; \
+ clazz->clazz.char_var_default = char_var_default_; \
+ clazz->clazz.variant_list = variant_list_; \
+ clazz->clazz.charvariant_list = charvariant_list_; \
+ clazz->clazz.variantchar_list = variantchar_list_; \
+ clazz->format = format_; \
+ clazz->validate = validate_; \
+ clazz->get_cmap_info = get_cmap_info_; \
}
#endif /* FT_CONFIG_OPTION_PIC */
+
typedef struct TT_ValidatorRec_
{
FT_ValidatorRec validator;
@@ -104,7 +137,7 @@ FT_BEGIN_HEADER
} TT_ValidatorRec, *TT_Validator;
-#define TT_VALIDATOR( x ) ((TT_Validator)( x ))
+#define TT_VALIDATOR( x ) ( (TT_Validator)( x ) )
#define TT_VALID_GLYPH_COUNT( x ) TT_VALIDATOR( x )->num_glyphs
diff --git a/freetype/src/sfnt/ttcmapc.h b/freetype/src/sfnt/ttcmapc.h
index 4c9c6a56f..2ea204309 100644
--- a/freetype/src/sfnt/ttcmapc.h
+++ b/freetype/src/sfnt/ttcmapc.h
@@ -17,39 +17,40 @@
#ifdef TT_CONFIG_CMAP_FORMAT_0
- TTCMAPCITEM(tt_cmap0_class_rec)
+ TTCMAPCITEM( tt_cmap0_class_rec )
#endif
#ifdef TT_CONFIG_CMAP_FORMAT_2
- TTCMAPCITEM(tt_cmap2_class_rec)
+ TTCMAPCITEM( tt_cmap2_class_rec )
#endif
#ifdef TT_CONFIG_CMAP_FORMAT_4
- TTCMAPCITEM(tt_cmap4_class_rec)
+ TTCMAPCITEM( tt_cmap4_class_rec )
#endif
#ifdef TT_CONFIG_CMAP_FORMAT_6
- TTCMAPCITEM(tt_cmap6_class_rec)
+ TTCMAPCITEM( tt_cmap6_class_rec )
#endif
#ifdef TT_CONFIG_CMAP_FORMAT_8
- TTCMAPCITEM(tt_cmap8_class_rec)
+ TTCMAPCITEM( tt_cmap8_class_rec )
#endif
#ifdef TT_CONFIG_CMAP_FORMAT_10
- TTCMAPCITEM(tt_cmap10_class_rec)
+ TTCMAPCITEM( tt_cmap10_class_rec )
#endif
#ifdef TT_CONFIG_CMAP_FORMAT_12
- TTCMAPCITEM(tt_cmap12_class_rec)
+ TTCMAPCITEM( tt_cmap12_class_rec )
#endif
#ifdef TT_CONFIG_CMAP_FORMAT_13
- TTCMAPCITEM(tt_cmap13_class_rec)
+ TTCMAPCITEM( tt_cmap13_class_rec )
#endif
#ifdef TT_CONFIG_CMAP_FORMAT_14
- TTCMAPCITEM(tt_cmap14_class_rec)
+ TTCMAPCITEM( tt_cmap14_class_rec )
#endif
+
/* END */
diff --git a/freetype/src/sfnt/ttload.c b/freetype/src/sfnt/ttload.c
index cd3f6f332..819b90e81 100644
--- a/freetype/src/sfnt/ttload.c
+++ b/freetype/src/sfnt/ttload.c
@@ -361,14 +361,17 @@
FT_TRACE2(( "-- Number of tables: %10u\n", sfnt.num_tables ));
FT_TRACE2(( "-- Format version: 0x%08lx\n", sfnt.format_tag ));
- /* check first */
- error = check_table_dir( &sfnt, stream );
- if ( error )
+ if ( sfnt.format_tag != TTAG_OTTO )
{
- FT_TRACE2(( "tt_face_load_font_dir:"
- " invalid table directory for TrueType\n" ));
+ /* check first */
+ error = check_table_dir( &sfnt, stream );
+ if ( error )
+ {
+ FT_TRACE2(( "tt_face_load_font_dir:"
+ " invalid table directory for TrueType\n" ));
- goto Exit;
+ goto Exit;
+ }
}
face->num_tables = sfnt.num_tables;
@@ -1239,11 +1242,11 @@
num_ranges = face->gasp.numRanges;
FT_TRACE3(( "numRanges: %u\n", num_ranges ));
- if ( FT_QNEW_ARRAY( gaspranges, num_ranges ) ||
- FT_FRAME_ENTER( num_ranges * 4L ) )
+ if ( FT_QNEW_ARRAY( face->gasp.gaspRanges, num_ranges ) ||
+ FT_FRAME_ENTER( num_ranges * 4L ) )
goto Exit;
- face->gasp.gaspRanges = gaspranges;
+ gaspranges = face->gasp.gaspRanges;
for ( j = 0; j < num_ranges; j++ )
{
diff --git a/freetype/src/smooth/ftgrays.c b/freetype/src/smooth/ftgrays.c
index 849734b5d..579485a1e 100644
--- a/freetype/src/smooth/ftgrays.c
+++ b/freetype/src/smooth/ftgrays.c
@@ -1091,11 +1091,11 @@ typedef ptrdiff_t FT_PtrDist;
if ( s > s_limit )
goto Split;
- /* If P1 or P2 is outside P0-P3, split the curve. */
- if ( dy * dy1 + dx * dx1 < 0 ||
- dy * dy2 + dx * dx2 < 0 ||
- dy * (arc[3].y - arc[1].y) + dx * (arc[3].x - arc[1].x) < 0 ||
- dy * (arc[3].y - arc[2].y) + dx * (arc[3].x - arc[2].x) < 0 )
+ /* Split super curvy segments where the off points are so far
+ from the chord that the angles P0-P1-P3 or P0-P2-P3 become
+ acute as detected by appropriate dot products. */
+ if ( dx1 * ( dx1 - dx ) + dy1 * ( dy1 - dy ) > 0 ||
+ dx2 * ( dx2 - dx ) + dy2 * ( dy2 - dy ) > 0 )
goto Split;
/* No reason to split. */
@@ -1400,7 +1400,26 @@ typedef ptrdiff_t FT_PtrDist;
ras.render_span( ras.span_y, ras.num_gray_spans,
ras.gray_spans, ras.render_span_data );
+#ifdef FT_DEBUG_LEVEL_TRACE
+
+ if ( ras.num_gray_spans > 0 )
+ {
+ FT_Span* span;
+ int n;
+
+
+ FT_TRACE7(( "y = %3d ", ras.span_y ));
+ span = ras.gray_spans;
+ for ( n = 0; n < ras.num_gray_spans; n++, span++ )
+ FT_TRACE7(( "[%d..%d]:%02x ",
+ span->x, span->x + span->len - 1, span->coverage ));
+ FT_TRACE7(( "\n" ));
+ }
+
FT_TRACE7(( "gray_sweep: end\n" ));
+
+#endif /* FT_DEBUG_LEVEL_TRACE */
+
}
diff --git a/freetype/src/smooth/ftsmooth.c b/freetype/src/smooth/ftsmooth.c
index 233dd6524..7150fe9a5 100644
--- a/freetype/src/smooth/ftsmooth.c
+++ b/freetype/src/smooth/ftsmooth.c
@@ -116,6 +116,10 @@
FT_Raster_Params params;
+ FT_Bool have_translated_origin = FALSE;
+ FT_Bool have_outline_shifted = FALSE;
+ FT_Bool have_buffer = FALSE;
+
/* check glyph image format */
if ( slot->format != render->glyph_format )
@@ -126,13 +130,19 @@
/* check mode */
if ( mode != required_mode )
- return Smooth_Err_Cannot_Render_Glyph;
+ {
+ error = Smooth_Err_Cannot_Render_Glyph;
+ goto Exit;
+ }
outline = &slot->outline;
/* translate the outline to the new origin if needed */
if ( origin )
+ {
FT_Outline_Translate( outline, origin->x, origin->y );
+ have_translated_origin = TRUE;
+ }
/* compute the control box, and grid fit it */
FT_Outline_Get_CBox( outline, &cbox );
@@ -147,17 +157,19 @@
FT_ERROR(( "ft_smooth_render_generic: glyph too large:"
" xMin = %d, xMax = %d\n",
cbox.xMin >> 6, cbox.xMax >> 6 ));
- return Smooth_Err_Raster_Overflow;
+ error = Smooth_Err_Raster_Overflow;
+ goto Exit;
}
else
- width = ( cbox.xMax - cbox.xMin ) >> 6;
+ width = ( cbox.xMax - cbox.xMin ) >> 6;
if ( cbox.yMin < 0 && cbox.yMax > FT_INT_MAX + cbox.yMin )
{
FT_ERROR(( "ft_smooth_render_generic: glyph too large:"
" yMin = %d, yMax = %d\n",
cbox.yMin >> 6, cbox.yMax >> 6 ));
- return Smooth_Err_Raster_Overflow;
+ error = Smooth_Err_Raster_Overflow;
+ goto Exit;
}
else
height = ( cbox.yMax - cbox.yMin ) >> 6;
@@ -220,13 +232,14 @@
#if FT_UINT_MAX > 0xFFFFU
- /* Required check is ( pitch * height < FT_ULONG_MAX ), */
- /* but we care realistic cases only. Always pitch <= width. */
+ /* Required check is (pitch * height < FT_ULONG_MAX), */
+ /* but we care realistic cases only. Always pitch <= width. */
if ( width > 0x7FFF || height > 0x7FFF )
{
FT_ERROR(( "ft_smooth_render_generic: glyph too large: %u x %u\n",
width, height ));
- return Smooth_Err_Raster_Overflow;
+ error = Smooth_Err_Raster_Overflow;
+ goto Exit;
}
#endif
@@ -239,9 +252,12 @@
/* translate outline to render it into the bitmap */
FT_Outline_Translate( outline, -x_shift, -y_shift );
+ have_outline_shifted = TRUE;
if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) )
goto Exit;
+ else
+ have_buffer = TRUE;
slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
@@ -287,6 +303,9 @@
vec->y /= 3;
}
+ if ( error )
+ goto Exit;
+
if ( slot->library->lcd_filter_func )
slot->library->lcd_filter_func( bitmap, mode, slot->library );
@@ -294,6 +313,8 @@
/* render outline into bitmap */
error = render->raster_render( render->raster, &params );
+ if ( error )
+ goto Exit;
/* expand it horizontally */
if ( hmul )
@@ -345,25 +366,35 @@
#endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
- FT_Outline_Translate( outline, x_shift, y_shift );
-
/*
* XXX: on 16bit system, we return an error for huge bitmap
* to prevent an overflow.
*/
if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX )
- return Smooth_Err_Invalid_Pixel_Size;
-
- if ( error )
+ {
+ error = Smooth_Err_Invalid_Pixel_Size;
goto Exit;
+ }
slot->format = FT_GLYPH_FORMAT_BITMAP;
slot->bitmap_left = (FT_Int)x_left;
slot->bitmap_top = (FT_Int)y_top;
+ /* everything is fine; don't deallocate buffer */
+ have_buffer = FALSE;
+
+ error = Smooth_Err_Ok;
+
Exit:
- if ( outline && origin )
+ if ( have_outline_shifted )
+ FT_Outline_Translate( outline, x_shift, y_shift );
+ if ( have_translated_origin )
FT_Outline_Translate( outline, -origin->x, -origin->y );
+ if ( have_buffer )
+ {
+ FT_FREE( bitmap->buffer );
+ slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
+ }
return error;
}
diff --git a/freetype/src/smooth/ftspic.c b/freetype/src/smooth/ftspic.c
index 49485328f..820fb8aca 100644
--- a/freetype/src/smooth/ftspic.c
+++ b/freetype/src/smooth/ftspic.c
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for smooth module. */
/* */
-/* Copyright 2009, 2010 by */
+/* Copyright 2009, 2010, 2012 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -53,7 +53,7 @@
{
FT_PIC_Container* pic_container = &library->pic_container;
FT_Error error = Smooth_Err_Ok;
- SmoothPIC* container;
+ SmoothPIC* container = NULL;
FT_Memory memory = library->memory;
diff --git a/freetype/src/tools/docmaker/content.py b/freetype/src/tools/docmaker/content.py
index b398955b8..26087f7b8 100644
--- a/freetype/src/tools/docmaker/content.py
+++ b/freetype/src/tools/docmaker/content.py
@@ -1,4 +1,4 @@
-# Content (c) 2002, 2004, 2006, 2007, 2008, 2009
+# Content (c) 2002, 2004, 2006-2009, 2012
# David Turner <david@freetype.org>
#
# This file contains routines used to parse the content of documentation
@@ -32,7 +32,7 @@ re_code_end = re.compile( r"(\s*)}\s*$" )
# this regular expression is used to isolate identifiers from
# other text
#
-re_identifier = re.compile( r'(\w*)' )
+re_identifier = re.compile( r'((?:\w|-)*)' )
# we collect macros ending in `_H'; while outputting the object data, we use
diff --git a/freetype/src/tools/docmaker/sources.py b/freetype/src/tools/docmaker/sources.py
index 7b68c0701..490ba2506 100644
--- a/freetype/src/tools/docmaker/sources.py
+++ b/freetype/src/tools/docmaker/sources.py
@@ -1,4 +1,4 @@
-# Sources (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009
+# Sources (c) 2002-2004, 2006-2009, 2012
# David Turner <david@freetype.org>
#
#
@@ -120,8 +120,8 @@ re_source_block_formats = [re_source_block_format1, re_source_block_format2]
#
# notice how each markup tag _must_ begin a new line
#
-re_markup_tag1 = re.compile( r'''\s*<(\w*)>''' ) # <xxxx> format
-re_markup_tag2 = re.compile( r'''\s*@(\w*):''' ) # @xxxx: format
+re_markup_tag1 = re.compile( r'''\s*<((?:\w|-)*)>''' ) # <xxxx> format
+re_markup_tag2 = re.compile( r'''\s*@((?:\w|-)*):''' ) # @xxxx: format
#
# the list of supported markup tags, we could add new ones relatively
@@ -132,7 +132,7 @@ re_markup_tags = [re_markup_tag1, re_markup_tag2]
#
# used to detect a cross-reference, after markup tags have been stripped
#
-re_crossref = re.compile( r'@(\w*)(.*)' )
+re_crossref = re.compile( r'@((?:\w|-)*)(.*)' )
#
# used to detect italic and bold styles in paragraph text
diff --git a/freetype/src/truetype/rules.mk b/freetype/src/truetype/rules.mk
index 507ef16b0..d4b69f578 100644
--- a/freetype/src/truetype/rules.mk
+++ b/freetype/src/truetype/rules.mk
@@ -3,7 +3,7 @@
#
-# Copyright 1996-2000, 2001, 2003, 2004, 2011 by
+# Copyright 1996-2001, 2003-2004, 2011-2012 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
@@ -31,7 +31,8 @@ TT_DRV_SRC := $(TT_DIR)/ttdriver.c \
$(TT_DIR)/ttinterp.c \
$(TT_DIR)/ttobjs.c \
$(TT_DIR)/ttpic.c \
- $(TT_DIR)/ttpload.c
+ $(TT_DIR)/ttpload.c \
+ $(TT_DIR)/ttsubpix.c
# TrueType driver headers
#
diff --git a/freetype/src/truetype/truetype.c b/freetype/src/truetype/truetype.c
index 4bd120978..576912b21 100644
--- a/freetype/src/truetype/truetype.c
+++ b/freetype/src/truetype/truetype.c
@@ -4,7 +4,7 @@
/* */
/* FreeType TrueType driver component (body only). */
/* */
-/* Copyright 1996-2001, 2004, 2006 by */
+/* Copyright 1996-2001, 2004, 2006, 2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -27,6 +27,7 @@
#ifdef TT_USE_BYTECODE_INTERPRETER
#include "ttinterp.c"
+#include "ttsubpix.c"
#endif
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
diff --git a/freetype/src/truetype/ttdriver.c b/freetype/src/truetype/ttdriver.c
index 9cecfb388..0e4addf3b 100644
--- a/freetype/src/truetype/ttdriver.c
+++ b/freetype/src/truetype/ttdriver.c
@@ -353,13 +353,13 @@
/*************************************************************************/
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
- FT_DEFINE_SERVICE_MULTIMASTERSREC(tt_service_gx_multi_masters,
+ FT_DEFINE_SERVICE_MULTIMASTERSREC(
+ tt_service_gx_multi_masters,
(FT_Get_MM_Func) NULL,
(FT_Set_MM_Design_Func) NULL,
(FT_Set_MM_Blend_Func) TT_Set_MM_Blend,
(FT_Get_MM_Var_Func) TT_Get_MM_Var,
- (FT_Set_Var_Design_Func)TT_Set_Var_Design
- )
+ (FT_Set_Var_Design_Func)TT_Set_Var_Design )
#endif
static const FT_Service_TrueTypeEngineRec tt_service_truetype_engine =
@@ -379,25 +379,26 @@
#endif /* TT_USE_BYTECODE_INTERPRETER */
};
- FT_DEFINE_SERVICE_TTGLYFREC(tt_service_truetype_glyf,
- (TT_Glyf_GetLocationFunc)tt_face_get_location
- )
+ FT_DEFINE_SERVICE_TTGLYFREC(
+ tt_service_truetype_glyf,
+ (TT_Glyf_GetLocationFunc)tt_face_get_location )
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
- FT_DEFINE_SERVICEDESCREC4(tt_services,
+ FT_DEFINE_SERVICEDESCREC4(
+ tt_services,
FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE,
- FT_SERVICE_ID_MULTI_MASTERS, &FT_TT_SERVICE_GX_MULTI_MASTERS_GET,
+ FT_SERVICE_ID_MULTI_MASTERS, &TT_SERVICE_GX_MULTI_MASTERS_GET,
FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine,
- FT_SERVICE_ID_TT_GLYF, &FT_TT_SERVICE_TRUETYPE_GLYF_GET
- )
+ FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET )
#else
- FT_DEFINE_SERVICEDESCREC3(tt_services,
+ FT_DEFINE_SERVICEDESCREC3(
+ tt_services,
FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE,
FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine,
- FT_SERVICE_ID_TT_GLYF, &FT_TT_SERVICE_TRUETYPE_GLYF_GET
- )
+ FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET )
#endif
+
FT_CALLBACK_DEF( FT_Module_Interface )
tt_get_interface( FT_Module driver, /* TT_Driver */
const char* tt_interface )
@@ -408,7 +409,7 @@
SFNT_Service sfnt;
- /* FT_TT_SERVICES_GET derefers `library' in PIC mode */
+ /* TT_SERVICES_GET derefers `library' in PIC mode */
#ifdef FT_CONFIG_OPTION_PIC
if ( !driver )
return NULL;
@@ -417,7 +418,7 @@
return NULL;
#endif
- result = ft_service_list_lookup( FT_TT_SERVICES_GET, tt_interface );
+ result = ft_service_list_lookup( TT_SERVICES_GET, tt_interface );
if ( result != NULL )
return result;
@@ -445,15 +446,15 @@
/* The FT_DriverInterface structure is defined in ftdriver.h. */
#ifdef TT_USE_BYTECODE_INTERPRETER
-#define TT_HINTER_FLAG FT_MODULE_DRIVER_HAS_HINTER
+#define TT_HINTER_FLAG FT_MODULE_DRIVER_HAS_HINTER
#else
-#define TT_HINTER_FLAG 0
+#define TT_HINTER_FLAG 0
#endif
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
-#define TT_SIZE_SELECT tt_size_select
+#define TT_SIZE_SELECT tt_size_select
#else
-#define TT_SIZE_SELECT 0
+#define TT_SIZE_SELECT 0
#endif
FT_DEFINE_DRIVER( tt_driver_class,
diff --git a/freetype/src/truetype/ttgload.c b/freetype/src/truetype/ttgload.c
index 1e6102cc6..04a5a2933 100644
--- a/freetype/src/truetype/ttgload.c
+++ b/freetype/src/truetype/ttgload.c
@@ -32,6 +32,7 @@
#endif
#include "tterrors.h"
+#include "ttsubpix.h"
/*************************************************************************/
@@ -149,6 +150,15 @@
loader->top_bearing = top_bearing;
loader->vadvance = advance_height;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( loader->exec )
+ loader->exec->sph_tweak_flags = 0;
+
+ /* this may not be the right place for this, but it works */
+ if ( loader->exec && loader->exec->ignore_x_mode )
+ sph_set_tweaks( loader, glyph_index );
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
if ( !loader->linear_def )
{
loader->linear_def = 1;
@@ -252,10 +262,6 @@
}
-#undef IS_HINTED
-#define IS_HINTED( flags ) ( ( flags & FT_LOAD_NO_HINTING ) == 0 )
-
-
/*************************************************************************/
/* */
/* The following functions are used by default with TrueType fonts. */
@@ -813,6 +819,13 @@
loader->pp4 = zone->cur[zone->n_points - 1];
}
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( loader->exec->sph_tweak_flags & SPH_TWEAK_DEEMBOLDEN )
+ FT_Outline_EmboldenXY( &loader->gloader->current.outline, -24, 0 );
+
+ else if ( loader->exec->sph_tweak_flags & SPH_TWEAK_EMBOLDEN )
+ FT_Outline_EmboldenXY( &loader->gloader->current.outline, 24, 0 );
+#endif
return TT_Err_Ok;
}
@@ -835,6 +848,14 @@
FT_Outline* outline;
FT_Int n_points;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ TT_Face face = (TT_Face)loader->face;
+ FT_String* family = face->root.family_name;
+ FT_Int ppem = loader->size->metrics.x_ppem;
+ FT_String* style = face->root.style_name;
+ FT_Int x_scale_factor = 1000;
+#endif
+
outline = &gloader->current.outline;
n_points = outline->n_points;
@@ -889,6 +910,32 @@
loader->zone.n_points + 4 );
}
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ /* scale, but only if enabled and only if TT hinting is being used */
+ if ( IS_HINTED( loader->load_flags ) )
+ x_scale_factor = scale_test_tweak( face, family, ppem, style,
+ loader->glyph_index, X_SCALING_Rules,
+ X_SCALING_RULES_SIZE );
+ /* scale the glyph */
+ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ||
+ x_scale_factor != 1000 )
+ {
+ FT_Vector* vec = outline->points;
+ FT_Vector* limit = outline->points + n_points;
+ FT_Fixed x_scale = FT_MulDiv(
+ ((TT_Size)loader->size)->metrics.x_scale,
+ x_scale_factor, 1000 );
+ FT_Fixed y_scale = ((TT_Size)loader->size)->metrics.y_scale;
+
+
+ /* compensate for any scaling by de/emboldening; */
+ /* the amount was determined via experimentation */
+ if ( x_scale_factor != 1000 && ppem > 11 )
+ FT_Outline_EmboldenXY( outline,
+ FT_MulFix( 1280 * ppem,
+ 1000 - x_scale_factor ),
+ 0 );
+#else
/* scale the glyph */
if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
{
@@ -896,6 +943,7 @@
FT_Vector* limit = outline->points + n_points;
FT_Fixed x_scale = ((TT_Size)loader->size)->metrics.x_scale;
FT_Fixed y_scale = ((TT_Size)loader->size)->metrics.y_scale;
+#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
for ( ; vec < limit; vec++ )
@@ -1648,12 +1696,26 @@
{
FT_Byte* widthp;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ FT_Bool ignore_x_mode;
+
+
+ ignore_x_mode = FT_BOOL( FT_LOAD_TARGET_MODE( loader->load_flags ) !=
+ FT_RENDER_MODE_MONO );
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
widthp = tt_face_get_device_metrics( face,
size->root.metrics.x_ppem,
glyph_index );
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( widthp &&
+ ( ( ignore_x_mode && loader->exec->compatible_widths ) ||
+ !ignore_x_mode ||
+ SPH_OPTION_BITMAP_WIDTHS ) )
+#else
if ( widthp )
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
glyph->metrics.horiAdvance = *widthp << 6;
}
@@ -1833,7 +1895,9 @@
{
TT_Face face;
FT_Stream stream;
+#ifdef TT_USE_BYTECODE_INTERPRETER
FT_Bool pedantic = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
+#endif
face = (TT_Face)glyph->face;
@@ -1848,6 +1912,16 @@
{
TT_ExecContext exec;
FT_Bool grayscale;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ FT_Bool subpixel_hinting;
+ FT_Bool grayscale_hinting;
+#if 0
+ FT_Bool compatible_widths;
+ FT_Bool symmetrical_smoothing;
+ FT_Bool bgr;
+ FT_Bool subpixel_positioned;
+#endif
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
if ( !size->cvt_ready )
@@ -1865,11 +1939,90 @@
if ( !exec )
return TT_Err_Could_Not_Find_Context;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+
+ subpixel_hinting = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags )
+ != FT_RENDER_MODE_MONO ) &&
+ SPH_OPTION_SET_SUBPIXEL );
+
+ if ( subpixel_hinting )
+ grayscale = grayscale_hinting = FALSE;
+
+ else if ( SPH_OPTION_SET_GRAYSCALE )
+ {
+ grayscale = grayscale_hinting = TRUE;
+ subpixel_hinting = FALSE;
+ }
+
+ if ( FT_IS_TRICKY( glyph->face ) )
+ subpixel_hinting = grayscale_hinting = FALSE;
+
+ exec->ignore_x_mode = subpixel_hinting || grayscale_hinting;
+ exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION;
+ if ( exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 )
+ exec->rasterizer_version = 35;
+
+#if 1
+ exec->compatible_widths = SPH_OPTION_SET_COMPATIBLE_WIDTHS;
+ exec->symmetrical_smoothing = FALSE;
+ exec->bgr = FALSE;
+ exec->subpixel_positioned = TRUE;
+#else /* 0 */
+ exec->compatible_widths =
+ FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
+ TT_LOAD_COMPATIBLE_WIDTHS );
+ exec->symmetrical_smoothing =
+ FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
+ TT_LOAD_SYMMETRICAL_SMOOTHING );
+ exec->bgr =
+ FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
+ TT_LOAD_BGR );
+ exec->subpixel_positioned =
+ FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
+ TT_LOAD_SUBPIXEL_POSITIONED );
+#endif /* 0 */
+
+#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
grayscale =
FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != FT_RENDER_MODE_MONO );
+#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
TT_Load_Context( exec, face, size );
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+
+ /* a change from mono to subpixel rendering (and vice versa) */
+ /* requires a re-execution of the CVT program */
+ if ( subpixel_hinting != exec->subpixel_hinting )
+ {
+ FT_UInt i;
+
+
+ exec->subpixel_hinting = subpixel_hinting;
+
+ for ( i = 0; i < size->cvt_size; i++ )
+ size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
+ tt_size_run_prep( size, pedantic );
+ }
+
+ /* a change from mono to grayscale rendering (and vice versa) */
+ /* requires a re-execution of the CVT program */
+ if ( grayscale != exec->grayscale_hinting )
+ {
+ FT_UInt i;
+
+
+ exec->grayscale_hinting = grayscale_hinting;
+
+ for ( i = 0; i < size->cvt_size; i++ )
+ size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
+ tt_size_run_prep( size, pedantic );
+ }
+
+#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
/* a change from mono to grayscale rendering (and vice versa) */
/* requires a re-execution of the CVT program */
if ( grayscale != exec->grayscale )
@@ -1887,6 +2040,8 @@
tt_size_run_prep( size, pedantic );
}
+#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
/* see whether the cvt program has disabled hinting */
if ( exec->GS.instruct_control & 1 )
load_flags |= FT_LOAD_NO_HINTING;
diff --git a/freetype/src/truetype/ttgxvar.c b/freetype/src/truetype/ttgxvar.c
index f0a4973ee..975a00a24 100644
--- a/freetype/src/truetype/ttgxvar.c
+++ b/freetype/src/truetype/ttgxvar.c
@@ -4,7 +4,7 @@
/* */
/* TrueType GX Font Variation loader */
/* */
-/* Copyright 2004-2011 by */
+/* Copyright 2004-2012 by */
/* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -91,7 +91,7 @@
/* indicates that there is a delta for every point without needing to */
/* enumerate all of them. */
/* */
-#define ALL_POINTS (FT_UShort*)( -1 )
+#define ALL_POINTS (FT_UShort*)( ~0 )
#define GX_PT_POINTS_ARE_WORDS 0x80
@@ -501,11 +501,9 @@
FT_Fixed* im_end_coords )
{
FT_UInt i;
- FT_Fixed apply;
- FT_Fixed temp;
+ FT_Fixed apply = 0x10000L;
- apply = 0x10000L;
for ( i = 0; i < blend->num_axis; ++i )
{
if ( tuple_coords[i] == 0 )
@@ -525,11 +523,10 @@
else if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) )
/* not an intermediate tuple */
- apply = FT_MulDiv( apply,
+ apply = FT_MulFix( apply,
blend->normalizedcoords[i] > 0
? blend->normalizedcoords[i]
- : -blend->normalizedcoords[i],
- 0x10000L );
+ : -blend->normalizedcoords[i] );
else if ( blend->normalizedcoords[i] <= im_start_coords[i] ||
blend->normalizedcoords[i] >= im_end_coords[i] )
@@ -539,20 +536,14 @@
}
else if ( blend->normalizedcoords[i] < tuple_coords[i] )
- {
- temp = FT_MulDiv( blend->normalizedcoords[i] - im_start_coords[i],
- 0x10000L,
- tuple_coords[i] - im_start_coords[i]);
- apply = FT_MulDiv( apply, temp, 0x10000L );
- }
+ apply = FT_MulDiv( apply,
+ blend->normalizedcoords[i] - im_start_coords[i],
+ tuple_coords[i] - im_start_coords[i] );
else
- {
- temp = FT_MulDiv( im_end_coords[i] - blend->normalizedcoords[i],
- 0x10000L,
- im_end_coords[i] - tuple_coords[i] );
- apply = FT_MulDiv( apply, temp, 0x10000L );
- }
+ apply = FT_MulDiv( apply,
+ im_end_coords[i] - blend->normalizedcoords[i],
+ im_end_coords[i] - tuple_coords[i] );
}
return apply;
@@ -712,7 +703,7 @@
mmvar->num_axis =
fvar_head.axisCount;
mmvar->num_designs =
- (FT_UInt)-1; /* meaningless in this context; each glyph */
+ ~0; /* meaningless in this context; each glyph */
/* may have a different number of designs */
/* (or tuples, as called by Apple) */
mmvar->num_namedstyles =
@@ -1034,19 +1025,11 @@
}
if ( coords[i] < a->def )
- {
- normalized[i] = -FT_MulDiv( coords[i] - a->def,
- 0x10000L,
- a->minimum - a->def );
- }
+ normalized[i] = -FT_DivFix( coords[i] - a->def, a->minimum - a->def );
else if ( a->maximum == a->def )
normalized[i] = 0;
else
- {
- normalized[i] = FT_MulDiv( coords[i] - a->def,
- 0x10000L,
- a->maximum - a->def );
- }
+ normalized[i] = FT_DivFix( coords[i] - a->def, a->maximum - a->def );
}
if ( !blend->avar_checked )
@@ -1061,15 +1044,11 @@
if ( normalized[i] < av->correspondence[j].fromCoord )
{
normalized[i] =
- FT_MulDiv(
- FT_MulDiv(
- normalized[i] - av->correspondence[j - 1].fromCoord,
- 0x10000L,
- av->correspondence[j].fromCoord -
- av->correspondence[j - 1].fromCoord ),
- av->correspondence[j].toCoord -
- av->correspondence[j - 1].toCoord,
- 0x10000L ) +
+ FT_MulDiv( normalized[i] - av->correspondence[j - 1].fromCoord,
+ av->correspondence[j].toCoord -
+ av->correspondence[j - 1].toCoord,
+ av->correspondence[j].fromCoord -
+ av->correspondence[j - 1].fromCoord ) +
av->correspondence[j - 1].toCoord;
break;
}
diff --git a/freetype/src/truetype/ttinterp.c b/freetype/src/truetype/ttinterp.c
index 68969a9f4..1fc38905b 100644
--- a/freetype/src/truetype/ttinterp.c
+++ b/freetype/src/truetype/ttinterp.c
@@ -27,16 +27,15 @@
#include FT_SYSTEM_H
#include "ttinterp.h"
-
#include "tterrors.h"
+#include "ttsubpix.h"
#ifdef TT_USE_BYTECODE_INTERPRETER
-#define TT_MULFIX FT_MulFix
-#define TT_MULDIV FT_MulDiv
-#define TT_MULDIV_NO_ROUND FT_MulDiv_No_Round
+#define xxxSPH_DEBUG
+#define xxxSPH_DEBUG_MORE_VERBOSE
/*************************************************************************/
@@ -232,6 +231,14 @@
#define BOUNDS( x, n ) ( (FT_UInt)(x) >= (FT_UInt)(n) )
#define BOUNDSL( x, n ) ( (FT_ULong)(x) >= (FT_ULong)(n) )
+ /*************************************************************************/
+ /* */
+ /* This macro computes (a*2^14)/b and complements TT_MulFix14. */
+ /* */
+#define TT_DivFix14( a, b ) \
+ FT_DivFix( a, (b) << 2 )
+
+
#undef SUCCESS
#define SUCCESS 0
@@ -1661,13 +1668,13 @@
else
{
- FT_Long x, y;
+ FT_F26Dot6 x, y;
- x = TT_MULDIV( CUR.GS.projVector.x,
- CUR.tt_metrics.x_ratio, 0x4000 );
- y = TT_MULDIV( CUR.GS.projVector.y,
- CUR.tt_metrics.y_ratio, 0x4000 );
+ x = TT_MulFix14( CUR.tt_metrics.x_ratio,
+ CUR.GS.projVector.x );
+ y = TT_MulFix14( CUR.tt_metrics.y_ratio,
+ CUR.GS.projVector.y );
CUR.tt_metrics.ratio = TT_VecLen( x, y );
}
}
@@ -1679,7 +1686,7 @@
static FT_Long
Current_Ppem( EXEC_OP )
{
- return TT_MULFIX( CUR.tt_metrics.ppem, CURRENT_Ratio() );
+ return FT_MulFix( CUR.tt_metrics.ppem, CURRENT_Ratio() );
}
@@ -1700,7 +1707,7 @@
FT_CALLBACK_DEF( FT_F26Dot6 )
Read_CVT_Stretched( EXEC_OP_ FT_ULong idx )
{
- return TT_MULFIX( CUR.cvt[idx], CURRENT_Ratio() );
+ return FT_MulFix( CUR.cvt[idx], CURRENT_Ratio() );
}
@@ -1850,9 +1857,11 @@
if ( v != 0 )
{
- zone->cur[point].x += TT_MULDIV( distance,
- v * 0x10000L,
- CUR.F_dot_P );
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( !CUR.ignore_x_mode ||
+ ( CUR.sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) )
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ zone->cur[point].x += FT_MulDiv( distance, v, CUR.F_dot_P );
zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
}
@@ -1861,9 +1870,7 @@
if ( v != 0 )
{
- zone->cur[point].y += TT_MULDIV( distance,
- v * 0x10000L,
- CUR.F_dot_P );
+ zone->cur[point].y += FT_MulDiv( distance, v, CUR.F_dot_P );
zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
}
@@ -1902,16 +1909,12 @@
v = CUR.GS.freeVector.x;
if ( v != 0 )
- zone->org[point].x += TT_MULDIV( distance,
- v * 0x10000L,
- CUR.F_dot_P );
+ zone->org[point].x += FT_MulDiv( distance, v, CUR.F_dot_P );
v = CUR.GS.freeVector.y;
if ( v != 0 )
- zone->org[point].y += TT_MULDIV( distance,
- v * 0x10000L,
- CUR.F_dot_P );
+ zone->org[point].y += FT_MulDiv( distance, v, CUR.F_dot_P );
}
@@ -1932,6 +1935,10 @@
{
FT_UNUSED_EXEC;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( !CUR.ignore_x_mode ||
+ ( CUR.sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVEX ) )
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
zone->cur[point].x += distance;
zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
}
@@ -2193,7 +2200,7 @@
}
else
{
- val = - FT_PIX_CEIL( compensation - distance );
+ val = -FT_PIX_CEIL( compensation - distance );
if ( val > 0 )
val = 0;
}
@@ -2404,8 +2411,9 @@
/* Sets Super Round parameters. */
/* */
/* <Input> */
- /* GridPeriod :: Grid period */
- /* selector :: SROUND opcode */
+ /* GridPeriod :: The grid period. */
+ /* */
+ /* selector :: The SROUND opcode. */
/* */
static void
SetSuperRound( EXEC_OP_ FT_F26Dot6 GridPeriod,
@@ -2617,13 +2625,10 @@
if ( CUR.GS.dualVector.x == 0x4000 )
CUR.func_dualproj = Project_x;
+ else if ( CUR.GS.dualVector.y == 0x4000 )
+ CUR.func_dualproj = Project_y;
else
- {
- if ( CUR.GS.dualVector.y == 0x4000 )
- CUR.func_dualproj = Project_y;
- else
- CUR.func_dualproj = Dual_Project;
- }
+ CUR.func_dualproj = Dual_Project;
/* Force recalculation of cached aspect ratio */
CUR.tt_metrics.ratio = 0;
@@ -2633,61 +2638,50 @@
#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */
if ( CUR.GS.freeVector.x == 0x4000 )
- CUR.F_dot_P = CUR.GS.projVector.x * 0x10000L;
+ CUR.F_dot_P = CUR.GS.projVector.x;
+ else if ( CUR.GS.freeVector.y == 0x4000 )
+ CUR.F_dot_P = CUR.GS.projVector.y;
else
- {
- if ( CUR.GS.freeVector.y == 0x4000 )
- CUR.F_dot_P = CUR.GS.projVector.y * 0x10000L;
- else
- CUR.F_dot_P = (FT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x * 4 +
- (FT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y * 4;
- }
+ CUR.F_dot_P = ( (FT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x +
+ (FT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y ) >>
+ 14;
if ( CUR.GS.projVector.x == 0x4000 )
CUR.func_project = (TT_Project_Func)Project_x;
+ else if ( CUR.GS.projVector.y == 0x4000 )
+ CUR.func_project = (TT_Project_Func)Project_y;
else
- {
- if ( CUR.GS.projVector.y == 0x4000 )
- CUR.func_project = (TT_Project_Func)Project_y;
- else
- CUR.func_project = (TT_Project_Func)Project;
- }
+ CUR.func_project = (TT_Project_Func)Project;
if ( CUR.GS.dualVector.x == 0x4000 )
CUR.func_dualproj = (TT_Project_Func)Project_x;
+ else if ( CUR.GS.dualVector.y == 0x4000 )
+ CUR.func_dualproj = (TT_Project_Func)Project_y;
else
- {
- if ( CUR.GS.dualVector.y == 0x4000 )
- CUR.func_dualproj = (TT_Project_Func)Project_y;
- else
- CUR.func_dualproj = (TT_Project_Func)Dual_Project;
- }
+ CUR.func_dualproj = (TT_Project_Func)Dual_Project;
CUR.func_move = (TT_Move_Func)Direct_Move;
CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig;
- if ( CUR.F_dot_P == 0x40000000L )
+ if ( CUR.F_dot_P == 0x4000L )
{
if ( CUR.GS.freeVector.x == 0x4000 )
{
CUR.func_move = (TT_Move_Func)Direct_Move_X;
CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_X;
}
- else
+ else if ( CUR.GS.freeVector.y == 0x4000 )
{
- if ( CUR.GS.freeVector.y == 0x4000 )
- {
- CUR.func_move = (TT_Move_Func)Direct_Move_Y;
- CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y;
- }
+ CUR.func_move = (TT_Move_Func)Direct_Move_Y;
+ CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y;
}
}
/* at small sizes, F_dot_P can become too small, resulting */
/* in overflows and `spikes' in a number of glyphs like `w'. */
- if ( FT_ABS( CUR.F_dot_P ) < 0x4000000L )
- CUR.F_dot_P = 0x40000000L;
+ if ( FT_ABS( CUR.F_dot_P ) < 0x400L )
+ CUR.F_dot_P = 0x4000L;
/* Disable cached aspect ratio */
CUR.tt_metrics.ratio = 0;
@@ -2743,16 +2737,16 @@
return SUCCESS;
}
- R->x = (FT_F2Dot14)FT_MulDiv( Vx, 0x4000L, W );
- R->y = (FT_F2Dot14)FT_MulDiv( Vy, 0x4000L, W );
+ R->x = (FT_F2Dot14)TT_DivFix14( Vx, W );
+ R->y = (FT_F2Dot14)TT_DivFix14( Vy, W );
return SUCCESS;
}
W = TT_VecLen( Vx, Vy );
- Vx = FT_MulDiv( Vx, 0x4000L, W );
- Vy = FT_MulDiv( Vy, 0x4000L, W );
+ Vx = TT_DivFix14( Vx, W );
+ Vy = TT_DivFix14( Vy, W );
W = Vx * Vx + Vy * Vy;
@@ -3111,7 +3105,7 @@
#define DO_SSW \
- CUR.GS.single_width_value = TT_MULFIX( args[0], \
+ CUR.GS.single_width_value = FT_MulFix( args[0], \
CUR.tt_metrics.scale );
@@ -3289,11 +3283,11 @@
if ( args[1] == 0 ) \
CUR.error = TT_Err_Divide_By_Zero; \
else \
- args[0] = TT_MULDIV_NO_ROUND( args[0], 64L, args[1] );
+ args[0] = FT_MulDiv_No_Round( args[0], 64L, args[1] );
#define DO_MUL \
- args[0] = TT_MULDIV( args[0], args[1], 64L );
+ args[0] = FT_MulDiv( args[0], args[1], 64L );
#define DO_ABS \
@@ -3311,6 +3305,34 @@
#define DO_CEILING \
args[0] = FT_PIX_CEIL( args[0] );
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+
+#define DO_RS \
+ { \
+ FT_ULong I = (FT_ULong)args[0]; \
+ \
+ \
+ if ( BOUNDSL( I, CUR.storeSize ) ) \
+ { \
+ if ( CUR.pedantic_hinting ) \
+ ARRAY_BOUND_ERROR; \
+ else \
+ args[0] = 0; \
+ } \
+ else \
+ { \
+ /* subpixel hinting - avoid Typeman Dstroke and */ \
+ /* IStroke and Vacuform rounds */ \
+ \
+ if ( CUR.compatibility_mode && \
+ ( I == 24 || I == 22 || I == 8 ) ) \
+ args[0] = 0; \
+ else \
+ args[0] = CUR.storage[I]; \
+ } \
+ }
+
+#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
#define DO_RS \
{ \
@@ -3330,6 +3352,8 @@
args[0] = CUR.storage[I]; \
}
+#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
#define DO_WS \
{ \
@@ -3397,7 +3421,7 @@
} \
} \
else \
- CUR.cvt[I] = TT_MULFIX( args[1], CUR.tt_metrics.scale ); \
+ CUR.cvt[I] = FT_MulFix( args[1], CUR.tt_metrics.scale ); \
}
@@ -4587,6 +4611,27 @@
TT_DefRecord* rec;
TT_DefRecord* limit;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ /* arguments to opcodes are skipped by `SKIP_Code' */
+ FT_Byte opcode_pattern[1][12] = {
+ /* #0 TTFautohint bytecode (old) */
+ {
+ 0x20, /* DUP */
+ 0x64, /* ABS */
+ 0xB0, /* PUSHB_1 */
+ /* 32 */
+ 0x60, /* ADD */
+ 0x66, /* FLOOR */
+ 0x23, /* SWAP */
+ 0xB0 /* PUSHB_1 */
+ },
+ };
+ FT_UShort opcode_patterns = 1;
+ FT_UShort opcode_pointer[1] = { 0, };
+ FT_UShort opcode_size[1] = { 7, };
+ FT_UShort i;
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
/* some font programs are broken enough to redefine functions! */
/* We will then parse the current table. */
@@ -4620,10 +4665,11 @@
return;
}
- rec->range = CUR.curRange;
- rec->opc = (FT_UInt16)n;
- rec->start = CUR.IP + 1;
- rec->active = TRUE;
+ rec->range = CUR.curRange;
+ rec->opc = (FT_UInt16)n;
+ rec->start = CUR.IP + 1;
+ rec->active = TRUE;
+ rec->inline_delta = FALSE;
if ( n > CUR.maxFunc )
CUR.maxFunc = (FT_UInt16)n;
@@ -4633,6 +4679,46 @@
while ( SKIP_Code() == SUCCESS )
{
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+
+#ifdef SPH_DEBUG_MORE_VERBOSE
+ printf ( "Opcode: %d ", CUR.opcode );
+#endif
+
+ for ( i = 0; i < opcode_patterns; i++ )
+ {
+ if ( opcode_pointer[i] < opcode_size[i] &&
+ CUR.opcode == opcode_pattern[i][opcode_pointer[i]] )
+ {
+#ifdef SPH_DEBUG_MORE_VERBOSE
+ printf( "function %d, opcode ptrn: %d"
+ " op# %d: %d FOUND \n",
+ n, i, opcode_pointer[i], CUR.opcode );
+#endif
+ opcode_pointer[i] += 1;
+
+ if ( opcode_pointer[i] == opcode_size[i] )
+ {
+#ifdef SPH_DEBUG
+ printf( "Function signature %d detected in FDEF %d\n", i, n);
+#endif
+
+ switch ( i )
+ {
+ case 0:
+ CUR.size->ttfautohinted = TRUE;
+ break;
+ }
+ opcode_pointer[i] = 0;
+ }
+ }
+
+ else
+ opcode_pointer[i] = 0;
+ }
+
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
switch ( CUR.opcode )
{
case 0x89: /* IDEF */
@@ -4676,6 +4762,15 @@
CUR.step_ins = FALSE;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ /*
+ * CUR.ignore_x_mode may be turned off prior to function calls. This
+ * ensures it is turned back on.
+ */
+ CUR.ignore_x_mode = ( CUR.subpixel_hinting || CUR.grayscale_hinting ) &&
+ !( CUR.sph_tweak_flags & SPH_TWEAK_PIXEL_HINTING );
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
if ( pRec->Cur_Count > 0 )
{
CUR.callTop++;
@@ -4746,6 +4841,7 @@
if ( !def->active )
goto Fail;
+
/* check the call stack */
if ( CUR.callTop >= CUR.callSize )
{
@@ -4846,6 +4942,7 @@
CUR.step_ins = FALSE;
}
+
return;
Fail:
@@ -5179,15 +5276,15 @@
{
/* this should be faster */
D = CUR_Func_dualproj( vec1, vec2 );
- D = TT_MULFIX( D, CUR.metrics.x_scale );
+ D = FT_MulFix( D, CUR.metrics.x_scale );
}
else
{
FT_Vector vec;
- vec.x = TT_MULFIX( vec1->x - vec2->x, CUR.metrics.x_scale );
- vec.y = TT_MULFIX( vec1->y - vec2->y, CUR.metrics.y_scale );
+ vec.x = FT_MulFix( vec1->x - vec2->x, CUR.metrics.x_scale );
+ vec.y = FT_MulFix( vec1->y - vec2->y, CUR.metrics.y_scale );
D = CUR_fast_dualproj( &vec );
}
@@ -5195,6 +5292,12 @@
}
}
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */
+ if ( CUR.ignore_x_mode && FT_ABS( D ) == 64 )
+ D += 1;
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
args[0] = D;
}
@@ -5652,12 +5755,8 @@
else
#endif
{
- *x = TT_MULDIV( d,
- (FT_Long)CUR.GS.freeVector.x * 0x10000L,
- CUR.F_dot_P );
- *y = TT_MULDIV( d,
- (FT_Long)CUR.GS.freeVector.y * 0x10000L,
- CUR.F_dot_P );
+ *x = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.x, CUR.F_dot_P );
+ *y = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.y, CUR.F_dot_P );
}
return SUCCESS;
@@ -5691,7 +5790,12 @@
if ( CUR.GS.freeVector.x != 0 )
{
- CUR.zp2.cur[point].x += dx;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( !CUR.ignore_x_mode ||
+ ( CUR.ignore_x_mode &&
+ ( CUR.sph_tweak_flags & SPH_TWEAK_ALLOW_X_MOVE_ZP2 ) ) )
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ CUR.zp2.cur[point].x += dx;
if ( touch )
CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
}
@@ -5872,6 +5976,9 @@
{
FT_F26Dot6 dx, dy;
FT_UShort point;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ FT_Int B1, B2;
+#endif
if ( CUR.top < CUR.GS.loop + 1 )
@@ -5886,13 +5993,13 @@
{
if ( CUR.GS.both_x_axis )
{
- dx = TT_MulFix14( (FT_UInt32)args[0], 0x4000 );
+ dx = (FT_UInt32)args[0];
dy = 0;
}
else
{
dx = 0;
- dy = TT_MulFix14( (FT_UInt32)args[0], 0x4000 );
+ dy = (FT_UInt32)args[0];
}
}
else
@@ -5917,7 +6024,80 @@
}
}
else
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ {
+ /* If not using ignore_x_mode rendering, allow ZP2 move. */
+ /* If inline deltas aren't allowed, skip ZP2 move. */
+ /* If using ignore_x_mode rendering, allow ZP2 point move if: */
+ /* - freedom vector is y and compatibility_mode is off */
+ /* - the glyph is composite and the move is in the Y direction */
+ /* - the glyph is specifically set to allow SHPIX moves */
+ /* - the move is on a previously Y-touched point */
+
+ if ( CUR.ignore_x_mode )
+ {
+ /* save point for later comparison */
+ if ( CUR.GS.freeVector.y != 0 )
+ B1 = CUR.zp2.cur[point].y;
+ else
+ B1 = CUR.zp2.cur[point].x;
+
+ if ( CUR.GS.freeVector.y != 0 &&
+ ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_INLINE_DELTAS ) )
+ goto Skip;
+
+ if ( CUR.ignore_x_mode &&
+ !CUR.compatibility_mode && CUR.GS.freeVector.y != 0 )
+ MOVE_Zp2_Point( point, dx, dy, TRUE );
+
+ else if ( CUR.ignore_x_mode && CUR.compatibility_mode )
+ {
+ if ( CUR.ignore_x_mode &&
+ ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) )
+ {
+ dx = FT_PIX_ROUND( B1 + dx ) - B1;
+ dy = FT_PIX_ROUND( B1 + dy ) - B1;
+ }
+
+ if ( !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) &&
+ ( ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) ||
+ ( CUR.zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) ||
+ ( CUR.sph_tweak_flags & SPH_TWEAK_DO_SHPIX ) ) )
+ MOVE_Zp2_Point( point, dx, dy, TRUE );
+ }
+
+ /* save new point */
+ if ( CUR.GS.freeVector.y != 0 )
+ B2 = CUR.zp2.cur[point].y;
+ else
+ B2 = CUR.zp2.cur[point].x;
+
+ /* reverse any disallowed moves */
+ if ( ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
+ CUR.GS.freeVector.y != 0 &&
+ B1 % 64 != 0 &&
+ B2 % 64 != 0 &&
+ B1 != B2 ) ||
+ ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES ) &&
+ CUR.GS.freeVector.y != 0 &&
+ B1 % 64 == 0 &&
+ B2 % 64 != 0 &&
+ B1 != B2 &&
+ !CUR.size->ttfautohinted ) )
+ {
+#ifdef SPH_DEBUG
+ printf( "Reversing ZP2 move\n" );
+#endif
+ MOVE_Zp2_Point( point, -dx, -dy, TRUE );
+ }
+ }
+ else
+ MOVE_Zp2_Point( point, dx, dy, TRUE );
+ }
+ Skip:
+#else
MOVE_Zp2_Point( point, dx, dy, TRUE );
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
CUR.GS.loop--;
}
@@ -5939,7 +6119,17 @@
{
FT_UShort point;
FT_F26Dot6 distance;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ FT_F26Dot6 control_value_cutin;
+
+
+ control_value_cutin = CUR.GS.control_value_cutin;
+ if ( CUR.ignore_x_mode &&
+ CUR.GS.freeVector.x != 0 &&
+ !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
+ control_value_cutin = 0;
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
point = (FT_UShort)args[0];
@@ -5963,6 +6153,14 @@
distance = CUR_Func_project( CUR.zp1.cur + point,
CUR.zp0.cur + CUR.GS.rp0 );
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ /* subpixel hinting - make MSIRP respect CVT cut-in; */
+ if ( CUR.ignore_x_mode &&
+ CUR.GS.freeVector.x != 0 &&
+ FT_ABS( distance - args[1] ) >= control_value_cutin )
+ distance = args[1];
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
CUR_Func_move( &CUR.zp1, point, args[1] - distance );
CUR.GS.rp1 = CUR.GS.rp0;
@@ -5983,8 +6181,8 @@
Ins_MDAP( INS_ARG )
{
FT_UShort point;
- FT_F26Dot6 cur_dist,
- distance;
+ FT_F26Dot6 cur_dist;
+ FT_F26Dot6 distance;
point = (FT_UShort)args[0];
@@ -5999,8 +6197,17 @@
if ( ( CUR.opcode & 1 ) != 0 )
{
cur_dist = CUR_fast_project( &CUR.zp0.cur[point] );
- distance = CUR_Func_round( cur_dist,
- CUR.tt_metrics.compensations[0] ) - cur_dist;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( CUR.ignore_x_mode &&
+ CUR.GS.freeVector.x != 0 )
+ distance = ROUND_None(
+ cur_dist,
+ CUR.tt_metrics.compensations[0] ) - cur_dist;
+ else
+#endif
+ distance = CUR_Func_round(
+ cur_dist,
+ CUR.tt_metrics.compensations[0] ) - cur_dist;
}
else
distance = 0;
@@ -6023,12 +6230,21 @@
{
FT_ULong cvtEntry;
FT_UShort point;
- FT_F26Dot6 distance,
- org_dist;
+ FT_F26Dot6 distance;
+ FT_F26Dot6 org_dist;
+ FT_F26Dot6 control_value_cutin;
+
+ control_value_cutin = CUR.GS.control_value_cutin;
+ cvtEntry = (FT_ULong)args[1];
+ point = (FT_UShort)args[0];
- cvtEntry = (FT_ULong)args[1];
- point = (FT_UShort)args[0];
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( CUR.ignore_x_mode &&
+ CUR.GS.freeVector.x != 0 &&
+ !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
+ control_value_cutin = 0;
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
if ( BOUNDS( point, CUR.zp0.n_points ) ||
BOUNDSL( cvtEntry, CUR.cvtSize ) )
@@ -6062,21 +6278,39 @@
if ( CUR.GS.gep0 == 0 ) /* If in twilight zone */
{
- CUR.zp0.org[point].x = TT_MulFix14( (FT_UInt32)distance,
- CUR.GS.freeVector.x );
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ /* only adjust legacy fonts x otherwise breaks Calibri italic */
+ if ( CUR.compatibility_mode )
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ CUR.zp0.org[point].x = TT_MulFix14( (FT_UInt32)distance,
+ CUR.GS.freeVector.x );
CUR.zp0.org[point].y = TT_MulFix14( (FT_UInt32)distance,
CUR.GS.freeVector.y ),
CUR.zp0.cur[point] = CUR.zp0.org[point];
}
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( ( CUR.sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) &&
+ distance > 0 &&
+ CUR.GS.freeVector.y != 0 )
+ distance = 0;
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
org_dist = CUR_fast_project( &CUR.zp0.cur[point] );
- if ( ( CUR.opcode & 1 ) != 0 ) /* rounding and control cutin flag */
+ if ( ( CUR.opcode & 1 ) != 0 ) /* rounding and control cut-in flag */
{
- if ( FT_ABS( distance - org_dist ) > CUR.GS.control_value_cutin )
+ if ( FT_ABS( distance - org_dist ) > control_value_cutin )
distance = org_dist;
- distance = CUR_Func_round( distance, CUR.tt_metrics.compensations[0] );
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( CUR.ignore_x_mode &&
+ CUR.GS.freeVector.x != 0 )
+ distance = ROUND_None( distance,
+ CUR.tt_metrics.compensations[0] );
+ else
+#endif
+ distance = CUR_Func_round( distance,
+ CUR.tt_metrics.compensations[0] );
}
CUR_Func_move( &CUR.zp0, point, distance - org_dist );
@@ -6097,7 +6331,17 @@
Ins_MDRP( INS_ARG )
{
FT_UShort point;
- FT_F26Dot6 org_dist, distance;
+ FT_F26Dot6 org_dist, distance, minimum_distance;
+
+
+ minimum_distance = CUR.GS.minimum_distance;
+
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( CUR.ignore_x_mode &&
+ CUR.GS.freeVector.x != 0 &&
+ !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
+ minimum_distance = 0;
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
point = (FT_UShort)args[0];
@@ -6133,15 +6377,15 @@
{
/* this should be faster */
org_dist = CUR_Func_dualproj( vec1, vec2 );
- org_dist = TT_MULFIX( org_dist, CUR.metrics.x_scale );
+ org_dist = FT_MulFix( org_dist, CUR.metrics.x_scale );
}
else
{
FT_Vector vec;
- vec.x = TT_MULFIX( vec1->x - vec2->x, CUR.metrics.x_scale );
- vec.y = TT_MULFIX( vec1->y - vec2->y, CUR.metrics.y_scale );
+ vec.x = FT_MulFix( vec1->x - vec2->x, CUR.metrics.x_scale );
+ vec.y = FT_MulFix( vec1->y - vec2->y, CUR.metrics.y_scale );
org_dist = CUR_fast_dualproj( &vec );
}
@@ -6161,9 +6405,18 @@
/* round flag */
if ( ( CUR.opcode & 4 ) != 0 )
+ {
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( CUR.ignore_x_mode && CUR.GS.freeVector.x != 0 )
+ distance = ROUND_None(
+ org_dist,
+ CUR.tt_metrics.compensations[CUR.opcode & 3] );
+ else
+#endif
distance = CUR_Func_round(
org_dist,
CUR.tt_metrics.compensations[CUR.opcode & 3] );
+ }
else
distance = ROUND_None(
org_dist,
@@ -6175,13 +6428,13 @@
{
if ( org_dist >= 0 )
{
- if ( distance < CUR.GS.minimum_distance )
- distance = CUR.GS.minimum_distance;
+ if ( distance < minimum_distance )
+ distance = minimum_distance;
}
else
{
- if ( distance > -CUR.GS.minimum_distance )
- distance = -CUR.GS.minimum_distance;
+ if ( distance > -minimum_distance )
+ distance = -minimum_distance;
}
}
@@ -6216,11 +6469,27 @@
FT_F26Dot6 cvt_dist,
distance,
cur_dist,
- org_dist;
-
-
- point = (FT_UShort)args[0];
- cvtEntry = (FT_ULong)( args[1] + 1 );
+ org_dist,
+ control_value_cutin,
+ minimum_distance;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ FT_Int B1;
+ FT_Int B2;
+ FT_Bool reverse_move = FALSE;
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
+
+ minimum_distance = CUR.GS.minimum_distance;
+ control_value_cutin = CUR.GS.control_value_cutin;
+ point = (FT_UShort)args[0];
+ cvtEntry = (FT_ULong)( args[1] + 1 );
+
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( CUR.ignore_x_mode &&
+ CUR.GS.freeVector.x != 0 &&
+ !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
+ control_value_cutin = minimum_distance = 0;
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
/* XXX: UNDOCUMENTED! cvt[-1] = 0 always */
@@ -6237,6 +6506,10 @@
cvt_dist = 0;
else
cvt_dist = CUR_Func_read_cvt( cvtEntry - 1 );
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( CUR.sph_tweak_flags & SPH_TWEAK_MIRP_CVT_ZERO )
+ cvt_dist = 0;
+#endif
/* single width test */
@@ -6274,8 +6547,17 @@
if ( ( org_dist ^ cvt_dist ) < 0 )
cvt_dist = -cvt_dist;
}
-
- /* control value cutin and round */
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( CUR.GS.freeVector.y != 0 &&
+ ( CUR.sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) )
+ {
+ if ( cur_dist < -64 )
+ cvt_dist -= 16;
+ else if ( cur_dist > 64 && cur_dist < 84 )
+ cvt_dist += 32;
+ }
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ /* control value cut-in and round */
if ( ( CUR.opcode & 4 ) != 0 )
{
@@ -6296,7 +6578,7 @@
/* `ttinst2.doc', version 1.66, is thus incorrect since */
/* it implies `>=' instead of `>'. */
- if ( FT_ABS( cvt_dist - org_dist ) > CUR.GS.control_value_cutin )
+ if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin )
cvt_dist = org_dist;
}
@@ -6315,18 +6597,65 @@
{
if ( org_dist >= 0 )
{
- if ( distance < CUR.GS.minimum_distance )
- distance = CUR.GS.minimum_distance;
+ if ( distance < minimum_distance )
+ distance = minimum_distance;
}
else
{
- if ( distance > -CUR.GS.minimum_distance )
- distance = -CUR.GS.minimum_distance;
+ if ( distance > -minimum_distance )
+ distance = -minimum_distance;
}
}
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ B1 = CUR.zp1.cur[point].y;
+
+ /* Round moves if necessary */
+ if ( CUR.ignore_x_mode &&
+ CUR.GS.freeVector.y != 0 &&
+ ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) )
+ distance = FT_PIX_ROUND( B1 + distance - cur_dist ) - B1 + cur_dist;
+
+ if ( CUR.GS.freeVector.y != 0 &&
+ ( CUR.opcode & 16 ) == 0 &&
+ ( CUR.opcode & 8 ) == 0 &&
+ ( CUR.sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) )
+ distance += 64;
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
CUR_Func_move( &CUR.zp1, point, distance - cur_dist );
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ B2 = CUR.zp1.cur[point].y;
+
+ /* Reverse move if necessary */
+ if ( CUR.ignore_x_mode )
+ {
+ if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES ) &&
+ CUR.GS.freeVector.y != 0 &&
+ B1 % 64 == 0 &&
+ B2 % 64 != 0 &&
+ !CUR.size->ttfautohinted )
+ reverse_move = TRUE;
+
+ if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
+ CUR.GS.freeVector.y != 0 &&
+ B2 % 64 != 0 &&
+ B1 % 64 != 0 )
+ reverse_move = TRUE;
+
+ if ( ( CUR.sph_tweak_flags &
+ SPH_TWEAK_DELTAP_SKIP_EXAGGERATED_VALUES ) &&
+ !reverse_move &&
+ FT_ABS( B1 - B2 ) >= 64 )
+ reverse_move = TRUE;
+ }
+
+ if ( reverse_move )
+ CUR_Func_move( &CUR.zp1, point, -( distance - cur_dist ) );
+
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
Fail:
CUR.GS.rp1 = CUR.GS.rp0;
@@ -6352,6 +6681,16 @@
FT_UNUSED_ARG;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( CUR.ignore_x_mode &&
+ CUR.iup_called &&
+ ( CUR.sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) )
+ {
+ CUR.error = TT_Err_Invalid_Reference;
+ goto Fail;
+ }
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
if ( CUR.top < CUR.GS.loop ||
BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
{
@@ -6404,7 +6743,7 @@
a0, a1,
b0, b1;
- FT_F26Dot6 discriminant;
+ FT_F26Dot6 discriminant, dotproduct;
FT_F26Dot6 dx, dy,
dax, day,
@@ -6433,6 +6772,8 @@
return;
}
+ /* Cramer's rule */
+
dbx = CUR.zp0.cur[b1].x - CUR.zp0.cur[b0].x;
dby = CUR.zp0.cur[b1].y - CUR.zp0.cur[b0].y;
@@ -6444,15 +6785,25 @@
CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH;
- discriminant = TT_MULDIV( dax, -dby, 0x40 ) +
- TT_MULDIV( day, dbx, 0x40 );
+ discriminant = FT_MulDiv( dax, -dby, 0x40 ) +
+ FT_MulDiv( day, dbx, 0x40 );
+ dotproduct = FT_MulDiv( dax, dbx, 0x40 ) +
+ FT_MulDiv( day, dby, 0x40 );
- if ( FT_ABS( discriminant ) >= 0x40 )
+ /* The discriminant above is actually a cross product of vectors */
+ /* da and db. Together with the dot product, they can be used as */
+ /* surrogates for sine and cosine of the angle between the vectors. */
+ /* Indeed, */
+ /* dotproduct = |da||db|cos(angle) */
+ /* discriminant = |da||db|sin(angle) . */
+ /* We use these equations to reject grazing intersections by */
+ /* thresholding abs(tan(angle)) at 1/19, corresponding to 3 degrees. */
+ if ( 19 * FT_ABS( discriminant ) > FT_ABS( dotproduct ) )
{
- val = TT_MULDIV( dx, -dby, 0x40 ) + TT_MULDIV( dy, dbx, 0x40 );
+ val = FT_MulDiv( dx, -dby, 0x40 ) + FT_MulDiv( dy, dbx, 0x40 );
- R.x = TT_MULDIV( val, dax, discriminant );
- R.y = TT_MULDIV( val, day, discriminant );
+ R.x = FT_MulDiv( val, dax, discriminant );
+ R.y = FT_MulDiv( val, day, discriminant );
CUR.zp2.cur[point].x = CUR.zp1.cur[a0].x + R.x;
CUR.zp2.cur[point].y = CUR.zp1.cur[a0].y + R.y;
@@ -6576,9 +6927,9 @@
FT_Vector vec;
- vec.x = TT_MULFIX( CUR.zp1.orus[CUR.GS.rp2].x - orus_base->x,
+ vec.x = FT_MulFix( CUR.zp1.orus[CUR.GS.rp2].x - orus_base->x,
CUR.metrics.x_scale );
- vec.y = TT_MULFIX( CUR.zp1.orus[CUR.GS.rp2].y - orus_base->y,
+ vec.y = FT_MulFix( CUR.zp1.orus[CUR.GS.rp2].y - orus_base->y,
CUR.metrics.y_scale );
old_range = CUR_fast_dualproj( &vec );
@@ -6613,9 +6964,9 @@
FT_Vector vec;
- vec.x = TT_MULFIX( CUR.zp2.orus[point].x - orus_base->x,
+ vec.x = FT_MulFix( CUR.zp2.orus[point].x - orus_base->x,
CUR.metrics.x_scale );
- vec.y = TT_MULFIX( CUR.zp2.orus[point].y - orus_base->y,
+ vec.y = FT_MulFix( CUR.zp2.orus[point].y - orus_base->y,
CUR.metrics.y_scale );
org_dist = CUR_fast_dualproj( &vec );
@@ -6625,7 +6976,7 @@
if ( org_dist )
new_dist = ( old_range != 0 )
- ? TT_MULDIV( org_dist, cur_range, old_range )
+ ? FT_MulDiv( org_dist, cur_range, old_range )
: cur_dist;
else
new_dist = 0;
@@ -6786,12 +7137,12 @@
if ( !scale_valid )
{
scale_valid = 1;
- scale = TT_MULDIV( org2 + delta2 - ( org1 + delta1 ),
- 0x10000L, orus2 - orus1 );
+ scale = FT_DivFix( org2 + delta2 - ( org1 + delta1 ),
+ orus2 - orus1 );
}
x = ( org1 + delta1 ) +
- TT_MULFIX( worker->orus[i].x - orus1, scale );
+ FT_MulFix( worker->orus[i].x - orus1, scale );
}
worker->curs[i].x = x;
}
@@ -6846,6 +7197,15 @@
contour = 0;
point = 0;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( CUR.ignore_x_mode )
+ {
+ CUR.iup_called = 1;
+ if ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_IUP )
+ return;
+ }
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
do
{
end_point = CUR.pts.contours[contour] - CUR.pts.first_point;
@@ -6915,6 +7275,9 @@
FT_UShort A;
FT_ULong C;
FT_Long B;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ FT_UShort B1, B2;
+#endif
#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
@@ -6988,7 +7351,69 @@
B++;
B = B * 64 / ( 1L << CUR.GS.delta_shift );
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ /*
+ * Allow delta move if
+ *
+ * - not using ignore_x_mode rendering
+ * - glyph is specifically set to allow it
+ * - glyph is composite and freedom vector is not subpixel vector
+ */
+ if ( !CUR.ignore_x_mode ||
+ ( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) ||
+ ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) )
+ CUR_Func_move( &CUR.zp0, A, B );
+
+ /* Otherwise apply subpixel hinting and compatibility mode rules */
+ else if ( CUR.ignore_x_mode )
+ {
+ if ( CUR.GS.freeVector.y != 0 )
+ B1 = CUR.zp0.cur[A].y;
+ else
+ B1 = CUR.zp0.cur[A].x;
+
+ /* Standard Subpixel Hinting: Allow y move */
+ if ( !CUR.compatibility_mode && CUR.GS.freeVector.y != 0 )
+ CUR_Func_move( &CUR.zp0, A, B );
+
+ /* Compatibility Mode: Allow x or y move if point touched in
+ Y direction */
+ else if ( CUR.compatibility_mode &&
+ !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) )
+ {
+ /* save the y value of the point now; compare after move */
+ B1 = CUR.zp0.cur[A].y;
+
+ if ( ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) )
+ B = FT_PIX_ROUND( B1 + B ) - B1;
+
+ /*
+ * Allow delta move if using compatibility_mode, IUP has not
+ * been called, and point is touched on Y.
+ */
+ if ( !CUR.iup_called &&
+ ( CUR.zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
+ CUR_Func_move( &CUR.zp0, A, B );
+ }
+
+ B2 = CUR.zp0.cur[A].y;
+
+ /* Reverse this move if it results in a disallowed move */
+ if ( CUR.GS.freeVector.y != 0 &&
+ ( ( ( CUR.sph_tweak_flags &
+ SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES ) &&
+ B1 % 64 == 0 &&
+ B2 % 64 != 0 &&
+ !CUR.size->ttfautohinted ) ||
+ ( ( CUR.sph_tweak_flags &
+ SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
+ B1 % 64 != 0 &&
+ B2 % 64 != 0 ) ) )
+ CUR_Func_move( &CUR.zp0, A, -B );
+ }
+#else
CUR_Func_move( &CUR.zp0, A, B );
+#endif /* *TT_CONFIG_OPTION_SUBPIXEL_HINTING */
}
}
else
@@ -7118,22 +7543,113 @@
K = 0;
- /* We return MS rasterizer version 1.7 for the font scaler. */
- if ( ( args[0] & 1 ) != 0 )
- K = 35;
-
- /* Has the glyph been rotated? */
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ /********************************/
+ /* RASTERIZER VERSION */
+ /* Selector Bit: 0 */
+ /* Return Bit(s): 0-7 */
+ /* */
+ if ( ( args[0] & 1 ) != 0 && CUR.ignore_x_mode )
+ {
+ K = CUR.rasterizer_version;
+#ifdef SPH_DEBUG_MORE_VERBOSE
+ printf(" SETTING AS %d\n", CUR.rasterizer_version );
+#endif
+ }
+ else
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ if ( ( args[0] & 1 ) != 0 )
+ K = 35;
+
+ /********************************/
+ /* GLYPH ROTATED */
+ /* Selector Bit: 1 */
+ /* Return Bit(s): 8 */
+ /* */
if ( ( args[0] & 2 ) != 0 && CUR.tt_metrics.rotated )
K |= 0x80;
- /* Has the glyph been stretched? */
+ /********************************/
+ /* GLYPH STRETCHED */
+ /* Selector Bit: 2 */
+ /* Return Bit(s): 9 */
+ /* */
if ( ( args[0] & 4 ) != 0 && CUR.tt_metrics.stretched )
K |= 1 << 8;
- /* Are we hinting for grayscale? */
+ /********************************/
+ /* HINTING FOR GRAYSCALE */
+ /* Selector Bit: 5 */
+ /* Return Bit(s): 12 */
+ /* */
if ( ( args[0] & 32 ) != 0 && CUR.grayscale )
K |= 1 << 12;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( CUR.ignore_x_mode && CUR.rasterizer_version >= 35 )
+ {
+ /********************************/
+ /* HINTING FOR GRAYSCALE */
+ /* Selector Bit: 5 */
+ /* Return Bit(s): 12 */
+ /* */
+ if ( ( args[0] & 32 ) != 0 && CUR.grayscale_hinting )
+ K |= 1 << 12;
+
+ /********************************/
+ /* HINTING FOR SUBPIXEL */
+ /* Selector Bit: 6 */
+ /* Return Bit(s): 13 */
+ /* */
+ if ( ( args[0] & 64 ) != 0 &&
+ CUR.subpixel_hinting &&
+ CUR.rasterizer_version >= 37 )
+ {
+ K |= 1 << 13;
+
+ /* the stuff below is irrelevant if subpixel_hinting is not set */
+
+ /********************************/
+ /* COMPATIBLE WIDTHS ENABLED */
+ /* Selector Bit: 7 */
+ /* Return Bit(s): 14 */
+ /* */
+ /* Functionality still needs to be added */
+ if ( ( args[0] & 128 ) != 0 && CUR.compatible_widths )
+ K |= 1 << 14;
+
+ /********************************/
+ /* SYMMETRICAL SMOOTHING */
+ /* Selector Bit: 8 */
+ /* Return Bit(s): 15 */
+ /* */
+ /* Functionality still needs to be added */
+ if ( ( args[0] & 256 ) != 0 && CUR.symmetrical_smoothing )
+ K |= 1 << 15;
+
+ /********************************/
+ /* HINTING FOR BGR? */
+ /* Selector Bit: 9 */
+ /* Return Bit(s): 16 */
+ /* */
+ /* Functionality still needs to be added */
+ if ( ( args[0] & 512 ) != 0 && CUR.bgr )
+ K |= 1 << 16;
+
+ if ( CUR.rasterizer_version >= 38 )
+ {
+ /********************************/
+ /* SUBPIXEL POSITIONED? */
+ /* Selector Bit: 10 */
+ /* Return Bit(s): 17 */
+ /* */
+ /* Functionality still needs to be added */
+ if ( ( args[0] & 1024 ) != 0 && CUR.subpixel_positioned )
+ K |= 1 << 17;
+ }
+ }
+ }
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
args[0] = K;
}
@@ -7509,6 +8025,11 @@
cur = *exc;
#endif
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( CUR.ignore_x_mode )
+ CUR.iup_called = FALSE;
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
/* set CVT functions */
CUR.tt_metrics.ratio = 0;
if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem )
@@ -7780,7 +8301,13 @@
break;
case 0x2B: /* CALL */
- Ins_CALL( EXEC_ARG_ args );
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( !CUR.ignore_x_mode ||
+ !CUR.iup_called ||
+ ( CUR.iup_called &&
+ !( CUR.sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) )
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ Ins_CALL( EXEC_ARG_ args );
break;
case 0x2C: /* FDEF */
@@ -7796,10 +8323,13 @@
Ins_MDAP( EXEC_ARG_ args );
break;
-
case 0x30: /* IUP */
case 0x31: /* IUP */
- Ins_IUP( EXEC_ARG_ args );
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( CUR.ignore_x_mode )
+ CUR.iup_called = TRUE;
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ Ins_IUP( EXEC_ARG_ args );
break;
case 0x32: /* SHP */
@@ -7958,7 +8488,13 @@
break;
case 0x5D: /* DELTAP1 */
- Ins_DELTAP( EXEC_ARG_ args );
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ if ( !CUR.ignore_x_mode ||
+ !CUR.iup_called ||
+ ( CUR.iup_called &&
+ !( CUR.sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) ) )
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+ Ins_DELTAP( EXEC_ARG_ args );
break;
case 0x5E: /* SDB */
diff --git a/freetype/src/truetype/ttinterp.h b/freetype/src/truetype/ttinterp.h
index 6d0fc03d6..f4336121b 100644
--- a/freetype/src/truetype/ttinterp.h
+++ b/freetype/src/truetype/ttinterp.h
@@ -4,7 +4,7 @@
/* */
/* TrueType bytecode interpreter (specification). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2010 by */
+/* Copyright 1996-2007, 2010, 2012 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -107,6 +107,48 @@ FT_BEGIN_HEADER
} TT_CallRec, *TT_CallStack;
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+
+ /*************************************************************************/
+ /* */
+ /* These structures define rules used to tweak subpixel hinting for */
+ /* various fonts. "", 0, "", NULL value indicates to match any value. */
+ /* */
+
+#define MAX_NAME_SIZE 32
+#define MAX_CLASS_MEMBERS 100
+
+ typedef struct SPH_TweakRule_
+ {
+ const char family[MAX_NAME_SIZE];
+ const FT_UInt ppem;
+ const char style[MAX_NAME_SIZE];
+ const FT_ULong glyph;
+
+ } SPH_TweakRule;
+
+
+ typedef struct SPH_ScaleRule_
+ {
+ const char family[MAX_NAME_SIZE];
+ const FT_UInt ppem;
+ const char style[MAX_NAME_SIZE];
+ const FT_ULong glyph;
+ const FT_ULong scale;
+
+ } SPH_ScaleRule;
+
+
+ typedef struct Font_Class_
+ {
+ const char name[MAX_NAME_SIZE];
+ const char member[MAX_CLASS_MEMBERS][MAX_NAME_SIZE];
+
+ } Font_Class;
+
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
+
/*************************************************************************/
/* */
/* The main structure for the interpreter which collects all necessary */
@@ -218,12 +260,43 @@ FT_BEGIN_HEADER
FT_Bool grayscale; /* are we hinting for grayscale? */
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ TT_Round_Func func_round_sphn; /* subpixel rounding function */
+
+ FT_Bool grayscale_hinting; /* Using grayscale hinting? */
+ FT_Bool subpixel_hinting; /* Using subpixel hinting? */
+ FT_Bool native_hinting; /* Using native hinting? */
+ FT_Bool ignore_x_mode; /* Standard rendering mode for */
+ /* subpixel hinting. On if gray */
+ /* or subpixel hinting is on ) */
+ FT_Bool compatibility_mode;/* Additional exceptions to */
+ /* native TT rules for legacy */
+ /* fonts. Implies */
+ /* ignore_x_mode. */
+
+ /* The following 4 aren't fully implemented but here for MS rasterizer */
+ /* compatibility. */
+ FT_Bool compatible_widths; /* compatible widths? */
+ FT_Bool symmetrical_smoothing; /* symmetrical_smoothing? */
+ FT_Bool bgr; /* bgr instead of rgb? */
+ FT_Bool subpixel_positioned; /* subpixel positioned */
+ /* (DirectWrite ClearType)? */
+
+ FT_Int rasterizer_version; /* MS rasterizer version */
+
+ FT_Bool iup_called; /* IUP called for glyph? */
+
+ FT_ULong sph_tweak_flags; /* flags to control */
+ /* hint tweaks */
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
} TT_ExecContextRec;
extern const TT_GraphicsState tt_default_graphics_state;
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
FT_LOCAL( FT_Error )
TT_Goto_CodeRange( TT_ExecContext exec,
FT_Int range,
@@ -246,6 +319,7 @@ FT_BEGIN_HEADER
FT_Long multiplier,
void* _pbuff,
FT_ULong new_max );
+#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
/*************************************************************************/
@@ -270,6 +344,8 @@ FT_BEGIN_HEADER
FT_EXPORT( TT_ExecContext )
TT_New_Context( TT_Driver driver );
+
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
FT_LOCAL( FT_Error )
TT_Done_Context( TT_ExecContext exec );
@@ -285,6 +361,7 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
TT_Run_Context( TT_ExecContext exec,
FT_Bool debug );
+#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
/*************************************************************************/
diff --git a/freetype/src/truetype/ttobjs.c b/freetype/src/truetype/ttobjs.c
index 07b0570f1..54fffcb58 100644
--- a/freetype/src/truetype/ttobjs.c
+++ b/freetype/src/truetype/ttobjs.c
@@ -4,7 +4,7 @@
/* */
/* Objects manager (body). */
/* */
-/* Copyright 1996-2011 */
+/* Copyright 1996-2012 */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -764,7 +764,7 @@
exec->threshold = 0;
exec->instruction_trap = FALSE;
- exec->F_dot_P = 0x10000L;
+ exec->F_dot_P = 0x4000L;
exec->pedantic_hinting = pedantic;
@@ -1190,16 +1190,14 @@
size->ttmetrics.scale = metrics->x_scale;
size->ttmetrics.ppem = metrics->x_ppem;
size->ttmetrics.x_ratio = 0x10000L;
- size->ttmetrics.y_ratio = FT_MulDiv( metrics->y_ppem,
- 0x10000L,
+ size->ttmetrics.y_ratio = FT_DivFix( metrics->y_ppem,
metrics->x_ppem );
}
else
{
size->ttmetrics.scale = metrics->y_scale;
size->ttmetrics.ppem = metrics->y_ppem;
- size->ttmetrics.x_ratio = FT_MulDiv( metrics->x_ppem,
- 0x10000L,
+ size->ttmetrics.x_ratio = FT_DivFix( metrics->x_ppem,
metrics->y_ppem );
size->ttmetrics.y_ratio = 0x10000L;
}
diff --git a/freetype/src/truetype/ttobjs.h b/freetype/src/truetype/ttobjs.h
index 149428869..612018eb7 100644
--- a/freetype/src/truetype/ttobjs.h
+++ b/freetype/src/truetype/ttobjs.h
@@ -173,11 +173,12 @@ FT_BEGIN_HEADER
/* */
typedef struct TT_DefRecord_
{
- FT_Int range; /* in which code range is it located? */
- FT_Long start; /* where does it start? */
- FT_Long end; /* where does it end? */
- FT_UInt opc; /* function #, or instruction code */
- FT_Bool active; /* is it active? */
+ FT_Int range; /* in which code range is it located? */
+ FT_Long start; /* where does it start? */
+ FT_Long end; /* where does it end? */
+ FT_UInt opc; /* function #, or instruction code */
+ FT_Bool active; /* is it active? */
+ FT_Bool inline_delta; /* is function that defines inline delta? */
} TT_DefRecord, *TT_DefArray;
@@ -190,7 +191,7 @@ FT_BEGIN_HEADER
{
FT_Fixed xx, xy; /* transformation matrix coefficients */
FT_Fixed yx, yy;
- FT_F26Dot6 ox, oy; /* offsets */
+ FT_F26Dot6 ox, oy; /* offsets */
} TT_Transform;
@@ -333,6 +334,7 @@ FT_BEGIN_HEADER
FT_Bool bytecode_ready;
FT_Bool cvt_ready;
+ FT_Bool ttfautohinted;
#endif /* TT_USE_BYTECODE_INTERPRETER */
@@ -427,6 +429,10 @@ FT_BEGIN_HEADER
tt_slot_init( FT_GlyphSlot slot );
+ /* auxiliary */
+#define IS_HINTED( flags ) ( ( flags & FT_LOAD_NO_HINTING ) == 0 )
+
+
FT_END_HEADER
#endif /* __TTOBJS_H__ */
diff --git a/freetype/src/truetype/ttpic.c b/freetype/src/truetype/ttpic.c
index ada8f1b3c..20bd2e668 100644
--- a/freetype/src/truetype/ttpic.c
+++ b/freetype/src/truetype/ttpic.c
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for truetype module. */
/* */
-/* Copyright 2009, 2010 by */
+/* Copyright 2009, 2010, 2012 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -41,11 +41,12 @@
FT_Init_Class_tt_service_truetype_glyf(
FT_Service_TTGlyfRec* sv_ttglyf );
+
void
tt_driver_class_pic_free( FT_Library library )
{
FT_PIC_Container* pic_container = &library->pic_container;
- FT_Memory memory = library->memory;
+ FT_Memory memory = library->memory;
if ( pic_container->truetype )
@@ -67,7 +68,7 @@
{
FT_PIC_Container* pic_container = &library->pic_container;
FT_Error error = TT_Err_Ok;
- TTModulePIC* container;
+ TTModulePIC* container = NULL;
FT_Memory memory = library->memory;
@@ -77,7 +78,8 @@
FT_MEM_SET( container, 0, sizeof ( *container ) );
pic_container->truetype = container;
- /* initialize pointer table - this is how the module usually expects this data */
+ /* initialize pointer table - this is how the module usually */
+ /* expects this data */
error = FT_Create_Class_tt_services( library,
&container->tt_services );
if ( error )
@@ -88,6 +90,7 @@
#endif
FT_Init_Class_tt_service_truetype_glyf(
&container->tt_service_truetype_glyf );
+
Exit:
if ( error )
tt_driver_class_pic_free( library );
diff --git a/freetype/src/truetype/ttpic.h b/freetype/src/truetype/ttpic.h
index 48f43a5f9..625c9f169 100644
--- a/freetype/src/truetype/ttpic.h
+++ b/freetype/src/truetype/ttpic.h
@@ -4,7 +4,7 @@
/* */
/* The FreeType position independent code services for truetype module. */
/* */
-/* Copyright 2009 by */
+/* Copyright 2009, 2012 by */
/* Oran Agra and Mickey Gabel. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -23,9 +23,10 @@
FT_BEGIN_HEADER
#ifndef FT_CONFIG_OPTION_PIC
-#define FT_TT_SERVICES_GET tt_services
-#define FT_TT_SERVICE_GX_MULTI_MASTERS_GET tt_service_gx_multi_masters
-#define FT_TT_SERVICE_TRUETYPE_GLYF_GET tt_service_truetype_glyf
+
+#define TT_SERVICES_GET tt_services
+#define TT_SERVICE_GX_MULTI_MASTERS_GET tt_service_gx_multi_masters
+#define TT_SERVICE_TRUETYPE_GLYF_GET tt_service_truetype_glyf
#else /* FT_CONFIG_OPTION_PIC */
@@ -33,19 +34,27 @@ FT_BEGIN_HEADER
#include FT_SERVICE_MULTIPLE_MASTERS_H
#include FT_SERVICE_TRUETYPE_GLYF_H
- typedef struct TTModulePIC_
+
+ typedef struct TTModulePIC_
{
- FT_ServiceDescRec* tt_services;
+ FT_ServiceDescRec* tt_services;
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
FT_Service_MultiMastersRec tt_service_gx_multi_masters;
#endif
- FT_Service_TTGlyfRec tt_service_truetype_glyf;
+ FT_Service_TTGlyfRec tt_service_truetype_glyf;
+
} TTModulePIC;
-#define GET_PIC(lib) ((TTModulePIC*)((lib)->pic_container.truetype))
-#define FT_TT_SERVICES_GET (GET_PIC(library)->tt_services)
-#define FT_TT_SERVICE_GX_MULTI_MASTERS_GET (GET_PIC(library)->tt_service_gx_multi_masters)
-#define FT_TT_SERVICE_TRUETYPE_GLYF_GET (GET_PIC(library)->tt_service_truetype_glyf)
+
+#define GET_PIC( lib ) \
+ ( (TTModulePIC*)((lib)->pic_container.truetype) )
+#define TT_SERVICES_GET \
+ ( GET_PIC( library )->tt_services )
+#define TT_SERVICE_GX_MULTI_MASTERS_GET \
+ ( GET_PIC( library )->tt_service_gx_multi_masters )
+#define TT_SERVICE_TRUETYPE_GLYF_GET \
+ ( GET_PIC( library )->tt_service_truetype_glyf )
+
/* see ttpic.c for the implementation */
void
diff --git a/freetype/src/truetype/ttsubpix.c b/freetype/src/truetype/ttsubpix.c
new file mode 100644
index 000000000..d09d3d89d
--- /dev/null
+++ b/freetype/src/truetype/ttsubpix.c
@@ -0,0 +1,265 @@
+/***************************************************************************/
+/* */
+/* ttsubpix.c */
+/* */
+/* TrueType Subpixel Hinting. */
+/* */
+/* Copyright 2010-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. */
+/* */
+/***************************************************************************/
+
+#include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
+#include FT_INTERNAL_CALC_H
+#include FT_INTERNAL_STREAM_H
+#include FT_INTERNAL_SFNT_H
+#include FT_TRUETYPE_TAGS_H
+#include FT_OUTLINE_H
+
+#include "ttsubpix.h"
+
+
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+
+ FT_LOCAL_DEF( FT_Bool )
+ is_member_of_family_class( const FT_String* detected_font_name,
+ const FT_String* rule_font_name )
+ {
+ FT_UInt i, j;
+
+
+ /* Does font name match rule family? */
+ if ( strcmp( detected_font_name, rule_font_name ) == 0 )
+ return TRUE;
+
+ /* Is font name a wildcard ""? */
+ if ( strcmp( rule_font_name, "" ) == 0 )
+ return TRUE;
+
+ /* Is font name contained in a class list? */
+ for ( i = 0; i < FAMILY_CLASS_RULES_SIZE; i++ )
+ {
+ if ( strcmp( FAMILY_CLASS_Rules[i].name, rule_font_name ) == 0 )
+ {
+ for ( j = 0; j < MAX_CLASS_MEMBERS; j++ )
+ {
+ if ( strcmp( FAMILY_CLASS_Rules[i].member[j], "" ) == 0 )
+ continue;
+ if ( strcmp( FAMILY_CLASS_Rules[i].member[j],
+ detected_font_name ) == 0 )
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+ }
+
+
+ FT_LOCAL_DEF( FT_Bool )
+ is_member_of_style_class( const FT_String* detected_font_style,
+ const FT_String* rule_font_style )
+ {
+ FT_UInt i, j;
+
+
+ /* Does font style match rule style? */
+ if ( strcmp( detected_font_style, rule_font_style ) == 0 )
+ return TRUE;
+
+ /* Is font style a wildcard ""? */
+ if ( strcmp( rule_font_style, "" ) == 0 )
+ return TRUE;
+
+ /* Is font style contained in a class list? */
+ for ( i = 0; i < STYLE_CLASS_RULES_SIZE; i++ )
+ {
+ if ( strcmp( STYLE_CLASS_Rules[i].name, rule_font_style ) == 0 )
+ {
+ for ( j = 0; j < MAX_CLASS_MEMBERS; j++ )
+ {
+ if ( strcmp( STYLE_CLASS_Rules[i].member[j], "" ) == 0 )
+ continue;
+ if ( strcmp( STYLE_CLASS_Rules[i].member[j],
+ detected_font_style ) == 0 )
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+ }
+
+
+ FT_LOCAL_DEF( FT_Bool )
+ sph_test_tweak( TT_Face face,
+ FT_String* family,
+ FT_UInt ppem,
+ FT_String* style,
+ FT_UInt glyph_index,
+ SPH_TweakRule* rule,
+ FT_UInt num_rules )
+ {
+ FT_UInt i;
+
+
+ /* rule checks may be able to be optimized further */
+ for ( i = 0; i < num_rules; i++ )
+ {
+ if ( family &&
+ ( is_member_of_family_class ( family, rule[i].family ) ) )
+ if ( rule[i].ppem == 0 ||
+ rule[i].ppem == ppem )
+ if ( style &&
+ is_member_of_style_class ( style, rule[i].style ) )
+ if ( rule[i].glyph == 0 ||
+ FT_Get_Char_Index( (FT_Face)face,
+ rule[i].glyph ) == glyph_index )
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+
+
+ FT_LOCAL_DEF( FT_UInt )
+ scale_test_tweak( TT_Face face,
+ FT_String* family,
+ FT_UInt ppem,
+ FT_String* style,
+ FT_UInt glyph_index,
+ SPH_ScaleRule* rule,
+ FT_UInt num_rules )
+ {
+ FT_UInt i;
+
+
+ /* rule checks may be able to be optimized further */
+ for ( i = 0; i < num_rules; i++ )
+ {
+ if ( family &&
+ ( is_member_of_family_class ( family, rule[i].family ) ) )
+ if ( rule[i].ppem == 0 ||
+ rule[i].ppem == ppem )
+ if ( style &&
+ is_member_of_style_class( style, rule[i].style ) )
+ if ( rule[i].glyph == 0 ||
+ FT_Get_Char_Index( (FT_Face)face,
+ rule[i].glyph ) == glyph_index )
+ return rule[i].scale;
+ }
+
+ return 1000;
+ }
+
+
+#define TWEAK_RULES( x ) \
+ if ( sph_test_tweak( face, family, ppem, style, glyph_index, \
+ x##_Rules, x##_RULES_SIZE ) ) \
+ loader->exec->sph_tweak_flags |= SPH_TWEAK_##x;
+
+#define TWEAK_RULES_EXCEPTIONS( x ) \
+ if ( sph_test_tweak( face, family, ppem, style, glyph_index, \
+ x##_Rules_Exceptions, x##_RULES_EXCEPTIONS_SIZE ) ) \
+ loader->exec->sph_tweak_flags &= ~SPH_TWEAK_##x;
+
+
+ FT_LOCAL_DEF( void )
+ sph_set_tweaks( TT_Loader loader,
+ FT_UInt glyph_index )
+ {
+ TT_Face face = (TT_Face)loader->face;
+ FT_String* family = face->root.family_name;
+ int ppem = loader->size->metrics.x_ppem;
+ FT_String* style = face->root.style_name;
+
+
+ /* don't apply rules if style isn't set */
+ if ( !face->root.style_name )
+ return;
+
+#ifdef SPH_DEBUG_MORE_VERBOSE
+ printf( "%s,%d,%s,%c=%d ",
+ family, ppem, style, glyph_index, glyph_index );
+#endif
+
+ TWEAK_RULES( PIXEL_HINTING );
+
+ if ( loader->exec->sph_tweak_flags & SPH_TWEAK_PIXEL_HINTING )
+ {
+ loader->exec->ignore_x_mode = FALSE;
+ return;
+ }
+
+ TWEAK_RULES( ALLOW_X_DMOVE );
+ TWEAK_RULES( ALLOW_X_DMOVEX );
+ TWEAK_RULES( ALLOW_X_MOVE_ZP2 );
+ TWEAK_RULES( ALWAYS_DO_DELTAP );
+ TWEAK_RULES( ALWAYS_SKIP_DELTAP );
+ TWEAK_RULES( DEEMBOLDEN );
+ TWEAK_RULES( DELTAP_SKIP_EXAGGERATED_VALUES );
+ TWEAK_RULES( DO_SHPIX );
+ TWEAK_RULES( EMBOLDEN );
+ TWEAK_RULES( MIAP_HACK );
+ TWEAK_RULES( NORMAL_ROUND );
+ TWEAK_RULES( NO_ALIGNRP_AFTER_IUP );
+ TWEAK_RULES( NO_CALL_AFTER_IUP );
+ TWEAK_RULES( NO_DELTAP_AFTER_IUP );
+ TWEAK_RULES( RASTERIZER_35 );
+ TWEAK_RULES( SKIP_INLINE_DELTAS );
+ TWEAK_RULES( SKIP_IUP );
+ TWEAK_RULES( MIRP_CVT_ZERO );
+
+ TWEAK_RULES( SKIP_OFFPIXEL_Y_MOVES );
+ TWEAK_RULES_EXCEPTIONS( SKIP_OFFPIXEL_Y_MOVES );
+
+ TWEAK_RULES( SKIP_NONPIXEL_Y_MOVES );
+ TWEAK_RULES_EXCEPTIONS( SKIP_NONPIXEL_Y_MOVES );
+
+ TWEAK_RULES( ROUND_NONPIXEL_Y_MOVES );
+ TWEAK_RULES_EXCEPTIONS( ROUND_NONPIXEL_Y_MOVES );
+
+ if ( loader->exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 )
+ loader->exec->rasterizer_version = 35;
+ else
+ loader->exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION;
+
+ /* re-execute fpgm always to avoid problems */
+ loader->exec->size->cvt_ready = FALSE;
+ tt_size_ready_bytecode( loader->exec->size,
+ FT_BOOL( loader->load_flags & FT_LOAD_PEDANTIC ) );
+
+ if ( IS_HINTED( loader->load_flags ) )
+ {
+ TWEAK_RULES( TIMES_NEW_ROMAN_HACK );
+ TWEAK_RULES( COURIER_NEW_2_HACK );
+ }
+
+ if ( sph_test_tweak( face, family, ppem, style, glyph_index,
+ COMPATIBILITY_MODE_Rules, COMPATIBILITY_MODE_RULES_SIZE ) )
+ {
+ loader->exec->compatibility_mode |= TRUE;
+ loader->exec->ignore_x_mode |= TRUE;
+ }
+ else
+ loader->exec->compatibility_mode &= FALSE;
+
+ if ( IS_HINTED( loader->load_flags ) )
+ {
+ if ( sph_test_tweak( face, family, ppem, style, glyph_index,
+ COMPATIBLE_WIDTHS_Rules, COMPATIBLE_WIDTHS_RULES_SIZE ) )
+ loader->exec->compatible_widths |= TRUE;
+ }
+ }
+
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
+
+/* END */
diff --git a/freetype/src/truetype/ttsubpix.h b/freetype/src/truetype/ttsubpix.h
new file mode 100644
index 000000000..2fbff2681
--- /dev/null
+++ b/freetype/src/truetype/ttsubpix.h
@@ -0,0 +1,908 @@
+/***************************************************************************/
+/* */
+/* ttsubpix.h */
+/* */
+/* TrueType Subpixel Hinting. */
+/* */
+/* Copyright 2010-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 __TTSUBPIX_H__
+#define __TTSUBPIX_H__
+
+#include <ft2build.h>
+#include "ttobjs.h"
+#include "ttinterp.h"
+
+
+FT_BEGIN_HEADER
+
+
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+
+ /*************************************************************************/
+ /* */
+ /* Tweak flags that are set for each glyph by the below rules. */
+ /* */
+ /* */
+#define SPH_TWEAK_ALLOW_X_DMOVE 0x0000001
+#define SPH_TWEAK_ALLOW_X_DMOVEX 0x0000002
+#define SPH_TWEAK_ALLOW_X_MOVE_ZP2 0x0000004
+#define SPH_TWEAK_ALWAYS_DO_DELTAP 0x0000008
+#define SPH_TWEAK_ALWAYS_SKIP_DELTAP 0x0000010
+#define SPH_TWEAK_COURIER_NEW_2_HACK 0x0000020
+#define SPH_TWEAK_DEEMBOLDEN 0x0000040
+#define SPH_TWEAK_DELTAP_SKIP_EXAGGERATED_VALUES 0x0000080
+#define SPH_TWEAK_DO_SHPIX 0x0000100
+#define SPH_TWEAK_EMBOLDEN 0x0000200
+#define SPH_TWEAK_MIAP_HACK 0x0000400
+#define SPH_TWEAK_NORMAL_ROUND 0x0000800
+#define SPH_TWEAK_NO_ALIGNRP_AFTER_IUP 0x0001000
+#define SPH_TWEAK_NO_CALL_AFTER_IUP 0x0002000
+#define SPH_TWEAK_NO_DELTAP_AFTER_IUP 0x0004000
+#define SPH_TWEAK_PIXEL_HINTING 0x0008000
+#define SPH_TWEAK_RASTERIZER_35 0x0010000
+#define SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES 0x0020000
+#define SPH_TWEAK_SKIP_INLINE_DELTAS 0x0040000
+#define SPH_TWEAK_SKIP_IUP 0x0080000
+#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES 0x0100000
+#define SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES 0x0200000
+#define SPH_TWEAK_TIMES_NEW_ROMAN_HACK 0x0400000
+#define SPH_TWEAK_MIRP_CVT_ZERO 0x0800000
+
+
+ FT_LOCAL( FT_Bool )
+ sph_test_tweak( TT_Face face,
+ FT_String* family,
+ FT_UInt ppem,
+ FT_String* style,
+ FT_UInt glyph_index,
+ SPH_TweakRule* rule,
+ FT_UInt num_rules );
+
+ FT_LOCAL_DEF( FT_UInt )
+ scale_test_tweak( TT_Face face,
+ FT_String* family,
+ FT_UInt ppem,
+ FT_String* style,
+ FT_UInt glyph_index,
+ SPH_ScaleRule* rule,
+ FT_UInt num_rules );
+
+ FT_LOCAL( void )
+ sph_set_tweaks( TT_Loader loader,
+ FT_UInt glyph_index );
+
+
+ /*************************************************************************/
+ /* */
+ /* These rules affect how the TT Interpreter does hinting, with the */
+ /* goal of doing subpixel hinting by (in general) ignoring x moves. */
+ /* Some of these rules are fixes that go above and beyond the */
+ /* stated techniques in the MS whitepaper on Cleartype, due to */
+ /* artifacts in many glyphs. So, these rules make some glyphs render */
+ /* better than they do in the MS rasterizer. */
+ /* */
+ /* "" string or 0 int/char indicates to apply to all glyphs. */
+ /* "-" used as dummy placeholders, but any non-matching string works. */
+ /* */
+ /* Some of this could arguably be implemented in fontconfig, however: */
+ /* */
+ /* - Fontconfig can't set things on a glyph-by-glyph basis. */
+ /* - The tweaks that happen here are very low-level, from an average */
+ /* user's point of view and are best implemented in the hinter. */
+ /* */
+ /* The goal is to make the subpixel hinting techniques as generalized */
+ /* as possible across all fonts to prevent the need for extra rules such */
+ /* as these. */
+ /* */
+ /* The rule structure is designed so that entirely new rules can easily */
+ /* be added when a new compatibility feature is discovered. */
+ /* */
+ /* The rule structures could also use some enhancement to handle ranges. */
+ /* */
+ /* ****************** WORK IN PROGRESS ******************* */
+ /* */
+
+ /* These macros are defined absent a method for setting them */
+#define SPH_OPTION_BITMAP_WIDTHS FALSE
+#define SPH_OPTION_SET_SUBPIXEL TRUE
+#define SPH_OPTION_SET_GRAYSCALE FALSE
+#define SPH_OPTION_SET_COMPATIBLE_WIDTHS FALSE
+#define SPH_OPTION_SET_RASTERIZER_VERSION 38
+
+
+ /* Define this to force natural (i.e. not bitmap-compatible) widths. */
+ /* The default leans strongly towards natural widths except for a few */
+ /* legacy fonts where a selective combination produces nicer results. */
+/* #define FORCE_NATURAL_WIDTHS */
+
+
+ /* These are `classes' of fonts that can be grouped together and used in */
+ /* rules below. A blank entry "" is required at the end of these! */
+#define FAMILY_CLASS_RULES_SIZE 7
+
+ Font_Class FAMILY_CLASS_Rules
+ [FAMILY_CLASS_RULES_SIZE] =
+ {
+ { "MS Legacy Fonts",
+ { "Aharoni",
+ "Andale Mono",
+ "Andalus",
+ "Angsana New",
+ "AngsanaUPC",
+ "Arabic Transparent",
+ "Arial Black",
+ "Arial Narrow",
+ "Arial Unicode MS",
+ "Arial",
+ "Batang",
+ "Browallia New",
+ "BrowalliaUPC",
+ "Comic Sans MS",
+ "Cordia New",
+ "CordiaUPC",
+ "Courier New",
+ "DFKai-SB",
+ "David Transparent",
+ "David",
+ "DilleniaUPC",
+ "Estrangelo Edessa",
+ "EucrosiaUPC",
+ "FangSong_GB2312",
+ "Fixed Miriam Transparent",
+ "FrankRuehl",
+ "Franklin Gothic Medium",
+ "FreesiaUPC",
+ "Garamond",
+ "Gautami",
+ "Georgia",
+ "Gulim",
+ "Impact",
+ "IrisUPC",
+ "JasmineUPC",
+ "KaiTi_GB2312",
+ "KodchiangUPC",
+ "Latha",
+ "Levenim MT",
+ "LilyUPC",
+ "Lucida Console",
+ "Lucida Sans Unicode",
+ "MS Gothic",
+ "MS Mincho",
+ "MV Boli",
+ "Mangal",
+ "Marlett",
+ "Microsoft Sans Serif",
+ "Mingliu",
+ "Miriam Fixed",
+ "Miriam Transparent",
+ "Miriam",
+ "Narkisim",
+ "Palatino Linotype",
+ "Raavi",
+ "Rod Transparent",
+ "Rod",
+ "Shruti",
+ "SimHei",
+ "Simplified Arabic Fixed",
+ "Simplified Arabic",
+ "Simsun",
+ "Sylfaen",
+ "Symbol",
+ "Tahoma",
+ "Times New Roman",
+ "Traditional Arabic",
+ "Trebuchet MS",
+ "Tunga",
+ "Verdana",
+ "Webdings",
+ "Wingdings",
+ "",
+ },
+ },
+ { "Core MS Legacy Fonts",
+ { "Arial Black",
+ "Arial Narrow",
+ "Arial Unicode MS",
+ "Arial",
+ "Comic Sans MS",
+ "Courier New",
+ "Garamond",
+ "Georgia",
+ "Impact",
+ "Lucida Console",
+ "Lucida Sans Unicode",
+ "Microsoft Sans Serif",
+ "Palatino Linotype",
+ "Tahoma",
+ "Times New Roman",
+ "Trebuchet MS",
+ "Verdana",
+ "",
+ },
+ },
+ { "Apple Legacy Fonts",
+ { "Geneva",
+ "Times",
+ "Monaco",
+ "Century",
+ "Chalkboard",
+ "Lobster",
+ "Century Gothic",
+ "Optima",
+ "Lucida Grande",
+ "Gill Sans",
+ "Baskerville",
+ "Helvetica",
+ "Helvetica Neue",
+ "",
+ },
+ },
+ { "Legacy Sans Fonts",
+ { "Andale Mono",
+ "Arial Unicode MS",
+ "Arial",
+ "Century Gothic",
+ "Comic Sans MS",
+ "Franklin Gothic Medium",
+ "Geneva",
+ "Lucida Console",
+ "Lucida Grande",
+ "Lucida Sans Unicode",
+ "Lucida Sans Typewriter",
+ "Microsoft Sans Serif",
+ "Monaco",
+ "Tahoma",
+ "Trebuchet MS",
+ "Verdana",
+ "",
+ },
+ },
+
+ { "Misc Legacy Fonts",
+ { "Dark Courier", "", }, },
+ { "Verdana Clones",
+ { "DejaVu Sans",
+ "Bitstream Vera Sans", "", }, },
+ { "Verdana and Clones",
+ { "DejaVu Sans",
+ "Bitstream Vera Sans",
+ "Verdana", "", }, },
+ };
+
+
+ /* Define `classes' of styles that can be grouped together and used in */
+ /* rules below. A blank entry "" is required at the end of these! */
+#define STYLE_CLASS_RULES_SIZE 5
+
+ Font_Class STYLE_CLASS_Rules
+ [STYLE_CLASS_RULES_SIZE] =
+ {
+ { "Regular Class",
+ { "Regular",
+ "Book",
+ "Medium",
+ "Roman",
+ "Normal",
+ "",
+ },
+ },
+ { "Regular/Italic Class",
+ { "Regular",
+ "Book",
+ "Medium",
+ "Italic",
+ "Oblique",
+ "Roman",
+ "Normal",
+ "",
+ },
+ },
+ { "Bold/BoldItalic Class",
+ { "Bold",
+ "Bold Italic",
+ "Black",
+ "",
+ },
+ },
+ { "Bold/Italic/BoldItalic Class",
+ { "Bold",
+ "Bold Italic",
+ "Black",
+ "Italic",
+ "Oblique",
+ "",
+ },
+ },
+ { "Regular/Bold Class",
+ { "Regular",
+ "Book",
+ "Medium",
+ "Normal",
+ "Roman",
+ "Bold",
+ "Black",
+ "",
+ },
+ },
+ };
+
+
+ /* Special fixes for known legacy fonts; */
+ /* this is the primary workhorse rule for legacy fonts */
+#define COMPATIBILITY_MODE_RULES_SIZE 4
+
+ SPH_TweakRule COMPATIBILITY_MODE_Rules
+ [COMPATIBILITY_MODE_RULES_SIZE] =
+ {
+ { "MS Legacy Fonts", 0, "", 0 },
+ { "Apple Legacy Fonts", 0, "", 0 },
+ { "Misc Legacy Fonts", 0, "", 0 },
+ { "Verdana Clones", 0, "", 0 },
+ };
+
+
+ /* Don't do subpixel (ignore_x_mode) hinting; do normal hinting. */
+#define PIXEL_HINTING_RULES_SIZE 4
+
+ SPH_TweakRule PIXEL_HINTING_Rules
+ [PIXEL_HINTING_RULES_SIZE] =
+ {
+ /* these characters are almost always safe */
+ { "", 0, "", '<' },
+ { "", 0, "", '>' },
+ /* fixes the vanishing stem */
+ { "Times New Roman", 0, "Bold", 'A' },
+ { "Times New Roman", 0, "Bold", 'V' },
+ };
+
+
+ /* According to Greg Hitchcock and the MS whitepaper, this should work */
+ /* on all legacy MS fonts, but creates artifacts with some. Only using */
+ /* where absolutely necessary. */
+#define SKIP_INLINE_DELTAS_RULES_SIZE 1
+
+ SPH_TweakRule SKIP_INLINE_DELTAS_Rules
+ [SKIP_INLINE_DELTAS_RULES_SIZE] =
+ {
+ { "-", 0, "", 0 },
+ };
+
+
+ /* Subpixel hinting ignores SHPIX rules on X. Force SHPIX for these. */
+#define DO_SHPIX_RULES_SIZE 1
+
+ SPH_TweakRule DO_SHPIX_Rules
+ [DO_SHPIX_RULES_SIZE] =
+ {
+ { "-", 0, "", 0 },
+ };
+
+
+ /* Skip Y moves that start with a point that is not on a Y pixel */
+ /* boundary and don't move that point to a Y pixel boundary. */
+#define SKIP_NONPIXEL_Y_MOVES_RULES_SIZE 10
+
+ SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules
+ [SKIP_NONPIXEL_Y_MOVES_RULES_SIZE] =
+ {
+ /* fix vwxyz thinness*/
+ { "Consolas", 0, "Regular", 0 },
+ /* fix tiny gap at top of m */
+ { "Arial", 0, "Regular", 'm' },
+ /* Fix thin middle stems */
+ { "Core MS Legacy Fonts", 0, "Regular/Bold Class", 'N' },
+ { "Lucida Grande", 0, "", 'N' },
+ { "Lucida Grande", 0, "Bold", 'y' },
+ /* Cyrillic small letter I */
+ { "Legacy Sans Fonts", 0, "", 0x438 },
+ { "Verdana Clones", 0, "",'N' },
+ { "Ubuntu", 0, "Regular Class", 'N' },
+ /* Fix misshapen x */
+ { "Verdana", 0, "Bold", 'x' },
+ /* Fix misshapen s */
+ { "Tahoma", 0, "", 's' },
+ };
+
+
+#define SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 6
+
+ SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules_Exceptions
+ [SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
+ {
+ { "Tahoma", 0, "", 'N' },
+ { "Comic Sans MS", 0, "", 'N' },
+ { "Verdana", 0, "Regular/Bold Class", 'N' },
+ { "Verdana", 11, "Bold", 'x' },
+ /* Cyrillic small letter I */
+ { "Arial", 0, "", 0x438 },
+ { "Trebuchet MS", 0, "Bold", 0 },
+ };
+
+
+ /* Skip Y moves that move a point off a Y pixel boundary. */
+ /* This fixes Tahoma, Trebuchet oddities and some issues with `$'. */
+#define SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE 5
+
+ SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules
+ [SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE] =
+ {
+ { "MS Legacy Fonts", 0, "", 0 },
+ { "Apple Legacy Fonts", 0, "", 0 },
+ { "Misc Legacy Fonts", 0, "", 0 },
+ { "Ubuntu", 0, "Regular Class", 0 },
+ { "Verdana Clones", 0, "", 0 },
+ };
+
+
+#define SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 1
+
+ SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules_Exceptions
+ [SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
+ {
+ { "-", 0, "", 0 },
+ };
+
+
+ /* Round moves that don't move a point to a Y pixel boundary. */
+#define ROUND_NONPIXEL_Y_MOVES_RULES_SIZE 3
+
+ SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules
+ [ROUND_NONPIXEL_Y_MOVES_RULES_SIZE] =
+ {
+ /* Droid font instructions don't snap Y to pixels */
+ { "Droid Sans", 0, "Regular/Italic Class", 0 },
+ { "Droid Sans Mono", 0, "", 0 },
+ { "Ubuntu", 0, "", 0 },
+ };
+
+
+#define ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 3
+
+ SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules_Exceptions
+ [ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
+ {
+ { "Droid Sans", 12, "Bold", 0 },
+ { "Droid Sans", 13, "Bold", 0 },
+ { "Droid Sans", 16, "Bold", 0 },
+ };
+
+
+ /* Allow a Direct_Move_X along X freedom vector if matched. */
+#define ALLOW_X_DMOVEX_RULES_SIZE 1
+
+ SPH_TweakRule ALLOW_X_DMOVEX_Rules
+ [ALLOW_X_DMOVEX_RULES_SIZE] =
+ {
+ { "-", 0, "Regular", 0 },
+ };
+
+
+ /* Allow a Direct_Move along X freedom vector if matched. */
+#define ALLOW_X_DMOVE_RULES_SIZE 1
+
+ SPH_TweakRule ALLOW_X_DMOVE_Rules
+ [ALLOW_X_DMOVE_RULES_SIZE] =
+ {
+ /* Fixes vanishing diagonal in 4 */
+ { "Verdana", 0, "Regular", '4' },
+ };
+
+
+ /* Allow a ZP2 move along freedom vector if matched; */
+ /* This is called from SHP, SHPIX, SHC, SHZ. */
+#define ALLOW_X_MOVE_ZP2_RULES_SIZE 1
+
+ SPH_TweakRule ALLOW_X_MOVE_ZP2_Rules
+ [ALLOW_X_MOVE_ZP2_RULES_SIZE] =
+ {
+ { "-", 0, "", 0 },
+ };
+
+
+ /* Return MS rasterizer version 35 if matched. */
+#define RASTERIZER_35_RULES_SIZE 8
+
+ SPH_TweakRule RASTERIZER_35_Rules
+ [RASTERIZER_35_RULES_SIZE] =
+ {
+ /* This seems to be the only way to make these look good */
+ { "Times New Roman", 0, "Regular", 'i' },
+ { "Times New Roman", 0, "Regular", 'j' },
+ { "Times New Roman", 0, "Regular", 'm' },
+ { "Times New Roman", 0, "Regular", 'r' },
+ { "Times New Roman", 0, "Regular", 'a' },
+ { "Times New Roman", 0, "Regular", 'n' },
+ { "Times New Roman", 0, "Regular", 'p' },
+ { "Times", 0, "", 0 },
+ };
+
+
+ /* Don't round to the subpixel grid. Round to pixel grid. */
+#define NORMAL_ROUND_RULES_SIZE 2
+
+ SPH_TweakRule NORMAL_ROUND_Rules
+ [NORMAL_ROUND_RULES_SIZE] =
+ {
+ /* Fix point "explosions" */
+ { "Courier New", 0, "", 0 },
+ { "Verdana", 10, "Regular", '4' },
+ };
+
+
+ /* Skip IUP instructions if matched. */
+#define SKIP_IUP_RULES_SIZE 1
+
+ SPH_TweakRule SKIP_IUP_Rules
+ [SKIP_IUP_RULES_SIZE] =
+ {
+ { "Arial", 13, "Regular", 'a' },
+ };
+
+
+ /* Skip MIAP Twilight hack if matched. */
+#define MIAP_HACK_RULES_SIZE 1
+
+ SPH_TweakRule MIAP_HACK_Rules
+ [MIAP_HACK_RULES_SIZE] =
+ {
+ { "Geneva", 12, "", 0 },
+ };
+
+
+ /* Skip DELTAP instructions if matched. */
+#define ALWAYS_SKIP_DELTAP_RULES_SIZE 16
+
+ SPH_TweakRule ALWAYS_SKIP_DELTAP_Rules
+ [ALWAYS_SKIP_DELTAP_RULES_SIZE] =
+ {
+ { "Georgia", 0, "Regular", 'k' },
+ /* fixes problems with W M w */
+ { "Trebuchet MS", 0, "Italic", 0 },
+ /* fix various problems with e in different versions */
+ { "Trebuchet MS", 14, "Regular", 'e' },
+ { "Trebuchet MS", 13, "Regular", 'e' },
+ { "Trebuchet MS", 15, "Regular", 'e' },
+ { "Arial", 11, "Regular", 's' },
+ { "Verdana", 10, "Regular", 0 },
+ { "Verdana", 9, "Regular", 0 },
+ /* Cyrillic small letter short I */
+ { "Legacy Sans Fonts", 0, "", 0x438 },
+ { "Legacy Sans Fonts", 0, "", 0x439 },
+ { "Arial", 10, "Regular", '6' },
+ { "Arial", 0, "Bold/BoldItalic Class", 'a' },
+ /* Make horizontal stems consistent with the rest */
+ { "Arial", 24, "Bold", 's' },
+ { "Arial", 25, "Bold", 's' },
+ { "Arial", 24, "Bold", 'a' },
+ { "Arial", 25, "Bold", 'a' },
+ };
+
+
+ /* Always do DELTAP instructions if matched. */
+#define ALWAYS_DO_DELTAP_RULES_SIZE 2
+
+ SPH_TweakRule ALWAYS_DO_DELTAP_Rules
+ [ALWAYS_DO_DELTAP_RULES_SIZE] =
+ {
+ { "Verdana Clones", 17, "Regular Class", 'K' },
+ { "Verdana Clones", 17, "Regular Class", 'k' },
+ };
+
+
+ /* Do an extra RTG instruction in DELTAP if matched. */
+#define DELTAP_RTG_RULES_SIZE 1
+
+ SPH_TweakRule DELTAP_RTG_Rules
+ [DELTAP_RTG_RULES_SIZE] =
+ {
+ { "-", 0, "", 0 },
+ };
+
+
+ /* Force CVT distance to zero in MIRP. */
+#define MIRP_CVT_ZERO_RULES_SIZE 1
+
+ SPH_TweakRule MIRP_CVT_ZERO_Rules
+ [MIRP_CVT_ZERO_RULES_SIZE] =
+ {
+ { "-", 0, "", 0 },
+ };
+
+
+ /* Skip moves that meet or exceed 1 pixel. */
+#define DELTAP_SKIP_EXAGGERATED_VALUES_RULES_SIZE 1
+
+ SPH_TweakRule DELTAP_SKIP_EXAGGERATED_VALUES_Rules
+ [DELTAP_SKIP_EXAGGERATED_VALUES_RULES_SIZE] =
+ {
+ /* Fix vanishing stems */
+ { "Ubuntu", 0, "Regular", 'M' },
+ };
+
+
+ /* Don't allow ALIGNRP after IUP. */
+#define NO_ALIGNRP_AFTER_IUP_RULES_SIZE 4
+
+ SPH_TweakRule NO_ALIGNRP_AFTER_IUP_Rules
+ [NO_ALIGNRP_AFTER_IUP_RULES_SIZE] =
+ {
+ /* Prevent creation of dents in outline */
+ { "Courier New", 0, "Bold", 'C' },
+ { "Courier New", 0, "Bold", 'D' },
+ { "Courier New", 0, "Bold", 'Q' },
+ { "Courier New", 0, "Bold", '0' },
+ };
+
+
+ /* Don't allow DELTAP after IUP. */
+#define NO_DELTAP_AFTER_IUP_RULES_SIZE 2
+
+ SPH_TweakRule NO_DELTAP_AFTER_IUP_Rules
+ [NO_DELTAP_AFTER_IUP_RULES_SIZE] =
+ {
+ { "Arial", 0, "Bold", 'N' },
+ { "Verdana", 0, "Regular", '4' },
+ };
+
+
+ /* Don't allow CALL after IUP. */
+#define NO_CALL_AFTER_IUP_RULES_SIZE 4
+
+ SPH_TweakRule NO_CALL_AFTER_IUP_Rules
+ [NO_CALL_AFTER_IUP_RULES_SIZE] =
+ {
+ /* Prevent creation of dents in outline */
+ { "Courier New", 0, "Bold", 'O' },
+ { "Courier New", 0, "Bold", 'Q' },
+ { "Courier New", 0, "Bold", 'k' },
+ { "Courier New", 0, "Bold Italic", 'M' },
+ };
+
+
+ /* De-embolden these glyphs slightly. */
+#define DEEMBOLDEN_RULES_SIZE 9
+
+ SPH_TweakRule DEEMBOLDEN_Rules
+ [DEEMBOLDEN_RULES_SIZE] =
+ {
+ { "Courier New", 0, "Bold", 'A' },
+ { "Courier New", 0, "Bold", 'W' },
+ { "Courier New", 0, "Bold", 'w' },
+ { "Courier New", 0, "Bold", 'M' },
+ { "Courier New", 0, "Bold", 'X' },
+ { "Courier New", 0, "Bold", 'K' },
+ { "Courier New", 0, "Bold", 'x' },
+ { "Courier New", 0, "Bold", 'z' },
+ { "Courier New", 0, "Bold", 'v' },
+ };
+
+
+ /* Embolden these glyphs slightly. */
+#define EMBOLDEN_RULES_SIZE 5
+
+ SPH_TweakRule EMBOLDEN_Rules
+ [EMBOLDEN_RULES_SIZE] =
+ {
+ { "Courier New", 12, "Italic", 'z' },
+ { "Courier New", 11, "Italic", 'z' },
+ { "Courier New", 10, "Italic", 'z' },
+ { "Courier New", 0, "Regular", 0 },
+ { "Courier New", 0, "Italic", 0 },
+ };
+
+
+ /* Do an extra RDTG instruction in DELTAP if matched. */
+#define DELTAP_RDTG_RULES_SIZE 1
+
+ SPH_TweakRule DELTAP_RDTG_Rules
+ [DELTAP_RDTG_RULES_SIZE] =
+ {
+ { "-", 0, "", 0 },
+ };
+
+
+ /* This is a CVT hack that makes thick horizontal stems on 2, 5, 7 */
+ /* similar to Windows XP. */
+#define TIMES_NEW_ROMAN_HACK_RULES_SIZE 12
+
+ SPH_TweakRule TIMES_NEW_ROMAN_HACK_Rules
+ [TIMES_NEW_ROMAN_HACK_RULES_SIZE] =
+ {
+ { "Times New Roman", 16, "Italic", '2' },
+ { "Times New Roman", 16, "Italic", '5' },
+ { "Times New Roman", 16, "Italic", '7' },
+ { "Times New Roman", 16, "Regular", '2' },
+ { "Times New Roman", 16, "Regular", '5' },
+ { "Times New Roman", 16, "Regular", '7' },
+ { "Times New Roman", 17, "Italic", '2' },
+ { "Times New Roman", 17, "Italic", '5' },
+ { "Times New Roman", 17, "Italic", '7' },
+ { "Times New Roman", 17, "Regular", '2' },
+ { "Times New Roman", 17, "Regular", '5' },
+ { "Times New Roman", 17, "Regular", '7' },
+ };
+
+
+ /* This fudges distance on 2 to get rid of the vanishing stem issue. */
+ /* A real solution to this is certainly welcome. */
+#define COURIER_NEW_2_HACK_RULES_SIZE 15
+
+ SPH_TweakRule COURIER_NEW_2_HACK_Rules
+ [COURIER_NEW_2_HACK_RULES_SIZE] =
+ {
+ { "Courier New", 10, "Regular", '2' },
+ { "Courier New", 11, "Regular", '2' },
+ { "Courier New", 12, "Regular", '2' },
+ { "Courier New", 13, "Regular", '2' },
+ { "Courier New", 14, "Regular", '2' },
+ { "Courier New", 15, "Regular", '2' },
+ { "Courier New", 16, "Regular", '2' },
+ { "Courier New", 17, "Regular", '2' },
+ { "Courier New", 18, "Regular", '2' },
+ { "Courier New", 19, "Regular", '2' },
+ { "Courier New", 20, "Regular", '2' },
+ { "Courier New", 21, "Regular", '2' },
+ { "Courier New", 22, "Regular", '2' },
+ { "Courier New", 23, "Regular", '2' },
+ { "Courier New", 24, "Regular", '2' },
+ };
+
+
+#ifndef FORCE_NATURAL_WIDTHS
+
+ /* Use compatible widths with these glyphs. Compatible widths is always */
+ /* on when doing B/W TrueType instructing, but is used selectively here, */
+ /* typically on glyphs with 3 or more vertical stems. */
+#define COMPATIBLE_WIDTHS_RULES_SIZE 38
+
+ SPH_TweakRule COMPATIBLE_WIDTHS_Rules
+ [COMPATIBLE_WIDTHS_RULES_SIZE] =
+ {
+ { "Arial Unicode MS", 12, "Regular Class", 'm' },
+ { "Arial Unicode MS", 14, "Regular Class", 'm' },
+ /* Cyrillic small letter sha */
+ { "Arial", 10, "Regular Class", 0x448 },
+ { "Arial", 11, "Regular Class", 'm' },
+ { "Arial", 12, "Regular Class", 'm' },
+ /* Cyrillic small letter sha */
+ { "Arial", 12, "Regular Class", 0x448 },
+ { "Arial", 13, "Regular Class", 0x448 },
+ { "Arial", 14, "Regular Class", 'm' },
+ /* Cyrillic small letter sha */
+ { "Arial", 14, "Regular Class", 0x448 },
+ { "Arial", 15, "Regular Class", 0x448 },
+ { "Arial", 17, "Regular Class", 'm' },
+ { "DejaVu Sans", 15, "Regular Class", 0 },
+ { "Microsoft Sans Serif", 11, "Regular Class", 0 },
+ { "Microsoft Sans Serif", 12, "Regular Class", 0 },
+ { "Segoe UI", 11, "Regular Class", 0 },
+ { "Monaco", 0, "Regular Class", 0 },
+ { "Segoe UI", 12, "Regular Class", 'm' },
+ { "Segoe UI", 14, "Regular Class", 'm' },
+ { "Tahoma", 11, "Regular Class", 0 },
+ { "Times New Roman", 16, "Regular Class", 'c' },
+ { "Times New Roman", 16, "Regular Class", 'm' },
+ { "Times New Roman", 16, "Regular Class", 'o' },
+ { "Times New Roman", 16, "Regular Class", 'w' },
+ { "Trebuchet MS", 11, "Regular Class", 0 },
+ { "Trebuchet MS", 12, "Regular Class", 0 },
+ { "Trebuchet MS", 14, "Regular Class", 0 },
+ { "Trebuchet MS", 15, "Regular Class", 0 },
+ { "Ubuntu", 12, "Regular Class", 'm' },
+ /* Cyrillic small letter sha */
+ { "Verdana", 10, "Regular Class", 0x448 },
+ { "Verdana", 11, "Regular Class", 0x448 },
+ { "Verdana and Clones", 12, "Regular Class", 'i' },
+ { "Verdana and Clones", 12, "Regular Class", 'j' },
+ { "Verdana and Clones", 12, "Regular Class", 'l' },
+ { "Verdana and Clones", 12, "Regular Class", 'm' },
+ { "Verdana and Clones", 13, "Regular Class", 'i' },
+ { "Verdana and Clones", 13, "Regular Class", 'j' },
+ { "Verdana and Clones", 13, "Regular Class", 'l' },
+ { "Verdana and Clones", 14, "Regular Class", 'm' },
+ };
+
+
+ /* Scaling slightly in the x-direction prior to hinting results in */
+ /* more visually pleasing glyphs in certain cases. */
+ /* This sometimes needs to be coordinated with compatible width rules. */
+ /* A value of 1000 corresponds to a scaled value of 1.0. */
+#define X_SCALING_RULES_SIZE 50
+
+ SPH_ScaleRule X_SCALING_Rules
+ [X_SCALING_RULES_SIZE] =
+ {
+ { "DejaVu Sans", 12, "Regular Class", 'm', 950 },
+ { "Verdana and Clones", 12, "Regular Class", 'a', 1100 },
+ { "Verdana and Clones", 13, "Regular Class", 'a', 1050 },
+ { "Arial", 11, "Regular Class", 'm', 975 },
+ { "Arial", 12, "Regular Class", 'm', 1050 },
+ /* Cyrillic small letter el */
+ { "Arial", 13, "Regular Class", 0x43B, 950 },
+ { "Arial", 13, "Regular Class", 'o', 950 },
+ { "Arial", 13, "Regular Class", 'e', 950 },
+ { "Arial", 14, "Regular Class", 'm', 950 },
+ /* Cyrillic small letter el */
+ { "Arial", 15, "Regular Class", 0x43B, 925 },
+ { "Bitstream Vera Sans", 10, "Regular/Italic Class", 0, 1100 },
+ { "Bitstream Vera Sans", 12, "Regular/Italic Class", 0, 1050 },
+ { "Bitstream Vera Sans", 16, "Regular Class", 0, 1050 },
+ { "Bitstream Vera Sans", 9, "Regular/Italic Class", 0, 1050 },
+ { "DejaVu Sans", 12, "Regular Class", 'l', 975 },
+ { "DejaVu Sans", 12, "Regular Class", 'i', 975 },
+ { "DejaVu Sans", 12, "Regular Class", 'j', 975 },
+ { "DejaVu Sans", 13, "Regular Class", 'l', 950 },
+ { "DejaVu Sans", 13, "Regular Class", 'i', 950 },
+ { "DejaVu Sans", 13, "Regular Class", 'j', 950 },
+ { "DejaVu Sans", 10, "Regular/Italic Class", 0, 1100 },
+ { "DejaVu Sans", 12, "Regular/Italic Class", 0, 1050 },
+ { "Georgia", 10, "", 0, 1050 },
+ { "Georgia", 11, "", 0, 1100 },
+ { "Georgia", 12, "", 0, 1025 },
+ { "Georgia", 13, "", 0, 1050 },
+ { "Georgia", 16, "", 0, 1050 },
+ { "Georgia", 17, "", 0, 1030 },
+ { "Liberation Sans", 12, "Regular Class", 'm', 1100 },
+ { "Lucida Grande", 11, "Regular Class", 'm', 1100 },
+ { "Microsoft Sans Serif", 11, "Regular Class", 'm', 950 },
+ { "Microsoft Sans Serif", 12, "Regular Class", 'm', 1050 },
+ { "Segoe UI", 12, "Regular Class", 'H', 1050 },
+ { "Segoe UI", 12, "Regular Class", 'm', 1050 },
+ { "Segoe UI", 14, "Regular Class", 'm', 1050 },
+ { "Tahoma", 11, "Regular Class", 'i', 975 },
+ { "Tahoma", 11, "Regular Class", 'l', 975 },
+ { "Tahoma", 11, "Regular Class", 'j', 900 },
+ { "Tahoma", 11, "Regular Class", 'm', 918 },
+ { "Verdana", 10, "Regular/Italic Class", 0, 1100 },
+ { "Verdana", 12, "Regular Class", 'm', 975 },
+ { "Verdana", 12, "Regular/Italic Class", 0, 1050 },
+ { "Verdana", 13, "Regular/Italic Class", 'i', 950 },
+ { "Verdana", 13, "Regular/Italic Class", 'j', 950 },
+ { "Verdana", 13, "Regular/Italic Class", 'l', 950 },
+ { "Verdana", 16, "Regular Class", 0, 1050 },
+ { "Verdana", 9, "Regular/Italic Class", 0, 1050 },
+ { "Times New Roman", 16, "Regular Class", 'm', 918 },
+ { "Trebuchet MS", 11, "Regular Class", 'm', 800 },
+ { "Trebuchet MS", 12, "Regular Class", 'm', 800 },
+ };
+
+#else
+
+#define COMPATIBLE_WIDTHS_RULES_SIZE 1
+
+ SPH_TweakRule COMPATIBLE_WIDTHS_Rules
+ [COMPATIBLE_WIDTHS_RULES_SIZE] =
+ {
+ { "-", 0, "", 0 },
+ };
+
+
+#define X_SCALING_RULES_SIZE 1
+
+ SPH_ScaleRule X_SCALING_Rules
+ [X_SCALING_RULES_SIZE] =
+ {
+ { "-", 0, "", 0, 1000 },
+ };
+
+#endif /* FORCE_NATURAL_WIDTHS */
+
+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
+
+FT_END_HEADER
+
+#endif /* __TTSUBPIX_H__ */
+
+/* END */
diff --git a/freetype/src/type1/t1load.c b/freetype/src/type1/t1load.c
index 1a5fcdcd4..2661d95a6 100644
--- a/freetype/src/type1/t1load.c
+++ b/freetype/src/type1/t1load.c
@@ -239,18 +239,11 @@
for ( j = 1; j < axismap->num_points; ++j )
{
if ( ncv <= axismap->blend_points[j] )
- {
- FT_Fixed t = FT_MulDiv( ncv - axismap->blend_points[j - 1],
- 0x10000L,
- axismap->blend_points[j] -
- axismap->blend_points[j - 1] );
-
return INT_TO_FIXED( axismap->design_points[j - 1] ) +
- FT_MulDiv( t,
- axismap->design_points[j] -
- axismap->design_points[j - 1],
- 1L );
- }
+ ( axismap->design_points[j] - axismap->design_points[j - 1] ) *
+ FT_DivFix( ncv - axismap->blend_points[j - 1],
+ axismap->blend_points[j] -
+ axismap->blend_points[j - 1] );
}
return INT_TO_FIXED( axismap->design_points[axismap->num_points - 1] );
@@ -327,7 +320,7 @@
mmvar->num_axis = mmaster.num_axis;
mmvar->num_designs = mmaster.num_designs;
- mmvar->num_namedstyles = (FT_UInt)-1; /* Does not apply */
+ mmvar->num_namedstyles = ~0; /* Does not apply */
mmvar->axis = (FT_Var_Axis*)&mmvar[1];
/* Point to axes after MM_Var struct */
mmvar->namedstyle = NULL;
@@ -340,8 +333,8 @@
mmvar->axis[i].def = ( mmvar->axis[i].minimum +
mmvar->axis[i].maximum ) / 2;
/* Does not apply. But this value is in range */
- mmvar->axis[i].strid = (FT_UInt)-1; /* Does not apply */
- mmvar->axis[i].tag = (FT_ULong)-1; /* Does not apply */
+ mmvar->axis[i].strid = ~0; /* Does not apply */
+ mmvar->axis[i].tag = ~0; /* Does not apply */
if ( ft_strcmp( mmvar->axis[i].name, "Weight" ) == 0 )
mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'g', 'h', 't' );
@@ -622,7 +615,7 @@
goto Exit;
}
- if ( FT_ALLOC( blend->axis_names[n], len + 1 ) )
+ if ( FT_ALLOC( blend->axis_names[n], (FT_Long)( len + 1 ) ) )
goto Exit;
name = (FT_Byte*)blend->axis_names[n];
@@ -1131,8 +1124,7 @@
/* 1000 / temp_scale, because temp_scale was already multiplied by */
/* 1000 (in t1_tofixed, from psobjs.c). */
- root->units_per_EM = (FT_UShort)( FT_DivFix( 1000 * 0x10000L,
- temp_scale ) >> 16 );
+ root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale );
/* we need to scale the values by 1.0/temp_scale */
if ( temp_scale != 0x10000L )
@@ -1284,7 +1276,7 @@
cur = parser->root.cursor;
- if ( *cur == '/' && cur + 2 < limit && n < count )
+ if ( cur + 2 < limit && *cur == '/' && n < count )
{
FT_PtrDist len;
@@ -1293,6 +1285,8 @@
parser->root.cursor = cur;
T1_Skip_PS_Token( parser );
+ if ( parser->root.cursor >= limit )
+ return;
if ( parser->root.error )
return;
@@ -1512,6 +1506,12 @@
num_glyphs = (FT_Int)T1_ToInt( parser );
+ if ( num_glyphs < 0 )
+ {
+ error = T1_Err_Invalid_File_Format;
+ goto Fail;
+ }
+
/* some fonts like Optima-Oblique not only define the /CharStrings */
/* array but access it also */
if ( num_glyphs == 0 || parser->root.error )
diff --git a/freetype/src/type1/t1parse.c b/freetype/src/type1/t1parse.c
index 52aad905c..3a4511f07 100644
--- a/freetype/src/type1/t1parse.c
+++ b/freetype/src/type1/t1parse.c
@@ -342,7 +342,7 @@
{
c = cur[0];
if ( c == 'e' && cur + 9 < limit ) /* 9 = 5 letters for `eexec' + */
- /* newline + 4 chars */
+ /* whitespace + 4 chars */
{
if ( cur[1] == 'e' &&
cur[2] == 'x' &&
@@ -364,7 +364,8 @@
/* or string (as e.g. in u003043t.gsf from ghostscript) */
parser->root.cursor = parser->base_dict;
- parser->root.limit = cur + 9;
+ /* set limit to `eexec' + whitespace + 4 characters */
+ parser->root.limit = cur + 10;
cur = parser->root.cursor;
limit = parser->root.limit;
@@ -396,7 +397,8 @@
parser->root.limit = parser->base_dict + parser->base_len;
T1_Skip_PS_Token( parser );
- cur = parser->root.cursor;
+ cur = parser->root.cursor;
+ limit = parser->root.limit;
/* according to the Type1 spec, the first cipher byte must not be */
/* an ASCII whitespace character code (blank, tab, carriage return */
@@ -437,11 +439,12 @@
/* now determine whether the private dictionary is encoded in binary */
/* or hexadecimal ASCII format -- decode it accordingly */
- /* we need to access the next 4 bytes (after the final \r following */
- /* the `eexec' keyword); if they all are hexadecimal digits, then */
- /* we have a case of ASCII storage */
+ /* we need to access the next 4 bytes (after the final whitespace */
+ /* following the `eexec' keyword); if they all are hexadecimal */
+ /* digits, then we have a case of ASCII storage */
- if ( ft_isxdigit( cur[0] ) && ft_isxdigit( cur[1] ) &&
+ if ( cur + 3 < limit &&
+ ft_isxdigit( cur[0] ) && ft_isxdigit( cur[1] ) &&
ft_isxdigit( cur[2] ) && ft_isxdigit( cur[3] ) )
{
/* ASCII hexadecimal encoding */
diff --git a/freetype/src/type42/t42parse.c b/freetype/src/type42/t42parse.c
index 19c9680c0..20c136549 100644
--- a/freetype/src/type42/t42parse.c
+++ b/freetype/src/type42/t42parse.c
@@ -265,8 +265,7 @@
/* 1000 / temp_scale, because temp_scale was already multiplied by */
/* 1000 (in t1_tofixed, from psobjs.c). */
- root->units_per_EM = (FT_UShort)( FT_DivFix( 1000 * 0x10000L,
- temp_scale ) >> 16 );
+ root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale );
/* we need to scale the values by 1.0/temp_scale */
if ( temp_scale != 0x10000L )